-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Caplin: Introduced cached merkle tree #11096
Conversation
f934ec0
to
764263e
Compare
I will address comments and all after the Erigon 3.0 release |
Quality Gate passedIssues Measures |
@domiwei all done, review again. |
lgtm, but i noticed that seems this cached merkle tree struct is not thread-safe. Maybe you need mutex to protect it? |
No issue, not supposed to |
Merkle Tree cache for Intermediate hashes
this PR implements a cached Merkle tree for ARM-based computers which do not have significant gains from
gohashtree
.Overview
Merkle Tree Structure
The
MerkleTree
struct contains:computeLeaf
: A function to compute the hash of a leaf node.layers
: A slice of byte slices representing the intermediate layers of the tree.leavesCount
: The number of leaves in the tree.hashBuf
: A buffer to store input for hashing.limit
: An optional limit for the number of leaves.Key Constants
OptimalMaxTreeCacheDepth
: A constant defining the maximum depth of the tree cache.Initialization
The
Initialize
method sets up the Merkle tree with a specified number of leaves and a maximum cache depth. It also initializes the layers and sets an optional limit for the number of leaves.Marking Leaves as Dirty
The
MarkLeafAsDirty
method marks a leaf node as "dirty", indicating it needs to be recomputed during the next root calculation.Adding Leaves
The
AppendLeaf
method allows adding a new leaf to the tree. It marks the new leaf as dirty and extends the layers as needed.Extending Layers
The
extendLayer
method extends a given layer by 1.5 times its current size, ensuring the new leaf is marked as dirty.Computing the Root
The
ComputeRoot
method calculates the root hash of the Merkle tree. It handles various cases:Copying the Tree
The
CopyInto
method copies the current Merkle tree into another instance.Internal Helper Methods
finishHashing
: Completes the hashing process for the last layer.computeLayer
: Computes the hash for a specific layer.High-Level Workflow
Intermediate Hash Storage
The implementation stores only intermediate hashes, not the leaves themselves. This is achieved through the following:
layers
field holds intermediate hashes between the leaves and the root. Each entry inlayers
represents a level in the Merkle tree, starting from the first intermediate layer up to the layer just before the root.computeLeaf
function is used to compute the hash of a leaf node when needed, but these leaf hashes are not stored directly in thelayers
.layers
to derive the final root hash. This ensures that only the necessary intermediate hashes are kept in memory, optimizing storage efficiency.Rationale for Intermediate Hash Storage
The primary rationale for storing only intermediate hashes and not recomputing leaves is efficiency. By retaining intermediate hashes: