Skip to content
Open
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
84 changes: 2 additions & 82 deletions pallets/subtensor/src/coinbase/block_emission.rs
Original file line number Diff line number Diff line change
@@ -1,90 +1,10 @@
use super::*;
use frame_support::traits::Get;
use safe_math::*;
use substrate_fixed::{
transcendental::log2,
types::{I96F32, U96F32},
};
use subtensor_runtime_common::{NetUid, TaoCurrency};
use subtensor_swap_interface::SwapHandler;
use substrate_fixed::{transcendental::log2, types::I96F32};
use subtensor_runtime_common::TaoCurrency;

impl<T: Config> Pallet<T> {
/// Calculates the dynamic TAO emission for a given subnet.
///
/// This function determines the three terms tao_in, alpha_in, alpha_out
/// which are consecutively, 1) the amount of tao injected into the pool
/// 2) the amount of alpha injected into the pool, and 3) the amount of alpha
/// left to be distributed towards miners/validators/owners per block.
///
/// # Arguments
/// * `netuid` - The unique identifier of the subnet.
/// * `tao_emission` - The amount of tao to distribute for this subnet.
/// * `alpha_block_emission` - The maximum alpha emission allowed for the block.
///
/// # Returns
/// * `(u64, u64, u64)` - A tuple containing:
/// - `tao_in_emission`: The adjusted TAO emission always lower or equal to tao_emission
/// - `alpha_in_emission`: The adjusted alpha emission amount to be added into the pool.
/// - `alpha_out_emission`: The remaining alpha emission after adjustments to be distributed to miners/validators.
///
/// The algorithm ensures that the pool injection of tao_in_emission, alpha_in_emission does not effect the pool price
/// It also ensures that the total amount of alpha_in_emission + alpha_out_emission sum to 2 * alpha_block_emission
/// It also ensures that 1 < alpha_out_emission < 2 * alpha_block_emission and 0 < alpha_in_emission < alpha_block_emission.
pub fn get_dynamic_tao_emission(
netuid: NetUid,
tao_emission: u64,
alpha_block_emission: u64,
) -> (u64, u64, u64) {
// Init terms.
let mut tao_in_emission: U96F32 = U96F32::saturating_from_num(tao_emission);
let float_alpha_block_emission: U96F32 = U96F32::saturating_from_num(alpha_block_emission);

// Get alpha price for subnet.
let alpha_price = T::SwapInterface::current_alpha_price(netuid.into());
log::debug!("{netuid:?} - alpha_price: {alpha_price:?}");

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

// Check if we are emitting too much alpha_in
if alpha_in_emission >= float_alpha_block_emission {
log::debug!(
"{netuid:?} - alpha_in_emission: {alpha_in_emission:?} > alpha_block_emission: {float_alpha_block_emission:?}"
);

// Scale down tao_in
// tao_in_emission = alpha_price.saturating_mul(float_alpha_block_emission);

// Set to max alpha_block_emission
alpha_in_emission = float_alpha_block_emission;
}

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

// Set Alpha in emission.
let alpha_out_emission = float_alpha_block_emission;

// Log results.
log::debug!("{netuid:?} - tao_in_emission: {tao_in_emission:?}");
log::debug!("{netuid:?} - alpha_in_emission: {alpha_in_emission:?}");
log::debug!("{netuid:?} - alpha_out_emission: {alpha_out_emission:?}");

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

/// Calculates the block emission based on the total issuance.
///
/// This function computes the block emission by applying a logarithmic function
Expand Down
30 changes: 0 additions & 30 deletions pallets/subtensor/src/tests/coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,36 +46,6 @@ fn test_hotkey_take() {
});
}

// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --package pallet-subtensor --lib -- tests::coinbase::test_dynamic_function_various_values --exact --show-output --nocapture
#[test]
fn test_dynamic_function_various_values() {
new_test_ext(1).execute_with(|| {
let price_values: [f64; 9] = [0.001, 0.1, 0.5, 1.0, 2.0, 10.0, 100.0, 200.0, 1000.0];
let tao_in_values: [u64; 9] = [0, 1, 10, 100, 1_000, 1_000_000, 1_000_000_000, 1_000_000_000_000, 1_000_000_000_000_000 ];
let alpha_emission_values: [u64; 9] = [0, 1, 10, 100, 1_000, 1_000_000, 1_000_000_000, 1_000_000_000_000, 1_000_000_000_000_000 ];

for &price in price_values.iter() {
for &tao_in in tao_in_values.iter() {
for &alpha_emission in alpha_emission_values.iter() {
// Set the price.
SubnetMechanism::<Test>::insert(NetUid::from(1), 1);
SubnetTAO::<Test>::insert(NetUid::from(1), TaoCurrency::from((price * 1_000_000_000.0) as u64));
SubnetAlphaIn::<Test>::insert(NetUid::from(1), AlphaCurrency::from(1_000_000_000));
let (tao_in_emission, alpha_in_emission, alpha_out_emission) = SubtensorModule::get_dynamic_tao_emission(1.into(), tao_in, alpha_emission);
assert!(tao_in_emission <= tao_in, "tao_in_emission is greater than tao_in");
assert!(alpha_in_emission <= alpha_emission, "alpha_in_emission is greater than alpha_emission");
assert!(alpha_out_emission <= 2 * alpha_emission, "alpha_out_emission is greater than 2 * alpha_emission");
assert!((alpha_in_emission + alpha_out_emission) <= 2 * alpha_emission, "Sum of alpha_in_emission and alpha_out_emission is less than or equal to. 2 * alpha_emission");
close( alpha_in_emission + alpha_out_emission, alpha_in_emission + alpha_emission, 10 );
// if alpha_in_emission > 0 || tao_in_emission > 0 {
// assert!((tao_in_emission as f64 / alpha_in_emission as f64 - price).abs() < 1e-1, "Ratio of tao_in_emission to alpha_in_emission is not equal to price");
// }
}
}
}
});
}

// Test the base case of running coinbase with zero emission.
// This test verifies that the coinbase mechanism can handle the edge case
// of zero emission without errors or unexpected behavior.
Expand Down
Loading