Skip to content

Heartbeat Chain

PoC 1 establishes the foundational primitive: a linear hash chain of dual-signed heartbeats between provider and consumer.

Concept

Every ~60 seconds, both parties participate in creating a heartbeat that cryptographically chains to the previous one. Neither party can fabricate heartbeats alone, and the chain cannot be backfilled because each heartbeat depends on the hash of its predecessor.

H0 ← H1 ← H2 ← H3 ← ... ← Hn
│         │              │
tip      each links     genesis
         to prev

Signing Process

Heartbeat creation is a four-step protocol between provider and consumer:

Step 1: Provider Creates Payload

The provider constructs the heartbeat payload:

leaseId:sequence:timestamp:prevHash
Field Type Description
leaseId string Hash of the lease block
sequence uint64 Monotonically increasing counter (0-indexed)
timestamp int64 Unix nanosecond timestamp
prevHash hex string SHA-256 hash of the previous heartbeat (zero hash for genesis)

Step 2: Provider Signs

The provider computes the SHA-256 hash of the payload and signs it with ed25519:

payloadHash = SHA-256(payload)
providerSig = ed25519.Sign(providerKey, payloadHash)

Step 3: Consumer Countersigns

The consumer receives the payload and provider signature, verifies the provider's signature, then countersigns the concatenation of payload + provider signature:

consumerInput = payload + providerSig
consumerSig   = ed25519.Sign(consumerKey, SHA-256(consumerInput))

Step 4: Final Hash

The complete heartbeat hash chains everything together:

finalHash = SHA-256(payload + providerSig + consumerSig)

This finalHash becomes the prevHash for the next heartbeat.

Heartbeat Structure

type Heartbeat struct {
    LeaseID       string // lease block hash
    Sequence      uint64 // monotonic counter
    Timestamp     int64  // unix nanos
    PrevHash      []byte // SHA-256 of previous heartbeat
    ProviderSig   []byte // ed25519 signature
    ConsumerSig   []byte // ed25519 countersignature
    Hash          []byte // SHA-256 of complete heartbeat
}

Each heartbeat is approximately 250 bytes.

Properties

Forward-Only

Each heartbeat references the hash of the previous one. To insert or modify a heartbeat mid-chain, every subsequent hash would need to be recomputed -- but that would require both signatures to be regenerated, which requires both private keys.

Dual-Signature Requirement

Both provider and consumer must actively participate. A provider cannot fabricate heartbeats without the consumer's signing key, and vice versa.

Why dual signatures matter

A single-signed chain proves only that the signer was running something. Dual signatures prove that two specific parties were communicating at the claimed time -- a much stronger guarantee.

Discardable History

The chain tip is self-verifying. Given heartbeat Hn, you can verify its signatures and confirm it claims to follow Hn-1 (via prevHash). You don't need the full history to validate the latest state -- only to prove specific past heartbeats existed.

Compact On-Chain Footprint

Only the chain tip needs to be stored on-chain for basic verification. The full chain can be stored off-chain by either party and disclosed during disputes.

Weakness: Batch Fabrication

The collusion problem

If provider and consumer collude, they can batch-generate an entire chain of heartbeats instantly. There is no mechanism in PoC 1 to bind heartbeats to real wall-clock time.

1,000 fake heartbeats can be generated in ~1 millisecond.

This is the motivation for PoC 3's VDF addition.

VDF Hardening (PoC 3)

PoC 3 addresses batch fabrication by adding a Verifiable Delay Function (VDF) to each heartbeat. The VDF is implemented as iterative SHA-256 hashing:

vdfInput  = SHA-256(payload)
vdfOutput = SHA-256(SHA-256(...SHA-256(vdfInput)...))  // N iterations

With N = 100,000 iterations and ~60ns per SHA-256 hash, each heartbeat takes approximately 6 milliseconds of sequential computation that cannot be parallelised.

VDF Impact

Metric Without VDF With VDF (100K iterations)
1 heartbeat ~1 μs ~6 ms
1,000 heartbeats ~1 ms ~6 seconds
1 day (1,440 heartbeats) ~1.4 ms ~8.6 seconds
30 days (43,200 heartbeats) ~43 ms ~4.3 minutes

VDF verification

Verification requires the same number of iterations -- there is no shortcut. The verifier recomputes the VDF from the input and confirms the output matches. This is the "verifiable" part: anyone can check the work, but no one can skip it.

Production Decision

Despite VDF's effectiveness, the production design omits it from the base protocol. The reasoning: VDFs add computational overhead to honest participants while only raising the cost of fabrication by a constant factor. Economic incentives (collateral, emission caps) make collusion unprofitable regardless.

VDFs remain available as an optional hardening layer that can be activated via state chain governance if needed.