From 73292e08b4eda8ae6786c46a593fca0a053ddbdf Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Mon, 3 Sep 2018 17:01:49 +0200 Subject: [PATCH 01/35] 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 5e40c17e6c..1c396c1ac0 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 4368699b6b..dc52ec76a3 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 60c694ff76..a03b3cdbe4 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 44b0474e8b..d48a9d9898 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 b11a774cd9..c5ec604fa0 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 ba11cd5f86..c52e020dd2 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 fc7543280a..02000cc354 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 253daa4128..3210a0f331 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 25167578d1..fccdd844ae 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 0d93093118..7e71b5b251 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/35] 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 a03b3cdbe4..433ed51698 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 8f369d517f..9c8fcfc1fb 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 70f6659a87..a47f1396d1 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 daffa7dd55..71cc4f7e9d 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 c52e020dd2..84f98f9cb5 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 2725165857..081e1c1e58 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 3210a0f331..007d937887 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 7a004bccd2..ff41a73bf5 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 4b478fffd7..d19b5b942b 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 47a5d5f66f..9f8ce7e24c 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 7e71b5b251..d7c0bdb65b 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/35] 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 8e56cfa1ae..a2ef0a30e6 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 4c1cad8777..58dca639af 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 7d9a46403c..6ed80aa45d 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/35] 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 2245223419..7da07e4c2b 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 e2cd585500..b49142a3b4 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/35] 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 6ccd96be36..1f86ae050d 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 63d650cef6..dd53f495c0 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 dad8191b35..1cf74e7f8c 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 e964dbad25..731a21c5fe 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 e7958dfcdf..4c56b9b877 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 49793d3766..1e9263b7bb 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 c3e690925e..b71200b36a 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 2f91a4f263..6f5d1e6da7 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 3a8afba9d8..52703d3d9e 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 2f471a2a5e..8c6cfd071b 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 d7c0bdb65b..540798e2bf 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 b81ae44585..84e0ba7bb9 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/35] 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 9e70978555..aef8d8e32b 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 ddd29f6f84..aa7b1ad692 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/35] 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 2f23fd54fe..51a1a46e23 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 42788714bf..a7b9ab5175 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/35] 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 84f98f9cb5..1e37da0478 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 ff41a73bf5..13f2bec04d 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 aa7b1ad692..6460c35e08 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 d9a9c5faef..957fb845d8 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 540798e2bf..4359abb3f0 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 84e0ba7bb9..be5d331320 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/35] 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 ec5b7b0fda..8f9bd19be8 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 5316be75b5842d6e28065837e83b7b42125ee797 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 06:44:11 +0200 Subject: [PATCH 10/35] Update PENDING.md --- PENDING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/PENDING.md b/PENDING.md index 1f86ae050d..f279eeaf88 100644 --- a/PENDING.md +++ b/PENDING.md @@ -28,6 +28,7 @@ BREAKING CHANGES * [x/stake] \#2040 Validator operator type has now changed to `sdk.ValAddress` * A new bech32 prefix has been introduced for Tendermint signing keys and addresses, `cosmosconspub` and `cosmoscons` respectively. + * [x/slashing] \#1789 Slashing changes for Tendermint validator set offset (NextValSet) * SDK * [core] \#2219 Update to Tendermint 0.24.0 From 549eba0d549c0c29358e542f3b9c8ded7be60848 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 06:56:05 +0200 Subject: [PATCH 11/35] Add height offsets --- x/slashing/keeper.go | 10 ++++++++-- x/slashing/params.go | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 081e1c1e58..4567f538bb 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -62,8 +62,11 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio revisedFraction := k.capBySlashingPeriod(ctx, address, fraction, infractionHeight) logger.Info(fmt.Sprintf("Fraction slashed capped by slashing period from %v to %v", fraction, revisedFraction)) + // We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height. + distributionHeight := infractionHeight - ValidatorUpdateDelay + // Slash validator - k.validatorSet.Slash(ctx, pubkey, infractionHeight, power, revisedFraction) + k.validatorSet.Slash(ctx, pubkey, distributionHeight, power, revisedFraction) // Jail validator k.validatorSet.Jail(ctx, pubkey) @@ -123,7 +126,10 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p // Downtime confirmed: slash and jail the validator logger.Info(fmt.Sprintf("Validator %s past min height of %d and below signed blocks threshold of %d", pubkey.Address(), minHeight, k.MinSignedPerWindow(ctx))) - k.validatorSet.Slash(ctx, pubkey, height, power, k.SlashFractionDowntime(ctx)) + // We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height, + // and subtract an additional 1 since this is the LastCommit. + distributionHeight := height - ValidatorUpdateDelay - 1 + k.validatorSet.Slash(ctx, pubkey, distributionHeight, power, k.SlashFractionDowntime(ctx)) k.validatorSet.Jail(ctx, pubkey) signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeUnbondDuration(ctx)) } else { diff --git a/x/slashing/params.go b/x/slashing/params.go index 6e18e5f481..467af3c113 100644 --- a/x/slashing/params.go +++ b/x/slashing/params.go @@ -15,6 +15,12 @@ const ( DowntimeUnbondDurationKey = "slashing/DowntimeUnbondDuration" SlashFractionDoubleSignKey = "slashing/SlashFractionDoubleSign" SlashFractionDowntimeKey = "slashing/SlashFractionDowntime" + + // Delay, in blocks, between when validator updates are returned to Tendermint and when they are applied + // For example, if this is 0, the validator set at the end of a block will sign the next block, or + // if this is 1, the validator set at the end of a block will sign the block after the next. + // Constant as this should not change without a hard fork. + ValidatorUpdateDelay int64 = 1 ) // MaxEvidenceAge - Max age for evidence - 21 days (3 weeks) From 9dd430386d892e823cfd11e068c54d3415886d16 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 7 Sep 2018 16:18:32 +0200 Subject: [PATCH 12/35] 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 7da07e4c2b..ee5481301e 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 b49142a3b4..a0aeb869fb 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 13/35] 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 cd2e497b05..31b8a03c00 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 e9311958312f6b0b5c9c647614a52319fd70868b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 26 Sep 2018 18:06:52 +0200 Subject: [PATCH 14/35] 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 3c9e676a9a..ee93cfea39 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 c12758de67..566e8a46f8 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 15/35] 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 4cd3c427f9..e4e4881904 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 44def2d323..d734dc9898 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 4802e785b4..e3fef4c6e6 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 f1d13b608a..a1b7e5552a 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 16/35] '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 fcb2523753..a1d38a016f 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 f47f2397c7..1516ed35af 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 6c42701754..049910ed10 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 83e51c0416..186ad87e58 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 5b204f4df7..04bc4c84a5 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 2f66caadd6..5be9d76e82 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 c9bfd08129..99632e7642 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 2a602461a1..3273c229af 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 6c6c78d6ec..e2ec36876c 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 ba7038010a..bc04412791 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 95fc779d73..b196acb230 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 566e8a46f8..7533fed6e9 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 17/35] 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 589137407f..5c30a6216a 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 186ad87e58..24789b10ed 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 46bf748f48..abb0c3921d 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 18/35] 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 abb0c3921d..266e6d14c3 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 4fee7913b5415fb532b363d39c7a498092cfada8 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Wed, 3 Oct 2018 17:59:01 +0200 Subject: [PATCH 19/35] Fix issue from earlier merge --- x/slashing/keeper.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index d41c2d12d7..73d4113679 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -66,7 +66,7 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio distributionHeight := infractionHeight - ValidatorUpdateDelay // Slash validator - k.validatorSet.Slash(ctx, consAddr, infractionHeight, power, revisedFraction) + k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, revisedFraction) // Jail validator k.validatorSet.Jail(ctx, consAddr) @@ -129,7 +129,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p // We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height, // and subtract an additional 1 since this is the LastCommit. distributionHeight := height - ValidatorUpdateDelay - 1 - k.validatorSet.Slash(ctx, consAddr, height, power, k.SlashFractionDowntime(ctx)) + k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, k.SlashFractionDowntime(ctx)) k.validatorSet.Jail(ctx, consAddr) signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeUnbondDuration(ctx)) } else { From 48672c4c0b25da30a0d448a7ee2effbf64792b6b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Thu, 4 Oct 2018 18:22:51 +0200 Subject: [PATCH 20/35] More comments, update sim for NextValSet --- PENDING.md | 5 ++--- x/mock/simulation/random_simulate_blocks.go | 8 ++++++-- x/slashing/keeper.go | 6 ++++++ 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/PENDING.md b/PENDING.md index d556264eda..7799a4a728 100644 --- a/PENDING.md +++ b/PENDING.md @@ -28,10 +28,9 @@ BREAKING CHANGES * [x/stake, x/slashing] [#1305](https://github.com/cosmos/cosmos-sdk/issues/1305) - Rename "revoked" to "jailed" * [x/stake] [#1676] Revoked and jailed validators put into the unbonding state * [x/stake] [#1877] Redelegations/unbonding-delegation from unbonding validator have reduced time - * [x/stake] \#2040 Validator operator type has now changed to `sdk.ValAddress` - * A new bech32 prefix has been introduced for Tendermint signing keys and - addresses, `cosmosconspub` and `cosmoscons` respectively. * [x/slashing] \#1789 Slashing changes for Tendermint validator set offset (NextValSet) + * [x/stake] [\#2040](https://github.com/cosmos/cosmos-sdk/issues/2040) Validator + operator type has now changed to `sdk.ValAddress` * [x/stake] [\#2221](https://github.com/cosmos/cosmos-sdk/issues/2221) New Bech32 prefixes have been introduced for a validator's consensus address and public key: `cosmosvalcons` and `cosmosvalconspub` respectively. Also, existing Bech32 prefixes have been diff --git a/x/mock/simulation/random_simulate_blocks.go b/x/mock/simulation/random_simulate_blocks.go index 51705cbef0..0fc9c21a95 100644 --- a/x/mock/simulation/random_simulate_blocks.go +++ b/x/mock/simulation/random_simulate_blocks.go @@ -77,6 +77,9 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp, } validators := initChain(r, accs, setups, app, appStateFn) + // Second variable to keep pending validator set (delayed one block since TM 0.24) + // Initially this is the same as the initial validator set + nextValidators := validators header := abci.Header{Height: 0, Time: timestamp} opCount := 0 @@ -160,8 +163,9 @@ func SimulateFromSeed(tb testing.TB, app *baseapp.BaseApp, // Generate a random RequestBeginBlock with the current validator set for the next block request = RandomRequestBeginBlock(r, validators, livenessTransitionMatrix, evidenceFraction, pastTimes, pastVoteInfos, event, header) - // Update the validator set - validators = updateValidators(tb, r, validators, res.ValidatorUpdates, event) + // Update the validator set, which will be reflected in the application on the next block + validators = nextValidators + nextValidators = updateValidators(tb, r, validators, res.ValidatorUpdates, event) } if stopEarly { DisplayEvents(events) diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 73d4113679..a745a52d36 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -63,6 +63,9 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio logger.Info(fmt.Sprintf("Fraction slashed capped by slashing period from %v to %v", fraction, revisedFraction)) // We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height. + // Note that this *can* result in a "distributionHeight" of -1, + // i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block. + // That's fine since this is just used to filter unbonding delegations & redelegations. distributionHeight := infractionHeight - ValidatorUpdateDelay // Slash validator @@ -128,6 +131,9 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p pubkey.Address(), minHeight, k.MinSignedPerWindow(ctx))) // We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height, // and subtract an additional 1 since this is the LastCommit. + // Note that this *can* result in a "distributionHeight" of -1 or -2, + // i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block. + // That's fine since this is just used to filter unbonding delegations & redelegations. distributionHeight := height - ValidatorUpdateDelay - 1 k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, k.SlashFractionDowntime(ctx)) k.validatorSet.Jail(ctx, consAddr) From a2113b24dcf1ef5e1289d0bff30b461b33a5f7b4 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 13:31:26 +0200 Subject: [PATCH 21/35] Address TODOs in slashing tests --- x/slashing/keeper_test.go | 54 +++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 28 deletions(-) diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index e32e7af5b3..46a684d5db 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -22,20 +22,19 @@ func init() { // Test that a validator is slashed correctly // when we discover evidence of infraction -// TODO fix this test to not be using the same pubkey/address for signing and operating, it's confusing func TestHandleDoubleSign(t *testing.T) { // initial setup ctx, ck, sk, _, keeper := createTestInput(t) sk = sk.WithHooks(keeper.Hooks()) amtInt := int64(100) - addr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt) - got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, val, amt)) + operatorAddr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt) + got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(operatorAddr, val, amt)) require.True(t, got.IsOK()) validatorUpdates := stake.EndBlocker(ctx, sk) keeper.AddValidators(ctx, validatorUpdates) - require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}}) - require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower())) + require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}}) + require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, operatorAddr).GetPower())) // handle a signature to set signing info keeper.handleValidatorSignature(ctx, val.Address(), amtInt, true) @@ -44,13 +43,13 @@ func TestHandleDoubleSign(t *testing.T) { keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt) // should be jailed - require.True(t, sk.Validator(ctx, addr).GetJailed()) + require.True(t, sk.Validator(ctx, operatorAddr).GetJailed()) // unjail to measure power - sk.Unjail(ctx, sdk.ConsAddress(addr)) // TODO distinguish cons address + sk.Unjail(ctx, sdk.ConsAddress(val.Address())) // power should be reduced require.Equal( t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))), - sk.Validator(ctx, addr).GetPower(), + sk.Validator(ctx, operatorAddr).GetPower(), ) ctx = ctx.WithBlockHeader(abci.Header{Time: time.Unix(1, 0).Add(keeper.MaxEvidenceAge(ctx))}) @@ -58,74 +57,73 @@ func TestHandleDoubleSign(t *testing.T) { keeper.handleDoubleSign(ctx, val.Address(), 0, time.Unix(0, 0), amtInt) require.Equal( t, sdk.NewDecFromInt(amt).Mul(sdk.NewDec(19).Quo(sdk.NewDec(20))), - sk.Validator(ctx, addr).GetPower(), + sk.Validator(ctx, operatorAddr).GetPower(), ) } // Test that the amount a validator is slashed for multiple double signs // is correctly capped by the slashing period in which they were committed -// TODO properly distinguish between consensus and operator address is variable names func TestSlashingPeriodCap(t *testing.T) { // initial setup ctx, ck, sk, _, keeper := createTestInput(t) sk = sk.WithHooks(keeper.Hooks()) amtInt := int64(100) - addr, amt := addrs[0], sdk.NewInt(amtInt) - valConsPubKey, valConsAddr := pks[0], sdk.ConsAddress(pks[0].Address()) - got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(addr, valConsPubKey, amt)) + operatorAddr, amt := addrs[0], sdk.NewInt(amtInt) + valConsPubKey, valConsAddr := pks[0], pks[0].Address() + got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(operatorAddr, valConsPubKey, amt)) require.True(t, got.IsOK()) validatorUpdates := stake.EndBlocker(ctx, sk) keeper.AddValidators(ctx, validatorUpdates) - require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(addr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}}) - require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, addr).GetPower())) + require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}}) + require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, operatorAddr).GetPower())) // handle a signature to set signing info - keeper.handleValidatorSignature(ctx, valConsPubKey.Address(), amtInt, true) + keeper.handleValidatorSignature(ctx, valConsAddr, amtInt, true) // double sign less than max age - keeper.handleDoubleSign(ctx, valConsPubKey.Address(), 0, time.Unix(0, 0), amtInt) + keeper.handleDoubleSign(ctx, valConsAddr, 0, time.Unix(0, 0), amtInt) // should be jailed - require.True(t, sk.Validator(ctx, addr).GetJailed()) + require.True(t, sk.Validator(ctx, operatorAddr).GetJailed()) // end block stake.EndBlocker(ctx, sk) // update block height ctx = ctx.WithBlockHeight(int64(1)) // unjail to measure power - sk.Unjail(ctx, valConsAddr) + sk.Unjail(ctx, sdk.ConsAddress(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()) + require.Equal(t, expectedPower, sk.Validator(ctx, operatorAddr).GetPower()) // double sign again, same slashing period - keeper.handleDoubleSign(ctx, valConsPubKey.Address(), 0, time.Unix(0, 0), amtInt) + keeper.handleDoubleSign(ctx, valConsAddr, 0, time.Unix(0, 0), amtInt) // should be jailed - require.True(t, sk.Validator(ctx, addr).GetJailed()) + require.True(t, sk.Validator(ctx, operatorAddr).GetJailed()) // end block stake.EndBlocker(ctx, sk) // update block height ctx = ctx.WithBlockHeight(int64(2)) // unjail to measure power - sk.Unjail(ctx, valConsAddr) + sk.Unjail(ctx, sdk.ConsAddress(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()) + require.Equal(t, expectedPower, sk.Validator(ctx, operatorAddr).GetPower()) // double sign again, new slashing period - keeper.handleDoubleSign(ctx, valConsPubKey.Address(), 2, time.Unix(0, 0), amtInt) + keeper.handleDoubleSign(ctx, valConsAddr, 2, time.Unix(0, 0), amtInt) // should be jailed - require.True(t, sk.Validator(ctx, addr).GetJailed()) + require.True(t, sk.Validator(ctx, operatorAddr).GetJailed()) // unjail to measure power - sk.Unjail(ctx, valConsAddr) + sk.Unjail(ctx, sdk.ConsAddress(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()) + require.Equal(t, expectedPower, sk.Validator(ctx, operatorAddr).GetPower()) } // Test a validator through uptime, downtime, revocation, From 018aaeb443ca986e01385091854c04cd5eb24acd Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 13:40:00 +0200 Subject: [PATCH 22/35] Add testcase for slash at negative height --- x/stake/keeper/slash_test.go | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/x/stake/keeper/slash_test.go b/x/stake/keeper/slash_test.go index 7959679c6f..edc7ff16b4 100644 --- a/x/stake/keeper/slash_test.go +++ b/x/stake/keeper/slash_test.go @@ -191,6 +191,34 @@ func TestSlashAtFutureHeight(t *testing.T) { require.Panics(t, func() { keeper.Slash(ctx, consAddr, 1, 10, fraction) }) } +// test slash at a negative height +// this just represents pre-genesis and should have the same effect as slashing at height 0 +func TestSlashAtNegativeHeight(t *testing.T) { + ctx, keeper, _ := setupHelper(t, 10) + consAddr := sdk.ConsAddress(PKs[0].Address()) + fraction := sdk.NewDecWithPrec(5, 1) + + oldPool := keeper.GetPool(ctx) + validator, found := keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + keeper.Slash(ctx, consAddr, -2, 10, fraction) + + // read updated state + validator, found = keeper.GetValidatorByConsAddr(ctx, consAddr) + require.True(t, found) + newPool := keeper.GetPool(ctx) + + // end block + updates := keeper.ApplyAndReturnValidatorSetUpdates(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 + require.Equal(t, sdk.NewDec(5).RoundInt64(), oldPool.BondedTokens.Sub(newPool.BondedTokens).RoundInt64()) +} + // tests Slash at the current height func TestSlashValidatorAtCurrentHeight(t *testing.T) { ctx, keeper, _ := setupHelper(t, 10) From 91b755d220dc62ebad86dee58ecfc80a03550a57 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 13:52:30 +0200 Subject: [PATCH 23/35] Add testcase for failing to sign "extra block" --- x/slashing/keeper_test.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 46a684d5db..b4b28c2e1b 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -194,6 +194,24 @@ func TestHandleAbsentValidator(t *testing.T) { validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) require.Equal(t, sdk.Unbonding, validator.GetStatus()) + // validator should have been slashed + require.Equal(t, int64(99), validator.GetTokens().RoundInt64()) + + // 502nd block *also* missed (since the LastCommit would have still included the just-unbonded validator) + height++ + ctx = ctx.WithBlockHeight(height) + keeper.handleValidatorSignature(ctx, val.Address(), amtInt, false) + info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) + require.True(t, found) + require.Equal(t, int64(0), info.StartHeight) + require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-2, info.SignedBlocksCounter) + + // end block + stake.EndBlocker(ctx, sk) + + // validator should not have been slashed any more, since it was already jailed + require.Equal(t, int64(99), validator.GetTokens().RoundInt64()) + // unrevocation should fail prior to jail expiration got = slh(ctx, NewMsgUnjail(addr)) require.False(t, got.IsOK()) @@ -219,7 +237,7 @@ func TestHandleAbsentValidator(t *testing.T) { info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) require.True(t, found) require.Equal(t, height, info.StartHeight) - require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-1, info.SignedBlocksCounter) + require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-2, info.SignedBlocksCounter) // validator should not be immediately jailed again height++ From 1f12f204ce0078bd353e542a4ffd2b6e2a21b58b Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 14:11:36 +0200 Subject: [PATCH 24/35] Testcase fixes, 'make format', negative pre-genesis block --- client/rpc/validators.go | 2 +- x/distribution/types/validator_info.go | 6 ++-- x/slashing/keeper.go | 19 ++++++----- x/slashing/keeper_test.go | 47 +++++++++++++++----------- x/stake/genesis.go | 6 ++++ 5 files changed, 49 insertions(+), 31 deletions(-) diff --git a/client/rpc/validators.go b/client/rpc/validators.go index f937ac4c82..fc37881cba 100644 --- a/client/rpc/validators.go +++ b/client/rpc/validators.go @@ -11,10 +11,10 @@ import ( "github.com/cosmos/cosmos-sdk/client" "github.com/cosmos/cosmos-sdk/client/context" + "github.com/cosmos/cosmos-sdk/client/utils" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/spf13/viper" tmtypes "github.com/tendermint/tendermint/types" - "github.com/cosmos/cosmos-sdk/client/utils" ) // TODO these next two functions feel kinda hacky based on their placement diff --git a/x/distribution/types/validator_info.go b/x/distribution/types/validator_info.go index 18aef8bde6..c8a02569cb 100644 --- a/x/distribution/types/validator_info.go +++ b/x/distribution/types/validator_info.go @@ -19,9 +19,9 @@ func NewValidatorDistInfo(operatorAddr sdk.ValAddress, currentHeight int64) Vali return ValidatorDistInfo{ OperatorAddr: operatorAddr, FeePoolWithdrawalHeight: currentHeight, - Pool: DecCoins{}, - PoolCommission: DecCoins{}, - DelAccum: NewTotalAccum(currentHeight), + Pool: DecCoins{}, + PoolCommission: DecCoins{}, + DelAccum: NewTotalAccum(currentHeight), } } diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index a745a52d36..e61c1d9fbf 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -56,23 +56,26 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio // Double sign confirmed logger.Info(fmt.Sprintf("Confirmed double sign from %s at height %d, age of %d less than max age of %d", pubkey.Address(), infractionHeight, age, maxEvidenceAge)) - // Cap the amount slashed to the penalty for the worst infraction - // within the slashing period when this infraction was committed - fraction := k.SlashFractionDoubleSign(ctx) - revisedFraction := k.capBySlashingPeriod(ctx, consAddr, fraction, infractionHeight) - logger.Info(fmt.Sprintf("Fraction slashed capped by slashing period from %v to %v", fraction, revisedFraction)) - // We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height. // Note that this *can* result in a "distributionHeight" of -1, // i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block. // That's fine since this is just used to filter unbonding delegations & redelegations. distributionHeight := infractionHeight - ValidatorUpdateDelay + // Cap the amount slashed to the penalty for the worst infraction + // within the slashing period when this infraction was committed + fraction := k.SlashFractionDoubleSign(ctx) + revisedFraction := k.capBySlashingPeriod(ctx, consAddr, fraction, distributionHeight) + logger.Info(fmt.Sprintf("Fraction slashed capped by slashing period from %v to %v", fraction, revisedFraction)) + // Slash validator k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, revisedFraction) - // Jail validator - k.validatorSet.Jail(ctx, consAddr) + // Jail validator if not already jailed + validator := k.validatorSet.ValidatorByConsAddr(ctx, consAddr) + if !validator.GetJailed() { + k.validatorSet.Jail(ctx, consAddr) + } // Set validator jail duration signInfo, found := k.getValidatorSigningInfo(ctx, consAddr) diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index b4b28c2e1b..a3191d6e11 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -74,6 +74,7 @@ func TestSlashingPeriodCap(t *testing.T) { got := stake.NewHandler(sk)(ctx, newTestMsgCreateValidator(operatorAddr, valConsPubKey, amt)) require.True(t, got.IsOK()) validatorUpdates := stake.EndBlocker(ctx, sk) + ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1) keeper.AddValidators(ctx, validatorUpdates) require.Equal(t, ck.GetCoins(ctx, sdk.AccAddress(operatorAddr)), sdk.Coins{{sk.GetParams(ctx).BondDenom, initCoins.Sub(amt)}}) require.True(t, sdk.NewDecFromInt(amt).Equal(sk.Validator(ctx, operatorAddr).GetPower())) @@ -82,23 +83,7 @@ func TestSlashingPeriodCap(t *testing.T) { keeper.handleValidatorSignature(ctx, valConsAddr, amtInt, true) // double sign less than max age - keeper.handleDoubleSign(ctx, valConsAddr, 0, time.Unix(0, 0), amtInt) - // should be jailed - require.True(t, sk.Validator(ctx, operatorAddr).GetJailed()) - // end block - stake.EndBlocker(ctx, sk) - // update block height - ctx = ctx.WithBlockHeight(int64(1)) - // unjail to measure power - sk.Unjail(ctx, sdk.ConsAddress(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, operatorAddr).GetPower()) - - // double sign again, same slashing period - keeper.handleDoubleSign(ctx, valConsAddr, 0, time.Unix(0, 0), amtInt) + keeper.handleDoubleSign(ctx, valConsAddr, 1, time.Unix(0, 0), amtInt) // should be jailed require.True(t, sk.Validator(ctx, operatorAddr).GetJailed()) // end block @@ -109,12 +94,28 @@ func TestSlashingPeriodCap(t *testing.T) { sk.Unjail(ctx, sdk.ConsAddress(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, operatorAddr).GetPower()) + + // double sign again, same slashing period + keeper.handleDoubleSign(ctx, valConsAddr, 1, time.Unix(0, 0), amtInt) + // should be jailed + require.True(t, sk.Validator(ctx, operatorAddr).GetJailed()) + // end block + stake.EndBlocker(ctx, sk) + // update block height + ctx = ctx.WithBlockHeight(int64(3)) + // unjail to measure power + sk.Unjail(ctx, sdk.ConsAddress(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, operatorAddr).GetPower()) // double sign again, new slashing period - keeper.handleDoubleSign(ctx, valConsAddr, 2, time.Unix(0, 0), amtInt) + keeper.handleDoubleSign(ctx, valConsAddr, 3, time.Unix(0, 0), amtInt) // should be jailed require.True(t, sk.Validator(ctx, operatorAddr).GetJailed()) // unjail to measure power @@ -210,8 +211,16 @@ func TestHandleAbsentValidator(t *testing.T) { stake.EndBlocker(ctx, sk) // validator should not have been slashed any more, since it was already jailed + validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) require.Equal(t, int64(99), validator.GetTokens().RoundInt64()) + // 502nd block *double signed* (oh no!) + keeper.handleDoubleSign(ctx, val.Address(), height, ctx.BlockHeader().Time, amtInt) + + // validator should have been slashed + validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) + require.Equal(t, int64(94), validator.GetTokens().RoundInt64()) + // unrevocation should fail prior to jail expiration got = slh(ctx, NewMsgUnjail(addr)) require.False(t, got.IsOK()) @@ -231,7 +240,7 @@ func TestHandleAbsentValidator(t *testing.T) { // validator should have been slashed pool = sk.GetPool(ctx) slashAmt := sdk.NewDec(amtInt).Mul(keeper.SlashFractionDowntime(ctx)).RoundInt64() - require.Equal(t, amtInt-slashAmt, pool.BondedTokens.RoundInt64()) + require.Equal(t, amtInt-slashAmt-5, pool.BondedTokens.RoundInt64()) // validator start height should have been changed info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) diff --git a/x/stake/genesis.go b/x/stake/genesis.go index e1f33d94cd..336e414fe7 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -16,6 +16,12 @@ import ( // 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.ValidatorUpdate, err error) { + + // We need to pretend to be "one block before genesis" so that e.g. slashing periods + // are correctly initialized for the validator set one-block offset - the first TM block + // is at height 0, so state updates applied from genesis.json are in block -1. + ctx = ctx.WithBlockHeight(-1) + keeper.SetPool(ctx, data.Pool) keeper.SetParams(ctx, data.Params) keeper.InitIntraTxCounter(ctx) From 1909d8f2694508a1fba04c78a55b7b2b6d485a38 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 14:24:02 +0200 Subject: [PATCH 25/35] Update slashing period key appropriately --- x/slashing/keys.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x/slashing/keys.go b/x/slashing/keys.go index 1f84a285dd..183dfde60d 100644 --- a/x/slashing/keys.go +++ b/x/slashing/keys.go @@ -34,7 +34,8 @@ func GetValidatorSlashingPeriodPrefix(v sdk.ConsAddress) []byte { // stored by *Tendermint* address (not operator address) followed by start height func GetValidatorSlashingPeriodKey(v sdk.ConsAddress, startHeight int64) []byte { b := make([]byte, 8) - binary.LittleEndian.PutUint64(b, uint64(startHeight)) + // this needs to be height + 1 because the slashing period for genesis validators starts at height -1 + binary.LittleEndian.PutUint64(b, uint64(startHeight+1)) return append(GetValidatorSlashingPeriodPrefix(v), b...) } From fdc7b4d7a57c869b77ae1829cc176b09ea2236f2 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 14:33:46 +0200 Subject: [PATCH 26/35] Add default CI multi-seed sim --- .circleci/config.yml | 18 ++++++++++++++++++ Makefile | 8 ++++---- scripts/multisim.sh | 10 +++++++--- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index ad4ca5a168..051e075547 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -136,6 +136,24 @@ jobs: export PATH="$GOBIN:$PATH" make test_sim_gaia_fast + test_sim_gaia_multi_seed: + <<: *defaults + parallelism: 1 + steps: + - attach_workspace: + at: /tmp/workspace + - checkout + - run: + name: dependencies + command: | + export PATH="$GOBIN:$PATH" + make get_vendor_deps + - run: + name: Test multi-seed Gaia simulation + command: | + export PATH="$GOBIN:$PATH" + make test_sim_gaia_multi_seed + test_cover: <<: *defaults parallelism: 4 diff --git a/Makefile b/Makefile index acf81fc977..e5a7847714 100644 --- a/Makefile +++ b/Makefile @@ -162,9 +162,9 @@ test_sim_gaia_fast: @echo "Running quick Gaia simulation. This may take several minutes..." @go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=400 -SimulationBlockSize=200 -SimulationCommit=true -v -timeout 24h -test_sim_gaia_full: - @echo "Running full multi-seed Gaia simulation. This may take awhile!" - @sh scripts/multisim.sh +test_sim_gaia_multi_seed: + @echo "Running multi-seed Gaia simulation. This may take awhile!" + @sh scripts/multisim.sh 10 SIM_NUM_BLOCKS ?= 210 SIM_BLOCK_SIZE ?= 200 @@ -241,4 +241,4 @@ localnet-stop: check_tools check_dev_tools get_tools get_dev_tools get_vendor_deps draw_deps test test_cli test_unit \ test_cover test_lint benchmark devdoc_init devdoc devdoc_save devdoc_update \ build-linux build-docker-gaiadnode localnet-start localnet-stop \ -format check-ledger test_sim_gaia_nondeterminism test_sim_modules test_sim_gaia_fast test_sim_gaia_slow update_tools update_dev_tools +format check-ledger test_sim_gaia_nondeterminism test_sim_modules test_sim_gaia_fast test_sim_gaia_multi_seed update_tools update_dev_tools diff --git a/scripts/multisim.sh b/scripts/multisim.sh index be59b0f1a8..34ff952ca7 100755 --- a/scripts/multisim.sh +++ b/scripts/multisim.sh @@ -1,8 +1,10 @@ #!/bin/bash seeds=(1 2 4 7 9 20 32 123 4728 37827 981928 87821 891823782 989182 89182391) +blocks=$1 -echo "Running multi-seed simulation with seeds: ${seeds[@]}" +echo "Running multi-seed simulation with seeds ${seeds[@]}" +echo "Running $blocks blocks per seed" echo "Edit scripts/multisim.sh to add new seeds. Keeping parameters in the file makes failures easy to reproduce." echo "This script will kill all sub-simulations on SIGINT/SIGTERM/EXIT (i.e. Ctrl-C)." @@ -16,7 +18,7 @@ sim() { echo "Running full Gaia simulation with seed $seed. This may take awhile!" file="$tmpdir/gaia-simulation-seed-$seed-date-$(date -Iseconds -u).stdout" echo "Writing stdout to $file..." - go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=1000 \ + go test ./cmd/gaia/app -run TestFullGaiaSimulation -SimulationEnabled=true -SimulationNumBlocks=$blocks \ -SimulationVerbose=true -SimulationCommit=true -SimulationSeed=$seed -v -timeout 24h > $file } @@ -37,10 +39,12 @@ i=0 for pid in ${pids[*]}; do wait $pid last=$? + seed=${seeds[${i}]} if [ $last -ne 0 ]; then - seed=${seeds[${i}]} echo "Simulation with seed $seed failed!" code=1 + else + echo "Simulation with seed $seed OK!" fi i=$(($i+1)) done From fa3b459314de0468a76f026eb8def9a1e51b1d0e Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 14:41:12 +0200 Subject: [PATCH 27/35] Actually run multi-seed simulation --- .circleci/config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.circleci/config.yml b/.circleci/config.yml index 051e075547..69ba3c4cc3 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -258,6 +258,9 @@ workflows: - test_sim_gaia_fast: requires: - setup_dependencies + - test_sim_gaia_multi_seed: + requires: + - setup_dependencies - test_cover: requires: - setup_dependencies From 034163c021ac1e6d6150d92b8c944b769aec7ec5 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 14:58:19 +0200 Subject: [PATCH 28/35] Minor fixes --- Makefile | 2 +- x/slashing/keeper_test.go | 2 ++ x/slashing/slashing_period.go | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index e5a7847714..5225076fa5 100644 --- a/Makefile +++ b/Makefile @@ -164,7 +164,7 @@ test_sim_gaia_fast: test_sim_gaia_multi_seed: @echo "Running multi-seed Gaia simulation. This may take awhile!" - @sh scripts/multisim.sh 10 + @bash scripts/multisim.sh 10 SIM_NUM_BLOCKS ?= 210 SIM_BLOCK_SIZE ?= 200 diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index a3191d6e11..ef5d0ad266 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -26,6 +26,8 @@ func TestHandleDoubleSign(t *testing.T) { // initial setup ctx, ck, sk, _, keeper := createTestInput(t) + // validator added pre-genesis + ctx = ctx.WithBlockHeight(-1) sk = sk.WithHooks(keeper.Hooks()) amtInt := int64(100) operatorAddr, val, amt := addrs[0], pks[0], sdk.NewInt(amtInt) diff --git a/x/slashing/slashing_period.go b/x/slashing/slashing_period.go index fc57e663ae..923cac44c9 100644 --- a/x/slashing/slashing_period.go +++ b/x/slashing/slashing_period.go @@ -68,7 +68,7 @@ func (k Keeper) unmarshalSlashingPeriodKeyValue(key []byte, value []byte) Valida var slashingPeriodValue ValidatorSlashingPeriodValue k.cdc.MustUnmarshalBinary(value, &slashingPeriodValue) address := sdk.ConsAddress(key[1 : 1+sdk.AddrLen]) - startHeight := int64(binary.LittleEndian.Uint64(key[1+sdk.AddrLen : 1+sdk.AddrLen+8])) + startHeight := int64(binary.LittleEndian.Uint64(key[1+sdk.AddrLen:1+sdk.AddrLen+8]) - 1) return ValidatorSlashingPeriod{ ValidatorAddr: address, StartHeight: startHeight, From 104683129677e7730b93ed9bdb6ba863b65b2dbb Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 15:03:17 +0200 Subject: [PATCH 29/35] Don't trap EXIT --- scripts/multisim.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/multisim.sh b/scripts/multisim.sh index 34ff952ca7..5286fba0a5 100755 --- a/scripts/multisim.sh +++ b/scripts/multisim.sh @@ -6,9 +6,9 @@ blocks=$1 echo "Running multi-seed simulation with seeds ${seeds[@]}" echo "Running $blocks blocks per seed" echo "Edit scripts/multisim.sh to add new seeds. Keeping parameters in the file makes failures easy to reproduce." -echo "This script will kill all sub-simulations on SIGINT/SIGTERM/EXIT (i.e. Ctrl-C)." +echo "This script will kill all sub-simulations on SIGINT/SIGTERM (i.e. Ctrl-C)." -trap 'kill $(jobs -pr)' SIGINT SIGTERM EXIT +trap 'kill $(jobs -pr)' SIGINT SIGTERM tmpdir=$(mktemp -d) echo "Using temporary log directory: $tmpdir" From b7cb2e4252e142adc2c7840ac26993fd091dcaae Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 15:07:28 +0200 Subject: [PATCH 30/35] Slowly start multiple simulations in parallel --- scripts/multisim.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/multisim.sh b/scripts/multisim.sh index 5286fba0a5..c6437f4210 100755 --- a/scripts/multisim.sh +++ b/scripts/multisim.sh @@ -28,7 +28,7 @@ for seed in ${seeds[@]}; do sim $seed & pids[${i}]=$! i=$(($i+1)) - sleep 0.1 # start in order, nicer logs + sleep 5 # start in order, nicer logs done echo "Simulation processes spawned, waiting for completion..." From 482537e6c18c129e7978dfb12c4ef484cafff296 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 19:42:52 +0200 Subject: [PATCH 31/35] Merge PR #2430: Aggressive slashing simulation & fixes --- PENDING.md | 1 + scripts/multisim.sh | 9 +++++---- x/mock/simulation/constants.go | 2 +- x/slashing/keeper.go | 2 +- x/slashing/keys.go | 2 +- x/slashing/slashing_period.go | 6 +++--- 6 files changed, 12 insertions(+), 10 deletions(-) diff --git a/PENDING.md b/PENDING.md index 6c731d2248..44a4f87b68 100644 --- a/PENDING.md +++ b/PENDING.md @@ -42,6 +42,7 @@ BREAKING CHANGES * [x/gov] [#2195] Governance uses BFT Time * [x/gov] \#2256 Removed slashing for governance non-voting validators * [simulation] \#2162 Added back correct supply invariants + * [x/slashing] \#2430 Simulate more slashes, check if validator is jailed before jailing * SDK * [core] \#2219 Update to Tendermint 0.24.0 diff --git a/scripts/multisim.sh b/scripts/multisim.sh index c6437f4210..8ffa338b84 100755 --- a/scripts/multisim.sh +++ b/scripts/multisim.sh @@ -1,6 +1,6 @@ #!/bin/bash -seeds=(1 2 4 7 9 20 32 123 4728 37827 981928 87821 891823782 989182 89182391) +seeds=(1 2 4 7 9 20 32 123 124 582 1893 2989 3012 4728 37827 981928 87821 891823782 989182 89182391) blocks=$1 echo "Running multi-seed simulation with seeds ${seeds[@]}" @@ -28,7 +28,7 @@ for seed in ${seeds[@]}; do sim $seed & pids[${i}]=$! i=$(($i+1)) - sleep 5 # start in order, nicer logs + sleep 10 # start in order, nicer logs done echo "Simulation processes spawned, waiting for completion..." @@ -40,11 +40,12 @@ for pid in ${pids[*]}; do wait $pid last=$? seed=${seeds[${i}]} - if [ $last -ne 0 ]; then + if [ $last -ne 0 ] + then echo "Simulation with seed $seed failed!" code=1 else - echo "Simulation with seed $seed OK!" + echo "Simulation with seed $seed OK" fi i=$(($i+1)) done diff --git a/x/mock/simulation/constants.go b/x/mock/simulation/constants.go index 544da50e3e..a96d4541f1 100644 --- a/x/mock/simulation/constants.go +++ b/x/mock/simulation/constants.go @@ -14,7 +14,7 @@ const ( numKeys int = 250 // Chance that double-signing evidence is found on a given block - evidenceFraction float64 = 0.01 + evidenceFraction float64 = 0.5 // TODO Remove in favor of binary search for invariant violation onOperation bool = false diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index e61c1d9fbf..dc316b2b6f 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -77,7 +77,7 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio k.validatorSet.Jail(ctx, consAddr) } - // Set validator jail duration + // Set or updated validator jail duration signInfo, found := k.getValidatorSigningInfo(ctx, consAddr) if !found { panic(fmt.Sprintf("Expected signing info for validator %s but not found", consAddr)) diff --git a/x/slashing/keys.go b/x/slashing/keys.go index 183dfde60d..4303f4635e 100644 --- a/x/slashing/keys.go +++ b/x/slashing/keys.go @@ -35,7 +35,7 @@ func GetValidatorSlashingPeriodPrefix(v sdk.ConsAddress) []byte { func GetValidatorSlashingPeriodKey(v sdk.ConsAddress, startHeight int64) []byte { b := make([]byte, 8) // this needs to be height + 1 because the slashing period for genesis validators starts at height -1 - binary.LittleEndian.PutUint64(b, uint64(startHeight+1)) + binary.BigEndian.PutUint64(b, uint64(startHeight+1)) return append(GetValidatorSlashingPeriodPrefix(v), b...) } diff --git a/x/slashing/slashing_period.go b/x/slashing/slashing_period.go index 923cac44c9..1d94aa5599 100644 --- a/x/slashing/slashing_period.go +++ b/x/slashing/slashing_period.go @@ -15,7 +15,7 @@ func (k Keeper) capBySlashingPeriod(ctx sdk.Context, address sdk.ConsAddress, fr // Sanity check if slashingPeriod.EndHeight > 0 && slashingPeriod.EndHeight < infractionHeight { - panic(fmt.Sprintf("slashing period ended before infraction: infraction height %d, slashing period ended at %d", infractionHeight, slashingPeriod.EndHeight)) + panic(fmt.Sprintf("slashing period ended before infraction: validator %s, infraction height %d, slashing period ended at %d", address, infractionHeight, slashingPeriod.EndHeight)) } // Calculate the updated total slash amount @@ -43,7 +43,7 @@ func (k Keeper) getValidatorSlashingPeriodForHeight(ctx sdk.Context, address sdk end := sdk.PrefixEndBytes(GetValidatorSlashingPeriodKey(address, height)) iterator := store.ReverseIterator(start, end) if !iterator.Valid() { - panic("expected to find slashing period, but none was found") + panic(fmt.Sprintf("expected to find slashing period for validator %s before height %d, but none was found", address, height)) } slashingPeriod = k.unmarshalSlashingPeriodKeyValue(iterator.Key(), iterator.Value()) return @@ -68,7 +68,7 @@ func (k Keeper) unmarshalSlashingPeriodKeyValue(key []byte, value []byte) Valida var slashingPeriodValue ValidatorSlashingPeriodValue k.cdc.MustUnmarshalBinary(value, &slashingPeriodValue) address := sdk.ConsAddress(key[1 : 1+sdk.AddrLen]) - startHeight := int64(binary.LittleEndian.Uint64(key[1+sdk.AddrLen:1+sdk.AddrLen+8]) - 1) + startHeight := int64(binary.BigEndian.Uint64(key[1+sdk.AddrLen:1+sdk.AddrLen+8]) - 1) return ValidatorSlashingPeriod{ ValidatorAddr: address, StartHeight: startHeight, From b625cf85a1f2a7a947ffb4918d0985d2da1933fb Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 19:45:45 +0200 Subject: [PATCH 32/35] Cleanup testcase --- x/slashing/keeper_test.go | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index ef5d0ad266..43c8e2a203 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -197,8 +197,10 @@ func TestHandleAbsentValidator(t *testing.T) { validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) require.Equal(t, sdk.Unbonding, validator.GetStatus()) + slashAmt := sdk.NewDec(amtInt).Mul(keeper.SlashFractionDowntime(ctx)).RoundInt64() + // validator should have been slashed - require.Equal(t, int64(99), validator.GetTokens().RoundInt64()) + require.Equal(t, amtInt-slashAmt, validator.GetTokens().RoundInt64()) // 502nd block *also* missed (since the LastCommit would have still included the just-unbonded validator) height++ @@ -214,14 +216,15 @@ func TestHandleAbsentValidator(t *testing.T) { // validator should not have been slashed any more, since it was already jailed validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) - require.Equal(t, int64(99), validator.GetTokens().RoundInt64()) + require.Equal(t, amtInt-slashAmt, validator.GetTokens().RoundInt64()) // 502nd block *double signed* (oh no!) keeper.handleDoubleSign(ctx, val.Address(), height, ctx.BlockHeader().Time, amtInt) // validator should have been slashed validator, _ = sk.GetValidatorByConsAddr(ctx, sdk.GetConsAddress(val)) - require.Equal(t, int64(94), validator.GetTokens().RoundInt64()) + secondSlashAmt := sdk.NewDec(amtInt).Mul(keeper.SlashFractionDoubleSign(ctx)).RoundInt64() + require.Equal(t, amtInt-slashAmt-secondSlashAmt, validator.GetTokens().RoundInt64()) // unrevocation should fail prior to jail expiration got = slh(ctx, NewMsgUnjail(addr)) @@ -241,8 +244,7 @@ func TestHandleAbsentValidator(t *testing.T) { // validator should have been slashed pool = sk.GetPool(ctx) - slashAmt := sdk.NewDec(amtInt).Mul(keeper.SlashFractionDowntime(ctx)).RoundInt64() - require.Equal(t, amtInt-slashAmt-5, pool.BondedTokens.RoundInt64()) + require.Equal(t, amtInt-slashAmt-secondSlashAmt, pool.BondedTokens.RoundInt64()) // validator start height should have been changed info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) From 317be2bc16c923b705117d77cd3ff86c9a2cdc36 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 19:56:17 +0200 Subject: [PATCH 33/35] Clarify ValidatorUpdateDelay --- x/slashing/keeper.go | 5 +++-- x/slashing/keeper_test.go | 1 + x/slashing/keys.go | 5 +++-- x/slashing/params.go | 6 ------ x/slashing/slashing_period.go | 3 ++- x/stake/genesis.go | 8 ++++---- x/stake/types/params.go | 14 +++++++++++--- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index dc316b2b6f..473a5f5f68 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -9,6 +9,7 @@ import ( "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/x/params" + stake "github.com/cosmos/cosmos-sdk/x/stake/types" abci "github.com/tendermint/tendermint/abci/types" "github.com/tendermint/tendermint/crypto" ) @@ -60,7 +61,7 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio // Note that this *can* result in a "distributionHeight" of -1, // i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block. // That's fine since this is just used to filter unbonding delegations & redelegations. - distributionHeight := infractionHeight - ValidatorUpdateDelay + distributionHeight := infractionHeight - stake.ValidatorUpdateDelay // Cap the amount slashed to the penalty for the worst infraction // within the slashing period when this infraction was committed @@ -137,7 +138,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p // Note that this *can* result in a "distributionHeight" of -1 or -2, // i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block. // That's fine since this is just used to filter unbonding delegations & redelegations. - distributionHeight := height - ValidatorUpdateDelay - 1 + distributionHeight := height - stake.ValidatorUpdateDelay - 1 k.validatorSet.Slash(ctx, consAddr, distributionHeight, power, k.SlashFractionDowntime(ctx)) k.validatorSet.Jail(ctx, consAddr) signInfo.JailedUntil = ctx.BlockHeader().Time.Add(k.DowntimeUnbondDuration(ctx)) diff --git a/x/slashing/keeper_test.go b/x/slashing/keeper_test.go index 43c8e2a203..cf67af1920 100644 --- a/x/slashing/keeper_test.go +++ b/x/slashing/keeper_test.go @@ -250,6 +250,7 @@ func TestHandleAbsentValidator(t *testing.T) { info, found = keeper.getValidatorSigningInfo(ctx, sdk.ConsAddress(val.Address())) require.True(t, found) require.Equal(t, height, info.StartHeight) + // we've missed 2 blocks more than the maximum require.Equal(t, keeper.SignedBlocksWindow(ctx)-keeper.MinSignedPerWindow(ctx)-2, info.SignedBlocksCounter) // validator should not be immediately jailed again diff --git a/x/slashing/keys.go b/x/slashing/keys.go index 4303f4635e..ec453cedca 100644 --- a/x/slashing/keys.go +++ b/x/slashing/keys.go @@ -4,6 +4,7 @@ import ( "encoding/binary" sdk "github.com/cosmos/cosmos-sdk/types" + stake "github.com/cosmos/cosmos-sdk/x/stake/types" ) // key prefix bytes @@ -34,8 +35,8 @@ func GetValidatorSlashingPeriodPrefix(v sdk.ConsAddress) []byte { // stored by *Tendermint* address (not operator address) followed by start height func GetValidatorSlashingPeriodKey(v sdk.ConsAddress, startHeight int64) []byte { b := make([]byte, 8) - // this needs to be height + 1 because the slashing period for genesis validators starts at height -1 - binary.BigEndian.PutUint64(b, uint64(startHeight+1)) + // this needs to be height + ValidatorUpdateDelay because the slashing period for genesis validators starts at height -ValidatorUpdateDelay + binary.BigEndian.PutUint64(b, uint64(startHeight+stake.ValidatorUpdateDelay)) return append(GetValidatorSlashingPeriodPrefix(v), b...) } diff --git a/x/slashing/params.go b/x/slashing/params.go index 467af3c113..6e18e5f481 100644 --- a/x/slashing/params.go +++ b/x/slashing/params.go @@ -15,12 +15,6 @@ const ( DowntimeUnbondDurationKey = "slashing/DowntimeUnbondDuration" SlashFractionDoubleSignKey = "slashing/SlashFractionDoubleSign" SlashFractionDowntimeKey = "slashing/SlashFractionDowntime" - - // Delay, in blocks, between when validator updates are returned to Tendermint and when they are applied - // For example, if this is 0, the validator set at the end of a block will sign the next block, or - // if this is 1, the validator set at the end of a block will sign the block after the next. - // Constant as this should not change without a hard fork. - ValidatorUpdateDelay int64 = 1 ) // MaxEvidenceAge - Max age for evidence - 21 days (3 weeks) diff --git a/x/slashing/slashing_period.go b/x/slashing/slashing_period.go index 1d94aa5599..0595d5eeb2 100644 --- a/x/slashing/slashing_period.go +++ b/x/slashing/slashing_period.go @@ -5,6 +5,7 @@ import ( "fmt" sdk "github.com/cosmos/cosmos-sdk/types" + stake "github.com/cosmos/cosmos-sdk/x/stake/types" ) // Cap an infraction's slash amount by the slashing period in which it was committed @@ -68,7 +69,7 @@ func (k Keeper) unmarshalSlashingPeriodKeyValue(key []byte, value []byte) Valida var slashingPeriodValue ValidatorSlashingPeriodValue k.cdc.MustUnmarshalBinary(value, &slashingPeriodValue) address := sdk.ConsAddress(key[1 : 1+sdk.AddrLen]) - startHeight := int64(binary.BigEndian.Uint64(key[1+sdk.AddrLen:1+sdk.AddrLen+8]) - 1) + startHeight := int64(binary.BigEndian.Uint64(key[1+sdk.AddrLen:1+sdk.AddrLen+8]) - uint64(stake.ValidatorUpdateDelay)) return ValidatorSlashingPeriod{ ValidatorAddr: address, StartHeight: startHeight, diff --git a/x/stake/genesis.go b/x/stake/genesis.go index 336e414fe7..1d500bd822 100644 --- a/x/stake/genesis.go +++ b/x/stake/genesis.go @@ -17,10 +17,10 @@ import ( // Returns final validator set after applying all declaration and delegations func InitGenesis(ctx sdk.Context, keeper Keeper, data types.GenesisState) (res []abci.ValidatorUpdate, err error) { - // We need to pretend to be "one block before genesis" so that e.g. slashing periods - // are correctly initialized for the validator set one-block offset - the first TM block - // is at height 0, so state updates applied from genesis.json are in block -1. - ctx = ctx.WithBlockHeight(-1) + // We need to pretend to be "n blocks before genesis", where "n" is the validator update delay, + // so that e.g. slashing periods are correctly initialized for the validator set + // e.g. with a one-block offset - the first TM block is at height 0, so state updates applied from genesis.json are in block -1. + ctx = ctx.WithBlockHeight(-types.ValidatorUpdateDelay) keeper.SetPool(ctx, data.Pool) keeper.SetParams(ctx, data.Params) diff --git a/x/stake/types/params.go b/x/stake/types/params.go index 4dcc3782a8..c3685f7c30 100644 --- a/x/stake/types/params.go +++ b/x/stake/types/params.go @@ -9,9 +9,17 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" ) -// defaultUnbondingTime reflects three weeks in seconds as the default -// unbonding time. -const defaultUnbondingTime time.Duration = 60 * 60 * 24 * 3 * time.Second +const ( + // defaultUnbondingTime reflects three weeks in seconds as the default + // unbonding time. + defaultUnbondingTime time.Duration = 60 * 60 * 24 * 3 * time.Second + + // Delay, in blocks, between when validator updates are returned to Tendermint and when they are applied + // For example, if this is 0, the validator set at the end of a block will sign the next block, or + // if this is 1, the validator set at the end of a block will sign the block after the next. + // Constant as this should not change without a hard fork. + ValidatorUpdateDelay int64 = 1 +) // Params defines the high level settings for staking type Params struct { From 1ed338fc5f34f19adcf6e416e5740ca7af6c41d3 Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Fri, 5 Oct 2018 20:00:01 +0200 Subject: [PATCH 34/35] Fixup comments --- x/slashing/keeper.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/slashing/keeper.go b/x/slashing/keeper.go index 473a5f5f68..94dd9f0d0f 100644 --- a/x/slashing/keeper.go +++ b/x/slashing/keeper.go @@ -58,7 +58,7 @@ func (k Keeper) handleDoubleSign(ctx sdk.Context, addr crypto.Address, infractio logger.Info(fmt.Sprintf("Confirmed double sign from %s at height %d, age of %d less than max age of %d", pubkey.Address(), infractionHeight, age, maxEvidenceAge)) // We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height. - // Note that this *can* result in a "distributionHeight" of -1, + // Note that this *can* result in a negative "distributionHeight", up to -ValidatorUpdateDelay, // i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block. // That's fine since this is just used to filter unbonding delegations & redelegations. distributionHeight := infractionHeight - stake.ValidatorUpdateDelay @@ -135,7 +135,7 @@ func (k Keeper) handleValidatorSignature(ctx sdk.Context, addr crypto.Address, p pubkey.Address(), minHeight, k.MinSignedPerWindow(ctx))) // We need to retrieve the stake distribution which signed the block, so we subtract ValidatorUpdateDelay from the evidence height, // and subtract an additional 1 since this is the LastCommit. - // Note that this *can* result in a "distributionHeight" of -1 or -2, + // Note that this *can* result in a negative "distributionHeight" up to -ValidatorUpdateDelay-1, // i.e. at the end of the pre-genesis block (none) = at the beginning of the genesis block. // That's fine since this is just used to filter unbonding delegations & redelegations. distributionHeight := height - stake.ValidatorUpdateDelay - 1 From 71a80bf176127945128271036fab4afe6f85359a Mon Sep 17 00:00:00 2001 From: Christopher Goes Date: Tue, 9 Oct 2018 06:38:58 +0200 Subject: [PATCH 35/35] 'make format' --- client/keys/add.go | 3 ++- client/keys/errors.go | 2 +- client/keys/utils.go | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/client/keys/add.go b/client/keys/add.go index 29ed3e4568..21a372e2f7 100644 --- a/client/keys/add.go +++ b/client/keys/add.go @@ -241,6 +241,7 @@ func AddNewKeyRequestHandler(indent bool) http.HandlerFunc { PostProcessResponse(w, cdc, keyOutput, indent) } } + // function to just a new seed to display in the UI before actually persisting it in the keybase func getSeed(algo keys.SigningAlgo) string { kb := client.MockKeyBase() @@ -341,4 +342,4 @@ func RecoverRequestHandler(indent bool) http.HandlerFunc { PostProcessResponse(w, cdc, keyOutput, indent) } -} \ No newline at end of file +} diff --git a/client/keys/errors.go b/client/keys/errors.go index 2689a918fe..9c6139d7a7 100644 --- a/client/keys/errors.go +++ b/client/keys/errors.go @@ -16,4 +16,4 @@ func errMissingPassword() error { func errMissingSeed() error { return fmt.Errorf("you have to specify seed for key recover") -} \ No newline at end of file +} diff --git a/client/keys/utils.go b/client/keys/utils.go index a4fa867eb0..4ca8fc8f42 100644 --- a/client/keys/utils.go +++ b/client/keys/utils.go @@ -12,9 +12,9 @@ import ( "github.com/cosmos/cosmos-sdk/client" + "github.com/cosmos/cosmos-sdk/codec" sdk "github.com/cosmos/cosmos-sdk/types" "net/http" - "github.com/cosmos/cosmos-sdk/codec" ) // KeyDBName is the directory under root where we store the keys