From 4732c32ab1aa506801c4bb8c1099815202941e48 Mon Sep 17 00:00:00 2001 From: rhuairahrighairigh Date: Tue, 10 Jul 2018 14:56:04 +0100 Subject: [PATCH] add handler logic --- internal/x/paychan/handler.go | 40 ++++++++++++++++++++++++----------- internal/x/paychan/keeper.go | 33 +++++++++++++++++++++++------ internal/x/paychan/types.go | 32 ++++++++++++++-------------- 3 files changed, 70 insertions(+), 35 deletions(-) diff --git a/internal/x/paychan/handler.go b/internal/x/paychan/handler.go index b32556f9..cb89735d 100644 --- a/internal/x/paychan/handler.go +++ b/internal/x/paychan/handler.go @@ -1,19 +1,19 @@ package paychan import ( - sdk "github.com/cosmos/cosmos-sdk/types" "reflect" + sdk "github.com/cosmos/cosmos-sdk/types" ) -// Called when adding routes to a newly created app. // NewHandler returns a handler for "paychan" type messages. +// Called when adding routes to a newly created app. func NewHandler(k Keeper) sdk.Handler { return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { switch msg := msg.(type) { - case MsgSend: - return handleMsgSend(ctx, k, msg) - case MsgIssue: - return handleMsgIssue(ctx, k, msg) + case MsgCreate: + return handleMsgCreate(ctx, k, msg) + case MsgClose: + return handleMsgClose(ctx, k, msg) default: errMsg := "Unrecognized paychan Msg type: " + reflect.TypeOf(msg).Name() return sdk.ErrUnknownRequest(errMsg).Result() @@ -21,14 +21,30 @@ func NewHandler(k Keeper) sdk.Handler { } } +// TODO does validation go here or in the keeper? + // Handle CreateMsg. -func handleMsgCreate(ctx sdk.Context, k Keeper, msg MsgSend) sdk.Result { - // k.CreatePaychan(args...) - // handle erros +func handleMsgCreate(ctx sdk.Context, k Keeper, msg MsgCreate) sdk.Result { + // TODO maybe remove tags for first version + tags, err := k.CreatePaychan(msg.sender, msg.receiver, msg.amount) + if err != nil { + return err.Result() + } + // TODO any other information that should be returned in Result? + return sdk.Result{ + Tags: tags + } } // Handle CloseMsg. -func handleMsgClose(ctx sdk.Context, k Keeper, msg MsgIssue) sdk.Result { - // k.ClosePaychan(args...) - // handle errors +func handleMsgClose(ctx sdk.Context, k Keeper, msg MsgClose) sdk.Result { + // TODO maybe remove tags for first version + tags, err := k.ClosePaychan(msg.sender, msg.receiver, msg.id, msg.receiverAmount) + if err != nil { + return err.Result() + } + // These tags can be used to subscribe to channel closures + return sdk.Result{ + Tags: tags + } } diff --git a/internal/x/paychan/keeper.go b/internal/x/paychan/keeper.go index 58209f63..1a22136b 100644 --- a/internal/x/paychan/keeper.go +++ b/internal/x/paychan/keeper.go @@ -2,12 +2,15 @@ package paychan import ( "strconv" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" ) // keeper of the paychan store type Keeper struct { storeKey sdk.StoreKey - //cdc *wire.Codec // needed? + cdc *wire.Codec // needed to serialize objects before putting them in the store coinKeeper bank.Keeper // codespace @@ -16,10 +19,10 @@ type Keeper struct { // Called when creating new app. //func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper, codespace sdk.CodespaceType) Keeper { -func NewKeeper(key sdk.StoreKey, ck bank.Keeper) Keeper { +func NewKeeper(cdc *wire.Codec, key sdk.StoreKey, ck bank.Keeper) Keeper { keeper := Keeper{ storeKey: key, - //cdc: cdc, + cdc: cdc, coinKeeper: ck, //codespace: codespace, } @@ -58,7 +61,9 @@ func (keeper Keeper) setPaychan(pych Paychan) sdk.Error { } // Create a new payment channel and lock up sender funds. -func (keeer Keeper) CreatePaychan(sender sdk.Address, receiver sdkAddress, id integer, amt sdk.Coins) (Paychan, sdk.Error) { +func (keeer Keeper) CreatePaychan(sender sdk.Address, receiver sdkAddress, amt sdk.Coins) (sdk.Tags, sdk.Error) { + // Calculate next id (num existing paychans plus 1) + id := len(keeper.GetPaychans(sender, receiver)) + 1 // subtract coins from sender k.coinKeeper.SubtractCoins(ctx, sender, amt) // create new Paychan struct (create ID) @@ -69,16 +74,18 @@ func (keeer Keeper) CreatePaychan(sender sdk.Address, receiver sdkAddress, id in // save to db err := k.setPaychan(pych) - return pych, err // TODO validation // sender has enough coins - done in Subtract method // receiver address exists? // paychan doesn't exist already + + tags := sdk.NewTags() + return tags, err } // Close a payment channel and distribute funds to participants. -func (keeper Keeper) ClosePaychan(sender sdk.Address, receiver sdk.Address, id integer, receiverAmt sdk.Coins) sdk.Error { +func (keeper Keeper) ClosePaychan(sender sdk.Address, receiver sdk.Address, id integer, receiverAmt sdk.Coins) (sdk.Tags, sdk.Error) { pych := GetPaychan(ctx, sender, receiver, id) // compute coin distribution senderAmt = pych.balance.Minus(receiverAmt) // Minus sdk.Coins method @@ -96,7 +103,13 @@ func (keeper Keeper) ClosePaychan(sender sdk.Address, receiver sdk.Address, id i // output coins are less than paychan balance // sender and receiver addresses exist? - return nil + //sdk.NewTags( + // "action", []byte("channel closure"), + // "receiver", receiver.Bytes(), + // "sender", sender.Bytes(), + // "id", ??) + tags := sdk.NewTags() + return tags, nil } // Creates a key to reference a paychan in the blockchain store. @@ -109,4 +122,10 @@ func paychanKey(sender sdk.Address, receiver sdk.Address, id integer) []byte { return append(sender.Bytes(), receiver.Bytes()..., idAsBytes...) } +// Get all paychans between a given sender and receiver. +func (keeper Keeper) GetPaychans(sender sdk.Address, receiver sdk.Address) []Paychan { + var paychans []Paychan + // TODO Implement this + return paychans +} // maybe getAllPaychans(sender sdk.address) []Paychan diff --git a/internal/x/paychan/types.go b/internal/x/paychan/types.go index a710c554..d6fc939b 100644 --- a/internal/x/paychan/types.go +++ b/internal/x/paychan/types.go @@ -8,10 +8,10 @@ import ( // probably want to convert this to a general purpose "state" struct Paychan { - balance sdk.Coins sender sdk.Address receiver sdk.Address id integer + balance sdk.Coins } @@ -40,29 +40,29 @@ struct Paychan { /////////////// CreatePayChan // find a less confusing name -type CreateMsg struct { +type MsgCreate struct { // maybe just wrap a paychan struct sender sdk.Address receiver sdk.Address - amount sdk.Balance + amount sdk.Coins } -func (msg CreatMsg) NewCreateMsg() CreateMsg { - return CreateMsg{ } +func (msg CreatMsg) NewMsgCreate() MsgCreate { + return MsgCreate{ } } -func (msg CreateMsg) Type() string { return "paychan" } +func (msg MsgCreate) Type() string { return "paychan" } -func (msg CreateMsg) GetSigners() []sdk.Address { +func (msg MsgCreate) GetSigners() []sdk.Address { // sender //return []sdk.Address{msg.sender} } -func (msg CreateMsg) GetSignBytes() []byte { +func (msg MsgCreate) GetSignBytes() []byte { } -func (msg CreateMsg) ValidateBasic() sdk.Error { +func (msg MsgCreate) ValidateBasic() sdk.Error { // verify msg as much as possible without using external information (such as account balance) // are all fields present // are all fields valid @@ -70,7 +70,7 @@ func (msg CreateMsg) ValidateBasic() sdk.Error { } ///////////////// -type CloseMsg struct { +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 @@ -79,21 +79,21 @@ type CloseMsg struct { receiverAmount sdk.Coins // amount the receiver should get - sender amount implicit with paychan balance } -func (msg CloseMsg) NewCloseMsg( args... ) CloseMsg { - return CloseMsg{ args... } +func (msg MsgClose) NewMsgClose( args... ) MsgClose { + return MsgClose{ args... } } -func (msg CloseMsg) Type() string { return "paychan" } +func (msg MsgClose) Type() string { return "paychan" } -func (msg CloseMsg) GetSigners() []sdk.Address { +func (msg MsgClose) GetSigners() []sdk.Address { // sender and receiver } -func (msg CloseMsg) GetSignBytes() []byte { +func (msg MsgClose) GetSignBytes() []byte { } -func (msg CloseMsg) ValidateBasic() sdk.Error { +func (msg MsgClose) ValidateBasic() sdk.Error { return msg.IBCPacket.ValidateBasic() }