Skip to main content

๐Ÿ› Overview

pallet-commitment is not a simple locking pallet.

It is a trait-driven commitment engine that provides:

  • ๐Ÿ”’ semantic asset bonding
  • ๐Ÿงพ digest-level accounting
  • โš– lazy balance resolution
  • ๐Ÿงบ indexed commitments
  • ๐ŸŠ managed commitment pools
  • โš  imbalance reconciliation
  • ๐Ÿ›  runtime-controlled balance behavior

The pallet acts as shared economic infrastructure for consumer pallets like staking, governance, escrow, lending, and contracts.

Its responsibility is not protocol logic.

Its responsibility is safe commitment execution.


๐Ÿง  System Designโ€‹

At the highest level:

Consumer pallets define business logic. pallet-commitment manages bonding, accounting, and resolution.

  • The fungible asset system performs the actual asset mutations.
  • Each layer has a strict responsibility.
  • This is why the primitive remains extensible.

๐ŸŽฏ Responsibility Boundariesโ€‹

The pallet is intentionally generic.

It does not decide:

  • ๐Ÿงพ what a digest means
  • ๐Ÿ’ฐ why funds are committed
  • ๐Ÿฆ how staking works
  • ๐Ÿ“‰ how lending rules behave
  • ๐Ÿ—ณ governance semantics

Those belong to the usage pallet.

It only guarantees:

safe bonding -> correct accounting -> valid resolution

This makes the pallet reusable across many runtime modules.


1๏ธโƒฃ Public Commitment Traitsโ€‹

The pallet implements the Commitment family from frame_suite.

Main traits include:

TraitResponsibilityPurpose
CommitmentCore commitment lifecycleHandles placing, raising, resolving, and withdrawing commitments across all digest models
CommitIndexIndexed commitmentsSupports index-based commitment aggregation where multiple commitments resolve through shared indexed state
CommitPoolManaged poolsProvides pool-level commitment management, redistribution, and controlled ownership semantics
CommitVariantCommitment positional selectionDetermines which commitment positional variant applies for a given digest
IndexVariantPositional Index EntriesDefines how index entry digests differentiate and apply variant based commitments
PoolVariantPositional Pool SlotsDefines how pool slot digests differentiate and apply variant based commitments
DigestModelDigest classificationDefines how different commitment model's digests are classified and interpreted
InspectAssetRead-only inspectionExposes safe inspection APIs for fungible balances without mutation

These are the public interfaces used by consumer pallets.

They define:

  • place / raise / resolve
  • index creation
  • pool management
  • digest classification
  • variant semantics
  • inspection APIs

This is the external surface of the pallet.


2๏ธโƒฃ Internal Helper Traits (Not Public)โ€‹

The pallet separates low-level execution into helper traits.

Examples:

Helper TraitResponsibility
CommitBalanceCore balance mutation and settlement logic
CommitDepositLow-level deposit execution and receipt creation
CommitWithdrawLow-level withdrawal execution and resolution
CommitOpsShared commitment operations and internal state transitions
CommitInspectRead-only inspection of commitment state
IndexOpsInternal execution for indexed commitment structures
PoolOpsInternal execution for managed commitment pools

These traits are intentionally low-level, unchecked, and its implementation types are not exposed as part of the public pallet interface.

Callers must ensure invariants before using them. This keeps validation separate from execution.

These performs:

  • actual deposits
  • actual withdrawals
  • imbalance resolution
  • index distribution
  • pool redistribution
  • storage mutation
  • balance settlement

This is where real commitment execution happens and the pallet publicly exposed trait implementations delegate here.


3๏ธโƒฃ LazyBalance Engineโ€‹

The pallet does not hardcode accounting logic.

Instead it implements frame_suite::LazyBalance trait interface.

and through plugin-driven execution from Config it takes in a LazyBalance compatible plugin.

impl pallet_commitment::Config for Runtime {
type LazyBalance<'a> = ConcreteBalancePluginModel<'a>; // Swappable model
}

Not to be confused, as the pallet implements LazyBalance not the plugin, the plugin is expected to have behaviours expected by the pallet's LazyBalance implementation

This handles:

  • receipt creation and resolution
  • mint / reap balance mutations
  • proportional rewards and penalties
  • state snapshots and balance queries

Different runtimes can use different balance models without changing pallet logic.

This is one of the most significant architectural decisions.


5๏ธโƒฃ Storage Layerโ€‹

Storage is split by responsibility.

Primary storage maps include:

Storage MapResponsibility
CommitMapStores proprietor ownership and active commitments
DigestMapTracks shared digest-level bonded state
EntryMapGroups commitment entries under digest ownership
IndexMapStores indexed commitment structures and references
PoolMapManages pooled commitment state and redistribution data
ReasonValueTracks total committed value per commitment reason
AssetToIssueRecords pending mint imbalance to be issued to underlying fungible system
AssetToReapRecords pending reap imbalance to be settled to underlying fungible system

Each one tracks a different invariant:

  • ownership
  • digest state
  • grouped commitments
  • index internals
  • pool internals
  • global reason accounting
  • imbalance settlement

However, storage values should not be interpreted as immediate live withdrawable value.

pallet-commitment is fundamentally lazy.

Receipts, digest balances, and imbalance records represent deferred accounting state, not eagerly resolved balances.

For example:

  • a receipt does not store final withdraw value
  • a digest balance may require proportional resolution
  • pending issue/reap values may not yet be settled into assets

This means storage reflects accounting state and protocol invariants, not always the exact real-time economic value visible to a user.


6๏ธโƒฃ Native Reserve Layerโ€‹

The pallet exposes very few extrinsics.

It does not expose direct user-facing commitment extrinsics.

Instead:

consumer pallets call commitment traits.

Only an optional reserve funding is exposed directly as extrinsics:

deposit_reserve()
withdraw_reserve()

This reserve uses:

HoldReason::PrepareForCommit

as the default and optional reserved funding source for all effective future commitments of a particular commitment system's instance in the runtime.


๐Ÿ“Œ Design Philosophyโ€‹

The pallet is built around one principle:

commitment logic should exist once, and be reused everywhere

Instead of every pallet building custom bonding systems:

  • ๐Ÿฆ staking reuses commitment
  • ๐Ÿ’ธ lending reuses commitment
  • ๐Ÿ—ณ governance reuses commitment
  • ๐Ÿ“œ contracts reuses commitment

One engine. Many protocols.

This is why the architecture is heavily trait-driven.


๐Ÿ“Œ In One Sentenceโ€‹

pallet-commitment is a reusable economic engine that separates commitment semantics from commitment execution through traits, lazy balance plugins, and strict storage invariants.

This is the architectural foundation of the pallet.


๐Ÿš€ Next Stepโ€‹

Now we move into the base commitment architecture.

This is where the base lifecycle, storage, traits, and digest-backed commitment flow are defined.

๐Ÿ‘‰ Architecture -> Commitment (Base)