Merkle Epochs
Merkle Epochs
PoC 2 introduces merkle tree epochs -- a compression layer that groups heartbeats into fixed-size epochs, each summarised by a single 32-byte merkle root.
#Concept
Instead of storing every heartbeat on-chain, heartbeats are grouped into epochs. Each epoch is a merkle tree of heartbeat hashes, yielding a compact root hash. Epochs themselves chain together, forming a verifiable timeline.
Epoch 0 Epoch 1 Epoch 2┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐│ H0 H1 ... H59 │ │ H60 H61 ... H119 │ │ H120 H121 ... ││ │ │ │ │ │ │ │ ││ merkle tree │ │ merkle tree │ │ merkle tree ││ │ │ │ │ │ │ │ ││ epoch root │──────│ epoch root │──────│ epoch root │└──────────────────┘ └──────────────────┘ └──────────────────┘ prevEpochHash prevEpochHashWith 60 heartbeats per epoch (one per minute), each epoch covers 1 hour of uptime.
#Merkle Tree Construction
Heartbeat hashes are arranged as leaves of a binary merkle tree. The tree is built bottom-up:
Root / \ H01 H23 / \ / \ H0 H1 H2 H3Each internal node is the SHA-256 hash of its two children concatenated:
parent = SHA-256(left || right)#Selective Disclosure
The key property of merkle trees is selective disclosure: you can prove a specific heartbeat existed within an epoch without revealing any other heartbeats.
#Example: Proving Heartbeat #37
To prove heartbeat #37 existed in an epoch of 60 heartbeats:
- Provide heartbeat #37 (the leaf).
- Provide the merkle proof path -- the sibling hashes needed to reconstruct the root.
- The verifier hashes heartbeat #37, then combines with each sibling hash up the tree, arriving at the root.
- If the computed root matches the published epoch root, the heartbeat is proven.
Root ← verifier arrives here / \ ... ... / \ ... H_sibling ← provided in proof / H_sibling ← provided in proof /H37 ← start hereThe proof path contains O(log n) sibling hashes -- logarithmic in the number of heartbeats per epoch.
#Proof Sizes
| Heartbeats per Epoch | Tree Depth | Proof Hashes | Proof Size |
|---|---|---|---|
| 60 (1 hour) | 6 | 6 | 192 bytes |
| 1,440 (1 day) | 11 | 11 | 352 bytes |
| 43,200 (30 days) | 16 | 16 | 512 bytes |
#Epoch Structure
type Epoch struct { LeaseID string // lease block hash EpochIndex uint64 // monotonic epoch counter StartSeq uint64 // first heartbeat sequence in this epoch EndSeq uint64 // last heartbeat sequence in this epoch MerkleRoot []byte // root of heartbeat merkle tree PrevEpochHash []byte // SHA-256 of previous epoch (zero for first) Timestamp int64 // unix nanos when epoch was sealed Hash []byte // SHA-256 of this epoch's fields}#Epoch Chaining
Each epoch includes a prevEpochHash field -- the hash of the previous epoch. This creates a chain of epochs analogous to the heartbeat chain itself:
E0 ← E1 ← E2 ← E3 ← ... ← En#Properties
Ordering is immutable. You cannot reorder epochs without breaking the chain of prevEpochHash references.
Insertion is impossible. Inserting a new epoch between two existing ones would require recomputing the prevEpochHash of all subsequent epochs.
Deletion is detectable. Removing an epoch creates a gap: the next epoch's prevEpochHash will not match the preceding epoch's hash.
#Verification
#Verify Epoch Chain Integrity
for each epoch Ei where i > 0: assert Ei.prevEpochHash == SHA-256(Ei-1) assert Ei.startSeq == Ei-1.endSeq + 1 assert Ei.epochIndex == Ei-1.epochIndex + 1#Verify Heartbeat Membership
1. Compute leaf = SHA-256(heartbeat)2. Walk proof path: for each (sibling, direction) in proof: if direction == left: current = SHA-256(sibling || current) else: current = SHA-256(current || sibling)3. Assert current == epoch.merkleRoot#Compression Ratio
For a 24-hour lease with 1-minute heartbeats:
| Layer | Data | Size |
|---|---|---|
| Raw heartbeats | 1,440 x ~250 bytes | 360 KB |
| Epoch roots | 24 x 32 bytes | 768 bytes |
| Single claim root | 1 x 32 bytes | 32 bytes |
The epoch layer alone achieves a 480x compression from raw heartbeats. Combined with the claim layer, the total compression reaches 3,681x.
#Related Pages
- Heartbeat Chain -- the heartbeats that feed into merkle epochs
- Production Design -- how epochs integrate into the three-layer architecture
- Threat Analysis -- attacks against merkle proofs and mitigations