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
-
Managed aggregation
- Pools group commitments under a single digest for a given reason.
- Slots remain immutable commitments.
-
Dynamic shares
- Managers adjust shares to change exposure or strategy.
- Share changes require releasing and recovering the pool.
-
Semi-trusted management
- Managers cannot withdraw deposits directly.
- Operations are restricted by pool rules and fixed commission rates.
-
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:
| Proprietor | Reason | Digest | Value |
|---|---|---|---|
| Alice | staking | dave_pool | 100 |
| Bob | staking | dave_pool | 200 |
| Carol | staking | dave_pool | 300 |
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]
- Entries =
-
After:
- Entries =
[digest_a123, digest_b456, digest_c789, digest_d999] - Shares =
[2, 1, 4, 2]
- Entries =
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:
| Proprietor | Reason | Digest | Value |
|---|---|---|---|
| Carol | escrow | pool_digest_escrow | 1000 |
| Bob | escrow | pool_digest_escrow | 1500 |
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:
| Proprietor | Reason | Digest | Value |
|---|---|---|---|
| A | investment | inv_pool | 1000 |
| B | investment | inv_pool | 2000 |
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§
Sourcetype Pool: Elastic + Storable
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
Sourcetype Commission: Percentage
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§
Sourcefn pool_exists(reason: &Self::Reason, pool_of: &Self::Digest) -> DispatchResult
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 existsErr(DispatchError)if the pool is not found
Sourcefn slot_exists(
reason: &Self::Reason,
pool_of: &Self::Digest,
slot_of: &Self::Digest,
) -> DispatchResult
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 poolErr(DispatchError)if the slot is not found in the pool
Sourcefn has_pool(reason: &Self::Reason) -> DispatchResult
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 reasonErr(DispatchError)if no pools are found for the reason
Sourcefn get_manager(
reason: &Self::Reason,
pool_of: &Self::Digest,
) -> Result<Proprietor, DispatchError>
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 managerErr(DispatchError)if the pool does not exist
Sourcefn get_commission(
reason: &Self::Reason,
pool_of: &Self::Digest,
) -> Result<Self::Commission, DispatchError>
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 structureErr(DispatchError)if the pool does not exist
Sourcefn get_pool(
reason: &Self::Reason,
pool_of: &Self::Digest,
) -> Result<Self::Pool, DispatchError>
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 structureErr(DispatchError)if the pool does not exist
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 pairsErr(DispatchError)if the pool does not exist or retrieval fails
Sourcefn get_slot_value(
reason: &Self::Reason,
pool_of: &Self::Digest,
slot_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError>
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 valueErr(DispatchError)if the pool or slot does not exist
Sourcefn get_slot_value_for(
who: &Proprietor,
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>
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 slotErr(DispatchError)if the pool or slot does not exist
Sourcefn gen_pool_digest(
manager: &Proprietor,
reason: &Self::Reason,
index_of: &Self::Digest,
commission: Self::Commission,
) -> Result<Self::Digest, DispatchError>
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 digestErr(DispatchError)if digest generation fails due to invalid inputs
Sourcefn set_pool(
who: &Proprietor,
reason: &Self::Reason,
pool_of: &Self::Digest,
index_of: &Self::Digest,
commission: Self::Commission,
) -> DispatchResult
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 createdErr(DispatchError)if the index does not exist, pool digest conflicts, or validation fails
Sourcefn set_pool_manager(
reason: &Self::Reason,
pool_of: &Self::Digest,
manager: &Proprietor,
) -> DispatchResult
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 updatedErr(DispatchError)if the pool does not exist or authorization fails
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 updatedErr(DispatchError)if the pool or slot does not exist, or authorization fails
Sourcefn reap_pool(reason: &Self::Reason, pool_of: &Self::Digest) -> DispatchResult
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 removedErr(DispatchError)if the pool does not exist or contains active commitments
Provided Methods§
Sourcefn get_pool_value(
reason: &Self::Reason,
pool_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError>
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 poolErr(DispatchError)if the pool does not exist or value computation fails
Sourcefn get_slots_value(
reason: &Self::Reason,
pool_of: &Self::Digest,
) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError>
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 pairsErr(DispatchError)if the pool does not exist or value retrieval fails
Sourcefn get_slots_value_for(
who: &Proprietor,
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>
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 proprietorErr(DispatchError)if the pool does not exist or value retrieval fails
Sourcefn get_pool_value_for(
who: &Proprietor,
reason: &Self::Reason,
pool_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError>
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 poolErr(DispatchError)if the pool does not exist or computation fails
Sourcefn set_commission(
who: &Proprietor,
reason: &Self::Reason,
index_of: &Self::Digest,
commission: Self::Commission,
) -> Result<Self::Digest, DispatchError>
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 digestErr(DispatchError)if pool creation fails due to invalid parameters or conflicts
Sourcefn on_set_pool(
_who: &Proprietor,
_pool_of: &Self::Digest,
_reason: &Self::Reason,
_pool: &Self::Pool,
)
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.
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.
Sourcefn on_set_manager(
_pool_of: &Self::Digest,
_reason: &Self::Reason,
_manager: &Proprietor,
)
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.
Sourcefn on_reap_pool(
_pool_of: &Self::Digest,
_reason: &Self::Reason,
_dust: Self::Asset,
)
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.