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.

220 lines
6.2 KiB

8 years ago
7 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
7 years ago
8 years ago
7 years ago
8 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
8 years ago
8 years ago
8 years ago
7 years ago
7 years ago
8 years ago
8 years ago
8 years ago
7 years ago
7 years ago
  1. package state
  2. import (
  3. "fmt"
  4. "testing"
  5. "time"
  6. "github.com/stretchr/testify/assert"
  7. "github.com/stretchr/testify/require"
  8. "github.com/tendermint/abci/example/kvstore"
  9. abci "github.com/tendermint/abci/types"
  10. crypto "github.com/tendermint/go-crypto"
  11. cmn "github.com/tendermint/tmlibs/common"
  12. dbm "github.com/tendermint/tmlibs/db"
  13. "github.com/tendermint/tmlibs/log"
  14. "github.com/tendermint/tendermint/proxy"
  15. "github.com/tendermint/tendermint/types"
  16. )
  17. var (
  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(1), dbm.NewMemDB()
  29. blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(),
  30. MockMempool{}, 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. // TestBeginBlockValidators ensures we send absent validators list.
  38. func TestBeginBlockValidators(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(2)
  46. prevHash := state.LastBlockID.Hash
  47. prevParts := types.PartSetHeader{}
  48. prevBlockID := types.BlockID{prevHash, prevParts}
  49. now := time.Now().UTC()
  50. vote0 := &types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.VoteTypePrecommit}
  51. vote1 := &types.Vote{ValidatorIndex: 1, Timestamp: now}
  52. testCases := []struct {
  53. desc string
  54. lastCommitPrecommits []*types.Vote
  55. expectedAbsentValidators []int
  56. }{
  57. {"none absent", []*types.Vote{vote0, vote1}, []int{}},
  58. {"one absent", []*types.Vote{vote0, nil}, []int{1}},
  59. {"multiple absent", []*types.Vote{nil, nil}, []int{0, 1}},
  60. }
  61. for _, tc := range testCases {
  62. lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
  63. block, _ := state.MakeBlock(2, makeTxs(2), lastCommit)
  64. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators)
  65. require.Nil(t, err, tc.desc)
  66. // -> app receives a list of validators with a bool indicating if they signed
  67. ctr := 0
  68. for i, v := range app.Validators {
  69. if ctr < len(tc.expectedAbsentValidators) &&
  70. tc.expectedAbsentValidators[ctr] == i {
  71. assert.False(t, v.SignedLastBlock)
  72. ctr++
  73. } else {
  74. assert.True(t, v.SignedLastBlock)
  75. }
  76. }
  77. }
  78. }
  79. // TestBeginBlockByzantineValidators ensures we send byzantine validators list.
  80. func TestBeginBlockByzantineValidators(t *testing.T) {
  81. app := &testApp{}
  82. cc := proxy.NewLocalClientCreator(app)
  83. proxyApp := proxy.NewAppConns(cc, nil)
  84. err := proxyApp.Start()
  85. require.Nil(t, err)
  86. defer proxyApp.Stop()
  87. state := state(2)
  88. prevHash := state.LastBlockID.Hash
  89. prevParts := types.PartSetHeader{}
  90. prevBlockID := types.BlockID{prevHash, prevParts}
  91. height1, idx1, val1 := int64(8), 0, []byte("val1")
  92. height2, idx2, val2 := int64(3), 1, []byte("val2")
  93. ev1 := types.NewMockGoodEvidence(height1, idx1, val1)
  94. ev2 := types.NewMockGoodEvidence(height2, idx2, val2)
  95. testCases := []struct {
  96. desc string
  97. evidence []types.Evidence
  98. expectedByzantineValidators []abci.Evidence
  99. }{
  100. {"none byzantine", []types.Evidence{}, []abci.Evidence{}},
  101. {"one byzantine", []types.Evidence{ev1}, []abci.Evidence{types.TM2PB.Evidence(ev1)}},
  102. {"multiple byzantine", []types.Evidence{ev1, ev2}, []abci.Evidence{
  103. types.TM2PB.Evidence(ev1),
  104. types.TM2PB.Evidence(ev2)}},
  105. }
  106. now := time.Now().UTC()
  107. vote0 := &types.Vote{ValidatorIndex: 0, Timestamp: now, Type: types.VoteTypePrecommit}
  108. vote1 := &types.Vote{ValidatorIndex: 1, Timestamp: now}
  109. votes := []*types.Vote{vote0, vote1}
  110. lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: votes}
  111. for _, tc := range testCases {
  112. block, _ := state.MakeBlock(10, makeTxs(2), lastCommit)
  113. block.Evidence.Evidence = tc.evidence
  114. _, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), state.Validators)
  115. require.Nil(t, err, tc.desc)
  116. // -> app must receive an index of the byzantine validator
  117. assert.Equal(t, tc.expectedByzantineValidators, app.ByzantineValidators, tc.desc)
  118. }
  119. }
  120. //----------------------------------------------------------------------------
  121. // make some bogus txs
  122. func makeTxs(height int64) (txs []types.Tx) {
  123. for i := 0; i < nTxsPerBlock; i++ {
  124. txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
  125. }
  126. return txs
  127. }
  128. func state(nVals int) State {
  129. vals := make([]types.GenesisValidator, nVals)
  130. for i := 0; i < nVals; i++ {
  131. secret := []byte(fmt.Sprintf("test%d", i))
  132. pk := crypto.GenPrivKeyEd25519FromSecret(secret)
  133. vals[i] = types.GenesisValidator{
  134. pk.PubKey(), 1000, fmt.Sprintf("test%d", i),
  135. }
  136. }
  137. s, _ := MakeGenesisState(&types.GenesisDoc{
  138. ChainID: chainID,
  139. Validators: vals,
  140. AppHash: nil,
  141. })
  142. return s
  143. }
  144. func makeBlock(state State, height int64) *types.Block {
  145. block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit))
  146. return block
  147. }
  148. //----------------------------------------------------------------------------
  149. var _ abci.Application = (*testApp)(nil)
  150. type testApp struct {
  151. abci.BaseApplication
  152. Validators []abci.SigningValidator
  153. ByzantineValidators []abci.Evidence
  154. }
  155. func NewKVStoreApplication() *testApp {
  156. return &testApp{}
  157. }
  158. func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
  159. return abci.ResponseInfo{}
  160. }
  161. func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
  162. app.Validators = req.Validators
  163. app.ByzantineValidators = req.ByzantineValidators
  164. return abci.ResponseBeginBlock{}
  165. }
  166. func (app *testApp) DeliverTx(tx []byte) abci.ResponseDeliverTx {
  167. return abci.ResponseDeliverTx{Tags: []cmn.KVPair{}}
  168. }
  169. func (app *testApp) CheckTx(tx []byte) abci.ResponseCheckTx {
  170. return abci.ResponseCheckTx{}
  171. }
  172. func (app *testApp) Commit() abci.ResponseCommit {
  173. return abci.ResponseCommit{}
  174. }
  175. func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
  176. return
  177. }