From 3988ee533111308ed2eedaa5614bcde6075d7ce1 Mon Sep 17 00:00:00 2001 From: JayT106 Date: Tue, 20 Sep 2022 05:30:22 -0400 Subject: [PATCH] state: move pruneBlocks from consensus/state to state/execution (#9443) This enables pruning of cometbft db instances during initial block sync (starting either from the checkpoint or genesis). Cherry-picked from commit (cometbft/cometbft: db26cff) and resolved the conflicts: * Changelog was removed. * Where applicable `ApplyVerifiedBlock` was used. --- blocksync/reactor.go | 2 +- blocksync/reactor_test.go | 4 +-- consensus/byzantine_test.go | 2 +- consensus/common_test.go | 2 +- consensus/reactor_test.go | 2 +- consensus/replay.go | 4 +-- consensus/replay_file.go | 2 +- consensus/replay_test.go | 27 +++++++------- consensus/state.go | 32 +---------------- consensus/wal_generator.go | 2 +- node/node.go | 1 + node/node_test.go | 4 +++ state/execution.go | 72 ++++++++++++++++++++++++++----------- state/execution_test.go | 39 +++++++++++++++----- state/helpers_test.go | 2 +- state/validation_test.go | 11 ++++++ 16 files changed, 124 insertions(+), 84 deletions(-) diff --git a/blocksync/reactor.go b/blocksync/reactor.go index 84374b73623..aa15ccb7f8a 100644 --- a/blocksync/reactor.go +++ b/blocksync/reactor.go @@ -423,7 +423,7 @@ FOR_LOOP: // TODO: same thing for app - but we would need a way to // get the hash without persisting the state - state, _, err = bcR.blockExec.ApplyVerifiedBlock(state, firstID, first) + state, err = bcR.blockExec.ApplyVerifiedBlock(state, firstID, first) if err != nil { // TODO This is bad, are we zombie? panic(fmt.Sprintf("Failed to process committed block (%d:%X): %v", first.Height, first.Hash(), err)) diff --git a/blocksync/reactor_test.go b/blocksync/reactor_test.go index 66a61b509e9..09a9048d89a 100644 --- a/blocksync/reactor_test.go +++ b/blocksync/reactor_test.go @@ -104,7 +104,7 @@ func newReactor( DiscardABCIResponses: false, }) blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), - mp, sm.EmptyEvidencePool{}) + mp, sm.EmptyEvidencePool{}, blockStore) if err = stateStore.Save(state); err != nil { panic(err) } @@ -137,7 +137,7 @@ func newReactor( require.NoError(t, err) blockID := types.BlockID{Hash: thisBlock.Hash(), PartSetHeader: thisParts.Header()} - state, _, err = blockExec.ApplyBlock(state, blockID, thisBlock) + state, err = blockExec.ApplyBlock(state, blockID, thisBlock) if err != nil { panic(fmt.Errorf("error apply block: %w", err)) } diff --git a/consensus/byzantine_test.go b/consensus/byzantine_test.go index 861f5e4277f..8ef46b33d28 100644 --- a/consensus/byzantine_test.go +++ b/consensus/byzantine_test.go @@ -101,7 +101,7 @@ func TestByzantinePrevoteEquivocation(t *testing.T) { evpool.SetLogger(logger.With("module", "evidence")) // Make State - blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool) + blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool, blockStore) cs := NewState(thisConfig.Consensus, state, blockExec, blockStore, mempool, evpool) cs.SetLogger(cs.Logger) // set private validator diff --git a/consensus/common_test.go b/consensus/common_test.go index 02235cb2cf7..1ef0b178167 100644 --- a/consensus/common_test.go +++ b/consensus/common_test.go @@ -438,7 +438,7 @@ func newStateWithConfigAndBlockStore( panic(err) } - blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool) + blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool, blockStore) cs := NewState(thisConfig.Consensus, state, blockExec, blockStore, mempool, evpool) cs.SetLogger(log.TestingLogger().With("module", "consensus")) cs.SetPrivValidator(pv) diff --git a/consensus/reactor_test.go b/consensus/reactor_test.go index 9d36ff35fa6..23dbfe94ddf 100644 --- a/consensus/reactor_test.go +++ b/consensus/reactor_test.go @@ -203,7 +203,7 @@ func TestReactorWithEvidence(t *testing.T) { evpool2 := sm.EmptyEvidencePool{} // Make State - blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool) + blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyAppConnCon, mempool, evpool, blockStore) cs := NewState(thisConfig.Consensus, state, blockExec, blockStore, mempool, evpool2) cs.SetLogger(log.TestingLogger().With("module", "consensus")) cs.SetPrivValidator(pv) diff --git a/consensus/replay.go b/consensus/replay.go index 9159c27520b..bbc19167fe9 100644 --- a/consensus/replay.go +++ b/consensus/replay.go @@ -525,11 +525,11 @@ func (h *Handshaker) replayBlock(state sm.State, height int64, proxyApp proxy.Ap // Use stubs for both mempool and evidence pool since no transactions nor // evidence are needed here - block already exists. - blockExec := sm.NewBlockExecutor(h.stateStore, h.logger, proxyApp, emptyMempool{}, sm.EmptyEvidencePool{}) + blockExec := sm.NewBlockExecutor(h.stateStore, h.logger, proxyApp, emptyMempool{}, sm.EmptyEvidencePool{}, h.store) blockExec.SetEventBus(h.eventBus) var err error - state, _, err = blockExec.ApplyBlock(state, meta.BlockID, block) + state, err = blockExec.ApplyBlock(state, meta.BlockID, block) if err != nil { return sm.State{}, err } diff --git a/consensus/replay_file.go b/consensus/replay_file.go index f164c02cbeb..269dcc0fd82 100644 --- a/consensus/replay_file.go +++ b/consensus/replay_file.go @@ -329,7 +329,7 @@ func newConsensusStateForReplay(config cfg.BaseConfig, csConfig *cfg.ConsensusCo } mempool, evpool := emptyMempool{}, sm.EmptyEvidencePool{} - blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool) + blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool, blockStore) consensusState := NewState(csConfig, state.Copy(), blockExec, blockStore, mempool, evpool) diff --git a/consensus/replay_test.go b/consensus/replay_test.go index 9b267514aee..74d75ce6ca4 100644 --- a/consensus/replay_test.go +++ b/consensus/replay_test.go @@ -719,7 +719,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin state := genesisState.Copy() // run the chain through state.ApplyBlock to build up the CometBFT state - state = buildTMStateFromChain(t, config, stateStore, state, chain, nBlocks, mode) + state = buildTMStateFromChain(t, config, stateStore, state, chain, nBlocks, mode, store) latestAppHash := state.AppHash // make a new client creator @@ -737,7 +737,7 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin }) err := stateStore.Save(genesisState) require.NoError(t, err) - buildAppStateFromChain(t, proxyApp, stateStore, genesisState, chain, nBlocks, mode) + buildAppStateFromChain(t, proxyApp, stateStore, genesisState, chain, nBlocks, mode, store) } // Prune block store if requested @@ -797,20 +797,20 @@ func testHandshakeReplay(t *testing.T, config *cfg.Config, nBlocks int, mode uin } } -func applyBlock(t *testing.T, stateStore sm.Store, st sm.State, blk *types.Block, proxyApp proxy.AppConns) sm.State { +func applyBlock(t *testing.T, stateStore sm.Store, st sm.State, blk *types.Block, proxyApp proxy.AppConns, bs *mockBlockStore) sm.State { testPartSize := types.BlockPartSizeBytes - blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool) + blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool, bs) bps, err := blk.MakePartSet(testPartSize) require.NoError(t, err) blkID := types.BlockID{Hash: blk.Hash(), PartSetHeader: bps.Header()} - newState, _, err := blockExec.ApplyBlock(st, blkID, blk) + newState, err := blockExec.ApplyBlock(st, blkID, blk) require.NoError(t, err) return newState } func buildAppStateFromChain(t *testing.T, proxyApp proxy.AppConns, stateStore sm.Store, - state sm.State, chain []*types.Block, nBlocks int, mode uint) { + state sm.State, chain []*types.Block, nBlocks int, mode uint, blockStore *mockBlockStore) { // start a new app without handshake, play nBlocks blocks if err := proxyApp.Start(); err != nil { panic(err) @@ -831,18 +831,18 @@ func buildAppStateFromChain(t *testing.T, proxyApp proxy.AppConns, stateStore sm case 0: for i := 0; i < nBlocks; i++ { block := chain[i] - state = applyBlock(t, stateStore, state, block, proxyApp) + state = applyBlock(t, stateStore, state, block, proxyApp, blockStore) } case 1, 2, 3: for i := 0; i < nBlocks-1; i++ { block := chain[i] - state = applyBlock(t, stateStore, state, block, proxyApp) + state = applyBlock(t, stateStore, state, block, proxyApp, blockStore) } if mode == 2 || mode == 3 { // update the kvstore height and apphash // as if we ran commit but not - state = applyBlock(t, stateStore, state, chain[nBlocks-1], proxyApp) + state = applyBlock(t, stateStore, state, chain[nBlocks-1], proxyApp, blockStore) } default: panic(fmt.Sprintf("unknown mode %v", mode)) @@ -856,7 +856,8 @@ func buildTMStateFromChain( state sm.State, chain []*types.Block, nBlocks int, - mode uint) sm.State { + mode uint, + blockStore *mockBlockStore) sm.State { // run the whole chain against this client to build up the CometBFT state clientCreator := proxy.NewLocalClientCreator( kvstore.NewPersistentKVStoreApplication( @@ -881,19 +882,19 @@ func buildTMStateFromChain( case 0: // sync right up for _, block := range chain { - state = applyBlock(t, stateStore, state, block, proxyApp) + state = applyBlock(t, stateStore, state, block, proxyApp, blockStore) } case 1, 2, 3: // sync up to the penultimate as if we stored the block. // whether we commit or not depends on the appHash for _, block := range chain[:len(chain)-1] { - state = applyBlock(t, stateStore, state, block, proxyApp) + state = applyBlock(t, stateStore, state, block, proxyApp, blockStore) } // apply the final block to a state copy so we can // get the right next appHash but keep the state back - applyBlock(t, stateStore, state, chain[len(chain)-1], proxyApp) + applyBlock(t, stateStore, state, chain[len(chain)-1], proxyApp, blockStore) default: panic(fmt.Sprintf("unknown mode %v", mode)) } diff --git a/consensus/state.go b/consensus/state.go index fbbebe47d9a..22ab0cbb854 100644 --- a/consensus/state.go +++ b/consensus/state.go @@ -1713,11 +1713,7 @@ func (cs *State) finalizeCommit(height int64) { // Execute and commit the block, update and save the state, and update the mempool. // We use apply verified block here because we have verified the block in this function already. // NOTE The block.AppHash wont reflect these txs until the next block. - var ( - err error - retainHeight int64 - ) - stateCopy, retainHeight, err = cs.blockExec.ApplyVerifiedBlock( + stateCopy, err := cs.blockExec.ApplyVerifiedBlock( stateCopy, types.BlockID{ Hash: block.Hash(), @@ -1731,16 +1727,6 @@ func (cs *State) finalizeCommit(height int64) { fail.Fail() // XXX - // Prune old heights, if requested by ABCI app. - if retainHeight > 0 { - pruned, err := cs.pruneBlocks(retainHeight) - if err != nil { - logger.Error("failed to prune blocks", "retain_height", retainHeight, "err", err) - } else { - logger.Debug("pruned blocks", "pruned", pruned, "retain_height", retainHeight) - } - } - // must be called before we update state cs.recordMetrics(height, block) @@ -1764,22 +1750,6 @@ func (cs *State) finalizeCommit(height int64) { // * cs.StartTime is set to when we will start round0. } -func (cs *State) pruneBlocks(retainHeight int64) (uint64, error) { - base := cs.blockStore.Base() - if retainHeight <= base { - return 0, nil - } - pruned, err := cs.blockStore.PruneBlocks(retainHeight) - if err != nil { - return 0, fmt.Errorf("failed to prune block store: %w", err) - } - err = cs.blockExec.Store().PruneStates(base, retainHeight) - if err != nil { - return 0, fmt.Errorf("failed to prune state database: %w", err) - } - return pruned, nil -} - func (cs *State) recordMetrics(height int64, block *types.Block) { cs.metrics.Validators.Set(float64(cs.Validators.Size())) cs.metrics.ValidatorsPower.Set(float64(cs.Validators.TotalVotingPower())) diff --git a/consensus/wal_generator.go b/consensus/wal_generator.go index fb13bdc58c4..8a814ad840f 100644 --- a/consensus/wal_generator.go +++ b/consensus/wal_generator.go @@ -84,7 +84,7 @@ func WALGenerateNBlocks(t *testing.T, wr io.Writer, numBlocks int) (err error) { }) mempool := emptyMempool{} evpool := sm.EmptyEvidencePool{} - blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool) + blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), mempool, evpool, blockStore) consensusState := NewState(config.Consensus, state.Copy(), blockExec, blockStore, mempool, evpool) consensusState.SetLogger(logger) consensusState.SetEventBus(eventBus) diff --git a/node/node.go b/node/node.go index 195ff33a357..b81307ccb39 100644 --- a/node/node.go +++ b/node/node.go @@ -962,6 +962,7 @@ func NewNodeWithContext(ctx context.Context, proxyApp.Consensus(), mempool, evidencePool, + blockStore, sm.BlockExecutorWithMetrics(smMetrics), ) offlineStateSyncHeight := int64(0) diff --git a/node/node_test.go b/node/node_test.go index ea22a157fef..db9742382c6 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -305,6 +305,7 @@ func TestCreateProposalBlock(t *testing.T) { proxyApp.Consensus(), mempool, evidencePool, + blockStore, ) commit := types.NewCommit(height-1, 0, types.BlockID{}, nil) @@ -375,6 +376,8 @@ func TestMaxProposalBlockSize(t *testing.T) { ) } + blockStore := store.NewBlockStore(dbm.NewMemDB()) + // fill the mempool with one txs just below the maximum size txLength := int(types.MaxDataBytesNoEvidence(maxBytes, 1)) tx := cmtrand.Bytes(txLength - 4) // to account for the varint @@ -387,6 +390,7 @@ func TestMaxProposalBlockSize(t *testing.T) { proxyApp.Consensus(), mempool, sm.EmptyEvidencePool{}, + blockStore, ) commit := types.NewCommit(height-1, 0, types.BlockID{}, nil) diff --git a/state/execution.go b/state/execution.go index dced97233ba..a8e2289bae1 100644 --- a/state/execution.go +++ b/state/execution.go @@ -25,6 +25,9 @@ type BlockExecutor struct { // save state, validators, consensus params, abci responses here store Store + // use blockstore for the pruning functions. + blockStore BlockStore + // execute the app against this proxyApp proxy.AppConnConsensus @@ -57,16 +60,18 @@ func NewBlockExecutor( proxyApp proxy.AppConnConsensus, mempool mempool.Mempool, evpool EvidencePool, + blockStore BlockStore, options ...BlockExecutorOption, ) *BlockExecutor { res := &BlockExecutor{ - store: stateStore, - proxyApp: proxyApp, - eventBus: types.NopEventBus{}, - mempool: mempool, - evpool: evpool, - logger: logger, - metrics: NopMetrics(), + store: stateStore, + proxyApp: proxyApp, + eventBus: types.NopEventBus{}, + mempool: mempool, + evpool: evpool, + logger: logger, + metrics: NopMetrics(), + blockStore: blockStore, } for _, option := range options { @@ -182,28 +187,28 @@ func (blockExec *BlockExecutor) ValidateBlock(state State, block *types.Block) e // ApplyVerifiedBlock does the same as `ApplyBlock`, but skips verification. func (blockExec *BlockExecutor) ApplyVerifiedBlock( state State, blockID types.BlockID, block *types.Block, -) (State, int64, error) { +) (State, error) { return blockExec.applyBlock(state, blockID, block) } // ApplyBlock validates the block against the state, executes it against the app, // fires the relevant events, commits the app, and saves the new state and responses. -// It returns the new state and the block height to retain (pruning older blocks). +// It returns the new state. // It's the only function that needs to be called // from outside this package to process and commit an entire block. // It takes a blockID to avoid recomputing the parts hash. func (blockExec *BlockExecutor) ApplyBlock( state State, blockID types.BlockID, block *types.Block, -) (State, int64, error) { +) (State, error) { if err := validateBlock(state, block); err != nil { - return state, 0, ErrInvalidBlock(err) + return state, ErrInvalidBlock(err) } return blockExec.applyBlock(state, blockID, block) } -func (blockExec *BlockExecutor) applyBlock(state State, blockID types.BlockID, block *types.Block) (State, int64, error) { +func (blockExec *BlockExecutor) applyBlock(state State, blockID types.BlockID, block *types.Block) (State, error) { startTime := time.Now().UnixNano() abciResponses, err := execBlockOnProxyApp( blockExec.logger, blockExec.proxyApp, block, blockExec.store, state.InitialHeight, @@ -211,14 +216,14 @@ func (blockExec *BlockExecutor) applyBlock(state State, blockID types.BlockID, b endTime := time.Now().UnixNano() blockExec.metrics.BlockProcessingTime.Observe(float64(endTime-startTime) / 1000000) if err != nil { - return state, 0, ErrProxyAppConn(err) + return state, ErrProxyAppConn(err) } fail.Fail() // XXX // Save the results before we commit. if err := blockExec.store.SaveABCIResponses(block.Height, abciResponses); err != nil { - return state, 0, err + return state, err } fail.Fail() // XXX @@ -227,12 +232,12 @@ func (blockExec *BlockExecutor) applyBlock(state State, blockID types.BlockID, b abciValUpdates := abciResponses.EndBlock.ValidatorUpdates err = validateValidatorUpdates(abciValUpdates, state.ConsensusParams.Validator) if err != nil { - return state, 0, fmt.Errorf("error in validator updates: %v", err) + return state, fmt.Errorf("error in validator updates: %v", err) } validatorUpdates, err := types.PB2TM.ValidatorUpdates(abciValUpdates) if err != nil { - return state, 0, err + return state, err } if len(validatorUpdates) > 0 { blockExec.logger.Info("updates to validators", "updates", types.ValidatorListString(validatorUpdates)) @@ -245,13 +250,13 @@ func (blockExec *BlockExecutor) applyBlock(state State, blockID types.BlockID, b // Update the state with the block and responses. state, err = updateState(state, blockID, &block.Header, abciResponses, validatorUpdates) if err != nil { - return state, 0, fmt.Errorf("commit failed for application: %v", err) + return state, fmt.Errorf("commit failed for application: %v", err) } // Lock mempool, commit app state, update mempoool. appHash, retainHeight, err := blockExec.Commit(state, block, abciResponses.DeliverTxs) if err != nil { - return state, 0, fmt.Errorf("commit failed for application: %v", err) + return state, fmt.Errorf("commit failed for application: %v", err) } // Update evpool with the latest state. @@ -262,16 +267,26 @@ func (blockExec *BlockExecutor) applyBlock(state State, blockID types.BlockID, b // Update the app hash and save the state. state.AppHash = appHash if err := blockExec.store.Save(state); err != nil { - return state, 0, err + return state, err } fail.Fail() // XXX + // Prune old heights, if requested by ABCI app. + if retainHeight > 0 { + pruned, err := blockExec.pruneBlocks(retainHeight) + if err != nil { + blockExec.logger.Error("failed to prune blocks", "retain_height", retainHeight, "err", err) + } else { + blockExec.logger.Debug("pruned blocks", "pruned", pruned, "retain_height", retainHeight) + } + } + // Events are fired after everything else. // NOTE: if we crash between Commit and Save, events wont be fired during replay fireEvents(blockExec.logger, blockExec.eventBus, block, abciResponses, validatorUpdates) - return state, retainHeight, nil + return state, nil } // Commit locks the mempool, runs the ABCI Commit message, and updates the @@ -636,3 +651,20 @@ func ExecCommitBlock( // ResponseCommit has no error or log, just data return res.Data, nil } + +func (blockExec *BlockExecutor) pruneBlocks(retainHeight int64) (uint64, error) { + base := blockExec.blockStore.Base() + if retainHeight <= base { + return 0, nil + } + pruned, err := blockExec.blockStore.PruneBlocks(retainHeight) + if err != nil { + return 0, fmt.Errorf("failed to prune block store: %w", err) + } + + err = blockExec.Store().PruneStates(base, retainHeight) + if err != nil { + return 0, fmt.Errorf("failed to prune state store: %w", err) + } + return pruned, nil +} diff --git a/state/execution_test.go b/state/execution_test.go index 0c8a1685131..14cc14f9330 100644 --- a/state/execution_test.go +++ b/state/execution_test.go @@ -10,6 +10,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + dbm "github.com/cometbft/cometbft-db" abciclientmocks "github.com/cometbft/cometbft/abci/client/mocks" abci "github.com/cometbft/cometbft/abci/types" abcimocks "github.com/cometbft/cometbft/abci/types/mocks" @@ -25,6 +26,7 @@ import ( pmocks "github.com/cometbft/cometbft/proxy/mocks" sm "github.com/cometbft/cometbft/state" "github.com/cometbft/cometbft/state/mocks" + "github.com/cometbft/cometbft/store" "github.com/cometbft/cometbft/types" cmttime "github.com/cometbft/cometbft/types/time" "github.com/cometbft/cometbft/version" @@ -47,6 +49,8 @@ func TestApplyBlock(t *testing.T) { stateStore := sm.NewStore(stateDB, sm.StoreOptions{ DiscardABCIResponses: false, }) + blockStore := store.NewBlockStore(dbm.NewMemDB()) + mp := &mpmocks.Mempool{} mp.On("Lock").Return() mp.On("Unlock").Return() @@ -59,16 +63,15 @@ func TestApplyBlock(t *testing.T) { mock.Anything, mock.Anything).Return(nil) blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), - mp, sm.EmptyEvidencePool{}) + mp, sm.EmptyEvidencePool{}, blockStore) block := makeBlock(state, 1, new(types.Commit)) bps, err := block.MakePartSet(testPartSize) require.NoError(t, err) blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} - state, retainHeight, err := blockExec.ApplyBlock(state, blockID, block) + state, err = blockExec.ApplyBlock(state, blockID, block) require.Nil(t, err) - assert.EqualValues(t, retainHeight, 1) // TODO check state and mempool assert.EqualValues(t, 1, state.Version.Consensus.App, "App version wasn't updated") @@ -231,8 +234,10 @@ func TestBeginBlockByzantineValidators(t *testing.T) { mock.Anything, mock.Anything).Return(nil) + blockStore := store.NewBlockStore(dbm.NewMemDB()) + blockExec := sm.NewBlockExecutor(stateStore, log.TestingLogger(), proxyApp.Consensus(), - mp, evpool) + mp, evpool, blockStore) block := makeBlock(state, 1, new(types.Commit)) block.Evidence = types.EvidenceData{Evidence: ev} @@ -242,9 +247,8 @@ func TestBeginBlockByzantineValidators(t *testing.T) { blockID = types.BlockID{Hash: block.Hash(), PartSetHeader: bps.Header()} - state, retainHeight, err := blockExec.ApplyBlock(state, blockID, block) + state, err = blockExec.ApplyBlock(state, blockID, block) require.Nil(t, err) - assert.EqualValues(t, retainHeight, 1) // TODO check state and mempool assert.Equal(t, abciMb, app.Misbehavior) @@ -268,7 +272,7 @@ func TestProcessProposal(t *testing.T) { stateStore := sm.NewStore(stateDB, sm.StoreOptions{ DiscardABCIResponses: false, }) - + blockStore := store.NewBlockStore(dbm.NewMemDB()) eventBus := types.NewEventBus() err = eventBus.Start() require.NoError(t, err) @@ -279,6 +283,7 @@ func TestProcessProposal(t *testing.T) { proxyApp.Consensus(), new(mpmocks.Mempool), sm.EmptyEvidencePool{}, + blockStore, ) block0 := makeBlock(state, height-1, new(types.Commit)) @@ -488,12 +493,14 @@ func TestEndBlockValidatorUpdates(t *testing.T) { mock.Anything).Return(nil) mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs{}) + blockStore := store.NewBlockStore(dbm.NewMemDB()) blockExec := sm.NewBlockExecutor( stateStore, log.TestingLogger(), proxyApp.Consensus(), mp, sm.EmptyEvidencePool{}, + blockStore, ) eventBus := types.NewEventBus() @@ -522,7 +529,7 @@ func TestEndBlockValidatorUpdates(t *testing.T) { {PubKey: pk, Power: 10}, } - state, _, err = blockExec.ApplyBlock(state, blockID, block) + state, err = blockExec.ApplyBlock(state, blockID, block) require.Nil(t, err) // test new validator was added to NextValidators if assert.Equal(t, state.Validators.Size()+1, state.NextValidators.Size()) { @@ -562,12 +569,14 @@ func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { stateStore := sm.NewStore(stateDB, sm.StoreOptions{ DiscardABCIResponses: false, }) + blockStore := store.NewBlockStore(dbm.NewMemDB()) blockExec := sm.NewBlockExecutor( stateStore, log.TestingLogger(), proxyApp.Consensus(), new(mpmocks.Mempool), sm.EmptyEvidencePool{}, + blockStore, ) block := makeBlock(state, 1, new(types.Commit)) @@ -582,7 +591,7 @@ func TestEndBlockValidatorUpdatesResultingInEmptySet(t *testing.T) { {PubKey: vp, Power: 0}, } - assert.NotPanics(t, func() { state, _, err = blockExec.ApplyBlock(state, blockID, block) }) + assert.NotPanics(t, func() { state, err = blockExec.ApplyBlock(state, blockID, block) }) assert.NotNil(t, err) assert.NotEmpty(t, state.NextValidators.Validators) } @@ -614,12 +623,14 @@ func TestEmptyPrepareProposal(t *testing.T) { mock.Anything).Return(nil) mp.On("ReapMaxBytesMaxGas", mock.Anything, mock.Anything).Return(types.Txs{}) + blockStore := store.NewBlockStore(dbm.NewMemDB()) blockExec := sm.NewBlockExecutor( stateStore, log.TestingLogger(), proxyApp.Consensus(), mp, sm.EmptyEvidencePool{}, + blockStore, ) pa, _ := state.Validators.GetByIndex(0) commit, err := makeValidCommit(height, types.BlockID{}, state.Validators, privVals) @@ -655,12 +666,14 @@ func TestPrepareProposalTxsAllIncluded(t *testing.T) { require.NoError(t, err) defer proxyApp.Stop() //nolint:errcheck // ignore for tests + blockStore := store.NewBlockStore(dbm.NewMemDB()) blockExec := sm.NewBlockExecutor( stateStore, log.TestingLogger(), proxyApp.Consensus(), mp, evpool, + blockStore, ) pa, _ := state.Validators.GetByIndex(0) commit, err := makeValidCommit(height, types.BlockID{}, state.Validators, privVals) @@ -706,12 +719,14 @@ func TestPrepareProposalReorderTxs(t *testing.T) { require.NoError(t, err) defer proxyApp.Stop() //nolint:errcheck // ignore for tests + blockStore := store.NewBlockStore(dbm.NewMemDB()) blockExec := sm.NewBlockExecutor( stateStore, log.TestingLogger(), proxyApp.Consensus(), mp, evpool, + blockStore, ) pa, _ := state.Validators.GetByIndex(0) commit, err := makeValidCommit(height, types.BlockID{}, state.Validators, privVals) @@ -758,12 +773,14 @@ func TestPrepareProposalErrorOnTooManyTxs(t *testing.T) { require.NoError(t, err) defer proxyApp.Stop() //nolint:errcheck // ignore for tests + blockStore := store.NewBlockStore(dbm.NewMemDB()) blockExec := sm.NewBlockExecutor( stateStore, log.NewNopLogger(), proxyApp.Consensus(), mp, evpool, + blockStore, ) pa, _ := state.Validators.GetByIndex(0) commit, err := makeValidCommit(height, types.BlockID{}, state.Validators, privVals) @@ -812,12 +829,14 @@ func TestPrepareProposalCountSerializationOverhead(t *testing.T) { require.NoError(t, err) defer proxyApp.Stop() //nolint:errcheck // ignore for tests + blockStore := store.NewBlockStore(dbm.NewMemDB()) blockExec := sm.NewBlockExecutor( stateStore, log.NewNopLogger(), proxyApp.Consensus(), mp, evpool, + blockStore, ) pa, _ := state.Validators.GetByIndex(0) commit, err := makeValidCommit(height, types.BlockID{}, state.Validators, privVals) @@ -859,12 +878,14 @@ func TestPrepareProposalErrorOnPrepareProposalError(t *testing.T) { require.NoError(t, err) defer proxyApp.Stop() //nolint:errcheck // ignore for tests + blockStore := store.NewBlockStore(dbm.NewMemDB()) blockExec := sm.NewBlockExecutor( stateStore, log.NewNopLogger(), proxyApp.Consensus(), mp, evpool, + blockStore, ) pa, _ := state.Validators.GetByIndex(0) commit, err := makeValidCommit(height, types.BlockID{}, state.Validators, privVals) diff --git a/state/helpers_test.go b/state/helpers_test.go index e864c7c30f2..ef8200d13c0 100644 --- a/state/helpers_test.go +++ b/state/helpers_test.go @@ -68,7 +68,7 @@ func makeAndApplyGoodBlock(state sm.State, height int64, lastCommit *types.Commi } blockID := types.BlockID{Hash: block.Hash(), PartSetHeader: partSet.Header()} - state, _, err = blockExec.ApplyBlock(state, blockID, block) + state, err = blockExec.ApplyBlock(state, blockID, block) if err != nil { return state, types.BlockID{}, err } diff --git a/state/validation_test.go b/state/validation_test.go index 96be61cd08b..c527f54971b 100644 --- a/state/validation_test.go +++ b/state/validation_test.go @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + dbm "github.com/cometbft/cometbft-db" abci "github.com/cometbft/cometbft/abci/types" "github.com/cometbft/cometbft/crypto/ed25519" "github.com/cometbft/cometbft/crypto/tmhash" @@ -17,6 +18,7 @@ import ( cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" sm "github.com/cometbft/cometbft/state" "github.com/cometbft/cometbft/state/mocks" + "github.com/cometbft/cometbft/store" "github.com/cometbft/cometbft/types" cmttime "github.com/cometbft/cometbft/types/time" ) @@ -44,12 +46,15 @@ func TestValidateBlockHeader(t *testing.T) { mock.Anything, mock.Anything).Return(nil) + blockStore := store.NewBlockStore(dbm.NewMemDB()) + blockExec := sm.NewBlockExecutor( stateStore, log.TestingLogger(), proxyApp.Consensus(), mp, sm.EmptyEvidencePool{}, + blockStore, ) lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil) @@ -129,12 +134,15 @@ func TestValidateBlockCommit(t *testing.T) { mock.Anything, mock.Anything).Return(nil) + blockStore := store.NewBlockStore(dbm.NewMemDB()) + blockExec := sm.NewBlockExecutor( stateStore, log.TestingLogger(), proxyApp.Consensus(), mp, sm.EmptyEvidencePool{}, + blockStore, ) lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil) wrongSigsCommit := types.NewCommit(1, 0, types.BlockID{}, nil) @@ -268,12 +276,15 @@ func TestValidateBlockEvidence(t *testing.T) { mock.Anything, mock.Anything).Return(nil) state.ConsensusParams.Evidence.MaxBytes = 1000 + blockStore := store.NewBlockStore(dbm.NewMemDB()) + blockExec := sm.NewBlockExecutor( stateStore, log.TestingLogger(), proxyApp.Consensus(), mp, evpool, + blockStore, ) lastCommit := types.NewCommit(0, 0, types.BlockID{}, nil)