-
Notifications
You must be signed in to change notification settings - Fork 708
feat: cache validator workload in BuildLastCommitInfo for 28x performance improvement #5421
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
state/execution.go
Outdated
} | ||
|
||
// ExecCommitBlockWithCache is an optimized version that uses caching for better performance | ||
func (blockExec *BlockExecutor) ExecCommitBlockWithCache( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is unused. looks like the previous ExecCommitBlock
is only used when replaying blocks. do we want to use that there?
state/execution.go
Outdated
} | ||
|
||
// ClearValidatorCache clears the validator caches to free memory | ||
func (blockExec *BlockExecutor) ClearValidatorCache() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is unused except in tests, so the part of your test that is testing cache clearing isn't really testing anything
validatorCache: make(map[int64]*types.ValidatorSet), | ||
abciValidatorCache: make(map[string]abci.Validator), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in real execution, no values from these caches are ever removed, so these will grow forever. We will need someway to periodically remove elements from them.
state/execution.go
Outdated
commitSig := block.LastCommit.Signatures[i] | ||
|
||
// Create cache key for this validator | ||
cacheKey := fmt.Sprintf("%s_%d", val.PubKey.Address(), val.VotingPower) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
from my understanding the point of the abciValidatorCache
is to not have to do the expensive val.PubKey.Address()
call. however you are calling val.PubKey.Address()
when generating the cacheKey
. doesn't this eliminate most of the point of the cache?
|
||
// Cleanup old cache entries if needed | ||
blockExec.cleanupOldCacheEntries() | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug: Validator Cache Issues in ABCI
The abciValidatorCache
in BuildLastCommitInfoWithCache
has a few problems: it uses a manual abci.Validator
conversion that may miss important logic, its cache key (validator address) can lead to stale voting power if power changes, and it has a race condition allowing redundant conversions and cache writes.
Summary
Implements caching for
state.BuildLastCommitInfo
to eliminate performance bottlenecks in consensus operations.Changes
BlockExecutor
BuildLastCommitInfoFromStoreWithCache
andBuildLastCommitInfoWithCache
methodsapplyBlock
,ExtendVote
,ProcessProposal
ClearValidatorCache()
for memory managementPerformance Impact
Fixes #3152
Note
Introduce cached validator/ABCI validator lookups in
BuildLastCommitInfo
and update call sites for faster block processing.state/execution.go
):validatorCache
andabciValidatorCache
with RW locks toBlockExecutor
.BuildLastCommitInfoFromStoreWithCache
,BuildLastCommitInfoWithCache
, andClearValidatorCache
.buildLastCommitInfoFromStore
inProcessProposal
,FinalizeBlock
path (applyBlock
), andExtendVote
with cached variants.NewBlockExecutor
.ExecCommitBlockWithCache
helper.state/execution_test.go
):Written by Cursor Bugbot for commit 5663a3f. This will update automatically on new commits. Configure here.