pub trait CommitIndex<Proprietor>: Commitment<Proprietor> {
type Index: Elastic + Storable;
type Shares: Countable;
Show 18 methods
// Required methods
fn index_exists(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> DispatchResult;
fn entry_exists(
reason: &Self::Reason,
index_of: &Self::Digest,
entry_of: &Self::Digest,
) -> DispatchResult;
fn has_index(reason: &Self::Reason) -> DispatchResult;
fn get_index(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Self::Index, DispatchError>;
fn get_entries_shares(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Vec<(Self::Digest, Self::Shares)>, DispatchError>;
fn get_entry_value(
reason: &Self::Reason,
index_of: &Self::Digest,
entry_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError>;
fn get_entry_value_for(
who: &Proprietor,
reason: &Self::Reason,
index_of: &Self::Digest,
entry_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError>;
fn gen_index_digest(
from: &Proprietor,
reason: &Self::Reason,
index: &Self::Index,
) -> Result<Self::Digest, DispatchError>;
fn prepare_index(
who: &Proprietor,
reason: &Self::Reason,
entries: &[(Self::Digest, Self::Shares)],
) -> Result<Self::Index, DispatchError>;
fn set_index(
who: &Proprietor,
reason: &Self::Reason,
index: &Self::Index,
digest: &Self::Digest,
) -> DispatchResult;
fn set_entry_shares(
who: &Proprietor,
reason: &Self::Reason,
index_of: &Self::Digest,
entry_of: &Self::Digest,
shares: Self::Shares,
) -> Result<Self::Digest, DispatchError>;
fn reap_index(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> DispatchResult;
// Provided methods
fn get_index_value(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError> { ... }
fn get_entries_value(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError> { ... }
fn get_entries_value_for(
who: &Proprietor,
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError> { ... }
fn get_index_value_for(
who: &Proprietor,
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError> { ... }
fn on_set_index(
_who: &Proprietor,
_index_of: &Self::Digest,
_reason: &Self::Reason,
_index: &Self::Index,
) { ... }
fn on_reap_index(
_index_of: &Self::Digest,
_reason: &Self::Reason,
_dust: Self::Asset,
) { ... }
}Expand description
CommitIndex extends Commitment by providing a higher-level financial abstraction
that groups multiple commitments under a single “index”.
This enables proprietors to manage related commitments collectively,
while preserving the atomicity and immutability guarantees of Commitment.
§Use Cases
- Portfolio management: Aggregate commitments.
- Betting pools: Collective tracking and settlement.
- Multi-asset contracts: Manage grouped assets with shares.
- Escrow pools: Efficient tracking of grouped escrows.
- Market positions: Aggregate for easier tracking.
§Why CommitIndex?
The base Commitment trait enforces:
“One reason -> one digest”.
This is restrictive when:
- A proprietor needs to manage multiple related commitments under one reason.
- Aggregation of commitments is required.
- Ownership of grouped commitments must be tracked proportionally.
- Trustless, composable structures are desired.
CommitIndex solves this by introducing indexes:
- An index digest references multiple committed digests (entries).
- Each entry remains an independent
Commitment. - The index enables aggregation, share-tracking, and collective management without breaking core commitment rules.
§Core Principles
-
Wrapper over commitments
- Index digest groups multiple committed digests.
- Entries retain individual commitment properties.
-
Management layer
- Tracks shares and values for each entry.
- Aggregates entry values into a single index value.
-
Integrity
- Entries remain independent commitments.
- Index creation does not alter entry commitments.
-
Trustless design
- Anyone can interact with indexes without requiring creator consent, provided the share structure allows it.
§Examples
§Example 1: Portfolio Staking
Alice stakes multiple digests under a single reason to manage risk:
| Reason | Digest | Value |
|---|---|---|
| “staking” | “digest_a123” | 100 |
| “staking” | “digest_b456” | 200 |
| “staking” | “digest_c789” | 300 |
Each row is an independent commitment.
Alice creates a CommitIndex:
- Reason =
"staking" - Digest =
"index_digest_xyz" - Entries =
[digest_a123, digest_b456, digest_c789] - Shares =
[1, 2, 3]
Total value = 600, with proportional share tracking.
§Example 2: Betting Pool
Bettors commit value for different bets under the same reason:
| Reason | Digest | Value |
|---|---|---|
| “betting_pool” | “digest_bet101” | 50 |
| “betting_pool” | “digest_bet102” | 80 |
CommitIndex:
- Reason =
"betting_pool" - Digest =
"index_digest_betting" - Entries =
[digest_bet101, digest_bet102] - Shares =
[2, 3]
Total value = 130, with proportional share tracking.
§Example 3: Market Position Index
Dave aggregates multiple market positions:
| Reason | Digest | Value |
|---|---|---|
| “market_positions” | “digest_order1” | 500 |
| “market_positions” | “digest_order2” | 300 |
CommitIndex:
- Reason =
"market_positions" - Digest =
"index_digest_market" - Entries =
[digest_order1, digest_order2] - Shares =
[5, 3]
Aggregates positions without altering atomic commitments.
§Example 4: Escrow Pool
Multiple escrows under one reason:
| Reason | Digest | Value |
|---|---|---|
| “escrow_pool” | “digest_escrow1” | 1000 |
| “escrow_pool” | “digest_escrow2” | 1500 |
CommitIndex:
- Reason =
"escrow_pool" - Digest =
"index_digest_escrow" - Entries =
[digest_escrow1, digest_escrow2] - Shares =
[1, 1.5]
Tracks total escrow commitments (2500) and proportional ownership.
§Invariants
- An index digest is a managed wrapper over multiple committed digests.
- Each entry is an independent
Commitment. - Index creation preserves atomicity, immutability, and reason-digest invariants.
- Shares define proportional ownership of aggregated commitments.
- Must maintain the base-invariant “One Reason -> One Digest”
Generics:
- Proprietor - the entity that owns the asset and can make commitments.
Required Associated Types§
Sourcetype Index: Elastic + Storable
type Index: Elastic + Storable
The type representing an index. This could be a struct containing entries and shares.
The type representing shares for an entry.
Should be a simple unsigned numeric type.
Required Methods§
Sourcefn index_exists(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> DispatchResult
fn index_exists( reason: &Self::Reason, index_of: &Self::Digest, ) -> DispatchResult
Checks whether an index exists for the given reason and index digest.
§Returns
Ok(())if the index existsErr(DispatchError)if the index is not found
Sourcefn entry_exists(
reason: &Self::Reason,
index_of: &Self::Digest,
entry_of: &Self::Digest,
) -> DispatchResult
fn entry_exists( reason: &Self::Reason, index_of: &Self::Digest, entry_of: &Self::Digest, ) -> DispatchResult
Checks whether a specific entry exists within the given index.
Verifies that the specified entry digest is part of the index’s entry list under the given reason.
§Returns
Ok(())if the entry exists within the indexErr(DispatchError)if the entry is not found in the index
Sourcefn has_index(reason: &Self::Reason) -> DispatchResult
fn has_index(reason: &Self::Reason) -> DispatchResult
Checks whether any index exists for the given reason.
Verifies that at least one index has been created under the specified reason across all proprietors.
§Returns
Ok(())if at least one index exists for the reasonErr(DispatchError)if no indexes are found for the reason
Sourcefn get_index(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Self::Index, DispatchError>
fn get_index( reason: &Self::Reason, index_of: &Self::Digest, ) -> Result<Self::Index, DispatchError>
Retrieves the complete index structure for the given reason and index digest.
Returns the full index object containing all entries, shares, and associated metadata for inspection or processing.
§Returns
Ok(Index)containing the complete index structure i.e.,CommitIndex::IndexErr(DispatchError)if the index does not exist
Retrieves the shares of each entry in the given index.
Returns a list of entry digests paired with their corresponding shares, representing each entry’s proportional weight within the index.
§Returns
Ok(Vec<(Self::Digest, Self::Shares)>)containing entry-share pairsErr(DispatchError)if the index does not exist or retrieval fails
Sourcefn get_entry_value(
reason: &Self::Reason,
index_of: &Self::Digest,
entry_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError>
fn get_entry_value( reason: &Self::Reason, index_of: &Self::Digest, entry_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>
Retrieves the real-time committed value of a specific entry within an index.
Returns the current value for the given entry digest under the specified
reason and index. Since the supertrait Commitment allows digest values
to be updated via Commitment::set_digest_value, this reflects the
live state rather than the original deposit.
§Returns
Ok(Asset)containing the entry’s current committed valueErr(DispatchError)if the index or entry does not exist
Sourcefn get_entry_value_for(
who: &Proprietor,
reason: &Self::Reason,
index_of: &Self::Digest,
entry_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError>
fn get_entry_value_for( who: &Proprietor, reason: &Self::Reason, index_of: &Self::Digest, entry_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>
Retrieves the real-time value of a proprietor’s commitment to a specific entry within an index.
Returns the live committed value for the given proprietor and entry 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 entryErr(DispatchError)if the index or entry does not exist
Sourcefn gen_index_digest(
from: &Proprietor,
reason: &Self::Reason,
index: &Self::Index,
) -> Result<Self::Digest, DispatchError>
fn gen_index_digest( from: &Proprietor, reason: &Self::Reason, index: &Self::Index, ) -> Result<Self::Digest, DispatchError>
Generates a unique digest for the given index object.
Creates a distinct identifier derived from the proprietor, reason, and index structure (including entries and shares). The generated digest must be collision-resistant and unique across all indexes of reason.
§Returns
Ok(Digest)containing the generated unique index digestErr(DispatchError)if digest generation fails due to invalid inputs
Sourcefn prepare_index(
who: &Proprietor,
reason: &Self::Reason,
entries: &[(Self::Digest, Self::Shares)],
) -> Result<Self::Index, DispatchError>
fn prepare_index( who: &Proprietor, reason: &Self::Reason, entries: &[(Self::Digest, Self::Shares)], ) -> Result<Self::Index, DispatchError>
Prepares an index object from the provided entry data.
Constructs a valid index structure from a list of (Digest, Shares) pairs,
where each pair represents:
- Digest: The unique identifier of an entry within the index
- Shares: The proportional weight or ownership of that entry
This method:
- Validates entry data for consistency and integrity
- Ensures no duplicate digests exist
- Rejects entries with nil/empty digests or zero shares
- Creates an immutable, atomic index object
§Returns
Ok(Index)containing the prepared index structureErr(DispatchError)if preparation fails due to invalid data or validation errors
Sourcefn set_index(
who: &Proprietor,
reason: &Self::Reason,
index: &Self::Index,
digest: &Self::Digest,
) -> DispatchResult
fn set_index( who: &Proprietor, reason: &Self::Reason, index: &Self::Index, digest: &Self::Digest, ) -> DispatchResult
Binds the prepared index to the specified digest under the given reason.
Associates the provided digest with the index structure, making it
queryable and usable within the commitment system. The index object
should be safely prepared via CommitIndex::prepare_index before
calling this method.
This operation ensures:
- The digest uniquely identifies the index
- All entries and shares are preserved with integrity
- The index conforms to
CommitIndexinvariants
§Returns
Ok(())if the index is successfully setErr(DispatchError)if the operation fails due to invalid data or conflicts
Updates the shares of a single entry within an existing index.
Since indexes are immutable once created, this method internally:
- Prepares a new index with the updated share for the specified entry
- Generates a new digest for the modified index
- Returns the new index digest
Since no explicit entry-removal methods are provided, this method may be used to remove an entry when its share is set to zero.
By invariant, commitment indexes must not contain entries with zero shares.
For updating multiple entries, use CommitIndex::prepare_index and
CommitIndex::set_index to create a completely new index structure.
§Returns
Ok(Digest)containing the new index digest after share updateErr(DispatchError)if the index or entry does not exist, or update fails
Sourcefn reap_index(reason: &Self::Reason, index_of: &Self::Digest) -> DispatchResult
fn reap_index(reason: &Self::Reason, index_of: &Self::Digest) -> DispatchResult
Removes an index if it contains no active commitments.
Permanently deletes the specified index digest under the given reason, freeing associated resources. Indexes can only be reaped when they have no committed entries or remaining balances.
§Returns
Ok(())if the index is successfully removedErr(DispatchError)if the index does not exist or contains active commitments
Provided Methods§
Sourcefn get_index_value(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError>
fn get_index_value( reason: &Self::Reason, index_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>
Retrieves the real-time aggregated value of the specified index.
Computes the total value by summing the current values of all entry digests
under the index. Since the supertrait Commitment allows digest values
to be updated via Commitment::set_digest_value, this reflects the
live state rather than historical deposits.
Ensures each entry’s digest value is current before aggregation.
§Returns
Ok(Asset)containing the total aggregated value of the indexErr(DispatchError)if the index does not exist or value computation fails
Sourcefn get_entries_value(
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError>
fn get_entries_value( reason: &Self::Reason, index_of: &Self::Digest, ) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError>
Retrieves the real-time values of all entries within the specified index.
Each entry’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 entry digests paired with their current committed values.
§Returns
Ok(Vec<(Self::Digest, Self::Asset)>)containing entry-value pairsErr(DispatchError)if the index does not exist or value retrieval fails
Sourcefn get_entries_value_for(
who: &Proprietor,
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError>
fn get_entries_value_for( who: &Proprietor, reason: &Self::Reason, index_of: &Self::Digest, ) -> Result<Vec<(Self::Digest, Self::Asset)>, DispatchError>
Retrieves the real-time values of a proprietor’s commitments to all entries within the specified index.
Each entry’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 entry digests paired with their current committed values for the specified proprietor.
§Returns
Ok(Vec<(Self::Digest, Self::Asset)>)containing entry-value pairs for the proprietorErr(DispatchError)if the index does not exist or value retrieval fails
Sourcefn get_index_value_for(
who: &Proprietor,
reason: &Self::Reason,
index_of: &Self::Digest,
) -> Result<Self::Asset, DispatchError>
fn get_index_value_for( who: &Proprietor, reason: &Self::Reason, index_of: &Self::Digest, ) -> Result<Self::Asset, DispatchError>
Retrieves the real-time total value of a proprietor’s commitment to an index.
Aggregates the live committed values of all entry digests within the index
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.
§Returns
Ok(Asset)containing the proprietor’s total commitment to the indexErr(DispatchError)if the index does not exist or computation fails
Sourcefn on_set_index(
_who: &Proprietor,
_index_of: &Self::Digest,
_reason: &Self::Reason,
_index: &Self::Index,
)
fn on_set_index( _who: &Proprietor, _index_of: &Self::Digest, _reason: &Self::Reason, _index: &Self::Index, )
Hook called after an index is created and its digest is set by a proprietor.
Provides an extension point for triggering side-effects such as events, logging, recalculations, or external state updates when a new index is established.
Default implementation is a no-op.
Sourcefn on_reap_index(
_index_of: &Self::Digest,
_reason: &Self::Reason,
_dust: Self::Asset,
)
fn on_reap_index( _index_of: &Self::Digest, _reason: &Self::Reason, _dust: Self::Asset, )
Hook called after an index is reaped (removed).
Provides an extension point for cleanup tasks, logging, freeing related resources, or triggering external notifications when an index 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.