tendermint/state/execution_test.go

197 lines
5.6 KiB
Go
Raw Normal View History

2017-02-21 11:40:26 -08:00
package state
import (
"testing"
2017-12-15 10:12:45 -08:00
"time"
2017-02-21 11:40:26 -08:00
2017-12-11 10:26:19 -08:00
"github.com/stretchr/testify/assert"
2017-02-21 11:40:26 -08:00
"github.com/stretchr/testify/require"
2017-10-04 13:40:45 -07:00
2017-02-21 11:40:26 -08:00
"github.com/tendermint/abci/example/dummy"
2017-12-11 10:26:19 -08:00
abci "github.com/tendermint/abci/types"
2017-02-21 11:40:26 -08:00
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/tendermint/proxy"
"github.com/tendermint/tendermint/types"
cmn "github.com/tendermint/tmlibs/common"
2017-05-01 18:25:10 -07:00
dbm "github.com/tendermint/tmlibs/db"
2017-05-02 00:53:32 -07:00
"github.com/tendermint/tmlibs/log"
2017-02-21 11:40:26 -08:00
)
var (
privKey = crypto.GenPrivKeyEd25519FromSecret([]byte("execution_test"))
chainID = "execution_chain"
testPartSize = 65536
nTxsPerBlock = 10
)
func TestApplyBlock(t *testing.T) {
cc := proxy.NewLocalClientCreator(dummy.NewDummyApplication())
2017-05-01 18:25:10 -07:00
proxyApp := proxy.NewAppConns(cc, nil)
err := proxyApp.Start()
2017-02-21 11:40:26 -08:00
require.Nil(t, err)
defer proxyApp.Stop()
2017-12-27 17:03:48 -08:00
state, stateDB := state(), dbm.NewMemDB()
2017-02-21 11:40:26 -08:00
2017-12-28 15:26:13 -08:00
blockExec := NewBlockExecutor(stateDB, log.TestingLogger(), proxyApp.Consensus(),
types.MockMempool{}, types.MockEvidencePool{})
2017-12-27 17:03:48 -08:00
block := makeBlock(state, 1)
blockID := types.BlockID{block.Hash(), block.MakePartSet(testPartSize).Header()}
state, err = blockExec.ApplyBlock(state, blockID, block)
2017-02-21 11:40:26 -08:00
require.Nil(t, err)
// TODO check state and mempool
}
2017-12-11 10:26:19 -08:00
// TestBeginBlockAbsentValidators ensures we send absent validators list.
func TestBeginBlockAbsentValidators(t *testing.T) {
app := &testApp{}
cc := proxy.NewLocalClientCreator(app)
proxyApp := proxy.NewAppConns(cc, nil)
err := proxyApp.Start()
require.Nil(t, err)
defer proxyApp.Stop()
state := state()
prevHash := state.LastBlockID.Hash
prevParts := types.PartSetHeader{}
prevBlockID := types.BlockID{prevHash, prevParts}
2017-12-15 10:12:45 -08:00
now := time.Now().UTC()
testCases := []struct {
desc string
lastCommitPrecommits []*types.Vote
expectedAbsentValidators []int32
}{
{"none absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now}, {ValidatorIndex: 1, Timestamp: now}}, []int32{}},
{"one absent", []*types.Vote{{ValidatorIndex: 0, Timestamp: now}, nil}, []int32{1}},
{"multiple absent", []*types.Vote{nil, nil}, []int32{0, 1}},
}
2017-12-11 10:26:19 -08:00
2017-12-15 10:12:45 -08:00
for _, tc := range testCases {
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits}
2017-12-11 10:26:19 -08:00
block, _ := state.MakeBlock(2, makeTxs(2), lastCommit)
2017-12-27 17:03:48 -08:00
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger())
2017-12-15 10:12:45 -08:00
require.Nil(t, err, tc.desc)
// -> app must receive an index of the absent validator
assert.Equal(t, tc.expectedAbsentValidators, app.AbsentValidators, tc.desc)
}
2017-12-11 10:26:19 -08:00
}
// TestBeginBlockByzantineValidators ensures we send byzantine validators list.
func TestBeginBlockByzantineValidators(t *testing.T) {
app := &testApp{}
cc := proxy.NewLocalClientCreator(app)
proxyApp := proxy.NewAppConns(cc, nil)
err := proxyApp.Start()
require.Nil(t, err)
defer proxyApp.Stop()
state := state()
prevHash := state.LastBlockID.Hash
prevParts := types.PartSetHeader{}
prevBlockID := types.BlockID{prevHash, prevParts}
height1, idx1, val1 := int64(8), 0, []byte("val1")
height2, idx2, val2 := int64(3), 1, []byte("val2")
ev1 := types.NewMockGoodEvidence(height1, idx1, val1)
ev2 := types.NewMockGoodEvidence(height2, idx2, val2)
testCases := []struct {
desc string
evidence []types.Evidence
expectedByzantineValidators []abci.Evidence
}{
{"none byzantine", []types.Evidence{}, []abci.Evidence{}},
{"one byzantine", []types.Evidence{ev1}, []abci.Evidence{{ev1.Address(), ev1.Height()}}},
{"multiple byzantine", []types.Evidence{ev1, ev2}, []abci.Evidence{
{ev1.Address(), ev1.Height()},
{ev2.Address(), ev2.Height()}}},
}
for _, tc := range testCases {
lastCommit := &types.Commit{BlockID: prevBlockID}
block, _ := state.MakeBlock(10, makeTxs(2), lastCommit)
block.Evidence.Evidence = tc.evidence
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger())
require.Nil(t, err, tc.desc)
// -> app must receive an index of the byzantine validator
assert.Equal(t, tc.expectedByzantineValidators, app.ByzantineValidators, tc.desc)
}
}
2017-02-21 11:40:26 -08:00
//----------------------------------------------------------------------------
// make some bogus txs
func makeTxs(height int64) (txs []types.Tx) {
2017-02-21 11:40:26 -08:00
for i := 0; i < nTxsPerBlock; i++ {
2017-11-30 11:08:38 -08:00
txs = append(txs, types.Tx([]byte{byte(height), byte(i)}))
2017-02-21 11:40:26 -08:00
}
return txs
}
2017-12-27 17:03:48 -08:00
func state() State {
s, _ := MakeGenesisState(&types.GenesisDoc{
2017-02-21 11:40:26 -08:00
ChainID: chainID,
Validators: []types.GenesisValidator{
{privKey.PubKey(), 10000, "test"},
2017-02-21 11:40:26 -08:00
},
AppHash: nil,
})
return s
2017-02-21 11:40:26 -08:00
}
2017-12-27 17:03:48 -08:00
func makeBlock(state State, height int64) *types.Block {
block, _ := state.MakeBlock(height, makeTxs(state.LastBlockHeight), new(types.Commit))
2017-02-21 11:40:26 -08:00
return block
}
2017-12-11 10:26:19 -08:00
//----------------------------------------------------------------------------
var _ abci.Application = (*testApp)(nil)
type testApp struct {
abci.BaseApplication
AbsentValidators []int32
ByzantineValidators []abci.Evidence
2017-12-11 10:26:19 -08:00
}
func NewDummyApplication() *testApp {
return &testApp{}
}
func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
return abci.ResponseInfo{}
}
func (app *testApp) BeginBlock(req abci.RequestBeginBlock) abci.ResponseBeginBlock {
app.AbsentValidators = req.AbsentValidators
app.ByzantineValidators = req.ByzantineValidators
2017-12-11 10:26:19 -08:00
return abci.ResponseBeginBlock{}
}
func (app *testApp) DeliverTx(tx []byte) abci.ResponseDeliverTx {
return abci.ResponseDeliverTx{Tags: []cmn.KVPair{}}
2017-12-11 10:26:19 -08:00
}
func (app *testApp) CheckTx(tx []byte) abci.ResponseCheckTx {
return abci.ResponseCheckTx{}
}
func (app *testApp) Commit() abci.ResponseCommit {
return abci.ResponseCommit{}
}
func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
return
}