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

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
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. tmtime "github.com/tendermint/tendermint/types/time"
  17. "github.com/tendermint/tendermint/proxy"
  18. "github.com/tendermint/tendermint/types"
  19. )
  20. var (
  21. chainID = "execution_chain"
  22. testPartSize = 65536
  23. nTxsPerBlock = 10
  24. )
  25. func TestApplyBlock(t *testing.T) {
  26. cc := proxy.NewLocalClientCreator(kvstore.NewKVStoreApplication())
  27. proxyApp := proxy.NewAppConns(cc)
  28. err := proxyApp.Start()
  29. require.Nil(t, err)
  30. defer proxyApp.Stop()
  31. state, stateDB := state(1, 1)
  32. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(),
  33. MockMempool{}, MockEvidencePool{})
  34. block := makeBlock(state, 1)
  35. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  36. //nolint:ineffassign
  37. state, err = blockExec.ApplyBlock(state, blockID, block)
  38. require.Nil(t, err)
  39. // TODO check state and mempool
  40. }
  41. // TestBeginBlockValidators ensures we send absent validators list.
  42. func TestBeginBlockValidators(t *testing.T) {
  43. app := &testApp{}
  44. cc := proxy.NewLocalClientCreator(app)
  45. proxyApp := proxy.NewAppConns(cc)
  46. err := proxyApp.Start()
  47. require.Nil(t, err)
  48. defer proxyApp.Stop()
  49. state, stateDB := state(2, 2)
  50. prevHash := state.LastBlockID.Hash
  51. prevParts := types.PartSetHeader{}
  52. prevBlockID := types.BlockID{prevHash, prevParts}
  53. now := tmtime.Now()
  54. commitSig0 := (&types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.PrecommitType}).CommitSig()
  55. commitSig1 := (&types.Vote{ValidatorIndex: 1, Timestamp: now}).CommitSig()
  56. testCases := []struct {
  57. desc string
  58. lastCommitPrecommits []*types.CommitSig
  59. expectedAbsentValidators []int
  60. }{
  61. {"none absent", []*types.CommitSig{commitSig0, commitSig1}, []int{}},
  62. {"one absent", []*types.CommitSig{commitSig0, nil}, []int{1}},
  63. {"multiple absent", []*types.CommitSig{nil, nil}, []int{0, 1}},
  64. }
  65. for _, tc := range testCases {
  66. lastCommit := types.NewCommit(prevBlockID, tc.lastCommitPrecommits)
  67. // block for height 2
  68. block, _ := state.MakeBlock(2, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
  69. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
  70. require.Nil(t, err, tc.desc)
  71. // -> app receives a list of validators with a bool indicating if they signed
  72. ctr := 0
  73. for i, v := range app.CommitVotes {
  74. if ctr < len(tc.expectedAbsentValidators) &&
  75. tc.expectedAbsentValidators[ctr] == i {
  76. assert.False(t, v.SignedLastBlock)
  77. ctr++
  78. } else {
  79. assert.True(t, v.SignedLastBlock)
  80. }
  81. }
  82. }
  83. }
  84. // TestBeginBlockByzantineValidators ensures we send byzantine validators list.
  85. func TestBeginBlockByzantineValidators(t *testing.T) {
  86. app := &testApp{}
  87. cc := proxy.NewLocalClientCreator(app)
  88. proxyApp := proxy.NewAppConns(cc)
  89. err := proxyApp.Start()
  90. require.Nil(t, err)
  91. defer proxyApp.Stop()
  92. state, stateDB := state(2, 12)
  93. prevHash := state.LastBlockID.Hash
  94. prevParts := types.PartSetHeader{}
  95. prevBlockID := types.BlockID{prevHash, prevParts}
  96. height1, idx1, val1 := int64(8), 0, state.Validators.Validators[0].Address
  97. height2, idx2, val2 := int64(3), 1, state.Validators.Validators[1].Address
  98. ev1 := types.NewMockGoodEvidence(height1, idx1, val1)
  99. ev2 := types.NewMockGoodEvidence(height2, idx2, val2)
  100. now := tmtime.Now()
  101. valSet := state.Validators
  102. testCases := []struct {
  103. desc string
  104. evidence []types.Evidence
  105. expectedByzantineValidators []abci.Evidence
  106. }{
  107. {"none byzantine", []types.Evidence{}, []abci.Evidence{}},
  108. {"one byzantine", []types.Evidence{ev1}, []abci.Evidence{types.TM2PB.Evidence(ev1, valSet, now)}},
  109. {"multiple byzantine", []types.Evidence{ev1, ev2}, []abci.Evidence{
  110. types.TM2PB.Evidence(ev1, valSet, now),
  111. types.TM2PB.Evidence(ev2, valSet, now)}},
  112. }
  113. commitSig0 := (&types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.PrecommitType}).CommitSig()
  114. commitSig1 := (&types.Vote{ValidatorIndex: 1, Timestamp: now}).CommitSig()
  115. commitSigs := []*types.CommitSig{commitSig0, commitSig1}
  116. lastCommit := types.NewCommit(prevBlockID, commitSigs)
  117. for _, tc := range testCases {
  118. block, _ := state.MakeBlock(10, makeTxs(2), lastCommit, nil, state.Validators.GetProposer().Address)
  119. block.Time = now
  120. block.Evidence.Evidence = tc.evidence
  121. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators, stateDB)
  122. require.Nil(t, err, tc.desc)
  123. // -> app must receive an index of the byzantine validator
  124. assert.Equal(t, tc.expectedByzantineValidators, app.ByzantineValidators, tc.desc)
  125. }
  126. }
  127. func TestValidateValidatorUpdates(t *testing.T) {
  128. pubkey1 := ed25519.GenPrivKey().PubKey()
  129. pubkey2 := ed25519.GenPrivKey().PubKey()
  130. secpKey := secp256k1.GenPrivKey().PubKey()
  131. defaultValidatorParams := types.ValidatorParams{[]string{types.ABCIPubKeyTypeEd25519}}
  132. testCases := []struct {
  133. name string
  134. abciUpdates []abci.ValidatorUpdate
  135. validatorParams types.ValidatorParams
  136. shouldErr bool
  137. }{
  138. {
  139. "adding a validator is OK",
  140. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 20}},
  141. defaultValidatorParams,
  142. false,
  143. },
  144. {
  145. "updating a validator is OK",
  146. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey1), Power: 20}},
  147. defaultValidatorParams,
  148. false,
  149. },
  150. {
  151. "removing a validator is OK",
  152. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
  153. defaultValidatorParams,
  154. false,
  155. },
  156. {
  157. "adding a validator with negative power results in error",
  158. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: -100}},
  159. defaultValidatorParams,
  160. true,
  161. },
  162. {
  163. "adding a validator with pubkey thats not in validator params results in error",
  164. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(secpKey), Power: -100}},
  165. defaultValidatorParams,
  166. true,
  167. },
  168. }
  169. for _, tc := range testCases {
  170. t.Run(tc.name, func(t *testing.T) {
  171. err := validateValidatorUpdates(tc.abciUpdates, tc.validatorParams)
  172. if tc.shouldErr {
  173. assert.Error(t, err)
  174. } else {
  175. assert.NoError(t, err)
  176. }
  177. })
  178. }
  179. }
  180. func TestUpdateValidators(t *testing.T) {
  181. pubkey1 := ed25519.GenPrivKey().PubKey()
  182. val1 := types.NewValidator(pubkey1, 10)
  183. pubkey2 := ed25519.GenPrivKey().PubKey()
  184. val2 := types.NewValidator(pubkey2, 20)
  185. testCases := []struct {
  186. name string
  187. currentSet *types.ValidatorSet
  188. abciUpdates []abci.ValidatorUpdate
  189. resultingSet *types.ValidatorSet
  190. shouldErr bool
  191. }{
  192. {
  193. "adding a validator is OK",
  194. types.NewValidatorSet([]*types.Validator{val1}),
  195. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 20}},
  196. types.NewValidatorSet([]*types.Validator{val1, val2}),
  197. false,
  198. },
  199. {
  200. "updating a validator is OK",
  201. types.NewValidatorSet([]*types.Validator{val1}),
  202. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey1), Power: 20}},
  203. types.NewValidatorSet([]*types.Validator{types.NewValidator(pubkey1, 20)}),
  204. false,
  205. },
  206. {
  207. "removing a validator is OK",
  208. types.NewValidatorSet([]*types.Validator{val1, val2}),
  209. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
  210. types.NewValidatorSet([]*types.Validator{val1}),
  211. false,
  212. },
  213. {
  214. "removing a non-existing validator results in error",
  215. types.NewValidatorSet([]*types.Validator{val1}),
  216. []abci.ValidatorUpdate{{PubKey: types.TM2PB.PubKey(pubkey2), Power: 0}},
  217. types.NewValidatorSet([]*types.Validator{val1}),
  218. true,
  219. },
  220. }
  221. for _, tc := range testCases {
  222. t.Run(tc.name, func(t *testing.T) {
  223. updates, err := types.PB2TM.ValidatorUpdates(tc.abciUpdates)
  224. assert.NoError(t, err)
  225. err = tc.currentSet.UpdateWithChangeSet(updates)
  226. if tc.shouldErr {
  227. assert.Error(t, err)
  228. } else {
  229. assert.NoError(t, err)
  230. require.Equal(t, tc.resultingSet.Size(), tc.currentSet.Size())
  231. assert.Equal(t, tc.resultingSet.TotalVotingPower(), tc.currentSet.TotalVotingPower())
  232. assert.Equal(t, tc.resultingSet.Validators[0].Address, tc.currentSet.Validators[0].Address)
  233. if tc.resultingSet.Size() > 1 {
  234. assert.Equal(t, tc.resultingSet.Validators[1].Address, tc.currentSet.Validators[1].Address)
  235. }
  236. }
  237. })
  238. }
  239. }
  240. // TestEndBlockValidatorUpdates ensures we update validator set and send an event.
  241. func TestEndBlockValidatorUpdates(t *testing.T) {
  242. app := &testApp{}
  243. cc := proxy.NewLocalClientCreator(app)
  244. proxyApp := proxy.NewAppConns(cc)
  245. err := proxyApp.Start()
  246. require.Nil(t, err)
  247. defer proxyApp.Stop()
  248. state, stateDB := state(1, 1)
  249. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), MockMempool{}, MockEvidencePool{})
  250. eventBus := types.NewEventBus()
  251. err = eventBus.Start()
  252. require.NoError(t, err)
  253. defer eventBus.Stop()
  254. blockExec.SetEventBus(eventBus)
  255. updatesSub, err := eventBus.Subscribe(context.Background(), "TestEndBlockValidatorUpdates", types.EventQueryValidatorSetUpdates)
  256. require.NoError(t, err)
  257. block := makeBlock(state, 1)
  258. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  259. pubkey := ed25519.GenPrivKey().PubKey()
  260. app.ValidatorUpdates = []abci.ValidatorUpdate{
  261. {PubKey: types.TM2PB.PubKey(pubkey), Power: 10},
  262. }
  263. state, err = blockExec.ApplyBlock(state, blockID, block)
  264. require.Nil(t, err)
  265. // test new validator was added to NextValidators
  266. if assert.Equal(t, state.Validators.Size()+1, state.NextValidators.Size()) {
  267. idx, _ := state.NextValidators.GetByAddress(pubkey.Address())
  268. if idx < 0 {
  269. t.Fatalf("can't find address %v in the set %v", pubkey.Address(), state.NextValidators)
  270. }
  271. }
  272. // test we threw an event
  273. select {
  274. case msg := <-updatesSub.Out():
  275. event, ok := msg.Data().(types.EventDataValidatorSetUpdates)
  276. require.True(t, ok, "Expected event of type EventDataValidatorSetUpdates, got %T", msg.Data())
  277. if assert.NotEmpty(t, event.ValidatorUpdates) {
  278. assert.Equal(t, pubkey, event.ValidatorUpdates[0].PubKey)
  279. assert.EqualValues(t, 10, event.ValidatorUpdates[0].VotingPower)
  280. }
  281. case <-updatesSub.Cancelled():
  282. t.Fatalf("updatesSub was cancelled (reason: %v)", updatesSub.Err())
  283. case <-time.After(1 * time.Second):
  284. t.Fatal("Did not receive EventValidatorSetUpdates within 1 sec.")
  285. }
  286. }
  287. // TestEndBlockValidatorUpdatesResultingInEmptySet checks that processing validator updates that
  288. // would result in empty set causes no panic, an error is raised and NextValidators is not updated
  289. func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) {
  290. app := &testApp{}
  291. cc := proxy.NewLocalClientCreator(app)
  292. proxyApp := proxy.NewAppConns(cc)
  293. err := proxyApp.Start()
  294. require.Nil(t, err)
  295. defer proxyApp.Stop()
  296. state, stateDB := state(1, 1)
  297. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(), MockMempool{}, MockEvidencePool{})
  298. block := makeBlock(state, 1)
  299. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  300. // Remove the only validator
  301. app.ValidatorUpdates = []abci.ValidatorUpdate{
  302. {PubKey: types.TM2PB.PubKey(state.Validators.Validators[0].PubKey), Power: 0},
  303. }
  304. assert.NotPanics(t, func() { state, err = blockExec.ApplyBlock(state, blockID, block) })
  305. assert.NotNil(t, err)
  306. assert.NotEmpty(t, state.NextValidators.Validators)
  307. }
  308. //----------------------------------------------------------------------------
  309. // make some bogus txs
  310. func makeTxs(height int64) (txs []types.Tx) {
  311. for i := 0; i < nTxsPerBlock; i++ {
  312. txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
  313. }
  314. return txs
  315. }
  316. func state(nVals, height int) (State, dbm.DB) {
  317. vals := make([]types.GenesisValidator, nVals)
  318. for i := 0; i < nVals; i++ {
  319. secret := []byte(fmt.Sprintf("test%d", i))
  320. pk := ed25519.GenPrivKeyFromSecret(secret)
  321. vals[i] = types.GenesisValidator{
  322. pk.PubKey().Address(),
  323. pk.PubKey(),
  324. 1000,
  325. fmt.Sprintf("test%d", i),
  326. }
  327. }
  328. s, _ := MakeGenesisState(&types.GenesisDoc{
  329. ChainID: chainID,
  330. Validators: vals,
  331. AppHash: nil,
  332. })
  333. // save validators to db for 2 heights
  334. stateDB := dbm.NewMemDB()
  335. SaveState(stateDB, s)
  336. for i := 1; i < height; i++ {
  337. s.LastBlockHeight++
  338. s.LastValidators = s.Validators.Copy()
  339. SaveState(stateDB, s)
  340. }
  341. return s, stateDB
  342. }
  343. func makeBlock(state State, height int64) *types.Block {
  344. block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit), nil, state.Validators.GetProposer().Address)
  345. return block
  346. }
  347. //----------------------------------------------------------------------------
  348. type testApp struct {
  349. abci.BaseApplication
  350. CommitVotes []abci.VoteInfo
  351. ByzantineValidators []abci.Evidence
  352. ValidatorUpdates []abci.ValidatorUpdate
  353. }
  354. var _ abci.Application = (*testApp)(nil)
  355. func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
  356. return abci.ResponseInfo{}
  357. }
  358. func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
  359. app.CommitVotes = req.LastCommitInfo.Votes
  360. app.ByzantineValidators = req.ByzantineValidators
  361. return abci.ResponseBeginBlock{}
  362. }
  363. func (app *testApp) EndBlock(req abci.RequestEndBlock) abci.ResponseEndBlock {
  364. return abci.ResponseEndBlock{ValidatorUpdates: app.ValidatorUpdates}
  365. }
  366. func (app *testApp) DeliverTx(tx []byte) abci.ResponseDeliverTx {
  367. return abci.ResponseDeliverTx{Tags: []cmn.KVPair{}}
  368. }
  369. func (app *testApp) CheckTx(tx []byte) abci.ResponseCheckTx {
  370. return abci.ResponseCheckTx{}
  371. }
  372. func (app *testApp) Commit() abci.ResponseCommit {
  373. return abci.ResponseCommit{}
  374. }
  375. func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
  376. return
  377. }