diff --git a/pallets/subtensor/src/staking/claim_root.rs b/pallets/subtensor/src/staking/claim_root.rs index 1c8e23257b..738eeafcb9 100644 --- a/pallets/subtensor/src/staking/claim_root.rs +++ b/pallets/subtensor/src/staking/claim_root.rs @@ -3,7 +3,7 @@ use frame_support::weights::Weight; use sp_core::Get; use sp_std::collections::btree_set::BTreeSet; use substrate_fixed::types::{I96F32, U96F32}; -use subtensor_swap_interface::SwapHandler; +use subtensor_swap_interface::{Order, SwapHandler}; impl Pallet { pub fn block_hash_to_indices(block_hash: T::Hash, k: u64, n: u64) -> Vec { @@ -190,8 +190,7 @@ impl Pallet { } }; - let recorded_tao_outflow = - Self::calculate_tao_outflow(netuid, owed_tao.amount_paid_out); + let recorded_tao_outflow = Self::calculate_tao_flow(netuid, owed_tao.amount_paid_out); // Importantly measures swap as flow. Self::record_tao_outflow(netuid, recorded_tao_outflow.into()); @@ -218,6 +217,26 @@ impl Pallet { netuid, owed_u64.into(), ); + + // Record simulated swapped TAO as in flow. + let moving_price = SubnetMovingPrice::::get(netuid).saturating_to_num::(); + let order = GetTaoForAlpha::::with_amount(owed_u64); + + let owed_tao = + match T::SwapInterface::swap(netuid.into(), order, moving_price.into(), true, true) + { + Ok(owed_tao) => owed_tao, + Err(err) => { + log::error!("Error sim swapping alpha for TAO: {err:?}"); + + return; + } + }; + + // Apply root_prop multiplier + let recorded_tao_inflow = Self::calculate_tao_flow(netuid, owed_tao.amount_paid_out); + + Self::record_tao_inflow(netuid, recorded_tao_inflow.into()); } // Increase root claimed by owed amount. @@ -228,7 +247,7 @@ impl Pallet { // Calculates root proportion for subnet, uses "1 / root_prop" (with 10 as an upper bound) as // a multiplier for provided Tao amount. - pub(crate) fn calculate_tao_outflow(netuid: NetUid, amount: TaoCurrency) -> TaoCurrency { + pub(crate) fn calculate_tao_flow(netuid: NetUid, amount: TaoCurrency) -> TaoCurrency { let root_tao: U96F32 = U96F32::saturating_from_num(SubnetTAO::::get(NetUid::ROOT)); let tao_weight: U96F32 = root_tao.saturating_mul(Self::get_tao_weight()); let alpha_issuance: U96F32 = U96F32::saturating_from_num(Self::get_alpha_issuance(netuid)); @@ -250,9 +269,9 @@ impl Pallet { }; let tao = U96F32::saturating_from_num(amount.to_u64()); - let recorded_tao_outflow: u64 = tao.saturating_mul(root_prop_multiplier).to_num(); + let recorded_tao_flow: u64 = tao.saturating_mul(root_prop_multiplier).to_num(); - recorded_tao_outflow.into() + recorded_tao_flow.into() } fn root_claim_on_subnet_weight(_root_claim_type: RootClaimTypeEnum) -> Weight { diff --git a/pallets/subtensor/src/tests/claim_root.rs b/pallets/subtensor/src/tests/claim_root.rs index 60f6beab7c..7e68998b2d 100644 --- a/pallets/subtensor/src/tests/claim_root.rs +++ b/pallets/subtensor/src/tests/claim_root.rs @@ -5,10 +5,11 @@ use crate::tests::mock::{ run_to_block, }; use crate::{ - DefaultMinRootClaimAmount, Error, MAX_NUM_ROOT_CLAIMS, MAX_ROOT_CLAIM_THRESHOLD, NetworksAdded, - NumRootClaim, NumStakingColdkeys, PendingRootAlphaDivs, RootClaimable, RootClaimableThreshold, - StakingColdkeys, StakingColdkeysByIndex, SubnetAlphaIn, SubnetMechanism, SubnetMovingPrice, - SubnetTAO, SubnetTaoFlow, SubtokenEnabled, Tempo, pallet, + DefaultMinRootClaimAmount, Error, GetTaoForAlpha, MAX_NUM_ROOT_CLAIMS, + MAX_ROOT_CLAIM_THRESHOLD, NetworksAdded, NumRootClaim, NumStakingColdkeys, + PendingRootAlphaDivs, RootClaimable, RootClaimableThreshold, StakingColdkeys, + StakingColdkeysByIndex, SubnetAlphaIn, SubnetMechanism, SubnetMovingPrice, SubnetTAO, + SubnetTaoFlow, SubtokenEnabled, Tempo, pallet, }; use crate::{Event, RootAlphaDividendsPerSubnet}; use crate::{RootClaimType, RootClaimTypeEnum, RootClaimed, ValidatorClaimType}; @@ -22,7 +23,7 @@ use sp_runtime::DispatchError; use std::collections::BTreeSet; use substrate_fixed::types::{I96F32, U64F64, U96F32}; use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency}; -use subtensor_swap_interface::SwapHandler; +use subtensor_swap_interface::{Order, SwapHandler}; #[test] fn test_claim_root_set_claim_type() { @@ -46,7 +47,9 @@ fn test_claim_root_with_drain_emissions() { let coldkey = U256::from(1003); let netuid = add_dynamic_network(&hotkey, &owner_coldkey); + SubnetMovingPrice::::insert(netuid, I96F32::saturating_from_num(1)); SubtensorModule::set_tao_weight(u64::MAX); // Set TAO weight to 1.0 + SubnetTAO::::insert(NetUid::ROOT, TaoCurrency::from(1_000_000_000_000u64)); let root_stake = 2_000_000u64; SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( @@ -141,6 +144,28 @@ fn test_claim_root_with_drain_emissions() { let claimed = RootClaimed::::get((netuid, &hotkey, &coldkey)); assert_eq!(u128::from(new_stake), claimed); + // Check tao flow + let moving_price = SubnetMovingPrice::::get(netuid).saturating_to_num::(); + let order = GetTaoForAlpha::::with_amount(new_stake); + + let swapped_tao = ::SwapInterface::swap( + netuid.into(), + order, + moving_price.into(), + true, + true, + ) + .expect("Swap must work here"); + + let tao_inflow: u64 = + SubtensorModule::calculate_tao_flow(netuid, swapped_tao.amount_paid_out).into(); + + assert_abs_diff_eq!( + SubnetTaoFlow::::get(netuid), + tao_inflow as i64, + epsilon = 10i64, + ); + // Distribute pending root alpha (round 2) SubtensorModule::distribute_emission( @@ -684,11 +709,9 @@ fn test_claim_root_with_drain_emissions_and_swap_claim_type() { ); // Check tao flow - let tao_outflow: u64 = SubtensorModule::calculate_tao_outflow( - netuid, - (estimated_stake_increment as u64).into(), - ) - .into(); + let tao_outflow: u64 = + SubtensorModule::calculate_tao_flow(netuid, (estimated_stake_increment as u64).into()) + .into(); assert_abs_diff_eq!( SubnetTaoFlow::::get(netuid), @@ -2134,7 +2157,7 @@ fn test_claim_root_keep_subnets_swap_claim_type() { } #[test] -fn test_claim_root_calculate_tao_outflow() { +fn test_claim_root_calculate_tao_flow() { new_test_ext(1).execute_with(|| { let hotkey = U256::from(1002); let coldkey = U256::from(1003); @@ -2151,22 +2174,19 @@ fn test_claim_root_calculate_tao_outflow() { let tao_reserve = TaoCurrency::from(1_000_000_000_000u64); SubnetTAO::::insert(NetUid::ROOT, tao_reserve); - let tao_outflow_unbounded: u64 = - SubtensorModule::calculate_tao_outflow(netuid, tao_amount.into()).into(); + let tao_flow_unbounded: u64 = + SubtensorModule::calculate_tao_flow(netuid, tao_amount.into()).into(); - assert_abs_diff_eq!(tao_outflow_unbounded, tao_amount, epsilon = 1u64,); + assert_abs_diff_eq!(tao_flow_unbounded, tao_amount, epsilon = 1u64,); - // Check bounded tao outflow (coefficient > 10). + // Check bounded tao flow (coefficient > 10). let tao_reserve = TaoCurrency::from(10_000_000_000u64); SubnetTAO::::insert(NetUid::ROOT, tao_reserve); - let tao_outflow_bounded: u64 = - SubtensorModule::calculate_tao_outflow(netuid, tao_amount.into()).into(); + let tao_flow_bounded: u64 = + SubtensorModule::calculate_tao_flow(netuid, tao_amount.into()).into(); let bounded_root_prop_multiplier = 10u64; - assert_eq!( - tao_outflow_bounded, - bounded_root_prop_multiplier * tao_amount, - ); + assert_eq!(tao_flow_bounded, bounded_root_prop_multiplier * tao_amount,); }); }