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.

488 lines
15 KiB

  1. package state
  2. import (
  3. "bytes"
  4. "fmt"
  5. "testing"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. abci "github.com/tendermint/tendermint/abci/types"
  9. crypto "github.com/tendermint/tendermint/crypto"
  10. cmn "github.com/tendermint/tmlibs/common"
  11. dbm "github.com/tendermint/tmlibs/db"
  12. cfg "github.com/tendermint/tendermint/config"
  13. "github.com/tendermint/tendermint/types"
  14. )
  15. // setupTestCase does setup common to all test cases.
  16. func setupTestCase(t *testing.T) (func(t *testing.T), dbm.DB, State) {
  17. config := cfg.ResetTestRoot("state_")
  18. dbType := dbm.DBBackendType(config.DBBackend)
  19. stateDB := dbm.NewDB("state", dbType, config.DBDir())
  20. state, err := LoadStateFromDBOrGenesisFile(stateDB, config.GenesisFile())
  21. assert.NoError(t, err, "expected no error on LoadStateFromDBOrGenesisFile")
  22. tearDown := func(t *testing.T) {}
  23. return tearDown, stateDB, state
  24. }
  25. // TestStateCopy tests the correct copying behaviour of State.
  26. func TestStateCopy(t *testing.T) {
  27. tearDown, _, state := setupTestCase(t)
  28. defer tearDown(t)
  29. // nolint: vetshadow
  30. assert := assert.New(t)
  31. stateCopy := state.Copy()
  32. assert.True(state.Equals(stateCopy),
  33. cmn.Fmt("expected state and its copy to be identical.\ngot: %v\nexpected: %v\n",
  34. stateCopy, state))
  35. stateCopy.LastBlockHeight++
  36. assert.False(state.Equals(stateCopy), cmn.Fmt(`expected states to be different. got same
  37. %v`, state))
  38. }
  39. // TestStateSaveLoad tests saving and loading State from a db.
  40. func TestStateSaveLoad(t *testing.T) {
  41. tearDown, stateDB, state := setupTestCase(t)
  42. defer tearDown(t)
  43. // nolint: vetshadow
  44. assert := assert.New(t)
  45. state.LastBlockHeight++
  46. SaveState(stateDB, state)
  47. loadedState := LoadState(stateDB)
  48. assert.True(state.Equals(loadedState),
  49. cmn.Fmt("expected state and its copy to be identical.\ngot: %v\nexpected: %v\n",
  50. loadedState, state))
  51. }
  52. // TestABCIResponsesSaveLoad tests saving and loading ABCIResponses.
  53. func TestABCIResponsesSaveLoad1(t *testing.T) {
  54. tearDown, stateDB, state := setupTestCase(t)
  55. defer tearDown(t)
  56. // nolint: vetshadow
  57. assert := assert.New(t)
  58. state.LastBlockHeight++
  59. // Build mock responses.
  60. block := makeBlock(state, 2)
  61. abciResponses := NewABCIResponses(block)
  62. abciResponses.DeliverTx[0] = &abci.ResponseDeliverTx{Data: []byte("foo"), Tags: nil}
  63. abciResponses.DeliverTx[1] = &abci.ResponseDeliverTx{Data: []byte("bar"), Log: "ok", Tags: nil}
  64. abciResponses.EndBlock = &abci.ResponseEndBlock{ValidatorUpdates: []abci.Validator{
  65. types.TM2PB.ValidatorFromPubKeyAndPower(crypto.GenPrivKeyEd25519().PubKey(), 10),
  66. }}
  67. saveABCIResponses(stateDB, block.Height, abciResponses)
  68. loadedABCIResponses, err := LoadABCIResponses(stateDB, block.Height)
  69. assert.Nil(err)
  70. assert.Equal(abciResponses, loadedABCIResponses,
  71. cmn.Fmt("ABCIResponses don't match:\ngot: %v\nexpected: %v\n",
  72. loadedABCIResponses, abciResponses))
  73. }
  74. // TestResultsSaveLoad tests saving and loading ABCI results.
  75. func TestABCIResponsesSaveLoad2(t *testing.T) {
  76. tearDown, stateDB, _ := setupTestCase(t)
  77. defer tearDown(t)
  78. // nolint: vetshadow
  79. assert := assert.New(t)
  80. cases := [...]struct {
  81. // Height is implied to equal index+2,
  82. // as block 1 is created from genesis.
  83. added []*abci.ResponseDeliverTx
  84. expected types.ABCIResults
  85. }{
  86. 0: {
  87. nil,
  88. nil,
  89. },
  90. 1: {
  91. []*abci.ResponseDeliverTx{
  92. {Code: 32, Data: []byte("Hello"), Log: "Huh?"},
  93. },
  94. types.ABCIResults{
  95. {32, []byte("Hello")},
  96. }},
  97. 2: {
  98. []*abci.ResponseDeliverTx{
  99. {Code: 383},
  100. {Data: []byte("Gotcha!"),
  101. Tags: []cmn.KVPair{
  102. cmn.KVPair{[]byte("a"), []byte("1")},
  103. cmn.KVPair{[]byte("build"), []byte("stuff")},
  104. }},
  105. },
  106. types.ABCIResults{
  107. {383, nil},
  108. {0, []byte("Gotcha!")},
  109. }},
  110. 3: {
  111. nil,
  112. nil,
  113. },
  114. }
  115. // Query all before, this should return error.
  116. for i := range cases {
  117. h := int64(i + 1)
  118. res, err := LoadABCIResponses(stateDB, h)
  119. assert.Error(err, "%d: %#v", i, res)
  120. }
  121. // Add all cases.
  122. for i, tc := range cases {
  123. h := int64(i + 1) // last block height, one below what we save
  124. responses := &ABCIResponses{
  125. DeliverTx: tc.added,
  126. EndBlock: &abci.ResponseEndBlock{},
  127. }
  128. saveABCIResponses(stateDB, h, responses)
  129. }
  130. // Query all before, should return expected value.
  131. for i, tc := range cases {
  132. h := int64(i + 1)
  133. res, err := LoadABCIResponses(stateDB, h)
  134. assert.NoError(err, "%d", i)
  135. assert.Equal(tc.expected.Hash(), res.ResultsHash(), "%d", i)
  136. }
  137. }
  138. // TestValidatorSimpleSaveLoad tests saving and loading validators.
  139. func TestValidatorSimpleSaveLoad(t *testing.T) {
  140. tearDown, stateDB, state := setupTestCase(t)
  141. defer tearDown(t)
  142. // nolint: vetshadow
  143. assert := assert.New(t)
  144. // Can't load anything for height 0.
  145. v, err := LoadValidators(stateDB, 0)
  146. assert.IsType(ErrNoValSetForHeight{}, err, "expected err at height 0")
  147. // Should be able to load for height 1.
  148. v, err = LoadValidators(stateDB, 1)
  149. assert.Nil(err, "expected no err at height 1")
  150. assert.Equal(v.Hash(), state.Validators.Hash(), "expected validator hashes to match")
  151. // Should be able to load for height 2.
  152. v, err = LoadValidators(stateDB, 2)
  153. assert.Nil(err, "expected no err at height 2")
  154. assert.Equal(v.Hash(), state.NextValidators.Hash(), "expected validator hashes to match")
  155. // Increment height, save; should be able to load for next & next next height.
  156. state.LastBlockHeight++
  157. nextHeight := state.LastBlockHeight + 1
  158. saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
  159. vp0, err := LoadValidators(stateDB, nextHeight+0)
  160. assert.Nil(err, "expected no err")
  161. vp1, err := LoadValidators(stateDB, nextHeight+1)
  162. assert.Nil(err, "expected no err")
  163. assert.Equal(vp0.Hash(), state.Validators.Hash(), "expected validator hashes to match")
  164. assert.Equal(vp1.Hash(), state.NextValidators.Hash(), "expected next validator hashes to match")
  165. }
  166. // TestValidatorChangesSaveLoad tests saving and loading a validator set with changes.
  167. func TestOneValidatorChangesSaveLoad(t *testing.T) {
  168. tearDown, stateDB, state := setupTestCase(t)
  169. defer tearDown(t)
  170. // Change vals at these heights.
  171. changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
  172. N := len(changeHeights)
  173. // Build the validator history by running updateState
  174. // with the right validator set for each height.
  175. highestHeight := changeHeights[N-1] + 5
  176. changeIndex := 0
  177. _, val := state.Validators.GetByIndex(0)
  178. power := val.VotingPower
  179. var err error
  180. for i := int64(1); i < highestHeight; i++ {
  181. // When we get to a change height, use the next pubkey.
  182. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
  183. changeIndex++
  184. power++
  185. }
  186. header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, power)
  187. state, err = updateState(state, blockID, header, responses)
  188. assert.Nil(t, err)
  189. nextHeight := state.LastBlockHeight + 1
  190. saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
  191. }
  192. // On each height change, increment the power by one.
  193. testCases := make([]int64, highestHeight)
  194. changeIndex = 0
  195. power = val.VotingPower
  196. for i := int64(1); i < highestHeight+1; i++ {
  197. // We get to the height after a change height use the next pubkey (note
  198. // our counter starts at 0 this time).
  199. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
  200. changeIndex++
  201. power++
  202. }
  203. testCases[i-1] = power
  204. }
  205. for i, power := range testCases {
  206. v, err := LoadValidators(stateDB, int64(i+1+1)) // +1 because vset changes delayed by 1 block.
  207. assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", i))
  208. assert.Equal(t, v.Size(), 1, "validator set size is greater than 1: %d", v.Size())
  209. _, val := v.GetByIndex(0)
  210. assert.Equal(t, val.VotingPower, power, fmt.Sprintf(`unexpected powerat
  211. height %d`, i))
  212. }
  213. }
  214. // TestValidatorChangesSaveLoad tests saving and loading a validator set with
  215. // changes.
  216. func TestManyValidatorChangesSaveLoad(t *testing.T) {
  217. const valSetSize = 7
  218. tearDown, stateDB, state := setupTestCase(t)
  219. require.Equal(t, int64(0), state.LastBlockHeight)
  220. state.Validators = genValSet(valSetSize)
  221. state.NextValidators = state.Validators.CopyIncrementAccum(1)
  222. SaveState(stateDB, state)
  223. defer tearDown(t)
  224. _, valOld := state.Validators.GetByIndex(0)
  225. var pubkeyOld = valOld.PubKey
  226. var pubkey = crypto.GenPrivKeyEd25519().PubKey()
  227. // Swap the first validator with a new one (validator set size stays the same).
  228. header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, pubkey)
  229. // Save state etc.
  230. var err error
  231. state, err = updateState(state, blockID, header, responses)
  232. require.Nil(t, err)
  233. nextHeight := state.LastBlockHeight + 1
  234. saveValidatorsInfo(stateDB, nextHeight+1, state.LastHeightValidatorsChanged, state.NextValidators)
  235. // Load nextheight, it should be the oldpubkey.
  236. v0, err := LoadValidators(stateDB, nextHeight)
  237. assert.Nil(t, err)
  238. assert.Equal(t, valSetSize, v0.Size())
  239. index, val := v0.GetByAddress(pubkeyOld.Address())
  240. assert.NotNil(t, val)
  241. if index < 0 {
  242. t.Fatal("expected to find old validator")
  243. }
  244. // Load nextheight+1, it should be the new pubkey.
  245. v1, err := LoadValidators(stateDB, nextHeight+1)
  246. assert.Nil(t, err)
  247. assert.Equal(t, valSetSize, v1.Size())
  248. index, val = v1.GetByAddress(pubkey.Address())
  249. assert.NotNil(t, val)
  250. if index < 0 {
  251. t.Fatal("expected to find newly added validator")
  252. }
  253. }
  254. func genValSet(size int) *types.ValidatorSet {
  255. vals := make([]*types.Validator, size)
  256. for i := 0; i < size; i++ {
  257. vals[i] = types.NewValidator(crypto.GenPrivKeyEd25519().PubKey(), 10)
  258. }
  259. return types.NewValidatorSet(vals)
  260. }
  261. // TestConsensusParamsChangesSaveLoad tests saving and loading consensus params
  262. // with changes.
  263. func TestConsensusParamsChangesSaveLoad(t *testing.T) {
  264. tearDown, stateDB, state := setupTestCase(t)
  265. defer tearDown(t)
  266. // Change vals at these heights.
  267. changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
  268. N := len(changeHeights)
  269. // Each valset is just one validator.
  270. // create list of them.
  271. params := make([]types.ConsensusParams, N+1)
  272. params[0] = state.ConsensusParams
  273. for i := 1; i < N+1; i++ {
  274. params[i] = *types.DefaultConsensusParams()
  275. params[i].BlockSize.MaxBytes += i
  276. }
  277. // Build the params history by running updateState
  278. // with the right params set for each height.
  279. highestHeight := changeHeights[N-1] + 5
  280. changeIndex := 0
  281. cp := params[changeIndex]
  282. var err error
  283. for i := int64(1); i < highestHeight; i++ {
  284. // When we get to a change height, use the next params.
  285. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
  286. changeIndex++
  287. cp = params[changeIndex]
  288. }
  289. header, blockID, responses := makeHeaderPartsResponsesParams(state, cp)
  290. state, err = updateState(state, blockID, header, responses)
  291. require.Nil(t, err)
  292. nextHeight := state.LastBlockHeight + 1
  293. saveConsensusParamsInfo(stateDB, nextHeight, state.LastHeightConsensusParamsChanged, state.ConsensusParams)
  294. }
  295. // Make all the test cases by using the same params until after the change.
  296. testCases := make([]paramsChangeTestCase, highestHeight)
  297. changeIndex = 0
  298. cp = params[changeIndex]
  299. for i := int64(1); i < highestHeight+1; i++ {
  300. // We get to the height after a change height use the next pubkey (note
  301. // our counter starts at 0 this time).
  302. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
  303. changeIndex++
  304. cp = params[changeIndex]
  305. }
  306. testCases[i-1] = paramsChangeTestCase{i, cp}
  307. }
  308. for _, testCase := range testCases {
  309. p, err := LoadConsensusParams(stateDB, testCase.height)
  310. assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", testCase.height))
  311. assert.Equal(t, testCase.params, p, fmt.Sprintf(`unexpected consensus params at
  312. height %d`, testCase.height))
  313. }
  314. }
  315. func makeParams(blockBytes, blockTx, blockGas, txBytes,
  316. txGas, partSize int) types.ConsensusParams {
  317. return types.ConsensusParams{
  318. BlockSize: types.BlockSize{
  319. MaxBytes: blockBytes,
  320. MaxTxs: blockTx,
  321. MaxGas: int64(blockGas),
  322. },
  323. TxSize: types.TxSize{
  324. MaxBytes: txBytes,
  325. MaxGas: int64(txGas),
  326. },
  327. BlockGossip: types.BlockGossip{
  328. BlockPartSizeBytes: partSize,
  329. },
  330. }
  331. }
  332. func pk() []byte {
  333. return crypto.GenPrivKeyEd25519().PubKey().Bytes()
  334. }
  335. func TestApplyUpdates(t *testing.T) {
  336. initParams := makeParams(1, 2, 3, 4, 5, 6)
  337. cases := [...]struct {
  338. init types.ConsensusParams
  339. updates abci.ConsensusParams
  340. expected types.ConsensusParams
  341. }{
  342. 0: {initParams, abci.ConsensusParams{}, initParams},
  343. 1: {initParams, abci.ConsensusParams{}, initParams},
  344. 2: {initParams,
  345. abci.ConsensusParams{
  346. TxSize: &abci.TxSize{
  347. MaxBytes: 123,
  348. },
  349. },
  350. makeParams(1, 2, 3, 123, 5, 6)},
  351. 3: {initParams,
  352. abci.ConsensusParams{
  353. BlockSize: &abci.BlockSize{
  354. MaxTxs: 44,
  355. MaxGas: 55,
  356. },
  357. },
  358. makeParams(1, 44, 55, 4, 5, 6)},
  359. 4: {initParams,
  360. abci.ConsensusParams{
  361. BlockSize: &abci.BlockSize{
  362. MaxTxs: 789,
  363. },
  364. TxSize: &abci.TxSize{
  365. MaxGas: 888,
  366. },
  367. BlockGossip: &abci.BlockGossip{
  368. BlockPartSizeBytes: 2002,
  369. },
  370. },
  371. makeParams(1, 789, 3, 4, 888, 2002)},
  372. }
  373. for i, tc := range cases {
  374. res := tc.init.Update(&(tc.updates))
  375. assert.Equal(t, tc.expected, res, "case %d", i)
  376. }
  377. }
  378. func makeHeaderPartsResponsesValPubKeyChange(state State, pubkey crypto.PubKey) (
  379. *types.Header, types.BlockID, *ABCIResponses) {
  380. block := makeBlock(state, state.LastBlockHeight+1)
  381. abciResponses := &ABCIResponses{
  382. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  383. }
  384. // If the pubkey is new, remove the old and add the new.
  385. _, val := state.NextValidators.GetByIndex(0)
  386. if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) {
  387. abciResponses.EndBlock = &abci.ResponseEndBlock{
  388. ValidatorUpdates: []abci.Validator{
  389. types.TM2PB.ValidatorFromPubKeyAndPower(val.PubKey, 0),
  390. types.TM2PB.ValidatorFromPubKeyAndPower(pubkey, 10),
  391. },
  392. }
  393. }
  394. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  395. }
  396. func makeHeaderPartsResponsesValPowerChange(state State, power int64) (
  397. *types.Header, types.BlockID, *ABCIResponses) {
  398. block := makeBlock(state, state.LastBlockHeight+1)
  399. abciResponses := &ABCIResponses{
  400. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  401. }
  402. // If the pubkey is new, remove the old and add the new.
  403. _, val := state.NextValidators.GetByIndex(0)
  404. if val.VotingPower != power {
  405. abciResponses.EndBlock = &abci.ResponseEndBlock{
  406. ValidatorUpdates: []abci.Validator{
  407. types.TM2PB.ValidatorFromPubKeyAndPower(val.PubKey, power),
  408. },
  409. }
  410. }
  411. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  412. }
  413. func makeHeaderPartsResponsesParams(state State, params types.ConsensusParams) (
  414. *types.Header, types.BlockID, *ABCIResponses) {
  415. block := makeBlock(state, state.LastBlockHeight+1)
  416. abciResponses := &ABCIResponses{
  417. EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: types.TM2PB.ConsensusParams(&params)},
  418. }
  419. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  420. }
  421. type paramsChangeTestCase struct {
  422. height int64
  423. params types.ConsensusParams
  424. }