Skip to content

multi: hook up supply commitment state machine to minting and burning operations #1648

@Roasbeef

Description

@Roasbeef

Background & Motivation

The Taproot Assets protocol allows for off-chain asset issuance and transfers, but maintaining a verifiable, global view of the total supply of any asset requires an on-chain commitment mechanism. This is critical for:

  1. Supply Transparency: Users and auditors need to verify the total supply of an asset
  2. Preventing Inflation: Ensuring no unauthorized minting occurs
  3. Burn Verification: Proving that burned assets are permanently removed from circulation
  4. Universe Synchronization: Allowing universe servers to verify supply commitments

The universe/supplycommit package implements a sophisticated state machine for this purpose, creating periodic on-chain commitments that aggregate all supply changes (mints, burns, and ignored outputs) into a merkle tree (MS-SMT) structure. Each commitment transaction spends the previous commitment, creating an auditable chain of supply state transitions.

The Missing Link

While the supply commitment state machine is fully implemented, it's currently not connected to the actual minting and burning operations in the codebase. This means:

  • New asset mints are not registered with the supply commitment system
  • Asset burns are not tracked in the supply commitment tree
  • No on-chain supply commitments are being created

High-Level Integration Approach

The key insight is to integrate supply commitment calls directly into the existing state machines (BatchCaretaker for mints, ChainPorter for burns) rather than using external event listeners. This provides natural fault tolerance - if a supply commit fails, the state machine won't advance, and will retry on restart.

1. Mint Integration

Location: tapgarden/caretaker.go - in BatchCaretaker.stateStep()

When transitioning from BatchStateConfirmed to BatchStateFinalized:

  1. Extract issuance proofs from the finalized batch
  2. Create NewMintEvent instances for each minted asset
  3. Submit to supply committer BEFORE updating batch state in database
  4. Only mark batch as finalized after successful supply commit registration

This ensures if the supply commit fails, the batch remains in BatchStateConfirmed and will retry the entire finalization process on restart.

2. Burn Integration

Location: tapfreighter/chain_porter.go - in main event loop

When processing parcels with burn outputs:

  1. Detect burns via Asset.IsBurn() check after confirmation
  2. Extract burn proofs and create NewBurnEvent instances
  3. Submit to supply committer as part of burn finalization
  4. Only mark burn as complete after successful supply commit registration

This ensures burns are only committed to the supply tree after on-chain confirmation, with automatic retry on failure.

3. Supply Committer Component

Create a new component that:

  • Manages supply commit state machine instances per asset specifier
  • Provides async-safe methods to queue mint/burn events
  • Handles the periodic commitment cycle (via CommitTickEvent)
  • Integrates with existing wallet and chain infrastructure

Key interfaces:

type SupplyCommitter interface {
    // QueueMintUpdate queues a mint event (called from BatchCaretaker)
    QueueMintUpdate(ctx context.Context, assetID asset.ID, event *supplycommit.NewMintEvent) error
    
    // QueueBurnUpdate queues a burn event (called from ChainPorter)
    QueueBurnUpdate(ctx context.Context, assetID asset.ID, event *supplycommit.NewBurnEvent) error
}

4. Configuration

Add configuration options:

  • Enable/disable supply commitments
  • Commitment interval (default: 10 minutes)
  • Minimum confirmations before commitment (default: 6)
  • Fee rate for commitment transactions

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions