rfc-5 · persistence

persistence pool

version 0.1 · updated 2026-04-16 · status: published


§1

scope

This document defines the Persistence Pool: a Solidity contract on Base that holds cUSDC and compensates provider nodes for audited replication. It specifies the contract interface, the challenge-response protocol, the compensation formula, and the parameters governable via Council (RFC-7). Provider nodes MUST implement valid responses to challenges per §3 to be eligible for payment.

MUST, SHOULD, MAY follow RFC 2119.

§2

contract interface

The canonical Persistence Pool interface includes, at a minimum:

interface IPersistencePool {
  // A provider node registers with region and replication intent.
  function register(uint8 region) external;

  // The contract emits a byte-range challenge for a CID under custody.
  event Challenge(
    bytes32 indexed challengeId,
    address indexed provider,
    bytes32 cidHash,
    uint64 rangeStart,
    uint64 rangeEnd,
    uint64 deadlineBlock
  );

  // Provider responds with the requested bytes + Merkle proof.
  function respond(
    bytes32 challengeId,
    bytes calldata rangeBytes,
    bytes32[] calldata merkleProof
  ) external;

  // Epoch closes, disbursement computed off-chain, submitted in batch.
  function submitSettlement(
    uint64 epoch,
    bytes32 merkleRoot,
    address[] calldata providers,
    uint256[] calldata amounts
  ) external;
}

Reference implementations live in packages/contracts/src/PersistencePool.sol. The canonical address on Base Sepolia is published in the network footer.

§3

challenge-response protocol

At random intervals (Poisson with rate λ per node per epoch), the contract emits a challenge consisting of:

  • challengeId — unique identifier;
  • cidHash — hash of the target CID under the provider’s custody;
  • [rangeStart, rangeEnd] — random byte range within the object;
  • deadlineBlock — block number by which the response must be submitted.

Provider nodes MUST, within the deadline:

  1. read the bytes O[rangeStart..rangeEnd] from locally stored data;
  2. compute the Merkle proof of the range against the pre-computed root for the CID (64 KiB chunk tree);
  3. submit via respond() the bytes and the proof.

The contract verifies the proof; a valid response increments R_i for the provider. A missing or invalid response decrements it. The deadline window SHOULD be short enough (typically ≤ 2 minutes) to defeat inter-peer fetch at challenge time.

§4

compensation formula

The compensation of a provider node in epoch t is:

P_i(t) = R_i(t) · B_i(t) · W_region(i) · ρ(t)
  • R_i(t) ∈ [0,1] — fraction of challenges correctly answered in the epoch.
  • B_i(t) — byte-hours of audited replicated content (sum of object sizes under custody × epoch hours).
  • W_region(i){0.5, 1.0, 1.5} — regional weight (§5).
  • ρ(t) — pool unit rate for the epoch: ε · S(t) / Σ_i (R_i · B_i · W_region), where S(t) is the pool balance and ε is the per-epoch disbursement fraction.

By construction, Σ_i P_i(t) = ε · S(t). The contract MUST reject settlements that violate this conservation.

§5

region weights

Regional weights encode geographic scarcity of custody. Initial values:

regionweightrationale
0 (default)1.0global north — baseline
1 (low scarcity)0.5regions with >30% of nodes — weighted less
2 (high scarcity)1.5global south, central asia, africa — weighted more

Regional classification is re-evaluated every 6 epochs by the Council, based on a public node distribution map. Changes MUST be announced on the Trust Ledger with ≥ 14 days of notice.

§6

epochs and disbursement

  • default epoch duration: 168 hours (7 days).
  • default disbursement fraction ε: 0.10 (10% of balance per epoch).
  • default challenge rate λ: 100 challenges per node per epoch — sufficient for a dishonest provider’s survival probability to be (1 − p)^λ ≈ 10^-100 for p = 0.9.
  • settlement is computed off-chain by a trusted aggregator (currently Aevia LLC), producing a Merkle root of (provider → amount); the contract verifies conservation and executes payments.

Parameters ε, λ, and epoch duration are governable via Council (RFC-7) with a veto process.

§7

security considerations

  • dishonest provider: defeated by the combination of random byte-range + short deadline (§3). Survival probability made explicit in §10(a) of the whitepaper.
  • Sybil: neutralized because payment is proportional to B_i actually replicated, not node count.
  • aggregator capture: a malicious aggregator could submit wrong settlements. Mitigation: settlements MUST have an on-chain contestation window (e.g., 72h after submission) during which any provider can submit a counter-proof. Migration to decentralized aggregation is in RFC-7 scope.
  • economic attack via B dumping: a large actor could inflate B, depressing ρ for small operators. The Council MAY propose a contract fork excluding the actor.
§8

references

  1. IETF RFC 2119 — Key words for RFCs
  2. Aevia Whitepaper §5, §10, §12
  3. RFC-2 — Content Addressing
  4. RFC-6 — Risk Score (draft)
  5. RFC-7 — Moderation and Ecumenical Jury (draft)
  6. cUSDC on Base — Circle documentation
  7. PersistencePool.sol — reference implementation