From 02ab73e26690e08f25c9acb1c13a55e704930934 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 28 May 2018 23:39:57 +0200 Subject: [PATCH] Signing info slashing testcases --- x/slashing/keeper_test.go | 86 ----------------------------- x/slashing/signing_info.go | 8 +-- x/slashing/signing_info_test.go | 35 ++++++++++++ x/slashing/test_common.go | 98 +++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+), 90 deletions(-) create mode 100644 x/slashing/signing_info_test.go create mode 100644 x/slashing/test_common.go diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 9598b24f3..0919b0a20 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -1,75 +1,16 @@ package slashing import ( - "encoding/hex" - "os" "testing" "github.com/stretchr/testify/require" abci "github.com/tendermint/abci/types" - crypto "github.com/tendermint/go-crypto" - dbm "github.com/tendermint/tmlibs/db" - "github.com/tendermint/tmlibs/log" - "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" - "github.com/cosmos/cosmos-sdk/wire" - "github.com/cosmos/cosmos-sdk/x/auth" - "github.com/cosmos/cosmos-sdk/x/bank" "github.com/cosmos/cosmos-sdk/x/stake" ) -var ( - addrs = []sdk.Address{ - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6160"), - testAddr("A58856F0FD53BF058B4909A21AEC019107BA6161"), - } - pks = []crypto.PubKey{ - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB50"), - newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB51"), - } - initCoins int64 = 200 -) - -func createTestCodec() *wire.Codec { - cdc := wire.NewCodec() - sdk.RegisterWire(cdc) - auth.RegisterWire(cdc) - bank.RegisterWire(cdc) - stake.RegisterWire(cdc) - wire.RegisterCrypto(cdc) - return cdc -} - -func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, Keeper) { - keyAcc := sdk.NewKVStoreKey("acc") - keyStake := sdk.NewKVStoreKey("stake") - keySlashing := sdk.NewKVStoreKey("slashing") - db := dbm.NewMemDB() - ms := store.NewCommitMultiStore(db) - ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keyStake, sdk.StoreTypeIAVL, db) - ms.MountStoreWithDB(keySlashing, sdk.StoreTypeIAVL, db) - err := ms.LoadLatestVersion() - require.Nil(t, err) - ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewTMLogger(os.Stdout), nil) - cdc := createTestCodec() - accountMapper := auth.NewAccountMapper(cdc, keyAcc, &auth.BaseAccount{}) - ck := bank.NewKeeper(accountMapper) - sk := stake.NewKeeper(cdc, keyStake, ck, stake.DefaultCodespace) - genesis := stake.DefaultGenesisState() - genesis.Pool.LooseUnbondedTokens = initCoins * int64(len(addrs)) - stake.InitGenesis(ctx, sk, genesis) - for _, addr := range addrs { - ck.AddCoins(ctx, addr, sdk.Coins{ - {sk.GetParams(ctx).BondDenom, initCoins}, - }) - } - keeper := NewKeeper(cdc, keySlashing, sk, DefaultCodespace) - return ctx, ck, sk, keeper -} - func TestHandleDoubleSign(t *testing.T) { ctx, ck, sk, keeper := createTestInput(t) addr, val, amt := addrs[0], pks[0], int64(100) @@ -145,30 +86,3 @@ func TestHandleAbsentValidator(t *testing.T) { pool = sk.GetPool(ctx) require.Equal(t, int64(99), pool.BondedTokens) } - -func newPubKey(pk string) (res crypto.PubKey) { - pkBytes, err := hex.DecodeString(pk) - if err != nil { - panic(err) - } - var pkEd crypto.PubKeyEd25519 - copy(pkEd[:], pkBytes[:]) - return pkEd -} - -func testAddr(addr string) sdk.Address { - res, err := sdk.GetAddress(addr) - if err != nil { - panic(err) - } - return res -} - -func newTestMsgDeclareCandidacy(address sdk.Address, pubKey crypto.PubKey, amt int64) stake.MsgDeclareCandidacy { - return stake.MsgDeclareCandidacy{ - Description: stake.Description{}, - ValidatorAddr: address, - PubKey: pubKey, - Bond: sdk.Coin{"steak", amt}, - } -} diff --git a/x/slashing/signing_info.go b/x/slashing/signing_info.go index 8cb66318d..cadd6d580 100644 --- a/x/slashing/signing_info.go +++ b/x/slashing/signing_info.go @@ -43,10 +43,10 @@ func (k Keeper) setValidatorSigningBitArray(ctx sdk.Context, address sdk.Address } type validatorSigningInfo struct { - StartHeight int64 `json:"start_height"` - IndexOffset int64 `json:"index_offset"` - JailedUntil int64 `json:"jailed_until"` - SignedBlocksCounter int64 `json:"signed_blocks_counter"` + StartHeight int64 `json:"start_height"` // height at which validator was first a candidate OR was unrevoked + IndexOffset int64 `json:"index_offset"` // index offset into signed block bit array + JailedUntil int64 `json:"jailed_until"` // timestamp validator cannot be unrevoked until + SignedBlocksCounter int64 `json:"signed_blocks_counter"` // signed blocks counter (to avoid scanning the array every time) } func validatorSigningInfoKey(v sdk.Address) []byte { diff --git a/x/slashing/signing_info_test.go b/x/slashing/signing_info_test.go new file mode 100644 index 000000000..8000d6745 --- /dev/null +++ b/x/slashing/signing_info_test.go @@ -0,0 +1,35 @@ +package slashing + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +func TestGetSetValidatorSigningInfo(t *testing.T) { + ctx, _, _, keeper := createTestInput(t) + info, found := keeper.getValidatorSigningInfo(ctx, addrs[0]) + require.False(t, found) + newInfo := validatorSigningInfo{ + StartHeight: int64(4), + IndexOffset: int64(3), + JailedUntil: int64(2), + SignedBlocksCounter: int64(10), + } + keeper.setValidatorSigningInfo(ctx, addrs[0], newInfo) + info, found = keeper.getValidatorSigningInfo(ctx, addrs[0]) + require.True(t, found) + require.Equal(t, info.StartHeight, int64(4)) + require.Equal(t, info.IndexOffset, int64(3)) + require.Equal(t, info.JailedUntil, int64(2)) + require.Equal(t, info.SignedBlocksCounter, int64(10)) +} + +func TestGetSetValidatorSigningBitArray(t *testing.T) { + ctx, _, _, keeper := createTestInput(t) + signed := keeper.getValidatorSigningBitArray(ctx, addrs[0], 0) + require.False(t, signed) // treat empty key as unsigned + keeper.setValidatorSigningBitArray(ctx, addrs[0], 0, true) + signed = keeper.getValidatorSigningBitArray(ctx, addrs[0], 0) + require.True(t, signed) // now should be signed +} diff --git a/x/slashing/test_common.go b/x/slashing/test_common.go new file mode 100644 index 000000000..21274df1b --- /dev/null +++ b/x/slashing/test_common.go @@ -0,0 +1,98 @@ +package slashing + +import ( + "encoding/hex" + "os" + "testing" + + "github.com/stretchr/testify/require" + + abci "github.com/tendermint/abci/types" + crypto "github.com/tendermint/go-crypto" + dbm "github.com/tendermint/tmlibs/db" + "github.com/tendermint/tmlibs/log" + + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/wire" + "github.com/cosmos/cosmos-sdk/x/auth" + "github.com/cosmos/cosmos-sdk/x/bank" + "github.com/cosmos/cosmos-sdk/x/stake" +) + +var ( + addrs = []sdk.Address{ + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6160"), + testAddr("A58856F0FD53BF058B4909A21AEC019107BA6161"), + } + pks = []crypto.PubKey{ + newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB50"), + newPubKey("0B485CFC0EECC619440448436F8FC9DF40566F2369E72400281454CB552AFB51"), + } + initCoins int64 = 200 +) + +func createTestCodec() *wire.Codec { + cdc := wire.NewCodec() + sdk.RegisterWire(cdc) + auth.RegisterWire(cdc) + bank.RegisterWire(cdc) + stake.RegisterWire(cdc) + wire.RegisterCrypto(cdc) + return cdc +} + +func createTestInput(t *testing.T) (sdk.Context, bank.Keeper, stake.Keeper, Keeper) { + keyAcc := sdk.NewKVStoreKey("acc") + keyStake := sdk.NewKVStoreKey("stake") + keySlashing := sdk.NewKVStoreKey("slashing") + db := dbm.NewMemDB() + ms := store.NewCommitMultiStore(db) + ms.MountStoreWithDB(keyAcc, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(keyStake, sdk.StoreTypeIAVL, db) + ms.MountStoreWithDB(keySlashing, sdk.StoreTypeIAVL, db) + err := ms.LoadLatestVersion() + require.Nil(t, err) + ctx := sdk.NewContext(ms, abci.Header{}, false, nil, log.NewTMLogger(os.Stdout), nil) + cdc := createTestCodec() + accountMapper := auth.NewAccountMapper(cdc, keyAcc, &auth.BaseAccount{}) + ck := bank.NewKeeper(accountMapper) + sk := stake.NewKeeper(cdc, keyStake, ck, stake.DefaultCodespace) + genesis := stake.DefaultGenesisState() + genesis.Pool.LooseUnbondedTokens = initCoins * int64(len(addrs)) + stake.InitGenesis(ctx, sk, genesis) + for _, addr := range addrs { + ck.AddCoins(ctx, addr, sdk.Coins{ + {sk.GetParams(ctx).BondDenom, initCoins}, + }) + } + keeper := NewKeeper(cdc, keySlashing, sk, DefaultCodespace) + return ctx, ck, sk, keeper +} + +func newPubKey(pk string) (res crypto.PubKey) { + pkBytes, err := hex.DecodeString(pk) + if err != nil { + panic(err) + } + var pkEd crypto.PubKeyEd25519 + copy(pkEd[:], pkBytes[:]) + return pkEd +} + +func testAddr(addr string) sdk.Address { + res, err := sdk.GetAddress(addr) + if err != nil { + panic(err) + } + return res +} + +func newTestMsgDeclareCandidacy(address sdk.Address, pubKey crypto.PubKey, amt int64) stake.MsgDeclareCandidacy { + return stake.MsgDeclareCandidacy{ + Description: stake.Description{}, + ValidatorAddr: address, + PubKey: pubKey, + Bond: sdk.Coin{"steak", amt}, + } +}