Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion pallets/collective/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -549,7 +549,8 @@ pub mod pallet {
);

let threshold = T::GetVotingMembers::get_count()
.saturating_div(2)
.checked_div(2)
.unwrap_or(0)
.saturating_add(1);

let members = Self::members();
Expand Down
2 changes: 2 additions & 0 deletions pallets/subtensor/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pallet-utility = { workspace = true }
ndarray = { workspace = true }
hex = { workspace = true }
share-pool = { default-features = false, path = "../../primitives/share-pool" }
safe-math = { default-features = false, path = "../../primitives/safe-math" }
approx = { workspace = true }

pallet-collective = { version = "4.0.0-dev", default-features = false, path = "../collective" }
Expand Down Expand Up @@ -104,6 +105,7 @@ std = [
"ark-serialize/std",
"w3f-bls/std",
"rand_chacha/std",
"safe-math/std",
"sha2/std",
"share-pool/std"
]
Expand Down
49 changes: 26 additions & 23 deletions pallets/subtensor/src/coinbase/block_emission.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;
use frame_support::traits::Get;
use safe_math::*;
use substrate_fixed::{transcendental::log2, types::I96F32};

impl<T: Config> Pallet<T> {
Expand Down Expand Up @@ -30,15 +31,15 @@ impl<T: Config> Pallet<T> {
alpha_block_emission: u64,
) -> (u64, u64, u64) {
// Init terms.
let mut tao_in_emission: I96F32 = I96F32::from_num(tao_emission);
let float_alpha_block_emission: I96F32 = I96F32::from_num(alpha_block_emission);
let mut tao_in_emission: I96F32 = I96F32::saturating_from_num(tao_emission);
let float_alpha_block_emission: I96F32 = I96F32::saturating_from_num(alpha_block_emission);

// Get alpha price for subnet.
let alpha_price: I96F32 = Self::get_alpha_price(netuid);
log::debug!("{:?} - alpha_price: {:?}", netuid, alpha_price);

// Get initial alpha_in
let mut alpha_in_emission: I96F32 = I96F32::from_num(tao_emission)
let mut alpha_in_emission: I96F32 = I96F32::saturating_from_num(tao_emission)
.checked_div(alpha_price)
.unwrap_or(float_alpha_block_emission);

Expand All @@ -59,9 +60,11 @@ impl<T: Config> Pallet<T> {
}

// Avoid rounding errors.
if tao_in_emission < I96F32::from_num(1) || alpha_in_emission < I96F32::from_num(1) {
alpha_in_emission = I96F32::from_num(0);
tao_in_emission = I96F32::from_num(0);
if tao_in_emission < I96F32::saturating_from_num(1)
|| alpha_in_emission < I96F32::saturating_from_num(1)
{
alpha_in_emission = I96F32::saturating_from_num(0);
tao_in_emission = I96F32::saturating_from_num(0);
}

// Set Alpha in emission.
Expand All @@ -78,9 +81,9 @@ impl<T: Config> Pallet<T> {

// Return result.
(
tao_in_emission.to_num::<u64>(),
alpha_in_emission.to_num::<u64>(),
alpha_out_emission.to_num::<u64>(),
tao_in_emission.saturating_to_num::<u64>(),
alpha_in_emission.saturating_to_num::<u64>(),
alpha_out_emission.saturating_to_num::<u64>(),
)
}

Expand All @@ -103,23 +106,22 @@ impl<T: Config> Pallet<T> {
/// Returns the block emission for an issuance value.
pub fn get_block_emission_for_issuance(issuance: u64) -> Result<u64, &'static str> {
// Convert issuance to a float for calculations below.
let total_issuance: I96F32 = I96F32::from_num(issuance);
let total_issuance: I96F32 = I96F32::saturating_from_num(issuance);
// Check to prevent division by zero when the total supply is reached
// and creating an issuance greater than the total supply.
if total_issuance >= I96F32::from_num(TotalSupply::<T>::get()) {
if total_issuance >= I96F32::saturating_from_num(TotalSupply::<T>::get()) {
return Ok(0);
}
// Calculate the logarithmic residual of the issuance against half the total supply.
let residual: I96F32 = log2(
I96F32::from_num(1.0)
I96F32::saturating_from_num(1.0)
.checked_div(
I96F32::from_num(1.0)
I96F32::saturating_from_num(1.0)
.checked_sub(
total_issuance
.checked_div(
I96F32::from_num(2.0)
.saturating_mul(I96F32::from_num(10_500_000_000_000_000.0)),
)
.checked_div(I96F32::saturating_from_num(2.0).saturating_mul(
I96F32::saturating_from_num(10_500_000_000_000_000.0),
))
.ok_or("Logarithm calculation failed")?,
)
.ok_or("Logarithm calculation failed")?,
Expand All @@ -131,18 +133,19 @@ impl<T: Config> Pallet<T> {
let floored_residual: I96F32 = residual.floor();
// Calculate the final emission rate using the floored residual.
// Convert floored_residual to an integer
let floored_residual_int: u64 = floored_residual.to_num::<u64>();
let floored_residual_int: u64 = floored_residual.saturating_to_num::<u64>();
// Multiply 2.0 by itself floored_residual times to calculate the power of 2.
let mut multiplier: I96F32 = I96F32::from_num(1.0);
let mut multiplier: I96F32 = I96F32::saturating_from_num(1.0);
for _ in 0..floored_residual_int {
multiplier = multiplier.saturating_mul(I96F32::from_num(2.0));
multiplier = multiplier.saturating_mul(I96F32::saturating_from_num(2.0));
}
let block_emission_percentage: I96F32 = I96F32::from_num(1.0).saturating_div(multiplier);
let block_emission_percentage: I96F32 =
I96F32::saturating_from_num(1.0).safe_div(multiplier);
// Calculate the actual emission based on the emission rate
let block_emission: I96F32 = block_emission_percentage
.saturating_mul(I96F32::from_num(DefaultBlockEmission::<T>::get()));
.saturating_mul(I96F32::saturating_from_num(DefaultBlockEmission::<T>::get()));
// Convert to u64
let block_emission_u64: u64 = block_emission.to_num::<u64>();
let block_emission_u64: u64 = block_emission.saturating_to_num::<u64>();
if BlockEmission::<T>::get() != block_emission_u64 {
BlockEmission::<T>::put(block_emission_u64);
}
Expand Down
44 changes: 23 additions & 21 deletions pallets/subtensor/src/coinbase/block_step.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use super::*;
use frame_support::storage::IterableStorageMap;
use safe_math::*;
use substrate_fixed::types::{I110F18, I96F32};

impl<T: Config + pallet_drand::Config> Pallet<T> {
Expand All @@ -10,7 +11,8 @@ impl<T: Config + pallet_drand::Config> Pallet<T> {
// --- 1. Adjust difficulties.
Self::adjust_registration_terms_for_networks();
// --- 2. Get the current coinbase emission.
let block_emission: I96F32 = I96F32::from_num(Self::get_block_emission().unwrap_or(0));
let block_emission: I96F32 =
I96F32::saturating_from_num(Self::get_block_emission().unwrap_or(0));
log::debug!("Block emission: {:?}", block_emission);
// --- 3. Run emission through network.
Self::run_coinbase(block_emission);
Expand Down Expand Up @@ -198,28 +200,28 @@ impl<T: Config + pallet_drand::Config> Pallet<T> {
registrations_this_interval: u16,
target_registrations_per_interval: u16,
) -> u64 {
let updated_difficulty: I110F18 = I110F18::from_num(current_difficulty)
.saturating_mul(I110F18::from_num(
let updated_difficulty: I110F18 = I110F18::saturating_from_num(current_difficulty)
.saturating_mul(I110F18::saturating_from_num(
registrations_this_interval.saturating_add(target_registrations_per_interval),
))
.saturating_div(I110F18::from_num(
.safe_div(I110F18::saturating_from_num(
target_registrations_per_interval.saturating_add(target_registrations_per_interval),
));
let alpha: I110F18 = I110F18::from_num(Self::get_adjustment_alpha(netuid))
.saturating_div(I110F18::from_num(u64::MAX));
let alpha: I110F18 = I110F18::saturating_from_num(Self::get_adjustment_alpha(netuid))
.safe_div(I110F18::saturating_from_num(u64::MAX));
let next_value: I110F18 = alpha
.saturating_mul(I110F18::from_num(current_difficulty))
.saturating_mul(I110F18::saturating_from_num(current_difficulty))
.saturating_add(
I110F18::from_num(1.0)
I110F18::saturating_from_num(1.0)
.saturating_sub(alpha)
.saturating_mul(updated_difficulty),
);
if next_value >= I110F18::from_num(Self::get_max_difficulty(netuid)) {
if next_value >= I110F18::saturating_from_num(Self::get_max_difficulty(netuid)) {
Self::get_max_difficulty(netuid)
} else if next_value <= I110F18::from_num(Self::get_min_difficulty(netuid)) {
} else if next_value <= I110F18::saturating_from_num(Self::get_min_difficulty(netuid)) {
return Self::get_min_difficulty(netuid);
} else {
return next_value.to_num::<u64>();
return next_value.saturating_to_num::<u64>();
}
}

Expand All @@ -232,28 +234,28 @@ impl<T: Config + pallet_drand::Config> Pallet<T> {
registrations_this_interval: u16,
target_registrations_per_interval: u16,
) -> u64 {
let updated_burn: I110F18 = I110F18::from_num(current_burn)
.saturating_mul(I110F18::from_num(
let updated_burn: I110F18 = I110F18::saturating_from_num(current_burn)
.saturating_mul(I110F18::saturating_from_num(
registrations_this_interval.saturating_add(target_registrations_per_interval),
))
.saturating_div(I110F18::from_num(
.safe_div(I110F18::saturating_from_num(
target_registrations_per_interval.saturating_add(target_registrations_per_interval),
));
let alpha: I110F18 = I110F18::from_num(Self::get_adjustment_alpha(netuid))
.saturating_div(I110F18::from_num(u64::MAX));
let alpha: I110F18 = I110F18::saturating_from_num(Self::get_adjustment_alpha(netuid))
.safe_div(I110F18::saturating_from_num(u64::MAX));
let next_value: I110F18 = alpha
.saturating_mul(I110F18::from_num(current_burn))
.saturating_mul(I110F18::saturating_from_num(current_burn))
.saturating_add(
I110F18::from_num(1.0)
I110F18::saturating_from_num(1.0)
.saturating_sub(alpha)
.saturating_mul(updated_burn),
);
if next_value >= I110F18::from_num(Self::get_max_burn_as_u64(netuid)) {
if next_value >= I110F18::saturating_from_num(Self::get_max_burn_as_u64(netuid)) {
Self::get_max_burn_as_u64(netuid)
} else if next_value <= I110F18::from_num(Self::get_min_burn_as_u64(netuid)) {
} else if next_value <= I110F18::saturating_from_num(Self::get_min_burn_as_u64(netuid)) {
return Self::get_min_burn_as_u64(netuid);
} else {
return next_value.to_num::<u64>();
return next_value.saturating_to_num::<u64>();
}
}
}
7 changes: 4 additions & 3 deletions pallets/subtensor/src/coinbase/root.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use super::*;
use frame_support::dispatch::Pays;
use frame_support::storage::IterableStorageDoubleMap;
use frame_support::weights::Weight;
use safe_math::*;
use sp_core::Get;
use sp_std::vec;
use substrate_fixed::types::I64F64;
Expand Down Expand Up @@ -112,7 +113,7 @@ impl<T: Config> Pallet<T> {

// --- 2. Initialize a 2D vector with zeros to store the weights. The dimensions are determined
// by `n` (number of validators) and `k` (total number of subnets).
let mut weights: Vec<Vec<I64F64>> = vec![vec![I64F64::from_num(0.0); k]; n];
let mut weights: Vec<Vec<I64F64>> = vec![vec![I64F64::saturating_from_num(0.0); k]; n];
log::debug!("weights:\n{:?}\n", weights);

let subnet_list = Self::get_all_subnet_netuids();
Expand All @@ -134,7 +135,7 @@ impl<T: Config> Pallet<T> {
.zip(&subnet_list)
.find(|(_, subnet)| *subnet == netuid)
{
*w = I64F64::from_num(*weight_ij);
*w = I64F64::saturating_from_num(*weight_ij);
}
}
}
Expand Down Expand Up @@ -624,7 +625,7 @@ impl<T: Config> Pallet<T> {

let mut lock_cost = last_lock.saturating_mul(mult).saturating_sub(
last_lock
.saturating_div(lock_reduction_interval)
.safe_div(lock_reduction_interval)
.saturating_mul(current_block.saturating_sub(last_lock_block)),
);

Expand Down
Loading