From fe5b0d70749eec50674b1702c3cf9b5e32e5e7cd Mon Sep 17 00:00:00 2001 From: Ethan Buchman Date: Fri, 27 Jul 2018 13:52:42 -0400 Subject: [PATCH 01/16] consensus: fix test for blocks with evidence --- consensus/common_test.go | 8 +-- consensus/reactor_test.go | 117 +++++++++++++++++++++++++++++++------- 2 files changed, 100 insertions(+), 25 deletions(-) diff --git a/consensus/common_test.go b/consensus/common_test.go index 2df226ba1..992b6fcd6 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -17,14 +17,14 @@ import ( bc "github.com/tendermint/tendermint/blockchain" cfg "github.com/tendermint/tendermint/config" cstypes "github.com/tendermint/tendermint/consensus/types" + cmn "github.com/tendermint/tendermint/libs/common" + dbm "github.com/tendermint/tendermint/libs/db" + "github.com/tendermint/tendermint/libs/log" mempl "github.com/tendermint/tendermint/mempool" "github.com/tendermint/tendermint/p2p" "github.com/tendermint/tendermint/privval" sm "github.com/tendermint/tendermint/state" "github.com/tendermint/tendermint/types" - cmn "github.com/tendermint/tendermint/libs/common" - dbm "github.com/tendermint/tendermint/libs/db" - "github.com/tendermint/tendermint/libs/log" "github.com/tendermint/tendermint/abci/example/counter" "github.com/tendermint/tendermint/abci/example/kvstore" @@ -429,7 +429,7 @@ func randGenesisDoc(numValidators int, randPower bool, minPower int64) (*types.G func randGenesisState(numValidators int, randPower bool, minPower int64) (sm.State, []types.PrivValidator) { genDoc, privValidators := randGenesisDoc(numValidators, randPower, minPower) s0, _ := sm.MakeGenesisState(genDoc) - db := dbm.NewMemDB() + db := dbm.NewMemDB() // remove this ? sm.SaveState(db, s0) return s0, privValidators } diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index 90def612b..63dd9075f 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -4,15 +4,21 @@ import ( "context" "fmt" "os" + "path" "runtime" "runtime/pprof" "sync" "testing" "time" + abcicli "github.com/tendermint/tendermint/abci/client" "github.com/tendermint/tendermint/abci/example/kvstore" + abci "github.com/tendermint/tendermint/abci/types" + bc "github.com/tendermint/tendermint/blockchain" cmn "github.com/tendermint/tendermint/libs/common" + dbm "github.com/tendermint/tendermint/libs/db" "github.com/tendermint/tendermint/libs/log" + mempl "github.com/tendermint/tendermint/mempool" sm "github.com/tendermint/tendermint/state" cfg "github.com/tendermint/tendermint/config" @@ -94,49 +100,118 @@ func TestReactorBasic(t *testing.T) { // Ensure we can process blocks with evidence func TestReactorWithEvidence(t *testing.T) { - N := 4 - css := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter) - evpool := mockEvidencePool{ - t: t, - ev: []types.Evidence{types.NewMockGoodEvidence(1, 1, []byte("somone"))}, + nValidators := 4 + testName := "consensus_reactor_test" + tickerFunc := newMockTickerFunc(true) + appFunc := newCounter + + // heed the advice from https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction + // to unroll unwieldy abstractions. Here we duplicate the code from: + // css := randConsensusNet(N, "consensus_reactor_test", newMockTickerFunc(true), newCounter) + + genDoc, privVals := randGenesisDoc(nValidators, false, 30) + css := make([]*ConsensusState, nValidators) + logger := consensusLogger() + for i := 0; i < nValidators; i++ { + stateDB := dbm.NewMemDB() // each state needs its own db + state, _ := sm.LoadStateFromDBOrGenesisDoc(stateDB, genDoc) + thisConfig := ResetConfig(cmn.Fmt("%s_%d", testName, i)) + ensureDir(path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal + app := appFunc() + vals := types.TM2PB.Validators(state.Validators) + app.InitChain(abci.RequestInitChain{Validators: vals}) + + pv := privVals[i] + // duplicate code from: + // css[i] = newConsensusStateWithConfig(thisConfig, state, privVals[i], app) + + blockDB := dbm.NewMemDB() + blockStore := bc.NewBlockStore(blockDB) + + // one for mempool, one for consensus + mtx := new(sync.Mutex) + proxyAppConnMem := abcicli.NewLocalClient(mtx, app) + proxyAppConnCon := abcicli.NewLocalClient(mtx, app) + + // Make Mempool + mempool := mempl.NewMempool(thisConfig.Mempool, proxyAppConnMem, 0) + mempool.SetLogger(log.TestingLogger().With("module", "mempool")) + if thisConfig.Consensus.WaitForTxs() { + mempool.EnableTxsAvailable() + } + + // mock the evidence pool + // everyone includes evidence of another double signing + vIdx := (i + 1) % nValidators + evpool := newMockEvidencePool(privVals[vIdx].GetAddress()) + + // Make ConsensusState + blockExec := sm.NewBlockExecutor(stateDB, log.TestingLogger(), proxyAppConnCon, mempool, evpool) + cs := NewConsensusState(thisConfig.Consensus, state, blockExec, blockStore, mempool, evpool) + cs.SetLogger(log.TestingLogger().With("module", "consensus")) + cs.SetPrivValidator(pv) + + eventBus := types.NewEventBus() + eventBus.SetLogger(log.TestingLogger().With("module", "events")) + eventBus.Start() + cs.SetEventBus(eventBus) + + cs.SetTimeoutTicker(tickerFunc()) + cs.SetLogger(logger.With("validator", i, "module", "consensus")) + + css[i] = cs } - for i := 0; i < N; i++ { - css[i].evpool = evpool - } - reactors, eventChans, eventBuses := startConsensusNet(t, css, N) + + reactors, eventChans, eventBuses := startConsensusNet(t, css, nValidators) defer stopConsensusNet(log.TestingLogger(), reactors, eventBuses) - // wait till everyone makes the first new block - timeoutWaitGroup(t, N, func(j int) { - <-eventChans[j] + + // wait till everyone makes the first new block with no evidence + timeoutWaitGroup(t, nValidators, func(j int) { + blockI := <-eventChans[j] + block := blockI.(types.EventDataNewBlock).Block + assert.True(t, len(block.Evidence.Evidence) == 0) }, css) // second block should have evidence - timeoutWaitGroup(t, N, func(j int) { - <-eventChans[j] + timeoutWaitGroup(t, nValidators, func(j int) { + blockI := <-eventChans[j] + block := blockI.(types.EventDataNewBlock).Block + assert.True(t, len(block.Evidence.Evidence) > 0) }, css) } +// mock evidence pool returns no evidence for block 1, +// and returnes one piece for all higher blocks. The one piece +// is for a given validator at block 1. type mockEvidencePool struct { height int ev []types.Evidence - t *testing.T } -func (m mockEvidencePool) PendingEvidence() []types.Evidence { +func newMockEvidencePool(val []byte) *mockEvidencePool { + return &mockEvidencePool{ + ev: []types.Evidence{types.NewMockGoodEvidence(1, 1, val)}, + } +} + +func (m *mockEvidencePool) PendingEvidence() []types.Evidence { if m.height > 0 { return m.ev } return nil } -func (m mockEvidencePool) AddEvidence(types.Evidence) error { return nil } -func (m mockEvidencePool) Update(block *types.Block, state sm.State) { - m.height += 1 - +func (m *mockEvidencePool) AddEvidence(types.Evidence) error { return nil } +func (m *mockEvidencePool) Update(block *types.Block, state sm.State) { if m.height > 0 { - require.True(m.t, len(block.Evidence.Evidence) > 0) + if len(block.Evidence.Evidence) == 0 { + panic("block has no evidence") + } } + m.height += 1 } +//------------------------------------ + // Ensure a testnet sends proposal heartbeats and makes blocks when there are txs func TestReactorProposalHeartbeats(t *testing.T) { N := 4 From 7634073718e124bf9864f43c1afe7bd02c446b67 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Sat, 28 Jul 2018 09:09:53 +0400 Subject: [PATCH 02/16] revert "make `/status` RPC endpoint resistant to consensus halt" Refs #1772 Reasons: - this was a bad patch for something not well understood Lessons learned: - nobody should be modifying code without understanding the problem first. it will only result in more technical debt and code rot. - we never hide information when we suspect a bug or we'not sure what's going on. --- rpc/core/status.go | 45 ++--------------------------------------- rpc/core/status_test.go | 39 ----------------------------------- 2 files changed, 2 insertions(+), 82 deletions(-) delete mode 100644 rpc/core/status_test.go diff --git a/rpc/core/status.go b/rpc/core/status.go index 137aaf422..4cb7667b7 100644 --- a/rpc/core/status.go +++ b/rpc/core/status.go @@ -104,20 +104,11 @@ func Status() (*ctypes.ResultStatus, error) { return result, nil } -const consensusTimeout = time.Second - func validatorAtHeight(h int64) *types.Validator { - lastBlockHeight, vals := getValidatorsWithTimeout( - consensusState, - consensusTimeout, - ) - - if lastBlockHeight == -1 { - return nil - } - privValAddress := pubKey.Address() + lastBlockHeight, vals := consensusState.GetValidators() + // if we're still at height h, search in the current validator set if lastBlockHeight == h { for _, val := range vals { @@ -140,35 +131,3 @@ func validatorAtHeight(h int64) *types.Validator { return nil } - -type validatorRetriever interface { - GetValidators() (int64, []*types.Validator) -} - -// NOTE: Consensus might halt, but we still need to process RPC requests (at -// least for endpoints whole output does not depend on consensus state). -func getValidatorsWithTimeout( - vr validatorRetriever, - t time.Duration, -) (int64, []*types.Validator) { - resultCh := make(chan struct { - lastBlockHeight int64 - vals []*types.Validator - }) - go func() { - h, v := vr.GetValidators() - resultCh <- struct { - lastBlockHeight int64 - vals []*types.Validator - }{h, v} - }() - select { - case res := <-resultCh: - return res.lastBlockHeight, res.vals - case <-time.After(t): - if logger != nil { - logger.Error("Timed out querying validators from consensus", "timeout", t) - } - return -1, []*types.Validator{} - } -} diff --git a/rpc/core/status_test.go b/rpc/core/status_test.go deleted file mode 100644 index e44ffed0f..000000000 --- a/rpc/core/status_test.go +++ /dev/null @@ -1,39 +0,0 @@ -package core - -import ( - "testing" - "time" - - "github.com/tendermint/tendermint/types" -) - -func TestGetValidatorsWithTimeout(t *testing.T) { - height, vs := getValidatorsWithTimeout( - testValidatorReceiver{}, - time.Millisecond, - ) - - if height != -1 { - t.Errorf("expected negative height") - } - - if len(vs) != 0 { - t.Errorf("expected no validators") - } -} - -type testValidatorReceiver struct{} - -func (tr testValidatorReceiver) GetValidators() (int64, []*types.Validator) { - vs := []*types.Validator{} - - for i := 0; i < 3; i++ { - v, _ := types.RandValidator(true, 10) - - vs = append(vs, v) - } - - time.Sleep(time.Millisecond) - - return 10, vs -} From 188e4592731878c893d0a11fc4723747a232ca35 Mon Sep 17 00:00:00 2001 From: VenkatDatta Date: Sun, 29 Jul 2018 11:16:53 +0530 Subject: [PATCH 03/16] Removed unnecessary onStart call (#2098) * Removed unnecessary onStart & onStop calls in reactor * Refactor OnStart & OnStop in reactor * Removed redundant OnStart func in reactor --- blockchain/reactor.go | 4 ---- consensus/reactor.go | 4 ---- evidence/reactor.go | 5 ----- p2p/pex/pex_reactor.go | 4 ---- 4 files changed, 17 deletions(-) diff --git a/blockchain/reactor.go b/blockchain/reactor.go index eadeedc91..f00df50c3 100644 --- a/blockchain/reactor.go +++ b/blockchain/reactor.go @@ -109,9 +109,6 @@ func (bcR *BlockchainReactor) SetLogger(l log.Logger) { // OnStart implements cmn.Service. func (bcR *BlockchainReactor) OnStart() error { - if err := bcR.BaseReactor.OnStart(); err != nil { - return err - } if bcR.fastSync { err := bcR.pool.Start() if err != nil { @@ -124,7 +121,6 @@ func (bcR *BlockchainReactor) OnStart() error { // OnStop implements cmn.Service. func (bcR *BlockchainReactor) OnStop() { - bcR.BaseReactor.OnStop() bcR.pool.Stop() } diff --git a/consensus/reactor.go b/consensus/reactor.go index 3eb1d73aa..58ff42ae2 100644 --- a/consensus/reactor.go +++ b/consensus/reactor.go @@ -58,9 +58,6 @@ func NewConsensusReactor(consensusState *ConsensusState, fastSync bool) *Consens // broadcasted to other peers and starting state if we're not in fast sync. func (conR *ConsensusReactor) OnStart() error { conR.Logger.Info("ConsensusReactor ", "fastSync", conR.FastSync()) - if err := conR.BaseReactor.OnStart(); err != nil { - return err - } conR.subscribeToBroadcastEvents() @@ -77,7 +74,6 @@ func (conR *ConsensusReactor) OnStart() error { // OnStop implements BaseService by unsubscribing from events and stopping // state. func (conR *ConsensusReactor) OnStop() { - conR.BaseReactor.OnStop() conR.unsubscribeFromBroadcastEvents() conR.conS.Stop() if !conR.FastSync() { diff --git a/evidence/reactor.go b/evidence/reactor.go index bf11ac105..cfe47364c 100644 --- a/evidence/reactor.go +++ b/evidence/reactor.go @@ -44,11 +44,6 @@ func (evR *EvidenceReactor) SetLogger(l log.Logger) { evR.evpool.SetLogger(l) } -// OnStart implements cmn.Service -func (evR *EvidenceReactor) OnStart() error { - return evR.BaseReactor.OnStart() -} - // GetChannels implements Reactor. // It returns the list of channels for this reactor. func (evR *EvidenceReactor) GetChannels() []*p2p.ChannelDescriptor { diff --git a/p2p/pex/pex_reactor.go b/p2p/pex/pex_reactor.go index 5c4894ce4..2929d9336 100644 --- a/p2p/pex/pex_reactor.go +++ b/p2p/pex/pex_reactor.go @@ -113,9 +113,6 @@ func NewPEXReactor(b AddrBook, config *PEXReactorConfig) *PEXReactor { // OnStart implements BaseService func (r *PEXReactor) OnStart() error { - if err := r.BaseReactor.OnStart(); err != nil { - return err - } err := r.book.Start() if err != nil && err != cmn.ErrAlreadyStarted { return err @@ -139,7 +136,6 @@ func (r *PEXReactor) OnStart() error { // OnStop implements BaseService func (r *PEXReactor) OnStop() { - r.BaseReactor.OnStop() r.book.Stop() } From f00b52b71025694017dfd5dc046d14b073a084ad Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Sat, 28 Jul 2018 22:48:37 -0700 Subject: [PATCH 04/16] libs/autofile/group_test: Remove unnecessary logging (#2100) Previously we logged `Testing for i ` for all i in [0,100). This was unnecessary. This changes it to just log the value for i on error messages, to reduce the unnecessary verbosity in log files. --- libs/autofile/group_test.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/libs/autofile/group_test.go b/libs/autofile/group_test.go index 72581f9e2..c7e8725cf 100644 --- a/libs/autofile/group_test.go +++ b/libs/autofile/group_test.go @@ -147,14 +147,13 @@ func TestSearch(t *testing.T) { // Now search for each number for i := 0; i < 100; i++ { - t.Log("Testing for i", i) gr, match, err := g.Search("INFO", makeSearchFunc(i)) - require.NoError(t, err, "Failed to search for line") - assert.True(t, match, "Expected Search to return exact match") + require.NoError(t, err, "Failed to search for line, tc #%d", i) + assert.True(t, match, "Expected Search to return exact match, tc #%d", i) line, err := gr.ReadLine() - require.NoError(t, err, "Failed to read line after search") + require.NoError(t, err, "Failed to read line after search, tc #%d", i) if !strings.HasPrefix(line, fmt.Sprintf("INFO %v ", i)) { - t.Fatal("Failed to get correct line") + t.Fatalf("Failed to get correct line, tc #%d", i) } // Make sure we can continue to read from there. cur := i + 1 @@ -165,16 +164,16 @@ func TestSearch(t *testing.T) { // OK! break } else { - t.Fatal("Got EOF after the wrong INFO #") + t.Fatalf("Got EOF after the wrong INFO #, tc #%d", i) } } else if err != nil { - t.Fatal("Error reading line", err) + t.Fatalf("Error reading line, tc #%d, err:\n%s", i, err) } if !strings.HasPrefix(line, "INFO ") { continue } if !strings.HasPrefix(line, fmt.Sprintf("INFO %v ", cur)) { - t.Fatalf("Unexpected INFO #. Expected %v got:\n%v", cur, line) + t.Fatalf("Unexpected INFO #. Expected %v got:\n%v, tc #%d", cur, line, i) } cur++ } From fef4fe1c667d91c2b75f8d0cba388ceda1929b6e Mon Sep 17 00:00:00 2001 From: Zaki Manian Date: Sat, 28 Jul 2018 22:49:42 -0700 Subject: [PATCH 05/16] Link to "The latest gossip on BFT consensus" (#2102) The paper is such a useful resource to anyone building on Tendermint. It should be linked in the ReadMe. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6268e0547..94d8d7f01 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ develop | [![CircleCI](https://circleci.com/gh/tendermint/tendermint/tree/deve Tendermint Core is Byzantine Fault Tolerant (BFT) middleware that takes a state transition machine - written in any programming language - and securely replicates it on many machines. -For protocol details, see [the specification](/docs/spec). +For protocol details, see [the specification](/docs/spec). For a consensus proof and detailed protocol analysis checkout our recent paper, "[The latest gossip on BFT consensus](https://arxiv.org/abs/1807.04938)". ## A Note on Production Readiness From 231cdc1320d3c5299432081d55db10c2b3b6cff8 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Sun, 29 Jul 2018 16:05:27 -0700 Subject: [PATCH 06/16] ci: Reduce log output in test_cover (#2105) This commit makes it such that circle CI only shows the module whose tests it is currently running in the log, unless a test fails. For each failing test, it will display the name of all failing tests, along with their log output. This is done to make our log output far more scrollable. We lose no information in debugging. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index e76499712..8d321e9e6 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -147,7 +147,7 @@ jobs: for pkg in $(go list github.com/tendermint/tendermint/... | circleci tests split --split-by=timings); do id=$(basename "$pkg") - GOCACHE=off go test -v -timeout 5m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg" | tee "/tmp/logs/$id-$RANDOM.log" + GOCACHE=off go test -timeout 5m -race -coverprofile=/tmp/workspace/profiles/$id.out -covermode=atomic "$pkg" | tee "/tmp/logs/$id-$RANDOM.log" done - persist_to_workspace: root: /tmp/workspace From 0c7338c5f037fc17621427a778a9bf19b1abb2e4 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Mon, 30 Jul 2018 19:29:40 +0400 Subject: [PATCH 07/16] abci: Change validators to last_commit_info in RequestBeginBlock (#2074) * change validators to last_commit_info in RequestBeginBlock * do not send pubkeys with RequestBeginBlock Refs #1856 --- CHANGELOG_PENDING.md | 1 + abci/types/types.pb.go | 965 +++++++++++++++++++++++-------------- abci/types/types.proto | 12 +- abci/types/typespb_test.go | 124 +++++ docs/app-dev/abci-spec.md | 17 +- state/execution.go | 11 +- state/execution_test.go | 2 +- types/protobuf.go | 9 +- types/protobuf_test.go | 21 + 9 files changed, 792 insertions(+), 370 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 5bb79e4f6..76d06b496 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -7,6 +7,7 @@ BREAKING CHANGES: - [tools] Removed `make ensure_deps` in favor of `make get_vendor_deps` - [p2p] Remove salsa and ripemd primitives, in favor of using chacha as a stream cipher, and hkdf - [abci] Changed time format from int64 to google.protobuf.Timestamp +- [abci] Changed Validators to LastCommitInfo in RequestBeginBlock FEATURES: - [tools] Added `make check_dep` diff --git a/abci/types/types.pb.go b/abci/types/types.pb.go index 9a2b511b2..ac71d91c8 100644 --- a/abci/types/types.pb.go +++ b/abci/types/types.pb.go @@ -59,7 +59,7 @@ func (m *Request) Reset() { *m = Request{} } func (m *Request) String() string { return proto.CompactTextString(m) } func (*Request) ProtoMessage() {} func (*Request) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{0} + return fileDescriptor_types_d8da2202f45d32c0, []int{0} } func (m *Request) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -481,7 +481,7 @@ func (m *RequestEcho) Reset() { *m = RequestEcho{} } func (m *RequestEcho) String() string { return proto.CompactTextString(m) } func (*RequestEcho) ProtoMessage() {} func (*RequestEcho) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{1} + return fileDescriptor_types_d8da2202f45d32c0, []int{1} } func (m *RequestEcho) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -527,7 +527,7 @@ func (m *RequestFlush) Reset() { *m = RequestFlush{} } func (m *RequestFlush) String() string { return proto.CompactTextString(m) } func (*RequestFlush) ProtoMessage() {} func (*RequestFlush) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{2} + return fileDescriptor_types_d8da2202f45d32c0, []int{2} } func (m *RequestFlush) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -567,7 +567,7 @@ func (m *RequestInfo) Reset() { *m = RequestInfo{} } func (m *RequestInfo) String() string { return proto.CompactTextString(m) } func (*RequestInfo) ProtoMessage() {} func (*RequestInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{3} + return fileDescriptor_types_d8da2202f45d32c0, []int{3} } func (m *RequestInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -616,7 +616,7 @@ func (m *RequestSetOption) Reset() { *m = RequestSetOption{} } func (m *RequestSetOption) String() string { return proto.CompactTextString(m) } func (*RequestSetOption) ProtoMessage() {} func (*RequestSetOption) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{4} + return fileDescriptor_types_d8da2202f45d32c0, []int{4} } func (m *RequestSetOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -674,7 +674,7 @@ func (m *RequestInitChain) Reset() { *m = RequestInitChain{} } func (m *RequestInitChain) String() string { return proto.CompactTextString(m) } func (*RequestInitChain) ProtoMessage() {} func (*RequestInitChain) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{5} + return fileDescriptor_types_d8da2202f45d32c0, []int{5} } func (m *RequestInitChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -752,7 +752,7 @@ func (m *RequestQuery) Reset() { *m = RequestQuery{} } func (m *RequestQuery) String() string { return proto.CompactTextString(m) } func (*RequestQuery) ProtoMessage() {} func (*RequestQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{6} + return fileDescriptor_types_d8da2202f45d32c0, []int{6} } func (m *RequestQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -809,21 +809,22 @@ func (m *RequestQuery) GetProve() bool { return false } +// NOTE: validators here have empty pubkeys. type RequestBeginBlock struct { - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` - Header Header `protobuf:"bytes,2,opt,name=header" json:"header"` - Validators []SigningValidator `protobuf:"bytes,3,rep,name=validators" json:"validators"` - ByzantineValidators []Evidence `protobuf:"bytes,4,rep,name=byzantine_validators,json=byzantineValidators" json:"byzantine_validators"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` + Header Header `protobuf:"bytes,2,opt,name=header" json:"header"` + LastCommitInfo LastCommitInfo `protobuf:"bytes,3,opt,name=last_commit_info,json=lastCommitInfo" json:"last_commit_info"` + ByzantineValidators []Evidence `protobuf:"bytes,4,rep,name=byzantine_validators,json=byzantineValidators" json:"byzantine_validators"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *RequestBeginBlock) Reset() { *m = RequestBeginBlock{} } func (m *RequestBeginBlock) String() string { return proto.CompactTextString(m) } func (*RequestBeginBlock) ProtoMessage() {} func (*RequestBeginBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{7} + return fileDescriptor_types_d8da2202f45d32c0, []int{7} } func (m *RequestBeginBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -866,11 +867,11 @@ func (m *RequestBeginBlock) GetHeader() Header { return Header{} } -func (m *RequestBeginBlock) GetValidators() []SigningValidator { +func (m *RequestBeginBlock) GetLastCommitInfo() LastCommitInfo { if m != nil { - return m.Validators + return m.LastCommitInfo } - return nil + return LastCommitInfo{} } func (m *RequestBeginBlock) GetByzantineValidators() []Evidence { @@ -891,7 +892,7 @@ func (m *RequestCheckTx) Reset() { *m = RequestCheckTx{} } func (m *RequestCheckTx) String() string { return proto.CompactTextString(m) } func (*RequestCheckTx) ProtoMessage() {} func (*RequestCheckTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{8} + return fileDescriptor_types_d8da2202f45d32c0, []int{8} } func (m *RequestCheckTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -938,7 +939,7 @@ func (m *RequestDeliverTx) Reset() { *m = RequestDeliverTx{} } func (m *RequestDeliverTx) String() string { return proto.CompactTextString(m) } func (*RequestDeliverTx) ProtoMessage() {} func (*RequestDeliverTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{9} + return fileDescriptor_types_d8da2202f45d32c0, []int{9} } func (m *RequestDeliverTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -985,7 +986,7 @@ func (m *RequestEndBlock) Reset() { *m = RequestEndBlock{} } func (m *RequestEndBlock) String() string { return proto.CompactTextString(m) } func (*RequestEndBlock) ProtoMessage() {} func (*RequestEndBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{10} + return fileDescriptor_types_d8da2202f45d32c0, []int{10} } func (m *RequestEndBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1031,7 +1032,7 @@ func (m *RequestCommit) Reset() { *m = RequestCommit{} } func (m *RequestCommit) String() string { return proto.CompactTextString(m) } func (*RequestCommit) ProtoMessage() {} func (*RequestCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{11} + return fileDescriptor_types_d8da2202f45d32c0, []int{11} } func (m *RequestCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1084,7 +1085,7 @@ func (m *Response) Reset() { *m = Response{} } func (m *Response) String() string { return proto.CompactTextString(m) } func (*Response) ProtoMessage() {} func (*Response) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{12} + return fileDescriptor_types_d8da2202f45d32c0, []int{12} } func (m *Response) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1537,7 +1538,7 @@ func (m *ResponseException) Reset() { *m = ResponseException{} } func (m *ResponseException) String() string { return proto.CompactTextString(m) } func (*ResponseException) ProtoMessage() {} func (*ResponseException) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{13} + return fileDescriptor_types_d8da2202f45d32c0, []int{13} } func (m *ResponseException) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1584,7 +1585,7 @@ func (m *ResponseEcho) Reset() { *m = ResponseEcho{} } func (m *ResponseEcho) String() string { return proto.CompactTextString(m) } func (*ResponseEcho) ProtoMessage() {} func (*ResponseEcho) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{14} + return fileDescriptor_types_d8da2202f45d32c0, []int{14} } func (m *ResponseEcho) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1630,7 +1631,7 @@ func (m *ResponseFlush) Reset() { *m = ResponseFlush{} } func (m *ResponseFlush) String() string { return proto.CompactTextString(m) } func (*ResponseFlush) ProtoMessage() {} func (*ResponseFlush) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{15} + return fileDescriptor_types_d8da2202f45d32c0, []int{15} } func (m *ResponseFlush) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1673,7 +1674,7 @@ func (m *ResponseInfo) Reset() { *m = ResponseInfo{} } func (m *ResponseInfo) String() string { return proto.CompactTextString(m) } func (*ResponseInfo) ProtoMessage() {} func (*ResponseInfo) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{16} + return fileDescriptor_types_d8da2202f45d32c0, []int{16} } func (m *ResponseInfo) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1745,7 +1746,7 @@ func (m *ResponseSetOption) Reset() { *m = ResponseSetOption{} } func (m *ResponseSetOption) String() string { return proto.CompactTextString(m) } func (*ResponseSetOption) ProtoMessage() {} func (*ResponseSetOption) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{17} + return fileDescriptor_types_d8da2202f45d32c0, []int{17} } func (m *ResponseSetOption) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1807,7 +1808,7 @@ func (m *ResponseInitChain) Reset() { *m = ResponseInitChain{} } func (m *ResponseInitChain) String() string { return proto.CompactTextString(m) } func (*ResponseInitChain) ProtoMessage() {} func (*ResponseInitChain) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{18} + return fileDescriptor_types_d8da2202f45d32c0, []int{18} } func (m *ResponseInitChain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1869,7 +1870,7 @@ func (m *ResponseQuery) Reset() { *m = ResponseQuery{} } func (m *ResponseQuery) String() string { return proto.CompactTextString(m) } func (*ResponseQuery) ProtoMessage() {} func (*ResponseQuery) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{19} + return fileDescriptor_types_d8da2202f45d32c0, []int{19} } func (m *ResponseQuery) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1965,7 +1966,7 @@ func (m *ResponseBeginBlock) Reset() { *m = ResponseBeginBlock{} } func (m *ResponseBeginBlock) String() string { return proto.CompactTextString(m) } func (*ResponseBeginBlock) ProtoMessage() {} func (*ResponseBeginBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{20} + return fileDescriptor_types_d8da2202f45d32c0, []int{20} } func (m *ResponseBeginBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2018,7 +2019,7 @@ func (m *ResponseCheckTx) Reset() { *m = ResponseCheckTx{} } func (m *ResponseCheckTx) String() string { return proto.CompactTextString(m) } func (*ResponseCheckTx) ProtoMessage() {} func (*ResponseCheckTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{21} + return fileDescriptor_types_d8da2202f45d32c0, []int{21} } func (m *ResponseCheckTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2113,7 +2114,7 @@ func (m *ResponseDeliverTx) Reset() { *m = ResponseDeliverTx{} } func (m *ResponseDeliverTx) String() string { return proto.CompactTextString(m) } func (*ResponseDeliverTx) ProtoMessage() {} func (*ResponseDeliverTx) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{22} + return fileDescriptor_types_d8da2202f45d32c0, []int{22} } func (m *ResponseDeliverTx) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2204,7 +2205,7 @@ func (m *ResponseEndBlock) Reset() { *m = ResponseEndBlock{} } func (m *ResponseEndBlock) String() string { return proto.CompactTextString(m) } func (*ResponseEndBlock) ProtoMessage() {} func (*ResponseEndBlock) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{23} + return fileDescriptor_types_d8da2202f45d32c0, []int{23} } func (m *ResponseEndBlock) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2266,7 +2267,7 @@ func (m *ResponseCommit) Reset() { *m = ResponseCommit{} } func (m *ResponseCommit) String() string { return proto.CompactTextString(m) } func (*ResponseCommit) ProtoMessage() {} func (*ResponseCommit) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{24} + return fileDescriptor_types_d8da2202f45d32c0, []int{24} } func (m *ResponseCommit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2317,7 +2318,7 @@ func (m *ConsensusParams) Reset() { *m = ConsensusParams{} } func (m *ConsensusParams) String() string { return proto.CompactTextString(m) } func (*ConsensusParams) ProtoMessage() {} func (*ConsensusParams) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{25} + return fileDescriptor_types_d8da2202f45d32c0, []int{25} } func (m *ConsensusParams) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2367,7 +2368,7 @@ func (m *ConsensusParams) GetBlockGossip() *BlockGossip { return nil } -// BlockSize contain limits on the block size. +// BlockSize contains limits on the block size. type BlockSize struct { MaxBytes int32 `protobuf:"varint,1,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"` MaxTxs int32 `protobuf:"varint,2,opt,name=max_txs,json=maxTxs,proto3" json:"max_txs,omitempty"` @@ -2381,7 +2382,7 @@ func (m *BlockSize) Reset() { *m = BlockSize{} } func (m *BlockSize) String() string { return proto.CompactTextString(m) } func (*BlockSize) ProtoMessage() {} func (*BlockSize) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{26} + return fileDescriptor_types_d8da2202f45d32c0, []int{26} } func (m *BlockSize) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2431,7 +2432,7 @@ func (m *BlockSize) GetMaxGas() int64 { return 0 } -// TxSize contain limits on the tx size. +// TxSize contains limits on the tx size. type TxSize struct { MaxBytes int32 `protobuf:"varint,1,opt,name=max_bytes,json=maxBytes,proto3" json:"max_bytes,omitempty"` MaxGas int64 `protobuf:"varint,2,opt,name=max_gas,json=maxGas,proto3" json:"max_gas,omitempty"` @@ -2444,7 +2445,7 @@ func (m *TxSize) Reset() { *m = TxSize{} } func (m *TxSize) String() string { return proto.CompactTextString(m) } func (*TxSize) ProtoMessage() {} func (*TxSize) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{27} + return fileDescriptor_types_d8da2202f45d32c0, []int{27} } func (m *TxSize) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2501,7 +2502,7 @@ func (m *BlockGossip) Reset() { *m = BlockGossip{} } func (m *BlockGossip) String() string { return proto.CompactTextString(m) } func (*BlockGossip) ProtoMessage() {} func (*BlockGossip) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{28} + return fileDescriptor_types_d8da2202f45d32c0, []int{28} } func (m *BlockGossip) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2537,6 +2538,61 @@ func (m *BlockGossip) GetBlockPartSizeBytes() int32 { return 0 } +type LastCommitInfo struct { + CommitRound int32 `protobuf:"varint,1,opt,name=commit_round,json=commitRound,proto3" json:"commit_round,omitempty"` + Validators []SigningValidator `protobuf:"bytes,2,rep,name=validators" json:"validators"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LastCommitInfo) Reset() { *m = LastCommitInfo{} } +func (m *LastCommitInfo) String() string { return proto.CompactTextString(m) } +func (*LastCommitInfo) ProtoMessage() {} +func (*LastCommitInfo) Descriptor() ([]byte, []int) { + return fileDescriptor_types_d8da2202f45d32c0, []int{29} +} +func (m *LastCommitInfo) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LastCommitInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LastCommitInfo.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalTo(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (dst *LastCommitInfo) XXX_Merge(src proto.Message) { + xxx_messageInfo_LastCommitInfo.Merge(dst, src) +} +func (m *LastCommitInfo) XXX_Size() int { + return m.Size() +} +func (m *LastCommitInfo) XXX_DiscardUnknown() { + xxx_messageInfo_LastCommitInfo.DiscardUnknown(m) +} + +var xxx_messageInfo_LastCommitInfo proto.InternalMessageInfo + +func (m *LastCommitInfo) GetCommitRound() int32 { + if m != nil { + return m.CommitRound + } + return 0 +} + +func (m *LastCommitInfo) GetValidators() []SigningValidator { + if m != nil { + return m.Validators + } + return nil +} + // just the minimum the app might need type Header struct { // basics @@ -2561,7 +2617,7 @@ func (m *Header) Reset() { *m = Header{} } func (m *Header) String() string { return proto.CompactTextString(m) } func (*Header) ProtoMessage() {} func (*Header) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{29} + return fileDescriptor_types_d8da2202f45d32c0, []int{30} } func (m *Header) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2667,7 +2723,7 @@ func (m *Validator) Reset() { *m = Validator{} } func (m *Validator) String() string { return proto.CompactTextString(m) } func (*Validator) ProtoMessage() {} func (*Validator) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{30} + return fileDescriptor_types_d8da2202f45d32c0, []int{31} } func (m *Validator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2730,7 +2786,7 @@ func (m *SigningValidator) Reset() { *m = SigningValidator{} } func (m *SigningValidator) String() string { return proto.CompactTextString(m) } func (*SigningValidator) ProtoMessage() {} func (*SigningValidator) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{31} + return fileDescriptor_types_d8da2202f45d32c0, []int{32} } func (m *SigningValidator) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2785,7 +2841,7 @@ func (m *PubKey) Reset() { *m = PubKey{} } func (m *PubKey) String() string { return proto.CompactTextString(m) } func (*PubKey) ProtoMessage() {} func (*PubKey) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{32} + return fileDescriptor_types_d8da2202f45d32c0, []int{33} } func (m *PubKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2843,7 +2899,7 @@ func (m *Evidence) Reset() { *m = Evidence{} } func (m *Evidence) String() string { return proto.CompactTextString(m) } func (*Evidence) ProtoMessage() {} func (*Evidence) Descriptor() ([]byte, []int) { - return fileDescriptor_types_2c69c6b96b429b1c, []int{33} + return fileDescriptor_types_d8da2202f45d32c0, []int{34} } func (m *Evidence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2966,6 +3022,8 @@ func init() { golang_proto.RegisterType((*TxSize)(nil), "types.TxSize") proto.RegisterType((*BlockGossip)(nil), "types.BlockGossip") golang_proto.RegisterType((*BlockGossip)(nil), "types.BlockGossip") + proto.RegisterType((*LastCommitInfo)(nil), "types.LastCommitInfo") + golang_proto.RegisterType((*LastCommitInfo)(nil), "types.LastCommitInfo") proto.RegisterType((*Header)(nil), "types.Header") golang_proto.RegisterType((*Header)(nil), "types.Header") proto.RegisterType((*Validator)(nil), "types.Validator") @@ -3487,14 +3545,9 @@ func (this *RequestBeginBlock) Equal(that interface{}) bool { if !this.Header.Equal(&that1.Header) { return false } - if len(this.Validators) != len(that1.Validators) { + if !this.LastCommitInfo.Equal(&that1.LastCommitInfo) { return false } - for i := range this.Validators { - if !this.Validators[i].Equal(&that1.Validators[i]) { - return false - } - } if len(this.ByzantineValidators) != len(that1.ByzantineValidators) { return false } @@ -4489,6 +4542,41 @@ func (this *BlockGossip) Equal(that interface{}) bool { } return true } +func (this *LastCommitInfo) Equal(that interface{}) bool { + if that == nil { + return this == nil + } + + that1, ok := that.(*LastCommitInfo) + if !ok { + that2, ok := that.(LastCommitInfo) + if ok { + that1 = &that2 + } else { + return false + } + } + if that1 == nil { + return this == nil + } else if this == nil { + return false + } + if this.CommitRound != that1.CommitRound { + return false + } + if len(this.Validators) != len(that1.Validators) { + return false + } + for i := range this.Validators { + if !this.Validators[i].Equal(&that1.Validators[i]) { + return false + } + } + if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) { + return false + } + return true +} func (this *Header) Equal(that interface{}) bool { if that == nil { return this == nil @@ -5507,18 +5595,14 @@ func (m *RequestBeginBlock) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n15 - if len(m.Validators) > 0 { - for _, msg := range m.Validators { - dAtA[i] = 0x1a - i++ - i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) - n, err := msg.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n - } + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.LastCommitInfo.Size())) + n16, err := m.LastCommitInfo.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err } + i += n16 if len(m.ByzantineValidators) > 0 { for _, msg := range m.ByzantineValidators { dAtA[i] = 0x22 @@ -5654,11 +5738,11 @@ func (m *Response) MarshalTo(dAtA []byte) (int, error) { var l int _ = l if m.Value != nil { - nn16, err := m.Value.MarshalTo(dAtA[i:]) + nn17, err := m.Value.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += nn16 + i += nn17 } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) @@ -5672,11 +5756,11 @@ func (m *Response_Exception) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Exception.Size())) - n17, err := m.Exception.MarshalTo(dAtA[i:]) + n18, err := m.Exception.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n17 + i += n18 } return i, nil } @@ -5686,11 +5770,11 @@ func (m *Response_Echo) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Echo.Size())) - n18, err := m.Echo.MarshalTo(dAtA[i:]) + n19, err := m.Echo.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n18 + i += n19 } return i, nil } @@ -5700,11 +5784,11 @@ func (m *Response_Flush) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Flush.Size())) - n19, err := m.Flush.MarshalTo(dAtA[i:]) + n20, err := m.Flush.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n19 + i += n20 } return i, nil } @@ -5714,11 +5798,11 @@ func (m *Response_Info) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Info.Size())) - n20, err := m.Info.MarshalTo(dAtA[i:]) + n21, err := m.Info.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n20 + i += n21 } return i, nil } @@ -5728,11 +5812,11 @@ func (m *Response_SetOption) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x2a i++ i = encodeVarintTypes(dAtA, i, uint64(m.SetOption.Size())) - n21, err := m.SetOption.MarshalTo(dAtA[i:]) + n22, err := m.SetOption.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n21 + i += n22 } return i, nil } @@ -5742,11 +5826,11 @@ func (m *Response_InitChain) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x32 i++ i = encodeVarintTypes(dAtA, i, uint64(m.InitChain.Size())) - n22, err := m.InitChain.MarshalTo(dAtA[i:]) + n23, err := m.InitChain.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n22 + i += n23 } return i, nil } @@ -5756,11 +5840,11 @@ func (m *Response_Query) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x3a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Query.Size())) - n23, err := m.Query.MarshalTo(dAtA[i:]) + n24, err := m.Query.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n23 + i += n24 } return i, nil } @@ -5770,11 +5854,11 @@ func (m *Response_BeginBlock) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x42 i++ i = encodeVarintTypes(dAtA, i, uint64(m.BeginBlock.Size())) - n24, err := m.BeginBlock.MarshalTo(dAtA[i:]) + n25, err := m.BeginBlock.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n24 + i += n25 } return i, nil } @@ -5784,11 +5868,11 @@ func (m *Response_CheckTx) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x4a i++ i = encodeVarintTypes(dAtA, i, uint64(m.CheckTx.Size())) - n25, err := m.CheckTx.MarshalTo(dAtA[i:]) + n26, err := m.CheckTx.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n25 + i += n26 } return i, nil } @@ -5798,11 +5882,11 @@ func (m *Response_DeliverTx) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x52 i++ i = encodeVarintTypes(dAtA, i, uint64(m.DeliverTx.Size())) - n26, err := m.DeliverTx.MarshalTo(dAtA[i:]) + n27, err := m.DeliverTx.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n26 + i += n27 } return i, nil } @@ -5812,11 +5896,11 @@ func (m *Response_EndBlock) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x5a i++ i = encodeVarintTypes(dAtA, i, uint64(m.EndBlock.Size())) - n27, err := m.EndBlock.MarshalTo(dAtA[i:]) + n28, err := m.EndBlock.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n27 + i += n28 } return i, nil } @@ -5826,11 +5910,11 @@ func (m *Response_Commit) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x62 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Commit.Size())) - n28, err := m.Commit.MarshalTo(dAtA[i:]) + n29, err := m.Commit.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n28 + i += n29 } return i, nil } @@ -6010,11 +6094,11 @@ func (m *ResponseInitChain) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.ConsensusParams.Size())) - n29, err := m.ConsensusParams.MarshalTo(dAtA[i:]) + n30, err := m.ConsensusParams.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n29 + i += n30 } if len(m.Validators) > 0 { for _, msg := range m.Validators { @@ -6296,11 +6380,11 @@ func (m *ResponseEndBlock) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.ConsensusParamUpdates.Size())) - n30, err := m.ConsensusParamUpdates.MarshalTo(dAtA[i:]) + n31, err := m.ConsensusParamUpdates.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n30 + i += n31 } if len(m.Tags) > 0 { for _, msg := range m.Tags { @@ -6366,32 +6450,32 @@ func (m *ConsensusParams) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.BlockSize.Size())) - n31, err := m.BlockSize.MarshalTo(dAtA[i:]) - if err != nil { - return 0, err - } - i += n31 - } - if m.TxSize != nil { - dAtA[i] = 0x12 - i++ - i = encodeVarintTypes(dAtA, i, uint64(m.TxSize.Size())) - n32, err := m.TxSize.MarshalTo(dAtA[i:]) + n32, err := m.BlockSize.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n32 } - if m.BlockGossip != nil { - dAtA[i] = 0x1a + if m.TxSize != nil { + dAtA[i] = 0x12 i++ - i = encodeVarintTypes(dAtA, i, uint64(m.BlockGossip.Size())) - n33, err := m.BlockGossip.MarshalTo(dAtA[i:]) + i = encodeVarintTypes(dAtA, i, uint64(m.TxSize.Size())) + n33, err := m.TxSize.MarshalTo(dAtA[i:]) if err != nil { return 0, err } i += n33 } + if m.BlockGossip != nil { + dAtA[i] = 0x1a + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.BlockGossip.Size())) + n34, err := m.BlockGossip.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n34 + } if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -6491,6 +6575,44 @@ func (m *BlockGossip) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *LastCommitInfo) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LastCommitInfo) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.CommitRound != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintTypes(dAtA, i, uint64(m.CommitRound)) + } + if len(m.Validators) > 0 { + for _, msg := range m.Validators { + dAtA[i] = 0x12 + i++ + i = encodeVarintTypes(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + if m.XXX_unrecognized != nil { + i += copy(dAtA[i:], m.XXX_unrecognized) + } + return i, nil +} + func (m *Header) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -6520,11 +6642,11 @@ func (m *Header) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x1a i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Time))) - n34, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) + n35, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) if err != nil { return 0, err } - i += n34 + i += n35 if m.NumTxs != 0 { dAtA[i] = 0x20 i++ @@ -6556,11 +6678,11 @@ func (m *Header) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x4a i++ i = encodeVarintTypes(dAtA, i, uint64(m.Proposer.Size())) - n35, err := m.Proposer.MarshalTo(dAtA[i:]) + n36, err := m.Proposer.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n35 + i += n36 if m.XXX_unrecognized != nil { i += copy(dAtA[i:], m.XXX_unrecognized) } @@ -6591,11 +6713,11 @@ func (m *Validator) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.PubKey.Size())) - n36, err := m.PubKey.MarshalTo(dAtA[i:]) + n37, err := m.PubKey.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n36 + i += n37 if m.Power != 0 { dAtA[i] = 0x18 i++ @@ -6625,11 +6747,11 @@ func (m *SigningValidator) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0xa i++ i = encodeVarintTypes(dAtA, i, uint64(m.Validator.Size())) - n37, err := m.Validator.MarshalTo(dAtA[i:]) + n38, err := m.Validator.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n37 + i += n38 if m.SignedLastBlock { dAtA[i] = 0x10 i++ @@ -6703,11 +6825,11 @@ func (m *Evidence) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x12 i++ i = encodeVarintTypes(dAtA, i, uint64(m.Validator.Size())) - n38, err := m.Validator.MarshalTo(dAtA[i:]) + n39, err := m.Validator.MarshalTo(dAtA[i:]) if err != nil { return 0, err } - i += n38 + i += n39 if m.Height != 0 { dAtA[i] = 0x18 i++ @@ -6716,11 +6838,11 @@ func (m *Evidence) MarshalTo(dAtA []byte) (int, error) { dAtA[i] = 0x22 i++ i = encodeVarintTypes(dAtA, i, uint64(github_com_gogo_protobuf_types.SizeOfStdTime(m.Time))) - n39, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) + n40, err := github_com_gogo_protobuf_types.StdTimeMarshalTo(m.Time, dAtA[i:]) if err != nil { return 0, err } - i += n39 + i += n40 if m.TotalVotingPower != 0 { dAtA[i] = 0x28 i++ @@ -6920,20 +7042,14 @@ func NewPopulatedRequestBeginBlock(r randyTypes, easy bool) *RequestBeginBlock { } v7 := NewPopulatedHeader(r, easy) this.Header = *v7 + v8 := NewPopulatedLastCommitInfo(r, easy) + this.LastCommitInfo = *v8 if r.Intn(10) != 0 { - v8 := r.Intn(5) - this.Validators = make([]SigningValidator, v8) - for i := 0; i < v8; i++ { - v9 := NewPopulatedSigningValidator(r, easy) - this.Validators[i] = *v9 - } - } - if r.Intn(10) != 0 { - v10 := r.Intn(5) - this.ByzantineValidators = make([]Evidence, v10) - for i := 0; i < v10; i++ { - v11 := NewPopulatedEvidence(r, easy) - this.ByzantineValidators[i] = *v11 + v9 := r.Intn(5) + this.ByzantineValidators = make([]Evidence, v9) + for i := 0; i < v9; i++ { + v10 := NewPopulatedEvidence(r, easy) + this.ByzantineValidators[i] = *v10 } } if !easy && r.Intn(10) != 0 { @@ -6944,9 +7060,9 @@ func NewPopulatedRequestBeginBlock(r randyTypes, easy bool) *RequestBeginBlock { func NewPopulatedRequestCheckTx(r randyTypes, easy bool) *RequestCheckTx { this := &RequestCheckTx{} - v12 := r.Intn(100) - this.Tx = make([]byte, v12) - for i := 0; i < v12; i++ { + v11 := r.Intn(100) + this.Tx = make([]byte, v11) + for i := 0; i < v11; i++ { this.Tx[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -6957,9 +7073,9 @@ func NewPopulatedRequestCheckTx(r randyTypes, easy bool) *RequestCheckTx { func NewPopulatedRequestDeliverTx(r randyTypes, easy bool) *RequestDeliverTx { this := &RequestDeliverTx{} - v13 := r.Intn(100) - this.Tx = make([]byte, v13) - for i := 0; i < v13; i++ { + v12 := r.Intn(100) + this.Tx = make([]byte, v12) + for i := 0; i < v12; i++ { this.Tx[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -7117,9 +7233,9 @@ func NewPopulatedResponseInfo(r randyTypes, easy bool) *ResponseInfo { if r.Intn(2) == 0 { this.LastBlockHeight *= -1 } - v14 := r.Intn(100) - this.LastBlockAppHash = make([]byte, v14) - for i := 0; i < v14; i++ { + v13 := r.Intn(100) + this.LastBlockAppHash = make([]byte, v13) + for i := 0; i < v13; i++ { this.LastBlockAppHash[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -7145,11 +7261,11 @@ func NewPopulatedResponseInitChain(r randyTypes, easy bool) *ResponseInitChain { this.ConsensusParams = NewPopulatedConsensusParams(r, easy) } if r.Intn(10) != 0 { - v15 := r.Intn(5) - this.Validators = make([]Validator, v15) - for i := 0; i < v15; i++ { - v16 := NewPopulatedValidator(r, easy) - this.Validators[i] = *v16 + v14 := r.Intn(5) + this.Validators = make([]Validator, v14) + for i := 0; i < v14; i++ { + v15 := NewPopulatedValidator(r, easy) + this.Validators[i] = *v15 } } if !easy && r.Intn(10) != 0 { @@ -7167,19 +7283,19 @@ func NewPopulatedResponseQuery(r randyTypes, easy bool) *ResponseQuery { if r.Intn(2) == 0 { this.Index *= -1 } - v17 := r.Intn(100) - this.Key = make([]byte, v17) - for i := 0; i < v17; i++ { + v16 := r.Intn(100) + this.Key = make([]byte, v16) + for i := 0; i < v16; i++ { this.Key[i] = byte(r.Intn(256)) } - v18 := r.Intn(100) - this.Value = make([]byte, v18) - for i := 0; i < v18; i++ { + v17 := r.Intn(100) + this.Value = make([]byte, v17) + for i := 0; i < v17; i++ { this.Value[i] = byte(r.Intn(256)) } - v19 := r.Intn(100) - this.Proof = make([]byte, v19) - for i := 0; i < v19; i++ { + v18 := r.Intn(100) + this.Proof = make([]byte, v18) + for i := 0; i < v18; i++ { this.Proof[i] = byte(r.Intn(256)) } this.Height = int64(r.Int63()) @@ -7195,11 +7311,11 @@ func NewPopulatedResponseQuery(r randyTypes, easy bool) *ResponseQuery { func NewPopulatedResponseBeginBlock(r randyTypes, easy bool) *ResponseBeginBlock { this := &ResponseBeginBlock{} if r.Intn(10) != 0 { - v20 := r.Intn(5) - this.Tags = make([]common.KVPair, v20) - for i := 0; i < v20; i++ { - v21 := common.NewPopulatedKVPair(r, easy) - this.Tags[i] = *v21 + v19 := r.Intn(5) + this.Tags = make([]common.KVPair, v19) + for i := 0; i < v19; i++ { + v20 := common.NewPopulatedKVPair(r, easy) + this.Tags[i] = *v20 } } if !easy && r.Intn(10) != 0 { @@ -7211,9 +7327,9 @@ func NewPopulatedResponseBeginBlock(r randyTypes, easy bool) *ResponseBeginBlock func NewPopulatedResponseCheckTx(r randyTypes, easy bool) *ResponseCheckTx { this := &ResponseCheckTx{} this.Code = uint32(r.Uint32()) - v22 := r.Intn(100) - this.Data = make([]byte, v22) - for i := 0; i < v22; i++ { + v21 := r.Intn(100) + this.Data = make([]byte, v21) + for i := 0; i < v21; i++ { this.Data[i] = byte(r.Intn(256)) } this.Log = string(randStringTypes(r)) @@ -7227,11 +7343,11 @@ func NewPopulatedResponseCheckTx(r randyTypes, easy bool) *ResponseCheckTx { this.GasUsed *= -1 } if r.Intn(10) != 0 { - v23 := r.Intn(5) - this.Tags = make([]common.KVPair, v23) - for i := 0; i < v23; i++ { - v24 := common.NewPopulatedKVPair(r, easy) - this.Tags[i] = *v24 + v22 := r.Intn(5) + this.Tags = make([]common.KVPair, v22) + for i := 0; i < v22; i++ { + v23 := common.NewPopulatedKVPair(r, easy) + this.Tags[i] = *v23 } } if !easy && r.Intn(10) != 0 { @@ -7243,9 +7359,9 @@ func NewPopulatedResponseCheckTx(r randyTypes, easy bool) *ResponseCheckTx { func NewPopulatedResponseDeliverTx(r randyTypes, easy bool) *ResponseDeliverTx { this := &ResponseDeliverTx{} this.Code = uint32(r.Uint32()) - v25 := r.Intn(100) - this.Data = make([]byte, v25) - for i := 0; i < v25; i++ { + v24 := r.Intn(100) + this.Data = make([]byte, v24) + for i := 0; i < v24; i++ { this.Data[i] = byte(r.Intn(256)) } this.Log = string(randStringTypes(r)) @@ -7259,11 +7375,11 @@ func NewPopulatedResponseDeliverTx(r randyTypes, easy bool) *ResponseDeliverTx { this.GasUsed *= -1 } if r.Intn(10) != 0 { - v26 := r.Intn(5) - this.Tags = make([]common.KVPair, v26) - for i := 0; i < v26; i++ { - v27 := common.NewPopulatedKVPair(r, easy) - this.Tags[i] = *v27 + v25 := r.Intn(5) + this.Tags = make([]common.KVPair, v25) + for i := 0; i < v25; i++ { + v26 := common.NewPopulatedKVPair(r, easy) + this.Tags[i] = *v26 } } if !easy && r.Intn(10) != 0 { @@ -7275,22 +7391,22 @@ func NewPopulatedResponseDeliverTx(r randyTypes, easy bool) *ResponseDeliverTx { func NewPopulatedResponseEndBlock(r randyTypes, easy bool) *ResponseEndBlock { this := &ResponseEndBlock{} if r.Intn(10) != 0 { - v28 := r.Intn(5) - this.ValidatorUpdates = make([]Validator, v28) - for i := 0; i < v28; i++ { - v29 := NewPopulatedValidator(r, easy) - this.ValidatorUpdates[i] = *v29 + v27 := r.Intn(5) + this.ValidatorUpdates = make([]Validator, v27) + for i := 0; i < v27; i++ { + v28 := NewPopulatedValidator(r, easy) + this.ValidatorUpdates[i] = *v28 } } if r.Intn(10) != 0 { this.ConsensusParamUpdates = NewPopulatedConsensusParams(r, easy) } if r.Intn(10) != 0 { - v30 := r.Intn(5) - this.Tags = make([]common.KVPair, v30) - for i := 0; i < v30; i++ { - v31 := common.NewPopulatedKVPair(r, easy) - this.Tags[i] = *v31 + v29 := r.Intn(5) + this.Tags = make([]common.KVPair, v29) + for i := 0; i < v29; i++ { + v30 := common.NewPopulatedKVPair(r, easy) + this.Tags[i] = *v30 } } if !easy && r.Intn(10) != 0 { @@ -7301,9 +7417,9 @@ func NewPopulatedResponseEndBlock(r randyTypes, easy bool) *ResponseEndBlock { func NewPopulatedResponseCommit(r randyTypes, easy bool) *ResponseCommit { this := &ResponseCommit{} - v32 := r.Intn(100) - this.Data = make([]byte, v32) - for i := 0; i < v32; i++ { + v31 := r.Intn(100) + this.Data = make([]byte, v31) + for i := 0; i < v31; i++ { this.Data[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -7377,6 +7493,26 @@ func NewPopulatedBlockGossip(r randyTypes, easy bool) *BlockGossip { return this } +func NewPopulatedLastCommitInfo(r randyTypes, easy bool) *LastCommitInfo { + this := &LastCommitInfo{} + this.CommitRound = int32(r.Int31()) + if r.Intn(2) == 0 { + this.CommitRound *= -1 + } + if r.Intn(10) != 0 { + v32 := r.Intn(5) + this.Validators = make([]SigningValidator, v32) + for i := 0; i < v32; i++ { + v33 := NewPopulatedSigningValidator(r, easy) + this.Validators[i] = *v33 + } + } + if !easy && r.Intn(10) != 0 { + this.XXX_unrecognized = randUnrecognizedTypes(r, 3) + } + return this +} + func NewPopulatedHeader(r randyTypes, easy bool) *Header { this := &Header{} this.ChainID = string(randStringTypes(r)) @@ -7384,8 +7520,8 @@ func NewPopulatedHeader(r randyTypes, easy bool) *Header { if r.Intn(2) == 0 { this.Height *= -1 } - v33 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy) - this.Time = *v33 + v34 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy) + this.Time = *v34 this.NumTxs = int32(r.Int31()) if r.Intn(2) == 0 { this.NumTxs *= -1 @@ -7394,23 +7530,23 @@ func NewPopulatedHeader(r randyTypes, easy bool) *Header { if r.Intn(2) == 0 { this.TotalTxs *= -1 } - v34 := r.Intn(100) - this.LastBlockHash = make([]byte, v34) - for i := 0; i < v34; i++ { + v35 := r.Intn(100) + this.LastBlockHash = make([]byte, v35) + for i := 0; i < v35; i++ { this.LastBlockHash[i] = byte(r.Intn(256)) } - v35 := r.Intn(100) - this.ValidatorsHash = make([]byte, v35) - for i := 0; i < v35; i++ { + v36 := r.Intn(100) + this.ValidatorsHash = make([]byte, v36) + for i := 0; i < v36; i++ { this.ValidatorsHash[i] = byte(r.Intn(256)) } - v36 := r.Intn(100) - this.AppHash = make([]byte, v36) - for i := 0; i < v36; i++ { + v37 := r.Intn(100) + this.AppHash = make([]byte, v37) + for i := 0; i < v37; i++ { this.AppHash[i] = byte(r.Intn(256)) } - v37 := NewPopulatedValidator(r, easy) - this.Proposer = *v37 + v38 := NewPopulatedValidator(r, easy) + this.Proposer = *v38 if !easy && r.Intn(10) != 0 { this.XXX_unrecognized = randUnrecognizedTypes(r, 10) } @@ -7419,13 +7555,13 @@ func NewPopulatedHeader(r randyTypes, easy bool) *Header { func NewPopulatedValidator(r randyTypes, easy bool) *Validator { this := &Validator{} - v38 := r.Intn(100) - this.Address = make([]byte, v38) - for i := 0; i < v38; i++ { + v39 := r.Intn(100) + this.Address = make([]byte, v39) + for i := 0; i < v39; i++ { this.Address[i] = byte(r.Intn(256)) } - v39 := NewPopulatedPubKey(r, easy) - this.PubKey = *v39 + v40 := NewPopulatedPubKey(r, easy) + this.PubKey = *v40 this.Power = int64(r.Int63()) if r.Intn(2) == 0 { this.Power *= -1 @@ -7438,8 +7574,8 @@ func NewPopulatedValidator(r randyTypes, easy bool) *Validator { func NewPopulatedSigningValidator(r randyTypes, easy bool) *SigningValidator { this := &SigningValidator{} - v40 := NewPopulatedValidator(r, easy) - this.Validator = *v40 + v41 := NewPopulatedValidator(r, easy) + this.Validator = *v41 this.SignedLastBlock = bool(bool(r.Intn(2) == 0)) if !easy && r.Intn(10) != 0 { this.XXX_unrecognized = randUnrecognizedTypes(r, 3) @@ -7450,9 +7586,9 @@ func NewPopulatedSigningValidator(r randyTypes, easy bool) *SigningValidator { func NewPopulatedPubKey(r randyTypes, easy bool) *PubKey { this := &PubKey{} this.Type = string(randStringTypes(r)) - v41 := r.Intn(100) - this.Data = make([]byte, v41) - for i := 0; i < v41; i++ { + v42 := r.Intn(100) + this.Data = make([]byte, v42) + for i := 0; i < v42; i++ { this.Data[i] = byte(r.Intn(256)) } if !easy && r.Intn(10) != 0 { @@ -7464,14 +7600,14 @@ func NewPopulatedPubKey(r randyTypes, easy bool) *PubKey { func NewPopulatedEvidence(r randyTypes, easy bool) *Evidence { this := &Evidence{} this.Type = string(randStringTypes(r)) - v42 := NewPopulatedValidator(r, easy) - this.Validator = *v42 + v43 := NewPopulatedValidator(r, easy) + this.Validator = *v43 this.Height = int64(r.Int63()) if r.Intn(2) == 0 { this.Height *= -1 } - v43 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy) - this.Time = *v43 + v44 := github_com_gogo_protobuf_types.NewPopulatedStdTime(r, easy) + this.Time = *v44 this.TotalVotingPower = int64(r.Int63()) if r.Intn(2) == 0 { this.TotalVotingPower *= -1 @@ -7501,9 +7637,9 @@ func randUTF8RuneTypes(r randyTypes) rune { return rune(ru + 61) } func randStringTypes(r randyTypes) string { - v44 := r.Intn(100) - tmps := make([]rune, v44) - for i := 0; i < v44; i++ { + v45 := r.Intn(100) + tmps := make([]rune, v45) + for i := 0; i < v45; i++ { tmps[i] = randUTF8RuneTypes(r) } return string(tmps) @@ -7525,11 +7661,11 @@ func randFieldTypes(dAtA []byte, r randyTypes, fieldNumber int, wire int) []byte switch wire { case 0: dAtA = encodeVarintPopulateTypes(dAtA, uint64(key)) - v45 := r.Int63() + v46 := r.Int63() if r.Intn(2) == 0 { - v45 *= -1 + v46 *= -1 } - dAtA = encodeVarintPopulateTypes(dAtA, uint64(v45)) + dAtA = encodeVarintPopulateTypes(dAtA, uint64(v46)) case 1: dAtA = encodeVarintPopulateTypes(dAtA, uint64(key)) dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256))) @@ -7778,12 +7914,8 @@ func (m *RequestBeginBlock) Size() (n int) { } l = m.Header.Size() n += 1 + l + sovTypes(uint64(l)) - if len(m.Validators) > 0 { - for _, e := range m.Validators { - l = e.Size() - n += 1 + l + sovTypes(uint64(l)) - } - } + l = m.LastCommitInfo.Size() + n += 1 + l + sovTypes(uint64(l)) if len(m.ByzantineValidators) > 0 { for _, e := range m.ByzantineValidators { l = e.Size() @@ -8290,6 +8422,24 @@ func (m *BlockGossip) Size() (n int) { return n } +func (m *LastCommitInfo) Size() (n int) { + var l int + _ = l + if m.CommitRound != 0 { + n += 1 + sovTypes(uint64(m.CommitRound)) + } + if len(m.Validators) > 0 { + for _, e := range m.Validators { + l = e.Size() + n += 1 + l + sovTypes(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *Header) Size() (n int) { var l int _ = l @@ -9583,7 +9733,7 @@ func (m *RequestBeginBlock) Unmarshal(dAtA []byte) error { iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Validators", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field LastCommitInfo", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -9607,8 +9757,7 @@ func (m *RequestBeginBlock) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - m.Validators = append(m.Validators, SigningValidator{}) - if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.LastCommitInfo.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex @@ -12440,6 +12589,107 @@ func (m *BlockGossip) Unmarshal(dAtA []byte) error { } return nil } +func (m *LastCommitInfo) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LastCommitInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LastCommitInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field CommitRound", wireType) + } + m.CommitRound = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.CommitRound |= (int32(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Validators", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTypes + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTypes + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Validators = append(m.Validators, SigningValidator{}) + if err := m.Validators[len(m.Validators)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipTypes(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthTypes + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *Header) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 @@ -13356,131 +13606,134 @@ var ( ErrIntOverflowTypes = fmt.Errorf("proto: integer overflow") ) -func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_2c69c6b96b429b1c) } +func init() { proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_d8da2202f45d32c0) } func init() { - golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_2c69c6b96b429b1c) + golang_proto.RegisterFile("abci/types/types.proto", fileDescriptor_types_d8da2202f45d32c0) } -var fileDescriptor_types_2c69c6b96b429b1c = []byte{ - // 1911 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x4b, 0x73, 0x24, 0x47, - 0x11, 0x56, 0xcf, 0xbb, 0x73, 0x24, 0x8d, 0xb6, 0xb4, 0x2b, 0xcd, 0x8e, 0x41, 0xda, 0xe8, 0x20, - 0xd6, 0x5a, 0x2c, 0x8f, 0x40, 0x66, 0x1d, 0x5a, 0x1b, 0x1c, 0x68, 0xe4, 0xc5, 0xa3, 0x30, 0x0f, - 0xd1, 0xbb, 0x5e, 0x22, 0xb8, 0x4c, 0xd4, 0x4c, 0x97, 0x7a, 0x3a, 0x76, 0xfa, 0xe1, 0xae, 0x1a, - 0x79, 0xb4, 0x3f, 0x81, 0x70, 0x10, 0xdc, 0x38, 0x73, 0xe3, 0x0f, 0x10, 0xc1, 0x91, 0x13, 0xe1, - 0x23, 0x07, 0x08, 0xb8, 0xb0, 0x80, 0x7c, 0xe3, 0x17, 0x70, 0x24, 0xb2, 0xaa, 0xdf, 0xea, 0xd9, - 0x90, 0x97, 0x1b, 0x17, 0xa9, 0xb2, 0x33, 0xb3, 0xaa, 0x32, 0x27, 0xf3, 0xcb, 0xcc, 0x82, 0x2d, - 0x3a, 0x9e, 0x38, 0x07, 0xe2, 0x32, 0x60, 0x5c, 0xfd, 0xed, 0x07, 0xa1, 0x2f, 0x7c, 0x52, 0x97, - 0x44, 0xef, 0x6d, 0xdb, 0x11, 0xd3, 0xf9, 0xb8, 0x3f, 0xf1, 0xdd, 0x03, 0xdb, 0xb7, 0xfd, 0x03, - 0xc9, 0x1d, 0xcf, 0xcf, 0x25, 0x25, 0x09, 0xb9, 0x52, 0x5a, 0xbd, 0x5d, 0xdb, 0xf7, 0xed, 0x19, - 0x4b, 0xa5, 0x84, 0xe3, 0x32, 0x2e, 0xa8, 0x1b, 0x44, 0x02, 0x47, 0x99, 0xfd, 0x04, 0xf3, 0x2c, - 0x16, 0xba, 0x8e, 0x27, 0xb2, 0xcb, 0x99, 0x33, 0xe6, 0x07, 0x13, 0xdf, 0x75, 0x7d, 0x2f, 0x7b, - 0x21, 0xe3, 0x8f, 0x35, 0x68, 0x9a, 0xec, 0xd3, 0x39, 0xe3, 0x82, 0xec, 0x41, 0x8d, 0x4d, 0xa6, - 0x7e, 0xb7, 0x72, 0x4f, 0xdb, 0x6b, 0x1f, 0x92, 0xbe, 0x92, 0x8b, 0xb8, 0x8f, 0x27, 0x53, 0x7f, - 0xb8, 0x62, 0x4a, 0x09, 0xf2, 0x16, 0xd4, 0xcf, 0x67, 0x73, 0x3e, 0xed, 0x56, 0xa5, 0xe8, 0x66, - 0x5e, 0xf4, 0x07, 0xc8, 0x1a, 0xae, 0x98, 0x4a, 0x06, 0xb7, 0x75, 0xbc, 0x73, 0xbf, 0x5b, 0x2b, - 0xdb, 0xf6, 0xd4, 0x3b, 0x97, 0xdb, 0xa2, 0x04, 0x39, 0x02, 0xe0, 0x4c, 0x8c, 0xfc, 0x40, 0x38, - 0xbe, 0xd7, 0xad, 0x4b, 0xf9, 0xed, 0xbc, 0xfc, 0x13, 0x26, 0x7e, 0x22, 0xd9, 0xc3, 0x15, 0x53, - 0xe7, 0x31, 0x81, 0x9a, 0x8e, 0xe7, 0x88, 0xd1, 0x64, 0x4a, 0x1d, 0xaf, 0xdb, 0x28, 0xd3, 0x3c, - 0xf5, 0x1c, 0x71, 0x82, 0x6c, 0xd4, 0x74, 0x62, 0x02, 0x4d, 0xf9, 0x74, 0xce, 0xc2, 0xcb, 0x6e, - 0xb3, 0xcc, 0x94, 0x9f, 0x22, 0x0b, 0x4d, 0x91, 0x32, 0xe4, 0x7d, 0x68, 0x8f, 0x99, 0xed, 0x78, - 0xa3, 0xf1, 0xcc, 0x9f, 0x3c, 0xef, 0xb6, 0xa4, 0x4a, 0x37, 0xaf, 0x32, 0x40, 0x81, 0x01, 0xf2, - 0x87, 0x2b, 0x26, 0x8c, 0x13, 0x8a, 0x1c, 0x42, 0x6b, 0x32, 0x65, 0x93, 0xe7, 0x23, 0xb1, 0xe8, - 0xea, 0x52, 0xf3, 0x4e, 0x5e, 0xf3, 0x04, 0xb9, 0x4f, 0x17, 0xc3, 0x15, 0xb3, 0x39, 0x51, 0x4b, - 0xf2, 0x10, 0x74, 0xe6, 0x59, 0xd1, 0x71, 0x6d, 0xa9, 0xb4, 0x55, 0xf8, 0x5d, 0x3c, 0x2b, 0x3e, - 0xac, 0xc5, 0xa2, 0x35, 0xe9, 0x43, 0x03, 0x7f, 0x6b, 0x47, 0x74, 0x57, 0xa5, 0xce, 0xed, 0xc2, - 0x41, 0x92, 0x37, 0x5c, 0x31, 0x23, 0x29, 0x74, 0x9f, 0xc5, 0x66, 0xce, 0x05, 0x0b, 0xf1, 0x72, - 0x9b, 0x65, 0xee, 0xfb, 0x50, 0xf1, 0xe5, 0xf5, 0x74, 0x2b, 0x26, 0x06, 0x4d, 0xa8, 0x5f, 0xd0, - 0xd9, 0x9c, 0x19, 0x6f, 0x42, 0x3b, 0x13, 0x29, 0xa4, 0x0b, 0x4d, 0x97, 0x71, 0x4e, 0x6d, 0xd6, - 0xd5, 0xee, 0x69, 0x7b, 0xba, 0x19, 0x93, 0xc6, 0x3a, 0xac, 0x66, 0xe3, 0x24, 0xa3, 0x88, 0xb1, - 0x80, 0x8a, 0x17, 0x2c, 0xe4, 0x18, 0x00, 0x91, 0x62, 0x44, 0x1a, 0xef, 0xc1, 0x46, 0x31, 0x08, - 0xc8, 0x06, 0x54, 0x9f, 0xb3, 0xcb, 0x48, 0x12, 0x97, 0xe4, 0x76, 0x74, 0x21, 0x19, 0xc5, 0xba, - 0x19, 0xdd, 0xee, 0x17, 0x95, 0x44, 0x39, 0x89, 0x03, 0x72, 0x04, 0x35, 0x4c, 0x24, 0xa9, 0xdd, - 0x3e, 0xec, 0xf5, 0x55, 0x96, 0xf5, 0xe3, 0x2c, 0xeb, 0x3f, 0x8d, 0xb3, 0x6c, 0xd0, 0xfa, 0xe2, - 0xe5, 0xee, 0xca, 0xaf, 0xfe, 0xb1, 0xab, 0x99, 0x52, 0x83, 0xdc, 0xc5, 0x9f, 0x92, 0x3a, 0xde, - 0xc8, 0xb1, 0xa2, 0x73, 0x9a, 0x92, 0x3e, 0xb5, 0xc8, 0x31, 0x6c, 0x4c, 0x7c, 0x8f, 0x33, 0x8f, - 0xcf, 0xf9, 0x28, 0xa0, 0x21, 0x75, 0x79, 0x94, 0x25, 0xf1, 0x0f, 0x77, 0x12, 0xb3, 0xcf, 0x24, - 0xd7, 0xec, 0x4c, 0xf2, 0x1f, 0xc8, 0xbb, 0x00, 0x17, 0x74, 0xe6, 0x58, 0x54, 0xf8, 0x21, 0xef, - 0xd6, 0xee, 0x55, 0xf7, 0xda, 0x87, 0x1b, 0x91, 0xf2, 0xb3, 0x98, 0x31, 0xa8, 0xe1, 0x9d, 0xcc, - 0x8c, 0x24, 0xb9, 0x0f, 0x1d, 0x1a, 0x04, 0x23, 0x2e, 0xa8, 0x60, 0xa3, 0xf1, 0xa5, 0x60, 0x5c, - 0xe6, 0xd0, 0xaa, 0xb9, 0x46, 0x83, 0xe0, 0x09, 0x7e, 0x1d, 0xe0, 0x47, 0xc3, 0x4a, 0x7e, 0x01, - 0x19, 0xde, 0x84, 0x40, 0xcd, 0xa2, 0x82, 0x4a, 0x3f, 0xac, 0x9a, 0x72, 0x8d, 0xdf, 0x02, 0x2a, - 0xa6, 0x91, 0x75, 0x72, 0x4d, 0xb6, 0xa0, 0x31, 0x65, 0x8e, 0x3d, 0x15, 0xd2, 0xa0, 0xaa, 0x19, - 0x51, 0xe8, 0xf2, 0x20, 0xf4, 0x2f, 0x98, 0xcc, 0xf0, 0x96, 0xa9, 0x08, 0xe3, 0xef, 0x1a, 0xdc, - 0xba, 0x96, 0x12, 0xb8, 0xef, 0x94, 0xf2, 0x69, 0x7c, 0x16, 0xae, 0xc9, 0x5b, 0xb8, 0x2f, 0xb5, - 0x58, 0x18, 0x21, 0xcf, 0x5a, 0x64, 0xeb, 0x50, 0x7e, 0x8c, 0x0c, 0x8d, 0x44, 0xc8, 0xf7, 0x72, - 0xce, 0xa9, 0x4a, 0xe7, 0xc4, 0xa1, 0xfa, 0xc4, 0xb1, 0x3d, 0xc7, 0xb3, 0x5f, 0xe5, 0xa3, 0x21, - 0xdc, 0x1e, 0x5f, 0xbe, 0xa0, 0x9e, 0x70, 0x3c, 0x36, 0xba, 0xe6, 0xe5, 0x4e, 0xb4, 0xd1, 0xe3, - 0x0b, 0xc7, 0x62, 0xde, 0x84, 0x45, 0x1b, 0x6c, 0x26, 0x2a, 0xc9, 0xd6, 0xdc, 0xb8, 0x07, 0xeb, - 0xf9, 0xbc, 0x25, 0xeb, 0x50, 0x11, 0x8b, 0xc8, 0xb2, 0x8a, 0x58, 0x18, 0x46, 0x12, 0x73, 0x49, - 0xf2, 0x5c, 0x93, 0x79, 0x00, 0x9d, 0x42, 0x22, 0x67, 0xdc, 0xac, 0x65, 0xdd, 0x6c, 0x74, 0x60, - 0x2d, 0x97, 0xbf, 0xc6, 0xe7, 0x75, 0x68, 0x99, 0x8c, 0x07, 0x18, 0x3e, 0xe4, 0x08, 0x74, 0xb6, - 0x98, 0x30, 0x05, 0x9d, 0x5a, 0x01, 0x98, 0x94, 0xcc, 0xe3, 0x98, 0x8f, 0x29, 0x9c, 0x08, 0x93, - 0x07, 0x39, 0xd8, 0xdf, 0x2c, 0x2a, 0x65, 0x71, 0x7f, 0x3f, 0x8f, 0xfb, 0xb7, 0x0b, 0xb2, 0x05, - 0xe0, 0x7f, 0x90, 0x03, 0xfe, 0xe2, 0xc6, 0x39, 0xe4, 0x7f, 0x54, 0x82, 0xfc, 0xc5, 0xeb, 0x2f, - 0x81, 0xfe, 0x47, 0x25, 0xd0, 0xdf, 0xbd, 0x76, 0x56, 0x29, 0xf6, 0xef, 0xe7, 0xb1, 0xbf, 0x68, - 0x4e, 0x01, 0xfc, 0xbf, 0x5b, 0x06, 0xfe, 0x77, 0x0b, 0x3a, 0x4b, 0xd1, 0xff, 0x9d, 0x6b, 0xe8, - 0xbf, 0x55, 0x50, 0x2d, 0x81, 0xff, 0x47, 0x39, 0x5c, 0x86, 0x52, 0xdb, 0xca, 0x81, 0x99, 0xbc, - 0x7b, 0xbd, 0x72, 0x6c, 0x17, 0x7f, 0xda, 0xb2, 0xd2, 0x71, 0x50, 0x28, 0x1d, 0x77, 0x8a, 0xb7, - 0x2c, 0xd4, 0x8e, 0xb4, 0x02, 0x3c, 0xc0, 0x7c, 0x2f, 0x44, 0x1a, 0x62, 0x03, 0x0b, 0x43, 0x3f, - 0x8c, 0x20, 0x5a, 0x11, 0xc6, 0x1e, 0x22, 0x50, 0x1a, 0x5f, 0xaf, 0xa8, 0x16, 0x32, 0xe8, 0x33, - 0xd1, 0x65, 0xfc, 0x5a, 0x4b, 0x75, 0x65, 0xc1, 0xc8, 0xa2, 0x97, 0x1e, 0xa1, 0x57, 0xa6, 0x88, - 0x54, 0x72, 0x45, 0x84, 0x7c, 0x13, 0x6e, 0xcd, 0x28, 0x17, 0xca, 0x2f, 0xa3, 0x1c, 0x9c, 0x75, - 0x90, 0xa1, 0x1c, 0xa2, 0x70, 0xed, 0x6d, 0xd8, 0xcc, 0xc8, 0x22, 0xb4, 0x4a, 0xe8, 0xaa, 0xc9, - 0xe4, 0xdd, 0x48, 0xa4, 0x8f, 0x83, 0x60, 0x48, 0xf9, 0xd4, 0xf8, 0x51, 0x6a, 0x7f, 0x5a, 0xa0, - 0x08, 0xd4, 0x26, 0xbe, 0xa5, 0xcc, 0x5a, 0x33, 0xe5, 0x1a, 0x8b, 0xd6, 0xcc, 0xb7, 0xe5, 0xa9, - 0xba, 0x89, 0x4b, 0x94, 0x4a, 0x32, 0x45, 0x57, 0x29, 0x61, 0xfc, 0x52, 0x4b, 0xf7, 0x4b, 0x6b, - 0x56, 0x59, 0x79, 0xd1, 0xfe, 0x97, 0xf2, 0x52, 0xb9, 0x69, 0x79, 0x31, 0x7e, 0xa7, 0xa5, 0xbf, - 0x45, 0x52, 0x38, 0x5e, 0xcf, 0x38, 0x0c, 0x0b, 0xc7, 0xb3, 0xd8, 0x42, 0xa6, 0x7a, 0xd5, 0x54, - 0x44, 0x5c, 0xcd, 0x1b, 0xd2, 0xc1, 0xf9, 0x6a, 0xde, 0x94, 0xdf, 0x14, 0x11, 0x15, 0x1c, 0xff, - 0x5c, 0xe6, 0xe0, 0xaa, 0xa9, 0x88, 0x0c, 0x6e, 0xea, 0x39, 0xdc, 0x3c, 0x03, 0x72, 0x3d, 0x3b, - 0xc9, 0x7b, 0x50, 0x13, 0xd4, 0x46, 0xe7, 0xa1, 0xfd, 0xeb, 0x7d, 0xd5, 0x1b, 0xf7, 0x3f, 0x7e, - 0x76, 0x46, 0x9d, 0x70, 0xb0, 0x85, 0xd6, 0xff, 0xfb, 0xe5, 0xee, 0x3a, 0xca, 0xec, 0xfb, 0xae, - 0x23, 0x98, 0x1b, 0x88, 0x4b, 0x53, 0xea, 0x18, 0x7f, 0xd1, 0x10, 0xb5, 0x73, 0x59, 0x5b, 0xea, - 0x8b, 0x38, 0x34, 0x2b, 0x99, 0xc2, 0x7a, 0x33, 0xff, 0x7c, 0x1d, 0xc0, 0xa6, 0x7c, 0xf4, 0x19, - 0xf5, 0x04, 0xb3, 0x22, 0x27, 0xe9, 0x36, 0xe5, 0x3f, 0x93, 0x1f, 0xb0, 0xff, 0x40, 0xf6, 0x9c, - 0x33, 0x4b, 0x7a, 0xab, 0x6a, 0x36, 0x6d, 0xca, 0x3f, 0xe1, 0xcc, 0x4a, 0xec, 0x6a, 0xbe, 0x86, - 0x5d, 0x7f, 0xcd, 0x84, 0x5c, 0x5a, 0xb2, 0xfe, 0x1f, 0x2c, 0xfb, 0x52, 0xc3, 0x5a, 0x9c, 0x87, - 0x3d, 0x72, 0x02, 0xb7, 0x92, 0xf0, 0x1e, 0xcd, 0x03, 0x8b, 0x62, 0xc7, 0xa4, 0xbd, 0x32, 0x1f, - 0x36, 0x12, 0x85, 0x4f, 0x94, 0x3c, 0xf9, 0x31, 0x6c, 0x17, 0x12, 0x32, 0xd9, 0xaa, 0xf2, 0xca, - 0xbc, 0xbc, 0x93, 0xcf, 0xcb, 0x78, 0xbf, 0xd8, 0xca, 0xea, 0x6b, 0x58, 0xf9, 0x0d, 0x6c, 0x49, - 0xb2, 0x30, 0x5d, 0xf6, 0x3b, 0x19, 0xbf, 0xd1, 0xa0, 0x53, 0xb8, 0x0c, 0x39, 0x00, 0x50, 0x28, - 0xc7, 0x9d, 0x17, 0x71, 0x43, 0x1c, 0xfb, 0x40, 0x3a, 0xeb, 0x89, 0xf3, 0x82, 0x99, 0xfa, 0x38, - 0x5e, 0x92, 0xfb, 0xd0, 0x14, 0x0b, 0x25, 0x9d, 0x6f, 0xda, 0x9e, 0x2e, 0xa4, 0x68, 0x43, 0xc8, - 0xff, 0xe4, 0x21, 0xac, 0xaa, 0x8d, 0x6d, 0x9f, 0x73, 0x27, 0x88, 0x1a, 0x07, 0x92, 0xdd, 0xfa, - 0x23, 0xc9, 0x31, 0xdb, 0xe3, 0x94, 0x30, 0x7e, 0x0e, 0x7a, 0x72, 0x2c, 0x79, 0x03, 0x74, 0x97, - 0x2e, 0xa2, 0x8e, 0x16, 0xef, 0x56, 0x37, 0x5b, 0x2e, 0x5d, 0xc8, 0x66, 0x96, 0x6c, 0x43, 0x13, - 0x99, 0x62, 0xa1, 0xfc, 0x5d, 0x37, 0x1b, 0x2e, 0x5d, 0x3c, 0x5d, 0x24, 0x0c, 0x9b, 0xf2, 0xb8, - 0x5d, 0x75, 0xe9, 0xe2, 0x23, 0xca, 0x8d, 0x0f, 0xa0, 0xa1, 0x2e, 0x79, 0xa3, 0x8d, 0x51, 0xbf, - 0x92, 0xd3, 0xff, 0x3e, 0xb4, 0x33, 0xf7, 0x26, 0xdf, 0x86, 0x3b, 0xca, 0xc2, 0x80, 0x86, 0x42, - 0x7a, 0x24, 0xb7, 0x21, 0x91, 0xcc, 0x33, 0x1a, 0x0a, 0x3c, 0x52, 0x35, 0xe0, 0x7f, 0xab, 0x40, - 0x43, 0x35, 0xb7, 0xe4, 0x7e, 0x66, 0x92, 0x90, 0x15, 0x6c, 0xd0, 0xbe, 0x7a, 0xb9, 0xdb, 0x94, - 0x60, 0x7f, 0xfa, 0x61, 0x3a, 0x56, 0xa4, 0xe0, 0x56, 0xc9, 0xf5, 0xde, 0xf1, 0x0c, 0x53, 0xfd, - 0xca, 0x33, 0xcc, 0x36, 0x34, 0xbd, 0xb9, 0x2b, 0x1d, 0x57, 0x53, 0x8e, 0xf3, 0xe6, 0x2e, 0x3a, - 0xee, 0x0d, 0xd0, 0x85, 0x2f, 0xe8, 0x4c, 0xb2, 0x54, 0x82, 0xb6, 0xe4, 0x07, 0x64, 0xde, 0x87, - 0x4e, 0xb6, 0x7e, 0x62, 0x3d, 0x54, 0x70, 0xbd, 0x96, 0x56, 0x4f, 0xec, 0xe9, 0xdf, 0x84, 0x4e, - 0x5a, 0x3a, 0x94, 0x9c, 0x82, 0xf0, 0xf5, 0xf4, 0xb3, 0x14, 0xbc, 0x0b, 0xad, 0xa4, 0xb2, 0x2a, - 0x38, 0x6f, 0x52, 0x55, 0x50, 0x71, 0x60, 0x0e, 0x42, 0x3f, 0xf0, 0x39, 0x0b, 0xa3, 0x96, 0x69, - 0x59, 0x5a, 0x26, 0x72, 0x86, 0x03, 0x7a, 0xc2, 0xc4, 0x36, 0x80, 0x5a, 0x56, 0xc8, 0x38, 0x8f, - 0x3a, 0xee, 0x98, 0x24, 0xfb, 0xd0, 0x0c, 0xe6, 0xe3, 0x11, 0x56, 0x9b, 0x7c, 0xf8, 0x9e, 0xcd, - 0xc7, 0x1f, 0xb3, 0xcb, 0x78, 0xe6, 0x08, 0x24, 0x25, 0xeb, 0x8d, 0xff, 0x19, 0x0b, 0xa3, 0x40, - 0x52, 0x84, 0x21, 0x60, 0xa3, 0x38, 0x70, 0x90, 0xef, 0x80, 0x9e, 0xd8, 0x57, 0x48, 0xa3, 0xe2, - 0x9d, 0x53, 0x41, 0x6c, 0x4a, 0xb8, 0x63, 0x7b, 0xcc, 0x1a, 0xa5, 0xbe, 0x95, 0xf7, 0x6a, 0x99, - 0x1d, 0xc5, 0xf8, 0x61, 0xec, 0x5c, 0xe3, 0x5b, 0xd0, 0x50, 0x77, 0xc4, 0xdc, 0xc6, 0x9d, 0xe3, - 0xc6, 0x07, 0xd7, 0xa5, 0xf9, 0xfe, 0x67, 0x0d, 0x5a, 0xf1, 0x40, 0x53, 0xaa, 0x94, 0xbb, 0x74, - 0xe5, 0xa6, 0x97, 0x5e, 0x36, 0x0d, 0xc6, 0x11, 0x59, 0xfb, 0xca, 0x11, 0xb9, 0x0f, 0x44, 0x05, - 0xde, 0x85, 0x2f, 0x1c, 0xcf, 0x1e, 0x29, 0x9f, 0xab, 0x08, 0xdc, 0x90, 0x9c, 0x67, 0x92, 0x71, - 0x86, 0xdf, 0x0f, 0x3f, 0xaf, 0x43, 0xe7, 0x78, 0x70, 0x72, 0x7a, 0x1c, 0x04, 0x33, 0x67, 0x42, - 0x65, 0xb7, 0x75, 0x00, 0x35, 0xd9, 0x4f, 0x96, 0xbc, 0x5d, 0xf5, 0xca, 0x06, 0x1b, 0x72, 0x08, - 0x75, 0xd9, 0x56, 0x92, 0xb2, 0x27, 0xac, 0x5e, 0xe9, 0x7c, 0x83, 0x87, 0xa8, 0xc6, 0xf3, 0xfa, - 0x4b, 0x56, 0xaf, 0x6c, 0xc8, 0x21, 0x1f, 0x80, 0x9e, 0x36, 0x84, 0xcb, 0xde, 0xb3, 0x7a, 0x4b, - 0xc7, 0x1d, 0xd4, 0x4f, 0xab, 0xf1, 0xb2, 0x67, 0x99, 0xde, 0xd2, 0xb9, 0x80, 0x1c, 0x41, 0x33, - 0xee, 0x52, 0xca, 0x5f, 0x9c, 0x7a, 0x4b, 0x46, 0x11, 0x74, 0x8f, 0xea, 0xf4, 0xca, 0x9e, 0xc5, - 0x7a, 0xa5, 0xf3, 0x12, 0x79, 0x08, 0x8d, 0xa8, 0xf8, 0x94, 0xbe, 0x3a, 0xf5, 0xca, 0x07, 0x0a, - 0x34, 0x32, 0xed, 0x72, 0x97, 0x3d, 0xdd, 0xf5, 0x96, 0x0e, 0x76, 0xe4, 0x18, 0x20, 0xd3, 0xdd, - 0x2d, 0x7d, 0x93, 0xeb, 0x2d, 0x1f, 0xd8, 0xc8, 0xfb, 0xd0, 0x4a, 0x87, 0xf0, 0xf2, 0x57, 0xb6, - 0xde, 0xb2, 0x19, 0x6a, 0xf0, 0xb5, 0xff, 0xfc, 0x6b, 0x47, 0xfb, 0xed, 0xd5, 0x8e, 0xf6, 0xfb, - 0xab, 0x1d, 0xed, 0x8b, 0xab, 0x1d, 0xed, 0x4f, 0x57, 0x3b, 0xda, 0x3f, 0xaf, 0x76, 0xb4, 0x3f, - 0x7c, 0xb9, 0xa3, 0x8d, 0x1b, 0x32, 0xfc, 0xdf, 0xf9, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9c, - 0x90, 0xd5, 0xfd, 0x18, 0x16, 0x00, 0x00, +var fileDescriptor_types_d8da2202f45d32c0 = []byte{ + // 1959 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x58, 0x4f, 0x73, 0x1b, 0x49, + 0x15, 0xf7, 0xc8, 0xb2, 0xa4, 0x79, 0xb2, 0x2d, 0xa7, 0x9d, 0xd8, 0x8a, 0x16, 0xec, 0x30, 0x45, + 0x65, 0x1d, 0xd6, 0x2b, 0x83, 0x97, 0x6c, 0x39, 0xbb, 0xb0, 0x85, 0xe5, 0x0d, 0x2b, 0xd7, 0x2e, + 0x60, 0x26, 0xd9, 0x50, 0xc5, 0x45, 0xd5, 0xd2, 0xb4, 0x47, 0x53, 0x91, 0x66, 0x66, 0xa7, 0x5b, + 0x5e, 0x39, 0x1f, 0x81, 0xda, 0xa2, 0xb8, 0x71, 0xe6, 0xc6, 0x17, 0xa0, 0x8a, 0x23, 0x27, 0x6a, + 0x8f, 0x1c, 0xa0, 0xe0, 0x14, 0xc0, 0x5b, 0x5c, 0xf8, 0x04, 0x1c, 0xa9, 0xd7, 0xdd, 0xf3, 0xd7, + 0xa3, 0x54, 0x12, 0x6e, 0x5c, 0xa4, 0xee, 0x7e, 0xef, 0xf5, 0xf4, 0x7b, 0xfd, 0xde, 0xfb, 0xbd, + 0xd7, 0xb0, 0x45, 0x87, 0x23, 0xef, 0x40, 0x5c, 0x86, 0x8c, 0xab, 0xdf, 0x6e, 0x18, 0x05, 0x22, + 0x20, 0x2b, 0x72, 0xd2, 0x79, 0xdb, 0xf5, 0xc4, 0x78, 0x36, 0xec, 0x8e, 0x82, 0xe9, 0x81, 0x1b, + 0xb8, 0xc1, 0x81, 0xa4, 0x0e, 0x67, 0xe7, 0x72, 0x26, 0x27, 0x72, 0xa4, 0xa4, 0x3a, 0xbb, 0x6e, + 0x10, 0xb8, 0x13, 0x96, 0x72, 0x09, 0x6f, 0xca, 0xb8, 0xa0, 0xd3, 0x50, 0x33, 0x1c, 0x65, 0xf6, + 0x13, 0xcc, 0x77, 0x58, 0x34, 0xf5, 0x7c, 0x91, 0x1d, 0x4e, 0xbc, 0x21, 0x3f, 0x18, 0x05, 0xd3, + 0x69, 0xe0, 0x67, 0x0f, 0x64, 0xfd, 0xb1, 0x0a, 0x75, 0x9b, 0x7d, 0x36, 0x63, 0x5c, 0x90, 0x3d, + 0xa8, 0xb2, 0xd1, 0x38, 0x68, 0x57, 0xee, 0x18, 0x7b, 0xcd, 0x43, 0xd2, 0x55, 0x7c, 0x9a, 0xfa, + 0x70, 0x34, 0x0e, 0xfa, 0x4b, 0xb6, 0xe4, 0x20, 0x6f, 0xc1, 0xca, 0xf9, 0x64, 0xc6, 0xc7, 0xed, + 0x65, 0xc9, 0xba, 0x99, 0x67, 0xfd, 0x21, 0x92, 0xfa, 0x4b, 0xb6, 0xe2, 0xc1, 0x6d, 0x3d, 0xff, + 0x3c, 0x68, 0x57, 0xcb, 0xb6, 0x3d, 0xf5, 0xcf, 0xe5, 0xb6, 0xc8, 0x41, 0x8e, 0x00, 0x38, 0x13, + 0x83, 0x20, 0x14, 0x5e, 0xe0, 0xb7, 0x57, 0x24, 0xff, 0x76, 0x9e, 0xff, 0x11, 0x13, 0x3f, 0x91, + 0xe4, 0xfe, 0x92, 0x6d, 0xf2, 0x78, 0x82, 0x92, 0x9e, 0xef, 0x89, 0xc1, 0x68, 0x4c, 0x3d, 0xbf, + 0x5d, 0x2b, 0x93, 0x3c, 0xf5, 0x3d, 0x71, 0x82, 0x64, 0x94, 0xf4, 0xe2, 0x09, 0xaa, 0xf2, 0xd9, + 0x8c, 0x45, 0x97, 0xed, 0x7a, 0x99, 0x2a, 0x3f, 0x45, 0x12, 0xaa, 0x22, 0x79, 0xc8, 0xfb, 0xd0, + 0x1c, 0x32, 0xd7, 0xf3, 0x07, 0xc3, 0x49, 0x30, 0x7a, 0xda, 0x6e, 0x48, 0x91, 0x76, 0x5e, 0xa4, + 0x87, 0x0c, 0x3d, 0xa4, 0xf7, 0x97, 0x6c, 0x18, 0x26, 0x33, 0x72, 0x08, 0x8d, 0xd1, 0x98, 0x8d, + 0x9e, 0x0e, 0xc4, 0xbc, 0x6d, 0x4a, 0xc9, 0x5b, 0x79, 0xc9, 0x13, 0xa4, 0x3e, 0x9e, 0xf7, 0x97, + 0xec, 0xfa, 0x48, 0x0d, 0xc9, 0x7d, 0x30, 0x99, 0xef, 0xe8, 0xcf, 0x35, 0xa5, 0xd0, 0x56, 0xe1, + 0x5e, 0x7c, 0x27, 0xfe, 0x58, 0x83, 0xe9, 0x31, 0xe9, 0x42, 0x0d, 0xef, 0xda, 0x13, 0xed, 0x55, + 0x29, 0x73, 0xb3, 0xf0, 0x21, 0x49, 0xeb, 0x2f, 0xd9, 0x9a, 0x0b, 0xcd, 0xe7, 0xb0, 0x89, 0x77, + 0xc1, 0x22, 0x3c, 0xdc, 0x66, 0x99, 0xf9, 0x3e, 0x54, 0x74, 0x79, 0x3c, 0xd3, 0x89, 0x27, 0xbd, + 0x3a, 0xac, 0x5c, 0xd0, 0xc9, 0x8c, 0x59, 0x6f, 0x42, 0x33, 0xe3, 0x29, 0xa4, 0x0d, 0xf5, 0x29, + 0xe3, 0x9c, 0xba, 0xac, 0x6d, 0xdc, 0x31, 0xf6, 0x4c, 0x3b, 0x9e, 0x5a, 0xeb, 0xb0, 0x9a, 0xf5, + 0x93, 0x8c, 0x20, 0xfa, 0x02, 0x0a, 0x5e, 0xb0, 0x88, 0xa3, 0x03, 0x68, 0x41, 0x3d, 0xb5, 0xde, + 0x83, 0x8d, 0xa2, 0x13, 0x90, 0x0d, 0x58, 0x7e, 0xca, 0x2e, 0x35, 0x27, 0x0e, 0xc9, 0x4d, 0x7d, + 0x20, 0xe9, 0xc5, 0xa6, 0xad, 0x4f, 0xf7, 0x8b, 0x4a, 0x22, 0x9c, 0xf8, 0x01, 0x39, 0x82, 0x2a, + 0x06, 0x92, 0x94, 0x6e, 0x1e, 0x76, 0xba, 0x2a, 0xca, 0xba, 0x71, 0x94, 0x75, 0x1f, 0xc7, 0x51, + 0xd6, 0x6b, 0x7c, 0xf9, 0x7c, 0x77, 0xe9, 0x57, 0x7f, 0xdf, 0x35, 0x6c, 0x29, 0x41, 0x6e, 0xe3, + 0x55, 0x52, 0xcf, 0x1f, 0x78, 0x8e, 0xfe, 0x4e, 0x5d, 0xce, 0x4f, 0x1d, 0x72, 0x0c, 0x1b, 0xa3, + 0xc0, 0xe7, 0xcc, 0xe7, 0x33, 0x3e, 0x08, 0x69, 0x44, 0xa7, 0x5c, 0x47, 0x49, 0x7c, 0x71, 0x27, + 0x31, 0xf9, 0x4c, 0x52, 0xed, 0xd6, 0x28, 0xbf, 0x40, 0xde, 0x05, 0xb8, 0xa0, 0x13, 0xcf, 0xa1, + 0x22, 0x88, 0x78, 0xbb, 0x7a, 0x67, 0x79, 0xaf, 0x79, 0xb8, 0xa1, 0x85, 0x9f, 0xc4, 0x84, 0x5e, + 0x15, 0xcf, 0x64, 0x67, 0x38, 0xc9, 0x5d, 0x68, 0xd1, 0x30, 0x1c, 0x70, 0x41, 0x05, 0x1b, 0x0c, + 0x2f, 0x05, 0xe3, 0x32, 0x86, 0x56, 0xed, 0x35, 0x1a, 0x86, 0x8f, 0x70, 0xb5, 0x87, 0x8b, 0x96, + 0x93, 0xdc, 0x80, 0x74, 0x6f, 0x42, 0xa0, 0xea, 0x50, 0x41, 0xa5, 0x1d, 0x56, 0x6d, 0x39, 0xc6, + 0xb5, 0x90, 0x8a, 0xb1, 0xd6, 0x4e, 0x8e, 0xc9, 0x16, 0xd4, 0xc6, 0xcc, 0x73, 0xc7, 0x42, 0x2a, + 0xb4, 0x6c, 0xeb, 0x19, 0x9a, 0x3c, 0x8c, 0x82, 0x0b, 0x26, 0x23, 0xbc, 0x61, 0xab, 0x89, 0xf5, + 0x2f, 0x03, 0x6e, 0x5c, 0x0b, 0x09, 0xdc, 0x77, 0x4c, 0xf9, 0x38, 0xfe, 0x16, 0x8e, 0xc9, 0x5b, + 0xb8, 0x2f, 0x75, 0x58, 0xa4, 0x33, 0xcf, 0x9a, 0xd6, 0xb5, 0x2f, 0x17, 0xb5, 0xa2, 0x9a, 0x85, + 0x3c, 0x84, 0x8d, 0x09, 0xe5, 0x62, 0xa0, 0x3c, 0x77, 0x20, 0x33, 0xcb, 0x72, 0x2e, 0x9a, 0x3e, + 0xa1, 0xb1, 0x87, 0xa3, 0x43, 0x69, 0xf1, 0xf5, 0x49, 0x6e, 0x95, 0xf4, 0xe1, 0xe6, 0xf0, 0xf2, + 0x19, 0xf5, 0x85, 0xe7, 0xb3, 0xc1, 0x35, 0x6b, 0xb7, 0xf4, 0x56, 0x0f, 0x2f, 0x3c, 0x87, 0xf9, + 0x23, 0xa6, 0x37, 0xd9, 0x4c, 0x44, 0x92, 0x6b, 0xe0, 0xd6, 0x1d, 0x58, 0xcf, 0xc7, 0x2f, 0x59, + 0x87, 0x8a, 0x98, 0x6b, 0x0d, 0x2b, 0x62, 0x6e, 0x59, 0x89, 0xef, 0x25, 0x41, 0x74, 0x8d, 0xe7, + 0x1e, 0xb4, 0x0a, 0x01, 0x9d, 0x31, 0xb7, 0x91, 0x35, 0xb7, 0xd5, 0x82, 0xb5, 0x5c, 0x1c, 0x5b, + 0x5f, 0xac, 0x40, 0xc3, 0x66, 0x3c, 0x44, 0x37, 0x22, 0x47, 0x60, 0xb2, 0xf9, 0x88, 0xa9, 0x14, + 0x6a, 0x14, 0x12, 0x94, 0xe2, 0x79, 0x18, 0xd3, 0x31, 0x94, 0x13, 0x66, 0x72, 0x2f, 0x97, 0xfe, + 0x37, 0x8b, 0x42, 0xd9, 0xfc, 0xbf, 0x9f, 0xcf, 0xff, 0x37, 0x0b, 0xbc, 0x05, 0x00, 0xb8, 0x97, + 0x03, 0x80, 0xe2, 0xc6, 0x39, 0x04, 0x78, 0x50, 0x82, 0x00, 0xc5, 0xe3, 0x2f, 0x80, 0x80, 0x07, + 0x25, 0x10, 0xd0, 0xbe, 0xf6, 0xad, 0x52, 0x0c, 0xd8, 0xcf, 0x63, 0x40, 0x51, 0x9d, 0x02, 0x08, + 0x7c, 0xaf, 0x0c, 0x04, 0x6e, 0x17, 0x64, 0x16, 0xa2, 0xc0, 0x3b, 0xd7, 0x50, 0x60, 0xab, 0x20, + 0x5a, 0x02, 0x03, 0x0f, 0x72, 0xf9, 0x19, 0x4a, 0x75, 0x2b, 0x4f, 0xd0, 0xe4, 0xdd, 0xeb, 0x08, + 0xb2, 0x5d, 0xbc, 0xda, 0x32, 0x08, 0x39, 0x28, 0x40, 0xc8, 0xad, 0xe2, 0x29, 0x0b, 0x18, 0x92, + 0x22, 0xc1, 0x3d, 0x8c, 0xfb, 0x82, 0xa7, 0x61, 0x8e, 0x60, 0x51, 0x14, 0x44, 0x3a, 0x55, 0xab, + 0x89, 0xb5, 0x87, 0x99, 0x28, 0xf5, 0xaf, 0x17, 0xa0, 0x86, 0x74, 0xfa, 0x8c, 0x77, 0x59, 0xbf, + 0x36, 0x52, 0x59, 0x19, 0xd1, 0xd9, 0x2c, 0x66, 0xea, 0x2c, 0x96, 0x01, 0x93, 0x4a, 0x0e, 0x4c, + 0xc8, 0xb7, 0xe0, 0x86, 0x4c, 0x23, 0xd2, 0x2e, 0x83, 0x5c, 0x5a, 0x6b, 0x21, 0x41, 0x19, 0x44, + 0xe5, 0xb7, 0xb7, 0x61, 0x33, 0xc3, 0x8b, 0x29, 0x56, 0xa6, 0xb0, 0xaa, 0x0c, 0xde, 0x8d, 0x84, + 0xfb, 0x38, 0x0c, 0xfb, 0x94, 0x8f, 0xad, 0x1f, 0xa5, 0xfa, 0xa7, 0x40, 0x45, 0xa0, 0x3a, 0x0a, + 0x1c, 0xa5, 0xd6, 0x9a, 0x2d, 0xc7, 0x08, 0x5e, 0x93, 0xc0, 0x95, 0x5f, 0x35, 0x6d, 0x1c, 0x22, + 0x57, 0x12, 0x29, 0xa6, 0x0a, 0x09, 0xeb, 0x97, 0x46, 0xba, 0x5f, 0x8a, 0x5d, 0x65, 0x30, 0x63, + 0xfc, 0x2f, 0x30, 0x53, 0x79, 0x59, 0x98, 0xb1, 0x7e, 0x67, 0xa4, 0x77, 0x91, 0x00, 0xc8, 0xeb, + 0x29, 0x87, 0x6e, 0xe1, 0xf9, 0x0e, 0x9b, 0xcb, 0x50, 0x5f, 0xb6, 0xd5, 0x24, 0x46, 0xf5, 0x9a, + 0x34, 0x70, 0x1e, 0xd5, 0xeb, 0x72, 0x4d, 0x4d, 0x34, 0xf0, 0x04, 0xe7, 0x32, 0x06, 0x57, 0x6d, + 0x35, 0xc9, 0xe4, 0x4d, 0x33, 0x97, 0x37, 0xcf, 0x80, 0x5c, 0x8f, 0x4e, 0xf2, 0x1e, 0x54, 0x05, + 0x75, 0xd1, 0x78, 0xa8, 0xff, 0x7a, 0x57, 0xd5, 0xc8, 0xdd, 0x8f, 0x9f, 0x9c, 0x51, 0x2f, 0xea, + 0x6d, 0xa1, 0xf6, 0xff, 0x7e, 0xbe, 0xbb, 0x8e, 0x3c, 0xfb, 0xc1, 0xd4, 0x13, 0x6c, 0x1a, 0x8a, + 0x4b, 0x5b, 0xca, 0x58, 0x7f, 0x31, 0x30, 0x6b, 0xe7, 0xa2, 0xb6, 0xd4, 0x16, 0xb1, 0x6b, 0x56, + 0x32, 0x00, 0xfb, 0x72, 0xf6, 0xf9, 0x3a, 0x80, 0x4b, 0xf9, 0xe0, 0x73, 0xea, 0x0b, 0xe6, 0x68, + 0x23, 0x99, 0x2e, 0xe5, 0x3f, 0x93, 0x0b, 0x58, 0x87, 0x20, 0x79, 0xc6, 0x99, 0x23, 0xad, 0xb5, + 0x6c, 0xd7, 0x5d, 0xca, 0x3f, 0xe5, 0xcc, 0x49, 0xf4, 0xaa, 0xbf, 0x86, 0x5e, 0x7f, 0xcd, 0xb8, + 0x5c, 0x0a, 0x59, 0xff, 0x0f, 0x9a, 0x7d, 0x65, 0x20, 0x16, 0xe7, 0xd3, 0x1e, 0x39, 0x81, 0x1b, + 0x89, 0x7b, 0x0f, 0x66, 0xa1, 0x43, 0xb1, 0x72, 0x32, 0x5e, 0x18, 0x0f, 0x1b, 0x89, 0xc0, 0xa7, + 0x8a, 0x9f, 0xfc, 0x18, 0xb6, 0x0b, 0x01, 0x99, 0x6c, 0x55, 0x79, 0x61, 0x5c, 0xde, 0xca, 0xc7, + 0x65, 0xbc, 0x5f, 0xac, 0xe5, 0xf2, 0x6b, 0x68, 0xf9, 0x4d, 0x2c, 0x49, 0xb2, 0x69, 0xba, 0xec, + 0x9e, 0xac, 0xdf, 0x18, 0xd0, 0x2a, 0x1c, 0x86, 0x1c, 0x00, 0xa8, 0x2c, 0xc7, 0xbd, 0x67, 0x71, + 0x61, 0x1c, 0xdb, 0x40, 0x1a, 0xeb, 0x91, 0xf7, 0x8c, 0xd9, 0xe6, 0x30, 0x1e, 0x92, 0xbb, 0x50, + 0x17, 0x73, 0xc5, 0x9d, 0x2f, 0xde, 0x1e, 0xcf, 0x25, 0x6b, 0x4d, 0xc8, 0x7f, 0x72, 0x1f, 0x56, + 0xd5, 0xc6, 0x6e, 0xc0, 0xb9, 0x17, 0xea, 0xc2, 0x81, 0x64, 0xb7, 0xfe, 0x48, 0x52, 0xec, 0xe6, + 0x30, 0x9d, 0x58, 0x3f, 0x07, 0x33, 0xf9, 0x2c, 0x79, 0x03, 0xcc, 0x29, 0x9d, 0xeb, 0xca, 0x16, + 0xcf, 0xb6, 0x62, 0x37, 0xa6, 0x74, 0x2e, 0x8b, 0x5a, 0xb2, 0x0d, 0x75, 0x24, 0x8a, 0xb9, 0xb2, + 0xf7, 0x8a, 0x5d, 0x9b, 0xd2, 0xf9, 0xe3, 0x79, 0x42, 0x70, 0x29, 0x8f, 0xcb, 0xd6, 0x29, 0x9d, + 0x7f, 0x44, 0xb9, 0xf5, 0x01, 0xd4, 0xd4, 0x21, 0x5f, 0x6a, 0x63, 0x94, 0xaf, 0xe4, 0xe4, 0x7f, + 0x00, 0xcd, 0xcc, 0xb9, 0xc9, 0x77, 0xe0, 0x96, 0xd2, 0x30, 0xa4, 0x91, 0x90, 0x16, 0xc9, 0x6d, + 0x48, 0x24, 0xf1, 0x8c, 0x46, 0x02, 0x3f, 0xa9, 0x0a, 0xf1, 0x08, 0xd6, 0xf3, 0xc5, 0x2a, 0xf9, + 0x06, 0xac, 0xea, 0xc2, 0x36, 0x0a, 0x66, 0xbe, 0xa3, 0x65, 0x9b, 0x6a, 0xcd, 0xc6, 0x25, 0xf2, + 0xfd, 0x92, 0xb4, 0x1d, 0x23, 0xfa, 0x23, 0xcf, 0xf5, 0x3d, 0xdf, 0x7d, 0x51, 0xf6, 0xfe, 0x5b, + 0x05, 0x6a, 0xaa, 0xb0, 0x26, 0x77, 0x33, 0x5d, 0x8c, 0x44, 0xcd, 0x5e, 0xf3, 0xea, 0xf9, 0x6e, + 0x5d, 0x02, 0xcc, 0xe9, 0x87, 0x69, 0x4b, 0x93, 0x26, 0xd4, 0x4a, 0xae, 0xee, 0x8f, 0xfb, 0xa7, + 0xe5, 0x57, 0xee, 0x9f, 0xb6, 0xa1, 0xee, 0xcf, 0xa6, 0xf2, 0xb2, 0xaa, 0xea, 0xb2, 0xfc, 0xd9, + 0x14, 0x2f, 0xeb, 0x0d, 0x30, 0x45, 0x20, 0xe8, 0x44, 0x92, 0x54, 0x52, 0x68, 0xc8, 0x05, 0x24, + 0xde, 0x85, 0x56, 0x16, 0xb3, 0x11, 0x83, 0x15, 0x44, 0xac, 0xa5, 0x88, 0x8d, 0xfd, 0xc4, 0x9b, + 0xd0, 0x4a, 0x15, 0x56, 0x7c, 0x0a, 0x36, 0xd6, 0xd3, 0x65, 0xc9, 0x78, 0x1b, 0x1a, 0x09, 0x9a, + 0x2b, 0x08, 0xa9, 0x53, 0x05, 0xe2, 0xd8, 0xac, 0x87, 0x51, 0x10, 0x06, 0x9c, 0x45, 0xba, 0x4c, + 0x5b, 0x94, 0x0a, 0x12, 0x3e, 0xcb, 0x03, 0x33, 0x21, 0x62, 0xe9, 0x41, 0x1d, 0x27, 0x62, 0x9c, + 0xeb, 0x2a, 0x3f, 0x9e, 0x92, 0x7d, 0xa8, 0x87, 0xb3, 0xe1, 0x00, 0x11, 0x2e, 0x1f, 0x32, 0x67, + 0xb3, 0xe1, 0xc7, 0xec, 0x32, 0xee, 0x77, 0x42, 0x39, 0x93, 0x18, 0x17, 0x7c, 0xce, 0x22, 0xed, + 0xbc, 0x6a, 0x62, 0x09, 0xd8, 0x28, 0xde, 0x35, 0xf9, 0x2e, 0x98, 0x89, 0x7e, 0x85, 0xd0, 0x2d, + 0x9e, 0x39, 0x65, 0xc4, 0x42, 0x88, 0x7b, 0xae, 0xcf, 0x9c, 0x41, 0x6a, 0x5b, 0x79, 0xae, 0x86, + 0xdd, 0x52, 0x84, 0x4f, 0x62, 0xe3, 0x5a, 0xdf, 0x86, 0x9a, 0x3a, 0x23, 0xe6, 0x13, 0xdc, 0x39, + 0x2e, 0xb6, 0x70, 0x5c, 0x9a, 0x63, 0xfe, 0x6c, 0x40, 0x23, 0x6e, 0xa2, 0x4a, 0x85, 0x72, 0x87, + 0xae, 0xbc, 0xec, 0xa1, 0x17, 0x75, 0xa2, 0xb1, 0x47, 0x56, 0x5f, 0xd9, 0x23, 0xf7, 0x81, 0x28, + 0xc7, 0xbb, 0x08, 0x84, 0xe7, 0xbb, 0x03, 0x65, 0x73, 0xe5, 0x81, 0x1b, 0x92, 0xf2, 0x44, 0x12, + 0xce, 0x70, 0xfd, 0xf0, 0x8b, 0x15, 0x68, 0x1d, 0xf7, 0x4e, 0x4e, 0x8f, 0xc3, 0x70, 0xe2, 0x8d, + 0xa8, 0xac, 0xf0, 0x0e, 0xa0, 0x2a, 0x6b, 0xd8, 0x92, 0x77, 0xb3, 0x4e, 0x59, 0x33, 0x45, 0x0e, + 0x61, 0x45, 0x96, 0xb2, 0xa4, 0xec, 0xf9, 0xac, 0x53, 0xda, 0x53, 0xe1, 0x47, 0x54, 0xb1, 0x7b, + 0xfd, 0x15, 0xad, 0x53, 0xd6, 0x58, 0x91, 0x0f, 0xc0, 0x4c, 0x8b, 0xd0, 0x45, 0x6f, 0x69, 0x9d, + 0x85, 0x2d, 0x16, 0xca, 0xa7, 0x15, 0xc0, 0xa2, 0x27, 0xa1, 0xce, 0xc2, 0x5e, 0x84, 0x1c, 0x41, + 0x3d, 0xae, 0x8c, 0xca, 0x5f, 0xbb, 0x3a, 0x0b, 0xda, 0x1f, 0x34, 0x8f, 0xaa, 0x2e, 0xcb, 0x9e, + 0xe4, 0x3a, 0xa5, 0x3d, 0x1a, 0xb9, 0x0f, 0x35, 0x0d, 0x78, 0xa5, 0x2f, 0x5e, 0x9d, 0xf2, 0x26, + 0x06, 0x95, 0x4c, 0x2b, 0xeb, 0x45, 0xcf, 0x86, 0x9d, 0x85, 0xcd, 0x24, 0x39, 0x06, 0xc8, 0x54, + 0x94, 0x0b, 0xdf, 0x03, 0x3b, 0x8b, 0x9b, 0x44, 0xf2, 0x3e, 0x34, 0xd2, 0xc6, 0xbf, 0xfc, 0x85, + 0xaf, 0xb3, 0xa8, 0x6f, 0xeb, 0x7d, 0xed, 0x3f, 0xff, 0xdc, 0x31, 0x7e, 0x7b, 0xb5, 0x63, 0xfc, + 0xfe, 0x6a, 0xc7, 0xf8, 0xf2, 0x6a, 0xc7, 0xf8, 0xd3, 0xd5, 0x8e, 0xf1, 0x8f, 0xab, 0x1d, 0xe3, + 0x0f, 0x5f, 0xed, 0x18, 0xc3, 0x9a, 0x74, 0xff, 0x77, 0xfe, 0x1b, 0x00, 0x00, 0xff, 0xff, 0xc1, + 0xc2, 0x93, 0xfb, 0x94, 0x16, 0x00, 0x00, } diff --git a/abci/types/types.proto b/abci/types/types.proto index 7f87628e1..6e6b1cd36 100644 --- a/abci/types/types.proto +++ b/abci/types/types.proto @@ -71,10 +71,11 @@ message RequestQuery { bool prove = 4; } +// NOTE: validators here have empty pubkeys. message RequestBeginBlock { bytes hash = 1; Header header = 2 [(gogoproto.nullable)=false]; - repeated SigningValidator validators = 3 [(gogoproto.nullable)=false]; + LastCommitInfo last_commit_info = 3 [(gogoproto.nullable)=false]; repeated Evidence byzantine_validators = 4 [(gogoproto.nullable)=false]; } @@ -203,14 +204,14 @@ message ConsensusParams { BlockGossip block_gossip = 3; } -// BlockSize contain limits on the block size. +// BlockSize contains limits on the block size. message BlockSize { int32 max_bytes = 1; int32 max_txs = 2; int64 max_gas = 3; } -// TxSize contain limits on the tx size. +// TxSize contains limits on the tx size. message TxSize { int32 max_bytes = 1; int64 max_gas = 2; @@ -223,6 +224,11 @@ message BlockGossip { int32 block_part_size_bytes = 1; } +message LastCommitInfo { + int32 commit_round = 1; + repeated SigningValidator validators = 2 [(gogoproto.nullable)=false]; +} + //---------------------------------------- // Blockchain Types diff --git a/abci/types/typespb_test.go b/abci/types/typespb_test.go index db88ed394..33a368af4 100644 --- a/abci/types/typespb_test.go +++ b/abci/types/typespb_test.go @@ -1646,6 +1646,62 @@ func TestBlockGossipMarshalTo(t *testing.T) { } } +func TestLastCommitInfoProto(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, false) + dAtA, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &LastCommitInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + littlefuzz := make([]byte, len(dAtA)) + copy(littlefuzz, dAtA) + for i := range dAtA { + dAtA[i] = byte(popr.Intn(256)) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } + if len(littlefuzz) > 0 { + fuzzamount := 100 + for i := 0; i < fuzzamount; i++ { + littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256)) + littlefuzz = append(littlefuzz, byte(popr.Intn(256))) + } + // shouldn't panic + _ = github_com_gogo_protobuf_proto.Unmarshal(littlefuzz, msg) + } +} + +func TestLastCommitInfoMarshalTo(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, false) + size := p.Size() + dAtA := make([]byte, size) + for i := range dAtA { + dAtA[i] = byte(popr.Intn(256)) + } + _, err := p.MarshalTo(dAtA) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &LastCommitInfo{} + if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + for i := range dAtA { + dAtA[i] = byte(popr.Intn(256)) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } +} + func TestHeaderProto(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) @@ -2448,6 +2504,24 @@ func TestBlockGossipJSON(t *testing.T) { t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) } } +func TestLastCommitInfoJSON(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, true) + marshaler := github_com_gogo_protobuf_jsonpb.Marshaler{} + jsondata, err := marshaler.MarshalToString(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + msg := &LastCommitInfo{} + err = github_com_gogo_protobuf_jsonpb.UnmarshalString(jsondata, msg) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p) + } +} func TestHeaderJSON(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) @@ -3350,6 +3424,34 @@ func TestBlockGossipProtoCompactText(t *testing.T) { } } +func TestLastCommitInfoProtoText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, true) + dAtA := github_com_gogo_protobuf_proto.MarshalTextString(p) + msg := &LastCommitInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } +} + +func TestLastCommitInfoProtoCompactText(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, true) + dAtA := github_com_gogo_protobuf_proto.CompactTextString(p) + msg := &LastCommitInfo{} + if err := github_com_gogo_protobuf_proto.UnmarshalText(dAtA, msg); err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + if !p.Equal(msg) { + t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p) + } +} + func TestHeaderProtoText(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) @@ -4128,6 +4230,28 @@ func TestBlockGossipSize(t *testing.T) { } } +func TestLastCommitInfoSize(t *testing.T) { + seed := time.Now().UnixNano() + popr := math_rand.New(math_rand.NewSource(seed)) + p := NewPopulatedLastCommitInfo(popr, true) + size2 := github_com_gogo_protobuf_proto.Size(p) + dAtA, err := github_com_gogo_protobuf_proto.Marshal(p) + if err != nil { + t.Fatalf("seed = %d, err = %v", seed, err) + } + size := p.Size() + if len(dAtA) != size { + t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(dAtA)) + } + if size2 != size { + t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2) + } + size3 := github_com_gogo_protobuf_proto.Size(p) + if size3 != size { + t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3) + } +} + func TestHeaderSize(t *testing.T) { seed := time.Now().UnixNano() popr := math_rand.New(math_rand.NewSource(seed)) diff --git a/docs/app-dev/abci-spec.md b/docs/app-dev/abci-spec.md index 0e5eb0044..770740b86 100644 --- a/docs/app-dev/abci-spec.md +++ b/docs/app-dev/abci-spec.md @@ -160,9 +160,8 @@ See below for more details on the message types and how they are used. - **Request**: - `Hash ([]byte)`: The block's hash. This can be derived from the block header. - - `Header (struct{})`: The block header - - `Validators ([]SigningValidator)`: List of validators in the current validator - set and whether or not they signed a vote in the LastCommit + - `Header (struct{})`: The block header. + - `LastCommitInfo (LastCommitInfo)`: Info about the last commit. - `ByzantineValidators ([]Evidence)`: List of evidence of validators that acted maliciously - **Response**: @@ -171,8 +170,9 @@ See below for more details on the message types and how they are used. - Signals the beginning of a new block. Called prior to any DeliverTxs. - The header is expected to at least contain the Height. - - The `Validators` and `ByzantineValidators` can be used to - determine rewards and punishments for the validators. + - The `LastCommitInfo` and `ByzantineValidators` can be used to determine + rewards and punishments for the validators. NOTE validators here do not + include pubkeys. ### CheckTx @@ -326,3 +326,10 @@ See below for more details on the message types and how they are used. It is the proposer's local time when block was created. - `TotalVotingPower (int64)`: Total voting power of the validator set at height `Height` + +### LastCommitInfo + +- **Fields**: + - `CommitRound (int32)`: Commit round. + - `Validators ([]SigningValidator)`: List of validators in the current + validator set and whether or not they signed a vote. diff --git a/state/execution.go b/state/execution.go index f57b6e4dd..54e1ec73a 100644 --- a/state/execution.go +++ b/state/execution.go @@ -188,9 +188,12 @@ func execBlockOnProxyApp(logger log.Logger, proxyAppConn proxy.AppConnConsensus, // Begin block _, err := proxyAppConn.BeginBlockSync(abci.RequestBeginBlock{ - Hash: block.Hash(), - Header: types.TM2PB.Header(&block.Header), - Validators: signVals, + Hash: block.Hash(), + Header: types.TM2PB.Header(&block.Header), + LastCommitInfo: abci.LastCommitInfo{ + CommitRound: int32(block.LastCommit.Round()), + Validators: signVals, + }, ByzantineValidators: byzVals, }) if err != nil { @@ -245,7 +248,7 @@ func getBeginBlockValidatorInfo(block *types.Block, lastValSet *types.ValidatorS vote = block.LastCommit.Precommits[i] } val := abci.SigningValidator{ - Validator: types.TM2PB.Validator(val), + Validator: types.TM2PB.ValidatorWithoutPubKey(val), SignedLastBlock: vote != nil, } signVals[i] = val diff --git a/state/execution_test.go b/state/execution_test.go index 516ca2ed5..53c5c882b 100644 --- a/state/execution_test.go +++ b/state/execution_test.go @@ -293,7 +293,7 @@ func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) { } func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock { - app.Validators = req.Validators + app.Validators = req.LastCommitInfo.Validators app.ByzantineValidators = req.ByzantineValidators return abci.ResponseBeginBlock{} } diff --git a/types/protobuf.go b/types/protobuf.go index 0ed3d0c43..01d4ebf0c 100644 --- a/types/protobuf.go +++ b/types/protobuf.go @@ -50,6 +50,13 @@ func (tm2pb) Header(header *Header) abci.Header { } } +func (tm2pb) ValidatorWithoutPubKey(val *Validator) abci.Validator { + return abci.Validator{ + Address: val.PubKey.Address(), + Power: val.VotingPower, + } +} + // XXX: panics on unknown pubkey type func (tm2pb) Validator(val *Validator) abci.Validator { return abci.Validator{ @@ -129,7 +136,7 @@ func (tm2pb) Evidence(ev Evidence, valSet *ValidatorSet, evTime time.Time) abci. return abci.Evidence{ Type: evType, - Validator: TM2PB.Validator(val), + Validator: TM2PB.ValidatorWithoutPubKey(val), Height: ev.Height(), Time: evTime, TotalVotingPower: valSet.TotalVotingPower(), diff --git a/types/protobuf_test.go b/types/protobuf_test.go index 6ee79b906..8711974e3 100644 --- a/types/protobuf_test.go +++ b/types/protobuf_test.go @@ -102,6 +102,9 @@ func TestABCIEvidence(t *testing.T) { ) assert.Equal(t, "duplicate/vote", abciEv.Type) + + // test we do not send pubkeys + assert.Empty(t, abciEv.Validator.PubKey) } type pubKeyEddie struct{} @@ -120,3 +123,21 @@ func TestABCIValidatorFromPubKeyAndPower(t *testing.T) { assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(nil, 10) }) assert.Panics(t, func() { TM2PB.ValidatorFromPubKeyAndPower(pubKeyEddie{}, 10) }) } + +func TestABCIValidatorWithoutPubKey(t *testing.T) { + pkEd := ed25519.GenPrivKey().PubKey() + + abciVal := TM2PB.ValidatorWithoutPubKey(&Validator{ + Address: pkEd.Address(), + PubKey: pkEd, + VotingPower: 10, + }) + + // pubkey must be nil + tmValExpected := abci.Validator{ + Address: pkEd.Address(), + Power: 10, + } + + assert.Equal(t, tmValExpected, abciVal) +} From 62b8ee270d55c562ac5262d3c456f9e0ad74efe9 Mon Sep 17 00:00:00 2001 From: Anton Kaliaev Date: Tue, 31 Jul 2018 20:28:19 +0400 Subject: [PATCH 08/16] [docs] Validator's address can be skipped (#2117) Refs #1712 --- docs/app-dev/app-development.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/app-dev/app-development.md b/docs/app-dev/app-development.md index a795673f1..d3f22362b 100644 --- a/docs/app-dev/app-development.md +++ b/docs/app-dev/app-development.md @@ -365,14 +365,14 @@ ResponseBeginBlock requestBeginBlock(RequestBeginBlock req) { ### EndBlock -The EndBlock request can be used to run some code at the end of every -block. Additionally, the response may contain a list of validators, -which can be used to update the validator set. To add a new validator or -update an existing one, simply include them in the list returned in the -EndBlock response. To remove one, include it in the list with a `power` -equal to `0`. Tendermint core will take care of updating the validator -set. Note the change in voting power must be strictly less than 1/3 per -block if you want a light client to be able to prove the transition +The EndBlock request can be used to run some code at the end of every block. +Additionally, the response may contain a list of validators, which can be used +to update the validator set. To add a new validator or update an existing one, +simply include them in the list returned in the EndBlock response. To remove +one, include it in the list with a `power` equal to `0`. Validator's `address` +field can be left empty. Tendermint core will take care of updating the +validator set. Note the change in voting power must be strictly less than 1/3 +per block if you want a light client to be able to prove the transition externally. See the [light client docs](https://godoc.org/github.com/tendermint/tendermint/lite#hdr-How_We_Track_Validators) for details on how it tracks validators. From 2608249e5ba280ba3912099d7b8f89516b049fb1 Mon Sep 17 00:00:00 2001 From: ValarDragon Date: Mon, 30 Jul 2018 12:24:39 -0700 Subject: [PATCH 09/16] libs/common: Refactor tempfile code into its own file --- libs/common/os.go | 55 ----------------------------------- libs/common/tempfile.go | 63 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 55 deletions(-) create mode 100644 libs/common/tempfile.go diff --git a/libs/common/os.go b/libs/common/os.go index 00f4da57b..b8419764e 100644 --- a/libs/common/os.go +++ b/libs/common/os.go @@ -8,7 +8,6 @@ import ( "os" "os/exec" "os/signal" - "path/filepath" "strings" "syscall" ) @@ -124,60 +123,6 @@ func MustWriteFile(filePath string, contents []byte, mode os.FileMode) { } } -// WriteFileAtomic creates a temporary file with data and the perm given and -// swaps it atomically with filename if successful. -func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error { - var ( - dir = filepath.Dir(filename) - tempFile = filepath.Join(dir, "write-file-atomic-"+RandStr(32)) - // Override in case it does exist, create in case it doesn't and force kernel - // flush, which still leaves the potential of lingering disk cache. - flag = os.O_WRONLY | os.O_CREATE | os.O_SYNC | os.O_TRUNC - ) - - f, err := os.OpenFile(tempFile, flag, perm) - if err != nil { - return err - } - // Clean up in any case. Defer stacking order is last-in-first-out. - defer os.Remove(f.Name()) - defer f.Close() - - if n, err := f.Write(data); err != nil { - return err - } else if n < len(data) { - return io.ErrShortWrite - } - // Close the file before renaming it, otherwise it will cause "The process - // cannot access the file because it is being used by another process." on windows. - f.Close() - - return os.Rename(f.Name(), filename) -} - -//-------------------------------------------------------------------------------- - -func Tempfile(prefix string) (*os.File, string) { - file, err := ioutil.TempFile("", prefix) - if err != nil { - PanicCrisis(err) - } - return file, file.Name() -} - -func Tempdir(prefix string) (*os.File, string) { - tempDir := os.TempDir() + "/" + prefix + RandStr(12) - err := EnsureDir(tempDir, 0700) - if err != nil { - panic(Fmt("Error creating temp dir: %v", err)) - } - dir, err := os.Open(tempDir) - if err != nil { - panic(Fmt("Error opening temp dir: %v", err)) - } - return dir, tempDir -} - //-------------------------------------------------------------------------------- func Prompt(prompt string, defaultValue string) (string, error) { diff --git a/libs/common/tempfile.go b/libs/common/tempfile.go new file mode 100644 index 000000000..94abd2c77 --- /dev/null +++ b/libs/common/tempfile.go @@ -0,0 +1,63 @@ +package common + +import ( + "io" + "io/ioutil" + "os" + "path/filepath" +) + +// WriteFileAtomic creates a temporary file with data and the perm given and +// swaps it atomically with filename if successful. +func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error { + var ( + dir = filepath.Dir(filename) + // Create in case it doesn't exist and force kernel + // flush, which still leaves the potential of lingering disk cache. + // Never overwrites files + flag = os.O_WRONLY | os.O_CREATE | os.O_SYNC | os.O_TRUNC | os.O_EXCL + ) + + tempFile := filepath.Join(dir, "write-file-atomic-"+RandStr(32)) + f, err := os.OpenFile(tempFile, flag, perm) + if err != nil { + return err + } + // Clean up in any case. Defer stacking order is last-in-first-out. + defer os.Remove(f.Name()) + defer f.Close() + + if n, err := f.Write(data); err != nil { + return err + } else if n < len(data) { + return io.ErrShortWrite + } + // Close the file before renaming it, otherwise it will cause "The process + // cannot access the file because it is being used by another process." on windows. + f.Close() + + return os.Rename(f.Name(), filename) +} + +//-------------------------------------------------------------------------------- + +func Tempfile(prefix string) (*os.File, string) { + file, err := ioutil.TempFile("", prefix) + if err != nil { + PanicCrisis(err) + } + return file, file.Name() +} + +func Tempdir(prefix string) (*os.File, string) { + tempDir := os.TempDir() + "/" + prefix + RandStr(12) + err := EnsureDir(tempDir, 0700) + if err != nil { + panic(Fmt("Error creating temp dir: %v", err)) + } + dir, err := os.Open(tempDir) + if err != nil { + panic(Fmt("Error opening temp dir: %v", err)) + } + return dir, tempDir +} From be642754f5da7a27b9534a5239bff1d3be10a286 Mon Sep 17 00:00:00 2001 From: ValarDragon Date: Mon, 30 Jul 2018 14:06:48 -0700 Subject: [PATCH 10/16] libs/cmn/writefileatomic: Handle file already exists gracefully (#2113) This uses the stdlib's method of creating a tempfile in our write file atomimc method, with a few modifications. We use a 64 bit number rather than 32 bit, and therefore a corresponding LCG. This is to reduce collision probability. (Note we currently used 32 bytes previously, so this is likely a concern) We handle reseeding the LCG in such a way that multiple threads are even less likely to reuse the same seed. --- CHANGELOG_PENDING.md | 1 + libs/common/os_test.go | 42 ----------- libs/common/tempfile.go | 109 ++++++++++++++++++++++++--- libs/common/tempfile_test.go | 138 +++++++++++++++++++++++++++++++++++ 4 files changed, 238 insertions(+), 52 deletions(-) create mode 100644 libs/common/tempfile_test.go diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 76d06b496..481f5b452 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -22,5 +22,6 @@ IMPROVEMENTS: - [common] bit array functions which take in another parameter are now thread safe BUG FIXES: +- [common] \#2109 Safely handle cases where atomic write files already exist - [privval] fix a deadline for accepting new connections in socket private validator. diff --git a/libs/common/os_test.go b/libs/common/os_test.go index 3edd6496e..bf65f0c99 100644 --- a/libs/common/os_test.go +++ b/libs/common/os_test.go @@ -1,52 +1,10 @@ package common import ( - "bytes" - "io/ioutil" "os" "testing" ) -func TestWriteFileAtomic(t *testing.T) { - var ( - data = []byte(RandStr(RandIntn(2048))) - old = RandBytes(RandIntn(2048)) - perm os.FileMode = 0600 - ) - - f, err := ioutil.TempFile("/tmp", "write-atomic-test-") - if err != nil { - t.Fatal(err) - } - defer os.Remove(f.Name()) - - if err = ioutil.WriteFile(f.Name(), old, 0664); err != nil { - t.Fatal(err) - } - - if err = WriteFileAtomic(f.Name(), data, perm); err != nil { - t.Fatal(err) - } - - rData, err := ioutil.ReadFile(f.Name()) - if err != nil { - t.Fatal(err) - } - - if !bytes.Equal(data, rData) { - t.Fatalf("data mismatch: %v != %v", data, rData) - } - - stat, err := os.Stat(f.Name()) - if err != nil { - t.Fatal(err) - } - - if have, want := stat.Mode().Perm(), perm; have != want { - t.Errorf("have %v, want %v", have, want) - } -} - func TestGoPath(t *testing.T) { // restore original gopath upon exit path := os.Getenv("GOPATH") diff --git a/libs/common/tempfile.go b/libs/common/tempfile.go index 94abd2c77..bc1343e5d 100644 --- a/libs/common/tempfile.go +++ b/libs/common/tempfile.go @@ -1,28 +1,117 @@ package common import ( + fmt "fmt" "io" "io/ioutil" "os" "path/filepath" + "strconv" + "strings" + "sync" + "time" ) -// WriteFileAtomic creates a temporary file with data and the perm given and +const ( + atomicWriteFilePrefix = "write-file-atomic-" + // Maximum number of atomic write file conflicts before we start reseeding + // (reduced from golang's default 10 due to using an increased randomness space) + atomicWriteFileMaxNumConflicts = 5 + // Maximum number of attempts to make at writing the write file before giving up + // (reduced from golang's default 10000 due to using an increased randomness space) + atomicWriteFileMaxNumWriteAttempts = 1000 + // LCG constants from Donald Knuth MMIX + // This LCG's has a period equal to 2**64 + lcgA = 6364136223846793005 + lcgC = 1442695040888963407 + // Create in case it doesn't exist and force kernel + // flush, which still leaves the potential of lingering disk cache. + // Never overwrites files + atomicWriteFileFlag = os.O_WRONLY | os.O_CREATE | os.O_SYNC | os.O_TRUNC | os.O_EXCL +) + +var ( + atomicWriteFileRand uint64 + atomicWriteFileRandMu sync.Mutex +) + +func writeFileRandReseed() uint64 { + // Scale the PID, to minimize the chance that two processes seeded at similar times + // don't get the same seed. Note that PID typically ranges in [0, 2**15), but can be + // up to 2**22 under certain configurations. We left bit-shift the PID by 20, so that + // a PID difference of one corresponds to a time difference of 2048 seconds. + // The important thing here is that now for a seed conflict, they would both have to be on + // the correct nanosecond offset, and second-based offset, which is much less likely than + // just a conflict with the correct nanosecond offset. + return uint64(time.Now().UnixNano() + int64(os.Getpid()<<20)) +} + +// Use a fast thread safe LCG for atomic write file names. +// Returns a string corresponding to a 64 bit int. +// If it was a negative int, the leading number is a 0. +func randWriteFileSuffix() string { + atomicWriteFileRandMu.Lock() + r := atomicWriteFileRand + if r == 0 { + r = writeFileRandReseed() + } + + // Update randomness according to lcg + r = r*lcgA + lcgC + + atomicWriteFileRand = r + atomicWriteFileRandMu.Unlock() + // Can have a negative name, replace this in the following + suffix := strconv.Itoa(int(r)) + if string(suffix[0]) == "-" { + // Replace first "-" with "0". This is purely for UI clarity, + // as otherwhise there would be two `-` in a row. + suffix = strings.Replace(suffix, "-", "0", 1) + } + return suffix +} + +// WriteFileAtomic creates a temporary file with data and provided perm and // swaps it atomically with filename if successful. -func WriteFileAtomic(filename string, data []byte, perm os.FileMode) error { +func WriteFileAtomic(filename string, data []byte, perm os.FileMode) (err error) { + // This implementation is inspired by the golang stdlibs method of creating + // tempfiles. Notable differences are that we use different flags, a 64 bit LCG + // and handle negatives differently. + // The core reason we can't use golang's TempFile is that we must write + // to the file synchronously, as we need this to persist to disk. + // We also open it in write-only mode, to avoid concerns that arise with read. var ( dir = filepath.Dir(filename) - // Create in case it doesn't exist and force kernel - // flush, which still leaves the potential of lingering disk cache. - // Never overwrites files - flag = os.O_WRONLY | os.O_CREATE | os.O_SYNC | os.O_TRUNC | os.O_EXCL + f *os.File ) - tempFile := filepath.Join(dir, "write-file-atomic-"+RandStr(32)) - f, err := os.OpenFile(tempFile, flag, perm) - if err != nil { - return err + nconflict := 0 + // Limit the number of attempts to create a file. Something is seriously + // wrong if it didn't get created after 1000 attempts, and we don't want + // an infinite loop + i := 0 + for ; i < atomicWriteFileMaxNumWriteAttempts; i++ { + name := filepath.Join(dir, atomicWriteFilePrefix+randWriteFileSuffix()) + f, err = os.OpenFile(name, atomicWriteFileFlag, perm) + // If the file already exists, try a new file + if os.IsExist(err) { + // If the files exists too many times, start reseeding as we've + // likely hit another instances seed. + if nconflict++; nconflict > atomicWriteFileMaxNumConflicts { + atomicWriteFileRandMu.Lock() + atomicWriteFileRand = writeFileRandReseed() + atomicWriteFileRandMu.Unlock() + } + continue + } else if err != nil { + return err + } + break } + if i == atomicWriteFileMaxNumWriteAttempts { + return fmt.Errorf("Could not create atomic write file after %d attempts", i) + } + // Clean up in any case. Defer stacking order is last-in-first-out. defer os.Remove(f.Name()) defer f.Close() diff --git a/libs/common/tempfile_test.go b/libs/common/tempfile_test.go new file mode 100644 index 000000000..51da90913 --- /dev/null +++ b/libs/common/tempfile_test.go @@ -0,0 +1,138 @@ +package common + +// Need access to internal variables, so can't use _test package + +import ( + "bytes" + fmt "fmt" + "io/ioutil" + "os" + testing "testing" + + "github.com/stretchr/testify/require" +) + +func TestWriteFileAtomic(t *testing.T) { + var ( + data = []byte(RandStr(RandIntn(2048))) + old = RandBytes(RandIntn(2048)) + perm os.FileMode = 0600 + ) + + f, err := ioutil.TempFile("/tmp", "write-atomic-test-") + if err != nil { + t.Fatal(err) + } + defer os.Remove(f.Name()) + + if err = ioutil.WriteFile(f.Name(), old, 0664); err != nil { + t.Fatal(err) + } + + if err = WriteFileAtomic(f.Name(), data, perm); err != nil { + t.Fatal(err) + } + + rData, err := ioutil.ReadFile(f.Name()) + if err != nil { + t.Fatal(err) + } + + if !bytes.Equal(data, rData) { + t.Fatalf("data mismatch: %v != %v", data, rData) + } + + stat, err := os.Stat(f.Name()) + if err != nil { + t.Fatal(err) + } + + if have, want := stat.Mode().Perm(), perm; have != want { + t.Errorf("have %v, want %v", have, want) + } +} + +// This tests atomic write file when there is a single duplicate file. +// Expected behavior is for a new file to be created, and the original write file to be unaltered. +func TestWriteFileAtomicDuplicateFile(t *testing.T) { + var ( + defaultSeed uint64 = 1 + testString = "This is a glorious test string" + expectedString = "Did the test file's string appear here?" + + fileToWrite = "/tmp/TestWriteFileAtomicDuplicateFile-test.txt" + ) + // Create a file at the seed, and reset the seed. + atomicWriteFileRand = defaultSeed + firstFileRand := randWriteFileSuffix() + atomicWriteFileRand = defaultSeed + fname := "/tmp/" + atomicWriteFilePrefix + firstFileRand + f, err := os.OpenFile(fname, atomicWriteFileFlag, 0777) + defer os.Remove(fname) + // Defer here, in case there is a panic in WriteFileAtomic. + defer os.Remove(fileToWrite) + + require.Nil(t, err) + f.WriteString(testString) + WriteFileAtomic(fileToWrite, []byte(expectedString), 0777) + // Check that the first atomic file was untouched + firstAtomicFileBytes, err := ioutil.ReadFile(fname) + require.Nil(t, err, "Error reading first atomic file") + require.Equal(t, []byte(testString), firstAtomicFileBytes, "First atomic file was overwritten") + // Check that the resultant file is correct + resultantFileBytes, err := ioutil.ReadFile(fileToWrite) + require.Nil(t, err, "Error reading resultant file") + require.Equal(t, []byte(expectedString), resultantFileBytes, "Written file had incorrect bytes") + + // Check that the intermediate write file was deleted + // Get the second write files' randomness + atomicWriteFileRand = defaultSeed + _ = randWriteFileSuffix() + secondFileRand := randWriteFileSuffix() + _, err = os.Stat("/tmp/" + atomicWriteFilePrefix + secondFileRand) + require.True(t, os.IsNotExist(err), "Intermittent atomic write file not deleted") +} + +// This tests atomic write file when there are many duplicate files. +// Expected behavior is for a new file to be created under a completely new seed, +// and the original write files to be unaltered. +func TestWriteFileAtomicManyDuplicates(t *testing.T) { + var ( + defaultSeed uint64 = 2 + testString = "This is a glorious test string, from file %d" + expectedString = "Did any of the test file's string appear here?" + + fileToWrite = "/tmp/TestWriteFileAtomicDuplicateFile-test.txt" + ) + // Initialize all of the atomic write files + atomicWriteFileRand = defaultSeed + for i := 0; i < atomicWriteFileMaxNumConflicts+2; i++ { + fileRand := randWriteFileSuffix() + fname := "/tmp/" + atomicWriteFilePrefix + fileRand + f, err := os.OpenFile(fname, atomicWriteFileFlag, 0777) + require.Nil(t, err) + f.WriteString(fmt.Sprintf(testString, i)) + defer os.Remove(fname) + } + + atomicWriteFileRand = defaultSeed + // Defer here, in case there is a panic in WriteFileAtomic. + defer os.Remove(fileToWrite) + + WriteFileAtomic(fileToWrite, []byte(expectedString), 0777) + // Check that all intermittent atomic file were untouched + atomicWriteFileRand = defaultSeed + for i := 0; i < atomicWriteFileMaxNumConflicts+2; i++ { + fileRand := randWriteFileSuffix() + fname := "/tmp/" + atomicWriteFilePrefix + fileRand + firstAtomicFileBytes, err := ioutil.ReadFile(fname) + require.Nil(t, err, "Error reading first atomic file") + require.Equal(t, []byte(fmt.Sprintf(testString, i)), firstAtomicFileBytes, + "atomic write file %d was overwritten", i) + } + + // Check that the resultant file is correct + resultantFileBytes, err := ioutil.ReadFile(fileToWrite) + require.Nil(t, err, "Error reading resultant file") + require.Equal(t, []byte(expectedString), resultantFileBytes, "Written file had incorrect bytes") +} From a83eed104c13813fb5b4f9b94e40470f88f2f863 Mon Sep 17 00:00:00 2001 From: ValarDragon Date: Mon, 30 Jul 2018 16:19:33 -0700 Subject: [PATCH 11/16] libs/cmn: Remove Tempfile, Tempdir, switch to ioutil variants (#2114) Our Tempfile was just a wrapper on ioutil that panicked instead of error. Our Tempdir was a less safe variant of ioutil's Tempdir. --- CHANGELOG_PENDING.md | 2 +- consensus/common_test.go | 7 +++++-- libs/autofile/autofile_test.go | 9 +++++++-- libs/common/tempfile.go | 24 ------------------------ libs/db/backend_test.go | 5 +++-- libs/db/common_test.go | 6 +++--- privval/priv_validator_test.go | 32 +++++++++++++++++++------------- 7 files changed, 38 insertions(+), 47 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 481f5b452..a65c6e45c 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -22,6 +22,6 @@ IMPROVEMENTS: - [common] bit array functions which take in another parameter are now thread safe BUG FIXES: -- [common] \#2109 Safely handle cases where atomic write files already exist +- [common] Safely handle cases where atomic write files already exist [#2109](https://github.com/tendermint/tendermint/issues/2109) - [privval] fix a deadline for accepting new connections in socket private validator. diff --git a/consensus/common_test.go b/consensus/common_test.go index 992b6fcd6..f4855992d 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -378,8 +378,11 @@ func randConsensusNetWithPeers(nValidators, nPeers int, testName string, tickerF if i < nValidators { privVal = privVals[i] } else { - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal = privval.GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + if err != nil { + panic(err) + } + privVal = privval.GenFilePV(tempFile.Name()) } app := appFunc() diff --git a/libs/autofile/autofile_test.go b/libs/autofile/autofile_test.go index b39fb7cf3..67397380b 100644 --- a/libs/autofile/autofile_test.go +++ b/libs/autofile/autofile_test.go @@ -1,6 +1,7 @@ package autofile import ( + "io/ioutil" "os" "sync/atomic" "syscall" @@ -13,10 +14,14 @@ import ( func TestSIGHUP(t *testing.T) { // First, create an AutoFile writing to a tempfile dir - file, name := cmn.Tempfile("sighup_test") - if err := file.Close(); err != nil { + file, err := ioutil.TempFile("", "sighup_test") + if err != nil { t.Fatalf("Error creating tempfile: %v", err) } + if err := file.Close(); err != nil { + t.Fatalf("Error closing tempfile: %v", err) + } + name := file.Name() // Here is the actual AutoFile af, err := OpenAutoFile(name) if err != nil { diff --git a/libs/common/tempfile.go b/libs/common/tempfile.go index bc1343e5d..a5bb7a5b5 100644 --- a/libs/common/tempfile.go +++ b/libs/common/tempfile.go @@ -3,7 +3,6 @@ package common import ( fmt "fmt" "io" - "io/ioutil" "os" "path/filepath" "strconv" @@ -127,26 +126,3 @@ func WriteFileAtomic(filename string, data []byte, perm os.FileMode) (err error) return os.Rename(f.Name(), filename) } - -//-------------------------------------------------------------------------------- - -func Tempfile(prefix string) (*os.File, string) { - file, err := ioutil.TempFile("", prefix) - if err != nil { - PanicCrisis(err) - } - return file, file.Name() -} - -func Tempdir(prefix string) (*os.File, string) { - tempDir := os.TempDir() + "/" + prefix + RandStr(12) - err := EnsureDir(tempDir, 0700) - if err != nil { - panic(Fmt("Error creating temp dir: %v", err)) - } - dir, err := os.Open(tempDir) - if err != nil { - panic(Fmt("Error opening temp dir: %v", err)) - } - return dir, tempDir -} diff --git a/libs/db/backend_test.go b/libs/db/backend_test.go index 493ed83f9..b31b4d74a 100644 --- a/libs/db/backend_test.go +++ b/libs/db/backend_test.go @@ -2,6 +2,7 @@ package db import ( "fmt" + "io/ioutil" "os" "path/filepath" "testing" @@ -17,8 +18,8 @@ func cleanupDBDir(dir, name string) { func testBackendGetSetDelete(t *testing.T, backend DBBackendType) { // Default - dir, dirname := cmn.Tempdir(fmt.Sprintf("test_backend_%s_", backend)) - defer dir.Close() + dirname, err := ioutil.TempDir("", fmt.Sprintf("test_backend_%s_", backend)) + require.Nil(t, err) db := NewDB("testdb", backend, dirname) // A nonexistent key should return nil, even if the key is empty diff --git a/libs/db/common_test.go b/libs/db/common_test.go index 027b8ee53..68420cd2b 100644 --- a/libs/db/common_test.go +++ b/libs/db/common_test.go @@ -2,12 +2,12 @@ package db import ( "fmt" + "io/ioutil" "sync" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - cmn "github.com/tendermint/tendermint/libs/common" ) //---------------------------------------- @@ -61,9 +61,9 @@ func checkValuePanics(t *testing.T, itr Iterator) { } func newTempDB(t *testing.T, backend DBBackendType) (db DB) { - dir, dirname := cmn.Tempdir("db_common_test") + dirname, err := ioutil.TempDir("", "db_common_test") + require.Nil(t, err) db = NewDB("testdb", backend, dirname) - dir.Close() return db } diff --git a/privval/priv_validator_test.go b/privval/priv_validator_test.go index 7c9c93fcf..127f5c1f3 100644 --- a/privval/priv_validator_test.go +++ b/privval/priv_validator_test.go @@ -3,6 +3,7 @@ package privval import ( "encoding/base64" "fmt" + "io/ioutil" "os" "testing" "time" @@ -11,22 +12,22 @@ import ( "github.com/stretchr/testify/require" "github.com/tendermint/tendermint/crypto" "github.com/tendermint/tendermint/crypto/ed25519" - cmn "github.com/tendermint/tendermint/libs/common" "github.com/tendermint/tendermint/types" ) func TestGenLoadValidator(t *testing.T) { assert := assert.New(t) - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal := GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + privVal := GenFilePV(tempFile.Name()) height := int64(100) privVal.LastHeight = height privVal.Save() addr := privVal.GetAddress() - privVal = LoadFilePV(tempFilePath) + privVal = LoadFilePV(tempFile.Name()) assert.Equal(addr, privVal.GetAddress(), "expected privval addr to be the same") assert.Equal(height, privVal.LastHeight, "expected privval.LastHeight to have been saved") } @@ -34,7 +35,9 @@ func TestGenLoadValidator(t *testing.T) { func TestLoadOrGenValidator(t *testing.T) { assert := assert.New(t) - _, tempFilePath := cmn.Tempfile("priv_validator_") + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + tempFilePath := tempFile.Name() if err := os.Remove(tempFilePath); err != nil { t.Error(err) } @@ -91,8 +94,9 @@ func TestUnmarshalValidator(t *testing.T) { func TestSignVote(t *testing.T) { assert := assert.New(t) - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal := GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + privVal := GenFilePV(tempFile.Name()) block1 := types.BlockID{[]byte{1, 2, 3}, types.PartSetHeader{}} block2 := types.BlockID{[]byte{3, 2, 1}, types.PartSetHeader{}} @@ -101,7 +105,7 @@ func TestSignVote(t *testing.T) { // sign a vote for first time vote := newVote(privVal.Address, 0, height, round, voteType, block1) - err := privVal.SignVote("mychainid", vote) + err = privVal.SignVote("mychainid", vote) assert.NoError(err, "expected no error signing vote") // try to sign the same vote again; should be fine @@ -132,8 +136,9 @@ func TestSignVote(t *testing.T) { func TestSignProposal(t *testing.T) { assert := assert.New(t) - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal := GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + privVal := GenFilePV(tempFile.Name()) block1 := types.PartSetHeader{5, []byte{1, 2, 3}} block2 := types.PartSetHeader{10, []byte{3, 2, 1}} @@ -141,7 +146,7 @@ func TestSignProposal(t *testing.T) { // sign a proposal for first time proposal := newProposal(height, round, block1) - err := privVal.SignProposal("mychainid", proposal) + err = privVal.SignProposal("mychainid", proposal) assert.NoError(err, "expected no error signing proposal") // try to sign the same proposal again; should be fine @@ -170,8 +175,9 @@ func TestSignProposal(t *testing.T) { } func TestDifferByTimestamp(t *testing.T) { - _, tempFilePath := cmn.Tempfile("priv_validator_") - privVal := GenFilePV(tempFilePath) + tempFile, err := ioutil.TempFile("", "priv_validator_") + require.Nil(t, err) + privVal := GenFilePV(tempFile.Name()) block1 := types.PartSetHeader{5, []byte{1, 2, 3}} height, round := int64(10), 1 From 08ad162daaef7309203653864017153211b80887 Mon Sep 17 00:00:00 2001 From: Zarko Milosevic Date: Tue, 31 Jul 2018 21:19:57 +0300 Subject: [PATCH 12/16] docs: Modify blockchain spec to reflect validator set changes (#2107) --- docs/spec/blockchain/blockchain.md | 38 +++++++++++++++++------------- docs/spec/blockchain/state.md | 5 ++-- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/docs/spec/blockchain/blockchain.md b/docs/spec/blockchain/blockchain.md index eb34f4c87..e3171818a 100644 --- a/docs/spec/blockchain/blockchain.md +++ b/docs/spec/blockchain/blockchain.md @@ -52,7 +52,8 @@ type Header struct { // application ResultsHash []byte // SimpleMerkle of []abci.Result from prevBlock AppHash []byte // Arbitrary state digest - ValidatorsHash []byte // SimpleMerkle of the ValidatorSet + ValidatorsHash []byte // SimpleMerkle of the current ValidatorSet + NextValidatorsHash []byte // SimpleMerkle of the next ValidatorSet ConsensusParamsHash []byte // SimpleMerkle of the ConsensusParams // consensus @@ -160,9 +161,12 @@ We refer to certain globally available objects: `block` is the block under consideration, `prevBlock` is the `block` at the previous height, and `state` keeps track of the validator set, the consensus parameters -and other results from the application. +and other results from the application. At the point when `block` is the block under consideration, +the current version of the `state` corresponds to the state +after executing transactions from the `prevBlock`. Elements of an object are accessed as expected, -ie. `block.Header`. See [here](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/state.md) for the definition of `state`. +ie. `block.Header`. +See [here](https://github.com/tendermint/tendermint/blob/master/docs/spec/blockchain/state.md) for the definition of `state`. ### Header @@ -278,7 +282,14 @@ block.ValidatorsHash == SimpleMerkleRoot(state.Validators) Simple Merkle root of the current validator set that is committing the block. This can be used to validate the `LastCommit` included in the next block. -May be updated by the application. + +### NextValidatorsHash + +```go +block.NextValidatorsHash == SimpleMerkleRoot(state.NextValidators) +``` +Simple Merkle root of the next validator set that will be the validator set that commits the next block. +Modifications to the validator set are defined by the application. ### ConsensusParamsHash @@ -407,25 +418,20 @@ set (TODO). Execute is defined as: ```go Execute(s State, app ABCIApp, block Block) State { - TODO: just spell out ApplyBlock here - and remove ABCIResponses struct. - abciResponses := app.ApplyBlock(block) + // Fuction ApplyBlock executes block of transactions against the app and returns the new root hash of the app state, + // modifications to the validator set and the changes of the consensus parameters. + AppHash, ValidatorChanges, ConsensusParamChanges := app.ApplyBlock(block) return State{ LastResults: abciResponses.DeliverTxResults, - AppHash: abciResponses.AppHash, - Validators: UpdateValidators(state.Validators, abciResponses.ValidatorChanges), + AppHash: AppHash, LastValidators: state.Validators, - ConsensusParams: UpdateConsensusParams(state.ConsensusParams, abci.Responses.ConsensusParamChanges), + Validators: state.NextValidators, + NextValidators: UpdateValidators(state.NextValidators, ValidatorChanges), + ConsensusParams: UpdateConsensusParams(state.ConsensusParams, ConsensusParamChanges), } } -type ABCIResponses struct { - DeliverTxResults []Result - ValidatorChanges []Validator - ConsensusParamChanges ConsensusParams - AppHash []byte -} ``` diff --git a/docs/spec/blockchain/state.md b/docs/spec/blockchain/state.md index 3b374f70a..df86cd450 100644 --- a/docs/spec/blockchain/state.md +++ b/docs/spec/blockchain/state.md @@ -3,7 +3,7 @@ ## State The state contains information whose cryptographic digest is included in block headers, and thus is -necessary for validating new blocks. For instance, the set of validators and the results of +necessary for validating new blocks. For instance, the validators set and the results of transactions are never included in blocks, but their Merkle roots are - the state keeps track of them. Note that the `State` object itself is an implementation detail, since it is never @@ -18,8 +18,9 @@ type State struct { LastResults []Result AppHash []byte - Validators []Validator LastValidators []Validator + Validators []Validator + NextValidators []Validator ConsensusParams ConsensusParams } From 6fb2f44cc33027e3e70963b5029dc64314975bcf Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Tue, 31 Jul 2018 13:09:01 -0700 Subject: [PATCH 13/16] p2p: Connect to peers from a seed node immediately (#2115) This is to reduce wait times when initially connecting. This still runs checks such as whether you still want additional peers. A test case has been created, which fails if this change is not included. --- CHANGELOG_PENDING.md | 1 + p2p/pex/pex_reactor.go | 28 +++++--- p2p/pex/pex_reactor_test.go | 129 ++++++++++++++++++++++++++++-------- 3 files changed, 121 insertions(+), 37 deletions(-) diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index a65c6e45c..e85a6ed64 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -20,6 +20,7 @@ IMPROVEMENTS: - only process one block at a time to avoid starving - [crypto] Switch hkdfchachapoly1305 to xchachapoly1305 - [common] bit array functions which take in another parameter are now thread safe +- [p2p] begin connecting to peers as soon a seed node provides them to you ([#2093](https://github.com/tendermint/tendermint/issues/2093)) BUG FIXES: - [common] Safely handle cases where atomic write files already exist [#2109](https://github.com/tendermint/tendermint/issues/2109) diff --git a/p2p/pex/pex_reactor.go b/p2p/pex/pex_reactor.go index 2929d9336..c59b3797d 100644 --- a/p2p/pex/pex_reactor.go +++ b/p2p/pex/pex_reactor.go @@ -74,6 +74,8 @@ type PEXReactor struct { requestsSent *cmn.CMap // ID->struct{}: unanswered send requests lastReceivedRequests *cmn.CMap // ID->time.Time: last time peer requested from us + seedAddrs []*p2p.NetAddress + attemptsToDial sync.Map // address (string) -> {number of attempts (int), last time dialed (time.Time)} } @@ -120,10 +122,13 @@ func (r *PEXReactor) OnStart() error { // return err if user provided a bad seed address // or a host name that we cant resolve - if err := r.checkSeeds(); err != nil { + seedAddrs, err := r.checkSeeds() + if err != nil { return err } + r.seedAddrs = seedAddrs + // Check if this node should run // in seed/crawler mode if r.config.SeedMode { @@ -281,7 +286,6 @@ func (r *PEXReactor) RequestAddrs(p Peer) { // request for this peer and deletes the open request. // If there's no open request for the src peer, it returns an error. func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error { - id := string(src.ID()) if !r.requestsSent.Has(id) { return cmn.NewError("Received unsolicited pexAddrsMessage") @@ -297,6 +301,13 @@ func (r *PEXReactor) ReceiveAddrs(addrs []*p2p.NetAddress, src Peer) error { err := r.book.AddAddress(netAddr, srcAddr) r.logErrAddrBook(err) + + // If this address came from a seed node, try to connect to it without waiting. + for _, seedAddr := range r.seedAddrs { + if seedAddr.Equals(srcAddr) { + r.ensurePeers() + } + } } return nil } @@ -468,18 +479,18 @@ func (r *PEXReactor) dialPeer(addr *p2p.NetAddress) { } // check seed addresses are well formed -func (r *PEXReactor) checkSeeds() error { +func (r *PEXReactor) checkSeeds() ([]*p2p.NetAddress, error) { lSeeds := len(r.config.Seeds) if lSeeds == 0 { - return nil + return nil, nil } - _, errs := p2p.NewNetAddressStrings(r.config.Seeds) + netAddrs, errs := p2p.NewNetAddressStrings(r.config.Seeds) for _, err := range errs { if err != nil { - return err + return nil, err } } - return nil + return netAddrs, nil } // randomly dial seeds until we connect to one or exhaust them @@ -488,13 +499,12 @@ func (r *PEXReactor) dialSeeds() { if lSeeds == 0 { return } - seedAddrs, _ := p2p.NewNetAddressStrings(r.config.Seeds) perm := cmn.RandPerm(lSeeds) // perm := r.Switch.rng.Perm(lSeeds) for _, i := range perm { // dial a random seed - seedAddr := seedAddrs[i] + seedAddr := r.seedAddrs[i] err := r.Switch.DialPeerWithAddress(seedAddr, false) if err == nil { return diff --git a/p2p/pex/pex_reactor_test.go b/p2p/pex/pex_reactor_test.go index 8d54693fe..36f38c570 100644 --- a/p2p/pex/pex_reactor_test.go +++ b/p2p/pex/pex_reactor_test.go @@ -211,31 +211,26 @@ func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) { defer os.RemoveAll(dir) // nolint: errcheck // 1. create seed - seed := p2p.MakeSwitch( - cfg, - 0, - "127.0.0.1", - "123.123.123", - func(i int, sw *p2p.Switch) *p2p.Switch { - book := NewAddrBook(filepath.Join(dir, "addrbook0.json"), false) - book.SetLogger(log.TestingLogger()) - sw.SetAddrBook(book) - - sw.SetLogger(log.TestingLogger()) - - r := NewPEXReactor(book, &PEXReactorConfig{}) - r.SetLogger(log.TestingLogger()) - sw.AddReactor("pex", r) - return sw - }, - ) - seed.AddListener( - p2p.NewDefaultListener("tcp://"+seed.NodeInfo().ListenAddr, "", false, log.TestingLogger()), - ) + seed := testCreateSeed(dir, 0, []*p2p.NetAddress{}, []*p2p.NetAddress{}) require.Nil(t, seed.Start()) defer seed.Stop() // 2. create usual peer with only seed configured. + peer := testCreatePeerWithSeed(dir, 1, seed) + require.Nil(t, peer.Start()) + defer peer.Stop() + + // 3. check that the peer connects to seed immediately + assertPeersWithTimeout(t, []*p2p.Switch{peer}, 10*time.Millisecond, 3*time.Second, 1) +} + +func TestConnectionSpeedForPeerReceivedFromSeed(t *testing.T) { + // directory to store address books + dir, err := ioutil.TempDir("", "pex_reactor") + require.Nil(t, err) + defer os.RemoveAll(dir) // nolint: errcheck + + // 1. create peer peer := p2p.MakeSwitch( cfg, 1, @@ -250,20 +245,34 @@ func TestPEXReactorUsesSeedsIfNeeded(t *testing.T) { r := NewPEXReactor( book, - &PEXReactorConfig{ - Seeds: []string{seed.NodeInfo().NetAddress().String()}, - }, + &PEXReactorConfig{}, ) r.SetLogger(log.TestingLogger()) sw.AddReactor("pex", r) return sw }, ) + peer.AddListener( + p2p.NewDefaultListener("tcp://"+peer.NodeInfo().ListenAddr, "", false, log.TestingLogger()), + ) require.Nil(t, peer.Start()) defer peer.Stop() - // 3. check that the peer connects to seed immediately - assertPeersWithTimeout(t, []*p2p.Switch{peer}, 10*time.Millisecond, 3*time.Second, 1) + // 2. Create seed which knows about the peer + seed := testCreateSeed(dir, 2, []*p2p.NetAddress{peer.NodeInfo().NetAddress()}, []*p2p.NetAddress{peer.NodeInfo().NetAddress()}) + require.Nil(t, seed.Start()) + defer seed.Stop() + + // 3. create another peer with only seed configured. + secondPeer := testCreatePeerWithSeed(dir, 3, seed) + require.Nil(t, secondPeer.Start()) + defer secondPeer.Stop() + + // 4. check that the second peer connects to seed immediately + assertPeersWithTimeout(t, []*p2p.Switch{secondPeer}, 10*time.Millisecond, 3*time.Second, 1) + + // 5. check that the second peer connects to the first peer immediately + assertPeersWithTimeout(t, []*p2p.Switch{secondPeer}, 10*time.Millisecond, 1*time.Second, 2) } func TestPEXReactorCrawlStatus(t *testing.T) { @@ -401,6 +410,7 @@ func assertPeersWithTimeout( outbound, inbound, _ := s.NumPeers() if outbound+inbound < nPeers { allGood = false + break } } remaining -= checkPeriod @@ -417,14 +427,77 @@ func assertPeersWithTimeout( numPeersStr += fmt.Sprintf("%d => {outbound: %d, inbound: %d}, ", i, outbound, inbound) } t.Errorf( - "expected all switches to be connected to at least one peer (switches: %s)", - numPeersStr, + "expected all switches to be connected to at least %d peer(s) (switches: %s)", + nPeers, numPeersStr, ) return } } } +// Creates a seed which knows about the provided addresses / source address pairs. +// Starting and stopping the seed is left to the caller +func testCreateSeed(dir string, id int, knownAddrs, srcAddrs []*p2p.NetAddress) *p2p.Switch { + seed := p2p.MakeSwitch( + cfg, + id, + "127.0.0.1", + "123.123.123", + func(i int, sw *p2p.Switch) *p2p.Switch { + book := NewAddrBook(filepath.Join(dir, "addrbookSeed.json"), false) + book.SetLogger(log.TestingLogger()) + for j := 0; j < len(knownAddrs); j++ { + book.AddAddress(knownAddrs[j], srcAddrs[j]) + book.MarkGood(knownAddrs[j]) + } + sw.SetAddrBook(book) + + sw.SetLogger(log.TestingLogger()) + + r := NewPEXReactor(book, &PEXReactorConfig{}) + r.SetLogger(log.TestingLogger()) + sw.AddReactor("pex", r) + return sw + }, + ) + seed.AddListener( + p2p.NewDefaultListener("tcp://"+seed.NodeInfo().ListenAddr, "", false, log.TestingLogger()), + ) + return seed +} + +// Creates a peer which knows about the provided seed. +// Starting and stopping the peer is left to the caller +func testCreatePeerWithSeed(dir string, id int, seed *p2p.Switch) *p2p.Switch { + peer := p2p.MakeSwitch( + cfg, + id, + "127.0.0.1", + "123.123.123", + func(i int, sw *p2p.Switch) *p2p.Switch { + book := NewAddrBook(filepath.Join(dir, fmt.Sprintf("addrbook%d.json", id)), false) + book.SetLogger(log.TestingLogger()) + sw.SetAddrBook(book) + + sw.SetLogger(log.TestingLogger()) + + r := NewPEXReactor( + book, + &PEXReactorConfig{ + Seeds: []string{seed.NodeInfo().NetAddress().String()}, + }, + ) + r.SetLogger(log.TestingLogger()) + sw.AddReactor("pex", r) + return sw + }, + ) + peer.AddListener( + p2p.NewDefaultListener("tcp://"+peer.NodeInfo().ListenAddr, "", false, log.TestingLogger()), + ) + return peer +} + func createReactor(conf *PEXReactorConfig) (r *PEXReactor, book *addrBook) { // directory to store address book dir, err := ioutil.TempDir("", "pex_reactor") From dde96b75ce3684283f980b968b9edb29ecdff973 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Wed, 1 Aug 2018 02:57:31 -0700 Subject: [PATCH 14/16] abci: Update readme for building protoc (#2124) --- abci/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/abci/README.md b/abci/README.md index 6de9f7069..493d862f0 100644 --- a/abci/README.md +++ b/abci/README.md @@ -29,7 +29,7 @@ The two guides to focus on are the `Application Development Guide` and `Using AB To compile the protobuf file, run: ``` -make protoc +cd $GOPATH/src/github.com/tendermint/tendermint/; make protoc_abci ``` See `protoc --help` and [the Protocol Buffers site](https://developers.google.com/protocol-buffers) From 023bb99eb07916f20e867b928a19f7e0efc790f9 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Wed, 1 Aug 2018 12:06:30 -0700 Subject: [PATCH 15/16] p2p: Add test vectors for deriving secrets (#2120) These test vectors are needed for comparison with the Rust implementation. To implement this effectively, a "RandBool" method was added to cmn.Rand. --- libs/common/random.go | 11 +++ p2p/conn/secret_connection_test.go | 68 +++++++++++++++++++ ...TestDeriveSecretsAndChallengeGolden.golden | 32 +++++++++ 3 files changed, 111 insertions(+) create mode 100644 p2p/conn/testdata/TestDeriveSecretsAndChallengeGolden.golden diff --git a/libs/common/random.go b/libs/common/random.go index 51bfd15c4..4b0594d0e 100644 --- a/libs/common/random.go +++ b/libs/common/random.go @@ -109,6 +109,10 @@ func RandInt63n(n int64) int64 { return grand.Int63n(n) } +func RandBool() bool { + return grand.Bool() +} + func RandFloat32() float32 { return grand.Float32() } @@ -274,6 +278,13 @@ func (r *Rand) Intn(n int) int { return i } +// Bool returns a uniformly random boolean +func (r *Rand) Bool() bool { + // See https://github.com/golang/go/issues/23804#issuecomment-365370418 + // for reasoning behind computing like this + return r.Int63()%2 == 0 +} + // Perm returns a pseudo-random permutation of n integers in [0, n). func (r *Rand) Perm(n int) []int { r.Lock() diff --git a/p2p/conn/secret_connection_test.go b/p2p/conn/secret_connection_test.go index 27dca034a..75ed8fe02 100644 --- a/p2p/conn/secret_connection_test.go +++ b/p2p/conn/secret_connection_test.go @@ -1,8 +1,16 @@ package conn import ( + "bufio" + "encoding/hex" + "flag" "fmt" "io" + "log" + "os" + "path/filepath" + "strconv" + "strings" "testing" "github.com/stretchr/testify/assert" @@ -208,6 +216,66 @@ func TestSecretConnectionReadWrite(t *testing.T) { } +// Run go test -update from within this module +// to update the golden test vector file +var update = flag.Bool("update", false, "update .golden files") + +func TestDeriveSecretsAndChallengeGolden(t *testing.T) { + goldenFilepath := filepath.Join("testdata", t.Name()+".golden") + if *update { + t.Logf("Updating golden test vector file %s", goldenFilepath) + data := createGoldenTestVectors(t) + cmn.WriteFile(goldenFilepath, []byte(data), 0644) + } + f, err := os.Open(goldenFilepath) + if err != nil { + log.Fatal(err) + } + defer f.Close() + scanner := bufio.NewScanner(f) + for scanner.Scan() { + line := scanner.Text() + params := strings.Split(line, ",") + randSecretVector, err := hex.DecodeString(params[0]) + require.Nil(t, err) + randSecret := new([32]byte) + copy((*randSecret)[:], randSecretVector) + locIsLeast, err := strconv.ParseBool(params[1]) + require.Nil(t, err) + expectedRecvSecret, err := hex.DecodeString(params[2]) + require.Nil(t, err) + expectedSendSecret, err := hex.DecodeString(params[3]) + require.Nil(t, err) + expectedChallenge, err := hex.DecodeString(params[4]) + require.Nil(t, err) + + recvSecret, sendSecret, challenge := deriveSecretAndChallenge(randSecret, locIsLeast) + require.Equal(t, expectedRecvSecret, (*recvSecret)[:], "Recv Secrets aren't equal") + require.Equal(t, expectedSendSecret, (*sendSecret)[:], "Send Secrets aren't equal") + require.Equal(t, expectedChallenge, (*challenge)[:], "challenges aren't equal") + } +} + +// Creates the data for a test vector file. +// The file format is: +// Hex(diffie_hellman_secret), loc_is_least, Hex(recvSecret), Hex(sendSecret), Hex(challenge) +func createGoldenTestVectors(t *testing.T) string { + data := "" + for i := 0; i < 32; i++ { + randSecretVector := cmn.RandBytes(32) + randSecret := new([32]byte) + copy((*randSecret)[:], randSecretVector) + data += hex.EncodeToString((*randSecret)[:]) + "," + locIsLeast := cmn.RandBool() + data += strconv.FormatBool(locIsLeast) + "," + recvSecret, sendSecret, challenge := deriveSecretAndChallenge(randSecret, locIsLeast) + data += hex.EncodeToString((*recvSecret)[:]) + "," + data += hex.EncodeToString((*sendSecret)[:]) + "," + data += hex.EncodeToString((*challenge)[:]) + "\n" + } + return data +} + func BenchmarkSecretConnection(b *testing.B) { b.StopTimer() fooSecConn, barSecConn := makeSecretConnPair(b) diff --git a/p2p/conn/testdata/TestDeriveSecretsAndChallengeGolden.golden b/p2p/conn/testdata/TestDeriveSecretsAndChallengeGolden.golden new file mode 100644 index 000000000..eb69b29fe --- /dev/null +++ b/p2p/conn/testdata/TestDeriveSecretsAndChallengeGolden.golden @@ -0,0 +1,32 @@ +9fe4a5a73df12dbd8659b1d9280873fe993caefec6b0ebc2686dd65027148e03,true,80a83ad6afcb6f8175192e41973aed31dd75e3c106f813d986d9567a4865eb2f,96362a04f628a0666d9866147326898bb0847b8db8680263ad19e6336d4eed9e,2632c3fd20f456c5383ed16aa1d56dc7875a2b0fc0d5ff053c3ada8934098c69 +0716764b370d543fee692af03832c16410f0a56e4ddb79604ea093b10bb6f654,false,84f2b1e8658456529a2c324f46c3406c3c6fecd5fbbf9169f60bed8956a8b03d,cba357ae33d7234520d5742102a2a6cdb39b7db59c14a58fa8aadd310127630f,576643a8fcc1a4cf866db900f4a150dbe35d44a1b3ff36e4911565c3fa22fc32 +358dd73aae2c5b7b94b57f950408a3c681e748777ecab2063c8ca51a63588fa8,false,c2e2f664c8ee561af8e1e30553373be4ae23edecc8c6bd762d44b2afb7f2a037,d1563f428ac1c023c15d8082b2503157fe9ecbde4fb3493edd69ebc299b4970c,89fb6c6439b12fe11a4c604b8ad883f7dc76be33df590818fe5eb15ddb01face +0958308bdb583e639dd399a98cd21077d834b4b5e30771275a5a73a62efcc7e0,false,523c0ae97039173566f7ab4b8f271d8d78feef5a432d618e58ced4f80f7c1696,c1b743401c6e4508e62b8245ea7c3252bbad082e10af10e80608084d63877977,d7c52adf12ebc69677aec4bd387b0c5a35570fe61cb7b8ae55f3ab14b1b79be0 +d93d134e72f58f177642ac30f36b2d3cd4720aa7e60feb1296411a9009cf4524,false,47a427bcc1ef6f0ce31dbf343bc8bbf49554b4dd1e2330fd97d0df23ecdbba10,73e23adb7801179349ecf9c8cdf64d71d64a9f1145ba6730e5d029f99eaf8840,a8fdcb77f591bfba7b8483aa15ae7b42054ba68625d51dec005896dfe910281f +6104474c791cda24d952b356fb41a5d273c0ce6cc87d270b1701d0523cd5aa13,true,1cb4397b9e478430321af4647da2ccbef62ff8888542d31cca3f626766c8080f,673b23318826bd31ad1a4995c6e5095c4b092f5598aa0a96381a3e977bc0eaf9,4a25a25c5f75d6cc512f2ba8c1546e6263e9ef8269f0c046c37838cc66aa83e6 +8a6002503c15cab763e27c53fc449f6854a210c95cdd67e4466b0f2cb46b629c,false,f01ff06aef356c87f8d2646ff9ed8b855497c2ca00ea330661d84ef421a67e63,4f59bb23090010614877265a1597f1a142fa97b7208e1d554435763505f36f6a,1aadcb1c8b5993da102cebcb60c545b03197c98137064530840f45d917ad300e +31a57c6b1fe33beb1f7ebbbfc06d58c4f307cd355b6f9753e58f3edec16c7559,false,13e126c4cb240349dccf0dc843977671d34a1daffd0517d06ed66b703344db22,d491431906a306af45ecf9f1977e32d7f65a79f5139f931760416de27554b687,5ea7e8e3d5a30503423341609d360d246b61a9159fc07f253a46e357977cd745 +71a3c79718b824627faeefdce887d9465b353bd962cc5e97c5b5dfedab457ef9,true,e2e8eea547dcee7eafa89ae41f48ab049beac24935fad75258924fd5273d23cb,45d2e839bf36a3616cbe8a9bdbd4e7b288bf5bf1e6e79c07995eb2b18eb2eaff,7ee50e0810bc9f98e56bc46de5da22d84b3efa52fe5d85db4b2344530ef17ed8 +2e9dba2eb4f9019c2628ff5899744469c26caf793636f30ddb76601751aee968,false,8bfc3b314e4468d4e19c9d28b7bfd5b5532263105273b0fe80801f6146313993,b77d2b223e27038f978ab87a725859f6995f903056bdbd594ab04f0b2cbad517,9032be49a9cbcd1de6fee332f8f24ebf545c05e0175b98c564e7d1e69630ae20 +81322b22c835efb26d78051f3a3840a9d01aa558c019ecfa26483b5c5535728c,true,61eacb7e9665e362ef492ef950cea58f8bc67434ab7ee5545139147adf395da4,0f600ef0c358cae938969f434c2ec0ce3be632fdf5246b7bb8ee3ff294036ecd,a7026b4c21fe225ecd775ae81249405c6f492882eb85f3f8e2232f11e515561e +826b86c5e8cb4173ff2d05c48e3537140c5e0f26f7866bbcd4e57616806e1be2,true,ae44dabd077d227c8d898930a7705a2b785c8849121282106c045bb58b66eb36,24b2c1b1e2a9ebe387df6dfb9fbde6c681e4eeb0a33bb1c3df3789087f56ffe3,b37a64ea97431b25cb271c4c8435f6dd97118b35da57168f3c3c269920f7bbc1 +18b5a7b973d4b263072e69515c5b6ed22191c3d6e851aaba872904672f8344ec,true,ce402af2fb93b6ef18cd406f7c437d3cbfb09141b7a02116b1cfbabbf75ad84a,c86bdb1709ef0f4a31a818843660f83338b9db77e262bb7c6546138e51c6046b,11fcd8e59c4e7f6050d3cd332337db794ae31260c159e409af3ed8f4d6523bf4 +26d10c56872b72bb76ae7c7b3f074afb3d4a364e5e3f8c661be9b4f5a522ea75,true,1c9782a8485c4ecb13904ec551a7f9300ecd687abfbe63c91c7fd583f84a7a4d,ae3f4ccd0dfee8b514f67db2e923714d324935b9ae9e488d088ebb79569d8cc4,8139a3ab728b0e765e4d90549ab8eed7e1048a83267eafa7442208a7f627558a +558838dfcfe94105c46a4ade4548e6c96271d33e6c752661356cc66024615bae,true,d5a38625be74177318072cf877f2427ce2327e9b58d2eb134d0ac52c9126572f,dead938f77007e3164b6eee4cd153433d03ca5d9ec64f41aa6b2d6a069edeeda,4a081a356361da429c564cf7ac8e217121bbe8c5ee5c9632bae0b7ddbe94f9d4 +f4a3f6a93a4827a59682fd8bf1a8e4fd9aaff01a337a86e1966c8fff0e746014,true,39a0aea2a8ac7f0524d63e395a25b98fc3844ed039f20b11058019dca2b3840f,6ff53243426ded506d22501ae0f989d9946b86a8bb2550d7ed6e90fdf41d0e7c,8784e728bf12f465ed20dc6f0e1d949a68e5795d4799536427a6f859547b7fd6 +1717020e1c4fca1b4926dba16671c0c04e4f19c621c646cb4525fa533b1c205c,false,b9a909767f3044608b4e314b149a729bef199f8311310e1ecd2072e5659b7194,7baf0ff4b980919cf545312f45234976f0b6c574aac5b772024f73248aad7538,99a18e1e4b039ef3777a8fdd0d9ffaccaf3b4523b6d26adacfe91cc5fcd9977e +de769062be27b2a4248dd5be315960c8d231738417ece670c2d6a1c52877b59e,true,cc6c2086718b21813513894546e85766d34c754e81fd6a19c12fc322ffb9b1c3,5a7da7500191c65a5f1fbb2a6122717edc70ca0469baf2bbbd6ca8255b93c077,8c0d32091dc687f1399c754a617d224742726bece848b50c35b4db5f0469ace7 +7c5549f36767e02ebf49a4616467199459aa6932dcc091f182f822185659559a,true,d8335e606128b0c621ff6cda99dc62babf4a4436c574c5c478c20122712727d0,0a7c673cccd6f7fd4ed1673f7d0f2cb08961faced123ca901b74581d5bdc8b25,16ac1eb2a39384716c7d490272d87e76c10665fdb331e1883435de175ce4460e +ecf8261ebda248dc7796f98987efe1b7be363a59037c9e61044490d08a077610,true,53def80fcdba01367c0ea36459b57409f59a771f57a8259b54f24785e5656b7d,90140870b3b1e84c9dcf7836eac0581b16fe0a40307619d267c6f871e1efce6a,c6d1836b66c1a722a377c7eb058995a0ef8711839c6d6a0cdd6ad1ff70f935a5 +21c0ef76ce0eae9391ceabfb08a861899db55ac4ccf010ed672599669c6938f2,false,8af5482cc015093f261d5b7ce87035dda41d8318b9960b52cca3e5f0d3f61808,f4d5338bcb57262e1034f01ed3858ca1e5d66a73f18588e72f3dc8c6a730be0c,7ba82c2820c95e3354d9a6ab4920ebcd7938ce19e25930fee58439246b0321b1 +05f3b66d6b0fe906137e60b4719083a2465106badedcdae3a4c91c46c5367340,false,e5c9e074e95c2896fa4093830e96e9cf159b8dcba2ead21f37237cf6e9a9aaa2,b3a0a50309b4ca23cd34363fd8df30e73ec4a275973986c2e11a53752eff0a3b,358a62056ff05f27185b9952d291c6346171937f6811cafbacddd82e17010f39 +fef0251cff7c5d1ba0514f1820a8265453365fd9f5bb8a92f955dc007a40e730,true,e35a0aff6e9060a39c15d276a1337f1948d0be0aef81fcd563a6783115b5283d,20a8efe83474253d70e5fd847df0cd26222cd39e9210687b68c0a23b73429108,2989fab4278b32f4f40dc02227ab30e10f62e15ab7aa7382da769b1d084e33df +1b7bb172baa2753ec9c3e81a7a9b4c6ef10f9ed7afcafa975395f095eca63a54,false,a98257203987d0c4d260d8feef841466977276612e268b69b5ce4191af161b29,ea177a20d6c1f73f9667090568f9197943037d6586f7e2d6b7b81756fc71df5f,844eff318ef4c6ee45f158c1946ff999e40ffac70883ab6d6b90995f246e69a2 +5ee9b60a25753066d0ecc1155ca6afcc6b853ba558c9533c134a93b82e756856,true,9889460b95ca9545864a4a5194891b7d475362428d6d797532da10bf1fc92076,a7a96739abd8eceb6751afc98df68e29f7af16fbfda3d4710df9c35b6dcdb4d5,998326285c90a2ea2e1f6c6dac79530742645e3dd1b2b42a0733388a99cab81b +a102613781872f88a949d82cb5efcc2e0f437010a950d71b87929ecb480af3b3,false,e099080a55b9b29ccecbbb0d91dbe49defcc217efd1de0588e0836ce5970d327,319293b8660a3cea9879487645ddadda72a5c60079c9154bb0dbb8a0c9cda79e,4d567f1b1a1b304347cf7b129e4c7a05aa57e2bbb8ea335db9e33d05fab12e4d +1d4538180d06f37c43e8caa2d0d80aa7c5d701c8c3e31508704131427837f5cc,true,73afeeb46efc03d2b9f20fc271752528e52b8931287296a7e4367c96bccb32bd,59dc4b69d9ccf6f77715e47fb9bf454f1b90bbd05f1d2bbd07c7d6666f31c91f,ac59d735dfcdc3a0a4ce5a10f09dea8c6afd47de9c0308dc817e3789c8aee963 +e4c480af1b0e3487a331761f64eb3f020a2b8ffa25ad17e00f57aa7ec2c5e84d,true,1145e9f001c70d364e97fcdbc88a2a3d6aecdd975212923820f90a0b215f11f6,b802ac7ef21c8abaeae024c76e3fa70a2a82f73e0bb7c7fe76752ad1742af2e6,0a95876e30617e32ae25acd3af97c37dc075825f800def3f2bf3f68a268744e9 +3a7a83dd657dd6277bcfa957534f40d9b559039aad752066a8d7ed9a6d9c0ab5,false,f90a251ad2338b19cfee6a7965f6f5098136974abb99b3d24553fa6117384978,e422ed7567e5602731b3d980106d0546ef4a4da5eb7175d66a452df12d37bad2,b086bed71dfb6662cb10e2b4fb16a7c22394f488e822fc19697db6077f6caf6f +273e8560c2b1734e863a6542bded7a6fcbfb49a12770bd8866d4863dceea3ae9,false,3b7849a362e7b7ba8c8b8a0cd00df5180604987dbda6c03f37d9a09fdb27fb28,e6cdf4d767df0f411e970da8dda6acd3c2c34ce63908d8a6dbf3715daa0318e4,359a4a39fbdffc808161a48a3ffbe77fc6a03ff52324c22510a42e46c08a6f22 +9b4f8702991be9569b6c0b07a2173104d41325017b27d68fa5af91cdab164c4d,true,598323677db11ece050289f31881ee8caacb59376c7182f9055708b2a4673f84,7675adc1264b6758beb097a991f766f62796f78c1cfa58a4de3d81c36434d3ae,d5d8d610ffd85b04cbe1c73ff5becd5917c513d9625b001f51d486d0dadcefe3 +e1a686ba0169eb97379ebf9d22e073819450ee5ad5f049c8e93016e8d2ec1430,false,ffe461e6075865cde2704aa148fd29bcf0af245803f446cb6153244f25617993,46df6c25fa0344e662490c4da0bddca626644e67e66705840ef08aae35c343fa,e9a56d75acad4272ab0c49ee5919a4e86e6c5695ef065704c1e592d4e7b41a10 From eaa137512cddbb691bb301102c8355ea2a4e47e9 Mon Sep 17 00:00:00 2001 From: Dev Ojha Date: Wed, 1 Aug 2018 15:19:21 -0700 Subject: [PATCH 16/16] adr: Encoding for cryptography at launch (#2121) --- docs/architecture/adr-015-crypto-encoding.md | 80 ++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 docs/architecture/adr-015-crypto-encoding.md diff --git a/docs/architecture/adr-015-crypto-encoding.md b/docs/architecture/adr-015-crypto-encoding.md new file mode 100644 index 000000000..983411270 --- /dev/null +++ b/docs/architecture/adr-015-crypto-encoding.md @@ -0,0 +1,80 @@ +# ADR 015: Crypto encoding + +## Context + +We must standardize our method for encoding public keys and signatures on chain. +Currently we amino encode the public keys and signatures. +The reason we are using amino here is primarily due to ease of support in +parsing for other languages. +We don't need its upgradability properties in cryptosystems, as a change in +the crypto that requires adapting the encoding, likely warrants being deemed +a new cryptosystem. +(I.e. using new public parameters) + +## Decision + +### Public keys + +For public keys, we will continue to use amino encoding on the canonical +representation of the pubkey. +(Canonical as defined by the cryptosystem itself) +This has two significant drawbacks. +Amino encoding is less space-efficient, due to requiring support for upgradability. +Amino encoding support requires forking protobuf and adding this new interface support +option in the langauge of choice. + +The reason for continuing to use amino however is that people can create code +more easily in languages that already have an up to date amino library. +It is possible that this will change in the future, if it is deemed that +requiring amino for interacting with tendermint cryptography is unneccessary. + +The arguments for space efficiency here are refuted on the basis that there are +far more egregious wastages of space in the SDK. +The space requirement of the public keys doesn't cause many problems beyond +increasing the space attached to each validator / account. + +The alternative to using amino here would be for us to create an enum type. +Switching to just an enum type is worthy of investigation post-launch. +For referrence, part of amino encoding interfaces is basically a 4 byte enum +type definition. +Enum types would just change that 4 bytes to be a varuint, and it would remove +the protobuf overhead, but it would be hard to integrate into the existing API. + +### Signatures + +Signatures should be switched to be `[]byte`. +Spatial efficiency in the signatures is quite important, +as it directly affects the gas cost of every transaction, +and the throughput of the chain. +Signatures don't need to encode what type they are for (unlike public keys) +since public keys must already be known. +Therefore we can validate the signature without needing to encode its type. + +When placed in state, signatures will still be amino encoded, but it will be the +primitive type `[]byte` getting encoded. + +#### Ed25519 +Use the canonical representation for signatures. + +#### Secp256k1 +There isn't a clear canonical representation here. +Signatures have two elements `r,s`. +We should encode these bytes as `r || s`, where `r` and `s` are both exactly +32 bytes long. +This is basically Ethereum's encoding, but without the leading recovery bit. + +## Status + +Proposed. The signature section seems to be agreed upon for the most part. +Needs decision on Enum types. + +## Consequences + +### Positive +* More space efficient signatures + +### Negative +* We have an amino dependency for cryptography. + +### Neutral +* No change to public keys \ No newline at end of file