You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

471 lines
14 KiB

mempool: move interface into mempool package (#3524) ## Description Refs #2659 Breaking changes in the mempool package: [mempool] #2659 Mempool now an interface old Mempool renamed to CListMempool NewMempool renamed to NewCListMempool Option renamed to CListOption MempoolReactor renamed to Reactor NewMempoolReactor renamed to NewReactor unexpose TxID method TxInfo.PeerID renamed to SenderID unexpose MempoolReactor.Mempool Breaking changes in the state package: [state] #2659 Mempool interface moved to mempool package MockMempool moved to top-level mock package and renamed to Mempool Non Breaking changes in the node package: [node] #2659 Add Mempool method, which allows you to access mempool ## Commits * move Mempool interface into mempool package Refs #2659 Breaking changes in the mempool package: - Mempool now an interface - old Mempool renamed to CListMempool Breaking changes to state package: - MockMempool moved to mempool/mock package and renamed to Mempool - Mempool interface moved to mempool package * assert CListMempool impl Mempool * gofmt code * rename MempoolReactor to Reactor - combine everything into one interface - rename TxInfo.PeerID to TxInfo.SenderID - unexpose MempoolReactor.Mempool * move mempool mock into top-level mock package * add a fixme TxsFront should not be a part of the Mempool interface because it leaks implementation details. Instead, we need to come up with general interface for querying the mempool so the MempoolReactor can fetch and broadcast txs to peers. * change node#Mempool to return interface * save commit = new reactor arch * Revert "save commit = new reactor arch" This reverts commit 1bfceacd9d65a720574683a7f22771e69af9af4d. * require CListMempool in mempool.Reactor * add two changelog entries * fixes after my own review * quote interfaces, structs and functions * fixes after Ismail's review * make node's mempool an interface * make InitWAL/CloseWAL methods a part of Mempool interface * fix merge conflicts * make node's mempool an interface
6 years ago
mempool: move interface into mempool package (#3524) ## Description Refs #2659 Breaking changes in the mempool package: [mempool] #2659 Mempool now an interface old Mempool renamed to CListMempool NewMempool renamed to NewCListMempool Option renamed to CListOption MempoolReactor renamed to Reactor NewMempoolReactor renamed to NewReactor unexpose TxID method TxInfo.PeerID renamed to SenderID unexpose MempoolReactor.Mempool Breaking changes in the state package: [state] #2659 Mempool interface moved to mempool package MockMempool moved to top-level mock package and renamed to Mempool Non Breaking changes in the node package: [node] #2659 Add Mempool method, which allows you to access mempool ## Commits * move Mempool interface into mempool package Refs #2659 Breaking changes in the mempool package: - Mempool now an interface - old Mempool renamed to CListMempool Breaking changes to state package: - MockMempool moved to mempool/mock package and renamed to Mempool - Mempool interface moved to mempool package * assert CListMempool impl Mempool * gofmt code * rename MempoolReactor to Reactor - combine everything into one interface - rename TxInfo.PeerID to TxInfo.SenderID - unexpose MempoolReactor.Mempool * move mempool mock into top-level mock package * add a fixme TxsFront should not be a part of the Mempool interface because it leaks implementation details. Instead, we need to come up with general interface for querying the mempool so the MempoolReactor can fetch and broadcast txs to peers. * change node#Mempool to return interface * save commit = new reactor arch * Revert "save commit = new reactor arch" This reverts commit 1bfceacd9d65a720574683a7f22771e69af9af4d. * require CListMempool in mempool.Reactor * add two changelog entries * fixes after my own review * quote interfaces, structs and functions * fixes after Ismail's review * make node's mempool an interface * make InitWAL/CloseWAL methods a part of Mempool interface * fix merge conflicts * make node's mempool an interface
6 years ago
mempool: move interface into mempool package (#3524) ## Description Refs #2659 Breaking changes in the mempool package: [mempool] #2659 Mempool now an interface old Mempool renamed to CListMempool NewMempool renamed to NewCListMempool Option renamed to CListOption MempoolReactor renamed to Reactor NewMempoolReactor renamed to NewReactor unexpose TxID method TxInfo.PeerID renamed to SenderID unexpose MempoolReactor.Mempool Breaking changes in the state package: [state] #2659 Mempool interface moved to mempool package MockMempool moved to top-level mock package and renamed to Mempool Non Breaking changes in the node package: [node] #2659 Add Mempool method, which allows you to access mempool ## Commits * move Mempool interface into mempool package Refs #2659 Breaking changes in the mempool package: - Mempool now an interface - old Mempool renamed to CListMempool Breaking changes to state package: - MockMempool moved to mempool/mock package and renamed to Mempool - Mempool interface moved to mempool package * assert CListMempool impl Mempool * gofmt code * rename MempoolReactor to Reactor - combine everything into one interface - rename TxInfo.PeerID to TxInfo.SenderID - unexpose MempoolReactor.Mempool * move mempool mock into top-level mock package * add a fixme TxsFront should not be a part of the Mempool interface because it leaks implementation details. Instead, we need to come up with general interface for querying the mempool so the MempoolReactor can fetch and broadcast txs to peers. * change node#Mempool to return interface * save commit = new reactor arch * Revert "save commit = new reactor arch" This reverts commit 1bfceacd9d65a720574683a7f22771e69af9af4d. * require CListMempool in mempool.Reactor * add two changelog entries * fixes after my own review * quote interfaces, structs and functions * fixes after Ismail's review * make node's mempool an interface * make InitWAL/CloseWAL methods a part of Mempool interface * fix merge conflicts * make node's mempool an interface
6 years ago
cs/replay: execCommitBlock should not read from state.lastValidators (#3067) * execCommitBlock should not read from state.lastValidators * fix height 1 * fix blockchain/reactor_test * fix consensus/mempool_test * fix consensus/reactor_test * fix consensus/replay_test * add CHANGELOG * fix consensus/reactor_test * fix consensus/replay_test * add a test for replay validators change * fix mem_pool test * fix byzantine test * remove a redundant code * reduce validator change blocks to 6 * fix * return peer0 config * seperate testName * seperate testName 1 * seperate testName 2 * seperate app db path * seperate app db path 1 * add a lock before startNet * move the lock to reactor_test * simulate just once * try to find problem * handshake only saveState when app version changed * update gometalinter to 3.0.0 (#3233) in the attempt to fix https://circleci.com/gh/tendermint/tendermint/43165 also code is simplified by running gofmt -s . remove unused vars enable linters we're currently passing remove deprecated linters (cherry picked from commit d47094550315c094512a242445e0dde24b5a03f5) * gofmt code * goimport code * change the bool name to testValidatorsChange * adjust receive kvstore.ProtocolVersion * adjust receive kvstore.ProtocolVersion 1 * adjust receive kvstore.ProtocolVersion 3 * fix merge execution.go * fix merge develop * fix merge develop 1 * fix run cleanupFunc * adjust code according to reviewers' opinion * modify the func name match the convention * simplify simulate a chain containing some validator change txs 1 * test CI error * Merge remote-tracking branch 'upstream/develop' into fixReplay 1 * fix pubsub_test * subscribeUnbuffered vote channel
6 years ago
cs/replay: execCommitBlock should not read from state.lastValidators (#3067) * execCommitBlock should not read from state.lastValidators * fix height 1 * fix blockchain/reactor_test * fix consensus/mempool_test * fix consensus/reactor_test * fix consensus/replay_test * add CHANGELOG * fix consensus/reactor_test * fix consensus/replay_test * add a test for replay validators change * fix mem_pool test * fix byzantine test * remove a redundant code * reduce validator change blocks to 6 * fix * return peer0 config * seperate testName * seperate testName 1 * seperate testName 2 * seperate app db path * seperate app db path 1 * add a lock before startNet * move the lock to reactor_test * simulate just once * try to find problem * handshake only saveState when app version changed * update gometalinter to 3.0.0 (#3233) in the attempt to fix https://circleci.com/gh/tendermint/tendermint/43165 also code is simplified by running gofmt -s . remove unused vars enable linters we're currently passing remove deprecated linters (cherry picked from commit d47094550315c094512a242445e0dde24b5a03f5) * gofmt code * goimport code * change the bool name to testValidatorsChange * adjust receive kvstore.ProtocolVersion * adjust receive kvstore.ProtocolVersion 1 * adjust receive kvstore.ProtocolVersion 3 * fix merge execution.go * fix merge develop * fix merge develop 1 * fix run cleanupFunc * adjust code according to reviewers' opinion * modify the func name match the convention * simplify simulate a chain containing some validator change txs 1 * test CI error * Merge remote-tracking branch 'upstream/develop' into fixReplay 1 * fix pubsub_test * subscribeUnbuffered vote channel
6 years ago
mempool: move interface into mempool package (#3524) ## Description Refs #2659 Breaking changes in the mempool package: [mempool] #2659 Mempool now an interface old Mempool renamed to CListMempool NewMempool renamed to NewCListMempool Option renamed to CListOption MempoolReactor renamed to Reactor NewMempoolReactor renamed to NewReactor unexpose TxID method TxInfo.PeerID renamed to SenderID unexpose MempoolReactor.Mempool Breaking changes in the state package: [state] #2659 Mempool interface moved to mempool package MockMempool moved to top-level mock package and renamed to Mempool Non Breaking changes in the node package: [node] #2659 Add Mempool method, which allows you to access mempool ## Commits * move Mempool interface into mempool package Refs #2659 Breaking changes in the mempool package: - Mempool now an interface - old Mempool renamed to CListMempool Breaking changes to state package: - MockMempool moved to mempool/mock package and renamed to Mempool - Mempool interface moved to mempool package * assert CListMempool impl Mempool * gofmt code * rename MempoolReactor to Reactor - combine everything into one interface - rename TxInfo.PeerID to TxInfo.SenderID - unexpose MempoolReactor.Mempool * move mempool mock into top-level mock package * add a fixme TxsFront should not be a part of the Mempool interface because it leaks implementation details. Instead, we need to come up with general interface for querying the mempool so the MempoolReactor can fetch and broadcast txs to peers. * change node#Mempool to return interface * save commit = new reactor arch * Revert "save commit = new reactor arch" This reverts commit 1bfceacd9d65a720574683a7f22771e69af9af4d. * require CListMempool in mempool.Reactor * add two changelog entries * fixes after my own review * quote interfaces, structs and functions * fixes after Ismail's review * make node's mempool an interface * make InitWAL/CloseWAL methods a part of Mempool interface * fix merge conflicts * make node's mempool an interface
6 years ago
pubsub 2.0 (#3227) * green pubsub tests :OK: * get rid of clientToQueryMap * Subscribe and SubscribeUnbuffered * start adapting other pkgs to new pubsub * nope * rename MsgAndTags to Message * remove TagMap it does not bring any additional benefits * bring back EventSubscriber * fix test * fix data race in TestStartNextHeightCorrectly ``` Write at 0x00c0001c7418 by goroutine 796: github.com/tendermint/tendermint/consensus.TestStartNextHeightCorrectly() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:1296 +0xad testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 Previous read at 0x00c0001c7418 by goroutine 858: github.com/tendermint/tendermint/consensus.(*ConsensusState).addVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1631 +0x1366 github.com/tendermint/tendermint/consensus.(*ConsensusState).tryAddVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1476 +0x8f github.com/tendermint/tendermint/consensus.(*ConsensusState).handleMsg() /go/src/github.com/tendermint/tendermint/consensus/state.go:667 +0xa1e github.com/tendermint/tendermint/consensus.(*ConsensusState).receiveRoutine() /go/src/github.com/tendermint/tendermint/consensus/state.go:628 +0x794 Goroutine 796 (running) created at: testing.(*T).Run() /usr/local/go/src/testing/testing.go:878 +0x659 testing.runTests.func1() /usr/local/go/src/testing/testing.go:1119 +0xa8 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 testing.runTests() /usr/local/go/src/testing/testing.go:1117 +0x4ee testing.(*M).Run() /usr/local/go/src/testing/testing.go:1034 +0x2ee main.main() _testmain.go:214 +0x332 Goroutine 858 (running) created at: github.com/tendermint/tendermint/consensus.(*ConsensusState).startRoutines() /go/src/github.com/tendermint/tendermint/consensus/state.go:334 +0x221 github.com/tendermint/tendermint/consensus.startTestRound() /go/src/github.com/tendermint/tendermint/consensus/common_test.go:122 +0x63 github.com/tendermint/tendermint/consensus.TestStateFullRound1() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:255 +0x397 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 ``` * fixes after my own review * fix formatting * wait 100ms before kicking a subscriber out + a test for indexer_service * fixes after my second review * no timeout * add changelog entries * fix merge conflicts * fix typos after Thane's review Co-Authored-By: melekes <anton.kalyaev@gmail.com> * reformat code * rewrite indexer service in the attempt to fix failing test https://github.com/tendermint/tendermint/pull/3227/#issuecomment-462316527 * Revert "rewrite indexer service in the attempt to fix failing test" This reverts commit 0d9107a098230de7138abb1c201877c246e89ed1. * another attempt to fix indexer * fixes after Ethan's review * use unbuffered channel when indexing transactions Refs https://github.com/tendermint/tendermint/pull/3227#discussion_r258786716 * add a comment for EventBus#SubscribeUnbuffered * format code
6 years ago
6 years ago
pubsub 2.0 (#3227) * green pubsub tests :OK: * get rid of clientToQueryMap * Subscribe and SubscribeUnbuffered * start adapting other pkgs to new pubsub * nope * rename MsgAndTags to Message * remove TagMap it does not bring any additional benefits * bring back EventSubscriber * fix test * fix data race in TestStartNextHeightCorrectly ``` Write at 0x00c0001c7418 by goroutine 796: github.com/tendermint/tendermint/consensus.TestStartNextHeightCorrectly() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:1296 +0xad testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 Previous read at 0x00c0001c7418 by goroutine 858: github.com/tendermint/tendermint/consensus.(*ConsensusState).addVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1631 +0x1366 github.com/tendermint/tendermint/consensus.(*ConsensusState).tryAddVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1476 +0x8f github.com/tendermint/tendermint/consensus.(*ConsensusState).handleMsg() /go/src/github.com/tendermint/tendermint/consensus/state.go:667 +0xa1e github.com/tendermint/tendermint/consensus.(*ConsensusState).receiveRoutine() /go/src/github.com/tendermint/tendermint/consensus/state.go:628 +0x794 Goroutine 796 (running) created at: testing.(*T).Run() /usr/local/go/src/testing/testing.go:878 +0x659 testing.runTests.func1() /usr/local/go/src/testing/testing.go:1119 +0xa8 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 testing.runTests() /usr/local/go/src/testing/testing.go:1117 +0x4ee testing.(*M).Run() /usr/local/go/src/testing/testing.go:1034 +0x2ee main.main() _testmain.go:214 +0x332 Goroutine 858 (running) created at: github.com/tendermint/tendermint/consensus.(*ConsensusState).startRoutines() /go/src/github.com/tendermint/tendermint/consensus/state.go:334 +0x221 github.com/tendermint/tendermint/consensus.startTestRound() /go/src/github.com/tendermint/tendermint/consensus/common_test.go:122 +0x63 github.com/tendermint/tendermint/consensus.TestStateFullRound1() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:255 +0x397 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 ``` * fixes after my own review * fix formatting * wait 100ms before kicking a subscriber out + a test for indexer_service * fixes after my second review * no timeout * add changelog entries * fix merge conflicts * fix typos after Thane's review Co-Authored-By: melekes <anton.kalyaev@gmail.com> * reformat code * rewrite indexer service in the attempt to fix failing test https://github.com/tendermint/tendermint/pull/3227/#issuecomment-462316527 * Revert "rewrite indexer service in the attempt to fix failing test" This reverts commit 0d9107a098230de7138abb1c201877c246e89ed1. * another attempt to fix indexer * fixes after Ethan's review * use unbuffered channel when indexing transactions Refs https://github.com/tendermint/tendermint/pull/3227#discussion_r258786716 * add a comment for EventBus#SubscribeUnbuffered * format code
6 years ago
pubsub 2.0 (#3227) * green pubsub tests :OK: * get rid of clientToQueryMap * Subscribe and SubscribeUnbuffered * start adapting other pkgs to new pubsub * nope * rename MsgAndTags to Message * remove TagMap it does not bring any additional benefits * bring back EventSubscriber * fix test * fix data race in TestStartNextHeightCorrectly ``` Write at 0x00c0001c7418 by goroutine 796: github.com/tendermint/tendermint/consensus.TestStartNextHeightCorrectly() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:1296 +0xad testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 Previous read at 0x00c0001c7418 by goroutine 858: github.com/tendermint/tendermint/consensus.(*ConsensusState).addVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1631 +0x1366 github.com/tendermint/tendermint/consensus.(*ConsensusState).tryAddVote() /go/src/github.com/tendermint/tendermint/consensus/state.go:1476 +0x8f github.com/tendermint/tendermint/consensus.(*ConsensusState).handleMsg() /go/src/github.com/tendermint/tendermint/consensus/state.go:667 +0xa1e github.com/tendermint/tendermint/consensus.(*ConsensusState).receiveRoutine() /go/src/github.com/tendermint/tendermint/consensus/state.go:628 +0x794 Goroutine 796 (running) created at: testing.(*T).Run() /usr/local/go/src/testing/testing.go:878 +0x659 testing.runTests.func1() /usr/local/go/src/testing/testing.go:1119 +0xa8 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 testing.runTests() /usr/local/go/src/testing/testing.go:1117 +0x4ee testing.(*M).Run() /usr/local/go/src/testing/testing.go:1034 +0x2ee main.main() _testmain.go:214 +0x332 Goroutine 858 (running) created at: github.com/tendermint/tendermint/consensus.(*ConsensusState).startRoutines() /go/src/github.com/tendermint/tendermint/consensus/state.go:334 +0x221 github.com/tendermint/tendermint/consensus.startTestRound() /go/src/github.com/tendermint/tendermint/consensus/common_test.go:122 +0x63 github.com/tendermint/tendermint/consensus.TestStateFullRound1() /go/src/github.com/tendermint/tendermint/consensus/state_test.go:255 +0x397 testing.tRunner() /usr/local/go/src/testing/testing.go:827 +0x162 ``` * fixes after my own review * fix formatting * wait 100ms before kicking a subscriber out + a test for indexer_service * fixes after my second review * no timeout * add changelog entries * fix merge conflicts * fix typos after Thane's review Co-Authored-By: melekes <anton.kalyaev@gmail.com> * reformat code * rewrite indexer service in the attempt to fix failing test https://github.com/tendermint/tendermint/pull/3227/#issuecomment-462316527 * Revert "rewrite indexer service in the attempt to fix failing test" This reverts commit 0d9107a098230de7138abb1c201877c246e89ed1. * another attempt to fix indexer * fixes after Ethan's review * use unbuffered channel when indexing transactions Refs https://github.com/tendermint/tendermint/pull/3227#discussion_r258786716 * add a comment for EventBus#SubscribeUnbuffered * format code
6 years ago
mempool: move interface into mempool package (#3524) ## Description Refs #2659 Breaking changes in the mempool package: [mempool] #2659 Mempool now an interface old Mempool renamed to CListMempool NewMempool renamed to NewCListMempool Option renamed to CListOption MempoolReactor renamed to Reactor NewMempoolReactor renamed to NewReactor unexpose TxID method TxInfo.PeerID renamed to SenderID unexpose MempoolReactor.Mempool Breaking changes in the state package: [state] #2659 Mempool interface moved to mempool package MockMempool moved to top-level mock package and renamed to Mempool Non Breaking changes in the node package: [node] #2659 Add Mempool method, which allows you to access mempool ## Commits * move Mempool interface into mempool package Refs #2659 Breaking changes in the mempool package: - Mempool now an interface - old Mempool renamed to CListMempool Breaking changes to state package: - MockMempool moved to mempool/mock package and renamed to Mempool - Mempool interface moved to mempool package * assert CListMempool impl Mempool * gofmt code * rename MempoolReactor to Reactor - combine everything into one interface - rename TxInfo.PeerID to TxInfo.SenderID - unexpose MempoolReactor.Mempool * move mempool mock into top-level mock package * add a fixme TxsFront should not be a part of the Mempool interface because it leaks implementation details. Instead, we need to come up with general interface for querying the mempool so the MempoolReactor can fetch and broadcast txs to peers. * change node#Mempool to return interface * save commit = new reactor arch * Revert "save commit = new reactor arch" This reverts commit 1bfceacd9d65a720574683a7f22771e69af9af4d. * require CListMempool in mempool.Reactor * add two changelog entries * fixes after my own review * quote interfaces, structs and functions * fixes after Ismail's review * make node's mempool an interface * make InitWAL/CloseWAL methods a part of Mempool interface * fix merge conflicts * make node's mempool an interface
6 years ago
6 years ago
  1. package state
  2. import (
  3. "context"
  4. "fmt"
  5. "testing"
  6. "time"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. "github.com/tendermint/tendermint/abci/example/kvstore"
  10. abci "github.com/tendermint/tendermint/abci/types"
  11. "github.com/tendermint/tendermint/crypto/ed25519"
  12. "github.com/tendermint/tendermint/crypto/secp256k1"
  13. cmn "github.com/tendermint/tendermint/libs/common"
  14. dbm "github.com/tendermint/tendermint/libs/db"
  15. "github.com/tendermint/tendermint/libs/log"
  16. "github.com/tendermint/tendermint/mock"
  17. "github.com/tendermint/tendermint/proxy"
  18. "github.com/tendermint/tendermint/types"
  19. tmtime "github.com/tendermint/tendermint/types/time"
  20. )
  21. var (
  22. chainID = "execution_chain"
  23. testPartSize = 65536
  24. nTxsPerBlock = 10
  25. )
  26. func TestApplyBlock(t *testing.T) {
  27. cc := proxy.NewLocalClientCreator(kvstore.NewKVStoreApplication())
  28. proxyApp := proxy.NewAppConns(cc)
  29. err := proxyApp.Start()
  30. require.Nil(t, err)
  31. defer proxyApp.Stop()
  32. state, stateDB := state(1, 1)
  33. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(),
  34. mock.Mempool{}, MockEvidencePool{})
  35. block := makeBlock(state, 1)
  36. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  37. //nolint:ineffassign
  38. state, err = blockExec.ApplyBlock(state, blockID, block)
  39. require.Nil(t, err)
  40. // TODO check state and mempool
  41. }
  42. // TestBeginBlockValidators ensures we send absent validators list.
  43. func TestBeginBlockValidators(t *testing.T) {
  44. app := &testApp{}
  45. cc := proxy.NewLocalClientCreator(app)
  46. proxyApp := proxy.NewAppConns(cc)
  47. err := proxyApp.Start()
  48. require.Nil(t, err)
  49. defer proxyApp.Stop()
  50. state, stateDB := state(2, 2)
  51. prevHash := state.LastBlockID.Hash
  52. prevParts := types.PartSetHeader{}
  53. prevBlockID := types.BlockID{prevHash, prevParts}
  54. now := tmtime.Now()
  55. commitSig0 := (&types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.PrecommitType}).CommitSig()
  56. commitSig1 := (&types.Vote{ValidatorIndex: 1, Timestamp: now}).CommitSig()
  57. testCases := []struct {
  58. desc string
  59. lastCommitPrecommits []*types.CommitSig
  60. expectedAbsentValidators []int
  61. }{
  62. {"none absent", []*types.CommitSig{commitSig0, commitSig1}, []int{}},
  63. {"one absent", []*types.CommitSig{commitSig0, nil}, []int{1}},
  64. {"multiple absent", []*types.CommitSig{nil, nil}, []int{0, 1}},
  65. }
  66. for _, tc := range testCases {
  67. lastCommit := types.NewCommit(prevBlockID, tc.lastCommitPrecommits)
  68. // block for height 2
  69. block, _ := state.MakeBlock(2, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
  70. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB)
  71. require.Nil(t, err, tc.desc)
  72. // -> app receives a list of validators with a bool indicating if they signed
  73. ctr := 0
  74. for i, v := range app.CommitVotes {
  75. if ctr < len(tc.expectedAbsentValidators) &&
  76. tc.expectedAbsentValidators[ctr] == i {
  77. assert.False(t, v.SignedLastBlock)
  78. ctr++
  79. } else {
  80. assert.True(t, v.SignedLastBlock)
  81. }
  82. }
  83. }
  84. }
  85. // TestBeginBlockByzantineValidators ensures we send byzantine validators list.
  86. func TestBeginBlockByzantineValidators(t *testing.T) {
  87. app := &testApp{}
  88. cc := proxy.NewLocalClientCreator(app)
  89. proxyApp := proxy.NewAppConns(cc)
  90. err := proxyApp.Start()
  91. require.Nil(t, err)
  92. defer proxyApp.Stop()
  93. state, stateDB := state(2, 12)
  94. prevHash := state.LastBlockID.Hash
  95. prevParts := types.PartSetHeader{}
  96. prevBlockID := types.BlockID{prevHash, prevParts}
  97. height1, idx1, val1 := int64(8), 0, state.Validators.Validators[0].Address
  98. height2, idx2, val2 := int64(3), 1, state.Validators.Validators[1].Address
  99. ev1 := types.NewMockGoodEvidence(height1, idx1, val1)
  100. ev2 := types.NewMockGoodEvidence(height2, idx2, val2)
  101. now := tmtime.Now()
  102. valSet := state.Validators
  103. testCases := []struct {
  104. desc string
  105. evidence []types.Evidence
  106. expectedByzantineValidators []abci.Evidence
  107. }{
  108. {"none byzantine", []types.Evidence{}, []abci.Evidence{}},
  109. {"one byzantine", []types.Evidence{ev1}, []abci.Evidence{types.TM2PB.Evidence(ev1, valSet, now)}},
  110. {"multiple byzantine", []types.Evidence{ev1, ev2}, []abci.Evidence{
  111. types.TM2PB.Evidence(ev1, valSet, now),
  112. types.TM2PB.Evidence(ev2, valSet, now)}},
  113. }
  114. commitSig0 := (&types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.PrecommitType}).CommitSig()
  115. commitSig1 := (&types.Vote{ValidatorIndex: 1, Timestamp: now}).CommitSig()
  116. commitSigs := []*types.CommitSig{commitSig0, commitSig1}
  117. lastCommit := types.NewCommit(prevBlockID, commitSigs)
  118. for _, tc := range testCases {
  119. block, _ := state.MakeBlock(10, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
  120. block.Time = now
  121. block.Evidence.Evidence = tc.evidence
  122. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), stateDB)
  123. require.Nil(t, err, tc.desc)
  124. // -> app must receive an index of the byzantine validator
  125. assert.Equal(t, tc.expectedByzantineValidators, app.ByzantineValidators, tc.desc)
  126. }
  127. }
  128. func TestValidateValidatorUpdates(t *testing.T) {
  129. pubkey1 := ed25519.GenPrivKey().PubKey()
  130. pubkey2 := ed25519.GenPrivKey().PubKey()
  131. secpKey := secp256k1.GenPrivKey().PubKey()
  132. defaultValidatorParams := types.ValidatorParams{[]string{types.ABCIPubKeyTypeEd25519}}
  133. testCases := []struct {
  134. name string
  135. abciUpdates []abci.ValidatorUpdate
  136. validatorParams types.ValidatorParams
  137. shouldErr bool
  138. }{
  139. {
  140. "adding a validator is OK",
  141. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 20}},
  142. defaultValidatorParams,
  143. false,
  144. },
  145. {
  146. "updating a validator is OK",
  147. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey1), Power: 20}},
  148. defaultValidatorParams,
  149. false,
  150. },
  151. {
  152. "removing a validator is OK",
  153. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
  154. defaultValidatorParams,
  155. false,
  156. },
  157. {
  158. "adding a validator with negative power results in error",
  159. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: -100}},
  160. defaultValidatorParams,
  161. true,
  162. },
  163. {
  164. "adding a validator with pubkey thats not in validator params results in error",
  165. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(secpKey), Power: -100}},
  166. defaultValidatorParams,
  167. true,
  168. },
  169. }
  170. for _, tc := range testCases {
  171. t.Run(tc.name, func(t *testing.T) {
  172. err := validateValidatorUpdates(tc.abciUpdates, tc.validatorParams)
  173. if tc.shouldErr {
  174. assert.Error(t, err)
  175. } else {
  176. assert.NoError(t, err)
  177. }
  178. })
  179. }
  180. }
  181. func TestUpdateValidators(t *testing.T) {
  182. pubkey1 := ed25519.GenPrivKey().PubKey()
  183. val1 := types.NewValidator(pubkey1, 10)
  184. pubkey2 := ed25519.GenPrivKey().PubKey()
  185. val2 := types.NewValidator(pubkey2, 20)
  186. testCases := []struct {
  187. name string
  188. currentSet *types.ValidatorSet
  189. abciUpdates []abci.ValidatorUpdate
  190. resultingSet *types.ValidatorSet
  191. shouldErr bool
  192. }{
  193. {
  194. "adding a validator is OK",
  195. types.NewValidatorSet([]*types.Validator{val1}),
  196. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 20}},
  197. types.NewValidatorSet([]*types.Validator{val1, val2}),
  198. false,
  199. },
  200. {
  201. "updating a validator is OK",
  202. types.NewValidatorSet([]*types.Validator{val1}),
  203. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey1), Power: 20}},
  204. types.NewValidatorSet([]*types.Validator{types.NewValidator(pubkey1, 20)}),
  205. false,
  206. },
  207. {
  208. "removing a validator is OK",
  209. types.NewValidatorSet([]*types.Validator{val1, val2}),
  210. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
  211. types.NewValidatorSet([]*types.Validator{val1}),
  212. false,
  213. },
  214. {
  215. "removing a non-existing validator results in error",
  216. types.NewValidatorSet([]*types.Validator{val1}),
  217. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
  218. types.NewValidatorSet([]*types.Validator{val1}),
  219. true,
  220. },
  221. }
  222. for _, tc := range testCases {
  223. t.Run(tc.name, func(t *testing.T) {
  224. updates, err := types.PB2TM.ValidatorUpdates(tc.abciUpdates)
  225. assert.NoError(t, err)
  226. err = tc.currentSet.UpdateWithChangeSet(updates)
  227. if tc.shouldErr {
  228. assert.Error(t, err)
  229. } else {
  230. assert.NoError(t, err)
  231. require.Equal(t, tc.resultingSet.Size(), tc.currentSet.Size())
  232. assert.Equal(t, tc.resultingSet.TotalVotingPower(), tc.currentSet.TotalVotingPower())
  233. assert.Equal(t, tc.resultingSet.Validators[0].Address, tc.currentSet.Validators[0].Address)
  234. if tc.resultingSet.Size() > 1 {
  235. assert.Equal(t, tc.resultingSet.Validators[1].Address, tc.currentSet.Validators[1].Address)
  236. }
  237. }
  238. })
  239. }
  240. }
  241. // TestEndBlockValidatorUpdates ensures we update validator set and send an event.
  242. func TestEndBlockValidatorUpdates(t *testing.T) {
  243. app := &testApp{}
  244. cc := proxy.NewLocalClientCreator(app)
  245. proxyApp := proxy.NewAppConns(cc)
  246. err := proxyApp.Start()
  247. require.Nil(t, err)
  248. defer proxyApp.Stop()
  249. state, stateDB := state(1, 1)
  250. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), mock.Mempool{}, MockEvidencePool{})
  251. eventBus := types.NewEventBus()
  252. err = eventBus.Start()
  253. require.NoError(t, err)
  254. defer eventBus.Stop()
  255. blockExec.SetEventBus(eventBus)
  256. updatesSub, err := eventBus.Subscribe(context.Background(), "TestEndBlockValidatorUpdates", types.EventQueryValidatorSetUpdates)
  257. require.NoError(t, err)
  258. block := makeBlock(state, 1)
  259. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  260. pubkey := ed25519.GenPrivKey().PubKey()
  261. app.ValidatorUpdates = []abci.ValidatorUpdate{
  262. {PubKey: types.TM2PB.PubKey(pubkey), Power: 10},
  263. }
  264. state, err = blockExec.ApplyBlock(state, blockID, block)
  265. require.Nil(t, err)
  266. // test new validator was added to NextValidators
  267. if assert.Equal(t, state.Validators.Size()+1, state.NextValidators.Size()) {
  268. idx, _ := state.NextValidators.GetByAddress(pubkey.Address())
  269. if idx < 0 {
  270. t.Fatalf("can't find address %v in the set %v", pubkey.Address(), state.NextValidators)
  271. }
  272. }
  273. // test we threw an event
  274. select {
  275. case msg := <-updatesSub.Out():
  276. event, ok := msg.Data().(types.EventDataValidatorSetUpdates)
  277. require.True(t, ok, "Expected event of type EventDataValidatorSetUpdates, got %T", msg.Data())
  278. if assert.NotEmpty(t, event.ValidatorUpdates) {
  279. assert.Equal(t, pubkey, event.ValidatorUpdates[0].PubKey)
  280. assert.EqualValues(t, 10, event.ValidatorUpdates[0].VotingPower)
  281. }
  282. case <-updatesSub.Cancelled():
  283. t.Fatalf("updatesSub was cancelled (reason: %v)", updatesSub.Err())
  284. case <-time.After(1 * time.Second):
  285. t.Fatal("Did not receive EventValidatorSetUpdates within 1 sec.")
  286. }
  287. }
  288. // TestEndBlockValidatorUpdatesResultingInEmptySet checks that processing validator updates that
  289. // would result in empty set causes no panic, an error is raised and NextValidators is not updated
  290. func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) {
  291. app := &testApp{}
  292. cc := proxy.NewLocalClientCreator(app)
  293. proxyApp := proxy.NewAppConns(cc)
  294. err := proxyApp.Start()
  295. require.Nil(t, err)
  296. defer proxyApp.Stop()
  297. state, stateDB := state(1, 1)
  298. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), mock.Mempool{}, MockEvidencePool{})
  299. block := makeBlock(state, 1)
  300. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  301. // Remove the only validator
  302. app.ValidatorUpdates = []abci.ValidatorUpdate{
  303. {PubKey: types.TM2PB.PubKey(state.Validators.Validators[0].PubKey), Power: 0},
  304. }
  305. assert.NotPanics(t, func() { state, err = blockExec.ApplyBlock(state, blockID, block) })
  306. assert.NotNil(t, err)
  307. assert.NotEmpty(t, state.NextValidators.Validators)
  308. }
  309. //----------------------------------------------------------------------------
  310. // make some bogus txs
  311. func makeTxs(height int64) (txs []types.Tx) {
  312. for i := 0; i < nTxsPerBlock; i++ {
  313. txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
  314. }
  315. return txs
  316. }
  317. func state(nVals, height int) (State, dbm.DB) {
  318. vals := make([]types.GenesisValidator, nVals)
  319. for i := 0; i < nVals; i++ {
  320. secret := []byte(fmt.Sprintf("test%d", i))
  321. pk := ed25519.GenPrivKeyFromSecret(secret)
  322. vals[i] = types.GenesisValidator{
  323. pk.PubKey().Address(),
  324. pk.PubKey(),
  325. 1000,
  326. fmt.Sprintf("test%d", i),
  327. }
  328. }
  329. s, _ := MakeGenesisState(&types.GenesisDoc{
  330. ChainID: chainID,
  331. Validators: vals,
  332. AppHash: nil,
  333. })
  334. // save validators to db for 2 heights
  335. stateDB := dbm.NewMemDB()
  336. SaveState(stateDB, s)
  337. for i := 1; i < height; i++ {
  338. s.LastBlockHeight++
  339. s.LastValidators = s.Validators.Copy()
  340. SaveState(stateDB, s)
  341. }
  342. return s, stateDB
  343. }
  344. func makeBlock(state State, height int64) *types.Block {
  345. block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit), nil, state.Validators.GetProposer().Address)
  346. return block
  347. }
  348. //----------------------------------------------------------------------------
  349. type testApp struct {
  350. abci.BaseApplication
  351. CommitVotes []abci.VoteInfo
  352. ByzantineValidators []abci.Evidence
  353. ValidatorUpdates []abci.ValidatorUpdate
  354. }
  355. var _ abci.Application = (*testApp)(nil)
  356. func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
  357. return abci.ResponseInfo{}
  358. }
  359. func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
  360. app.CommitVotes = req.LastCommitInfo.Votes
  361. app.ByzantineValidators = req.ByzantineValidators
  362. return abci.ResponseBeginBlock{}
  363. }
  364. func (app *testApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock {
  365. return abci.ResponseEndBlock{ValidatorUpdates: app.ValidatorUpdates}
  366. }
  367. func (app *testApp) DeliverTx(tx []byte) abci.ResponseDeliverTx {
  368. return abci.ResponseDeliverTx{Tags: []cmn.KVPair{}}
  369. }
  370. func (app *testApp) CheckTx(tx []byte) abci.ResponseCheckTx {
  371. return abci.ResponseCheckTx{}
  372. }
  373. func (app *testApp) Commit() abci.ResponseCommit {
  374. return abci.ResponseCommit{}
  375. }
  376. func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
  377. return
  378. }