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.

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