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.

215 lines
5.6 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  1. package state
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/stretchr/testify/require"
  7. "github.com/tendermint/abci/example/dummy"
  8. abci "github.com/tendermint/abci/types"
  9. crypto "github.com/tendermint/go-crypto"
  10. "github.com/tendermint/tendermint/proxy"
  11. "github.com/tendermint/tendermint/types"
  12. dbm "github.com/tendermint/tmlibs/db"
  13. "github.com/tendermint/tmlibs/log"
  14. )
  15. var (
  16. privKey = crypto.GenPrivKeyEd25519FromSecret([]byte("execution_test"))
  17. chainID = "execution_chain"
  18. testPartSize = 65536
  19. nTxsPerBlock = 10
  20. )
  21. func TestValidateBlock(t *testing.T) {
  22. state := state()
  23. state.SetLogger(log.TestingLogger())
  24. // proper block must pass
  25. block := makeBlock(state, 1)
  26. err := state.ValidateBlock(block)
  27. require.NoError(t, err)
  28. // wrong chain fails
  29. block = makeBlock(state, 1)
  30. block.ChainID = "not-the-real-one"
  31. err = state.ValidateBlock(block)
  32. require.Error(t, err)
  33. // wrong height fails
  34. block = makeBlock(state, 1)
  35. block.Height += 10
  36. err = state.ValidateBlock(block)
  37. require.Error(t, err)
  38. // wrong total tx fails
  39. block = makeBlock(state, 1)
  40. block.TotalTxs += 10
  41. err = state.ValidateBlock(block)
  42. require.Error(t, err)
  43. // wrong blockid fails
  44. block = makeBlock(state, 1)
  45. block.LastBlockID.PartsHeader.Total += 10
  46. err = state.ValidateBlock(block)
  47. require.Error(t, err)
  48. // wrong app hash fails
  49. block = makeBlock(state, 1)
  50. block.AppHash = []byte("wrong app hash")
  51. err = state.ValidateBlock(block)
  52. require.Error(t, err)
  53. // wrong consensus hash fails
  54. block = makeBlock(state, 1)
  55. block.ConsensusHash = []byte("wrong consensus hash")
  56. err = state.ValidateBlock(block)
  57. require.Error(t, err)
  58. // wrong results hash fails
  59. block = makeBlock(state, 1)
  60. block.LastResultsHash = []byte("wrong results hash")
  61. err = state.ValidateBlock(block)
  62. require.Error(t, err)
  63. // wrong validators hash fails
  64. block = makeBlock(state, 1)
  65. block.ValidatorsHash = []byte("wrong validators hash")
  66. err = state.ValidateBlock(block)
  67. require.Error(t, err)
  68. }
  69. func TestApplyBlock(t *testing.T) {
  70. cc := proxy.NewLocalClientCreator(dummy.NewDummyApplication())
  71. proxyApp := proxy.NewAppConns(cc, nil)
  72. err := proxyApp.Start()
  73. require.Nil(t, err)
  74. defer proxyApp.Stop()
  75. state := state()
  76. state.SetLogger(log.TestingLogger())
  77. block := makeBlock(state, 1)
  78. err = state.ApplyBlock(types.NopEventBus{}, proxyApp.Consensus(),
  79. block, block.MakePartSet(testPartSize).Header(),
  80. types.MockMempool{}, types.MockEvidencePool{})
  81. require.Nil(t, err)
  82. // TODO check state and mempool
  83. }
  84. // TestBeginBlockAbsentValidators ensures we send absent validators list.
  85. func TestBeginBlockAbsentValidators(t *testing.T) {
  86. app := &testApp{}
  87. cc := proxy.NewLocalClientCreator(app)
  88. proxyApp := proxy.NewAppConns(cc, nil)
  89. err := proxyApp.Start()
  90. require.Nil(t, err)
  91. defer proxyApp.Stop()
  92. state := state()
  93. state.SetLogger(log.TestingLogger())
  94. // there were 2 validators
  95. val1PrivKey := crypto.GenPrivKeyEd25519()
  96. val2PrivKey := crypto.GenPrivKeyEd25519()
  97. lastValidators := types.NewValidatorSet([]*types.Validator{
  98. types.NewValidator(val1PrivKey.PubKey(), 10),
  99. types.NewValidator(val2PrivKey.PubKey(), 5),
  100. })
  101. prevHash := state.LastBlockID.Hash
  102. prevParts := types.PartSetHeader{}
  103. prevBlockID := types.BlockID{prevHash, prevParts}
  104. now := time.Now().UTC()
  105. testCases := []struct {
  106. desc string
  107. lastCommitPrecommits []*types.Vote
  108. expectedAbsentValidators []int32
  109. }{
  110. {"none absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now}, {ValidatorIndex: 1, Timestamp: now}}, []int32{}},
  111. {"one absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now}, nil}, []int32{1}},
  112. {"multiple absent", []*types.Vote{nil, nil}, []int32{0, 1}},
  113. }
  114. for _, tc := range testCases {
  115. lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
  116. block, _ := state.MakeBlock(2, makeTxs(2), lastCommit)
  117. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), lastValidators)
  118. require.Nil(t, err, tc.desc)
  119. // -> app must receive an index of the absent validator
  120. assert.Equal(t, tc.expectedAbsentValidators, app.AbsentValidators, tc.desc)
  121. }
  122. }
  123. //----------------------------------------------------------------------------
  124. // make some bogus txs
  125. func makeTxs(height int64) (txs []types.Tx) {
  126. for i := 0; i < nTxsPerBlock; i++ {
  127. txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
  128. }
  129. return txs
  130. }
  131. func state() *State {
  132. s, _ := MakeGenesisState(dbm.NewMemDB(), &types.GenesisDoc{
  133. ChainID: chainID,
  134. Validators: []types.GenesisValidator{
  135. {privKey.PubKey(), 10000, "test"},
  136. },
  137. AppHash: nil,
  138. })
  139. return s
  140. }
  141. func makeBlock(state *State, height int64) *types.Block {
  142. block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit))
  143. return block
  144. }
  145. //----------------------------------------------------------------------------
  146. var _ abci.Application = (*testApp)(nil)
  147. type testApp struct {
  148. abci.BaseApplication
  149. AbsentValidators []int32
  150. }
  151. func NewDummyApplication() *testApp {
  152. return &testApp{}
  153. }
  154. func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
  155. return abci.ResponseInfo{}
  156. }
  157. func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
  158. app.AbsentValidators = req.AbsentValidators
  159. return abci.ResponseBeginBlock{}
  160. }
  161. func (app *testApp) DeliverTx(tx []byte) abci.ResponseDeliverTx {
  162. return abci.ResponseDeliverTx{Tags: []*abci.KVPair{}}
  163. }
  164. func (app *testApp) CheckTx(tx []byte) abci.ResponseCheckTx {
  165. return abci.ResponseCheckTx{}
  166. }
  167. func (app *testApp) Commit() abci.ResponseCommit {
  168. return abci.ResponseCommit{}
  169. }
  170. func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
  171. return
  172. }