Skip to content

Commit

Permalink
WIP - Moved extension node into its own file and removed the resolver…
Browse files Browse the repository at this point in the history
… helper
  • Loading branch information
Olshansk committed Feb 8, 2024
1 parent b876799 commit d83d374
Show file tree
Hide file tree
Showing 8 changed files with 296 additions and 288 deletions.
16 changes: 15 additions & 1 deletion docs/faq.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
# FAQ <!-- omit in toc -->

- [History](#history)
- [Fork](#fork)
- [Implementation](#implementation)
- [What's the story behind Extension Node Implementation?](#whats-the-story-behind-extension-node-implementation)

This documentation is meant to capture common questions that come up and act
as a supplement or secondary reference to the primary documentation.

## History

### Fork

This library was originally forked off of [celestiaorg/smt](https://github.com/celestiaorg/smt)
which was archived on Feb 27th, 2023.

## Implementation

### What's the story behind Extension Node Implementation?

[smt](./smt.md#extension-nodes)
The [SMT extension node](./smt.md#extension-nodes) is very similar to that of
Ethereum's [Modified Merkle Patricia Trie](https://ethereum.org/developers/docs/data-structures-and-encoding/patricia-merkle-trie).

A quick primer on it can be found in this [5P;1R post](https://olshansky.substack.com/p/5p1r-ethereums-modified-merkle-patricia).

WIP
186 changes: 93 additions & 93 deletions docs/merkle-sum-trie.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
- [Implementation](#implementation)
- [Sum Encoding](#sum-encoding)
- [Digests](#digests)
- [Visualisations](#visualisations)
- [Visualizations](#visualizations)
- [General Trie Structure](#general-trie-structure)
- [Binary Sum Digests](#binary-sum-digests)
- [Sum](#sum)
Expand Down Expand Up @@ -65,34 +65,34 @@ The golang `encoding/binary` package is used to encode the sum with
`binary.BigEndian.PutUint64(sumBz[:], sum)` into a byte array `sumBz`.

In order for the SMST to include the sum into a leaf node the SMT the SMST
initialises the SMT with the `WithValueHasher(nil)` option so that the SMT does
initializes the SMT with the `WithValueHasher(nil)` option so that the SMT does
**not** hash any values. The SMST will then hash the value and append the sum
bytes to the end of the hashed value, using whatever `ValueHasher` was given to
the SMST on initialisation.
the SMST on initialization.

```mermaid
graph TD
subgraph KVS[Key-Value-Sum]
K1["Key: foo"]
K2["Value: bar"]
K3["Sum: 10"]
end
subgraph SMST[SMST]
SS1[ValueHasher: SHA256]
subgraph SUM["SMST.Update()"]
SU1["valueHash = ValueHasher(Value)"]
SU2["sumBytes = binary(Sum)"]
SU3["valueHash = append(valueHash, sumBytes...)"]
end
end
subgraph SMT[SMT]
SM1[ValueHasher: nil]
subgraph UPD["SMT.Update()"]
U2["SMT.nodeStore.Set(Key, valueHash)"]
end
end
KVS --"Key + Value + Sum"--> SMST
SMST --"Key + valueHash"--> SMT
subgraph KVS[Key-Value-Sum]
K1["Key: foo"]
K2["Value: bar"]
K3["Sum: 10"]
end
subgraph SMST[SMST]
SS1[ValueHasher: SHA256]
subgraph SUM["SMST.Update()"]
SU1["valueHash = ValueHasher(Value)"]
SU2["sumBytes = binary(Sum)"]
SU3["valueHash = append(valueHash, sumBytes...)"]
end
end
subgraph SMT[SMT]
SM1[ValueHasher: nil]
subgraph UPD["SMT.Update()"]
U2["SMT.nodeStore.Set(Key, valueHash)"]
end
end
KVS --"Key + Value + Sum"--> SMST
SMST --"Key + valueHash"--> SMT
```

### Digests
Expand Down Expand Up @@ -129,10 +129,10 @@ Therefore for the following node types, the digests are computed as follows:
This means that with a hasher such as `sha256.New()` whose hash size is
`32 bytes`, the digest of any node will be `40 bytes` in length.

### Visualisations
### Visualizations

The following diagrams are representations of how the trie and its components
can be visualised.
can be visualized.

#### General Trie Structure

Expand All @@ -143,45 +143,45 @@ nodes as an extra field.

```mermaid
graph TB
subgraph Root
A1["Digest: Hash(Hash(Path+H1)+Hash(H2+(Hash(H3+H4)))+Binary(20))+Binary(20)"]
subgraph Root
A1["Digest: Hash(Hash(Path+H1)+Hash(H2+(Hash(H3+H4)))+Binary(20))+Binary(20)"]
A2[Sum: 20]
end
subgraph BI[Inner Node]
B1["Digest: Hash(H2+(Hash(H3+H4))+Binary(12))+Binary(12)"]
end
subgraph BI[Inner Node]
B1["Digest: Hash(H2+(Hash(H3+H4))+Binary(12))+Binary(12)"]
B2[Sum: 12]
end
subgraph BE[Extension Node]
B3["Digest: Hash(Path+H1+Binary(8))+Binary(8)"]
end
subgraph BE[Extension Node]
B3["Digest: Hash(Path+H1+Binary(8))+Binary(8)"]
B4[Sum: 8]
end
subgraph CI[Inner Node]
C1["Digest: Hash(H3+H4+Binary(7))+Binary(7)"]
end
subgraph CI[Inner Node]
C1["Digest: Hash(H3+H4+Binary(7))+Binary(7)"]
C2[Sum: 7]
end
subgraph CL[Leaf Node]
C3[Digest: H2]
end
subgraph CL[Leaf Node]
C3[Digest: H2]
C4[Sum: 5]
end
subgraph DL1[Leaf Node]
D1[Digest: H3]
end
subgraph DL1[Leaf Node]
D1[Digest: H3]
D2[Sum: 4]
end
subgraph DL2[Leaf Node]
D3[Digest: H4]
end
subgraph DL2[Leaf Node]
D3[Digest: H4]
D4[Sum: 3]
end
subgraph EL[Leaf Node]
E1[Digest: H1]
end
subgraph EL[Leaf Node]
E1[Digest: H1]
E2[Sum: 8]
end
Root-->|0| BE
Root-->|1| BI
BI-->|0| CL
BI-->|1| CI
CI-->|0| DL1
CI-->|1| DL2
BE-->EL
end
Root-->|0| BE
Root-->|1| BI
BI-->|0| CL
BI-->|1| CI
CI-->|0| DL1
CI-->|1| DL2
BE-->EL
```

#### Binary Sum Digests
Expand All @@ -193,56 +193,56 @@ exception of the leaf nodes where the sum is shown as part of its value.

```mermaid
graph TB
subgraph RI[Inner Node]
RIA["Root Hash: Hash(D6+D7+Binary(18))+Binary(18)"]
subgraph RI[Inner Node]
RIA["Root Hash: Hash(D6+D7+Binary(18))+Binary(18)"]
RIB[Sum: 15]
end
subgraph I1[Inner Node]
I1A["D7: Hash(D1+D5+Binary(11))+Binary(11)"]
end
subgraph I1[Inner Node]
I1A["D7: Hash(D1+D5+Binary(11))+Binary(11)"]
I1B[Sum: 11]
end
subgraph I2[Inner Node]
I2A["D6: Hash(D3+D4+Binary(7))+Binary(7)"]
end
subgraph I2[Inner Node]
I2A["D6: Hash(D3+D4+Binary(7))+Binary(7)"]
I2B[Sum: 7]
end
subgraph L1[Leaf Node]
L1A[Path: 0b0010000]
L1B["Value: 0x01+Binary(6)"]
end
subgraph L1[Leaf Node]
L1A[Path: 0b0010000]
L1B["Value: 0x01+Binary(6)"]
L1C["H1: Hash(Path+Value+Binary(6))"]
L1D["D1: H1+Binary(6)"]
end
subgraph L3[Leaf Node]
L3A[Path: 0b1010000]
L3B["Value: 0x03+Binary(3)"]
end
subgraph L3[Leaf Node]
L3A[Path: 0b1010000]
L3B["Value: 0x03+Binary(3)"]
L3C["H3: Hash(Path+Value+Binary(3))"]
L3D["D3: H3+Binary(3)"]
end
subgraph L4[Leaf Node]
L4A[Path: 0b1100000]
L4B["Value: 0x04+Binary(4)"]
end
subgraph L4[Leaf Node]
L4A[Path: 0b1100000]
L4B["Value: 0x04+Binary(4)"]
L4C["H4: Hash(Path+Value+Binary(4))"]
L4D["D4: H4+Binary(4)"]
end
subgraph E1[Extension Node]
E1A[Path: 0b01100101]
E1B["Path Bounds: [2, 6)"]
end
subgraph E1[Extension Node]
E1A[Path: 0b01100101]
E1B["Path Bounds: [2, 6)"]
E1C[Sum: 5]
E1D["H5: Hash(Path+PathBounds+D2+Binary(5))"]
E1E["D5: H5+Binary(5)"]
end
subgraph L2[Leaf Node]
L2A[Path: 0b01100101]
L2B["Value: 0x02+Binary(5)"]
end
subgraph L2[Leaf Node]
L2A[Path: 0b01100101]
L2B["Value: 0x02+Binary(5)"]
L2C["H2: Hash(Path+Value+Hex(5))+Binary(5)"]
L2D["D2: H2+Binary(5)"]
end
RI -->|0| I1
RI -->|1| I2
I1 -->|0| L1
I1 -->|1| E1
E1 --> L2
I2 -->|0| L3
I2 -->|1| L4
end
RI -->|0| I1
RI -->|1| I2
I1 -->|0| L1
I1 -->|1| E1
E1 --> L2
I2 -->|0| L3
I2 -->|1| L4
```

## Sum
Expand Down
13 changes: 8 additions & 5 deletions docs/smt.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ The SMT has 4 node types that are used to construct the trie:
- [Inner Nodes](#inner-nodes)
- [Extension Nodes](#extension-nodes)
- [Leaf Nodes](#leaf-nodes)
- Lazy Nodes
- [Lazy Nodes](#lazy-nodes)
- Prefix of the actual node type is stored in the persisted digest as
determined above
- `digest = persistedDigest`
Expand Down Expand Up @@ -205,12 +205,15 @@ Where `Hash(Hash1 + Hash2)` is the same root hash as the previous example.

## Paths

Paths are **only** stored in two types of nodes: Leaf nodes and Extension nodes.
Paths are **only** stored in two types of nodes: `Leaf` nodes and `Extension` nodes.

- Extension nodes contain not only the path they represent but also the path
- `Leaf` nodes contain:
- The full path which it represent
- The value stored at that path
- `Extension` nodes contain:
- not only the path they represent but also the path
bounds (ie. the start and end of the path they cover).
- Leaf nodes contain the full path which they represent, as well as the value
stored at that path.


Inner nodes do **not** contain a path, as they represent a branch in the trie
and not a path. As such their children, _if they are extension nodes or leaf
Expand Down
Loading

0 comments on commit d83d374

Please sign in to comment.