#![cfg(feature = "std")]
#![allow(unused)]
use crate as pallet_commitment;
use crate::CommitHelpers;
use frame_plugins::balances::{ShareBalanceContext, ShareBalanceFamily};
use frame_suite::{
commitment::*,
misc::{Disposition, Ignore},
plugin_context,
xp::XpMutate,
Commitment as CommitmentTrait
};
use frame_support::{
derive_impl,
pallet_prelude::*,
traits::{
fungible::{Mutate, UnbalancedHold},
VariantCount,
},
};
use pallet_xp::types::GenesisAcc;
use serde::{Deserialize, Serialize};
use sp_core::ConstBool;
use sp_runtime::{AccountId32, BuildStorage, DispatchResult, FixedU64, Perbill};
pub type Block = frame_system::mocking::MockBlock<Test>;
pub type AccountId = AccountId32;
pub type Account = frame_system::Account<Test>;
pub type Asset = u128;
pub type Shares = u32;
pub type Commission = Perbill;
pub type Pallet = crate::Pallet<Test>;
pub type Error = crate::Error<Test>;
pub type Event = crate::Event<Test>;
pub type CommitHelper = CommitHelpers<Test>;
pub type AssetOf = <Test as crate::Config>::Asset;
pub type Position = <Test as crate::Config>::Position;
pub type ReasonValue = crate::ReasonValue<Test>;
pub type DigestMap = crate::DigestMap<Test>;
pub type CommitMap = crate::CommitMap<Test>;
pub type EntryMap = crate::EntryMap<Test>;
pub type IndexMap = crate::IndexMap<Test>;
pub type PoolMap = crate::PoolMap<Test>;
pub type AssetToIssue = crate::AssetToIssue<Test>;
pub type AssetToReap = crate::AssetToReap<Test>;
pub type CommitInfo = crate::types::CommitInfo<Test>;
pub type EntryInfo = crate::types::EntryInfo<Test>;
pub type IndexInfo = crate::types::IndexInfo<Test>;
pub type PoolInfo = crate::types::PoolInfo<Test>;
pub type SlotInfo = crate::types::SlotInfo<Test>;
pub type AssetDelta = crate::types::AssetDelta<Test>;
pub type Commits = crate::types::Commits<Test>;
pub type Entries = crate::types::Entries<Test>;
pub type Slots = crate::types::Slots<Test>;
pub type CommitInstance = crate::types::CommitInstance<Test>;
pub type DigestVariant = crate::types::DigestVariant<Test>;
pub type DigestInfo = crate::types::DigestInfo<Test>;
pub type LazyBalance = crate::types::LazyBalanceOf<Test>;
pub const fn account_frm_seed(seed: u8) -> AccountId {
let mut data = [0u8; 32];
data[31] = seed;
AccountId::new(data)
}
pub const PREPARE_FOR_COMMIT: HoldReason = HoldReason::PrepareForCommit;
pub const EXTERNAL_HOLD: HoldReason = HoldReason::External;
pub const STAKING: FreezeReason = FreezeReason::Staking;
pub const GOVERNANCE: FreezeReason = FreezeReason::Governance;
pub const ESCROW: FreezeReason = FreezeReason::Escrow;
pub const INITIAL_BALANCE: Asset = 1000;
pub const STANDARD_HOLD: Asset = 500;
pub const STANDARD_COMMIT: Asset = 250;
pub const LARGE_COMMIT: Asset = 500;
pub const SMALL_COMMIT: Asset = 100;
pub const STANDARD_REWARD: Asset = 50;
pub const SMALL_REWARD: Asset = 10;
pub const STANDARD_PENALTY: Asset = 100;
pub const SMALL_PENALTY: Asset = 10;
pub const LARGE_VALUE: Asset = 20;
pub const STANDARD_VALUE: Asset = 10;
pub const SMALL_VALUE: Asset = 5;
pub const ZERO_VALUE: Asset = 0;
pub const MAX_VALUE: Asset = Asset::MAX;
pub const SHARE_DOMINANT: Shares = 60;
pub const SHARE_MAJOR: Shares = 40;
pub const SHARE_EQUAL: Shares = 100;
pub const MAX_SHARES: Shares = Shares::MAX;
pub const ZERO_SHARE: Shares = 0;
pub const COMMISSION_ZERO: Commission = Commission::from_percent(0);
pub const COMMISSION_ONE: Commission = Commission::from_percent(1);
pub const COMMISSION_LOW: Commission = Commission::from_percent(5);
pub const COMMISSION_STANDARD: Commission = Commission::from_percent(10);
pub const COMMISSION_HIGH: Commission = Commission::from_percent(15);
pub const COMMISSION_MAX: Commission = Commission::from_percent(100);
pub const BLOCK_START: u64 = 1;
pub const BLOCK_EARLY: u64 = 100;
pub const BLOCK_MID: u64 = 300;
pub const BLOCK_LATE: u64 = 500;
pub const ALICE: AccountId = account_frm_seed(1);
pub const BOB: AccountId = account_frm_seed(2);
pub const CHARLIE: AccountId = account_frm_seed(3);
pub const ALAN: AccountId = account_frm_seed(4);
pub const MIKE: AccountId = account_frm_seed(5);
pub const NIX: AccountId = account_frm_seed(6);
pub const DAVE: AccountId = account_frm_seed(7);
pub const AMY: AccountId = account_frm_seed(8);
pub const ALPHA_DIGEST: AccountId = account_frm_seed(11);
pub const BETA_DIGEST: AccountId = account_frm_seed(12);
pub const GAMMA_DIGEST: AccountId = account_frm_seed(13);
pub const DELTA_DIGEST: AccountId = account_frm_seed(14);
pub const ALPHA_ENTRY_DIGEST: AccountId = account_frm_seed(21);
pub const BETA_ENTRY_DIGEST: AccountId = account_frm_seed(22);
pub const GAMMA_ENTRY_DIGEST: AccountId = account_frm_seed(23);
pub const DELTA_ENTRY_DIGEST: AccountId = account_frm_seed(24);
pub const ALPHA_INDEX_DIGEST: AccountId = account_frm_seed(31);
pub const BETA_INDEX_DIGEST: AccountId = account_frm_seed(32);
pub const GAMMA_INDEX_DIGEST: AccountId = account_frm_seed(33);
pub const DELTA_INDEX_DIGEST: AccountId = account_frm_seed(34);
pub const ALPHA_POOL_DIGEST: AccountId = account_frm_seed(41);
pub const BETA_POOL_DIGEST: AccountId = account_frm_seed(42);
pub const GAMMA_POOL_DIGEST: AccountId = account_frm_seed(43);
pub const DELTA_POOL_DIGEST: AccountId = account_frm_seed(44);
pub const VALIDATOR_ALPHA: AccountId = account_frm_seed(51);
pub const VALIDATOR_BETA: AccountId = account_frm_seed(52);
pub const VALIDATOR_GAMMA: AccountId = account_frm_seed(53);
pub const VALIDATOR_DELTA: AccountId = account_frm_seed(54);
pub const PROPOSAL_RUNTIME_UPGRADE: AccountId = account_frm_seed(61);
pub const PROPOSAL_TREASURY_SPEND: AccountId = account_frm_seed(62);
pub const CONTRACT_FREELANCE: AccountId = account_frm_seed(71);
pub const CONTRACT_SUPPLY_CHAIN: AccountId = account_frm_seed(72);
pub const INDEX_OPTIMIZED_STAKING: AccountId = account_frm_seed(81);
pub const INDEX_BALANCED_STAKING: AccountId = account_frm_seed(82);
pub const INDEX_GOVERNANCE_BUNDLE: AccountId = account_frm_seed(83);
pub const INDEX_ESCROW_DISTRIBUTION: AccountId = account_frm_seed(84);
pub const POOL_MANAGED_STAKING: AccountId = account_frm_seed(91);
pub const POOL_EXPERT_GOVERNANCE: AccountId = account_frm_seed(92);
pub const POOL_PROFESSIONAL_ESCROW: AccountId = account_frm_seed(93);
pub fn commit_test_ext() -> sp_io::TestExternalities {
let mut t = frame_system::GenesisConfig::<Test>::default()
.build_storage()
.unwrap();
crate::GenesisConfig::<Test>::default()
.assimilate_storage(&mut t)
.unwrap();
pallet_xp::GenesisConfig::<Test> {
genesis_acc: vec![
GenesisAcc {
owner: ALICE,
id: ALICE,
},
GenesisAcc {
owner: BOB,
id: BOB,
},
GenesisAcc {
owner: MIKE,
id: MIKE,
},
GenesisAcc {
owner: CHARLIE,
id: CHARLIE,
},
GenesisAcc {
owner: ALAN,
id: ALAN,
},
GenesisAcc {
owner: NIX,
id: NIX,
},
GenesisAcc {
owner: DAVE,
id: DAVE,
},
],
..Default::default()
}
.assimilate_storage(&mut t)
.unwrap();
t.into()
}
pub fn set_user_balance_and_hold(who: AccountId, balance: Asset, hold: Asset) -> DispatchResult {
AssetOf::set_balance(&who, balance);
AssetOf::set_balance_on_hold(&PREPARE_FOR_COMMIT, &who, hold)?;
Ok(())
}
pub fn set_default_user_balance_and_standard_hold(who: AccountId) -> DispatchResult {
AssetOf::set_balance(&who, INITIAL_BALANCE);
AssetOf::set_balance_on_hold(&PREPARE_FOR_COMMIT, &who, STANDARD_HOLD)?;
Ok(())
}
pub fn initiate_key_and_set_balance_and_hold(
who: AccountId,
balance: Asset,
hold: Asset,
) -> DispatchResult {
AssetOf::new_xp(&who, &who);
AssetOf::set_balance(&who, balance);
AssetOf::set_balance_on_hold(&PREPARE_FOR_COMMIT, &who, hold)?;
Ok(())
}
pub fn initiate_digest_with_default_balance(
reason: FreezeReason,
digest: AccountId,
) -> DispatchResult {
let mut digest_info = DigestInfo::default();
digest_info
.init_balance(&Default::default())
.map_err(|_| "Failed to push default variant balance")?;
DigestMap::insert((reason, digest), digest_info);
Ok(())
}
pub fn prepare_and_initiate_index(
who: AccountId,
reason: FreezeReason,
entries: &[(AccountId, Shares)], index_digest: AccountId,
) -> DispatchResult {
for (entry, _) in entries{
if Pallet::digest_exists(&reason, &entry).is_err() {
initiate_digest_with_default_balance(reason, entry.clone())?;
}
}
let index = Pallet::prepare_index(&who, &reason, entries)?;
Pallet::set_index(&who, &reason, &index, &index_digest)?;
Ok(())
}
pub fn prepare_and_initiate_pool(
who: AccountId,
reason: FreezeReason,
entries: &[(AccountId, Shares)],
index_digest: AccountId,
pool_digest: AccountId,
commission: Commission,
) -> DispatchResult {
prepare_and_initiate_index(who.clone(), reason, entries, index_digest.clone())?;
Pallet::set_pool(&who, &reason, &pool_digest, &index_digest, commission).unwrap();
Ok(())
}
#[macro_export]
macro_rules! assert_debug_panic_or_err {
($expr:expr, $err:expr) => {{
use std::panic::{catch_unwind, AssertUnwindSafe};
let result = catch_unwind(AssertUnwindSafe(|| $expr));
#[cfg(debug_assertions)]
{
assert!(
result.is_err(),
"Expected panic in debug build, but call succeeded"
);
}
#[cfg(not(debug_assertions))]
{
let inner = result.expect("Call panicked in release build");
assert_err!(inner, $err);
}
}};
}
#[frame_support::runtime]
pub mod runtime {
#[runtime::runtime]
#[runtime::derive(
RuntimeCall,
RuntimeEvent,
RuntimeError,
RuntimeOrigin,
RuntimeFreezeReason,
RuntimeHoldReason,
RuntimeSlashReason,
RuntimeLockId,
RuntimeTask,
RuntimeViewFunction
)]
pub struct Test;
#[runtime::pallet_index(0)]
pub type System = frame_system::Pallet<Test>;
#[runtime::pallet_index(1)]
pub type Commitment = pallet_commitment::Pallet<Test>;
#[runtime::pallet_index(2)]
pub type Xp = pallet_xp::Pallet<Test>;
}
#[derive(
Clone,
Copy,
PartialEq,
PartialOrd,
Ord,
Eq,
DecodeWithMemTracking,
RuntimeDebug,
Encode,
Decode,
TypeInfo,
MaxEncodedLen,
Serialize,
Deserialize,
)]
pub enum HoldReason {
PrepareForCommit,
External,
}
impl VariantCount for HoldReason {
const VARIANT_COUNT: u32 = 2;
}
#[derive(
Clone,
Copy,
PartialEq,
PartialOrd,
Ord,
Eq,
DecodeWithMemTracking,
RuntimeDebug,
Encode,
Decode,
TypeInfo,
MaxEncodedLen,
Serialize,
Deserialize,
)]
pub enum FreezeReason {
Staking,
Governance,
Escrow,
Benchmarks,
}
impl VariantCount for FreezeReason {
const VARIANT_COUNT: u32 = 4;
}
impl From<pallet_commitment::HoldReason> for HoldReason {
fn from(reason: pallet_commitment::HoldReason) -> Self {
match reason {
crate::HoldReason::PrepareForCommit => HoldReason::PrepareForCommit,
crate::HoldReason::__Ignore(_) => unreachable!("composite enum __Ignore should never be constructed")
}
}
}
impl From<pallet_commitment::FreezeReason> for FreezeReason {
fn from(reason: pallet_commitment::FreezeReason) -> Self {
match reason {
crate::FreezeReason::BenchTestReason => FreezeReason::Benchmarks,
crate::FreezeReason::__Ignore(_) => unreachable!("composite enum __Ignore should never be constructed")
}
}
}
#[derive_impl(frame_system::config_preludes::TestDefaultConfig)]
impl frame_system::Config for Test {
type Block = Block;
type AccountId = AccountId;
type Lookup = sp_runtime::traits::IdentityLookup<Self::AccountId>;
}
impl pallet_commitment::Config for Test {
type RuntimeEvent = RuntimeEvent;
type Shares = Shares;
type Bias = FixedU64;
type Asset = Xp;
type Commission = Commission;
type Position = Disposition;
type AssetHold = HoldReason;
type AssetFreeze = FreezeReason;
type MaxIndexEntries = ConstU32<3>;
type MaxCommits = ConstU32<3>;
type Time = u32;
type BalanceFamily<'a> = ShareBalanceFamily<'a>;
type BalanceContext = MyBalanceContext<Commitment>;
type WeightInfo = ();
type EmitEvents = ConstBool<true>;
}
plugin_context!(
name: pub MyBalanceContext,
context: ShareBalanceContext<T>,
marker: [T,],
value: ShareBalanceContext(PhantomData)
);
impl pallet_xp::Config for Test {
type Xp = Asset;
type Pulse = u32;
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type LockReason = FreezeReason;
type ReserveReason = HoldReason;
type Extensions = Ignore<Xp>;
type WeightInfo = ();
type EmitEvents = ConstBool<true>;
}