-
Notifications
You must be signed in to change notification settings - Fork 168
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
unconst
committed
Jul 24, 2024
1 parent
af50dd6
commit f9b6828
Showing
11 changed files
with
317 additions
and
92 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
pallets/subtensor/src/migrations/migrate_init_total_issuance.rs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
use super::*; | ||
use frame_support::pallet_prelude::OptionQuery; | ||
use frame_support::{pallet_prelude::Identity, storage_alias}; | ||
use sp_std::vec::Vec; | ||
|
||
// TODO: Implement comprehensive tests for this migration | ||
|
||
/// Module containing deprecated storage format for LoadedEmission | ||
pub mod deprecated_loaded_emission_format { | ||
use super::*; | ||
|
||
#[storage_alias] | ||
pub(super) type LoadedEmission<T: Config> = | ||
StorageMap<Pallet<T>, Identity, u16, Vec<(AccountIdOf<T>, u64)>, OptionQuery>; | ||
} | ||
|
||
pub mod initialise_total_issuance { | ||
use frame_support::pallet_prelude::Weight; | ||
use frame_support::traits::{fungible, OnRuntimeUpgrade}; | ||
use sp_core::Get; | ||
|
||
use crate::*; | ||
|
||
pub struct Migration<T: Config>(PhantomData<T>); | ||
|
||
impl<T: Config> OnRuntimeUpgrade for Migration<T> { | ||
/// Performs the migration to initialize and update the total issuance. | ||
/// | ||
/// This function does the following: | ||
/// 1. Calculates the total locked tokens across all subnets | ||
/// 2. Retrieves the total account balances and total stake | ||
/// 3. Computes and updates the new total issuance | ||
/// | ||
/// Returns the weight of the migration operation. | ||
fn on_runtime_upgrade() -> Weight { | ||
// Calculate the total locked tokens across all subnets | ||
let subnets_len = crate::SubnetLocked::<T>::iter().count() as u64; | ||
let total_subnet_locked: u64 = | ||
crate::SubnetLocked::<T>::iter().fold(0, |acc, (_, v)| acc.saturating_add(v)); | ||
|
||
// Retrieve the total balance of all accounts | ||
let total_account_balances = <<T as crate::Config>::Currency as fungible::Inspect< | ||
<T as frame_system::Config>::AccountId, | ||
>>::total_issuance(); | ||
|
||
// Get the total stake from the system | ||
let total_stake = crate::TotalStake::<T>::get(); | ||
|
||
// Retrieve the previous total issuance for logging purposes | ||
let prev_total_issuance = crate::TotalIssuance::<T>::get(); | ||
|
||
// Calculate the new total issuance | ||
let new_total_issuance = total_account_balances | ||
.saturating_add(total_stake) | ||
.saturating_add(total_subnet_locked); | ||
|
||
// Update the total issuance in storage | ||
crate::TotalIssuance::<T>::put(new_total_issuance); | ||
|
||
// Log the change in total issuance | ||
log::info!( | ||
"Subtensor Pallet Total Issuance Updated: previous: {:?}, new: {:?}", | ||
prev_total_issuance, | ||
new_total_issuance | ||
); | ||
|
||
// Return the weight of the operation | ||
// We performed subnets_len + 5 reads and 1 write | ||
<T as frame_system::Config>::DbWeight::get() | ||
.reads_writes(subnets_len.saturating_add(5), 1) | ||
} | ||
|
||
/// Performs post-upgrade checks to ensure the migration was successful. | ||
/// | ||
/// This function is only compiled when the "try-runtime" feature is enabled. | ||
#[cfg(feature = "try-runtime")] | ||
fn post_upgrade(_state: Vec<u8>) -> Result<(), sp_runtime::TryRuntimeError> { | ||
// Verify that all accounting invariants are satisfied after the migration | ||
crate::Pallet::<T>::check_accounting_invariants()?; | ||
Ok(()) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
use super::*; | ||
pub mod misc; | ||
pub mod rate_limiting; | ||
pub mod try_state; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
use super::*; | ||
use sp_core::Get; | ||
|
||
/// Enum representing different types of transactions | ||
#[derive(Copy, Clone)] | ||
pub enum TransactionType { | ||
SetChildren, | ||
Unknown, | ||
} | ||
|
||
/// Implement conversion from TransactionType to u16 | ||
impl From<TransactionType> for u16 { | ||
fn from(tx_type: TransactionType) -> Self { | ||
match tx_type { | ||
TransactionType::SetChildren => 0, | ||
TransactionType::Unknown => 1, | ||
} | ||
} | ||
} | ||
|
||
/// Implement conversion from u16 to TransactionType | ||
impl From<u16> for TransactionType { | ||
fn from(value: u16) -> Self { | ||
match value { | ||
0 => TransactionType::SetChildren, | ||
_ => TransactionType::Unknown, | ||
} | ||
} | ||
} | ||
impl<T: Config> Pallet<T> { | ||
// ======================== | ||
// ==== Rate Limiting ===== | ||
// ======================== | ||
/// Get the rate limit for a specific transaction type | ||
pub fn get_rate_limit(tx_type: &TransactionType) -> u64 { | ||
match tx_type { | ||
TransactionType::SetChildren => (DefaultTempo::<T>::get().saturating_mul(2)).into(), // Cannot set children twice within the default tempo period. | ||
TransactionType::Unknown => 0, // Default to no limit for unknown types (no limit) | ||
} | ||
} | ||
|
||
/// Check if a transaction should be rate limited on a specific subnet | ||
pub fn passes_rate_limit_on_subnet( | ||
tx_type: &TransactionType, | ||
hotkey: &T::AccountId, | ||
netuid: u16, | ||
) -> bool { | ||
let block: u64 = Self::get_current_block_as_u64(); | ||
let limit: u64 = Self::get_rate_limit(tx_type); | ||
let last_block: u64 = Self::get_last_transaction_block(hotkey, netuid, tx_type); | ||
block.saturating_sub(last_block) < limit | ||
} | ||
|
||
/// Check if a transaction should be rate limited globally | ||
pub fn passes_rate_limit_globally(tx_type: &TransactionType, hotkey: &T::AccountId) -> bool { | ||
let netuid: u16 = u16::MAX; | ||
let block: u64 = Self::get_current_block_as_u64(); | ||
let limit: u64 = Self::get_rate_limit(tx_type); | ||
let last_block: u64 = Self::get_last_transaction_block(hotkey, netuid, tx_type); | ||
block.saturating_sub(last_block) >= limit | ||
} | ||
|
||
/// Get the block number of the last transaction for a specific hotkey, network, and transaction type | ||
pub fn get_last_transaction_block( | ||
hotkey: &T::AccountId, | ||
netuid: u16, | ||
tx_type: &TransactionType, | ||
) -> u64 { | ||
let tx_as_u16: u16 = (*tx_type).into(); | ||
TransactionKeyLastBlock::<T>::get((hotkey, netuid, tx_as_u16)) | ||
} | ||
|
||
/// Set the block number of the last transaction for a specific hotkey, network, and transaction type | ||
pub fn set_last_transaction_block( | ||
hotkey: &T::AccountId, | ||
netuid: u16, | ||
tx_type: &TransactionType, | ||
block: u64, | ||
) { | ||
let tx_as_u16: u16 = (*tx_type).into(); | ||
TransactionKeyLastBlock::<T>::insert((hotkey, netuid, tx_as_u16), block); | ||
} | ||
|
||
pub fn set_last_tx_block(key: &T::AccountId, block: u64) { | ||
LastTxBlock::<T>::insert(key, block) | ||
} | ||
pub fn get_last_tx_block(key: &T::AccountId) -> u64 { | ||
LastTxBlock::<T>::get(key) | ||
} | ||
pub fn set_last_tx_block_delegate_take(key: &T::AccountId, block: u64) { | ||
LastTxBlockDelegateTake::<T>::insert(key, block) | ||
} | ||
pub fn get_last_tx_block_delegate_take(key: &T::AccountId) -> u64 { | ||
LastTxBlockDelegateTake::<T>::get(key) | ||
} | ||
pub fn exceeds_tx_rate_limit(prev_tx_block: u64, current_block: u64) -> bool { | ||
let rate_limit: u64 = Self::get_tx_rate_limit(); | ||
if rate_limit == 0 || prev_tx_block == 0 { | ||
return false; | ||
} | ||
|
||
current_block.saturating_sub(prev_tx_block) <= rate_limit | ||
} | ||
pub fn exceeds_tx_delegate_take_rate_limit(prev_tx_block: u64, current_block: u64) -> bool { | ||
let rate_limit: u64 = Self::get_tx_delegate_take_rate_limit(); | ||
if rate_limit == 0 || prev_tx_block == 0 { | ||
return false; | ||
} | ||
|
||
current_block.saturating_sub(prev_tx_block) <= rate_limit | ||
} | ||
} |
Oops, something went wrong.