Skip to content

Performance: Add warmup cache#18473

Merged
Giulio2002 merged 43 commits intomainfrom
parallel-commitment-giulio-2
Jan 25, 2026
Merged

Performance: Add warmup cache#18473
Giulio2002 merged 43 commits intomainfrom
parallel-commitment-giulio-2

Conversation

@Giulio2002
Copy link
Copy Markdown
Collaborator

@Giulio2002 Giulio2002 commented Dec 25, 2025

This PR introduces a warmup cache for the commitment trie processing that reduces redundant DB reads during block execution. Data fetched during the warmup phase is cached and reused during the actual trie computation, improving performance.

Key Changes

  • New WarmupCache - A cache that stores pre-fetched branch, account, and storage data using maphash.Map for efficient byte slice lookups without allocations
  • Cache integration in Warmuper - The warmuper now optionally caches data it reads, making it available during trie processing
  • BranchEncoder cache support - Branch lookups check the cache first before hitting the DB
  • Key eviction - Keys being modified are evicted from the cache to ensure consistency

Architecture Diagram

┌─────────────────────────────────────────────────────────────────────┐
│                        Block Execution                               │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                          Warmuper                                    │
│  ┌──────────────────┐    ┌──────────────────┐                       │
│  │  Parallel Workers │───▶│   WarmupCache    │                       │
│  │  (prefetch data)  │    │                  │                       │
│  └──────────────────┘    │  ┌────────────┐  │                       │
│                          │  │  branches  │  │                       │
│                          │  ├────────────┤  │                       │
│                          │  │  accounts  │  │                       │
│                          │  ├────────────┤  │                       │
│                          │  │  storage   │  │                       │
│                          │  └────────────┘  │                       │
│                          └────────┬─────────┘                       │
└───────────────────────────────────┼─────────────────────────────────┘
                                    │
                    ┌───────────────┴───────────────┐
                    │         Cache Lookup          │
                    ▼                               ▼
         ┌─────────────────┐             ┌─────────────────┐
         │   Cache Hit     │             │   Cache Miss    │
         │  (return data)  │             │   (read DB)     │
         └─────────────────┘             └─────────────────┘
                                                  │
                                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                     HexPatriciaHashed Trie                          │
│                                                                      │
│   Process() ──▶ BranchEncoder.CollectUpdate()                       │
│                        │                                             │
│                        ▼                                             │
│              ┌─────────────────┐                                    │
│              │ Check WarmupCache│                                    │
│              │   for branch     │                                    │
│              └────────┬────────┘                                    │
│                       │                                              │
│           ┌───────────┴───────────┐                                 │
│           ▼                       ▼                                 │
│     Cache Hit               Cache Miss                              │
│   (skip DB read)          (read from DB)                            │
│                                                                      │
└─────────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      Key Eviction Flow                              │
│                                                                      │
│   Updates.HashSort() ──▶ For each modified key:                     │
│                              cache.EvictKey(key)                    │
│                                                                      │
│   (Ensures modified keys are re-read from DB, not stale cache)     │
└─────────────────────────────────────────────────────────────────────┘

Giulio added 2 commits January 3, 2026 22:37
Comment thread execution/commitment/hex_patricia_hashed.go
Comment thread execution/commitment/hex_patricia_hashed.go Outdated
Comment thread execution/commitment/warmup_cache_test.go Outdated
@Giulio2002 Giulio2002 enabled auto-merge (squash) January 5, 2026 21:56
Giulio and others added 3 commits January 11, 2026 12:09
@Giulio2002 Giulio2002 requested a review from domiwei as a code owner January 11, 2026 18:17
Giulio and others added 4 commits January 11, 2026 19:17
Comment thread execution/stagedsync/exec3.go Outdated
Copy link
Copy Markdown
Contributor

@mh0lt mh0lt left a comment

Choose a reason for hiding this comment

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

How is this code dealing with hash collisions ?

Given that you are using a 64 bit hash this is quite likely, if this happens the value returned won't necessarily be for the expected key - which is likely to cause hard to debug issues.

@Giulio2002
Copy link
Copy Markdown
Collaborator Author

@mh0lt this is not likely, do the math yourself. it is very hard even with birthday paradox

@Giulio2002
Copy link
Copy Markdown
Collaborator Author

Screenshot 2026-01-24 alle 16 35 12

here is the math, thanks to claude. it become significant if someone can spam it with 100million kvs but this is not actualizable since the attacker has no way of knowing the seed and has limited attack. this is also a method Nethermind uses

@Giulio2002
Copy link
Copy Markdown
Collaborator Author

btw in the entire history of the chain there is 100% a collision no doubt but for it to happen, you need to use THAT pair and that probability is actually bounded in the best-case (pessimistic) by random reads. in reality, we dont do random reads in blockchain. pattern exists so even that pessimistic unlikely case is too optimistic.

@Giulio2002
Copy link
Copy Markdown
Collaborator Author

@antonis19 can you approve?

Comment on lines +230 to +237
if be.cache != nil {
prev, prevStep, foundInCache = be.cache.GetAndEvictBranch(prefix)
}
if !foundInCache {
prev, prevStep, err = ctx.Branch(prefix)
if err != nil {
return 0, err
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This code can be simplified into ctx.Branch(prefix) the behavior will be different based on the concrete type of ctx (i.e if it is with cache or without cache)

if !cell.loaded.storage() {
hph.metrics.StorageLoad(cell.storageAddr[:cell.storageAddrLen])
update, err := hph.ctx.Storage(cell.storageAddr[:cell.storageAddrLen])
update, err := hph.storageFromCacheOrDB(cell.storageAddr[:cell.storageAddrLen])
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Can use hph.ctx , just have 2 concrete implementations (1 with cache, 1 without). The desired implementation can be instantiated based on the config

@Giulio2002 Giulio2002 merged commit d5e202a into main Jan 25, 2026
21 of 24 checks passed
@Giulio2002 Giulio2002 deleted the parallel-commitment-giulio-2 branch January 25, 2026 16:31
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.

6 participants