diff --git a/merkle/README.md b/merkle/README.md index e51e842..29a56d3 100644 --- a/merkle/README.md +++ b/merkle/README.md @@ -11,15 +11,15 @@ Multiple Implemenations are included, introducing different optimizations: / [ e ] / \ - [ d ] [ 0 ] <-- No child leafs + [ d ] [ 0 ] <-- No child leaves / \ - [ c ] [ 0 ] <-- No child leafs + [ c ] [ 0 ] <-- No child leaves / \ [ a ] [ b ] ``` -* [merkle_h0.ts](./src/trees/merkle_h0.ts) - On top of `merkle_naive`, eliminates the computation of zero hashes by setting empty leafs to `H(0 | 0)` and defining this as:
+* [merkle_h0.ts](./src/trees/merkle_h0.ts) - On top of `merkle_naive`, eliminates the computation of zero hashes by setting empty leaves to `H(0 | 0)` and defining this as:
`H(0 | 0) = 0` diff --git a/merkle/src/config.ts b/merkle/src/config.ts index a336480..3dfb863 100644 --- a/merkle/src/config.ts +++ b/merkle/src/config.ts @@ -22,7 +22,7 @@ export type TreeConfig = { type: string, level: number, sort_hash: boolean, - leafs: LeafConfig[] + leaves: LeafConfig[] }; function isLeafConfig(obj: any): obj is LeafConfig { @@ -42,8 +42,8 @@ function isTreeConfig(obj: any): obj is TreeConfig { isValidType(obj.type) && typeof obj.level === 'number' && typeof obj.sort_hash === 'boolean' && - Array.isArray(obj.leafs) && - obj.leafs.every(isLeafConfig); + Array.isArray(obj.leaves) && + obj.leaves.every(isLeafConfig); } function normalizeIndex(config: LeafConfig): bigint { @@ -64,7 +64,7 @@ export async function loadConfig(path: string): Promise { // Check if leaf indexes are in range let MAX = 2n ** BigInt(json.level); - json.leafs.forEach(leaf => { + json.leaves.forEach(leaf => { let idx = normalizeIndex(leaf); if ((idx < 0n) || (idx >= MAX)) throw `Configuration error: Leaf index out of range ${leaf.index}`; diff --git a/merkle/src/index.ts b/merkle/src/index.ts index 3c1fa26..fc07b2b 100644 --- a/merkle/src/index.ts +++ b/merkle/src/index.ts @@ -16,7 +16,7 @@ const DEFAULT_CONFIG: TreeConfig = { type: TREE_TYPE_DEFAULT, level: 5, sort_hash: true, - leafs: [] + leaves: [] }; let g_horiz_offset: number; @@ -42,7 +42,7 @@ async function main() { g_tree_type = json_config.type; g_sortHashes = json_config.sort_hash; g_tree = new TreeDisplay(initTreeType(g_tree_type, json_config.level, g_sortHashes), PRETTY); - json_config.leafs.forEach(leaf => { + json_config.leaves.forEach(leaf => { g_tree.addLeaf(BigInt(leaf.index), leaf.value); }) diff --git a/merkle/src/index2.ts b/merkle/src/index2.ts index 2d9cf20..05768d7 100644 --- a/merkle/src/index2.ts +++ b/merkle/src/index2.ts @@ -10,7 +10,7 @@ async function main() { console.log(tree.NAME()); console.log(); - config.leafs.forEach((leaf) => { + config.leaves.forEach((leaf) => { let hash = tree.addLeaf(BigInt(leaf.index), leaf.value) console.log(`Added leaf #${leaf.index}`) console.log(` Hash: ${hash}`) @@ -18,7 +18,7 @@ async function main() { console.log() }); - config.leafs.forEach((leaf) => { + config.leaves.forEach((leaf) => { let proof = tree.getProof(BigInt(leaf.index)) console.log() diff --git a/merkle/src/tests/test_single_leaf.ts b/merkle/src/tests/test_single_leaf.ts index 67cc06d..572f039 100644 --- a/merkle/src/tests/test_single_leaf.ts +++ b/merkle/src/tests/test_single_leaf.ts @@ -1,7 +1,7 @@ // SMTSingleLeaf and SMTHashZero should always produce the same root. // The two implementations only differ in how they store the tree. // -// Randomly add/remove tree leafs and check that the roots always match. +// Randomly add/remove tree leaves and check that the roots always match. import { SMTHashZero } from '../trees/merkle_h0' import { SMTSingleLeaf } from '../trees/merkle_single_leaf' @@ -30,7 +30,7 @@ function reproduce() { console.log(`${pos}. Root after ${(addr[1] ? "adding" : "removing")} leaf ${addr[0]} : ${tree1.ROOT()}`) if (leaf0 !== leaf1) - throw "Leafs added/removed did not match!"; + throw "Leaves added/removed did not match!"; if (tree0.ROOT() !== tree1.ROOT()) throw "Roots did not match!"; @@ -53,7 +53,7 @@ function main() { console.log(); if (leaf0 !== leaf1) - throw "Leafs added/removed did not match!"; + throw "Leaves added/removed did not match!"; if (tree0.ROOT() !== tree1.ROOT()) throw "Roots did not match!"; diff --git a/merkle/src/trees/merkle_single_leaf.ts b/merkle/src/trees/merkle_single_leaf.ts index ec59bb4..a0771de 100644 --- a/merkle/src/trees/merkle_single_leaf.ts +++ b/merkle/src/trees/merkle_single_leaf.ts @@ -77,6 +77,17 @@ export class SMTSingleLeaf implements IMerkle { } // Get the root hash for a single non-zero leaf subtree + // + // Inputs + // address - address of non-zero leaf + // + // hashLeaf - hash of non-zero leaf + // + // lvl - subtree root level, where zero is the tree + // root and LEVELS_TOTAL() is the leaf level. + // + // Returns + // subtree hash private _singleLeafSubtree(address: bigint, hashLeaf: string, lvl: bigint): string { let bitmask = 1n; let hashLevel = hashLeaf; @@ -195,7 +206,7 @@ export class SMTSingleLeaf implements IMerkle { node = subtree[1]; } else { - // As long as the paths for the two leafs overlap, + // As long as the paths for the two leaves overlap, // the sibling hash will be zero. for (; pos < this.LEVELS_TOTAL(); ++pos) { if ((address & bitmask) != (leaf_address & bitmask)) @@ -208,7 +219,7 @@ export class SMTSingleLeaf implements IMerkle { // We now have two sibling subtrees, both with a single // non-zero leaf. Get the hash of the sibiling subtree. // Here we need to handle a limit case where the two - // leafs are siblings. + // leaves are siblings. // // [ a ] [ z ] // | | @@ -337,7 +348,7 @@ export class SMTSingleLeaf implements IMerkle { private _tree_set(log: string, parent: string, children: string[]) { // Filter out entries whose parent is zero. - // This happens because of the way we handle removal of leafs + // This happens because of the way we handle removal of leaves // which involves setting the leaf to a zero hash. if (parent === this.HASH_ZERO()) return; @@ -375,7 +386,7 @@ export class SMTSingleLeaf implements IMerkle { throw `Unexpected siblings array length: ${siblings.length}!`; // When an auxiliary node IS included, the sibling list will always have missing - // leafs. We thus expect the nodes array to be terminated with two extra hashes: + // entries. We expect the nodes array to be terminated with two extra hashes: // [..., single_leaf_subtree_hash, leaf_hash] if ((aux.length !== 0) && (nodes.length !== siblings.length + 2)) throw `Unexpected nodes array length, with auxiliary node! Nodes: ${nodes.length}, Siblings: ${siblings.length}`; diff --git a/merkle/tree_config.json b/merkle/tree_config.json index d3c69be..8e9ce35 100644 --- a/merkle/tree_config.json +++ b/merkle/tree_config.json @@ -2,7 +2,7 @@ "type": "h0", "level": 160, "sort_hash": true, - "leafs": [ + "leaves": [ { "index": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", "value": "000000000000000000000000f39Fd6e51aad88F6F4ce6aB8827279cffFb922660000000000000000000000000000000000000000000000004563918244f400000000000000000000000000000000000000000000000000000000000000000001" diff --git a/pom_check/README.md b/pom_check/README.md index 18254a1..52526cf 100644 --- a/pom_check/README.md +++ b/pom_check/README.md @@ -24,7 +24,7 @@ This test was excuted against a Reth node. Some harcoded address values may chan { "level": 3, "sort_hash": true, - "leafs": [ + "leaves": [ { "index": 0, "value": "000000000000000000000000f39Fd6e51aad88F6F4ce6aB8827279cffFb922660000000000000000000000000000000000000000000000004563918244f40000" diff --git a/pom_check/ignition/modules/TokenDrop.ts b/pom_check/ignition/modules/TokenDrop.ts index 722a84f..07cd661 100644 --- a/pom_check/ignition/modules/TokenDrop.ts +++ b/pom_check/ignition/modules/TokenDrop.ts @@ -6,7 +6,7 @@ const TokenDropModule = buildModule("TokenDropModule", (m) => { const drop = m.contract( "TokenDrop", - // Root for Level=3, Sorted, Leafs Set: 0,1,2,3 + // Root for Level=3, Sorted, Leaf Set: 0,1,2,3 [usd, "0xef0f86bd9a12acd5285d712174c8f8035f503428154c4b4a40c2494f32a77b3b"], { after: [usd] }); diff --git a/solarity_tree/README.md b/solarity_tree/README.md index 84e2350..aa7de3e 100644 --- a/solarity_tree/README.md +++ b/solarity_tree/README.md @@ -33,9 +33,9 @@ Some conclusions that standout: 1. The library makes extensive use of recursion. This is not a good practice in Solidity programming, where the maximum stack size is limited. - For large SMTs, one should analyze the potential of an attack where leaf operations fails due to stack overflow. Can an attacker add leafs such that to block proof-of-ownership for other leafs? + For large SMTs, one should analyze the potential of an attack where leaf operations fails due to stack overflow. Can an attacker add leaves such that to block proof-of-ownership for other leaves? -1. Gas consumption is highly dependent on the current tree size. As new leafs are added, the traversal depth and storage access operations required to add a new leaf increases. Thus tree access becomes more expensive over time. +1. Gas consumption is highly dependent on the current tree size. As new leaves are added, the traversal depth and storage access operations required to add a new leaf increases. Thus tree access becomes more expensive over time. 1. The design is wasteful in storage. This is especially true for the `Node` struct which encapsulates different variables for `MIDDLE` and `LEAF` nodes. @@ -120,7 +120,7 @@ struct Node { `nodeHash` - Node hash where for...
`MIDDLE` nodes `nodeHash = Hash(Left_Hash | Right_Hash)`
- `LEAF` nodes `nodeHash = Hash(key | value | 1)`. The doc says _1 acts as a domain separator_ i.e. it separates leafs from non-leafs. + `LEAF` nodes `nodeHash = Hash(key | value | 1)`. The doc says _1 acts as a domain separator_ i.e. it separates leaves from intermediate nodes. `key`, `value` - Node address and value in case of a `LEAF` node. @@ -405,7 +405,7 @@ function _setNode( let treeFactory = await ethers.getContractFactory("TokenSnapshot") let tree = await treeFactory.attach(contract_addrs.DeployModule_TokenSnapshot) - // Create tree leafs... + // Create tree leaves... let accounts = await ethers.getSigners() await tree.getLeafValue(accounts[0]) await tree.recordBalance(accounts[0], 5n*10n**18n) diff --git a/vitalik_merkle_optimizations/new_bintrie_hex.py b/vitalik_merkle_optimizations/new_bintrie_hex.py index af9901b..85c5529 100644 --- a/vitalik_merkle_optimizations/new_bintrie_hex.py +++ b/vitalik_merkle_optimizations/new_bintrie_hex.py @@ -93,7 +93,7 @@ def make_single_key_hash(path, depth, value): # vals is reallocated 4 times in each round halfing its size. # # In this manner we are hashing adjecent siblings moving from -# leafs to root +# leaf to root def hash_16_els(vals): assert len(vals) == 16 for _ in range(4): diff --git a/vitalik_merkle_optimizations/new_bintrie_optimized.py b/vitalik_merkle_optimizations/new_bintrie_optimized.py index 20a3bb8..afefdbc 100644 --- a/vitalik_merkle_optimizations/new_bintrie_optimized.py +++ b/vitalik_merkle_optimizations/new_bintrie_optimized.py @@ -115,7 +115,7 @@ def make_single_key_hash(path, depth, value): # Make a root hash of a (sub)tree with two key/value pairs, and save intermediate nodes in the DB # -# Adds DB nodes in cases where the subtree includes 2 non-zero leafs. +# Adds DB nodes in cases where the subtree includes 2 non-zero leaves. # # Function shows how the value of a single leaf subtree is encoded # with an extra byte.