mirror of
https://github.com/tendermint/tendermint.git
synced 2026-09-19 14:34:17 +00:00
Merge remote-tracking branch 'origin' into jasmina/4457-blocksync-verification_part1
This commit is contained in:
@@ -357,7 +357,7 @@ func (r *Reactor) SwitchToBlockSync(ctx context.Context, state sm.State) error {
|
||||
go r.requestRoutine(ctx, bsCh)
|
||||
go r.poolRoutine(ctx, true, bsCh)
|
||||
|
||||
if err := r.PublishStatus(ctx, types.EventDataBlockSyncStatus{
|
||||
if err := r.PublishStatus(types.EventDataBlockSyncStatus{
|
||||
Complete: false,
|
||||
Height: state.LastBlockHeight,
|
||||
}); err != nil {
|
||||
@@ -623,11 +623,11 @@ func (r *Reactor) GetRemainingSyncTime() time.Duration {
|
||||
return time.Duration(int64(remain * float64(time.Second)))
|
||||
}
|
||||
|
||||
func (r *Reactor) PublishStatus(ctx context.Context, event types.EventDataBlockSyncStatus) error {
|
||||
func (r *Reactor) PublishStatus(event types.EventDataBlockSyncStatus) error {
|
||||
if r.eventBus == nil {
|
||||
return errors.New("event bus is not configured")
|
||||
}
|
||||
return r.eventBus.PublishEventBlockSyncStatus(ctx, event)
|
||||
return r.eventBus.PublishEventBlockSyncStatus(event)
|
||||
}
|
||||
|
||||
// atomicBool is an atomic Boolean, safe for concurrent use by multiple
|
||||
|
||||
@@ -50,7 +50,6 @@ func setup(
|
||||
genDoc *types.GenesisDoc,
|
||||
privVal types.PrivValidator,
|
||||
maxBlockHeights []int64,
|
||||
chBuf uint,
|
||||
) *reactorTestSuite {
|
||||
t.Helper()
|
||||
|
||||
@@ -228,7 +227,7 @@ func TestReactor_AbruptDisconnect(t *testing.T) {
|
||||
genDoc := factory.GenesisDoc(cfg, time.Now(), valSet.Validators, factory.ConsensusParams())
|
||||
maxBlockHeight := int64(64)
|
||||
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0)
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0})
|
||||
|
||||
require.Equal(t, maxBlockHeight, rts.reactors[rts.nodes[0]].store.Height())
|
||||
|
||||
@@ -268,7 +267,7 @@ func TestReactor_SyncTime(t *testing.T) {
|
||||
genDoc := factory.GenesisDoc(cfg, time.Now(), valSet.Validators, factory.ConsensusParams())
|
||||
maxBlockHeight := int64(101)
|
||||
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0)
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0})
|
||||
require.Equal(t, maxBlockHeight, rts.reactors[rts.nodes[0]].store.Height())
|
||||
rts.start(ctx, t)
|
||||
|
||||
@@ -297,7 +296,7 @@ func TestReactor_NoBlockResponse(t *testing.T) {
|
||||
genDoc := factory.GenesisDoc(cfg, time.Now(), valSet.Validators, factory.ConsensusParams())
|
||||
maxBlockHeight := int64(65)
|
||||
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0}, 0)
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0})
|
||||
|
||||
require.Equal(t, maxBlockHeight, rts.reactors[rts.nodes[0]].store.Height())
|
||||
|
||||
@@ -352,7 +351,7 @@ func TestReactor_BadBlockStopsPeer(t *testing.T) {
|
||||
valSet, privVals := factory.ValidatorSet(ctx, t, 1, 30)
|
||||
genDoc := factory.GenesisDoc(cfg, time.Now(), valSet.Validators, factory.ConsensusParams())
|
||||
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0, 0, 0, 0}, 1000)
|
||||
rts := setup(ctx, t, genDoc, privVals[0], []int64{maxBlockHeight, 0, 0, 0, 0})
|
||||
|
||||
require.Equal(t, maxBlockHeight, rts.reactors[rts.nodes[0]].store.Height())
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
ensureDir(t, path.Dir(thisConfig.Consensus.WalFile()), 0700) // dir for wal
|
||||
app := kvstore.NewApplication()
|
||||
vals := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
_, err = app.InitChain(ctx, &abci.RequestInitChain{Validators: vals})
|
||||
require.NoError(t, err)
|
||||
|
||||
blockDB := dbm.NewMemDB()
|
||||
blockStore := store.NewBlockStore(blockDB)
|
||||
@@ -96,7 +97,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
|
||||
// Make State
|
||||
blockExec := sm.NewBlockExecutor(stateStore, log.NewNopLogger(), proxyAppConnCon, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
|
||||
cs, err := NewState(ctx, logger, thisConfig.Consensus, stateStore, blockExec, blockStore, mempool, evpool, eventBus)
|
||||
cs, err := NewState(logger, thisConfig.Consensus, stateStore, blockExec, blockStore, mempool, evpool, eventBus)
|
||||
require.NoError(t, err)
|
||||
// set private validator
|
||||
pv := privVals[i]
|
||||
@@ -203,7 +204,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) {
|
||||
proposerAddr := lazyNodeState.privValidatorPubKey.Address()
|
||||
|
||||
block, err := lazyNodeState.blockExec.CreateProposalBlock(
|
||||
ctx, lazyNodeState.Height, lazyNodeState.state, commit, proposerAddr, nil)
|
||||
ctx, lazyNodeState.Height, lazyNodeState.state, commit, proposerAddr, lazyNodeState.LastCommit.GetVotes())
|
||||
require.NoError(t, err)
|
||||
blockParts, err := block.MakePartSet(types.BlockPartSizeBytes)
|
||||
require.NoError(t, err)
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
dbm "github.com/tendermint/tm-db"
|
||||
|
||||
@@ -112,7 +113,8 @@ func (vs *validatorStub) signVote(
|
||||
ctx context.Context,
|
||||
voteType tmproto.SignedMsgType,
|
||||
chainID string,
|
||||
blockID types.BlockID) (*types.Vote, error) {
|
||||
blockID types.BlockID,
|
||||
voteExtension []byte) (*types.Vote, error) {
|
||||
|
||||
pubKey, err := vs.PrivValidator.GetPubKey(ctx)
|
||||
if err != nil {
|
||||
@@ -120,28 +122,30 @@ func (vs *validatorStub) signVote(
|
||||
}
|
||||
|
||||
vote := &types.Vote{
|
||||
ValidatorIndex: vs.Index,
|
||||
ValidatorAddress: pubKey.Address(),
|
||||
Type: voteType,
|
||||
Height: vs.Height,
|
||||
Round: vs.Round,
|
||||
Timestamp: vs.clock.Now(),
|
||||
Type: voteType,
|
||||
BlockID: blockID,
|
||||
VoteExtension: types.VoteExtensionFromProto(kvstore.ConstructVoteExtension(pubKey.Address())),
|
||||
Timestamp: vs.clock.Now(),
|
||||
ValidatorAddress: pubKey.Address(),
|
||||
ValidatorIndex: vs.Index,
|
||||
Extension: voteExtension,
|
||||
}
|
||||
v := vote.ToProto()
|
||||
if err := vs.PrivValidator.SignVote(ctx, chainID, v); err != nil {
|
||||
if err = vs.PrivValidator.SignVote(ctx, chainID, v); err != nil {
|
||||
return nil, fmt.Errorf("sign vote failed: %w", err)
|
||||
}
|
||||
|
||||
// ref: signVote in FilePV, the vote should use the privious vote info when the sign data is the same.
|
||||
// ref: signVote in FilePV, the vote should use the previous vote info when the sign data is the same.
|
||||
if signDataIsEqual(vs.lastVote, v) {
|
||||
v.Signature = vs.lastVote.Signature
|
||||
v.Timestamp = vs.lastVote.Timestamp
|
||||
v.ExtensionSignature = vs.lastVote.ExtensionSignature
|
||||
}
|
||||
|
||||
vote.Signature = v.Signature
|
||||
vote.Timestamp = v.Timestamp
|
||||
vote.ExtensionSignature = v.ExtensionSignature
|
||||
|
||||
return vote, err
|
||||
}
|
||||
@@ -155,13 +159,9 @@ func signVote(
|
||||
chainID string,
|
||||
blockID types.BlockID) *types.Vote {
|
||||
|
||||
v, err := vs.signVote(ctx, voteType, chainID, blockID)
|
||||
v, err := vs.signVote(ctx, voteType, chainID, blockID, []byte("extension"))
|
||||
require.NoError(t, err, "failed to sign vote")
|
||||
|
||||
// TODO: remove hardcoded vote extension.
|
||||
// currently set for abci/examples/kvstore/persistent_kvstore.go
|
||||
v.VoteExtension = types.VoteExtensionFromProto(kvstore.ConstructVoteExtension(v.ValidatorAddress))
|
||||
|
||||
vs.lastVote = v
|
||||
|
||||
return v
|
||||
@@ -351,18 +351,19 @@ func validatePrecommit(
|
||||
require.True(t, bytes.Equal(vote.BlockID.Hash, votedBlockHash), "Expected precommit to be for proposal block")
|
||||
}
|
||||
|
||||
rs := cs.GetRoundState()
|
||||
if lockedBlockHash == nil {
|
||||
require.False(t, cs.LockedRound != lockRound || cs.LockedBlock != nil,
|
||||
require.False(t, rs.LockedRound != lockRound || rs.LockedBlock != nil,
|
||||
"Expected to be locked on nil at round %d. Got locked at round %d with block %v",
|
||||
lockRound,
|
||||
cs.LockedRound,
|
||||
cs.LockedBlock)
|
||||
rs.LockedRound,
|
||||
rs.LockedBlock)
|
||||
} else {
|
||||
require.False(t, cs.LockedRound != lockRound || !bytes.Equal(cs.LockedBlock.Hash(), lockedBlockHash),
|
||||
require.False(t, rs.LockedRound != lockRound || !bytes.Equal(rs.LockedBlock.Hash(), lockedBlockHash),
|
||||
"Expected block to be locked on round %d, got %d. Got locked block %X, expected %X",
|
||||
lockRound,
|
||||
cs.LockedRound,
|
||||
cs.LockedBlock.Hash(),
|
||||
rs.LockedRound,
|
||||
rs.LockedBlock.Hash(),
|
||||
lockedBlockHash)
|
||||
}
|
||||
}
|
||||
@@ -491,8 +492,7 @@ func newStateWithConfigAndBlockStore(
|
||||
require.NoError(t, eventBus.Start(ctx))
|
||||
|
||||
blockExec := sm.NewBlockExecutor(stateStore, logger, proxyAppConnCon, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
|
||||
cs, err := NewState(ctx,
|
||||
logger.With("module", "consensus"),
|
||||
cs, err := NewState(logger.With("module", "consensus"),
|
||||
thisConfig.Consensus,
|
||||
stateStore,
|
||||
blockExec,
|
||||
@@ -731,10 +731,9 @@ func ensureVoteMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64,
|
||||
msg.Data())
|
||||
|
||||
vote := voteEvent.Vote
|
||||
require.Equal(t, height, vote.Height)
|
||||
require.Equal(t, round, vote.Round)
|
||||
|
||||
require.Equal(t, voteType, vote.Type)
|
||||
assert.Equal(t, height, vote.Height, "expected height %d, but got %d", height, vote.Height)
|
||||
assert.Equal(t, round, vote.Round, "expected round %d, but got %d", round, vote.Round)
|
||||
assert.Equal(t, voteType, vote.Type, "expected type %s, but got %s", voteType, vote.Type)
|
||||
if hash == nil {
|
||||
require.Nil(t, vote.BlockID.Hash, "Expected prevote to be for nil, got %X", vote.BlockID.Hash)
|
||||
} else {
|
||||
@@ -742,6 +741,7 @@ func ensureVoteMatch(t *testing.T, voteCh <-chan tmpubsub.Message, height int64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ensureVote(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, round int32, voteType tmproto.SignedMsgType) {
|
||||
t.Helper()
|
||||
msg := ensureMessageBeforeTimeout(t, voteCh, ensureTimeout)
|
||||
@@ -750,10 +750,9 @@ func ensureVote(t *testing.T, voteCh <-chan tmpubsub.Message, height int64, roun
|
||||
msg.Data())
|
||||
|
||||
vote := voteEvent.Vote
|
||||
require.Equal(t, height, vote.Height)
|
||||
require.Equal(t, round, vote.Round)
|
||||
|
||||
require.Equal(t, voteType, vote.Type)
|
||||
require.Equal(t, height, vote.Height, "expected height %d, but got %d", height, vote.Height)
|
||||
require.Equal(t, round, vote.Round, "expected round %d, but got %d", round, vote.Round)
|
||||
require.Equal(t, voteType, vote.Type, "expected type %s, but got %s", voteType, vote.Type)
|
||||
}
|
||||
|
||||
func ensureNewEventOnChannel(t *testing.T, ch <-chan tmpubsub.Message) {
|
||||
@@ -822,7 +821,8 @@ func makeConsensusState(
|
||||
closeFuncs = append(closeFuncs, app.Close)
|
||||
|
||||
vals := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
_, err = app.InitChain(ctx, &abci.RequestInitChain{Validators: vals})
|
||||
require.NoError(t, err)
|
||||
|
||||
l := logger.With("validator", i, "module", "consensus")
|
||||
css[i] = newStateWithConfigAndBlockStore(ctx, t, l, thisConfig, state, privVals[i], app, blockStore)
|
||||
@@ -893,7 +893,8 @@ func randConsensusNetWithPeers(
|
||||
case *kvstore.Application:
|
||||
state.Version.Consensus.App = kvstore.ProtocolVersion
|
||||
}
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
_, err = app.InitChain(ctx, &abci.RequestInitChain{Validators: vals})
|
||||
require.NoError(t, err)
|
||||
// sm.SaveState(stateDB,state) //height 1's validatorsInfo already saved in LoadStateFromDBOrGenesisDoc above
|
||||
|
||||
css[i] = newStateWithConfig(ctx, t, logger.With("validator", i, "module", "consensus"), thisConfig, state, privVal, app)
|
||||
@@ -987,5 +988,6 @@ func signDataIsEqual(v1 *types.Vote, v2 *tmproto.Vote) bool {
|
||||
v1.Height == v2.GetHeight() &&
|
||||
v1.Round == v2.Round &&
|
||||
bytes.Equal(v1.ValidatorAddress.Bytes(), v2.GetValidatorAddress()) &&
|
||||
v1.ValidatorIndex == v2.GetValidatorIndex()
|
||||
v1.ValidatorIndex == v2.GetValidatorIndex() &&
|
||||
bytes.Equal(v1.Extension, v2.Extension)
|
||||
}
|
||||
|
||||
@@ -199,10 +199,12 @@ func TestMempoolRmBadTx(t *testing.T) {
|
||||
txBytes := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(txBytes, uint64(0))
|
||||
|
||||
resFinalize := app.FinalizeBlock(abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}})
|
||||
resFinalize, err := app.FinalizeBlock(ctx, &abci.RequestFinalizeBlock{Txs: [][]byte{txBytes}})
|
||||
require.NoError(t, err)
|
||||
assert.False(t, resFinalize.TxResults[0].IsErr(), fmt.Sprintf("expected no error. got %v", resFinalize))
|
||||
|
||||
resCommit := app.Commit()
|
||||
resCommit, err := app.Commit(ctx)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, len(resCommit.Data) > 0)
|
||||
|
||||
emptyMempoolCh := make(chan struct{})
|
||||
@@ -267,11 +269,11 @@ func NewCounterApplication() *CounterApplication {
|
||||
return &CounterApplication{}
|
||||
}
|
||||
|
||||
func (app *CounterApplication) Info(req abci.RequestInfo) abci.ResponseInfo {
|
||||
return abci.ResponseInfo{Data: fmt.Sprintf("txs:%v", app.txCount)}
|
||||
func (app *CounterApplication) Info(_ context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) {
|
||||
return &abci.ResponseInfo{Data: fmt.Sprintf("txs:%v", app.txCount)}, nil
|
||||
}
|
||||
|
||||
func (app *CounterApplication) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock {
|
||||
func (app *CounterApplication) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) {
|
||||
respTxs := make([]*abci.ExecTxResult, len(req.Txs))
|
||||
for i, tx := range req.Txs {
|
||||
txValue := txAsUint64(tx)
|
||||
@@ -285,18 +287,19 @@ func (app *CounterApplication) FinalizeBlock(req abci.RequestFinalizeBlock) abci
|
||||
app.txCount++
|
||||
respTxs[i] = &abci.ExecTxResult{Code: code.CodeTypeOK}
|
||||
}
|
||||
return abci.ResponseFinalizeBlock{TxResults: respTxs}
|
||||
return &abci.ResponseFinalizeBlock{TxResults: respTxs}, nil
|
||||
}
|
||||
|
||||
func (app *CounterApplication) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
||||
func (app *CounterApplication) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) {
|
||||
txValue := txAsUint64(req.Tx)
|
||||
if txValue != uint64(app.mempoolTxCount) {
|
||||
return abci.ResponseCheckTx{
|
||||
return &abci.ResponseCheckTx{
|
||||
Code: code.CodeTypeBadNonce,
|
||||
Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.mempoolTxCount, txValue)}
|
||||
Log: fmt.Sprintf("Invalid nonce. Expected %v, got %v", app.mempoolTxCount, txValue),
|
||||
}, nil
|
||||
}
|
||||
app.mempoolTxCount++
|
||||
return abci.ResponseCheckTx{Code: code.CodeTypeOK}
|
||||
return &abci.ResponseCheckTx{Code: code.CodeTypeOK}, nil
|
||||
}
|
||||
|
||||
func txAsUint64(tx []byte) uint64 {
|
||||
@@ -305,19 +308,17 @@ func txAsUint64(tx []byte) uint64 {
|
||||
return binary.BigEndian.Uint64(tx8)
|
||||
}
|
||||
|
||||
func (app *CounterApplication) Commit() abci.ResponseCommit {
|
||||
func (app *CounterApplication) Commit(context.Context) (*abci.ResponseCommit, error) {
|
||||
app.mempoolTxCount = app.txCount
|
||||
if app.txCount == 0 {
|
||||
return abci.ResponseCommit{}
|
||||
return &abci.ResponseCommit{}, nil
|
||||
}
|
||||
hash := make([]byte, 8)
|
||||
binary.BigEndian.PutUint64(hash, uint64(app.txCount))
|
||||
return abci.ResponseCommit{Data: hash}
|
||||
return &abci.ResponseCommit{Data: hash}, nil
|
||||
}
|
||||
|
||||
func (app *CounterApplication) PrepareProposal(
|
||||
req abci.RequestPrepareProposal) abci.ResponsePrepareProposal {
|
||||
|
||||
func (app *CounterApplication) PrepareProposal(_ context.Context, req *abci.RequestPrepareProposal) (*abci.ResponsePrepareProposal, error) {
|
||||
trs := make([]*abci.TxRecord, 0, len(req.Txs))
|
||||
var totalBytes int64
|
||||
for _, tx := range req.Txs {
|
||||
@@ -330,10 +331,9 @@ func (app *CounterApplication) PrepareProposal(
|
||||
Tx: tx,
|
||||
})
|
||||
}
|
||||
return abci.ResponsePrepareProposal{TxRecords: trs}
|
||||
return &abci.ResponsePrepareProposal{TxRecords: trs}, nil
|
||||
}
|
||||
|
||||
func (app *CounterApplication) ProcessProposal(
|
||||
req abci.RequestProcessProposal) abci.ResponseProcessProposal {
|
||||
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
|
||||
func (app *CounterApplication) ProcessProposal(_ context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) {
|
||||
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
testing "testing"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
state "github.com/tendermint/tendermint/internal/state"
|
||||
)
|
||||
@@ -26,3 +28,13 @@ func (_m *ConsSyncReactor) SetStateSyncingMetrics(_a0 float64) {
|
||||
func (_m *ConsSyncReactor) SwitchToConsensus(_a0 state.State, _a1 bool) {
|
||||
_m.Called(_a0, _a1)
|
||||
}
|
||||
|
||||
// NewConsSyncReactor creates a new instance of ConsSyncReactor. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewConsSyncReactor(t testing.TB) *ConsSyncReactor {
|
||||
mock := &ConsSyncReactor{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -357,11 +357,6 @@ func TestConsMsgsVectors(t *testing.T) {
|
||||
}
|
||||
pbProposal := proposal.ToProto()
|
||||
|
||||
ext := types.VoteExtension{
|
||||
AppDataToSign: []byte("signed"),
|
||||
AppDataSelfAuthenticating: []byte("auth"),
|
||||
}
|
||||
|
||||
v := &types.Vote{
|
||||
ValidatorAddress: []byte("add_more_exclamation"),
|
||||
ValidatorIndex: 1,
|
||||
@@ -370,7 +365,7 @@ func TestConsMsgsVectors(t *testing.T) {
|
||||
Timestamp: date,
|
||||
Type: tmproto.PrecommitType,
|
||||
BlockID: bi,
|
||||
VoteExtension: ext,
|
||||
Extension: []byte("extension"),
|
||||
}
|
||||
vpb := v.ToProto()
|
||||
|
||||
@@ -407,7 +402,7 @@ func TestConsMsgsVectors(t *testing.T) {
|
||||
"2a36080110011a3008011204746573741a26080110011a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d"},
|
||||
{"Vote", &tmcons.Message{Sum: &tmcons.Message_Vote{
|
||||
Vote: &tmcons.Vote{Vote: vpb}}},
|
||||
"3280010a7e0802100122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d2a0608c0b89fdc0532146164645f6d6f72655f6578636c616d6174696f6e38014a0e0a067369676e6564120461757468"},
|
||||
"327b0a790802100122480a206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d1224080112206164645f6d6f72655f6578636c616d6174696f6e5f6d61726b735f636f64652d2a0608c0b89fdc0532146164645f6d6f72655f6578636c616d6174696f6e38014a09657874656e73696f6e"},
|
||||
{"HasVote", &tmcons.Message{Sum: &tmcons.Message_HasVote{
|
||||
HasVote: &tmcons.HasVote{Height: 1, Round: 1, Type: tmproto.PrevoteType, Index: 1}}},
|
||||
"3a080801100118012001"},
|
||||
|
||||
@@ -210,7 +210,7 @@ func (r *Reactor) OnStart(ctx context.Context) error {
|
||||
// leak the goroutine when stopping the reactor.
|
||||
go r.peerStatsRoutine(ctx, peerUpdates)
|
||||
|
||||
r.subscribeToBroadcastEvents(chBundle.state)
|
||||
r.subscribeToBroadcastEvents(ctx, chBundle.state)
|
||||
|
||||
if !r.WaitSync() {
|
||||
if err := r.state.Start(ctx); err != nil {
|
||||
@@ -260,7 +260,7 @@ func (r *Reactor) SwitchToConsensus(ctx context.Context, state sm.State, skipWAL
|
||||
|
||||
// NOTE: The line below causes broadcastNewRoundStepRoutine() to broadcast a
|
||||
// NewRoundStepMessage.
|
||||
r.state.updateToState(ctx, state)
|
||||
r.state.updateToState(state)
|
||||
if err := r.state.Start(ctx); err != nil {
|
||||
panic(fmt.Sprintf(`failed to start consensus state: %v
|
||||
|
||||
@@ -284,7 +284,7 @@ conR:
|
||||
}
|
||||
|
||||
d := types.EventDataBlockSyncStatus{Complete: true, Height: state.LastBlockHeight}
|
||||
if err := r.eventBus.PublishEventBlockSyncStatus(ctx, d); err != nil {
|
||||
if err := r.eventBus.PublishEventBlockSyncStatus(d); err != nil {
|
||||
r.logger.Error("failed to emit the blocksync complete event", "err", err)
|
||||
}
|
||||
}
|
||||
@@ -344,13 +344,13 @@ func (r *Reactor) broadcastHasVoteMessage(ctx context.Context, vote *types.Vote,
|
||||
// subscribeToBroadcastEvents subscribes for new round steps and votes using the
|
||||
// internal pubsub defined in the consensus state to broadcast them to peers
|
||||
// upon receiving.
|
||||
func (r *Reactor) subscribeToBroadcastEvents(stateCh *p2p.Channel) {
|
||||
func (r *Reactor) subscribeToBroadcastEvents(ctx context.Context, stateCh *p2p.Channel) {
|
||||
onStopCh := r.state.getOnStopCh()
|
||||
|
||||
err := r.state.evsw.AddListenerForEvent(
|
||||
listenerIDConsensus,
|
||||
types.EventNewRoundStepValue,
|
||||
func(ctx context.Context, data tmevents.EventData) error {
|
||||
func(data tmevents.EventData) error {
|
||||
if err := r.broadcastNewRoundStepMessage(ctx, data.(*cstypes.RoundState), stateCh); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -371,7 +371,7 @@ func (r *Reactor) subscribeToBroadcastEvents(stateCh *p2p.Channel) {
|
||||
err = r.state.evsw.AddListenerForEvent(
|
||||
listenerIDConsensus,
|
||||
types.EventValidBlockValue,
|
||||
func(ctx context.Context, data tmevents.EventData) error {
|
||||
func(data tmevents.EventData) error {
|
||||
return r.broadcastNewValidBlockMessage(ctx, data.(*cstypes.RoundState), stateCh)
|
||||
},
|
||||
)
|
||||
@@ -382,7 +382,7 @@ func (r *Reactor) subscribeToBroadcastEvents(stateCh *p2p.Channel) {
|
||||
err = r.state.evsw.AddListenerForEvent(
|
||||
listenerIDConsensus,
|
||||
types.EventVoteValue,
|
||||
func(ctx context.Context, data tmevents.EventData) error {
|
||||
func(data tmevents.EventData) error {
|
||||
return r.broadcastHasVoteMessage(ctx, data.(*types.Vote), stateCh)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -466,7 +466,8 @@ func TestReactorWithEvidence(t *testing.T) {
|
||||
|
||||
app := kvstore.NewApplication()
|
||||
vals := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
app.InitChain(abci.RequestInitChain{Validators: vals})
|
||||
_, err = app.InitChain(ctx, &abci.RequestInitChain{Validators: vals})
|
||||
require.NoError(t, err)
|
||||
|
||||
pv := privVals[i]
|
||||
blockDB := dbm.NewMemDB()
|
||||
@@ -505,7 +506,7 @@ func TestReactorWithEvidence(t *testing.T) {
|
||||
|
||||
blockExec := sm.NewBlockExecutor(stateStore, log.NewNopLogger(), proxyAppConnCon, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
|
||||
|
||||
cs, err := NewState(ctx, logger.With("validator", i, "module", "consensus"),
|
||||
cs, err := NewState(logger.With("validator", i, "module", "consensus"),
|
||||
thisConfig.Consensus, stateStore, blockExec, blockStore, mempool, evpool2, eventBus)
|
||||
require.NoError(t, err)
|
||||
cs.SetPrivValidator(ctx, pv)
|
||||
|
||||
@@ -239,7 +239,7 @@ func (h *Handshaker) NBlocks() int {
|
||||
func (h *Handshaker) Handshake(ctx context.Context, appClient abciclient.Client) error {
|
||||
|
||||
// Handshake is done via ABCI Info on the query conn.
|
||||
res, err := appClient.Info(ctx, proxy.RequestInfo)
|
||||
res, err := appClient.Info(ctx, &proxy.RequestInfo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error calling Info: %w", err)
|
||||
}
|
||||
@@ -307,15 +307,14 @@ func (h *Handshaker) ReplayBlocks(
|
||||
validatorSet := types.NewValidatorSet(validators)
|
||||
nextVals := types.TM2PB.ValidatorUpdates(validatorSet)
|
||||
pbParams := h.genDoc.ConsensusParams.ToProto()
|
||||
req := abci.RequestInitChain{
|
||||
res, err := appClient.InitChain(ctx, &abci.RequestInitChain{
|
||||
Time: h.genDoc.GenesisTime,
|
||||
ChainId: h.genDoc.ChainID,
|
||||
InitialHeight: h.genDoc.InitialHeight,
|
||||
ConsensusParams: &pbParams,
|
||||
Validators: nextVals,
|
||||
AppStateBytes: h.genDoc.AppState,
|
||||
}
|
||||
res, err := appClient.InitChain(ctx, req)
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -429,7 +428,7 @@ func (h *Handshaker) ReplayBlocks(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mockApp, err := newMockProxyApp(ctx, h.logger, appHash, abciResponses)
|
||||
mockApp, err := newMockProxyApp(h.logger, appHash, abciResponses)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ func (pb *playback) replayReset(ctx context.Context, count int, newStepSub event
|
||||
pb.cs.Stop()
|
||||
pb.cs.Wait()
|
||||
|
||||
newCS, err := NewState(ctx, pb.cs.logger, pb.cs.config, pb.stateStore, pb.cs.blockExec,
|
||||
newCS, err := NewState(pb.cs.logger, pb.cs.config, pb.stateStore, pb.cs.blockExec,
|
||||
pb.cs.blockStore, pb.cs.txNotifier, pb.cs.evpool, pb.cs.eventBus)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -350,7 +350,7 @@ func newConsensusStateForReplay(
|
||||
mempool, evpool := emptyMempool{}, sm.EmptyEvidencePool{}
|
||||
blockExec := sm.NewBlockExecutor(stateStore, logger, proxyApp, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
|
||||
|
||||
consensusState, err := NewState(ctx, logger, csConfig, stateStore, blockExec,
|
||||
consensusState, err := NewState(logger, csConfig, stateStore, blockExec,
|
||||
blockStore, mempool, evpool, eventBus)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -57,7 +57,6 @@ func (emptyMempool) CloseWAL() {}
|
||||
// the real app.
|
||||
|
||||
func newMockProxyApp(
|
||||
ctx context.Context,
|
||||
logger log.Logger,
|
||||
appHash []byte,
|
||||
abciResponses *tmstate.ABCIResponses,
|
||||
@@ -76,15 +75,15 @@ type mockProxyApp struct {
|
||||
abciResponses *tmstate.ABCIResponses
|
||||
}
|
||||
|
||||
func (mock *mockProxyApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock {
|
||||
func (mock *mockProxyApp) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) {
|
||||
r := mock.abciResponses.FinalizeBlock
|
||||
mock.txCount++
|
||||
if r == nil {
|
||||
return abci.ResponseFinalizeBlock{}
|
||||
return &abci.ResponseFinalizeBlock{}, nil
|
||||
}
|
||||
return *r
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (mock *mockProxyApp) Commit() abci.ResponseCommit {
|
||||
return abci.ResponseCommit{Data: mock.appHash}
|
||||
func (mock *mockProxyApp) Commit(context.Context) (*abci.ResponseCommit, error) {
|
||||
return &abci.ResponseCommit{Data: mock.appHash}, nil
|
||||
}
|
||||
|
||||
@@ -118,9 +118,6 @@ func sendTxs(ctx context.Context, t *testing.T, cs *State) {
|
||||
|
||||
// TestWALCrash uses crashing WAL to test we can recover from any WAL failure.
|
||||
func TestWALCrash(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
initFn func(dbm.DB, *State, context.Context)
|
||||
@@ -139,6 +136,9 @@ func TestWALCrash(t *testing.T) {
|
||||
for _, tc := range testCases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
consensusReplayConfig, err := ResetConfig(t.TempDir(), tc.name)
|
||||
require.NoError(t, err)
|
||||
crashWALandCheckLiveness(ctx, t, consensusReplayConfig, tc.initFn, tc.heightToStop)
|
||||
@@ -788,7 +788,7 @@ func testHandshakeReplay(
|
||||
require.NoError(t, err, "Error on abci handshake")
|
||||
|
||||
// get the latest app hash from the app
|
||||
res, err := proxyApp.Info(ctx, abci.RequestInfo{Version: ""})
|
||||
res, err := proxyApp.Info(ctx, &abci.RequestInfo{Version: ""})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@@ -856,7 +856,7 @@ func buildAppStateFromChain(
|
||||
|
||||
state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version
|
||||
validators := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
_, err := appClient.InitChain(ctx, abci.RequestInitChain{
|
||||
_, err := appClient.InitChain(ctx, &abci.RequestInitChain{
|
||||
Validators: validators,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -910,7 +910,7 @@ func buildTMStateFromChain(
|
||||
|
||||
state.Version.Consensus.App = kvstore.ProtocolVersion // simulate handshake, receive app version
|
||||
validators := types.TM2PB.ValidatorUpdates(state.Validators)
|
||||
_, err := proxyApp.InitChain(ctx, abci.RequestInitChain{
|
||||
_, err := proxyApp.InitChain(ctx, &abci.RequestInitChain{
|
||||
Validators: validators,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -1017,15 +1017,15 @@ type badApp struct {
|
||||
onlyLastHashIsWrong bool
|
||||
}
|
||||
|
||||
func (app *badApp) Commit() abci.ResponseCommit {
|
||||
func (app *badApp) Commit(context.Context) (*abci.ResponseCommit, error) {
|
||||
app.height++
|
||||
if app.onlyLastHashIsWrong {
|
||||
if app.height == app.numBlocks {
|
||||
return abci.ResponseCommit{Data: tmrand.Bytes(8)}
|
||||
return &abci.ResponseCommit{Data: tmrand.Bytes(8)}, nil
|
||||
}
|
||||
return abci.ResponseCommit{Data: []byte{app.height}}
|
||||
return &abci.ResponseCommit{Data: []byte{app.height}}, nil
|
||||
} else if app.allHashesAreWrong {
|
||||
return abci.ResponseCommit{Data: tmrand.Bytes(8)}
|
||||
return &abci.ResponseCommit{Data: tmrand.Bytes(8)}, nil
|
||||
}
|
||||
|
||||
panic("either allHashesAreWrong or onlyLastHashIsWrong must be set")
|
||||
@@ -1275,8 +1275,6 @@ type initChainApp struct {
|
||||
vals []abci.ValidatorUpdate
|
||||
}
|
||||
|
||||
func (ica *initChainApp) InitChain(req abci.RequestInitChain) abci.ResponseInitChain {
|
||||
return abci.ResponseInitChain{
|
||||
Validators: ica.vals,
|
||||
}
|
||||
func (ica *initChainApp) InitChain(_ context.Context, req *abci.RequestInitChain) (*abci.ResponseInitChain, error) {
|
||||
return &abci.ResponseInitChain{Validators: ica.vals}, nil
|
||||
}
|
||||
|
||||
+41
-43
@@ -194,7 +194,6 @@ func SkipStateStoreBootstrap(sm *State) {
|
||||
|
||||
// NewState returns a new State.
|
||||
func NewState(
|
||||
ctx context.Context,
|
||||
logger log.Logger,
|
||||
cfg *config.ConsensusConfig,
|
||||
store sm.Store,
|
||||
@@ -240,7 +239,7 @@ func NewState(
|
||||
// node-fragments gracefully while letting the nodes
|
||||
// themselves avoid this.
|
||||
if !cs.skipBootstrapping {
|
||||
if err := cs.updateStateFromStore(ctx); err != nil {
|
||||
if err := cs.updateStateFromStore(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -248,7 +247,7 @@ func NewState(
|
||||
return cs, nil
|
||||
}
|
||||
|
||||
func (cs *State) updateStateFromStore(ctx context.Context) error {
|
||||
func (cs *State) updateStateFromStore() error {
|
||||
if cs.initialStatePopulated {
|
||||
return nil
|
||||
}
|
||||
@@ -265,7 +264,7 @@ func (cs *State) updateStateFromStore(ctx context.Context) error {
|
||||
cs.reconstructLastCommit(state)
|
||||
}
|
||||
|
||||
cs.updateToState(ctx, state)
|
||||
cs.updateToState(state)
|
||||
|
||||
cs.initialStatePopulated = true
|
||||
return nil
|
||||
@@ -393,7 +392,7 @@ func (cs *State) LoadCommit(height int64) *types.Commit {
|
||||
// OnStart loads the latest state via the WAL, and starts the timeout and
|
||||
// receive routines.
|
||||
func (cs *State) OnStart(ctx context.Context) error {
|
||||
if err := cs.updateStateFromStore(ctx); err != nil {
|
||||
if err := cs.updateStateFromStore(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -718,7 +717,7 @@ func (cs *State) reconstructLastCommit(state sm.State) {
|
||||
|
||||
// Updates State and increments height to match that of state.
|
||||
// The round becomes 0 and cs.Step becomes cstypes.RoundStepNewHeight.
|
||||
func (cs *State) updateToState(ctx context.Context, state sm.State) {
|
||||
func (cs *State) updateToState(state sm.State) {
|
||||
if cs.CommitRound > -1 && 0 < cs.Height && cs.Height != state.LastBlockHeight {
|
||||
panic(fmt.Sprintf(
|
||||
"updateToState() expected state height of %v but found %v",
|
||||
@@ -753,7 +752,7 @@ func (cs *State) updateToState(ctx context.Context, state sm.State) {
|
||||
"new_height", state.LastBlockHeight+1,
|
||||
"old_height", cs.state.LastBlockHeight+1,
|
||||
)
|
||||
cs.newStep(ctx)
|
||||
cs.newStep()
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -823,10 +822,10 @@ func (cs *State) updateToState(ctx context.Context, state sm.State) {
|
||||
cs.state = state
|
||||
|
||||
// Finally, broadcast RoundState
|
||||
cs.newStep(ctx)
|
||||
cs.newStep()
|
||||
}
|
||||
|
||||
func (cs *State) newStep(ctx context.Context) {
|
||||
func (cs *State) newStep() {
|
||||
rs := cs.RoundStateEvent()
|
||||
if err := cs.wal.Write(rs); err != nil {
|
||||
cs.logger.Error("failed writing to WAL", "err", err)
|
||||
@@ -836,11 +835,11 @@ func (cs *State) newStep(ctx context.Context) {
|
||||
|
||||
// newStep is called by updateToState in NewState before the eventBus is set!
|
||||
if cs.eventBus != nil {
|
||||
if err := cs.eventBus.PublishEventNewRoundStep(ctx, rs); err != nil {
|
||||
if err := cs.eventBus.PublishEventNewRoundStep(rs); err != nil {
|
||||
cs.logger.Error("failed publishing new round step", "err", err)
|
||||
}
|
||||
|
||||
cs.evsw.FireEvent(ctx, types.EventNewRoundStepValue, &cs.RoundState)
|
||||
cs.evsw.FireEvent(types.EventNewRoundStepValue, &cs.RoundState)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -923,7 +922,6 @@ func (cs *State) receiveRoutine(ctx context.Context, maxSteps int) {
|
||||
if err := cs.wal.Write(mi); err != nil {
|
||||
cs.logger.Error("failed writing to WAL", "err", err)
|
||||
}
|
||||
|
||||
// handles proposals, block parts, votes
|
||||
// may generate internal events (votes, complete proposals, 2/3 majorities)
|
||||
cs.handleMsg(ctx, mi)
|
||||
@@ -977,7 +975,7 @@ func (cs *State) handleMsg(ctx context.Context, mi msgInfo) {
|
||||
|
||||
case *BlockPartMessage:
|
||||
// if the proposal is complete, we'll enterPrevote or tryFinalizeCommit
|
||||
added, err = cs.addProposalBlockPart(ctx, msg, peerID)
|
||||
added, err = cs.addProposalBlockPart(msg, peerID)
|
||||
|
||||
// We unlock here to yield to any routines that need to read the the RoundState.
|
||||
// Previously, this code held the lock from the point at which the final block
|
||||
@@ -1083,21 +1081,21 @@ func (cs *State) handleTimeout(
|
||||
cs.enterPropose(ctx, ti.Height, 0)
|
||||
|
||||
case cstypes.RoundStepPropose:
|
||||
if err := cs.eventBus.PublishEventTimeoutPropose(ctx, cs.RoundStateEvent()); err != nil {
|
||||
if err := cs.eventBus.PublishEventTimeoutPropose(cs.RoundStateEvent()); err != nil {
|
||||
cs.logger.Error("failed publishing timeout propose", "err", err)
|
||||
}
|
||||
|
||||
cs.enterPrevote(ctx, ti.Height, ti.Round)
|
||||
|
||||
case cstypes.RoundStepPrevoteWait:
|
||||
if err := cs.eventBus.PublishEventTimeoutWait(ctx, cs.RoundStateEvent()); err != nil {
|
||||
if err := cs.eventBus.PublishEventTimeoutWait(cs.RoundStateEvent()); err != nil {
|
||||
cs.logger.Error("failed publishing timeout wait", "err", err)
|
||||
}
|
||||
|
||||
cs.enterPrecommit(ctx, ti.Height, ti.Round)
|
||||
|
||||
case cstypes.RoundStepPrecommitWait:
|
||||
if err := cs.eventBus.PublishEventTimeoutWait(ctx, cs.RoundStateEvent()); err != nil {
|
||||
if err := cs.eventBus.PublishEventTimeoutWait(cs.RoundStateEvent()); err != nil {
|
||||
cs.logger.Error("failed publishing timeout wait", "err", err)
|
||||
}
|
||||
|
||||
@@ -1200,7 +1198,7 @@ func (cs *State) enterNewRound(ctx context.Context, height int64, round int32) {
|
||||
cs.Votes.SetRound(r) // also track next round (round+1) to allow round-skipping
|
||||
cs.TriggeredTimeoutPrecommit = false
|
||||
|
||||
if err := cs.eventBus.PublishEventNewRound(ctx, cs.NewRoundEvent()); err != nil {
|
||||
if err := cs.eventBus.PublishEventNewRound(cs.NewRoundEvent()); err != nil {
|
||||
cs.logger.Error("failed publishing new round", "err", err)
|
||||
}
|
||||
// Wait for txs to be available in the mempool
|
||||
@@ -1263,7 +1261,7 @@ func (cs *State) enterPropose(ctx context.Context, height int64, round int32) {
|
||||
defer func() {
|
||||
// Done enterPropose:
|
||||
cs.updateRoundStep(round, cstypes.RoundStepPropose)
|
||||
cs.newStep(ctx)
|
||||
cs.newStep()
|
||||
|
||||
// If we have the whole proposal + POL, then goto Prevote now.
|
||||
// else, we'll enterPrevote when the rest of the proposal is received (in AddProposalBlockPart),
|
||||
@@ -1455,7 +1453,7 @@ func (cs *State) enterPrevote(ctx context.Context, height int64, round int32) {
|
||||
defer func() {
|
||||
// Done enterPrevote:
|
||||
cs.updateRoundStep(round, cstypes.RoundStepPrevote)
|
||||
cs.newStep(ctx)
|
||||
cs.newStep()
|
||||
}()
|
||||
|
||||
logger.Debug("entering prevote step", "current", fmt.Sprintf("%v/%v/%v", cs.Height, cs.Round, cs.Step))
|
||||
@@ -1606,7 +1604,7 @@ func (cs *State) defaultDoPrevote(ctx context.Context, height int64, round int32
|
||||
}
|
||||
|
||||
// Enter: any +2/3 prevotes at next round.
|
||||
func (cs *State) enterPrevoteWait(ctx context.Context, height int64, round int32) {
|
||||
func (cs *State) enterPrevoteWait(height int64, round int32) {
|
||||
logger := cs.logger.With("height", height, "round", round)
|
||||
|
||||
if cs.Height != height || round < cs.Round || (cs.Round == round && cstypes.RoundStepPrevoteWait <= cs.Step) {
|
||||
@@ -1629,7 +1627,7 @@ func (cs *State) enterPrevoteWait(ctx context.Context, height int64, round int32
|
||||
defer func() {
|
||||
// Done enterPrevoteWait:
|
||||
cs.updateRoundStep(round, cstypes.RoundStepPrevoteWait)
|
||||
cs.newStep(ctx)
|
||||
cs.newStep()
|
||||
}()
|
||||
|
||||
// Wait for some more prevotes; enterPrecommit
|
||||
@@ -1657,7 +1655,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
|
||||
defer func() {
|
||||
// Done enterPrecommit:
|
||||
cs.updateRoundStep(round, cstypes.RoundStepPrecommit)
|
||||
cs.newStep(ctx)
|
||||
cs.newStep()
|
||||
}()
|
||||
|
||||
// check for a polka
|
||||
@@ -1676,7 +1674,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
|
||||
}
|
||||
|
||||
// At this point +2/3 prevoted for a particular block or nil.
|
||||
if err := cs.eventBus.PublishEventPolka(ctx, cs.RoundStateEvent()); err != nil {
|
||||
if err := cs.eventBus.PublishEventPolka(cs.RoundStateEvent()); err != nil {
|
||||
logger.Error("failed publishing polka", "err", err)
|
||||
}
|
||||
|
||||
@@ -1713,7 +1711,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
|
||||
logger.Debug("precommit step: +2/3 prevoted locked block; relocking")
|
||||
cs.LockedRound = round
|
||||
|
||||
if err := cs.eventBus.PublishEventRelock(ctx, cs.RoundStateEvent()); err != nil {
|
||||
if err := cs.eventBus.PublishEventRelock(cs.RoundStateEvent()); err != nil {
|
||||
logger.Error("precommit step: failed publishing event relock", "err", err)
|
||||
}
|
||||
|
||||
@@ -1736,7 +1734,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
|
||||
cs.LockedBlock = cs.ProposalBlock
|
||||
cs.LockedBlockParts = cs.ProposalBlockParts
|
||||
|
||||
if err := cs.eventBus.PublishEventLock(ctx, cs.RoundStateEvent()); err != nil {
|
||||
if err := cs.eventBus.PublishEventLock(cs.RoundStateEvent()); err != nil {
|
||||
logger.Error("precommit step: failed publishing event lock", "err", err)
|
||||
}
|
||||
|
||||
@@ -1758,7 +1756,7 @@ func (cs *State) enterPrecommit(ctx context.Context, height int64, round int32)
|
||||
}
|
||||
|
||||
// Enter: any +2/3 precommits for next round.
|
||||
func (cs *State) enterPrecommitWait(ctx context.Context, height int64, round int32) {
|
||||
func (cs *State) enterPrecommitWait(height int64, round int32) {
|
||||
logger := cs.logger.With("height", height, "round", round)
|
||||
|
||||
if cs.Height != height || round < cs.Round || (cs.Round == round && cs.TriggeredTimeoutPrecommit) {
|
||||
@@ -1782,7 +1780,7 @@ func (cs *State) enterPrecommitWait(ctx context.Context, height int64, round int
|
||||
defer func() {
|
||||
// Done enterPrecommitWait:
|
||||
cs.TriggeredTimeoutPrecommit = true
|
||||
cs.newStep(ctx)
|
||||
cs.newStep()
|
||||
}()
|
||||
|
||||
// wait for some more precommits; enterNewRound
|
||||
@@ -1809,7 +1807,7 @@ func (cs *State) enterCommit(ctx context.Context, height int64, commitRound int3
|
||||
cs.updateRoundStep(cs.Round, cstypes.RoundStepCommit)
|
||||
cs.CommitRound = commitRound
|
||||
cs.CommitTime = tmtime.Now()
|
||||
cs.newStep(ctx)
|
||||
cs.newStep()
|
||||
|
||||
// Maybe finalize immediately.
|
||||
cs.tryFinalizeCommit(ctx, height)
|
||||
@@ -1844,11 +1842,11 @@ func (cs *State) enterCommit(ctx context.Context, height int64, commitRound int3
|
||||
cs.metrics.MarkBlockGossipStarted()
|
||||
cs.ProposalBlockParts = types.NewPartSetFromHeader(blockID.PartSetHeader)
|
||||
|
||||
if err := cs.eventBus.PublishEventValidBlock(ctx, cs.RoundStateEvent()); err != nil {
|
||||
if err := cs.eventBus.PublishEventValidBlock(cs.RoundStateEvent()); err != nil {
|
||||
logger.Error("failed publishing valid block", "err", err)
|
||||
}
|
||||
|
||||
cs.evsw.FireEvent(ctx, types.EventValidBlockValue, &cs.RoundState)
|
||||
cs.evsw.FireEvent(types.EventValidBlockValue, &cs.RoundState)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1975,7 +1973,7 @@ func (cs *State) finalizeCommit(ctx context.Context, height int64) {
|
||||
cs.RecordMetrics(height, block)
|
||||
|
||||
// NewHeightStep!
|
||||
cs.updateToState(ctx, stateCopy)
|
||||
cs.updateToState(stateCopy)
|
||||
|
||||
// Private validator might have changed it's key pair => refetch pubkey.
|
||||
if err := cs.updatePrivValidatorPubKey(ctx); err != nil {
|
||||
@@ -2130,7 +2128,6 @@ func (cs *State) defaultSetProposal(proposal *types.Proposal, recvTime time.Time
|
||||
// Asynchronously triggers either enterPrevote (before we timeout of propose) or tryFinalizeCommit,
|
||||
// once we have the full block.
|
||||
func (cs *State) addProposalBlockPart(
|
||||
ctx context.Context,
|
||||
msg *BlockPartMessage,
|
||||
peerID types.NodeID,
|
||||
) (added bool, err error) {
|
||||
@@ -2196,7 +2193,7 @@ func (cs *State) addProposalBlockPart(
|
||||
// NOTE: it's possible to receive complete proposal blocks for future rounds without having the proposal
|
||||
cs.logger.Info("received complete proposal block", "height", cs.ProposalBlock.Height, "hash", cs.ProposalBlock.Hash())
|
||||
|
||||
if err := cs.eventBus.PublishEventCompleteProposal(ctx, cs.CompleteProposalEvent()); err != nil {
|
||||
if err := cs.eventBus.PublishEventCompleteProposal(cs.CompleteProposalEvent()); err != nil {
|
||||
cs.logger.Error("failed publishing event complete proposal", "err", err)
|
||||
}
|
||||
}
|
||||
@@ -2315,11 +2312,11 @@ func (cs *State) addVote(
|
||||
}
|
||||
|
||||
cs.logger.Debug("added vote to last precommits", "last_commit", cs.LastCommit.StringShort())
|
||||
if err := cs.eventBus.PublishEventVote(ctx, types.EventDataVote{Vote: vote}); err != nil {
|
||||
if err := cs.eventBus.PublishEventVote(types.EventDataVote{Vote: vote}); err != nil {
|
||||
return added, err
|
||||
}
|
||||
|
||||
cs.evsw.FireEvent(ctx, types.EventVoteValue, vote)
|
||||
cs.evsw.FireEvent(types.EventVoteValue, vote)
|
||||
|
||||
// if we can skip timeoutCommit and have all the votes now,
|
||||
if cs.bypassCommitTimeout() && cs.LastCommit.HasAll() {
|
||||
@@ -2352,10 +2349,10 @@ func (cs *State) addVote(
|
||||
return
|
||||
}
|
||||
|
||||
if err := cs.eventBus.PublishEventVote(ctx, types.EventDataVote{Vote: vote}); err != nil {
|
||||
if err := cs.eventBus.PublishEventVote(types.EventDataVote{Vote: vote}); err != nil {
|
||||
return added, err
|
||||
}
|
||||
cs.evsw.FireEvent(ctx, types.EventVoteValue, vote)
|
||||
cs.evsw.FireEvent(types.EventVoteValue, vote)
|
||||
|
||||
switch vote.Type {
|
||||
case tmproto.PrevoteType:
|
||||
@@ -2390,8 +2387,8 @@ func (cs *State) addVote(
|
||||
cs.ProposalBlockParts = types.NewPartSetFromHeader(blockID.PartSetHeader)
|
||||
}
|
||||
|
||||
cs.evsw.FireEvent(ctx, types.EventValidBlockValue, &cs.RoundState)
|
||||
if err := cs.eventBus.PublishEventValidBlock(ctx, cs.RoundStateEvent()); err != nil {
|
||||
cs.evsw.FireEvent(types.EventValidBlockValue, &cs.RoundState)
|
||||
if err := cs.eventBus.PublishEventValidBlock(cs.RoundStateEvent()); err != nil {
|
||||
return added, err
|
||||
}
|
||||
}
|
||||
@@ -2408,7 +2405,7 @@ func (cs *State) addVote(
|
||||
if ok && (cs.isProposalComplete() || blockID.IsNil()) {
|
||||
cs.enterPrecommit(ctx, height, vote.Round)
|
||||
} else if prevotes.HasTwoThirdsAny() {
|
||||
cs.enterPrevoteWait(ctx, height, vote.Round)
|
||||
cs.enterPrevoteWait(height, vote.Round)
|
||||
}
|
||||
|
||||
case cs.Proposal != nil && 0 <= cs.Proposal.POLRound && cs.Proposal.POLRound == vote.Round:
|
||||
@@ -2439,11 +2436,11 @@ func (cs *State) addVote(
|
||||
cs.enterNewRound(ctx, cs.Height, 0)
|
||||
}
|
||||
} else {
|
||||
cs.enterPrecommitWait(ctx, height, vote.Round)
|
||||
cs.enterPrecommitWait(height, vote.Round)
|
||||
}
|
||||
} else if cs.Round <= vote.Round && precommits.HasTwoThirdsAny() {
|
||||
cs.enterNewRound(ctx, height, vote.Round)
|
||||
cs.enterPrecommitWait(ctx, height, vote.Round)
|
||||
cs.enterPrecommitWait(height, vote.Round)
|
||||
}
|
||||
|
||||
default:
|
||||
@@ -2494,7 +2491,7 @@ func (cs *State) signVote(
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
vote.VoteExtension = ext
|
||||
vote.Extension = ext
|
||||
default:
|
||||
timeout = time.Second
|
||||
}
|
||||
@@ -2506,6 +2503,7 @@ func (cs *State) signVote(
|
||||
|
||||
err := cs.privValidator.SignVote(ctxto, cs.state.ChainID, v)
|
||||
vote.Signature = v.Signature
|
||||
vote.ExtensionSignature = v.ExtensionSignature
|
||||
vote.Timestamp = v.Timestamp
|
||||
|
||||
return vote, err
|
||||
|
||||
@@ -1912,12 +1912,13 @@ func TestProcessProposalAccept(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
m := abcimocks.NewBaseMock()
|
||||
m := abcimocks.NewApplication(t)
|
||||
status := abci.ResponseProcessProposal_REJECT
|
||||
if testCase.accept {
|
||||
status = abci.ResponseProcessProposal_ACCEPT
|
||||
}
|
||||
m.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: status})
|
||||
m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: status}, nil)
|
||||
m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil).Maybe()
|
||||
cs1, _ := makeState(ctx, t, makeStateArgs{config: config, application: m})
|
||||
height, round := cs1.Height, cs1.Round
|
||||
|
||||
@@ -1964,12 +1965,18 @@ func TestFinalizeBlockCalled(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
m := abcimocks.NewBaseMock()
|
||||
m.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT})
|
||||
m.On("VerifyVoteExtension", mock.Anything).Return(abci.ResponseVerifyVoteExtension{
|
||||
m := abcimocks.NewApplication(t)
|
||||
m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{
|
||||
Status: abci.ResponseProcessProposal_ACCEPT,
|
||||
}, nil)
|
||||
m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil)
|
||||
m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(&abci.ResponseVerifyVoteExtension{
|
||||
Status: abci.ResponseVerifyVoteExtension_ACCEPT,
|
||||
})
|
||||
m.On("FinalizeBlock", mock.Anything).Return(abci.ResponseFinalizeBlock{}).Maybe()
|
||||
}, nil)
|
||||
m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(&abci.ResponseFinalizeBlock{}, nil).Maybe()
|
||||
m.On("ExtendVote", mock.Anything, mock.Anything).Return(&abci.ResponseExtendVote{}, nil)
|
||||
m.On("Commit", mock.Anything).Return(&abci.ResponseCommit{}, nil).Maybe()
|
||||
|
||||
cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m})
|
||||
height, round := cs1.Height, cs1.Round
|
||||
|
||||
@@ -2007,14 +2014,254 @@ func TestFinalizeBlockCalled(t *testing.T) {
|
||||
m.AssertExpectations(t)
|
||||
|
||||
if !testCase.expectCalled {
|
||||
m.AssertNotCalled(t, "FinalizeBlock", mock.Anything)
|
||||
m.AssertNotCalled(t, "FinalizeBlock", ctx, mock.Anything)
|
||||
} else {
|
||||
m.AssertCalled(t, "FinalizeBlock", mock.Anything)
|
||||
m.AssertCalled(t, "FinalizeBlock", ctx, mock.Anything)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestExtendVoteCalled tests that the vote extension methods are called at the
|
||||
// correct point in the consensus algorithm.
|
||||
func TestExtendVoteCalled(t *testing.T) {
|
||||
config := configSetup(t)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
m := abcimocks.NewApplication(t)
|
||||
m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil)
|
||||
m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil)
|
||||
m.On("ExtendVote", mock.Anything, mock.Anything).Return(&abci.ResponseExtendVote{
|
||||
VoteExtension: []byte("extension"),
|
||||
}, nil)
|
||||
m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(&abci.ResponseVerifyVoteExtension{
|
||||
Status: abci.ResponseVerifyVoteExtension_ACCEPT,
|
||||
}, nil)
|
||||
m.On("Commit", mock.Anything).Return(&abci.ResponseCommit{}, nil).Maybe()
|
||||
m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(&abci.ResponseFinalizeBlock{}, nil).Maybe()
|
||||
cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m})
|
||||
height, round := cs1.Height, cs1.Round
|
||||
|
||||
proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal)
|
||||
newRoundCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryNewRound)
|
||||
pv1, err := cs1.privValidator.GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
addr := pv1.Address()
|
||||
voteCh := subscribeToVoter(ctx, t, cs1, addr)
|
||||
|
||||
startTestRound(ctx, cs1, cs1.Height, round)
|
||||
ensureNewRound(t, newRoundCh, height, round)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
|
||||
m.AssertNotCalled(t, "ExtendVote", mock.Anything, mock.Anything)
|
||||
|
||||
rs := cs1.GetRoundState()
|
||||
|
||||
blockID := types.BlockID{
|
||||
Hash: rs.ProposalBlock.Hash(),
|
||||
PartSetHeader: rs.ProposalBlockParts.Header(),
|
||||
}
|
||||
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss[1:]...)
|
||||
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
|
||||
|
||||
ensurePrecommit(t, voteCh, height, round)
|
||||
|
||||
m.AssertCalled(t, "ExtendVote", ctx, &abci.RequestExtendVote{
|
||||
Height: height,
|
||||
Hash: blockID.Hash,
|
||||
})
|
||||
|
||||
m.AssertCalled(t, "VerifyVoteExtension", ctx, &abci.RequestVerifyVoteExtension{
|
||||
Hash: blockID.Hash,
|
||||
ValidatorAddress: addr,
|
||||
Height: height,
|
||||
VoteExtension: []byte("extension"),
|
||||
})
|
||||
signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), blockID, vss[1:]...)
|
||||
ensureNewRound(t, newRoundCh, height+1, 0)
|
||||
m.AssertExpectations(t)
|
||||
|
||||
// Only 3 of the vote extensions are seen, as consensus proceeds as soon as the +2/3 threshold
|
||||
// is observed by the consensus engine.
|
||||
for _, pv := range vss[:3] {
|
||||
pv, err := pv.GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
addr := pv.Address()
|
||||
m.AssertCalled(t, "VerifyVoteExtension", ctx, &abci.RequestVerifyVoteExtension{
|
||||
Hash: blockID.Hash,
|
||||
ValidatorAddress: addr,
|
||||
Height: height,
|
||||
VoteExtension: []byte("extension"),
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// TestVerifyVoteExtensionNotCalledOnAbsentPrecommit tests that the VerifyVoteExtension
|
||||
// method is not called for a validator's vote that is never delivered.
|
||||
func TestVerifyVoteExtensionNotCalledOnAbsentPrecommit(t *testing.T) {
|
||||
config := configSetup(t)
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
m := abcimocks.NewApplication(t)
|
||||
m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil)
|
||||
m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil)
|
||||
m.On("ExtendVote", mock.Anything, mock.Anything).Return(&abci.ResponseExtendVote{
|
||||
VoteExtension: []byte("extension"),
|
||||
}, nil)
|
||||
m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(&abci.ResponseVerifyVoteExtension{
|
||||
Status: abci.ResponseVerifyVoteExtension_ACCEPT,
|
||||
}, nil)
|
||||
m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(&abci.ResponseFinalizeBlock{}, nil).Maybe()
|
||||
cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m})
|
||||
height, round := cs1.Height, cs1.Round
|
||||
|
||||
proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal)
|
||||
newRoundCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryNewRound)
|
||||
pv1, err := cs1.privValidator.GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
addr := pv1.Address()
|
||||
voteCh := subscribeToVoter(ctx, t, cs1, addr)
|
||||
|
||||
startTestRound(ctx, cs1, cs1.Height, round)
|
||||
ensureNewRound(t, newRoundCh, height, round)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
rs := cs1.GetRoundState()
|
||||
|
||||
blockID := types.BlockID{
|
||||
Hash: rs.ProposalBlock.Hash(),
|
||||
PartSetHeader: rs.ProposalBlockParts.Header(),
|
||||
}
|
||||
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss[2:]...)
|
||||
ensurePrevoteMatch(t, voteCh, height, round, blockID.Hash)
|
||||
|
||||
ensurePrecommit(t, voteCh, height, round)
|
||||
|
||||
m.AssertCalled(t, "ExtendVote", mock.Anything, &abci.RequestExtendVote{
|
||||
Height: height,
|
||||
Hash: blockID.Hash,
|
||||
})
|
||||
|
||||
m.AssertCalled(t, "VerifyVoteExtension", mock.Anything, &abci.RequestVerifyVoteExtension{
|
||||
Hash: blockID.Hash,
|
||||
ValidatorAddress: addr,
|
||||
Height: height,
|
||||
VoteExtension: []byte("extension"),
|
||||
})
|
||||
|
||||
m.On("Commit", mock.Anything).Return(&abci.ResponseCommit{}, nil).Maybe()
|
||||
signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), blockID, vss[2:]...)
|
||||
ensureNewRound(t, newRoundCh, height+1, 0)
|
||||
m.AssertExpectations(t)
|
||||
|
||||
// vss[1] did not issue a precommit for the block, ensure that a vote extension
|
||||
// for its address was not sent to the application.
|
||||
pv, err := vss[1].GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
addr = pv.Address()
|
||||
|
||||
m.AssertNotCalled(t, "VerifyVoteExtension", ctx, &abci.RequestVerifyVoteExtension{
|
||||
Hash: blockID.Hash,
|
||||
ValidatorAddress: addr,
|
||||
Height: height,
|
||||
VoteExtension: []byte("extension"),
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
// TestPrepareProposalReceivesVoteExtensions tests that the PrepareProposal method
|
||||
// is called with the vote extensions from the previous height. The test functions
|
||||
// be completing a consensus height with a mock application as the proposer. The
|
||||
// test then proceeds to fail sever rounds of consensus until the mock application
|
||||
// is the proposer again and ensures that the mock application receives the set of
|
||||
// vote extensions from the previous consensus instance.
|
||||
func TestPrepareProposalReceivesVoteExtensions(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
config := configSetup(t)
|
||||
|
||||
// create a list of vote extensions, one for each validator.
|
||||
voteExtensions := [][]byte{
|
||||
[]byte("extension 0"),
|
||||
[]byte("extension 1"),
|
||||
[]byte("extension 2"),
|
||||
[]byte("extension 3"),
|
||||
}
|
||||
|
||||
// m := abcimocks.NewApplication(t)
|
||||
m := &abcimocks.Application{}
|
||||
m.On("ExtendVote", mock.Anything, mock.Anything).Return(&abci.ResponseExtendVote{
|
||||
VoteExtension: voteExtensions[0],
|
||||
}, nil)
|
||||
m.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil)
|
||||
|
||||
// capture the prepare proposal request.
|
||||
rpp := &abci.RequestPrepareProposal{}
|
||||
m.On("PrepareProposal", mock.Anything, mock.MatchedBy(func(r *abci.RequestPrepareProposal) bool {
|
||||
rpp = r
|
||||
return true
|
||||
})).Return(&abci.ResponsePrepareProposal{}, nil)
|
||||
|
||||
m.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil).Once()
|
||||
m.On("VerifyVoteExtension", mock.Anything, mock.Anything).Return(&abci.ResponseVerifyVoteExtension{Status: abci.ResponseVerifyVoteExtension_ACCEPT}, nil)
|
||||
m.On("Commit", mock.Anything).Return(&abci.ResponseCommit{}, nil).Maybe()
|
||||
m.On("FinalizeBlock", mock.Anything, mock.Anything).Return(&abci.ResponseFinalizeBlock{}, nil)
|
||||
|
||||
cs1, vss := makeState(ctx, t, makeStateArgs{config: config, application: m})
|
||||
height, round := cs1.Height, cs1.Round
|
||||
|
||||
newRoundCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryNewRound)
|
||||
proposalCh := subscribe(ctx, t, cs1.eventBus, types.EventQueryCompleteProposal)
|
||||
pv1, err := cs1.privValidator.GetPubKey(ctx)
|
||||
require.NoError(t, err)
|
||||
addr := pv1.Address()
|
||||
voteCh := subscribeToVoter(ctx, t, cs1, addr)
|
||||
|
||||
startTestRound(ctx, cs1, height, round)
|
||||
ensureNewRound(t, newRoundCh, height, round)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
|
||||
rs := cs1.GetRoundState()
|
||||
blockID := types.BlockID{
|
||||
Hash: rs.ProposalBlock.Hash(),
|
||||
PartSetHeader: rs.ProposalBlockParts.Header(),
|
||||
}
|
||||
signAddVotes(ctx, t, cs1, tmproto.PrevoteType, config.ChainID(), blockID, vss[1:]...)
|
||||
|
||||
// create a precommit for each validator with the associated vote extension.
|
||||
for i, vs := range vss[1:] {
|
||||
signAddPrecommitWithExtension(ctx, t, cs1, config.ChainID(), blockID, voteExtensions[i+1], vs)
|
||||
}
|
||||
|
||||
ensurePrevote(t, voteCh, height, round)
|
||||
|
||||
// ensure that the height is committed.
|
||||
ensurePrecommitMatch(t, voteCh, height, round, blockID.Hash)
|
||||
incrementHeight(vss[1:]...)
|
||||
|
||||
height++
|
||||
round = 0
|
||||
ensureNewRound(t, newRoundCh, height, round)
|
||||
incrementRound(vss[1:]...)
|
||||
incrementRound(vss[1:]...)
|
||||
incrementRound(vss[1:]...)
|
||||
round = 3
|
||||
|
||||
signAddVotes(ctx, t, cs1, tmproto.PrecommitType, config.ChainID(), types.BlockID{}, vss[1:]...)
|
||||
ensureNewRound(t, newRoundCh, height, round)
|
||||
ensureNewProposal(t, proposalCh, height, round)
|
||||
|
||||
// ensure that the proposer received the list of vote extensions from the
|
||||
// previous height.
|
||||
require.Len(t, rpp.LocalLastCommit.Votes, len(vss))
|
||||
for i := range vss {
|
||||
require.Equal(t, rpp.LocalLastCommit.Votes[i].VoteExtension, voteExtensions[i])
|
||||
}
|
||||
}
|
||||
|
||||
// 4 vals, 3 Nil Precommits at P0
|
||||
// What we want:
|
||||
// P0 waits for timeoutPrecommit before starting next round
|
||||
@@ -2719,3 +2966,15 @@ func subscribe(
|
||||
}()
|
||||
return ch
|
||||
}
|
||||
|
||||
func signAddPrecommitWithExtension(ctx context.Context,
|
||||
t *testing.T,
|
||||
cs *State,
|
||||
chainID string,
|
||||
blockID types.BlockID,
|
||||
extension []byte,
|
||||
stub *validatorStub) {
|
||||
v, err := stub.signVote(ctx, tmproto.PrecommitType, chainID, blockID, extension)
|
||||
require.NoError(t, err, "failed to sign vote")
|
||||
addVotes(cs, v)
|
||||
}
|
||||
|
||||
@@ -88,6 +88,7 @@ func makeVoteHR(
|
||||
require.NoError(t, err, "Error signing vote")
|
||||
|
||||
vote.Signature = v.Signature
|
||||
vote.ExtensionSignature = v.ExtensionSignature
|
||||
|
||||
return vote
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ func WALGenerateNBlocks(ctx context.Context, t *testing.T, logger log.Logger, wr
|
||||
mempool := emptyMempool{}
|
||||
evpool := sm.EmptyEvidencePool{}
|
||||
blockExec := sm.NewBlockExecutor(stateStore, log.NewNopLogger(), proxyApp, mempool, evpool, blockStore, eventBus, sm.NopMetrics())
|
||||
consensusState, err := NewState(ctx, logger, cfg.Consensus, stateStore, blockExec, blockStore, mempool, evpool, eventBus)
|
||||
consensusState, err := NewState(logger, cfg.Consensus, stateStore, blockExec, blockStore, mempool, evpool, eventBus)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func (b *EventBus) Observe(ctx context.Context, observe func(tmpubsub.Message) e
|
||||
return b.pubsub.Observe(ctx, observe, queries...)
|
||||
}
|
||||
|
||||
func (b *EventBus) Publish(ctx context.Context, eventValue string, eventData types.EventData) error {
|
||||
func (b *EventBus) Publish(eventValue string, eventData types.EventData) error {
|
||||
tokens := strings.Split(types.EventTypeKey, ".")
|
||||
event := abci.Event{
|
||||
Type: tokens[0],
|
||||
@@ -78,19 +78,19 @@ func (b *EventBus) Publish(ctx context.Context, eventValue string, eventData typ
|
||||
},
|
||||
}
|
||||
|
||||
return b.pubsub.PublishWithEvents(ctx, eventData, []abci.Event{event})
|
||||
return b.pubsub.PublishWithEvents(eventData, []abci.Event{event})
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventNewBlock(ctx context.Context, data types.EventDataNewBlock) error {
|
||||
func (b *EventBus) PublishEventNewBlock(data types.EventDataNewBlock) error {
|
||||
events := data.ResultFinalizeBlock.Events
|
||||
|
||||
// add Tendermint-reserved new block event
|
||||
events = append(events, types.EventNewBlock)
|
||||
|
||||
return b.pubsub.PublishWithEvents(ctx, data, events)
|
||||
return b.pubsub.PublishWithEvents(data, events)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventNewBlockHeader(ctx context.Context, data types.EventDataNewBlockHeader) error {
|
||||
func (b *EventBus) PublishEventNewBlockHeader(data types.EventDataNewBlockHeader) error {
|
||||
// no explicit deadline for publishing events
|
||||
|
||||
events := data.ResultFinalizeBlock.Events
|
||||
@@ -98,33 +98,33 @@ func (b *EventBus) PublishEventNewBlockHeader(ctx context.Context, data types.Ev
|
||||
// add Tendermint-reserved new block header event
|
||||
events = append(events, types.EventNewBlockHeader)
|
||||
|
||||
return b.pubsub.PublishWithEvents(ctx, data, events)
|
||||
return b.pubsub.PublishWithEvents(data, events)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventNewEvidence(ctx context.Context, evidence types.EventDataNewEvidence) error {
|
||||
return b.Publish(ctx, types.EventNewEvidenceValue, evidence)
|
||||
func (b *EventBus) PublishEventNewEvidence(evidence types.EventDataNewEvidence) error {
|
||||
return b.Publish(types.EventNewEvidenceValue, evidence)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventVote(ctx context.Context, data types.EventDataVote) error {
|
||||
return b.Publish(ctx, types.EventVoteValue, data)
|
||||
func (b *EventBus) PublishEventVote(data types.EventDataVote) error {
|
||||
return b.Publish(types.EventVoteValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventValidBlock(ctx context.Context, data types.EventDataRoundState) error {
|
||||
return b.Publish(ctx, types.EventValidBlockValue, data)
|
||||
func (b *EventBus) PublishEventValidBlock(data types.EventDataRoundState) error {
|
||||
return b.Publish(types.EventValidBlockValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventBlockSyncStatus(ctx context.Context, data types.EventDataBlockSyncStatus) error {
|
||||
return b.Publish(ctx, types.EventBlockSyncStatusValue, data)
|
||||
func (b *EventBus) PublishEventBlockSyncStatus(data types.EventDataBlockSyncStatus) error {
|
||||
return b.Publish(types.EventBlockSyncStatusValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventStateSyncStatus(ctx context.Context, data types.EventDataStateSyncStatus) error {
|
||||
return b.Publish(ctx, types.EventStateSyncStatusValue, data)
|
||||
func (b *EventBus) PublishEventStateSyncStatus(data types.EventDataStateSyncStatus) error {
|
||||
return b.Publish(types.EventStateSyncStatusValue, data)
|
||||
}
|
||||
|
||||
// PublishEventTx publishes tx event with events from Result. Note it will add
|
||||
// predefined keys (EventTypeKey, TxHashKey). Existing events with the same keys
|
||||
// will be overwritten.
|
||||
func (b *EventBus) PublishEventTx(ctx context.Context, data types.EventDataTx) error {
|
||||
func (b *EventBus) PublishEventTx(data types.EventDataTx) error {
|
||||
events := data.Result.Events
|
||||
|
||||
// add Tendermint-reserved events
|
||||
@@ -152,45 +152,45 @@ func (b *EventBus) PublishEventTx(ctx context.Context, data types.EventDataTx) e
|
||||
},
|
||||
})
|
||||
|
||||
return b.pubsub.PublishWithEvents(ctx, data, events)
|
||||
return b.pubsub.PublishWithEvents(data, events)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventNewRoundStep(ctx context.Context, data types.EventDataRoundState) error {
|
||||
return b.Publish(ctx, types.EventNewRoundStepValue, data)
|
||||
func (b *EventBus) PublishEventNewRoundStep(data types.EventDataRoundState) error {
|
||||
return b.Publish(types.EventNewRoundStepValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventTimeoutPropose(ctx context.Context, data types.EventDataRoundState) error {
|
||||
return b.Publish(ctx, types.EventTimeoutProposeValue, data)
|
||||
func (b *EventBus) PublishEventTimeoutPropose(data types.EventDataRoundState) error {
|
||||
return b.Publish(types.EventTimeoutProposeValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventTimeoutWait(ctx context.Context, data types.EventDataRoundState) error {
|
||||
return b.Publish(ctx, types.EventTimeoutWaitValue, data)
|
||||
func (b *EventBus) PublishEventTimeoutWait(data types.EventDataRoundState) error {
|
||||
return b.Publish(types.EventTimeoutWaitValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventNewRound(ctx context.Context, data types.EventDataNewRound) error {
|
||||
return b.Publish(ctx, types.EventNewRoundValue, data)
|
||||
func (b *EventBus) PublishEventNewRound(data types.EventDataNewRound) error {
|
||||
return b.Publish(types.EventNewRoundValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventCompleteProposal(ctx context.Context, data types.EventDataCompleteProposal) error {
|
||||
return b.Publish(ctx, types.EventCompleteProposalValue, data)
|
||||
func (b *EventBus) PublishEventCompleteProposal(data types.EventDataCompleteProposal) error {
|
||||
return b.Publish(types.EventCompleteProposalValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventPolka(ctx context.Context, data types.EventDataRoundState) error {
|
||||
return b.Publish(ctx, types.EventPolkaValue, data)
|
||||
func (b *EventBus) PublishEventPolka(data types.EventDataRoundState) error {
|
||||
return b.Publish(types.EventPolkaValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventRelock(ctx context.Context, data types.EventDataRoundState) error {
|
||||
return b.Publish(ctx, types.EventRelockValue, data)
|
||||
func (b *EventBus) PublishEventRelock(data types.EventDataRoundState) error {
|
||||
return b.Publish(types.EventRelockValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventLock(ctx context.Context, data types.EventDataRoundState) error {
|
||||
return b.Publish(ctx, types.EventLockValue, data)
|
||||
func (b *EventBus) PublishEventLock(data types.EventDataRoundState) error {
|
||||
return b.Publish(types.EventLockValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventValidatorSetUpdates(ctx context.Context, data types.EventDataValidatorSetUpdates) error {
|
||||
return b.Publish(ctx, types.EventValidatorSetUpdatesValue, data)
|
||||
func (b *EventBus) PublishEventValidatorSetUpdates(data types.EventDataValidatorSetUpdates) error {
|
||||
return b.Publish(types.EventValidatorSetUpdatesValue, data)
|
||||
}
|
||||
|
||||
func (b *EventBus) PublishEventEvidenceValidated(ctx context.Context, evidence types.EventDataEvidenceValidated) error {
|
||||
return b.Publish(ctx, types.EventEvidenceValidatedValue, evidence)
|
||||
func (b *EventBus) PublishEventEvidenceValidated(evidence types.EventDataEvidenceValidated) error {
|
||||
return b.Publish(types.EventEvidenceValidatedValue, evidence)
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@ func TestEventBusPublishEventTx(t *testing.T) {
|
||||
assert.Equal(t, result, edt.Result)
|
||||
}()
|
||||
|
||||
err = eventBus.PublishEventTx(ctx, types.EventDataTx{
|
||||
err = eventBus.PublishEventTx(types.EventDataTx{
|
||||
TxResult: abci.TxResult{
|
||||
Height: 1,
|
||||
Index: 0,
|
||||
@@ -112,7 +112,7 @@ func TestEventBusPublishEventNewBlock(t *testing.T) {
|
||||
assert.Equal(t, resultFinalizeBlock, edt.ResultFinalizeBlock)
|
||||
}()
|
||||
|
||||
err = eventBus.PublishEventNewBlock(ctx, types.EventDataNewBlock{
|
||||
err = eventBus.PublishEventNewBlock(types.EventDataNewBlock{
|
||||
Block: block,
|
||||
BlockID: blockID,
|
||||
ResultFinalizeBlock: resultFinalizeBlock,
|
||||
@@ -223,7 +223,7 @@ func TestEventBusPublishEventTxDuplicateKeys(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
|
||||
assert.NoError(t, eventBus.PublishEventTx(ctx, types.EventDataTx{
|
||||
assert.NoError(t, eventBus.PublishEventTx(types.EventDataTx{
|
||||
TxResult: abci.TxResult{
|
||||
Height: 1,
|
||||
Index: 0,
|
||||
@@ -280,7 +280,7 @@ func TestEventBusPublishEventNewBlockHeader(t *testing.T) {
|
||||
assert.Equal(t, resultFinalizeBlock, edt.ResultFinalizeBlock)
|
||||
}()
|
||||
|
||||
err = eventBus.PublishEventNewBlockHeader(ctx, types.EventDataNewBlockHeader{
|
||||
err = eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{
|
||||
Header: block.Header,
|
||||
ResultFinalizeBlock: resultFinalizeBlock,
|
||||
})
|
||||
@@ -322,7 +322,7 @@ func TestEventBusPublishEventEvidenceValidated(t *testing.T) {
|
||||
assert.Equal(t, int64(1), edt.Height)
|
||||
}()
|
||||
|
||||
err = eventBus.PublishEventEvidenceValidated(ctx, types.EventDataEvidenceValidated{
|
||||
err = eventBus.PublishEventEvidenceValidated(types.EventDataEvidenceValidated{
|
||||
Evidence: ev,
|
||||
Height: int64(1),
|
||||
})
|
||||
@@ -364,7 +364,7 @@ func TestEventBusPublishEventNewEvidence(t *testing.T) {
|
||||
assert.Equal(t, int64(4), edt.Height)
|
||||
}()
|
||||
|
||||
err = eventBus.PublishEventNewEvidence(ctx, types.EventDataNewEvidence{
|
||||
err = eventBus.PublishEventNewEvidence(types.EventDataNewEvidence{
|
||||
Evidence: ev,
|
||||
Height: 4,
|
||||
})
|
||||
@@ -408,22 +408,22 @@ func TestEventBusPublish(t *testing.T) {
|
||||
}
|
||||
}()
|
||||
|
||||
require.NoError(t, eventBus.Publish(ctx, types.EventNewBlockHeaderValue,
|
||||
require.NoError(t, eventBus.Publish(types.EventNewBlockHeaderValue,
|
||||
types.EventDataNewBlockHeader{}))
|
||||
require.NoError(t, eventBus.PublishEventNewBlock(ctx, types.EventDataNewBlock{}))
|
||||
require.NoError(t, eventBus.PublishEventNewBlockHeader(ctx, types.EventDataNewBlockHeader{}))
|
||||
require.NoError(t, eventBus.PublishEventVote(ctx, types.EventDataVote{}))
|
||||
require.NoError(t, eventBus.PublishEventNewRoundStep(ctx, types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventTimeoutPropose(ctx, types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventTimeoutWait(ctx, types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventNewRound(ctx, types.EventDataNewRound{}))
|
||||
require.NoError(t, eventBus.PublishEventCompleteProposal(ctx, types.EventDataCompleteProposal{}))
|
||||
require.NoError(t, eventBus.PublishEventPolka(ctx, types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventRelock(ctx, types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventLock(ctx, types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventValidatorSetUpdates(ctx, types.EventDataValidatorSetUpdates{}))
|
||||
require.NoError(t, eventBus.PublishEventBlockSyncStatus(ctx, types.EventDataBlockSyncStatus{}))
|
||||
require.NoError(t, eventBus.PublishEventStateSyncStatus(ctx, types.EventDataStateSyncStatus{}))
|
||||
require.NoError(t, eventBus.PublishEventNewBlock(types.EventDataNewBlock{}))
|
||||
require.NoError(t, eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{}))
|
||||
require.NoError(t, eventBus.PublishEventVote(types.EventDataVote{}))
|
||||
require.NoError(t, eventBus.PublishEventNewRoundStep(types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventTimeoutPropose(types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventTimeoutWait(types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventNewRound(types.EventDataNewRound{}))
|
||||
require.NoError(t, eventBus.PublishEventCompleteProposal(types.EventDataCompleteProposal{}))
|
||||
require.NoError(t, eventBus.PublishEventPolka(types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventRelock(types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventLock(types.EventDataRoundState{}))
|
||||
require.NoError(t, eventBus.PublishEventValidatorSetUpdates(types.EventDataValidatorSetUpdates{}))
|
||||
require.NoError(t, eventBus.PublishEventBlockSyncStatus(types.EventDataBlockSyncStatus{}))
|
||||
require.NoError(t, eventBus.PublishEventStateSyncStatus(types.EventDataStateSyncStatus{}))
|
||||
|
||||
require.GreaterOrEqual(t, <-count, numEventsExpected)
|
||||
}
|
||||
@@ -505,7 +505,7 @@ func benchmarkEventBus(numClients int, randQueries bool, randEvents bool, b *tes
|
||||
eventValue = randEventValue()
|
||||
}
|
||||
|
||||
err := eventBus.Publish(ctx, eventValue, types.EventDataString("Gamora"))
|
||||
err := eventBus.Publish(eventValue, types.EventDataString("Gamora"))
|
||||
if err != nil {
|
||||
b.Error(err)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
testing "testing"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
types "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -57,3 +60,13 @@ func (_m *BlockStore) LoadBlockMeta(height int64) *types.BlockMeta {
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewBlockStore creates a new instance of BlockStore. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewBlockStore(t testing.TB) *BlockStore {
|
||||
mock := &BlockStore{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -338,7 +338,7 @@ func (evpool *Pool) addPendingEvidence(ctx context.Context, ev types.Evidence) e
|
||||
return nil
|
||||
|
||||
}
|
||||
return evpool.eventBus.PublishEventEvidenceValidated(ctx, types.EventDataEvidenceValidated{
|
||||
return evpool.eventBus.PublishEventEvidenceValidated(types.EventDataEvidenceValidated{
|
||||
Evidence: ev,
|
||||
Height: ev.Height(),
|
||||
})
|
||||
|
||||
@@ -46,7 +46,7 @@ type reactorTestSuite struct {
|
||||
numStateStores int
|
||||
}
|
||||
|
||||
func setup(ctx context.Context, t *testing.T, stateStores []sm.Store, chBuf uint) *reactorTestSuite {
|
||||
func setup(ctx context.Context, t *testing.T, stateStores []sm.Store) *reactorTestSuite {
|
||||
t.Helper()
|
||||
|
||||
pID := make([]byte, 16)
|
||||
@@ -245,7 +245,7 @@ func TestReactorMultiDisconnect(t *testing.T) {
|
||||
stateDB1 := initializeValidatorState(ctx, t, val, height)
|
||||
stateDB2 := initializeValidatorState(ctx, t, val, height)
|
||||
|
||||
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2}, 20)
|
||||
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2})
|
||||
primary := rts.nodes[0]
|
||||
secondary := rts.nodes[1]
|
||||
|
||||
@@ -290,7 +290,7 @@ func TestReactorBroadcastEvidence(t *testing.T) {
|
||||
stateDBs[i] = initializeValidatorState(ctx, t, val, height)
|
||||
}
|
||||
|
||||
rts := setup(ctx, t, stateDBs, 0)
|
||||
rts := setup(ctx, t, stateDBs)
|
||||
|
||||
rts.start(ctx, t)
|
||||
|
||||
@@ -348,7 +348,7 @@ func TestReactorBroadcastEvidence_Lagging(t *testing.T) {
|
||||
stateDB1 := initializeValidatorState(ctx, t, val, height1)
|
||||
stateDB2 := initializeValidatorState(ctx, t, val, height2)
|
||||
|
||||
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2}, 100)
|
||||
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2})
|
||||
rts.start(ctx, t)
|
||||
|
||||
primary := rts.nodes[0]
|
||||
@@ -382,7 +382,7 @@ func TestReactorBroadcastEvidence_Pending(t *testing.T) {
|
||||
stateDB1 := initializeValidatorState(ctx, t, val, height)
|
||||
stateDB2 := initializeValidatorState(ctx, t, val, height)
|
||||
|
||||
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2}, 100)
|
||||
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2})
|
||||
primary := rts.nodes[0]
|
||||
secondary := rts.nodes[1]
|
||||
|
||||
@@ -423,7 +423,7 @@ func TestReactorBroadcastEvidence_Committed(t *testing.T) {
|
||||
stateDB1 := initializeValidatorState(ctx, t, val, height)
|
||||
stateDB2 := initializeValidatorState(ctx, t, val, height)
|
||||
|
||||
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2}, 0)
|
||||
rts := setup(ctx, t, []sm.Store{stateDB1, stateDB2})
|
||||
|
||||
primary := rts.nodes[0]
|
||||
secondary := rts.nodes[1]
|
||||
@@ -482,7 +482,7 @@ func TestReactorBroadcastEvidence_FullyConnected(t *testing.T) {
|
||||
stateDBs[i] = initializeValidatorState(ctx, t, val, height)
|
||||
}
|
||||
|
||||
rts := setup(ctx, t, stateDBs, 0)
|
||||
rts := setup(ctx, t, stateDBs)
|
||||
rts.start(ctx, t)
|
||||
|
||||
evList := createEvidenceList(ctx, t, rts.pools[rts.network.RandomNode().NodeID], val, numEvidence)
|
||||
|
||||
@@ -260,7 +260,7 @@ func (txmp *TxMempool) CheckTx(
|
||||
return types.ErrTxInCache
|
||||
}
|
||||
|
||||
res, err := txmp.proxyAppConn.CheckTx(ctx, abci.RequestCheckTx{Tx: tx})
|
||||
res, err := txmp.proxyAppConn.CheckTx(ctx, &abci.RequestCheckTx{Tx: tx})
|
||||
if err != nil {
|
||||
txmp.cache.Remove(tx)
|
||||
return err
|
||||
@@ -700,7 +700,7 @@ func (txmp *TxMempool) updateReCheckTxs(ctx context.Context) {
|
||||
// Only execute CheckTx if the transaction is not marked as removed which
|
||||
// could happen if the transaction was evicted.
|
||||
if !txmp.txStore.IsTxRemoved(wtx.hash) {
|
||||
res, err := txmp.proxyAppConn.CheckTx(ctx, abci.RequestCheckTx{
|
||||
res, err := txmp.proxyAppConn.CheckTx(ctx, &abci.RequestCheckTx{
|
||||
Tx: wtx.tx,
|
||||
Type: abci.CheckTxType_Recheck,
|
||||
})
|
||||
|
||||
@@ -25,7 +25,7 @@ func BenchmarkTxMempool_CheckTx(b *testing.B) {
|
||||
|
||||
// setup the cache and the mempool number for hitting GetEvictableTxs during the
|
||||
// benchmark. 5000 is the current default mempool size in the TM config.
|
||||
txmp := setup(ctx, b, client, 10000)
|
||||
txmp := setup(b, client, 10000)
|
||||
txmp.config.Size = 5000
|
||||
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
@@ -36,7 +36,7 @@ type testTx struct {
|
||||
priority int64
|
||||
}
|
||||
|
||||
func (app *application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
||||
func (app *application) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) {
|
||||
var (
|
||||
priority int64
|
||||
sender string
|
||||
@@ -47,32 +47,32 @@ func (app *application) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
||||
if len(parts) == 3 {
|
||||
v, err := strconv.ParseInt(string(parts[2]), 10, 64)
|
||||
if err != nil {
|
||||
return abci.ResponseCheckTx{
|
||||
return &abci.ResponseCheckTx{
|
||||
Priority: priority,
|
||||
Code: 100,
|
||||
GasWanted: 1,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
priority = v
|
||||
sender = string(parts[0])
|
||||
} else {
|
||||
return abci.ResponseCheckTx{
|
||||
return &abci.ResponseCheckTx{
|
||||
Priority: priority,
|
||||
Code: 101,
|
||||
GasWanted: 1,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
return abci.ResponseCheckTx{
|
||||
return &abci.ResponseCheckTx{
|
||||
Priority: priority,
|
||||
Sender: sender,
|
||||
Code: code.CodeTypeOK,
|
||||
GasWanted: 1,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func setup(ctx context.Context, t testing.TB, app abciclient.Client, cacheSize int, options ...TxMempoolOption) *TxMempool {
|
||||
func setup(t testing.TB, app abciclient.Client, cacheSize int, options ...TxMempoolOption) *TxMempool {
|
||||
t.Helper()
|
||||
|
||||
logger := log.NewNopLogger()
|
||||
@@ -131,7 +131,7 @@ func TestTxMempool_TxsAvailable(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
txmp := setup(ctx, t, client, 0)
|
||||
txmp := setup(t, client, 0)
|
||||
txmp.EnableTxsAvailable()
|
||||
|
||||
ensureNoTxFire := func() {
|
||||
@@ -194,7 +194,7 @@ func TestTxMempool_Size(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
txmp := setup(ctx, t, client, 0)
|
||||
txmp := setup(t, client, 0)
|
||||
txs := checkTxs(ctx, t, txmp, 100, 0)
|
||||
require.Equal(t, len(txs), txmp.Size())
|
||||
require.Equal(t, int64(5690), txmp.SizeBytes())
|
||||
@@ -227,7 +227,7 @@ func TestTxMempool_Flush(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
txmp := setup(ctx, t, client, 0)
|
||||
txmp := setup(t, client, 0)
|
||||
txs := checkTxs(ctx, t, txmp, 100, 0)
|
||||
require.Equal(t, len(txs), txmp.Size())
|
||||
require.Equal(t, int64(5690), txmp.SizeBytes())
|
||||
@@ -261,7 +261,7 @@ func TestTxMempool_ReapMaxBytesMaxGas(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
txmp := setup(ctx, t, client, 0)
|
||||
txmp := setup(t, client, 0)
|
||||
tTxs := checkTxs(ctx, t, txmp, 100, 0) // all txs request 1 gas unit
|
||||
require.Equal(t, len(tTxs), txmp.Size())
|
||||
require.Equal(t, int64(5690), txmp.SizeBytes())
|
||||
@@ -320,7 +320,7 @@ func TestTxMempool_ReapMaxTxs(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
txmp := setup(ctx, t, client, 0)
|
||||
txmp := setup(t, client, 0)
|
||||
tTxs := checkTxs(ctx, t, txmp, 100, 0)
|
||||
require.Equal(t, len(tTxs), txmp.Size())
|
||||
require.Equal(t, int64(5690), txmp.SizeBytes())
|
||||
@@ -377,7 +377,7 @@ func TestTxMempool_CheckTxExceedsMaxSize(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
txmp := setup(ctx, t, client, 0)
|
||||
txmp := setup(t, client, 0)
|
||||
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
tx := make([]byte, txmp.config.MaxTxBytes+1)
|
||||
@@ -403,7 +403,7 @@ func TestTxMempool_CheckTxSamePeer(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
txmp := setup(ctx, t, client, 100)
|
||||
txmp := setup(t, client, 100)
|
||||
peerID := uint16(1)
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
@@ -427,7 +427,7 @@ func TestTxMempool_CheckTxSameSender(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
txmp := setup(ctx, t, client, 100)
|
||||
txmp := setup(t, client, 100)
|
||||
peerID := uint16(1)
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
@@ -458,7 +458,7 @@ func TestTxMempool_ConcurrentTxs(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
txmp := setup(ctx, t, client, 100)
|
||||
txmp := setup(t, client, 100)
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
checkTxDone := make(chan struct{})
|
||||
|
||||
@@ -531,7 +531,7 @@ func TestTxMempool_ExpiredTxs_NumBlocks(t *testing.T) {
|
||||
}
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
txmp := setup(ctx, t, client, 500)
|
||||
txmp := setup(t, client, 500)
|
||||
txmp.height = 100
|
||||
txmp.config.TTLNumBlocks = 10
|
||||
|
||||
@@ -612,7 +612,7 @@ func TestTxMempool_CheckTxPostCheckError(t *testing.T) {
|
||||
postCheckFn := func(_ types.Tx, _ *abci.ResponseCheckTx) error {
|
||||
return testCase.err
|
||||
}
|
||||
txmp := setup(ctx, t, client, 0, WithPostCheck(postCheckFn))
|
||||
txmp := setup(t, client, 0, WithPostCheck(postCheckFn))
|
||||
rng := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
tx := make([]byte, txmp.config.MaxTxBytes-1)
|
||||
_, err := rng.Read(tx)
|
||||
|
||||
@@ -11,6 +11,8 @@ import (
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
testing "testing"
|
||||
|
||||
types "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -170,3 +172,13 @@ func (_m *Mempool) Update(ctx context.Context, blockHeight int64, blockTxs types
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewMempool creates a new instance of Mempool. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewMempool(t testing.TB) *Mempool {
|
||||
mock := &Mempool{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ func setupReactors(ctx context.Context, t *testing.T, logger log.Logger, numNode
|
||||
require.NoError(t, client.Start(ctx))
|
||||
t.Cleanup(client.Wait)
|
||||
|
||||
mempool := setup(ctx, t, client, 0)
|
||||
mempool := setup(t, client, 0)
|
||||
rts.mempools[nodeID] = mempool
|
||||
|
||||
rts.peerChans[nodeID] = make(chan p2p.PeerUpdate, chBuf)
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
//go:build go1.10
|
||||
// +build go1.10
|
||||
|
||||
package conn
|
||||
|
||||
// Go1.10 has a proper net.Conn implementation that
|
||||
// has the SetDeadline method implemented as per
|
||||
// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706
|
||||
// lest we run into problems like
|
||||
// https://github.com/tendermint/tendermint/issues/851
|
||||
|
||||
import "net"
|
||||
|
||||
func NetPipe() (net.Conn, net.Conn) {
|
||||
return net.Pipe()
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
//go:build !go1.10
|
||||
// +build !go1.10
|
||||
|
||||
package conn
|
||||
|
||||
import (
|
||||
"net"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Only Go1.10 has a proper net.Conn implementation that
|
||||
// has the SetDeadline method implemented as per
|
||||
// https://github.com/golang/go/commit/e2dd8ca946be884bb877e074a21727f1a685a706
|
||||
// lest we run into problems like
|
||||
// https://github.com/tendermint/tendermint/issues/851
|
||||
// so for go versions < Go1.10 use our custom net.Conn creator
|
||||
// that doesn't return an `Unimplemented error` for net.Conn.
|
||||
// Before https://github.com/tendermint/tendermint/commit/49faa79bdce5663894b3febbf4955fb1d172df04
|
||||
// we hadn't cared about errors from SetDeadline so swallow them up anyways.
|
||||
type pipe struct {
|
||||
net.Conn
|
||||
}
|
||||
|
||||
func (p *pipe) SetDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NetPipe() (net.Conn, net.Conn) {
|
||||
p1, p2 := net.Pipe()
|
||||
return &pipe{p1}, &pipe{p2}
|
||||
}
|
||||
|
||||
var _ net.Conn = (*pipe)(nil)
|
||||
@@ -48,7 +48,7 @@ func createMConnectionWithCallbacks(
|
||||
}
|
||||
|
||||
func TestMConnectionSendFlushStop(t *testing.T) {
|
||||
server, client := NetPipe()
|
||||
server, client := net.Pipe()
|
||||
t.Cleanup(closeAll(t, client, server))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@@ -85,7 +85,7 @@ func TestMConnectionSendFlushStop(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMConnectionSend(t *testing.T) {
|
||||
server, client := NetPipe()
|
||||
server, client := net.Pipe()
|
||||
t.Cleanup(closeAll(t, client, server))
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
@@ -116,7 +116,7 @@ func TestMConnectionSend(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMConnectionReceive(t *testing.T) {
|
||||
server, client := NetPipe()
|
||||
server, client := net.Pipe()
|
||||
t.Cleanup(closeAll(t, client, server))
|
||||
|
||||
receivedCh := make(chan []byte)
|
||||
@@ -378,7 +378,7 @@ func TestMConnectionPingPongs(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMConnectionStopsAndReturnsError(t *testing.T) {
|
||||
server, client := NetPipe()
|
||||
server, client := net.Pipe()
|
||||
t.Cleanup(closeAll(t, client, server))
|
||||
|
||||
receivedCh := make(chan []byte)
|
||||
@@ -423,7 +423,7 @@ func newClientAndServerConnsForReadErrors(
|
||||
t *testing.T,
|
||||
chOnErr chan struct{},
|
||||
) (*MConnection, *MConnection) {
|
||||
server, client := NetPipe()
|
||||
server, client := net.Pipe()
|
||||
|
||||
onReceive := func(context.Context, ChannelID, []byte) {}
|
||||
onError := func(context.Context, interface{}) {}
|
||||
@@ -558,7 +558,7 @@ func TestMConnectionReadErrorUnknownMsgType(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMConnectionTrySend(t *testing.T) {
|
||||
server, client := NetPipe()
|
||||
server, client := net.Pipe()
|
||||
t.Cleanup(closeAll(t, client, server))
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
@@ -228,7 +228,7 @@ func TestDeriveSecretsAndChallengeGolden(t *testing.T) {
|
||||
goldenFilepath := filepath.Join("testdata", t.Name()+".golden")
|
||||
if *update {
|
||||
t.Logf("Updating golden test vector file %s", goldenFilepath)
|
||||
data := createGoldenTestVectors(t)
|
||||
data := createGoldenTestVectors()
|
||||
require.NoError(t, os.WriteFile(goldenFilepath, []byte(data), 0644))
|
||||
}
|
||||
f, err := os.Open(goldenFilepath)
|
||||
@@ -306,7 +306,7 @@ func readLots(t *testing.T, wg *sync.WaitGroup, conn io.Reader, n int) {
|
||||
// Creates the data for a test vector file.
|
||||
// The file format is:
|
||||
// Hex(diffie_hellman_secret), loc_is_least, Hex(recvSecret), Hex(sendSecret), Hex(challenge)
|
||||
func createGoldenTestVectors(t *testing.T) string {
|
||||
func createGoldenTestVectors() string {
|
||||
data := ""
|
||||
for i := 0; i < 32; i++ {
|
||||
randSecretVector := tmrand.Bytes(32)
|
||||
|
||||
@@ -26,6 +26,7 @@ func newConnTracker(max uint, window time.Duration) connectionTracker {
|
||||
cache: make(map[string]uint),
|
||||
lastConnect: make(map[string]time.Time),
|
||||
max: max,
|
||||
window: window,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +44,7 @@ func (rat *connTrackerImpl) AddConn(addr net.IP) error {
|
||||
if num := rat.cache[address]; num >= rat.max {
|
||||
return fmt.Errorf("%q has %d connections [max=%d]", address, num, rat.max)
|
||||
} else if num == 0 {
|
||||
// if there is already at least connection, check to
|
||||
// if there is already at least one connection, check to
|
||||
// see if it was established before within the window,
|
||||
// and error if so.
|
||||
if last := rat.lastConnect[address]; time.Since(last) < rat.window {
|
||||
|
||||
@@ -70,4 +70,15 @@ func TestConnTracker(t *testing.T) {
|
||||
}
|
||||
require.Equal(t, 10, ct.Len())
|
||||
})
|
||||
t.Run("Window", func(t *testing.T) {
|
||||
const window = 100 * time.Millisecond
|
||||
ct := newConnTracker(10, window)
|
||||
ip := randLocalIPv4()
|
||||
require.NoError(t, ct.AddConn(ip))
|
||||
ct.RemoveConn(ip)
|
||||
require.Error(t, ct.AddConn(ip))
|
||||
time.Sleep(window)
|
||||
require.NoError(t, ct.AddConn(ip))
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import (
|
||||
|
||||
p2p "github.com/tendermint/tendermint/internal/p2p"
|
||||
|
||||
testing "testing"
|
||||
|
||||
types "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -150,3 +152,13 @@ func (_m *Connection) String() string {
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewConnection creates a new instance of Connection. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewConnection(t testing.TB) *Connection {
|
||||
mock := &Connection{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
p2p "github.com/tendermint/tendermint/internal/p2p"
|
||||
|
||||
testing "testing"
|
||||
)
|
||||
|
||||
// Transport is an autogenerated mock type for the Transport type
|
||||
@@ -141,3 +143,13 @@ func (_m *Transport) String() string {
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewTransport creates a new instance of Transport. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewTransport(t testing.TB) *Transport {
|
||||
mock := &Transport{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -151,14 +151,14 @@ func TestReactorErrorsOnReceivingTooManyPeers(t *testing.T) {
|
||||
defer cancel()
|
||||
|
||||
r := setupSingle(ctx, t)
|
||||
peer := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID(t)}
|
||||
peer := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID()}
|
||||
added, err := r.manager.Add(peer)
|
||||
require.NoError(t, err)
|
||||
require.True(t, added)
|
||||
|
||||
addresses := make([]p2pproto.PexAddress, 101)
|
||||
for i := 0; i < len(addresses); i++ {
|
||||
nodeAddress := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID(t)}
|
||||
nodeAddress := p2p.NodeAddress{Protocol: p2p.MemoryProtocol, NodeID: randomNodeID()}
|
||||
addresses[i] = p2pproto.PexAddress{
|
||||
URL: nodeAddress.String(),
|
||||
}
|
||||
@@ -730,6 +730,6 @@ func newNodeID(t *testing.T, id string) types.NodeID {
|
||||
return nodeID
|
||||
}
|
||||
|
||||
func randomNodeID(t *testing.T) types.NodeID {
|
||||
func randomNodeID() types.NodeID {
|
||||
return types.NodeIDFromPubKey(ed25519.GenPrivKey().PubKey())
|
||||
}
|
||||
|
||||
+14
-14
@@ -124,32 +124,32 @@ func kill() error {
|
||||
return p.Signal(syscall.SIGABRT)
|
||||
}
|
||||
|
||||
func (app *proxyClient) InitChain(ctx context.Context, req types.RequestInitChain) (*types.ResponseInitChain, error) {
|
||||
func (app *proxyClient) InitChain(ctx context.Context, req *types.RequestInitChain) (*types.ResponseInitChain, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "init_chain", "type", "sync"))()
|
||||
return app.client.InitChain(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) PrepareProposal(ctx context.Context, req types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) {
|
||||
func (app *proxyClient) PrepareProposal(ctx context.Context, req *types.RequestPrepareProposal) (*types.ResponsePrepareProposal, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "prepare_proposal", "type", "sync"))()
|
||||
return app.client.PrepareProposal(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) ProcessProposal(ctx context.Context, req types.RequestProcessProposal) (*types.ResponseProcessProposal, error) {
|
||||
func (app *proxyClient) ProcessProposal(ctx context.Context, req *types.RequestProcessProposal) (*types.ResponseProcessProposal, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "process_proposal", "type", "sync"))()
|
||||
return app.client.ProcessProposal(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) ExtendVote(ctx context.Context, req types.RequestExtendVote) (*types.ResponseExtendVote, error) {
|
||||
func (app *proxyClient) ExtendVote(ctx context.Context, req *types.RequestExtendVote) (*types.ResponseExtendVote, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "extend_vote", "type", "sync"))()
|
||||
return app.client.ExtendVote(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) VerifyVoteExtension(ctx context.Context, req types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) {
|
||||
func (app *proxyClient) VerifyVoteExtension(ctx context.Context, req *types.RequestVerifyVoteExtension) (*types.ResponseVerifyVoteExtension, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "verify_vote_extension", "type", "sync"))()
|
||||
return app.client.VerifyVoteExtension(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) FinalizeBlock(ctx context.Context, req types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) {
|
||||
func (app *proxyClient) FinalizeBlock(ctx context.Context, req *types.RequestFinalizeBlock) (*types.ResponseFinalizeBlock, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "finalize_block", "type", "sync"))()
|
||||
return app.client.FinalizeBlock(ctx, req)
|
||||
}
|
||||
@@ -164,7 +164,7 @@ func (app *proxyClient) Flush(ctx context.Context) error {
|
||||
return app.client.Flush(ctx)
|
||||
}
|
||||
|
||||
func (app *proxyClient) CheckTx(ctx context.Context, req types.RequestCheckTx) (*types.ResponseCheckTx, error) {
|
||||
func (app *proxyClient) CheckTx(ctx context.Context, req *types.RequestCheckTx) (*types.ResponseCheckTx, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "check_tx", "type", "sync"))()
|
||||
return app.client.CheckTx(ctx, req)
|
||||
}
|
||||
@@ -174,32 +174,32 @@ func (app *proxyClient) Echo(ctx context.Context, msg string) (*types.ResponseEc
|
||||
return app.client.Echo(ctx, msg)
|
||||
}
|
||||
|
||||
func (app *proxyClient) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) {
|
||||
func (app *proxyClient) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "info", "type", "sync"))()
|
||||
return app.client.Info(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) Query(ctx context.Context, reqQuery types.RequestQuery) (*types.ResponseQuery, error) {
|
||||
func (app *proxyClient) Query(ctx context.Context, req *types.RequestQuery) (*types.ResponseQuery, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "query", "type", "sync"))()
|
||||
return app.client.Query(ctx, reqQuery)
|
||||
return app.client.Query(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) ListSnapshots(ctx context.Context, req types.RequestListSnapshots) (*types.ResponseListSnapshots, error) {
|
||||
func (app *proxyClient) ListSnapshots(ctx context.Context, req *types.RequestListSnapshots) (*types.ResponseListSnapshots, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "list_snapshots", "type", "sync"))()
|
||||
return app.client.ListSnapshots(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) OfferSnapshot(ctx context.Context, req types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) {
|
||||
func (app *proxyClient) OfferSnapshot(ctx context.Context, req *types.RequestOfferSnapshot) (*types.ResponseOfferSnapshot, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "offer_snapshot", "type", "sync"))()
|
||||
return app.client.OfferSnapshot(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) LoadSnapshotChunk(ctx context.Context, req types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) {
|
||||
func (app *proxyClient) LoadSnapshotChunk(ctx context.Context, req *types.RequestLoadSnapshotChunk) (*types.ResponseLoadSnapshotChunk, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "load_snapshot_chunk", "type", "sync"))()
|
||||
return app.client.LoadSnapshotChunk(ctx, req)
|
||||
}
|
||||
|
||||
func (app *proxyClient) ApplySnapshotChunk(ctx context.Context, req types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) {
|
||||
func (app *proxyClient) ApplySnapshotChunk(ctx context.Context, req *types.RequestApplySnapshotChunk) (*types.ResponseApplySnapshotChunk, error) {
|
||||
defer addTimeSample(app.metrics.MethodTiming.With("method", "apply_snapshot_chunk", "type", "sync"))()
|
||||
return app.client.ApplySnapshotChunk(ctx, req)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
type appConnTestI interface {
|
||||
Echo(context.Context, string) (*types.ResponseEcho, error)
|
||||
Flush(context.Context) error
|
||||
Info(context.Context, types.RequestInfo) (*types.ResponseInfo, error)
|
||||
Info(context.Context, *types.RequestInfo) (*types.ResponseInfo, error)
|
||||
}
|
||||
|
||||
type appConnTest struct {
|
||||
@@ -49,7 +49,7 @@ func (app *appConnTest) Flush(ctx context.Context) error {
|
||||
return app.appConn.Flush(ctx)
|
||||
}
|
||||
|
||||
func (app *appConnTest) Info(ctx context.Context, req types.RequestInfo) (*types.ResponseInfo, error) {
|
||||
func (app *appConnTest) Info(ctx context.Context, req *types.RequestInfo) (*types.ResponseInfo, error) {
|
||||
return app.appConn.Info(ctx, req)
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ func TestInfo(t *testing.T) {
|
||||
proxy := newAppConnTest(client)
|
||||
t.Log("Connected")
|
||||
|
||||
resInfo, err := proxy.Info(ctx, RequestInfo)
|
||||
resInfo, err := proxy.Info(ctx, &RequestInfo)
|
||||
require.NoError(t, err)
|
||||
|
||||
if resInfo.Data != "{\"size\":0}" {
|
||||
|
||||
@@ -29,6 +29,6 @@ func TestExample(t *testing.T) {
|
||||
Attributes: []abci.EventAttribute{{Key: "name", Value: "John"}},
|
||||
},
|
||||
}
|
||||
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Tombstone"), events))
|
||||
require.NoError(t, s.PublishWithEvents(pubstring("Tombstone"), events))
|
||||
sub.mustReceive(ctx, pubstring("Tombstone"))
|
||||
}
|
||||
|
||||
@@ -287,16 +287,16 @@ func (s *Server) NumClientSubscriptions(clientID string) int {
|
||||
}
|
||||
|
||||
// Publish publishes the given message. An error will be returned to the caller
|
||||
// if the context is canceled.
|
||||
func (s *Server) Publish(ctx context.Context, msg types.EventData) error {
|
||||
return s.publish(ctx, msg, []abci.Event{})
|
||||
// if the pubsub server has shut down.
|
||||
func (s *Server) Publish(msg types.EventData) error {
|
||||
return s.publish(msg, []abci.Event{})
|
||||
}
|
||||
|
||||
// PublishWithEvents publishes the given message with the set of events. The set
|
||||
// is matched with clients queries. If there is a match, the message is sent to
|
||||
// the client.
|
||||
func (s *Server) PublishWithEvents(ctx context.Context, msg types.EventData, events []abci.Event) error {
|
||||
return s.publish(ctx, msg, events)
|
||||
func (s *Server) PublishWithEvents(msg types.EventData, events []abci.Event) error {
|
||||
return s.publish(msg, events)
|
||||
}
|
||||
|
||||
// OnStop implements part of the Service interface. It is a no-op.
|
||||
@@ -309,15 +309,13 @@ func (s *Server) Wait() { <-s.exited; s.BaseService.Wait() }
|
||||
// OnStart implements Service.OnStart by starting the server.
|
||||
func (s *Server) OnStart(ctx context.Context) error { s.run(ctx); return nil }
|
||||
|
||||
func (s *Server) publish(ctx context.Context, data types.EventData, events []abci.Event) error {
|
||||
func (s *Server) publish(data types.EventData, events []abci.Event) error {
|
||||
s.pubs.RLock()
|
||||
defer s.pubs.RUnlock()
|
||||
|
||||
select {
|
||||
case <-s.done:
|
||||
return ErrServerStopped
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case s.queue <- item{
|
||||
Data: data,
|
||||
Events: events,
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestSubscribeWithArgs(t *testing.T) {
|
||||
require.Equal(t, 1, s.NumClients())
|
||||
require.Equal(t, 1, s.NumClientSubscriptions(clientID))
|
||||
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Ka-Zar")))
|
||||
require.NoError(t, s.Publish(pubstring("Ka-Zar")))
|
||||
sub.mustReceive(ctx, pubstring("Ka-Zar"))
|
||||
})
|
||||
t.Run("PositiveLimit", func(t *testing.T) {
|
||||
@@ -51,7 +51,7 @@ func TestSubscribeWithArgs(t *testing.T) {
|
||||
Query: query.All,
|
||||
Limit: 10,
|
||||
}))
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Aggamon")))
|
||||
require.NoError(t, s.Publish(pubstring("Aggamon")))
|
||||
sub.mustReceive(ctx, pubstring("Aggamon"))
|
||||
})
|
||||
}
|
||||
@@ -72,7 +72,7 @@ func TestObserver(t *testing.T) {
|
||||
}))
|
||||
|
||||
const input = pubstring("Lions and tigers and bears, oh my!")
|
||||
require.NoError(t, s.Publish(ctx, input))
|
||||
require.NoError(t, s.Publish(input))
|
||||
<-done
|
||||
require.Equal(t, got, input)
|
||||
}
|
||||
@@ -106,9 +106,9 @@ func TestPublishDoesNotBlock(t *testing.T) {
|
||||
go func() {
|
||||
defer close(published)
|
||||
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Quicksilver")))
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Asylum")))
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Ivan")))
|
||||
require.NoError(t, s.Publish(pubstring("Quicksilver")))
|
||||
require.NoError(t, s.Publish(pubstring("Asylum")))
|
||||
require.NoError(t, s.Publish(pubstring("Ivan")))
|
||||
}()
|
||||
|
||||
select {
|
||||
@@ -149,9 +149,9 @@ func TestSlowSubscriber(t *testing.T) {
|
||||
Query: query.All,
|
||||
}))
|
||||
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Fat Cobra")))
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Viper")))
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Black Panther")))
|
||||
require.NoError(t, s.Publish(pubstring("Fat Cobra")))
|
||||
require.NoError(t, s.Publish(pubstring("Viper")))
|
||||
require.NoError(t, s.Publish(pubstring("Black Panther")))
|
||||
|
||||
// We had capacity for one item, so we should get that item, but after that
|
||||
// the subscription should have been terminated by the publisher.
|
||||
@@ -176,7 +176,7 @@ func TestDifferentClients(t *testing.T) {
|
||||
Attributes: []abci.EventAttribute{{Key: "type", Value: "NewBlock"}},
|
||||
}}
|
||||
|
||||
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Iceman"), events))
|
||||
require.NoError(t, s.PublishWithEvents(pubstring("Iceman"), events))
|
||||
sub1.mustReceive(ctx, pubstring("Iceman"))
|
||||
|
||||
sub2 := newTestSub(t).must(s.SubscribeWithArgs(ctx, pubsub.SubscribeArgs{
|
||||
@@ -195,7 +195,7 @@ func TestDifferentClients(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Ultimo"), events))
|
||||
require.NoError(t, s.PublishWithEvents(pubstring("Ultimo"), events))
|
||||
sub1.mustReceive(ctx, pubstring("Ultimo"))
|
||||
sub2.mustReceive(ctx, pubstring("Ultimo"))
|
||||
|
||||
@@ -210,7 +210,7 @@ func TestDifferentClients(t *testing.T) {
|
||||
Attributes: []abci.EventAttribute{{Key: "type", Value: "NewRoundStep"}},
|
||||
}}
|
||||
|
||||
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Valeria Richards"), events))
|
||||
require.NoError(t, s.PublishWithEvents(pubstring("Valeria Richards"), events))
|
||||
sub3.mustTimeOut(ctx, 100*time.Millisecond)
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ func TestSubscribeDuplicateKeys(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Iceman"), events))
|
||||
require.NoError(t, s.PublishWithEvents(pubstring("Iceman"), events))
|
||||
|
||||
if tc.expected != nil {
|
||||
sub.mustReceive(ctx, tc.expected)
|
||||
@@ -288,7 +288,7 @@ func TestClientSubscribesTwice(t *testing.T) {
|
||||
Query: q,
|
||||
}))
|
||||
|
||||
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Goblin Queen"), events))
|
||||
require.NoError(t, s.PublishWithEvents(pubstring("Goblin Queen"), events))
|
||||
sub1.mustReceive(ctx, pubstring("Goblin Queen"))
|
||||
|
||||
// Subscribing a second time with the same client ID and query fails.
|
||||
@@ -302,7 +302,7 @@ func TestClientSubscribesTwice(t *testing.T) {
|
||||
}
|
||||
|
||||
// The attempt to re-subscribe does not disrupt the existing sub.
|
||||
require.NoError(t, s.PublishWithEvents(ctx, pubstring("Spider-Man"), events))
|
||||
require.NoError(t, s.PublishWithEvents(pubstring("Spider-Man"), events))
|
||||
sub1.mustReceive(ctx, pubstring("Spider-Man"))
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ func TestUnsubscribe(t *testing.T) {
|
||||
}))
|
||||
|
||||
// Publishing should still work.
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Nick Fury")))
|
||||
require.NoError(t, s.Publish(pubstring("Nick Fury")))
|
||||
|
||||
// The unsubscribed subscriber should report as such.
|
||||
sub.mustFail(ctx, pubsub.ErrUnsubscribed)
|
||||
@@ -373,7 +373,7 @@ func TestResubscribe(t *testing.T) {
|
||||
|
||||
sub := newTestSub(t).must(s.SubscribeWithArgs(ctx, args))
|
||||
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Cable")))
|
||||
require.NoError(t, s.Publish(pubstring("Cable")))
|
||||
sub.mustReceive(ctx, pubstring("Cable"))
|
||||
}
|
||||
|
||||
@@ -394,7 +394,7 @@ func TestUnsubscribeAll(t *testing.T) {
|
||||
}))
|
||||
|
||||
require.NoError(t, s.UnsubscribeAll(ctx, clientID))
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Nick Fury")))
|
||||
require.NoError(t, s.Publish(pubstring("Nick Fury")))
|
||||
|
||||
sub1.mustFail(ctx, pubsub.ErrUnsubscribed)
|
||||
sub2.mustFail(ctx, pubsub.ErrUnsubscribed)
|
||||
@@ -410,13 +410,24 @@ func TestBufferCapacity(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Nighthawk")))
|
||||
require.NoError(t, s.Publish(ctx, pubstring("Sage")))
|
||||
require.NoError(t, s.Publish(pubstring("Nighthawk")))
|
||||
require.NoError(t, s.Publish(pubstring("Sage")))
|
||||
|
||||
ctx, cancel = context.WithTimeout(ctx, 100*time.Millisecond)
|
||||
defer cancel()
|
||||
|
||||
require.ErrorIs(t, s.Publish(ctx, pubstring("Ironclad")), context.DeadlineExceeded)
|
||||
sig := make(chan struct{})
|
||||
|
||||
go func() { defer close(sig); _ = s.Publish(pubstring("Ironclad")) }()
|
||||
|
||||
select {
|
||||
case <-sig:
|
||||
t.Fatal("should not fire")
|
||||
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func newTestServer(ctx context.Context, t testing.TB, logger log.Logger) *pubsub.Server {
|
||||
|
||||
@@ -18,7 +18,7 @@ func (env *Environment) ABCIQuery(
|
||||
height int64,
|
||||
prove bool,
|
||||
) (*coretypes.ResultABCIQuery, error) {
|
||||
resQuery, err := env.ProxyApp.Query(ctx, abci.RequestQuery{
|
||||
resQuery, err := env.ProxyApp.Query(ctx, &abci.RequestQuery{
|
||||
Path: path,
|
||||
Data: data,
|
||||
Height: height,
|
||||
@@ -34,7 +34,7 @@ func (env *Environment) ABCIQuery(
|
||||
// ABCIInfo gets some info about the application.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/ABCI/abci_info
|
||||
func (env *Environment) ABCIInfo(ctx context.Context) (*coretypes.ResultABCIInfo, error) {
|
||||
resInfo, err := env.ProxyApp.Info(ctx, proxy.RequestInfo)
|
||||
resInfo, err := env.ProxyApp.Info(ctx, &proxy.RequestInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ func (env *Environment) NumUnconfirmedTxs(ctx context.Context) (*coretypes.Resul
|
||||
// be added to the mempool either.
|
||||
// More: https://docs.tendermint.com/master/rpc/#/Tx/check_tx
|
||||
func (env *Environment) CheckTx(ctx context.Context, tx types.Tx) (*coretypes.ResultCheckTx, error) {
|
||||
res, err := env.ProxyApp.CheckTx(ctx, abci.RequestCheckTx{Tx: tx})
|
||||
res, err := env.ProxyApp.CheckTx(ctx, &abci.RequestCheckTx{Tx: tx})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+55
-34
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
abciclient "github.com/tendermint/tendermint/abci/client"
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
"github.com/tendermint/tendermint/crypto/encoding"
|
||||
"github.com/tendermint/tendermint/crypto/merkle"
|
||||
"github.com/tendermint/tendermint/internal/eventbus"
|
||||
@@ -105,7 +106,7 @@ func (blockExec *BlockExecutor) CreateProposalBlock(
|
||||
localLastCommit := buildLastCommitInfo(block, blockExec.store, state.InitialHeight)
|
||||
rpp, err := blockExec.appClient.PrepareProposal(
|
||||
ctx,
|
||||
abci.RequestPrepareProposal{
|
||||
&abci.RequestPrepareProposal{
|
||||
MaxTxBytes: maxDataBytes,
|
||||
Txs: block.Txs.ToSliceOfBytes(),
|
||||
LocalLastCommit: extendedCommitInfo(localLastCommit, votes),
|
||||
@@ -147,7 +148,7 @@ func (blockExec *BlockExecutor) ProcessProposal(
|
||||
block *types.Block,
|
||||
state State,
|
||||
) (bool, error) {
|
||||
req := abci.RequestProcessProposal{
|
||||
resp, err := blockExec.appClient.ProcessProposal(ctx, &abci.RequestProcessProposal{
|
||||
Hash: block.Header.Hash(),
|
||||
Height: block.Header.Height,
|
||||
Time: block.Header.Time,
|
||||
@@ -156,9 +157,7 @@ func (blockExec *BlockExecutor) ProcessProposal(
|
||||
ByzantineValidators: block.Evidence.ToABCI(),
|
||||
ProposerAddress: block.ProposerAddress,
|
||||
NextValidatorsHash: block.NextValidatorsHash,
|
||||
}
|
||||
|
||||
resp, err := blockExec.appClient.ProcessProposal(ctx, req)
|
||||
})
|
||||
if err != nil {
|
||||
return false, ErrInvalidBlock(err)
|
||||
}
|
||||
@@ -210,7 +209,7 @@ func (blockExec *BlockExecutor) ApplyBlock(
|
||||
startTime := time.Now().UnixNano()
|
||||
finalizeBlockResponse, err := blockExec.appClient.FinalizeBlock(
|
||||
ctx,
|
||||
abci.RequestFinalizeBlock{
|
||||
&abci.RequestFinalizeBlock{
|
||||
Hash: block.Hash(),
|
||||
Height: block.Header.Height,
|
||||
Time: block.Header.Time,
|
||||
@@ -291,34 +290,34 @@ func (blockExec *BlockExecutor) ApplyBlock(
|
||||
|
||||
// Events are fired after everything else.
|
||||
// NOTE: if we crash between Commit and Save, events wont be fired during replay
|
||||
fireEvents(ctx, blockExec.logger, blockExec.eventBus, block, blockID, finalizeBlockResponse, validatorUpdates)
|
||||
fireEvents(blockExec.logger, blockExec.eventBus, block, blockID, finalizeBlockResponse, validatorUpdates)
|
||||
|
||||
return state, nil
|
||||
}
|
||||
|
||||
func (blockExec *BlockExecutor) ExtendVote(ctx context.Context, vote *types.Vote) (types.VoteExtension, error) {
|
||||
req := abci.RequestExtendVote{
|
||||
Vote: vote.ToProto(),
|
||||
}
|
||||
|
||||
resp, err := blockExec.appClient.ExtendVote(ctx, req)
|
||||
func (blockExec *BlockExecutor) ExtendVote(ctx context.Context, vote *types.Vote) ([]byte, error) {
|
||||
resp, err := blockExec.appClient.ExtendVote(ctx, &abci.RequestExtendVote{
|
||||
Hash: vote.BlockID.Hash,
|
||||
Height: vote.Height,
|
||||
})
|
||||
if err != nil {
|
||||
return types.VoteExtension{}, err
|
||||
panic(fmt.Errorf("ExtendVote call failed: %w", err))
|
||||
}
|
||||
return types.VoteExtensionFromProto(resp.VoteExtension), nil
|
||||
return resp.VoteExtension, nil
|
||||
}
|
||||
|
||||
func (blockExec *BlockExecutor) VerifyVoteExtension(ctx context.Context, vote *types.Vote) error {
|
||||
req := abci.RequestVerifyVoteExtension{
|
||||
Vote: vote.ToProto(),
|
||||
}
|
||||
|
||||
resp, err := blockExec.appClient.VerifyVoteExtension(ctx, req)
|
||||
resp, err := blockExec.appClient.VerifyVoteExtension(ctx, &abci.RequestVerifyVoteExtension{
|
||||
Hash: vote.BlockID.Hash,
|
||||
ValidatorAddress: vote.ValidatorAddress,
|
||||
Height: vote.Height,
|
||||
VoteExtension: vote.Extension,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
panic(fmt.Errorf("VerifyVoteExtension call failed: %w", err))
|
||||
}
|
||||
|
||||
if resp.IsErr() {
|
||||
if !resp.IsOK() {
|
||||
return types.ErrVoteInvalidExtension
|
||||
}
|
||||
|
||||
@@ -417,16 +416,39 @@ func buildLastCommitInfo(block *types.Block, store Store, initialHeight int64) a
|
||||
}
|
||||
}
|
||||
|
||||
// extendedCommitInfo expects a CommitInfo struct along with all of the
|
||||
// original votes relating to that commit, including their vote extensions. The
|
||||
// order of votes does not matter.
|
||||
func extendedCommitInfo(c abci.CommitInfo, votes []*types.Vote) abci.ExtendedCommitInfo {
|
||||
if len(c.Votes) != len(votes) {
|
||||
panic(fmt.Sprintf("extendedCommitInfo: number of votes from commit differ from the number of votes supplied (%d != %d)", len(c.Votes), len(votes)))
|
||||
}
|
||||
votesByVal := make(map[string]*types.Vote)
|
||||
for _, vote := range votes {
|
||||
if vote != nil {
|
||||
valAddr := vote.ValidatorAddress.String()
|
||||
if _, ok := votesByVal[valAddr]; ok {
|
||||
panic(fmt.Sprintf("extendedCommitInfo: found duplicate vote for validator with address %s", valAddr))
|
||||
}
|
||||
votesByVal[valAddr] = vote
|
||||
}
|
||||
}
|
||||
vs := make([]abci.ExtendedVoteInfo, len(c.Votes))
|
||||
for i := range vs {
|
||||
var ext []byte
|
||||
// votes[i] will be nil if c.Votes[i].SignedLastBlock is false
|
||||
if c.Votes[i].SignedLastBlock {
|
||||
valAddr := crypto.Address(c.Votes[i].Validator.Address).String()
|
||||
vote, ok := votesByVal[valAddr]
|
||||
if !ok || vote == nil {
|
||||
panic(fmt.Sprintf("extendedCommitInfo: validator with address %s signed last block, but could not find vote for it", valAddr))
|
||||
}
|
||||
ext = vote.Extension
|
||||
}
|
||||
vs[i] = abci.ExtendedVoteInfo{
|
||||
Validator: c.Votes[i].Validator,
|
||||
SignedLastBlock: c.Votes[i].SignedLastBlock,
|
||||
/*
|
||||
TODO: Include vote extensions information when implementing vote extensions.
|
||||
VoteExtension: []byte{},
|
||||
*/
|
||||
VoteExtension: ext,
|
||||
}
|
||||
}
|
||||
return abci.ExtendedCommitInfo{
|
||||
@@ -530,7 +552,6 @@ func (state State) Update(
|
||||
// Fire TxEvent for every tx.
|
||||
// NOTE: if Tendermint crashes before commit, some or all of these events may be published again.
|
||||
func fireEvents(
|
||||
ctx context.Context,
|
||||
logger log.Logger,
|
||||
eventBus types.BlockEventPublisher,
|
||||
block *types.Block,
|
||||
@@ -538,7 +559,7 @@ func fireEvents(
|
||||
finalizeBlockResponse *abci.ResponseFinalizeBlock,
|
||||
validatorUpdates []*types.Validator,
|
||||
) {
|
||||
if err := eventBus.PublishEventNewBlock(ctx, types.EventDataNewBlock{
|
||||
if err := eventBus.PublishEventNewBlock(types.EventDataNewBlock{
|
||||
Block: block,
|
||||
BlockID: blockID,
|
||||
ResultFinalizeBlock: *finalizeBlockResponse,
|
||||
@@ -546,7 +567,7 @@ func fireEvents(
|
||||
logger.Error("failed publishing new block", "err", err)
|
||||
}
|
||||
|
||||
if err := eventBus.PublishEventNewBlockHeader(ctx, types.EventDataNewBlockHeader{
|
||||
if err := eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{
|
||||
Header: block.Header,
|
||||
NumTxs: int64(len(block.Txs)),
|
||||
ResultFinalizeBlock: *finalizeBlockResponse,
|
||||
@@ -556,7 +577,7 @@ func fireEvents(
|
||||
|
||||
if len(block.Evidence) != 0 {
|
||||
for _, ev := range block.Evidence {
|
||||
if err := eventBus.PublishEventNewEvidence(ctx, types.EventDataNewEvidence{
|
||||
if err := eventBus.PublishEventNewEvidence(types.EventDataNewEvidence{
|
||||
Evidence: ev,
|
||||
Height: block.Height,
|
||||
}); err != nil {
|
||||
@@ -572,7 +593,7 @@ func fireEvents(
|
||||
}
|
||||
|
||||
for i, tx := range block.Data.Txs {
|
||||
if err := eventBus.PublishEventTx(ctx, types.EventDataTx{
|
||||
if err := eventBus.PublishEventTx(types.EventDataTx{
|
||||
TxResult: abci.TxResult{
|
||||
Height: block.Height,
|
||||
Index: uint32(i),
|
||||
@@ -585,7 +606,7 @@ func fireEvents(
|
||||
}
|
||||
|
||||
if len(finalizeBlockResponse.ValidatorUpdates) > 0 {
|
||||
if err := eventBus.PublishEventValidatorSetUpdates(ctx,
|
||||
if err := eventBus.PublishEventValidatorSetUpdates(
|
||||
types.EventDataValidatorSetUpdates{ValidatorUpdates: validatorUpdates}); err != nil {
|
||||
logger.Error("failed publishing event", "err", err)
|
||||
}
|
||||
@@ -609,7 +630,7 @@ func ExecCommitBlock(
|
||||
) ([]byte, error) {
|
||||
finalizeBlockResponse, err := appConn.FinalizeBlock(
|
||||
ctx,
|
||||
abci.RequestFinalizeBlock{
|
||||
&abci.RequestFinalizeBlock{
|
||||
Hash: block.Hash(),
|
||||
Height: block.Height,
|
||||
Time: block.Time,
|
||||
@@ -644,7 +665,7 @@ func ExecCommitBlock(
|
||||
}
|
||||
|
||||
blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()}
|
||||
fireEvents(ctx, be.logger, be.eventBus, block, blockID, finalizeBlockResponse, validatorUpdates)
|
||||
fireEvents(be.logger, be.eventBus, block, blockID, finalizeBlockResponse, validatorUpdates)
|
||||
}
|
||||
|
||||
// Commit block, get hash back
|
||||
|
||||
@@ -277,7 +277,7 @@ func TestProcessProposal(t *testing.T) {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app := abcimocks.NewApplication(t)
|
||||
logger := log.NewNopLogger()
|
||||
cc := abciclient.NewLocalClient(logger, app)
|
||||
proxyApp := proxy.New(cc, logger, proxy.NopMetrics())
|
||||
@@ -329,7 +329,7 @@ func TestProcessProposal(t *testing.T) {
|
||||
block1 := sf.MakeBlock(state, height, lastCommit)
|
||||
block1.Txs = txs
|
||||
|
||||
expectedRpp := abci.RequestProcessProposal{
|
||||
expectedRpp := &abci.RequestProcessProposal{
|
||||
Txs: block1.Txs.ToSliceOfBytes(),
|
||||
Hash: block1.Hash(),
|
||||
Height: block1.Header.Height,
|
||||
@@ -343,12 +343,12 @@ func TestProcessProposal(t *testing.T) {
|
||||
ProposerAddress: block1.ProposerAddress,
|
||||
}
|
||||
|
||||
app.On("ProcessProposal", mock.Anything).Return(abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT})
|
||||
app.On("ProcessProposal", mock.Anything, mock.Anything).Return(&abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil)
|
||||
acceptBlock, err := blockExec.ProcessProposal(ctx, block1, state)
|
||||
require.NoError(t, err)
|
||||
require.True(t, acceptBlock)
|
||||
app.AssertExpectations(t)
|
||||
app.AssertCalled(t, "ProcessProposal", expectedRpp)
|
||||
app.AssertCalled(t, "ProcessProposal", ctx, expectedRpp)
|
||||
}
|
||||
|
||||
func TestValidateValidatorUpdates(t *testing.T) {
|
||||
@@ -621,8 +621,8 @@ func TestEmptyPrepareProposal(t *testing.T) {
|
||||
eventBus := eventbus.NewDefault(logger)
|
||||
require.NoError(t, eventBus.Start(ctx))
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{})
|
||||
app := abcimocks.NewApplication(t)
|
||||
app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{}, nil)
|
||||
cc := abciclient.NewLocalClient(logger, app)
|
||||
proxyApp := proxy.New(cc, logger, proxy.NopMetrics())
|
||||
err := proxyApp.Start(ctx)
|
||||
@@ -654,8 +654,8 @@ func TestEmptyPrepareProposal(t *testing.T) {
|
||||
sm.NopMetrics(),
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
_, err = blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
|
||||
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
_, err = blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
@@ -680,10 +680,10 @@ func TestPrepareProposalErrorOnNonExistingRemoved(t *testing.T) {
|
||||
mp := &mpmocks.Mempool{}
|
||||
mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs{})
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app := abcimocks.NewApplication(t)
|
||||
|
||||
// create an invalid ResponsePrepareProposal
|
||||
rpp := abci.ResponsePrepareProposal{
|
||||
rpp := &abci.ResponsePrepareProposal{
|
||||
TxRecords: []*abci.TxRecord{
|
||||
{
|
||||
Action: abci.TxRecord_REMOVED,
|
||||
@@ -691,7 +691,7 @@ func TestPrepareProposalErrorOnNonExistingRemoved(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
app.On("PrepareProposal", mock.Anything).Return(rpp)
|
||||
app.On("PrepareProposal", mock.Anything, mock.Anything).Return(rpp, nil)
|
||||
|
||||
cc := abciclient.NewLocalClient(logger, app)
|
||||
proxyApp := proxy.New(cc, logger, proxy.NopMetrics())
|
||||
@@ -709,10 +709,10 @@ func TestPrepareProposalErrorOnNonExistingRemoved(t *testing.T) {
|
||||
sm.NopMetrics(),
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
|
||||
require.Nil(t, block)
|
||||
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
|
||||
require.ErrorContains(t, err, "new transaction incorrectly marked as removed")
|
||||
require.Nil(t, block)
|
||||
|
||||
mp.AssertExpectations(t)
|
||||
}
|
||||
@@ -744,10 +744,10 @@ func TestPrepareProposalRemoveTxs(t *testing.T) {
|
||||
trs[1].Action = abci.TxRecord_REMOVED
|
||||
mp.On("RemoveTxByKey", mock.Anything).Return(nil).Twice()
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{
|
||||
app := abcimocks.NewApplication(t)
|
||||
app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{
|
||||
TxRecords: trs,
|
||||
})
|
||||
}, nil)
|
||||
|
||||
cc := abciclient.NewLocalClient(logger, app)
|
||||
proxyApp := proxy.New(cc, logger, proxy.NopMetrics())
|
||||
@@ -765,8 +765,8 @@ func TestPrepareProposalRemoveTxs(t *testing.T) {
|
||||
sm.NopMetrics(),
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
|
||||
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, block.Data.Txs.ToSliceOfBytes(), len(trs)-2)
|
||||
|
||||
@@ -803,10 +803,10 @@ func TestPrepareProposalAddedTxsIncluded(t *testing.T) {
|
||||
trs[0].Action = abci.TxRecord_ADDED
|
||||
trs[1].Action = abci.TxRecord_ADDED
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{
|
||||
app := abcimocks.NewApplication(t)
|
||||
app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{
|
||||
TxRecords: trs,
|
||||
})
|
||||
}, nil)
|
||||
|
||||
cc := abciclient.NewLocalClient(logger, app)
|
||||
proxyApp := proxy.New(cc, logger, proxy.NopMetrics())
|
||||
@@ -824,8 +824,8 @@ func TestPrepareProposalAddedTxsIncluded(t *testing.T) {
|
||||
sm.NopMetrics(),
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
|
||||
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
|
||||
require.NoError(t, err)
|
||||
|
||||
require.Equal(t, txs[0], block.Data.Txs[0])
|
||||
@@ -859,10 +859,10 @@ func TestPrepareProposalReorderTxs(t *testing.T) {
|
||||
trs = trs[2:]
|
||||
trs = append(trs[len(trs)/2:], trs[:len(trs)/2]...)
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{
|
||||
app := abcimocks.NewApplication(t)
|
||||
app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{
|
||||
TxRecords: trs,
|
||||
})
|
||||
}, nil)
|
||||
|
||||
cc := abciclient.NewLocalClient(logger, app)
|
||||
proxyApp := proxy.New(cc, logger, proxy.NopMetrics())
|
||||
@@ -880,8 +880,8 @@ func TestPrepareProposalReorderTxs(t *testing.T) {
|
||||
sm.NopMetrics(),
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
|
||||
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
|
||||
require.NoError(t, err)
|
||||
for i, tx := range block.Data.Txs {
|
||||
require.Equal(t, types.Tx(trs[i].Tx), tx)
|
||||
@@ -919,10 +919,10 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) {
|
||||
|
||||
trs := txsToTxRecords(types.Txs(txs))
|
||||
|
||||
app := abcimocks.NewBaseMock()
|
||||
app.On("PrepareProposal", mock.Anything).Return(abci.ResponsePrepareProposal{
|
||||
app := abcimocks.NewApplication(t)
|
||||
app.On("PrepareProposal", mock.Anything, mock.Anything).Return(&abci.ResponsePrepareProposal{
|
||||
TxRecords: trs,
|
||||
})
|
||||
}, nil)
|
||||
|
||||
cc := abciclient.NewLocalClient(logger, app)
|
||||
proxyApp := proxy.New(cc, logger, proxy.NopMetrics())
|
||||
@@ -940,11 +940,11 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) {
|
||||
sm.NopMetrics(),
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
|
||||
require.Nil(t, block)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
|
||||
require.ErrorContains(t, err, "transaction data size exceeds maximum")
|
||||
require.Nil(t, block, "")
|
||||
|
||||
mp.AssertExpectations(t)
|
||||
}
|
||||
@@ -992,9 +992,9 @@ func TestPrepareProposalErrorOnPrepareProposalError(t *testing.T) {
|
||||
sm.NopMetrics(),
|
||||
)
|
||||
pa, _ := state.Validators.GetByIndex(0)
|
||||
commit := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
commit, votes := makeValidCommit(ctx, t, height, types.BlockID{}, state.Validators, privVals)
|
||||
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, nil)
|
||||
block, err := blockExec.CreateProposalBlock(ctx, height, state, commit, pa, votes)
|
||||
require.Nil(t, block)
|
||||
require.ErrorContains(t, err, "an injected error")
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ func makeAndCommitGoodBlock(
|
||||
state, blockID := makeAndApplyGoodBlock(ctx, t, state, height, lastCommit, proposerAddr, blockExec, evidence)
|
||||
|
||||
// Simulate a lastCommit for this block from all validators for the next height
|
||||
commit := makeValidCommit(ctx, t, height, blockID, state.Validators, privVals)
|
||||
commit, _ := makeValidCommit(ctx, t, height, blockID, state.Validators, privVals)
|
||||
|
||||
return state, blockID, commit
|
||||
}
|
||||
@@ -82,17 +82,19 @@ func makeValidCommit(
|
||||
blockID types.BlockID,
|
||||
vals *types.ValidatorSet,
|
||||
privVals map[string]types.PrivValidator,
|
||||
) *types.Commit {
|
||||
) (*types.Commit, []*types.Vote) {
|
||||
t.Helper()
|
||||
sigs := make([]types.CommitSig, 0)
|
||||
sigs := make([]types.CommitSig, vals.Size())
|
||||
votes := make([]*types.Vote, vals.Size())
|
||||
for i := 0; i < vals.Size(); i++ {
|
||||
_, val := vals.GetByIndex(int32(i))
|
||||
vote, err := factory.MakeVote(ctx, privVals[val.Address.String()], chainID, int32(i), height, 0, 2, blockID, time.Now())
|
||||
require.NoError(t, err)
|
||||
sigs = append(sigs, vote.CommitSig())
|
||||
sigs[i] = vote.CommitSig()
|
||||
votes[i] = vote
|
||||
}
|
||||
|
||||
return types.NewCommit(height, 0, blockID, sigs)
|
||||
return types.NewCommit(height, 0, blockID, sigs), votes
|
||||
}
|
||||
|
||||
func makeState(t *testing.T, nVals, height int) (sm.State, dbm.DB, map[string]types.PrivValidator) {
|
||||
@@ -276,11 +278,11 @@ type testApp struct {
|
||||
|
||||
var _ abci.Application = (*testApp)(nil)
|
||||
|
||||
func (app *testApp) Info(req abci.RequestInfo) (resInfo abci.ResponseInfo) {
|
||||
return abci.ResponseInfo{}
|
||||
func (app *testApp) Info(_ context.Context, req *abci.RequestInfo) (*abci.ResponseInfo, error) {
|
||||
return &abci.ResponseInfo{}, nil
|
||||
}
|
||||
|
||||
func (app *testApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFinalizeBlock {
|
||||
func (app *testApp) FinalizeBlock(_ context.Context, req *abci.RequestFinalizeBlock) (*abci.ResponseFinalizeBlock, error) {
|
||||
app.CommitVotes = req.DecidedLastCommit.Votes
|
||||
app.ByzantineValidators = req.ByzantineValidators
|
||||
|
||||
@@ -293,7 +295,7 @@ func (app *testApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFi
|
||||
}
|
||||
}
|
||||
|
||||
return abci.ResponseFinalizeBlock{
|
||||
return &abci.ResponseFinalizeBlock{
|
||||
ValidatorUpdates: app.ValidatorUpdates,
|
||||
ConsensusParamUpdates: &tmproto.ConsensusParams{
|
||||
Version: &tmproto.VersionParams{
|
||||
@@ -302,26 +304,26 @@ func (app *testApp) FinalizeBlock(req abci.RequestFinalizeBlock) abci.ResponseFi
|
||||
},
|
||||
Events: []abci.Event{},
|
||||
TxResults: resTxs,
|
||||
}
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (app *testApp) CheckTx(req abci.RequestCheckTx) abci.ResponseCheckTx {
|
||||
return abci.ResponseCheckTx{}
|
||||
func (app *testApp) CheckTx(_ context.Context, req *abci.RequestCheckTx) (*abci.ResponseCheckTx, error) {
|
||||
return &abci.ResponseCheckTx{}, nil
|
||||
}
|
||||
|
||||
func (app *testApp) Commit() abci.ResponseCommit {
|
||||
return abci.ResponseCommit{RetainHeight: 1}
|
||||
func (app *testApp) Commit(context.Context) (*abci.ResponseCommit, error) {
|
||||
return &abci.ResponseCommit{RetainHeight: 1}, nil
|
||||
}
|
||||
|
||||
func (app *testApp) Query(reqQuery abci.RequestQuery) (resQuery abci.ResponseQuery) {
|
||||
return
|
||||
func (app *testApp) Query(_ context.Context, req *abci.RequestQuery) (*abci.ResponseQuery, error) {
|
||||
return &abci.ResponseQuery{}, nil
|
||||
}
|
||||
|
||||
func (app *testApp) ProcessProposal(req abci.RequestProcessProposal) abci.ResponseProcessProposal {
|
||||
func (app *testApp) ProcessProposal(_ context.Context, req *abci.RequestProcessProposal) (*abci.ResponseProcessProposal, error) {
|
||||
for _, tx := range req.Txs {
|
||||
if len(tx) == 0 {
|
||||
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}
|
||||
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_REJECT}, nil
|
||||
}
|
||||
}
|
||||
return abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}
|
||||
return &abci.ResponseProcessProposal{Status: abci.ResponseProcessProposal_ACCEPT}, nil
|
||||
}
|
||||
|
||||
@@ -54,8 +54,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) {
|
||||
assert.False(t, indexer.IndexingEnabled([]indexer.EventSink{}))
|
||||
|
||||
// event sink setup
|
||||
pool, err := setupDB(t)
|
||||
assert.NoError(t, err)
|
||||
pool := setupDB(t)
|
||||
|
||||
store := dbm.NewMemDB()
|
||||
eventSinks := []indexer.EventSink{kv.NewEventSink(store), pSink}
|
||||
@@ -71,7 +70,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) {
|
||||
t.Cleanup(service.Wait)
|
||||
|
||||
// publish block with txs
|
||||
err = eventBus.PublishEventNewBlockHeader(ctx, types.EventDataNewBlockHeader{
|
||||
err = eventBus.PublishEventNewBlockHeader(types.EventDataNewBlockHeader{
|
||||
Header: types.Header{Height: 1},
|
||||
NumTxs: int64(2),
|
||||
})
|
||||
@@ -82,7 +81,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) {
|
||||
Tx: types.Tx("foo"),
|
||||
Result: abci.ExecTxResult{Code: 0},
|
||||
}
|
||||
err = eventBus.PublishEventTx(ctx, types.EventDataTx{TxResult: *txResult1})
|
||||
err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult1})
|
||||
require.NoError(t, err)
|
||||
txResult2 := &abci.TxResult{
|
||||
Height: 1,
|
||||
@@ -90,7 +89,7 @@ func TestIndexerServiceIndexesBlocks(t *testing.T) {
|
||||
Tx: types.Tx("bar"),
|
||||
Result: abci.ExecTxResult{Code: 0},
|
||||
}
|
||||
err = eventBus.PublishEventTx(ctx, types.EventDataTx{TxResult: *txResult2})
|
||||
err = eventBus.PublishEventTx(types.EventDataTx{TxResult: *txResult2})
|
||||
require.NoError(t, err)
|
||||
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
@@ -133,7 +132,7 @@ func resetDB(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func setupDB(t *testing.T) (*dockertest.Pool, error) {
|
||||
func setupDB(t *testing.T) *dockertest.Pool {
|
||||
t.Helper()
|
||||
pool, err := dockertest.NewPool(os.Getenv("DOCKER_URL"))
|
||||
assert.NoError(t, err)
|
||||
@@ -187,7 +186,7 @@ func setupDB(t *testing.T) (*dockertest.Pool, error) {
|
||||
err = migrator.Apply(psqldb, sm)
|
||||
assert.NoError(t, err)
|
||||
|
||||
return pool, nil
|
||||
return pool
|
||||
}
|
||||
|
||||
func teardown(t *testing.T, pool *dockertest.Pool) error {
|
||||
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
|
||||
tenderminttypes "github.com/tendermint/tendermint/types"
|
||||
|
||||
testing "testing"
|
||||
|
||||
types "github.com/tendermint/tendermint/abci/types"
|
||||
)
|
||||
|
||||
@@ -165,3 +167,13 @@ func (_m *EventSink) Type() indexer.EventSinkType {
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewEventSink creates a new instance of EventSink. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewEventSink(t testing.TB) *EventSink {
|
||||
mock := &EventSink{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@ package mocks
|
||||
import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
|
||||
testing "testing"
|
||||
|
||||
types "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -208,3 +210,13 @@ func (_m *BlockStore) Size() int64 {
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewBlockStore creates a new instance of BlockStore. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewBlockStore(t testing.TB) *BlockStore {
|
||||
mock := &BlockStore{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
state "github.com/tendermint/tendermint/internal/state"
|
||||
|
||||
testing "testing"
|
||||
|
||||
types "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -71,3 +73,13 @@ func (_m *EvidencePool) PendingEvidence(maxBytes int64) ([]types.Evidence, int64
|
||||
func (_m *EvidencePool) Update(_a0 context.Context, _a1 state.State, _a2 types.EvidenceList) {
|
||||
_m.Called(_a0, _a1, _a2)
|
||||
}
|
||||
|
||||
// NewEvidencePool creates a new instance of EvidencePool. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewEvidencePool(t testing.TB) *EvidencePool {
|
||||
mock := &EvidencePool{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import (
|
||||
state "github.com/tendermint/tendermint/internal/state"
|
||||
tendermintstate "github.com/tendermint/tendermint/proto/tendermint/state"
|
||||
|
||||
testing "testing"
|
||||
|
||||
types "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -186,3 +188,13 @@ func (_m *Store) SaveValidatorSets(_a0 int64, _a1 int64, _a2 *types.ValidatorSet
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// NewStore creates a new instance of Store. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewStore(t testing.TB) *Store {
|
||||
mock := &Store{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
state "github.com/tendermint/tendermint/internal/state"
|
||||
|
||||
testing "testing"
|
||||
|
||||
types "github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -82,3 +84,13 @@ func (_m *StateProvider) State(ctx context.Context, height uint64) (state.State,
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// NewStateProvider creates a new instance of StateProvider. It also registers the testing.TB interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewStateProvider(t testing.TB) *StateProvider {
|
||||
mock := &StateProvider{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
||||
|
||||
@@ -333,7 +333,7 @@ func (r *Reactor) OnStop() {
|
||||
// of historical blocks before participating in consensus
|
||||
func (r *Reactor) Sync(ctx context.Context) (sm.State, error) {
|
||||
if r.eventBus != nil {
|
||||
if err := r.eventBus.PublishEventStateSyncStatus(ctx, types.EventDataStateSyncStatus{
|
||||
if err := r.eventBus.PublishEventStateSyncStatus(types.EventDataStateSyncStatus{
|
||||
Complete: false,
|
||||
Height: r.initialHeight,
|
||||
}); err != nil {
|
||||
@@ -387,7 +387,7 @@ func (r *Reactor) Sync(ctx context.Context) (sm.State, error) {
|
||||
}
|
||||
|
||||
if r.eventBus != nil {
|
||||
if err := r.eventBus.PublishEventStateSyncStatus(ctx, types.EventDataStateSyncStatus{
|
||||
if err := r.eventBus.PublishEventStateSyncStatus(types.EventDataStateSyncStatus{
|
||||
Complete: true,
|
||||
Height: state.LastBlockHeight,
|
||||
}); err != nil {
|
||||
@@ -688,7 +688,7 @@ func (r *Reactor) handleChunkMessage(ctx context.Context, envelope *p2p.Envelope
|
||||
"chunk", msg.Index,
|
||||
"peer", envelope.From,
|
||||
)
|
||||
resp, err := r.conn.LoadSnapshotChunk(ctx, abci.RequestLoadSnapshotChunk{
|
||||
resp, err := r.conn.LoadSnapshotChunk(ctx, &abci.RequestLoadSnapshotChunk{
|
||||
Height: msg.Height,
|
||||
Format: msg.Format,
|
||||
Chunk: msg.Index,
|
||||
@@ -1015,7 +1015,7 @@ func (r *Reactor) processPeerUpdates(ctx context.Context, peerUpdates *p2p.PeerU
|
||||
|
||||
// recentSnapshots fetches the n most recent snapshots from the app
|
||||
func (r *Reactor) recentSnapshots(ctx context.Context, n uint32) ([]*snapshot, error) {
|
||||
resp, err := r.conn.ListSnapshots(ctx, abci.RequestListSnapshots{})
|
||||
resp, err := r.conn.ListSnapshots(ctx, &abci.RequestListSnapshots{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -204,15 +204,15 @@ func TestReactor_Sync(t *testing.T) {
|
||||
rts := setup(ctx, t, nil, nil, 100)
|
||||
chain := buildLightBlockChain(ctx, t, 1, 10, time.Now())
|
||||
// app accepts any snapshot
|
||||
rts.conn.On("OfferSnapshot", ctx, mock.AnythingOfType("types.RequestOfferSnapshot")).
|
||||
rts.conn.On("OfferSnapshot", ctx, mock.IsType(&abci.RequestOfferSnapshot{})).
|
||||
Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ACCEPT}, nil)
|
||||
|
||||
// app accepts every chunk
|
||||
rts.conn.On("ApplySnapshotChunk", ctx, mock.AnythingOfType("types.RequestApplySnapshotChunk")).
|
||||
rts.conn.On("ApplySnapshotChunk", ctx, mock.IsType(&abci.RequestApplySnapshotChunk{})).
|
||||
Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
|
||||
// app query returns valid state app hash
|
||||
rts.conn.On("Info", mock.Anything, proxy.RequestInfo).Return(&abci.ResponseInfo{
|
||||
rts.conn.On("Info", mock.Anything, &proxy.RequestInfo).Return(&abci.ResponseInfo{
|
||||
AppVersion: testAppVersion,
|
||||
LastBlockHeight: snapshotHeight,
|
||||
LastBlockAppHash: chain[snapshotHeight+1].AppHash,
|
||||
@@ -307,7 +307,7 @@ func TestReactor_ChunkRequest(t *testing.T) {
|
||||
|
||||
// mock ABCI connection to return local snapshots
|
||||
conn := &clientmocks.Client{}
|
||||
conn.On("LoadSnapshotChunk", mock.Anything, abci.RequestLoadSnapshotChunk{
|
||||
conn.On("LoadSnapshotChunk", mock.Anything, &abci.RequestLoadSnapshotChunk{
|
||||
Height: tc.request.Height,
|
||||
Format: tc.request.Format,
|
||||
Chunk: tc.request.Index,
|
||||
@@ -396,7 +396,7 @@ func TestReactor_SnapshotsRequest(t *testing.T) {
|
||||
|
||||
// mock ABCI connection to return local snapshots
|
||||
conn := &clientmocks.Client{}
|
||||
conn.On("ListSnapshots", mock.Anything, abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{
|
||||
conn.On("ListSnapshots", mock.Anything, &abci.RequestListSnapshots{}).Return(&abci.ResponseListSnapshots{
|
||||
Snapshots: tc.snapshots,
|
||||
}, nil)
|
||||
|
||||
|
||||
@@ -379,7 +379,7 @@ func (s *stateProviderP2P) consensusParams(ctx context.Context, height int64) (t
|
||||
}
|
||||
|
||||
wg.Add(1)
|
||||
go func(p *BlockProvider, peer types.NodeID) {
|
||||
go func(peer types.NodeID) {
|
||||
defer wg.Done()
|
||||
|
||||
timer := time.NewTimer(0)
|
||||
@@ -424,7 +424,7 @@ func (s *stateProviderP2P) consensusParams(ctx context.Context, height int64) (t
|
||||
}
|
||||
}
|
||||
|
||||
}(p, peer)
|
||||
}(peer)
|
||||
}
|
||||
sig := make(chan struct{})
|
||||
go func() { wg.Wait(); close(sig) }()
|
||||
|
||||
@@ -337,7 +337,7 @@ func (s *syncer) Sync(ctx context.Context, snapshot *snapshot, chunks *chunkQueu
|
||||
func (s *syncer) offerSnapshot(ctx context.Context, snapshot *snapshot) error {
|
||||
s.logger.Info("Offering snapshot to ABCI app", "height", snapshot.Height,
|
||||
"format", snapshot.Format, "hash", snapshot.Hash)
|
||||
resp, err := s.conn.OfferSnapshot(ctx, abci.RequestOfferSnapshot{
|
||||
resp, err := s.conn.OfferSnapshot(ctx, &abci.RequestOfferSnapshot{
|
||||
Snapshot: &abci.Snapshot{
|
||||
Height: snapshot.Height,
|
||||
Format: snapshot.Format,
|
||||
@@ -379,7 +379,7 @@ func (s *syncer) applyChunks(ctx context.Context, chunks *chunkQueue, start time
|
||||
return fmt.Errorf("failed to fetch chunk: %w", err)
|
||||
}
|
||||
|
||||
resp, err := s.conn.ApplySnapshotChunk(ctx, abci.RequestApplySnapshotChunk{
|
||||
resp, err := s.conn.ApplySnapshotChunk(ctx, &abci.RequestApplySnapshotChunk{
|
||||
Index: chunk.Index,
|
||||
Chunk: chunk.Chunk,
|
||||
Sender: string(chunk.Sender),
|
||||
@@ -519,7 +519,7 @@ func (s *syncer) requestChunk(ctx context.Context, snapshot *snapshot, chunk uin
|
||||
|
||||
// verifyApp verifies the sync, checking the app hash, last block height and app version
|
||||
func (s *syncer) verifyApp(ctx context.Context, snapshot *snapshot, appVersion uint64) error {
|
||||
resp, err := s.conn.Info(ctx, proxy.RequestInfo)
|
||||
resp, err := s.conn.Info(ctx, &proxy.RequestInfo)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to query ABCI app for appHash: %w", err)
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ func TestSyncer_SyncAny(t *testing.T) {
|
||||
|
||||
// We start a sync, with peers sending back chunks when requested. We first reject the snapshot
|
||||
// with height 2 format 2, and accept the snapshot at height 1.
|
||||
conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: &abci.Snapshot{
|
||||
Height: 2,
|
||||
Format: 2,
|
||||
@@ -118,7 +118,7 @@ func TestSyncer_SyncAny(t *testing.T) {
|
||||
},
|
||||
AppHash: []byte("app_hash_2"),
|
||||
}).Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil)
|
||||
conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: &abci.Snapshot{
|
||||
Height: s.Height,
|
||||
Format: s.Format,
|
||||
@@ -170,7 +170,7 @@ func TestSyncer_SyncAny(t *testing.T) {
|
||||
// The first time we're applying chunk 2 we tell it to retry the snapshot and discard chunk 1,
|
||||
// which should cause it to keep the existing chunk 0 and 2, and restart restoration from
|
||||
// beginning. We also wait for a little while, to exercise the retry logic in fetchChunks().
|
||||
conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 2, Chunk: []byte{1, 1, 2},
|
||||
}).Once().Run(func(args mock.Arguments) { time.Sleep(1 * time.Second) }).Return(
|
||||
&abci.ResponseApplySnapshotChunk{
|
||||
@@ -178,16 +178,16 @@ func TestSyncer_SyncAny(t *testing.T) {
|
||||
RefetchChunks: []uint32{1},
|
||||
}, nil)
|
||||
|
||||
conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 0, Chunk: []byte{1, 1, 0},
|
||||
}).Times(2).Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 1, Chunk: []byte{1, 1, 1},
|
||||
}).Times(2).Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 2, Chunk: []byte{1, 1, 2},
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
conn.On("Info", mock.Anything, proxy.RequestInfo).Return(&abci.ResponseInfo{
|
||||
conn.On("Info", mock.Anything, &proxy.RequestInfo).Return(&abci.ResponseInfo{
|
||||
AppVersion: testAppVersion,
|
||||
LastBlockHeight: 1,
|
||||
LastBlockAppHash: []byte("app_hash"),
|
||||
@@ -247,7 +247,7 @@ func TestSyncer_SyncAny_abort(t *testing.T) {
|
||||
_, err := rts.syncer.AddSnapshot(peerID, s)
|
||||
require.NoError(t, err)
|
||||
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(s), AppHash: []byte("app_hash"),
|
||||
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil)
|
||||
|
||||
@@ -281,15 +281,15 @@ func TestSyncer_SyncAny_reject(t *testing.T) {
|
||||
_, err = rts.syncer.AddSnapshot(peerID, s11)
|
||||
require.NoError(t, err)
|
||||
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(s22), AppHash: []byte("app_hash"),
|
||||
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil)
|
||||
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(s12), AppHash: []byte("app_hash"),
|
||||
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil)
|
||||
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(s11), AppHash: []byte("app_hash"),
|
||||
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil)
|
||||
|
||||
@@ -323,11 +323,11 @@ func TestSyncer_SyncAny_reject_format(t *testing.T) {
|
||||
_, err = rts.syncer.AddSnapshot(peerID, s11)
|
||||
require.NoError(t, err)
|
||||
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(s22), AppHash: []byte("app_hash"),
|
||||
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_FORMAT}, nil)
|
||||
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(s11), AppHash: []byte("app_hash"),
|
||||
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_ABORT}, nil)
|
||||
|
||||
@@ -372,11 +372,11 @@ func TestSyncer_SyncAny_reject_sender(t *testing.T) {
|
||||
_, err = rts.syncer.AddSnapshot(peerCID, sbc)
|
||||
require.NoError(t, err)
|
||||
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(sbc), AppHash: []byte("app_hash"),
|
||||
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT_SENDER}, nil)
|
||||
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(sa), AppHash: []byte("app_hash"),
|
||||
}).Once().Return(&abci.ResponseOfferSnapshot{Result: abci.ResponseOfferSnapshot_REJECT}, nil)
|
||||
|
||||
@@ -402,7 +402,7 @@ func TestSyncer_SyncAny_abciError(t *testing.T) {
|
||||
_, err := rts.syncer.AddSnapshot(peerID, s)
|
||||
require.NoError(t, err)
|
||||
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(s), AppHash: []byte("app_hash"),
|
||||
}).Once().Return(nil, errBoom)
|
||||
|
||||
@@ -445,7 +445,7 @@ func TestSyncer_offerSnapshot(t *testing.T) {
|
||||
rts := setup(ctx, t, nil, stateProvider, 2)
|
||||
|
||||
s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}, trustedAppHash: []byte("app_hash")}
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, abci.RequestOfferSnapshot{
|
||||
rts.conn.On("OfferSnapshot", mock.Anything, &abci.RequestOfferSnapshot{
|
||||
Snapshot: toABCI(s),
|
||||
AppHash: []byte("app_hash"),
|
||||
}).Return(&abci.ResponseOfferSnapshot{Result: tc.result}, tc.err)
|
||||
@@ -506,11 +506,11 @@ func TestSyncer_applyChunks_Results(t *testing.T) {
|
||||
_, err = chunks.Add(&chunk{Height: 1, Format: 1, Index: 0, Chunk: body})
|
||||
require.NoError(t, err)
|
||||
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 0, Chunk: body,
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{Result: tc.result}, tc.err)
|
||||
if tc.result == abci.ResponseApplySnapshotChunk_RETRY {
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 0, Chunk: body,
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{
|
||||
Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
@@ -573,13 +573,13 @@ func TestSyncer_applyChunks_RefetchChunks(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// The first two chunks are accepted, before the last one asks for 1 to be refetched
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 0, Chunk: []byte{0},
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 1, Chunk: []byte{1},
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 2, Chunk: []byte{2},
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{
|
||||
Result: tc.result,
|
||||
@@ -673,13 +673,13 @@ func TestSyncer_applyChunks_RejectSenders(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// The first two chunks are accepted, before the last one asks for b sender to be rejected
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 0, Chunk: []byte{0}, Sender: "aa",
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 1, Chunk: []byte{1}, Sender: "bb",
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 2, Chunk: []byte{2}, Sender: "cc",
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{
|
||||
Result: tc.result,
|
||||
@@ -688,7 +688,7 @@ func TestSyncer_applyChunks_RejectSenders(t *testing.T) {
|
||||
|
||||
// On retry, the last chunk will be tried again, so we just accept it then.
|
||||
if tc.result == abci.ResponseApplySnapshotChunk_RETRY {
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, abci.RequestApplySnapshotChunk{
|
||||
rts.conn.On("ApplySnapshotChunk", mock.Anything, &abci.RequestApplySnapshotChunk{
|
||||
Index: 2, Chunk: []byte{2}, Sender: "cc",
|
||||
}).Once().Return(&abci.ResponseApplySnapshotChunk{Result: abci.ResponseApplySnapshotChunk_ACCEPT}, nil)
|
||||
}
|
||||
@@ -761,7 +761,7 @@ func TestSyncer_verifyApp(t *testing.T) {
|
||||
|
||||
rts := setup(ctx, t, nil, nil, 2)
|
||||
|
||||
rts.conn.On("Info", mock.Anything, proxy.RequestInfo).Return(tc.response, tc.err)
|
||||
rts.conn.On("Info", mock.Anything, &proxy.RequestInfo).Return(tc.response, tc.err)
|
||||
err := rts.syncer.verifyApp(ctx, s, appVersion)
|
||||
unwrapped := errors.Unwrap(err)
|
||||
if unwrapped != nil {
|
||||
|
||||
@@ -17,7 +17,6 @@ import (
|
||||
"github.com/tendermint/tendermint/crypto"
|
||||
sm "github.com/tendermint/tendermint/internal/state"
|
||||
"github.com/tendermint/tendermint/internal/state/test/factory"
|
||||
"github.com/tendermint/tendermint/libs/log"
|
||||
tmrand "github.com/tendermint/tendermint/libs/rand"
|
||||
tmtime "github.com/tendermint/tendermint/libs/time"
|
||||
"github.com/tendermint/tendermint/types"
|
||||
@@ -46,7 +45,7 @@ func makeTestCommit(height int64, timestamp time.Time) *types.Commit {
|
||||
commitSigs)
|
||||
}
|
||||
|
||||
func makeStateAndBlockStore(dir string, logger log.Logger) (sm.State, *BlockStore, cleanupFunc, error) {
|
||||
func makeStateAndBlockStore(dir string) (sm.State, *BlockStore, cleanupFunc, error) {
|
||||
cfg, err := config.ResetTestRoot(dir, "blockchain_reactor_test")
|
||||
if err != nil {
|
||||
return sm.State{}, nil, nil, err
|
||||
@@ -81,7 +80,7 @@ func TestMain(m *testing.M) {
|
||||
}
|
||||
var cleanup cleanupFunc
|
||||
|
||||
state, _, cleanup, err = makeStateAndBlockStore(dir, log.NewNopLogger())
|
||||
state, _, cleanup, err = makeStateAndBlockStore(dir)
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
@@ -103,7 +102,7 @@ func TestMain(m *testing.M) {
|
||||
|
||||
// TODO: This test should be simplified ...
|
||||
func TestBlockStoreSaveLoadBlock(t *testing.T) {
|
||||
state, bs, cleanup, err := makeStateAndBlockStore(t.TempDir(), log.NewNopLogger())
|
||||
state, bs, cleanup, err := makeStateAndBlockStore(t.TempDir())
|
||||
defer cleanup()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, bs.Base(), int64(0), "initially the base should be zero")
|
||||
@@ -492,7 +491,7 @@ func TestLoadBlockMeta(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBlockFetchAtHeight(t *testing.T) {
|
||||
state, bs, cleanup, err := makeStateAndBlockStore(t.TempDir(), log.NewNopLogger())
|
||||
state, bs, cleanup, err := makeStateAndBlockStore(t.TempDir())
|
||||
defer cleanup()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, bs.Height(), int64(0), "initially the height should be zero")
|
||||
|
||||
@@ -31,6 +31,7 @@ func MakeCommit(ctx context.Context, blockID types.BlockID, height int64, round
|
||||
return nil, err
|
||||
}
|
||||
vote.Signature = v.Signature
|
||||
vote.ExtensionSignature = v.ExtensionSignature
|
||||
if _, err := voteSet.AddVote(vote); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user