diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index e595dc50a..e59375461 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1445,39 +1445,7 @@ pub mod pallet { #[cfg(feature = "try-runtime")] fn try_state(_n: BlockNumberFor) -> Result<(), sp_runtime::TryRuntimeError> { - use frame_support::traits::fungible::Inspect; - use sp_runtime::Saturating; - - // Assert [`TotalStake`] accounting is correct - let mut total_staked = 0; - for stake in Stake::::iter() { - total_staked.saturating_accrue(stake.2); - } - ensure!( - total_staked == TotalStake::::get(), - "TotalStake does not match total staked" - ); - - // Assert [`TotalSubnetLocked`] accounting is correct - let mut total_subnet_locked = 0; - for (_, locked) in SubnetLocked::::iter() { - total_subnet_locked.saturating_accrue(locked); - } - ensure!( - total_subnet_locked == TotalSubnetLocked::::get(), - "TotalSubnetLocked does not match total subnet locked" - ); - - // Assert [`TotalIssuance`] accounting is correct - let currency_issuance = T::Currency::total_issuance(); - ensure!( - TotalIssuance::::get() - == currency_issuance - .saturating_add(total_staked) - .saturating_add(total_subnet_locked), - "TotalIssuance accounting discrepancy" - ); - + Self::check_accounting_invariants()?; Ok(()) } } @@ -2321,42 +2289,6 @@ pub mod pallet { ) -> DispatchResult { Ok(()) } - - /// Set the [`TotalIssuance`] storage value to the total account balances issued + the - /// total amount staked + the total amount locked in subnets. - #[pallet::call_index(67)] - #[pallet::weight(( - Weight::default() - .saturating_add(T::DbWeight::get().reads(3)) - .saturating_add(T::DbWeight::get().writes(1)), - DispatchClass::Normal, - Pays::Yes - ))] - pub fn rejig_total_issuance(origin: OriginFor) -> DispatchResult { - let who = ensure_signed_or_root(origin)?; - - let total_account_balances = - >::total_issuance(); - let total_stake = TotalStake::::get(); - let total_subnet_locked = TotalSubnetLocked::::get(); - - let prev_total_issuance = TotalIssuance::::get(); - let new_total_issuance = total_account_balances - .saturating_add(total_stake) - .saturating_add(total_subnet_locked); - TotalIssuance::::put(new_total_issuance); - - Self::deposit_event(Event::TotalIssuanceRejigged { - who, - prev_total_issuance, - new_total_issuance, - total_stake, - total_account_balances, - total_subnet_locked, - }); - - Ok(()) - } } // ---- Subtensor helper functions. @@ -2402,6 +2334,46 @@ pub mod pallet { } true } + + #[cfg(feature = "try-runtime")] + /// Assets [`TotalStake`], [`TotalSubnetLocked`], and [`TotalIssuance`] accounting invariants + /// are correct. + pub fn check_accounting_invariants() -> Result<(), sp_runtime::TryRuntimeError> { + use frame_support::traits::fungible::Inspect; + use sp_runtime::Saturating; + + // Assert [`TotalStake`] accounting is correct + let mut total_staked = 0; + for stake in Stake::::iter() { + total_staked.saturating_accrue(stake.2); + } + ensure!( + total_staked == TotalStake::::get(), + "TotalStake does not match total staked" + ); + + // Assert [`TotalSubnetLocked`] accounting is correct + let mut total_subnet_locked = 0; + for (_, locked) in SubnetLocked::::iter() { + total_subnet_locked.saturating_accrue(locked); + } + ensure!( + total_subnet_locked == TotalSubnetLocked::::get(), + "TotalSubnetLocked does not match total subnet locked" + ); + + // Assert [`TotalIssuance`] accounting is correct + let currency_issuance = T::Currency::total_issuance(); + ensure!( + TotalIssuance::::get() + == currency_issuance + .saturating_add(total_staked) + .saturating_add(total_subnet_locked), + "TotalIssuance accounting discrepancy" + ); + + Ok(()) + } } } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 67d711e20..a2651a464 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1297,7 +1297,7 @@ pub type SignedExtra = ( pallet_commitments::CommitmentsSignedExtension, ); -type Migrations = pallet_grandpa::migrations::MigrateV4ToV5; +type Migrations = migrations::initialise_ti::Migration; // Unchecked extrinsic type as expected by this runtime. pub type UncheckedExtrinsic = diff --git a/runtime/src/migrations/initialise_ti.rs b/runtime/src/migrations/initialise_ti.rs new file mode 100644 index 000000000..e480f9665 --- /dev/null +++ b/runtime/src/migrations/initialise_ti.rs @@ -0,0 +1,46 @@ +use frame_support::traits::{fungible, OnRuntimeUpgrade}; + +use crate::*; + +pub struct Migration; + +impl OnRuntimeUpgrade for Migration { + fn on_runtime_upgrade() -> Weight { + // First, we need to initialize the TotalSubnetLocked + let subnets_len = pallet_subtensor::SubnetLocked::::iter().count() as u64; + let total_subnet_locked: u64 = pallet_subtensor::SubnetLocked::::iter() + .fold(0, |acc, (_, v)| acc.saturating_add(v)); + pallet_subtensor::TotalSubnetLocked::::put(total_subnet_locked); + + // Now, we can rejig the total issuance + let total_account_balances = + <::Currency as fungible::Inspect< + ::AccountId, + >>::total_issuance(); + let total_stake = pallet_subtensor::TotalStake::::get(); + let total_subnet_locked = pallet_subtensor::TotalSubnetLocked::::get(); + + let prev_total_issuance = pallet_subtensor::TotalIssuance::::get(); + let new_total_issuance = total_account_balances + .saturating_add(total_stake) + .saturating_add(total_subnet_locked); + pallet_subtensor::TotalIssuance::::put(new_total_issuance); + + log::info!( + "Subtensor Pallet TI Rejigged: previously: {:?}, new: {:?}", + prev_total_issuance, + new_total_issuance + ); + + ::DbWeight::get() + .reads_writes(subnets_len.saturating_add(5), 1) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade(_state: Vec) -> Result<(), sp_runtime::TryRuntimeError> { + // These are usually checked anyway by try-runtime-cli, but just in case check them again + // explicitly here. + pallet_subtensor::Pallet::::check_accounting_invariants()?; + Ok(()) + } +} diff --git a/runtime/src/migrations/mod.rs b/runtime/src/migrations/mod.rs index ecc48efcd..ddd5359a5 100644 --- a/runtime/src/migrations/mod.rs +++ b/runtime/src/migrations/mod.rs @@ -1 +1,3 @@ //! Export migrations from here. + +pub mod initialise_ti;