auto nullification during finalization and appropriate tests

Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
Uncle Stretch 2025-06-03 19:06:50 +03:00
parent 5847097e94
commit c55d9a05d9
Signed by: str3tch
GPG Key ID: 84F3190747EE79AA
4 changed files with 52 additions and 7 deletions

4
Cargo.lock generated
View File

@ -3648,7 +3648,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-networks" name = "ghost-networks"
version = "0.1.3" version = "0.1.4"
dependencies = [ dependencies = [
"frame-benchmarking", "frame-benchmarking",
"frame-support", "frame-support",
@ -3868,7 +3868,7 @@ dependencies = [
[[package]] [[package]]
name = "ghost-traits" name = "ghost-traits"
version = "0.3.19" version = "0.3.20"
dependencies = [ dependencies = [
"frame-support", "frame-support",
"sp-runtime 31.0.1", "sp-runtime 31.0.1",

View File

@ -1,6 +1,6 @@
[package] [package]
name = "ghost-networks" name = "ghost-networks"
version = "0.1.3" version = "0.1.4"
license.workspace = true license.workspace = true
authors.workspace = true authors.workspace = true
edition.workspace = true edition.workspace = true
@ -50,4 +50,6 @@ runtime-benchmarks = [
try-runtime = [ try-runtime = [
"frame-support/try-runtime", "frame-support/try-runtime",
"frame-system/try-runtime", "frame-system/try-runtime",
"pallet-staking/try-runtime",
"pallet-balances/try-runtime",
] ]

View File

@ -8,13 +8,13 @@ use frame_support::{
}; };
use frame_system::pallet_prelude::*; use frame_system::pallet_prelude::*;
use scale_info::TypeInfo; use scale_info::TypeInfo;
use sp_runtime::{ use sp_runtime::{
traits::{CheckedSub, CheckedAdd, AtLeast32BitUnsigned, Member}, traits::{CheckedSub, CheckedAdd, AtLeast32BitUnsigned, Member},
curve::PiecewiseLinear, curve::PiecewiseLinear,
DispatchResult, DispatchResult,
}; };
use sp_std::prelude::*; use sp_std::{prelude::*, convert::TryInto};
use sp_std::convert::TryInto;
pub use ghost_traits::networks::{ pub use ghost_traits::networks::{
NetworkDataBasicHandler, NetworkDataInspectHandler, NetworkDataBasicHandler, NetworkDataInspectHandler,
@ -93,6 +93,8 @@ where
false => total_issuance.saturating_sub(Balance::from(bridged_in - bridged_out)), false => total_issuance.saturating_sub(Balance::from(bridged_in - bridged_out)),
}; };
NullifyNeeded::<T>::set(true);
match piecewise_linear match piecewise_linear
.calculate_for_fraction_times_denominator(total_staked, adjusted_issuance) .calculate_for_fraction_times_denominator(total_staked, adjusted_issuance)
.checked_mul(&accumulated_balance) .checked_mul(&accumulated_balance)
@ -165,6 +167,10 @@ pub mod module {
NetworkRemoved { chain_id: T::NetworkId }, NetworkRemoved { chain_id: T::NetworkId },
} }
#[pallet::storage]
#[pallet::getter(fn nullify_needed)]
pub type NullifyNeeded<T: Config> = StorageValue<_, bool, ValueQuery>;
#[pallet::storage] #[pallet::storage]
#[pallet::getter(fn bridged_imbalance)] #[pallet::getter(fn bridged_imbalance)]
pub type BridgedImbalance<T: Config> = pub type BridgedImbalance<T: Config> =
@ -221,7 +227,18 @@ pub mod module {
pub struct Pallet<T>(PhantomData<T>); pub struct Pallet<T>(PhantomData<T>);
#[pallet::hooks] #[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {} impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(_: BlockNumberFor<T>) -> Weight {
T::DbWeight::get().reads_writes(1, 1)
}
fn on_finalize(_: BlockNumberFor<T>) {
if Self::nullify_needed() {
Self::nullify_commission();
NullifyNeeded::<T>::put(false);
}
}
}
#[pallet::call] #[pallet::call]
impl<T: Config> Pallet<T> { impl<T: Config> Pallet<T> {
@ -596,6 +613,10 @@ impl<T: Config> NetworkDataInspectHandler<NetworkData> for Pallet<T> {
fn iter() -> PrefixIterator<(Self::NetworkId, NetworkData)> { fn iter() -> PrefixIterator<(Self::NetworkId, NetworkData)> {
Networks::<T>::iter() Networks::<T>::iter()
} }
fn is_nullification_period() -> bool {
NullifyNeeded::<T>::get()
}
} }
impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T> { impl<T: Config> NetworkDataMutateHandler<NetworkData, BalanceOf<T>> for Pallet<T> {

View File

@ -798,7 +798,6 @@ fn bridged_inlation_reward_works() {
let total_staked_not_ideal: u128 = 68; let total_staked_not_ideal: u128 = 68;
let total_issuance: u128 = 100; let total_issuance: u128 = 100;
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout( assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000, total_staked_ideal * 1_000,
total_issuance * 1_000, total_issuance * 1_000,
@ -913,3 +912,26 @@ fn bridged_inlation_reward_works() {
1, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0), (0, 0)); 1, total_issuance * 1_000_000_000_000_000_000_000_000 + amount, 0), (0, 0));
}); });
} }
#[test]
fn bridged_inflation_era_payout_triggers_need_of_nullification() {
ExtBuilder::build()
.execute_with(|| {
let chain_id: u32 = 1;
let amount: u128 = 1337 * 1_000_000_000;
let commission: u128 = amount / 100; // 1% commission
let total_staked_ideal: u128 = 69;
let total_issuance: u128 = 100;
assert_ok!(GhostNetworks::accumulate_commission(&commission));
assert_ok!(GhostNetworks::increase_gatekeeper_amount(&chain_id, &amount));
assert_eq!(NullifyNeeded::<Test>::get(), false);
assert_eq!(BridgedInflationCurve::<RewardCurve, Test>::era_payout(
total_staked_ideal * 1_000,
total_issuance * 1_000 + amount,
0), (commission, 0));
assert_eq!(NullifyNeeded::<Test>::get(), true);
GhostNetworks::on_finalize(69);
assert_eq!(NullifyNeeded::<Test>::get(), false);
});
}