Navigation, Hashing, and Merkle Properties

← Back to SHAMap and NodeStore: Data Persistence and State Management


Introduction

Now that you understand SHAMap's architecture and node types, let's explore how navigation actually works and how hashes propagate through the tree.

These operations are at the heart of what makes SHAMap efficient:

  • Navigation: Finding the correct path to any account

  • Hashing: Computing cryptographic commitments at each level

  • Verification: Ensuring data integrity through hash chains

Finding a leaf in a SHAMap is straightforward because the account's key determines the exact path:

Algorithm: findLeaf

std::shared_ptr<SHAMapLeafNode> findLeaf(uint256 key) {
    std::shared_ptr<SHAMapTreeNode> node = mRoot;

    for (int depth = 0; depth < 64; ++depth) {
        // Is this a leaf?
        if (auto leaf = std::dynamic_pointer_cast<SHAMapLeafNode>(node)) {
            return leaf;
        }

        // Must be inner node
        auto inner = std::dynamic_pointer_cast<SHAMapInnerNode>(node);

        // Extract 4-bit chunk (nibble) at position 'depth'
        int branch = key.nthNibble(depth);

        // Get child node at that branch
        node = inner->getChild(branch);

        if (!node) {
            // Child doesn't exist - key not in tree
            return nullptr;
        }
    }

    return nullptr;  // Key not found
}

Step-by-Step Example:

Time Complexity:

  • Worst case: O(64) inner node traversals (fixed depth)

  • Each traversal: O(1) array access to branch pointer

  • Total: O(1) expected time (with high probability leaf found before depth 64)

Space Requirement:

  • Path from root to leaf: ~64 pointers maximum

  • Working memory: O(1) per operation

Hash Computation

Hashing is fundamental to SHAMap's integrity guarantees:

Leaf Node Hashing

Leaves compute their hash from their data with a type prefix:

Example:

Inner Node Hashing

Inner nodes compute their hash from their children's hashes:

Example:

Hash Update Process

When tree is modified, hashes must be recomputed bottom-up:

Critical Property: All Hashes Change

This is why root hash is used as the ledger's cryptographic commitment. Change anything in the ledger → root hash changes.

Merkle Tree Properties

Property 1: O(1) Subtree Comparison

Two complete SHAMaps can be compared by comparing single 256-bit values:

Implication:

Peers can quickly determine if their ledgers match:

Property 2: Efficient Difference Detection

If root hashes differ, child hashes pinpoint the differences:

Search Complexity:

Property 3: Cryptographic Proofs

Prove that a specific item is in the tree:

Proof Verification:

Proof Size:

Use Cases:

  1. Light Clients: Verify account state without full ledger

  2. Cross-Chain Bridges: Prove XRPL state to other chains

  3. Auditing: Prove specific transactions were executed

Mutable Tree Operations

When constructing a new ledger, trees must support modifications:

Adding a New Leaf

Hash Updates

After modification, hashes propagate up:

Summary

Navigation:

  • Keys determine paths through tree

  • O(1) expected lookup time

  • Fixed depth ensures bounded operations

Hashing:

  • Leaves hash their data with type prefixes

  • Inner nodes hash their children's hashes

  • Changes propagate bottom-up to root

Merkle Properties:

  • O(1) tree comparison through root hash

  • O(log N) difference detection

  • O(log N) proof generation and verification

Performance:

  • Single account lookup: microseconds (tree traversal)

  • Root hash computation: milliseconds (hash all changed nodes)

  • Proof verification: thousands of hashes (proof depth)

These properties make SHAMap practical for blockchain state management: efficient updates, verifiable state, and fast synchronization.

Last updated