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.

868 lines
34 KiB

  1. package state
  2. import (
  3. "bytes"
  4. "fmt"
  5. "math/big"
  6. "testing"
  7. "github.com/stretchr/testify/assert"
  8. "github.com/stretchr/testify/require"
  9. abci "github.com/tendermint/tendermint/abci/types"
  10. "github.com/tendermint/tendermint/crypto"
  11. "github.com/tendermint/tendermint/crypto/ed25519"
  12. cmn "github.com/tendermint/tendermint/libs/common"
  13. dbm "github.com/tendermint/tendermint/libs/db"
  14. cfg "github.com/tendermint/tendermint/config"
  15. "github.com/tendermint/tendermint/types"
  16. )
  17. // setupTestCase does setup common to all test cases.
  18. func setupTestCase(t *testing.T) (func(t *testing.T), dbm.DB, State) {
  19. config := cfg.ResetTestRoot("state_")
  20. dbType := dbm.DBBackendType(config.DBBackend)
  21. stateDB := dbm.NewDB("state", dbType, config.DBDir())
  22. state, err := LoadStateFromDBOrGenesisFile(stateDB, config.GenesisFile())
  23. assert.NoError(t, err, "expected no error on LoadStateFromDBOrGenesisFile")
  24. tearDown := func(t *testing.T) {}
  25. return tearDown, stateDB, state
  26. }
  27. // TestStateCopy tests the correct copying behaviour of State.
  28. func TestStateCopy(t *testing.T) {
  29. tearDown, _, state := setupTestCase(t)
  30. defer tearDown(t)
  31. // nolint: vetshadow
  32. assert := assert.New(t)
  33. stateCopy := state.Copy()
  34. assert.True(state.Equals(stateCopy),
  35. fmt.Sprintf("expected state and its copy to be identical.\ngot: %v\nexpected: %v\n",
  36. stateCopy, state))
  37. stateCopy.LastBlockHeight++
  38. assert.False(state.Equals(stateCopy), fmt.Sprintf(`expected states to be different. got same
  39. %v`, state))
  40. }
  41. //TestMakeGenesisStateNilValidators tests state's consistency when genesis file's validators field is nil.
  42. func TestMakeGenesisStateNilValidators(t *testing.T) {
  43. doc := types.GenesisDoc{
  44. ChainID: "dummy",
  45. Validators: nil,
  46. }
  47. require.Nil(t, doc.ValidateAndComplete())
  48. state, err := MakeGenesisState(&doc)
  49. require.Nil(t, err)
  50. require.Equal(t, 0, len(state.Validators.Validators))
  51. require.Equal(t, 0, len(state.NextValidators.Validators))
  52. }
  53. // TestStateSaveLoad tests saving and loading State from a db.
  54. func TestStateSaveLoad(t *testing.T) {
  55. tearDown, stateDB, state := setupTestCase(t)
  56. defer tearDown(t)
  57. // nolint: vetshadow
  58. assert := assert.New(t)
  59. state.LastBlockHeight++
  60. SaveState(stateDB, state)
  61. loadedState := LoadState(stateDB)
  62. assert.True(state.Equals(loadedState),
  63. fmt.Sprintf("expected state and its copy to be identical.\ngot: %v\nexpected: %v\n",
  64. loadedState, state))
  65. }
  66. // TestABCIResponsesSaveLoad tests saving and loading ABCIResponses.
  67. func TestABCIResponsesSaveLoad1(t *testing.T) {
  68. tearDown, stateDB, state := setupTestCase(t)
  69. defer tearDown(t)
  70. // nolint: vetshadow
  71. assert := assert.New(t)
  72. state.LastBlockHeight++
  73. // Build mock responses.
  74. block := makeBlock(state, 2)
  75. abciResponses := NewABCIResponses(block)
  76. abciResponses.DeliverTx[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Tags: nil}
  77. abciResponses.DeliverTx[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Tags: nil}
  78. abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{
  79. types.TM2PB.NewValidatorUpdate(ed25519.GenPrivKey().PubKey(), 10),
  80. }}
  81. saveABCIResponses(stateDB, block.Height, abciResponses)
  82. loadedABCIResponses, err := LoadABCIResponses(stateDB, block.Height)
  83. assert.Nil(err)
  84. assert.Equal(abciResponses, loadedABCIResponses,
  85. fmt.Sprintf("ABCIResponses don't match:\ngot: %v\nexpected: %v\n",
  86. loadedABCIResponses, abciResponses))
  87. }
  88. // TestResultsSaveLoad tests saving and loading ABCI results.
  89. func TestABCIResponsesSaveLoad2(t *testing.T) {
  90. tearDown, stateDB, _ := setupTestCase(t)
  91. defer tearDown(t)
  92. // nolint: vetshadow
  93. assert := assert.New(t)
  94. cases := [...]struct {
  95. // Height is implied to equal index+2,
  96. // as block 1 is created from genesis.
  97. added []*abci.ResponseDeliverTx
  98. expected types.ABCIResults
  99. }{
  100. 0: {
  101. nil,
  102. nil,
  103. },
  104. 1: {
  105. []*abci.ResponseDeliverTx{
  106. {Code: 32, Data: []byte("Hello"), Log: "Huh?"},
  107. },
  108. types.ABCIResults{
  109. {32, []byte("Hello")},
  110. }},
  111. 2: {
  112. []*abci.ResponseDeliverTx{
  113. {Code: 383},
  114. {Data: []byte("Gotcha!"),
  115. Tags: []cmn.KVPair{
  116. {Key: []byte("a"), Value: []byte("1")},
  117. {Key: []byte("build"), Value: []byte("stuff")},
  118. }},
  119. },
  120. types.ABCIResults{
  121. {383, nil},
  122. {0, []byte("Gotcha!")},
  123. }},
  124. 3: {
  125. nil,
  126. nil,
  127. },
  128. }
  129. // Query all before, this should return error.
  130. for i := range cases {
  131. h := int64(i + 1)
  132. res, err := LoadABCIResponses(stateDB, h)
  133. assert.Error(err, "%d: %#v", i, res)
  134. }
  135. // Add all cases.
  136. for i, tc := range cases {
  137. h := int64(i + 1) // last block height, one below what we save
  138. responses := &ABCIResponses{
  139. DeliverTx: tc.added,
  140. EndBlock: &abci.ResponseEndBlock{},
  141. }
  142. saveABCIResponses(stateDB, h, responses)
  143. }
  144. // Query all before, should return expected value.
  145. for i, tc := range cases {
  146. h := int64(i + 1)
  147. res, err := LoadABCIResponses(stateDB, h)
  148. assert.NoError(err, "%d", i)
  149. assert.Equal(tc.expected.Hash(), res.ResultsHash(), "%d", i)
  150. }
  151. }
  152. // TestValidatorSimpleSaveLoad tests saving and loading validators.
  153. func TestValidatorSimpleSaveLoad(t *testing.T) {
  154. tearDown, stateDB, state := setupTestCase(t)
  155. defer tearDown(t)
  156. // nolint: vetshadow
  157. assert := assert.New(t)
  158. // Can't load anything for height 0.
  159. v, err := LoadValidators(stateDB, 0)
  160. assert.IsType(ErrNoValSetForHeight{}, err, "expected err at height 0")
  161. // Should be able to load for height 1.
  162. v, err = LoadValidators(stateDB, 1)
  163. assert.Nil(err, "expected no err at height 1")
  164. assert.Equal(v.Hash(), state.Validators.Hash(), "expected validator hashes to match")
  165. // Should be able to load for height 2.
  166. v, err = LoadValidators(stateDB, 2)
  167. assert.Nil(err, "expected no err at height 2")
  168. assert.Equal(v.Hash(), state.NextValidators.Hash(), "expected validator hashes to match")
  169. // Increment height, save; should be able to load for next & next next height.
  170. state.LastBlockHeight++
  171. nextHeight := state.LastBlockHeight + 1
  172. saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
  173. vp0, err := LoadValidators(stateDB, nextHeight+0)
  174. assert.Nil(err, "expected no err")
  175. vp1, err := LoadValidators(stateDB, nextHeight+1)
  176. assert.Nil(err, "expected no err")
  177. assert.Equal(vp0.Hash(), state.Validators.Hash(), "expected validator hashes to match")
  178. assert.Equal(vp1.Hash(), state.NextValidators.Hash(), "expected next validator hashes to match")
  179. }
  180. // TestValidatorChangesSaveLoad tests saving and loading a validator set with changes.
  181. func TestOneValidatorChangesSaveLoad(t *testing.T) {
  182. tearDown, stateDB, state := setupTestCase(t)
  183. defer tearDown(t)
  184. // Change vals at these heights.
  185. changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
  186. N := len(changeHeights)
  187. // Build the validator history by running updateState
  188. // with the right validator set for each height.
  189. highestHeight := changeHeights[N-1] + 5
  190. changeIndex := 0
  191. _, val := state.Validators.GetByIndex(0)
  192. power := val.VotingPower
  193. var err error
  194. var validatorUpdates []*types.Validator
  195. for i := int64(1); i < highestHeight; i++ {
  196. // When we get to a change height, use the next pubkey.
  197. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
  198. changeIndex++
  199. power++
  200. }
  201. header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, i, power)
  202. validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
  203. require.NoError(t, err)
  204. state, err = updateState(state, blockID, &header, responses, validatorUpdates)
  205. require.NoError(t, err)
  206. nextHeight := state.LastBlockHeight + 1
  207. saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
  208. }
  209. // On each height change, increment the power by one.
  210. testCases := make([]int64, highestHeight)
  211. changeIndex = 0
  212. power = val.VotingPower
  213. for i := int64(1); i < highestHeight+1; i++ {
  214. // We get to the height after a change height use the next pubkey (note
  215. // our counter starts at 0 this time).
  216. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
  217. changeIndex++
  218. power++
  219. }
  220. testCases[i-1] = power
  221. }
  222. for i, power := range testCases {
  223. v, err := LoadValidators(stateDB, int64(i+1+1)) // +1 because vset changes delayed by 1 block.
  224. assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", i))
  225. assert.Equal(t, v.Size(), 1, "validator set size is greater than 1: %d", v.Size())
  226. _, val := v.GetByIndex(0)
  227. assert.Equal(t, val.VotingPower, power, fmt.Sprintf(`unexpected powerat
  228. height %d`, i))
  229. }
  230. }
  231. func TestProposerPriorityDoesNotGetResetToZero(t *testing.T) {
  232. // assert that we preserve accum when calling updateState:
  233. // https://github.com/tendermint/tendermint/issues/2718
  234. tearDown, _, state := setupTestCase(t)
  235. defer tearDown(t)
  236. origVotingPower := int64(10)
  237. val1PubKey := ed25519.GenPrivKey().PubKey()
  238. val1 := &types.Validator{Address: val1PubKey.Address(), PubKey: val1PubKey, VotingPower: origVotingPower}
  239. state.Validators = types.NewValidatorSet([]*types.Validator{val1})
  240. state.NextValidators = state.Validators
  241. // NewValidatorSet calls IncrementProposerPriority but uses on a copy of val1
  242. assert.EqualValues(t, 0, val1.ProposerPriority)
  243. block := makeBlock(state, state.LastBlockHeight+1)
  244. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  245. abciResponses := &ABCIResponses{
  246. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  247. }
  248. validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  249. require.NoError(t, err)
  250. updatedState, err := updateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
  251. assert.NoError(t, err)
  252. assert.Equal(t, -origVotingPower, updatedState.NextValidators.Validators[0].ProposerPriority)
  253. // add a validator
  254. val2PubKey := ed25519.GenPrivKey().PubKey()
  255. val2VotingPower := int64(100)
  256. updateAddVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(val2PubKey), Power: val2VotingPower}
  257. validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal})
  258. assert.NoError(t, err)
  259. updatedState2, err := updateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates)
  260. assert.NoError(t, err)
  261. require.Equal(t, len(updatedState2.NextValidators.Validators), 2)
  262. _, addedVal2 := updatedState2.NextValidators.GetByAddress(val2PubKey.Address())
  263. // adding a validator should not lead to a ProposerPriority equal to zero (unless the combination of averaging and
  264. // incrementing would cause so; which is not the case here)
  265. totalPowerBefore2 := origVotingPower // 10
  266. wantVal2ProposerPrio := -(totalPowerBefore2 + (totalPowerBefore2 >> 3)) + val2VotingPower // 89
  267. avg := (0 + wantVal2ProposerPrio) / 2 // 44
  268. wantVal2ProposerPrio -= avg // 45
  269. totalPowerAfter := origVotingPower + val2VotingPower // 110
  270. wantVal2ProposerPrio -= totalPowerAfter // -65
  271. assert.Equal(t, wantVal2ProposerPrio, addedVal2.ProposerPriority) // not zero == -65
  272. // Updating a validator does not reset the ProposerPriority to zero:
  273. updatedVotingPowVal2 := int64(1)
  274. updateVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(val2PubKey), Power: updatedVotingPowVal2}
  275. validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateVal})
  276. assert.NoError(t, err)
  277. updatedState3, err := updateState(updatedState2, blockID, &block.Header, abciResponses, validatorUpdates)
  278. assert.NoError(t, err)
  279. require.Equal(t, len(updatedState3.NextValidators.Validators), 2)
  280. _, prevVal1 := updatedState3.Validators.GetByAddress(val1PubKey.Address())
  281. _, updatedVal2 := updatedState3.NextValidators.GetByAddress(val2PubKey.Address())
  282. expectedVal1PrioBeforeAvg := prevVal1.ProposerPriority + prevVal1.VotingPower // -44 + 10 == -34
  283. wantVal2ProposerPrio = wantVal2ProposerPrio + updatedVotingPowVal2 // -64
  284. avg = (wantVal2ProposerPrio + expectedVal1PrioBeforeAvg) / 2 // (-64-34)/2 == -49
  285. wantVal2ProposerPrio = wantVal2ProposerPrio - avg // -15
  286. assert.Equal(t, wantVal2ProposerPrio, updatedVal2.ProposerPriority) // -15
  287. }
  288. func TestProposerPriorityProposerAlternates(t *testing.T) {
  289. // Regression test that would fail if the inner workings of
  290. // IncrementProposerPriority change.
  291. // Additionally, make sure that same power validators alternate if both
  292. // have the same voting power (and the 2nd was added later).
  293. tearDown, _, state := setupTestCase(t)
  294. defer tearDown(t)
  295. origVotinPower := int64(10)
  296. val1PubKey := ed25519.GenPrivKey().PubKey()
  297. val1 := &types.Validator{Address: val1PubKey.Address(), PubKey: val1PubKey, VotingPower: origVotinPower}
  298. // reset state validators to above validator
  299. state.Validators = types.NewValidatorSet([]*types.Validator{val1})
  300. state.NextValidators = state.Validators
  301. // we only have one validator:
  302. assert.Equal(t, val1PubKey.Address(), state.Validators.Proposer.Address)
  303. block := makeBlock(state, state.LastBlockHeight+1)
  304. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  305. // no updates:
  306. abciResponses := &ABCIResponses{
  307. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  308. }
  309. validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  310. require.NoError(t, err)
  311. updatedState, err := updateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
  312. assert.NoError(t, err)
  313. // 0 + 10 (initial prio) - 10 (avg) - 10 (mostest - total) = -10
  314. assert.Equal(t, -origVotinPower, updatedState.NextValidators.Validators[0].ProposerPriority)
  315. assert.Equal(t, val1PubKey.Address(), updatedState.NextValidators.Proposer.Address)
  316. // add a validator with the same voting power as the first
  317. val2PubKey := ed25519.GenPrivKey().PubKey()
  318. updateAddVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(val2PubKey), Power: origVotinPower}
  319. validatorUpdates, err = types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{updateAddVal})
  320. assert.NoError(t, err)
  321. updatedState2, err := updateState(updatedState, blockID, &block.Header, abciResponses, validatorUpdates)
  322. assert.NoError(t, err)
  323. require.Equal(t, len(updatedState2.NextValidators.Validators), 2)
  324. assert.Equal(t, updatedState2.Validators, updatedState.NextValidators)
  325. // val1 will still be proposer as val2 just got added:
  326. assert.Equal(t, val1PubKey.Address(), updatedState.NextValidators.Proposer.Address)
  327. assert.Equal(t, updatedState2.Validators.Proposer.Address, updatedState2.NextValidators.Proposer.Address)
  328. assert.Equal(t, updatedState2.Validators.Proposer.Address, val1PubKey.Address())
  329. assert.Equal(t, updatedState2.NextValidators.Proposer.Address, val1PubKey.Address())
  330. _, updatedVal1 := updatedState2.NextValidators.GetByAddress(val1PubKey.Address())
  331. _, oldVal1 := updatedState2.Validators.GetByAddress(val1PubKey.Address())
  332. _, updatedVal2 := updatedState2.NextValidators.GetByAddress(val2PubKey.Address())
  333. totalPower := origVotinPower
  334. v2PrioWhenAddedVal2 := -(totalPower + (totalPower >> 3))
  335. v2PrioWhenAddedVal2 = v2PrioWhenAddedVal2 + origVotinPower // -11 + 10 == -1
  336. v1PrioWhenAddedVal2 := oldVal1.ProposerPriority + origVotinPower // -10 + 10 == 0
  337. // have to express the AVG in big.Ints as -1/2 == -1 in big.Int while -1/2 == 0 in int64
  338. avgSum := big.NewInt(0).Add(big.NewInt(v2PrioWhenAddedVal2), big.NewInt(v1PrioWhenAddedVal2))
  339. avg := avgSum.Div(avgSum, big.NewInt(2))
  340. expectedVal2Prio := v2PrioWhenAddedVal2 - avg.Int64()
  341. totalPower = 2 * origVotinPower // 10 + 10
  342. expectedVal1Prio := oldVal1.ProposerPriority + origVotinPower - avg.Int64() - totalPower
  343. // val1's ProposerPriority story: -10 (see above) + 10 (voting pow) - (-1) (avg) - 20 (total) == -19
  344. assert.EqualValues(t, expectedVal1Prio, updatedVal1.ProposerPriority)
  345. // val2 prio when added: -(totalVotingPower + (totalVotingPower >> 3)) == -11
  346. // -> -11 + 10 (voting power) - (-1) (avg) == 0
  347. assert.EqualValues(t, expectedVal2Prio, updatedVal2.ProposerPriority, "unexpected proposer priority for validator: %v", updatedVal2)
  348. validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  349. require.NoError(t, err)
  350. updatedState3, err := updateState(updatedState2, blockID, &block.Header, abciResponses, validatorUpdates)
  351. assert.NoError(t, err)
  352. // proposer changes from now on (every iteration) as long as there are no changes in the validator set:
  353. assert.NotEqual(t, updatedState3.Validators.Proposer.Address, updatedState3.NextValidators.Proposer.Address)
  354. assert.Equal(t, updatedState3.Validators, updatedState2.NextValidators)
  355. _, updatedVal1 = updatedState3.NextValidators.GetByAddress(val1PubKey.Address())
  356. _, oldVal1 = updatedState3.Validators.GetByAddress(val1PubKey.Address())
  357. _, updatedVal2 = updatedState3.NextValidators.GetByAddress(val2PubKey.Address())
  358. _, oldVal2 := updatedState3.Validators.GetByAddress(val2PubKey.Address())
  359. // val2 will be proposer:
  360. assert.Equal(t, val2PubKey.Address(), updatedState3.NextValidators.Proposer.Address)
  361. // check if expected proposer prio is matched:
  362. avgSum = big.NewInt(oldVal1.ProposerPriority + origVotinPower + oldVal2.ProposerPriority + origVotinPower)
  363. avg = avgSum.Div(avgSum, big.NewInt(2))
  364. expectedVal1Prio2 := oldVal1.ProposerPriority + origVotinPower - avg.Int64()
  365. expectedVal2Prio2 := oldVal2.ProposerPriority + origVotinPower - avg.Int64() - totalPower
  366. // -19 + 10 - 0 (avg) == -9
  367. assert.EqualValues(t, expectedVal1Prio2, updatedVal1.ProposerPriority, "unexpected proposer priority for validator: %v", updatedVal2)
  368. // 0 + 10 - 0 (avg) - 20 (total) == -10
  369. assert.EqualValues(t, expectedVal2Prio2, updatedVal2.ProposerPriority, "unexpected proposer priority for validator: %v", updatedVal2)
  370. // no changes in voting power and both validators have same voting power
  371. // -> proposers should alternate:
  372. oldState := updatedState3
  373. for i := 0; i < 1000; i++ {
  374. // no validator updates:
  375. abciResponses := &ABCIResponses{
  376. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  377. }
  378. validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  379. require.NoError(t, err)
  380. updatedState, err := updateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
  381. assert.NoError(t, err)
  382. // alternate (and cyclic priorities):
  383. assert.NotEqual(t, updatedState.Validators.Proposer.Address, updatedState.NextValidators.Proposer.Address, "iter: %v", i)
  384. assert.Equal(t, oldState.Validators.Proposer.Address, updatedState.NextValidators.Proposer.Address, "iter: %v", i)
  385. _, updatedVal1 = updatedState.NextValidators.GetByAddress(val1PubKey.Address())
  386. _, updatedVal2 = updatedState.NextValidators.GetByAddress(val2PubKey.Address())
  387. if i%2 == 0 {
  388. assert.Equal(t, updatedState.Validators.Proposer.Address, val2PubKey.Address())
  389. assert.Equal(t, expectedVal1Prio, updatedVal1.ProposerPriority) // -19
  390. assert.Equal(t, expectedVal2Prio, updatedVal2.ProposerPriority) // 0
  391. } else {
  392. assert.Equal(t, updatedState.Validators.Proposer.Address, val1PubKey.Address())
  393. assert.Equal(t, expectedVal1Prio2, updatedVal1.ProposerPriority) // -9
  394. assert.Equal(t, expectedVal2Prio2, updatedVal2.ProposerPriority) // -10
  395. }
  396. // update for next iteration:
  397. oldState = updatedState
  398. }
  399. }
  400. func TestLargeGenesisValidator(t *testing.T) {
  401. tearDown, _, state := setupTestCase(t)
  402. defer tearDown(t)
  403. // TODO: increase genesis voting power to sth. more close to MaxTotalVotingPower with changes that
  404. // fix with tendermint/issues/2960; currently, the last iteration would take forever though
  405. genesisVotingPower := int64(types.MaxTotalVotingPower / 100000000000000)
  406. genesisPubKey := ed25519.GenPrivKey().PubKey()
  407. // fmt.Println("genesis addr: ", genesisPubKey.Address())
  408. genesisVal := &types.Validator{Address: genesisPubKey.Address(), PubKey: genesisPubKey, VotingPower: genesisVotingPower}
  409. // reset state validators to above validator
  410. state.Validators = types.NewValidatorSet([]*types.Validator{genesisVal})
  411. state.NextValidators = state.Validators
  412. require.True(t, len(state.Validators.Validators) == 1)
  413. // update state a few times with no validator updates
  414. // asserts that the single validator's ProposerPrio stays the same
  415. oldState := state
  416. for i := 0; i < 10; i++ {
  417. // no updates:
  418. abciResponses := &ABCIResponses{
  419. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  420. }
  421. validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  422. require.NoError(t, err)
  423. block := makeBlock(oldState, oldState.LastBlockHeight+1)
  424. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  425. updatedState, err := updateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
  426. // no changes in voting power (ProposerPrio += VotingPower == 0 in 1st round; than shiftByAvg == no-op,
  427. // than -Total == -Voting)
  428. // -> no change in ProposerPrio (stays -Total == -VotingPower):
  429. assert.EqualValues(t, oldState.NextValidators, updatedState.NextValidators)
  430. assert.EqualValues(t, -genesisVotingPower, updatedState.NextValidators.Proposer.ProposerPriority)
  431. oldState = updatedState
  432. }
  433. // add another validator, do a few iterations (create blocks),
  434. // add more validators with same voting power as the 2nd
  435. // let the genesis validator "unbond",
  436. // see how long it takes until the effect wears off and both begin to alternate
  437. // see: https://github.com/tendermint/tendermint/issues/2960
  438. firstAddedValPubKey := ed25519.GenPrivKey().PubKey()
  439. // fmt.Println("first added addr: ", firstAddedValPubKey.Address())
  440. firstAddedValVotingPower := int64(10)
  441. firstAddedVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(firstAddedValPubKey), Power: firstAddedValVotingPower}
  442. validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{firstAddedVal})
  443. assert.NoError(t, err)
  444. abciResponses := &ABCIResponses{
  445. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{firstAddedVal}},
  446. }
  447. block := makeBlock(oldState, oldState.LastBlockHeight+1)
  448. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  449. updatedState, err := updateState(oldState, blockID, &block.Header, abciResponses, validatorUpdates)
  450. lastState := updatedState
  451. for i := 0; i < 200; i++ {
  452. // no updates:
  453. abciResponses := &ABCIResponses{
  454. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  455. }
  456. validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  457. require.NoError(t, err)
  458. block := makeBlock(lastState, lastState.LastBlockHeight+1)
  459. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  460. updatedStateInner, err := updateState(lastState, blockID, &block.Header, abciResponses, validatorUpdates)
  461. lastState = updatedStateInner
  462. }
  463. // set state to last state of above iteration
  464. state = lastState
  465. // set oldState to state before above iteration
  466. oldState = updatedState
  467. _, oldGenesisVal := oldState.NextValidators.GetByAddress(genesisVal.Address)
  468. _, newGenesisVal := state.NextValidators.GetByAddress(genesisVal.Address)
  469. _, addedOldVal := oldState.NextValidators.GetByAddress(firstAddedValPubKey.Address())
  470. _, addedNewVal := state.NextValidators.GetByAddress(firstAddedValPubKey.Address())
  471. // expect large negative proposer priority for both (genesis validator decreased, 2nd validator increased):
  472. assert.True(t, oldGenesisVal.ProposerPriority > newGenesisVal.ProposerPriority)
  473. assert.True(t, addedOldVal.ProposerPriority < addedNewVal.ProposerPriority)
  474. // add 10 validators with the same voting power as the one added directly after genesis:
  475. for i := 0; i < 10; i++ {
  476. addedPubKey := ed25519.GenPrivKey().PubKey()
  477. addedVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(addedPubKey), Power: firstAddedValVotingPower}
  478. validatorUpdates, err := types.PB2TM.ValidatorUpdates([]abci.ValidatorUpdate{addedVal})
  479. assert.NoError(t, err)
  480. abciResponses := &ABCIResponses{
  481. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{addedVal}},
  482. }
  483. block := makeBlock(oldState, oldState.LastBlockHeight+1)
  484. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  485. state, err = updateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
  486. }
  487. require.Equal(t, 10+2, len(state.NextValidators.Validators))
  488. // remove genesis validator:
  489. removeGenesisVal := abci.ValidatorUpdate{PubKey: types.TM2PB.PubKey(genesisPubKey), Power: 0}
  490. abciResponses = &ABCIResponses{
  491. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: []abci.ValidatorUpdate{removeGenesisVal}},
  492. }
  493. block = makeBlock(oldState, oldState.LastBlockHeight+1)
  494. blockID = types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  495. validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  496. require.NoError(t, err)
  497. updatedState, err = updateState(state, blockID, &block.Header, abciResponses, validatorUpdates)
  498. require.NoError(t, err)
  499. // only the first added val (not the genesis val) should be left
  500. assert.Equal(t, 11, len(updatedState.NextValidators.Validators))
  501. // call update state until the effect for the 3rd added validator
  502. // being proposer for a long time after the genesis validator left wears off:
  503. curState := updatedState
  504. count := 0
  505. isProposerUnchanged := true
  506. for isProposerUnchanged {
  507. abciResponses := &ABCIResponses{
  508. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  509. }
  510. validatorUpdates, err = types.PB2TM.ValidatorUpdates(abciResponses.EndBlock.ValidatorUpdates)
  511. require.NoError(t, err)
  512. block = makeBlock(curState, curState.LastBlockHeight+1)
  513. blockID = types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  514. curState, err = updateState(curState, blockID, &block.Header, abciResponses, validatorUpdates)
  515. if !bytes.Equal(curState.Validators.Proposer.Address, curState.NextValidators.Proposer.Address) {
  516. isProposerUnchanged = false
  517. }
  518. count++
  519. }
  520. // first proposer change happens after this many iters; we probably want to lower this number:
  521. // TODO: change with https://github.com/tendermint/tendermint/issues/2960
  522. firstProposerChangeExpectedAfter := 438
  523. assert.Equal(t, firstProposerChangeExpectedAfter, count)
  524. }
  525. func TestStoreLoadValidatorsIncrementsProposerPriority(t *testing.T) {
  526. const valSetSize = 2
  527. tearDown, stateDB, state := setupTestCase(t)
  528. state.Validators = genValSet(valSetSize)
  529. state.NextValidators = state.Validators.CopyIncrementProposerPriority(1)
  530. SaveState(stateDB, state)
  531. defer tearDown(t)
  532. nextHeight := state.LastBlockHeight + 1
  533. v0, err := LoadValidators(stateDB, nextHeight)
  534. assert.Nil(t, err)
  535. acc0 := v0.Validators[0].ProposerPriority
  536. v1, err := LoadValidators(stateDB, nextHeight+1)
  537. assert.Nil(t, err)
  538. acc1 := v1.Validators[0].ProposerPriority
  539. assert.NotEqual(t, acc1, acc0, "expected ProposerPriority value to change between heights")
  540. }
  541. // TestValidatorChangesSaveLoad tests saving and loading a validator set with
  542. // changes.
  543. func TestManyValidatorChangesSaveLoad(t *testing.T) {
  544. const valSetSize = 7
  545. tearDown, stateDB, state := setupTestCase(t)
  546. require.Equal(t, int64(0), state.LastBlockHeight)
  547. state.Validators = genValSet(valSetSize)
  548. state.NextValidators = state.Validators.CopyIncrementProposerPriority(1)
  549. SaveState(stateDB, state)
  550. defer tearDown(t)
  551. _, valOld := state.Validators.GetByIndex(0)
  552. var pubkeyOld = valOld.PubKey
  553. pubkey := ed25519.GenPrivKey().PubKey()
  554. const height = 1
  555. // Swap the first validator with a new one (validator set size stays the same).
  556. header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, height, pubkey)
  557. // Save state etc.
  558. var err error
  559. var validatorUpdates []*types.Validator
  560. validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
  561. require.NoError(t, err)
  562. state, err = updateState(state, blockID, &header, responses, validatorUpdates)
  563. require.Nil(t, err)
  564. nextHeight := state.LastBlockHeight + 1
  565. saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
  566. // Load nextheight, it should be the oldpubkey.
  567. v0, err := LoadValidators(stateDB, nextHeight)
  568. assert.Nil(t, err)
  569. assert.Equal(t, valSetSize, v0.Size())
  570. index, val := v0.GetByAddress(pubkeyOld.Address())
  571. assert.NotNil(t, val)
  572. if index < 0 {
  573. t.Fatal("expected to find old validator")
  574. }
  575. // Load nextheight+1, it should be the new pubkey.
  576. v1, err := LoadValidators(stateDB, nextHeight+1)
  577. assert.Nil(t, err)
  578. assert.Equal(t, valSetSize, v1.Size())
  579. index, val = v1.GetByAddress(pubkey.Address())
  580. assert.NotNil(t, val)
  581. if index < 0 {
  582. t.Fatal("expected to find newly added validator")
  583. }
  584. }
  585. func genValSet(size int) *types.ValidatorSet {
  586. vals := make([]*types.Validator, size)
  587. for i := 0; i < size; i++ {
  588. vals[i] = types.NewValidator(ed25519.GenPrivKey().PubKey(), 10)
  589. }
  590. return types.NewValidatorSet(vals)
  591. }
  592. func TestStateMakeBlock(t *testing.T) {
  593. tearDown, _, state := setupTestCase(t)
  594. defer tearDown(t)
  595. proposerAddress := state.Validators.GetProposer().Address
  596. stateVersion := state.Version.Consensus
  597. block := makeBlock(state, 2)
  598. // test we set some fields
  599. assert.Equal(t, stateVersion, block.Version)
  600. assert.Equal(t, proposerAddress, block.ProposerAddress)
  601. }
  602. // TestConsensusParamsChangesSaveLoad tests saving and loading consensus params
  603. // with changes.
  604. func TestConsensusParamsChangesSaveLoad(t *testing.T) {
  605. tearDown, stateDB, state := setupTestCase(t)
  606. defer tearDown(t)
  607. // Change vals at these heights.
  608. changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
  609. N := len(changeHeights)
  610. // Each valset is just one validator.
  611. // create list of them.
  612. params := make([]types.ConsensusParams, N+1)
  613. params[0] = state.ConsensusParams
  614. for i := 1; i < N+1; i++ {
  615. params[i] = *types.DefaultConsensusParams()
  616. params[i].BlockSize.MaxBytes += int64(i)
  617. }
  618. // Build the params history by running updateState
  619. // with the right params set for each height.
  620. highestHeight := changeHeights[N-1] + 5
  621. changeIndex := 0
  622. cp := params[changeIndex]
  623. var err error
  624. var validatorUpdates []*types.Validator
  625. for i := int64(1); i < highestHeight; i++ {
  626. // When we get to a change height, use the next params.
  627. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
  628. changeIndex++
  629. cp = params[changeIndex]
  630. }
  631. header, blockID, responses := makeHeaderPartsResponsesParams(state, i, cp)
  632. validatorUpdates, err = types.PB2TM.ValidatorUpdates(responses.EndBlock.ValidatorUpdates)
  633. require.NoError(t, err)
  634. state, err = updateState(state, blockID, &header, responses, validatorUpdates)
  635. require.Nil(t, err)
  636. nextHeight := state.LastBlockHeight + 1
  637. saveConsensusParamsInfo(stateDB, nextHeight, state.LastHeightConsensusParamsChanged, state.ConsensusParams)
  638. }
  639. // Make all the test cases by using the same params until after the change.
  640. testCases := make([]paramsChangeTestCase, highestHeight)
  641. changeIndex = 0
  642. cp = params[changeIndex]
  643. for i := int64(1); i < highestHeight+1; i++ {
  644. // We get to the height after a change height use the next pubkey (note
  645. // our counter starts at 0 this time).
  646. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
  647. changeIndex++
  648. cp = params[changeIndex]
  649. }
  650. testCases[i-1] = paramsChangeTestCase{i, cp}
  651. }
  652. for _, testCase := range testCases {
  653. p, err := LoadConsensusParams(stateDB, testCase.height)
  654. assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", testCase.height))
  655. assert.Equal(t, testCase.params, p, fmt.Sprintf(`unexpected consensus params at
  656. height %d`, testCase.height))
  657. }
  658. }
  659. func makeParams(blockBytes, blockGas, evidenceAge int64) types.ConsensusParams {
  660. return types.ConsensusParams{
  661. BlockSize: types.BlockSizeParams{
  662. MaxBytes: blockBytes,
  663. MaxGas: blockGas,
  664. },
  665. Evidence: types.EvidenceParams{
  666. MaxAge: evidenceAge,
  667. },
  668. }
  669. }
  670. func pk() []byte {
  671. return ed25519.GenPrivKey().PubKey().Bytes()
  672. }
  673. func TestApplyUpdates(t *testing.T) {
  674. initParams := makeParams(1, 2, 3)
  675. cases := [...]struct {
  676. init types.ConsensusParams
  677. updates abci.ConsensusParams
  678. expected types.ConsensusParams
  679. }{
  680. 0: {initParams, abci.ConsensusParams{}, initParams},
  681. 1: {initParams, abci.ConsensusParams{}, initParams},
  682. 2: {initParams,
  683. abci.ConsensusParams{
  684. BlockSize: &abci.BlockSizeParams{
  685. MaxBytes: 44,
  686. MaxGas: 55,
  687. },
  688. },
  689. makeParams(44, 55, 3)},
  690. 3: {initParams,
  691. abci.ConsensusParams{
  692. Evidence: &abci.EvidenceParams{
  693. MaxAge: 66,
  694. },
  695. },
  696. makeParams(1, 2, 66)},
  697. }
  698. for i, tc := range cases {
  699. res := tc.init.Update(&(tc.updates))
  700. assert.Equal(t, tc.expected, res, "case %d", i)
  701. }
  702. }
  703. func makeHeaderPartsResponsesValPubKeyChange(state State, height int64,
  704. pubkey crypto.PubKey) (types.Header, types.BlockID, *ABCIResponses) {
  705. block := makeBlock(state, state.LastBlockHeight+1)
  706. abciResponses := &ABCIResponses{
  707. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  708. }
  709. // If the pubkey is new, remove the old and add the new.
  710. _, val := state.NextValidators.GetByIndex(0)
  711. if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) {
  712. abciResponses.EndBlock = &abci.ResponseEndBlock{
  713. ValidatorUpdates: []abci.ValidatorUpdate{
  714. types.TM2PB.NewValidatorUpdate(val.PubKey, 0),
  715. types.TM2PB.NewValidatorUpdate(pubkey, 10),
  716. },
  717. }
  718. }
  719. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  720. }
  721. func makeHeaderPartsResponsesValPowerChange(state State, height int64,
  722. power int64) (types.Header, types.BlockID, *ABCIResponses) {
  723. block := makeBlock(state, state.LastBlockHeight+1)
  724. abciResponses := &ABCIResponses{
  725. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  726. }
  727. // If the pubkey is new, remove the old and add the new.
  728. _, val := state.NextValidators.GetByIndex(0)
  729. if val.VotingPower != power {
  730. abciResponses.EndBlock = &abci.ResponseEndBlock{
  731. ValidatorUpdates: []abci.ValidatorUpdate{
  732. types.TM2PB.NewValidatorUpdate(val.PubKey, power),
  733. },
  734. }
  735. }
  736. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  737. }
  738. func makeHeaderPartsResponsesParams(state State, height int64,
  739. params types.ConsensusParams) (types.Header, types.BlockID, *ABCIResponses) {
  740. block := makeBlock(state, state.LastBlockHeight+1)
  741. abciResponses := &ABCIResponses{
  742. EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: types.TM2PB.ConsensusParams(&params)},
  743. }
  744. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  745. }
  746. type paramsChangeTestCase struct {
  747. height int64
  748. params types.ConsensusParams
  749. }