Skip to content

Commit

Permalink
perf(consensus): add simplistic block validation cache (cometbft#3070) (
Browse files Browse the repository at this point in the history
#133)

Closes cometbft#2854

Follow up from cometbft#2960

This PR adds a simplistic 1-element block validation cache in
`BlockExecutor`. This addresses a performance bottleneck raised as part
of cometbft#2854

---

- [ ] Tests written/updated
- [ ] Changelog entry added in `.changelog` (we use
[unclog](https://github.com/informalsystems/unclog) to manage our
changelog)
- [ ] Updated relevant documentation (`docs/` or `spec/`) and code
comments
- [ ] Title follows the [Conventional
Commits](https://www.conventionalcommits.org/en/v1.0.0/) spec

---------

Co-authored-by: Sergio Mena <sergio@informal.systems>
Co-authored-by: Andy Nogueira <me@andynogueira.dev>
  • Loading branch information
3 people authored Aug 19, 2024
1 parent 4e0fc75 commit 8b6562b
Showing 1 changed file with 13 additions and 7 deletions.
20 changes: 13 additions & 7 deletions state/execution.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ type BlockExecutor struct {
mempool mempool.Mempool
evpool EvidencePool

// 1-element cache of validated blocks
lastValidatedBlock *types.Block

logger log.Logger

metrics *Metrics
Expand Down Expand Up @@ -188,9 +191,11 @@ func (blockExec *BlockExecutor) ProcessProposal(
// Validation does not mutate state, but does require historical information from the stateDB,
// ie. to verify evidence from a validator at an old height.
func (blockExec *BlockExecutor) ValidateBlock(state State, block *types.Block) error {
err := validateBlock(state, block)
if err != nil {
return err
if !blockExec.lastValidatedBlock.HashesTo(block.Hash()) {
if err := validateBlock(state, block); err != nil {
return err
}
blockExec.lastValidatedBlock = block
}
return blockExec.evpool.CheckEvidence(block.Evidence.Evidence)
}
Expand All @@ -211,11 +216,12 @@ func (blockExec *BlockExecutor) ApplyVerifiedBlock(
func (blockExec *BlockExecutor) ApplyBlock(
state State, blockID types.BlockID, block *types.Block,
) (State, error) {

if err := validateBlock(state, block); err != nil {
return state, ErrInvalidBlock(err)
if !blockExec.lastValidatedBlock.HashesTo(block.Hash()) {
if err := validateBlock(state, block); err != nil {
return state, ErrInvalidBlock(err)
}
blockExec.lastValidatedBlock = block
}

return blockExec.applyBlock(state, blockID, block)
}

Expand Down

0 comments on commit 8b6562b

Please sign in to comment.