Skip to content
11 changes: 10 additions & 1 deletion chain-extensions/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use sp_runtime::{
traits::{BlakeTwo256, Convert, IdentityLookup},
};
use sp_std::{cell::RefCell, cmp::Ordering, sync::OnceLock};
use subtensor_runtime_common::{AlphaCurrency, NetUid, TaoCurrency};
use subtensor_runtime_common::{AlphaCurrency, AuthorshipInfo, NetUid, TaoCurrency};

type Block = frame_system::mocking::MockBlock<Test>;

Expand Down Expand Up @@ -262,6 +262,14 @@ parameter_types! {
pub const AnnouncementDepositFactor: Balance = 1;
}

pub struct MockAuthorshipProvider;

impl AuthorshipInfo<U256> for MockAuthorshipProvider {
fn author() -> Option<U256> {
Some(U256::from(12345u64))
}
}

parameter_types! {
pub const InitialMinAllowedWeights: u16 = 0;
pub const InitialEmissionValue: u16 = 0;
Expand Down Expand Up @@ -411,6 +419,7 @@ impl pallet_subtensor::Config for Test {
type MaxImmuneUidsPercentage = MaxImmuneUidsPercentage;
type CommitmentsInterface = CommitmentsI;
type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit;
type AuthorshipProvider = MockAuthorshipProvider;
}

// Swap-related parameter types
Expand Down
6 changes: 6 additions & 0 deletions common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,12 @@ pub trait BalanceOps<AccountId> {
) -> Result<AlphaCurrency, DispatchError>;
}

/// Allows to query the current block author
pub trait AuthorshipInfo<AccountId> {
/// Return the current block author
fn author() -> Option<AccountId>;
}

pub mod time {
use super::*;

Expand Down
11 changes: 10 additions & 1 deletion pallets/admin-utils/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use sp_runtime::{
};
use sp_std::cmp::Ordering;
use sp_weights::Weight;
use subtensor_runtime_common::{NetUid, TaoCurrency};
use subtensor_runtime_common::{AuthorshipInfo, NetUid, TaoCurrency};

type Block = frame_system::mocking::MockBlock<Test>;
// Configure a mock runtime to test the pallet.
Expand Down Expand Up @@ -74,6 +74,14 @@ pub type BlockNumber = u64;
pub type TestAuthId = test_crypto::TestAuthId;
pub type UncheckedExtrinsic = TestXt<RuntimeCall, ()>;

pub struct MockAuthorshipProvider;

impl AuthorshipInfo<U256> for MockAuthorshipProvider {
fn author() -> Option<U256> {
Some(U256::from(12345u64))
}
}

parameter_types! {
pub const InitialMinAllowedWeights: u16 = 0;
pub const InitialEmissionValue: u16 = 0;
Expand Down Expand Up @@ -222,6 +230,7 @@ impl pallet_subtensor::Config for Test {
type MaxImmuneUidsPercentage = MaxImmuneUidsPercentage;
type CommitmentsInterface = CommitmentsI;
type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit;
type AuthorshipProvider = MockAuthorshipProvider;
}

parameter_types! {
Expand Down
4 changes: 4 additions & 0 deletions pallets/subtensor/src/macros/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ mod config {

use crate::{CommitmentsInterface, GetAlphaForTao, GetTaoForAlpha};
use pallet_commitments::GetCommitments;
use subtensor_runtime_common::AuthorshipInfo;
use subtensor_swap_interface::{SwapEngine, SwapHandler};

/// Configure the pallet by specifying the parameters and types on which it depends.
Expand Down Expand Up @@ -59,6 +60,9 @@ mod config {
/// Rate limit for associating an EVM key.
type EvmKeyAssociateRateLimit: Get<u64>;

/// Provider of current block author
type AuthorshipProvider: AuthorshipInfo<Self::AccountId>;

/// =================================
/// ==== Initial Value Constants ====
/// =================================
Expand Down
24 changes: 12 additions & 12 deletions pallets/subtensor/src/macros/dispatches.rs
Original file line number Diff line number Diff line change
Expand Up @@ -711,8 +711,8 @@ mod dispatches {
///
#[pallet::call_index(2)]
#[pallet::weight((Weight::from_parts(523_200_000, 0)
.saturating_add(T::DbWeight::get().reads(19_u64))
.saturating_add(T::DbWeight::get().writes(13_u64)), DispatchClass::Normal, Pays::Yes))]
.saturating_add(T::DbWeight::get().reads(20_u64))
.saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::Yes))]
pub fn add_stake(
origin: OriginFor<T>,
hotkey: T::AccountId,
Expand Down Expand Up @@ -1491,8 +1491,8 @@ mod dispatches {
/// - Thrown if key has hit transaction rate limit
#[pallet::call_index(84)]
#[pallet::weight((Weight::from_parts(486_500_000, 0)
.saturating_add(T::DbWeight::get().reads(34_u64))
.saturating_add(T::DbWeight::get().writes(22_u64)), DispatchClass::Normal, Pays::Yes))]
.saturating_add(T::DbWeight::get().reads(35_u64))
.saturating_add(T::DbWeight::get().writes(23_u64)), DispatchClass::Normal, Pays::Yes))]
pub fn unstake_all_alpha(origin: OriginFor<T>, hotkey: T::AccountId) -> DispatchResult {
Self::do_unstake_all_alpha(origin, hotkey)
}
Expand Down Expand Up @@ -1605,8 +1605,8 @@ mod dispatches {
#[pallet::call_index(87)]
#[pallet::weight((
Weight::from_parts(453_800_000, 0)
.saturating_add(T::DbWeight::get().reads(30_u64))
.saturating_add(T::DbWeight::get().writes(20_u64)),
.saturating_add(T::DbWeight::get().reads(31_u64))
.saturating_add(T::DbWeight::get().writes(21_u64)),
DispatchClass::Normal,
Pays::Yes
))]
Expand Down Expand Up @@ -1670,8 +1670,8 @@ mod dispatches {
///
#[pallet::call_index(88)]
#[pallet::weight((Weight::from_parts(713_200_000, 0)
.saturating_add(T::DbWeight::get().reads(19_u64))
.saturating_add(T::DbWeight::get().writes(13_u64)), DispatchClass::Normal, Pays::Yes))]
.saturating_add(T::DbWeight::get().reads(20_u64))
.saturating_add(T::DbWeight::get().writes(14_u64)), DispatchClass::Normal, Pays::Yes))]
pub fn add_stake_limit(
origin: OriginFor<T>,
hotkey: T::AccountId,
Expand Down Expand Up @@ -1779,8 +1779,8 @@ mod dispatches {
#[pallet::call_index(90)]
#[pallet::weight((
Weight::from_parts(661_800_000, 0)
.saturating_add(T::DbWeight::get().reads(30_u64))
.saturating_add(T::DbWeight::get().writes(20_u64)),
.saturating_add(T::DbWeight::get().reads(31_u64))
.saturating_add(T::DbWeight::get().writes(21_u64)),
DispatchClass::Normal,
Pays::Yes
))]
Expand Down Expand Up @@ -2567,8 +2567,8 @@ mod dispatches {
#[pallet::call_index(132)]
#[pallet::weight((
Weight::from_parts(757_700_000, 8556)
.saturating_add(T::DbWeight::get().reads(22_u64))
.saturating_add(T::DbWeight::get().writes(14_u64)),
.saturating_add(T::DbWeight::get().reads(23_u64))
.saturating_add(T::DbWeight::get().writes(15_u64)),
DispatchClass::Normal,
Pays::Yes
))]
Expand Down
51 changes: 45 additions & 6 deletions pallets/subtensor/src/staking/stake_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use safe_math::*;
use share_pool::{SharePool, SharePoolDataOperations};
use sp_std::ops::Neg;
use substrate_fixed::types::{I64F64, I96F32, U64F64, U96F32};
use subtensor_runtime_common::{AlphaCurrency, Currency, NetUid, TaoCurrency};
use subtensor_runtime_common::{AlphaCurrency, AuthorshipInfo, Currency, NetUid, TaoCurrency};
use subtensor_swap_interface::{Order, SwapHandler, SwapResult};

impl<T: Config> Pallet<T> {
Expand Down Expand Up @@ -590,6 +590,7 @@ impl<T: Config> Pallet<T> {
amount_paid_in: tao,
amount_paid_out: tao.to_u64().into(),
fee_paid: TaoCurrency::ZERO,
fee_to_block_author: TaoCurrency::ZERO,
}
};

Expand Down Expand Up @@ -643,19 +644,17 @@ impl<T: Config> Pallet<T> {
amount_paid_in: alpha,
amount_paid_out: alpha.to_u64().into(),
fee_paid: AlphaCurrency::ZERO,
fee_to_block_author: AlphaCurrency::ZERO,
}
};

// Increase only the protocol Alpha reserve. We only use the sum of
// (SubnetAlphaIn + SubnetAlphaInProvided) in alpha_reserve(), so it is irrelevant
// which one to increase.
// Increase only the protocol Alpha reserve
let alpha_delta = swap_result.paid_in_reserve_delta_i64().unsigned_abs();
SubnetAlphaIn::<T>::mutate(netuid, |total| {
*total = total.saturating_add(alpha_delta.into());
});

// Decrease Alpha outstanding.
// TODO: Deprecate, not accurate in v3 anymore
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

off topic, but this removed comment is still true.

SubnetAlphaOut::<T>::mutate(netuid, |total| {
*total = total.saturating_sub(alpha_delta.into());
});
Expand Down Expand Up @@ -706,6 +705,26 @@ impl<T: Config> Pallet<T> {
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid, refund);
}

// Swap (in a fee-less way) the block builder alpha fee
let mut fee_outflow = 0_u64;
let maybe_block_author_coldkey = T::AuthorshipProvider::author();
if let Some(block_author_coldkey) = maybe_block_author_coldkey {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay, this took me forever to come to the conclusion that it is correct, but it is correct. I would have taken fees on the claim_fees event that the protocol position calls at each block step because then it's super obivous that accounting is correct, but the accounting here is in fact correct. Just took me a long time to realize it.

let bb_swap_result = Self::swap_alpha_for_tao(
netuid,
swap_result.fee_to_block_author,
T::SwapInterface::min_price::<TaoCurrency>(),
true,
)?;
Self::add_balance_to_coldkey_account(
&block_author_coldkey,
bb_swap_result.amount_paid_out.into(),
);
fee_outflow = bb_swap_result.amount_paid_out.into();
} else {
// block author is not found, burn this alpha
Self::burn_subnet_alpha(netuid, swap_result.fee_to_block_author);
}

// If this is a root-stake
if netuid == NetUid::ROOT {
// Adjust root claimed value for this hotkey and coldkey.
Expand All @@ -721,7 +740,12 @@ impl<T: Config> Pallet<T> {
// }

// Record TAO outflow
Self::record_tao_outflow(netuid, swap_result.amount_paid_out.into());
Self::record_tao_outflow(
netuid,
swap_result
.amount_paid_out
.saturating_add(fee_outflow.into()),
);

LastColdkeyHotkeyStakeBlock::<T>::insert(coldkey, hotkey, Self::get_current_block_as_u64());

Expand Down Expand Up @@ -797,6 +821,21 @@ impl<T: Config> Pallet<T> {
StakingHotkeys::<T>::insert(coldkey, staking_hotkeys.clone());
}

// Increase the balance of the block author
let maybe_block_author_coldkey = T::AuthorshipProvider::author();
if let Some(block_author_coldkey) = maybe_block_author_coldkey {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

symmetric to alpha case except we don't have to swap back to TAO.

Self::add_balance_to_coldkey_account(
&block_author_coldkey,
swap_result.fee_to_block_author.into(),
);
} else {
// Block author is not found - burn this TAO
// Pallet balances total issuance was taken care of when balance was withdrawn for this swap
TotalIssuance::<T>::mutate(|ti| {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: probably should use the burning utils we have.

*ti = ti.saturating_sub(swap_result.fee_to_block_author);
});
}

// Record TAO inflow
Self::record_tao_inflow(netuid, swap_result.amount_paid_in.into());

Expand Down
11 changes: 10 additions & 1 deletion pallets/subtensor/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use sp_runtime::{
};
use sp_std::{cell::RefCell, cmp::Ordering, sync::OnceLock};
use sp_tracing::tracing_subscriber;
use subtensor_runtime_common::{NetUid, TaoCurrency};
use subtensor_runtime_common::{AuthorshipInfo, NetUid, TaoCurrency};
use subtensor_swap_interface::{Order, SwapHandler};
use tracing_subscriber::{EnvFilter, layer::SubscriberExt, util::SubscriberInitExt};
type Block = frame_system::mocking::MockBlock<Test>;
Expand Down Expand Up @@ -153,6 +153,14 @@ parameter_types! {
pub const SS58Prefix: u8 = 42;
}

pub struct MockAuthorshipProvider;

impl AuthorshipInfo<U256> for MockAuthorshipProvider {
fn author() -> Option<U256> {
Some(U256::from(12345u64))
}
}

parameter_types! {
pub const InitialMinAllowedWeights: u16 = 0;
pub const InitialEmissionValue: u16 = 0;
Expand Down Expand Up @@ -302,6 +310,7 @@ impl crate::Config for Test {
type MaxImmuneUidsPercentage = MaxImmuneUidsPercentage;
type CommitmentsInterface = CommitmentsI;
type EvmKeyAssociateRateLimit = EvmKeyAssociateRateLimit;
type AuthorshipProvider = MockAuthorshipProvider;
}

// Swap-related parameter types
Expand Down
2 changes: 1 addition & 1 deletion pallets/subtensor/src/tests/move_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -711,7 +711,7 @@ fn test_do_move_storage_updates() {
destination_netuid
),
alpha2,
epsilon = 2.into()
epsilon = 50.into()
);
});
}
Expand Down
3 changes: 2 additions & 1 deletion pallets/subtensor/src/tests/networks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -829,7 +829,8 @@ fn destroy_alpha_out_many_stakers_complex_distribution() {
netuid.into(),
min_stake,
);
min_stake.saturating_add(fee)
// Double the fees because fee is calculated for min_stake, not for min_amount
min_stake + fee * 2.into()
};

const N: usize = 20;
Expand Down
Loading
Loading