Skip to content

Settlement Batch Finalization with Merkle Proof Verification #60

Description

@elizabetheonoja-art

Problem Statement / Feature Objective

The settlement contract finalizes billing periods by minting utility tokens. Each settlement transaction processes one record per meter, leading to high gas costs. A batch finalization mechanism must be implemented that accepts a Merkle tree root of multiple settlement records, stores only the root on-chain, and supports individual settlement verification via Merkle inclusion proofs. This reduces on-chain storage from O(n) to O(1) per batch.

Technical Invariants & Bounds

  • Batch structure: (batch_id: u64, merkle_root: [u8;32], period_start: u64, period_end: u64, record_count: u32).
  • Merkle tree: binary SHA256 tree; leaves are (meter_id, amount, period_id) serialized with XDR.
  • Batch submission cost: < 5000 gas per batch regardless of record count.
  • Individual claim: claim_settlement(batch_id, leaf_index, merkle_proof, meter_id, amount); contract verifies inclusion and emits Settled event.
  • Batch expiry: if not fully claimed within 30 days, anyone may call expire_batch() to free storage.
  • Max records per batch: 65,535 (16-level Merkle tree).

Codebase Navigation Guide

  • contracts/settlement/src/batch.rs — batch struct, storage, lifecycle.
  • contracts/settlement/src/merkle.rs — Merkle inclusion verification.
  • contracts/settlement/src/lib.rssubmit_batch(), claim_settlement(), expire_batch() entry points.
  • lib/merkle-utils/ — off-chain Merkle tree builder.

Implementation Blueprint

  1. Implement submit_batch(batch_id, merkle_root, period_start, period_end, record_count) storing only root.
  2. Implement claim_settlement(batch_id, leaf_index, proof, meter_id, amount): verify MerkleProof.verify(root, leaf_hash, proof), then mint tokens.
  3. Implement expire_batch(batch_id): only callable after 30 days; delete root entry.
  4. Build off-chain Merkle tree builder in lib/merkle-utils/.
  5. Foundry test: submit batch with 1000 records, claim 500 via proofs, expire remaining, verify claims succeed and expiry frees storage.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions