mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-10-31 23:08:32 +00:00 
			
		
		
		
	initial refactor sketch
This commit is contained in:
		
							parent
							
								
									3b325798c2
								
							
						
					
					
						commit
						3549c75474
					
				| @ -4,12 +4,7 @@ Simplifications: | ||||
| 
 | ||||
|  - unidirectional paychans | ||||
|  - no top ups or partial withdrawals (only opening and closing) | ||||
|  - no protection against fund lock up from dissapearing receiver | ||||
| 
 | ||||
| 
 | ||||
|  TODO | ||||
|   - fix issue with multisig accounts and sequence numbers | ||||
|   - create a nicer paychan store key for querying (and implement query) | ||||
|   - expand client code | ||||
|   - tidy up - add return tags | ||||
|   - start removing simplifications, refactor | ||||
|  - chnge module name to "channel"? | ||||
|  | ||||
| @ -33,6 +33,7 @@ import ( | ||||
| // send paychan payment
 | ||||
| // get balance from receiver
 | ||||
| 
 | ||||
| /* | ||||
| func CreatePaychanCmd(cdc *wire.Codec) *cobra.Command { | ||||
| 	flagTo := "to" | ||||
| 	flagAmount := "amount" | ||||
| @ -297,3 +298,4 @@ func EnsureSignBuild(ctx context.CoreContext, name string, msg sdk.Msg, cdc *wir | ||||
| 	} | ||||
| 	return txBytes, nil | ||||
| } | ||||
| */ | ||||
|  | ||||
| @ -7,6 +7,7 @@ import ( | ||||
| 	//"github.com/cosmos/cosmos-sdk/wire"
 | ||||
| ) | ||||
| 
 | ||||
| /* | ||||
| // RegisterRoutes registers paychan-related REST handlers to a router
 | ||||
| func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb keys.Keybase) { | ||||
| 	//r.HandleFunc("/accounts/{address}/send", SendRequestHandlerFn(cdc, kb, ctx)).Methods("POST")
 | ||||
| @ -20,3 +21,4 @@ func RegisterRoutes(ctx context.CoreContext, r *mux.Router, cdc *wire.Codec, kb | ||||
| // get balance from receiver
 | ||||
| // get balance from local storage
 | ||||
| // handle incoming payment
 | ||||
| */ | ||||
|  | ||||
							
								
								
									
										13
									
								
								internal/x/paychan/endblocker.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								internal/x/paychan/endblocker.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,13 @@ | ||||
| package paychan | ||||
| 
 | ||||
| import () | ||||
| 
 | ||||
| func EndBlocker(ctx sdk.Context k Keeper) sdk.Tags { | ||||
| 
 | ||||
| 	// Iterate through submittedUpdates and for each
 | ||||
| 	//		if current block height >= executionDate
 | ||||
| 	//			k.CloseChannel(...)
 | ||||
| 
 | ||||
| 	tags := sdk.NewTags() | ||||
| 	return tags | ||||
| } | ||||
| @ -12,8 +12,8 @@ func NewHandler(k Keeper) sdk.Handler { | ||||
| 		switch msg := msg.(type) { | ||||
| 		case MsgCreate: | ||||
| 			return handleMsgCreate(ctx, k, msg) | ||||
| 		case MsgClose: | ||||
| 			return handleMsgClose(ctx, k, msg) | ||||
| 		case MsgSubmitUpdate: | ||||
| 			return handleMsgSubmitUpdate(ctx, k, msg) | ||||
| 		default: | ||||
| 			errMsg := "Unrecognized paychan Msg type: " + reflect.TypeOf(msg).Name() | ||||
| 			return sdk.ErrUnknownRequest(errMsg).Result() | ||||
| @ -21,11 +21,10 @@ func NewHandler(k Keeper) sdk.Handler { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Handle CreateMsg.
 | ||||
| // Handle MsgCreate
 | ||||
| // Leaves validation to the keeper methods.
 | ||||
| func handleMsgCreate(ctx sdk.Context, k Keeper, msg MsgCreate) sdk.Result { | ||||
| 	// TODO maybe remove tags for first version
 | ||||
| 	tags, err := k.CreatePaychan(ctx, msg.Sender, msg.Receiver, msg.Amount) | ||||
| 	tags, err := k.CreateChannel(ctx, msg.Participants[0], msg.Participants[len(msg.Participants)-1], msg.Coins) | ||||
| 	if err != nil { | ||||
| 		return err.Result() | ||||
| 	} | ||||
| @ -35,15 +34,19 @@ func handleMsgCreate(ctx sdk.Context, k Keeper, msg MsgCreate) sdk.Result { | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| // Handle CloseMsg.
 | ||||
| // Handle MsgSubmitUpdate
 | ||||
| // Leaves validation to the keeper methods.
 | ||||
| func handleMsgClose(ctx sdk.Context, k Keeper, msg MsgClose) sdk.Result { | ||||
| 	// TODO maybe remove tags for first version
 | ||||
| 	tags, err := k.ClosePaychan(ctx, msg.Sender, msg.Receiver, msg.Id, msg.ReceiverAmount) | ||||
| func handleMsgSubmitUpdate(ctx sdk.Context, k Keeper, msg MsgSubmitUpdate) sdk.Result { | ||||
| 
 | ||||
| 	// if only sender sig then
 | ||||
| 	tags, err := k.InitChannelCloseBySender() | ||||
| 	// else (if there are both)
 | ||||
| 	tags, err := k.ChannelCloseByReceiver() | ||||
| 
 | ||||
| 	if err != nil { | ||||
| 		return err.Result() | ||||
| 	} | ||||
| 	// These tags can be used to subscribe to channel closures
 | ||||
| 	// These tags can be used by clients to subscribe to channel close attempts
 | ||||
| 	return sdk.Result{ | ||||
| 		Tags: tags, | ||||
| 	} | ||||
|  | ||||
| @ -8,20 +8,19 @@ import ( | ||||
| 	"github.com/cosmos/cosmos-sdk/x/bank" | ||||
| ) | ||||
| 
 | ||||
| // keeper of the paychan store
 | ||||
| // Keeper of the paychan store
 | ||||
| // Handles validation internally. Does not rely on calling code to do validation.
 | ||||
| // Aim to keep public methids safe, private ones not necessaily.
 | ||||
| // Aim to keep public methods safe, private ones not necessaily.
 | ||||
| type Keeper struct { | ||||
| 	storeKey   sdk.StoreKey | ||||
| 	cdc        *wire.Codec // needed to serialize objects before putting them in the store
 | ||||
| 	coinKeeper bank.Keeper | ||||
| 
 | ||||
| 	// codespace
 | ||||
| 	//codespace sdk.CodespaceType // ??
 | ||||
| 	// TODO investigate codespace
 | ||||
| 	//codespace sdk.CodespaceType
 | ||||
| } | ||||
| 
 | ||||
| // Called when creating new app.
 | ||||
| //func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper {
 | ||||
| func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper) Keeper { | ||||
| 	keeper := Keeper{ | ||||
| 		storeKey:   key, | ||||
| @ -33,7 +32,7 @@ func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper) Keeper { | ||||
| } | ||||
| 
 | ||||
| // bunch of business logic ...
 | ||||
| 
 | ||||
| /* | ||||
| // Reteive a payment channel struct from the blockchain store.
 | ||||
| // They are indexed by a concatenation of sender address, receiver address, and an integer.
 | ||||
| func (k Keeper) GetPaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, id int64) (Paychan, bool) { | ||||
| @ -60,60 +59,91 @@ func (k Keeper) setPaychan(ctx sdk.Context, pych Paychan) { | ||||
| 	pychKey := paychanKey(pych.Sender, pych.Receiver, pych.Id) | ||||
| 	store.Set(pychKey, bz) // panics if something goes wrong
 | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| // Create a new payment channel and lock up sender funds.
 | ||||
| func (k Keeper) CreatePaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, amount sdk.Coins) (sdk.Tags, sdk.Error) { | ||||
| 	// TODO move validation somewhere nicer
 | ||||
| 	// args present
 | ||||
| 	if len(sender) == 0 { | ||||
| 		return nil, sdk.ErrInvalidAddress(sender.String()) | ||||
| 	} | ||||
| 	if len(receiver) == 0 { | ||||
| 		return nil, sdk.ErrInvalidAddress(receiver.String()) | ||||
| 	} | ||||
| 	if len(amount) == 0 { | ||||
| 		return nil, sdk.ErrInvalidCoins(amount.String()) | ||||
| 	} | ||||
| 	// Check if coins are sorted, non zero, positive
 | ||||
| 	if !amount.IsValid() { | ||||
| 		return nil, sdk.ErrInvalidCoins(amount.String()) | ||||
| 	} | ||||
| 	if !amount.IsPositive() { | ||||
| 		return nil, sdk.ErrInvalidCoins(amount.String()) | ||||
| 	} | ||||
| 	// sender should exist already as they had to sign.
 | ||||
| 	// receiver address exists. am is the account mapper in the coin keeper.
 | ||||
| 	// TODO automatically create account if not present?
 | ||||
| 	// TODO remove as account mapper not available to this pkg
 | ||||
| 	//if k.coinKeeper.am.GetAccount(ctx, receiver) == nil {
 | ||||
| 	//	return nil, sdk.ErrUnknownAddress(receiver.String())
 | ||||
| 	//}
 | ||||
| func (k Keeper) CreatePaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, coins sdk.Coins) (sdk.Tags, sdk.Error) { | ||||
| 	// TODO do validation and maybe move somewhere nicer
 | ||||
| 	/* | ||||
| 		// args present
 | ||||
| 		if len(sender) == 0 { | ||||
| 			return nil, sdk.ErrInvalidAddress(sender.String()) | ||||
| 		} | ||||
| 		if len(receiver) == 0 { | ||||
| 			return nil, sdk.ErrInvalidAddress(receiver.String()) | ||||
| 		} | ||||
| 		if len(amount) == 0 { | ||||
| 			return nil, sdk.ErrInvalidCoins(amount.String()) | ||||
| 		} | ||||
| 		// Check if coins are sorted, non zero, positive
 | ||||
| 		if !amount.IsValid() { | ||||
| 			return nil, sdk.ErrInvalidCoins(amount.String()) | ||||
| 		} | ||||
| 		if !amount.IsPositive() { | ||||
| 			return nil, sdk.ErrInvalidCoins(amount.String()) | ||||
| 		} | ||||
| 		// sender should exist already as they had to sign.
 | ||||
| 		// receiver address exists. am is the account mapper in the coin keeper.
 | ||||
| 		// TODO automatically create account if not present?
 | ||||
| 		// TODO remove as account mapper not available to this pkg
 | ||||
| 		//if k.coinKeeper.am.GetAccount(ctx, receiver) == nil {
 | ||||
| 		//	return nil, sdk.ErrUnknownAddress(receiver.String())
 | ||||
| 		//}
 | ||||
| 
 | ||||
| 	// sender has enough coins - done in Subtract method
 | ||||
| 	// TODO check if sender and receiver different?
 | ||||
| 		// sender has enough coins - done in Subtract method
 | ||||
| 		// TODO check if sender and receiver different?
 | ||||
| 	*/ | ||||
| 
 | ||||
| 	// Calculate next id (just num of existing paychans - zero indexed)
 | ||||
| 	id := int64(len(k.GetPaychans(sender, receiver))) | ||||
| 	// Calculate next id
 | ||||
| 	id := k.getNewChannelID(ctx) | ||||
| 	// subtract coins from sender
 | ||||
| 	_, tags, err := k.coinKeeper.SubtractCoins(ctx, sender, amount) | ||||
| 	_, tags, err := k.coinKeeper.SubtractCoins(ctx, sender, coins) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	// create new Paychan struct
 | ||||
| 	pych := Paychan{ | ||||
| 		Sender:   sender, | ||||
| 		Receiver: receiver, | ||||
| 		Id:       id, | ||||
| 		Balance:  amount, | ||||
| 	channel := Channel{ | ||||
| 		ID: id | ||||
| 		Participants:	[2]sdk.AccAddress{sender, receiver}, | ||||
| 		Coins:  coins, | ||||
| 	} | ||||
| 	// save to db
 | ||||
| 	k.setPaychan(ctx, pych) | ||||
| 	k.setChannel(ctx, channel) | ||||
| 
 | ||||
| 	// TODO create tags
 | ||||
| 	//tags := sdk.NewTags()
 | ||||
| 	return tags, err | ||||
| } | ||||
| 
 | ||||
| /* This is how gov manages creating unique IDs. Needs to be deterministic - can't use UUID | ||||
| func (keeper Keeper) getNewChannelID(ctx sdk.Context) (channelID int64, err sdk.Error) { | ||||
| 	store := ctx.KVStore(keeper.storeKey) | ||||
| 	bz := store.Get(KeyNextProposalID) | ||||
| 	if bz == nil { | ||||
| 		return -1, ErrInvalidGenesis(keeper.codespace, "InitialProposalID never set") | ||||
| 	} | ||||
| 	keeper.cdc.MustUnmarshalBinary(bz, &proposalID) | ||||
| 	bz = keeper.cdc.MustMarshalBinary(proposalID + 1) | ||||
| 	store.Set(KeyNextProposalID, bz) | ||||
| 	return proposalID, nil | ||||
| */ | ||||
| 
 | ||||
| func (k Keeper) ChannelCloseByReceiver() () { | ||||
| 	// Validate inputs
 | ||||
| 	// k.closeChannel
 | ||||
| } | ||||
| 
 | ||||
| func (k Keeper) InitChannelCloseBySender() () { | ||||
| 	// Validate inputs
 | ||||
| 	// Create SubmittedUpdate from Update and add to queue
 | ||||
| } | ||||
| 
 | ||||
| func (k Keeper) closeChannel() () { | ||||
| 	// Remove corresponding SubmittedUpdate from queue (if it exist)
 | ||||
| 	// Add coins to sender and receiver
 | ||||
| 	// Delete Channel
 | ||||
| } | ||||
| /* | ||||
| // Close a payment channel and distribute funds to participants.
 | ||||
| func (k Keeper) ClosePaychan(ctx sdk.Context, sender sdk.Address, receiver sdk.Address, id int64, receiverAmount sdk.Coins) (sdk.Tags, sdk.Error) { | ||||
| 	if len(sender) == 0 { | ||||
| @ -190,3 +220,4 @@ func (k Keeper) GetPaychans(sender sdk.Address, receiver sdk.Address) []Paychan | ||||
| } | ||||
| 
 | ||||
| // maybe getAllPaychans(sender sdk.address) []Paychan
 | ||||
| */ | ||||
|  | ||||
| @ -5,81 +5,91 @@ import ( | ||||
| 	"strconv" | ||||
| ) | ||||
| 
 | ||||
| // Paychan Type
 | ||||
| // Used to represent paychan in keeper module and to serialize.
 | ||||
| // probably want to convert this to a general purpose "state"
 | ||||
| type Paychan struct { | ||||
| 	Sender   sdk.Address | ||||
| 	Receiver sdk.Address | ||||
| 	Id       int64 | ||||
| 	Balance  sdk.Coins | ||||
| /*  CHANNEL TYPES  */ | ||||
| 
 | ||||
| // Used to represent a channel in the keeper module.
 | ||||
| // Participants is limited to two as currently these are unidirectional channels.
 | ||||
| // Last participant is designated as receiver.
 | ||||
| type Channel struct { | ||||
| 	ID       int64 | ||||
| 	Participants [2]sdk.AccAddress | ||||
| 	Coins  sdk.Coins | ||||
| } | ||||
| 
 | ||||
| // Message Types
 | ||||
| // The data that is passed between participants as payments, and submitted to the blockchain to close a channel.
 | ||||
| type Update struct { | ||||
| 	ChannelID int64 | ||||
| 	CoinsUpdate //TODO type
 | ||||
| 	Sequence int64 | ||||
| 	sig // TODO type, only sender needs to sign
 | ||||
| } | ||||
| 
 | ||||
| // Message implement the sdk.Msg interface:
 | ||||
| // An update that has been submitted to the blockchain, but not yet acted on.
 | ||||
| type SubmittedUpdate { | ||||
| 	Update | ||||
| 	executionDate int64 // BlockHeight
 | ||||
| } | ||||
| 
 | ||||
| // type Msg interface {
 | ||||
| /*  MESSAGE TYPES  */ | ||||
| /* | ||||
| Message implement the sdk.Msg interface: | ||||
| type Msg interface { | ||||
| 
 | ||||
| // 	// Return the message type.
 | ||||
| // 	// Must be alphanumeric or empty.
 | ||||
| // 	Type() string
 | ||||
| 	// Return the message type.
 | ||||
| 	// Must be alphanumeric or empty.
 | ||||
| 	Type() string | ||||
| 
 | ||||
| // 	// Get the canonical byte representation of the Msg.
 | ||||
| // 	GetSignBytes() []byte
 | ||||
| 	// Get the canonical byte representation of the Msg.
 | ||||
| 	GetSignBytes() []byte | ||||
| 
 | ||||
| // 	// ValidateBasic does a simple validation check that
 | ||||
| // 	// doesn't require access to any other information.
 | ||||
| // 	ValidateBasic() Error
 | ||||
| 	// ValidateBasic does a simple validation check that
 | ||||
| 	// doesn't require access to any other information.
 | ||||
| 	ValidateBasic() Error | ||||
| 
 | ||||
| // 	// Signers returns the addrs of signers that must sign.
 | ||||
| // 	// CONTRACT: All signatures must be present to be valid.
 | ||||
| // 	// CONTRACT: Returns addrs in some deterministic order.
 | ||||
| // 	GetSigners() []Address
 | ||||
| // }
 | ||||
| 	// Signers returns the addrs of signers that must sign.
 | ||||
| 	// CONTRACT: All signatures must be present to be valid.
 | ||||
| 	// CONTRACT: Returns addrs in some deterministic order.
 | ||||
| 	GetSigners() []Address | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| // A message to create a payment channel.
 | ||||
| type MsgCreate struct { | ||||
| 	// maybe just wrap a paychan struct
 | ||||
| 	Sender   sdk.Address | ||||
| 	Receiver sdk.Address | ||||
| 	Amount   sdk.Coins | ||||
| 	Participants	[2]sdk.AccAddress | ||||
| 	Coins	sdk.Coins | ||||
| } | ||||
| 
 | ||||
| // Create a new message.
 | ||||
| // Called in client code when constructing transaction from cli args to send to the network.
 | ||||
| // maybe just a placeholder for more advanced future functionality?
 | ||||
| // func (msg CreatMsg) NewMsgCreate(sender sdk.Address, receiver sdk.Address, amount sdk.Coins) MsgCreate {
 | ||||
| // 	return MsgCreate{
 | ||||
| // 		sender
 | ||||
| // 		receiver
 | ||||
| // 		amount
 | ||||
| // 	}
 | ||||
| // }
 | ||||
| //Create a new message.
 | ||||
| /* | ||||
| Called in client code when constructing transaction from cli args to send to the network. | ||||
| maybe just a placeholder for more advanced future functionality? | ||||
| func (msg CreatMsg) NewMsgCreate(sender sdk.Address, receiver sdk.Address, amount sdk.Coins) MsgCreate { | ||||
| 	return MsgCreate{ | ||||
| 		sender | ||||
| 		receiver | ||||
| 		amount | ||||
| 	} | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| func (msg MsgCreate) Type() string { return "paychan" } | ||||
| 
 | ||||
| func (msg MsgCreate) GetSignBytes() []byte { | ||||
| 	// TODO create msgCdc in wire.go
 | ||||
| 	b, err := msgCdc.MarshalJSON(struct { | ||||
| 		SenderAddr   string    `json:"sender_addr"` | ||||
| 		ReceiverAddr string    `json:"receiver_addr"` | ||||
| 		Amount       sdk.Coins `json:"amount"` | ||||
| 	}{ | ||||
| 		SenderAddr:   sdk.MustBech32ifyAcc(msg.Sender), | ||||
| 		ReceiverAddr: sdk.MustBech32ifyAcc(msg.Receiver), | ||||
| 		Amount:       msg.Amount, | ||||
| 	}) | ||||
| 	bz, err := msgCdc.Marshal(msg) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	return b | ||||
| 	return MustSortJSON(bz) | ||||
| } | ||||
| 
 | ||||
| func (msg MsgCreate) ValidateBasic() sdk.Error { | ||||
| 	// Validate msg as an optimisation to avoid all validation going to keeper. It's run before the sigs are checked by the auth module.
 | ||||
| 	// Validate without external information (such as account balance)
 | ||||
| 
 | ||||
| 	//TODO implement
 | ||||
| 
 | ||||
| 	/* | ||||
| 	// check if all fields present / not 0 valued
 | ||||
| 	if len(msg.Sender) == 0 { | ||||
| 		return sdk.ErrInvalidAddress(msg.Sender.String()) | ||||
| @ -98,55 +108,42 @@ func (msg MsgCreate) ValidateBasic() sdk.Error { | ||||
| 		return sdk.ErrInvalidCoins(msg.Amount.String()) | ||||
| 	} | ||||
| 	// TODO check if Address valid?
 | ||||
| 	*/ | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (msg MsgCreate) GetSigners() []sdk.Address { | ||||
| 	// Only sender must sign to create a paychan
 | ||||
| 	return []sdk.Address{msg.Sender} | ||||
| 	return []sdk.AccAddress{msg.Participants[0]} // select sender address
 | ||||
| } | ||||
| 
 | ||||
| // A message to close a payment channel.
 | ||||
| type MsgClose struct { | ||||
| 	// have to include sender and receiver in msg explicitly (rather than just universal paychanID)
 | ||||
| 	//  this gives ability to verify signatures with no external information
 | ||||
| 	Sender         sdk.Address | ||||
| 	Receiver       sdk.Address | ||||
| 	Id             int64     // TODO is another int type better?
 | ||||
| 	ReceiverAmount sdk.Coins // amount the receiver should get - sender amount implicit with paychan balance
 | ||||
| type MsgSubmitUpdate struct { | ||||
| 	Update | ||||
| 	// might need a "signer" to be able to say who is signing this as either can or not
 | ||||
| } | ||||
| 
 | ||||
| // func (msg MsgClose) NewMsgClose(sender sdk.Address, receiver sdk.Address, id integer, receiverAmount sdk.Coins) MsgClose {
 | ||||
| // 	return MsgClose{
 | ||||
| // 		sender
 | ||||
| // 		receiver
 | ||||
| // 		id
 | ||||
| // 		receiverAmount
 | ||||
| // func (msg MsgSubmitUpdate) NewMsgSubmitUpdate(update Update) MsgSubmitUpdate {
 | ||||
| // 	return MsgSubmitUpdate{
 | ||||
| // 		update
 | ||||
| // 	}
 | ||||
| // }
 | ||||
| 
 | ||||
| func (msg MsgClose) Type() string { return "paychan" } | ||||
| func (msg MsgSubmitUpdate) Type() string { return "paychan" } | ||||
| 
 | ||||
| func (msg MsgClose) GetSignBytes() []byte { | ||||
| func (msg MsgSubmitUpdate) GetSignBytes() []byte { | ||||
| 	// TODO create msgCdc in wire.go
 | ||||
| 	b, err := msgCdc.MarshalJSON(struct { | ||||
| 		SenderAddr     string    `json:"sender_addr"` | ||||
| 		ReceiverAddr   string    `json:"receiver_addr"` | ||||
| 		Id             int64     `json:"id"` | ||||
| 		ReceiverAmount sdk.Coins `json:"receiver_amount"` | ||||
| 	}{ | ||||
| 		SenderAddr:     sdk.MustBech32ifyAcc(msg.Sender), | ||||
| 		ReceiverAddr:   sdk.MustBech32ifyAcc(msg.Receiver), | ||||
| 		Id:             msg.Id, | ||||
| 		ReceiverAmount: msg.ReceiverAmount, | ||||
| 	}) | ||||
| 	bz, err := msgCdc.Marshal(msg) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	return b | ||||
| 	return MustSortJSON(bz) | ||||
| } | ||||
| 
 | ||||
| func (msg MsgClose) ValidateBasic() sdk.Error { | ||||
| func (msg MsgSubmitUpdate) ValidateBasic() sdk.Error { | ||||
| 
 | ||||
| 	// TODO implement
 | ||||
| 	/* | ||||
| 	// check if all fields present / not 0 valued
 | ||||
| 	if len(msg.Sender) == 0 { | ||||
| 		return sdk.ErrInvalidAddress(msg.Sender.String()) | ||||
| @ -169,10 +166,12 @@ func (msg MsgClose) ValidateBasic() sdk.Error { | ||||
| 		return sdk.ErrInvalidCoins(msg.ReceiverAmount.String()) | ||||
| 	} | ||||
| 	// TODO check if Address valid?
 | ||||
| 	*/ | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func (msg MsgClose) GetSigners() []sdk.Address { | ||||
| 	// Both sender and receiver must sign in order to close a channel
 | ||||
| 	return []sdk.Address{msg.Sender, msg.Receiver} | ||||
| func (msg MsgSubmitUpdate) GetSigners() []sdk.Address { | ||||
| 	// Signing not strictly necessary as signatures contained within the channel update.
 | ||||
| 	// TODO add signature by submitting address
 | ||||
| 	return []sdk.Address{} | ||||
| } | ||||
|  | ||||
| @ -4,6 +4,7 @@ import ( | ||||
| 	"github.com/cosmos/cosmos-sdk/wire" | ||||
| ) | ||||
| 
 | ||||
| /* | ||||
| func RegisterWire(cdc *wire.Codec) { | ||||
| 	cdc.RegisterConcrete(MsgCreate{}, "paychan/MsgCreate", nil) | ||||
| 	cdc.RegisterConcrete(MsgClose{}, "paychan/MsgClose", nil) | ||||
| @ -16,3 +17,4 @@ func init() { | ||||
| 	// TODO is this needed?
 | ||||
| 	//wire.RegisterCrypto(msgCdc)
 | ||||
| } | ||||
| */ | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 rhuairahrighairigh
						rhuairahrighairigh