From bef7e44f6dcb2b1c41aa33d291c072567c00454e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 16:14:51 +0200 Subject: [PATCH 1/9] Example tag implementation for CoinKeeper --- examples/democoin/x/cool/handler.go | 2 +- examples/democoin/x/pow/keeper.go | 2 +- examples/democoin/x/simplestake/keeper.go | 4 +- types/result.go | 3 +- types/tags.go | 31 +++++++++++++ types/tags_test.go | 30 +++++++++++++ x/bank/handler.go | 7 +-- x/bank/keeper.go | 54 +++++++++++++---------- x/bank/keeper_test.go | 6 +-- x/ibc/handler.go | 4 +- x/ibc/ibc_test.go | 5 ++- x/stake/handler.go | 2 +- 12 files changed, 109 insertions(+), 41 deletions(-) create mode 100644 types/tags.go create mode 100644 types/tags_test.go diff --git a/examples/democoin/x/cool/handler.go b/examples/democoin/x/cool/handler.go index c82fa4ae43..b4375c5dcd 100644 --- a/examples/democoin/x/cool/handler.go +++ b/examples/democoin/x/cool/handler.go @@ -53,7 +53,7 @@ func handleMsgQuiz(ctx sdk.Context, k Keeper, msg MsgQuiz) sdk.Result { bonusCoins := sdk.Coins{{msg.CoolAnswer, 69}} - _, err := k.ck.AddCoins(ctx, msg.Sender, bonusCoins) + _, _, err := k.ck.AddCoins(ctx, msg.Sender, bonusCoins) if err != nil { return err.Result() } diff --git a/examples/democoin/x/pow/keeper.go b/examples/democoin/x/pow/keeper.go index 931e41a320..35fccf7424 100644 --- a/examples/democoin/x/pow/keeper.go +++ b/examples/democoin/x/pow/keeper.go @@ -125,7 +125,7 @@ func (k Keeper) CheckValid(ctx sdk.Context, difficulty uint64, count uint64) (ui // Add some coins for a POW well done func (k Keeper) ApplyValid(ctx sdk.Context, sender sdk.Address, newDifficulty uint64, newCount uint64) sdk.Error { - _, ckErr := k.ck.AddCoins(ctx, sender, []sdk.Coin{sdk.Coin{k.config.Denomination, k.config.Reward}}) + _, _, ckErr := k.ck.AddCoins(ctx, sender, []sdk.Coin{sdk.Coin{k.config.Denomination, k.config.Reward}}) if ckErr != nil { return ckErr } diff --git a/examples/democoin/x/simplestake/keeper.go b/examples/democoin/x/simplestake/keeper.go index 7b61c36236..5bd2639610 100644 --- a/examples/democoin/x/simplestake/keeper.go +++ b/examples/democoin/x/simplestake/keeper.go @@ -66,7 +66,7 @@ func (k Keeper) Bond(ctx sdk.Context, addr sdk.Address, pubKey crypto.PubKey, st return 0, ErrIncorrectStakingToken(k.codespace) } - _, err := k.ck.SubtractCoins(ctx, addr, []sdk.Coin{stake}) + _, _, err := k.ck.SubtractCoins(ctx, addr, []sdk.Coin{stake}) if err != nil { return 0, err } @@ -95,7 +95,7 @@ func (k Keeper) Unbond(ctx sdk.Context, addr sdk.Address) (crypto.PubKey, int64, returnedBond := sdk.Coin{stakingToken, bi.Power} - _, err := k.ck.AddCoins(ctx, addr, []sdk.Coin{returnedBond}) + _, _, err := k.ck.AddCoins(ctx, addr, []sdk.Coin{returnedBond}) if err != nil { return bi.PubKey, bi.Power, err } diff --git a/types/result.go b/types/result.go index f4f7454e2c..65f87400d2 100644 --- a/types/result.go +++ b/types/result.go @@ -2,7 +2,6 @@ package types import ( abci "github.com/tendermint/abci/types" - cmn "github.com/tendermint/tmlibs/common" ) // Result is the union of ResponseDeliverTx and ResponseCheckTx. @@ -31,7 +30,7 @@ type Result struct { ValidatorUpdates []abci.Validator // Tags are used for transaction indexing and pubsub. - Tags []cmn.KVPair + Tags Tags } // TODO: In the future, more codes may be OK. diff --git a/types/tags.go b/types/tags.go new file mode 100644 index 0000000000..82e9bc9963 --- /dev/null +++ b/types/tags.go @@ -0,0 +1,31 @@ +package types + +import ( + cmn "github.com/tendermint/tmlibs/common" +) + +type Tag = cmn.KVPair + +type Tags = cmn.KVPairs + +// Append two lists of tags +func AppendTags(a, b Tags) Tags { + return append(a, b...) +} + +// New empty tags +func EmptyTags() Tags { + return make(Tags, 0) +} + +// Single tag to tags +func SingleTag(t Tag) Tags { + return append(EmptyTags(), t) +} + +// Make a tag from a key and a value +func MakeTag(k string, v []byte) Tag { + return Tag{Key: []byte(k), Value: v} +} + +// TODO: Deduplication? diff --git a/types/tags_test.go b/types/tags_test.go new file mode 100644 index 0000000000..ae00ffdd91 --- /dev/null +++ b/types/tags_test.go @@ -0,0 +1,30 @@ +package types + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestAppendTags(t *testing.T) { + a := SingleTag(MakeTag("a", []byte("1"))) + b := SingleTag(MakeTag("b", []byte("2"))) + c := AppendTags(a, b) + require.Equal(t, c, Tags{MakeTag("a", []byte("1")), MakeTag("b", []byte("2"))}) +} + +func TestEmptyTags(t *testing.T) { + a := EmptyTags() + require.Equal(t, a, Tags{}) +} + +func TestSingleTag(t *testing.T) { + a := MakeTag("a", []byte("1")) + b := SingleTag(a) + require.Equal(t, b, Tags{MakeTag("a", []byte("1"))}) +} + +func TestMakeTag(t *testing.T) { + a := MakeTag("a", []byte("1")) + require.Equal(t, a, Tag{[]byte("a"), []byte("1")}) +} diff --git a/x/bank/handler.go b/x/bank/handler.go index a50b0afcf3..ec56d05b42 100644 --- a/x/bank/handler.go +++ b/x/bank/handler.go @@ -25,13 +25,14 @@ func NewHandler(k Keeper) sdk.Handler { func handleMsgSend(ctx sdk.Context, k Keeper, msg MsgSend) sdk.Result { // NOTE: totalIn == totalOut should already have been checked - err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs) + tags, err := k.InputOutputCoins(ctx, msg.Inputs, msg.Outputs) if err != nil { return err.Result() } - // TODO: add some tags so we can search it! - return sdk.Result{} // TODO + return sdk.Result{ + Tags: tags, + } } // Handle MsgIssue. diff --git a/x/bank/keeper.go b/x/bank/keeper.go index d1fdeaea06..869caeb259 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -32,22 +32,22 @@ func (keeper Keeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) } // SubtractCoins subtracts amt from the coins at the addr. -func (keeper Keeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { +func (keeper Keeper) SubtractCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { return subtractCoins(ctx, keeper.am, addr, amt) } // AddCoins adds amt to the coins at the addr. -func (keeper Keeper) AddCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { +func (keeper Keeper) AddCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { return addCoins(ctx, keeper.am, addr, amt) } // SendCoins moves coins from one account to another -func (keeper Keeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { +func (keeper Keeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) (sdk.Tags, sdk.Error) { return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt) } // InputOutputCoins handles a list of inputs and outputs -func (keeper Keeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { +func (keeper Keeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) { return inputOutputCoins(ctx, keeper.am, inputs, outputs) } @@ -74,12 +74,12 @@ func (keeper SendKeeper) HasCoins(ctx sdk.Context, addr sdk.Address, amt sdk.Coi } // SendCoins moves coins from one account to another -func (keeper SendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { +func (keeper SendKeeper) SendCoins(ctx sdk.Context, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) (sdk.Tags, sdk.Error) { return sendCoins(ctx, keeper.am, fromAddr, toAddr, amt) } // InputOutputCoins handles a list of inputs and outputs -func (keeper SendKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) sdk.Error { +func (keeper SendKeeper) InputOutputCoins(ctx sdk.Context, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) { return inputOutputCoins(ctx, keeper.am, inputs, outputs) } @@ -131,59 +131,65 @@ func hasCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.C } // SubtractCoins subtracts amt from the coins at the addr. -func subtractCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { +func subtractCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { oldCoins := getCoins(ctx, am, addr) newCoins := oldCoins.Minus(amt) if !newCoins.IsNotNegative() { - return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) + return amt, nil, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) } err := setCoins(ctx, am, addr, newCoins) - return newCoins, err + tags := sdk.SingleTag(sdk.MakeTag("sender", addr.Bytes())) + return newCoins, tags, err } // AddCoins adds amt to the coins at the addr. -func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Error) { +func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.Coins) (sdk.Coins, sdk.Tags, sdk.Error) { oldCoins := getCoins(ctx, am, addr) newCoins := oldCoins.Plus(amt) if !newCoins.IsNotNegative() { - return amt, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) + return amt, nil, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) } err := setCoins(ctx, am, addr, newCoins) - return newCoins, err + tags := sdk.SingleTag(sdk.MakeTag("recipient", addr.Bytes())) + return newCoins, tags, err } // SendCoins moves coins from one account to another // NOTE: Make sure to revert state changes from tx on error -func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) sdk.Error { - _, err := subtractCoins(ctx, am, fromAddr, amt) +func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAddr sdk.Address, amt sdk.Coins) (sdk.Tags, sdk.Error) { + _, subTags, err := subtractCoins(ctx, am, fromAddr, amt) if err != nil { - return err + return nil, err } - _, err = addCoins(ctx, am, toAddr, amt) + _, addTags, err := addCoins(ctx, am, toAddr, amt) if err != nil { - return err + return nil, err } - return nil + return sdk.AppendTags(subTags, addTags), nil } // InputOutputCoins handles a list of inputs and outputs // NOTE: Make sure to revert state changes from tx on error -func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, outputs []Output) sdk.Error { +func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, outputs []Output) (sdk.Tags, sdk.Error) { + allTags := sdk.EmptyTags() + for _, in := range inputs { - _, err := subtractCoins(ctx, am, in.Address, in.Coins) + _, tags, err := subtractCoins(ctx, am, in.Address, in.Coins) if err != nil { - return err + return nil, err } + allTags = sdk.AppendTags(allTags, tags) } for _, out := range outputs { - _, err := addCoins(ctx, am, out.Address, out.Coins) + _, tags, err := addCoins(ctx, am, out.Address, out.Coins) if err != nil { - return err + return nil, err } + allTags = sdk.AppendTags(allTags, tags) } - return nil + return allTags, nil } diff --git a/x/bank/keeper_test.go b/x/bank/keeper_test.go index 4394392dde..3db16c5f92 100644 --- a/x/bank/keeper_test.go +++ b/x/bank/keeper_test.go @@ -65,7 +65,7 @@ func TestKeeper(t *testing.T) { coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{{"barcoin", 5}}) assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 10}, {"foocoin", 15}})) - _, err := coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{{"barcoin", 11}}) + _, _, err := coinKeeper.SubtractCoins(ctx, addr, sdk.Coins{{"barcoin", 11}}) assert.Implements(t, (*sdk.Error)(nil), err) assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"barcoin", 10}, {"foocoin", 15}})) @@ -78,7 +78,7 @@ func TestKeeper(t *testing.T) { assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) assert.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"foocoin", 5}})) - err2 := coinKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"foocoin", 50}}) + _, err2 := coinKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"foocoin", 50}}) assert.Implements(t, (*sdk.Error)(nil), err2) assert.True(t, coinKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) assert.True(t, coinKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"foocoin", 5}})) @@ -147,7 +147,7 @@ func TestSendKeeper(t *testing.T) { assert.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) assert.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"foocoin", 5}})) - err2 := sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"foocoin", 50}}) + _, err2 := sendKeeper.SendCoins(ctx, addr, addr2, sdk.Coins{{"foocoin", 50}}) assert.Implements(t, (*sdk.Error)(nil), err2) assert.True(t, sendKeeper.GetCoins(ctx, addr).IsEqual(sdk.Coins{{"foocoin", 10}})) assert.True(t, sendKeeper.GetCoins(ctx, addr2).IsEqual(sdk.Coins{{"foocoin", 5}})) diff --git a/x/ibc/handler.go b/x/ibc/handler.go index 46cbf1e309..1f334166bf 100644 --- a/x/ibc/handler.go +++ b/x/ibc/handler.go @@ -25,7 +25,7 @@ func NewHandler(ibcm Mapper, ck bank.Keeper) sdk.Handler { func handleIBCTransferMsg(ctx sdk.Context, ibcm Mapper, ck bank.Keeper, msg IBCTransferMsg) sdk.Result { packet := msg.IBCPacket - _, err := ck.SubtractCoins(ctx, packet.SrcAddr, packet.Coins) + _, _, err := ck.SubtractCoins(ctx, packet.SrcAddr, packet.Coins) if err != nil { return err.Result() } @@ -47,7 +47,7 @@ func handleIBCReceiveMsg(ctx sdk.Context, ibcm Mapper, ck bank.Keeper, msg IBCRe return ErrInvalidSequence(ibcm.codespace).Result() } - _, err := ck.AddCoins(ctx, packet.DestAddr, packet.Coins) + _, _, err := ck.AddCoins(ctx, packet.DestAddr, packet.Coins) if err != nil { return err.Result() } diff --git a/x/ibc/ibc_test.go b/x/ibc/ibc_test.go index d0019002fd..60cc59bad9 100644 --- a/x/ibc/ibc_test.go +++ b/x/ibc/ibc_test.go @@ -34,7 +34,8 @@ func newAddress() crypto.Address { func getCoins(ck bank.Keeper, ctx sdk.Context, addr crypto.Address) (sdk.Coins, sdk.Error) { zero := sdk.Coins(nil) - return ck.AddCoins(ctx, addr, zero) + coins, _, err := ck.AddCoins(ctx, addr, zero) + return coins, err } func makeCodec() *wire.Codec { @@ -70,7 +71,7 @@ func TestIBC(t *testing.T) { zero := sdk.Coins(nil) mycoins := sdk.Coins{sdk.Coin{"mycoin", 10}} - coins, err := ck.AddCoins(ctx, src, mycoins) + coins, _, err := ck.AddCoins(ctx, src, mycoins) assert.Nil(t, err) assert.Equal(t, mycoins, coins) diff --git a/x/stake/handler.go b/x/stake/handler.go index 1408c5bb13..5eff822e6e 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -171,7 +171,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, // Account new shares, save pool := k.GetPool(ctx) - _, err := k.coinKeeper.SubtractCoins(ctx, bond.DelegatorAddr, sdk.Coins{bondAmt}) + _, _, err := k.coinKeeper.SubtractCoins(ctx, bond.DelegatorAddr, sdk.Coins{bondAmt}) if err != nil { return err } From f103cd412d45b55e22a2cb308a802c0f8955a5dc Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 26 Apr 2018 16:18:01 +0200 Subject: [PATCH 2/9] Linter fix --- types/tags.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/types/tags.go b/types/tags.go index 82e9bc9963..0811ef8702 100644 --- a/types/tags.go +++ b/types/tags.go @@ -4,8 +4,10 @@ import ( cmn "github.com/tendermint/tmlibs/common" ) +// Type synonym for convenience type Tag = cmn.KVPair +// Type synonym for convenience type Tags = cmn.KVPairs // Append two lists of tags From 60b56f9b1c5c5de76ba8e0a01a367b9cb8ccd15d Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 10 May 2018 00:47:28 +0200 Subject: [PATCH 3/9] Slight tags API changes (Jae comments) --- types/tags.go | 37 ++++++++++++++++++++++++++----------- types/tags_test.go | 14 ++++---------- x/bank/keeper.go | 4 ++-- 3 files changed, 32 insertions(+), 23 deletions(-) diff --git a/types/tags.go b/types/tags.go index 0811ef8702..5a94e9bde8 100644 --- a/types/tags.go +++ b/types/tags.go @@ -8,26 +8,41 @@ import ( type Tag = cmn.KVPair // Type synonym for convenience -type Tags = cmn.KVPairs - -// Append two lists of tags -func AppendTags(a, b Tags) Tags { - return append(a, b...) -} +type Tags cmn.KVPairs // New empty tags func EmptyTags() Tags { return make(Tags, 0) } -// Single tag to tags -func SingleTag(t Tag) Tags { - return append(EmptyTags(), t) +// Append a single tag +func (t Tags) AppendTag(k string, v []byte) Tags { + return append(t, MakeTag(k, v)) +} + +// Append two lists of tags +func AppendTags(a, b Tags) Tags { + return append(a, b...) +} + +// New variadic tags, must be k string, v []byte repeating +func NewTags(tags ...interface{}) Tags { + var ret Tags + if len(tags)%2 != 0 { + panic("must specify key-value pairs as varargs") + } + i := 0 + for { + if i == len(tags) { + break + } + ret = append(ret, Tag{Key: []byte(tags[i].(string)), Value: tags[i+1].([]byte)}) + i += 2 + } + return ret } // Make a tag from a key and a value func MakeTag(k string, v []byte) Tag { return Tag{Key: []byte(k), Value: v} } - -// TODO: Deduplication? diff --git a/types/tags_test.go b/types/tags_test.go index ae00ffdd91..84dc10b33d 100644 --- a/types/tags_test.go +++ b/types/tags_test.go @@ -7,8 +7,8 @@ import ( ) func TestAppendTags(t *testing.T) { - a := SingleTag(MakeTag("a", []byte("1"))) - b := SingleTag(MakeTag("b", []byte("2"))) + a := NewTags("a", []byte("1")) + b := NewTags("b", []byte("2")) c := AppendTags(a, b) require.Equal(t, c, Tags{MakeTag("a", []byte("1")), MakeTag("b", []byte("2"))}) } @@ -18,13 +18,7 @@ func TestEmptyTags(t *testing.T) { require.Equal(t, a, Tags{}) } -func TestSingleTag(t *testing.T) { - a := MakeTag("a", []byte("1")) - b := SingleTag(a) +func TestNewTags(t *testing.T) { + b := NewTags("a", []byte("1")) require.Equal(t, b, Tags{MakeTag("a", []byte("1"))}) } - -func TestMakeTag(t *testing.T) { - a := MakeTag("a", []byte("1")) - require.Equal(t, a, Tag{[]byte("a"), []byte("1")}) -} diff --git a/x/bank/keeper.go b/x/bank/keeper.go index 869caeb259..8a73b964df 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -138,7 +138,7 @@ func subtractCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt return amt, nil, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) } err := setCoins(ctx, am, addr, newCoins) - tags := sdk.SingleTag(sdk.MakeTag("sender", addr.Bytes())) + tags := sdk.NewTags("sender", addr.Bytes()) return newCoins, tags, err } @@ -150,7 +150,7 @@ func addCoins(ctx sdk.Context, am sdk.AccountMapper, addr sdk.Address, amt sdk.C return amt, nil, sdk.ErrInsufficientCoins(fmt.Sprintf("%s < %s", oldCoins, amt)) } err := setCoins(ctx, am, addr, newCoins) - tags := sdk.SingleTag(sdk.MakeTag("recipient", addr.Bytes())) + tags := sdk.NewTags("recipient", addr.Bytes()) return newCoins, tags, err } From c0eb66b1333436dd1e351b474f5280b30aa26ddd Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 10 May 2018 00:53:24 +0200 Subject: [PATCH 4/9] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ca0189666..16b76aade2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ FEATURES: * Context now has access to the application-configured logger * Add (non-proof) subspace query helper functions * Add more staking query functions: candidates, delegator-bonds +* Bank module now tags transactions with sender/recipient for indexing & later retrieval BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia From 2b707f6b0a0d4b0b87d3ba4e6d97a3dcd5b07bb2 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 10 May 2018 17:14:46 +0200 Subject: [PATCH 5/9] AppendTags a function of Tags --- types/tags.go | 4 ++-- types/tags_test.go | 2 +- x/bank/keeper.go | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/types/tags.go b/types/tags.go index 5a94e9bde8..95a826fd78 100644 --- a/types/tags.go +++ b/types/tags.go @@ -21,8 +21,8 @@ func (t Tags) AppendTag(k string, v []byte) Tags { } // Append two lists of tags -func AppendTags(a, b Tags) Tags { - return append(a, b...) +func (t Tags) AppendTags(a Tags) Tags { + return append(t, a...) } // New variadic tags, must be k string, v []byte repeating diff --git a/types/tags_test.go b/types/tags_test.go index 84dc10b33d..4ef5561240 100644 --- a/types/tags_test.go +++ b/types/tags_test.go @@ -9,7 +9,7 @@ import ( func TestAppendTags(t *testing.T) { a := NewTags("a", []byte("1")) b := NewTags("b", []byte("2")) - c := AppendTags(a, b) + c := a.AppendTags(b) require.Equal(t, c, Tags{MakeTag("a", []byte("1")), MakeTag("b", []byte("2"))}) } diff --git a/x/bank/keeper.go b/x/bank/keeper.go index 8a73b964df..d23167c3c5 100644 --- a/x/bank/keeper.go +++ b/x/bank/keeper.go @@ -167,7 +167,7 @@ func sendCoins(ctx sdk.Context, am sdk.AccountMapper, fromAddr sdk.Address, toAd return nil, err } - return sdk.AppendTags(subTags, addTags), nil + return subTags.AppendTags(addTags), nil } // InputOutputCoins handles a list of inputs and outputs @@ -180,7 +180,7 @@ func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, out if err != nil { return nil, err } - allTags = sdk.AppendTags(allTags, tags) + allTags = allTags.AppendTags(tags) } for _, out := range outputs { @@ -188,7 +188,7 @@ func inputOutputCoins(ctx sdk.Context, am sdk.AccountMapper, inputs []Input, out if err != nil { return nil, err } - allTags = sdk.AppendTags(allTags, tags) + allTags = allTags.AppendTags(tags) } return allTags, nil From e4e1068390118a37af08ed575c11b0d1f24d5197 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 10 May 2018 17:19:06 +0200 Subject: [PATCH 6/9] Add delegate() tags --- x/stake/handler.go | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index 5eff822e6e..926d109114 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -100,11 +100,13 @@ func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keepe // move coins from the msg.Address account to a (self-bond) delegator account // the candidate account and global shares are updated within here - err := delegate(ctx, k, msg.CandidateAddr, msg.Bond, candidate) + tags, err := delegate(ctx, k, msg.CandidateAddr, msg.Bond, candidate) if err != nil { return err.Result() } - return sdk.Result{} + return sdk.Result{ + Tags: tags, + } } func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk.Result { @@ -148,16 +150,18 @@ func handleMsgDelegate(ctx sdk.Context, msg MsgDelegate, k Keeper) sdk.Result { GasUsed: GasDelegate, } } - err := delegate(ctx, k, msg.DelegatorAddr, msg.Bond, candidate) + tags, err := delegate(ctx, k, msg.DelegatorAddr, msg.Bond, candidate) if err != nil { return err.Result() } - return sdk.Result{} + return sdk.Result{ + Tags: tags, + } } // common functionality between handlers func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, - bondAmt sdk.Coin, candidate Candidate) sdk.Error { + bondAmt sdk.Coin, candidate Candidate) (sdk.Tags, sdk.Error) { // Get or create the delegator bond bond, found := k.GetDelegatorBond(ctx, delegatorAddr, candidate.Address) @@ -173,7 +177,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, pool := k.GetPool(ctx) _, _, err := k.coinKeeper.SubtractCoins(ctx, bond.DelegatorAddr, sdk.Coins{bondAmt}) if err != nil { - return err + return nil, err } pool, candidate, newShares := pool.candidateAddTokens(candidate, bondAmt.Amount) bond.Shares = bond.Shares.Add(newShares) @@ -184,7 +188,8 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, k.setDelegatorBond(ctx, bond) k.setCandidate(ctx, candidate) k.setPool(ctx, pool) - return nil + tags := sdk.NewTags("delegator", delegatorAddr.Bytes(), "candidate", candidate.Address.Bytes()) + return tags, nil } func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { From 580ac5f57b098a5570dd14f8911ad9893af50dfb Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 10 May 2018 17:23:46 +0200 Subject: [PATCH 7/9] Add tagging for MsgUnbond --- x/stake/handler.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index 926d109114..c3e76888ef 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -188,7 +188,7 @@ func delegate(ctx sdk.Context, k Keeper, delegatorAddr sdk.Address, k.setDelegatorBond(ctx, bond) k.setCandidate(ctx, candidate) k.setPool(ctx, pool) - tags := sdk.NewTags("delegator", delegatorAddr.Bytes(), "candidate", candidate.Address.Bytes()) + tags := sdk.NewTags("action", []byte("delegate"), "delegator", delegatorAddr.Bytes(), "candidate", candidate.Address.Bytes()) return tags, nil } @@ -286,5 +286,8 @@ func handleMsgUnbond(ctx sdk.Context, msg MsgUnbond, k Keeper) sdk.Result { k.setCandidate(ctx, candidate) } k.setPool(ctx, p) - return sdk.Result{} + tags := sdk.NewTags("action", []byte("unbond"), "delegator", msg.DelegatorAddr.Bytes(), "candidate", msg.CandidateAddr.Bytes()) + return sdk.Result{ + Tags: tags, + } } From 0ec21e4e27793f841f95588dedcfbbd54754ee27 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 10 May 2018 17:31:22 +0200 Subject: [PATCH 8/9] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 16b76aade2..a04650813d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ FEATURES: * Add (non-proof) subspace query helper functions * Add more staking query functions: candidates, delegator-bonds * Bank module now tags transactions with sender/recipient for indexing & later retrieval +* Stake module now tags transactions with delegator/candidate for delegation & unbonding BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia From a2f5855d8e04a7f0bee5e070717c454ac730a034 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 10 May 2018 21:55:51 +0200 Subject: [PATCH 9/9] Add tags for declare & edit candidacy txs --- CHANGELOG.md | 2 +- x/stake/handler.go | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a04650813d..f574667110 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,7 +31,7 @@ FEATURES: * Add (non-proof) subspace query helper functions * Add more staking query functions: candidates, delegator-bonds * Bank module now tags transactions with sender/recipient for indexing & later retrieval -* Stake module now tags transactions with delegator/candidate for delegation & unbonding +* Stake module now tags transactions with delegator/candidate for delegation & unbonding, and candidate info for declare candidate / edit candidacy BUG FIXES * Gaia now uses stake, ported from github.com/cosmos/gaia diff --git a/x/stake/handler.go b/x/stake/handler.go index c3e76888ef..8d3bbb8b80 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -97,13 +97,15 @@ func handleMsgDeclareCandidacy(ctx sdk.Context, msg MsgDeclareCandidacy, k Keepe candidate := NewCandidate(msg.CandidateAddr, msg.PubKey, msg.Description) k.setCandidate(ctx, candidate) + tags := sdk.NewTags("action", []byte("declareCandidacy"), "candidate", msg.CandidateAddr.Bytes(), "moniker", []byte(msg.Description.Moniker), "identity", []byte(msg.Description.Identity)) // move coins from the msg.Address account to a (self-bond) delegator account // the candidate account and global shares are updated within here - tags, err := delegate(ctx, k, msg.CandidateAddr, msg.Bond, candidate) + delegateTags, err := delegate(ctx, k, msg.CandidateAddr, msg.Bond, candidate) if err != nil { return err.Result() } + tags = tags.AppendTags(delegateTags) return sdk.Result{ Tags: tags, } @@ -130,7 +132,10 @@ func handleMsgEditCandidacy(ctx sdk.Context, msg MsgEditCandidacy, k Keeper) sdk candidate.Description.Details = msg.Description.Details k.setCandidate(ctx, candidate) - return sdk.Result{} + tags := sdk.NewTags("action", []byte("editCandidacy"), "candidate", msg.CandidateAddr.Bytes(), "moniker", []byte(msg.Description.Moniker), "identity", []byte(msg.Description.Identity)) + return sdk.Result{ + Tags: tags, + } } func handleMsgDelegate(ctx sdk.Context, msg MsgDelegate, k Keeper) sdk.Result {