From 8b19ffa7c1b1a34795833d36e741ed960b2fd946 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Wed, 21 Mar 2018 17:46:12 +0100 Subject: [PATCH 01/11] worked on coolKeeper --- examples/basecoin/app/app.go | 4 +-- examples/basecoin/app/app_test.go | 4 +-- examples/basecoin/x/cool/errors.go | 15 +++++++++ examples/basecoin/x/cool/handler.go | 48 ++++++++++++++++------------- examples/basecoin/x/cool/keeper.go | 42 +++++++++++++++++++++++++ examples/basecoin/x/cool/mapper.go | 30 ------------------ x/bank/{mapper.go => keeper.go} | 17 ++++++++++ 7 files changed, 104 insertions(+), 56 deletions(-) create mode 100644 examples/basecoin/x/cool/errors.go create mode 100644 examples/basecoin/x/cool/keeper.go delete mode 100644 examples/basecoin/x/cool/mapper.go rename x/bank/{mapper.go => keeper.go} (76%) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 1d31b0edc4..86860f0465 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -58,12 +58,12 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { // add handlers coinKeeper := bank.NewCoinKeeper(app.accountMapper) - coolMapper := cool.NewMapper(app.capKeyMainStore) + coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper) ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) stakingMapper := staking.NewMapper(app.capKeyStakingStore) app.Router(). AddRoute("bank", bank.NewHandler(coinKeeper)). - AddRoute("cool", cool.NewHandler(coinKeeper, coolMapper)). + AddRoute("cool", coolKeeper.Handler). AddRoute("sketchy", sketchy.NewHandler()). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("staking", staking.NewHandler(stakingMapper, coinKeeper)) diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index f97ae30bf6..7168cb2161 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -259,12 +259,12 @@ func TestQuizMsg(t *testing.T) { SignCheckDeliver(t, bapp, setTrendMsg1, 0, true) SignCheckDeliver(t, bapp, quizMsg1, 1, true) CheckBalance(t, bapp, "69icecold") - SignCheckDeliver(t, bapp, quizMsg2, 2, true) // result without reward + SignCheckDeliver(t, bapp, quizMsg2, 2, false) // result without reward CheckBalance(t, bapp, "69icecold") SignCheckDeliver(t, bapp, quizMsg1, 3, true) CheckBalance(t, bapp, "138icecold") SignCheckDeliver(t, bapp, setTrendMsg2, 4, true) // reset the trend - SignCheckDeliver(t, bapp, quizMsg1, 5, true) // the same answer will nolonger do! + SignCheckDeliver(t, bapp, quizMsg1, 5, false) // the same answer will nolonger do! CheckBalance(t, bapp, "138icecold") SignCheckDeliver(t, bapp, quizMsg2, 6, true) // earlier answer now relavent again CheckBalance(t, bapp, "69badvibesonly,138icecold") diff --git a/examples/basecoin/x/cool/errors.go b/examples/basecoin/x/cool/errors.go new file mode 100644 index 0000000000..9001c3c243 --- /dev/null +++ b/examples/basecoin/x/cool/errors.go @@ -0,0 +1,15 @@ +package cool + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" +) + +const ( + // Cool module reserves error 300-399 lawl + CodeIncorrectCoolAnswer sdk.CodeType = 300 +) + +// ErrIncorrectCoolAnswer - Error returned upon an incorrect guess +func ErrIncorrectCoolAnswer(answer string) sdk.Error { + return sdk.NewError(CodeIncorrectCoolAnswer, "Incorrect Cool answer - `"+answer+"'") +} diff --git a/examples/basecoin/x/cool/handler.go b/examples/basecoin/x/cool/handler.go index c0aae11bba..fc3dc44ad4 100644 --- a/examples/basecoin/x/cool/handler.go +++ b/examples/basecoin/x/cool/handler.go @@ -5,7 +5,6 @@ import ( "reflect" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/bank" ) // This is just an example to demonstrate a functional custom module @@ -19,37 +18,42 @@ import ( // \_______/ \______/ \______/ |______/ // Handle all "coolmodule" type objects -func NewHandler(ck bank.CoinKeeper, cm Mapper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { - switch msg := msg.(type) { - case SetTrendMsg: - return handleSetTrendMsg(ctx, cm, msg) - case QuizMsg: - return handleQuizMsg(ctx, ck, cm, msg) - default: - errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name()) - return sdk.ErrUnknownRequest(errMsg).Result() - } +func (k Keeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result { + switch msg := msg.(type) { + case SetTrendMsg: + return handleSetTrendMsg(ctx, k, msg) + case QuizMsg: + return handleQuizMsg(ctx, k, msg) + default: + errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name()) + return sdk.ErrUnknownRequest(errMsg).Result() } } // Handle QuizMsg This is the engine of your module -func handleSetTrendMsg(ctx sdk.Context, cm Mapper, msg SetTrendMsg) sdk.Result { - cm.SetTrend(ctx, msg.Cool) +func handleSetTrendMsg(ctx sdk.Context, k Keeper, msg SetTrendMsg) sdk.Result { + k.setTrend(ctx, msg.Cool) return sdk.Result{} } // Handle QuizMsg This is the engine of your module -func handleQuizMsg(ctx sdk.Context, ck bank.CoinKeeper, cm Mapper, msg QuizMsg) sdk.Result { +func handleQuizMsg(ctx sdk.Context, k Keeper, msg QuizMsg) sdk.Result { - currentTrend := cm.GetTrend(ctx) + correct := k.CheckTrend(ctx, msg.CoolAnswer) - if msg.CoolAnswer == currentTrend { - bonusCoins := sdk.Coins{{currentTrend, 69}} - _, err := ck.AddCoins(ctx, msg.Sender, bonusCoins) - if err != nil { - return err.Result() - } + if !correct { + return ErrIncorrectCoolAnswer(msg.CoolAnswer).Result() + } + + if ctx.IsCheckTx() { + return sdk.Result{} // TODO + } + + bonusCoins := sdk.Coins{{msg.CoolAnswer, 69}} + + _, err := k.ck.AddCoins(ctx, msg.Sender, bonusCoins) + if err != nil { + return err.Result() } return sdk.Result{} diff --git a/examples/basecoin/x/cool/keeper.go b/examples/basecoin/x/cool/keeper.go new file mode 100644 index 0000000000..e1fbe8f587 --- /dev/null +++ b/examples/basecoin/x/cool/keeper.go @@ -0,0 +1,42 @@ +package cool + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank" +) + +// Keeper - handlers sets/gets of custom variables for your module +type Keeper struct { + ck bank.CoinKeeper + + storeKey sdk.StoreKey // The (unexposed) key used to access the store from the Context. +} + +// NewKeeper - Returns the Keeper +func NewKeeper(key sdk.StoreKey, bankKeeper bank.CoinKeeper) Keeper { + return Keeper{bankKeeper, key} +} + +// Key to knowing the trend on the streets! +var trendKey = []byte("TrendKey") + +// GetTrend - returns the current cool trend +func (k Keeper) GetTrend(ctx sdk.Context) string { + store := ctx.KVStore(k.storeKey) + bz := store.Get(trendKey) + return string(bz) +} + +// Implements sdk.AccountMapper. +func (k Keeper) setTrend(ctx sdk.Context, newTrend string) { + store := ctx.KVStore(k.storeKey) + store.Set(trendKey, []byte(newTrend)) +} + +// CheckTrend - Returns true or false based on whether guessedTrend is currently cool or not +func (k Keeper) CheckTrend(ctx sdk.Context, guessedTrend string) bool { + if guessedTrend == k.GetTrend(ctx) { + return true + } + return false +} diff --git a/examples/basecoin/x/cool/mapper.go b/examples/basecoin/x/cool/mapper.go deleted file mode 100644 index 2e0a791fa6..0000000000 --- a/examples/basecoin/x/cool/mapper.go +++ /dev/null @@ -1,30 +0,0 @@ -package cool - -import ( - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// This Cool Mapper handlers sets/gets of custom variables for your module -type Mapper struct { - key sdk.StoreKey // The (unexposed) key used to access the store from the Context. -} - -func NewMapper(key sdk.StoreKey) Mapper { - return Mapper{key} -} - -// Key to knowing the trend on the streets! -var trendKey = []byte("TrendKey") - -// Implements sdk.AccountMapper. -func (am Mapper) GetTrend(ctx sdk.Context) string { - store := ctx.KVStore(am.key) - bz := store.Get(trendKey) - return string(bz) -} - -// Implements sdk.AccountMapper. -func (am Mapper) SetTrend(ctx sdk.Context, newTrend string) { - store := ctx.KVStore(am.key) - store.Set(trendKey, []byte(newTrend)) -} diff --git a/x/bank/mapper.go b/x/bank/keeper.go similarity index 76% rename from x/bank/mapper.go rename to x/bank/keeper.go index 0530967f12..919867c65d 100644 --- a/x/bank/mapper.go +++ b/x/bank/keeper.go @@ -6,6 +6,8 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) +const moduleName = "bank" + // CoinKeeper manages transfers between accounts type CoinKeeper struct { am sdk.AccountMapper @@ -48,3 +50,18 @@ func (ck CoinKeeper) AddCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) ck.am.SetAccount(ctx, acc) return newCoins, nil } + +// SendCoins moves coins from one account to another +func (ck CoinKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { + _, err := ck.SubtractCoins(ctx, fromAddr, amt) + if err != nil { + return err + } + + _, err = ck.AddCoins(ctx, toAddr, amt) + if err != nil { + return err + } + + return nil +} From 658f58015f498b8e1544b1ba0c23d4fcda6ea0e9 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 21 Mar 2018 18:07:12 +0100 Subject: [PATCH 02/11] ... --- examples/basecoin/app/app_test.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index 7168cb2161..b1a1c4cade 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -325,6 +325,7 @@ func TestHandler(t *testing.T) { SignCheckDeliver(t, bapp, receiveMsg, 3, false) } +// TODO describe the use of this function func SignCheckDeliver(t *testing.T, bapp *BasecoinApp, msg sdk.Msg, seq int64, expPass bool) { // Sign the tx @@ -350,6 +351,8 @@ func SignCheckDeliver(t *testing.T, bapp *BasecoinApp, msg sdk.Msg, seq int64, e } else { require.NotEqual(t, sdk.CodeOK, res.Code, res.Log) } + bapp.EndBlock(abci.RequestEndBlock{}) + //bapp.Commit() } func CheckBalance(t *testing.T, bapp *BasecoinApp, balExpected string) { From 917d431f39c12259ca159948f08f1b77b597b71d Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Wed, 21 Mar 2018 18:23:43 +0100 Subject: [PATCH 03/11] updated app.go --- examples/basecoin/app/app.go | 4 +--- x/bank/handler.go | 20 +++++++++----------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 86860f0465..fbd04d0617 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -19,7 +19,6 @@ import ( "github.com/cosmos/cosmos-sdk/examples/basecoin/types" "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool" - "github.com/cosmos/cosmos-sdk/examples/basecoin/x/sketchy" ) const ( @@ -62,9 +61,8 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) stakingMapper := staking.NewMapper(app.capKeyStakingStore) app.Router(). - AddRoute("bank", bank.NewHandler(coinKeeper)). + AddRoute("bank", coinKeeper.Handler). AddRoute("cool", coolKeeper.Handler). - AddRoute("sketchy", sketchy.NewHandler()). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("staking", staking.NewHandler(stakingMapper, coinKeeper)) diff --git a/x/bank/handler.go b/x/bank/handler.go index b5d2a67572..34f86ddc6a 100644 --- a/x/bank/handler.go +++ b/x/bank/handler.go @@ -7,17 +7,15 @@ import ( ) // Handle all "bank" type messages. -func NewHandler(ck CoinKeeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { - switch msg := msg.(type) { - case SendMsg: - return handleSendMsg(ctx, ck, msg) - case IssueMsg: - return handleIssueMsg(ctx, ck, msg) - default: - errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name() - return sdk.ErrUnknownRequest(errMsg).Result() - } +func (ck CoinKeeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result { + switch msg := msg.(type) { + case SendMsg: + return handleSendMsg(ctx, ck, msg) + case IssueMsg: + return handleIssueMsg(ctx, ck, msg) + default: + errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name() + return sdk.ErrUnknownRequest(errMsg).Result() } } From b118b34695934f0af4ddec213dc91443aa5575d0 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Wed, 21 Mar 2018 17:46:12 +0100 Subject: [PATCH 04/11] worked on coolKeeper --- examples/basecoin/app/app.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index fbd04d0617..86860f0465 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -19,6 +19,7 @@ import ( "github.com/cosmos/cosmos-sdk/examples/basecoin/types" "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool" + "github.com/cosmos/cosmos-sdk/examples/basecoin/x/sketchy" ) const ( @@ -61,8 +62,9 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) stakingMapper := staking.NewMapper(app.capKeyStakingStore) app.Router(). - AddRoute("bank", coinKeeper.Handler). + AddRoute("bank", bank.NewHandler(coinKeeper)). AddRoute("cool", coolKeeper.Handler). + AddRoute("sketchy", sketchy.NewHandler()). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("staking", staking.NewHandler(stakingMapper, coinKeeper)) From 2fc5cc6bcd91bd80767f3b44a876a49f72f55352 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Wed, 21 Mar 2018 18:23:43 +0100 Subject: [PATCH 05/11] updated app.go --- examples/basecoin/app/app.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index 86860f0465..fbd04d0617 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -19,7 +19,6 @@ import ( "github.com/cosmos/cosmos-sdk/examples/basecoin/types" "github.com/cosmos/cosmos-sdk/examples/basecoin/x/cool" - "github.com/cosmos/cosmos-sdk/examples/basecoin/x/sketchy" ) const ( @@ -62,9 +61,8 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) stakingMapper := staking.NewMapper(app.capKeyStakingStore) app.Router(). - AddRoute("bank", bank.NewHandler(coinKeeper)). + AddRoute("bank", coinKeeper.Handler). AddRoute("cool", coolKeeper.Handler). - AddRoute("sketchy", sketchy.NewHandler()). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). AddRoute("staking", staking.NewHandler(stakingMapper, coinKeeper)) From 131289ce70211043539329b7e6e80cdb9f9b2055 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Wed, 21 Mar 2018 23:21:46 +0100 Subject: [PATCH 06/11] everything but IBC module --- examples/basecoin/app/app.go | 4 +- x/staking/errors.go | 11 ++- x/staking/handler.go | 34 +++---- x/staking/keeper.go | 88 ++++++++++++++++++ x/staking/{mapper_test.go => keeper_test.go} | 23 ++--- x/staking/mapper.go | 92 ------------------- x/staking/msgs.go | 95 +++++++++++++++++++ x/staking/{types_test.go => msgs_test.go} | 0 x/staking/types.go | 96 ++------------------ 9 files changed, 226 insertions(+), 217 deletions(-) create mode 100644 x/staking/keeper.go rename x/staking/{mapper_test.go => keeper_test.go} (71%) delete mode 100644 x/staking/mapper.go create mode 100644 x/staking/msgs.go rename x/staking/{types_test.go => msgs_test.go} (100%) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index fbd04d0617..f69bb96d0a 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -59,12 +59,12 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { coinKeeper := bank.NewCoinKeeper(app.accountMapper) coolKeeper := cool.NewKeeper(app.capKeyMainStore, coinKeeper) ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) - stakingMapper := staking.NewMapper(app.capKeyStakingStore) + stakeKeeper := staking.NewKeeper(app.capKeyStakingStore, coinKeeper) app.Router(). AddRoute("bank", coinKeeper.Handler). AddRoute("cool", coolKeeper.Handler). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). - AddRoute("staking", staking.NewHandler(stakingMapper, coinKeeper)) + AddRoute("staking", stakeKeeper.Handler) // initialize BaseApp app.SetTxDecoder(app.txDecoder) diff --git a/x/staking/errors.go b/x/staking/errors.go index 77f009fe0f..6c3e4d34b6 100644 --- a/x/staking/errors.go +++ b/x/staking/errors.go @@ -6,11 +6,16 @@ import ( const ( // Staking errors reserve 300 - 399. - CodeEmptyValidator sdk.CodeType = 300 - CodeInvalidUnbond sdk.CodeType = 301 - CodeEmptyStake sdk.CodeType = 302 + CodeEmptyValidator sdk.CodeType = 300 + CodeInvalidUnbond sdk.CodeType = 301 + CodeEmptyStake sdk.CodeType = 302 + CodeIncorrectStakingToken sdk.CodeType = 303 ) +func ErrIncorrectStakingToken() sdk.Error { + return newError(CodeIncorrectStakingToken, "") +} + func ErrEmptyValidator() sdk.Error { return newError(CodeEmptyValidator, "") } diff --git a/x/staking/handler.go b/x/staking/handler.go index c14756b7ab..7efc074650 100644 --- a/x/staking/handler.go +++ b/x/staking/handler.go @@ -4,29 +4,21 @@ import ( abci "github.com/tendermint/abci/types" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/x/bank" ) -func NewHandler(sm StakingMapper, ck bank.CoinKeeper) sdk.Handler { - return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { - switch msg := msg.(type) { - case BondMsg: - return handleBondMsg(ctx, sm, ck, msg) - case UnbondMsg: - return handleUnbondMsg(ctx, sm, ck, msg) - default: - return sdk.ErrUnknownRequest("No match for message type.").Result() - } +func (k Keeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result { + switch msg := msg.(type) { + case BondMsg: + return handleBondMsg(ctx, k, msg) + case UnbondMsg: + return handleUnbondMsg(ctx, k, msg) + default: + return sdk.ErrUnknownRequest("No match for message type.").Result() } } -func handleBondMsg(ctx sdk.Context, sm StakingMapper, ck bank.CoinKeeper, msg BondMsg) sdk.Result { - _, err := ck.SubtractCoins(ctx, msg.Address, []sdk.Coin{msg.Stake}) - if err != nil { - return err.Result() - } - - power, err := sm.Bond(ctx, msg.Address, msg.PubKey, msg.Stake.Amount) +func handleBondMsg(ctx sdk.Context, k Keeper, msg BondMsg) sdk.Result { + _, err := k.Bond(ctx, msg.Address, msg.Stake) if err != nil { return err.Result() } @@ -42,8 +34,8 @@ func handleBondMsg(ctx sdk.Context, sm StakingMapper, ck bank.CoinKeeper, msg Bo } } -func handleUnbondMsg(ctx sdk.Context, sm StakingMapper, ck bank.CoinKeeper, msg UnbondMsg) sdk.Result { - pubKey, power, err := sm.Unbond(ctx, msg.Address) +func handleUnbondMsg(ctx sdk.Context, k Keeper, msg UnbondMsg) sdk.Result { + pubKey, power, err := k.Unbond(ctx, msg.Address) if err != nil { return err.Result() } @@ -52,7 +44,7 @@ func handleUnbondMsg(ctx sdk.Context, sm StakingMapper, ck bank.CoinKeeper, msg Denom: "mycoin", Amount: power, } - _, err = ck.AddCoins(ctx, msg.Address, sdk.Coins{stake}) + _, err = k.ck.AddCoins(ctx, msg.Address, sdk.Coins{stake}) if err != nil { return err.Result() } diff --git a/x/staking/keeper.go b/x/staking/keeper.go new file mode 100644 index 0000000000..b74eebdd23 --- /dev/null +++ b/x/staking/keeper.go @@ -0,0 +1,88 @@ +package staking + +import ( + crypto "github.com/tendermint/go-crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/bank" +) + +const stakingToken = "steak" + +type Keeper struct { + ck bank.CoinKeeper + + key sdk.StoreKey + cdc *wire.Codec +} + +func NewKeeper(key sdk.StoreKey, coinKeeper bank.CoinKeeper) Keeper { + cdc := wire.NewCodec() + return Keeper{ + key: key, + cdc: cdc, + ck: coinKeeper, + } +} + +func (k Keeper) getBondInfo(ctx sdk.Context, addr sdk.Address) bondInfo { + store := ctx.KVStore(k.key) + bz := store.Get(addr) + if bz == nil { + return bondInfo{} + } + var bi bondInfo + err := k.cdc.UnmarshalBinary(bz, &bi) + if err != nil { + panic(err) + } + return bi +} + +func (k Keeper) setBondInfo(ctx sdk.Context, addr sdk.Address, bi bondInfo) { + store := ctx.KVStore(k.key) + bz, err := k.cdc.MarshalBinary(bi) + if err != nil { + panic(err) + } + store.Set(addr, bz) +} + +func (k Keeper) deleteBondInfo(ctx sdk.Context, addr sdk.Address) { + store := ctx.KVStore(k.key) + store.Delete(addr) +} + +func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) { + if stake.Denom != stakingToken { + return 0, ErrIncorrectStakingToken() + } + + _, err := k.ck.SubtractCoins(ctx, addr, []sdk.Coin{stake}) + if err != nil { + return 0, err + } + + bi := k.getBondInfo(ctx, addr) + if bi.isEmpty() { + bi = bondInfo{ + PubKey: pubKey, + Power: 0, + } + } + + bi.Power = bi.Power + stake.Amount + + k.setBondInfo(ctx, addr, bi) + return bi.Power, nil +} + +func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) { + bi := k.getBondInfo(ctx, addr) + if bi.isEmpty() { + return crypto.PubKey{}, 0, ErrInvalidUnbond() + } + k.deleteBondInfo(ctx, addr) + return bi.PubKey, bi.Power, nil +} diff --git a/x/staking/mapper_test.go b/x/staking/keeper_test.go similarity index 71% rename from x/staking/mapper_test.go rename to x/staking/keeper_test.go index 8f4e2d50e4..d799638d70 100644 --- a/x/staking/mapper_test.go +++ b/x/staking/keeper_test.go @@ -13,6 +13,7 @@ import ( "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/bank" ) func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { @@ -24,14 +25,14 @@ func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { return ms, capKey } -func TestStakingMapperGetSet(t *testing.T) { +func TestKeeperGetSet(t *testing.T) { ms, capKey := setupMultiStore() ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - stakingMapper := NewMapper(capKey) + stakeKeeper := NewKeeper(capKey, bank.NewCoinKeeper(nil)) addr := sdk.Address([]byte("some-address")) - bi := stakingMapper.getBondInfo(ctx, addr) + bi := stakeKeeper.getBondInfo(ctx, addr) assert.Equal(t, bi, bondInfo{}) privKey := crypto.GenPrivKeyEd25519() @@ -41,9 +42,9 @@ func TestStakingMapperGetSet(t *testing.T) { Power: int64(10), } fmt.Printf("Pubkey: %v\n", privKey.PubKey()) - stakingMapper.setBondInfo(ctx, addr, bi) + stakeKeeper.setBondInfo(ctx, addr, bi) - savedBi := stakingMapper.getBondInfo(ctx, addr) + savedBi := stakeKeeper.getBondInfo(ctx, addr) assert.NotNil(t, savedBi) fmt.Printf("Bond Info: %v\n", savedBi) assert.Equal(t, int64(10), savedBi.Power) @@ -53,24 +54,24 @@ func TestBonding(t *testing.T) { ms, capKey := setupMultiStore() ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - stakingMapper := NewMapper(capKey) + stakeKeeper := NewKeeper(capKey, bank.NewCoinKeeper(nil)) addr := sdk.Address([]byte("some-address")) privKey := crypto.GenPrivKeyEd25519() pubKey := privKey.PubKey() - _, _, err := stakingMapper.Unbond(ctx, addr) + _, _, err := stakeKeeper.Unbond(ctx, addr) assert.Equal(t, err, ErrInvalidUnbond()) - _, err = stakingMapper.Bond(ctx, addr, pubKey, 10) + _, err = stakeKeeper.Bond(ctx, addr, pubKey, 10) assert.Nil(t, err) - power, err := stakingMapper.Bond(ctx, addr, pubKey, 10) + power, err := stakeKeeper.Bond(ctx, addr, pubKey, 10) assert.Equal(t, int64(20), power) - pk, _, err := stakingMapper.Unbond(ctx, addr) + pk, _, err := stakeKeeper.Unbond(ctx, addr) assert.Nil(t, err) assert.Equal(t, pubKey, pk) - _, _, err = stakingMapper.Unbond(ctx, addr) + _, _, err = stakeKeeper.Unbond(ctx, addr) assert.Equal(t, err, ErrInvalidUnbond()) } diff --git a/x/staking/mapper.go b/x/staking/mapper.go deleted file mode 100644 index 7f155d00a1..0000000000 --- a/x/staking/mapper.go +++ /dev/null @@ -1,92 +0,0 @@ -package staking - -import ( - crypto "github.com/tendermint/go-crypto" - - sdk "github.com/cosmos/cosmos-sdk/types" - wire "github.com/cosmos/cosmos-sdk/wire" -) - -type StakingMapper struct { - key sdk.StoreKey - cdc *wire.Codec -} - -func NewMapper(key sdk.StoreKey) StakingMapper { - cdc := wire.NewCodec() - return StakingMapper{ - key: key, - cdc: cdc, - } -} - -func (sm StakingMapper) getBondInfo(ctx sdk.Context, addr sdk.Address) bondInfo { - store := ctx.KVStore(sm.key) - bz := store.Get(addr) - if bz == nil { - return bondInfo{} - } - var bi bondInfo - err := sm.cdc.UnmarshalBinary(bz, &bi) - if err != nil { - panic(err) - } - return bi -} - -func (sm StakingMapper) setBondInfo(ctx sdk.Context, addr sdk.Address, bi bondInfo) { - store := ctx.KVStore(sm.key) - bz, err := sm.cdc.MarshalBinary(bi) - if err != nil { - panic(err) - } - store.Set(addr, bz) -} - -func (sm StakingMapper) deleteBondInfo(ctx sdk.Context, addr sdk.Address) { - store := ctx.KVStore(sm.key) - store.Delete(addr) -} - -func (sm StakingMapper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, power int64) (int64, sdk.Error) { - - bi := sm.getBondInfo(ctx, addr) - if bi.isEmpty() { - bi = bondInfo{ - PubKey: pubKey, - Power: power, - } - sm.setBondInfo(ctx, addr, bi) - return bi.Power, nil - } - - newPower := bi.Power + power - newBi := bondInfo{ - PubKey: bi.PubKey, - Power: newPower, - } - sm.setBondInfo(ctx, addr, newBi) - - return newBi.Power, nil -} - -func (sm StakingMapper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) { - bi := sm.getBondInfo(ctx, addr) - if bi.isEmpty() { - return crypto.PubKey{}, 0, ErrInvalidUnbond() - } - sm.deleteBondInfo(ctx, addr) - return bi.PubKey, bi.Power, nil -} - -type bondInfo struct { - PubKey crypto.PubKey - Power int64 -} - -func (bi bondInfo) isEmpty() bool { - if bi == (bondInfo{}) { - return true - } - return false -} diff --git a/x/staking/msgs.go b/x/staking/msgs.go new file mode 100644 index 0000000000..9bbf425c7c --- /dev/null +++ b/x/staking/msgs.go @@ -0,0 +1,95 @@ +package staking + +import ( + "encoding/json" + + crypto "github.com/tendermint/go-crypto" + + sdk "github.com/cosmos/cosmos-sdk/types" +) + +// ------------------------- +// BondMsg + +type BondMsg struct { + Address sdk.Address `json:"address"` + Stake sdk.Coin `json:"coins"` + PubKey crypto.PubKey `json:"pub_key"` +} + +func NewBondMsg(addr sdk.Address, stake sdk.Coin, pubKey crypto.PubKey) BondMsg { + return BondMsg{ + Address: addr, + Stake: stake, + PubKey: pubKey, + } +} + +func (msg BondMsg) Type() string { + return "staking" +} + +func (msg BondMsg) ValidateBasic() sdk.Error { + if msg.Stake.IsZero() { + return ErrEmptyStake() + } + + if msg.PubKey.Empty() { + return sdk.ErrInvalidPubKey("BondMsg.PubKey must not be empty") + } + + return nil +} + +func (msg BondMsg) Get(key interface{}) interface{} { + return nil +} + +func (msg BondMsg) GetSignBytes() []byte { + bz, err := json.Marshal(msg) + if err != nil { + panic(err) + } + return bz +} + +func (msg BondMsg) GetSigners() []sdk.Address { + return []sdk.Address{msg.Address} +} + +// ------------------------- +// UnbondMsg + +type UnbondMsg struct { + Address sdk.Address `json:"address"` +} + +func NewUnbondMsg(addr sdk.Address) UnbondMsg { + return UnbondMsg{ + Address: addr, + } +} + +func (msg UnbondMsg) Type() string { + return "staking" +} + +func (msg UnbondMsg) ValidateBasic() sdk.Error { + return nil +} + +func (msg UnbondMsg) Get(key interface{}) interface{} { + return nil +} + +func (msg UnbondMsg) GetSignBytes() []byte { + bz, err := json.Marshal(msg) + if err != nil { + panic(err) + } + return bz +} + +func (msg UnbondMsg) GetSigners() []sdk.Address { + return []sdk.Address{msg.Address} +} diff --git a/x/staking/types_test.go b/x/staking/msgs_test.go similarity index 100% rename from x/staking/types_test.go rename to x/staking/msgs_test.go diff --git a/x/staking/types.go b/x/staking/types.go index 9bbf425c7c..9f1d045bc0 100644 --- a/x/staking/types.go +++ b/x/staking/types.go @@ -1,95 +1,15 @@ package staking -import ( - "encoding/json" +import crypto "github.com/tendermint/go-crypto" - crypto "github.com/tendermint/go-crypto" - - sdk "github.com/cosmos/cosmos-sdk/types" -) - -// ------------------------- -// BondMsg - -type BondMsg struct { - Address sdk.Address `json:"address"` - Stake sdk.Coin `json:"coins"` - PubKey crypto.PubKey `json:"pub_key"` +type bondInfo struct { + PubKey crypto.PubKey + Power int64 } -func NewBondMsg(addr sdk.Address, stake sdk.Coin, pubKey crypto.PubKey) BondMsg { - return BondMsg{ - Address: addr, - Stake: stake, - PubKey: pubKey, +func (bi bondInfo) isEmpty() bool { + if bi == (bondInfo{}) { + return true } -} - -func (msg BondMsg) Type() string { - return "staking" -} - -func (msg BondMsg) ValidateBasic() sdk.Error { - if msg.Stake.IsZero() { - return ErrEmptyStake() - } - - if msg.PubKey.Empty() { - return sdk.ErrInvalidPubKey("BondMsg.PubKey must not be empty") - } - - return nil -} - -func (msg BondMsg) Get(key interface{}) interface{} { - return nil -} - -func (msg BondMsg) GetSignBytes() []byte { - bz, err := json.Marshal(msg) - if err != nil { - panic(err) - } - return bz -} - -func (msg BondMsg) GetSigners() []sdk.Address { - return []sdk.Address{msg.Address} -} - -// ------------------------- -// UnbondMsg - -type UnbondMsg struct { - Address sdk.Address `json:"address"` -} - -func NewUnbondMsg(addr sdk.Address) UnbondMsg { - return UnbondMsg{ - Address: addr, - } -} - -func (msg UnbondMsg) Type() string { - return "staking" -} - -func (msg UnbondMsg) ValidateBasic() sdk.Error { - return nil -} - -func (msg UnbondMsg) Get(key interface{}) interface{} { - return nil -} - -func (msg UnbondMsg) GetSignBytes() []byte { - bz, err := json.Marshal(msg) - if err != nil { - panic(err) - } - return bz -} - -func (msg UnbondMsg) GetSigners() []sdk.Address { - return []sdk.Address{msg.Address} + return false } From 884b82773008014d1bd95e1350abf21764e4d185 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 25 Mar 2018 00:27:23 +0100 Subject: [PATCH 07/11] everything but IBC --- x/bank/keeper.go | 16 ++++++++-------- x/staking/handler.go | 13 ++----------- x/staking/keeper.go | 8 ++++++++ x/staking/keeper_test.go | 20 +++++++++++++------- 4 files changed, 31 insertions(+), 26 deletions(-) diff --git a/x/bank/keeper.go b/x/bank/keeper.go index 919867c65d..c32d6a1a45 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -1,8 +1,6 @@ package bank import ( - "fmt" - sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -25,13 +23,15 @@ func (ck CoinKeeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Co return amt, sdk.ErrUnknownAddress(addr.String()) } - coins := acc.GetCoins() - newCoins := coins.Minus(amt) - if !newCoins.IsNotNegative() { - return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", coins, amt)) - } + // coins := acc.GetCoins() + // newCoins := coins.Minus(amt) + // if !newCoins.IsNotNegative() { + // return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", coins, amt)) + // } - acc.SetCoins(newCoins) + newCoins := sdk.Coins{} + + // acc.SetCoins(newCoins) ck.am.SetAccount(ctx, acc) return newCoins, nil } diff --git a/x/staking/handler.go b/x/staking/handler.go index 7efc074650..40463cf033 100644 --- a/x/staking/handler.go +++ b/x/staking/handler.go @@ -18,7 +18,7 @@ func (k Keeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result { } func handleBondMsg(ctx sdk.Context, k Keeper, msg BondMsg) sdk.Result { - _, err := k.Bond(ctx, msg.Address, msg.Stake) + power, err := k.Bond(ctx, msg.Address, msg.PubKey, msg.Stake) if err != nil { return err.Result() } @@ -35,16 +35,7 @@ func handleBondMsg(ctx sdk.Context, k Keeper, msg BondMsg) sdk.Result { } func handleUnbondMsg(ctx sdk.Context, k Keeper, msg UnbondMsg) sdk.Result { - pubKey, power, err := k.Unbond(ctx, msg.Address) - if err != nil { - return err.Result() - } - - stake := sdk.Coin{ - Denom: "mycoin", - Amount: power, - } - _, err = k.ck.AddCoins(ctx, msg.Address, sdk.Coins{stake}) + pubKey, _, err := k.Unbond(ctx, msg.Address) if err != nil { return err.Result() } diff --git a/x/staking/keeper.go b/x/staking/keeper.go index b74eebdd23..20be44fbdb 100644 --- a/x/staking/keeper.go +++ b/x/staking/keeper.go @@ -84,5 +84,13 @@ func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, return crypto.PubKey{}, 0, ErrInvalidUnbond() } k.deleteBondInfo(ctx, addr) + + returnedBond := sdk.Coin{stakingToken, bi.Power} + + _, err := k.ck.AddCoins(ctx, addr, []sdk.Coin{returnedBond}) + if err != nil { + return bi.PubKey, bi.Power, err + } + return bi.PubKey, bi.Power, nil } diff --git a/x/staking/keeper_test.go b/x/staking/keeper_test.go index d799638d70..68af68e235 100644 --- a/x/staking/keeper_test.go +++ b/x/staking/keeper_test.go @@ -13,20 +13,23 @@ import ( "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/auth" "github.com/cosmos/cosmos-sdk/x/bank" ) -func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey) { +func setupMultiStore() (sdk.MultiStore, *sdk.KVStoreKey, *sdk.KVStoreKey) { db := dbm.NewMemDB() + authKey := sdk.NewKVStoreKey("authkey") capKey := sdk.NewKVStoreKey("capkey") ms := store.NewCommitMultiStore(db) ms.MountStoreWithDB(capKey, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(authKey, sdk.StoreTypeIAVL, db) ms.LoadLatestVersion() - return ms, capKey + return ms, authKey, capKey } func TestKeeperGetSet(t *testing.T) { - ms, capKey := setupMultiStore() + ms, _, capKey := setupMultiStore() ctx := sdk.NewContext(ms, abci.Header{}, false, nil) stakeKeeper := NewKeeper(capKey, bank.NewCoinKeeper(nil)) @@ -51,10 +54,13 @@ func TestKeeperGetSet(t *testing.T) { } func TestBonding(t *testing.T) { - ms, capKey := setupMultiStore() + ms, authKey, capKey := setupMultiStore() ctx := sdk.NewContext(ms, abci.Header{}, false, nil) - stakeKeeper := NewKeeper(capKey, bank.NewCoinKeeper(nil)) + + accountMapper := auth.NewAccountMapper(authKey, &auth.BaseAccount{}) + coinKeeper := bank.NewCoinKeeper(accountMapper) + stakeKeeper := NewKeeper(capKey, coinKeeper) addr := sdk.Address([]byte("some-address")) privKey := crypto.GenPrivKeyEd25519() pubKey := privKey.PubKey() @@ -62,10 +68,10 @@ func TestBonding(t *testing.T) { _, _, err := stakeKeeper.Unbond(ctx, addr) assert.Equal(t, err, ErrInvalidUnbond()) - _, err = stakeKeeper.Bond(ctx, addr, pubKey, 10) + _, err = stakeKeeper.Bond(ctx, addr, pubKey, sdk.Coin{"steak", 10}) assert.Nil(t, err) - power, err := stakeKeeper.Bond(ctx, addr, pubKey, 10) + power, err := stakeKeeper.Bond(ctx, addr, pubKey, sdk.Coin{"steak", 10}) assert.Equal(t, int64(20), power) pk, _, err := stakeKeeper.Unbond(ctx, addr) From 8fe34097ebfe492566e79b2431aa7d31e1401a14 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 25 Mar 2018 01:12:44 +0100 Subject: [PATCH 08/11] asdf --- x/bank/keeper.go | 14 +++++++------- x/staking/keeper.go | 31 +++++++++++++++++++++++++++++++ x/staking/keeper_test.go | 10 +++++----- 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/x/bank/keeper.go b/x/bank/keeper.go index c32d6a1a45..4f03e208b2 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -1,6 +1,8 @@ package bank import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" ) @@ -23,13 +25,11 @@ func (ck CoinKeeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Co return amt, sdk.ErrUnknownAddress(addr.String()) } - // coins := acc.GetCoins() - // newCoins := coins.Minus(amt) - // if !newCoins.IsNotNegative() { - // return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", coins, amt)) - // } - - newCoins := sdk.Coins{} + coins := acc.GetCoins() + newCoins := coins.Minus(amt) + if !newCoins.IsNotNegative() { + return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", coins, amt)) + } // acc.SetCoins(newCoins) ck.am.SetAccount(ctx, acc) diff --git a/x/staking/keeper.go b/x/staking/keeper.go index 20be44fbdb..615f94fae8 100644 --- a/x/staking/keeper.go +++ b/x/staking/keeper.go @@ -94,3 +94,34 @@ func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, return bi.PubKey, bi.Power, nil } + +// FOR TESTING PURPOSES ------------------------------------------------- + +func (k Keeper) bondWithoutCoins(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, stake sdk.Coin) (int64, sdk.Error) { + if stake.Denom != stakingToken { + return 0, ErrIncorrectStakingToken() + } + + bi := k.getBondInfo(ctx, addr) + if bi.isEmpty() { + bi = bondInfo{ + PubKey: pubKey, + Power: 0, + } + } + + bi.Power = bi.Power + stake.Amount + + k.setBondInfo(ctx, addr, bi) + return bi.Power, nil +} + +func (k Keeper) unbondWithoutCoins(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, sdk.Error) { + bi := k.getBondInfo(ctx, addr) + if bi.isEmpty() { + return crypto.PubKey{}, 0, ErrInvalidUnbond() + } + k.deleteBondInfo(ctx, addr) + + return bi.PubKey, bi.Power, nil +} diff --git a/x/staking/keeper_test.go b/x/staking/keeper_test.go index 68af68e235..1203658918 100644 --- a/x/staking/keeper_test.go +++ b/x/staking/keeper_test.go @@ -65,19 +65,19 @@ func TestBonding(t *testing.T) { privKey := crypto.GenPrivKeyEd25519() pubKey := privKey.PubKey() - _, _, err := stakeKeeper.Unbond(ctx, addr) + _, _, err := stakeKeeper.unbondWithoutCoins(ctx, addr) assert.Equal(t, err, ErrInvalidUnbond()) - _, err = stakeKeeper.Bond(ctx, addr, pubKey, sdk.Coin{"steak", 10}) + _, err = stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.Coin{"steak", 10}) assert.Nil(t, err) - power, err := stakeKeeper.Bond(ctx, addr, pubKey, sdk.Coin{"steak", 10}) + power, err := stakeKeeper.bondWithoutCoins(ctx, addr, pubKey, sdk.Coin{"steak", 10}) assert.Equal(t, int64(20), power) - pk, _, err := stakeKeeper.Unbond(ctx, addr) + pk, _, err := stakeKeeper.unbondWithoutCoins(ctx, addr) assert.Nil(t, err) assert.Equal(t, pubKey, pk) - _, _, err = stakeKeeper.Unbond(ctx, addr) + _, _, err = stakeKeeper.unbondWithoutCoins(ctx, addr) assert.Equal(t, err, ErrInvalidUnbond()) } From eac63038e3d94ba27ac44b17e9f6c2235bf2bbcb Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Sun, 25 Mar 2018 01:43:36 +0100 Subject: [PATCH 09/11] works --- x/bank/keeper.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/x/bank/keeper.go b/x/bank/keeper.go index 4f03e208b2..c1fec95b15 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -18,6 +18,12 @@ func NewCoinKeeper(am sdk.AccountMapper) CoinKeeper { return CoinKeeper{am: am} } +// GetCoins returns the coins at the addr. +func (ck CoinKeeper) GetCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) sdk.Coins { + acc := ck.am.GetAccount(ctx, addr) + return acc.GetCoins() +} + // SubtractCoins subtracts amt from the coins at the addr. func (ck CoinKeeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { acc := ck.am.GetAccount(ctx, addr) @@ -31,7 +37,7 @@ func (ck CoinKeeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Co return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", coins, amt)) } - // acc.SetCoins(newCoins) + acc.SetCoins(newCoins) ck.am.SetAccount(ctx, acc) return newCoins, nil } From 0be651fd2777baca64b9b03475ba9e6bced90e66 Mon Sep 17 00:00:00 2001 From: Sunny Aggarwal Date: Tue, 27 Mar 2018 19:42:09 +0200 Subject: [PATCH 10/11] address rigels review --- examples/basecoin/app/app.go | 6 ++--- examples/basecoin/x/cool/errors.go | 2 +- examples/basecoin/x/cool/handler.go | 22 +++++++++-------- x/bank/handler.go | 37 ++++++++++++----------------- x/bank/keeper.go | 19 +++++++++++++++ x/bank/{tx.go => msgs.go} | 0 x/bank/{tx_test.go => msgs_test.go} | 0 x/staking/handler.go | 19 ++++++++------- 8 files changed, 61 insertions(+), 44 deletions(-) rename x/bank/{tx.go => msgs.go} (100%) rename x/bank/{tx_test.go => msgs_test.go} (100%) diff --git a/examples/basecoin/app/app.go b/examples/basecoin/app/app.go index f69bb96d0a..e5235bd667 100644 --- a/examples/basecoin/app/app.go +++ b/examples/basecoin/app/app.go @@ -61,10 +61,10 @@ func NewBasecoinApp(logger log.Logger, db dbm.DB) *BasecoinApp { ibcMapper := ibc.NewIBCMapper(app.cdc, app.capKeyIBCStore) stakeKeeper := staking.NewKeeper(app.capKeyStakingStore, coinKeeper) app.Router(). - AddRoute("bank", coinKeeper.Handler). - AddRoute("cool", coolKeeper.Handler). + AddRoute("bank", bank.NewHandler(coinKeeper)). + AddRoute("cool", cool.NewHandler(coolKeeper)). AddRoute("ibc", ibc.NewHandler(ibcMapper, coinKeeper)). - AddRoute("staking", stakeKeeper.Handler) + AddRoute("staking", staking.NewHandler(stakeKeeper)) // initialize BaseApp app.SetTxDecoder(app.txDecoder) diff --git a/examples/basecoin/x/cool/errors.go b/examples/basecoin/x/cool/errors.go index 9001c3c243..707f2ef8c1 100644 --- a/examples/basecoin/x/cool/errors.go +++ b/examples/basecoin/x/cool/errors.go @@ -11,5 +11,5 @@ const ( // ErrIncorrectCoolAnswer - Error returned upon an incorrect guess func ErrIncorrectCoolAnswer(answer string) sdk.Error { - return sdk.NewError(CodeIncorrectCoolAnswer, "Incorrect Cool answer - `"+answer+"'") + return sdk.NewError(CodeIncorrectCoolAnswer, "Incorrect cool answer") } diff --git a/examples/basecoin/x/cool/handler.go b/examples/basecoin/x/cool/handler.go index fc3dc44ad4..ce86ecd5bc 100644 --- a/examples/basecoin/x/cool/handler.go +++ b/examples/basecoin/x/cool/handler.go @@ -17,16 +17,18 @@ import ( //| $$$$$$$| $$$$$$/| $$$$$$/| $$$$$$$ // \_______/ \______/ \______/ |______/ -// Handle all "coolmodule" type objects -func (k Keeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result { - switch msg := msg.(type) { - case SetTrendMsg: - return handleSetTrendMsg(ctx, k, msg) - case QuizMsg: - return handleQuizMsg(ctx, k, msg) - default: - errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name()) - return sdk.ErrUnknownRequest(errMsg).Result() +// NewHandler returns a handler for "cool" type messages. +func NewHandler(k Keeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + switch msg := msg.(type) { + case SetTrendMsg: + return handleSetTrendMsg(ctx, k, msg) + case QuizMsg: + return handleQuizMsg(ctx, k, msg) + default: + errMsg := fmt.Sprintf("Unrecognized cool Msg type: %v", reflect.TypeOf(msg).Name()) + return sdk.ErrUnknownRequest(errMsg).Result() + } } } diff --git a/x/bank/handler.go b/x/bank/handler.go index 34f86ddc6a..8eca94a861 100644 --- a/x/bank/handler.go +++ b/x/bank/handler.go @@ -6,16 +6,18 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// Handle all "bank" type messages. -func (ck CoinKeeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result { - switch msg := msg.(type) { - case SendMsg: - return handleSendMsg(ctx, ck, msg) - case IssueMsg: - return handleIssueMsg(ctx, ck, msg) - default: - errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name() - return sdk.ErrUnknownRequest(errMsg).Result() +// NewHandler returns a handler for "bank" type messages. +func NewHandler(ck CoinKeeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + switch msg := msg.(type) { + case SendMsg: + return handleSendMsg(ctx, ck, msg) + case IssueMsg: + return handleIssueMsg(ctx, ck, msg) + default: + errMsg := "Unrecognized bank Msg type: " + reflect.TypeOf(msg).Name() + return sdk.ErrUnknownRequest(errMsg).Result() + } } } @@ -23,18 +25,9 @@ func (ck CoinKeeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result { func handleSendMsg(ctx sdk.Context, ck CoinKeeper, msg SendMsg) sdk.Result { // NOTE: totalIn == totalOut should already have been checked - for _, in := range msg.Inputs { - _, err := ck.SubtractCoins(ctx, in.Address, in.Coins) - if err != nil { - return err.Result() - } - } - - for _, out := range msg.Outputs { - _, err := ck.AddCoins(ctx, out.Address, out.Coins) - if err != nil { - return err.Result() - } + err := ck.InputOutputCoins(ctx, msg.Inputs, msg.Outputs) + if err != nil { + return err.Result() } // TODO: add some tags so we can search it! diff --git a/x/bank/keeper.go b/x/bank/keeper.go index c1fec95b15..b52b480f6b 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -71,3 +71,22 @@ func (ck CoinKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk return nil } + +// InputOutputCoins handles a list of inputs and outputs +func (ck CoinKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { + for _, in := range inputs { + _, err := ck.SubtractCoins(ctx, in.Address, in.Coins) + if err != nil { + return err + } + } + + for _, out := range outputs { + _, err := ck.AddCoins(ctx, out.Address, out.Coins) + if err != nil { + return err + } + } + + return nil +} diff --git a/x/bank/tx.go b/x/bank/msgs.go similarity index 100% rename from x/bank/tx.go rename to x/bank/msgs.go diff --git a/x/bank/tx_test.go b/x/bank/msgs_test.go similarity index 100% rename from x/bank/tx_test.go rename to x/bank/msgs_test.go diff --git a/x/staking/handler.go b/x/staking/handler.go index 40463cf033..b405490b16 100644 --- a/x/staking/handler.go +++ b/x/staking/handler.go @@ -6,14 +6,17 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -func (k Keeper) Handler(ctx sdk.Context, msg sdk.Msg) sdk.Result { - switch msg := msg.(type) { - case BondMsg: - return handleBondMsg(ctx, k, msg) - case UnbondMsg: - return handleUnbondMsg(ctx, k, msg) - default: - return sdk.ErrUnknownRequest("No match for message type.").Result() +// NewHandler returns a handler for "bank" type messages. +func NewHandler(k Keeper) sdk.Handler { + return func(ctx sdk.Context, msg sdk.Msg) sdk.Result { + switch msg := msg.(type) { + case BondMsg: + return handleBondMsg(ctx, k, msg) + case UnbondMsg: + return handleUnbondMsg(ctx, k, msg) + default: + return sdk.ErrUnknownRequest("No match for message type.").Result() + } } } From 010386f48d8586e20b4644627f96246af6d63c95 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 27 Mar 2018 21:48:41 +0200 Subject: [PATCH 11/11] sprintf and fix error codes --- examples/basecoin/x/cool/errors.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/basecoin/x/cool/errors.go b/examples/basecoin/x/cool/errors.go index 707f2ef8c1..5db3efc399 100644 --- a/examples/basecoin/x/cool/errors.go +++ b/examples/basecoin/x/cool/errors.go @@ -1,15 +1,17 @@ package cool import ( + "fmt" + sdk "github.com/cosmos/cosmos-sdk/types" ) const ( - // Cool module reserves error 300-399 lawl - CodeIncorrectCoolAnswer sdk.CodeType = 300 + // Cool module reserves error 400-499 lawl + CodeIncorrectCoolAnswer sdk.CodeType = 400 ) // ErrIncorrectCoolAnswer - Error returned upon an incorrect guess func ErrIncorrectCoolAnswer(answer string) sdk.Error { - return sdk.NewError(CodeIncorrectCoolAnswer, "Incorrect cool answer") + return sdk.NewError(CodeIncorrectCoolAnswer, fmt.Sprintf("Incorrect cool answer: %v", answer)) }