Skip to content

Commit 816f7dc

Browse files
committed
add test to check rwards works with largest possible balances bonded
1 parent df73d7a commit 816f7dc

File tree

3 files changed

+155
-88
lines changed

3 files changed

+155
-88
lines changed

pallets/mining/rewards-allowance/src/lib.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,13 @@ pub mod pallet {
6565
},
6666
};
6767

68+
pub const default_bonded_amount: u128 = 25_133_000_000_000_000_000_000u128;
69+
6870
// type BalanceOf<T> = <T as pallet_balances::Config>::Balance;
6971
type BalanceOf<T> = <<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
7072
type BalanceFromBalancePallet<T> = <T as pallet_balances::Config>::Balance;
7173
type Date = i64;
7274

73-
7475
/// Configure the pallet by specifying the parameters and types on which it depends.
7576
#[pallet::config]
7677
pub trait Config: frame_system::Config
@@ -429,9 +430,10 @@ pub mod pallet {
429430
// half of 5000 DHX daily allowance (of 2500 DHX), but in that case we split the rewards
430431
// (i.e. 25,133 DHX locked at 10:1 gives 2513 DHX reward)
431432

432-
let mut locks_first_amount_as_u128 = 25_133_000_000_000_000_000_000u128;
433+
let mut locks_first_amount_as_u128 = default_bonded_amount.clone();
433434
let locked_vec = <pallet_balances::Pallet<T>>::locks(miner.clone()).into_inner();
434435
if locked_vec.len() != 0 {
436+
// println!("locked_vec: {:?}", locked_vec);
435437
let locks_first_amount: <T as pallet_balances::Config>::Balance =
436438
<pallet_balances::Pallet<T>>::locks(miner.clone()).into_inner().clone()[0].amount;
437439

pallets/mining/rewards-allowance/src/mock.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -444,12 +444,21 @@ impl MiningRewardsAllowanceConfig for Test {
444444
pub type SysEvent = frame_system::Event<Test>;
445445
pub type DemocracyEvent = pallet_democracy::Event<Test>;
446446

447+
pub const INIT_DAO_BALANCE: u128 = 30_000_000_000_000_000_000_000_000u128;
448+
pub const TOTAL_SUPPLY: u128 = 100_000_000_000_000_000_000_000_000u128;
449+
pub const TEN_DHX: u128 = 10_000_000_000_000_000_000u128;
450+
447451
// This function basically just builds a genesis storage key/value store according to
448452
// our desired mockup.
449453
pub fn new_test_ext() -> sp_io::TestExternalities {
450454
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap();
451455
pallet_balances::GenesisConfig::<Test> {
452-
balances: vec![(0, 10), (1, 10), (2, 20), (3, 30), (4, 40), (5, 50), (6, 60)],
456+
balances: vec![
457+
(0, INIT_DAO_BALANCE),
458+
(1, TEN_DHX),
459+
(2, TEN_DHX),
460+
(3, TEN_DHX),
461+
(100, TOTAL_SUPPLY)],
453462
}
454463
.assimilate_storage(&mut t)
455464
.unwrap();

pallets/mining/rewards-allowance/src/tests.rs

Lines changed: 141 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
use super::{Call, Event, *};
1+
use super::{Call, Event, default_bonded_amount, *};
22
use crate::{mock::*, Error};
3+
pub use mock::{INIT_DAO_BALANCE, TOTAL_SUPPLY};
34
use codec::Encode;
45
use frame_support::{assert_noop, assert_ok,
56
weights::{DispatchClass, DispatchInfo, GetDispatchInfo},
67
traits::{OnFinalize, OnInitialize},
78
};
8-
use frame_system::{self, AccountInfo, EventRecord, Phase};
9+
use frame_system::{self, AccountInfo, EventRecord, Phase, RawOrigin};
10+
use pallet_balances::{self, BalanceLock, Reasons};
911
use pallet_democracy::{self, AccountVote, ReferendumStatus, Tally, VoteThreshold};
1012
use sp_core::{
1113
H256,
@@ -15,6 +17,7 @@ use sp_runtime::{
1517
traits::{BlakeTwo256},
1618
};
1719

20+
const ONE_THIRD_OF_TOTAL_SUPPLY: u128 = 33_333_333_333_000_000_000_000_000u128;
1821

1922
#[test]
2023
// ignore this test until the FIXME is resolved
@@ -42,98 +45,61 @@ fn it_sets_rewards_allowance_with_genesis_defaults_automatically_in_on_finalize_
4245
// Note: if we remove `cooling_off_period_days_remaining.0 != start_of_requested_date_millis.clone() &&`
4346
// four times from the implementation, then all this happens on the same day so we'd need to use the
4447
// same timestamp for all the blocks and tests below.
45-
fn it_distributes_rewards_automatically_in_on_finalize() {
48+
fn it_distributes_rewards_automatically_in_on_finalize_for_default_amount() {
4649
new_test_ext().execute_with(|| {
47-
assert_ok!(MiningRewardsAllowanceTestModule::set_registered_dhx_miner(Origin::signed(1)));
48-
assert_ok!(MiningRewardsAllowanceTestModule::set_registered_dhx_miner(Origin::signed(2)));
49-
assert_ok!(MiningRewardsAllowanceTestModule::set_registered_dhx_miner(Origin::signed(3)));
50-
51-
assert_ok!(MiningRewardsAllowanceTestModule::set_min_bonded_dhx_daily(
52-
Origin::signed(1),
53-
10_u128,
54-
));
55-
assert_ok!(MiningRewardsAllowanceTestModule::set_cooling_off_period_days(
56-
Origin::signed(1),
57-
1_u32, // debug quickly for testing
58-
));
59-
assert_ok!(MiningRewardsAllowanceTestModule::set_rewards_allowance_dhx_daily(
60-
Origin::signed(1),
61-
5000_u128,
62-
));
63-
64-
assert_eq!(MiningRewardsAllowanceTestModule::registered_dhx_miners(), Some(vec![1, 2, 3]));
65-
assert_eq!(MiningRewardsAllowanceTestModule::min_bonded_dhx_daily(), Some(10));
66-
assert_eq!(MiningRewardsAllowanceTestModule::cooling_off_period_days(), Some(1));
67-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_daily(), Some(5_000u128));
68-
69-
// since the timestamp is 0 (corresponds to 1970-01-01) at block number #1, we early exit from on_initialize in
70-
// that block in the implementation and do not set any storage values associated with the date until block #2.
71-
// in the tests we could set the timestamp before we run on_initialize(1), but that wouldn't reflect reality.
72-
MiningRewardsAllowanceTestModule::on_initialize(1);
73-
74-
// 27th August 2021 @ ~7am is 1630049371000
75-
// where milliseconds/day 86400000
76-
// 27th August 2021 @ 12am is 1630022400000 (start of day)
77-
Timestamp::set_timestamp(1630049371000u64);
78-
MiningRewardsAllowanceTestModule::on_initialize(2);
79-
// System::on_initialize(2);
80-
// System::on_finalize(2);
81-
// System::set_block_number(2);
82-
83-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date(1630022400000), Some(5_000u128));
84-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date_distributed(1630022400000), Some(false));
85-
86-
// https://www.epochconverter.com/
87-
// 28th August 2021 @ ~7am is 1635406274000
88-
// where milliseconds/day 86400000
89-
// 28th August 2021 @ 12am is 1635379200000 (start of day)
90-
Timestamp::set_timestamp(1635406274000u64);
91-
MiningRewardsAllowanceTestModule::on_initialize(3);
92-
93-
// check that on_initialize has populated this storage value automatically for the start of the current date
94-
// still cooling off so no rewards distributed on this date
95-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date(1635379200000), Some(5_000u128));
96-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date_distributed(1635379200000), Some(false));
97-
98-
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1635379200000, 1)), Some(25_133_000_000_000_000_000_000u128));
99-
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1635379200000, 2)), Some(25_133_000_000_000_000_000_000u128));
100-
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1635379200000, 3)), Some(25_133_000_000_000_000_000_000u128));
101-
102-
// 29th August 2021 @ ~7am is 1630220400000
103-
// 29th August 2021 @ 12am is 1630195200000 (start of day)
104-
Timestamp::set_timestamp(1630195200000u64);
105-
MiningRewardsAllowanceTestModule::on_initialize(4);
106-
107-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date(1630195200000), Some(5_000u128));
108-
109-
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1630195200000, 1)), Some(25_133_000_000_000_000_000_000u128));
110-
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1630195200000, 2)), Some(25_133_000_000_000_000_000_000u128));
111-
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1630195200000, 3)), Some(25_133_000_000_000_000_000_000u128));
112-
113-
// i.e. for example, if locked is 25_133_000_000_000_000_000_000u128, which is 25,133 DHX,
114-
// then with 10:1 each of the 3x accounts get 2513.3 DHX, which is ~7538.9 DHX combined
115-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_aggregated_dhx_for_all_miners_for_date(1630195200000), Some(7_539_900_000_000_000_000_000u128));
116-
117-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_accumulated_dhx_for_miner_for_date((1630195200000, 1)), Some(2_513_300_000_000_000_000_000u128));
118-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_accumulated_dhx_for_miner_for_date((1630195200000, 2)), Some(2_513_300_000_000_000_000_000u128));
119-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_accumulated_dhx_for_miner_for_date((1630195200000, 3)), Some(2_513_300_000_000_000_000_000u128));
120-
121-
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date_distributed(1630195200000), Some(true));
122-
assert_eq!(MiningRewardsAllowanceTestModule::cooling_off_period_days_remaining(1), Some((1630195200000, 0, 1)));
50+
distribute_rewards(default_bonded_amount.clone());
12351
})
12452
}
12553

12654
#[test]
127-
#[ignore]
128-
fn it_distributes_rewards_automatically_in_on_finalize_for_large_amounts() {
55+
fn it_distributes_rewards_automatically_in_on_finalize_for_large_amount() {
12956
new_test_ext().execute_with(|| {
130-
// TODO - create a test that instead of using a hard-coded value for `locks_first_amount_as_u128`
131-
// that is in the implementation, it instead sets the locked value of each of then using frame_balances
57+
// create a test that instead of using a hard-coded value for `locks_first_amount_as_u128`
58+
// that is in the implementation, it instead sets the locked value of each of them using frame_balances
13259
// for the 3x miners, since we can then store that with `set_bonded_dhx_of_account_for_date` and
13360
// then use that easier for the tests too for trying different values that they have bonded.
13461
//
13562
// in this test we'll test that it distributes rewards when each of their account balances are very large
136-
// (i.e. a third of the total supply) 33_333_333_333_000_000_000_000_000u128
63+
// (i.e. a third of the total supply) ONE_THIRD_OF_TOTAL_SUPPLY
64+
65+
const large_bonded_amount: u128 = ONE_THIRD_OF_TOTAL_SUPPLY;
66+
assert_ok!(Balances::set_balance(Origin::root(), 1, large_bonded_amount.clone(), 0));
67+
assert_ok!(Balances::set_balance(Origin::root(), 2, large_bonded_amount.clone(), 0));
68+
assert_ok!(Balances::set_balance(Origin::root(), 3, large_bonded_amount.clone(), 0));
69+
70+
assert_eq!(Balances::free_balance(&1), large_bonded_amount.clone());
71+
assert_eq!(Balances::free_balance(&2), large_bonded_amount.clone());
72+
assert_eq!(Balances::free_balance(&3), large_bonded_amount.clone());
73+
74+
assert_eq!(Balances::reserved_balance(&1), 0);
75+
76+
let pre_image_hash = BlakeTwo256::hash(b"test");
77+
let r = Democracy::inject_referendum(1, pre_image_hash.clone(), VoteThreshold::SuperMajorityApprove, 2);
78+
// lock the whole balance of account 1, 2, and 3 in voting
79+
let v1a1 = AccountVote::Standard { vote: AYE, balance: Balances::free_balance(1) };
80+
let v1a2 = AccountVote::Standard { vote: AYE, balance: Balances::free_balance(2) };
81+
let v1a3 = AccountVote::Standard { vote: AYE, balance: Balances::free_balance(3) };
82+
// vote on referenda using time-lock voting with a conviction to scale the vote power
83+
// note: second parameter is the referendum index being voted on
84+
assert_ok!(Democracy::vote(Origin::signed(1), r, v1a1));
85+
assert_ok!(Democracy::vote(Origin::signed(2), r, v1a2));
86+
assert_ok!(Democracy::vote(Origin::signed(3), r, v1a3));
87+
// let v2 = AccountVote::Split { aye: 1, nay: 2 };
88+
// assert_ok!(Democracy::vote(Origin::signed(1), r, v2));
89+
90+
// TODO - use this later to simulate that unbonding works
91+
// // assert_ok!(Democracy::remove_vote(Origin::signed(1), r));
92+
// // assert_eq!(tally(r), Tally { ayes: 0, nays: 0, turnout: 0 });
93+
// // assert_ok!(Democracy::unlock(Origin::signed(1), 5));
94+
assert_eq!(Balances::locks(1)[0],
95+
BalanceLock {
96+
id: [100, 101, 109, 111, 99, 114, 97, 99],
97+
amount: large_bonded_amount.clone(),
98+
reasons: Reasons::Misc
99+
}
100+
);
101+
102+
distribute_rewards(large_bonded_amount.clone());
137103
})
138104
}
139105

@@ -312,5 +278,95 @@ fn setup_preimage() {
312278
AccountVote::Standard { vote: AYE, balance: Balances::free_balance(1) },
313279
));
314280
assert_eq!(Democracy::referendum_status(r).unwrap().tally, Tally { ayes: 30000000000000, nays: 0, turnout: 300000000000000 });
315-
});
281+
assert_eq!(Balances::locks(1)[0],
282+
BalanceLock {
283+
id: [100, 101, 109, 111, 99, 114, 97, 99],
284+
amount: 300000000000000,
285+
reasons: Reasons::Misc
286+
}
287+
);
288+
});
289+
}
290+
291+
fn distribute_rewards(amount_bonded_each_miner: u128) {
292+
assert_ok!(MiningRewardsAllowanceTestModule::set_registered_dhx_miner(Origin::signed(1)));
293+
assert_ok!(MiningRewardsAllowanceTestModule::set_registered_dhx_miner(Origin::signed(2)));
294+
assert_ok!(MiningRewardsAllowanceTestModule::set_registered_dhx_miner(Origin::signed(3)));
295+
296+
assert_ok!(MiningRewardsAllowanceTestModule::set_min_bonded_dhx_daily(
297+
Origin::signed(1),
298+
10_u128,
299+
));
300+
assert_ok!(MiningRewardsAllowanceTestModule::set_cooling_off_period_days(
301+
Origin::signed(1),
302+
1_u32, // debug quickly for testing
303+
));
304+
assert_ok!(MiningRewardsAllowanceTestModule::set_rewards_allowance_dhx_daily(
305+
Origin::signed(1),
306+
5000_u128,
307+
));
308+
309+
assert_eq!(MiningRewardsAllowanceTestModule::registered_dhx_miners(), Some(vec![1, 2, 3]));
310+
assert_eq!(MiningRewardsAllowanceTestModule::min_bonded_dhx_daily(), Some(10));
311+
assert_eq!(MiningRewardsAllowanceTestModule::cooling_off_period_days(), Some(1));
312+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_daily(), Some(5_000u128));
313+
314+
// since the timestamp is 0 (corresponds to 1970-01-01) at block number #1, we early exit from on_initialize in
315+
// that block in the implementation and do not set any storage values associated with the date until block #2.
316+
// in the tests we could set the timestamp before we run on_initialize(1), but that wouldn't reflect reality.
317+
MiningRewardsAllowanceTestModule::on_initialize(1);
318+
319+
// 27th August 2021 @ ~7am is 1630049371000
320+
// where milliseconds/day 86400000
321+
// 27th August 2021 @ 12am is 1630022400000 (start of day)
322+
Timestamp::set_timestamp(1630049371000u64);
323+
MiningRewardsAllowanceTestModule::on_initialize(2);
324+
// System::on_initialize(2);
325+
// System::on_finalize(2);
326+
// System::set_block_number(2);
327+
328+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date(1630022400000), Some(5_000u128));
329+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date_distributed(1630022400000), Some(false));
330+
331+
// https://www.epochconverter.com/
332+
// 28th August 2021 @ ~7am is 1635406274000
333+
// where milliseconds/day 86400000
334+
// 28th August 2021 @ 12am is 1635379200000 (start of day)
335+
Timestamp::set_timestamp(1635406274000u64);
336+
MiningRewardsAllowanceTestModule::on_initialize(3);
337+
338+
// check that on_initialize has populated this storage value automatically for the start of the current date
339+
// still cooling off so no rewards distributed on this date
340+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date(1635379200000), Some(5_000u128));
341+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date_distributed(1635379200000), Some(false));
342+
343+
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1635379200000, 1)), Some(amount_bonded_each_miner.clone()));
344+
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1635379200000, 2)), Some(amount_bonded_each_miner.clone()));
345+
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1635379200000, 3)), Some(amount_bonded_each_miner.clone()));
346+
347+
// 29th August 2021 @ ~7am is 1630220400000
348+
// 29th August 2021 @ 12am is 1630195200000 (start of day)
349+
Timestamp::set_timestamp(1630195200000u64);
350+
MiningRewardsAllowanceTestModule::on_initialize(4);
351+
352+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date(1630195200000), Some(5_000u128));
353+
354+
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1630195200000, 1)), Some(amount_bonded_each_miner.clone()));
355+
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1630195200000, 2)), Some(amount_bonded_each_miner.clone()));
356+
assert_eq!(MiningRewardsAllowanceTestModule::bonded_dhx_of_account_for_date((1630195200000, 3)), Some(amount_bonded_each_miner.clone()));
357+
358+
// i.e. for example, if locked is 25_133_000_000_000_000_000_000u128, which is 25,133 DHX,
359+
// then with 10:1 each of the 3x accounts get 2513.3 DHX, which is ~7538.9 DHX combined
360+
if amount_bonded_each_miner.clone() == 25_133_000_000_000_000_000_000u128 {
361+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_aggregated_dhx_for_all_miners_for_date(1630195200000), Some(7_539_900_000_000_000_000_000u128));
362+
} else if amount_bonded_each_miner.clone() == ONE_THIRD_OF_TOTAL_SUPPLY {
363+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_aggregated_dhx_for_all_miners_for_date(1630195200000), Some(9_999_999_999_900_000_000_000_000u128));
364+
}
365+
366+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_accumulated_dhx_for_miner_for_date((1630195200000, 1)), Some(amount_bonded_each_miner.clone() / 10));
367+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_accumulated_dhx_for_miner_for_date((1630195200000, 2)), Some(amount_bonded_each_miner.clone() / 10));
368+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_accumulated_dhx_for_miner_for_date((1630195200000, 3)), Some(amount_bonded_each_miner.clone() / 10));
369+
370+
assert_eq!(MiningRewardsAllowanceTestModule::rewards_allowance_dhx_for_date_distributed(1630195200000), Some(true));
371+
assert_eq!(MiningRewardsAllowanceTestModule::cooling_off_period_days_remaining(1), Some((1630195200000, 0, 1)));
316372
}

0 commit comments

Comments
 (0)