use crate::mock::*;
use frame_suite::{
keys::{test_utils, KeySeedFor},
xp::*,
};
use frame_support::{assert_err, assert_ok, traits::tokens::Precision};
use sp_runtime::traits::BlakeTwo256;
#[test]
fn create_and_earn_xp() {
xp_test_ext().execute_with(|| {
Pallet::new_xp(&ALICE, &XP_ALPHA);
assert_ok!(Pallet::xp_exists(&XP_ALPHA));
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, InitXp::get());
assert_eq!(xp.pulse.value, 0);
System::set_block_number(2);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_COMMENT).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 10);
assert_eq!(xp.pulse.value, 0);
System::set_block_number(3);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_COMMENT).unwrap();
System::set_block_number(5);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_COMMENT).unwrap();
System::set_block_number(10);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_PROPOSAL).unwrap();
System::set_block_number(15);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_COMMENT).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 10);
assert_eq!(xp.pulse.value, 1);
System::set_block_number(17);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_PROPOSAL).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 20);
assert_eq!(xp.pulse.value, 1);
System::set_block_number(18);
Pallet::lock_xp(&XP_ALPHA, &STAKING, DEFAULT_POINTS).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 10);
assert_eq!(xp.pulse.value, 1);
assert_eq!(xp.lock, 10);
System::set_block_number(20);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_COMMENT).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 15);
assert_eq!(xp.pulse.value, 1);
System::set_block_number(22);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_COMMENT).unwrap();
System::set_block_number(27);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_COMMENT).unwrap();
System::set_block_number(29);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_PROPOSAL).unwrap();
System::set_block_number(34);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_COMMENT).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 40);
assert_eq!(xp.pulse.value, 2);
System::set_block_number(40);
Pallet::earn_xp(&XP_ALPHA, XP_REWARD_PROPOSAL).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 60);
assert_eq!(xp.pulse.value, 2);
});
}
#[test]
fn earn_xp_overflow() {
xp_test_ext().execute_with(|| {
Pallet::new_xp(&ALICE, &XP_ALPHA);
Pallet::set_xp(&ALICE, SATURATED_MAX).unwrap();
System::set_block_number(3);
Pallet::earn_xp(&XP_ALPHA, DEFAULT_POINTS).unwrap();
System::set_block_number(6);
Pallet::earn_xp(&XP_ALPHA, DEFAULT_POINTS).unwrap();
System::set_block_number(8);
Pallet::earn_xp(&XP_ALPHA, DEFAULT_POINTS).unwrap();
System::set_block_number(10);
Pallet::earn_xp(&XP_ALPHA, DEFAULT_POINTS).unwrap();
System::set_block_number(12);
Pallet::earn_xp(&XP_ALPHA, DEFAULT_POINTS).unwrap();
System::set_block_number(15);
assert_err!(
Pallet::earn_xp(&XP_ALPHA, DEFAULT_POINTS),
Error::XpCapOverflowed
);
});
}
#[test]
fn transfer_owner() {
xp_test_ext().execute_with(|| {
Pallet::new_xp(&ALICE, &XP_ALPHA);
assert_ok!(Pallet::is_owner(&ALICE, &XP_ALPHA));
Pallet::new_xp(&BOB, &XP_BETA);
let _ = Pallet::transfer_owner(&ALICE, &XP_ALPHA, &BOB);
assert_err!(Pallet::is_owner(&ALICE, &XP_ALPHA), Error::InvalidXpOwner);
assert_ok!(Pallet::is_owner(&BOB, &XP_ALPHA));
let actual = Pallet::xp_of_owner(&BOB).unwrap();
let expected = vec![XP_ALPHA, XP_BETA];
assert_eq!(expected, actual);
});
}
#[test]
fn reap_xp() {
xp_test_ext().execute_with(|| {
System::set_block_number(2);
Pallet::new_xp(&ALICE, &XP_ALPHA);
assert_ok!(Pallet::xp_exists(&XP_ALPHA));
System::set_block_number(4);
System::set_block_number(6);
System::set_block_number(12);
Pallet::force_genesis_config(
RuntimeOrigin::root(),
crate::types::ForceGenesisConfig::MinTimeStamp(10),
)
.unwrap();
System::set_block_number(20);
Pallet::try_reap(&XP_ALPHA).unwrap();
assert_err!(Pallet::xp_exists(&XP_ALPHA), Error::XpNotFound);
assert_ok!(Pallet::is_reaped(&XP_ALPHA));
});
}
#[test]
fn reserve_and_withdraw_xp() {
xp_test_ext().execute_with(|| {
Pallet::new_xp(&ALICE, &XP_ALPHA);
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 10);
assert_eq!(xp.reserve, 0);
let new_points = 50;
Pallet::set_xp(&ALICE, new_points).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 50);
let reserve_points = 40;
Pallet::reserve_xp(&XP_ALPHA, &GOVERNANCE, reserve_points).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 10);
assert_eq!(xp.reserve, reserve_points);
let underflow_reserve_points = 30;
assert_err!(
Pallet::reserve_xp(&XP_ALPHA, &GOVERNANCE, underflow_reserve_points),
Error::InsufficientLiquidXp
);
let partial_withdraw = 20;
Pallet::withdraw_reserve_partial(
&XP_ALPHA,
&GOVERNANCE,
partial_withdraw,
Precision::BestEffort,
)
.unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 30);
assert_eq!(xp.reserve, 20);
let underflow_withdraw = 40;
assert_err!(
Pallet::withdraw_reserve_partial(
&XP_ALPHA,
&GOVERNANCE,
underflow_withdraw,
Precision::Exact
),
Error::InsufficientReserveXp
);
Pallet::withdraw_reserve(&XP_ALPHA, &GOVERNANCE).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 50);
assert_eq!(xp.reserve, 0);
});
}
#[test]
fn reserve_overflow() {
xp_test_ext().execute_with(|| {
Pallet::new_xp(&ALICE, &XP_ALPHA);
Pallet::set_reserve(&ALICE, &GOVERNANCE, SATURATED_MAX).unwrap();
assert_err!(
Pallet::reserve_xp(&XP_ALPHA, &GOVERNANCE, DEFAULT_POINTS),
Error::XpReserveCapOverflowed
);
});
}
#[test]
fn lock_and_withdraw_xp() {
xp_test_ext().execute_with(|| {
Pallet::new_xp(&ALICE, &XP_ALPHA);
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 10);
assert_eq!(xp.lock, 0);
let new_points = 50;
Pallet::set_xp(&ALICE, new_points).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 50);
let lock_points = 30;
Pallet::lock_xp(&XP_ALPHA, &STAKING, lock_points).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 20);
assert_eq!(xp.lock, lock_points);
let underflow_lock_points = 30;
assert_err!(
Pallet::lock_xp(&XP_ALPHA, &STAKING, underflow_lock_points),
Error::InsufficientLiquidXp
);
assert_err!(
Pallet::lock_xp(&XP_ALPHA, &STAKING, INVALID_POINTS),
Error::CannotLockZero
);
Pallet::withdraw_lock(&XP_ALPHA, &STAKING).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 50);
assert_eq!(xp.lock, 0);
assert_err!(
Pallet::lock_exists(&XP_ALPHA, &STAKING),
Error::XpLockNotFound
);
});
}
#[test]
fn lock_overflow() {
xp_test_ext().execute_with(|| {
Pallet::new_xp(&ALICE, &XP_ALPHA);
Pallet::set_lock(&ALICE, &STAKING, SATURATED_MAX).unwrap();
assert_err!(
Pallet::lock_xp(&XP_ALPHA, &STAKING, DEFAULT_POINTS),
Error::XpLockCapOverflowed
);
});
}
#[test]
fn begin_xp() {
xp_test_ext().execute_with(|| {
System::set_block_number(2);
assert_err!(Pallet::xp_exists(&XP_ALPHA), Error::XpNotFound);
Pallet::begin_xp(&ALICE, &XP_ALPHA, DEFAULT_POINTS).unwrap();
assert_ok!(Pallet::xp_exists(&XP_ALPHA));
System::set_block_number(4);
Pallet::begin_xp(&ALICE, &XP_ALPHA, DEFAULT_POINTS).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 10);
assert_eq!(xp.pulse.value, 0);
System::set_block_number(6);
Pallet::begin_xp(&ALICE, &XP_ALPHA, DEFAULT_POINTS).unwrap();
System::set_block_number(8);
Pallet::begin_xp(&ALICE, &XP_ALPHA, DEFAULT_POINTS).unwrap();
System::set_block_number(10);
Pallet::begin_xp(&ALICE, &XP_ALPHA, DEFAULT_POINTS).unwrap();
System::set_block_number(13);
Pallet::begin_xp(&ALICE, &XP_ALPHA, DEFAULT_POINTS).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 10);
assert_eq!(xp.pulse.value, 1);
System::set_block_number(15);
Pallet::begin_xp(&ALICE, &XP_ALPHA, DEFAULT_POINTS).unwrap();
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
assert_eq!(xp.free, 20);
assert_eq!(xp.pulse.value, 1);
System::set_block_number(15);
Pallet::reap_xp(&XP_ALPHA).unwrap();
assert_ok!(Pallet::is_reaped(&XP_ALPHA));
assert_err!(
Pallet::begin_xp(&ALICE, &XP_ALPHA, DEFAULT_POINTS),
Error::XpAlreadyReaped
);
});
}
#[test]
fn generic_key_gen_deterministic_check() {
xp_test_ext().execute_with(|| {
type Id = AccountId;
type Item = MockXp;
type Salt = u32;
type Hasher = BlakeTwo256;
type Impl = KeySeedFor<Id, Item, Salt, Hasher, Test>;
Pallet::new_xp(&ALICE, &XP_ALPHA);
let salt = System::account_nonce(ALICE);
let xp = Pallet::get_xp(&XP_ALPHA).unwrap();
test_utils::run_keygen_deterministic_check::<Id, Item, Salt, Hasher, Test, Impl>(
ALICE, xp, salt,
);
});
}
#[test]
fn generic_key_gen_collision_check() {
xp_test_ext().execute_with(|| {
type Id = AccountId;
type Item = MockXp;
type Salt = u32;
type Hasher = BlakeTwo256;
type Impl = KeySeedFor<Id, Item, Salt, Hasher, Test>;
System::set_block_number(2);
Pallet::new_xp(&ALICE, &XP_ALPHA);
let xp_alpha = Pallet::get_xp(&XP_ALPHA).unwrap();
let salt_alpha = System::account_nonce(ALICE);
System::set_block_number(4);
Pallet::new_xp(&BOB, &XP_BETA);
let xp_beta = Pallet::get_xp(&XP_BETA).unwrap();
Account::mutate(BOB, |info| {
info.nonce = 4;
});
let salt_beta = System::account_nonce(BOB);
assert_ne!(xp_alpha, xp_beta);
assert_ne!(salt_alpha, salt_beta);
assert_ne!(ALICE, BOB);
test_utils::run_keygen_collision_check::<Id, Item, Salt, Hasher, Test, Impl>(
ALICE, xp_alpha, salt_alpha, BOB, xp_beta, salt_beta,
);
});
}