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.

489 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 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, 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. // increment height, save; should be able to load for next height
  152. state.LastBlockHeight++
  153. nextHeight := state.LastBlockHeight + 1
  154. saveValidatorsInfo(stateDB, nextHeight, state.LastHeightValidatorsChanged, state.Validators)
  155. v, err = LoadValidators(stateDB, nextHeight)
  156. assert.Nil(err, "expected no err")
  157. assert.Equal(v.Hash(), state.Validators.Hash(), "expected validator hashes to match")
  158. // increment height, save; should be able to load for next height
  159. state.LastBlockHeight += 10
  160. nextHeight = state.LastBlockHeight + 1
  161. saveValidatorsInfo(stateDB, nextHeight, state.LastHeightValidatorsChanged, state.Validators)
  162. v, err = LoadValidators(stateDB, nextHeight)
  163. assert.Nil(err, "expected no err")
  164. assert.Equal(v.Hash(), state.Validators.Hash(), "expected validator hashes to match")
  165. // should be able to load for next next height
  166. _, err = LoadValidators(stateDB, state.LastBlockHeight+2)
  167. assert.IsType(ErrNoValSetForHeight{}, err, "expected err at unknown height")
  168. }
  169. // TestValidatorChangesSaveLoad tests saving and loading a validator set with changes.
  170. func TestOneValidatorChangesSaveLoad(t *testing.T) {
  171. tearDown, stateDB, state := setupTestCase(t)
  172. defer tearDown(t)
  173. // change vals at these heights
  174. changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
  175. N := len(changeHeights)
  176. // build the validator history by running updateState
  177. // with the right validator set for each height
  178. highestHeight := changeHeights[N-1] + 5
  179. changeIndex := 0
  180. _, val := state.Validators.GetByIndex(0)
  181. power := val.VotingPower
  182. var err error
  183. for i := int64(1); i < highestHeight; i++ {
  184. // when we get to a change height,
  185. // use the next pubkey
  186. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
  187. changeIndex++
  188. power++
  189. }
  190. header, blockID, responses := makeHeaderPartsResponsesValPowerChange(state, i, power)
  191. state, err = updateState(state, blockID, header, responses)
  192. assert.Nil(t, err)
  193. nextHeight := state.LastBlockHeight + 1
  194. saveValidatorsInfo(stateDB, nextHeight, state.LastHeightValidatorsChanged, state.Validators)
  195. }
  196. // on each change height, increment the power by one.
  197. testCases := make([]int64, highestHeight)
  198. changeIndex = 0
  199. power = val.VotingPower
  200. for i := int64(1); i < highestHeight+1; i++ {
  201. // we we get to the height after a change height
  202. // use the next pubkey (note our counter starts at 0 this time)
  203. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
  204. changeIndex++
  205. power++
  206. }
  207. testCases[i-1] = power
  208. }
  209. for i, power := range testCases {
  210. v, err := LoadValidators(stateDB, int64(i+1))
  211. assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", i))
  212. assert.Equal(t, v.Size(), 1, "validator set size is greater than 1: %d", v.Size())
  213. _, val := v.GetByIndex(0)
  214. assert.Equal(t, val.VotingPower, power, fmt.Sprintf(`unexpected powerat
  215. height %d`, i))
  216. }
  217. }
  218. // TestValidatorChangesSaveLoad tests saving and loading a validator set with
  219. // changes.
  220. func TestManyValidatorChangesSaveLoad(t *testing.T) {
  221. const valSetSize = 7
  222. tearDown, stateDB, state := setupTestCase(t)
  223. state.Validators = genValSet(valSetSize)
  224. SaveState(stateDB, state)
  225. defer tearDown(t)
  226. const height = 1
  227. pubkey := crypto.GenPrivKeyEd25519().PubKey()
  228. // swap the first validator with a new one ^^^ (validator set size stays the same)
  229. header, blockID, responses := makeHeaderPartsResponsesValPubKeyChange(state, height, pubkey)
  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, state.LastHeightValidatorsChanged, state.Validators)
  235. v, err := LoadValidators(stateDB, height+1)
  236. assert.Nil(t, err)
  237. assert.Equal(t, valSetSize, v.Size())
  238. index, val := v.GetByAddress(pubkey.Address())
  239. assert.NotNil(t, val)
  240. if index < 0 {
  241. t.Fatal("expected to find newly added validator")
  242. }
  243. }
  244. func genValSet(size int) *types.ValidatorSet {
  245. vals := make([]*types.Validator, size)
  246. for i := 0; i < size; i++ {
  247. vals[i] = types.NewValidator(crypto.GenPrivKeyEd25519().PubKey(), 10)
  248. }
  249. return types.NewValidatorSet(vals)
  250. }
  251. // TestConsensusParamsChangesSaveLoad tests saving and loading consensus params
  252. // with changes.
  253. func TestConsensusParamsChangesSaveLoad(t *testing.T) {
  254. tearDown, stateDB, state := setupTestCase(t)
  255. defer tearDown(t)
  256. // change vals at these heights
  257. changeHeights := []int64{1, 2, 4, 5, 10, 15, 16, 17, 20}
  258. N := len(changeHeights)
  259. // each valset is just one validator
  260. // create list of them
  261. params := make([]types.ConsensusParams, N+1)
  262. params[0] = state.ConsensusParams
  263. for i := 1; i < N+1; i++ {
  264. params[i] = *types.DefaultConsensusParams()
  265. params[i].BlockSize.MaxBytes += i
  266. }
  267. // build the params history by running updateState
  268. // with the right params set for each height
  269. highestHeight := changeHeights[N-1] + 5
  270. changeIndex := 0
  271. cp := params[changeIndex]
  272. var err error
  273. for i := int64(1); i < highestHeight; i++ {
  274. // when we get to a change height,
  275. // use the next params
  276. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex] {
  277. changeIndex++
  278. cp = params[changeIndex]
  279. }
  280. header, blockID, responses := makeHeaderPartsResponsesParams(state, i, cp)
  281. state, err = updateState(state, blockID, header, responses)
  282. require.Nil(t, err)
  283. nextHeight := state.LastBlockHeight + 1
  284. saveConsensusParamsInfo(stateDB, nextHeight, state.LastHeightConsensusParamsChanged, state.ConsensusParams)
  285. }
  286. // make all the test cases by using the same params until after the change
  287. testCases := make([]paramsChangeTestCase, highestHeight)
  288. changeIndex = 0
  289. cp = params[changeIndex]
  290. for i := int64(1); i < highestHeight+1; i++ {
  291. // we we get to the height after a change height
  292. // use the next pubkey (note our counter starts at 0 this time)
  293. if changeIndex < len(changeHeights) && i == changeHeights[changeIndex]+1 {
  294. changeIndex++
  295. cp = params[changeIndex]
  296. }
  297. testCases[i-1] = paramsChangeTestCase{i, cp}
  298. }
  299. for _, testCase := range testCases {
  300. p, err := LoadConsensusParams(stateDB, testCase.height)
  301. assert.Nil(t, err, fmt.Sprintf("expected no err at height %d", testCase.height))
  302. assert.Equal(t, testCase.params, p, fmt.Sprintf(`unexpected consensus params at
  303. height %d`, testCase.height))
  304. }
  305. }
  306. func makeParams(blockBytes, blockTx, blockGas, txBytes,
  307. txGas, partSize int) types.ConsensusParams {
  308. return types.ConsensusParams{
  309. BlockSize: types.BlockSize{
  310. MaxBytes: blockBytes,
  311. MaxTxs: blockTx,
  312. MaxGas: int64(blockGas),
  313. },
  314. TxSize: types.TxSize{
  315. MaxBytes: txBytes,
  316. MaxGas: int64(txGas),
  317. },
  318. BlockGossip: types.BlockGossip{
  319. BlockPartSizeBytes: partSize,
  320. },
  321. }
  322. }
  323. func pk() []byte {
  324. return crypto.GenPrivKeyEd25519().PubKey().Bytes()
  325. }
  326. func TestApplyUpdates(t *testing.T) {
  327. initParams := makeParams(1, 2, 3, 4, 5, 6)
  328. cases := [...]struct {
  329. init types.ConsensusParams
  330. updates abci.ConsensusParams
  331. expected types.ConsensusParams
  332. }{
  333. 0: {initParams, abci.ConsensusParams{}, initParams},
  334. 1: {initParams, abci.ConsensusParams{}, initParams},
  335. 2: {initParams,
  336. abci.ConsensusParams{
  337. TxSize: &abci.TxSize{
  338. MaxBytes: 123,
  339. },
  340. },
  341. makeParams(1, 2, 3, 123, 5, 6)},
  342. 3: {initParams,
  343. abci.ConsensusParams{
  344. BlockSize: &abci.BlockSize{
  345. MaxTxs: 44,
  346. MaxGas: 55,
  347. },
  348. },
  349. makeParams(1, 44, 55, 4, 5, 6)},
  350. 4: {initParams,
  351. abci.ConsensusParams{
  352. BlockSize: &abci.BlockSize{
  353. MaxTxs: 789,
  354. },
  355. TxSize: &abci.TxSize{
  356. MaxGas: 888,
  357. },
  358. BlockGossip: &abci.BlockGossip{
  359. BlockPartSizeBytes: 2002,
  360. },
  361. },
  362. makeParams(1, 789, 3, 4, 888, 2002)},
  363. }
  364. for i, tc := range cases {
  365. res := tc.init.Update(&(tc.updates))
  366. assert.Equal(t, tc.expected, res, "case %d", i)
  367. }
  368. }
  369. func makeHeaderPartsResponsesValPubKeyChange(state State, height int64,
  370. pubkey crypto.PubKey) (*types.Header, types.BlockID, *ABCIResponses) {
  371. block := makeBlock(state, height)
  372. abciResponses := &ABCIResponses{
  373. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  374. }
  375. // if the pubkey is new, remove the old and add the new
  376. _, val := state.Validators.GetByIndex(0)
  377. if !bytes.Equal(pubkey.Bytes(), val.PubKey.Bytes()) {
  378. abciResponses.EndBlock = &abci.ResponseEndBlock{
  379. ValidatorUpdates: []abci.Validator{
  380. types.TM2PB.ValidatorFromPubKeyAndPower(val.PubKey, 0),
  381. types.TM2PB.ValidatorFromPubKeyAndPower(pubkey, 10),
  382. },
  383. }
  384. }
  385. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  386. }
  387. func makeHeaderPartsResponsesValPowerChange(state State, height int64,
  388. power int64) (*types.Header, types.BlockID, *ABCIResponses) {
  389. block := makeBlock(state, height)
  390. abciResponses := &ABCIResponses{
  391. EndBlock: &abci.ResponseEndBlock{ValidatorUpdates: nil},
  392. }
  393. // if the pubkey is new, remove the old and add the new
  394. _, val := state.Validators.GetByIndex(0)
  395. if val.VotingPower != power {
  396. abciResponses.EndBlock = &abci.ResponseEndBlock{
  397. ValidatorUpdates: []abci.Validator{
  398. types.TM2PB.ValidatorFromPubKeyAndPower(val.PubKey, power),
  399. },
  400. }
  401. }
  402. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  403. }
  404. func makeHeaderPartsResponsesParams(state State, height int64,
  405. params types.ConsensusParams) (*types.Header, types.BlockID, *ABCIResponses) {
  406. block := makeBlock(state, height)
  407. abciResponses := &ABCIResponses{
  408. EndBlock: &abci.ResponseEndBlock{ConsensusParamUpdates: types.TM2PB.ConsensusParams(&params)},
  409. }
  410. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  411. }
  412. type paramsChangeTestCase struct {
  413. height int64
  414. params types.ConsensusParams
  415. }
  416. func makeHeaderPartsResults(state State, height int64,
  417. results []*abci.ResponseDeliverTx) (*types.Header, types.BlockID, *ABCIResponses) {
  418. block := makeBlock(state, height)
  419. abciResponses := &ABCIResponses{
  420. DeliverTx: results,
  421. EndBlock: &abci.ResponseEndBlock{},
  422. }
  423. return block.Header, types.BlockID{block.Hash(), types.PartSetHeader{}}, abciResponses
  424. }