Trait CommitPool

Source
pub trait CommitPool<Proprietor>: Commitment<Proprietor> + CommitIndex<Proprietor> {
    type Pool: Elastic + Storable;
    type Commission: Percentage;

Show 23 methods // Required methods fn pool_exists( reason: &Self::Reason, pool_of: &Self::Digest, ) -> DispatchResult; fn slot_exists( reason: &Self::Reason, pool_of: &Self::Digest, slot_of: &Self::Digest, ) -> DispatchResult; fn has_pool(reason: &Self::Reason) -> DispatchResult; fn get_manager( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Proprietor, DispatchError>; fn get_commission( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Self::Commission, DispatchError>; fn get_pool( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Self::Pool, DispatchError>; fn get_slots_shares( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Vec<(Self::Digest, Self::Shares)>, DispatchError>; fn get_slot_value( reason: &Self::Reason, pool_of: &Self::Digest, slot_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>; fn get_slot_value_for( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, slot_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>; fn gen_pool_digest( manager: &Proprietor, reason: &Self::Reason, index_of: &Self::Digest, commission: Self::Commission, ) -> Result<Self::Digest, DispatchError>; fn set_pool( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, index_of: &Self::Digest, commission: Self::Commission, ) -> DispatchResult; fn set_pool_manager( reason: &Self::Reason, pool_of: &Self::Digest, manager: &Proprietor, ) -> DispatchResult; fn set_slot_shares( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, slot_of: &Self::Digest, shares: Self::Shares, ) -> DispatchResult; fn reap_pool( reason: &Self::Reason, pool_of: &Self::Digest, ) -> DispatchResult; // Provided methods fn get_pool_value( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError> { ... } fn get_slots_value( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError> { ... } fn get_slots_value_for( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError> { ... } fn get_pool_value_for( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError> { ... } fn set_commission( who: &Proprietor, reason: &Self::Reason, index_of: &Self::Digest, commission: Self::Commission, ) -> Result<Self::Digest, DispatchError> { ... } fn on_set_pool( _who: &Proprietor, _pool_of: &Self::Digest, _reason: &Self::Reason, _pool: &Self::Pool, ) { ... } fn on_set_slot_shares( _pool_of: &Self::Digest, _reason: &Self::Reason, _slot_of: &Self::Digest, _shares: Self::Shares, ) { ... } fn on_set_manager( _pool_of: &Self::Digest, _reason: &Self::Reason, _manager: &Proprietor, ) { ... } fn on_reap_pool( _pool_of: &Self::Digest, _reason: &Self::Reason, _dust: Self::Asset, ) { ... }
}
Expand description

CommitPool extends Commitment and CommitIndex to provide a managed, dynamic commitment abstraction.

It enables a trusted manager to actively manage where deposited assets are committed

  • effectively controlling how and where value is allocated across different digests within a pool.

While CommitIndex aggregates multiple commitments under a single digest, CommitPool introduces live management:

  • Proprietors deposit assets into a managed pool.
  • The pool manager determines how these assets are allocated across underlying commitments to optimize yield, diversify risk, or execute specific strategies.
  • Proprietors trust the manager to act within agreed rules and immutable commission terms.

In short, Pool digests are stable identities; index digests are content hashes.

§Purpose

Pools are useful for:

  • Managed staking or investment
  • Delegated liquidity provision
  • Escrow pools with oversight
  • Collective asset management with dynamic strategy

They preserve the atomicity and immutability of individual commitments while enabling flexible allocation.

§Core Principles

  1. Managed aggregation

    • Pools group commitments under a single digest for a given reason.
    • Slots remain immutable commitments.
  2. Dynamic shares

    • Managers adjust shares to change exposure or strategy.
    • Share changes require releasing and recovering the pool.
  3. Semi-trusted management

    • Managers cannot withdraw deposits directly.
    • Operations are restricted by pool rules and fixed commission rates.
  4. Immutable commission

    • Commission rates are fixed at pool creation for transparency and trust.

§Examples

§Example 1: Managed Staking Pool

Manager Dave creates a managed pool:

  • Reason = "managed_staking"
  • Digest = "dave_pool"
  • Entries = [digest_a123, digest_b456, digest_c789]
  • Shares = [1, 2, 3]
  • Commission = 2%

Alice, Bob, and Carol deposit tokens into a staking pool managed by Dave:

ProprietorReasonDigestValue
Alicestakingdave_pool100
Bobstakingdave_pool200
Carolstakingdave_pool300

The pool holds a total value of 600, managed dynamically without altering deposits.

Dave can rebalance the pool or add new staking positions (new entry digests)
as opportunities arise, while depositors retain proportional ownership.

This makes CommitPool distinct from CommitIndex,
which has static entries and immutable share structures.

§Dynamic Reallocation and Expansion

After creation, the manager can update both shares and entries:

  • Before:

    • Entries = [digest_a123, digest_b456, digest_c789]
    • Shares = [1, 2, 3]
  • After:

    • Entries = [digest_a123, digest_b456, digest_c789, digest_d999]
    • Shares = [2, 1, 4, 2]

This allows the pool to grow by adding new slots (digests)
and to rebalance proportional exposure.
Proprietors can view current allocations at any time,
but allocations and entries may change as part of active management.

§Example 2: Managed Liquidity Pool

Manager creates:

  • Reason = "liquidity"
  • Digest = "pool_digest_lp"
  • Entries = [digest_lp_001, digest_lp_002]
  • Shares = [5, 7]
  • Commission = 1%

The pool manager may later add new liquidity positions (e.g., digest_lp_003)
or adjust existing shares to respond to market demand.
Depositors continue to share in the aggregated performance of the evolving pool.

§Example 3: Escrow Pool with Commission

Carol and Bob deposit into a managed escrow pool:

ProprietorReasonDigestValue
Carolescrowpool_digest_escrow1000
Bobescrowpool_digest_escrow1500

Manager creates:

  • Reason = "escrow"
  • Digest = "pool_digest_escrow"
  • Shares = [1, 1.5]
  • Commission = 0.5%

The manager can later add new escrow digests or rebalance shares
to adjust allocations, while commission is paid automatically upon resolution.

§Example 4: Delegated Investment Pool

Investors deposit:

ProprietorReasonDigestValue
Ainvestmentinv_pool1000
Binvestmentinv_pool2000

Manager creates:

  • Reason = "investment"
  • Digest = "inv_pool"
  • Shares = [1, 2]
  • Commission = 1.5%

After creation:

  • The manager may add new investment digests or update existing ones.
  • Proprietors can see current allocations, but these can change over time.

§Invariants

  • A pool digest wraps multiple committed entries.
  • Pools are created from indexes.
  • Mutations require full release and recovering.
  • Managers cannot withdraw deposits, only adjust shares.
  • Commission rate is fixed at creation.
  • Commission is paid upon commitment resolution.
  • Share adjustments must preserve proportional commitments.

§Summary

CommitPool enables managed aggregation of commitments with dynamic share adjustment, preserving safety, immutability, and fixed commission rates.

Ideal for managed staking, liquidity provision, delegated investment, escrow pools, and collective asset management where live management is required.

Generics:

  • Proprietor - the entity that owns the asset and can make commitments.

Required Associated Types§

Source

type Pool: Elastic + Storable

The type representing a managed pool.

Typically a struct that includes:

  • The pool’s manager (of type Proprietor)
  • A list of slot digests and their shares
  • The commission rate
  • Metadata
Source

type Commission: Percentage

The type representing a pool’s commission.

Can be a numeric percentage, ratio, or more complex type encoding the manager’s commission or performance fee model.

Required Methods§

Source

fn pool_exists(reason: &Self::Reason, pool_of: &Self::Digest) -> DispatchResult

Checks whether a pool exists for the given reason and pool digest.

§Returns
  • Ok(()) if the pool exists
  • Err(DispatchError) if the pool is not found
Source

fn slot_exists( reason: &Self::Reason, pool_of: &Self::Digest, slot_of: &Self::Digest, ) -> DispatchResult

Checks whether a specific slot exists within the given pool.

Verifies that the specified slot digest is part of the pool’s slot list under the given reason.

§Returns
  • Ok(()) if the slot exists within the pool
  • Err(DispatchError) if the slot is not found in the pool
Source

fn has_pool(reason: &Self::Reason) -> DispatchResult

Checks whether any pool exists for the given reason.

Verifies that at least one pool has been created under the specified reason across all managers.

§Returns
  • Ok(()) if at least one pool exists for the reason
  • Err(DispatchError) if no pools are found for the reason
Source

fn get_manager( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Proprietor, DispatchError>

Retrieves the manager (controller) of the specified pool.

Returns the proprietor who is responsible for managing the pool’s allocations, slot configurations, and commission distribution.

§Returns
  • Ok(Proprietor) containing the pool’s manager
  • Err(DispatchError) if the pool does not exist
Source

fn get_commission( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Self::Commission, DispatchError>

Retrieves the commission rate associated with the specified pool.

Returns the fixed commission structure that determines what portion of the pool’s yield or value the manager is entitled to receive.

§Returns
  • Ok(Commission) containing the pool’s commission structure
  • Err(DispatchError) if the pool does not exist
Source

fn get_pool( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Self::Pool, DispatchError>

Retrieves the complete pool structure for the given reason and pool digest.

Returns the full pool object containing all slots, shares, manager identity, commission details, and associated metadata for inspection or processing.

§Returns
  • Ok(Pool) containing the complete pool structure
  • Err(DispatchError) if the pool does not exist
Source

fn get_slots_shares( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Vec<(Self::Digest, Self::Shares)>, DispatchError>

Retrieves the shares of all slots within the specified pool.

Returns a list of slot digests paired with their corresponding shares, representing each slot’s proportional weight within the pool’s managed allocation strategy.

§Returns
  • Ok(Vec<(Self::Digest, Self::Shares)>) containing slot-share pairs
  • Err(DispatchError) if the pool does not exist or retrieval fails
Source

fn get_slot_value( reason: &Self::Reason, pool_of: &Self::Digest, slot_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>

Retrieves the real-time committed value of a specific slot within a pool.

Returns the current value for the given slot digest under the specified reason and pool. Since the supertrait Commitment allows digest values to be updated via Commitment::set_digest_value, this reflects the live state rather than the original allocation.

If no funds are available in a valid slot, it is expected to return zero.

§Returns
  • Ok(Asset) containing the slot’s current committed value
  • Err(DispatchError) if the pool or slot does not exist
Source

fn get_slot_value_for( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, slot_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>

Retrieves the real-time value of a proprietor’s commitment to a specific slot within a pool.

Returns the live committed value for the given proprietor and slot digest. Since the supertrait Commitment allows digest values to be updated via Commitment::set_digest_value, this reflects the current state rather than the deposited total.

§Returns
  • Ok(Asset) containing the proprietor’s current commitment to the slot
  • Err(DispatchError) if the pool or slot does not exist
Source

fn gen_pool_digest( manager: &Proprietor, reason: &Self::Reason, index_of: &Self::Digest, commission: Self::Commission, ) -> Result<Self::Digest, DispatchError>

Generates a unique digest that serves as the identifier for a pool configuration.

Creates a collision-resistant identifier derived from:

  • The manager’s identity
  • The reason (category/purpose)
  • The underlying index digest
  • The commission structure

The generated digest acts as a globally unique identifier across all pools, ensuring that even similar configurations or identical indexes result in distinct pool identities when managed by different entities or with different commission rates.

§Returns
  • Ok(Digest) containing the generated unique pool digest
  • Err(DispatchError) if digest generation fails due to invalid inputs
Source

fn set_pool( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, index_of: &Self::Digest, commission: Self::Commission, ) -> DispatchResult

Creates a managed pool from an existing index with a fixed commission rate.

Links the pool to an existing index structure under the specified reason and pool digest, establishing a managed aggregation layer with dynamic allocation capabilities.

This method:

  • Validates that the base index exists and is accessible
  • Ensures the pool digest is unique and available
  • Records the manager (who) and immutable commission rate
  • Enables trustless participation for depositors who rely on the index structure

Pools can be created from any valid index, regardless of who created it, enabling permissionless pool creation while maintaining security.

Once created, the pool introduces managed control and commission logic over the linked index, allowing the manager to dynamically update slots, adjust slot shares and allocations.

§Returns
  • Ok(()) if the pool is successfully created
  • Err(DispatchError) if the index does not exist, pool digest conflicts, or validation fails
Source

fn set_pool_manager( reason: &Self::Reason, pool_of: &Self::Digest, manager: &Proprietor, ) -> DispatchResult

Assigns or updates the manager of an existing pool.

Transfers management control of the pool to a new proprietor, who then assumes responsibility for slot configuration, share adjustments, and commission control.

This operation preserves all existing commitments, shares, and commission structures while changing only the entity authorized to manage the pool.

§Returns
  • Ok(()) if the manager is successfully updated
  • Err(DispatchError) if the pool does not exist or authorization fails
Source

fn set_slot_shares( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, slot_of: &Self::Digest, shares: Self::Shares, ) -> DispatchResult

Updates the shares of a specific slot within an existing pool.

Allows the pool manager to dynamically reallocate exposure between slots without recreating the entire pool structure. This enables responsive strategy adjustments based on market conditions, performance metrics, or risk management requirements.

The operation preserves all existing commitments while adjusting the proportional weight of the specified slot within the pool’s allocation.

§Returns
  • Ok(()) if the slot shares are successfully updated
  • Err(DispatchError) if the pool or slot does not exist, or authorization fails
Source

fn reap_pool(reason: &Self::Reason, pool_of: &Self::Digest) -> DispatchResult

Removes a pool if it contains no active commitments.

Permanently deletes the specified pool digest under the given reason, freeing associated resources and references. Pools can only be reaped when no proprietors have active commitments to any of its slots.

Attempting to reap a non-empty pool must return an error.

§Returns
  • Ok(()) if the pool is successfully removed
  • Err(DispatchError) if the pool does not exist or contains active commitments

Provided Methods§

Source

fn get_pool_value( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>

Retrieves the real-time aggregated value of the specified pool.

Computes the total value by summing the current values of all slot digests under the pool. Since the supertrait Commitment allows digest values to be updated via Commitment::set_digest_value, this reflects the live state rather than historical deposits.

The aggregated value represents the total exposure of all depositors across all slots managed by the pool.

§Returns
  • Ok(Asset) containing the total aggregated value of the pool
  • Err(DispatchError) if the pool does not exist or value computation fails
Source

fn get_slots_value( reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError>

Retrieves the real-time values of all slots within the specified pool.

Each slot’s value is fetched individually and reflects any changes since the commitment was created, as the supertrait Commitment allows digest values to be updated via Commitment::set_digest_value.

Returns a list of slot digests paired with their current committed values, representing the live state of the pool’s allocation.

§Returns
  • Ok(Vec<(Self::Digest, Self::Asset)>) containing slot-value pairs
  • Err(DispatchError) if the pool does not exist or value retrieval fails
Source

fn get_slots_value_for( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError>

Retrieves the real-time values of a proprietor’s commitments to all slots within the specified pool.

Each slot’s value is computed individually for the given proprietor and reflects any changes since commitment, as the supertrait Commitment allows digest values to be updated via Commitment::set_digest_value.

Returns a list of slot digests paired with their current committed values for the specified proprietor, showing their proportional exposure across the pool’s managed allocation.

§Returns
  • Ok(Vec<(Self::Digest, Self::Asset)>) containing slot-value pairs for the proprietor
  • Err(DispatchError) if the pool does not exist or value retrieval fails
Source

fn get_pool_value_for( who: &Proprietor, reason: &Self::Reason, pool_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>

Retrieves the real-time total value of a proprietor’s commitment to a pool.

Aggregates the live committed values of all slot digests within the pool for the given proprietor. Since the supertrait Commitment allows digest values to be updated via Commitment::set_digest_value, this reflects the current total rather than historical deposits.

Represents the proprietor’s total exposure to the pool’s managed allocation strategy.

§Returns
  • Ok(Asset) containing the proprietor’s total commitment to the pool
  • Err(DispatchError) if the pool does not exist or computation fails
Source

fn set_commission( who: &Proprietor, reason: &Self::Reason, index_of: &Self::Digest, commission: Self::Commission, ) -> Result<Self::Digest, DispatchError>

Creates a new pool digest from an index with a specified commission rate.

Generates a unique pool identifier by combining the index structure with a commission rate, enabling multiple pools with different commission structures to be created from the same underlying index.

Since commission rates are immutable after pool creation to protect depositors, this method allows participants to create or select pools with their preferred commission terms without altering existing pools.

The generated digest serves as the unique identifier for the new pool configuration and can be used for subsequent pool operations.

§Returns
  • Ok(Digest) containing the newly generated pool digest
  • Err(DispatchError) if pool creation fails due to invalid parameters or conflicts
Source

fn on_set_pool( _who: &Proprietor, _pool_of: &Self::Digest, _reason: &Self::Reason, _pool: &Self::Pool, )

Hook called after a pool is successfully created by a proprietor (assumed to be the current pool-manager).

Provides an extension point for triggering side-effects such as events, logging, recalculations, or external state updates when a pool is established or modified.

Default implementation is a no-op.

Source

fn on_set_slot_shares( _pool_of: &Self::Digest, _reason: &Self::Reason, _slot_of: &Self::Digest, _shares: Self::Shares, )

Hook called after slot shares are updated within a pool.

Provides an extension point for triggering recalculations, propagating changes to related state, or emitting events when a slot’s shares are adjusted as part of the pool’s dynamic allocation strategy.

Default implementation is a no-op.

Source

fn on_set_manager( _pool_of: &Self::Digest, _reason: &Self::Reason, _manager: &Proprietor, )

Hook called after a pool’s manager is changed.

Provides an extension point for triggering governance events, audit logging, or external notifications when management control of a pool is transferred to a new proprietor.

Default implementation is a no-op.

Source

fn on_reap_pool( _pool_of: &Self::Digest, _reason: &Self::Reason, _dust: Self::Asset, )

Hook called after a pool is reaped (removed).

Provides an extension point for cleanup tasks, audit logging, freeing related resources, or triggering external notifications when a pool is permanently removed from the system.

dust represents any residual value that was unclaimable and effectively considered dead.

Default implementation is a no-op.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§