forked from cosmos/cosmos-sdk
-
Notifications
You must be signed in to change notification settings - Fork 7
perf: optimise staking endblocker #1725
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
Merged
randy-cro
merged 151 commits into
crypto-org-chain:release/v0.50.x
from
randy-cro:debug/validator-queue
Oct 15, 2025
Merged
Changes from 87 commits
Commits
Show all changes
151 commits
Select commit
Hold shift + click to select a range
61cb8ea
add debug query for validator queue
randy-cro eccd06c
add debug timing logs
randy-cro b65f034
add more logs
randy-cro 2cc87de
add more debug logs
randy-cro 04160e6
chore:optimise staking endblocker iteration
randy-cro 516bb74
move queue iteration cache to in memory
randy-cro ee2bfce
add logs for debug
randy-cro ff3be06
fix compile
randy-cro 0a5f23c
fix test
randy-cro d2d3d64
comment out arg for convenience first
randy-cro afa075c
change keeper to receiver
randy-cro 066b93d
clean up code
randy-cro fbb339e
add logs
randy-cro 50d37d2
add more logs
randy-cro dd1902c
update keeper to pointers
randy-cro 3a34881
remove count
randy-cro 692150e
try reverse iterator
randy-cro cd61c5d
Revert "try reverse iterator"
randy-cro 612e30b
test out parallel iterators
randy-cro 0f96812
amalgamate errors before returning + remove waitgroup + close all ite…
randy-cro 12afbdd
add debug logs
randy-cro 71d3ebb
fix lowest height not saved
randy-cro 2401845
fix logging
randy-cro d88f5ea
remove debug staking query
randy-cro e86016c
code clean up and remove logs
randy-cro d70e018
remove debug logs
randy-cro 4459c77
proto-gen
randy-cro 99af2c5
backport refactor(x/staking)!: removing unbonding queue index (#22795)
randy-cro 99d87d7
move QueueLastProcessedState out of proto
randy-cro 92ec94f
fix:simapp build
randy-cro cfd7f5e
fix lint
randy-cro db6ec61
fix race
randy-cro 3667e94
fix panic
randy-cro 226098a
fix comments
randy-cro bbc455e
update CHANGELOG
randy-cro 10a7d4b
fix lint
randy-cro 4929fec
fix lint
randy-cro 7dabbad
remove integration test for unbonding as per backport
randy-cro 5a3e8da
remove unneccessary pointers
randy-cro 1d53ef4
fix integration test
randy-cro e97d516
add test cases
randy-cro 27493d5
minor optimisation
randy-cro a2fd275
check QueueLastProcessedState update state
randy-cro 62c0a20
remove logs
randy-cro efab08f
fix unbondallMatureValidators iteration
randy-cro d78c0e4
optimise lower bound height to be the lowest height of all unbonding …
randy-cro ecccd8c
minor changes
randy-cro d3ff394
minor changes
randy-cro de99781
minor changes
randy-cro a3e3d9f
fix tests
randy-cro cf60463
fix build
randy-cro d219c93
check iterator not nil before closing
randy-cro 0fc6198
update CHANGELOG.md
randy-cro 36c60a9
fix test and add more tests
randy-cro 6e9830f
try no op for testnet node to catchup (to be reverted)
randy-cro 8f71d3b
Revert "try no op for testnet node to catchup (to be reverted)"
randy-cro b0f0509
add caching for unbonding validators, unbonding delegations and redel…
randy-cro 88ee543
update delimiter for validator queue key to be '/'
randy-cro 7aa9bba
add getter and setter for caches
randy-cro 0be8a53
add test for unbonding validators
randy-cro 8daabd2
remove old tests
randy-cro ea08a6d
add timing logs to track
randy-cro 3a9963a
Revert "add timing logs to track"
randy-cro 788712c
change some keeper methods to pointer + rename function names
randy-cro fa9afaa
add delegation tests
randy-cro 83a9838
rename function name
randy-cro cc19a8a
add redelegation tests
randy-cro 835fbd8
fix test
randy-cro 8e92d20
update store before cache to prevent the need to rollback should pers…
randy-cro f6daf14
update store before cache to prevent the need to rollback should pers…
randy-cro 6d1197b
do not remove non-mature unbonds and redelegations
randy-cro 36994e3
fix lint
randy-cro ae29d02
gofumpt formatting
randy-cro 7766d61
add function comments
randy-cro 0049866
remove unnecessary empty variable
randy-cro 5874b9c
fix comments
randy-cro cd7b3a6
update CHANGELOG
randy-cro e3249d3
use common blockTime variable
randy-cro c9f93a8
remove redundant pairs and triplets variables
randy-cro 97f93a6
sort keys by ascending timestamp + add tests
randy-cro a821923
retrieve all unbonding delegations, reldegations, and unbonding valid…
randy-cro 3bb3625
Merge remote-tracking branch 'crypto/release/v0.50.x' into debug/vali…
randy-cro cb08219
update unbonding validators to use cache
randy-cro b052bd7
add comments to functions
randy-cro 3286d6c
update unbonding delegations and redelegations to use cache too
randy-cro dfd33e1
minor changes + formatting
randy-cro 758c901
expose max size parameter for cache initialization + simplify cache …
randy-cro 65464da
avoid getting cache when overflow is true + return empty slice instea…
randy-cro 99c1163
open store and delete entries for unbonding delegation and redelegati…
randy-cro 707fe35
fix cache to only allow slices as value
randy-cro 099c766
check overflow with slices length instead of key length + deep copy w…
randy-cro 019d251
fix get cache race condition
randy-cro 2683f10
refactor Slice to slice
randy-cro 0bd6e70
update Cache to ValidatorsCache so that it is less generic
randy-cro e8ec78b
encapsulate overflow boolean whenever getting the cache
randy-cro 3259e9d
refactor overflow to invalidated for greater semantic clarity
randy-cro 4fba2ea
initialize pending redelegations before setting new entry
randy-cro 88b0e90
init unbonding delegations / unbonding validator cache using common m…
randy-cro c2b8b34
minor optimization
randy-cro 8be7403
adding of comments for functions + minor changes
randy-cro b9f2f24
add cache related test for unbonding validators/unbonding delegations…
randy-cro 05dc22e
remove redundancy
randy-cro 1bf414c
refactor invalidated to full
randy-cro 045fda3
use keys for map length comparison
randy-cro 141cecb
refactor cache names
randy-cro abb4652
refactor unbonding validator queue cache
randy-cro a93bf2c
use preallocation and early exit when its full
randy-cro e56f0bf
use common method for logger
randy-cro 6958418
revert unneeded pointer methods
randy-cro d573545
add guard for cache
randy-cro 17b3759
refactor validator queue cache
randy-cro 0047c82
small change
randy-cro e5ca154
return error when setting if its not about max cache
randy-cro f1e6459
fix full check and setQueueEntry check to include reinitialization if…
randy-cro 6cee0d6
handle dirty outside cache, remove getEntry, set full as true upon hi…
randy-cro 1d41769
minor change
randy-cro 257ac7c
remove redundant need to set dirty to true if reinitialization fails
randy-cro 7e04788
refactor getFromStore to loadFromStore
randy-cro 8464abf
minor change
randy-cro 073667c
add guard to setEntry
randy-cro 92fe032
optimise GetUnbondingValidatorsQueueEntry
randy-cro add7515
combine max < 0 and data == nil checks
randy-cro 26b2faa
set dirty as false only if setting all keys are successful + move che…
randy-cro 76cb8ec
return empty map or empty slice instead of nil for get and getEntry
randy-cro 68080e0
fix unbonding validator error log
randy-cro f2bb298
add unbonding delegations into cache
randy-cro bc8b1e7
add redelegations queue into cache
randy-cro 4cbfed8
minor changes to validator queue function comments
randy-cro 1ef546b
initialize cache only if size is greater than 0
randy-cro 9921cdc
fix keeper test to have large cache
randy-cro 6d39fc3
add cache size to validator tests
randy-cro 7af0724
add cache size to delegation and redelegation tests
randy-cro 43ae90a
add clear function to refresh cache when reloading
randy-cro 35e1483
add cache tests
randy-cro cd1e537
fix tests
randy-cro b9b2082
optional maxCacheSize in dependency injection
randy-cro 91ed613
remove unneeded pointer methods
randy-cro d43ebe7
gofumpt
randy-cro 7181279
fix lint make CacheEntry exportable
randy-cro a7ac2af
remove redundant change
randy-cro ca0181d
add staking cache flag
randy-cro ae8b7c4
remove redundancy
randy-cro 79b984a
add dependency injection flag
randy-cro f6adffd
fix dependency injection
randy-cro e0c3838
change cache size = 0 means unlimited and if size < 0 do not initiali…
randy-cro bd9d391
fix logger text
randy-cro 1ae24ec
encapsulate cache initiation with NewValidatorsQueueCache constructor
randy-cro 22f48a8
return nil for DequeueAllMatureRedelegationQueue
randy-cro f1c53f9
log cache errors and fallback to store instead of returning error to …
randy-cro 9234e3a
change full and dirty to atomic bool to protect against race
randy-cro 0ab9f6b
remove cache warnings since errors are logged on the caller
randy-cro File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,163 @@ | ||
| package cache | ||
|
|
||
| import ( | ||
| "sync" | ||
|
|
||
| "github.com/cosmos/cosmos-sdk/x/staking/types" | ||
| ) | ||
|
|
||
| type cacheEntry[K comparable, V any] struct { | ||
| mu sync.RWMutex | ||
| data map[K]V | ||
| overflowed bool | ||
| // max defines the maximum number of entries in each cache map | ||
| // to prevent OOM attacks. | ||
| // - if max == 0, there is no cap on the number of entries in the cache | ||
| // - if max > 0, the cache will cap the number of entries it stores | ||
| // - if max < 0, the cache is a no-op cache. | ||
| max int | ||
| } | ||
|
|
||
| func newCacheEntry[K comparable, V any](max int) *cacheEntry[K, V] { | ||
| return &cacheEntry[K, V]{ | ||
| max: max, | ||
| } | ||
| } | ||
|
|
||
| func (e *cacheEntry[K, V]) get() map[K]V { | ||
randy-cro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| e.mu.RLock() | ||
randy-cro marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| defer e.mu.RUnlock() | ||
| return e.data | ||
| } | ||
|
|
||
| func (e *cacheEntry[K, V]) set(data map[K]V) { | ||
| if e.max < 0 { | ||
| return | ||
| } | ||
|
|
||
| e.mu.Lock() | ||
| defer e.mu.Unlock() | ||
|
|
||
| if e.max > 0 && len(data) > e.max { | ||
| e.overflowed = true | ||
| return | ||
| } | ||
|
|
||
| e.data = data | ||
randy-cro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| e.overflowed = false | ||
| } | ||
|
|
||
| func (e *cacheEntry[K, V]) setEntry(key K, value V) { | ||
| if e.max < 0 { | ||
| return | ||
| } | ||
|
|
||
| e.mu.Lock() | ||
| defer e.mu.Unlock() | ||
|
|
||
randy-cro marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if e.max > 0 && len(e.data) >= e.max { | ||
| if _, exists := e.data[key]; !exists { | ||
| e.overflowed = true | ||
| return | ||
| } | ||
| } | ||
|
|
||
| if e.data == nil { | ||
| e.data = make(map[K]V) | ||
| } | ||
|
|
||
| e.data[key] = value | ||
| } | ||
|
|
||
| func (e *cacheEntry[K, V]) deleteEntry(key K) { | ||
| if e.max < 0 { | ||
| return | ||
| } | ||
|
|
||
| e.mu.Lock() | ||
| defer e.mu.Unlock() | ||
|
|
||
| if e.data != nil { | ||
| delete(e.data, key) | ||
randy-cro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| } | ||
|
|
||
| func (e *cacheEntry[K, V]) hasOverflowed() bool { | ||
| e.mu.RLock() | ||
| defer e.mu.RUnlock() | ||
| return e.overflowed | ||
| } | ||
|
|
||
| type Cache struct { | ||
randy-cro marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| unbondingValidators *cacheEntry[string, []string] | ||
| unbondingDelegations *cacheEntry[string, []types.DVPair] | ||
| redelegations *cacheEntry[string, []types.DVVTriplet] | ||
| } | ||
|
|
||
| func NewCache(max int) *Cache { | ||
| return &Cache{ | ||
| unbondingValidators: newCacheEntry[string, []string](max), | ||
| unbondingDelegations: newCacheEntry[string, []types.DVPair](max), | ||
| redelegations: newCacheEntry[string, []types.DVVTriplet](max), | ||
| } | ||
| } | ||
|
|
||
| func (c *Cache) GetUnbondingValidators() map[string][]string { | ||
| return c.unbondingValidators.get() | ||
| } | ||
|
|
||
| func (c *Cache) SetUnbondingValidators(validators map[string][]string) { | ||
| c.unbondingValidators.set(validators) | ||
| } | ||
|
|
||
| func (c *Cache) SetUnbondingValidatorEntry(key string, addrs []string) { | ||
| c.unbondingValidators.setEntry(key, addrs) | ||
| } | ||
|
|
||
| func (c *Cache) DeleteUnbondingValidatorEntry(key string) { | ||
| c.unbondingValidators.deleteEntry(key) | ||
| } | ||
|
|
||
| func (c *Cache) HasUnbondingValidatorsOverflowed() bool { | ||
| return c.unbondingValidators.hasOverflowed() | ||
| } | ||
|
|
||
| func (c *Cache) GetUnbondingDelegations() map[string][]types.DVPair { | ||
| return c.unbondingDelegations.get() | ||
| } | ||
|
|
||
| func (c *Cache) SetUnbondingDelegations(delegations map[string][]types.DVPair) { | ||
| c.unbondingDelegations.set(delegations) | ||
| } | ||
|
|
||
| func (c *Cache) SetUnbondingDelegationEntry(key string, pairs []types.DVPair) { | ||
| c.unbondingDelegations.setEntry(key, pairs) | ||
| } | ||
|
|
||
| func (c *Cache) DeleteUnbondingDelegationEntry(key string) { | ||
| c.unbondingDelegations.deleteEntry(key) | ||
| } | ||
|
|
||
| func (c *Cache) HasUnbondingDelegationsOverflowed() bool { | ||
| return c.unbondingDelegations.hasOverflowed() | ||
| } | ||
|
|
||
| func (c *Cache) GetRedelegations() map[string][]types.DVVTriplet { | ||
| return c.redelegations.get() | ||
| } | ||
|
|
||
| func (c *Cache) SetRedelegations(reds map[string][]types.DVVTriplet) { | ||
| c.redelegations.set(reds) | ||
| } | ||
|
|
||
| func (c *Cache) SetRedelegationEntry(key string, triplets []types.DVVTriplet) { | ||
| c.redelegations.setEntry(key, triplets) | ||
| } | ||
|
|
||
| func (c *Cache) DeleteRedelegationEntry(key string) { | ||
| c.redelegations.deleteEntry(key) | ||
| } | ||
|
|
||
| func (c *Cache) HasRedelegationsOverflowed() bool { | ||
| return c.redelegations.hasOverflowed() | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.