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.

561 lines
17 KiB

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