-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Tracking: Trie ChangeSets #18460
Copy link
Copy link
Closed
11 / 1111 of 11 issues completedLabels
A-dbRelated to the databaseRelated to the databaseA-engineRelated to the engine implementationRelated to the engine implementationA-trieRelated to Merkle Patricia Trie implementationRelated to Merkle Patricia Trie implementationC-enhancementNew feature or requestNew feature or requestC-perfA change motivated by improving speed, memory usage or disk footprintA change motivated by improving speed, memory usage or disk footprintC-tracking-issueAn issue that collects information about a broad development initiativeAn issue that collects information about a broad development initiative
Milestone
Metadata
Metadata
Assignees
Labels
A-dbRelated to the databaseRelated to the databaseA-engineRelated to the engine implementationRelated to the engine implementationA-trieRelated to Merkle Patricia Trie implementationRelated to Merkle Patricia Trie implementationC-enhancementNew feature or requestNew feature or requestC-perfA change motivated by improving speed, memory usage or disk footprintA change motivated by improving speed, memory usage or disk footprintC-tracking-issueAn issue that collects information about a broad development initiativeAn issue that collects information about a broad development initiative
Type
Projects
Status
Completed
Describe the feature
Whenever dealing with the tries and trie updates we have to carefully consider which block the DB tip was synced to when an operation started, and then later when persisting trie updates we have to consider if the trie updates are still valid given a potentially updated DB tip.
This complexity has recently bitten us and caused a major outage on mainnet.
In addition the current design is quite slow during reorg situations: we are forced to fallback to the slower ParallelStateRoot implementation (rather than the faster ParallelSparseTrie) during validation if the block being validated does not connect to the database tip. ParallelStateRoot is slower because we cannot use it to do partial state root computations as the block is being processed, it does all computation at the very end.
We can simplify the overall engine logic, make it faster during forks, and reduce surface area for edge-cases, by storing trie update change sets in the database. These changesets will function similarly to account/storage plain state changesets, allowing us to cheaply generate historical views of the trie tables, and quickly unwind them as needed.
Design
We store trie changesets for the most recent MAX_TRIE_HISTORY blocks, with MAX_TRIE_HISTORY being at least finality but also configurable by the user to be higher if they wish (e.g. if they want to provide eth_getProof RPC calls going back farther).
Using these tables we can modify HistoricalStateProvider (or create a companion trait which functions similarly) which provides historical trie state.
Additional context
This set of changes is a step forwards also for #18070. By providing cheap historical trie state the proof computation for historical blocks should be significantly improved.