#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(feature = "runtime-benchmarks")]
mod benchmarking;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
mod balance;
mod commitment;
mod helpers;
pub mod traits;
pub mod types;
pub mod weights;
pub use pallet::*;
#[frame_support::pallet]
pub mod pallet {
use crate::{balance::*, types::*, weights::WeightInfo};
use frame_support::{
dispatch::DispatchResult,
pallet_prelude::*,
traits::{
fungible::InspectHold,
tokens::{fungible::*, Fortitude, Precision, Preservation},
BuildGenesisConfig, VariantCount,
},
};
use frame_system::{ensure_signed, pallet_prelude::OriginFor};
use frame_suite::{
assets::*,
base::{Countable, Delimited, Fractional, Percentage, RuntimeEnum, Time},
commitment::*,
misc::PositionIndex,
plugin_types,
};
use sp_runtime::{
traits::{Debug, MaybeDisplay},
DispatchError, FixedPointNumber, PerThing,
};
use sp_std::vec::Vec;
#[pallet::pallet]
pub struct Pallet<T, I = ()>(_);
pub(crate) struct CommitHelpers<T: Config<I>, I: 'static = ()>(PhantomData<(T, I)>);
#[pallet::config]
pub trait Config<I: 'static = ()>: frame_system::Config {
type RuntimeEvent: From<Event<Self, I>>
+ IsType<<Self as frame_system::Config>::RuntimeEvent>;
type AssetHold: From<HoldReason<I>> + RuntimeEnum + Delimited + Copy + VariantCount;
type AssetFreeze: From<FreezeReason<I>> + RuntimeEnum + Delimited + Copy + VariantCount;
type Shares: Countable + Into<AssetOf<Self, I>> + MaybeDisplay;
type Bias: Fractional;
type Time: Time;
type Commission: Percentage;
type Asset: Inspect<
Proprietor<Self>,
Balance: MaybeDisplay
+ From<<Self::Bias as FixedPointNumber>::Inner>
+ From<<Self::Commission as PerThing>::Inner>,
> + InspectFreeze<Proprietor<Self>, Id = Self::AssetFreeze>
+ InspectHold<Proprietor<Self>, Reason = Self::AssetHold>
+ Mutate<Proprietor<Self>>
+ UnbalancedHold<Proprietor<Self>>
+ Unbalanced<Proprietor<Self>>
+ MutateHold<Proprietor<Self>>
+ MutateFreeze<Proprietor<Self>>;
type Position: PositionIndex + RuntimeEnum + Delimited + Default;
plugin_types! {
input: LazyInput<'a, Self, I>,
output: LazyOutput<'a, Self, I>,
borrow: ['a],
root: LazyBalanceRoot,
family: BalanceFamily,
context: BalanceContext,
provides: [LazyBalanceContext],
}
type WeightInfo: WeightInfo;
#[pallet::constant]
type MaxIndexEntries: Get<u32> + Clone + Debug;
#[pallet::constant]
type MaxCommits: Get<u32> + Clone + Debug;
#[pallet::constant]
type EmitEvents: Get<bool> + Clone + Debug;
}
#[pallet::composite_enum]
pub enum HoldReason<I: 'static = ()> {
PrepareForCommit,
}
#[pallet::composite_enum]
pub enum FreezeReason<I: 'static = ()> {
BenchTestReason,
}
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config<I>, I: 'static = ()> {
_phantom: PhantomData<(T, I)>,
}
impl<T: Config<I>, I: 'static> Default for GenesisConfig<T, I> {
fn default() -> Self {
Self {
_phantom: Default::default(),
}
}
}
#[pallet::genesis_build]
impl<T: Config<I>, I: 'static> BuildGenesisConfig for GenesisConfig<T, I> {
fn build(&self) {
let zero = AssetOf::<T, I>::zero();
AssetToIssue::<T, I>::put(zero); AssetToReap::<T, I>::put(zero); }
}
#[pallet::storage]
pub type ReasonValue<T: Config<I>, I: 'static = ()> =
StorageMap<_, Blake2_128Concat, CommitReason<T, I>, AssetOf<T, I>, OptionQuery>;
#[pallet::storage]
pub type DigestMap<T: Config<I>, I: 'static = ()> = StorageNMap<
_,
(
NMapKey<Blake2_128Concat, CommitReason<T, I>>,
NMapKey<Blake2_128Concat, Digest<T>>,
),
DigestInfo<T, I>,
OptionQuery,
>;
#[pallet::storage]
pub type CommitMap<T: Config<I>, I: 'static = ()> = StorageNMap<
_,
(
NMapKey<Blake2_128Concat, Proprietor<T>>,
NMapKey<Blake2_128Concat, CommitReason<T, I>>,
),
CommitInfo<T, I>,
OptionQuery,
>;
#[pallet::storage]
pub type IndexMap<T: Config<I>, I: 'static = ()> = StorageNMap<
_,
(
NMapKey<Blake2_128Concat, CommitReason<T, I>>,
NMapKey<Blake2_128Concat, IndexDigest<T>>,
),
IndexInfo<T, I>,
OptionQuery,
>;
#[pallet::storage]
pub type EntryMap<T: Config<I>, I: 'static = ()> = StorageNMap<
_,
(
NMapKey<Blake2_128Concat, CommitReason<T, I>>,
NMapKey<Blake2_128Concat, IndexDigest<T>>,
NMapKey<Blake2_128Concat, EntryDigest<T>>,
NMapKey<Blake2_128Concat, Proprietor<T>>,
),
Commits<T, I>,
OptionQuery,
>;
#[pallet::storage]
pub type PoolMap<T: Config<I>, I: 'static = ()> = StorageNMap<
_,
(
NMapKey<Blake2_128Concat, CommitReason<T, I>>,
NMapKey<Blake2_128Concat, PoolDigest<T>>,
),
PoolInfo<T, I>,
OptionQuery,
>;
#[pallet::storage]
pub type PoolManager<T: Config<I>, I: 'static = ()> = StorageNMap<
_,
(
NMapKey<Blake2_128Concat, CommitReason<T, I>>,
NMapKey<Blake2_128Concat, PoolDigest<T>>,
),
Proprietor<T>,
OptionQuery,
>;
#[pallet::storage]
pub type AssetToIssue<T: Config<I>, I: 'static = ()> =
StorageValue<_, AssetOf<T, I>, ValueQuery>;
#[pallet::storage]
pub type AssetToReap<T: Config<I>, I: 'static = ()> =
StorageValue<_, AssetOf<T, I>, ValueQuery>;
#[pallet::storage]
pub type BalanceSnapShots<T: Config<I>, I: 'static = ()> = StorageNMap<
_,
(
NMapKey<Blake2_128Concat, Digest<T>>,
NMapKey<Blake2_128Concat, T::Position>,
NMapKey<Blake2_128Concat, T::Time>,
),
VirtualSnapShot<T, I>,
OptionQuery,
>;
#[pallet::error]
pub enum Error<T, I = ()> {
DigestNotFoundToDetermine,
InsufficientFunds,
CommitAlreadyExists,
CannotGenerateDigest,
MarkerCommitNotAllowed,
CommitNotFound,
DigestNotFound,
IndexNotFound,
EntryOfIndexNotFound,
IndexDigestTaken,
DigestHasFunds,
IndexHasFunds,
PoolNotFound,
SlotOfPoolNotFound,
PoolManagerNotFound,
PoolDigestTaken,
PoolHasFunds,
DigestVariantBalanceNotFound,
MaxAssetIssued,
MaxAssetReaped,
ShareCannotBeZero,
CapitalCannotBeZero,
ShareGreaterThanCapital,
MintingMoreThanIssued,
BurningMoreThanReapable,
ExpectsHoldWithdrawal,
ReserveLiquidOverflow,
ExpectsFreezeAndHoldWithdrawal,
InvalidDigestModel,
VariantsExhausted,
TooSmallShareValue,
DepositDeriveOverflowed,
FactorGreaterThanOne,
MaxIndexCapacityReached,
CommitNotFoundForEntry,
CommitNotFoundForSlot,
CommitNotFoundForPool,
DepositAccumulationExhausted,
EntryDigestNotFound,
WithdrawAccumulationExhausted,
CommitsAccumulationExhausted,
ReleasePoolToRecover,
EmptySlotsNotAllowed,
CapitalUnderflowed,
CapitalOverflowed,
MaxSlotsReached,
SlotDigestNotFound,
MaxCommitsReached,
MaxEntriesReached,
CommitsNotFoundForReason,
IndexBalanceUnderflow,
InvalidCommitVariantIndex,
ZeroMaxCommits,
TriedCreatingHaltedIndexes,
EmptyEntriesNotAllowed,
EmptyCommitsNotAllowed,
DuplicateEntry,
DuplicateSlot,
CommitConstructionFailed,
EntryCommitNotFound,
CorruptedPlugin,
DerivedLessThanZeroValue,
WithdrawalOverflow,
CommissionOverflow,
PoolUnsupported,
MintingOffLimits,
ReapingOffLimits,
PlacingOffLimits,
RaisingOffLimits,
EntryDigestNotInitiated,
SlotDigestNotInitiated,
}
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config<I>, I: 'static = ()> {
CommitPlaced {
who: Proprietor<T>,
reason: CommitReason<T, I>,
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
model: DigestVariant<T, I>,
#[cfg(not(any(feature = "dev", feature = "runtime-benchmarks")))]
digest: Digest<T>,
value: AssetOf<T, I>,
variant: T::Position,
},
CommitRaised {
who: Proprietor<T>,
reason: CommitReason<T, I>,
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
model: DigestVariant<T, I>,
#[cfg(not(any(feature = "dev", feature = "runtime-benchmarks")))]
digest: Digest<T>,
value: AssetOf<T, I>,
},
CommitResolved {
who: Proprietor<T>,
reason: CommitReason<T, I>,
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
model: DigestVariant<T, I>,
#[cfg(not(any(feature = "dev", feature = "runtime-benchmarks")))]
digest: Digest<T>,
value: AssetOf<T, I>,
},
CommitValue {
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
model: DigestVariant<T, I>,
#[cfg(not(any(feature = "dev", feature = "runtime-benchmarks")))]
digest: Digest<T>,
reason: CommitReason<T, I>,
value: AssetOf<T, I>,
},
DigestInfo {
digest: Digest<T>,
reason: CommitReason<T, I>,
value: AssetOf<T, I>,
variant: T::Position,
},
DigestReaped {
digest: Digest<T>,
reason: CommitReason<T, I>,
dust: AssetOf<T, I>,
},
IndexInitialized {
index_of: IndexDigest<T>,
reason: CommitReason<T, I>,
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
entries: Vec<(EntryDigest<T>, T::Shares, T::Position)>,
},
IndexValue {
index_of: IndexDigest<T>,
reason: CommitReason<T, I>,
value: AssetOf<T, I>,
},
IndexEntryValue {
index_of: IndexDigest<T>,
reason: CommitReason<T, I>,
entry_of: Digest<T>,
value: AssetOf<T, I>,
},
IndexEntriesValue {
index_of: IndexDigest<T>,
reason: CommitReason<T, I>,
entries: Vec<(EntryDigest<T>, AssetOf<T, I>)>,
},
IndexReaped {
index_of: IndexDigest<T>,
reason: CommitReason<T, I>,
},
PoolManager {
pool_of: PoolDigest<T>,
reason: CommitReason<T, I>,
manager: Proprietor<T>,
},
PoolInitialized {
pool_of: PoolDigest<T>,
reason: CommitReason<T, I>,
commission: T::Commission,
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
slots: Vec<(SlotDigest<T>, T::Shares, T::Position)>,
},
PoolSlot {
pool_of: PoolDigest<T>,
reason: CommitReason<T, I>,
slot_of: SlotDigest<T>,
variant: T::Position,
shares: T::Shares,
},
PoolValue {
pool_of: PoolDigest<T>,
reason: CommitReason<T, I>,
value: AssetOf<T, I>,
},
PoolSlotValue {
pool_of: PoolDigest<T>,
reason: CommitReason<T, I>,
slot_of: SlotDigest<T>,
value: AssetOf<T, I>,
},
PoolSlotsValue {
pool_of: PoolDigest<T>,
reason: CommitReason<T, I>,
slots: Vec<(SlotDigest<T>, AssetOf<T, I>)>,
},
PoolCommission {
pool_of: PoolDigest<T>,
reason: CommitReason<T, I>,
commission: T::Commission,
},
ReserveDeposited {
amount: AssetOf<T, I>,
total_on_hold: AssetOf<T, I>,
},
ReserveWithdrawn {
amount: AssetOf<T, I>,
total_on_hold: AssetOf<T, I>,
},
PoolReaped {
pool_of: PoolDigest<T>,
reason: CommitReason<T, I>,
},
PoolSlotRemoved {
pool_of: PoolDigest<T>,
reason: CommitReason<T, I>,
slot_of: SlotDigest<T>,
variant: T::Position,
},
DigestModel { digest: DigestVariant<T, I> },
AssetIssuable { asset: AssetOf<T, I> },
AssetReapable { asset: AssetOf<T, I> },
ReasonValuation {
reason: CommitReason<T, I>,
value: AssetOf<T, I>,
},
}
#[pallet::call]
impl<T: Config<I>, I: 'static> Pallet<T, I> {
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::deposit_reserve())]
pub fn deposit_reserve(
origin: OriginFor<T>,
amount: AssetOf<T, I>,
precision: PrecisionWrapper,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let hold_reason: T::AssetHold = HoldReason::PrepareForCommit.into();
let reducible_balance = <T as Config<I>>::Asset::reducible_balance(
&caller,
Preservation::Preserve,
Fortitude::Polite,
);
if reducible_balance < amount {
if precision == PrecisionWrapper::Exact {
return Err(Error::<T, I>::InsufficientFunds.into());
}
<T as Config<I>>::Asset::decrease_balance(
&caller,
reducible_balance,
Precision::Exact,
Preservation::Preserve,
Fortitude::Polite,
)?;
<T as Config<I>>::Asset::increase_balance_on_hold(
&hold_reason,
&caller,
reducible_balance,
Precision::Exact,
)?;
let total_on_hold = <T as Config<I>>::Asset::balance_on_hold(&hold_reason, &caller);
Self::deposit_event(Event::<T, I>::ReserveDeposited {
amount: reducible_balance,
total_on_hold: total_on_hold,
});
return Ok(());
}
<T as Config<I>>::Asset::decrease_balance(
&caller,
amount,
Precision::Exact,
Preservation::Preserve,
Fortitude::Force,
)?;
<T as Config<I>>::Asset::increase_balance_on_hold(
&hold_reason,
&caller,
amount,
Precision::Exact,
)?;
let total_on_hold = <T as Config<I>>::Asset::balance_on_hold(&hold_reason, &caller);
Self::deposit_event(Event::<T, I>::ReserveDeposited {
amount: amount,
total_on_hold: total_on_hold,
});
Ok(())
}
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::withdraw_reserve()
.max(T::WeightInfo::withdraw_reserve_partial())
)]
pub fn withdraw_reserve(
origin: OriginFor<T>,
amount: Option<AssetOf<T, I>>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let hold_reason: T::AssetHold = HoldReason::PrepareForCommit.into();
let hold_balance = <T as Config<I>>::Asset::balance_on_hold(&hold_reason, &caller);
match amount {
None => {
<T as Config<I>>::Asset::decrease_balance_on_hold(
&hold_reason,
&caller,
hold_balance,
Precision::Exact,
)?;
<T as Config<I>>::Asset::increase_balance(
&caller,
hold_balance,
Precision::Exact,
)?;
let total_on_hold =
<T as Config<I>>::Asset::balance_on_hold(&hold_reason, &caller);
Self::deposit_event(Event::<T, I>::ReserveWithdrawn {
amount: hold_balance,
total_on_hold: total_on_hold,
});
}
Some(amount) => {
if hold_balance < amount {
return Err(Error::<T, I>::InsufficientFunds.into());
}
<T as Config<I>>::Asset::decrease_balance_on_hold(
&hold_reason,
&caller,
amount,
Precision::Exact,
)?;
<T as Config<I>>::Asset::increase_balance(&caller, amount, Precision::Exact)?;
let total_on_hold =
<T as Config<I>>::Asset::balance_on_hold(&hold_reason, &caller);
Self::deposit_event(Event::<T, I>::ReserveWithdrawn {
amount: amount,
total_on_hold: total_on_hold,
});
}
}
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(2)]
#[pallet::weight(T::WeightInfo::inspect_commit_value())]
pub fn inspect_commit_value(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let commit_value = Self::query_commit_value(caller.clone(), reason)?;
let digest_model = Self::resolve_digest_model_for(caller.clone(), reason)?;
Self::deposit_event(Event::<T, I>::CommitValue {
model: digest_model,
reason: reason,
value: commit_value,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(3)]
#[pallet::weight(T::WeightInfo::inspect_digest_model())]
pub fn inspect_digest_model(
origin: OriginFor<T>,
digest: Digest<T>,
reason: CommitReason<T, I>,
) -> DispatchResult {
ensure_signed(origin)?;
let digest_variant = Self::resolve_digest_model(digest, reason)?;
Self::deposit_event(Event::<T, I>::DigestModel {
digest: digest_variant,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(4)]
#[pallet::weight(T::WeightInfo::inspect_index_value())]
pub fn inspect_index_value(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
index_of: IndexDigest<T>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let index_value =
Self::query_index_value_for(caller, reason, index_of.clone())?;
Self::deposit_event(Event::<T, I>::IndexValue {
index_of: index_of,
reason: reason,
value: index_value,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(5)]
#[pallet::weight(T::WeightInfo::inspect_entries_value())]
pub fn inspect_entries_value(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
index_of: IndexDigest<T>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let entries_value =
Self::query_entries_value_for(caller, reason, index_of.clone())?;
Self::deposit_event(Event::<T, I>::IndexEntriesValue {
index_of: index_of,
reason: reason,
entries: entries_value,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(6)]
#[pallet::weight(T::WeightInfo::inspect_entry_value())]
pub fn inspect_entry_value(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
index_of: IndexDigest<T>,
entry_of: Digest<T>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let entry_value = Self::query_entry_value_for(
caller,
reason,
index_of.clone(),
entry_of.clone(),
)?;
Self::deposit_event(Event::<T, I>::IndexEntryValue {
index_of: index_of,
reason: reason,
entry_of: entry_of,
value: entry_value,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(7)]
#[pallet::weight(T::WeightInfo::inspect_pool_value())]
pub fn inspect_pool_value(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
pool_of: PoolDigest<T>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let pool_value = Self::query_pool_value_for(caller, reason, pool_of.clone())?;
Self::deposit_event(Event::<T, I>::PoolValue {
pool_of: pool_of,
reason: reason,
value: pool_value,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(8)]
#[pallet::weight(T::WeightInfo::inspect_slots_value())]
pub fn inspect_slots_value(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
pool_of: PoolDigest<T>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let slots_value = Self::query_slots_value_for(caller, reason, pool_of.clone())?;
Self::deposit_event(Event::<T, I>::PoolSlotsValue {
pool_of: pool_of,
reason: reason,
slots: slots_value,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(9)]
#[pallet::weight(T::WeightInfo::inspect_slot_value())]
pub fn inspect_slot_value(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
pool_of: PoolDigest<T>,
slot_of: Digest<T>,
) -> DispatchResult {
let caller = ensure_signed(origin)?;
let slot_value = Self::query_slot_value_for(
caller,
reason,
pool_of.clone(),
slot_of.clone(),
)?;
Self::deposit_event(Event::<T, I>::PoolSlotValue {
pool_of: pool_of,
reason: reason,
slot_of: slot_of,
value: slot_value,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(10)]
#[pallet::weight(T::WeightInfo::inspect_pool_commission())]
pub fn inspect_pool_commission(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
pool_of: PoolDigest<T>,
) -> DispatchResult {
ensure_signed(origin)?;
let commission = Self::query_pool_commission(reason, pool_of.clone())?;
Self::deposit_event(Event::<T, I>::PoolCommission {
pool_of: pool_of,
reason: reason,
commission: commission,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(11)]
#[pallet::weight(T::WeightInfo::inspect_pool_manager())]
pub fn inspect_pool_manager(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
pool_of: PoolDigest<T>,
) -> DispatchResult {
ensure_signed(origin)?;
let manager = Self::query_pool_manager(reason, pool_of.clone())?;
Self::deposit_event(Event::<T, I>::PoolManager {
pool_of: pool_of,
reason: reason,
manager: manager,
});
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(12)]
#[pallet::weight(T::WeightInfo::inspect_asset_to_issue())]
pub fn inspect_asset_to_issue(origin: OriginFor<T>) -> DispatchResult {
ensure_signed(origin)?;
let asset = AssetToIssue::<T, I>::get();
Self::deposit_event(Event::<T, I>::AssetIssuable { asset });
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(13)]
#[pallet::weight(T::WeightInfo::inspect_asset_to_reap())]
pub fn inspect_asset_to_reap(origin: OriginFor<T>) -> DispatchResult {
ensure_signed(origin)?;
let asset = AssetToReap::<T, I>::get();
Self::deposit_event(Event::<T, I>::AssetReapable { asset });
Ok(())
}
#[cfg(any(feature = "dev", feature = "runtime-benchmarks"))]
#[pallet::call_index(14)]
#[pallet::weight(T::WeightInfo::inspect_reason_value())]
pub fn inspect_reason_value(
origin: OriginFor<T>,
reason: CommitReason<T, I>,
) -> DispatchResult {
ensure_signed(origin)?;
let value = ReasonValue::<T, I>::get(reason).unwrap_or(Zero::zero());
Self::deposit_event(Event::<T, I>::ReasonValuation { reason, value });
Ok(())
}
}
impl<T: Config<I>, I: 'static> Pallet<T, I> {
pub fn resolve_digest_model(
digest: Digest<T>,
reason: CommitReason<T, I>,
) -> Result<DigestVariant<T, I>, DispatchError> {
let digest_variant =
<Pallet<T, I> as DigestModel<Proprietor<T>>>::determine_digest(&digest, &reason)?;
Ok(digest_variant)
}
pub fn resolve_digest_model_for(
caller: T::AccountId,
reason: CommitReason<T, I>,
) -> Result<DigestVariant<T, I>, DispatchError> {
let digest = Self::get_commit_digest(&caller, &reason)?;
let digest_variant =
<Pallet<T, I> as DigestModel<Proprietor<T>>>::determine_digest(&digest, &reason)?;
Ok(digest_variant)
}
pub fn query_commit_value(
caller: T::AccountId,
reason: CommitReason<T, I>,
) -> Result<AssetOf<T, I>, DispatchError> {
let commit_value =
<Pallet<T, I> as Commitment<Proprietor<T>>>::get_commit_value(&caller, &reason)?;
Ok(commit_value)
}
pub fn query_asset_to_issue() -> AssetOf<T, I> {
AssetToIssue::<T, I>::get()
}
pub fn query_asset_to_reap() -> AssetOf<T, I> {
AssetToReap::<T, I>::get()
}
pub fn query_reason_value(reason: CommitReason<T, I>) -> AssetOf<T, I> {
ReasonValue::<T, I>::get(reason).unwrap_or(Zero::zero())
}
pub fn query_index_value(
reason: CommitReason<T, I>,
index: IndexDigest<T>,
) -> Result<AssetOf<T, I>, DispatchError> {
let index_value =
<Pallet<T, I> as CommitIndex<Proprietor<T>>>::get_index_value(&reason, &index)?;
Ok(index_value)
}
pub fn query_entries_value(
reason: CommitReason<T, I>,
index: IndexDigest<T>,
) -> Result<Vec<(Digest<T>, AssetOf<T, I>)>, DispatchError> {
let entries_value =
<Pallet<T, I> as CommitIndex<Proprietor<T>>>::get_entries_value(&reason, &index)?;
Ok(entries_value)
}
pub fn query_entry_value(
reason: CommitReason<T, I>,
index: IndexDigest<T>,
entry: EntryDigest<T>,
) -> Result<AssetOf<T, I>, DispatchError> {
let entry_value = <Pallet<T, I> as CommitIndex<Proprietor<T>>>::get_entry_value(
&reason, &index, &entry,
)?;
Ok(entry_value)
}
pub fn query_index_value_for(
caller: T::AccountId,
reason: CommitReason<T, I>,
index: IndexDigest<T>,
) -> Result<AssetOf<T, I>, DispatchError> {
let index_value = <Pallet<T, I> as CommitIndex<Proprietor<T>>>::get_index_value_for(
&caller, &reason, &index,
)?;
Ok(index_value)
}
pub fn query_entries_value_for(
caller: T::AccountId,
reason: CommitReason<T, I>,
index: IndexDigest<T>,
) -> Result<Vec<(Digest<T>, AssetOf<T, I>)>, DispatchError> {
let entries_value =
<Pallet<T, I> as CommitIndex<Proprietor<T>>>::get_entries_value_for(
&caller, &reason, &index,
)?;
Ok(entries_value)
}
pub fn query_entry_value_for(
caller: T::AccountId,
reason: CommitReason<T, I>,
index: IndexDigest<T>,
entry: EntryDigest<T>,
) -> Result<AssetOf<T, I>, DispatchError> {
let entry_value = <Pallet<T, I> as CommitIndex<Proprietor<T>>>::get_entry_value_for(
&caller, &reason, &index, &entry,
)?;
Ok(entry_value)
}
pub fn query_pool_value(
reason: CommitReason<T, I>,
pool: PoolDigest<T>,
) -> Result<AssetOf<T, I>, DispatchError> {
let pool_of =
<Pallet<T, I> as CommitPool<Proprietor<T>>>::get_pool_value(&reason, &pool)?;
Ok(pool_of)
}
pub fn query_slots_value(
reason: CommitReason<T, I>,
pool: PoolDigest<T>,
) -> Result<Vec<(Digest<T>, AssetOf<T, I>)>, DispatchError> {
let slots_value =
<Pallet<T, I> as CommitPool<Proprietor<T>>>::get_slots_value(&reason, &pool)?;
Ok(slots_value)
}
pub fn query_slot_value(
reason: CommitReason<T, I>,
pool: PoolDigest<T>,
slot: SlotDigest<T>,
) -> Result<AssetOf<T, I>, DispatchError> {
let slot_value =
<Pallet<T, I> as CommitPool<Proprietor<T>>>::get_slot_value(&reason, &pool, &slot)?;
Ok(slot_value)
}
pub fn query_pool_commission(
reason: CommitReason<T, I>,
pool: PoolDigest<T>,
) -> Result<T::Commission, DispatchError> {
let commission =
<Pallet<T, I> as CommitPool<Proprietor<T>>>::get_commission(&reason, &pool)?;
Ok(commission)
}
pub fn query_pool_manager(
reason: CommitReason<T, I>,
pool: PoolDigest<T>,
) -> Result<T::AccountId, DispatchError> {
let manager = <Pallet<T, I> as CommitPool<Proprietor<T>>>::get_manager(&reason, &pool)?;
Ok(manager)
}
pub fn query_pool_value_for(
caller: T::AccountId,
reason: CommitReason<T, I>,
pool: PoolDigest<T>,
) -> Result<AssetOf<T, I>, DispatchError> {
let pool_value = <Pallet<T, I> as CommitPool<Proprietor<T>>>::get_pool_value_for(
&caller, &reason, &pool,
)?;
Ok(pool_value)
}
pub fn query_slots_value_for(
caller: T::AccountId,
reason: CommitReason<T, I>,
pool_of: PoolDigest<T>,
) -> Result<Vec<(Digest<T>, AssetOf<T, I>)>, DispatchError> {
let slots_value = <Pallet<T, I> as CommitPool<Proprietor<T>>>::get_slots_value_for(
&caller, &reason, &pool_of,
)?;
Ok(slots_value)
}
pub fn query_slot_value_for(
caller: T::AccountId,
reason: CommitReason<T, I>,
pool: PoolDigest<T>,
slot: SlotDigest<T>,
) -> Result<AssetOf<T, I>, DispatchError> {
let slot_value = <Pallet<T, I> as CommitPool<Proprietor<T>>>::get_slot_value_for(
&caller, &reason, &pool, &slot,
)?;
Ok(slot_value)
}
}
}
#[cfg(test)]
mod ext_tests {
use crate::{mock::*, types::PrecisionWrapper};
use frame_suite::{commitment::*, misc::Directive};
use frame_support::{
assert_err, assert_ok,
pallet_prelude::DispatchError,
traits::{
fungible::{Inspect, InspectHold},
tokens::{Fortitude, Precision},
},
};
#[test]
fn deposit_reserve_success_exact() {
commit_test_ext().execute_with(|| {
System::set_block_number(2);
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
Pallet::deposit_reserve(RuntimeOrigin::signed(ALICE), 10, PrecisionWrapper::Exact)
.unwrap();
let actual_balance = AssetOf::balance(&ALICE);
let actual_hold_balance = AssetOf::balance_on_hold(&PREPARE_FOR_COMMIT, &ALICE);
let expected_balance = 10;
let expected_hold_balance = 30;
assert_eq!(actual_balance, expected_balance);
assert_eq!(actual_hold_balance, expected_hold_balance);
System::assert_last_event(
Event::ReserveDeposited {
amount: 10,
total_on_hold: actual_hold_balance,
}
.into(),
);
})
}
#[test]
fn deposit_reserve_success_best_efforts() {
commit_test_ext().execute_with(|| {
System::set_block_number(2);
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
Pallet::deposit_reserve(
RuntimeOrigin::signed(ALICE),
25,
PrecisionWrapper::BestEffort,
)
.unwrap();
let actual_balance = AssetOf::balance(&ALICE);
let actual_hold_balance = AssetOf::balance_on_hold(&PREPARE_FOR_COMMIT, &ALICE);
let expected_balance = 0;
let expected_hold_balance = 40;
assert_eq!(actual_balance, expected_balance);
assert_eq!(actual_hold_balance, expected_hold_balance);
System::assert_last_event(
Event::ReserveDeposited {
amount: 20,
total_on_hold: actual_hold_balance,
}
.into(),
);
})
}
#[test]
fn deposit_reserve_err_insufficient_funds() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
assert_err!(
Pallet::deposit_reserve(
RuntimeOrigin::signed(ALICE),
25,
PrecisionWrapper::Exact
),
Error::InsufficientFunds
);
})
}
#[test]
fn withdraw_reserve_success() {
commit_test_ext().execute_with(|| {
System::set_block_number(2);
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
Pallet::withdraw_reserve(RuntimeOrigin::signed(ALICE), None).unwrap();
let actual_balance = AssetOf::balance(&ALICE);
let actual_hold_balance = AssetOf::balance_on_hold(&PREPARE_FOR_COMMIT, &ALICE);
let expected_balance = 40;
let expected_hold_balance = 0;
assert_eq!(actual_balance, expected_balance);
assert_eq!(actual_hold_balance, expected_hold_balance);
System::assert_last_event(
Event::ReserveWithdrawn {
amount: 20,
total_on_hold: 0,
}
.into(),
);
})
}
#[test]
fn withdraw_reserve_err_insufficient_funds() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
assert_err!(
Pallet::withdraw_reserve(RuntimeOrigin::signed(ALICE), Some(25)),
Error::InsufficientFunds
);
})
}
#[test]
fn withdraw_reserve_partial_success() {
commit_test_ext().execute_with(|| {
System::set_block_number(2);
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
Pallet::withdraw_reserve(RuntimeOrigin::signed(ALICE), Some(15)).unwrap();
let actual_balance = AssetOf::balance(&ALICE);
let actual_hold_balance = AssetOf::balance_on_hold(&PREPARE_FOR_COMMIT, &ALICE);
let expected_balance = 35;
let expected_hold_balance = 5;
assert_eq!(actual_balance, expected_balance);
assert_eq!(actual_hold_balance, expected_hold_balance);
System::assert_last_event(
Event::ReserveWithdrawn {
amount: 15,
total_on_hold: 5,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_digest_model_direct_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_DIGEST,
15,
&Directive::new(Precision::Exact, Fortitude::Force),
)
.unwrap();
Pallet::inspect_digest_model(RuntimeOrigin::signed(ALICE), ALPHA_DIGEST, STAKING)
.unwrap();
System::assert_last_event(
Event::DigestModel {
digest: DigestVariant::Direct(ALPHA_DIGEST),
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_digest_model_index_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
initiate_digest_with_default_balance(STAKING, ALPHA_ENTRY_DIGEST).unwrap();
System::set_block_number(4);
prepare_and_initiate_index(
ALICE,
STAKING,
&[(ALPHA_ENTRY_DIGEST, 40)],
ALPHA_INDEX_DIGEST,
)
.unwrap();
assert_ok!(Pallet::index_exists(&STAKING, &ALPHA_INDEX_DIGEST));
System::set_block_number(6);
let commit_amount = 20;
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_INDEX_DIGEST,
commit_amount,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_digest_model(
RuntimeOrigin::signed(ALICE),
ALPHA_INDEX_DIGEST,
STAKING,
)
.unwrap();
System::assert_last_event(
Event::DigestModel {
digest: DigestVariant::Index(ALPHA_INDEX_DIGEST),
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_digest_model_pool_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(BOB, LARGE_VALUE, 30).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let entries = vec![(ALPHA_ENTRY_DIGEST, 40)];
prepare_and_initiate_pool(
BOB,
STAKING,
&entries,
ALPHA_INDEX_DIGEST,
ALPHA_POOL_DIGEST,
COMMISSION_ZERO,
)
.unwrap();
let commit_amount = 25;
System::set_block_number(6);
Pallet::place_commit(
&BOB,
&STAKING,
&ALPHA_POOL_DIGEST,
commit_amount,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_digest_model(
RuntimeOrigin::signed(ALICE),
ALPHA_POOL_DIGEST,
STAKING,
)
.unwrap();
System::assert_last_event(
Event::DigestModel {
digest: DigestVariant::Pool(ALPHA_POOL_DIGEST),
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_digest_model_err_bad_origin() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_DIGEST,
15,
&Directive::new(Precision::Exact, Fortitude::Force),
)
.unwrap();
assert_err!(
Pallet::inspect_digest_model(RuntimeOrigin::root(), ALPHA_DIGEST, STAKING,),
DispatchError::BadOrigin
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_commit_value_for_direct_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, STANDARD_VALUE).unwrap();
System::set_block_number(2);
let commit_amount = 10;
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_DIGEST,
commit_amount,
&Directive::new(Precision::BestEffort, Fortitude::Force),
)
.unwrap();
Pallet::inspect_commit_value(RuntimeOrigin::signed(ALICE), STAKING).unwrap();
System::assert_last_event(
Event::CommitValue {
model: DigestVariant::Direct(ALPHA_DIGEST),
reason: STAKING,
value: commit_amount,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_commit_value_for_index_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
initiate_digest_with_default_balance(STAKING, ALPHA_ENTRY_DIGEST).unwrap();
System::set_block_number(4);
prepare_and_initiate_index(
ALICE,
STAKING,
&[(ALPHA_ENTRY_DIGEST, 40)],
ALPHA_INDEX_DIGEST,
)
.unwrap();
assert_ok!(Pallet::index_exists(&STAKING, &ALPHA_INDEX_DIGEST));
System::set_block_number(6);
let commit_amount = 20;
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_INDEX_DIGEST,
commit_amount,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_commit_value(RuntimeOrigin::signed(ALICE), STAKING).unwrap();
System::assert_last_event(
Event::CommitValue {
model: DigestVariant::Index(ALPHA_INDEX_DIGEST),
reason: STAKING,
value: commit_amount,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_commit_value_for_pool_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(BOB, LARGE_VALUE, 30).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let entries = vec![(ALPHA_ENTRY_DIGEST, 40)];
prepare_and_initiate_pool(
BOB,
STAKING,
&entries,
ALPHA_INDEX_DIGEST,
ALPHA_POOL_DIGEST,
COMMISSION_ZERO,
)
.unwrap();
let commit_amount = 25;
System::set_block_number(6);
Pallet::place_commit(
&BOB,
&STAKING,
&ALPHA_POOL_DIGEST,
commit_amount,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_commit_value(RuntimeOrigin::signed(BOB), STAKING).unwrap();
System::assert_last_event(
Event::CommitValue {
model: DigestVariant::Pool(ALPHA_POOL_DIGEST),
reason: STAKING,
value: commit_amount,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_commit_value_err_bad_origin() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_DIGEST,
15,
&Directive::new(Precision::Exact, Fortitude::Force),
)
.unwrap();
assert_err!(
Pallet::inspect_commit_value(RuntimeOrigin::root(), STAKING),
DispatchError::BadOrigin
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_index_value_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, 40).unwrap();
initiate_digest_with_default_balance(STAKING, ALPHA_ENTRY_DIGEST).unwrap();
initiate_digest_with_default_balance(STAKING, BETA_ENTRY_DIGEST).unwrap();
prepare_and_initiate_index(
ALICE,
STAKING,
&[(ALPHA_ENTRY_DIGEST, 40), (BETA_ENTRY_DIGEST, 60)],
ALPHA_INDEX_DIGEST,
)
.unwrap();
System::set_block_number(2);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_INDEX_DIGEST,
35,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_index_value(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_INDEX_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::IndexValue {
index_of: ALPHA_INDEX_DIGEST,
reason: STAKING,
value: 35,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_entry_value_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, 40).unwrap();
initiate_digest_with_default_balance(STAKING, ALPHA_ENTRY_DIGEST).unwrap();
initiate_digest_with_default_balance(STAKING, BETA_ENTRY_DIGEST).unwrap();
prepare_and_initiate_index(
ALICE,
STAKING,
&[(ALPHA_ENTRY_DIGEST, 40), (BETA_ENTRY_DIGEST, 60)],
ALPHA_INDEX_DIGEST,
)
.unwrap();
System::set_block_number(2);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_INDEX_DIGEST,
35,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_entry_value(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_INDEX_DIGEST,
ALPHA_ENTRY_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::IndexEntryValue {
index_of: ALPHA_INDEX_DIGEST,
reason: STAKING,
entry_of: ALPHA_ENTRY_DIGEST,
value: 14,
}
.into(),
);
Pallet::inspect_entry_value(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_INDEX_DIGEST,
BETA_ENTRY_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::IndexEntryValue {
index_of: ALPHA_INDEX_DIGEST,
reason: STAKING,
entry_of: BETA_ENTRY_DIGEST,
value: 21,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_entries_value_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, 40).unwrap();
initiate_digest_with_default_balance(STAKING, ALPHA_ENTRY_DIGEST).unwrap();
initiate_digest_with_default_balance(STAKING, BETA_ENTRY_DIGEST).unwrap();
prepare_and_initiate_index(
ALICE,
STAKING,
&[(ALPHA_ENTRY_DIGEST, 40), (BETA_ENTRY_DIGEST, 60)],
ALPHA_INDEX_DIGEST,
)
.unwrap();
System::set_block_number(2);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_INDEX_DIGEST,
35,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_entries_value(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_INDEX_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::IndexEntriesValue {
index_of: ALPHA_INDEX_DIGEST,
reason: STAKING,
entries: vec![(ALPHA_ENTRY_DIGEST, 14), (BETA_ENTRY_DIGEST, 21)],
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_pool_value_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(BOB, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(CHARLIE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&BOB,
&STAKING,
&ALPHA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
System::set_block_number(6);
Pallet::place_commit(
&CHARLIE,
&STAKING,
&BETA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let entries = vec![(ALPHA_ENTRY_DIGEST, 60), (BETA_ENTRY_DIGEST, 40)];
prepare_and_initiate_pool(
ALICE,
STAKING,
&entries,
ALPHA_INDEX_DIGEST,
ALPHA_POOL_DIGEST,
COMMISSION_ZERO,
)
.unwrap();
System::set_block_number(10);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_POOL_DIGEST,
LARGE_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_pool_value(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_POOL_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::PoolValue {
pool_of: ALPHA_POOL_DIGEST,
reason: STAKING,
value: 20,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_slot_value_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(BOB, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(CHARLIE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&BOB,
&STAKING,
&ALPHA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
System::set_block_number(6);
Pallet::place_commit(
&CHARLIE,
&STAKING,
&BETA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let entries = vec![(ALPHA_ENTRY_DIGEST, 60), (BETA_ENTRY_DIGEST, 40)];
prepare_and_initiate_pool(
ALICE,
STAKING,
&entries,
ALPHA_INDEX_DIGEST,
ALPHA_POOL_DIGEST,
COMMISSION_ZERO,
)
.unwrap();
System::set_block_number(10);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_POOL_DIGEST,
LARGE_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_slot_value(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_POOL_DIGEST,
ALPHA_ENTRY_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::PoolSlotValue {
pool_of: ALPHA_POOL_DIGEST,
reason: STAKING,
slot_of: ALPHA_ENTRY_DIGEST,
value: 12,
}
.into(),
);
Pallet::inspect_slot_value(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_POOL_DIGEST,
BETA_ENTRY_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::PoolSlotValue {
pool_of: ALPHA_POOL_DIGEST,
reason: STAKING,
slot_of: BETA_ENTRY_DIGEST,
value: 8,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_slots_value_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(BOB, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(CHARLIE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&BOB,
&STAKING,
&ALPHA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
System::set_block_number(6);
Pallet::place_commit(
&CHARLIE,
&STAKING,
&BETA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let entries = vec![(ALPHA_ENTRY_DIGEST, 60), (BETA_ENTRY_DIGEST, 40)];
prepare_and_initiate_pool(
ALICE,
STAKING,
&entries,
ALPHA_INDEX_DIGEST,
ALPHA_POOL_DIGEST,
COMMISSION_ZERO,
)
.unwrap();
System::set_block_number(10);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_POOL_DIGEST,
LARGE_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_slots_value(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_POOL_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::PoolSlotsValue {
pool_of: ALPHA_POOL_DIGEST,
reason: STAKING,
slots: vec![(ALPHA_ENTRY_DIGEST, 12), (BETA_ENTRY_DIGEST, 8)],
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_pool_commission_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(BOB, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(CHARLIE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&BOB,
&STAKING,
&ALPHA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
System::set_block_number(6);
Pallet::place_commit(
&CHARLIE,
&STAKING,
&BETA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let entries = vec![(ALPHA_ENTRY_DIGEST, 60), (BETA_ENTRY_DIGEST, 40)];
let init_commission = COMMISSION_HIGH;
prepare_and_initiate_pool(
ALICE,
STAKING,
&entries,
ALPHA_INDEX_DIGEST,
ALPHA_POOL_DIGEST,
init_commission,
)
.unwrap();
System::set_block_number(10);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_POOL_DIGEST,
LARGE_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_pool_commission(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_POOL_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::PoolCommission {
pool_of: ALPHA_POOL_DIGEST,
reason: STAKING,
commission: init_commission,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_pool_manager_success() {
commit_test_ext().execute_with(|| {
initiate_key_and_set_balance_and_hold(ALICE, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(BOB, LARGE_VALUE, LARGE_VALUE).unwrap();
initiate_key_and_set_balance_and_hold(CHARLIE, LARGE_VALUE, LARGE_VALUE).unwrap();
System::set_block_number(2);
Pallet::place_commit(
&BOB,
&STAKING,
&ALPHA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
System::set_block_number(6);
Pallet::place_commit(
&CHARLIE,
&STAKING,
&BETA_ENTRY_DIGEST,
STANDARD_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let entries = vec![(ALPHA_ENTRY_DIGEST, 60), (BETA_ENTRY_DIGEST, 40)];
let manager = ALICE;
prepare_and_initiate_pool(
manager.clone(),
STAKING,
&entries,
ALPHA_INDEX_DIGEST,
ALPHA_POOL_DIGEST,
COMMISSION_ZERO,
)
.unwrap();
System::set_block_number(10);
Pallet::place_commit(
&ALICE,
&STAKING,
&ALPHA_POOL_DIGEST,
LARGE_VALUE,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_pool_manager(
RuntimeOrigin::signed(ALICE),
STAKING,
ALPHA_POOL_DIGEST,
)
.unwrap();
System::assert_last_event(
Event::PoolManager {
pool_of: ALPHA_POOL_DIGEST,
reason: STAKING,
manager: manager,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_asset_to_mint() {
commit_test_ext().execute_with(|| {
System::set_block_number(10);
initiate_key_and_set_balance_and_hold(ALICE, STANDARD_COMMIT, STANDARD_HOLD)
.unwrap();
Pallet::place_commit(
&ALICE,
&STAKING,
&VALIDATOR_ALPHA,
STANDARD_COMMIT,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let new_digest_val = 325; Pallet::set_digest_value(
&STAKING,
&VALIDATOR_ALPHA,
new_digest_val,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let expected_issuable = new_digest_val.saturating_sub(STANDARD_COMMIT); Pallet::inspect_asset_to_issue(RuntimeOrigin::signed(ALICE)).unwrap();
System::assert_last_event(
Event::AssetIssuable {
asset: expected_issuable,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_asset_to_reap() {
commit_test_ext().execute_with(|| {
System::set_block_number(10);
initiate_key_and_set_balance_and_hold(ALICE, STANDARD_COMMIT, STANDARD_HOLD)
.unwrap();
Pallet::place_commit(
&ALICE,
&STAKING,
&VALIDATOR_ALPHA,
STANDARD_COMMIT,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let new_digest_val = 215; Pallet::set_digest_value(
&STAKING,
&VALIDATOR_ALPHA,
new_digest_val,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let expected_reapable = STANDARD_COMMIT.saturating_sub(new_digest_val); Pallet::inspect_asset_to_reap(RuntimeOrigin::signed(ALICE)).unwrap();
System::assert_last_event(
Event::AssetReapable {
asset: expected_reapable,
}
.into(),
);
})
}
#[cfg(feature = "dev")]
#[test]
fn inspect_reason_value() {
commit_test_ext().execute_with(|| {
System::set_block_number(10);
initiate_key_and_set_balance_and_hold(ALICE, STANDARD_COMMIT, STANDARD_HOLD)
.unwrap();
initiate_key_and_set_balance_and_hold(BOB, STANDARD_COMMIT, STANDARD_HOLD).unwrap();
initiate_key_and_set_balance_and_hold(ALAN, STANDARD_COMMIT, STANDARD_HOLD)
.unwrap();
Pallet::place_commit(
&ALICE,
&STAKING,
&VALIDATOR_ALPHA,
150,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_reason_value(RuntimeOrigin::signed(ALICE), STAKING).unwrap();
System::assert_last_event(
Event::ReasonValuation {
reason: STAKING,
value: 150,
}
.into(),
);
Pallet::place_commit(
&BOB,
&ESCROW,
&CONTRACT_FREELANCE,
STANDARD_COMMIT,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_reason_value(RuntimeOrigin::signed(ALICE), ESCROW).unwrap();
System::assert_last_event(
Event::ReasonValuation {
reason: ESCROW,
value: 250,
}
.into(),
);
Pallet::place_commit(
&ALAN,
&STAKING,
&VALIDATOR_BETA,
STANDARD_COMMIT,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
Pallet::inspect_reason_value(RuntimeOrigin::signed(ALICE), STAKING).unwrap();
System::assert_last_event(
Event::ReasonValuation {
reason: STAKING,
value: 400,
}
.into(),
);
Pallet::inspect_reason_value(RuntimeOrigin::signed(ALICE), GOVERNANCE).unwrap();
System::assert_last_event(
Event::ReasonValuation {
reason: GOVERNANCE,
value: 0,
}
.into(),
);
})
}
#[test]
fn query_asset_to_mint() {
commit_test_ext().execute_with(|| {
System::set_block_number(10);
initiate_key_and_set_balance_and_hold(ALICE, STANDARD_COMMIT, STANDARD_HOLD)
.unwrap();
Pallet::place_commit(
&ALICE,
&STAKING,
&VALIDATOR_ALPHA,
STANDARD_COMMIT,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let new_digest_val = 325; Pallet::set_digest_value(
&STAKING,
&VALIDATOR_ALPHA,
new_digest_val,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let expected_issuable = new_digest_val.saturating_sub(STANDARD_COMMIT); let actual_issuable = Pallet::query_asset_to_issue();
assert_eq!(expected_issuable, actual_issuable);
})
}
#[test]
fn query_asset_to_reap() {
commit_test_ext().execute_with(|| {
System::set_block_number(10);
initiate_key_and_set_balance_and_hold(ALICE, STANDARD_COMMIT, STANDARD_HOLD)
.unwrap();
Pallet::place_commit(
&ALICE,
&STAKING,
&VALIDATOR_ALPHA,
STANDARD_COMMIT,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let new_digest_val = 215; Pallet::set_digest_value(
&STAKING,
&VALIDATOR_ALPHA,
new_digest_val,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let expected_reapable = STANDARD_COMMIT.saturating_sub(new_digest_val); let actual_reapable = Pallet::query_asset_to_reap();
assert_eq!(expected_reapable, actual_reapable);
})
}
#[test]
fn query_reason_value() {
commit_test_ext().execute_with(|| {
System::set_block_number(10);
initiate_key_and_set_balance_and_hold(ALICE, STANDARD_COMMIT, STANDARD_HOLD)
.unwrap();
initiate_key_and_set_balance_and_hold(BOB, STANDARD_COMMIT, STANDARD_HOLD).unwrap();
initiate_key_and_set_balance_and_hold(ALAN, STANDARD_COMMIT, STANDARD_HOLD)
.unwrap();
Pallet::place_commit(
&ALICE,
&STAKING,
&VALIDATOR_ALPHA,
150,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let staking_value = Pallet::query_reason_value(STAKING);
assert_eq!(staking_value, 150);
Pallet::place_commit(
&BOB,
&ESCROW,
&CONTRACT_FREELANCE,
STANDARD_COMMIT,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let escrow_value = Pallet::query_reason_value(ESCROW);
assert_eq!(escrow_value, 250);
Pallet::place_commit(
&ALAN,
&STAKING,
&VALIDATOR_BETA,
STANDARD_COMMIT,
&Directive::new(Precision::BestEffort, Fortitude::Polite),
)
.unwrap();
let staking_value = Pallet::query_reason_value(STAKING);
assert_eq!(staking_value, 400);
let governance_value = Pallet::query_reason_value(GOVERNANCE);
assert_eq!(governance_value, 0);
})
}
}