|
@ -2,10 +2,13 @@ package state |
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
"testing" |
|
|
"testing" |
|
|
|
|
|
"time" |
|
|
|
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert" |
|
|
"github.com/stretchr/testify/require" |
|
|
"github.com/stretchr/testify/require" |
|
|
|
|
|
|
|
|
"github.com/tendermint/abci/example/dummy" |
|
|
"github.com/tendermint/abci/example/dummy" |
|
|
|
|
|
abci "github.com/tendermint/abci/types" |
|
|
crypto "github.com/tendermint/go-crypto" |
|
|
crypto "github.com/tendermint/go-crypto" |
|
|
"github.com/tendermint/tendermint/proxy" |
|
|
"github.com/tendermint/tendermint/proxy" |
|
|
"github.com/tendermint/tendermint/types" |
|
|
"github.com/tendermint/tendermint/types" |
|
@ -30,16 +33,64 @@ func TestApplyBlock(t *testing.T) { |
|
|
state := state() |
|
|
state := state() |
|
|
state.SetLogger(log.TestingLogger()) |
|
|
state.SetLogger(log.TestingLogger()) |
|
|
|
|
|
|
|
|
// make block
|
|
|
|
|
|
block := makeBlock(1, state) |
|
|
block := makeBlock(1, state) |
|
|
|
|
|
|
|
|
err = state.ApplyBlock(types.NopEventBus{}, proxyApp.Consensus(), block, block.MakePartSet(testPartSize).Header(), types.MockMempool{}) |
|
|
err = state.ApplyBlock(types.NopEventBus{}, proxyApp.Consensus(), block, block.MakePartSet(testPartSize).Header(), types.MockMempool{}) |
|
|
|
|
|
|
|
|
require.Nil(t, err) |
|
|
require.Nil(t, err) |
|
|
|
|
|
|
|
|
// TODO check state and mempool
|
|
|
// TODO check state and mempool
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 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() |
|
|
|
|
|
state.SetLogger(log.TestingLogger()) |
|
|
|
|
|
|
|
|
|
|
|
// there were 2 validators
|
|
|
|
|
|
val1PrivKey := crypto.GenPrivKeyEd25519() |
|
|
|
|
|
val2PrivKey := crypto.GenPrivKeyEd25519() |
|
|
|
|
|
lastValidators := types.NewValidatorSet([]*types.Validator{ |
|
|
|
|
|
types.NewValidator(val1PrivKey.PubKey(), 10), |
|
|
|
|
|
types.NewValidator(val2PrivKey.PubKey(), 5), |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
|
|
prevHash := state.LastBlockID.Hash |
|
|
|
|
|
prevParts := types.PartSetHeader{} |
|
|
|
|
|
prevBlockID := types.BlockID{prevHash, prevParts} |
|
|
|
|
|
|
|
|
|
|
|
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}}, |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
for _, tc := range testCases { |
|
|
|
|
|
lastCommit := &types.Commit{BlockID: prevBlockID, Precommits: tc.lastCommitPrecommits} |
|
|
|
|
|
|
|
|
|
|
|
valHash := state.Validators.Hash() |
|
|
|
|
|
block, _ := types.MakeBlock(2, chainID, makeTxs(2), state.LastBlockTotalTx, lastCommit, |
|
|
|
|
|
prevBlockID, valHash, state.AppHash, testPartSize) |
|
|
|
|
|
|
|
|
|
|
|
_, err = ExecCommitBlock(proxyApp.Consensus(), block, log.TestingLogger(), lastValidators) |
|
|
|
|
|
require.Nil(t, err, tc.desc) |
|
|
|
|
|
|
|
|
|
|
|
// -> app must receive an index of the absent validator
|
|
|
|
|
|
assert.Equal(t, tc.expectedAbsentValidators, app.AbsentValidators, tc.desc) |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
// make some bogus txs
|
|
|
// make some bogus txs
|
|
@ -72,3 +123,42 @@ func makeBlock(height int64, state *State) *types.Block { |
|
|
state.AppHash, testPartSize) |
|
|
state.AppHash, testPartSize) |
|
|
return block |
|
|
return block |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
var _ abci.Application = (*testApp)(nil) |
|
|
|
|
|
|
|
|
|
|
|
type testApp struct { |
|
|
|
|
|
abci.BaseApplication |
|
|
|
|
|
|
|
|
|
|
|
AbsentValidators []int32 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
return abci.ResponseBeginBlock{} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
func (app *testApp) DeliverTx(tx []byte) abci.ResponseDeliverTx { |
|
|
|
|
|
return abci.ResponseDeliverTx{Tags: []*abci.KVPair{}} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
} |