mirror of
https://git.ghostchain.io/proxmio/ghost-node.git
synced 2025-12-27 11:19:57 +00:00
implement muldiv without overflow and underflow
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
@@ -1295,8 +1295,10 @@ fn accumulated_commission_could_be_nullified() {
|
||||
#[test]
|
||||
fn bridged_inlation_reward_works() {
|
||||
ExtBuilder::build().execute_with(|| {
|
||||
let amount: u128 = 1337 * 1_000_000_000;
|
||||
let commission: u128 = amount / 100; // 1% commission
|
||||
let amount_full: u128 = 1337 * 1_000_000_000;
|
||||
let commission: u128 = amount_full / 100; // 1% commission
|
||||
let amount: u128 = amount_full - commission;
|
||||
|
||||
let total_staked_ideal: u128 = 69;
|
||||
let total_staked_not_ideal: u128 = 68;
|
||||
let total_issuance: u128 = 100;
|
||||
@@ -1538,8 +1540,10 @@ fn bridged_inlation_reward_works() {
|
||||
#[test]
|
||||
fn bridged_inflation_era_payout_triggers_need_of_nullification() {
|
||||
ExtBuilder::build().execute_with(|| {
|
||||
let amount: u128 = 1337 * 1_000_000_000;
|
||||
let commission: u128 = amount / 100; // 1% commission
|
||||
let amount_full: u128 = 1337 * 1_000_000_000;
|
||||
let commission: u128 = amount_full / 100; // 1% commission
|
||||
let amount: u128 = amount_full - commission;
|
||||
|
||||
let total_staked_ideal: u128 = 69;
|
||||
let total_issuance: u128 = 100;
|
||||
|
||||
@@ -1570,3 +1574,165 @@ fn trigger_nullification_works_as_expected() {
|
||||
assert_eq!(NullifyNeeded::<Test>::get(), false);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_substrate_guarantees_not_to_overflow() {
|
||||
ExtBuilder::build().execute_with(|| {
|
||||
let reward_curve = RewardCurve::get();
|
||||
let mut n: u128 = 69;
|
||||
let mut d: u128 = 100;
|
||||
|
||||
loop {
|
||||
n = match n.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
d = match d.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
assert_eq!(
|
||||
reward_curve.calculate_for_fraction_times_denominator(n, d),
|
||||
d
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_muldiv_guarantees_not_to_overflow() {
|
||||
ExtBuilder::build().execute_with(|| {
|
||||
let mut a: u128 = 2;
|
||||
let mut b: u128 = 3;
|
||||
let mut c: u128 = 6;
|
||||
let mut result: u128 = 1;
|
||||
|
||||
loop {
|
||||
a = match a.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
b = match b.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
c = match c.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
result = match result.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
|
||||
assert_eq!(MulDiv::<u128>::calculate(a, b, c), result);
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
MulDiv::<u128>::calculate(u128::MAX, u128::MAX, u128::MAX),
|
||||
u128::MAX
|
||||
);
|
||||
assert_eq!(MulDiv::<u128>::calculate(u128::MAX, 0, 0), 0);
|
||||
assert_eq!(MulDiv::<u128>::calculate(0, u128::MAX, 0), 0);
|
||||
assert_eq!(MulDiv::<u128>::calculate(0, 0, u128::MAX), 0);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_bridged_inflation_curve_for_overflow() {
|
||||
ExtBuilder::build().execute_with(|| {
|
||||
let amount_full: u128 = 1337 * 1_000_000_000;
|
||||
let commission: u128 = amount_full / 100; // 1% commission
|
||||
let amount: u128 = amount_full - commission;
|
||||
|
||||
let tollerance: u128 = commission / 100; // 1% tollerance
|
||||
let precomputed_payout: u128 = 13177568884;
|
||||
let precomputed_rest: u128 = 192431116;
|
||||
assert_eq!(precomputed_payout + precomputed_rest, commission);
|
||||
|
||||
let mut total_staked_ideal: u128 = 69_000;
|
||||
let mut total_staked_not_ideal: u128 = 68_000;
|
||||
let mut total_issuance: u128 = 100_000;
|
||||
|
||||
assert_ok!(GhostNetworks::accumulate_commission(&commission));
|
||||
assert_ok!(GhostNetworks::accumulate_incoming_imbalance(&amount));
|
||||
|
||||
loop {
|
||||
total_staked_ideal = match total_staked_ideal.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
total_staked_not_ideal = match total_staked_not_ideal.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
total_issuance = match total_issuance.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
assert_eq!(
|
||||
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
|
||||
total_staked_ideal,
|
||||
total_issuance + amount,
|
||||
0
|
||||
),
|
||||
(commission, 0)
|
||||
);
|
||||
|
||||
let (payout, rest) = BridgedInflationCurve::<RewardCurve, Test>::era_payout(
|
||||
total_staked_not_ideal,
|
||||
total_issuance + amount,
|
||||
0,
|
||||
);
|
||||
|
||||
let payout_deviation = if precomputed_payout > payout {
|
||||
precomputed_payout - payout
|
||||
} else {
|
||||
payout - precomputed_payout
|
||||
};
|
||||
|
||||
let rest_deviation = if precomputed_rest > rest {
|
||||
precomputed_rest - rest
|
||||
} else {
|
||||
rest - precomputed_rest
|
||||
};
|
||||
|
||||
assert!(payout_deviation < tollerance);
|
||||
assert!(rest_deviation < tollerance);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn check_bridged_inflation_curve_for_big_commissions() {
|
||||
ExtBuilder::build().execute_with(|| {
|
||||
let mut amount_full: u128 = 1337;
|
||||
|
||||
let total_staked_ideal: u128 = 69_000_000;
|
||||
let total_issuance: u128 = 100_000_000;
|
||||
|
||||
loop {
|
||||
amount_full = match amount_full.checked_mul(1_000_000) {
|
||||
Some(value) => value,
|
||||
None => break,
|
||||
};
|
||||
let commission: u128 = amount_full / 100; // 1% commission
|
||||
let amount: u128 = amount_full - commission;
|
||||
|
||||
AccumulatedCommission::<Test>::set(commission);
|
||||
BridgedImbalance::<Test>::set(BridgeAdjustment {
|
||||
bridged_in: amount,
|
||||
bridged_out: 0,
|
||||
});
|
||||
|
||||
assert_eq!(
|
||||
BridgedInflationCurve::<RewardCurve, Test>::era_payout(
|
||||
total_staked_ideal,
|
||||
total_issuance + amount,
|
||||
0
|
||||
),
|
||||
(commission, 0)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user