Skip to content

flatkv cache#3027

Open
cody-littley wants to merge 89 commits intomainfrom
cjl/flatkv-cache
Open

flatkv cache#3027
cody-littley wants to merge 89 commits intomainfrom
cjl/flatkv-cache

Conversation

@cody-littley
Copy link
Contributor

@cody-littley cody-littley commented Mar 5, 2026

Describe your changes and provide context

Add a caching layer to FlatKV, more than doubling performance in cryptosim benchmarks.

Testing performed to validate your change

Unit tests, ran benchmark over several days.

@github-actions
Copy link

github-actions bot commented Mar 5, 2026

The latest Buf updates on your PR. Results from workflow Buf / buf (pull_request).

BuildFormatLintBreakingUpdated (UTC)
✅ passed✅ passed✅ passed✅ passedMar 20, 2026, 4:09 PM

@codecov
Copy link

codecov bot commented Mar 6, 2026

Codecov Report

❌ Patch coverage is 74.07407% with 105 lines in your changes missing coverage. Please review.
✅ Project coverage is 58.46%. Comparing base (02b141d) to head (38ffd35).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
sei-db/state_db/sc/flatkv/store_write.go 79.45% 17 Missing and 13 partials ⚠️
sei-db/db_engine/pebbledb/db.go 60.34% 18 Missing and 5 partials ⚠️
sei-db/state_db/sc/flatkv/config.go 62.71% 11 Missing and 11 partials ⚠️
sei-db/state_db/sc/flatkv/store.go 77.77% 7 Missing and 7 partials ⚠️
sei-db/db_engine/pebbledb/pebbledb_config.go 55.55% 4 Missing and 4 partials ⚠️
sei-cosmos/storev2/rootmulti/store.go 20.00% 2 Missing and 2 partials ⚠️
sei-db/db_engine/pebbledb/batch.go 60.00% 1 Missing and 1 partial ⚠️
sei-db/state_db/sc/composite/store.go 71.42% 1 Missing and 1 partial ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #3027      +/-   ##
==========================================
- Coverage   58.71%   58.46%   -0.25%     
==========================================
  Files        2094     2093       -1     
  Lines      172970   172886      -84     
==========================================
- Hits       101555   101082     -473     
- Misses      62430    62826     +396     
+ Partials     8985     8978       -7     
Flag Coverage Δ
sei-chain-pr 67.37% <74.07%> (?)
sei-db 70.41% <ø> (ø)

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
sei-db/common/metrics/phase_timer.go 74.46% <100.00%> (+0.55%) ⬆️
sei-db/config/sc_config.go 100.00% <ø> (ø)
sei-db/db_engine/pebbledb/pebble_metrics.go 69.09% <100.00%> (ø)
sei-db/db_engine/pebbledb/pebbledb_test_config.go 100.00% <100.00%> (ø)
sei-db/db_engine/types/types.go 100.00% <ø> (ø)
sei-db/state_db/sc/flatkv/flatkv_test_config.go 100.00% <100.00%> (ø)
sei-db/state_db/sc/flatkv/snapshot.go 66.86% <100.00%> (+0.29%) ⬆️
sei-db/state_db/sc/flatkv/store_lifecycle.go 62.50% <100.00%> (+0.52%) ⬆️
sei-db/state_db/sc/flatkv/store_read.go 59.52% <ø> (-4.82%) ⬇️
sei-db/db_engine/pebbledb/batch.go 88.23% <60.00%> (-11.77%) ⬇️
... and 7 more

... and 113 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cody-littley cody-littley marked this pull request as ready for review March 20, 2026 15:23
}

return store
return store, nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of changing the interface to return an error, wouldn't it be easier to just panic inside this constructor? Is there any benefit to return the error if we failed to create the store?


// FlatKVConfig is the configuration for the FlatKV (EVM) backend
FlatKVConfig flatkv.Config
FlatKVConfig *flatkv.Config
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to make this a pointer?

if err := scStore.CleanupCrashArtifacts(); err != nil {
panic(err)
}
if err := scStore.CleanupCrashArtifacts(); err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate CleanupCrashArtifacts call here, we should remove the one above?

return fmt.Errorf("failed to batch read old values: %w", err)
}

s.phaseTimer.SetPhase("apply_change_sets_prepare")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate code s.phaseTimer.SetPhase("apply_change_sets_prepare")

)

// Configuration for the PebbleDB database.
type PebbleDBConfig struct {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These configs are not specific to PebbleDB, instead, they are specific to flatkv, I think we should move them to flatkv instead of put them here, we could change the db engine in the future for flatkv, but these configs are universal to all db engines

// The number of shards in the key-value cache. Must be a power of two and greater than 0.
CacheShardCount uint64
// The size of pebbleDB's internal block cache, in bytes.
BlockCacheSize int
Copy link
Contributor

@yzang2019 yzang2019 Mar 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would recommend remove this BlockCacheSize from the config, we can set a tuned default value for now, we can add it in the future if we are 100% sure we need a different specific value for each DB.
In any way, we are not going rely on the PebbleDB internal cache for read optimization, so would recommend maybe just set a default number

opts types.OpenOptions,
enableMetrics bool,
config *PebbleDBConfig,
comparer *pebble.Comparer,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have to pass the comparer in? Under what scenario will we pass in a custom comparer?

return fmt.Errorf("account db config is invalid: %w", c.AccountDBConfig.Validate())
}
if c.CodeDBConfig.Validate() != nil {
return fmt.Errorf("code db config is invalid: %w", c.CodeDBConfig.Validate())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: We shouldn't need to call Validate() twice here

return fmt.Errorf("metadata db config is invalid: %w", c.MetadataDBConfig.Validate())
}

if c.ReaderThreadsPerCore < 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If ReaderThreadsPerCore == 0, and ReaderConstantThreadCount == 0, it will create a pool with 0 workers, causing deadlock issue?

if c.DataDir == "" {
return fmt.Errorf("data dir is required")
}
if c.CacheSize > 0 && (c.CacheShardCount&(c.CacheShardCount-1)) != 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we also validate and make sure CacheShardCount > 0?

@yzang2019
Copy link
Contributor

One blocker comment: I think we should decouple cache from db_engine as much as possible, which allows FlatKV to switch different db_engine easily without reimplmenting the cache for each engine in the future

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants