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.

195 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
  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 TestApplyBlock(t *testing.T) {
  22. cc := proxy.NewLocalClientCreator(dummy.NewDummyApplication())
  23. proxyApp := proxy.NewAppConns(cc, nil)
  24. err := proxyApp.Start()
  25. require.Nil(t, err)
  26. defer proxyApp.Stop()
  27. state, stateDB := state(), dbm.NewMemDB()
  28. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(),
  29. types.MockMempool{}, types.MockEvidencePool{})
  30. block := makeBlock(state, 1)
  31. blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
  32. state, err = blockExec.ApplyBlock(state, blockID, block)
  33. require.Nil(t, err)
  34. // TODO check state and mempool
  35. }
  36. // TestBeginBlockAbsentValidators ensures we send absent validators list.
  37. func TestBeginBlockAbsentValidators(t *testing.T) {
  38. app := &testApp{}
  39. cc := proxy.NewLocalClientCreator(app)
  40. proxyApp := proxy.NewAppConns(cc, nil)
  41. err := proxyApp.Start()
  42. require.Nil(t, err)
  43. defer proxyApp.Stop()
  44. state := state()
  45. prevHash := state.LastBlockID.Hash
  46. prevParts := types.PartSetHeader{}
  47. prevBlockID := types.BlockID{prevHash, prevParts}
  48. now := time.Now().UTC()
  49. testCases := []struct {
  50. desc string
  51. lastCommitPrecommits []*types.Vote
  52. expectedAbsentValidators []int32
  53. }{
  54. {"none absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now}, {ValidatorIndex: 1, Timestamp: now}}, []int32{}},
  55. {"one absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now}, nil}, []int32{1}},
  56. {"multiple absent", []*types.Vote{nil, nil}, []int32{0, 1}},
  57. }
  58. for _, tc := range testCases {
  59. lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
  60. block, _ := state.MakeBlock(2, makeTxs(2), lastCommit)
  61. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger())
  62. require.Nil(t, err, tc.desc)
  63. // -> app must receive an index of the absent validator
  64. assert.Equal(t, tc.expectedAbsentValidators, app.AbsentValidators, tc.desc)
  65. }
  66. }
  67. // TestBeginBlockByzantineValidators ensures we send byzantine validators list.
  68. func TestBeginBlockByzantineValidators(t *testing.T) {
  69. app := &testApp{}
  70. cc := proxy.NewLocalClientCreator(app)
  71. proxyApp := proxy.NewAppConns(cc, nil)
  72. err := proxyApp.Start()
  73. require.Nil(t, err)
  74. defer proxyApp.Stop()
  75. state := state()
  76. prevHash := state.LastBlockID.Hash
  77. prevParts := types.PartSetHeader{}
  78. prevBlockID := types.BlockID{prevHash, prevParts}
  79. height1, idx1, val1 := int64(8), 0, []byte("val1")
  80. height2, idx2, val2 := int64(3), 1, []byte("val2")
  81. ev1 := types.NewMockGoodEvidence(height1, idx1, val1)
  82. ev2 := types.NewMockGoodEvidence(height2, idx2, val2)
  83. testCases := []struct {
  84. desc string
  85. evidence []types.Evidence
  86. expectedByzantineValidators []*abci.Evidence
  87. }{
  88. {"none byzantine", []types.Evidence{}, []*abci.Evidence{}},
  89. {"one byzantine", []types.Evidence{ev1}, []*abci.Evidence{{ev1.Address(), ev1.Height()}}},
  90. {"multiple byzantine", []types.Evidence{ev1, ev2}, []*abci.Evidence{
  91. {ev1.Address(), ev1.Height()},
  92. {ev2.Address(), ev2.Height()}}},
  93. }
  94. for _, tc := range testCases {
  95. lastCommit := &types.Commit{BlockID: prevBlockID}
  96. block, _ := state.MakeBlock(10, makeTxs(2), lastCommit)
  97. block.Evidence.Evidence = tc.evidence
  98. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger())
  99. require.Nil(t, err, tc.desc)
  100. // -> app must receive an index of the byzantine validator
  101. assert.Equal(t, tc.expectedByzantineValidators, app.ByzantineValidators, tc.desc)
  102. }
  103. }
  104. //----------------------------------------------------------------------------
  105. // make some bogus txs
  106. func makeTxs(height int64) (txs []types.Tx) {
  107. for i := 0; i < nTxsPerBlock; i++ {
  108. txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
  109. }
  110. return txs
  111. }
  112. func state() State {
  113. s, _ := MakeGenesisState(&types.GenesisDoc{
  114. ChainID: chainID,
  115. Validators: []types.GenesisValidator{
  116. {privKey.PubKey(), 10000, "test"},
  117. },
  118. AppHash: nil,
  119. })
  120. return s
  121. }
  122. func makeBlock(state State, height int64) *types.Block {
  123. block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit))
  124. return block
  125. }
  126. //----------------------------------------------------------------------------
  127. var _ abci.Application = (*testApp)(nil)
  128. type testApp struct {
  129. abci.BaseApplication
  130. AbsentValidators []int32
  131. ByzantineValidators []*abci.Evidence
  132. }
  133. func NewDummyApplication() *testApp {
  134. return &testApp{}
  135. }
  136. func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
  137. return abci.ResponseInfo{}
  138. }
  139. func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
  140. app.AbsentValidators = req.AbsentValidators
  141. app.ByzantineValidators = req.ByzantineValidators
  142. return abci.ResponseBeginBlock{}
  143. }
  144. func (app *testApp) DeliverTx(tx []byte) abci.ResponseDeliverTx {
  145. return abci.ResponseDeliverTx{Tags: []*abci.KVPair{}}
  146. }
  147. func (app *testApp) CheckTx(tx []byte) abci.ResponseCheckTx {
  148. return abci.ResponseCheckTx{}
  149. }
  150. func (app *testApp) Commit() abci.ResponseCommit {
  151. return abci.ResponseCommit{}
  152. }
  153. func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
  154. return
  155. }