From 73292e08b4eda8ae6786c46a593fca0a053ddbdf Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 3 Sep 2018 17:01:49 +0200 Subject: [PATCH 01/52] Start of changes for TM 0.24 --- Gopkg.lock | 46 +++++++++++++-------- Gopkg.toml | 2 +- baseapp/baseapp.go | 10 ++--- types/context.go | 12 +++--- types/context_test.go | 8 ++-- types/stake.go | 2 - x/mock/simulation/random_simulate_blocks.go | 20 ++++----- x/slashing/tick.go | 5 +-- x/slashing/tick_test.go | 6 +-- x/stake/types/validator.go | 2 - 10 files changed, 59 insertions(+), 54 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 5e40c17e6cc2..1c396c1ac06d 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -38,7 +38,7 @@ name = "github.com/btcsuite/btcd" packages = ["btcec"] pruneopts = "UT" - revision = "d81d8877b8f327112e94e814937143a71d1692a7" + revision = "79e00513b1011888b1e675157ab89f527f901cae" [[projects]] digest = "1:386de157f7d19259a7f9c81f26ce011223ce0f090353c1152ffdf730d7d10ac2" @@ -95,12 +95,12 @@ version = "v0.3.0" [[projects]] - digest = "1:c4a2528ccbcabf90f9f3c464a5fc9e302d592861bbfd0b7135a7de8a943d0406" + digest = "1:586ea76dbd0374d6fb649a91d70d652b7fe0ccffb8910a77468e7702e7901f3d" name = "github.com/go-stack/stack" packages = ["."] pruneopts = "UT" - revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" - version = "v1.7.0" + revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a" + version = "v1.8.0" [[projects]] digest = "1:35621fe20f140f05a0c4ef662c26c0ab4ee50bca78aa30fe87d33120bd28165e" @@ -164,13 +164,13 @@ version = "v1.2.0" [[projects]] - branch = "master" - digest = "1:12247a2e99a060cc692f6680e5272c8adf0b8f572e6bce0d7095e624c958a240" + digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10" name = "github.com/hashicorp/hcl" packages = [ ".", "hcl/ast", "hcl/parser", + "hcl/printer", "hcl/scanner", "hcl/strconv", "hcl/token", @@ -179,7 +179,8 @@ "json/token", ] pruneopts = "UT" - revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" + revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241" + version = "v1.0.0" [[projects]] digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" @@ -214,12 +215,12 @@ version = "v1.8.0" [[projects]] - digest = "1:d4d17353dbd05cb52a2a52b7fe1771883b682806f68db442b436294926bbfafb" + digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5" name = "github.com/mattn/go-isatty" packages = ["."] pruneopts = "UT" - revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" - version = "v0.0.3" + revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c" + version = "v0.0.4" [[projects]] digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc" @@ -394,6 +395,13 @@ pruneopts = "UT" revision = "ae2bd5eed72d46b28834ec3f60db3a3ebedd8dbd" +[[projects]] + digest = "1:605b6546f3f43745695298ec2d342d3e952b6d91cdf9f349bea9315f677d759f" + name = "github.com/tendermint/btcd" + packages = ["btcec"] + pruneopts = "UT" + revision = "e5840949ff4fff0c56f9b6a541e22b63581ea9df" + [[projects]] branch = "master" digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722" @@ -423,7 +431,8 @@ version = "v0.9.2" [[projects]] - digest = "1:4f15e95fe3888cc75dd34f407d6394cbc7fd3ff24920851b92b295f6a8b556e6" + branch = "develop" + digest = "1:010630eb6059fa5dd143b9cddb8c9e7c740a9267aca553455de7839515b2fee0" name = "github.com/tendermint/tendermint" packages = [ "abci/client", @@ -441,6 +450,8 @@ "crypto/ed25519", "crypto/encoding/amino", "crypto/merkle", + "crypto/multisig", + "crypto/multisig/bitarray", "crypto/secp256k1", "crypto/tmhash", "crypto/xsalsa20symmetric", @@ -460,7 +471,6 @@ "lite", "lite/client", "lite/errors", - "lite/files", "lite/proxy", "mempool", "node", @@ -483,11 +493,11 @@ "state/txindex/kv", "state/txindex/null", "types", + "types/time", "version", ] pruneopts = "UT" - revision = "81df19e68ab1519399fccf0cab81cb75bf9d782e" - version = "v0.23.1-rc0" + revision = "1de32fba17a392b656c73a917843724b92b8989d" [[projects]] digest = "1:bf6d9a827ea3cad964c2f863302e4f6823170d0b5ed16f72cf1184a7c615067e" @@ -525,7 +535,7 @@ "salsa20/salsa", ] pruneopts = "UT" - revision = "614d502a4dac94afa3a6ce146bd1736da82514c6" + revision = "182538f80094b6a8efaade63a8fd8e0d9d5843dd" [[projects]] digest = "1:d36f55a999540d29b6ea3c2ea29d71c76b1d9853fdcd3e5c5cb4836f2ba118f1" @@ -545,14 +555,14 @@ [[projects]] branch = "master" - digest = "1:86171d21d59449dcf7cee0b7d2da83dff989dab9b9b69bfe0a3d59c3c1ca6081" + digest = "1:0cd3b4a6aec2641ff2bf7e35d93427787c60e5d94998460aab8f54921a1bc2db" name = "golang.org/x/sys" packages = [ "cpu", "unix", ] pruneopts = "UT" - revision = "11551d06cbcc94edc80a0facaccbda56473c19c1" + revision = "fa5fdf94c78965f1aa8423f0cc50b8b8d728b05a" [[projects]] digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18" @@ -583,7 +593,7 @@ name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] pruneopts = "UT" - revision = "c66870c02cf823ceb633bcd05be3c7cda29976f4" + revision = "11092d34479b07829b72e10713b159248caf5dad" [[projects]] digest = "1:2dab32a43451e320e49608ff4542fdfc653c95dcc35d0065ec9c6c3dd540ed74" diff --git a/Gopkg.toml b/Gopkg.toml index 4368699b6be9..dc52ec76a362 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -57,7 +57,7 @@ [[override]] name = "github.com/tendermint/tendermint" - version = "=v0.23.1-rc0" + branch = "develop" [[constraint]] name = "github.com/bartekn/go-bip39" diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index 60c694ff766e..a03b3cdbe4eb 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -64,9 +64,9 @@ type BaseApp struct { // checkState is set on initialization and reset on Commit. // deliverState is set in InitChain and BeginBlock and cleared on Commit. // See methods setCheckState and setDeliverState. - checkState *state // for CheckTx - deliverState *state // for DeliverTx - signedValidators []abci.SigningValidator // absent validators from begin block + checkState *state // for CheckTx + deliverState *state // for DeliverTx + voteInfos []abci.VoteInfo // absent validators from begin block // flag for sealing sealed bool @@ -494,12 +494,12 @@ func validateBasicTxMsgs(msgs []sdk.Msg) sdk.Error { } // retrieve the context for the ante handler and store the tx bytes; store -// the signing validators if the tx runs within the deliverTx() state. +// the vote infos if the tx runs within the deliverTx() state. func (app *BaseApp) getContextForAnte(mode runTxMode, txBytes []byte) (ctx sdk.Context) { // Get the context ctx = getState(app, mode).ctx.WithTxBytes(txBytes) if mode == runTxModeDeliver { - ctx = ctx.WithSigningValidators(app.signedValidators) + ctx = ctx.WithVoteInfos(app.voteInfos) } return } diff --git a/types/context.go b/types/context.go index 44b0474e8b6b..d48a9d989838 100644 --- a/types/context.go +++ b/types/context.go @@ -42,7 +42,7 @@ func NewContext(ms MultiStore, header abci.Header, isCheckTx bool, logger log.Lo c = c.WithChainID(header.ChainID) c = c.WithTxBytes(nil) c = c.WithLogger(logger) - c = c.WithSigningValidators(nil) + c = c.WithVoteInfos(nil) c = c.WithGasMeter(NewInfiniteGasMeter()) return c } @@ -133,7 +133,7 @@ const ( contextKeyChainID contextKeyTxBytes contextKeyLogger - contextKeySigningValidators + contextKeyVoteInfos contextKeyGasMeter ) @@ -163,8 +163,8 @@ func (c Context) TxBytes() []byte { func (c Context) Logger() log.Logger { return c.Value(contextKeyLogger).(log.Logger) } -func (c Context) SigningValidators() []abci.SigningValidator { - return c.Value(contextKeySigningValidators).([]abci.SigningValidator) +func (c Context) VoteInfos() []abci.VoteInfo { + return c.Value(contextKeyVoteInfos).([]abci.VoteInfo) } func (c Context) GasMeter() GasMeter { return c.Value(contextKeyGasMeter).(GasMeter) @@ -195,8 +195,8 @@ func (c Context) WithTxBytes(txBytes []byte) Context { func (c Context) WithLogger(logger log.Logger) Context { return c.withValue(contextKeyLogger, logger) } -func (c Context) WithSigningValidators(SigningValidators []abci.SigningValidator) Context { - return c.withValue(contextKeySigningValidators, SigningValidators) +func (c Context) WithVoteInfos(VoteInfos []abci.VoteInfo) Context { + return c.withValue(contextKeyVoteInfos, VoteInfos) } func (c Context) WithGasMeter(meter GasMeter) Context { return c.withValue(contextKeyGasMeter, meter) diff --git a/types/context_test.go b/types/context_test.go index b11a774cd90b..c5ec604fa061 100644 --- a/types/context_test.go +++ b/types/context_test.go @@ -151,7 +151,7 @@ func TestContextWithCustom(t *testing.T) { require.Panics(t, func() { ctx.ChainID() }) require.Panics(t, func() { ctx.TxBytes() }) require.Panics(t, func() { ctx.Logger() }) - require.Panics(t, func() { ctx.SigningValidators() }) + require.Panics(t, func() { ctx.VoteInfos() }) require.Panics(t, func() { ctx.GasMeter() }) header := abci.Header{} @@ -160,14 +160,14 @@ func TestContextWithCustom(t *testing.T) { ischeck := true txbytes := []byte("txbytes") logger := NewMockLogger() - signvals := []abci.SigningValidator{{}} + voteinfos := []abci.VoteInfo{{}} meter := types.NewGasMeter(10000) ctx = types.NewContext(nil, header, ischeck, logger). WithBlockHeight(height). WithChainID(chainid). WithTxBytes(txbytes). - WithSigningValidators(signvals). + WithVoteInfos(voteinfos). WithGasMeter(meter) require.Equal(t, header, ctx.BlockHeader()) @@ -175,7 +175,7 @@ func TestContextWithCustom(t *testing.T) { require.Equal(t, chainid, ctx.ChainID()) require.Equal(t, txbytes, ctx.TxBytes()) require.Equal(t, logger, ctx.Logger()) - require.Equal(t, signvals, ctx.SigningValidators()) + require.Equal(t, voteinfos, ctx.VoteInfos()) require.Equal(t, meter, ctx.GasMeter()) } diff --git a/types/stake.go b/types/stake.go index ba11cd5f86b6..c52e020dd2e6 100644 --- a/types/stake.go +++ b/types/stake.go @@ -3,7 +3,6 @@ package types import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" - tmtypes "github.com/tendermint/tendermint/types" ) // status of a validator @@ -51,7 +50,6 @@ type Validator interface { // validator which fulfills abci validator interface for use in Tendermint func ABCIValidator(v Validator) abci.Validator { return abci.Validator{ - PubKey: tmtypes.TM2PB.PubKey(v.GetPubKey()), Address: v.GetPubKey().Address(), Power: v.GetPower().RoundInt64(), } diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index fc7543280a74..02000cc354a6 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -77,9 +77,9 @@ func SimulateFromSeed( opCount := 0 var pastTimes []time.Time - var pastSigningValidators [][]abci.SigningValidator + var pastVoteInfos [][]abci.VoteInfo - request := RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastSigningValidators, event, header, log) + request := RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastVoteInfos, event, header, log) // These are operations which have been queued by previous operations operationQueue := make(map[int][]Operation) @@ -91,7 +91,7 @@ func SimulateFromSeed( for i := 0; i < numBlocks; i++ { // Log the header time for future lookup pastTimes = append(pastTimes, header.Time) - pastSigningValidators = append(pastSigningValidators, request.LastCommitInfo.Validators) + pastVoteInfos = append(pastVoteInfos, request.LastCommitInfo.Validators) // Run the BeginBlock handler app.BeginBlock(request) @@ -126,7 +126,7 @@ func SimulateFromSeed( } // Generate a random RequestBeginBlock with the current validator set for the next block - request = RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastSigningValidators, event, header, log) + request = RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastVoteInfos, event, header, log) // Update the validator set validators = updateValidators(tb, r, validators, res.ValidatorUpdates, event) @@ -244,11 +244,11 @@ func getKeys(validators map[string]mockValidator) []string { // RandomRequestBeginBlock generates a list of signing validators according to the provided list of validators, signing fraction, and evidence fraction func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, livenessTransitions TransitionMatrix, evidenceFraction float64, - pastTimes []time.Time, pastSigningValidators [][]abci.SigningValidator, event func(string), header abci.Header, log string) abci.RequestBeginBlock { + pastTimes []time.Time, pastVoteInfos [][]abci.VoteInfo, event func(string), header abci.Header, log string) abci.RequestBeginBlock { if len(validators) == 0 { return abci.RequestBeginBlock{Header: header} } - signingValidators := make([]abci.SigningValidator, len(validators)) + voteInfos := make([]abci.VoteInfo, len(validators)) i := 0 for _, key := range getKeys(validators) { mVal := validators[key] @@ -269,7 +269,7 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, } else { event("beginblock/signing/missed") } - signingValidators[i] = abci.SigningValidator{ + voteInfos[i] = abci.VoteInfo{ Validator: mVal.val, SignedLastBlock: signed, } @@ -282,11 +282,11 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, for r.Float64() < evidenceFraction { height := header.Height time := header.Time - vals := signingValidators + vals := voteInfos if r.Float64() < pastEvidenceFraction { height = int64(r.Intn(int(header.Height))) time = pastTimes[height] - vals = pastSigningValidators[height] + vals = pastVoteInfos[height] } validator := vals[r.Intn(len(vals))].Validator var totalVotingPower int64 @@ -306,7 +306,7 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, return abci.RequestBeginBlock{ Header: header, LastCommitInfo: abci.LastCommitInfo{ - Validators: signingValidators, + Validators: voteInfos, }, ByzantineValidators: evidence, } diff --git a/x/slashing/tick.go b/x/slashing/tick.go index 253daa4128d1..3210a0f331ba 100644 --- a/x/slashing/tick.go +++ b/x/slashing/tick.go @@ -20,9 +20,8 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags // Iterate over all the validators which *should* have signed this block // Store whether or not they have actually signed it and slash/unbond any // which have missed too many blocks in a row (downtime slashing) - for _, signingValidator := range req.LastCommitInfo.GetValidators() { - present := signingValidator.SignedLastBlock - sk.handleValidatorSignature(ctx, signingValidator.Validator.Address, signingValidator.Validator.Power, present) + for _, voteInfo := range req.LastCommitInfo.GetVoteInfos() { + sk.handleValidatorSignature(ctx, voteInfo.Validator.Address, voteInfo.Validator.Power, voteInfo.SignedLastBlock) } // Iterate through any newly discovered evidence of infraction diff --git a/x/slashing/tick_test.go b/x/slashing/tick_test.go index 25167578d1c1..fccdd844ae8e 100644 --- a/x/slashing/tick_test.go +++ b/x/slashing/tick_test.go @@ -32,7 +32,7 @@ func TestBeginBlocker(t *testing.T) { // mark the validator as having signed req := abci.RequestBeginBlock{ LastCommitInfo: abci.LastCommitInfo{ - Validators: []abci.SigningValidator{{ + Validators: []abci.VoteInfo{{ Validator: val, SignedLastBlock: true, }}, @@ -54,7 +54,7 @@ func TestBeginBlocker(t *testing.T) { ctx = ctx.WithBlockHeight(height) req = abci.RequestBeginBlock{ LastCommitInfo: abci.LastCommitInfo{ - Validators: []abci.SigningValidator{{ + Validators: []abci.VoteInfo{{ Validator: val, SignedLastBlock: true, }}, @@ -68,7 +68,7 @@ func TestBeginBlocker(t *testing.T) { ctx = ctx.WithBlockHeight(height) req = abci.RequestBeginBlock{ LastCommitInfo: abci.LastCommitInfo{ - Validators: []abci.SigningValidator{{ + Validators: []abci.VoteInfo{{ Validator: val, SignedLastBlock: false, }}, diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index 0d93093118e2..7e71b5b25189 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -312,7 +312,6 @@ func (d Description) EnsureLength() (Description, sdk.Error) { // ABCIValidator returns an abci.Validator from a staked validator type. func (v Validator) ABCIValidator() abci.Validator { return abci.Validator{ - PubKey: tmtypes.TM2PB.PubKey(v.PubKey), Address: v.PubKey.Address(), Power: v.BondedTokens().RoundInt64(), } @@ -322,7 +321,6 @@ func (v Validator) ABCIValidator() abci.Validator { // with with zero power used for validator updates. func (v Validator) ABCIValidatorZero() abci.Validator { return abci.Validator{ - PubKey: tmtypes.TM2PB.PubKey(v.PubKey), Address: v.PubKey.Address(), Power: 0, } From 14d5e686d9d94f6510930c91155fe8000a4b8235 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 3 Sep 2018 18:04:28 +0200 Subject: [PATCH 02/52] More TM 0.24 updates --- baseapp/baseapp.go | 2 +- server/start.go | 7 +++++++ store/firstlast.go | 6 +++--- store/iavlstore.go | 4 ++-- types/stake.go | 9 +++++++++ x/slashing/keeper.go | 2 +- x/slashing/tick.go | 2 +- x/stake/genesis.go | 6 +++--- x/stake/handler.go | 2 +- x/stake/keeper/validator.go | 14 +++++++------- x/stake/types/validator.go | 10 +++++----- 11 files changed, 40 insertions(+), 24 deletions(-) diff --git a/baseapp/baseapp.go b/baseapp/baseapp.go index a03b3cdbe4eb..433ed51698fb 100644 --- a/baseapp/baseapp.go +++ b/baseapp/baseapp.go @@ -420,7 +420,7 @@ func (app *BaseApp) BeginBlock(req abci.RequestBeginBlock) (res abci.ResponseBeg // set the signed validators for addition to context in deliverTx // TODO: communicate this result to the address to pubkey map in slashing - app.signedValidators = req.LastCommitInfo.GetValidators() + app.voteInfos = req.LastCommitInfo.GetVotes() return } diff --git a/server/start.go b/server/start.go index 8f369d517fbf..9c8fcfc1fbb0 100644 --- a/server/start.go +++ b/server/start.go @@ -10,6 +10,7 @@ import ( tcmd "github.com/tendermint/tendermint/cmd/tendermint/commands" cmn "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/node" + "github.com/tendermint/tendermint/p2p" pvm "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/proxy" ) @@ -94,10 +95,16 @@ func startInProcess(ctx *Context, appCreator AppCreator) (*node.Node, error) { return nil, err } + nodeKey, err := p2p.LoadOrGenNodeKey(cfg.NodeKeyFile()) + if err != nil { + return nil, err + } + // create & start tendermint node tmNode, err := node.NewNode( cfg, pvm.LoadOrGenFilePV(cfg.PrivValidatorFile()), + nodeKey, proxy.NewLocalClientCreator(app), node.DefaultGenesisDocProviderFunc(cfg), node.DefaultDBProvider, diff --git a/store/firstlast.go b/store/firstlast.go index 70f6659a8718..a47f1396d158 100644 --- a/store/firstlast.go +++ b/store/firstlast.go @@ -14,7 +14,7 @@ func First(st KVStore, start, end []byte) (kv cmn.KVPair, ok bool) { } defer iter.Close() - return cmn.KVPair{iter.Key(), iter.Value()}, true + return cmn.KVPair{Key: iter.Key(), Value: iter.Value()}, true } // Gets the last item. `end` is exclusive. @@ -22,7 +22,7 @@ func Last(st KVStore, start, end []byte) (kv cmn.KVPair, ok bool) { iter := st.ReverseIterator(end, start) if !iter.Valid() { if v := st.Get(start); v != nil { - return cmn.KVPair{cp(start), cp(v)}, true + return cmn.KVPair{Key: cp(start), Value: cp(v)}, true } return kv, false } @@ -36,5 +36,5 @@ func Last(st KVStore, start, end []byte) (kv cmn.KVPair, ok bool) { } } - return cmn.KVPair{iter.Key(), iter.Value()}, true + return cmn.KVPair{Key: iter.Key(), Value: iter.Value()}, true } diff --git a/store/iavlstore.go b/store/iavlstore.go index daffa7dd5553..71cc4f7e9d36 100644 --- a/store/iavlstore.go +++ b/store/iavlstore.go @@ -239,7 +239,7 @@ func (st *iavlStore) Query(req abci.RequestQuery) (res abci.ResponseQuery) { var KVs []KVPair iterator := sdk.KVStorePrefixIterator(st, subspace) for ; iterator.Valid(); iterator.Next() { - KVs = append(KVs, KVPair{iterator.Key(), iterator.Value()}) + KVs = append(KVs, KVPair{Key: iterator.Key(), Value: iterator.Value()}) } iterator.Close() res.Value = cdc.MustMarshalBinary(KVs) @@ -309,7 +309,7 @@ func (iter *iavlIterator) iterateRoutine() { select { case <-iter.quitCh: return true // done with iteration. - case iter.iterCh <- cmn.KVPair{key, value}: + case iter.iterCh <- cmn.KVPair{Key: key, Value: value}: return false // yay. } }, diff --git a/types/stake.go b/types/stake.go index c52e020dd2e6..84f98f9cb548 100644 --- a/types/stake.go +++ b/types/stake.go @@ -3,6 +3,7 @@ package types import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + tmtypes "github.com/tendermint/tendermint/types" ) // status of a validator @@ -55,6 +56,14 @@ func ABCIValidator(v Validator) abci.Validator { } } +// validator which fulfills abci validator update interface for use in Tendermint +func ABCIValidatorUpdate(v Validator) abci.ValidatorUpdate { + return abci.ValidatorUpdate{ + PubKey: tmtypes.TM2PB.PubKey(v.GetPubKey()), + Power: v.GetPower().RoundInt64(), + } +} + // properties for the set of all validators type ValidatorSet interface { // iterate through validator by owner-AccAddress, execute func for each validator diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 272516585765..081e1c1e582d 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -138,7 +138,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p } // AddValidators adds the validators to the keepers validator addr to pubkey mapping. -func (k Keeper) AddValidators(ctx sdk.Context, vals []abci.Validator) { +func (k Keeper) AddValidators(ctx sdk.Context, vals []abci.ValidatorUpdate) { for i := 0; i < len(vals); i++ { val := vals[i] pubkey, err := tmtypes.PB2TM.PubKey(val.PubKey) diff --git a/x/slashing/tick.go b/x/slashing/tick.go index 3210a0f331ba..007d93788772 100644 --- a/x/slashing/tick.go +++ b/x/slashing/tick.go @@ -20,7 +20,7 @@ func BeginBlocker(ctx sdk.Context, req abci.RequestBeginBlock, sk Keeper) (tags // Iterate over all the validators which *should* have signed this block // Store whether or not they have actually signed it and slash/unbond any // which have missed too many blocks in a row (downtime slashing) - for _, voteInfo := range req.LastCommitInfo.GetVoteInfos() { + for _, voteInfo := range req.LastCommitInfo.GetVotes() { sk.handleValidatorSignature(ctx, voteInfo.Validator.Address, voteInfo.Validator.Power, voteInfo.SignedLastBlock) } diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 7a004bccd270..ff41a73bf5bb 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -15,7 +15,7 @@ import ( // addition, it also sets any delegations found in data. Finally, it updates // the bonded validators. // Returns final validator set after applying all declaration and delegations -func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res []abci.Validator, err error) { +func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res []abci.ValidatorUpdate, err error) { keeper.SetPool(ctx, data.Pool) keeper.SetNewParams(ctx, data.Params) keeper.InitIntraTxCounter(ctx) @@ -47,9 +47,9 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ keeper.UpdateBondedValidatorsFull(ctx) vals := keeper.GetValidatorsBonded(ctx) - res = make([]abci.Validator, len(vals)) + res = make([]abci.ValidatorUpdate, len(vals)) for i, val := range vals { - res[i] = sdk.ABCIValidator(val) + res[i] = sdk.ABCIValidatorUpdate(val) } return } diff --git a/x/stake/handler.go b/x/stake/handler.go index 4b478fffd7b0..d19b5b942b67 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -36,7 +36,7 @@ func NewHandler(k keeper.Keeper) sdk.Handler { } // Called every block, process inflation, update validator set -func EndBlocker(ctx sdk.Context, k keeper.Keeper) (ValidatorUpdates []abci.Validator) { +func EndBlocker(ctx sdk.Context, k keeper.Keeper) (ValidatorUpdates []abci.ValidatorUpdate) { pool := k.GetPool(ctx) // Process provision inflation diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 47a5d5f66fa0..9f8ce7e24cd1 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -201,13 +201,13 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []types.Validator { // Accumulated updates to the active/bonded validator set for tendermint // get the most recently updated validators -func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) { +func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorUpdate) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, TendermintUpdatesKey) //smallest to largest for ; iterator.Valid(); iterator.Next() { valBytes := iterator.Value() - var val abci.Validator + var val abci.ValidatorUpdate k.cdc.MustUnmarshalBinary(valBytes, &val) updates = append(updates, val) } @@ -256,7 +256,7 @@ func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) type case powerIncreasing && !validator.Jailed && (oldFound && oldValidator.Status == sdk.Bonded): - bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) + bz := k.cdc.MustMarshalBinary(sdk.ABCIValidatorUpdate(validator)) store.Set(GetTendermintUpdatesKey(validator.Operator), bz) if cliffPower != nil { @@ -292,7 +292,7 @@ func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) type // if decreased in power but still bonded, update Tendermint validator if oldFound && oldValidator.BondedTokens().GT(validator.BondedTokens()) { - bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) + bz := k.cdc.MustMarshalBinary(sdk.ABCIValidatorUpdate(validator)) store.Set(GetTendermintUpdatesKey(validator.Operator), bz) } } @@ -634,7 +634,7 @@ func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validat k.SetValidator(ctx, validator) // add to accumulated changes for tendermint - bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) + bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidatorUpdateZero()) store.Set(GetTendermintUpdatesKey(validator.Operator), bzABCI) // also remove from the Bonded types.Validators Store @@ -669,7 +669,7 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. store.Set(GetValidatorsBondedIndexKey(validator.Operator), []byte{}) // add to accumulated changes for tendermint - bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidator()) + bzABCI := k.cdc.MustMarshalBinary(sdk.ABCIValidatorUpdate(validator)) store.Set(GetTendermintUpdatesKey(validator.Operator), bzABCI) // call the bond hook if present @@ -704,7 +704,7 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { } store.Delete(GetValidatorsBondedIndexKey(validator.Operator)) - bz := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) + bz := k.cdc.MustMarshalBinary(validator.ABCIValidatorUpdateZero()) store.Set(GetTendermintUpdatesKey(address), bz) } diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index 7e71b5b25189..d7c0bdb65bd5 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -317,12 +317,12 @@ func (v Validator) ABCIValidator() abci.Validator { } } -// ABCIValidatorZero returns an abci.Validator from a staked validator type +// ABCIValidatorUpdateZero returns an abci.ValidatorUpdate from a staked validator type // with with zero power used for validator updates. -func (v Validator) ABCIValidatorZero() abci.Validator { - return abci.Validator{ - Address: v.PubKey.Address(), - Power: 0, +func (v Validator) ABCIValidatorUpdateZero() abci.ValidatorUpdate { + return abci.ValidatorUpdate{ + PubKey: tmtypes.TM2PB.PubKey(v.PubKey), + Power: 0, } } From 532c9ee95e50993403b19f15635f717eeb2f9855 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 3 Sep 2018 18:24:32 +0200 Subject: [PATCH 03/52] Client updates for TM 0.24 --- client/context/context.go | 19 +++++++++++-------- client/context/query.go | 6 +++--- client/lcd/test_helpers.go | 6 ++++++ 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/client/context/context.go b/client/context/context.go index 8e56cfa1aeb3..a2ef0a30e630 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -11,6 +11,7 @@ import ( "github.com/spf13/viper" "github.com/tendermint/tendermint/libs/cli" + "github.com/tendermint/tendermint/libs/log" tmlite "github.com/tendermint/tendermint/lite" tmliteProxy "github.com/tendermint/tendermint/lite/proxy" rpcclient "github.com/tendermint/tendermint/rpc/client" @@ -36,7 +37,7 @@ type CLIContext struct { Async bool JSON bool PrintResponse bool - Certifier tmlite.Certifier + Verifier tmlite.Verifier DryRun bool } @@ -63,12 +64,12 @@ func NewCLIContext() CLIContext { Async: viper.GetBool(client.FlagAsync), JSON: viper.GetBool(client.FlagJson), PrintResponse: viper.GetBool(client.FlagPrintResponse), - Certifier: createCertifier(), + Verifier: createVerifier(), DryRun: viper.GetBool(client.FlagDryRun), } } -func createCertifier() tmlite.Certifier { +func createVerifier() tmlite.Verifier { trustNode := viper.GetBool(client.FlagTrustNode) if trustNode { return nil @@ -91,11 +92,13 @@ func createCertifier() tmlite.Certifier { if errMsg.Len() != 0 { panic(fmt.Errorf("can't create certifier for distrust mode, empty values from these options: %s", errMsg.String())) } - certifier, err := tmliteProxy.GetCertifier(chainID, home, nodeURI) + node := rpcclient.NewHTTP(nodeURI, "/websocket") + // TODO Utilize ctx.Logger correctly + verifier, err := tmliteProxy.NewVerifier(chainID, home, node, log.NewNopLogger()) if err != nil { panic(err) } - return certifier + return verifier } // WithCodec returns a copy of the context with an updated codec. @@ -156,9 +159,9 @@ func (ctx CLIContext) WithUseLedger(useLedger bool) CLIContext { return ctx } -// WithCertifier - return a copy of the context with an updated Certifier -func (ctx CLIContext) WithCertifier(certifier tmlite.Certifier) CLIContext { - ctx.Certifier = certifier +// WithVerifier - return a copy of the context with an updated Verifier +func (ctx CLIContext) WithVerifier(verifier tmlite.Verifier) CLIContext { + ctx.Verifier = verifier return ctx } diff --git a/client/context/query.go b/client/context/query.go index 4c1cad877785..58dca639afdf 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -325,8 +325,8 @@ func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, err erro // verifyProof perform response proof verification func (ctx CLIContext) verifyProof(path string, resp abci.ResponseQuery) error { - if ctx.Certifier == nil { - return fmt.Errorf("missing valid certifier to verify data from untrusted node") + if ctx.Verifier == nil { + return fmt.Errorf("missing valid verifier to verify data from untrusted node") } node, err := ctx.GetNode() @@ -335,7 +335,7 @@ func (ctx CLIContext) verifyProof(path string, resp abci.ResponseQuery) error { } // AppHash for height H is in header H+1 - commit, err := tmliteProxy.GetCertifiedCommit(resp.Height+1, node, ctx.Certifier) + commit, err := tmliteProxy.GetCertifiedCommit(resp.Height+1, node, ctx.Verifier) if err != nil { return err } diff --git a/client/lcd/test_helpers.go b/client/lcd/test_helpers.go index 7d9a46403c2a..6ed80aa45d2d 100644 --- a/client/lcd/test_helpers.go +++ b/client/lcd/test_helpers.go @@ -33,6 +33,7 @@ import ( dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" nm "github.com/tendermint/tendermint/node" + "github.com/tendermint/tendermint/p2p" pvm "github.com/tendermint/tendermint/privval" "github.com/tendermint/tendermint/proxy" tmrpc "github.com/tendermint/tendermint/rpc/lib/server" @@ -218,9 +219,14 @@ func startTM( ) (*nm.Node, error) { genDocProvider := func() (*tmtypes.GenesisDoc, error) { return genDoc, nil } dbProvider := func(*nm.DBContext) (dbm.DB, error) { return dbm.NewMemDB(), nil } + nodeKey, err := p2p.LoadOrGenNodeKey(tmcfg.NodeKeyFile()) + if err != nil { + return nil, err + } node, err := nm.NewNode( tmcfg, privVal, + nodeKey, proxy.NewLocalClientCreator(app), genDocProvider, dbProvider, From 8f6c9e1b9a97d4f39b92a2b662e8cc7b95f7bfb5 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 00:14:48 +0200 Subject: [PATCH 04/52] Pin to Tendermint 0.24.0-rc0 --- Gopkg.lock | 55 +++++++++++++++++++++++++++++++----------------------- Gopkg.toml | 4 ++-- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 2245223419a4..7da07e4c2b2d 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -26,11 +26,11 @@ [[projects]] branch = "master" - digest = "1:70f6b224a59b2fa453debffa85c77f71063d8754b90c8c4fbad5794e2c382b0f" + digest = "1:7736fc6da04620727f8f3aa2ced8d77be8e074a302820937aa5993848c769b27" name = "github.com/brejski/hid" packages = ["."] pruneopts = "UT" - revision = "06112dcfcc50a7e0e4fd06e17f9791e788fdaafc" + revision = "48b08affede2cea076a3cf13b2e3f72ed262b743" [[projects]] branch = "master" @@ -38,7 +38,7 @@ name = "github.com/btcsuite/btcd" packages = ["btcec"] pruneopts = "UT" - revision = "d81d8877b8f327112e94e814937143a71d1692a7" + revision = "cff30e1d23fc9e800b2b5b4b41ef1817dda07e9f" [[projects]] digest = "1:386de157f7d19259a7f9c81f26ce011223ce0f090353c1152ffdf730d7d10ac2" @@ -95,12 +95,12 @@ version = "v0.3.0" [[projects]] - digest = "1:c4a2528ccbcabf90f9f3c464a5fc9e302d592861bbfd0b7135a7de8a943d0406" + digest = "1:586ea76dbd0374d6fb649a91d70d652b7fe0ccffb8910a77468e7702e7901f3d" name = "github.com/go-stack/stack" packages = ["."] pruneopts = "UT" - revision = "259ab82a6cad3992b4e21ff5cac294ccb06474bc" - version = "v1.7.0" + revision = "2fee6af1a9795aafbe0253a0cfbdf668e1fb8a9a" + version = "v1.8.0" [[projects]] digest = "1:35621fe20f140f05a0c4ef662c26c0ab4ee50bca78aa30fe87d33120bd28165e" @@ -164,8 +164,7 @@ version = "v1.2.0" [[projects]] - branch = "master" - digest = "1:12247a2e99a060cc692f6680e5272c8adf0b8f572e6bce0d7095e624c958a240" + digest = "1:ea40c24cdbacd054a6ae9de03e62c5f252479b96c716375aace5c120d68647c8" name = "github.com/hashicorp/hcl" packages = [ ".", @@ -179,7 +178,8 @@ "json/token", ] pruneopts = "UT" - revision = "ef8a98b0bbce4a65b5aa4c368430a80ddc533168" + revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241" + version = "v1.0.0" [[projects]] digest = "1:870d441fe217b8e689d7949fef6e43efbc787e50f200cb1e70dbca9204a1d6be" @@ -214,12 +214,12 @@ version = "v1.8.0" [[projects]] - digest = "1:d4d17353dbd05cb52a2a52b7fe1771883b682806f68db442b436294926bbfafb" + digest = "1:0981502f9816113c9c8c4ac301583841855c8cf4da8c72f696b3ebedf6d0e4e5" name = "github.com/mattn/go-isatty" packages = ["."] pruneopts = "UT" - revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" - version = "v0.0.3" + revision = "6ca4dbf54d38eea1a992b3c722a76a5d1c4cb25c" + version = "v0.0.4" [[projects]] digest = "1:ff5ebae34cfbf047d505ee150de27e60570e8c394b3b8fdbb720ff6ac71985fc" @@ -394,6 +394,13 @@ pruneopts = "UT" revision = "ae2bd5eed72d46b28834ec3f60db3a3ebedd8dbd" +[[projects]] + digest = "1:605b6546f3f43745695298ec2d342d3e952b6d91cdf9f349bea9315f677d759f" + name = "github.com/tendermint/btcd" + packages = ["btcec"] + pruneopts = "UT" + revision = "e5840949ff4fff0c56f9b6a541e22b63581ea9df" + [[projects]] branch = "master" digest = "1:087aaa7920e5d0bf79586feb57ce01c35c830396ab4392798112e8aae8c47722" @@ -407,12 +414,12 @@ revision = "d8387025d2b9d158cf4efb07e7ebf814bcce2057" [[projects]] - digest = "1:e0a2a4be1e20c305badc2b0a7a9ab7fef6da500763bec23ab81df3b5f9eec9ee" + digest = "1:2c971a45c89ca2ccc735af50919cdee05fbdc54d4bf50625073693300e31ead8" name = "github.com/tendermint/go-amino" packages = ["."] pruneopts = "UT" - revision = "a8328986c1608950fa5d3d1c0472cccc4f8fc02c" - version = "v0.12.0-rc0" + revision = "faa6e731944e2b7b6a46ad202902851e8ce85bee" + version = "v0.12.0" [[projects]] digest = "1:e99ef92d64f2391efbbfb15310df635f96247532bbac2676ea43e466d706401d" @@ -423,7 +430,7 @@ version = "v0.10.0" [[projects]] - digest = "1:4f15e95fe3888cc75dd34f407d6394cbc7fd3ff24920851b92b295f6a8b556e6" + digest = "1:1b603d279b678be4efda149a1c6b03e23c0409f796513e0f858cfd4b3bd4f20a" name = "github.com/tendermint/tendermint" packages = [ "abci/client", @@ -441,6 +448,8 @@ "crypto/ed25519", "crypto/encoding/amino", "crypto/merkle", + "crypto/multisig", + "crypto/multisig/bitarray", "crypto/secp256k1", "crypto/tmhash", "crypto/xsalsa20symmetric", @@ -460,7 +469,6 @@ "lite", "lite/client", "lite/errors", - "lite/files", "lite/proxy", "mempool", "node", @@ -483,11 +491,12 @@ "state/txindex/kv", "state/txindex/null", "types", + "types/time", "version", ] pruneopts = "UT" - revision = "81df19e68ab1519399fccf0cab81cb75bf9d782e" - version = "v0.23.1-rc0" + revision = "604eae86b66282185e2a3a5906031f1df223b779" + version = "v0.24.0-rc0" [[projects]] digest = "1:bf6d9a827ea3cad964c2f863302e4f6823170d0b5ed16f72cf1184a7c615067e" @@ -525,7 +534,7 @@ "salsa20/salsa", ] pruneopts = "UT" - revision = "614d502a4dac94afa3a6ce146bd1736da82514c6" + revision = "0709b304e793a5edb4a2c0145f281ecdc20838a4" [[projects]] digest = "1:d36f55a999540d29b6ea3c2ea29d71c76b1d9853fdcd3e5c5cb4836f2ba118f1" @@ -545,14 +554,14 @@ [[projects]] branch = "master" - digest = "1:86171d21d59449dcf7cee0b7d2da83dff989dab9b9b69bfe0a3d59c3c1ca6081" + digest = "1:e54041967955fe3ddc2f5d75060301f2c7ef1ee8fae9a76e9e238b8bff82eb12" name = "golang.org/x/sys" packages = [ "cpu", "unix", ] pruneopts = "UT" - revision = "4ea2f632f6e912459fe60b26b1749377f0d889d5" + revision = "8cf3aee429924738c56c34bb819c4ea8273fc434" [[projects]] digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18" @@ -583,7 +592,7 @@ name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] pruneopts = "UT" - revision = "c66870c02cf823ceb633bcd05be3c7cda29976f4" + revision = "11092d34479b07829b72e10713b159248caf5dad" [[projects]] digest = "1:2dab32a43451e320e49608ff4542fdfc653c95dcc35d0065ec9c6c3dd540ed74" diff --git a/Gopkg.toml b/Gopkg.toml index e2cd58550039..b49142a3b484 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -49,7 +49,7 @@ [[override]] name = "github.com/tendermint/go-amino" - version = "=v0.12.0-rc0" + version = "=v0.12.0" [[override]] name = "github.com/tendermint/iavl" @@ -57,7 +57,7 @@ [[override]] name = "github.com/tendermint/tendermint" - branch = "develop" + version = "=0.24.0-rc0" [[constraint]] name = "github.com/bartekn/go-bip39" From 06adc691d2333f3fcc6becb9c6b5bc66628a5161 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 00:45:07 +0200 Subject: [PATCH 05/52] Update testcases for TM 0.24.0-rc0 --- PENDING.md | 4 ++++ cmd/gaia/app/app_test.go | 2 +- examples/basecoin/app/app_test.go | 4 ++-- examples/democoin/app/app_test.go | 2 +- store/cachekvstore_test.go | 5 ++-- store/iavlstore_test.go | 8 +++---- x/mock/simulation/random_simulate_blocks.go | 21 +++++++++++++---- x/mock/simulation/types.go | 2 +- x/slashing/tick_test.go | 6 ++--- x/stake/keeper/validator_test.go | 26 ++++++++++----------- x/stake/types/validator.go | 11 ++++++++- x/stake/types/validator_test.go | 6 ++--- 12 files changed, 61 insertions(+), 36 deletions(-) diff --git a/PENDING.md b/PENDING.md index 6ccd96be36e4..1f86ae050d72 100644 --- a/PENDING.md +++ b/PENDING.md @@ -30,6 +30,10 @@ BREAKING CHANGES addresses, `cosmosconspub` and `cosmoscons` respectively. * SDK + * [core] \#2219 Update to Tendermint 0.24.0 + * Validator set updates delayed by one block + * BFT timestamp that can safely be used by applications + * Fixed maximum block size enforcement * [core] \#1807 Switch from use of rational to decimal * [types] \#1901 Validator interface's GetOwner() renamed to GetOperator() * [x/slashing] [#2122](https://github.com/cosmos/cosmos-sdk/pull/2122) - Implement slashing period diff --git a/cmd/gaia/app/app_test.go b/cmd/gaia/app/app_test.go index 63d650cef6ed..dd53f495c005 100644 --- a/cmd/gaia/app/app_test.go +++ b/cmd/gaia/app/app_test.go @@ -31,7 +31,7 @@ func setGenesis(gapp *GaiaApp, accs ...*auth.BaseAccount) error { } // Initialize the chain - vals := []abci.Validator{} + vals := []abci.ValidatorUpdate{} gapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) gapp.Commit() diff --git a/examples/basecoin/app/app_test.go b/examples/basecoin/app/app_test.go index dad8191b356c..1cf74e7f8cd9 100644 --- a/examples/basecoin/app/app_test.go +++ b/examples/basecoin/app/app_test.go @@ -29,7 +29,7 @@ func setGenesis(baseApp *BasecoinApp, accounts ...*types.AppAccount) (types.Gene // initialize and commit the chain baseApp.InitChain(abci.RequestInitChain{ - Validators: []abci.Validator{}, AppStateBytes: stateBytes, + Validators: []abci.ValidatorUpdate{}, AppStateBytes: stateBytes, }) baseApp.Commit() @@ -72,7 +72,7 @@ func TestGenesis(t *testing.T) { // initialize the chain with the expected genesis state baseApp.InitChain(abci.RequestInitChain{ - Validators: []abci.Validator{}, AppStateBytes: stateBytes, + Validators: []abci.ValidatorUpdate{}, AppStateBytes: stateBytes, }) ctx = baseApp.BaseApp.NewContext(true, abci.Header{}) diff --git a/examples/democoin/app/app_test.go b/examples/democoin/app/app_test.go index e964dbad2541..731a21c5fe62 100644 --- a/examples/democoin/app/app_test.go +++ b/examples/democoin/app/app_test.go @@ -33,7 +33,7 @@ func setGenesis(bapp *DemocoinApp, trend string, accs ...auth.BaseAccount) error } // Initialize the chain - vals := []abci.Validator{} + vals := []abci.ValidatorUpdate{} bapp.InitChain(abci.RequestInitChain{Validators: vals, AppStateBytes: stateBytes}) bapp.Commit() diff --git a/store/cachekvstore_test.go b/store/cachekvstore_test.go index e7958dfcdf4c..4c56b9b877b2 100644 --- a/store/cachekvstore_test.go +++ b/store/cachekvstore_test.go @@ -1,6 +1,7 @@ package store import ( + "fmt" "testing" "github.com/stretchr/testify/require" @@ -13,8 +14,8 @@ func newCacheKVStore() CacheKVStore { return NewCacheKVStore(mem) } -func keyFmt(i int) []byte { return bz(cmn.Fmt("key%0.8d", i)) } -func valFmt(i int) []byte { return bz(cmn.Fmt("value%0.8d", i)) } +func keyFmt(i int) []byte { return bz(fmt.Sprintf("key%0.8d", i)) } +func valFmt(i int) []byte { return bz(fmt.Sprintf("value%0.8d", i)) } func TestCacheKVStore(t *testing.T) { mem := dbStoreAdapter{dbm.NewMemDB()} diff --git a/store/iavlstore_test.go b/store/iavlstore_test.go index 49793d376620..1e9263b7bbcf 100644 --- a/store/iavlstore_test.go +++ b/store/iavlstore_test.go @@ -387,12 +387,12 @@ func TestIAVLStoreQuery(t *testing.T) { ksub := []byte("key") KVs0 := []KVPair{} KVs1 := []KVPair{ - {k1, v1}, - {k2, v2}, + {Key: k1, Value: v1}, + {Key: k2, Value: v2}, } KVs2 := []KVPair{ - {k1, v3}, - {k2, v2}, + {Key: k1, Value: v3}, + {Key: k2, Value: v2}, } valExpSubEmpty := cdc.MustMarshalBinary(KVs0) valExpSub1 := cdc.MustMarshalBinary(KVs1) diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index c3e690925e8c..b71200b36af3 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -33,7 +33,12 @@ func initChain(r *rand.Rand, keys []crypto.PrivKey, accs []sdk.AccAddress, setup res := app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, keys, accs)}) validators = make(map[string]mockValidator) for _, validator := range res.Validators { - validators[string(validator.Address)] = mockValidator{validator, GetMemberOfInitialState(r, initialLivenessWeightings)} + pubkey, err := tmtypes.PB2TM.PubKey(validator.PubKey) + if err != nil { + panic(err) + } + address := pubkey.Address() + validators[string(address)] = mockValidator{validator, GetMemberOfInitialState(r, initialLivenessWeightings)} } for i := 0; i < len(setups); i++ { @@ -91,7 +96,7 @@ func SimulateFromSeed( for i := 0; i < numBlocks; i++ { // Log the header time for future lookup pastTimes = append(pastTimes, header.Time) - pastVoteInfos = append(pastVoteInfos, request.LastCommitInfo.Validators) + pastVoteInfos = append(pastVoteInfos, request.LastCommitInfo.Votes) // Run the BeginBlock handler app.BeginBlock(request) @@ -271,8 +276,14 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, } else { event("beginblock/signing/missed") } + pubkey, err := tmtypes.PB2TM.PubKey(mVal.val.PubKey) + if err != nil { + panic(err) + } voteInfos[i] = abci.VoteInfo{ - Validator: mVal.val, + Validator: abci.Validator{ + Address: pubkey.Address(), + }, SignedLastBlock: signed, } i++ @@ -308,7 +319,7 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, return abci.RequestBeginBlock{ Header: header, LastCommitInfo: abci.LastCommitInfo{ - Validators: voteInfos, + Votes: voteInfos, }, ByzantineValidators: evidence, } @@ -323,7 +334,7 @@ func AssertAllInvariants(t *testing.T, app *baseapp.BaseApp, tests []Invariant, // updateValidators mimicks Tendermint's update logic // nolint: unparam -func updateValidators(tb testing.TB, r *rand.Rand, current map[string]mockValidator, updates []abci.Validator, event func(string)) map[string]mockValidator { +func updateValidators(tb testing.TB, r *rand.Rand, current map[string]mockValidator, updates []abci.ValidatorUpdate, event func(string)) map[string]mockValidator { for _, update := range updates { switch { case update.Power == 0: diff --git a/x/mock/simulation/types.go b/x/mock/simulation/types.go index 2f91a4f26376..6f5d1e6da787 100644 --- a/x/mock/simulation/types.go +++ b/x/mock/simulation/types.go @@ -36,7 +36,7 @@ type ( Invariant func(t *testing.T, app *baseapp.BaseApp, log string) mockValidator struct { - val abci.Validator + val abci.ValidatorUpdate livenessState int } diff --git a/x/slashing/tick_test.go b/x/slashing/tick_test.go index 3a8afba9d833..52703d3d9ed3 100644 --- a/x/slashing/tick_test.go +++ b/x/slashing/tick_test.go @@ -32,7 +32,7 @@ func TestBeginBlocker(t *testing.T) { // mark the validator as having signed req := abci.RequestBeginBlock{ LastCommitInfo: abci.LastCommitInfo{ - Validators: []abci.VoteInfo{{ + Votes: []abci.VoteInfo{{ Validator: val, SignedLastBlock: true, }}, @@ -54,7 +54,7 @@ func TestBeginBlocker(t *testing.T) { ctx = ctx.WithBlockHeight(height) req = abci.RequestBeginBlock{ LastCommitInfo: abci.LastCommitInfo{ - Validators: []abci.VoteInfo{{ + Votes: []abci.VoteInfo{{ Validator: val, SignedLastBlock: true, }}, @@ -68,7 +68,7 @@ func TestBeginBlocker(t *testing.T) { ctx = ctx.WithBlockHeight(height) req = abci.RequestBeginBlock{ LastCommitInfo: abci.LastCommitInfo{ - Validators: []abci.VoteInfo{{ + Votes: []abci.VoteInfo{{ Validator: val, SignedLastBlock: false, }}, diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 2f471a2a5e70..8c6cfd071b34 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -47,7 +47,7 @@ func TestSetValidator(t *testing.T) { updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) - require.Equal(t, validator.ABCIValidator(), updates[0]) + require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) } func TestUpdateValidatorByPowerIndex(t *testing.T) { @@ -674,8 +674,8 @@ func TestGetTendermintUpdatesAllNone(t *testing.T) { updates := keeper.GetTendermintUpdates(ctx) assert.Equal(t, 2, len(updates)) - assert.Equal(t, validators[0].ABCIValidator(), updates[0]) - assert.Equal(t, validators[1].ABCIValidator(), updates[1]) + assert.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) // test from something to nothing // tendermintUpdate set: {} -> {c1, c2, c3, c4} @@ -741,7 +741,7 @@ func TestGetTendermintUpdatesSingleValueChange(t *testing.T) { updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) - require.Equal(t, validators[0].ABCIValidator(), updates[0]) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) } func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { @@ -771,8 +771,8 @@ func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates)) - require.Equal(t, validators[0].ABCIValidator(), updates[0]) - require.Equal(t, validators[1].ABCIValidator(), updates[1]) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) } func TestGetTendermintUpdatesInserted(t *testing.T) { @@ -796,7 +796,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) { validators[2] = keeper.UpdateValidator(ctx, validators[2]) updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) - require.Equal(t, validators[2].ABCIValidator(), updates[0]) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) // test validtor added at the beginning // tendermintUpdate set: {} -> {c0} @@ -804,7 +804,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) { validators[3] = keeper.UpdateValidator(ctx, validators[3]) updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) - require.Equal(t, validators[3].ABCIValidator(), updates[0]) + require.Equal(t, validators[3].ABCIValidatorUpdate(), updates[0]) // test validtor added at the end // tendermintUpdate set: {} -> {c0} @@ -812,7 +812,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) { validators[4] = keeper.UpdateValidator(ctx, validators[4]) updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) - require.Equal(t, validators[4].ABCIValidator(), updates[0]) + require.Equal(t, validators[4].ABCIValidatorUpdate(), updates[0]) } func TestGetTendermintUpdatesWithCliffValidator(t *testing.T) { @@ -852,8 +852,8 @@ func TestGetTendermintUpdatesWithCliffValidator(t *testing.T) { updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates), "%v", updates) - require.Equal(t, validators[0].ABCIValidatorZero(), updates[0]) - require.Equal(t, validators[2].ABCIValidator(), updates[1]) + require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[0]) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[1]) } func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { @@ -892,6 +892,6 @@ func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { // Tendermint updates should reflect power change updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates)) - require.Equal(t, validators[0].ABCIValidator(), updates[0]) - require.Equal(t, validators[1].ABCIValidator(), updates[1]) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) } diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index d7c0bdb65bd5..540798e2bf2a 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -317,8 +317,17 @@ func (v Validator) ABCIValidator() abci.Validator { } } +// ABCIValidatorUpdate returns an abci.ValidatorUpdate from a staked validator type +// with the full validator power +func (v Validator) ABCIValidatorUpdate() abci.ValidatorUpdate { + return abci.ValidatorUpdate{ + PubKey: tmtypes.TM2PB.PubKey(v.PubKey), + Power: v.BondedTokens().RoundInt64(), + } +} + // ABCIValidatorUpdateZero returns an abci.ValidatorUpdate from a staked validator type -// with with zero power used for validator updates. +// with zero power used for validator updates. func (v Validator) ABCIValidatorUpdateZero() abci.ValidatorUpdate { return abci.ValidatorUpdate{ PubKey: tmtypes.TM2PB.PubKey(v.PubKey), diff --git a/x/stake/types/validator_test.go b/x/stake/types/validator_test.go index b81ae4458589..84e0ba7bb9ba 100644 --- a/x/stake/types/validator_test.go +++ b/x/stake/types/validator_test.go @@ -57,14 +57,14 @@ func TestABCIValidator(t *testing.T) { validator := NewValidator(addr1, pk1, Description{}) abciVal := validator.ABCIValidator() - require.Equal(t, tmtypes.TM2PB.PubKey(validator.PubKey), abciVal.PubKey) + require.Equal(t, addr1, sdk.ValAddress(abciVal.Address)) require.Equal(t, validator.BondedTokens().RoundInt64(), abciVal.Power) } -func TestABCIValidatorZero(t *testing.T) { +func TestABCIValidatorUpdateZero(t *testing.T) { validator := NewValidator(addr1, pk1, Description{}) - abciVal := validator.ABCIValidatorZero() + abciVal := validator.ABCIValidatorUpdateZero() require.Equal(t, tmtypes.TM2PB.PubKey(validator.PubKey), abciVal.PubKey) require.Equal(t, int64(0), abciVal.Power) } From c667c5690a1691fce991092c584caa398efc6f51 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 00:47:37 +0200 Subject: [PATCH 06/52] More testcase fixes --- crypto/encode_test.go | 1 + x/stake/genesis_test.go | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/crypto/encode_test.go b/crypto/encode_test.go index 9e70978555dc..aef8d8e32b8d 100644 --- a/crypto/encode_test.go +++ b/crypto/encode_test.go @@ -55,6 +55,7 @@ func ExamplePrintRegisteredTypes() { //| PrivKeyLedgerSecp256k1 | tendermint/PrivKeyLedgerSecp256k1 | 0x10CAB393 | variable | | //| PubKeyEd25519 | tendermint/PubKeyEd25519 | 0x1624DE64 | 0x20 | | //| PubKeySecp256k1 | tendermint/PubKeySecp256k1 | 0xEB5AE987 | 0x21 | | + //| PubKeyMultisigThreshold | tendermint/PubKeyMultisigThreshold | 0x22C1F7E2 | variable | | //| PrivKeyEd25519 | tendermint/PrivKeyEd25519 | 0xA3288910 | 0x40 | | //| PrivKeySecp256k1 | tendermint/PrivKeySecp256k1 | 0xE1B0F79B | 0x20 | | } diff --git a/x/stake/genesis_test.go b/x/stake/genesis_test.go index ddd29f6f8498..aa7b1ad69254 100644 --- a/x/stake/genesis_test.go +++ b/x/stake/genesis_test.go @@ -53,9 +53,9 @@ func TestInitGenesis(t *testing.T) { require.Equal(t, sdk.Bonded, resVal.Status) require.Equal(t, int16(1), resVal.BondIntraTxCounter) - abcivals := make([]abci.Validator, len(vals)) + abcivals := make([]abci.ValidatorUpdate, len(vals)) for i, val := range validators { - abcivals[i] = sdk.ABCIValidator(val) + abcivals[i] = sdk.ABCIValidatorUpdate(val) } require.Equal(t, abcivals, vals) @@ -92,9 +92,9 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { vals, err := InitGenesis(ctx, keeper, genesisState) require.NoError(t, err) - abcivals := make([]abci.Validator, 100) + abcivals := make([]abci.ValidatorUpdate, 100) for i, val := range validators[:100] { - abcivals[i] = sdk.ABCIValidator(val) + abcivals[i] = sdk.ABCIValidatorUpdate(val) } require.Equal(t, abcivals, vals) From 1f5fe29c257385631988ada9087b6e5352553e77 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 00:52:44 +0200 Subject: [PATCH 07/52] Ignore Go src in linter --- Makefile | 2 +- tools/gometalinter.json | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 2f23fd54fe2b..51a1a46e2345 100644 --- a/Makefile +++ b/Makefile @@ -179,7 +179,7 @@ test_cover: test_lint: gometalinter.v2 --config=tools/gometalinter.json ./... - !(gometalinter.v2 --disable-all --enable='errcheck' --vendor ./... | grep -v "client/") + !(gometalinter.v2 --exclude /usr/lib/go/src/ --disable-all --enable='errcheck' --vendor ./... | grep -v "client/") find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" | xargs gofmt -d -s dep status >> /dev/null !(grep -n branch Gopkg.toml) diff --git a/tools/gometalinter.json b/tools/gometalinter.json index 42788714bf83..a7b9ab517575 100644 --- a/tools/gometalinter.json +++ b/tools/gometalinter.json @@ -5,5 +5,6 @@ "Enable": ["golint", "vet", "ineffassign", "unparam", "unconvert", "misspell"], "Deadline": "500s", "Vendor": true, - "Cyclo": 11 -} \ No newline at end of file + "Cyclo": 11, + "Exclude": ["/usr/lib/go/src/"] +} From dd75cd3049ca3d29a5b4873d28c49fd7cb7f7d17 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 01:00:06 +0200 Subject: [PATCH 08/52] Minor cleanup --- types/stake.go | 18 ------------------ x/stake/genesis.go | 2 +- x/stake/genesis_test.go | 4 ++-- x/stake/keeper/validator.go | 6 +++--- x/stake/types/validator.go | 8 -------- x/stake/types/validator_test.go | 6 +++--- 6 files changed, 9 insertions(+), 35 deletions(-) diff --git a/types/stake.go b/types/stake.go index 84f98f9cb548..1e37da0478e9 100644 --- a/types/stake.go +++ b/types/stake.go @@ -1,9 +1,7 @@ package types import ( - abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" - tmtypes "github.com/tendermint/tendermint/types" ) // status of a validator @@ -48,22 +46,6 @@ type Validator interface { GetBondHeight() int64 // height in which the validator became active } -// validator which fulfills abci validator interface for use in Tendermint -func ABCIValidator(v Validator) abci.Validator { - return abci.Validator{ - Address: v.GetPubKey().Address(), - Power: v.GetPower().RoundInt64(), - } -} - -// validator which fulfills abci validator update interface for use in Tendermint -func ABCIValidatorUpdate(v Validator) abci.ValidatorUpdate { - return abci.ValidatorUpdate{ - PubKey: tmtypes.TM2PB.PubKey(v.GetPubKey()), - Power: v.GetPower().RoundInt64(), - } -} - // properties for the set of all validators type ValidatorSet interface { // iterate through validator by owner-AccAddress, execute func for each validator diff --git a/x/stake/genesis.go b/x/stake/genesis.go index ff41a73bf5bb..13f2bec04d48 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -49,7 +49,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ vals := keeper.GetValidatorsBonded(ctx) res = make([]abci.ValidatorUpdate, len(vals)) for i, val := range vals { - res[i] = sdk.ABCIValidatorUpdate(val) + res[i] = val.ABCIValidatorUpdate() } return } diff --git a/x/stake/genesis_test.go b/x/stake/genesis_test.go index aa7b1ad69254..6460c35e0818 100644 --- a/x/stake/genesis_test.go +++ b/x/stake/genesis_test.go @@ -55,7 +55,7 @@ func TestInitGenesis(t *testing.T) { abcivals := make([]abci.ValidatorUpdate, len(vals)) for i, val := range validators { - abcivals[i] = sdk.ABCIValidatorUpdate(val) + abcivals[i] = val.ABCIValidatorUpdate() } require.Equal(t, abcivals, vals) @@ -94,7 +94,7 @@ func TestInitGenesisLargeValidatorSet(t *testing.T) { abcivals := make([]abci.ValidatorUpdate, 100) for i, val := range validators[:100] { - abcivals[i] = sdk.ABCIValidatorUpdate(val) + abcivals[i] = val.ABCIValidatorUpdate() } require.Equal(t, abcivals, vals) diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index d9a9c5faef58..957fb845d80e 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -256,7 +256,7 @@ func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) type case powerIncreasing && !validator.Jailed && (oldFound && oldValidator.Status == sdk.Bonded): - bz := k.cdc.MustMarshalBinary(sdk.ABCIValidatorUpdate(validator)) + bz := k.cdc.MustMarshalBinary(validator.ABCIValidatorUpdate()) store.Set(GetTendermintUpdatesKey(validator.Operator), bz) if cliffPower != nil { @@ -292,7 +292,7 @@ func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) type // if decreased in power but still bonded, update Tendermint validator if oldFound && oldValidator.BondedTokens().GT(validator.BondedTokens()) { - bz := k.cdc.MustMarshalBinary(sdk.ABCIValidatorUpdate(validator)) + bz := k.cdc.MustMarshalBinary(validator.ABCIValidatorUpdate()) store.Set(GetTendermintUpdatesKey(validator.Operator), bz) } } @@ -671,7 +671,7 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. store.Set(GetValidatorsBondedIndexKey(validator.Operator), []byte{}) // add to accumulated changes for tendermint - bzABCI := k.cdc.MustMarshalBinary(sdk.ABCIValidatorUpdate(validator)) + bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidatorUpdate()) store.Set(GetTendermintUpdatesKey(validator.Operator), bzABCI) // call the bond hook if present diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index 540798e2bf2a..4359abb3f0ec 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -309,14 +309,6 @@ func (d Description) EnsureLength() (Description, sdk.Error) { return d, nil } -// ABCIValidator returns an abci.Validator from a staked validator type. -func (v Validator) ABCIValidator() abci.Validator { - return abci.Validator{ - Address: v.PubKey.Address(), - Power: v.BondedTokens().RoundInt64(), - } -} - // ABCIValidatorUpdate returns an abci.ValidatorUpdate from a staked validator type // with the full validator power func (v Validator) ABCIValidatorUpdate() abci.ValidatorUpdate { diff --git a/x/stake/types/validator_test.go b/x/stake/types/validator_test.go index 84e0ba7bb9ba..be5d331320ce 100644 --- a/x/stake/types/validator_test.go +++ b/x/stake/types/validator_test.go @@ -53,11 +53,11 @@ func TestUpdateDescription(t *testing.T) { require.Equal(t, d, d3) } -func TestABCIValidator(t *testing.T) { +func TestABCIValidatorUpdate(t *testing.T) { validator := NewValidator(addr1, pk1, Description{}) - abciVal := validator.ABCIValidator() - require.Equal(t, addr1, sdk.ValAddress(abciVal.Address)) + abciVal := validator.ABCIValidatorUpdate() + require.Equal(t, tmtypes.TM2PB.PubKey(pk1), abciVal.PubKey) require.Equal(t, validator.BondedTokens().RoundInt64(), abciVal.Power) } From e013b9fc7d46f054079bd2d476a17cc0449f3405 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 01:07:29 +0200 Subject: [PATCH 09/52] Check errors --- crypto/keys/keybase.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/crypto/keys/keybase.go b/crypto/keys/keybase.go index ec5b7b0fda89..8f9bd19be897 100644 --- a/crypto/keys/keybase.go +++ b/crypto/keys/keybase.go @@ -224,9 +224,15 @@ func (kb dbKeybase) Sign(name, passphrase string, msg []byte) (sig []byte, pub t } case offlineInfo: linfo := info.(offlineInfo) - fmt.Fprintf(os.Stderr, "Bytes to sign:\n%s", msg) + _, err = fmt.Fprintf(os.Stderr, "Bytes to sign:\n%s", msg) + if err != nil { + panic(err) + } buf := bufio.NewReader(os.Stdin) - fmt.Fprintf(os.Stderr, "\nEnter Amino-encoded signature:\n") + _, err = fmt.Fprintf(os.Stderr, "\nEnter Amino-encoded signature:\n") + if err != nil { + panic(err) + } // Will block until user inputs the signature signed, err := buf.ReadString('\n') if err != nil { From 9dd430386d892e823cfd11e068c54d3415886d16 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 16:18:32 +0200 Subject: [PATCH 10/52] Pin final release --- Gopkg.lock | 21 +++++++++++---------- Gopkg.toml | 2 +- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 7da07e4c2b2d..ee5481301efa 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -164,12 +164,13 @@ version = "v1.2.0" [[projects]] - digest = "1:ea40c24cdbacd054a6ae9de03e62c5f252479b96c716375aace5c120d68647c8" + digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10" name = "github.com/hashicorp/hcl" packages = [ ".", "hcl/ast", "hcl/parser", + "hcl/printer", "hcl/scanner", "hcl/strconv", "hcl/token", @@ -312,15 +313,15 @@ revision = "e2704e165165ec55d062f5919b4b29494e9fa790" [[projects]] - digest = "1:bd1ae00087d17c5a748660b8e89e1043e1e5479d0fea743352cda2f8dd8c4f84" + digest = "1:6a4a11ba764a56d2758899ec6f3848d24698d48442ebce85ee7a3f63284526cd" name = "github.com/spf13/afero" packages = [ ".", "mem", ] pruneopts = "UT" - revision = "787d034dfe70e44075ccc060d346146ef53270ad" - version = "v1.1.1" + revision = "d40851caa0d747393da1ffb28f7f9d8b4eeffebd" + version = "v1.1.2" [[projects]] digest = "1:516e71bed754268937f57d4ecb190e01958452336fa73dbac880894164e91c1f" @@ -339,12 +340,12 @@ version = "v0.0.1" [[projects]] - branch = "master" - digest = "1:8a020f916b23ff574845789daee6818daf8d25a4852419aae3f0b12378ba432a" + digest = "1:68ea4e23713989dc20b1bded5d9da2c5f9be14ff9885beef481848edd18c26cb" name = "github.com/spf13/jwalterweatherman" packages = ["."] pruneopts = "UT" - revision = "14d3d4c518341bea657dd8a226f5121c0ff8c9f2" + revision = "4a4406e478ca629068e7768fc33f3f044173c0a6" + version = "v1.0.0" [[projects]] digest = "1:dab83a1bbc7ad3d7a6ba1a1cc1760f25ac38cdf7d96a5cdd55cd915a4f5ceaf9" @@ -430,7 +431,7 @@ version = "v0.10.0" [[projects]] - digest = "1:1b603d279b678be4efda149a1c6b03e23c0409f796513e0f858cfd4b3bd4f20a" + digest = "1:f4fcc1a4dbe079b200556ca26c1ff1dacf23712125b9c265d8f02c0dbc318f39" name = "github.com/tendermint/tendermint" packages = [ "abci/client", @@ -495,8 +496,8 @@ "version", ] pruneopts = "UT" - revision = "604eae86b66282185e2a3a5906031f1df223b779" - version = "v0.24.0-rc0" + revision = "d419fffe18531317c28c29a292ad7d253f6cafdf" + version = "v0.24.0" [[projects]] digest = "1:bf6d9a827ea3cad964c2f863302e4f6823170d0b5ed16f72cf1184a7c615067e" diff --git a/Gopkg.toml b/Gopkg.toml index b49142a3b484..a0aeb869fb69 100644 --- a/Gopkg.toml +++ b/Gopkg.toml @@ -57,7 +57,7 @@ [[override]] name = "github.com/tendermint/tendermint" - version = "=0.24.0-rc0" + version = "=0.24.0" [[constraint]] name = "github.com/bartekn/go-bip39" From d85eb987626f586158fdf582682819fe261efcdb Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Sat, 8 Sep 2018 17:46:08 +0800 Subject: [PATCH 11/52] make format --- x/stake/types/validator_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/x/stake/types/validator_test.go b/x/stake/types/validator_test.go index cd2e497b05a2..31b8a03c00f7 100644 --- a/x/stake/types/validator_test.go +++ b/x/stake/types/validator_test.go @@ -64,7 +64,6 @@ func TestABCIValidatorUpdate(t *testing.T) { func TestABCIValidatorUpdateZero(t *testing.T) { validator := NewValidator(addr1, pk1, Description{}) - abciVal := validator.ABCIValidatorUpdateZero() require.Equal(t, tmtypes.TM2PB.PubKey(validator.ConsPubKey), abciVal.PubKey) require.Equal(t, int64(0), abciVal.Power) From 19080d0733fc1fa2684675c617be65453cb8e771 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 25 Sep 2018 00:13:29 -0400 Subject: [PATCH 12/52] pulling in issue code --- x/stake/keeper/_store.md | 6 ---- x/stake/keeper/key.go | 10 +----- x/stake/keeper/validator.go | 72 ++++++++++++++++++++++++------------- 3 files changed, 48 insertions(+), 40 deletions(-) diff --git a/x/stake/keeper/_store.md b/x/stake/keeper/_store.md index 5c070b9e0930..d569389417c3 100644 --- a/x/stake/keeper/_store.md +++ b/x/stake/keeper/_store.md @@ -41,9 +41,3 @@ prefixed areas of the staking store which are accessed in `x/stake/keeper.go`. The transient store persists between transations but not between blocks -## Tendermint Updates - - Prefix Key Space: TendermintUpdatesTKey - - Key/Sort: Validator Operator Address - - Value: Tendermint ABCI Validator - - Contains: Validators are queued to affect the consensus validation set in Tendermint - - Used For: Informing Tendermint of the validator set updates diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index c445e255246e..370fb8d305bd 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -30,8 +30,7 @@ var ( RedelegationByValSrcIndexKey = []byte{0x0D} // prefix for each key for an redelegation, by source validator operator RedelegationByValDstIndexKey = []byte{0x0E} // prefix for each key for an redelegation, by destination validator operator - // Keys for store prefixes (transient) - TendermintUpdatesTKey = []byte{0x00} // prefix for each key to a validator which is being updated + // XXX remove this comment? Keys for store prefixes (transient) ) const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch @@ -97,13 +96,6 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte { counterBytes...) } -// get the key for the accumulated update validators -// VALUE: abci.Validator -// note records using these keys should never persist between blocks -func GetTendermintUpdatesTKey(operatorAddr sdk.ValAddress) []byte { - return append(TendermintUpdatesTKey, operatorAddr.Bytes()...) -} - //______________________________________________________________________________ // gets the key for delegator bond with validator diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index de4c4a187c80..29f1250af8be 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -8,6 +8,7 @@ import ( abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" + "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" ) @@ -195,38 +196,59 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []types.Validator { // at the previous block height or were removed from the validator set entirely // are returned to Tendermint. func (k Keeper) GetValidTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) { - tstore := ctx.TransientStore(k.storeTKey) - - iterator := sdk.KVStorePrefixIterator(tstore, TendermintUpdatesTKey) - defer iterator.Close() - - for ; iterator.Valid(); iterator.Next() { - var abciVal abci.Validator - - abciValBytes := iterator.Value() - k.cdc.MustUnmarshalBinary(abciValBytes, &abciVal) - val, found := k.GetValidator(ctx, abciVal.GetAddress()) - if found { - // The validator is new or already exists in the store and must adhere to - // Tendermint invariants. - prevBonded := val.BondHeight < ctx.BlockHeight() && val.BondHeight > val.UnbondingHeight - zeroPower := val.GetPower().Equal(sdk.ZeroDec()) - - if !zeroPower || zeroPower && prevBonded { - updates = append(updates, abciVal) + last := fetchOldValidatorSet() + tendermintUpdates := make(map[sdk.ValAddress]uint64) + + for _, validator := range topvalidator { //(iterate(top hundred)) { + switch validator.State { + case Unbonded: + unbondedToBonded(ctx, validator.Addr) + tendermintUpdates[validator.Addr] = validator.Power + case Unbonding: + unbondingToBonded(ctx, validator.Addr) + tendermintUpdates[validator.Addr] = validator.Power + case Bonded: // do nothing + store.delete(last[validator.Addr]) + // jailed validators are ranked last, so if we get to a jailed validator + // we have no more bonded validators + if validator.Jailed { + break } - } else { - // Add the ABCI validator in such a case where the validator was removed - // from the store as it must have existed before. - updates = append(updates, abciVal) } } - return + + for _, validator := range previousValidators { + bondedToUnbonding(ctx, validator.Addr) + tendermintUpdates[validator.Addr] = 0 + } + + return tendermintUpdates } //___________________________________________________________________________ +func (ctx sdk.Context, addr sdk.ValAddress) bondedToUnbonding() { + // perform appropriate store updates +} + +func (ctx sdk.Context, addr sdk.ValAddress) unbondingToBonded() { + // perform appropriate store updates +} + +func (ctx sdk.Context, addr sdk.ValAddress) unbondedToBonded() { + // perform appropriate store updates +} + +func (ctx sdk.Context, addr sdk.ValAddress) unbondingToUnbonded() { + // perform appropriate store updates +} + +func (ctx sdk.Context, addr sdk.ValAddress) jailValidator() { + // perform appropriate store updates +} + +// XXX delete // Perform all the necessary steps for when a validator changes its power. This // function updates all validator stores as well as tendermint update store. // It may kick out validators if a new validator is entering the bonded validator @@ -234,7 +256,7 @@ func (k Keeper) GetValidTendermintUpdates(ctx sdk.Context) (updates []abci.Valid // // nolint: gocyclo // TODO: Remove above nolint, function needs to be simplified! -func (k Keeper) UpdateValidator(ctx sdk.Context, validator types.Validator) types.Validator { +func (k Keeper) REFERENCEXXXDELETEUpdateValidator(ctx sdk.Context, validator types.Validator) types.Validator { tstore := ctx.TransientStore(k.storeTKey) pool := k.GetPool(ctx) oldValidator, oldFound := k.GetValidator(ctx, validator.OperatorAddr) From 1aa65e4eaa92d194e172a954d58c724f3c814c99 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 25 Sep 2018 20:34:40 -0400 Subject: [PATCH 13/52] replace ensureValidatorFound with mustGetValidator --- x/stake/keeper/validator.go | 70 ++++++++++--------------------------- 1 file changed, 19 insertions(+), 51 deletions(-) diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 464e96d61f2e..37dfa67db9e3 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -58,6 +58,14 @@ func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator ty return validator, true } +func (k Keeper) mustGetValidator(ctx sdk.Context, addr sdk.ValAddress) types.Validator { + validator, found := GetValidator(ctx, addr) + if !found { + panic(fmt.Sprintf("validator record not found for address: %X\n", ownerAddr)) + } + return validator +} + // get a single validator by consensus address func (k Keeper) GetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) (validator types.Validator, found bool) { store := ctx.KVStore(k.storeKey) @@ -153,8 +161,7 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validat panic("maxValidators is less than the number of records in ValidatorsBonded Store, store should have been updated") } address := GetAddressFromValBondedIndexKey(iterator.Key()) - validator, found := k.GetValidator(ctx, address) - ensureValidatorFound(found, address) + validator := k.mustGetValidator(ctx, address) validators[i] = validator i++ @@ -176,8 +183,7 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []types.Validator { i := 0 for ; iterator.Valid() && i < int(maxValidators); iterator.Next() { address := iterator.Value() - validator, found := k.GetValidator(ctx, address) - ensureValidatorFound(found, address) + validator := k.mustGetValidator(ctx, address) if validator.Status == sdk.Bonded { validators[i] = validator @@ -227,6 +233,7 @@ func (k Keeper) GetValidTendermintUpdates(ctx sdk.Context) (updates []abci.Valid } //___________________________________________________________________________ +// State transitions func (ctx sdk.Context, addr sdk.ValAddress) bondedToUnbonding() { // perform appropriate store updates @@ -248,7 +255,7 @@ func (ctx sdk.Context, addr sdk.ValAddress) jailValidator() { // perform appropriate store updates } -// XXX delete +// XXX Delete this reference function before merge // Perform all the necessary steps for when a validator changes its power. This // function updates all validator stores as well as tendermint update store. // It may kick out validators if a new validator is entering the bonded validator @@ -349,8 +356,7 @@ func (k Keeper) updateCliffValidator(ctx sdk.Context, affectedVal types.Validato if iterator.Valid() { ownerAddr := iterator.Value() - currVal, found := k.GetValidator(ctx, ownerAddr) - ensureValidatorFound(found, ownerAddr) + currVal := k.mustGetValidator(ctx, ownerAddr) if currVal.Status != sdk.Bonded || currVal.Jailed { panic(fmt.Sprintf("unexpected jailed or unbonded validator for address: %X\n", ownerAddr)) @@ -432,6 +438,7 @@ func (k Keeper) updateValidatorPower(ctx sdk.Context, oldFound bool, oldValidato return valPower } +// XXX Delete this reference function before merge // Update the bonded validator group based on a change to the validator // affectedValidator. This function potentially adds the affectedValidator to // the bonded validator group which kicks out the cliff validator. Under this @@ -443,7 +450,7 @@ func (k Keeper) updateValidatorPower(ctx sdk.Context, oldFound bool, oldValidato // updated in store with the ValidatorsBondedIndexKey. This store is used to // determine if a validator is a validator without needing to iterate over all // validators. -func (k Keeper) UpdateBondedValidators( +func (k Keeper) XXXREFERENCEUpdateBondedValidators( ctx sdk.Context, affectedValidator types.Validator) ( updatedVal types.Validator, updated bool) { @@ -467,8 +474,7 @@ func (k Keeper) UpdateBondedValidators( validator = affectedValidator } else { var found bool - validator, found = k.GetValidator(ctx, ownerAddr) - ensureValidatorFound(found, ownerAddr) + validator = k.mustGetValidator(ctx, ownerAddr) } // if we've reached jailed validators no further bonded validators exist @@ -510,8 +516,7 @@ func (k Keeper) UpdateBondedValidators( // was bonded if newValidatorBonded { if oldCliffValidatorAddr != nil { - oldCliffVal, found := k.GetValidator(ctx, oldCliffValidatorAddr) - ensureValidatorFound(found, oldCliffValidatorAddr) + oldCliffVal := k.mustGetValidator(ctx, oldCliffValidatorAddr) if bytes.Equal(validatorToBond.OperatorAddr, affectedValidator.OperatorAddr) { @@ -561,8 +566,7 @@ func (k Keeper) UpdateBondedValidatorsFull(ctx sdk.Context) { var found bool ownerAddr := iterator.Value() - validator, found = k.GetValidator(ctx, ownerAddr) - ensureValidatorFound(found, ownerAddr) + validator = k.mustGetValidator(ctx, ownerAddr) _, found = toKickOut[string(ownerAddr)] if found { @@ -602,8 +606,7 @@ func (k Keeper) UpdateBondedValidatorsFull(ctx sdk.Context) { func kickOutValidators(k Keeper, ctx sdk.Context, toKickOut map[string]byte) { for key := range toKickOut { ownerAddr := []byte(key) - validator, found := k.GetValidator(ctx, ownerAddr) - ensureValidatorFound(found, ownerAddr) + validator := k.mustGetValidator(ctx, ownerAddr) k.beginUnbondingValidator(ctx, validator) } } @@ -727,38 +730,3 @@ func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Valid k.SetValidator(ctx, validator) return nil } - -//__________________________________________________________________________ - -// get the current validator on the cliff -func (k Keeper) GetCliffValidator(ctx sdk.Context) []byte { - store := ctx.KVStore(k.storeKey) - return store.Get(ValidatorCliffIndexKey) -} - -// get the current power of the validator on the cliff -func (k Keeper) GetCliffValidatorPower(ctx sdk.Context) []byte { - store := ctx.KVStore(k.storeKey) - return store.Get(ValidatorPowerCliffKey) -} - -// set the current validator and power of the validator on the cliff -func (k Keeper) setCliffValidator(ctx sdk.Context, validator types.Validator, pool types.Pool) { - store := ctx.KVStore(k.storeKey) - bz := GetValidatorsByPowerIndexKey(validator, pool) - store.Set(ValidatorPowerCliffKey, bz) - store.Set(ValidatorCliffIndexKey, validator.OperatorAddr) -} - -// clear the current validator and power of the validator on the cliff -func (k Keeper) clearCliffValidator(ctx sdk.Context) { - store := ctx.KVStore(k.storeKey) - store.Delete(ValidatorPowerCliffKey) - store.Delete(ValidatorCliffIndexKey) -} - -func ensureValidatorFound(found bool, ownerAddr []byte) { - if !found { - panic(fmt.Sprintf("validator record not found for address: %X\n", ownerAddr)) - } -} From 8d394f6360052f10d4673c5446428f85e9883819 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Tue, 25 Sep 2018 20:43:53 -0400 Subject: [PATCH 14/52] split up keeper/validator.go --- x/stake/keeper/val_state_change.go | 453 +++++++++++++++++++++++++ x/stake/keeper/validator.go | 517 +---------------------------- 2 files changed, 463 insertions(+), 507 deletions(-) create mode 100644 x/stake/keeper/val_state_change.go diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go new file mode 100644 index 000000000000..39719cf6d213 --- /dev/null +++ b/x/stake/keeper/val_state_change.go @@ -0,0 +1,453 @@ +package keeper + +import ( + "bytes" + "fmt" + + abci "github.com/tendermint/tendermint/abci/types" + + "github.com/cosmos/cosmos-sdk/store" + sdk "github.com/cosmos/cosmos-sdk/types" + "github.com/cosmos/cosmos-sdk/x/stake/types" +) + +//_________________________________________________________________________ +// Accumulated updates to the active/bonded validator set for tendermint + +// get the most recently updated validators +// +// CONTRACT: Only validators with non-zero power or zero-power that were bonded +// at the previous block height or were removed from the validator set entirely +// are returned to Tendermint. +func (k Keeper) GetValidTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) { + + last := fetchOldValidatorSet() + tendermintUpdates := make(map[sdk.ValAddress]uint64) + + for _, validator := range topvalidator { //(iterate(top hundred)) { + switch validator.State { + case Unbonded: + unbondedToBonded(ctx, validator.Addr) + tendermintUpdates[validator.Addr] = validator.Power + case Unbonding: + unbondingToBonded(ctx, validator.Addr) + tendermintUpdates[validator.Addr] = validator.Power + case Bonded: // do nothing + store.delete(last[validator.Addr]) + // jailed validators are ranked last, so if we get to a jailed validator + // we have no more bonded validators + if validator.Jailed { + break + } + } + } + + for _, validator := range previousValidators { + bondedToUnbonding(ctx, validator.Addr) + tendermintUpdates[validator.Addr] = 0 + } + + return tendermintUpdates +} + +//___________________________________________________________________________ +// State transitions + +func (ctx sdk.Context, addr sdk.ValAddress) bondedToUnbonding() { + // perform appropriate store updates +} + +func (ctx sdk.Context, addr sdk.ValAddress) unbondingToBonded() { + // perform appropriate store updates +} + +func (ctx sdk.Context, addr sdk.ValAddress) unbondedToBonded() { + // perform appropriate store updates +} + +func (ctx sdk.Context, addr sdk.ValAddress) unbondingToUnbonded() { + // perform appropriate store updates +} + +func (ctx sdk.Context, addr sdk.ValAddress) jailValidator() { + // perform appropriate store updates +} + +// XXX Delete this reference function before merge +// Perform all the necessary steps for when a validator changes its power. This +// function updates all validator stores as well as tendermint update store. +// It may kick out validators if a new validator is entering the bonded validator +// group. +// +// TODO: Remove above nolint, function needs to be simplified! +func (k Keeper) REFERENCEXXXDELETEUpdateValidator(ctx sdk.Context, validator types.Validator) types.Validator { + tstore := ctx.TransientStore(k.storeTKey) + pool := k.GetPool(ctx) + oldValidator, oldFound := k.GetValidator(ctx, validator.OperatorAddr) + + validator = k.updateForJailing(ctx, oldFound, oldValidator, validator) + powerIncreasing := k.getPowerIncreasing(ctx, oldFound, oldValidator, validator) + validator.BondHeight, validator.BondIntraTxCounter = k.bondIncrement(ctx, oldFound, oldValidator) + valPower := k.updateValidatorPower(ctx, oldFound, oldValidator, validator, pool) + cliffPower := k.GetCliffValidatorPower(ctx) + cliffValExists := (cliffPower != nil) + var valPowerLTcliffPower bool + if cliffValExists { + valPowerLTcliffPower = (bytes.Compare(valPower, cliffPower) == -1) + } + + switch { + + // if the validator is already bonded and the power is increasing, we need + // perform the following: + // a) update Tendermint + // b) check if the cliff validator needs to be updated + case powerIncreasing && !validator.Jailed && + (oldFound && oldValidator.Status == sdk.Bonded): + + bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) + tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bz) + + if cliffValExists { + cliffAddr := sdk.ValAddress(k.GetCliffValidator(ctx)) + if bytes.Equal(cliffAddr, validator.OperatorAddr) { + k.updateCliffValidator(ctx, validator) + } + } + + // if is a new validator and the new power is less than the cliff validator + case cliffValExists && !oldFound && valPowerLTcliffPower: + // skip to completion + + // if was unbonded and the new power is less than the cliff validator + case cliffValExists && + (oldFound && oldValidator.Status == sdk.Unbonded) && + valPowerLTcliffPower: //(valPower < cliffPower + // skip to completion + + default: + // default case - validator was either: + // a) not-bonded and now has power-rank greater than cliff validator + // b) bonded and now has decreased in power + + // update the validator set for this validator + updatedVal, updated := k.UpdateBondedValidators(ctx, validator) + if updated { + // the validator has changed bonding status + validator = updatedVal + break + } + + // if decreased in power but still bonded, update Tendermint validator + if oldFound && oldValidator.BondedTokens().GT(validator.BondedTokens()) { + bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) + tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bz) + } + } + + k.SetValidator(ctx, validator) + return validator +} + +func (k Keeper) updateForJailing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) types.Validator { + if newValidator.Jailed && oldFound && oldValidator.Status == sdk.Bonded { + newValidator = k.beginUnbondingValidator(ctx, newValidator) + + // need to also clear the cliff validator spot because the jail has + // opened up a new spot which will be filled when + // updateValidatorsBonded is called + k.clearCliffValidator(ctx) + } + return newValidator +} + +// nolint: unparam +func (k Keeper) getPowerIncreasing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) bool { + if oldFound && oldValidator.BondedTokens().LT(newValidator.BondedTokens()) { + return true + } + return false +} + +// get the bond height and incremented intra-tx counter +// nolint: unparam +func (k Keeper) bondIncrement( + ctx sdk.Context, found bool, oldValidator types.Validator) (height int64, intraTxCounter int16) { + + // if already a validator, copy the old block height and counter + if found && oldValidator.Status == sdk.Bonded { + height = oldValidator.BondHeight + intraTxCounter = oldValidator.BondIntraTxCounter + return + } + + height = ctx.BlockHeight() + counter := k.GetIntraTxCounter(ctx) + intraTxCounter = counter + + k.SetIntraTxCounter(ctx, counter+1) + return +} + +func (k Keeper) updateValidatorPower(ctx sdk.Context, oldFound bool, oldValidator, + newValidator types.Validator, pool types.Pool) (valPower []byte) { + store := ctx.KVStore(k.storeKey) + + // update the list ordered by voting power + if oldFound { + store.Delete(GetValidatorsByPowerIndexKey(oldValidator, pool)) + } + valPower = GetValidatorsByPowerIndexKey(newValidator, pool) + store.Set(valPower, newValidator.OperatorAddr) + + return valPower +} + +// XXX Delete this reference function before merge +// Update the bonded validator group based on a change to the validator +// affectedValidator. This function potentially adds the affectedValidator to +// the bonded validator group which kicks out the cliff validator. Under this +// situation this function returns the updated affectedValidator. +// +// The correct bonded subset of validators is retrieved by iterating through an +// index of the validators sorted by power, stored using the +// ValidatorsByPowerIndexKey. Simultaneously the current validator records are +// updated in store with the ValidatorsBondedIndexKey. This store is used to +// determine if a validator is a validator without needing to iterate over all +// validators. +func (k Keeper) XXXREFERENCEUpdateBondedValidators( + ctx sdk.Context, affectedValidator types.Validator) ( + updatedVal types.Validator, updated bool) { + + store := ctx.KVStore(k.storeKey) + + oldCliffValidatorAddr := k.GetCliffValidator(ctx) + maxValidators := k.GetParams(ctx).MaxValidators + bondedValidatorsCount := 0 + var validator, validatorToBond types.Validator + newValidatorBonded := false + + // create a validator iterator ranging from largest to smallest by power + iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) + for ; iterator.Valid() && bondedValidatorsCount < int(maxValidators); iterator.Next() { + + // either retrieve the original validator from the store, or under the + // situation that this is the "affected validator" just use the + // validator provided because it has not yet been updated in the store + ownerAddr := iterator.Value() + if bytes.Equal(ownerAddr, affectedValidator.OperatorAddr) { + validator = affectedValidator + } else { + var found bool + validator = k.mustGetValidator(ctx, ownerAddr) + } + + // if we've reached jailed validators no further bonded validators exist + if validator.Jailed { + if validator.Status == sdk.Bonded { + panic(fmt.Sprintf("jailed validator cannot be bonded, address: %X\n", ownerAddr)) + } + + break + } + + // increment the total number of bonded validators and potentially mark + // the validator to bond + if validator.Status != sdk.Bonded { + validatorToBond = validator + if newValidatorBonded { + panic("already decided to bond a validator, can't bond another!") + } + newValidatorBonded = true + } + + bondedValidatorsCount++ + } + + iterator.Close() + + if newValidatorBonded && bytes.Equal(oldCliffValidatorAddr, validator.OperatorAddr) { + panic("cliff validator has not been changed, yet we bonded a new validator") + } + + // clear or set the cliff validator + if bondedValidatorsCount == int(maxValidators) { + k.setCliffValidator(ctx, validator, k.GetPool(ctx)) + } else if len(oldCliffValidatorAddr) > 0 { + k.clearCliffValidator(ctx) + } + + // swap the cliff validator for a new validator if the affected validator + // was bonded + if newValidatorBonded { + if oldCliffValidatorAddr != nil { + oldCliffVal := k.mustGetValidator(ctx, oldCliffValidatorAddr) + + if bytes.Equal(validatorToBond.OperatorAddr, affectedValidator.OperatorAddr) { + + // begin unbonding the old cliff validator iff the affected + // validator was newly bonded and has greater power + k.beginUnbondingValidator(ctx, oldCliffVal) + } else { + // otherwise begin unbonding the affected validator, which must + // have been kicked out + affectedValidator = k.beginUnbondingValidator(ctx, affectedValidator) + } + } + + validator = k.bondValidator(ctx, validatorToBond) + if bytes.Equal(validator.OperatorAddr, affectedValidator.OperatorAddr) { + return validator, true + } + + return affectedValidator, true + } + + return types.Validator{}, false +} + +// XXX Delete this reference function before merge +// full update of the bonded validator set, many can be added/kicked +func (k Keeper) XXXREFERENCEUpdateBondedValidatorsFull(ctx sdk.Context) { + store := ctx.KVStore(k.storeKey) + + // clear the current validators store, add to the ToKickOut temp store + toKickOut := make(map[string]byte) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) + for ; iterator.Valid(); iterator.Next() { + ownerAddr := GetAddressFromValBondedIndexKey(iterator.Key()) + toKickOut[string(ownerAddr)] = 0 + } + + iterator.Close() + + var validator types.Validator + + oldCliffValidatorAddr := k.GetCliffValidator(ctx) + maxValidators := k.GetParams(ctx).MaxValidators + bondedValidatorsCount := 0 + + iterator = sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) + for ; iterator.Valid() && bondedValidatorsCount < int(maxValidators); iterator.Next() { + var found bool + + ownerAddr := iterator.Value() + validator = k.mustGetValidator(ctx, ownerAddr) + + _, found = toKickOut[string(ownerAddr)] + if found { + delete(toKickOut, string(ownerAddr)) + } else { + // If the validator wasn't in the toKickOut group it means it wasn't + // previously a validator, therefor update the validator to enter + // the validator group. + validator = k.bondValidator(ctx, validator) + } + + if validator.Jailed { + // we should no longer consider jailed validators as they are ranked + // lower than any non-jailed/bonded validators + if validator.Status == sdk.Bonded { + panic(fmt.Sprintf("jailed validator cannot be bonded for address: %s\n", ownerAddr)) + } + break + } + + bondedValidatorsCount++ + } + + iterator.Close() + + // clear or set the cliff validator + if bondedValidatorsCount == int(maxValidators) { + k.setCliffValidator(ctx, validator, k.GetPool(ctx)) + } else if len(oldCliffValidatorAddr) > 0 { + k.clearCliffValidator(ctx) + } + + kickOutValidators(k, ctx, toKickOut) + return +} + +func kickOutValidators(k Keeper, ctx sdk.Context, toKickOut map[string]byte) { + for key := range toKickOut { + ownerAddr := []byte(key) + validator := k.mustGetValidator(ctx, ownerAddr) + k.beginUnbondingValidator(ctx, validator) + } +} + +// perform all the store operations for when a validator status becomes unbonded +func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validator) types.Validator { + + store := ctx.KVStore(k.storeKey) + pool := k.GetPool(ctx) + params := k.GetParams(ctx) + + // sanity check + if validator.Status == sdk.Unbonded || + validator.Status == sdk.Unbonding { + panic(fmt.Sprintf("should not already be unbonded or unbonding, validator: %v\n", validator)) + } + + // set the status + validator, pool = validator.UpdateStatus(pool, sdk.Unbonding) + k.SetPool(ctx, pool) + + validator.UnbondingMinTime = ctx.BlockHeader().Time.Add(params.UnbondingTime) + validator.UnbondingHeight = ctx.BlockHeader().Height + + // save the now unbonded validator record + k.SetValidator(ctx, validator) + + // add to accumulated changes for tendermint + bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) + tstore := ctx.TransientStore(k.storeTKey) + tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI) + + // also remove from the Bonded types.Validators Store + store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) + + // call the unbond hook if present + if k.hooks != nil { + k.hooks.OnValidatorBeginUnbonding(ctx, validator.ConsAddress()) + } + + // return updated validator + return validator +} + +// perform all the store operations for when a validator status becomes bonded +func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types.Validator { + + store := ctx.KVStore(k.storeKey) + pool := k.GetPool(ctx) + + // sanity check + if validator.Status == sdk.Bonded { + panic(fmt.Sprintf("should not already be bonded, validator: %v\n", validator)) + } + + validator.BondHeight = ctx.BlockHeight() + + // set the status + validator, pool = validator.UpdateStatus(pool, sdk.Bonded) + k.SetPool(ctx, pool) + + // save the now bonded validator record to the three referenced stores + k.SetValidator(ctx, validator) + store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) + + // add to accumulated changes for tendermint + bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidator()) + tstore := ctx.TransientStore(k.storeTKey) + tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI) + + // call the bond hook if present + if k.hooks != nil { + k.hooks.OnValidatorBonded(ctx, validator.ConsAddress()) + } + + // return updated validator + return validator +} diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 37dfa67db9e3..3e68474cd0de 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -1,13 +1,9 @@ package keeper import ( - "bytes" "container/list" "fmt" - abci "github.com/tendermint/tendermint/abci/types" - - "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" ) @@ -193,497 +189,21 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []types.Validator { return validators[:i] // trim } -//_________________________________________________________________________ -// Accumulated updates to the active/bonded validator set for tendermint - -// get the most recently updated validators -// -// CONTRACT: Only validators with non-zero power or zero-power that were bonded -// at the previous block height or were removed from the validator set entirely -// are returned to Tendermint. -func (k Keeper) GetValidTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) { - - last := fetchOldValidatorSet() - tendermintUpdates := make(map[sdk.ValAddress]uint64) - - for _, validator := range topvalidator { //(iterate(top hundred)) { - switch validator.State { - case Unbonded: - unbondedToBonded(ctx, validator.Addr) - tendermintUpdates[validator.Addr] = validator.Power - case Unbonding: - unbondingToBonded(ctx, validator.Addr) - tendermintUpdates[validator.Addr] = validator.Power - case Bonded: // do nothing - store.delete(last[validator.Addr]) - // jailed validators are ranked last, so if we get to a jailed validator - // we have no more bonded validators - if validator.Jailed { - break - } - } - } - - for _, validator := range previousValidators { - bondedToUnbonding(ctx, validator.Addr) - tendermintUpdates[validator.Addr] = 0 - } - - return tendermintUpdates -} - -//___________________________________________________________________________ -// State transitions - -func (ctx sdk.Context, addr sdk.ValAddress) bondedToUnbonding() { - // perform appropriate store updates -} - -func (ctx sdk.Context, addr sdk.ValAddress) unbondingToBonded() { - // perform appropriate store updates -} - -func (ctx sdk.Context, addr sdk.ValAddress) unbondedToBonded() { - // perform appropriate store updates -} - -func (ctx sdk.Context, addr sdk.ValAddress) unbondingToUnbonded() { - // perform appropriate store updates -} - -func (ctx sdk.Context, addr sdk.ValAddress) jailValidator() { - // perform appropriate store updates -} - -// XXX Delete this reference function before merge -// Perform all the necessary steps for when a validator changes its power. This -// function updates all validator stores as well as tendermint update store. -// It may kick out validators if a new validator is entering the bonded validator -// group. -// -// TODO: Remove above nolint, function needs to be simplified! -func (k Keeper) REFERENCEXXXDELETEUpdateValidator(ctx sdk.Context, validator types.Validator) types.Validator { - tstore := ctx.TransientStore(k.storeTKey) - pool := k.GetPool(ctx) - oldValidator, oldFound := k.GetValidator(ctx, validator.OperatorAddr) - - validator = k.updateForJailing(ctx, oldFound, oldValidator, validator) - powerIncreasing := k.getPowerIncreasing(ctx, oldFound, oldValidator, validator) - validator.BondHeight, validator.BondIntraTxCounter = k.bondIncrement(ctx, oldFound, oldValidator) - valPower := k.updateValidatorPower(ctx, oldFound, oldValidator, validator, pool) - cliffPower := k.GetCliffValidatorPower(ctx) - cliffValExists := (cliffPower != nil) - var valPowerLTcliffPower bool - if cliffValExists { - valPowerLTcliffPower = (bytes.Compare(valPower, cliffPower) == -1) - } - - switch { - - // if the validator is already bonded and the power is increasing, we need - // perform the following: - // a) update Tendermint - // b) check if the cliff validator needs to be updated - case powerIncreasing && !validator.Jailed && - (oldFound && oldValidator.Status == sdk.Bonded): - - bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bz) - - if cliffValExists { - cliffAddr := sdk.ValAddress(k.GetCliffValidator(ctx)) - if bytes.Equal(cliffAddr, validator.OperatorAddr) { - k.updateCliffValidator(ctx, validator) - } - } - - // if is a new validator and the new power is less than the cliff validator - case cliffValExists && !oldFound && valPowerLTcliffPower: - // skip to completion - - // if was unbonded and the new power is less than the cliff validator - case cliffValExists && - (oldFound && oldValidator.Status == sdk.Unbonded) && - valPowerLTcliffPower: //(valPower < cliffPower - // skip to completion - - default: - // default case - validator was either: - // a) not-bonded and now has power-rank greater than cliff validator - // b) bonded and now has decreased in power - - // update the validator set for this validator - updatedVal, updated := k.UpdateBondedValidators(ctx, validator) - if updated { - // the validator has changed bonding status - validator = updatedVal - break - } - - // if decreased in power but still bonded, update Tendermint validator - if oldFound && oldValidator.BondedTokens().GT(validator.BondedTokens()) { - bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bz) - } - } - - k.SetValidator(ctx, validator) - return validator -} - -// updateCliffValidator determines if the current cliff validator needs to be -// updated or swapped. If the provided affected validator is the current cliff -// validator before it's power was increased, either the cliff power key will -// be updated or if it's power is greater than the next bonded validator by -// power, it'll be swapped. -func (k Keeper) updateCliffValidator(ctx sdk.Context, affectedVal types.Validator) { - var newCliffVal types.Validator - - store := ctx.KVStore(k.storeKey) - pool := k.GetPool(ctx) - cliffAddr := sdk.ValAddress(k.GetCliffValidator(ctx)) - - oldCliffVal, found := k.GetValidator(ctx, cliffAddr) - if !found { - panic(fmt.Sprintf("cliff validator record not found for address: %X\n", cliffAddr)) - } - - // Create a validator iterator ranging from smallest to largest by power - // starting the current cliff validator's power. - start := GetValidatorsByPowerIndexKey(oldCliffVal, pool) - end := sdk.PrefixEndBytes(ValidatorsByPowerIndexKey) - iterator := store.Iterator(start, end) - - if iterator.Valid() { - ownerAddr := iterator.Value() - currVal := k.mustGetValidator(ctx, ownerAddr) - - if currVal.Status != sdk.Bonded || currVal.Jailed { - panic(fmt.Sprintf("unexpected jailed or unbonded validator for address: %X\n", ownerAddr)) - } - - newCliffVal = currVal - iterator.Close() - } else { - panic("failed to create valid validator power iterator") - } - - affectedValRank := GetValidatorsByPowerIndexKey(affectedVal, pool) - newCliffValRank := GetValidatorsByPowerIndexKey(newCliffVal, pool) - - if bytes.Equal(affectedVal.OperatorAddr, newCliffVal.OperatorAddr) { - // The affected validator remains the cliff validator, however, since - // the store does not contain the new power, update the new power rank. - store.Set(ValidatorPowerCliffKey, affectedValRank) - } else if bytes.Compare(affectedValRank, newCliffValRank) > 0 { - // The affected validator no longer remains the cliff validator as it's - // power is greater than the new cliff validator. - k.setCliffValidator(ctx, newCliffVal, pool) - } else { - panic("invariant broken: the cliff validator should change or it should remain the same") - } -} - -func (k Keeper) updateForJailing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) types.Validator { - if newValidator.Jailed && oldFound && oldValidator.Status == sdk.Bonded { - newValidator = k.beginUnbondingValidator(ctx, newValidator) - - // need to also clear the cliff validator spot because the jail has - // opened up a new spot which will be filled when - // updateValidatorsBonded is called - k.clearCliffValidator(ctx) - } - return newValidator -} - -// nolint: unparam -func (k Keeper) getPowerIncreasing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) bool { - if oldFound && oldValidator.BondedTokens().LT(newValidator.BondedTokens()) { - return true - } - return false -} - -// get the bond height and incremented intra-tx counter -// nolint: unparam -func (k Keeper) bondIncrement( - ctx sdk.Context, found bool, oldValidator types.Validator) (height int64, intraTxCounter int16) { - - // if already a validator, copy the old block height and counter - if found && oldValidator.Status == sdk.Bonded { - height = oldValidator.BondHeight - intraTxCounter = oldValidator.BondIntraTxCounter - return - } - - height = ctx.BlockHeight() - counter := k.GetIntraTxCounter(ctx) - intraTxCounter = counter - - k.SetIntraTxCounter(ctx, counter+1) - return -} - -func (k Keeper) updateValidatorPower(ctx sdk.Context, oldFound bool, oldValidator, - newValidator types.Validator, pool types.Pool) (valPower []byte) { - store := ctx.KVStore(k.storeKey) - - // update the list ordered by voting power - if oldFound { - store.Delete(GetValidatorsByPowerIndexKey(oldValidator, pool)) - } - valPower = GetValidatorsByPowerIndexKey(newValidator, pool) - store.Set(valPower, newValidator.OperatorAddr) - - return valPower -} - -// XXX Delete this reference function before merge -// Update the bonded validator group based on a change to the validator -// affectedValidator. This function potentially adds the affectedValidator to -// the bonded validator group which kicks out the cliff validator. Under this -// situation this function returns the updated affectedValidator. -// -// The correct bonded subset of validators is retrieved by iterating through an -// index of the validators sorted by power, stored using the -// ValidatorsByPowerIndexKey. Simultaneously the current validator records are -// updated in store with the ValidatorsBondedIndexKey. This store is used to -// determine if a validator is a validator without needing to iterate over all -// validators. -func (k Keeper) XXXREFERENCEUpdateBondedValidators( - ctx sdk.Context, affectedValidator types.Validator) ( - updatedVal types.Validator, updated bool) { - - store := ctx.KVStore(k.storeKey) - - oldCliffValidatorAddr := k.GetCliffValidator(ctx) - maxValidators := k.GetParams(ctx).MaxValidators - bondedValidatorsCount := 0 - var validator, validatorToBond types.Validator - newValidatorBonded := false - - // create a validator iterator ranging from largest to smallest by power - iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) - for ; iterator.Valid() && bondedValidatorsCount < int(maxValidators); iterator.Next() { - - // either retrieve the original validator from the store, or under the - // situation that this is the "affected validator" just use the - // validator provided because it has not yet been updated in the store - ownerAddr := iterator.Value() - if bytes.Equal(ownerAddr, affectedValidator.OperatorAddr) { - validator = affectedValidator - } else { - var found bool - validator = k.mustGetValidator(ctx, ownerAddr) - } - - // if we've reached jailed validators no further bonded validators exist - if validator.Jailed { - if validator.Status == sdk.Bonded { - panic(fmt.Sprintf("jailed validator cannot be bonded, address: %X\n", ownerAddr)) - } - - break - } - - // increment the total number of bonded validators and potentially mark - // the validator to bond - if validator.Status != sdk.Bonded { - validatorToBond = validator - if newValidatorBonded { - panic("already decided to bond a validator, can't bond another!") - } - newValidatorBonded = true - } - - bondedValidatorsCount++ - } - - iterator.Close() - - if newValidatorBonded && bytes.Equal(oldCliffValidatorAddr, validator.OperatorAddr) { - panic("cliff validator has not been changed, yet we bonded a new validator") - } - - // clear or set the cliff validator - if bondedValidatorsCount == int(maxValidators) { - k.setCliffValidator(ctx, validator, k.GetPool(ctx)) - } else if len(oldCliffValidatorAddr) > 0 { - k.clearCliffValidator(ctx) - } - - // swap the cliff validator for a new validator if the affected validator - // was bonded - if newValidatorBonded { - if oldCliffValidatorAddr != nil { - oldCliffVal := k.mustGetValidator(ctx, oldCliffValidatorAddr) - - if bytes.Equal(validatorToBond.OperatorAddr, affectedValidator.OperatorAddr) { - - // begin unbonding the old cliff validator iff the affected - // validator was newly bonded and has greater power - k.beginUnbondingValidator(ctx, oldCliffVal) - } else { - // otherwise begin unbonding the affected validator, which must - // have been kicked out - affectedValidator = k.beginUnbondingValidator(ctx, affectedValidator) - } - } - - validator = k.bondValidator(ctx, validatorToBond) - if bytes.Equal(validator.OperatorAddr, affectedValidator.OperatorAddr) { - return validator, true - } - - return affectedValidator, true - } - - return types.Validator{}, false -} - -// full update of the bonded validator set, many can be added/kicked -func (k Keeper) UpdateBondedValidatorsFull(ctx sdk.Context) { - store := ctx.KVStore(k.storeKey) - - // clear the current validators store, add to the ToKickOut temp store - toKickOut := make(map[string]byte) - iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) - for ; iterator.Valid(); iterator.Next() { - ownerAddr := GetAddressFromValBondedIndexKey(iterator.Key()) - toKickOut[string(ownerAddr)] = 0 - } - - iterator.Close() - - var validator types.Validator - - oldCliffValidatorAddr := k.GetCliffValidator(ctx) - maxValidators := k.GetParams(ctx).MaxValidators - bondedValidatorsCount := 0 - - iterator = sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) - for ; iterator.Valid() && bondedValidatorsCount < int(maxValidators); iterator.Next() { - var found bool - - ownerAddr := iterator.Value() - validator = k.mustGetValidator(ctx, ownerAddr) - - _, found = toKickOut[string(ownerAddr)] - if found { - delete(toKickOut, string(ownerAddr)) - } else { - // If the validator wasn't in the toKickOut group it means it wasn't - // previously a validator, therefor update the validator to enter - // the validator group. - validator = k.bondValidator(ctx, validator) - } - - if validator.Jailed { - // we should no longer consider jailed validators as they are ranked - // lower than any non-jailed/bonded validators - if validator.Status == sdk.Bonded { - panic(fmt.Sprintf("jailed validator cannot be bonded for address: %s\n", ownerAddr)) - } - break - } - - bondedValidatorsCount++ - } - - iterator.Close() - - // clear or set the cliff validator - if bondedValidatorsCount == int(maxValidators) { - k.setCliffValidator(ctx, validator, k.GetPool(ctx)) - } else if len(oldCliffValidatorAddr) > 0 { - k.clearCliffValidator(ctx) - } - - kickOutValidators(k, ctx, toKickOut) - return -} - -func kickOutValidators(k Keeper, ctx sdk.Context, toKickOut map[string]byte) { - for key := range toKickOut { - ownerAddr := []byte(key) - validator := k.mustGetValidator(ctx, ownerAddr) - k.beginUnbondingValidator(ctx, validator) - } -} - -// perform all the store operations for when a validator status becomes unbonded -func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validator) types.Validator { - - store := ctx.KVStore(k.storeKey) - pool := k.GetPool(ctx) - params := k.GetParams(ctx) - - // sanity check - if validator.Status == sdk.Unbonded || - validator.Status == sdk.Unbonding { - panic(fmt.Sprintf("should not already be unbonded or unbonding, validator: %v\n", validator)) - } - - // set the status - validator, pool = validator.UpdateStatus(pool, sdk.Unbonding) - k.SetPool(ctx, pool) - - validator.UnbondingMinTime = ctx.BlockHeader().Time.Add(params.UnbondingTime) - validator.UnbondingHeight = ctx.BlockHeader().Height - - // save the now unbonded validator record - k.SetValidator(ctx, validator) - - // add to accumulated changes for tendermint - bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) - tstore := ctx.TransientStore(k.storeTKey) - tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI) - - // also remove from the Bonded types.Validators Store - store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) - - // call the unbond hook if present - if k.hooks != nil { - k.hooks.OnValidatorBeginUnbonding(ctx, validator.ConsAddress()) - } - - // return updated validator - return validator -} - -// perform all the store operations for when a validator status becomes bonded -func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types.Validator { - - store := ctx.KVStore(k.storeKey) - pool := k.GetPool(ctx) +// UpdateValidatorCommission attempts to update a validator's commission rate. +// An error is returned if the new commission rate is invalid. +func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Validator, newRate sdk.Dec) sdk.Error { + commission := validator.Commission + blockTime := ctx.BlockHeader().Time - // sanity check - if validator.Status == sdk.Bonded { - panic(fmt.Sprintf("should not already be bonded, validator: %v\n", validator)) + if err := commission.ValidateNewRate(newRate, blockTime); err != nil { + return err } - validator.BondHeight = ctx.BlockHeight() - - // set the status - validator, pool = validator.UpdateStatus(pool, sdk.Bonded) - k.SetPool(ctx, pool) + validator.Commission.Rate = newRate + validator.Commission.UpdateTime = blockTime - // save the now bonded validator record to the three referenced stores k.SetValidator(ctx, validator) - store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) - - // add to accumulated changes for tendermint - bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - tstore := ctx.TransientStore(k.storeTKey) - tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI) - - // call the bond hook if present - if k.hooks != nil { - k.hooks.OnValidatorBonded(ctx, validator.ConsAddress()) - } - - // return updated validator - return validator + return nil } // remove the validator record and associated indexes @@ -713,20 +233,3 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { tstore := ctx.TransientStore(k.storeTKey) tstore.Set(GetTendermintUpdatesTKey(address), bz) } - -// UpdateValidatorCommission attempts to update a validator's commission rate. -// An error is returned if the new commission rate is invalid. -func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Validator, newRate sdk.Dec) sdk.Error { - commission := validator.Commission - blockTime := ctx.BlockHeader().Time - - if err := commission.ValidateNewRate(newRate, blockTime); err != nil { - return err - } - - validator.Commission.Rate = newRate - validator.Commission.UpdateTime = blockTime - - k.SetValidator(ctx, validator) - return nil -} From 8373329f9964e04b7757d66553b3f278600b7761 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 26 Sep 2018 00:16:48 -0400 Subject: [PATCH 15/52] move validatorByPowerIndexExists from keeper to test file --- x/stake/keeper/val_state_change.go | 376 ++++++++++++----------------- x/stake/keeper/validator.go | 36 ++- x/stake/keeper/validator_test.go | 11 +- x/stake/types/validator.go | 1 + 4 files changed, 172 insertions(+), 252 deletions(-) diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 39719cf6d213..88c6a6a9053c 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -19,7 +19,13 @@ import ( // CONTRACT: Only validators with non-zero power or zero-power that were bonded // at the previous block height or were removed from the validator set entirely // are returned to Tendermint. -func (k Keeper) GetValidTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) { +func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) { + + // REF CODE + //// add to accumulated changes for tendermint + //bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidator()) + //tstore := ctx.TransientStore(k.storeTKey) + //tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI) last := fetchOldValidatorSet() tendermintUpdates := make(map[sdk.ValAddress]uint64) @@ -50,29 +56,160 @@ func (k Keeper) GetValidTendermintUpdates(ctx sdk.Context) (updates []abci.Valid return tendermintUpdates } +func kickOutValidators(k Keeper, ctx sdk.Context, toKickOut map[string]byte) { + for key := range toKickOut { + ownerAddr := []byte(key) + validator := k.mustGetValidator(ctx, ownerAddr) + k.beginUnbondingValidator(ctx, validator) + } +} + //___________________________________________________________________________ // State transitions -func (ctx sdk.Context, addr sdk.ValAddress) bondedToUnbonding() { - // perform appropriate store updates +func (k Keeper) bondedToUnbonding(ctx sdk.Context, validator types.Validator) { + if validator.Status != sdk.Bonded { + panic(fmt.Sprintf("bad state transition bondedToUnbonded, validator: %v\n", validator)) + } + beginUnbondingValidator(ctx, validator) } -func (ctx sdk.Context, addr sdk.ValAddress) unbondingToBonded() { - // perform appropriate store updates +func (k Keeper) unbondingToBonded(ctx sdk.Context, validator types.Validator) { + if validator.Status != sdk.Unbonding { + panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator)) + } + bondValidator(ctx, validator) } -func (ctx sdk.Context, addr sdk.ValAddress) unbondedToBonded() { - // perform appropriate store updates +func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) { + if validator.Status != sdk.Unbonded { + panic(fmt.Sprintf("bad state transition unbondedToBonded, validator: %v\n", validator)) + } + bondValidator(ctx, validator) } -func (ctx sdk.Context, addr sdk.ValAddress) unbondingToUnbonded() { - // perform appropriate store updates +func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) { + if validator.Status != sdk.Unbonded { + panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator)) + } + completeUnbondingValidator(ctx, validator) } -func (ctx sdk.Context, addr sdk.ValAddress) jailValidator() { - // perform appropriate store updates +func (k Keeper) jailValidator(ctx sdk.Context, validator types.Validator) { + if validator.Jailed { + panic(fmt.Sprintf("cannot jail already jailed validator, validator: %v\n", validator)) + } + + validator.Jailed = true + + if validator.Status == sdk.Bonded { + validator = k.beginUnbondingValidator(ctx, newValidator) + } } +//________________________________________________________________________________________________ + +// perform all the store operations for when a validator status becomes bonded +func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) { + + store := ctx.KVStore(k.storeKey) + pool := k.GetPool(ctx) + + validator.BondHeight = ctx.BlockHeight() + + // set the status + validator, pool = validator.UpdateStatus(pool, sdk.Bonded) + k.SetPool(ctx, pool) + + // save the now bonded validator record to the three referenced stores + k.SetValidator(ctx, validator) + store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) + + // call the bond hook if present + if k.hooks != nil { + k.hooks.OnValidatorBonded(ctx, validator.ConsAddress()) + } +} + +// perform all the store operations for when a validator status begins unbonding +func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validator) { + + store := ctx.KVStore(k.storeKey) + pool := k.GetPool(ctx) + params := k.GetParams(ctx) + + // sanity check + if validator.Status == sdk.Unbonded || + validator.Status == sdk.Unbonding { + panic(fmt.Sprintf("should not already be unbonded or unbonding, validator: %v\n", validator)) + } + + // set the status + validator, pool = validator.UpdateStatus(pool, sdk.Unbonding) + k.SetPool(ctx, pool) + + validator.UnbondingMinTime = ctx.BlockHeader().Time.Add(params.UnbondingTime) + validator.UnbondingHeight = ctx.BlockHeader().Height + + // save the now unbonded validator record + k.SetValidator(ctx, validator) + + // also remove from the Bonded types.Validators Store + store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) + + // call the unbond hook if present + if k.hooks != nil { + k.hooks.OnValidatorBeginUnbonding(ctx, validator.ConsAddress()) + } +} + +// perform all the store operations for when a validator status becomes unbonded +func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Validator) { + store := ctx.KVStore(k.storeKey) + pool := k.GetPool(ctx) + validator, pool = validator.UpdateStatus(pool, sdk.Unbonded) + k.SetPool(ctx, pool) + k.SetValidator(ctx, validator) +} + +//______________________________________________________________________________________________________ + +func (k Keeper) updateValidatorPower(ctx sdk.Context, oldFound bool, oldValidator, + newValidator types.Validator, pool types.Pool) (valPower []byte) { + store := ctx.KVStore(k.storeKey) + + // update the list ordered by voting power + if oldFound { + store.Delete(GetValidatorsByPowerIndexKey(oldValidator, pool)) + } + valPower = GetValidatorsByPowerIndexKey(newValidator, pool) + store.Set(valPower, newValidator.OperatorAddr) + + return valPower +} + +// get the bond height and incremented intra-tx counter +// nolint: unparam +func (k Keeper) bondIncrement(ctx sdk.Context, isNewValidator bool, validator types.Validator) ( + height int64, intraTxCounter int16) { + + // if already a validator, copy the old block height and counter + if !isNewValidator && validator.Status == sdk.Bonded { + height = validator.BondHeight + intraTxCounter = validator.BondIntraTxCounter + return + } + + height = ctx.BlockHeight() + counter := k.GetIntraTxCounter(ctx) + intraTxCounter = counter + + k.SetIntraTxCounter(ctx, counter+1) + return +} + +//______________________________________________________________________________________________________ + // XXX Delete this reference function before merge // Perform all the necessary steps for when a validator changes its power. This // function updates all validator stores as well as tendermint update store. @@ -89,12 +226,6 @@ func (k Keeper) REFERENCEXXXDELETEUpdateValidator(ctx sdk.Context, validator typ powerIncreasing := k.getPowerIncreasing(ctx, oldFound, oldValidator, validator) validator.BondHeight, validator.BondIntraTxCounter = k.bondIncrement(ctx, oldFound, oldValidator) valPower := k.updateValidatorPower(ctx, oldFound, oldValidator, validator, pool) - cliffPower := k.GetCliffValidatorPower(ctx) - cliffValExists := (cliffPower != nil) - var valPowerLTcliffPower bool - if cliffValExists { - valPowerLTcliffPower = (bytes.Compare(valPower, cliffPower) == -1) - } switch { @@ -149,60 +280,6 @@ func (k Keeper) REFERENCEXXXDELETEUpdateValidator(ctx sdk.Context, validator typ return validator } -func (k Keeper) updateForJailing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) types.Validator { - if newValidator.Jailed && oldFound && oldValidator.Status == sdk.Bonded { - newValidator = k.beginUnbondingValidator(ctx, newValidator) - - // need to also clear the cliff validator spot because the jail has - // opened up a new spot which will be filled when - // updateValidatorsBonded is called - k.clearCliffValidator(ctx) - } - return newValidator -} - -// nolint: unparam -func (k Keeper) getPowerIncreasing(ctx sdk.Context, oldFound bool, oldValidator, newValidator types.Validator) bool { - if oldFound && oldValidator.BondedTokens().LT(newValidator.BondedTokens()) { - return true - } - return false -} - -// get the bond height and incremented intra-tx counter -// nolint: unparam -func (k Keeper) bondIncrement( - ctx sdk.Context, found bool, oldValidator types.Validator) (height int64, intraTxCounter int16) { - - // if already a validator, copy the old block height and counter - if found && oldValidator.Status == sdk.Bonded { - height = oldValidator.BondHeight - intraTxCounter = oldValidator.BondIntraTxCounter - return - } - - height = ctx.BlockHeight() - counter := k.GetIntraTxCounter(ctx) - intraTxCounter = counter - - k.SetIntraTxCounter(ctx, counter+1) - return -} - -func (k Keeper) updateValidatorPower(ctx sdk.Context, oldFound bool, oldValidator, - newValidator types.Validator, pool types.Pool) (valPower []byte) { - store := ctx.KVStore(k.storeKey) - - // update the list ordered by voting power - if oldFound { - store.Delete(GetValidatorsByPowerIndexKey(oldValidator, pool)) - } - valPower = GetValidatorsByPowerIndexKey(newValidator, pool) - store.Set(valPower, newValidator.OperatorAddr) - - return valPower -} - // XXX Delete this reference function before merge // Update the bonded validator group based on a change to the validator // affectedValidator. This function potentially adds the affectedValidator to @@ -266,17 +343,6 @@ func (k Keeper) XXXREFERENCEUpdateBondedValidators( iterator.Close() - if newValidatorBonded && bytes.Equal(oldCliffValidatorAddr, validator.OperatorAddr) { - panic("cliff validator has not been changed, yet we bonded a new validator") - } - - // clear or set the cliff validator - if bondedValidatorsCount == int(maxValidators) { - k.setCliffValidator(ctx, validator, k.GetPool(ctx)) - } else if len(oldCliffValidatorAddr) > 0 { - k.clearCliffValidator(ctx) - } - // swap the cliff validator for a new validator if the affected validator // was bonded if newValidatorBonded { @@ -305,149 +371,3 @@ func (k Keeper) XXXREFERENCEUpdateBondedValidators( return types.Validator{}, false } - -// XXX Delete this reference function before merge -// full update of the bonded validator set, many can be added/kicked -func (k Keeper) XXXREFERENCEUpdateBondedValidatorsFull(ctx sdk.Context) { - store := ctx.KVStore(k.storeKey) - - // clear the current validators store, add to the ToKickOut temp store - toKickOut := make(map[string]byte) - iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) - for ; iterator.Valid(); iterator.Next() { - ownerAddr := GetAddressFromValBondedIndexKey(iterator.Key()) - toKickOut[string(ownerAddr)] = 0 - } - - iterator.Close() - - var validator types.Validator - - oldCliffValidatorAddr := k.GetCliffValidator(ctx) - maxValidators := k.GetParams(ctx).MaxValidators - bondedValidatorsCount := 0 - - iterator = sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) - for ; iterator.Valid() && bondedValidatorsCount < int(maxValidators); iterator.Next() { - var found bool - - ownerAddr := iterator.Value() - validator = k.mustGetValidator(ctx, ownerAddr) - - _, found = toKickOut[string(ownerAddr)] - if found { - delete(toKickOut, string(ownerAddr)) - } else { - // If the validator wasn't in the toKickOut group it means it wasn't - // previously a validator, therefor update the validator to enter - // the validator group. - validator = k.bondValidator(ctx, validator) - } - - if validator.Jailed { - // we should no longer consider jailed validators as they are ranked - // lower than any non-jailed/bonded validators - if validator.Status == sdk.Bonded { - panic(fmt.Sprintf("jailed validator cannot be bonded for address: %s\n", ownerAddr)) - } - break - } - - bondedValidatorsCount++ - } - - iterator.Close() - - // clear or set the cliff validator - if bondedValidatorsCount == int(maxValidators) { - k.setCliffValidator(ctx, validator, k.GetPool(ctx)) - } else if len(oldCliffValidatorAddr) > 0 { - k.clearCliffValidator(ctx) - } - - kickOutValidators(k, ctx, toKickOut) - return -} - -func kickOutValidators(k Keeper, ctx sdk.Context, toKickOut map[string]byte) { - for key := range toKickOut { - ownerAddr := []byte(key) - validator := k.mustGetValidator(ctx, ownerAddr) - k.beginUnbondingValidator(ctx, validator) - } -} - -// perform all the store operations for when a validator status becomes unbonded -func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validator) types.Validator { - - store := ctx.KVStore(k.storeKey) - pool := k.GetPool(ctx) - params := k.GetParams(ctx) - - // sanity check - if validator.Status == sdk.Unbonded || - validator.Status == sdk.Unbonding { - panic(fmt.Sprintf("should not already be unbonded or unbonding, validator: %v\n", validator)) - } - - // set the status - validator, pool = validator.UpdateStatus(pool, sdk.Unbonding) - k.SetPool(ctx, pool) - - validator.UnbondingMinTime = ctx.BlockHeader().Time.Add(params.UnbondingTime) - validator.UnbondingHeight = ctx.BlockHeader().Height - - // save the now unbonded validator record - k.SetValidator(ctx, validator) - - // add to accumulated changes for tendermint - bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) - tstore := ctx.TransientStore(k.storeTKey) - tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI) - - // also remove from the Bonded types.Validators Store - store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) - - // call the unbond hook if present - if k.hooks != nil { - k.hooks.OnValidatorBeginUnbonding(ctx, validator.ConsAddress()) - } - - // return updated validator - return validator -} - -// perform all the store operations for when a validator status becomes bonded -func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types.Validator { - - store := ctx.KVStore(k.storeKey) - pool := k.GetPool(ctx) - - // sanity check - if validator.Status == sdk.Bonded { - panic(fmt.Sprintf("should not already be bonded, validator: %v\n", validator)) - } - - validator.BondHeight = ctx.BlockHeight() - - // set the status - validator, pool = validator.UpdateStatus(pool, sdk.Bonded) - k.SetPool(ctx, pool) - - // save the now bonded validator record to the three referenced stores - k.SetValidator(ctx, validator) - store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) - - // add to accumulated changes for tendermint - bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - tstore := ctx.TransientStore(k.storeTKey) - tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI) - - // call the bond hook if present - if k.hooks != nil { - k.hooks.OnValidatorBonded(ctx, validator.ConsAddress()) - } - - // return updated validator - return validator -} diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 3e68474cd0de..b3f2075fd99d 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -98,10 +98,21 @@ func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validat store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) } -// used in testing -func (k Keeper) validatorByPowerIndexExists(ctx sdk.Context, power []byte) bool { - store := ctx.KVStore(k.storeKey) - return store.Get(power) != nil +// UpdateValidatorCommission attempts to update a validator's commission rate. +// An error is returned if the new commission rate is invalid. +func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Validator, newRate sdk.Dec) sdk.Error { + commission := validator.Commission + blockTime := ctx.BlockHeader().Time + + if err := commission.ValidateNewRate(newRate, blockTime); err != nil { + return err + } + + validator.Commission.Rate = newRate + validator.Commission.UpdateTime = blockTime + + k.SetValidator(ctx, validator) + return nil } // Get the set of all validators with no limits, used during genesis dump @@ -189,23 +200,6 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []types.Validator { return validators[:i] // trim } -// UpdateValidatorCommission attempts to update a validator's commission rate. -// An error is returned if the new commission rate is invalid. -func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Validator, newRate sdk.Dec) sdk.Error { - commission := validator.Commission - blockTime := ctx.BlockHeader().Time - - if err := commission.ValidateNewRate(newRate, blockTime); err != nil { - return err - } - - validator.Commission.Rate = newRate - validator.Commission.UpdateTime = blockTime - - k.SetValidator(ctx, validator) - return nil -} - // remove the validator record and associated indexes func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 73a391acc70a..e018fa41097a 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -25,6 +25,11 @@ func clearTendermintUpdates(ctx sdk.Context, k Keeper) { iterator.Close() } +func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool { + store := ctx.KVStore(k.storeKey) + return store.Get(power) != nil +} + //_______________________________________________________ func TestSetValidator(t *testing.T) { @@ -101,20 +106,20 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { pool = keeper.GetPool(ctx) power := GetValidatorsByPowerIndexKey(validator, pool) - require.True(t, keeper.validatorByPowerIndexExists(ctx, power)) + require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) // burn half the delegator shares validator, pool, burned := validator.RemoveDelShares(pool, delSharesCreated.Quo(sdk.NewDec(2))) require.Equal(t, int64(50), burned.RoundInt64()) keeper.SetPool(ctx, pool) // update the pool keeper.UpdateValidator(ctx, validator) // update the validator, possibly kicking it out - require.False(t, keeper.validatorByPowerIndexExists(ctx, power)) + require.False(t, validatorByPowerIndexExists(keeper, ctx, power)) pool = keeper.GetPool(ctx) validator, found = keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) power = GetValidatorsByPowerIndexKey(validator, pool) - require.True(t, keeper.validatorByPowerIndexExists(ctx, power)) + require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) } func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index 051ffa9e5168..345df1bf95f1 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -430,6 +430,7 @@ func (v Validator) BondedTokens() sdk.Dec { return sdk.ZeroDec() } +// TODO remove this once the validator queue logic is implemented // Returns if the validator should be considered unbonded func (v Validator) IsUnbonded(ctx sdk.Context) bool { switch v.Status { From b6575bb15be583c188dea182ce82e61fa2963997 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 26 Sep 2018 01:36:20 -0400 Subject: [PATCH 16/52] reorganizing --- x/stake/keeper/validator.go | 78 ++++++++++++++++++++++--------------- 1 file changed, 47 insertions(+), 31 deletions(-) diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index b3f2075fd99d..c1d518ae8e7c 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -92,6 +92,21 @@ func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Valida store.Set(GetValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } +// Update the validators power index key +func (k Keeper) updateValidatorPower(ctx sdk.Context, + oldFound bool, oldValidator, newValidator types.Validator) { + + store := ctx.KVStore(k.storeKey) + pool := store.GetPool(ctx) + + // update the list ordered by voting power + if oldFound { + store.Delete(GetValidatorsByPowerIndexKey(oldValidator, pool)) + } + valPower = GetValidatorsByPowerIndexKey(newValidator, pool) + store.Set(valPower, newValidator.OperatorAddr) +} + // validator index func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) @@ -115,7 +130,38 @@ func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Valid return nil } -// Get the set of all validators with no limits, used during genesis dump +// remove the validator record and associated indexes +func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { + + // first retrieve the old validator record + validator, found := k.GetValidator(ctx, address) + if !found { + return + } + + // delete the old validator record + store := ctx.KVStore(k.storeKey) + pool := k.GetPool(ctx) + store.Delete(GetValidatorKey(address)) + store.Delete(GetValidatorByConsAddrKey(sdk.ConsAddress(validator.ConsPubKey.Address()))) + store.Delete(GetValidatorsByPowerIndexKey(validator, pool)) + + // delete from the current and power weighted validator groups if the validator + // is bonded - and add validator with zero power to the validator updates + if store.Get(GetValidatorsBondedIndexKey(validator.OperatorAddr)) == nil { + return + } + store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) + + bz := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) + tstore := ctx.TransientStore(k.storeTKey) + tstore.Set(GetTendermintUpdatesTKey(address), bz) +} + +//___________________________________________________________________________ +// get groups of validators + +// get the set of all validators with no limits, used during genesis dump func (k Keeper) GetAllValidators(ctx sdk.Context) (validators []types.Validator) { store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, ValidatorsKey) @@ -147,8 +193,6 @@ func (k Keeper) GetValidators(ctx sdk.Context, maxRetrieve uint16) (validators [ return validators[:i] // trim if the array length < maxRetrieve } -//___________________________________________________________________________ - // get the group of the bonded validators func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validator) { store := ctx.KVStore(k.storeKey) @@ -199,31 +243,3 @@ func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []types.Validator { } return validators[:i] // trim } - -// remove the validator record and associated indexes -func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { - - // first retrieve the old validator record - validator, found := k.GetValidator(ctx, address) - if !found { - return - } - - // delete the old validator record - store := ctx.KVStore(k.storeKey) - pool := k.GetPool(ctx) - store.Delete(GetValidatorKey(address)) - store.Delete(GetValidatorByConsAddrKey(sdk.ConsAddress(validator.ConsPubKey.Address()))) - store.Delete(GetValidatorsByPowerIndexKey(validator, pool)) - - // delete from the current and power weighted validator groups if the validator - // is bonded - and add validator with zero power to the validator updates - if store.Get(GetValidatorsBondedIndexKey(validator.OperatorAddr)) == nil { - return - } - store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) - - bz := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) - tstore := ctx.TransientStore(k.storeTKey) - tstore.Set(GetTendermintUpdatesTKey(address), bz) -} From 52c413f582f4d5d9a09d2156fb1d660eb1bf12be Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 26 Sep 2018 01:37:17 -0400 Subject: [PATCH 17/52] GetValidatorsByPower -> GetBondedValidatorsByPower --- x/stake/handler_test.go | 6 ++-- x/stake/keeper/key.go | 2 +- x/stake/keeper/val_state_change.go | 4 +-- x/stake/keeper/validator.go | 12 +++---- x/stake/keeper/validator_test.go | 50 +++++++++++++++--------------- x/stake/stake.go | 2 +- 6 files changed, 38 insertions(+), 38 deletions(-) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 5780bf5431bb..91fd51c2527e 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -75,7 +75,7 @@ func TestValidatorByPowerIndex(t *testing.T) { validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) pool := keeper.GetPool(ctx) - power := keep.GetValidatorsByPowerIndexKey(validator, pool) + power := keep.GetBondedValidatorsByPowerIndexKey(validator, pool) require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power)) // create a second validator keep it bonded @@ -99,7 +99,7 @@ func TestValidatorByPowerIndex(t *testing.T) { validator, found = keeper.GetValidator(ctx, validatorAddr) require.True(t, found) pool = keeper.GetPool(ctx) - power2 := GetValidatorsByPowerIndexKey(validator, pool) + power2 := GetBondedValidatorsByPowerIndexKey(validator, pool) require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power2)) // inflate a bunch @@ -110,7 +110,7 @@ func TestValidatorByPowerIndex(t *testing.T) { } // now the new record power index should be the same as the original record - power3 := GetValidatorsByPowerIndexKey(validator, pool) + power3 := GetBondedValidatorsByPowerIndexKey(validator, pool) require.Equal(t, power2, power3) // unbond self-delegation diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index 3de145c91f33..8bd0de35ad40 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -60,7 +60,7 @@ func GetAddressFromValBondedIndexKey(IndexKey []byte) []byte { // Power index is the key used in the power-store, and represents the relative // power ranking of the validator. // VALUE: validator operator address ([]byte) -func GetValidatorsByPowerIndexKey(validator types.Validator, pool types.Pool) []byte { +func GetBondedValidatorsByPowerIndexKey(validator types.Validator, pool types.Pool) []byte { // NOTE the address doesn't need to be stored because counter bytes must always be different return getValidatorPowerRank(validator, pool) } diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 88c6a6a9053c..551340a64e91 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -180,9 +180,9 @@ func (k Keeper) updateValidatorPower(ctx sdk.Context, oldFound bool, oldValidato // update the list ordered by voting power if oldFound { - store.Delete(GetValidatorsByPowerIndexKey(oldValidator, pool)) + store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) } - valPower = GetValidatorsByPowerIndexKey(newValidator, pool) + valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) store.Set(valPower, newValidator.OperatorAddr) return valPower diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index c1d518ae8e7c..ccda8b81e77b 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -89,7 +89,7 @@ func (k Keeper) SetValidatorByConsAddr(ctx sdk.Context, validator types.Validato // validator index func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Validator, pool types.Pool) { store := ctx.KVStore(k.storeKey) - store.Set(GetValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) + store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } // Update the validators power index key @@ -101,9 +101,9 @@ func (k Keeper) updateValidatorPower(ctx sdk.Context, // update the list ordered by voting power if oldFound { - store.Delete(GetValidatorsByPowerIndexKey(oldValidator, pool)) + store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) } - valPower = GetValidatorsByPowerIndexKey(newValidator, pool) + valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) store.Set(valPower, newValidator.OperatorAddr) } @@ -144,7 +144,7 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { pool := k.GetPool(ctx) store.Delete(GetValidatorKey(address)) store.Delete(GetValidatorByConsAddrKey(sdk.ConsAddress(validator.ConsPubKey.Address()))) - store.Delete(GetValidatorsByPowerIndexKey(validator, pool)) + store.Delete(GetBondedValidatorsByPowerIndexKey(validator, pool)) // delete from the current and power weighted validator groups if the validator // is bonded - and add validator with zero power to the validator updates @@ -222,8 +222,8 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validat // get the group of bonded validators sorted by power-rank // -// TODO: Rename to GetBondedValidatorsByPower or GetValidatorsByPower(ctx, status) -func (k Keeper) GetValidatorsByPower(ctx sdk.Context) []types.Validator { +// TODO: Rename to GetBondedValidatorsByPower or GetBondedValidatorsByPower(ctx, status) +func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator { store := ctx.KVStore(k.storeKey) maxValidators := k.GetParams(ctx).MaxValidators validators := make([]types.Validator, maxValidators) diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index e018fa41097a..ab6ac7e72520 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -64,7 +64,7 @@ func TestSetValidator(t *testing.T) { require.Equal(t, 1, len(resVals)) assert.True(ValEq(t, validator, resVals[0])) - resVals = keeper.GetValidatorsByPower(ctx) + resVals = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, 1, len(resVals)) require.True(ValEq(t, validator, resVals[0])) @@ -105,7 +105,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool) pool = keeper.GetPool(ctx) - power := GetValidatorsByPowerIndexKey(validator, pool) + power := GetBondedValidatorsByPowerIndexKey(validator, pool) require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) // burn half the delegator shares @@ -118,7 +118,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { pool = keeper.GetPool(ctx) validator, found = keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) - power = GetValidatorsByPowerIndexKey(validator, pool) + power = GetBondedValidatorsByPowerIndexKey(validator, pool) require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) } @@ -167,7 +167,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { // require the cliff validator power has changed cliffPower := keeper.GetCliffValidatorPower(ctx) - require.Equal(t, GetValidatorsByPowerIndexKey(cliffVal, pool), cliffPower) + require.Equal(t, GetBondedValidatorsByPowerIndexKey(cliffVal, pool), cliffPower) expectedValStatus := map[int]sdk.BondStatus{ 9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded, @@ -230,7 +230,7 @@ func TestCliffValidatorChange(t *testing.T) { // assert cliff validator power should have been updated cliffPower := keeper.GetCliffValidatorPower(ctx) - require.Equal(t, GetValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) + require.Equal(t, GetBondedValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) // add small amount of tokens to new current cliff validator newCliffVal, pool, _ = newCliffVal.AddTokensFromDel(pool, sdk.NewInt(1)) @@ -240,7 +240,7 @@ func TestCliffValidatorChange(t *testing.T) { // assert cliff validator has not change but increased in power cliffPower = keeper.GetCliffValidatorPower(ctx) require.Equal(t, newCliffVal.OperatorAddr, sdk.ValAddress(keeper.GetCliffValidator(ctx))) - require.Equal(t, GetValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) + require.Equal(t, GetBondedValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) // add enough power to cliff validator to be equal in rank to next validator newCliffVal, pool, _ = newCliffVal.AddTokensFromDel(pool, sdk.NewInt(9)) @@ -253,7 +253,7 @@ func TestCliffValidatorChange(t *testing.T) { // assert cliff validator power should have been updated cliffPower = keeper.GetCliffValidatorPower(ctx) - require.Equal(t, GetValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) + require.Equal(t, GetBondedValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) } func TestSlashToZeroPowerRemoved(t *testing.T) { @@ -369,7 +369,7 @@ func TestValidatorBasics(t *testing.T) { require.False(t, found) } -// test how the validators are sorted, tests GetValidatorsByPower +// test how the validators are sorted, tests GetBondedValidatorsByPower func GetValidatorSortingUnmixed(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) @@ -386,7 +386,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { } // first make sure everything made it in to the gotValidator group - resValidators := keeper.GetValidatorsByPower(ctx) + resValidators := keeper.GetBondedValidatorsByPower(ctx) assert.Equal(t, n, len(resValidators)) assert.Equal(t, sdk.NewDec(400), resValidators[0].BondedTokens(), "%v", resValidators) assert.Equal(t, sdk.NewDec(200), resValidators[1].BondedTokens(), "%v", resValidators) @@ -402,14 +402,14 @@ func GetValidatorSortingUnmixed(t *testing.T) { // test a basic increase in voting power validators[3].Tokens = sdk.NewDec(500) keeper.UpdateValidator(ctx, validators[3]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) // test a decrease in voting power validators[3].Tokens = sdk.NewDec(300) keeper.UpdateValidator(ctx, validators[3]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) assert.True(ValEq(t, validators[4], resValidators[1])) @@ -418,7 +418,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { validators[3].Tokens = sdk.NewDec(200) ctx = ctx.WithBlockHeight(10) keeper.UpdateValidator(ctx, validators[3]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) assert.True(ValEq(t, validators[4], resValidators[1])) @@ -428,7 +428,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { // no change in voting power - no change in sort ctx = ctx.WithBlockHeight(20) keeper.UpdateValidator(ctx, validators[4]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) assert.True(ValEq(t, validators[4], resValidators[1])) @@ -437,11 +437,11 @@ func GetValidatorSortingUnmixed(t *testing.T) { validators[3].Tokens = sdk.NewDec(300) validators[4].Tokens = sdk.NewDec(300) keeper.UpdateValidator(ctx, validators[3]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) ctx = ctx.WithBlockHeight(30) keeper.UpdateValidator(ctx, validators[4]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n, "%v", resValidators) assert.True(ValEq(t, validators[3], resValidators[0])) assert.True(ValEq(t, validators[4], resValidators[1])) @@ -497,7 +497,7 @@ func GetValidatorSortingMixed(t *testing.T) { require.Equal(t, sdk.Bonded, val4.Status) // first make sure everything made it in to the gotValidator group - resValidators := keeper.GetValidatorsByPower(ctx) + resValidators := keeper.GetBondedValidatorsByPower(ctx) assert.Equal(t, n, len(resValidators)) assert.Equal(t, sdk.NewDec(400), resValidators[0].BondedTokens(), "%v", resValidators) assert.Equal(t, sdk.NewDec(200), resValidators[1].BondedTokens(), "%v", resValidators) @@ -538,7 +538,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { validators[i], found = keeper.GetValidator(ctx, validators[i].OperatorAddr) require.True(t, found) } - resValidators := keeper.GetValidatorsByPower(ctx) + resValidators := keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[2], resValidators[0])) assert.True(ValEq(t, validators[3], resValidators[1])) @@ -547,7 +547,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(500)) keeper.SetPool(ctx, pool) validators[0] = keeper.UpdateValidator(ctx, validators[0]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) @@ -564,7 +564,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1)) keeper.SetPool(ctx, pool) validators[3] = keeper.UpdateValidator(ctx, validators[3]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[3], resValidators[1])) @@ -573,7 +573,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201)) keeper.SetPool(ctx, pool) validators[3] = keeper.UpdateValidator(ctx, validators[3]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) @@ -582,7 +582,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200)) keeper.SetPool(ctx, pool) validators[3] = keeper.UpdateValidator(ctx, validators[3]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) @@ -621,7 +621,7 @@ func TestValidatorBondHeight(t *testing.T) { pool = keeper.GetPool(ctx) - resValidators := keeper.GetValidatorsByPower(ctx) + resValidators := keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, uint16(len(resValidators)), params.MaxValidators) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -630,7 +630,7 @@ func TestValidatorBondHeight(t *testing.T) { validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50)) keeper.SetPool(ctx, pool) validators[2] = keeper.UpdateValidator(ctx, validators[2]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, params.MaxValidators, uint16(len(resValidators))) validators[1] = keeper.UpdateValidator(ctx, validators[1]) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -664,7 +664,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { assert.Equal(t, sdk.Bonded, validators[2].Status) assert.Equal(t, sdk.Bonded, validators[3].Status) assert.Equal(t, sdk.Unbonded, validators[4].Status) - resValidators := keeper.GetValidatorsByPower(ctx) + resValidators := keeper.GetBondedValidatorsByPower(ctx) assert.Equal(t, max, len(resValidators)) assert.True(ValEq(t, validators[2], resValidators[0])) // in the order of txs assert.True(ValEq(t, validators[3], resValidators[1])) @@ -674,7 +674,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(600)) keeper.SetPool(ctx, pool) validators[0] = keeper.UpdateValidator(ctx, validators[0]) - resValidators = keeper.GetValidatorsByPower(ctx) + resValidators = keeper.GetBondedValidatorsByPower(ctx) assert.Equal(t, max, len(resValidators)) assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) diff --git a/x/stake/stake.go b/x/stake/stake.go index 7e60b3113a83..5da9b0083ca1 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -38,7 +38,7 @@ var ( GetValidatorKey = keeper.GetValidatorKey GetValidatorByConsAddrKey = keeper.GetValidatorByConsAddrKey GetValidatorsBondedIndexKey = keeper.GetValidatorsBondedIndexKey - GetValidatorsByPowerIndexKey = keeper.GetValidatorsByPowerIndexKey + GetBondedValidatorsByPowerIndexKey = keeper.GetBondedValidatorsByPowerIndexKey GetTendermintUpdatesTKey = keeper.GetTendermintUpdatesTKey GetDelegationKey = keeper.GetDelegationKey GetDelegationsKey = keeper.GetDelegationsKey From 7debae02889951b9c535fc889ada20782f8dab3f Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 26 Sep 2018 02:09:58 -0400 Subject: [PATCH 18/52] remove duplicate SetValidator in handleMsgEditValidator --- x/stake/handler.go | 4 +-- x/stake/keeper/validator.go | 50 +++++++++++++++++++++++-------------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index 0524b2c117b7..94e2381e114f 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -126,13 +126,13 @@ func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keepe validator.Description = description if msg.CommissionRate != nil { + commission, err := k.UpdateValidatorCommission(ctx, validator, *msg.CommissionRate) if err := k.UpdateValidatorCommission(ctx, validator, *msg.CommissionRate); err != nil { return err.Result() } + validator.Commission = commission } - // We don't need to run through all the power update logic within k.UpdateValidator - // We just need to override the entry in state, since only the description has changed. k.SetValidator(ctx, validator) tags := sdk.NewTags( diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index ccda8b81e77b..c45ef0d708b3 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -72,6 +72,8 @@ func (k Keeper) GetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress return k.GetValidator(ctx, opAddr) } +//___________________________________________________________________________ + // set the main record holding validator details func (k Keeper) SetValidator(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) @@ -92,42 +94,54 @@ func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Valida store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } -// Update the validators power index key -func (k Keeper) updateValidatorPower(ctx sdk.Context, - oldFound bool, oldValidator, newValidator types.Validator) { +// validator index +func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validator) { + store := ctx.KVStore(k.storeKey) + store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) +} +//___________________________________________________________________________ + +// Update the tokens of an existing validator, update the validators power index key +func (k Keeper) UpdateValidatorTokens(ctx sdk.Context, validator types.Validator, newTokens sdk.Dec) sdk.Error { store := ctx.KVStore(k.storeKey) pool := store.GetPool(ctx) - // update the list ordered by voting power - if oldFound { - store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) - } - valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) + store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) + + k.SetValidator(ctx, validator) store.Set(valPower, newValidator.OperatorAddr) + + validator.Tokens = validator.Tokens.Add(newTokens) + valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) } -// validator index -func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validator) { +// Update the tokens for a new validator, create the validators power index key +func (k Keeper) NewValidatorTokens(ctx sdk.Context, validator types.Validator, newTokens sdk.Dec) sdk.Error { store := ctx.KVStore(k.storeKey) - store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) + + validator.Tokens = validator.Tokens.Add(newTokens) + k.SetValidator(ctx, validator) + + pool := store.GetPool(ctx) + valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) + store.Set(valPower, newValidator.OperatorAddr) } // UpdateValidatorCommission attempts to update a validator's commission rate. // An error is returned if the new commission rate is invalid. -func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Validator, newRate sdk.Dec) sdk.Error { +func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Validator, newRate sdk.Dec) (types.Commission, sdk.Error) { commission := validator.Commission blockTime := ctx.BlockHeader().Time if err := commission.ValidateNewRate(newRate, blockTime); err != nil { - return err + return commission, err } - validator.Commission.Rate = newRate - validator.Commission.UpdateTime = blockTime + commission.Rate = newRate + commission.UpdateTime = blockTime - k.SetValidator(ctx, validator) - return nil + return commission, nil } // remove the validator record and associated indexes @@ -221,8 +235,6 @@ func (k Keeper) GetValidatorsBonded(ctx sdk.Context) (validators []types.Validat } // get the group of bonded validators sorted by power-rank -// -// TODO: Rename to GetBondedValidatorsByPower or GetBondedValidatorsByPower(ctx, status) func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator { store := ctx.KVStore(k.storeKey) maxValidators := k.GetParams(ctx).MaxValidators From e838a024f2561a259f5aeff7f95a68bfa595ed96 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 26 Sep 2018 02:35:35 -0400 Subject: [PATCH 19/52] Added missing by-power index at validator creation --- x/stake/handler.go | 2 +- x/stake/keeper/slash.go | 18 +++--------------- x/stake/keeper/val_state_change.go | 18 +++++++++++++++++- x/stake/keeper/validator.go | 27 ++++++++++++++++++++------- 4 files changed, 41 insertions(+), 24 deletions(-) diff --git a/x/stake/handler.go b/x/stake/handler.go index 94e2381e114f..b40b7b98d8fc 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -82,7 +82,6 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k msg.Commission.Rate, msg.Commission.MaxChangeRate, msg.Commission.MaxChangeRate, ctx.BlockHeader().Time, ) - validator, err := validator.SetInitialCommission(commission) if err != nil { return err.Result() @@ -90,6 +89,7 @@ func handleMsgCreateValidator(ctx sdk.Context, msg types.MsgCreateValidator, k k k.SetValidator(ctx, validator) k.SetValidatorByConsAddr(ctx, validator) + k.SetNewValidatorByPowerIndex(ctx, validator) // move coins from the msg.Address account to a (self-delegation) delegator account // the validator account and global shares are updated within here diff --git a/x/stake/keeper/slash.go b/x/stake/keeper/slash.go index 486dc328695c..7c48c6085cfc 100644 --- a/x/stake/keeper/slash.go +++ b/x/stake/keeper/slash.go @@ -99,13 +99,12 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh tokensToBurn := sdk.MinDec(remainingSlashAmount, validator.Tokens) // burn validator's tokens + validator = k.RemoveValidatorTokens(ctx, validator, tokensToBurn) pool := k.GetPool(ctx) - validator, pool = validator.RemoveTokens(pool, tokensToBurn) pool.LooseTokens = pool.LooseTokens.Sub(tokensToBurn) k.SetPool(ctx, pool) // update the validator, possibly kicking it out - validator = k.UpdateValidator(ctx, validator) // remove validator if it has no more tokens if validator.Tokens.IsZero() { @@ -123,7 +122,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh // jail a validator func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress) { - k.setJailed(ctx, consAddr, true) + k.JailValidator(ctx, validator) logger := ctx.Logger().With("module", "x/stake") logger.Info(fmt.Sprintf("validator %s jailed", consAddr)) // TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803 @@ -132,24 +131,13 @@ func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress) { // unjail a validator func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress) { - k.setJailed(ctx, consAddr, false) + k.UnjailValidator(ctx, validator) logger := ctx.Logger().With("module", "x/stake") logger.Info(fmt.Sprintf("validator %s unjailed", consAddr)) // TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803 return } -// set the jailed flag on a validator -func (k Keeper) setJailed(ctx sdk.Context, consAddr sdk.ConsAddress, isJailed bool) { - validator, found := k.GetValidatorByConsAddr(ctx, consAddr) - if !found { - panic(fmt.Errorf("validator with consensus-Address %s not found, cannot set jailed to %v", consAddr, isJailed)) - } - validator.Jailed = isJailed - k.UpdateValidator(ctx, validator) // update validator, possibly unbonding or bonding it - return -} - // slash an unbonding delegation and update the pool // return the amount that would have been slashed assuming // the unbonding delegation had enough stake to slash diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 551340a64e91..d8ce0c0cd639 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -95,7 +95,8 @@ func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) completeUnbondingValidator(ctx, validator) } -func (k Keeper) jailValidator(ctx sdk.Context, validator types.Validator) { +// send a validator to jail +func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { if validator.Jailed { panic(fmt.Sprintf("cannot jail already jailed validator, validator: %v\n", validator)) } @@ -107,6 +108,21 @@ func (k Keeper) jailValidator(ctx sdk.Context, validator types.Validator) { } } +// remove a validator from jail +func (k Keeper) UnjailValidator(ctx sdk.Context, validator types.Validator) { + if !validator.Jailed { + panic(fmt.Sprintf("cannot jail already jailed validator, validator: %v\n", validator)) + } + + store.Delete(GetBondedValidatorsByPowerIndexKey(validator, pool)) + + validator.Jailed = false + k.SetValidator(ctx, validator) + + valPower = GetBondedValidatorsByPowerIndexKey(validator, pool) + store.Set(valPower, validator.OperatorAddr) +} + //________________________________________________________________________________________________ // perform all the store operations for when a validator status becomes bonded diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index c45ef0d708b3..a590bc2a770e 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -94,6 +94,13 @@ func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Valida store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } +// validator index +func (k Keeper) SetNewValidatorByPowerIndex(ctx sdk.Context, validator types.Validator) { + store := ctx.KVStore(k.storeKey) + pool := store.GetPool(ctx) + store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) +} + // validator index func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) @@ -103,29 +110,35 @@ func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validat //___________________________________________________________________________ // Update the tokens of an existing validator, update the validators power index key -func (k Keeper) UpdateValidatorTokens(ctx sdk.Context, validator types.Validator, newTokens sdk.Dec) sdk.Error { +func (k Keeper) AddValidatorTokens(ctx sdk.Context, validator types.Validator, newTokens sdk.Dec) types.Validator { store := ctx.KVStore(k.storeKey) pool := store.GetPool(ctx) store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) + validator, pool = validator.AddTokens(pool, newTokens) k.SetValidator(ctx, validator) - store.Set(valPower, newValidator.OperatorAddr) + k.SetPool(ctx, pool) - validator.Tokens = validator.Tokens.Add(newTokens) valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) + store.Set(valPower, newValidator.OperatorAddr) + return validator } -// Update the tokens for a new validator, create the validators power index key -func (k Keeper) NewValidatorTokens(ctx sdk.Context, validator types.Validator, newTokens sdk.Dec) sdk.Error { +// Update the tokens of an existing validator, update the validators power index key +func (k Keeper) RemoveValidatorTokens(ctx sdk.Context, validator types.Validator, tokensToRemove sdk.Dec) types.Validator { store := ctx.KVStore(k.storeKey) + pool := store.GetPool(ctx) - validator.Tokens = validator.Tokens.Add(newTokens) + store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) + + validator, pool = validator.RemoveTokens(pool, tokensToBurn) k.SetValidator(ctx, validator) + k.SetPool(ctx, pool) - pool := store.GetPool(ctx) valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) store.Set(valPower, newValidator.OperatorAddr) + return validator } // UpdateValidatorCommission attempts to update a validator's commission rate. From 0e91227da8aa11bdbef3ca3596b56dd95ec6bf0f Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 26 Sep 2018 03:00:58 -0400 Subject: [PATCH 20/52] removed codebase use of UpdateValidator --- x/stake/keeper/delegation.go | 20 +++------ x/stake/keeper/val_state_change.go | 71 +++++++++++++++--------------- x/stake/keeper/validator.go | 26 +++++++++-- 3 files changed, 63 insertions(+), 54 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 6efa4c8ed3b3..0bf3b4032d6a 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -265,18 +265,13 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Co } } - pool := k.GetPool(ctx) - validator, pool, newShares = validator.AddTokensFromDel(pool, bondAmt.Amount) - delegation.Shares = delegation.Shares.Add(newShares) + validator, newShares = k.AddValidatorTokensAndShares(ctx, validator) - // Update delegation height + // Update delegation + delegation.Shares = delegation.Shares.Add(newShares) delegation.Height = ctx.BlockHeight() - - k.SetPool(ctx, pool) k.SetDelegation(ctx, delegation) - k.UpdateValidator(ctx, validator) - - return + return newShares, nil } // unbond the the delegation return @@ -323,13 +318,8 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA } // remove the coins from the validator - pool := k.GetPool(ctx) - validator, pool, amount = validator.RemoveDelShares(pool, shares) - - k.SetPool(ctx, pool) + validator, amount = k.RemoveValidatorTokensAndShares(ctx, validator, shares) - // update then remove validator if necessary - validator = k.UpdateValidator(ctx, validator) if validator.DelegatorShares.IsZero() { k.RemoveValidator(ctx, validator.OperatorAddr) } diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index d8ce0c0cd639..10b10db0cb8d 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -27,35 +27,41 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) //tstore := ctx.TransientStore(k.storeTKey) //tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI) - last := fetchOldValidatorSet() - tendermintUpdates := make(map[sdk.ValAddress]uint64) - - for _, validator := range topvalidator { //(iterate(top hundred)) { - switch validator.State { - case Unbonded: - unbondedToBonded(ctx, validator.Addr) - tendermintUpdates[validator.Addr] = validator.Power - case Unbonding: - unbondingToBonded(ctx, validator.Addr) - tendermintUpdates[validator.Addr] = validator.Power - case Bonded: // do nothing - store.delete(last[validator.Addr]) - // jailed validators are ranked last, so if we get to a jailed validator - // we have no more bonded validators - if validator.Jailed { - break + // XXX code from issue + /* + last := fetchOldValidatorSet() + tendermintUpdates := make(map[sdk.ValAddress]uint64) + + for _, validator := range topvalidator { //(iterate(top hundred)) { + switch validator.State { + case Unbonded: + unbondedToBonded(ctx, validator.Addr) + tendermintUpdates[validator.Addr] = validator.Power + case Unbonding: + unbondingToBonded(ctx, validator.Addr) + tendermintUpdates[validator.Addr] = validator.Power + case Bonded: // do nothing + store.delete(last[validator.Addr]) + // jailed validators are ranked last, so if we get to a jailed validator + // we have no more bonded validators + if validator.Jailed { + break + } } } - } - for _, validator := range previousValidators { - bondedToUnbonding(ctx, validator.Addr) - tendermintUpdates[validator.Addr] = 0 - } + for _, validator := range previousValidators { + bondedToUnbonding(ctx, validator.Addr) + tendermintUpdates[validator.Addr] = 0 + } - return tendermintUpdates + return tendermintUpdates + */ + + return updates } +// XXX FOR REFERENCE USE OR DELETED func kickOutValidators(k Keeper, ctx sdk.Context, toKickOut map[string]byte) { for key := range toKickOut { ownerAddr := []byte(key) @@ -95,6 +101,8 @@ func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) completeUnbondingValidator(ctx, validator) } +//________________________________________________________________________________________________ + // send a validator to jail func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { if validator.Jailed { @@ -131,6 +139,8 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) pool := k.GetPool(ctx) + // XXX WHAT DO WE DO FOR BondIntraTxCounter Height Now?????????????????????????? + validator.BondHeight = ctx.BlockHeight() // set the status @@ -190,19 +200,8 @@ func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Vali //______________________________________________________________________________________________________ -func (k Keeper) updateValidatorPower(ctx sdk.Context, oldFound bool, oldValidator, - newValidator types.Validator, pool types.Pool) (valPower []byte) { - store := ctx.KVStore(k.storeKey) - - // update the list ordered by voting power - if oldFound { - store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) - } - valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) - store.Set(valPower, newValidator.OperatorAddr) - - return valPower -} +// XXX need to figure out how to set a validator's BondIntraTxCounter - probably during delegation bonding? +// or keep track of tx for final bonding and set during endblock??? wish we could reduce this complexity // get the bond height and incremented intra-tx counter // nolint: unparam diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index a590bc2a770e..0cabdfa96e46 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -110,19 +110,39 @@ func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validat //___________________________________________________________________________ // Update the tokens of an existing validator, update the validators power index key -func (k Keeper) AddValidatorTokens(ctx sdk.Context, validator types.Validator, newTokens sdk.Dec) types.Validator { +func (k Keeper) AddValidatorTokensAndShares(ctx sdk.Context, validator types.Validator, + tokensToAdd sdk.Dec) (valOut types.Validator, addedShares sdk.Dec) { + store := ctx.KVStore(k.storeKey) pool := store.GetPool(ctx) store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) - validator, pool = validator.AddTokens(pool, newTokens) + validator, pool, addedShares = validator.AddTokensFromDel(pool, tokensToAdd) k.SetValidator(ctx, validator) k.SetPool(ctx, pool) valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) store.Set(valPower, newValidator.OperatorAddr) - return validator + return validator, addedShares +} + +// Update the tokens of an existing validator, update the validators power index key +func (k Keeper) RemoveValidatorTokensAndShares(ctx sdk.Context, validator types.Validator, + sharesToRemove sdk.Dec) (valOut types.Validator, removedTokens sdk.Dec) { + + store := ctx.KVStore(k.storeKey) + pool := store.GetPool(ctx) + + store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) + + validator, pool, removedTokens = validator.RemoveDelShares(pool, sharesToRemove) + k.SetValidator(ctx, validator) + k.SetPool(ctx, pool) + + valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) + store.Set(valPower, newValidator.OperatorAddr) + return validator, removedTokens } // Update the tokens of an existing validator, update the validators power index key From cd9a9fb295a431aed171d1f7f3fa8d3be3d0da42 Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 26 Sep 2018 03:04:29 -0400 Subject: [PATCH 21/52] SetParams now doesnt update validator set as happens at endblock --- x/stake/keeper/delegation.go | 2 +- x/stake/keeper/keeper.go | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 0bf3b4032d6a..81842b463c7b 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -265,7 +265,7 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Co } } - validator, newShares = k.AddValidatorTokensAndShares(ctx, validator) + validator, newShares = k.AddValidatorTokensAndShares(ctx, validator, bondAmt) // Update delegation delegation.Shares = delegation.Shares.Add(newShares) diff --git a/x/stake/keeper/keeper.go b/x/stake/keeper/keeper.go index 0f700f9ab824..c443389de42d 100644 --- a/x/stake/keeper/keeper.go +++ b/x/stake/keeper/keeper.go @@ -64,25 +64,9 @@ func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { return } -// Need a distinct function because setParams depends on an existing previous -// record of params to exist (to check if maxValidators has changed) - and we -// panic on retrieval if it doesn't exist - hence if we use setParams for the very -// first params set it will panic. -func (k Keeper) SetNewParams(ctx sdk.Context, params types.Params) { - store := ctx.KVStore(k.storeKey) - b := k.cdc.MustMarshalBinary(params) - store.Set(ParamKey, b) -} - // set the params func (k Keeper) SetParams(ctx sdk.Context, params types.Params) { store := ctx.KVStore(k.storeKey) - exParams := k.GetParams(ctx) - - // if max validator count changes, must recalculate validator set - if exParams.MaxValidators != params.MaxValidators { - k.UpdateBondedValidatorsFull(ctx) - } b := k.cdc.MustMarshalBinary(params) store.Set(ParamKey, b) } From 76f18fd020a00af54d33018aaed02b41f6693c2a Mon Sep 17 00:00:00 2001 From: rigelrozanski Date: Wed, 26 Sep 2018 03:34:23 -0400 Subject: [PATCH 22/52] got non-test code compiling --- x/stake/genesis.go | 4 +- x/stake/handler.go | 4 +- x/stake/keeper/delegation.go | 2 +- x/stake/keeper/slash.go | 2 + x/stake/keeper/test_common.go | 2 +- x/stake/keeper/val_state_change.go | 44 +++++++++++---------- x/stake/keeper/validator.go | 61 ++++++++++++++---------------- x/stake/stake.go | 54 +++++++++++++------------- 8 files changed, 87 insertions(+), 86 deletions(-) diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 58b7ed1b4f25..1f1d1d9f8a70 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -17,7 +17,7 @@ import ( // Returns final validator set after applying all declaration and delegations func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res []abci.Validator, err error) { keeper.SetPool(ctx, data.Pool) - keeper.SetNewParams(ctx, data.Params) + keeper.SetParams(ctx, data.Params) keeper.InitIntraTxCounter(ctx) for i, validator := range data.Validators { @@ -44,7 +44,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ keeper.SetDelegation(ctx, bond) } - keeper.UpdateBondedValidatorsFull(ctx) + //keeper.UpdateBondedValidatorsFull(ctx) // XXX TODO must calculate the genesis validator set vals := keeper.GetValidatorsBonded(ctx) res = make([]abci.Validator, len(vals)) diff --git a/x/stake/handler.go b/x/stake/handler.go index b40b7b98d8fc..3f10fb93dc05 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -52,7 +52,7 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) (ValidatorUpdates []abci.Valid k.SetIntraTxCounter(ctx, 0) // calculate validator set changes - ValidatorUpdates = k.GetValidTendermintUpdates(ctx) + ValidatorUpdates = k.GetTendermintUpdates(ctx) return } @@ -127,7 +127,7 @@ func handleMsgEditValidator(ctx sdk.Context, msg types.MsgEditValidator, k keepe if msg.CommissionRate != nil { commission, err := k.UpdateValidatorCommission(ctx, validator, *msg.CommissionRate) - if err := k.UpdateValidatorCommission(ctx, validator, *msg.CommissionRate); err != nil { + if err != nil { return err.Result() } validator.Commission = commission diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 81842b463c7b..9e1687d596b0 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -265,7 +265,7 @@ func (k Keeper) Delegate(ctx sdk.Context, delAddr sdk.AccAddress, bondAmt sdk.Co } } - validator, newShares = k.AddValidatorTokensAndShares(ctx, validator, bondAmt) + validator, newShares = k.AddValidatorTokensAndShares(ctx, validator, bondAmt.Amount) // Update delegation delegation.Shares = delegation.Shares.Add(newShares) diff --git a/x/stake/keeper/slash.go b/x/stake/keeper/slash.go index 7c48c6085cfc..f32122df236e 100644 --- a/x/stake/keeper/slash.go +++ b/x/stake/keeper/slash.go @@ -122,6 +122,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh // jail a validator func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress) { + validator := k.mustGetValidatorByConsAddr(ctx, consAddr) k.JailValidator(ctx, validator) logger := ctx.Logger().With("module", "x/stake") logger.Info(fmt.Sprintf("validator %s jailed", consAddr)) @@ -131,6 +132,7 @@ func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress) { // unjail a validator func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress) { + validator := k.mustGetValidatorByConsAddr(ctx, consAddr) k.UnjailValidator(ctx, validator) logger := ctx.Logger().With("module", "x/stake") logger.Info(fmt.Sprintf("validator %s unjailed", consAddr)) diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index 03d4642b671b..388e7e247045 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -111,7 +111,7 @@ func CreateTestInput(t *testing.T, isCheckTx bool, initCoins int64) (sdk.Context ck := bank.NewBaseKeeper(accountMapper) keeper := NewKeeper(cdc, keyStake, tkeyStake, ck, types.DefaultCodespace) keeper.SetPool(ctx, types.InitialPool()) - keeper.SetNewParams(ctx, types.DefaultParams()) + keeper.SetParams(ctx, types.DefaultParams()) keeper.InitIntraTxCounter(ctx) // fill all the addresses with some coins, set the loose pool tokens simultaneously diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 10b10db0cb8d..10c65bb98caf 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -1,12 +1,10 @@ package keeper import ( - "bytes" "fmt" abci "github.com/tendermint/tendermint/abci/types" - "github.com/cosmos/cosmos-sdk/store" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" ) @@ -77,28 +75,28 @@ func (k Keeper) bondedToUnbonding(ctx sdk.Context, validator types.Validator) { if validator.Status != sdk.Bonded { panic(fmt.Sprintf("bad state transition bondedToUnbonded, validator: %v\n", validator)) } - beginUnbondingValidator(ctx, validator) + k.beginUnbondingValidator(ctx, validator) } func (k Keeper) unbondingToBonded(ctx sdk.Context, validator types.Validator) { if validator.Status != sdk.Unbonding { panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator)) } - bondValidator(ctx, validator) + k.bondValidator(ctx, validator) } func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) { if validator.Status != sdk.Unbonded { panic(fmt.Sprintf("bad state transition unbondedToBonded, validator: %v\n", validator)) } - bondValidator(ctx, validator) + k.bondValidator(ctx, validator) } func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) { if validator.Status != sdk.Unbonded { panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator)) } - completeUnbondingValidator(ctx, validator) + k.completeUnbondingValidator(ctx, validator) } //________________________________________________________________________________________________ @@ -109,11 +107,11 @@ func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { panic(fmt.Sprintf("cannot jail already jailed validator, validator: %v\n", validator)) } + pool := k.GetPool(ctx) + k.DeleteValidatorByPowerIndex(ctx, validator, pool) validator.Jailed = true - - if validator.Status == sdk.Bonded { - validator = k.beginUnbondingValidator(ctx, newValidator) - } + k.SetValidator(ctx, validator) + k.SetValidatorByPowerIndex(ctx, validator, pool) } // remove a validator from jail @@ -122,13 +120,11 @@ func (k Keeper) UnjailValidator(ctx sdk.Context, validator types.Validator) { panic(fmt.Sprintf("cannot jail already jailed validator, validator: %v\n", validator)) } - store.Delete(GetBondedValidatorsByPowerIndexKey(validator, pool)) - + pool := k.GetPool(ctx) + k.DeleteValidatorByPowerIndex(ctx, validator, pool) validator.Jailed = false k.SetValidator(ctx, validator) - - valPower = GetBondedValidatorsByPowerIndexKey(validator, pool) - store.Set(valPower, validator.OperatorAddr) + k.SetValidatorByPowerIndex(ctx, validator, pool) } //________________________________________________________________________________________________ @@ -139,6 +135,8 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) pool := k.GetPool(ctx) + k.DeleteValidatorByPowerIndex(ctx, validator, pool) + // XXX WHAT DO WE DO FOR BondIntraTxCounter Height Now?????????????????????????? validator.BondHeight = ctx.BlockHeight() @@ -151,6 +149,8 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) { k.SetValidator(ctx, validator) store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) + k.SetValidatorByPowerIndex(ctx, validator, pool) + // call the bond hook if present if k.hooks != nil { k.hooks.OnValidatorBonded(ctx, validator.ConsAddress()) @@ -158,12 +158,14 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) { } // perform all the store operations for when a validator status begins unbonding -func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validator) { +func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validator) types.Validator { store := ctx.KVStore(k.storeKey) pool := k.GetPool(ctx) params := k.GetParams(ctx) + k.DeleteValidatorByPowerIndex(ctx, validator, pool) + // sanity check if validator.Status == sdk.Unbonded || validator.Status == sdk.Unbonding { @@ -183,15 +185,18 @@ func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validat // also remove from the Bonded types.Validators Store store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) + k.SetValidatorByPowerIndex(ctx, validator, pool) + // call the unbond hook if present if k.hooks != nil { k.hooks.OnValidatorBeginUnbonding(ctx, validator.ConsAddress()) } + + return validator } // perform all the store operations for when a validator status becomes unbonded func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Validator) { - store := ctx.KVStore(k.storeKey) pool := k.GetPool(ctx) validator, pool = validator.UpdateStatus(pool, sdk.Unbonded) k.SetPool(ctx, pool) @@ -224,7 +229,7 @@ func (k Keeper) bondIncrement(ctx sdk.Context, isNewValidator bool, validator ty } //______________________________________________________________________________________________________ - +/* // XXX Delete this reference function before merge // Perform all the necessary steps for when a validator changes its power. This // function updates all validator stores as well as tendermint update store. @@ -317,7 +322,7 @@ func (k Keeper) XXXREFERENCEUpdateBondedValidators( maxValidators := k.GetParams(ctx).MaxValidators bondedValidatorsCount := 0 var validator, validatorToBond types.Validator - newValidatorBonded := false + //newValidatorBonded := false // create a validator iterator ranging from largest to smallest by power iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) @@ -386,3 +391,4 @@ func (k Keeper) XXXREFERENCEUpdateBondedValidators( return types.Validator{}, false } +*/ diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 0cabdfa96e46..5024ba17e4e6 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -55,9 +55,9 @@ func (k Keeper) GetValidator(ctx sdk.Context, addr sdk.ValAddress) (validator ty } func (k Keeper) mustGetValidator(ctx sdk.Context, addr sdk.ValAddress) types.Validator { - validator, found := GetValidator(ctx, addr) + validator, found := k.GetValidator(ctx, addr) if !found { - panic(fmt.Sprintf("validator record not found for address: %X\n", ownerAddr)) + panic(fmt.Sprintf("validator record not found for address: %X\n", addr)) } return validator } @@ -72,6 +72,14 @@ func (k Keeper) GetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress return k.GetValidator(ctx, opAddr) } +func (k Keeper) mustGetValidatorByConsAddr(ctx sdk.Context, consAddr sdk.ConsAddress) types.Validator { + validator, found := k.GetValidatorByConsAddr(ctx, consAddr) + if !found { + panic(fmt.Errorf("validator with consensus-Address %s not found", consAddr)) + } + return validator +} + //___________________________________________________________________________ // set the main record holding validator details @@ -94,10 +102,16 @@ func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Valida store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } +// validator index +func (k Keeper) DeleteValidatorByPowerIndex(ctx sdk.Context, validator types.Validator, pool types.Pool) { + store := ctx.KVStore(k.storeKey) + store.Delete(GetBondedValidatorsByPowerIndexKey(validator, pool)) +} + // validator index func (k Keeper) SetNewValidatorByPowerIndex(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) - pool := store.GetPool(ctx) + pool := k.GetPool(ctx) store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } @@ -111,19 +125,14 @@ func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validat // Update the tokens of an existing validator, update the validators power index key func (k Keeper) AddValidatorTokensAndShares(ctx sdk.Context, validator types.Validator, - tokensToAdd sdk.Dec) (valOut types.Validator, addedShares sdk.Dec) { - - store := ctx.KVStore(k.storeKey) - pool := store.GetPool(ctx) - - store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) + tokensToAdd sdk.Int) (valOut types.Validator, addedShares sdk.Dec) { + pool := k.GetPool(ctx) + k.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, addedShares = validator.AddTokensFromDel(pool, tokensToAdd) k.SetValidator(ctx, validator) k.SetPool(ctx, pool) - - valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) - store.Set(valPower, newValidator.OperatorAddr) + k.SetValidatorByPowerIndex(ctx, validator, pool) return validator, addedShares } @@ -131,33 +140,23 @@ func (k Keeper) AddValidatorTokensAndShares(ctx sdk.Context, validator types.Val func (k Keeper) RemoveValidatorTokensAndShares(ctx sdk.Context, validator types.Validator, sharesToRemove sdk.Dec) (valOut types.Validator, removedTokens sdk.Dec) { - store := ctx.KVStore(k.storeKey) - pool := store.GetPool(ctx) - - store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) - + pool := k.GetPool(ctx) + k.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, removedTokens = validator.RemoveDelShares(pool, sharesToRemove) k.SetValidator(ctx, validator) k.SetPool(ctx, pool) - - valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) - store.Set(valPower, newValidator.OperatorAddr) + k.SetValidatorByPowerIndex(ctx, validator, pool) return validator, removedTokens } // Update the tokens of an existing validator, update the validators power index key func (k Keeper) RemoveValidatorTokens(ctx sdk.Context, validator types.Validator, tokensToRemove sdk.Dec) types.Validator { - store := ctx.KVStore(k.storeKey) - pool := store.GetPool(ctx) - - store.Delete(GetBondedValidatorsByPowerIndexKey(oldValidator, pool)) - - validator, pool = validator.RemoveTokens(pool, tokensToBurn) + pool := k.GetPool(ctx) + k.DeleteValidatorByPowerIndex(ctx, validator, pool) + validator, pool = validator.RemoveTokens(pool, tokensToRemove) k.SetValidator(ctx, validator) k.SetPool(ctx, pool) - - valPower = GetBondedValidatorsByPowerIndexKey(newValidator, pool) - store.Set(valPower, newValidator.OperatorAddr) + k.SetValidatorByPowerIndex(ctx, validator, pool) return validator } @@ -199,10 +198,6 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { return } store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) - - bz := k.cdc.MustMarshalBinary(validator.ABCIValidatorZero()) - tstore := ctx.TransientStore(k.storeTKey) - tstore.Set(GetTendermintUpdatesTKey(address), bz) } //___________________________________________________________________________ diff --git a/x/stake/stake.go b/x/stake/stake.go index 5da9b0083ca1..e1d6f091a745 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -35,35 +35,33 @@ type ( var ( NewKeeper = keeper.NewKeeper - GetValidatorKey = keeper.GetValidatorKey - GetValidatorByConsAddrKey = keeper.GetValidatorByConsAddrKey - GetValidatorsBondedIndexKey = keeper.GetValidatorsBondedIndexKey + GetValidatorKey = keeper.GetValidatorKey + GetValidatorByConsAddrKey = keeper.GetValidatorByConsAddrKey + GetValidatorsBondedIndexKey = keeper.GetValidatorsBondedIndexKey GetBondedValidatorsByPowerIndexKey = keeper.GetBondedValidatorsByPowerIndexKey - GetTendermintUpdatesTKey = keeper.GetTendermintUpdatesTKey - GetDelegationKey = keeper.GetDelegationKey - GetDelegationsKey = keeper.GetDelegationsKey - ParamKey = keeper.ParamKey - PoolKey = keeper.PoolKey - ValidatorsKey = keeper.ValidatorsKey - ValidatorsByConsAddrKey = keeper.ValidatorsByConsAddrKey - ValidatorsBondedIndexKey = keeper.ValidatorsBondedIndexKey - ValidatorsByPowerIndexKey = keeper.ValidatorsByPowerIndexKey - ValidatorCliffIndexKey = keeper.ValidatorCliffIndexKey - ValidatorPowerCliffKey = keeper.ValidatorPowerCliffKey - TendermintUpdatesTKey = keeper.TendermintUpdatesTKey - DelegationKey = keeper.DelegationKey - IntraTxCounterKey = keeper.IntraTxCounterKey - GetUBDKey = keeper.GetUBDKey - GetUBDByValIndexKey = keeper.GetUBDByValIndexKey - GetUBDsKey = keeper.GetUBDsKey - GetUBDsByValIndexKey = keeper.GetUBDsByValIndexKey - GetREDKey = keeper.GetREDKey - GetREDByValSrcIndexKey = keeper.GetREDByValSrcIndexKey - GetREDByValDstIndexKey = keeper.GetREDByValDstIndexKey - GetREDsKey = keeper.GetREDsKey - GetREDsFromValSrcIndexKey = keeper.GetREDsFromValSrcIndexKey - GetREDsToValDstIndexKey = keeper.GetREDsToValDstIndexKey - GetREDsByDelToValDstIndexKey = keeper.GetREDsByDelToValDstIndexKey + GetDelegationKey = keeper.GetDelegationKey + GetDelegationsKey = keeper.GetDelegationsKey + ParamKey = keeper.ParamKey + PoolKey = keeper.PoolKey + ValidatorsKey = keeper.ValidatorsKey + ValidatorsByConsAddrKey = keeper.ValidatorsByConsAddrKey + ValidatorsBondedIndexKey = keeper.ValidatorsBondedIndexKey + ValidatorsByPowerIndexKey = keeper.ValidatorsByPowerIndexKey + ValidatorCliffIndexKey = keeper.ValidatorCliffIndexKey + ValidatorPowerCliffKey = keeper.ValidatorPowerCliffKey + DelegationKey = keeper.DelegationKey + IntraTxCounterKey = keeper.IntraTxCounterKey + GetUBDKey = keeper.GetUBDKey + GetUBDByValIndexKey = keeper.GetUBDByValIndexKey + GetUBDsKey = keeper.GetUBDsKey + GetUBDsByValIndexKey = keeper.GetUBDsByValIndexKey + GetREDKey = keeper.GetREDKey + GetREDByValSrcIndexKey = keeper.GetREDByValSrcIndexKey + GetREDByValDstIndexKey = keeper.GetREDByValDstIndexKey + GetREDsKey = keeper.GetREDsKey + GetREDsFromValSrcIndexKey = keeper.GetREDsFromValSrcIndexKey + GetREDsToValDstIndexKey = keeper.GetREDsToValDstIndexKey + GetREDsByDelToValDstIndexKey = keeper.GetREDsByDelToValDstIndexKey DefaultParams = types.DefaultParams InitialPool = types.InitialPool From e9311958312f6b0b5c9c647614a52319fd70868b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 26 Sep 2018 18:06:52 +0200 Subject: [PATCH 23/52] Remove unnecessary changes --- x/mock/simulation/random_simulate_blocks.go | 1 + x/stake/keeper/validator_test.go | 15 --------------- 2 files changed, 1 insertion(+), 15 deletions(-) diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index 3c9e676a9ae9..ee93cfea393a 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -398,6 +398,7 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, // updateValidators mimicks Tendermint's update logic // nolint: unparam func updateValidators(tb testing.TB, r *rand.Rand, current map[string]mockValidator, updates []abci.ValidatorUpdate, event func(string)) map[string]mockValidator { + for _, update := range updates { switch { case update.Power == 0: diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index c12758de6797..566e8a46f8d5 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -699,21 +699,6 @@ func TestGetValidTendermintUpdatesAllNone(t *testing.T) { updates := keeper.GetValidTendermintUpdates(ctx) assert.Equal(t, 2, len(updates)) - - // test from something to nothing - // tendermintUpdate set: {} -> {c1, c2, c3, c4} - keeper.ClearTendermintUpdates(ctx) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) - - keeper.RemoveValidator(ctx, validators[0].OperatorAddr) - keeper.RemoveValidator(ctx, validators[1].OperatorAddr) - - updates = keeper.GetTendermintUpdates(ctx) - assert.Equal(t, 2, len(updates)) - assert.Equal(t, tmtypes.TM2PB.PubKey(validators[0].ConsPubKey), updates[0].PubKey) - assert.Equal(t, tmtypes.TM2PB.PubKey(validators[1].ConsPubKey), updates[1].PubKey) - assert.Equal(t, int64(0), updates[0].Power) - assert.Equal(t, int64(0), updates[1].Power) assert.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) } From 1013703115e62f80fc81873710b5c0f5e180a906 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 26 Sep 2018 18:20:08 +0200 Subject: [PATCH 24/52] Update context.Verify --- client/context/query.go | 10 +++++----- client/rpc/block.go | 2 +- client/rpc/validators.go | 6 +++--- client/tx/query.go | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/client/context/query.go b/client/context/query.go index 4cd3c427f989..e4e48819047d 100644 --- a/client/context/query.go +++ b/client/context/query.go @@ -14,10 +14,10 @@ import ( "github.com/cosmos/cosmos-sdk/store" abci "github.com/tendermint/tendermint/abci/types" cmn "github.com/tendermint/tendermint/libs/common" - "github.com/tendermint/tendermint/lite" tmliteErr "github.com/tendermint/tendermint/lite/errors" tmliteProxy "github.com/tendermint/tendermint/lite/proxy" rpcclient "github.com/tendermint/tendermint/rpc/client" + tmtypes "github.com/tendermint/tendermint/types" ) // GetNode returns an RPC client. If the context's client is not defined, an @@ -185,13 +185,13 @@ func (ctx CLIContext) query(path string, key cmn.HexBytes) (res []byte, err erro } // Verify verifies the consensus proof at given height. -func (ctx CLIContext) Verify(height int64) (lite.Commit, error) { +func (ctx CLIContext) Verify(height int64) (tmtypes.SignedHeader, error) { check, err := tmliteProxy.GetCertifiedCommit(height, ctx.Client, ctx.Verifier) switch { - case tmliteErr.IsCommitNotFoundErr(err): - return lite.Commit{}, ErrVerifyCommit(height) + case tmliteErr.IsErrCommitNotFound(err): + return tmtypes.SignedHeader{}, ErrVerifyCommit(height) case err != nil: - return lite.Commit{}, err + return tmtypes.SignedHeader{}, err } return check, nil diff --git a/client/rpc/block.go b/client/rpc/block.go index 44def2d3236f..d734dc98981f 100644 --- a/client/rpc/block.go +++ b/client/rpc/block.go @@ -46,7 +46,7 @@ func getBlock(cliCtx context.CLIContext, height *int64) ([]byte, error) { } if !cliCtx.TrustNode { - check, err := cliCtx.Certify(res.Block.Height) + check, err := cliCtx.Verify(res.Block.Height) if err != nil { return nil, err } diff --git a/client/rpc/validators.go b/client/rpc/validators.go index 4802e785b49b..e3fef4c6e61f 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -12,8 +12,8 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" sdk "github.com/cosmos/cosmos-sdk/types" - tmtypes "github.com/tendermint/tendermint/types" "github.com/spf13/viper" + tmtypes "github.com/tendermint/tendermint/types" ) // TODO these next two functions feel kinda hacky based on their placement @@ -76,12 +76,12 @@ func getValidators(cliCtx context.CLIContext, height *int64) ([]byte, error) { } if !cliCtx.TrustNode { - check, err := cliCtx.Certify(validatorsRes.BlockHeight) + check, err := cliCtx.Verify(validatorsRes.BlockHeight) if err != nil { return nil, err } - if !bytes.Equal(check.ValidatorsHash(), tmtypes.NewValidatorSet(validatorsRes.Validators).Hash()) { + if !bytes.Equal(check.ValidatorsHash, tmtypes.NewValidatorSet(validatorsRes.Validators).Hash()) { return nil, fmt.Errorf("got invalid validatorset") } } diff --git a/client/tx/query.go b/client/tx/query.go index f1d13b608a76..a1b7e5552a42 100644 --- a/client/tx/query.go +++ b/client/tx/query.go @@ -3,8 +3,8 @@ package tx import ( "encoding/hex" "fmt" - "net/http" "github.com/tendermint/tendermint/libs/common" + "net/http" "github.com/gorilla/mux" "github.com/spf13/cobra" @@ -83,7 +83,7 @@ func queryTx(cdc *codec.Codec, cliCtx context.CLIContext, hashHexStr string) ([] // ValidateTxResult performs transaction verification func ValidateTxResult(cliCtx context.CLIContext, res *ctypes.ResultTx) error { - check, err := cliCtx.Certify(res.Height) + check, err := cliCtx.Verify(res.Height) if err != nil { return err } From da96e9372756555f3aa166f29067f6ae9f937c7a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 26 Sep 2018 18:23:14 +0200 Subject: [PATCH 25/52] 'make format' --- client/config.go | 14 ++-- client/lcd/certificates.go | 2 +- client/rpc/status.go | 2 +- cmd/gaia/app/benchmarks/txsize_test.go | 2 +- cmd/gaia/cli_test/cli_test.go | 2 +- cmd/gaia/cmd/gaiacli/main.go | 6 +- crypto/keys/keybase.go | 2 +- crypto/keys/keybase_test.go | 4 +- types/address_test.go | 2 +- types/coin_test.go | 4 +- types/utils.go | 2 +- x/stake/keeper/validator_test.go | 88 +++++++++++++------------- 12 files changed, 65 insertions(+), 65 deletions(-) diff --git a/client/config.go b/client/config.go index fcb252375371..a1d38a016ff2 100644 --- a/client/config.go +++ b/client/config.go @@ -1,15 +1,15 @@ package client import ( - "github.com/spf13/cobra" - "github.com/mitchellh/go-homedir" "bufio" - "path" - "os" - "io/ioutil" - "github.com/pelletier/go-toml" "fmt" "github.com/cosmos/cosmos-sdk/types" + "github.com/mitchellh/go-homedir" + "github.com/pelletier/go-toml" + "github.com/spf13/cobra" + "io/ioutil" + "os" + "path" ) type cliConfig struct { @@ -34,7 +34,7 @@ func ConfigCmd() *cobra.Command { return cfg } -func runConfigCmd(cmd *cobra.Command, args [] string) error { +func runConfigCmd(cmd *cobra.Command, args []string) error { home, err := homedir.Dir() if err != nil { return err diff --git a/client/lcd/certificates.go b/client/lcd/certificates.go index f47f2397c72e..1516ed35afaf 100644 --- a/client/lcd/certificates.go +++ b/client/lcd/certificates.go @@ -43,7 +43,7 @@ func generateSelfSignedCert(host string) (certBytes []byte, priv *ecdsa.PrivateK KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, - IsCA: true, + IsCA: true, } hosts := strings.Split(host, ",") for _, h := range hosts { diff --git a/client/rpc/status.go b/client/rpc/status.go index 6c427017544a..049910ed1082 100644 --- a/client/rpc/status.go +++ b/client/rpc/status.go @@ -9,8 +9,8 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" - ctypes "github.com/tendermint/tendermint/rpc/core/types" "github.com/spf13/viper" + ctypes "github.com/tendermint/tendermint/rpc/core/types" ) func statusCommand() *cobra.Command { diff --git a/cmd/gaia/app/benchmarks/txsize_test.go b/cmd/gaia/app/benchmarks/txsize_test.go index 83e51c041681..186ad87e5867 100644 --- a/cmd/gaia/app/benchmarks/txsize_test.go +++ b/cmd/gaia/app/benchmarks/txsize_test.go @@ -26,7 +26,7 @@ func ExampleTxSendSize() { Outputs: []bank.Output{bank.NewOutput(addr2, coins)}, } sig, _ := priv1.Sign(msg1.GetSignBytes()) - sigs := []auth.StdSignature{auth.StdSignature{nil, sig, 0, 0}} + sigs := []auth.StdSignature{{nil, sig, 0, 0}} tx := auth.NewStdTx([]sdk.Msg{msg1}, auth.NewStdFee(0, coins...), sigs, "") fmt.Println(len(cdc.MustMarshalBinaryBare([]sdk.Msg{msg1}))) fmt.Println(len(cdc.MustMarshalBinaryBare(tx))) diff --git a/cmd/gaia/cli_test/cli_test.go b/cmd/gaia/cli_test/cli_test.go index 5b204f4df78d..04bc4c84a590 100644 --- a/cmd/gaia/cli_test/cli_test.go +++ b/cmd/gaia/cli_test/cli_test.go @@ -7,8 +7,8 @@ import ( "fmt" "io/ioutil" "os" - "testing" "path" + "testing" "github.com/stretchr/testify/require" diff --git a/cmd/gaia/cmd/gaiacli/main.go b/cmd/gaia/cmd/gaiacli/main.go index 2f66caadd6c5..5be9d76e8224 100644 --- a/cmd/gaia/cmd/gaiacli/main.go +++ b/cmd/gaia/cmd/gaiacli/main.go @@ -18,9 +18,9 @@ import ( stakecmd "github.com/cosmos/cosmos-sdk/x/stake/client/cli" "github.com/cosmos/cosmos-sdk/cmd/gaia/app" - "path" - "os" "github.com/spf13/viper" + "os" + "path" ) const ( @@ -152,7 +152,7 @@ func initConfig(cmd *cobra.Command) error { } if err := viper.BindPFlag(cli.EncodingFlag, cmd.PersistentFlags().Lookup(cli.EncodingFlag)); err != nil { - return err + return err } return viper.BindPFlag(cli.OutputFlag, cmd.PersistentFlags().Lookup(cli.OutputFlag)) } diff --git a/crypto/keys/keybase.go b/crypto/keys/keybase.go index c9bfd0812970..99632e764268 100644 --- a/crypto/keys/keybase.go +++ b/crypto/keys/keybase.go @@ -9,12 +9,12 @@ import ( "github.com/cosmos/cosmos-sdk/crypto" "github.com/cosmos/cosmos-sdk/crypto/keys/bip39" "github.com/cosmos/cosmos-sdk/crypto/keys/hd" + "github.com/cosmos/cosmos-sdk/types" "github.com/pkg/errors" tmcrypto "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/encoding/amino" "github.com/tendermint/tendermint/crypto/secp256k1" dbm "github.com/tendermint/tendermint/libs/db" - "github.com/cosmos/cosmos-sdk/types" ) var _ Keybase = dbKeybase{} diff --git a/crypto/keys/keybase_test.go b/crypto/keys/keybase_test.go index 2a602461a162..3273c229afe6 100644 --- a/crypto/keys/keybase_test.go +++ b/crypto/keys/keybase_test.go @@ -10,8 +10,8 @@ import ( "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - dbm "github.com/tendermint/tendermint/libs/db" "github.com/cosmos/cosmos-sdk/types" + dbm "github.com/tendermint/tendermint/libs/db" ) func init() { @@ -403,4 +403,4 @@ func ExampleNew() { func accAddr(info Info) types.AccAddress { return (types.AccAddress)(info.GetPubKey().Address()) -} \ No newline at end of file +} diff --git a/types/address_test.go b/types/address_test.go index 6c6c78d6ec5b..e2ec36876cd5 100644 --- a/types/address_test.go +++ b/types/address_test.go @@ -10,7 +10,7 @@ import ( "github.com/tendermint/tendermint/crypto/ed25519" "github.com/cosmos/cosmos-sdk/types" - ) +) var invalidStrs = []string{ "", diff --git a/types/coin_test.go b/types/coin_test.go index ba7038010a38..bc0441279155 100644 --- a/types/coin_test.go +++ b/types/coin_test.go @@ -443,7 +443,7 @@ func BenchmarkCoinsAdditionIntersect(b *testing.B) { } } - benchmarkSizes := [][]int{[]int{1, 1}, []int{5, 5}, []int{5, 20}, []int{1, 1000}, []int{2, 1000}} + benchmarkSizes := [][]int{{1, 1}, {5, 5}, {5, 20}, {1, 1000}, {2, 1000}} for i := 0; i < len(benchmarkSizes); i++ { sizeA := benchmarkSizes[i][0] sizeB := benchmarkSizes[i][1] @@ -469,7 +469,7 @@ func BenchmarkCoinsAdditionNoIntersect(b *testing.B) { } } - benchmarkSizes := [][]int{[]int{1, 1}, []int{5, 5}, []int{5, 20}, []int{1, 1000}, []int{2, 1000}, []int{1000, 2}} + benchmarkSizes := [][]int{{1, 1}, {5, 5}, {5, 20}, {1, 1000}, {2, 1000}, {1000, 2}} for i := 0; i < len(benchmarkSizes); i++ { sizeA := benchmarkSizes[i][0] sizeB := benchmarkSizes[i][1] diff --git a/types/utils.go b/types/utils.go index 95fc779d7375..b196acb230c0 100644 --- a/types/utils.go +++ b/types/utils.go @@ -51,4 +51,4 @@ func DefaultChainID() (string, error) { } return doc.ChainID, nil -} \ No newline at end of file +} diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 566e8a46f8d5..7533fed6e928 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -71,7 +71,7 @@ func TestSetValidator(t *testing.T) { require.Equal(t, 1, len(resVals)) require.True(ValEq(t, validator, resVals[0])) - updates := keeper.GetValidTendermintUpdates(ctx) + updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) @@ -675,7 +675,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { assert.True(ValEq(t, validators[2], resValidators[1])) } -func TestGetValidTendermintUpdatesAllNone(t *testing.T) { +func TestGetTendermintUpdatesAllNone(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20} @@ -693,17 +693,17 @@ func TestGetValidTendermintUpdatesAllNone(t *testing.T) { // test from nothing to something // tendermintUpdate set: {} -> {c1, c3} - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) validators[0] = keeper.UpdateValidator(ctx, validators[0]) validators[1] = keeper.UpdateValidator(ctx, validators[1]) - updates := keeper.GetValidTendermintUpdates(ctx) + updates := keeper.GetTendermintUpdates(ctx) assert.Equal(t, 2, len(updates)) assert.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) } -func TestGetValidTendermintUpdatesIdentical(t *testing.T) { +func TestGetTendermintUpdatesIdentical(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20} @@ -717,16 +717,16 @@ func TestGetValidTendermintUpdatesIdentical(t *testing.T) { validators[0] = keeper.UpdateValidator(ctx, validators[0]) validators[1] = keeper.UpdateValidator(ctx, validators[1]) clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test identical, // tendermintUpdate set: {} -> {} validators[0] = keeper.UpdateValidator(ctx, validators[0]) validators[1] = keeper.UpdateValidator(ctx, validators[1]) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) } -func TestGetValidTendermintUpdatesSingleValueChange(t *testing.T) { +func TestGetTendermintUpdatesSingleValueChange(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20} @@ -740,7 +740,7 @@ func TestGetValidTendermintUpdatesSingleValueChange(t *testing.T) { validators[0] = keeper.UpdateValidator(ctx, validators[0]) validators[1] = keeper.UpdateValidator(ctx, validators[1]) clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test single value change // tendermintUpdate set: {} -> {c1'} @@ -748,13 +748,13 @@ func TestGetValidTendermintUpdatesSingleValueChange(t *testing.T) { validators[0].Tokens = sdk.NewDec(600) validators[0] = keeper.UpdateValidator(ctx, validators[0]) - updates := keeper.GetValidTendermintUpdates(ctx) + updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) } -func TestGetValidTendermintUpdatesMultipleValueChange(t *testing.T) { +func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20} @@ -768,7 +768,7 @@ func TestGetValidTendermintUpdatesMultipleValueChange(t *testing.T) { validators[0] = keeper.UpdateValidator(ctx, validators[0]) validators[1] = keeper.UpdateValidator(ctx, validators[1]) clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test multiple value change // tendermintUpdate set: {c1, c3} -> {c1', c3'} @@ -779,13 +779,13 @@ func TestGetValidTendermintUpdatesMultipleValueChange(t *testing.T) { validators[0] = keeper.UpdateValidator(ctx, validators[0]) validators[1] = keeper.UpdateValidator(ctx, validators[1]) - updates := keeper.GetValidTendermintUpdates(ctx) + updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates)) require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) } -func TestGetValidTendermintUpdatesInserted(t *testing.T) { +func TestGetTendermintUpdatesInserted(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20, 5, 15, 25} @@ -799,12 +799,12 @@ func TestGetValidTendermintUpdatesInserted(t *testing.T) { validators[0] = keeper.UpdateValidator(ctx, validators[0]) validators[1] = keeper.UpdateValidator(ctx, validators[1]) clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test validtor added at the beginning // tendermintUpdate set: {} -> {c0} validators[2] = keeper.UpdateValidator(ctx, validators[2]) - updates := keeper.GetValidTendermintUpdates(ctx) + updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) @@ -812,7 +812,7 @@ func TestGetValidTendermintUpdatesInserted(t *testing.T) { // tendermintUpdate set: {} -> {c0} clearTendermintUpdates(ctx, keeper) validators[3] = keeper.UpdateValidator(ctx, validators[3]) - updates = keeper.GetValidTendermintUpdates(ctx) + updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[3].ABCIValidatorUpdate(), updates[0]) @@ -820,12 +820,12 @@ func TestGetValidTendermintUpdatesInserted(t *testing.T) { // tendermintUpdate set: {} -> {c0} clearTendermintUpdates(ctx, keeper) validators[4] = keeper.UpdateValidator(ctx, validators[4]) - updates = keeper.GetValidTendermintUpdates(ctx) + updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[4].ABCIValidatorUpdate(), updates[0]) } -func TestGetValidTendermintUpdatesWithCliffValidator(t *testing.T) { +func TestGetTendermintUpdatesWithCliffValidator(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) params := types.DefaultParams() params.MaxValidators = 2 @@ -842,31 +842,31 @@ func TestGetValidTendermintUpdatesWithCliffValidator(t *testing.T) { validators[0] = keeper.UpdateValidator(ctx, validators[0]) validators[1] = keeper.UpdateValidator(ctx, validators[1]) clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test validator added at the end but not inserted in the valset // tendermintUpdate set: {} -> {} keeper.UpdateValidator(ctx, validators[2]) - updates := keeper.GetValidTendermintUpdates(ctx) + updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 0, len(updates)) // test validator change its power and become a gotValidator (pushing out an existing) // tendermintUpdate set: {} -> {c0, c4} clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) pool := keeper.GetPool(ctx) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(10)) keeper.SetPool(ctx, pool) validators[2] = keeper.UpdateValidator(ctx, validators[2]) - updates = keeper.GetValidTendermintUpdates(ctx) + updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates), "%v", updates) require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[0]) require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[1]) } -func TestGetValidTendermintUpdatesPowerDecrease(t *testing.T) { +func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{100, 100} @@ -880,7 +880,7 @@ func TestGetValidTendermintUpdatesPowerDecrease(t *testing.T) { validators[0] = keeper.UpdateValidator(ctx, validators[0]) validators[1] = keeper.UpdateValidator(ctx, validators[1]) clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // check initial power require.Equal(t, sdk.NewDec(100).RoundInt64(), validators[0].GetPower().RoundInt64()) @@ -900,13 +900,13 @@ func TestGetValidTendermintUpdatesPowerDecrease(t *testing.T) { require.Equal(t, sdk.NewDec(70).RoundInt64(), validators[1].GetPower().RoundInt64()) // Tendermint updates should reflect power change - updates := keeper.GetValidTendermintUpdates(ctx) + updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates)) require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) } -func TestGetValidTendermintUpdatesNewValidator(t *testing.T) { +func TestGetTendermintUpdatesNewValidator(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) params := keeper.GetParams(ctx) params.MaxValidators = uint16(3) @@ -930,13 +930,13 @@ func TestGetValidTendermintUpdatesNewValidator(t *testing.T) { } // verify initial Tendermint updates are correct - updates := keeper.GetValidTendermintUpdates(ctx) + updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, len(validators), len(updates)) - require.Equal(t, validators[0].ABCIValidator(), updates[0]) - require.Equal(t, validators[1].ABCIValidator(), updates[1]) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // update initial validator set for i, amt := range amts { @@ -974,14 +974,14 @@ func TestGetValidTendermintUpdatesNewValidator(t *testing.T) { validator = keeper.UpdateValidator(ctx, validator) // verify initial Tendermint updates are correct - updates = keeper.GetValidTendermintUpdates(ctx) + updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, len(validators)+1, len(updates)) - require.Equal(t, validator.ABCIValidator(), updates[0]) - require.Equal(t, validators[0].ABCIValidator(), updates[1]) - require.Equal(t, validators[1].ABCIValidator(), updates[2]) + require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[2]) } -func TestGetValidTendermintUpdatesBondTransition(t *testing.T) { +func TestGetTendermintUpdatesBondTransition(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) params := keeper.GetParams(ctx) params.MaxValidators = uint16(2) @@ -1006,13 +1006,13 @@ func TestGetValidTendermintUpdatesBondTransition(t *testing.T) { } // verify initial Tendermint updates are correct - updates := keeper.GetValidTendermintUpdates(ctx) + updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates)) - require.Equal(t, validators[2].ABCIValidator(), updates[0]) - require.Equal(t, validators[1].ABCIValidator(), updates[1]) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // delegate to validator with lowest power but not enough to bond ctx = ctx.WithBlockHeight(1) @@ -1027,7 +1027,7 @@ func TestGetValidTendermintUpdatesBondTransition(t *testing.T) { validators[0] = keeper.UpdateValidator(ctx, validator) // verify initial Tendermint updates are correct - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // create a series of events that will bond and unbond the validator with // lowest power in a single block context (height) @@ -1048,12 +1048,12 @@ func TestGetValidTendermintUpdatesBondTransition(t *testing.T) { validators[1] = keeper.UpdateValidator(ctx, validator) // verify initial Tendermint updates are correct - updates = keeper.GetValidTendermintUpdates(ctx) + updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) - require.Equal(t, validators[1].ABCIValidator(), updates[0]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) clearTendermintUpdates(ctx, keeper) - require.Equal(t, 0, len(keeper.GetValidTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) } func TestUpdateValidatorCommission(t *testing.T) { From fd36abfe0549fdf75715b892984514a6e2176efb Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 27 Sep 2018 12:41:24 +0200 Subject: [PATCH 26/52] Use own directory, fix tx size test, remove parseCmnError --- client/context/context.go | 17 +++++++++++++---- cmd/gaia/app/benchmarks/txsize_test.go | 2 +- types/errors.go | 19 +++---------------- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/client/context/context.go b/client/context/context.go index 589137407f71..5c30a6216a4f 100644 --- a/client/context/context.go +++ b/client/context/context.go @@ -4,6 +4,8 @@ import ( "bytes" "fmt" "io" + "os" + "path/filepath" "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/codec" @@ -19,11 +21,14 @@ import ( tmlite "github.com/tendermint/tendermint/lite" tmliteProxy "github.com/tendermint/tendermint/lite/proxy" rpcclient "github.com/tendermint/tendermint/rpc/client" - "os" ) const ctxAccStoreName = "acc" +var ( + verifier tmlite.Verifier +) + // CLIContext implements a typical CLI context created in SDK modules for // transaction handling and queries. type CLIContext struct { @@ -60,6 +65,11 @@ func NewCLIContext() CLIContext { from := viper.GetString(client.FlagFrom) fromAddress, fromName := fromFields(from) + // We need to use a single verifier for all contexts + if verifier == nil { + verifier = createVerifier() + } + return CLIContext{ Client: rpc, NodeURI: nodeURI, @@ -71,7 +81,7 @@ func NewCLIContext() CLIContext { Async: viper.GetBool(client.FlagAsync), JSON: viper.GetBool(client.FlagJson), PrintResponse: viper.GetBool(client.FlagPrintResponse), - Verifier: createVerifier(), + Verifier: verifier, DryRun: viper.GetBool(client.FlagDryRun), GenerateOnly: viper.GetBool(client.FlagGenerateOnly), fromAddress: fromAddress, @@ -109,8 +119,7 @@ func createVerifier() tmlite.Verifier { os.Exit(1) } node := rpcclient.NewHTTP(nodeURI, "/websocket") - // TODO Utilize ctx.Logger correctly - verifier, err := tmliteProxy.NewVerifier(chainID, home, node, log.NewNopLogger()) + verifier, err := tmliteProxy.NewVerifier(chainID, filepath.Join(home, ".gaialite"), node, log.NewNopLogger()) if err != nil { fmt.Printf("Create verifier failed: %s\n", err.Error()) diff --git a/cmd/gaia/app/benchmarks/txsize_test.go b/cmd/gaia/app/benchmarks/txsize_test.go index 186ad87e5867..24789b10edf8 100644 --- a/cmd/gaia/app/benchmarks/txsize_test.go +++ b/cmd/gaia/app/benchmarks/txsize_test.go @@ -31,5 +31,5 @@ func ExampleTxSendSize() { fmt.Println(len(cdc.MustMarshalBinaryBare([]sdk.Msg{msg1}))) fmt.Println(len(cdc.MustMarshalBinaryBare(tx))) // output: 80 - // 173 + // 167 } diff --git a/types/errors.go b/types/errors.go index 46bf748f48de..abb0c3921d04 100644 --- a/types/errors.go +++ b/types/errors.go @@ -2,7 +2,6 @@ package types import ( "fmt" - "strings" "github.com/cosmos/cosmos-sdk/codec" cmn "github.com/tendermint/tendermint/libs/common" @@ -231,13 +230,8 @@ func (err *sdkError) TraceSDK(format string, args ...interface{}) Error { } // Implements ABCIError. -// Overrides err.Error.Error(). func (err *sdkError) Error() string { - return fmt.Sprintf(`ERROR: -Codespace: %d -Code: %d -Message: %#v -`, err.codespace, err.code, parseCmnError(err.cmnError.Error())) + return err.cmnError.Error() } // Implements ABCIError. @@ -258,12 +252,12 @@ func (err *sdkError) Code() CodeType { // Implements ABCIError. func (err *sdkError) ABCILog() string { cdc := codec.New() - parsedErrMsg := parseCmnError(err.cmnError.Error()) + errMsg := err.cmnError.Error() jsonErr := humanReadableError{ Codespace: err.codespace, Code: err.code, ABCICode: err.ABCICode(), - Message: parsedErrMsg, + Message: errMsg, } bz, er := cdc.MarshalJSON(jsonErr) if er != nil { @@ -288,13 +282,6 @@ func (err *sdkError) QueryResult() abci.ResponseQuery { } } -func parseCmnError(err string) string { - if idx := strings.Index(err, "{"); idx != -1 { - err = err[idx+1 : len(err)-1] - } - return err -} - // nolint type humanReadableError struct { Codespace CodespaceType `json:"codespace"` From f2422cd9746910432ee36773a66e726795143010 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 27 Sep 2018 12:48:05 +0200 Subject: [PATCH 27/52] Keep code, codespace --- types/errors.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/types/errors.go b/types/errors.go index abb0c3921d04..266e6d14c331 100644 --- a/types/errors.go +++ b/types/errors.go @@ -231,7 +231,11 @@ func (err *sdkError) TraceSDK(format string, args ...interface{}) Error { // Implements ABCIError. func (err *sdkError) Error() string { - return err.cmnError.Error() + return fmt.Sprintf(`ERROR: +Codespace: %d +Code: %d +Message: %#v +`, err.codespace, err.code, err.cmnError.Error()) } // Implements ABCIError. From 54098df12ed5481c9381802f05478bd7ea7afaf9 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 27 Sep 2018 15:51:36 +0200 Subject: [PATCH 28/52] Remove old code, minor cleanup of existing work --- x/stake/genesis.go | 8 +- x/stake/keeper/val_state_change.go | 183 +---------------------------- x/stake/keeper/validator_test.go | 2 +- 3 files changed, 4 insertions(+), 189 deletions(-) diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 1f1d1d9f8a70..908c56e88385 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -44,13 +44,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ keeper.SetDelegation(ctx, bond) } - //keeper.UpdateBondedValidatorsFull(ctx) // XXX TODO must calculate the genesis validator set - - vals := keeper.GetValidatorsBonded(ctx) - res = make([]abci.Validator, len(vals)) - for i, val := range vals { - res[i] = sdk.ABCIValidator(val) - } + res = keeper.GetTendermintUpdates(ctx) return } diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 10c65bb98caf..de8873346643 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -59,17 +59,7 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) return updates } -// XXX FOR REFERENCE USE OR DELETED -func kickOutValidators(k Keeper, ctx sdk.Context, toKickOut map[string]byte) { - for key := range toKickOut { - ownerAddr := []byte(key) - validator := k.mustGetValidator(ctx, ownerAddr) - k.beginUnbondingValidator(ctx, validator) - } -} - -//___________________________________________________________________________ -// State transitions +// Validator state transitions func (k Keeper) bondedToUnbonding(ctx sdk.Context, validator types.Validator) { if validator.Status != sdk.Bonded { @@ -99,8 +89,6 @@ func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) k.completeUnbondingValidator(ctx, validator) } -//________________________________________________________________________________________________ - // send a validator to jail func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { if validator.Jailed { @@ -117,7 +105,7 @@ func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { // remove a validator from jail func (k Keeper) UnjailValidator(ctx sdk.Context, validator types.Validator) { if !validator.Jailed { - panic(fmt.Sprintf("cannot jail already jailed validator, validator: %v\n", validator)) + panic(fmt.Sprintf("cannot unjail already unjailed validator, validator: %v\n", validator)) } pool := k.GetPool(ctx) @@ -203,8 +191,6 @@ func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Vali k.SetValidator(ctx, validator) } -//______________________________________________________________________________________________________ - // XXX need to figure out how to set a validator's BondIntraTxCounter - probably during delegation bonding? // or keep track of tx for final bonding and set during endblock??? wish we could reduce this complexity @@ -227,168 +213,3 @@ func (k Keeper) bondIncrement(ctx sdk.Context, isNewValidator bool, validator ty k.SetIntraTxCounter(ctx, counter+1) return } - -//______________________________________________________________________________________________________ -/* -// XXX Delete this reference function before merge -// Perform all the necessary steps for when a validator changes its power. This -// function updates all validator stores as well as tendermint update store. -// It may kick out validators if a new validator is entering the bonded validator -// group. -// -// TODO: Remove above nolint, function needs to be simplified! -func (k Keeper) REFERENCEXXXDELETEUpdateValidator(ctx sdk.Context, validator types.Validator) types.Validator { - tstore := ctx.TransientStore(k.storeTKey) - pool := k.GetPool(ctx) - oldValidator, oldFound := k.GetValidator(ctx, validator.OperatorAddr) - - validator = k.updateForJailing(ctx, oldFound, oldValidator, validator) - powerIncreasing := k.getPowerIncreasing(ctx, oldFound, oldValidator, validator) - validator.BondHeight, validator.BondIntraTxCounter = k.bondIncrement(ctx, oldFound, oldValidator) - valPower := k.updateValidatorPower(ctx, oldFound, oldValidator, validator, pool) - - switch { - - // if the validator is already bonded and the power is increasing, we need - // perform the following: - // a) update Tendermint - // b) check if the cliff validator needs to be updated - case powerIncreasing && !validator.Jailed && - (oldFound && oldValidator.Status == sdk.Bonded): - - bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bz) - - if cliffValExists { - cliffAddr := sdk.ValAddress(k.GetCliffValidator(ctx)) - if bytes.Equal(cliffAddr, validator.OperatorAddr) { - k.updateCliffValidator(ctx, validator) - } - } - - // if is a new validator and the new power is less than the cliff validator - case cliffValExists && !oldFound && valPowerLTcliffPower: - // skip to completion - - // if was unbonded and the new power is less than the cliff validator - case cliffValExists && - (oldFound && oldValidator.Status == sdk.Unbonded) && - valPowerLTcliffPower: //(valPower < cliffPower - // skip to completion - - default: - // default case - validator was either: - // a) not-bonded and now has power-rank greater than cliff validator - // b) bonded and now has decreased in power - - // update the validator set for this validator - updatedVal, updated := k.UpdateBondedValidators(ctx, validator) - if updated { - // the validator has changed bonding status - validator = updatedVal - break - } - - // if decreased in power but still bonded, update Tendermint validator - if oldFound && oldValidator.BondedTokens().GT(validator.BondedTokens()) { - bz := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bz) - } - } - - k.SetValidator(ctx, validator) - return validator -} - -// XXX Delete this reference function before merge -// Update the bonded validator group based on a change to the validator -// affectedValidator. This function potentially adds the affectedValidator to -// the bonded validator group which kicks out the cliff validator. Under this -// situation this function returns the updated affectedValidator. -// -// The correct bonded subset of validators is retrieved by iterating through an -// index of the validators sorted by power, stored using the -// ValidatorsByPowerIndexKey. Simultaneously the current validator records are -// updated in store with the ValidatorsBondedIndexKey. This store is used to -// determine if a validator is a validator without needing to iterate over all -// validators. -func (k Keeper) XXXREFERENCEUpdateBondedValidators( - ctx sdk.Context, affectedValidator types.Validator) ( - updatedVal types.Validator, updated bool) { - - store := ctx.KVStore(k.storeKey) - - oldCliffValidatorAddr := k.GetCliffValidator(ctx) - maxValidators := k.GetParams(ctx).MaxValidators - bondedValidatorsCount := 0 - var validator, validatorToBond types.Validator - //newValidatorBonded := false - - // create a validator iterator ranging from largest to smallest by power - iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) - for ; iterator.Valid() && bondedValidatorsCount < int(maxValidators); iterator.Next() { - - // either retrieve the original validator from the store, or under the - // situation that this is the "affected validator" just use the - // validator provided because it has not yet been updated in the store - ownerAddr := iterator.Value() - if bytes.Equal(ownerAddr, affectedValidator.OperatorAddr) { - validator = affectedValidator - } else { - var found bool - validator = k.mustGetValidator(ctx, ownerAddr) - } - - // if we've reached jailed validators no further bonded validators exist - if validator.Jailed { - if validator.Status == sdk.Bonded { - panic(fmt.Sprintf("jailed validator cannot be bonded, address: %X\n", ownerAddr)) - } - - break - } - - // increment the total number of bonded validators and potentially mark - // the validator to bond - if validator.Status != sdk.Bonded { - validatorToBond = validator - if newValidatorBonded { - panic("already decided to bond a validator, can't bond another!") - } - newValidatorBonded = true - } - - bondedValidatorsCount++ - } - - iterator.Close() - - // swap the cliff validator for a new validator if the affected validator - // was bonded - if newValidatorBonded { - if oldCliffValidatorAddr != nil { - oldCliffVal := k.mustGetValidator(ctx, oldCliffValidatorAddr) - - if bytes.Equal(validatorToBond.OperatorAddr, affectedValidator.OperatorAddr) { - - // begin unbonding the old cliff validator iff the affected - // validator was newly bonded and has greater power - k.beginUnbondingValidator(ctx, oldCliffVal) - } else { - // otherwise begin unbonding the affected validator, which must - // have been kicked out - affectedValidator = k.beginUnbondingValidator(ctx, affectedValidator) - } - } - - validator = k.bondValidator(ctx, validatorToBond) - if bytes.Equal(validator.OperatorAddr, affectedValidator.OperatorAddr) { - return validator, true - } - - return affectedValidator, true - } - - return types.Validator{}, false -} -*/ diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index ab6ac7e72520..b5f1bc07fa3e 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -27,7 +27,7 @@ func clearTendermintUpdates(ctx sdk.Context, k Keeper) { func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool { store := ctx.KVStore(k.storeKey) - return store.Get(power) != nil + return store.Has(power) } //_______________________________________________________ From e2200a250356ef08bd9456e73ed4365f92036d92 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 27 Sep 2018 16:02:35 +0200 Subject: [PATCH 29/52] Fixes from merge --- x/stake/keeper/val_state_change.go | 2 +- x/stake/keeper/validator.go | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index de8873346643..c0c880a1bc23 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -17,7 +17,7 @@ import ( // CONTRACT: Only validators with non-zero power or zero-power that were bonded // at the previous block height or were removed from the validator set entirely // are returned to Tendermint. -func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.Validator) { +func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorUpdate) { // REF CODE //// add to accumulated changes for tendermint diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index c2b9b862125a..5024ba17e4e6 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -3,9 +3,7 @@ package keeper import ( "container/list" "fmt" - - abci "github.com/tendermint/tendermint/abci/types" - tmtypes "github.com/tendermint/tendermint/types" + sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/stake/types" ) @@ -284,4 +282,4 @@ func (k Keeper) GetBondedValidatorsByPower(ctx sdk.Context) []types.Validator { } } return validators[:i] // trim -} \ No newline at end of file +} From 174b321d401383f5199cdcee9aaea6828ab1d292 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 27 Sep 2018 16:36:00 +0200 Subject: [PATCH 30/52] Pseudocode to real-ish code --- x/stake/keeper/val_state_change.go | 47 ++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index c0c880a1bc23..8bfc64c6a930 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -19,6 +19,53 @@ import ( // are returned to Tendermint. func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorUpdate) { + var last map[string]interface{} + + store := ctx.KVStore(k.storeKey) + maxValidators := k.GetParams(ctx).MaxValidators + + iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) + count := 0 + for ; iterator.Valid() && count < int(maxValidators); iterator.Next() { + + // fetch the validator + operator := sdk.ValAddress(iterator.Value()) + validator := k.mustGetValidator(ctx, operator) + + // jailed validators are ranked last, so if we get to a jailed validator + // we have no more bonded validators + if validator.Jailed { + break + } + + // apply the appropriate state change if necessary + switch validator.Status { + case sdk.Unbonded: + k.unbondedToBonded(ctx, validator) + case sdk.Unbonding: + k.unbondingToBonded(ctx, validator) + case sdk.Bonded: + // no state change + } + + // update the validator (power might have changed) + updates = append(updates, validator.ABCIValidatorUpdate()) + + // validator still in the validator set + delete(last, string(operator)) + + // keep count + count++ + + } + + // any validators left in `last` are no longer bonded + for operator, _ := range last { + validator := k.mustGetValidator(ctx, []byte(operator)) + k.bondedToUnbonding(ctx, validator) + updates = append(updates, validator.ABCIValidatorUpdateZero()) + } + // REF CODE //// add to accumulated changes for tendermint //bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidator()) From 715ad0425f0209ed06a9a22277e1847527229421 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 27 Sep 2018 17:58:18 +0200 Subject: [PATCH 31/52] Remove cliff validator key (no longer used) --- x/stake/keeper/key.go | 24 +++++++++++++----------- x/stake/stake.go | 2 -- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index 8bd0de35ad40..2de4ac37c794 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -18,17 +18,14 @@ var ( ValidatorsByConsAddrKey = []byte{0x03} // prefix for each key to a validator index, by pubkey ValidatorsBondedIndexKey = []byte{0x04} // prefix for each key to a validator index, for bonded validators ValidatorsByPowerIndexKey = []byte{0x05} // prefix for each key to a validator index, sorted by power - ValidatorCliffIndexKey = []byte{0x06} // key for the validator index of the cliff validator - ValidatorPowerCliffKey = []byte{0x07} // key for the power of the validator on the cliff - IntraTxCounterKey = []byte{0x08} // key for intra-block tx index - DelegationKey = []byte{0x09} // key for a delegation - UnbondingDelegationKey = []byte{0x0A} // key for an unbonding-delegation - UnbondingDelegationByValIndexKey = []byte{0x0B} // prefix for each key for an unbonding-delegation, by validator operator - RedelegationKey = []byte{0x0C} // key for a redelegation - RedelegationByValSrcIndexKey = []byte{0x0D} // prefix for each key for an redelegation, by source validator operator - RedelegationByValDstIndexKey = []byte{0x0E} // prefix for each key for an redelegation, by destination validator operator - - // XXX remove this comment? Keys for store prefixes (transient) + IntraTxCounterKey = []byte{0x06} // key for intra-block tx index + DelegationKey = []byte{0x07} // key for a delegation + UnbondingDelegationKey = []byte{0x08} // key for an unbonding-delegation + UnbondingDelegationByValIndexKey = []byte{0x09} // prefix for each key for an unbonding-delegation, by validator operator + RedelegationKey = []byte{0x0A} // key for a redelegation + RedelegationByValSrcIndexKey = []byte{0x0B} // prefix for each key for an redelegation, by source validator operator + RedelegationByValDstIndexKey = []byte{0x0C} // prefix for each key for an redelegation, by destination validator operator + BondedValidatorsIndexKey = []byte{0x0D} // prefix for each key to the bonded validator set ) const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch @@ -65,6 +62,11 @@ func GetBondedValidatorsByPowerIndexKey(validator types.Validator, pool types.Po return getValidatorPowerRank(validator, pool) } +// get the bonded validator index key for an operator address +func GetBondedValidatorIndexKey(operator sdk.ValAddress) []byte { + return append(BondedValidatorsIndexKey, operator...) +} + // get the power ranking of a validator // NOTE the larger values are of higher value // nolint: unparam diff --git a/x/stake/stake.go b/x/stake/stake.go index e1d6f091a745..817f73ca311d 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -47,8 +47,6 @@ var ( ValidatorsByConsAddrKey = keeper.ValidatorsByConsAddrKey ValidatorsBondedIndexKey = keeper.ValidatorsBondedIndexKey ValidatorsByPowerIndexKey = keeper.ValidatorsByPowerIndexKey - ValidatorCliffIndexKey = keeper.ValidatorCliffIndexKey - ValidatorPowerCliffKey = keeper.ValidatorPowerCliffKey DelegationKey = keeper.DelegationKey IntraTxCounterKey = keeper.IntraTxCounterKey GetUBDKey = keeper.GetUBDKey From ba3c1f53770b294ace4691111378551fded95e59 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 28 Sep 2018 13:48:51 +0200 Subject: [PATCH 32/52] GetTendermintUpdates continued --- x/stake/keeper/val_state_change.go | 83 ++++++++++++++---------------- 1 file changed, 40 insertions(+), 43 deletions(-) diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 8bfc64c6a930..022c5030f7b8 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -1,7 +1,9 @@ package keeper import ( + "bytes" "fmt" + "sort" abci "github.com/tendermint/tendermint/abci/types" @@ -19,12 +21,19 @@ import ( // are returned to Tendermint. func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorUpdate) { - var last map[string]interface{} - store := ctx.KVStore(k.storeKey) maxValidators := k.GetParams(ctx).MaxValidators - iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) + // copy last validator set + var last map[[sdk.AddrLen]byte]interface{} + iterator := sdk.KVStorePrefixIterator(store, BondedValidatorsIndexKey) + for ; iterator.Valid(); iterator.Next() { + var operator [sdk.AddrLen]byte + copy(operator[:], iterator.Key()) + last[operator] = nil + } + + iterator = sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) count := 0 for ; iterator.Valid() && count < int(maxValidators); iterator.Next() { @@ -52,56 +61,44 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU updates = append(updates, validator.ABCIValidatorUpdate()) // validator still in the validator set - delete(last, string(operator)) + var opbytes [sdk.AddrLen]byte + copy(opbytes[:], operator) + delete(last, opbytes) + + // set the bonded validator index + store.Set(GetBondedValidatorIndexKey(operator), []byte{}) // keep count count++ } - // any validators left in `last` are no longer bonded - for operator, _ := range last { - validator := k.mustGetValidator(ctx, []byte(operator)) - k.bondedToUnbonding(ctx, validator) - updates = append(updates, validator.ABCIValidatorUpdateZero()) + // sort the map keys for determinism + noLongerBonded := make([][]byte, len(last)) + for oper, _ := range last { + var operator []byte + copy(operator[:], oper[:]) + noLongerBonded = append(noLongerBonded, operator) } + sort.SliceStable(noLongerBonded, func(i, j int) bool { + return bytes.Compare(noLongerBonded[i], noLongerBonded[j]) == -1 + }) - // REF CODE - //// add to accumulated changes for tendermint - //bzABCI := k.cdc.MustMarshalBinary(validator.ABCIValidator()) - //tstore := ctx.TransientStore(k.storeTKey) - //tstore.Set(GetTendermintUpdatesTKey(validator.OperatorAddr), bzABCI) - - // XXX code from issue - /* - last := fetchOldValidatorSet() - tendermintUpdates := make(map[sdk.ValAddress]uint64) - - for _, validator := range topvalidator { //(iterate(top hundred)) { - switch validator.State { - case Unbonded: - unbondedToBonded(ctx, validator.Addr) - tendermintUpdates[validator.Addr] = validator.Power - case Unbonding: - unbondingToBonded(ctx, validator.Addr) - tendermintUpdates[validator.Addr] = validator.Power - case Bonded: // do nothing - store.delete(last[validator.Addr]) - // jailed validators are ranked last, so if we get to a jailed validator - // we have no more bonded validators - if validator.Jailed { - break - } - } - } + // iterate through the sorted no-longer-bonded validators + // any validators left in `last` are no longer bonded + for _, operator := range noLongerBonded { + // fetch the validator + validator := k.mustGetValidator(ctx, sdk.ValAddress(operator)) - for _, validator := range previousValidators { - bondedToUnbonding(ctx, validator.Addr) - tendermintUpdates[validator.Addr] = 0 - } + // bonded to unbonding + k.bondedToUnbonding(ctx, validator) - return tendermintUpdates - */ + // delete from the bonded validator index + store.Delete(GetBondedValidatorIndexKey(operator)) + + // update the validator + updates = append(updates, validator.ABCIValidatorUpdateZero()) + } return updates } From ebc59ae3f8076af99ae48bf1d9d77ec48f2384ac Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 28 Sep 2018 19:06:15 +0200 Subject: [PATCH 33/52] Works with simulation --- x/stake/keeper/val_state_change.go | 51 ++++++++++++++++++------------ x/stake/simulation/invariants.go | 1 + 2 files changed, 32 insertions(+), 20 deletions(-) diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 022c5030f7b8..eba626af10fa 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -21,15 +21,17 @@ import ( // are returned to Tendermint. func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorUpdate) { + fmt.Printf("GetTendermintUpdates\n") + store := ctx.KVStore(k.storeKey) maxValidators := k.GetParams(ctx).MaxValidators // copy last validator set - var last map[[sdk.AddrLen]byte]interface{} + last := make(map[[sdk.AddrLen]byte]interface{}) iterator := sdk.KVStorePrefixIterator(store, BondedValidatorsIndexKey) for ; iterator.Valid(); iterator.Next() { var operator [sdk.AddrLen]byte - copy(operator[:], iterator.Key()) + copy(operator[:], iterator.Key()[1:]) last[operator] = nil } @@ -43,6 +45,7 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // jailed validators are ranked last, so if we get to a jailed validator // we have no more bonded validators + // TODO we can remove this if we remove jailed validators from the power store if validator.Jailed { break } @@ -50,9 +53,9 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // apply the appropriate state change if necessary switch validator.Status { case sdk.Unbonded: - k.unbondedToBonded(ctx, validator) + validator = k.unbondedToBonded(ctx, validator) case sdk.Unbonding: - k.unbondingToBonded(ctx, validator) + validator = k.unbondingToBonded(ctx, validator) case sdk.Bonded: // no state change } @@ -62,10 +65,11 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // validator still in the validator set var opbytes [sdk.AddrLen]byte - copy(opbytes[:], operator) + copy(opbytes[:], operator[:]) delete(last, opbytes) // set the bonded validator index + // TODO move me store.Set(GetBondedValidatorIndexKey(operator), []byte{}) // keep count @@ -75,10 +79,12 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // sort the map keys for determinism noLongerBonded := make([][]byte, len(last)) - for oper, _ := range last { - var operator []byte + index := 0 + for oper := range last { + operator := make([]byte, sdk.AddrLen) copy(operator[:], oper[:]) - noLongerBonded = append(noLongerBonded, operator) + noLongerBonded[index] = operator + index++ } sort.SliceStable(noLongerBonded, func(i, j int) bool { return bytes.Compare(noLongerBonded[i], noLongerBonded[j]) == -1 @@ -88,12 +94,14 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // any validators left in `last` are no longer bonded for _, operator := range noLongerBonded { // fetch the validator + // TODO might it have been deleted in RemoveValidator? validator := k.mustGetValidator(ctx, sdk.ValAddress(operator)) // bonded to unbonding k.bondedToUnbonding(ctx, validator) // delete from the bonded validator index + // TODO move me store.Delete(GetBondedValidatorIndexKey(operator)) // update the validator @@ -105,32 +113,32 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // Validator state transitions -func (k Keeper) bondedToUnbonding(ctx sdk.Context, validator types.Validator) { +func (k Keeper) bondedToUnbonding(ctx sdk.Context, validator types.Validator) types.Validator { if validator.Status != sdk.Bonded { panic(fmt.Sprintf("bad state transition bondedToUnbonded, validator: %v\n", validator)) } - k.beginUnbondingValidator(ctx, validator) + return k.beginUnbondingValidator(ctx, validator) } -func (k Keeper) unbondingToBonded(ctx sdk.Context, validator types.Validator) { +func (k Keeper) unbondingToBonded(ctx sdk.Context, validator types.Validator) types.Validator { if validator.Status != sdk.Unbonding { panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator)) } - k.bondValidator(ctx, validator) + return k.bondValidator(ctx, validator) } -func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) { +func (k Keeper) unbondedToBonded(ctx sdk.Context, validator types.Validator) types.Validator { if validator.Status != sdk.Unbonded { panic(fmt.Sprintf("bad state transition unbondedToBonded, validator: %v\n", validator)) } - k.bondValidator(ctx, validator) + return k.bondValidator(ctx, validator) } -func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) { +func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) types.Validator { if validator.Status != sdk.Unbonded { panic(fmt.Sprintf("bad state transition unbondingToBonded, validator: %v\n", validator)) } - k.completeUnbondingValidator(ctx, validator) + return k.completeUnbondingValidator(ctx, validator) } // send a validator to jail @@ -144,6 +152,7 @@ func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { validator.Jailed = true k.SetValidator(ctx, validator) k.SetValidatorByPowerIndex(ctx, validator, pool) + // TODO we should be able to just delete the index, and only set it again once unjailed } // remove a validator from jail @@ -162,7 +171,7 @@ func (k Keeper) UnjailValidator(ctx sdk.Context, validator types.Validator) { //________________________________________________________________________________________________ // perform all the store operations for when a validator status becomes bonded -func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) { +func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types.Validator { store := ctx.KVStore(k.storeKey) pool := k.GetPool(ctx) @@ -187,6 +196,8 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) { if k.hooks != nil { k.hooks.OnValidatorBonded(ctx, validator.ConsAddress()) } + + return validator } // perform all the store operations for when a validator status begins unbonding @@ -199,8 +210,7 @@ func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validat k.DeleteValidatorByPowerIndex(ctx, validator, pool) // sanity check - if validator.Status == sdk.Unbonded || - validator.Status == sdk.Unbonding { + if validator.Status != sdk.Bonded { panic(fmt.Sprintf("should not already be unbonded or unbonding, validator: %v\n", validator)) } @@ -228,11 +238,12 @@ func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validat } // perform all the store operations for when a validator status becomes unbonded -func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Validator) { +func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Validator) types.Validator { pool := k.GetPool(ctx) validator, pool = validator.UpdateStatus(pool, sdk.Unbonded) k.SetPool(ctx, pool) k.SetValidator(ctx, validator) + return validator } // XXX need to figure out how to set a validator's BondIntraTxCounter - probably during delegation bonding? diff --git a/x/stake/simulation/invariants.go b/x/stake/simulation/invariants.go index 2866f6292fef..b06c7bb7cce3 100644 --- a/x/stake/simulation/invariants.go +++ b/x/stake/simulation/invariants.go @@ -76,6 +76,7 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim // PositivePowerInvariant checks that all stored validators have > 0 power func PositivePowerInvariant(k stake.Keeper) simulation.Invariant { return func(app *baseapp.BaseApp) error { + // TODO Reenable but only check after EndBlock, is this accurate now? ctx := app.NewContext(false, abci.Header{}) var err error k.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) bool { From cfb12dab335969ded776ba60a31d482cb6ef4e44 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 1 Oct 2018 12:55:49 +0200 Subject: [PATCH 34/52] Refactor testcases in progress --- x/stake/handler_test.go | 136 ---------------- x/stake/keeper/delegation_test.go | 38 ++--- x/stake/keeper/slash_test.go | 2 +- x/stake/keeper/test_common.go | 17 +- x/stake/keeper/val_state_change.go | 2 - x/stake/keeper/validator_test.go | 240 ++++++++--------------------- x/stake/querier/queryable_test.go | 4 +- 7 files changed, 105 insertions(+), 334 deletions(-) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 91fd51c2527e..7d51aa90ec77 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -777,142 +777,6 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { require.Equal(t, sdk.Bonded, val1.Status, "%v", val1) } -func TestJoiningAsCliffValidator(t *testing.T) { - ctx, _, keeper := keep.CreateTestInput(t, false, 1000) - validatorAddr1, validatorAddr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) - - // make sure that the cliff validator is nil to begin with - cliffVal := keeper.GetCliffValidator(ctx) - require.Equal(t, []byte(nil), cliffVal) - - // set the unbonding time - params := keeper.GetParams(ctx) - params.UnbondingTime = 0 - params.MaxValidators = 2 - keeper.SetParams(ctx, params) - - // add the first validator - msgCreateValidator := newTestMsgCreateValidator(validatorAddr1, keep.PKs[0], 50) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") - - // cliff validator should still be nil - cliffVal = keeper.GetCliffValidator(ctx) - require.Equal(t, []byte(nil), cliffVal) - - // Add the second validator - msgCreateValidator = newTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 30) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") - - // now that we've reached maximum validators, the val-2 should be added to the cliff (top) - cliffVal = keeper.GetCliffValidator(ctx) - require.Equal(t, validatorAddr2.Bytes(), cliffVal) -} - -func TestJoiningToCreateFirstCliffValidator(t *testing.T) { - ctx, _, keeper := keep.CreateTestInput(t, false, 1000) - validatorAddr1, validatorAddr2 := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]) - - // make sure that the cliff validator is nil to begin with - cliffVal := keeper.GetCliffValidator(ctx) - require.Equal(t, []byte(nil), cliffVal) - - // set the unbonding time - params := keeper.GetParams(ctx) - params.UnbondingTime = 0 - params.MaxValidators = 2 - keeper.SetParams(ctx, params) - - // add the first validator - msgCreateValidator := newTestMsgCreateValidator(validatorAddr1, keep.PKs[0], 50) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") - - // cliff validator should still be nil - cliffVal = keeper.GetCliffValidator(ctx) - require.Equal(t, []byte(nil), cliffVal) - - // Add the second validator - msgCreateValidator = newTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 60) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") - - // now that we've reached maximum validators, validator-1 should be added to the cliff (top) - cliffVal = keeper.GetCliffValidator(ctx) - require.Equal(t, validatorAddr1.Bytes(), cliffVal) -} - -func TestCliffValidator(t *testing.T) { - ctx, _, keeper := keep.CreateTestInput(t, false, 1000) - validatorAddr1 := sdk.ValAddress(keep.Addrs[0]) - validatorAddr2 := sdk.ValAddress(keep.Addrs[1]) - validatorAddr3 := sdk.ValAddress(keep.Addrs[2]) - - // make sure that the cliff validator is nil to begin with - cliffVal := keeper.GetCliffValidator(ctx) - require.Equal(t, []byte(nil), cliffVal) - - // set the unbonding time - params := keeper.GetParams(ctx) - params.UnbondingTime = 0 - params.MaxValidators = 2 - keeper.SetParams(ctx, params) - - // add the first validator - msgCreateValidator := newTestMsgCreateValidator(validatorAddr1, keep.PKs[0], 50) - got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") - - // cliff validator should still be nil - cliffVal = keeper.GetCliffValidator(ctx) - require.Equal(t, []byte(nil), cliffVal) - - // Add the second validator - msgCreateValidator = newTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 30) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") - - // now that we've reached maximum validators, validator-2 should be added to the cliff (top) - cliffVal = keeper.GetCliffValidator(ctx) - require.Equal(t, validatorAddr2.Bytes(), cliffVal) - - // add the third validator, which should not make it to being bonded, - // so the cliff validator should not change because nobody has been kicked out - msgCreateValidator = newTestMsgCreateValidator(validatorAddr3, keep.PKs[2], 10) - got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") - - cliffVal = keeper.GetCliffValidator(ctx) - require.Equal(t, validatorAddr2.Bytes(), cliffVal) - - // unbond valdator-2 - msgBeginUnbonding := NewMsgBeginUnbonding(sdk.AccAddress(validatorAddr2), validatorAddr2, sdk.NewDec(30)) - got = handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgBeginUnbonding") - - vals := keeper.GetValidatorsBonded(ctx) - require.Equal(t, 2, len(vals)) - - // now the validator set should be updated, - // where val-3 enters the validator set on the cliff - cliffVal = keeper.GetCliffValidator(ctx) - require.Equal(t, validatorAddr3.Bytes(), cliffVal) - - // unbond valdator-1 - msgBeginUnbonding = NewMsgBeginUnbonding(sdk.AccAddress(validatorAddr1), validatorAddr1, sdk.NewDec(50)) - got = handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper) - require.True(t, got.IsOK(), "expected no error on runMsgBeginUnbonding") - - // get bonded validators - should just be one - vals = keeper.GetValidatorsBonded(ctx) - require.Equal(t, 1, len(vals)) - - // cliff now should be empty - cliffVal = keeper.GetCliffValidator(ctx) - require.Equal(t, []byte(nil), cliffVal) -} - func TestBondUnbondRedelegateSlashTwice(t *testing.T) { ctx, _, keeper := keep.CreateTestInput(t, false, 1000) valA, valB, del := sdk.ValAddress(keep.Addrs[0]), sdk.ValAddress(keep.Addrs[1]), keep.Addrs[2] diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index ed65f1f404b3..96f0ba383e93 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -25,9 +25,9 @@ func TestDelegation(t *testing.T) { } keeper.SetPool(ctx, pool) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) - validators[2] = keeper.UpdateValidator(ctx, validators[2]) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[2] = updateValidator(keeper, ctx, validators[2]) // first add a validators[0] to delegate too @@ -184,7 +184,7 @@ func TestUnbondDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) require.Equal(t, int64(10), pool.BondedTokens.RoundInt64()) @@ -226,7 +226,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) selfDelegation := types.Delegation{ DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()), @@ -239,7 +239,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -269,7 +269,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) selfDelegation := types.Delegation{ DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()), @@ -282,7 +282,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -340,7 +340,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -354,7 +354,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -506,7 +506,7 @@ func TestRedelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -521,13 +521,13 @@ func TestRedelegateSelfDelegation(t *testing.T) { validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator2 = keeper.UpdateValidator(ctx, validator2) + validator2 = updateValidator(keeper, ctx, validator2) // create a second delegation to this validator validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -556,7 +556,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -570,7 +570,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -584,7 +584,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator2 = keeper.UpdateValidator(ctx, validator2) + validator2 = updateValidator(keeper, ctx, validator2) header := ctx.BlockHeader() blockHeight := int64(10) @@ -634,7 +634,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -648,7 +648,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -662,7 +662,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator2 = keeper.UpdateValidator(ctx, validator2) + validator2 = updateValidator(keeper, ctx, validator2) header := ctx.BlockHeader() blockHeight := int64(10) diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index 0a6cccac2abf..b8c90d4a0a55 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -27,7 +27,7 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) { validator := types.NewValidator(addrVals[i], PKs[i], types.Description{}) validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) keeper.SetValidatorByConsAddr(ctx, validator) } pool = keeper.GetPool(ctx) diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index 388e7e247045..3b0287e4fe29 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -202,5 +202,20 @@ func createTestPubKeys(numPubKeys int) []crypto.PubKey { // does a certain by-power index record exist func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) bool { store := ctx.KVStore(keeper.storeKey) - return store.Get(power) != nil + return store.Has(power) +} + +func updateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator) types.Validator { + keeper.SetValidator(ctx, validator) + keeper.GetTendermintUpdates(ctx) + validator, found := keeper.GetValidator(ctx, validator.OperatorAddr) + if !found { + panic("validator expected but not found") + } + return validator +} + +func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool { + store := ctx.KVStore(k.storeKey) + return store.Has(power) } diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index eba626af10fa..f463e39c168d 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -21,8 +21,6 @@ import ( // are returned to Tendermint. func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorUpdate) { - fmt.Printf("GetTendermintUpdates\n") - store := ctx.KVStore(k.storeKey) maxValidators := k.GetParams(ctx).MaxValidators diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index cb30ebea1a18..3c7a4875371b 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -13,23 +13,6 @@ import ( "github.com/stretchr/testify/require" ) -// for testing, remove all validator update entries after applied to Tendermint -func clearTendermintUpdates(ctx sdk.Context, k Keeper) { - store := ctx.TransientStore(k.storeTKey) - - // delete subspace - iterator := sdk.KVStorePrefixIterator(store, TendermintUpdatesTKey) - for ; iterator.Valid(); iterator.Next() { - store.Delete(iterator.Key()) - } - iterator.Close() -} - -func validatorByPowerIndexExists(k Keeper, ctx sdk.Context, power []byte) bool { - store := ctx.KVStore(k.storeKey) - return store.Has(power) -} - //_______________________________________________________ func TestSetValidator(t *testing.T) { @@ -46,7 +29,7 @@ func TestSetValidator(t *testing.T) { assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens)) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares)) keeper.SetPool(ctx, pool) - keeper.UpdateValidator(ctx, validator) + updateValidator(keeper, ctx, validator) // after the save the validator should be bonded validator, found := keeper.GetValidator(ctx, valAddr) @@ -99,7 +82,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { require.Equal(t, sdk.Unbonded, validator.Status) require.Equal(t, int64(100), validator.Tokens.RoundInt64()) keeper.SetPool(ctx, pool) - keeper.UpdateValidator(ctx, validator) + updateValidator(keeper, ctx, validator) validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool) @@ -111,8 +94,8 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { // burn half the delegator shares validator, pool, burned := validator.RemoveDelShares(pool, delSharesCreated.Quo(sdk.NewDec(2))) require.Equal(t, int64(50), burned.RoundInt64()) - keeper.SetPool(ctx, pool) // update the pool - keeper.UpdateValidator(ctx, validator) // update the validator, possibly kicking it out + keeper.SetPool(ctx, pool) // update the pool + updateValidator(keeper, ctx, validator) // update the validator, possibly kicking it out require.False(t, validatorByPowerIndexExists(keeper, ctx, power)) pool = keeper.GetPool(ctx) @@ -149,7 +132,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { val, pool, _ = val.AddTokensFromDel(pool, sdk.NewInt(int64((i+1)*10))) keeper.SetPool(ctx, pool) - val = keeper.UpdateValidator(ctx, val) + val = updateValidator(keeper, ctx, val) validators[i] = val } @@ -159,15 +142,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { // validator and next in line cliff validator nextCliffVal, pool, _ = nextCliffVal.RemoveDelShares(pool, sdk.NewDec(21)) keeper.SetPool(ctx, pool) - nextCliffVal = keeper.UpdateValidator(ctx, nextCliffVal) - - // require the cliff validator has changed - cliffVal := validators[numVals-maxVals-1] - require.Equal(t, cliffVal.OperatorAddr, sdk.ValAddress(keeper.GetCliffValidator(ctx))) - - // require the cliff validator power has changed - cliffPower := keeper.GetCliffValidatorPower(ctx) - require.Equal(t, GetBondedValidatorsByPowerIndexKey(cliffVal, pool), cliffPower) + nextCliffVal = updateValidator(keeper, ctx, nextCliffVal) expectedValStatus := map[int]sdk.BondStatus{ 9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded, @@ -187,75 +162,6 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { } } -func TestCliffValidatorChange(t *testing.T) { - numVals := 10 - maxVals := 5 - - // create context, keeper, and pool for tests - ctx, _, keeper := CreateTestInput(t, false, 0) - pool := keeper.GetPool(ctx) - - // create keeper parameters - params := keeper.GetParams(ctx) - params.MaxValidators = uint16(maxVals) - keeper.SetParams(ctx, params) - - // create a random pool - pool.LooseTokens = sdk.NewDec(10000) - pool.BondedTokens = sdk.NewDec(1234) - keeper.SetPool(ctx, pool) - - validators := make([]types.Validator, numVals) - for i := 0; i < len(validators); i++ { - moniker := fmt.Sprintf("val#%d", int64(i)) - val := types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) - val.BondHeight = int64(i) - val.BondIntraTxCounter = int16(i) - val, pool, _ = val.AddTokensFromDel(pool, sdk.NewInt(int64((i+1)*10))) - - keeper.SetPool(ctx, pool) - val = keeper.UpdateValidator(ctx, val) - validators[i] = val - } - - // add a large amount of tokens to current cliff validator - currCliffVal := validators[numVals-maxVals] - currCliffVal, pool, _ = currCliffVal.AddTokensFromDel(pool, sdk.NewInt(200)) - keeper.SetPool(ctx, pool) - currCliffVal = keeper.UpdateValidator(ctx, currCliffVal) - - // assert new cliff validator to be set to the second lowest bonded validator by power - newCliffVal := validators[numVals-maxVals+1] - require.Equal(t, newCliffVal.OperatorAddr, sdk.ValAddress(keeper.GetCliffValidator(ctx))) - - // assert cliff validator power should have been updated - cliffPower := keeper.GetCliffValidatorPower(ctx) - require.Equal(t, GetBondedValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) - - // add small amount of tokens to new current cliff validator - newCliffVal, pool, _ = newCliffVal.AddTokensFromDel(pool, sdk.NewInt(1)) - keeper.SetPool(ctx, pool) - newCliffVal = keeper.UpdateValidator(ctx, newCliffVal) - - // assert cliff validator has not change but increased in power - cliffPower = keeper.GetCliffValidatorPower(ctx) - require.Equal(t, newCliffVal.OperatorAddr, sdk.ValAddress(keeper.GetCliffValidator(ctx))) - require.Equal(t, GetBondedValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) - - // add enough power to cliff validator to be equal in rank to next validator - newCliffVal, pool, _ = newCliffVal.AddTokensFromDel(pool, sdk.NewInt(9)) - keeper.SetPool(ctx, pool) - newCliffVal = keeper.UpdateValidator(ctx, newCliffVal) - - // assert new cliff validator due to power rank construction - newCliffVal = validators[numVals-maxVals+2] - require.Equal(t, newCliffVal.OperatorAddr, sdk.ValAddress(keeper.GetCliffValidator(ctx))) - - // assert cliff validator power should have been updated - cliffPower = keeper.GetCliffValidatorPower(ctx) - require.Equal(t, GetBondedValidatorsByPowerIndexKey(newCliffVal, pool), cliffPower) -} - func TestSlashToZeroPowerRemoved(t *testing.T) { // initialize setup ctx, _, keeper := CreateTestInput(t, false, 100) @@ -268,7 +174,7 @@ func TestSlashToZeroPowerRemoved(t *testing.T) { require.Equal(t, int64(100), validator.Tokens.RoundInt64()) keeper.SetPool(ctx, pool) keeper.SetValidatorByConsAddr(ctx, validator) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool) // slash the validator by 100% @@ -311,7 +217,7 @@ func TestValidatorBasics(t *testing.T) { assert.True(sdk.DecEq(t, sdk.ZeroDec(), pool.BondedTokens)) // set and retrieve a record - validators[0] = keeper.UpdateValidator(ctx, validators[0]) + validators[0] = updateValidator(keeper, ctx, validators[0]) keeper.SetValidatorByConsAddr(ctx, validators[0]) resVal, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) @@ -338,7 +244,7 @@ func TestValidatorBasics(t *testing.T) { validators[0].Status = sdk.Bonded validators[0].Tokens = sdk.NewDec(10) validators[0].DelegatorShares = sdk.NewDec(10) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) + validators[0] = updateValidator(keeper, ctx, validators[0]) resVal, found = keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) assert.True(ValEq(t, validators[0], resVal)) @@ -348,8 +254,8 @@ func TestValidatorBasics(t *testing.T) { assert.True(ValEq(t, validators[0], resVals[0])) // add other validators - validators[1] = keeper.UpdateValidator(ctx, validators[1]) - validators[2] = keeper.UpdateValidator(ctx, validators[2]) + validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[2] = updateValidator(keeper, ctx, validators[2]) resVal, found = keeper.GetValidator(ctx, addrVals[1]) require.True(t, found) assert.True(ValEq(t, validators[1], resVal)) @@ -382,7 +288,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { validators[i].Status = sdk.Bonded validators[i].Tokens = sdk.NewDec(amt) validators[i].DelegatorShares = sdk.NewDec(amt) - keeper.UpdateValidator(ctx, validators[i]) + updateValidator(keeper, ctx, validators[i]) } // first make sure everything made it in to the gotValidator group @@ -401,14 +307,14 @@ func GetValidatorSortingUnmixed(t *testing.T) { // test a basic increase in voting power validators[3].Tokens = sdk.NewDec(500) - keeper.UpdateValidator(ctx, validators[3]) + updateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) // test a decrease in voting power validators[3].Tokens = sdk.NewDec(300) - keeper.UpdateValidator(ctx, validators[3]) + updateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -417,7 +323,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { // test equal voting power, different age validators[3].Tokens = sdk.NewDec(200) ctx = ctx.WithBlockHeight(10) - keeper.UpdateValidator(ctx, validators[3]) + updateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -427,7 +333,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { // no change in voting power - no change in sort ctx = ctx.WithBlockHeight(20) - keeper.UpdateValidator(ctx, validators[4]) + updateValidator(keeper, ctx, validators[4]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -436,11 +342,11 @@ func GetValidatorSortingUnmixed(t *testing.T) { // change in voting power of both validators, both still in v-set, no age change validators[3].Tokens = sdk.NewDec(300) validators[4].Tokens = sdk.NewDec(300) - keeper.UpdateValidator(ctx, validators[3]) + updateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) ctx = ctx.WithBlockHeight(30) - keeper.UpdateValidator(ctx, validators[4]) + updateValidator(keeper, ctx, validators[4]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n, "%v", resValidators) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -478,7 +384,7 @@ func GetValidatorSortingMixed(t *testing.T) { validators[4].Tokens = sdk.NewDec(amts[4]) for i := range amts { - keeper.UpdateValidator(ctx, validators[i]) + updateValidator(keeper, ctx, validators[i]) } val0, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0])) require.True(t, found) @@ -531,7 +437,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) - validators[i] = keeper.UpdateValidator(ctx, validators[i]) + validators[i] = updateValidator(keeper, ctx, validators[i]) } for i := range amts { @@ -546,7 +452,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { pool := keeper.GetPool(ctx) validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(500)) keeper.SetPool(ctx, pool) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) + validators[0] = updateValidator(keeper, ctx, validators[0]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -563,7 +469,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { require.True(t, found) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1)) keeper.SetPool(ctx, pool) - validators[3] = keeper.UpdateValidator(ctx, validators[3]) + validators[3] = updateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -572,7 +478,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { // validator 3 kicked out temporarily validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201)) keeper.SetPool(ctx, pool) - validators[3] = keeper.UpdateValidator(ctx, validators[3]) + validators[3] = updateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -581,7 +487,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { // validator 4 does not get spot back validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200)) keeper.SetPool(ctx, pool) - validators[3] = keeper.UpdateValidator(ctx, validators[3]) + validators[3] = updateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -611,13 +517,13 @@ func TestValidatorBondHeight(t *testing.T) { validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(100)) keeper.SetPool(ctx, pool) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) + validators[0] = updateValidator(keeper, ctx, validators[0]) //////////////////////////////////////// // If two validators both increase to the same voting power in the same block, // the one with the first transaction should become bonded - validators[1] = keeper.UpdateValidator(ctx, validators[1]) - validators[2] = keeper.UpdateValidator(ctx, validators[2]) + validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[2] = updateValidator(keeper, ctx, validators[2]) pool = keeper.GetPool(ctx) @@ -629,10 +535,10 @@ func TestValidatorBondHeight(t *testing.T) { validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50)) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50)) keeper.SetPool(ctx, pool) - validators[2] = keeper.UpdateValidator(ctx, validators[2]) + validators[2] = updateValidator(keeper, ctx, validators[2]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, params.MaxValidators, uint16(len(resValidators))) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) + validators[1] = updateValidator(keeper, ctx, validators[1]) assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) } @@ -652,7 +558,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) - keeper.UpdateValidator(ctx, validators[i]) + updateValidator(keeper, ctx, validators[i]) } for i := range amts { var found bool @@ -673,7 +579,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { pool := keeper.GetPool(ctx) validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(600)) keeper.SetPool(ctx, pool) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) + validators[0] = updateValidator(keeper, ctx, validators[0]) resValidators = keeper.GetBondedValidatorsByPower(ctx) assert.Equal(t, max, len(resValidators)) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -699,8 +605,8 @@ func TestGetTendermintUpdatesAllNone(t *testing.T) { // test from nothing to something // tendermintUpdate set: {} -> {c1, c3} require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) updates := keeper.GetTendermintUpdates(ctx) assert.Equal(t, 2, len(updates)) @@ -719,15 +625,14 @@ func TestGetTendermintUpdatesIdentical(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) - clearTendermintUpdates(ctx, keeper) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test identical, // tendermintUpdate set: {} -> {} - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) } @@ -742,16 +647,15 @@ func TestGetTendermintUpdatesSingleValueChange(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) - clearTendermintUpdates(ctx, keeper) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test single value change // tendermintUpdate set: {} -> {c1'} validators[0].Status = sdk.Bonded validators[0].Tokens = sdk.NewDec(600) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) + validators[0] = updateValidator(keeper, ctx, validators[0]) updates := keeper.GetTendermintUpdates(ctx) @@ -770,9 +674,8 @@ func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) - clearTendermintUpdates(ctx, keeper) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test multiple value change @@ -781,8 +684,8 @@ func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(190)) validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(80)) keeper.SetPool(ctx, pool) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates)) @@ -801,30 +704,27 @@ func TestGetTendermintUpdatesInserted(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) - clearTendermintUpdates(ctx, keeper) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test validtor added at the beginning // tendermintUpdate set: {} -> {c0} - validators[2] = keeper.UpdateValidator(ctx, validators[2]) + validators[2] = updateValidator(keeper, ctx, validators[2]) updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) // test validtor added at the beginning // tendermintUpdate set: {} -> {c0} - clearTendermintUpdates(ctx, keeper) - validators[3] = keeper.UpdateValidator(ctx, validators[3]) + validators[3] = updateValidator(keeper, ctx, validators[3]) updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[3].ABCIValidatorUpdate(), updates[0]) // test validtor added at the end // tendermintUpdate set: {} -> {c0} - clearTendermintUpdates(ctx, keeper) - validators[4] = keeper.UpdateValidator(ctx, validators[4]) + validators[4] = updateValidator(keeper, ctx, validators[4]) updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[4].ABCIValidatorUpdate(), updates[0]) @@ -844,26 +744,24 @@ func TestGetTendermintUpdatesWithCliffValidator(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) - clearTendermintUpdates(ctx, keeper) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // test validator added at the end but not inserted in the valset // tendermintUpdate set: {} -> {} - keeper.UpdateValidator(ctx, validators[2]) + updateValidator(keeper, ctx, validators[2]) updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 0, len(updates)) // test validator change its power and become a gotValidator (pushing out an existing) // tendermintUpdate set: {} -> {c0, c4} - clearTendermintUpdates(ctx, keeper) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) pool := keeper.GetPool(ctx) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(10)) keeper.SetPool(ctx, pool) - validators[2] = keeper.UpdateValidator(ctx, validators[2]) + validators[2] = updateValidator(keeper, ctx, validators[2]) updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates), "%v", updates) @@ -882,9 +780,8 @@ func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) - clearTendermintUpdates(ctx, keeper) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // check initial power @@ -897,8 +794,8 @@ func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { validators[0], pool, _ = validators[0].RemoveDelShares(pool, sdk.NewDec(20)) validators[1], pool, _ = validators[1].RemoveDelShares(pool, sdk.NewDec(30)) keeper.SetPool(ctx, pool) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) + validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[1] = updateValidator(keeper, ctx, validators[1]) // power has changed require.Equal(t, sdk.NewDec(80).RoundInt64(), validators[0].GetPower().RoundInt64()) @@ -931,7 +828,7 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) - validators[i] = keeper.UpdateValidator(ctx, validators[i]) + validators[i] = updateValidator(keeper, ctx, validators[i]) } // verify initial Tendermint updates are correct @@ -940,7 +837,6 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) - clearTendermintUpdates(ctx, keeper) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // update initial validator set @@ -949,7 +845,7 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) - validators[i] = keeper.UpdateValidator(ctx, validators[i]) + validators[i] = updateValidator(keeper, ctx, validators[i]) } // add a new validator that goes from zero power, to non-zero power, back to @@ -963,10 +859,10 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { validator, pool, _ = validator.AddTokensFromDel(pool, amt) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) validator, pool, _ = validator.RemoveDelShares(pool, sdk.NewDecFromInt(amt)) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) // add a new validator that increases in power valPubKey = PKs[len(validators)+2] @@ -976,7 +872,7 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(500)) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) // verify initial Tendermint updates are correct updates = keeper.GetTendermintUpdates(ctx) @@ -1007,7 +903,7 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) - validators[i] = keeper.UpdateValidator(ctx, validators[i]) + validators[i] = updateValidator(keeper, ctx, validators[i]) } // verify initial Tendermint updates are correct @@ -1016,7 +912,6 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) - clearTendermintUpdates(ctx, keeper) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) // delegate to validator with lowest power but not enough to bond @@ -1029,7 +924,7 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(1)) keeper.SetPool(ctx, pool) - validators[0] = keeper.UpdateValidator(ctx, validator) + validators[0] = updateValidator(keeper, ctx, validator) // verify initial Tendermint updates are correct require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) @@ -1045,19 +940,18 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { validator, pool, _ = validator.RemoveDelShares(pool, validator.DelegatorShares) keeper.SetPool(ctx, pool) - validator = keeper.UpdateValidator(ctx, validator) + validator = updateValidator(keeper, ctx, validator) validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(250)) keeper.SetPool(ctx, pool) - validators[1] = keeper.UpdateValidator(ctx, validator) + validators[1] = updateValidator(keeper, ctx, validator) // verify initial Tendermint updates are correct updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) - clearTendermintUpdates(ctx, keeper) require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) } @@ -1090,7 +984,7 @@ func TestUpdateValidatorCommission(t *testing.T) { } for i, tc := range testCases { - err := keeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate) + _, err := keeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate) if tc.expectedErr { require.Error(t, err, "expected error for test case #%d with rate: %s", i, tc.newRate) diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/queryable_test.go index ee52773c6e4c..cbc947889f55 100644 --- a/x/stake/querier/queryable_test.go +++ b/x/stake/querier/queryable_test.go @@ -71,8 +71,8 @@ func TestQueryValidators(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, amt) } keeper.SetPool(ctx, pool) - validators[0] = keeper.UpdateValidator(ctx, validators[0]) - validators[1] = keeper.UpdateValidator(ctx, validators[1]) + keeper.SetValidator(ctx, validators[0]) + keeper.SetValidator(ctx, validators[1]) // Query Validators queriedValidators := keeper.GetValidators(ctx, params.MaxValidators) From 77c2cc8aeeee85a41f674a7c5b642a72465aa8de Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 1 Oct 2018 13:54:31 +0200 Subject: [PATCH 35/52] Testcase fixes in progress --- x/stake/handler_test.go | 29 +++++++++++++++++++++++++++++ x/stake/keeper/delegation.go | 7 ++++--- x/stake/keeper/delegation_test.go | 3 +++ x/stake/keeper/test_common.go | 2 ++ x/stake/keeper/val_state_change.go | 6 ++++++ 5 files changed, 44 insertions(+), 3 deletions(-) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 7d51aa90ec77..31adb307b7cd 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -63,6 +63,10 @@ func TestValidatorByPowerIndex(t *testing.T) { got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + // must end-block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + // verify the self-delegation exists bond, found := keeper.GetDelegation(ctx, sdk.AccAddress(validatorAddr), validatorAddr) require.True(t, found) @@ -82,6 +86,9 @@ func TestValidatorByPowerIndex(t *testing.T) { msgCreateValidator = newTestMsgCreateValidator(validatorAddr3, keep.PKs[2], int64(1000000)) got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + // must end-block + updates = keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) // slash and jail the first validator consAddr0 := sdk.ConsAddress(keep.PKs[0].Address()) @@ -160,6 +167,11 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { msgCreateValidator4 := newTestMsgCreateValidator(addr2, pk2, 10) got = handleMsgCreateValidator(ctx, msgCreateValidator4, keeper) require.True(t, got.IsOK(), "%v", got) + + // must end-block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + validator, found = keeper.GetValidator(ctx, addr2) require.True(t, found) @@ -180,6 +192,11 @@ func TestDuplicatesMsgCreateValidatorOnBehalfOf(t *testing.T) { msgCreateValidatorOnBehalfOf := newTestMsgCreateValidatorOnBehalfOf(delegatorAddr, validatorAddr, pk, 10) got := handleMsgCreateValidator(ctx, msgCreateValidatorOnBehalfOf, keeper) require.True(t, got.IsOK(), "%v", got) + + // must end-block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) @@ -211,6 +228,10 @@ func TestLegacyValidatorDelegations(t *testing.T) { got := handleMsgCreateValidator(ctx, msgCreateVal, keeper) require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got) + // must end-block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + // verify the validator exists and has the correct attributes validator, found := keeper.GetValidator(ctx, valAddr) require.True(t, found) @@ -795,6 +816,10 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { got = handleMsgDelegate(ctx, msgDelegate, keeper) require.True(t, got.IsOK(), "expected no error on runMsgDelegate") + // apply Tendermint updates + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + // a block passes ctx = ctx.WithBlockHeight(1) @@ -813,6 +838,10 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { require.True(t, found) require.Equal(t, sdk.NewDec(6), delegation.Shares) + // must apply validator updates + updates = keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + // slash the validator by half keeper.Slash(ctx, consAddr0, 0, 20, sdk.NewDecWithPrec(5, 1)) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index e640b997703d..f245da9e3db1 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -308,8 +308,9 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA // if the delegation is the operator of the validator then // trigger a jail validator - if bytes.Equal(delegation.DelegatorAddr, validator.OperatorAddr) && validator.Jailed == false { - validator.Jailed = true + if bytes.Equal(delegation.DelegatorAddr, validator.OperatorAddr) && !validator.Jailed { + k.JailValidator(ctx, validator) + validator = k.mustGetValidator(ctx, validator.OperatorAddr) } k.RemoveDelegation(ctx, delegation) @@ -358,7 +359,7 @@ func (k Keeper) getBeginInfo(ctx sdk.Context, params types.Params, valSrcAddr sd } } -// complete unbonding an unbonding record +// begin unbonding an unbonding record func (k Keeper) BeginUnbonding(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValAddress, sharesAmount sdk.Dec) sdk.Error { diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 96f0ba383e93..b9eb18be42e0 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -520,8 +520,10 @@ func TestRedelegateSelfDelegation(t *testing.T) { validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) + pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(10)) keeper.SetPool(ctx, pool) validator2 = updateValidator(keeper, ctx, validator2) + require.Equal(t, sdk.Bonded, validator2.Status) // create a second delegation to this validator validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) @@ -663,6 +665,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) validator2 = updateValidator(keeper, ctx, validator2) + require.Equal(t, sdk.Bonded, validator2.Status) header := ctx.BlockHeader() blockHeight := int64(10) diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index 3b0287e4fe29..cdd13a96b1a3 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -206,7 +206,9 @@ func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) b } func updateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator) types.Validator { + pool := keeper.GetPool(ctx) keeper.SetValidator(ctx, validator) + keeper.SetValidatorByPowerIndex(ctx, validator, pool) keeper.GetTendermintUpdates(ctx) validator, found := keeper.GetValidator(ctx, validator.OperatorAddr) if !found { diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index f463e39c168d..c6537455b629 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -150,6 +150,12 @@ func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { validator.Jailed = true k.SetValidator(ctx, validator) k.SetValidatorByPowerIndex(ctx, validator, pool) + + // if bonded, unbond + if validator.Status == sdk.Bonded { + k.bondedToUnbonding(ctx, validator) + } + // TODO we should be able to just delete the index, and only set it again once unjailed } From 123bc06bd116d046637fa10aaa536e2866318dc8 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 1 Oct 2018 14:23:48 +0200 Subject: [PATCH 36/52] Minor fixes --- x/stake/keeper/slash_test.go | 14 ++++++++++++ x/stake/keeper/val_state_change.go | 34 +++++++++++++++++------------- x/stake/types/validator.go | 6 ++++++ 3 files changed, 39 insertions(+), 15 deletions(-) diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index b8c90d4a0a55..b4e9e54499a7 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -1,6 +1,7 @@ package keeper import ( + "fmt" "testing" "time" @@ -26,6 +27,7 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) { for i := 0; i < numVals; i++ { validator := types.NewValidator(addrVals[i], PKs[i], types.Description{}) validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(amt)) + pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(amt)) keeper.SetPool(ctx, pool) validator = updateValidator(keeper, ctx, validator) keeper.SetValidatorByConsAddr(ctx, validator) @@ -161,6 +163,10 @@ func TestSlashRedelegation(t *testing.T) { rd, found = keeper.GetRedelegation(ctx, addrDels[0], addrVals[0], addrVals[1]) require.True(t, found) + // end block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 2, len(updates)) + // initialbalance unchanged require.Equal(t, sdk.NewInt64Coin(params.BondDenom, 10), rd.InitialBalance) @@ -201,6 +207,10 @@ func TestSlashValidatorAtCurrentHeight(t *testing.T) { require.True(t, found) newPool := keeper.GetPool(ctx) + // end block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) + // power decreased require.Equal(t, sdk.NewDec(5), validator.GetPower()) // pool bonded shares decreased @@ -232,6 +242,10 @@ func TestSlashWithUnbondingDelegation(t *testing.T) { require.True(t, found) keeper.Slash(ctx, consAddr, 10, 10, fraction) + // end block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + // read updating unbonding delegation ubd, found = keeper.GetUnbondingDelegation(ctx, addrDels[0], addrVals[0]) require.True(t, found) diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index c6537455b629..0c94c33b4aa2 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -25,12 +25,12 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU maxValidators := k.GetParams(ctx).MaxValidators // copy last validator set - last := make(map[[sdk.AddrLen]byte]interface{}) + last := make(map[[sdk.AddrLen]byte][]byte) iterator := sdk.KVStorePrefixIterator(store, BondedValidatorsIndexKey) for ; iterator.Valid(); iterator.Next() { var operator [sdk.AddrLen]byte copy(operator[:], iterator.Key()[1:]) - last[operator] = nil + last[operator] = iterator.Value() } iterator = sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) @@ -44,7 +44,8 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // jailed validators are ranked last, so if we get to a jailed validator // we have no more bonded validators // TODO we can remove this if we remove jailed validators from the power store - if validator.Jailed { + // likewise for zero-power validators, which we never bond + if validator.Jailed || validator.BondedTokens().Equal(sdk.ZeroDec()) { break } @@ -58,17 +59,26 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // no state change } - // update the validator (power might have changed) - updates = append(updates, validator.ABCIValidatorUpdate()) - // validator still in the validator set var opbytes [sdk.AddrLen]byte copy(opbytes[:], operator[:]) + + // fetch the old power bytes + powerBytes, ok := last[opbytes] + + // calculate the new power bytes + newPowerBytes := validator.ABCIValidatorPowerBytes(k.cdc) + + // update the validator set if power has changed + if !ok || !bytes.Equal(powerBytes, newPowerBytes) { + updates = append(updates, validator.ABCIValidatorUpdate()) + } + + // validator still in the validator set delete(last, opbytes) // set the bonded validator index - // TODO move me - store.Set(GetBondedValidatorIndexKey(operator), []byte{}) + store.Set(GetBondedValidatorIndexKey(operator), newPowerBytes) // keep count count++ @@ -99,7 +109,6 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU k.bondedToUnbonding(ctx, validator) // delete from the bonded validator index - // TODO move me store.Delete(GetBondedValidatorIndexKey(operator)) // update the validator @@ -113,7 +122,7 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU func (k Keeper) bondedToUnbonding(ctx sdk.Context, validator types.Validator) types.Validator { if validator.Status != sdk.Bonded { - panic(fmt.Sprintf("bad state transition bondedToUnbonded, validator: %v\n", validator)) + panic(fmt.Sprintf("bad state transition bondedToUnbonding, validator: %v\n", validator)) } return k.beginUnbondingValidator(ctx, validator) } @@ -151,11 +160,6 @@ func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { k.SetValidator(ctx, validator) k.SetValidatorByPowerIndex(ctx, validator, pool) - // if bonded, unbond - if validator.Status == sdk.Bonded { - k.bondedToUnbonding(ctx, validator) - } - // TODO we should be able to just delete the index, and only set it again once unjailed } diff --git a/x/stake/types/validator.go b/x/stake/types/validator.go index 5d0de4bc7d06..dbd4e2a54000 100644 --- a/x/stake/types/validator.go +++ b/x/stake/types/validator.go @@ -314,6 +314,12 @@ func (v Validator) ABCIValidatorUpdate() abci.ValidatorUpdate { } } +// ABCIValidatorPowerBytes +func (v Validator) ABCIValidatorPowerBytes(cdc *codec.Codec) []byte { + power := v.BondedTokens().RoundInt64() + return cdc.MustMarshalBinary(power) +} + // ABCIValidatorUpdateZero returns an abci.ValidatorUpdate from a staked validator type // with zero power used for validator updates. func (v Validator) ABCIValidatorUpdateZero() abci.ValidatorUpdate { From 6d4af75b3f638e3c5823d5f1c5b9ad66111da307 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 1 Oct 2018 17:19:34 +0200 Subject: [PATCH 37/52] Testcase fixes contd... --- x/stake/keeper/delegation_test.go | 24 +++++++ x/stake/keeper/slash_test.go | 5 +- x/stake/keeper/val_state_change.go | 13 ++-- x/stake/keeper/validator_test.go | 101 ++++++++++++++++++++--------- 4 files changed, 107 insertions(+), 36 deletions(-) diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index b9eb18be42e0..74d9866fd786 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -252,6 +252,10 @@ func TestUndelegateSelfDelegation(t *testing.T) { err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDec(10)) require.NoError(t, err) + // end block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, int64(10), validator.Tokens.RoundInt64()) @@ -303,6 +307,10 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDec(10)) require.NoError(t, err) + // end block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, blockHeight, validator.UnbondingHeight) @@ -374,6 +382,10 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDec(10)) require.NoError(t, err) + // end block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, blockHeight, validator.UnbondingHeight) @@ -541,6 +553,10 @@ func TestRedelegateSelfDelegation(t *testing.T) { err := keeper.BeginRedelegation(ctx, val0AccAddr, addrVals[0], addrVals[1], sdk.NewDec(10)) require.NoError(t, err) + // end block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 2, len(updates)) + validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, int64(10), validator.Tokens.RoundInt64()) @@ -599,6 +615,10 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDec(10)) require.NoError(t, err) + // end block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, blockHeight, validator.UnbondingHeight) @@ -678,6 +698,10 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { err := keeper.BeginUnbonding(ctx, val0AccAddr, addrVals[0], sdk.NewDec(10)) require.NoError(t, err) + // end block + updates := keeper.GetTendermintUpdates(ctx) + require.Equal(t, 1, len(updates)) + validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, blockHeight, validator.UnbondingHeight) diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index b4e9e54499a7..9db459539853 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -1,7 +1,6 @@ package keeper import ( - "fmt" "testing" "time" @@ -27,6 +26,7 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) { for i := 0; i < numVals; i++ { validator := types.NewValidator(addrVals[i], PKs[i], types.Description{}) validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(amt)) + validator.BondIntraTxCounter = int16(i) pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(amt)) keeper.SetPool(ctx, pool) validator = updateValidator(keeper, ctx, validator) @@ -165,7 +165,7 @@ func TestSlashRedelegation(t *testing.T) { // end block updates := keeper.GetTendermintUpdates(ctx) - require.Equal(t, 2, len(updates)) + require.Equal(t, 1, len(updates)) // initialbalance unchanged require.Equal(t, sdk.NewInt64Coin(params.BondDenom, 10), rd.InitialBalance) @@ -211,6 +211,7 @@ func TestSlashValidatorAtCurrentHeight(t *testing.T) { updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) + validator = keeper.mustGetValidator(ctx, validator.OperatorAddr) // power decreased require.Equal(t, sdk.NewDec(5), validator.GetPower()) // pool bonded shares decreased diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 0c94c33b4aa2..545c19379ba5 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -30,7 +30,9 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU for ; iterator.Valid(); iterator.Next() { var operator [sdk.AddrLen]byte copy(operator[:], iterator.Key()[1:]) - last[operator] = iterator.Value() + powerBytes := iterator.Value() + last[operator] = make([]byte, len(powerBytes)) + copy(last[operator][:], powerBytes[:]) } iterator = sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) @@ -45,7 +47,7 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // we have no more bonded validators // TODO we can remove this if we remove jailed validators from the power store // likewise for zero-power validators, which we never bond - if validator.Jailed || validator.BondedTokens().Equal(sdk.ZeroDec()) { + if validator.Jailed || validator.Tokens.Equal(sdk.ZeroDec()) { break } @@ -186,10 +188,13 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. k.DeleteValidatorByPowerIndex(ctx, validator, pool) - // XXX WHAT DO WE DO FOR BondIntraTxCounter Height Now?????????????????????????? - validator.BondHeight = ctx.BlockHeight() + // XXX Are we OK with this? In order of power decreasing, but addresses break ties. + counter := k.GetIntraTxCounter(ctx) + validator.BondIntraTxCounter = counter + k.SetIntraTxCounter(ctx, counter+1) + // set the status validator, pool = validator.UpdateStatus(pool, sdk.Bonded) k.SetPool(ctx, pool) diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 3c7a4875371b..1a0809c98eda 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -29,11 +29,17 @@ func TestSetValidator(t *testing.T) { assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens)) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares)) keeper.SetPool(ctx, pool) - updateValidator(keeper, ctx, validator) + keeper.SetValidator(ctx, validator) + keeper.SetValidatorByPowerIndex(ctx, validator, pool) - // after the save the validator should be bonded + // ensure update + updates := keeper.GetTendermintUpdates(ctx) validator, found := keeper.GetValidator(ctx, valAddr) require.True(t, found) + require.Equal(t, 1, len(updates)) + require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) + + // after the save the validator should be bonded require.Equal(t, sdk.Bonded, validator.Status) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.Tokens)) assert.True(sdk.DecEq(t, sdk.NewDec(10), validator.DelegatorShares)) @@ -59,10 +65,6 @@ func TestSetValidator(t *testing.T) { require.Equal(t, 1, len(resVals)) require.True(ValEq(t, validator, resVals[0])) - updates := keeper.GetTendermintUpdates(ctx) - require.Equal(t, 1, len(updates)) - require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) - allVals := keeper.GetAllValidators(ctx) require.Equal(t, 1, len(allVals)) } @@ -92,6 +94,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) // burn half the delegator shares + keeper.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, burned := validator.RemoveDelShares(pool, delSharesCreated.Quo(sdk.NewDec(2))) require.Equal(t, int64(50), burned.RoundInt64()) keeper.SetPool(ctx, pool) // update the pool @@ -140,6 +143,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { // remove enough tokens to kick out the validator below the current cliff // validator and next in line cliff validator + keeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal, pool) nextCliffVal, pool, _ = nextCliffVal.RemoveDelShares(pool, sdk.NewDec(21)) keeper.SetPool(ctx, pool) nextCliffVal = updateValidator(keeper, ctx, nextCliffVal) @@ -450,6 +454,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { assert.True(ValEq(t, validators[3], resValidators[1])) pool := keeper.GetPool(ctx) + keeper.DeleteValidatorByPowerIndex(ctx, validators[0], pool) validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(500)) keeper.SetPool(ctx, pool) validators[0] = updateValidator(keeper, ctx, validators[0]) @@ -467,6 +472,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { validators[3], found = keeper.GetValidator(ctx, validators[3].OperatorAddr) require.True(t, found) + keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1)) keeper.SetPool(ctx, pool) validators[3] = updateValidator(keeper, ctx, validators[3]) @@ -476,6 +482,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { assert.True(ValEq(t, validators[3], resValidators[1])) // validator 3 kicked out temporarily + keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201)) keeper.SetPool(ctx, pool) validators[3] = updateValidator(keeper, ctx, validators[3]) @@ -485,6 +492,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { assert.True(ValEq(t, validators[2], resValidators[1])) // validator 4 does not get spot back + keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200)) keeper.SetPool(ctx, pool) validators[3] = updateValidator(keeper, ctx, validators[3]) @@ -532,6 +540,8 @@ func TestValidatorBondHeight(t *testing.T) { assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[1], resValidators[1])) + keeper.DeleteValidatorByPowerIndex(ctx, validators[1], pool) + keeper.DeleteValidatorByPowerIndex(ctx, validators[2], pool) validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50)) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50)) keeper.SetPool(ctx, pool) @@ -557,6 +567,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { pool := keeper.GetPool(ctx) validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) + validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) updateValidator(keeper, ctx, validators[i]) } @@ -565,7 +576,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { validators[i], found = keeper.GetValidator(ctx, validators[i].OperatorAddr) require.True(t, found) } - assert.Equal(t, sdk.Unbonding, validators[0].Status) + assert.Equal(t, sdk.Unbonded, validators[0].Status) assert.Equal(t, sdk.Unbonding, validators[1].Status) assert.Equal(t, sdk.Bonded, validators[2].Status) assert.Equal(t, sdk.Bonded, validators[3].Status) @@ -605,13 +616,18 @@ func TestGetTendermintUpdatesAllNone(t *testing.T) { // test from nothing to something // tendermintUpdate set: {} -> {c1, c3} require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + pool := keeper.GetPool(ctx) + keeper.SetValidator(ctx, validators[0]) + keeper.SetValidatorByPowerIndex(ctx, validators[0], pool) + keeper.SetValidator(ctx, validators[1]) + keeper.SetValidatorByPowerIndex(ctx, validators[1], pool) updates := keeper.GetTendermintUpdates(ctx) assert.Equal(t, 2, len(updates)) - assert.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) - assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) + validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddr) + validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddr) + assert.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) + assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) } func TestGetTendermintUpdatesIdentical(t *testing.T) { @@ -689,8 +705,8 @@ func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates)) - require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) + require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) + require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) } func TestGetTendermintUpdatesInserted(t *testing.T) { @@ -710,22 +726,31 @@ func TestGetTendermintUpdatesInserted(t *testing.T) { // test validtor added at the beginning // tendermintUpdate set: {} -> {c0} - validators[2] = updateValidator(keeper, ctx, validators[2]) + pool := keeper.GetPool(ctx) + keeper.SetValidator(ctx, validators[2]) + keeper.SetValidatorByPowerIndex(ctx, validators[2], pool) updates := keeper.GetTendermintUpdates(ctx) + validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddr) require.Equal(t, 1, len(updates)) require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) // test validtor added at the beginning // tendermintUpdate set: {} -> {c0} - validators[3] = updateValidator(keeper, ctx, validators[3]) + pool = keeper.GetPool(ctx) + keeper.SetValidator(ctx, validators[3]) + keeper.SetValidatorByPowerIndex(ctx, validators[3], pool) updates = keeper.GetTendermintUpdates(ctx) + validators[3], _ = keeper.GetValidator(ctx, validators[3].OperatorAddr) require.Equal(t, 1, len(updates)) require.Equal(t, validators[3].ABCIValidatorUpdate(), updates[0]) // test validtor added at the end // tendermintUpdate set: {} -> {c0} - validators[4] = updateValidator(keeper, ctx, validators[4]) + pool = keeper.GetPool(ctx) + keeper.SetValidator(ctx, validators[4]) + keeper.SetValidatorByPowerIndex(ctx, validators[4], pool) updates = keeper.GetTendermintUpdates(ctx) + validators[4], _ = keeper.GetValidator(ctx, validators[4].OperatorAddr) require.Equal(t, 1, len(updates)) require.Equal(t, validators[4].ABCIValidatorUpdate(), updates[0]) } @@ -761,12 +786,13 @@ func TestGetTendermintUpdatesWithCliffValidator(t *testing.T) { pool := keeper.GetPool(ctx) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(10)) keeper.SetPool(ctx, pool) - validators[2] = updateValidator(keeper, ctx, validators[2]) - + keeper.SetValidator(ctx, validators[2]) + keeper.SetValidatorByPowerIndex(ctx, validators[2], pool) updates = keeper.GetTendermintUpdates(ctx) + validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddr) require.Equal(t, 2, len(updates), "%v", updates) - require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[0]) - require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[1]) + require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[1]) + require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) } func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { @@ -778,6 +804,7 @@ func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { pool := keeper.GetPool(ctx) validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) + validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) } validators[0] = updateValidator(keeper, ctx, validators[0]) @@ -825,15 +852,19 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { valAddr := sdk.ValAddress(valPubKey.Address().Bytes()) validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{}) + validators[i].BondIntraTxCounter = int16(i) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) - validators[i] = updateValidator(keeper, ctx, validators[i]) + keeper.SetValidator(ctx, validators[i]) + keeper.SetValidatorByPowerIndex(ctx, validators[i], pool) } // verify initial Tendermint updates are correct updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, len(validators), len(updates)) + validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddr) + validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddr) require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) @@ -842,10 +873,12 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { // update initial validator set for i, amt := range amts { pool := keeper.GetPool(ctx) + keeper.DeleteValidatorByPowerIndex(ctx, validators[i], pool) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) - validators[i] = updateValidator(keeper, ctx, validators[i]) + keeper.SetValidator(ctx, validators[i]) + keeper.SetValidatorByPowerIndex(ctx, validators[i], pool) } // add a new validator that goes from zero power, to non-zero power, back to @@ -859,10 +892,11 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { validator, pool, _ = validator.AddTokensFromDel(pool, amt) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + keeper.SetValidator(ctx, validator) validator, pool, _ = validator.RemoveDelShares(pool, sdk.NewDecFromInt(amt)) - validator = updateValidator(keeper, ctx, validator) + keeper.SetValidator(ctx, validator) + keeper.SetValidatorByPowerIndex(ctx, validator, pool) // add a new validator that increases in power valPubKey = PKs[len(validators)+2] @@ -870,12 +904,15 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { validator = types.NewValidator(valAddr, valPubKey, types.Description{}) validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(500)) - + keeper.SetValidator(ctx, validator) + keeper.SetValidatorByPowerIndex(ctx, validator, pool) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) // verify initial Tendermint updates are correct updates = keeper.GetTendermintUpdates(ctx) + validator, _ = keeper.GetValidator(ctx, validator.OperatorAddr) + validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddr) + validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddr) require.Equal(t, len(validators)+1, len(updates)) require.Equal(t, validator.ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) @@ -901,14 +938,17 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { validators[i] = types.NewValidator(valAddr, valPubKey, types.Description{Moniker: moniker}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) - + validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) - validators[i] = updateValidator(keeper, ctx, validators[i]) + keeper.SetValidator(ctx, validators[i]) + keeper.SetValidatorByPowerIndex(ctx, validators[i], pool) } // verify initial Tendermint updates are correct updates := keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(updates)) + validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddr) + validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddr) require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) @@ -942,10 +982,11 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { keeper.SetPool(ctx, pool) validator = updateValidator(keeper, ctx, validator) + keeper.DeleteValidatorByPowerIndex(ctx, validators[1], pool) validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(250)) - keeper.SetPool(ctx, pool) - validators[1] = updateValidator(keeper, ctx, validator) + keeper.SetValidator(ctx, validators[1]) + keeper.SetValidatorByPowerIndex(ctx, validators[1], pool) // verify initial Tendermint updates are correct updates = keeper.GetTendermintUpdates(ctx) From d8f2656818bed05ef16446254bdf0a4c116b4933 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 1 Oct 2018 17:45:22 +0200 Subject: [PATCH 38/52] Fix slashing tests (just adding stake.EndBlocker calls) --- x/slashing/handler_test.go | 3 +++ x/slashing/keeper_test.go | 27 ++++++++++++++++++++++++++- x/slashing/tick_test.go | 3 +++ x/stake/keeper/slash.go | 6 ++---- 4 files changed, 34 insertions(+), 5 deletions(-) diff --git a/x/slashing/handler_test.go b/x/slashing/handler_test.go index 9cdcd05334f0..7aebf0d0bf11 100644 --- a/x/slashing/handler_test.go +++ b/x/slashing/handler_test.go @@ -45,6 +45,9 @@ func TestJailedValidatorDelegations(t *testing.T) { got := stake.NewHandler(stakeKeeper)(ctx, msgCreateVal) require.True(t, got.IsOK(), "expected create validator msg to be ok, got: %v", got) + // end block + stake.EndBlocker(ctx, stakeKeeper) + // set dummy signing info newInfo := ValidatorSigningInfo{ StartHeight: int64(0), diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 6845f35ce2c2..e32e7af5b314 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -85,13 +85,16 @@ func TestSlashingPeriodCap(t *testing.T) { // double sign less than max age keeper.handleDoubleSign(ctx, valConsPubKey.Address(), 0, time.Unix(0, 0), amtInt) - // should be jailed require.True(t, sk.Validator(ctx, addr).GetJailed()) + // end block + stake.EndBlocker(ctx, sk) // update block height ctx = ctx.WithBlockHeight(int64(1)) // unjail to measure power sk.Unjail(ctx, valConsAddr) + // end block + stake.EndBlocker(ctx, sk) // power should be reduced expectedPower := sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))) require.Equal(t, expectedPower, sk.Validator(ctx, addr).GetPower()) @@ -100,10 +103,14 @@ func TestSlashingPeriodCap(t *testing.T) { keeper.handleDoubleSign(ctx, valConsPubKey.Address(), 0, time.Unix(0, 0), amtInt) // should be jailed require.True(t, sk.Validator(ctx, addr).GetJailed()) + // end block + stake.EndBlocker(ctx, sk) // update block height ctx = ctx.WithBlockHeight(int64(2)) // unjail to measure power sk.Unjail(ctx, valConsAddr) + // end block + stake.EndBlocker(ctx, sk) // power should be equal, no more should have been slashed expectedPower = sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))) require.Equal(t, expectedPower, sk.Validator(ctx, addr).GetPower()) @@ -114,6 +121,8 @@ func TestSlashingPeriodCap(t *testing.T) { require.True(t, sk.Validator(ctx, addr).GetJailed()) // unjail to measure power sk.Unjail(ctx, valConsAddr) + // end block + stake.EndBlocker(ctx, sk) // power should be reduced expectedPower = sdk.NewDecFromInt(amt).Mul(sdk.NewDec(18).Quo(sdk.NewDec(20))) require.Equal(t, expectedPower, sk.Validator(ctx, addr).GetPower()) @@ -180,6 +189,9 @@ func TestHandleAbsentValidator(t *testing.T) { require.Equal(t, int64(0), info.StartHeight) require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-1, info.SignedBlocksCounter) + // end block + stake.EndBlocker(ctx, sk) + // validator should have been jailed validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) require.Equal(t, sdk.Unbonding, validator.GetStatus()) @@ -193,6 +205,9 @@ func TestHandleAbsentValidator(t *testing.T) { got = slh(ctx, NewMsgUnjail(addr)) require.True(t, got.IsOK()) + // end block + stake.EndBlocker(ctx, sk) + // validator should be rebonded now validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) require.Equal(t, sdk.Bonded, validator.GetStatus()) @@ -222,12 +237,19 @@ func TestHandleAbsentValidator(t *testing.T) { keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) } + // end block + stake.EndBlocker(ctx, sk) + // validator should be jailed again after 500 unsigned blocks nextHeight = height + keeper.MinSignedPerWindow(ctx) + 1 for ; height <= nextHeight; height++ { ctx = ctx.WithBlockHeight(height) keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) } + + // end block + stake.EndBlocker(ctx, sk) + validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) require.Equal(t, sdk.Unbonding, validator.GetStatus()) } @@ -296,6 +318,9 @@ func TestHandleAlreadyJailed(t *testing.T) { keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) } + // end block + stake.EndBlocker(ctx, sk) + // validator should have been jailed and slashed validator, _ := sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) require.Equal(t, sdk.Unbonding, validator.GetStatus()) diff --git a/x/slashing/tick_test.go b/x/slashing/tick_test.go index 5f0ccf8ed54e..a98d97c54ce7 100644 --- a/x/slashing/tick_test.go +++ b/x/slashing/tick_test.go @@ -77,6 +77,9 @@ func TestBeginBlocker(t *testing.T) { BeginBlocker(ctx, req, keeper) } + // end block + stake.EndBlocker(ctx, sk) + // validator should be jailed validator, found := sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(pk)) require.True(t, found) diff --git a/x/stake/keeper/slash.go b/x/stake/keeper/slash.go index 60bff51ff108..9c8a0dac4b78 100644 --- a/x/stake/keeper/slash.go +++ b/x/stake/keeper/slash.go @@ -95,17 +95,15 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh } } - // Cannot decrease balance below zero + // cannot decrease balance below zero tokensToBurn := sdk.MinDec(remainingSlashAmount, validator.Tokens) - // burn validator's tokens + // burn validator's tokens and update the validator validator = k.RemoveValidatorTokens(ctx, validator, tokensToBurn) pool := k.GetPool(ctx) pool.LooseTokens = pool.LooseTokens.Sub(tokensToBurn) k.SetPool(ctx, pool) - // update the validator, possibly kicking it out - // remove validator if it has no more tokens if validator.Tokens.IsZero() { k.RemoveValidator(ctx, validator.OperatorAddr) From a12cda181ebf8fe846730072842ef0f6db83ccf0 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 1 Oct 2018 18:16:57 +0200 Subject: [PATCH 39/52] Fix more testcases --- x/stake/handler_test.go | 24 ++++- x/stake/keeper/delegation_test.go | 4 +- x/stake/keeper/key.go | 5 +- x/stake/keeper/val_state_change.go | 1 - x/stake/keeper/validator_test.go | 141 ++++++++++++++++------------- 5 files changed, 105 insertions(+), 70 deletions(-) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 31adb307b7cd..085e11503050 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -86,6 +86,7 @@ func TestValidatorByPowerIndex(t *testing.T) { msgCreateValidator = newTestMsgCreateValidator(validatorAddr3, keep.PKs[2], int64(1000000)) got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) + // must end-block updates = keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(updates)) @@ -94,6 +95,7 @@ func TestValidatorByPowerIndex(t *testing.T) { consAddr0 := sdk.ConsAddress(keep.PKs[0].Address()) keeper.Slash(ctx, consAddr0, 0, initBond, sdk.NewDecWithPrec(5, 1)) keeper.Jail(ctx, consAddr0) + keeper.GetTendermintUpdates(ctx) validator, found = keeper.GetValidator(ctx, validatorAddr) require.True(t, found) require.Equal(t, sdk.Unbonding, validator.Status) // ensure is unbonding @@ -143,8 +145,10 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { msgCreateValidator1 := newTestMsgCreateValidator(addr1, pk1, 10) got := handleMsgCreateValidator(ctx, msgCreateValidator1, keeper) require.True(t, got.IsOK(), "%v", got) - validator, found := keeper.GetValidator(ctx, addr1) + keeper.GetTendermintUpdates(ctx) + + validator, found := keeper.GetValidator(ctx, addr1) require.True(t, found) assert.Equal(t, sdk.Bonded, validator.Status) assert.Equal(t, addr1, validator.OperatorAddr) @@ -323,6 +327,9 @@ func TestIncrementsMsgDelegate(t *testing.T) { got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got) + // apply TM updates + keeper.GetTendermintUpdates(ctx) + validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) require.Equal(t, sdk.Bonded, validator.Status) @@ -405,6 +412,9 @@ func TestIncrementsMsgUnbond(t *testing.T) { amt2 := accMapper.GetAccount(ctx, delegatorAddr).GetCoins().AmountOf(denom) require.Equal(t, amt1.Sub(sdk.NewInt(initBond)).Int64(), amt2.Int64(), "expected coins to be subtracted") + // apply TM updates + keeper.GetTendermintUpdates(ctx) + validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) require.Equal(t, initBond*2, validator.DelegatorShares.RoundInt64()) @@ -587,9 +597,9 @@ func TestJailValidator(t *testing.T) { msgBeginUnbondingValidator := NewMsgBeginUnbonding(sdk.AccAddress(validatorAddr), validatorAddr, sdk.NewDec(10)) msgCompleteUnbondingValidator := NewMsgCompleteUnbonding(sdk.AccAddress(validatorAddr), validatorAddr) got = handleMsgBeginUnbonding(ctx, msgBeginUnbondingValidator, keeper) - require.True(t, got.IsOK(), "expected no error") + require.True(t, got.IsOK(), "expected no error: %v", got) got = handleMsgCompleteUnbonding(ctx, msgCompleteUnbondingValidator, keeper) - require.True(t, got.IsOK(), "expected no error") + require.True(t, got.IsOK(), "expected no error: %v", got) validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) @@ -771,22 +781,30 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { msgCreateValidator := newTestMsgCreateValidator(validatorAddr1, keep.PKs[0], 50) got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + // apply TM updates + keeper.GetTendermintUpdates(ctx) require.Equal(t, 1, len(keeper.GetValidatorsBonded(ctx))) msgCreateValidator = newTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 30) got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + // apply TM updates + keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(keeper.GetValidatorsBonded(ctx))) msgCreateValidator = newTestMsgCreateValidator(validatorAddr3, keep.PKs[2], 10) got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") + // apply TM updates + keeper.GetTendermintUpdates(ctx) require.Equal(t, 2, len(keeper.GetValidatorsBonded(ctx))) // unbond the valdator-2 msgBeginUnbonding := NewMsgBeginUnbonding(sdk.AccAddress(validatorAddr2), validatorAddr2, sdk.NewDec(30)) got = handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper) require.True(t, got.IsOK(), "expected no error on runMsgBeginUnbonding") + // apply TM updates + keeper.GetTendermintUpdates(ctx) // because there are extra validators waiting to get in, the queued // validator (aka. validator-1) should make it into the bonded group, thus diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 74d9866fd786..c101bec1c466 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -617,7 +617,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { // end block updates := keeper.GetTendermintUpdates(ctx) - require.Equal(t, 1, len(updates)) + require.Equal(t, 2, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) @@ -700,7 +700,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { // end block updates := keeper.GetTendermintUpdates(ctx) - require.Equal(t, 1, len(updates)) + require.Equal(t, 2, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index 2de4ac37c794..a93af0c120e5 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -88,12 +88,13 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte { counterBytes := make([]byte, 2) binary.BigEndian.PutUint16(counterBytes, ^uint16(validator.BondIntraTxCounter)) // invert counter (first txns have priority) - return append(append(append(append( + return append(append(append(append(append( ValidatorsByPowerIndexKey, jailedBytes...), powerBytes...), heightBytes...), - counterBytes...) + counterBytes...), + validator.OperatorAddr...) } //______________________________________________________________________________ diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 545c19379ba5..bc0c9eec5510 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -104,7 +104,6 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // any validators left in `last` are no longer bonded for _, operator := range noLongerBonded { // fetch the validator - // TODO might it have been deleted in RemoveValidator? validator := k.mustGetValidator(ctx, sdk.ValAddress(operator)) // bonded to unbonding diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 1a0809c98eda..773bc0d4d6d6 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -463,46 +463,52 @@ func TestGetValidatorsEdgeCases(t *testing.T) { assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) - // A validator which leaves the gotValidator set due to a decrease in voting power, - // then increases to the original voting power, does not get its spot back in the - // case of a tie. - - // validator 3 enters bonded validator set - ctx = ctx.WithBlockHeight(40) - - validators[3], found = keeper.GetValidator(ctx, validators[3].OperatorAddr) - require.True(t, found) - keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) - validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1)) - keeper.SetPool(ctx, pool) - validators[3] = updateValidator(keeper, ctx, validators[3]) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint16(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[3], resValidators[1])) - - // validator 3 kicked out temporarily - keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) - validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201)) - keeper.SetPool(ctx, pool) - validators[3] = updateValidator(keeper, ctx, validators[3]) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint16(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - - // validator 4 does not get spot back - keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) - validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200)) - keeper.SetPool(ctx, pool) - validators[3] = updateValidator(keeper, ctx, validators[3]) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint16(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - validator, exists := keeper.GetValidator(ctx, validators[3].OperatorAddr) - require.Equal(t, exists, true) - require.Equal(t, int64(40), validator.BondHeight) + /* + + TODO: This is no longer true, due to the BondIntraTxCounter changes. + + // A validator which leaves the gotValidator set due to a decrease in voting power, + // then increases to the original voting power, does not get its spot back in the + // case of a tie. + + // validator 3 enters bonded validator set + ctx = ctx.WithBlockHeight(40) + + validators[3], found = keeper.GetValidator(ctx, validators[3].OperatorAddr) + require.True(t, found) + keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) + validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1)) + keeper.SetPool(ctx, pool) + validators[3] = updateValidator(keeper, ctx, validators[3]) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint16(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[3], resValidators[1])) + + // validator 3 kicked out temporarily + keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) + validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201)) + keeper.SetPool(ctx, pool) + validators[3] = updateValidator(keeper, ctx, validators[3]) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint16(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + + // validator 4 does not get spot back + keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) + validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200)) + keeper.SetPool(ctx, pool) + validators[3] = updateValidator(keeper, ctx, validators[3]) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint16(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + validator, exists := keeper.GetValidator(ctx, validators[3].OperatorAddr) + require.Equal(t, exists, true) + require.Equal(t, int64(40), validator.BondHeight) + + */ } func TestValidatorBondHeight(t *testing.T) { @@ -527,30 +533,36 @@ func TestValidatorBondHeight(t *testing.T) { validators[0] = updateValidator(keeper, ctx, validators[0]) - //////////////////////////////////////// - // If two validators both increase to the same voting power in the same block, - // the one with the first transaction should become bonded - validators[1] = updateValidator(keeper, ctx, validators[1]) - validators[2] = updateValidator(keeper, ctx, validators[2]) + /* - pool = keeper.GetPool(ctx) + TODO: This is no longer true, due to the BondIntraTxCounter changes. - resValidators := keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, uint16(len(resValidators)), params.MaxValidators) + //////////////////////////////////////// + // If two validators both increase to the same voting power in the same block, + // the one with the first transaction should become bonded + validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[2] = updateValidator(keeper, ctx, validators[2]) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[1], resValidators[1])) - keeper.DeleteValidatorByPowerIndex(ctx, validators[1], pool) - keeper.DeleteValidatorByPowerIndex(ctx, validators[2], pool) - validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50)) - validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50)) - keeper.SetPool(ctx, pool) - validators[2] = updateValidator(keeper, ctx, validators[2]) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, params.MaxValidators, uint16(len(resValidators))) - validators[1] = updateValidator(keeper, ctx, validators[1]) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) + pool = keeper.GetPool(ctx) + + resValidators := keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, uint16(len(resValidators)), params.MaxValidators) + + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[1], resValidators[1])) + keeper.DeleteValidatorByPowerIndex(ctx, validators[1], pool) + keeper.DeleteValidatorByPowerIndex(ctx, validators[2], pool) + validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50)) + validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50)) + keeper.SetPool(ctx, pool) + validators[2] = updateValidator(keeper, ctx, validators[2]) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, params.MaxValidators, uint16(len(resValidators))) + validators[1] = updateValidator(keeper, ctx, validators[1]) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + + */ } func TestFullValidatorSetPowerChange(t *testing.T) { @@ -1012,6 +1024,9 @@ func TestUpdateValidatorCommission(t *testing.T) { val1, _ = val1.SetInitialCommission(commission1) val2, _ = val2.SetInitialCommission(commission2) + keeper.SetValidator(ctx, val1) + keeper.SetValidator(ctx, val2) + testCases := []struct { validator types.Validator newRate sdk.Dec @@ -1025,11 +1040,13 @@ func TestUpdateValidatorCommission(t *testing.T) { } for i, tc := range testCases { - _, err := keeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate) + commission, err := keeper.UpdateValidatorCommission(ctx, tc.validator, tc.newRate) if tc.expectedErr { require.Error(t, err, "expected error for test case #%d with rate: %s", i, tc.newRate) } else { + tc.validator.Commission = commission + keeper.SetValidator(ctx, tc.validator) val, found := keeper.GetValidator(ctx, tc.validator.OperatorAddr) require.True(t, found, From 0c1ddec314b06295c1f14a0b2ebf03169801c8be Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 1 Oct 2018 18:48:40 +0200 Subject: [PATCH 40/52] Unit tests as far as the eye can see --- x/gov/tally_test.go | 16 ++++++++++++++++ x/stake/handler_test.go | 16 ++++++++-------- x/stake/keeper/delegation.go | 3 ++- x/stake/keeper/slash.go | 3 ++- x/stake/keeper/slash_test.go | 4 ++++ x/stake/keeper/val_state_change.go | 5 +++++ x/stake/keeper/validator_test.go | 25 ++++++++++++++++--------- x/stake/querier/queryable_test.go | 7 ++++++- 8 files changed, 59 insertions(+), 20 deletions(-) diff --git a/x/gov/tally_test.go b/x/gov/tally_test.go index 28fe0cb5990e..26b32cc93a72 100644 --- a/x/gov/tally_test.go +++ b/x/gov/tally_test.go @@ -45,6 +45,7 @@ func TestTallyNoOneVotes(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{5, 5}) + stake.EndBlocker(ctx, sk) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() @@ -69,6 +70,7 @@ func TestTallyOnlyValidatorsAllYes(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{5, 5}) + stake.EndBlocker(ctx, sk) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() @@ -98,6 +100,7 @@ func TestTallyOnlyValidators51No(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{5, 6}) + stake.EndBlocker(ctx, sk) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() @@ -126,6 +129,7 @@ func TestTallyOnlyValidators51Yes(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{6, 6, 7}) + stake.EndBlocker(ctx, sk) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() @@ -157,6 +161,7 @@ func TestTallyOnlyValidatorsVetoed(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{6, 6, 7}) + stake.EndBlocker(ctx, sk) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() @@ -188,6 +193,7 @@ func TestTallyOnlyValidatorsAbstainPasses(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{6, 6, 7}) + stake.EndBlocker(ctx, sk) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() @@ -219,6 +225,7 @@ func TestTallyOnlyValidatorsAbstainFails(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{6, 6, 7}) + stake.EndBlocker(ctx, sk) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() @@ -250,6 +257,7 @@ func TestTallyOnlyValidatorsNonVoter(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{6, 6, 7}) + stake.EndBlocker(ctx, sk) proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() @@ -279,6 +287,7 @@ func TestTallyDelgatorOverride(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{5, 6, 7}) + stake.EndBlocker(ctx, sk) delegator1Msg := stake.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[2]), sdk.NewInt64Coin("steak", 30)) stakeHandler(ctx, delegator1Msg) @@ -315,6 +324,7 @@ func TestTallyDelgatorInherit(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{5, 6, 7}) + stake.EndBlocker(ctx, sk) delegator1Msg := stake.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[2]), sdk.NewInt64Coin("steak", 30)) stakeHandler(ctx, delegator1Msg) @@ -349,6 +359,7 @@ func TestTallyDelgatorMultipleOverride(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{5, 6, 7}) + stake.EndBlocker(ctx, sk) delegator1Msg := stake.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[2]), sdk.NewInt64Coin("steak", 10)) stakeHandler(ctx, delegator1Msg) @@ -402,6 +413,8 @@ func TestTallyDelgatorMultipleInherit(t *testing.T) { delegator1Msg2 := stake.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[1]), sdk.NewInt64Coin("steak", 10)) stakeHandler(ctx, delegator1Msg2) + stake.EndBlocker(ctx, sk) + proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() proposal.SetStatus(StatusVotingPeriod) @@ -432,6 +445,7 @@ func TestTallyJailedValidator(t *testing.T) { } createValidators(t, stakeHandler, ctx, valAddrs, []int64{25, 6, 7}) + stake.EndBlocker(ctx, sk) delegator1Msg := stake.NewMsgDelegate(addrs[3], sdk.ValAddress(addrs[2]), sdk.NewInt64Coin("steak", 10)) stakeHandler(ctx, delegator1Msg) @@ -443,6 +457,8 @@ func TestTallyJailedValidator(t *testing.T) { require.True(t, found) sk.Jail(ctx, sdk.ConsAddress(val2.ConsPubKey.Address())) + stake.EndBlocker(ctx, sk) + proposal := keeper.NewTextProposal(ctx, "Test", "description", ProposalTypeText) proposalID := proposal.GetProposalID() proposal.SetStatus(StatusVotingPeriod) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 085e11503050..8c3893cd0dde 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -130,6 +130,8 @@ func TestValidatorByPowerIndex(t *testing.T) { got = handleMsgCompleteUnbonding(ctx, msgCompleteUnbonding, keeper) require.True(t, got.IsOK(), "expected msg to be ok, got %v", got) + EndBlocker(ctx, keeper) + // verify that by power key nolonger exists _, found = keeper.GetValidator(ctx, validatorAddr) require.False(t, found) @@ -564,11 +566,8 @@ func TestMultipleMsgDelegate(t *testing.T) { // unbond them all for i, delegatorAddr := range delegatorAddrs { msgBeginUnbonding := NewMsgBeginUnbonding(delegatorAddr, validatorAddr, sdk.NewDec(10)) - msgCompleteUnbonding := NewMsgCompleteUnbonding(delegatorAddr, validatorAddr) got := handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper) require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) - got = handleMsgCompleteUnbonding(ctx, msgCompleteUnbonding, keeper) - require.True(t, got.IsOK(), "expected msg %d to be ok, got %v", i, got) //Check that the account is unbonded _, found := keeper.GetDelegation(ctx, delegatorAddr, validatorAddr) @@ -595,11 +594,8 @@ func TestJailValidator(t *testing.T) { // unbond the validators bond portion msgBeginUnbondingValidator := NewMsgBeginUnbonding(sdk.AccAddress(validatorAddr), validatorAddr, sdk.NewDec(10)) - msgCompleteUnbondingValidator := NewMsgCompleteUnbonding(sdk.AccAddress(validatorAddr), validatorAddr) got = handleMsgBeginUnbonding(ctx, msgBeginUnbondingValidator, keeper) require.True(t, got.IsOK(), "expected no error: %v", got) - got = handleMsgCompleteUnbonding(ctx, msgCompleteUnbondingValidator, keeper) - require.True(t, got.IsOK(), "expected no error: %v", got) validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) @@ -803,6 +799,7 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { msgBeginUnbonding := NewMsgBeginUnbonding(sdk.AccAddress(validatorAddr2), validatorAddr2, sdk.NewDec(30)) got = handleMsgBeginUnbonding(ctx, msgBeginUnbonding, keeper) require.True(t, got.IsOK(), "expected no error on runMsgBeginUnbonding") + // apply TM updates keeper.GetTendermintUpdates(ctx) @@ -836,7 +833,7 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { // apply Tendermint updates updates := keeper.GetTendermintUpdates(ctx) - require.Equal(t, 1, len(updates)) + require.Equal(t, 2, len(updates)) // a block passes ctx = ctx.WithBlockHeight(1) @@ -858,7 +855,7 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { // must apply validator updates updates = keeper.GetTendermintUpdates(ctx) - require.Equal(t, 1, len(updates)) + require.Equal(t, 2, len(updates)) // slash the validator by half keeper.Slash(ctx, consAddr0, 0, 20, sdk.NewDecWithPrec(5, 1)) @@ -902,6 +899,9 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { require.True(t, found) require.Equal(t, sdk.NewDec(3), delegation.Shares) + // end blocker + EndBlocker(ctx, keeper) + // validator power should have been reduced to zero // ergo validator should have been removed from the store _, found = keeper.GetValidator(ctx, valA) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index f245da9e3db1..7631be8efb0f 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -323,7 +323,8 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA // remove the coins from the validator validator, amount = k.RemoveValidatorTokensAndShares(ctx, validator, shares) - if validator.DelegatorShares.IsZero() { + if validator.DelegatorShares.IsZero() && validator.Status != sdk.Bonded { + // if bonded, we must remove in EndBlocker instead k.RemoveValidator(ctx, validator.OperatorAddr) } diff --git a/x/stake/keeper/slash.go b/x/stake/keeper/slash.go index 9c8a0dac4b78..9275689fe648 100644 --- a/x/stake/keeper/slash.go +++ b/x/stake/keeper/slash.go @@ -105,7 +105,8 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh k.SetPool(ctx, pool) // remove validator if it has no more tokens - if validator.Tokens.IsZero() { + if validator.Tokens.IsZero() && validator.Status != sdk.Bonded { + // if bonded, we must remove in GetTendermintUpdates instead k.RemoveValidator(ctx, validator.OperatorAddr) } diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index 9db459539853..275e39cdac79 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -316,6 +316,8 @@ func TestSlashWithUnbondingDelegation(t *testing.T) { newPool = keeper.GetPool(ctx) // just 1 bonded token burned again since that's all the validator now has require.Equal(t, int64(10), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64()) + // apply TM updates + keeper.GetTendermintUpdates(ctx) // read updated validator // power decreased by 1 again, validator is out of stake // ergo validator should have been removed from the store @@ -417,6 +419,8 @@ func TestSlashWithRedelegation(t *testing.T) { newPool = keeper.GetPool(ctx) // four more bonded tokens burned require.Equal(t, int64(16), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64()) + // apply TM updates + keeper.GetTendermintUpdates(ctx) // read updated validator // validator decreased to zero power, should have been removed from the store _, found = keeper.GetValidatorByConsAddr(ctx, consAddr) diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index bc0c9eec5510..528a53deadac 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -109,6 +109,11 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // bonded to unbonding k.bondedToUnbonding(ctx, validator) + // remove validator if it has no more tokens + if validator.Tokens.IsZero() { + k.RemoveValidator(ctx, validator.OperatorAddr) + } + // delete from the bonded validator index store.Delete(GetBondedValidatorIndexKey(operator)) diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 773bc0d4d6d6..e717b42956d1 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -184,6 +184,8 @@ func TestSlashToZeroPowerRemoved(t *testing.T) { // slash the validator by 100% consAddr0 := sdk.ConsAddress(PKs[0].Address()) keeper.Slash(ctx, consAddr0, 0, 100, sdk.OneDec()) + // apply TM updates + keeper.GetTendermintUpdates(ctx) // validator should have been deleted _, found := keeper.GetValidator(ctx, addrVals[0]) require.False(t, found) @@ -970,13 +972,15 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { ctx = ctx.WithBlockHeight(1) pool := keeper.GetPool(ctx) - validator, found := keeper.GetValidator(ctx, validators[0].OperatorAddr) + var found bool + validators[0], found = keeper.GetValidator(ctx, validators[0].OperatorAddr) require.True(t, found) - validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(1)) - + keeper.DeleteValidatorByPowerIndex(ctx, validators[0], pool) + validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(1)) keeper.SetPool(ctx, pool) - validators[0] = updateValidator(keeper, ctx, validator) + keeper.SetValidator(ctx, validators[0]) + keeper.SetValidatorByPowerIndex(ctx, validators[0], pool) // verify initial Tendermint updates are correct require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) @@ -986,16 +990,19 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { ctx = ctx.WithBlockHeight(2) pool = keeper.GetPool(ctx) - validator, found = keeper.GetValidator(ctx, validators[1].OperatorAddr) + validators[1], found = keeper.GetValidator(ctx, validators[1].OperatorAddr) require.True(t, found) - validator, pool, _ = validator.RemoveDelShares(pool, validator.DelegatorShares) - + keeper.DeleteValidatorByPowerIndex(ctx, validators[0], pool) + validators[0], pool, _ = validators[0].RemoveDelShares(pool, validators[0].DelegatorShares) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + keeper.SetValidator(ctx, validators[0]) + keeper.SetValidatorByPowerIndex(ctx, validators[0], pool) + updates = keeper.GetTendermintUpdates(ctx) + require.Equal(t, 0, len(updates)) keeper.DeleteValidatorByPowerIndex(ctx, validators[1], pool) - validator, pool, _ = validator.AddTokensFromDel(pool, sdk.NewInt(250)) + validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(250)) keeper.SetPool(ctx, pool) keeper.SetValidator(ctx, validators[1]) keeper.SetValidatorByPowerIndex(ctx, validators[1], pool) diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/queryable_test.go index cbc947889f55..6b403aebadab 100644 --- a/x/stake/querier/queryable_test.go +++ b/x/stake/querier/queryable_test.go @@ -114,9 +114,14 @@ func TestQueryDelegation(t *testing.T) { // Create Validators and Delegation val1 := types.NewValidator(addrVal1, pk1, types.Description{}) keeper.SetValidator(ctx, val1) + pool := keeper.GetPool(ctx) + keeper.SetValidatorByPowerIndex(ctx, val1, pool) keeper.Delegate(ctx, addrAcc2, sdk.NewCoin("steak", sdk.NewInt(20)), val1, true) + // apply TM updates + keeper.GetTendermintUpdates(ctx) + // Query Delegator bonded validators queryParams := newTestDelegatorQuery(addrAcc2) bz, errRes := cdc.MarshalJSON(queryParams) @@ -177,7 +182,7 @@ func TestQueryDelegation(t *testing.T) { require.Equal(t, delegation, delegationRes) - // Query unbonging delegation + // Query unbonding delegation keeper.BeginUnbonding(ctx, addrAcc2, val1.OperatorAddr, sdk.NewDec(10)) query = abci.RequestQuery{ From c7cac2d5f60c62839c76df4e97af59a74fb21395 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 1 Oct 2018 18:53:17 +0200 Subject: [PATCH 41/52] Update PENDING.md --- PENDING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/PENDING.md b/PENDING.md index 4956fbc2c6cb..fd16669aaf70 100644 --- a/PENDING.md +++ b/PENDING.md @@ -64,6 +64,7 @@ BREAKING CHANGES * [x/auth] \#2377 auth.StdSignMsg -> txbuilder.StdSignMsg * [x/staking] \#2244 staking now holds a consensus-address-index instead of a consensus-pubkey-index * [x/staking] \#2236 more distribution hooks for distribution + * [x/stake] \#2394 Split up UpdateValidator into distinct state transitions applied only in EndBlock * Tendermint From 7d82281715e9c1c87ed880e415421f548d4e7605 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 2 Oct 2018 09:43:18 +0200 Subject: [PATCH 42/52] Address review comments, round one --- x/stake/keeper/delegation_test.go | 4 + x/stake/keeper/key.go | 5 +- x/stake/keeper/val_state_change.go | 37 +------- x/stake/keeper/validator.go | 5 ++ x/stake/keeper/validator_test.go | 138 ++++++++++++++--------------- 5 files changed, 80 insertions(+), 109 deletions(-) diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index c101bec1c466..104d5d27635a 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -570,6 +570,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { //create a validator with a self-delegation validator := types.NewValidator(addrVals[0], PKs[0], types.Description{}) + validator.BondIntraTxCounter = 1 validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) @@ -599,6 +600,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { // create a second validator validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2.BondIntraTxCounter = 2 validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) @@ -668,6 +670,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { // create a second delegation to this validator validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) + validator.BondIntraTxCounter = 1 require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) validator = updateValidator(keeper, ctx, validator) @@ -681,6 +684,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { // create a second validator validator2 := types.NewValidator(addrVals[1], PKs[1], types.Description{}) + validator2.BondIntraTxCounter = 2 validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index a93af0c120e5..2de4ac37c794 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -88,13 +88,12 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte { counterBytes := make([]byte, 2) binary.BigEndian.PutUint16(counterBytes, ^uint16(validator.BondIntraTxCounter)) // invert counter (first txns have priority) - return append(append(append(append(append( + return append(append(append(append( ValidatorsByPowerIndexKey, jailedBytes...), powerBytes...), heightBytes...), - counterBytes...), - validator.OperatorAddr...) + counterBytes...) } //______________________________________________________________________________ diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 528a53deadac..afb600a713b3 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -61,18 +61,16 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU // no state change } - // validator still in the validator set + // fetch the old power bytes var opbytes [sdk.AddrLen]byte copy(opbytes[:], operator[:]) - - // fetch the old power bytes - powerBytes, ok := last[opbytes] + oldPowerBytes, ok := last[opbytes] // calculate the new power bytes newPowerBytes := validator.ABCIValidatorPowerBytes(k.cdc) // update the validator set if power has changed - if !ok || !bytes.Equal(powerBytes, newPowerBytes) { + if !ok || !bytes.Equal(oldPowerBytes, newPowerBytes) { updates = append(updates, validator.ABCIValidatorUpdate()) } @@ -88,6 +86,7 @@ func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorU } // sort the map keys for determinism + // sorted by address - order doesn't matter noLongerBonded := make([][]byte, len(last)) index := 0 for oper := range last { @@ -194,11 +193,6 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. validator.BondHeight = ctx.BlockHeight() - // XXX Are we OK with this? In order of power decreasing, but addresses break ties. - counter := k.GetIntraTxCounter(ctx) - validator.BondIntraTxCounter = counter - k.SetIntraTxCounter(ctx, counter+1) - // set the status validator, pool = validator.UpdateStatus(pool, sdk.Bonded) k.SetPool(ctx, pool) @@ -262,26 +256,3 @@ func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Vali k.SetValidator(ctx, validator) return validator } - -// XXX need to figure out how to set a validator's BondIntraTxCounter - probably during delegation bonding? -// or keep track of tx for final bonding and set during endblock??? wish we could reduce this complexity - -// get the bond height and incremented intra-tx counter -// nolint: unparam -func (k Keeper) bondIncrement(ctx sdk.Context, isNewValidator bool, validator types.Validator) ( - height int64, intraTxCounter int16) { - - // if already a validator, copy the old block height and counter - if !isNewValidator && validator.Status == sdk.Bonded { - height = validator.BondHeight - intraTxCounter = validator.BondIntraTxCounter - return - } - - height = ctx.BlockHeight() - counter := k.GetIntraTxCounter(ctx) - intraTxCounter = counter - - k.SetIntraTxCounter(ctx, counter+1) - return -} diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 5024ba17e4e6..568b24a0d527 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -130,6 +130,11 @@ func (k Keeper) AddValidatorTokensAndShares(ctx sdk.Context, validator types.Val pool := k.GetPool(ctx) k.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, addedShares = validator.AddTokensFromDel(pool, tokensToAdd) + // increment the intra-tx counter + // in case of a conflict, the validator which least recently changed power takes precedence + counter := k.GetIntraTxCounter(ctx) + validator.BondIntraTxCounter = counter + k.SetIntraTxCounter(ctx, counter+1) k.SetValidator(ctx, validator) k.SetPool(ctx, pool) k.SetValidatorByPowerIndex(ctx, validator, pool) diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index e717b42956d1..301f19a17f4e 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -442,6 +442,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { moniker := fmt.Sprintf("val#%d", int64(i)) validators[i] = types.NewValidator(sdk.ValAddress(Addrs[i]), PKs[i], types.Description{Moniker: moniker}) validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) + validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) validators[i] = updateValidator(keeper, ctx, validators[i]) } @@ -465,52 +466,46 @@ func TestGetValidatorsEdgeCases(t *testing.T) { assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) - /* - - TODO: This is no longer true, due to the BondIntraTxCounter changes. - - // A validator which leaves the gotValidator set due to a decrease in voting power, - // then increases to the original voting power, does not get its spot back in the - // case of a tie. - - // validator 3 enters bonded validator set - ctx = ctx.WithBlockHeight(40) - - validators[3], found = keeper.GetValidator(ctx, validators[3].OperatorAddr) - require.True(t, found) - keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) - validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1)) - keeper.SetPool(ctx, pool) - validators[3] = updateValidator(keeper, ctx, validators[3]) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint16(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[3], resValidators[1])) - - // validator 3 kicked out temporarily - keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) - validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201)) - keeper.SetPool(ctx, pool) - validators[3] = updateValidator(keeper, ctx, validators[3]) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint16(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - - // validator 4 does not get spot back - keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) - validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200)) - keeper.SetPool(ctx, pool) - validators[3] = updateValidator(keeper, ctx, validators[3]) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, nMax, uint16(len(resValidators))) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) - validator, exists := keeper.GetValidator(ctx, validators[3].OperatorAddr) - require.Equal(t, exists, true) - require.Equal(t, int64(40), validator.BondHeight) - - */ + // A validator which leaves the gotValidator set due to a decrease in voting power, + // then increases to the original voting power, does not get its spot back in the + // case of a tie. + + // validator 3 enters bonded validator set + ctx = ctx.WithBlockHeight(40) + + validators[3], found = keeper.GetValidator(ctx, validators[3].OperatorAddr) + require.True(t, found) + keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) + validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1)) + keeper.SetPool(ctx, pool) + validators[3] = updateValidator(keeper, ctx, validators[3]) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint16(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[3], resValidators[1])) + + // validator 3 kicked out temporarily + keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) + validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201)) + keeper.SetPool(ctx, pool) + validators[3] = updateValidator(keeper, ctx, validators[3]) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint16(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + + // validator 4 does not get spot back + keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) + validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200)) + keeper.SetPool(ctx, pool) + validators[3] = updateValidator(keeper, ctx, validators[3]) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, nMax, uint16(len(resValidators))) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) + validator, exists := keeper.GetValidator(ctx, validators[3].OperatorAddr) + require.Equal(t, exists, true) + require.Equal(t, int64(40), validator.BondHeight) } func TestValidatorBondHeight(t *testing.T) { @@ -527,6 +522,9 @@ func TestValidatorBondHeight(t *testing.T) { validators[0] = types.NewValidator(sdk.ValAddress(Addrs[0]), PKs[0], types.Description{}) validators[1] = types.NewValidator(sdk.ValAddress(Addrs[1]), PKs[1], types.Description{}) validators[2] = types.NewValidator(sdk.ValAddress(Addrs[2]), PKs[2], types.Description{}) + validators[0].BondIntraTxCounter = 0 + validators[1].BondIntraTxCounter = 1 + validators[2].BondIntraTxCounter = 2 validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(200)) validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(100)) @@ -535,36 +533,30 @@ func TestValidatorBondHeight(t *testing.T) { validators[0] = updateValidator(keeper, ctx, validators[0]) - /* - - TODO: This is no longer true, due to the BondIntraTxCounter changes. - - //////////////////////////////////////// - // If two validators both increase to the same voting power in the same block, - // the one with the first transaction should become bonded - validators[1] = updateValidator(keeper, ctx, validators[1]) - validators[2] = updateValidator(keeper, ctx, validators[2]) - - pool = keeper.GetPool(ctx) + //////////////////////////////////////// + // If two validators both increase to the same voting power in the same block, + // the one with the first transaction should become bonded + validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[2] = updateValidator(keeper, ctx, validators[2]) - resValidators := keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, uint16(len(resValidators)), params.MaxValidators) + pool = keeper.GetPool(ctx) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[1], resValidators[1])) - keeper.DeleteValidatorByPowerIndex(ctx, validators[1], pool) - keeper.DeleteValidatorByPowerIndex(ctx, validators[2], pool) - validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50)) - validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50)) - keeper.SetPool(ctx, pool) - validators[2] = updateValidator(keeper, ctx, validators[2]) - resValidators = keeper.GetBondedValidatorsByPower(ctx) - require.Equal(t, params.MaxValidators, uint16(len(resValidators))) - validators[1] = updateValidator(keeper, ctx, validators[1]) - assert.True(ValEq(t, validators[0], resValidators[0])) - assert.True(ValEq(t, validators[2], resValidators[1])) + resValidators := keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, uint16(len(resValidators)), params.MaxValidators) - */ + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[1], resValidators[1])) + keeper.DeleteValidatorByPowerIndex(ctx, validators[1], pool) + keeper.DeleteValidatorByPowerIndex(ctx, validators[2], pool) + validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50)) + validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50)) + keeper.SetPool(ctx, pool) + validators[2] = updateValidator(keeper, ctx, validators[2]) + resValidators = keeper.GetBondedValidatorsByPower(ctx) + require.Equal(t, params.MaxValidators, uint16(len(resValidators))) + validators[1] = updateValidator(keeper, ctx, validators[1]) + assert.True(ValEq(t, validators[0], resValidators[0])) + assert.True(ValEq(t, validators[2], resValidators[1])) } func TestFullValidatorSetPowerChange(t *testing.T) { From b96faf6dbb5990f9eb673f58692b5d6c44e39e6b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 2 Oct 2018 09:52:58 +0200 Subject: [PATCH 43/52] dep update, rename to clarify that function applies state changes --- Gopkg.lock | 16 +++---- x/stake/genesis.go | 2 +- x/stake/handler.go | 2 +- x/stake/handler_test.go | 30 ++++++------ x/stake/keeper/delegation_test.go | 12 ++--- x/stake/keeper/slash.go | 2 +- x/stake/keeper/slash_test.go | 10 ++-- x/stake/keeper/test_common.go | 2 +- x/stake/keeper/val_state_change.go | 2 +- x/stake/keeper/validator_test.go | 76 +++++++++++++++--------------- x/stake/querier/queryable_test.go | 2 +- x/stake/simulation/invariants.go | 1 - 12 files changed, 78 insertions(+), 79 deletions(-) diff --git a/Gopkg.lock b/Gopkg.lock index 5160d752e904..62f1f7e5b2f2 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -239,12 +239,12 @@ version = "v1.0.0" [[projects]] - digest = "1:645110e089152bd0f4a011a2648fbb0e4df5977be73ca605781157ac297f50c4" + digest = "1:e32dfc6abff6a3633ef4d9a1022fd707c8ef26f1e1e8f855dc58dc415ce7c8f3" name = "github.com/mitchellh/mapstructure" packages = ["."] pruneopts = "UT" - revision = "fa473d140ef3c6adf42d6b391fe76707f1f243c8" - version = "v1.0.0" + revision = "fe40af7a9c397fa3ddba203c38a5042c5d0475ad" + version = "v1.1.1" [[projects]] digest = "1:95741de3af260a92cc5c7f3f3061e85273f5a81b5db20d4bd68da74bd521675e" @@ -536,7 +536,7 @@ "salsa20/salsa", ] pruneopts = "UT" - revision = "0e37d006457bf46f9e6692014ba72ef82c33022c" + revision = "e3636079e1a4c1f337f212cc5cd2aca108f6c900" [[projects]] digest = "1:d36f55a999540d29b6ea3c2ea29d71c76b1d9853fdcd3e5c5cb4836f2ba118f1" @@ -556,14 +556,14 @@ [[projects]] branch = "master" - digest = "1:68023dc297a659d5eb2dafd62eda811456b338c5b3ec3c27da79e8a47d3f456a" + digest = "1:8bc8ecef1d63576cfab4d08b44a1f255dd67e5b019b7a44837d62380f266a91c" name = "golang.org/x/sys" packages = [ "cpu", "unix", ] pruneopts = "UT" - revision = "2f1df4e56cdeb503a08d8577e6f1a7eb12efab82" + revision = "e4b3c5e9061176387e7cea65e4dc5853801f3fb7" [[projects]] digest = "1:a2ab62866c75542dd18d2b069fec854577a20211d7c0ea6ae746072a1dccdd18" @@ -590,11 +590,11 @@ [[projects]] branch = "master" - digest = "1:56b0bca90b7e5d1facf5fbdacba23e4e0ce069d25381b8e2f70ef1e7ebfb9c1a" + digest = "1:1e6b0176e8c5dd8ff551af65c76f8b73a99bcf4d812cedff1b91711b7df4804c" name = "google.golang.org/genproto" packages = ["googleapis/rpc/status"] pruneopts = "UT" - revision = "0e822944c569bf5c9afd034adaa56208bd2906ac" + revision = "c7e5094acea1ca1b899e2259d80a6b0f882f81f8" [[projects]] digest = "1:2dab32a43451e320e49608ff4542fdfc653c95dcc35d0065ec9c6c3dd540ed74" diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 5bc76d562e7a..45754f34309d 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -44,7 +44,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ keeper.SetDelegation(ctx, bond) } - res = keeper.GetTendermintUpdates(ctx) + res = keeper.ApplyAndReturnValidatorSetUpdates(ctx) return } diff --git a/x/stake/handler.go b/x/stake/handler.go index 89b6406de26d..f3a007fd51d9 100644 --- a/x/stake/handler.go +++ b/x/stake/handler.go @@ -52,7 +52,7 @@ func EndBlocker(ctx sdk.Context, k keeper.Keeper) (ValidatorUpdates []abci.Valid k.SetIntraTxCounter(ctx, 0) // calculate validator set changes - ValidatorUpdates = k.GetTendermintUpdates(ctx) + ValidatorUpdates = k.ApplyAndReturnValidatorSetUpdates(ctx) return } diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 8c3893cd0dde..7c97b8190af7 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -64,7 +64,7 @@ func TestValidatorByPowerIndex(t *testing.T) { require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) // must end-block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) // verify the self-delegation exists @@ -88,14 +88,14 @@ func TestValidatorByPowerIndex(t *testing.T) { require.True(t, got.IsOK(), "expected create-validator to be ok, got %v", got) // must end-block - updates = keeper.GetTendermintUpdates(ctx) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) // slash and jail the first validator consAddr0 := sdk.ConsAddress(keep.PKs[0].Address()) keeper.Slash(ctx, consAddr0, 0, initBond, sdk.NewDecWithPrec(5, 1)) keeper.Jail(ctx, consAddr0) - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) validator, found = keeper.GetValidator(ctx, validatorAddr) require.True(t, found) require.Equal(t, sdk.Unbonding, validator.Status) // ensure is unbonding @@ -148,7 +148,7 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { got := handleMsgCreateValidator(ctx, msgCreateValidator1, keeper) require.True(t, got.IsOK(), "%v", got) - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) validator, found := keeper.GetValidator(ctx, addr1) require.True(t, found) @@ -175,7 +175,7 @@ func TestDuplicatesMsgCreateValidator(t *testing.T) { require.True(t, got.IsOK(), "%v", got) // must end-block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) validator, found = keeper.GetValidator(ctx, addr2) @@ -200,7 +200,7 @@ func TestDuplicatesMsgCreateValidatorOnBehalfOf(t *testing.T) { require.True(t, got.IsOK(), "%v", got) // must end-block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) validator, found := keeper.GetValidator(ctx, validatorAddr) @@ -235,7 +235,7 @@ func TestLegacyValidatorDelegations(t *testing.T) { require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got) // must end-block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) // verify the validator exists and has the correct attributes @@ -330,7 +330,7 @@ func TestIncrementsMsgDelegate(t *testing.T) { require.True(t, got.IsOK(), "expected create validator msg to be ok, got %v", got) // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) @@ -415,7 +415,7 @@ func TestIncrementsMsgUnbond(t *testing.T) { require.Equal(t, amt1.Sub(sdk.NewInt(initBond)).Int64(), amt2.Int64(), "expected coins to be subtracted") // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) @@ -778,21 +778,21 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { got := handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(keeper.GetValidatorsBonded(ctx))) msgCreateValidator = newTestMsgCreateValidator(validatorAddr2, keep.PKs[1], 30) got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(keeper.GetValidatorsBonded(ctx))) msgCreateValidator = newTestMsgCreateValidator(validatorAddr3, keep.PKs[2], 10) got = handleMsgCreateValidator(ctx, msgCreateValidator, keeper) require.True(t, got.IsOK(), "expected no error on runMsgCreateValidator") // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(keeper.GetValidatorsBonded(ctx))) // unbond the valdator-2 @@ -801,7 +801,7 @@ func TestUnbondingWhenExcessValidators(t *testing.T) { require.True(t, got.IsOK(), "expected no error on runMsgBeginUnbonding") // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) // because there are extra validators waiting to get in, the queued // validator (aka. validator-1) should make it into the bonded group, thus @@ -832,7 +832,7 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { require.True(t, got.IsOK(), "expected no error on runMsgDelegate") // apply Tendermint updates - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(updates)) // a block passes @@ -854,7 +854,7 @@ func TestBondUnbondRedelegateSlashTwice(t *testing.T) { require.Equal(t, sdk.NewDec(6), delegation.Shares) // must apply validator updates - updates = keeper.GetTendermintUpdates(ctx) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(updates)) // slash the validator by half diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 104d5d27635a..6197935746a2 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -253,7 +253,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { require.NoError(t, err) // end block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) @@ -308,7 +308,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { require.NoError(t, err) // end block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) @@ -383,7 +383,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { require.NoError(t, err) // end block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) @@ -554,7 +554,7 @@ func TestRedelegateSelfDelegation(t *testing.T) { require.NoError(t, err) // end block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) @@ -618,7 +618,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { require.NoError(t, err) // end block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) @@ -703,7 +703,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { require.NoError(t, err) // end block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) diff --git a/x/stake/keeper/slash.go b/x/stake/keeper/slash.go index 9275689fe648..dd678858c483 100644 --- a/x/stake/keeper/slash.go +++ b/x/stake/keeper/slash.go @@ -106,7 +106,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh // remove validator if it has no more tokens if validator.Tokens.IsZero() && validator.Status != sdk.Bonded { - // if bonded, we must remove in GetTendermintUpdates instead + // if bonded, we must remove in ApplyAndReturnValidatorSetUpdates instead k.RemoveValidator(ctx, validator.OperatorAddr) } diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index 275e39cdac79..70c456a02994 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -164,7 +164,7 @@ func TestSlashRedelegation(t *testing.T) { require.True(t, found) // end block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) // initialbalance unchanged @@ -208,7 +208,7 @@ func TestSlashValidatorAtCurrentHeight(t *testing.T) { newPool := keeper.GetPool(ctx) // end block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates), "cons addr: %v, updates: %v", []byte(consAddr), updates) validator = keeper.mustGetValidator(ctx, validator.OperatorAddr) @@ -244,7 +244,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) { keeper.Slash(ctx, consAddr, 10, 10, fraction) // end block - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) // read updating unbonding delegation @@ -317,7 +317,7 @@ func TestSlashWithUnbondingDelegation(t *testing.T) { // just 1 bonded token burned again since that's all the validator now has require.Equal(t, int64(10), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64()) // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) // read updated validator // power decreased by 1 again, validator is out of stake // ergo validator should have been removed from the store @@ -420,7 +420,7 @@ func TestSlashWithRedelegation(t *testing.T) { // four more bonded tokens burned require.Equal(t, int64(16), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64()) // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) // read updated validator // validator decreased to zero power, should have been removed from the store _, found = keeper.GetValidatorByConsAddr(ctx, consAddr) diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index cdd13a96b1a3..5cfbf603118c 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -209,7 +209,7 @@ func updateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator) pool := keeper.GetPool(ctx) keeper.SetValidator(ctx, validator) keeper.SetValidatorByPowerIndex(ctx, validator, pool) - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) validator, found := keeper.GetValidator(ctx, validator.OperatorAddr) if !found { panic("validator expected but not found") diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index afb600a713b3..d3c804efa745 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -19,7 +19,7 @@ import ( // CONTRACT: Only validators with non-zero power or zero-power that were bonded // at the previous block height or were removed from the validator set entirely // are returned to Tendermint. -func (k Keeper) GetTendermintUpdates(ctx sdk.Context) (updates []abci.ValidatorUpdate) { +func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []abci.ValidatorUpdate) { store := ctx.KVStore(k.storeKey) maxValidators := k.GetParams(ctx).MaxValidators diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 301f19a17f4e..b948fb87e517 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -33,7 +33,7 @@ func TestSetValidator(t *testing.T) { keeper.SetValidatorByPowerIndex(ctx, validator, pool) // ensure update - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) validator, found := keeper.GetValidator(ctx, valAddr) require.True(t, found) require.Equal(t, 1, len(updates)) @@ -185,7 +185,7 @@ func TestSlashToZeroPowerRemoved(t *testing.T) { consAddr0 := sdk.ConsAddress(PKs[0].Address()) keeper.Slash(ctx, consAddr0, 0, 100, sdk.OneDec()) // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) // validator should have been deleted _, found := keeper.GetValidator(ctx, addrVals[0]) require.False(t, found) @@ -603,7 +603,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { assert.True(ValEq(t, validators[2], resValidators[1])) } -func TestGetTendermintUpdatesAllNone(t *testing.T) { +func TestApplyAndReturnValidatorSetUpdatesAllNone(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20} @@ -621,14 +621,14 @@ func TestGetTendermintUpdatesAllNone(t *testing.T) { // test from nothing to something // tendermintUpdate set: {} -> {c1, c3} - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) pool := keeper.GetPool(ctx) keeper.SetValidator(ctx, validators[0]) keeper.SetValidatorByPowerIndex(ctx, validators[0], pool) keeper.SetValidator(ctx, validators[1]) keeper.SetValidatorByPowerIndex(ctx, validators[1], pool) - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) assert.Equal(t, 2, len(updates)) validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddr) validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddr) @@ -636,7 +636,7 @@ func TestGetTendermintUpdatesAllNone(t *testing.T) { assert.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) } -func TestGetTendermintUpdatesIdentical(t *testing.T) { +func TestApplyAndReturnValidatorSetUpdatesIdentical(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20} @@ -649,16 +649,16 @@ func TestGetTendermintUpdatesIdentical(t *testing.T) { } validators[0] = updateValidator(keeper, ctx, validators[0]) validators[1] = updateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test identical, // tendermintUpdate set: {} -> {} validators[0] = updateValidator(keeper, ctx, validators[0]) validators[1] = updateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) } -func TestGetTendermintUpdatesSingleValueChange(t *testing.T) { +func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20} @@ -671,7 +671,7 @@ func TestGetTendermintUpdatesSingleValueChange(t *testing.T) { } validators[0] = updateValidator(keeper, ctx, validators[0]) validators[1] = updateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test single value change // tendermintUpdate set: {} -> {c1'} @@ -679,13 +679,13 @@ func TestGetTendermintUpdatesSingleValueChange(t *testing.T) { validators[0].Tokens = sdk.NewDec(600) validators[0] = updateValidator(keeper, ctx, validators[0]) - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) } -func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { +func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20} @@ -698,7 +698,7 @@ func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { } validators[0] = updateValidator(keeper, ctx, validators[0]) validators[1] = updateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test multiple value change // tendermintUpdate set: {c1, c3} -> {c1', c3'} @@ -709,13 +709,13 @@ func TestGetTendermintUpdatesMultipleValueChange(t *testing.T) { validators[0] = updateValidator(keeper, ctx, validators[0]) validators[1] = updateValidator(keeper, ctx, validators[1]) - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(updates)) require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[1]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) } -func TestGetTendermintUpdatesInserted(t *testing.T) { +func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{10, 20, 5, 15, 25} @@ -728,14 +728,14 @@ func TestGetTendermintUpdatesInserted(t *testing.T) { } validators[0] = updateValidator(keeper, ctx, validators[0]) validators[1] = updateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test validtor added at the beginning // tendermintUpdate set: {} -> {c0} pool := keeper.GetPool(ctx) keeper.SetValidator(ctx, validators[2]) keeper.SetValidatorByPowerIndex(ctx, validators[2], pool) - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddr) require.Equal(t, 1, len(updates)) require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) @@ -745,7 +745,7 @@ func TestGetTendermintUpdatesInserted(t *testing.T) { pool = keeper.GetPool(ctx) keeper.SetValidator(ctx, validators[3]) keeper.SetValidatorByPowerIndex(ctx, validators[3], pool) - updates = keeper.GetTendermintUpdates(ctx) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) validators[3], _ = keeper.GetValidator(ctx, validators[3].OperatorAddr) require.Equal(t, 1, len(updates)) require.Equal(t, validators[3].ABCIValidatorUpdate(), updates[0]) @@ -755,13 +755,13 @@ func TestGetTendermintUpdatesInserted(t *testing.T) { pool = keeper.GetPool(ctx) keeper.SetValidator(ctx, validators[4]) keeper.SetValidatorByPowerIndex(ctx, validators[4], pool) - updates = keeper.GetTendermintUpdates(ctx) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) validators[4], _ = keeper.GetValidator(ctx, validators[4].OperatorAddr) require.Equal(t, 1, len(updates)) require.Equal(t, validators[4].ABCIValidatorUpdate(), updates[0]) } -func TestGetTendermintUpdatesWithCliffValidator(t *testing.T) { +func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) params := types.DefaultParams() params.MaxValidators = 2 @@ -777,31 +777,31 @@ func TestGetTendermintUpdatesWithCliffValidator(t *testing.T) { } validators[0] = updateValidator(keeper, ctx, validators[0]) validators[1] = updateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test validator added at the end but not inserted in the valset // tendermintUpdate set: {} -> {} updateValidator(keeper, ctx, validators[2]) - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 0, len(updates)) // test validator change its power and become a gotValidator (pushing out an existing) // tendermintUpdate set: {} -> {c0, c4} - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) pool := keeper.GetPool(ctx) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(10)) keeper.SetPool(ctx, pool) keeper.SetValidator(ctx, validators[2]) keeper.SetValidatorByPowerIndex(ctx, validators[2], pool) - updates = keeper.GetTendermintUpdates(ctx) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddr) require.Equal(t, 2, len(updates), "%v", updates) require.Equal(t, validators[0].ABCIValidatorUpdateZero(), updates[1]) require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) } -func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { +func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) amts := []int64{100, 100} @@ -815,7 +815,7 @@ func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { } validators[0] = updateValidator(keeper, ctx, validators[0]) validators[1] = updateValidator(keeper, ctx, validators[1]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // check initial power require.Equal(t, sdk.NewDec(100).RoundInt64(), validators[0].GetPower().RoundInt64()) @@ -835,13 +835,13 @@ func TestGetTendermintUpdatesPowerDecrease(t *testing.T) { require.Equal(t, sdk.NewDec(70).RoundInt64(), validators[1].GetPower().RoundInt64()) // Tendermint updates should reflect power change - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(updates)) require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) } -func TestGetTendermintUpdatesNewValidator(t *testing.T) { +func TestApplyAndReturnValidatorSetUpdatesNewValidator(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) params := keeper.GetParams(ctx) params.MaxValidators = uint16(3) @@ -867,14 +867,14 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { } // verify initial Tendermint updates are correct - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, len(validators), len(updates)) validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddr) validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddr) require.Equal(t, validators[0].ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // update initial validator set for i, amt := range amts { @@ -915,7 +915,7 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { keeper.SetPool(ctx, pool) // verify initial Tendermint updates are correct - updates = keeper.GetTendermintUpdates(ctx) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) validator, _ = keeper.GetValidator(ctx, validator.OperatorAddr) validators[0], _ = keeper.GetValidator(ctx, validators[0].OperatorAddr) validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddr) @@ -925,7 +925,7 @@ func TestGetTendermintUpdatesNewValidator(t *testing.T) { require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[2]) } -func TestGetTendermintUpdatesBondTransition(t *testing.T) { +func TestApplyAndReturnValidatorSetUpdatesBondTransition(t *testing.T) { ctx, _, keeper := CreateTestInput(t, false, 1000) params := keeper.GetParams(ctx) params.MaxValidators = uint16(2) @@ -951,14 +951,14 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { } // verify initial Tendermint updates are correct - updates := keeper.GetTendermintUpdates(ctx) + updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(updates)) validators[2], _ = keeper.GetValidator(ctx, validators[2].OperatorAddr) validators[1], _ = keeper.GetValidator(ctx, validators[1].OperatorAddr) require.Equal(t, validators[2].ABCIValidatorUpdate(), updates[0]) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[1]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // delegate to validator with lowest power but not enough to bond ctx = ctx.WithBlockHeight(1) @@ -975,7 +975,7 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { keeper.SetValidatorByPowerIndex(ctx, validators[0], pool) // verify initial Tendermint updates are correct - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // create a series of events that will bond and unbond the validator with // lowest power in a single block context (height) @@ -990,7 +990,7 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { keeper.SetPool(ctx, pool) keeper.SetValidator(ctx, validators[0]) keeper.SetValidatorByPowerIndex(ctx, validators[0], pool) - updates = keeper.GetTendermintUpdates(ctx) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 0, len(updates)) keeper.DeleteValidatorByPowerIndex(ctx, validators[1], pool) @@ -1000,11 +1000,11 @@ func TestGetTendermintUpdatesBondTransition(t *testing.T) { keeper.SetValidatorByPowerIndex(ctx, validators[1], pool) // verify initial Tendermint updates are correct - updates = keeper.GetTendermintUpdates(ctx) + updates = keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 1, len(updates)) require.Equal(t, validators[1].ABCIValidatorUpdate(), updates[0]) - require.Equal(t, 0, len(keeper.GetTendermintUpdates(ctx))) + require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) } func TestUpdateValidatorCommission(t *testing.T) { diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/queryable_test.go index 6b403aebadab..00a524b5b43d 100644 --- a/x/stake/querier/queryable_test.go +++ b/x/stake/querier/queryable_test.go @@ -120,7 +120,7 @@ func TestQueryDelegation(t *testing.T) { keeper.Delegate(ctx, addrAcc2, sdk.NewCoin("steak", sdk.NewInt(20)), val1, true) // apply TM updates - keeper.GetTendermintUpdates(ctx) + keeper.ApplyAndReturnValidatorSetUpdates(ctx) // Query Delegator bonded validators queryParams := newTestDelegatorQuery(addrAcc2) diff --git a/x/stake/simulation/invariants.go b/x/stake/simulation/invariants.go index b06c7bb7cce3..2866f6292fef 100644 --- a/x/stake/simulation/invariants.go +++ b/x/stake/simulation/invariants.go @@ -76,7 +76,6 @@ func SupplyInvariants(ck bank.Keeper, k stake.Keeper, am auth.AccountMapper) sim // PositivePowerInvariant checks that all stored validators have > 0 power func PositivePowerInvariant(k stake.Keeper) simulation.Invariant { return func(app *baseapp.BaseApp) error { - // TODO Reenable but only check after EndBlock, is this accurate now? ctx := app.NewContext(false, abci.Header{}) var err error k.IterateValidatorsBonded(ctx, func(_ int64, validator sdk.Validator) bool { From dbd2c0ae2eca1969990927e56d02f7d734c2271a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 2 Oct 2018 10:01:18 +0200 Subject: [PATCH 44/52] Split up function for clarity --- x/stake/keeper/val_state_change.go | 75 ++++++++++++++++++------------ 1 file changed, 44 insertions(+), 31 deletions(-) diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index d3c804efa745..ae76caf21e65 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -11,10 +11,7 @@ import ( "github.com/cosmos/cosmos-sdk/x/stake/types" ) -//_________________________________________________________________________ -// Accumulated updates to the active/bonded validator set for tendermint - -// get the most recently updated validators +// Apply and return accumulated updates to the bonded validator set // // CONTRACT: Only validators with non-zero power or zero-power that were bonded // at the previous block height or were removed from the validator set entirely @@ -24,18 +21,11 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab store := ctx.KVStore(k.storeKey) maxValidators := k.GetParams(ctx).MaxValidators - // copy last validator set - last := make(map[[sdk.AddrLen]byte][]byte) - iterator := sdk.KVStorePrefixIterator(store, BondedValidatorsIndexKey) - for ; iterator.Valid(); iterator.Next() { - var operator [sdk.AddrLen]byte - copy(operator[:], iterator.Key()[1:]) - powerBytes := iterator.Value() - last[operator] = make([]byte, len(powerBytes)) - copy(last[operator][:], powerBytes[:]) - } + // retrieve last validator set + last := k.retrieveLastValidatorSet(ctx) - iterator = sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) + // iterate over validators, highest power to lowest + iterator := sdk.KVStoreReversePrefixIterator(store, ValidatorsByPowerIndexKey) count := 0 for ; iterator.Valid() && count < int(maxValidators); iterator.Next() { @@ -74,7 +64,7 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab updates = append(updates, validator.ABCIValidatorUpdate()) } - // validator still in the validator set + // validator still in the validator set, so delete from the copy delete(last, opbytes) // set the bonded validator index @@ -85,23 +75,12 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab } - // sort the map keys for determinism - // sorted by address - order doesn't matter - noLongerBonded := make([][]byte, len(last)) - index := 0 - for oper := range last { - operator := make([]byte, sdk.AddrLen) - copy(operator[:], oper[:]) - noLongerBonded[index] = operator - index++ - } - sort.SliceStable(noLongerBonded, func(i, j int) bool { - return bytes.Compare(noLongerBonded[i], noLongerBonded[j]) == -1 - }) + // sort the no-longer-bonded validators + noLongerBonded := k.sortNoLongerBonded(last) // iterate through the sorted no-longer-bonded validators - // any validators left in `last` are no longer bonded for _, operator := range noLongerBonded { + // fetch the validator validator := k.mustGetValidator(ctx, sdk.ValAddress(operator)) @@ -116,8 +95,9 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab // delete from the bonded validator index store.Delete(GetBondedValidatorIndexKey(operator)) - // update the validator + // update the validator set updates = append(updates, validator.ABCIValidatorUpdateZero()) + } return updates @@ -256,3 +236,36 @@ func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Vali k.SetValidator(ctx, validator) return validator } + +// retrieve the last validator set +func (k Keeper) retrieveLastValidatorSet(ctx sdk.Context) map[[sdk.AddrLen]byte][]byte { + last := make(map[[sdk.AddrLen]byte][]byte) + store := ctx.KVStore(k.storeKey) + iterator := sdk.KVStorePrefixIterator(store, BondedValidatorsIndexKey) + for ; iterator.Valid(); iterator.Next() { + var operator [sdk.AddrLen]byte + copy(operator[:], iterator.Key()[1:]) + powerBytes := iterator.Value() + last[operator] = make([]byte, len(powerBytes)) + copy(last[operator][:], powerBytes[:]) + } + return last +} + +// sort the validators to be unbonded +func (k Keeper) sortNoLongerBonded(last map[[sdk.AddrLen]byte][]byte) [][]byte { + // sort the map keys for determinism + noLongerBonded := make([][]byte, len(last)) + index := 0 + for oper := range last { + operator := make([]byte, sdk.AddrLen) + copy(operator[:], oper[:]) + noLongerBonded[index] = operator + index++ + } + // sorted by address - order doesn't matter + sort.SliceStable(noLongerBonded, func(i, j int) bool { + return bytes.Compare(noLongerBonded[i], noLongerBonded[j]) == -1 + }) + return noLongerBonded +} From 54d5ce80a6fc073d566ecb874af806f38a0a5019 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 2 Oct 2018 10:37:56 +0200 Subject: [PATCH 45/52] Remove jailed validators from the power store entirely --- x/stake/handler_test.go | 1 + x/stake/keeper/delegation_test.go | 9 +++++++-- x/stake/keeper/key.go | 10 +--------- x/stake/keeper/val_state_change.go | 20 ++++++++------------ x/stake/keeper/validator.go | 4 ++++ 5 files changed, 21 insertions(+), 23 deletions(-) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 7c97b8190af7..7513b0881e2e 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -100,6 +100,7 @@ func TestValidatorByPowerIndex(t *testing.T) { require.True(t, found) require.Equal(t, sdk.Unbonding, validator.Status) // ensure is unbonding require.Equal(t, int64(500000), validator.Tokens.RoundInt64()) // ensure tokens slashed + keeper.Unjail(ctx, consAddr0) // the old power record should have been deleted as the power changed require.False(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power)) diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index 6197935746a2..ab79022d8c4a 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -236,6 +236,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { keeper.SetDelegation(ctx, selfDelegation) // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) @@ -283,6 +284,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { keeper.SetDelegation(ctx, selfDelegation) // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) @@ -359,6 +361,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { keeper.SetDelegation(ctx, selfDelegation) // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) @@ -586,6 +589,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { keeper.SetDelegation(ctx, selfDelegation) // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) @@ -619,7 +623,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { // end block updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) + require.Equal(t, 1, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) @@ -669,6 +673,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { keeper.SetDelegation(ctx, selfDelegation) // create a second delegation to this validator + keeper.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) validator.BondIntraTxCounter = 1 require.Equal(t, int64(10), issuedShares.RoundInt64()) @@ -704,7 +709,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { // end block updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) - require.Equal(t, 2, len(updates)) + require.Equal(t, 1, len(updates)) validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index 2de4ac37c794..f6e38a23071a 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -75,22 +75,14 @@ func getValidatorPowerRank(validator types.Validator, pool types.Pool) []byte { potentialPower := validator.Tokens powerBytes := []byte(potentialPower.ToLeftPadded(maxDigitsForAccount)) // power big-endian (more powerful validators first) - jailedBytes := make([]byte, 1) - if validator.Jailed { - jailedBytes[0] = byte(0x00) - } else { - jailedBytes[0] = byte(0x01) - } - // heightBytes and counterBytes represent strings like powerBytes does heightBytes := make([]byte, binary.MaxVarintLen64) binary.BigEndian.PutUint64(heightBytes, ^uint64(validator.BondHeight)) // invert height (older validators first) counterBytes := make([]byte, 2) binary.BigEndian.PutUint16(counterBytes, ^uint16(validator.BondIntraTxCounter)) // invert counter (first txns have priority) - return append(append(append(append( + return append(append(append( ValidatorsByPowerIndexKey, - jailedBytes...), powerBytes...), heightBytes...), counterBytes...) diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index ae76caf21e65..06782634f062 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -33,11 +33,13 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab operator := sdk.ValAddress(iterator.Value()) validator := k.mustGetValidator(ctx, operator) - // jailed validators are ranked last, so if we get to a jailed validator - // we have no more bonded validators - // TODO we can remove this if we remove jailed validators from the power store - // likewise for zero-power validators, which we never bond - if validator.Jailed || validator.Tokens.Equal(sdk.ZeroDec()) { + if validator.Jailed { + panic("should never retrieve a jailed validator from the power store") + } + + // if we get to a zero-power validator (which we don't bond), + // there are no more possible bonded validators + if validator.Tokens.Equal(sdk.ZeroDec()) { break } @@ -140,12 +142,9 @@ func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { } pool := k.GetPool(ctx) - k.DeleteValidatorByPowerIndex(ctx, validator, pool) validator.Jailed = true k.SetValidator(ctx, validator) - k.SetValidatorByPowerIndex(ctx, validator, pool) - - // TODO we should be able to just delete the index, and only set it again once unjailed + k.DeleteValidatorByPowerIndex(ctx, validator, pool) } // remove a validator from jail @@ -155,14 +154,11 @@ func (k Keeper) UnjailValidator(ctx sdk.Context, validator types.Validator) { } pool := k.GetPool(ctx) - k.DeleteValidatorByPowerIndex(ctx, validator, pool) validator.Jailed = false k.SetValidator(ctx, validator) k.SetValidatorByPowerIndex(ctx, validator, pool) } -//________________________________________________________________________________________________ - // perform all the store operations for when a validator status becomes bonded func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types.Validator { diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 568b24a0d527..0b78f2cbf2ec 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -98,6 +98,10 @@ func (k Keeper) SetValidatorByConsAddr(ctx sdk.Context, validator types.Validato // validator index func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Validator, pool types.Pool) { + // jailed validators are not kept in the power index + if validator.Jailed { + return + } store := ctx.KVStore(k.storeKey) store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } From 413fa42c97a27f1149738aa3767946309d2c3a3e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 2 Oct 2018 11:40:21 +0200 Subject: [PATCH 46/52] Remove redundant bonded validator store --- x/stake/genesis.go | 4 ---- x/stake/keeper/key.go | 9 +-------- x/stake/keeper/val_state_change.go | 8 +------- x/stake/keeper/validator.go | 12 ------------ x/stake/stake.go | 1 - 5 files changed, 2 insertions(+), 32 deletions(-) diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 45754f34309d..fa81cc03bc6f 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -34,10 +34,6 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ // Manually set indexes for the first time keeper.SetValidatorByConsAddr(ctx, validator) keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool) - - if validator.Status == sdk.Bonded { - keeper.SetValidatorBondedIndex(ctx, validator) - } } for _, bond := range data.Bonds { diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index f6e38a23071a..c6b3b6b55082 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -25,7 +25,6 @@ var ( RedelegationKey = []byte{0x0A} // key for a redelegation RedelegationByValSrcIndexKey = []byte{0x0B} // prefix for each key for an redelegation, by source validator operator RedelegationByValDstIndexKey = []byte{0x0C} // prefix for each key for an redelegation, by destination validator operator - BondedValidatorsIndexKey = []byte{0x0D} // prefix for each key to the bonded validator set ) const maxDigitsForAccount = 12 // ~220,000,000 atoms created at launch @@ -42,12 +41,6 @@ func GetValidatorByConsAddrKey(addr sdk.ConsAddress) []byte { return append(ValidatorsByConsAddrKey, addr.Bytes()...) } -// gets the key for the current validator group -// VALUE: none (key rearrangement with GetValKeyFromValBondedIndexKey) -func GetValidatorsBondedIndexKey(operatorAddr sdk.ValAddress) []byte { - return append(ValidatorsBondedIndexKey, operatorAddr.Bytes()...) -} - // Get the validator operator address from ValBondedIndexKey func GetAddressFromValBondedIndexKey(IndexKey []byte) []byte { return IndexKey[1:] // remove prefix bytes @@ -64,7 +57,7 @@ func GetBondedValidatorsByPowerIndexKey(validator types.Validator, pool types.Po // get the bonded validator index key for an operator address func GetBondedValidatorIndexKey(operator sdk.ValAddress) []byte { - return append(BondedValidatorsIndexKey, operator...) + return append(ValidatorsBondedIndexKey, operator...) } // get the power ranking of a validator diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 06782634f062..0fbc729787de 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -162,7 +162,6 @@ func (k Keeper) UnjailValidator(ctx sdk.Context, validator types.Validator) { // perform all the store operations for when a validator status becomes bonded func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types.Validator { - store := ctx.KVStore(k.storeKey) pool := k.GetPool(ctx) k.DeleteValidatorByPowerIndex(ctx, validator, pool) @@ -175,7 +174,6 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. // save the now bonded validator record to the three referenced stores k.SetValidator(ctx, validator) - store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) k.SetValidatorByPowerIndex(ctx, validator, pool) @@ -190,7 +188,6 @@ func (k Keeper) bondValidator(ctx sdk.Context, validator types.Validator) types. // perform all the store operations for when a validator status begins unbonding func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validator) types.Validator { - store := ctx.KVStore(k.storeKey) pool := k.GetPool(ctx) params := k.GetParams(ctx) @@ -211,9 +208,6 @@ func (k Keeper) beginUnbondingValidator(ctx sdk.Context, validator types.Validat // save the now unbonded validator record k.SetValidator(ctx, validator) - // also remove from the Bonded types.Validators Store - store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) - k.SetValidatorByPowerIndex(ctx, validator, pool) // call the unbond hook if present @@ -237,7 +231,7 @@ func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Vali func (k Keeper) retrieveLastValidatorSet(ctx sdk.Context) map[[sdk.AddrLen]byte][]byte { last := make(map[[sdk.AddrLen]byte][]byte) store := ctx.KVStore(k.storeKey) - iterator := sdk.KVStorePrefixIterator(store, BondedValidatorsIndexKey) + iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) for ; iterator.Valid(); iterator.Next() { var operator [sdk.AddrLen]byte copy(operator[:], iterator.Key()[1:]) diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 0b78f2cbf2ec..705c33b7ed7e 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -119,12 +119,6 @@ func (k Keeper) SetNewValidatorByPowerIndex(ctx sdk.Context, validator types.Val store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } -// validator index -func (k Keeper) SetValidatorBondedIndex(ctx sdk.Context, validator types.Validator) { - store := ctx.KVStore(k.storeKey) - store.Set(GetValidatorsBondedIndexKey(validator.OperatorAddr), []byte{}) -} - //___________________________________________________________________________ // Update the tokens of an existing validator, update the validators power index key @@ -201,12 +195,6 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { store.Delete(GetValidatorByConsAddrKey(sdk.ConsAddress(validator.ConsPubKey.Address()))) store.Delete(GetBondedValidatorsByPowerIndexKey(validator, pool)) - // delete from the current and power weighted validator groups if the validator - // is bonded - and add validator with zero power to the validator updates - if store.Get(GetValidatorsBondedIndexKey(validator.OperatorAddr)) == nil { - return - } - store.Delete(GetValidatorsBondedIndexKey(validator.OperatorAddr)) } //___________________________________________________________________________ diff --git a/x/stake/stake.go b/x/stake/stake.go index 817f73ca311d..b7ed8be4d027 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -37,7 +37,6 @@ var ( GetValidatorKey = keeper.GetValidatorKey GetValidatorByConsAddrKey = keeper.GetValidatorByConsAddrKey - GetValidatorsBondedIndexKey = keeper.GetValidatorsBondedIndexKey GetBondedValidatorsByPowerIndexKey = keeper.GetBondedValidatorsByPowerIndexKey GetDelegationKey = keeper.GetDelegationKey GetDelegationsKey = keeper.GetDelegationsKey From 1c1183a86ec65a052925a42c9f0f3a7b835d0a34 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 2 Oct 2018 12:05:43 +0200 Subject: [PATCH 47/52] Fix simulator bug --- x/mock/simulation/random_simulate_blocks.go | 17 +++++++---------- x/stake/genesis.go | 2 +- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index ee93cfea393a..51705cbef098 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -36,12 +36,8 @@ func initChain(r *rand.Rand, accounts []Account, setups []RandSetup, app *baseap res := app.InitChain(abci.RequestInitChain{AppStateBytes: appStateFn(r, accounts)}) validators = make(map[string]mockValidator) for _, validator := range res.Validators { - pubkey, err := tmtypes.PB2TM.PubKey(validator.PubKey) - if err != nil { - panic(err) - } - address := pubkey.Address() - validators[string(address)] = mockValidator{validator, GetMemberOfInitialState(r, initialLivenessWeightings)} + str := fmt.Sprintf("%v", validator.PubKey) + validators[str] = mockValidator{validator, GetMemberOfInitialState(r, initialLivenessWeightings)} } for i := 0; i < len(setups); i++ { @@ -400,22 +396,23 @@ func RandomRequestBeginBlock(r *rand.Rand, validators map[string]mockValidator, func updateValidators(tb testing.TB, r *rand.Rand, current map[string]mockValidator, updates []abci.ValidatorUpdate, event func(string)) map[string]mockValidator { for _, update := range updates { + str := fmt.Sprintf("%v", update.PubKey) switch { case update.Power == 0: - if _, ok := current[string(update.PubKey.Data)]; !ok { + if _, ok := current[str]; !ok { tb.Fatalf("tried to delete a nonexistent validator") } event("endblock/validatorupdates/kicked") - delete(current, string(update.PubKey.Data)) + delete(current, str) default: // Does validator already exist? - if mVal, ok := current[string(update.PubKey.Data)]; ok { + if mVal, ok := current[str]; ok { mVal.val = update event("endblock/validatorupdates/updated") } else { // Set this new validator - current[string(update.PubKey.Data)] = mockValidator{update, GetMemberOfInitialState(r, initialLivenessWeightings)} + current[str] = mockValidator{update, GetMemberOfInitialState(r, initialLivenessWeightings)} event("endblock/validatorupdates/added") } } diff --git a/x/stake/genesis.go b/x/stake/genesis.go index fa81cc03bc6f..e1f33d94cdff 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -31,7 +31,7 @@ func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res [ return res, errors.Errorf("genesis validator cannot have zero delegator shares, validator: %v", validator) } - // Manually set indexes for the first time + // Manually set indices for the first time keeper.SetValidatorByConsAddr(ctx, validator) keeper.SetValidatorByPowerIndex(ctx, validator, data.Pool) } From 951cacc46b4cc1c9ca7cb963cac4005430ee4f5e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 2 Oct 2018 12:16:34 +0200 Subject: [PATCH 48/52] Change key name to reflect usage --- x/stake/handler_test.go | 6 ++-- x/stake/keeper/key.go | 2 +- x/stake/keeper/val_state_change.go | 3 +- x/stake/keeper/validator.go | 8 ++--- x/stake/keeper/validator_test.go | 4 +-- x/stake/stake.go | 48 +++++++++++++++--------------- 6 files changed, 36 insertions(+), 35 deletions(-) diff --git a/x/stake/handler_test.go b/x/stake/handler_test.go index 7513b0881e2e..0e4a2bf65481 100644 --- a/x/stake/handler_test.go +++ b/x/stake/handler_test.go @@ -79,7 +79,7 @@ func TestValidatorByPowerIndex(t *testing.T) { validator, found := keeper.GetValidator(ctx, validatorAddr) require.True(t, found) pool := keeper.GetPool(ctx) - power := keep.GetBondedValidatorsByPowerIndexKey(validator, pool) + power := keep.GetValidatorsByPowerIndexKey(validator, pool) require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power)) // create a second validator keep it bonded @@ -109,7 +109,7 @@ func TestValidatorByPowerIndex(t *testing.T) { validator, found = keeper.GetValidator(ctx, validatorAddr) require.True(t, found) pool = keeper.GetPool(ctx) - power2 := GetBondedValidatorsByPowerIndexKey(validator, pool) + power2 := GetValidatorsByPowerIndexKey(validator, pool) require.True(t, keep.ValidatorByPowerIndexExists(ctx, keeper, power2)) // inflate a bunch @@ -120,7 +120,7 @@ func TestValidatorByPowerIndex(t *testing.T) { } // now the new record power index should be the same as the original record - power3 := GetBondedValidatorsByPowerIndexKey(validator, pool) + power3 := GetValidatorsByPowerIndexKey(validator, pool) require.Equal(t, power2, power3) // unbond self-delegation diff --git a/x/stake/keeper/key.go b/x/stake/keeper/key.go index c6b3b6b55082..02d54e2b71ae 100644 --- a/x/stake/keeper/key.go +++ b/x/stake/keeper/key.go @@ -50,7 +50,7 @@ func GetAddressFromValBondedIndexKey(IndexKey []byte) []byte { // Power index is the key used in the power-store, and represents the relative // power ranking of the validator. // VALUE: validator operator address ([]byte) -func GetBondedValidatorsByPowerIndexKey(validator types.Validator, pool types.Pool) []byte { +func GetValidatorsByPowerIndexKey(validator types.Validator, pool types.Pool) []byte { // NOTE the address doesn't need to be stored because counter bytes must always be different return getValidatorPowerRank(validator, pool) } diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 0fbc729787de..63b66e8d71d6 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -39,7 +39,8 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab // if we get to a zero-power validator (which we don't bond), // there are no more possible bonded validators - if validator.Tokens.Equal(sdk.ZeroDec()) { + // note: we must check the ABCI power, since we round before sending to Tendermint + if validator.Tokens.RoundInt64() == int64(0) { break } diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 705c33b7ed7e..927a361a2dd7 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -103,20 +103,20 @@ func (k Keeper) SetValidatorByPowerIndex(ctx sdk.Context, validator types.Valida return } store := ctx.KVStore(k.storeKey) - store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) + store.Set(GetValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } // validator index func (k Keeper) DeleteValidatorByPowerIndex(ctx sdk.Context, validator types.Validator, pool types.Pool) { store := ctx.KVStore(k.storeKey) - store.Delete(GetBondedValidatorsByPowerIndexKey(validator, pool)) + store.Delete(GetValidatorsByPowerIndexKey(validator, pool)) } // validator index func (k Keeper) SetNewValidatorByPowerIndex(ctx sdk.Context, validator types.Validator) { store := ctx.KVStore(k.storeKey) pool := k.GetPool(ctx) - store.Set(GetBondedValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) + store.Set(GetValidatorsByPowerIndexKey(validator, pool), validator.OperatorAddr) } //___________________________________________________________________________ @@ -193,7 +193,7 @@ func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { pool := k.GetPool(ctx) store.Delete(GetValidatorKey(address)) store.Delete(GetValidatorByConsAddrKey(sdk.ConsAddress(validator.ConsPubKey.Address()))) - store.Delete(GetBondedValidatorsByPowerIndexKey(validator, pool)) + store.Delete(GetValidatorsByPowerIndexKey(validator, pool)) } diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index b948fb87e517..c422cf803223 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -90,7 +90,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool) pool = keeper.GetPool(ctx) - power := GetBondedValidatorsByPowerIndexKey(validator, pool) + power := GetValidatorsByPowerIndexKey(validator, pool) require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) // burn half the delegator shares @@ -104,7 +104,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { pool = keeper.GetPool(ctx) validator, found = keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) - power = GetBondedValidatorsByPowerIndexKey(validator, pool) + power = GetValidatorsByPowerIndexKey(validator, pool) require.True(t, validatorByPowerIndexExists(keeper, ctx, power)) } diff --git a/x/stake/stake.go b/x/stake/stake.go index b7ed8be4d027..a9a3ca3cd544 100644 --- a/x/stake/stake.go +++ b/x/stake/stake.go @@ -35,30 +35,30 @@ type ( var ( NewKeeper = keeper.NewKeeper - GetValidatorKey = keeper.GetValidatorKey - GetValidatorByConsAddrKey = keeper.GetValidatorByConsAddrKey - GetBondedValidatorsByPowerIndexKey = keeper.GetBondedValidatorsByPowerIndexKey - GetDelegationKey = keeper.GetDelegationKey - GetDelegationsKey = keeper.GetDelegationsKey - ParamKey = keeper.ParamKey - PoolKey = keeper.PoolKey - ValidatorsKey = keeper.ValidatorsKey - ValidatorsByConsAddrKey = keeper.ValidatorsByConsAddrKey - ValidatorsBondedIndexKey = keeper.ValidatorsBondedIndexKey - ValidatorsByPowerIndexKey = keeper.ValidatorsByPowerIndexKey - DelegationKey = keeper.DelegationKey - IntraTxCounterKey = keeper.IntraTxCounterKey - GetUBDKey = keeper.GetUBDKey - GetUBDByValIndexKey = keeper.GetUBDByValIndexKey - GetUBDsKey = keeper.GetUBDsKey - GetUBDsByValIndexKey = keeper.GetUBDsByValIndexKey - GetREDKey = keeper.GetREDKey - GetREDByValSrcIndexKey = keeper.GetREDByValSrcIndexKey - GetREDByValDstIndexKey = keeper.GetREDByValDstIndexKey - GetREDsKey = keeper.GetREDsKey - GetREDsFromValSrcIndexKey = keeper.GetREDsFromValSrcIndexKey - GetREDsToValDstIndexKey = keeper.GetREDsToValDstIndexKey - GetREDsByDelToValDstIndexKey = keeper.GetREDsByDelToValDstIndexKey + GetValidatorKey = keeper.GetValidatorKey + GetValidatorByConsAddrKey = keeper.GetValidatorByConsAddrKey + GetValidatorsByPowerIndexKey = keeper.GetValidatorsByPowerIndexKey + GetDelegationKey = keeper.GetDelegationKey + GetDelegationsKey = keeper.GetDelegationsKey + ParamKey = keeper.ParamKey + PoolKey = keeper.PoolKey + ValidatorsKey = keeper.ValidatorsKey + ValidatorsByConsAddrKey = keeper.ValidatorsByConsAddrKey + ValidatorsBondedIndexKey = keeper.ValidatorsBondedIndexKey + ValidatorsByPowerIndexKey = keeper.ValidatorsByPowerIndexKey + DelegationKey = keeper.DelegationKey + IntraTxCounterKey = keeper.IntraTxCounterKey + GetUBDKey = keeper.GetUBDKey + GetUBDByValIndexKey = keeper.GetUBDByValIndexKey + GetUBDsKey = keeper.GetUBDsKey + GetUBDsByValIndexKey = keeper.GetUBDsByValIndexKey + GetREDKey = keeper.GetREDKey + GetREDByValSrcIndexKey = keeper.GetREDByValSrcIndexKey + GetREDByValDstIndexKey = keeper.GetREDByValDstIndexKey + GetREDsKey = keeper.GetREDsKey + GetREDsFromValSrcIndexKey = keeper.GetREDsFromValSrcIndexKey + GetREDsToValDstIndexKey = keeper.GetREDsToValDstIndexKey + GetREDsByDelToValDstIndexKey = keeper.GetREDsByDelToValDstIndexKey DefaultParams = types.DefaultParams InitialPool = types.InitialPool From 8e67f6d1b67f972b3e43cfc17889ee665efe2be3 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 3 Oct 2018 02:27:51 +0200 Subject: [PATCH 49/52] updateValidator -> testingUpdateValidator --- x/stake/keeper/delegation_test.go | 38 ++++++------ x/stake/keeper/slash_test.go | 2 +- x/stake/keeper/test_common.go | 2 +- x/stake/keeper/validator_test.go | 98 +++++++++++++++---------------- 4 files changed, 70 insertions(+), 70 deletions(-) diff --git a/x/stake/keeper/delegation_test.go b/x/stake/keeper/delegation_test.go index ab79022d8c4a..863c08a9674c 100644 --- a/x/stake/keeper/delegation_test.go +++ b/x/stake/keeper/delegation_test.go @@ -25,9 +25,9 @@ func TestDelegation(t *testing.T) { } keeper.SetPool(ctx, pool) - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) - validators[2] = updateValidator(keeper, ctx, validators[2]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) + validators[2] = testingUpdateValidator(keeper, ctx, validators[2]) // first add a validators[0] to delegate too @@ -184,7 +184,7 @@ func TestUnbondDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) require.Equal(t, int64(10), pool.BondedTokens.RoundInt64()) @@ -226,7 +226,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) selfDelegation := types.Delegation{ DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()), @@ -240,7 +240,7 @@ func TestUndelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -274,7 +274,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) selfDelegation := types.Delegation{ DelegatorAddr: sdk.AccAddress(addrVals[0].Bytes()), @@ -288,7 +288,7 @@ func TestUndelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -350,7 +350,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -365,7 +365,7 @@ func TestUndelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -521,7 +521,7 @@ func TestRedelegateSelfDelegation(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -537,14 +537,14 @@ func TestRedelegateSelfDelegation(t *testing.T) { require.Equal(t, int64(10), issuedShares.RoundInt64()) pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(10)) keeper.SetPool(ctx, pool) - validator2 = updateValidator(keeper, ctx, validator2) + validator2 = testingUpdateValidator(keeper, ctx, validator2) require.Equal(t, sdk.Bonded, validator2.Status) // create a second delegation to this validator validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -578,7 +578,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -593,7 +593,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { validator, pool, issuedShares = validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -608,7 +608,7 @@ func TestRedelegateFromUnbondingValidator(t *testing.T) { validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator2 = updateValidator(keeper, ctx, validator2) + validator2 = testingUpdateValidator(keeper, ctx, validator2) header := ctx.BlockHeader() blockHeight := int64(10) @@ -662,7 +662,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { validator, pool, issuedShares := validator.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) val0AccAddr := sdk.AccAddress(addrVals[0].Bytes()) selfDelegation := types.Delegation{ @@ -678,7 +678,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { validator.BondIntraTxCounter = 1 require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) pool = keeper.GetPool(ctx) delegation := types.Delegation{ DelegatorAddr: addrDels[0], @@ -693,7 +693,7 @@ func TestRedelegateFromUnbondedValidator(t *testing.T) { validator2, pool, issuedShares = validator2.AddTokensFromDel(pool, sdk.NewInt(10)) require.Equal(t, int64(10), issuedShares.RoundInt64()) keeper.SetPool(ctx, pool) - validator2 = updateValidator(keeper, ctx, validator2) + validator2 = testingUpdateValidator(keeper, ctx, validator2) require.Equal(t, sdk.Bonded, validator2.Status) header := ctx.BlockHeader() diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index 70c456a02994..7959679c6fbf 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -29,7 +29,7 @@ func setupHelper(t *testing.T, amt int64) (sdk.Context, Keeper, types.Params) { validator.BondIntraTxCounter = int16(i) pool.BondedTokens = pool.BondedTokens.Add(sdk.NewDec(amt)) keeper.SetPool(ctx, pool) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) keeper.SetValidatorByConsAddr(ctx, validator) } pool = keeper.GetPool(ctx) diff --git a/x/stake/keeper/test_common.go b/x/stake/keeper/test_common.go index 5cfbf603118c..8f5b2fa3967f 100644 --- a/x/stake/keeper/test_common.go +++ b/x/stake/keeper/test_common.go @@ -205,7 +205,7 @@ func ValidatorByPowerIndexExists(ctx sdk.Context, keeper Keeper, power []byte) b return store.Has(power) } -func updateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator) types.Validator { +func testingUpdateValidator(keeper Keeper, ctx sdk.Context, validator types.Validator) types.Validator { pool := keeper.GetPool(ctx) keeper.SetValidator(ctx, validator) keeper.SetValidatorByPowerIndex(ctx, validator, pool) diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index c422cf803223..0b18178fc81f 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -84,7 +84,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { require.Equal(t, sdk.Unbonded, validator.Status) require.Equal(t, int64(100), validator.Tokens.RoundInt64()) keeper.SetPool(ctx, pool) - updateValidator(keeper, ctx, validator) + testingUpdateValidator(keeper, ctx, validator) validator, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool) @@ -98,7 +98,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { validator, pool, burned := validator.RemoveDelShares(pool, delSharesCreated.Quo(sdk.NewDec(2))) require.Equal(t, int64(50), burned.RoundInt64()) keeper.SetPool(ctx, pool) // update the pool - updateValidator(keeper, ctx, validator) // update the validator, possibly kicking it out + testingUpdateValidator(keeper, ctx, validator) // update the validator, possibly kicking it out require.False(t, validatorByPowerIndexExists(keeper, ctx, power)) pool = keeper.GetPool(ctx) @@ -135,7 +135,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { val, pool, _ = val.AddTokensFromDel(pool, sdk.NewInt(int64((i+1)*10))) keeper.SetPool(ctx, pool) - val = updateValidator(keeper, ctx, val) + val = testingUpdateValidator(keeper, ctx, val) validators[i] = val } @@ -146,7 +146,7 @@ func TestUpdateBondedValidatorsDecreaseCliff(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, nextCliffVal, pool) nextCliffVal, pool, _ = nextCliffVal.RemoveDelShares(pool, sdk.NewDec(21)) keeper.SetPool(ctx, pool) - nextCliffVal = updateValidator(keeper, ctx, nextCliffVal) + nextCliffVal = testingUpdateValidator(keeper, ctx, nextCliffVal) expectedValStatus := map[int]sdk.BondStatus{ 9: sdk.Bonded, 8: sdk.Bonded, 7: sdk.Bonded, 5: sdk.Bonded, 4: sdk.Bonded, @@ -178,7 +178,7 @@ func TestSlashToZeroPowerRemoved(t *testing.T) { require.Equal(t, int64(100), validator.Tokens.RoundInt64()) keeper.SetPool(ctx, pool) keeper.SetValidatorByConsAddr(ctx, validator) - validator = updateValidator(keeper, ctx, validator) + validator = testingUpdateValidator(keeper, ctx, validator) require.Equal(t, int64(100), validator.Tokens.RoundInt64(), "\nvalidator %v\npool %v", validator, pool) // slash the validator by 100% @@ -223,7 +223,7 @@ func TestValidatorBasics(t *testing.T) { assert.True(sdk.DecEq(t, sdk.ZeroDec(), pool.BondedTokens)) // set and retrieve a record - validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) keeper.SetValidatorByConsAddr(ctx, validators[0]) resVal, found := keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) @@ -250,7 +250,7 @@ func TestValidatorBasics(t *testing.T) { validators[0].Status = sdk.Bonded validators[0].Tokens = sdk.NewDec(10) validators[0].DelegatorShares = sdk.NewDec(10) - validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) resVal, found = keeper.GetValidator(ctx, addrVals[0]) require.True(t, found) assert.True(ValEq(t, validators[0], resVal)) @@ -260,8 +260,8 @@ func TestValidatorBasics(t *testing.T) { assert.True(ValEq(t, validators[0], resVals[0])) // add other validators - validators[1] = updateValidator(keeper, ctx, validators[1]) - validators[2] = updateValidator(keeper, ctx, validators[2]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) + validators[2] = testingUpdateValidator(keeper, ctx, validators[2]) resVal, found = keeper.GetValidator(ctx, addrVals[1]) require.True(t, found) assert.True(ValEq(t, validators[1], resVal)) @@ -294,7 +294,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { validators[i].Status = sdk.Bonded validators[i].Tokens = sdk.NewDec(amt) validators[i].DelegatorShares = sdk.NewDec(amt) - updateValidator(keeper, ctx, validators[i]) + testingUpdateValidator(keeper, ctx, validators[i]) } // first make sure everything made it in to the gotValidator group @@ -313,14 +313,14 @@ func GetValidatorSortingUnmixed(t *testing.T) { // test a basic increase in voting power validators[3].Tokens = sdk.NewDec(500) - updateValidator(keeper, ctx, validators[3]) + testingUpdateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) // test a decrease in voting power validators[3].Tokens = sdk.NewDec(300) - updateValidator(keeper, ctx, validators[3]) + testingUpdateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -329,7 +329,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { // test equal voting power, different age validators[3].Tokens = sdk.NewDec(200) ctx = ctx.WithBlockHeight(10) - updateValidator(keeper, ctx, validators[3]) + testingUpdateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -339,7 +339,7 @@ func GetValidatorSortingUnmixed(t *testing.T) { // no change in voting power - no change in sort ctx = ctx.WithBlockHeight(20) - updateValidator(keeper, ctx, validators[4]) + testingUpdateValidator(keeper, ctx, validators[4]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -348,11 +348,11 @@ func GetValidatorSortingUnmixed(t *testing.T) { // change in voting power of both validators, both still in v-set, no age change validators[3].Tokens = sdk.NewDec(300) validators[4].Tokens = sdk.NewDec(300) - updateValidator(keeper, ctx, validators[3]) + testingUpdateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n) ctx = ctx.WithBlockHeight(30) - updateValidator(keeper, ctx, validators[4]) + testingUpdateValidator(keeper, ctx, validators[4]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, len(resValidators), n, "%v", resValidators) assert.True(ValEq(t, validators[3], resValidators[0])) @@ -390,7 +390,7 @@ func GetValidatorSortingMixed(t *testing.T) { validators[4].Tokens = sdk.NewDec(amts[4]) for i := range amts { - updateValidator(keeper, ctx, validators[i]) + testingUpdateValidator(keeper, ctx, validators[i]) } val0, found := keeper.GetValidator(ctx, sdk.ValAddress(Addrs[0])) require.True(t, found) @@ -444,7 +444,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) - validators[i] = updateValidator(keeper, ctx, validators[i]) + validators[i] = testingUpdateValidator(keeper, ctx, validators[i]) } for i := range amts { @@ -460,7 +460,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[0], pool) validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(500)) keeper.SetPool(ctx, pool) - validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -478,7 +478,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(1)) keeper.SetPool(ctx, pool) - validators[3] = updateValidator(keeper, ctx, validators[3]) + validators[3] = testingUpdateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -488,7 +488,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) validators[3], pool, _ = validators[3].RemoveDelShares(pool, sdk.NewDec(201)) keeper.SetPool(ctx, pool) - validators[3] = updateValidator(keeper, ctx, validators[3]) + validators[3] = testingUpdateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -498,7 +498,7 @@ func TestGetValidatorsEdgeCases(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validators[3], pool) validators[3], pool, _ = validators[3].AddTokensFromDel(pool, sdk.NewInt(200)) keeper.SetPool(ctx, pool) - validators[3] = updateValidator(keeper, ctx, validators[3]) + validators[3] = testingUpdateValidator(keeper, ctx, validators[3]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, nMax, uint16(len(resValidators))) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -531,13 +531,13 @@ func TestValidatorBondHeight(t *testing.T) { validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(100)) keeper.SetPool(ctx, pool) - validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) //////////////////////////////////////// // If two validators both increase to the same voting power in the same block, // the one with the first transaction should become bonded - validators[1] = updateValidator(keeper, ctx, validators[1]) - validators[2] = updateValidator(keeper, ctx, validators[2]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) + validators[2] = testingUpdateValidator(keeper, ctx, validators[2]) pool = keeper.GetPool(ctx) @@ -551,10 +551,10 @@ func TestValidatorBondHeight(t *testing.T) { validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(50)) validators[2], pool, _ = validators[2].AddTokensFromDel(pool, sdk.NewInt(50)) keeper.SetPool(ctx, pool) - validators[2] = updateValidator(keeper, ctx, validators[2]) + validators[2] = testingUpdateValidator(keeper, ctx, validators[2]) resValidators = keeper.GetBondedValidatorsByPower(ctx) require.Equal(t, params.MaxValidators, uint16(len(resValidators))) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) assert.True(ValEq(t, validators[0], resValidators[0])) assert.True(ValEq(t, validators[2], resValidators[1])) } @@ -575,7 +575,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) - updateValidator(keeper, ctx, validators[i]) + testingUpdateValidator(keeper, ctx, validators[i]) } for i := range amts { var found bool @@ -596,7 +596,7 @@ func TestFullValidatorSetPowerChange(t *testing.T) { pool := keeper.GetPool(ctx) validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(600)) keeper.SetPool(ctx, pool) - validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) resValidators = keeper.GetBondedValidatorsByPower(ctx) assert.Equal(t, max, len(resValidators)) assert.True(ValEq(t, validators[0], resValidators[0])) @@ -647,14 +647,14 @@ func TestApplyAndReturnValidatorSetUpdatesIdentical(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test identical, // tendermintUpdate set: {} -> {} - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) } @@ -669,15 +669,15 @@ func TestApplyAndReturnValidatorSetUpdatesSingleValueChange(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test single value change // tendermintUpdate set: {} -> {c1'} validators[0].Status = sdk.Bonded validators[0].Tokens = sdk.NewDec(600) - validators[0] = updateValidator(keeper, ctx, validators[0]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) @@ -696,8 +696,8 @@ func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test multiple value change @@ -706,8 +706,8 @@ func TestApplyAndReturnValidatorSetUpdatesMultipleValueChange(t *testing.T) { validators[0], pool, _ = validators[0].AddTokensFromDel(pool, sdk.NewInt(190)) validators[1], pool, _ = validators[1].AddTokensFromDel(pool, sdk.NewInt(80)) keeper.SetPool(ctx, pool) - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 2, len(updates)) @@ -726,8 +726,8 @@ func TestApplyAndReturnValidatorSetUpdatesInserted(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test validtor added at the beginning @@ -775,13 +775,13 @@ func TestApplyAndReturnValidatorSetUpdatesWithCliffValidator(t *testing.T) { validators[i], pool, _ = validators[i].AddTokensFromDel(pool, sdk.NewInt(amt)) keeper.SetPool(ctx, pool) } - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // test validator added at the end but not inserted in the valset // tendermintUpdate set: {} -> {} - updateValidator(keeper, ctx, validators[2]) + testingUpdateValidator(keeper, ctx, validators[2]) updates := keeper.ApplyAndReturnValidatorSetUpdates(ctx) require.Equal(t, 0, len(updates)) @@ -813,8 +813,8 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { validators[i].BondIntraTxCounter = int16(i) keeper.SetPool(ctx, pool) } - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) require.Equal(t, 0, len(keeper.ApplyAndReturnValidatorSetUpdates(ctx))) // check initial power @@ -827,8 +827,8 @@ func TestApplyAndReturnValidatorSetUpdatesPowerDecrease(t *testing.T) { validators[0], pool, _ = validators[0].RemoveDelShares(pool, sdk.NewDec(20)) validators[1], pool, _ = validators[1].RemoveDelShares(pool, sdk.NewDec(30)) keeper.SetPool(ctx, pool) - validators[0] = updateValidator(keeper, ctx, validators[0]) - validators[1] = updateValidator(keeper, ctx, validators[1]) + validators[0] = testingUpdateValidator(keeper, ctx, validators[0]) + validators[1] = testingUpdateValidator(keeper, ctx, validators[1]) // power has changed require.Equal(t, sdk.NewDec(80).RoundInt64(), validators[0].GetPower().RoundInt64()) From 94b0ca99fdc1ca64892fbcee48b81a3bf80adc76 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 3 Oct 2018 02:28:15 +0200 Subject: [PATCH 50/52] 'make format' --- x/stake/keeper/validator_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/stake/keeper/validator_test.go b/x/stake/keeper/validator_test.go index 0b18178fc81f..9b4dc3c55ef1 100644 --- a/x/stake/keeper/validator_test.go +++ b/x/stake/keeper/validator_test.go @@ -97,7 +97,7 @@ func TestUpdateValidatorByPowerIndex(t *testing.T) { keeper.DeleteValidatorByPowerIndex(ctx, validator, pool) validator, pool, burned := validator.RemoveDelShares(pool, delSharesCreated.Quo(sdk.NewDec(2))) require.Equal(t, int64(50), burned.RoundInt64()) - keeper.SetPool(ctx, pool) // update the pool + keeper.SetPool(ctx, pool) // update the pool testingUpdateValidator(keeper, ctx, validator) // update the validator, possibly kicking it out require.False(t, validatorByPowerIndexExists(keeper, ctx, power)) From 5893e2337cb3df951442d8f9a427dc694a723b62 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 3 Oct 2018 14:43:12 +0200 Subject: [PATCH 51/52] Address @rigelrozanski comments --- x/stake/keeper/delegation.go | 2 +- x/stake/keeper/slash.go | 4 ++-- x/stake/keeper/val_state_change.go | 32 ++++++++++++++++++------------ x/stake/querier/queryable_test.go | 2 +- 4 files changed, 23 insertions(+), 17 deletions(-) diff --git a/x/stake/keeper/delegation.go b/x/stake/keeper/delegation.go index 7631be8efb0f..d7e9c57952d6 100644 --- a/x/stake/keeper/delegation.go +++ b/x/stake/keeper/delegation.go @@ -309,7 +309,7 @@ func (k Keeper) unbond(ctx sdk.Context, delAddr sdk.AccAddress, valAddr sdk.ValA // if the delegation is the operator of the validator then // trigger a jail validator if bytes.Equal(delegation.DelegatorAddr, validator.OperatorAddr) && !validator.Jailed { - k.JailValidator(ctx, validator) + k.jailValidator(ctx, validator) validator = k.mustGetValidator(ctx, validator.OperatorAddr) } diff --git a/x/stake/keeper/slash.go b/x/stake/keeper/slash.go index dd678858c483..dc57dc5dd47b 100644 --- a/x/stake/keeper/slash.go +++ b/x/stake/keeper/slash.go @@ -122,7 +122,7 @@ func (k Keeper) Slash(ctx sdk.Context, consAddr sdk.ConsAddress, infractionHeigh // jail a validator func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress) { validator := k.mustGetValidatorByConsAddr(ctx, consAddr) - k.JailValidator(ctx, validator) + k.jailValidator(ctx, validator) logger := ctx.Logger().With("module", "x/stake") logger.Info(fmt.Sprintf("validator %s jailed", consAddr)) // TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803 @@ -132,7 +132,7 @@ func (k Keeper) Jail(ctx sdk.Context, consAddr sdk.ConsAddress) { // unjail a validator func (k Keeper) Unjail(ctx sdk.Context, consAddr sdk.ConsAddress) { validator := k.mustGetValidatorByConsAddr(ctx, consAddr) - k.UnjailValidator(ctx, validator) + k.unjailValidator(ctx, validator) logger := ctx.Logger().With("module", "x/stake") logger.Info(fmt.Sprintf("validator %s unjailed", consAddr)) // TODO Return event(s), blocked on https://github.com/tendermint/tendermint/pull/1803 diff --git a/x/stake/keeper/val_state_change.go b/x/stake/keeper/val_state_change.go index 63b66e8d71d6..f9cf6e463fb6 100644 --- a/x/stake/keeper/val_state_change.go +++ b/x/stake/keeper/val_state_change.go @@ -52,23 +52,25 @@ func (k Keeper) ApplyAndReturnValidatorSetUpdates(ctx sdk.Context) (updates []ab validator = k.unbondingToBonded(ctx, validator) case sdk.Bonded: // no state change + default: + panic("unexpected validator status") } // fetch the old power bytes - var opbytes [sdk.AddrLen]byte - copy(opbytes[:], operator[:]) - oldPowerBytes, ok := last[opbytes] + var operatorBytes [sdk.AddrLen]byte + copy(operatorBytes[:], operator[:]) + oldPowerBytes, found := last[operatorBytes] // calculate the new power bytes newPowerBytes := validator.ABCIValidatorPowerBytes(k.cdc) // update the validator set if power has changed - if !ok || !bytes.Equal(oldPowerBytes, newPowerBytes) { + if !found || !bytes.Equal(oldPowerBytes, newPowerBytes) { updates = append(updates, validator.ABCIValidatorUpdate()) } // validator still in the validator set, so delete from the copy - delete(last, opbytes) + delete(last, operatorBytes) // set the bonded validator index store.Set(GetBondedValidatorIndexKey(operator), newPowerBytes) @@ -137,7 +139,7 @@ func (k Keeper) unbondingToUnbonded(ctx sdk.Context, validator types.Validator) } // send a validator to jail -func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { +func (k Keeper) jailValidator(ctx sdk.Context, validator types.Validator) { if validator.Jailed { panic(fmt.Sprintf("cannot jail already jailed validator, validator: %v\n", validator)) } @@ -149,7 +151,7 @@ func (k Keeper) JailValidator(ctx sdk.Context, validator types.Validator) { } // remove a validator from jail -func (k Keeper) UnjailValidator(ctx sdk.Context, validator types.Validator) { +func (k Keeper) unjailValidator(ctx sdk.Context, validator types.Validator) { if !validator.Jailed { panic(fmt.Sprintf("cannot unjail already unjailed validator, validator: %v\n", validator)) } @@ -228,9 +230,12 @@ func (k Keeper) completeUnbondingValidator(ctx sdk.Context, validator types.Vali return validator } +// map of operator addresses to serialized power +type validatorsByAddr map[[sdk.AddrLen]byte][]byte + // retrieve the last validator set -func (k Keeper) retrieveLastValidatorSet(ctx sdk.Context) map[[sdk.AddrLen]byte][]byte { - last := make(map[[sdk.AddrLen]byte][]byte) +func (k Keeper) retrieveLastValidatorSet(ctx sdk.Context) validatorsByAddr { + last := make(validatorsByAddr) store := ctx.KVStore(k.storeKey) iterator := sdk.KVStorePrefixIterator(store, ValidatorsBondedIndexKey) for ; iterator.Valid(); iterator.Next() { @@ -243,14 +248,15 @@ func (k Keeper) retrieveLastValidatorSet(ctx sdk.Context) map[[sdk.AddrLen]byte] return last } -// sort the validators to be unbonded -func (k Keeper) sortNoLongerBonded(last map[[sdk.AddrLen]byte][]byte) [][]byte { +// given a map of remaining validators to previous bonded power +// returns the list of validators to be unbonded, sorted by operator address +func (k Keeper) sortNoLongerBonded(last validatorsByAddr) [][]byte { // sort the map keys for determinism noLongerBonded := make([][]byte, len(last)) index := 0 - for oper := range last { + for operatorBytes := range last { operator := make([]byte, sdk.AddrLen) - copy(operator[:], oper[:]) + copy(operator[:], operatorBytes[:]) noLongerBonded[index] = operator index++ } diff --git a/x/stake/querier/queryable_test.go b/x/stake/querier/queryable_test.go index 00a524b5b43d..d950f90bf91c 100644 --- a/x/stake/querier/queryable_test.go +++ b/x/stake/querier/queryable_test.go @@ -182,7 +182,7 @@ func TestQueryDelegation(t *testing.T) { require.Equal(t, delegation, delegationRes) - // Query unbonding delegation + // Query unbonging delegation keeper.BeginUnbonding(ctx, addrAcc2, val1.OperatorAddr, sdk.NewDec(10)) query = abci.RequestQuery{ From 8853f2bf92d5548b1d1f2043473cecc4c974d201 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 3 Oct 2018 18:26:57 +0200 Subject: [PATCH 52/52] Add descriptive comment --- x/stake/keeper/validator.go | 1 + 1 file changed, 1 insertion(+) diff --git a/x/stake/keeper/validator.go b/x/stake/keeper/validator.go index 927a361a2dd7..b405312a1b2d 100644 --- a/x/stake/keeper/validator.go +++ b/x/stake/keeper/validator.go @@ -180,6 +180,7 @@ func (k Keeper) UpdateValidatorCommission(ctx sdk.Context, validator types.Valid } // remove the validator record and associated indexes +// except for the bonded validator index which is only handled in ApplyAndReturnTendermintUpdates func (k Keeper) RemoveValidator(ctx sdk.Context, address sdk.ValAddress) { // first retrieve the old validator record