Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hotfix/Patch new tempo runtime upgrade #806

Merged
merged 15 commits into from
Sep 12, 2024
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
4 changes: 2 additions & 2 deletions .github/workflows/check-finney.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:

- name: Check that spec_version has been bumped
run: |
spec_version=$(PATH=$PATH:$HOME/.cargo/.bin substrate-spec-version ${{ secrets.NUCLEUS_ARCHIVE_NODE }} | tr -d '\n')
spec_version=$(PATH=$PATH:$HOME/.cargo/.bin substrate-spec-version ${{ vars.NUCLEUS_ARCHIVE_NODE }} | tr -d '\n')
echo "network spec_version: $spec_version"
: ${spec_version:?bad spec version}
local_spec_version=$(cargo run -p node-subtensor-runtime --bin spec_version | tr -d '\n')
Expand All @@ -49,6 +49,6 @@ jobs:
uses: "paritytech/[email protected]"
with:
runtime-package: "node-subtensor-runtime"
node-uri: ${{ secrets.NUCLEUS_ARCHIVE_NODE }}
node-uri: ${{ vars.NUCLEUS_ARCHIVE_NODE }}
checks: "pre-and-post"
extra-args: "--disable-spec-version-check --no-weight-warnings"
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ indexing-slicing = "deny"
arithmetic-side-effects = "deny"
type_complexity = "allow"
unwrap-used = "deny"
manual_inspect = "allow"

[workspace.dependencies]
cargo-husky = { version = "1", default-features = false }
Expand Down
66 changes: 38 additions & 28 deletions pallets/subtensor/src/coinbase/run_coinbase.rs
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,20 @@ impl<T: Config> Pallet<T> {
});
}

/// Calculates the nonviable stake for a nominator.
/// The nonviable stake is the stake that was added by the nominator since the last emission drain.
/// This stake will not receive emission until the next emission drain.
/// Note: if the stake delta is below zero, we return zero. We don't allow more stake than the nominator has.
pub fn get_nonviable_stake(hotkey: &T::AccountId, nominator: &T::AccountId) -> u64 {
let stake_delta = StakeDeltaSinceLastEmissionDrain::<T>::get(hotkey, nominator);
if stake_delta.is_negative() {
0
} else {
// Should never fail the into, but we handle it anyway.
stake_delta.try_into().unwrap_or(u64::MAX)
}
}

//. --- 4. Drains the accumulated hotkey emission through to the nominators. The hotkey takes a proportion of the emission.
/// The remainder is drained through to the nominators keeping track of the last stake increase event to ensure that the hotkey does not
/// gain more emission than it's stake since the last drain.
Expand All @@ -268,71 +282,67 @@ impl<T: Config> Pallet<T> {
// --- 1.0 Drain the hotkey emission.
PendingdHotkeyEmission::<T>::insert(hotkey, 0);

// --- 2 Retrieve the last time this hotkey's emissions were drained.
let last_emission_drain: u64 = LastHotkeyEmissionDrain::<T>::get(hotkey);

// --- 3 Update the block value to the current block number.
// --- 2 Update the block value to the current block number.
LastHotkeyEmissionDrain::<T>::insert(hotkey, block_number);

// --- 4 Retrieve the total stake for the hotkey from all nominations.
// --- 3 Retrieve the total stake for the hotkey from all nominations.
let total_hotkey_stake: u64 = Self::get_total_stake_for_hotkey(hotkey);

// --- 5 Calculate the emission take for the hotkey.
// --- 4 Calculate the emission take for the hotkey.
let take_proportion: I64F64 = I64F64::from_num(Delegates::<T>::get(hotkey))
.saturating_div(I64F64::from_num(u16::MAX));
let hotkey_take: u64 =
(take_proportion.saturating_mul(I64F64::from_num(emission))).to_num::<u64>();

// --- 6 Compute the remaining emission after deducting the hotkey's take.
// --- 5 Compute the remaining emission after deducting the hotkey's take.
let emission_minus_take: u64 = emission.saturating_sub(hotkey_take);

// --- 7 Calculate the remaining emission after the hotkey's take.
// --- 6 Calculate the remaining emission after the hotkey's take.
let mut remainder: u64 = emission_minus_take;

// --- 8 Iterate over each nominator and get all viable stake.
// --- 7 Iterate over each nominator and get all viable stake.
let mut total_viable_nominator_stake: u64 = total_hotkey_stake;
for (nominator, nominator_stake) in Stake::<T>::iter_prefix(hotkey) {
if false && LastAddStakeIncrease::<T>::get(hotkey, nominator) > last_emission_drain {
total_viable_nominator_stake =
total_viable_nominator_stake.saturating_sub(nominator_stake);
}
for (nominator, _) in Stake::<T>::iter_prefix(hotkey) {
let nonviable_nomintaor_stake = Self::get_nonviable_stake(hotkey, &nominator);

total_viable_nominator_stake =
total_viable_nominator_stake.saturating_sub(nonviable_nomintaor_stake);
}

// --- 9 Iterate over each nominator.
// --- 8 Iterate over each nominator.
if total_viable_nominator_stake != 0 {
for (nominator, nominator_stake) in Stake::<T>::iter_prefix(hotkey) {
// --- 10 Check if the stake was manually increased by the user since the last emission drain for this hotkey.
// If it was, skip this nominator as they will not receive their proportion of the emission.
if false
&& LastAddStakeIncrease::<T>::get(hotkey, nominator.clone())
> last_emission_drain
{
continue;
}
// --- 9 Skip emission for any stake the was added by the nominator since the last emission drain.
// This means the nominator will get emission on existing stake, but not on new stake, until the next emission drain.
let viable_nominator_stake =
nominator_stake.saturating_sub(Self::get_nonviable_stake(hotkey, &nominator));

// --- 11 Calculate this nominator's share of the emission.
let nominator_emission: I64F64 = I64F64::from_num(nominator_stake)
// --- 10 Calculate this nominator's share of the emission.
let nominator_emission: I64F64 = I64F64::from_num(viable_nominator_stake)
.checked_div(I64F64::from_num(total_viable_nominator_stake))
.unwrap_or(I64F64::from_num(0))
.saturating_mul(I64F64::from_num(emission_minus_take));

// --- 12 Increase the stake for the nominator.
// --- 11 Increase the stake for the nominator.
Self::increase_stake_on_coldkey_hotkey_account(
&nominator,
hotkey,
nominator_emission.to_num::<u64>(),
);

// --- 13* Record event and Subtract the nominator's emission from the remainder.
// --- 12* Record event and Subtract the nominator's emission from the remainder.
total_new_tao = total_new_tao.saturating_add(nominator_emission.to_num::<u64>());
remainder = remainder.saturating_sub(nominator_emission.to_num::<u64>());
}
}

// --- 14 Finally, add the stake to the hotkey itself, including its take and the remaining emission.
// --- 13 Finally, add the stake to the hotkey itself, including its take and the remaining emission.
let hotkey_new_tao: u64 = hotkey_take.saturating_add(remainder);
Self::increase_stake_on_hotkey_account(hotkey, hotkey_new_tao);

// --- 14 Reset the stake delta for the hotkey.
let _ = StakeDeltaSinceLastEmissionDrain::<T>::clear_prefix(hotkey, u32::MAX, None);

// --- 15 Record new tao creation event and return the amount created.
total_new_tao = total_new_tao.saturating_add(hotkey_new_tao);
total_new_tao
Expand Down
35 changes: 26 additions & 9 deletions pallets/subtensor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,11 @@ pub mod pallet {
0
}
#[pallet::type_value]
/// Default stake delta.
pub fn DefaultStakeDelta<T: Config>() -> i128 {
0
}
#[pallet::type_value]
/// Default stakes per interval.
pub fn DefaultStakesPerInterval<T: Config>() -> (u64, u64) {
(0, 0)
Expand Down Expand Up @@ -770,6 +775,18 @@ pub mod pallet {
DefaultAccountTake<T>,
>;
#[pallet::storage]
/// Map ( hot, cold ) --> stake: i128 | Stake added/removed since last emission drain.
pub type StakeDeltaSinceLastEmissionDrain<T: Config> = StorageDoubleMap<
_,
Blake2_128Concat,
T::AccountId,
Identity,
T::AccountId,
i128,
ValueQuery,
DefaultStakeDelta<T>,
>;
#[pallet::storage]
/// DMAP ( parent, netuid ) --> Vec<(proportion,child)>
pub type ChildKeys<T: Config> = StorageDoubleMap<
_,
Expand Down Expand Up @@ -1250,7 +1267,7 @@ pub mod pallet {
/// Returns the transaction priority for setting weights.
pub fn get_priority_set_weights(hotkey: &T::AccountId, netuid: u16) -> u64 {
if let Ok(uid) = Self::get_uid_for_net_and_hotkey(netuid, hotkey) {
let _stake = Self::get_total_stake_for_hotkey(hotkey);
let _stake = Self::get_stake_for_hotkey_on_subnet(hotkey, netuid);
let current_block_number: u64 = Self::get_current_block_as_u64();
let default_priority: u64 =
current_block_number.saturating_sub(Self::get_last_update_for_uid(netuid, uid));
Expand All @@ -1260,9 +1277,9 @@ pub mod pallet {
}

/// Is the caller allowed to set weights
pub fn check_weights_min_stake(hotkey: &T::AccountId) -> bool {
pub fn check_weights_min_stake(hotkey: &T::AccountId, netuid: u16) -> bool {
// Blacklist weights transactions for low stake peers.
Self::get_total_stake_for_hotkey(hotkey) >= Self::get_weights_min_stake()
Self::get_stake_for_hotkey_on_subnet(hotkey, netuid) >= Self::get_weights_min_stake()
}

/// Helper function to check if register is allowed
Expand Down Expand Up @@ -1355,8 +1372,8 @@ where
Pallet::<T>::get_priority_set_weights(who, netuid)
}

pub fn check_weights_min_stake(who: &T::AccountId) -> bool {
Pallet::<T>::check_weights_min_stake(who)
pub fn check_weights_min_stake(who: &T::AccountId, netuid: u16) -> bool {
Pallet::<T>::check_weights_min_stake(who, netuid)
}
}

Expand Down Expand Up @@ -1394,7 +1411,7 @@ where
) -> TransactionValidity {
match call.is_sub_type() {
Some(Call::commit_weights { netuid, .. }) => {
if Self::check_weights_min_stake(who) {
if Self::check_weights_min_stake(who, *netuid) {
let priority: u64 = Self::get_priority_set_weights(who, *netuid);
Ok(ValidTransaction {
priority,
Expand All @@ -1406,7 +1423,7 @@ where
}
}
Some(Call::reveal_weights { netuid, .. }) => {
if Self::check_weights_min_stake(who) {
if Self::check_weights_min_stake(who, *netuid) {
let priority: u64 = Self::get_priority_set_weights(who, *netuid);
Ok(ValidTransaction {
priority,
Expand All @@ -1418,7 +1435,7 @@ where
}
}
Some(Call::set_weights { netuid, .. }) => {
if Self::check_weights_min_stake(who) {
if Self::check_weights_min_stake(who, *netuid) {
let priority: u64 = Self::get_priority_set_weights(who, *netuid);
Ok(ValidTransaction {
priority,
Expand All @@ -1430,7 +1447,7 @@ where
}
}
Some(Call::set_root_weights { netuid, hotkey, .. }) => {
if Self::check_weights_min_stake(hotkey) {
if Self::check_weights_min_stake(hotkey, *netuid) {
let priority: u64 = Self::get_priority_set_weights(hotkey, *netuid);
Ok(ValidTransaction {
priority,
Expand Down
4 changes: 3 additions & 1 deletion pallets/subtensor/src/macros/hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ mod hooks {
// Storage version v8 -> v9
.saturating_add(migrations::migrate_fix_total_coldkey_stake::migrate_fix_total_coldkey_stake::<T>())
// Migrate Delegate Ids on chain
.saturating_add(migrations::migrate_chain_identity::migrate_set_hotkey_identities::<T>());
.saturating_add(migrations::migrate_chain_identity::migrate_set_hotkey_identities::<T>())
// Fix pending emissions
.saturating_add(migrations::migrate_fix_pending_emission::migrate_fix_pending_emission::<T>());
weight
}

Expand Down
Loading
Loading