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
36 changes: 22 additions & 14 deletions pallets/subtensor/src/staking/stake_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,9 +544,10 @@ impl<T: Config> Pallet<T> {
coldkey: &T::AccountId,
netuid: u16,
amount: u64,
) {
) -> u64 {
let mut alpha_share_pool = Self::get_alpha_share_pool(hotkey.clone(), netuid);
alpha_share_pool.update_value_for_one(coldkey, amount as i64);
let actual_alpha = alpha_share_pool.update_value_for_one(coldkey, amount as i64);
actual_alpha.unsigned_abs()
}

pub fn try_increase_stake_for_hotkey_and_coldkey_on_subnet(
Expand All @@ -573,13 +574,16 @@ impl<T: Config> Pallet<T> {
coldkey: &T::AccountId,
netuid: u16,
amount: u64,
) {
) -> u64 {
let mut alpha_share_pool = Self::get_alpha_share_pool(hotkey.clone(), netuid);
let mut actual_alpha = 0;
if let Ok(value) = alpha_share_pool.try_get_value(coldkey) {
if value >= amount {
alpha_share_pool.update_value_for_one(coldkey, (amount as i64).neg());
actual_alpha =
alpha_share_pool.update_value_for_one(coldkey, (amount as i64).neg());
}
}
actual_alpha.unsigned_abs()
}

/// Calculates Some(Alpha) returned from pool by staking operation
Expand Down Expand Up @@ -735,11 +739,12 @@ impl<T: Config> Pallet<T> {
alpha: u64,
fee: u64,
) -> u64 {
// Step 1: Swap the alpha for TAO.
let tao: u64 = Self::swap_alpha_for_tao(netuid, alpha);
// Step 1: Decrease alpha on subneet
let actual_alpha_decrease =
Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid, alpha);

// Step 2: Decrease alpha on subneet
Self::decrease_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid, alpha);
// Step 2: Swap the alpha for TAO.
let tao: u64 = Self::swap_alpha_for_tao(netuid, actual_alpha_decrease);

// Step 3: Update StakingHotkeys if the hotkey's total alpha, across all subnets, is zero
// TODO const: fix.
Expand All @@ -765,15 +770,15 @@ impl<T: Config> Pallet<T> {
coldkey.clone(),
hotkey.clone(),
tao_unstaked,
alpha,
actual_alpha_decrease,
netuid,
));
log::info!(
"StakeRemoved( coldkey: {:?}, hotkey:{:?}, tao: {:?}, alpha:{:?}, netuid: {:?} )",
coldkey.clone(),
hotkey.clone(),
tao_unstaked,
alpha,
actual_alpha_decrease,
netuid
);

Expand All @@ -799,9 +804,12 @@ impl<T: Config> Pallet<T> {

// Step 2. Swap the tao to alpha.
let alpha: u64 = Self::swap_tao_for_alpha(netuid, tao_staked);
let mut actual_alpha = 0;
if (tao_staked > 0) && (alpha > 0) {
// Step 3: Increase the alpha on the hotkey account.
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(hotkey, coldkey, netuid, alpha);
actual_alpha = Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
hotkey, coldkey, netuid, alpha,
);

// Step 4: Update the list of hotkeys staking for this coldkey
let mut staking_hotkeys = StakingHotkeys::<T>::get(coldkey);
Expand All @@ -825,20 +833,20 @@ impl<T: Config> Pallet<T> {
coldkey.clone(),
hotkey.clone(),
tao_staked,
alpha,
actual_alpha,
netuid,
));
log::info!(
"StakeAdded( coldkey: {:?}, hotkey:{:?}, tao: {:?}, alpha:{:?}, netuid: {:?} )",
coldkey.clone(),
hotkey.clone(),
tao_staked,
alpha,
actual_alpha,
netuid
);

// Step 7: Return the amount of alpha staked
alpha
actual_alpha
}

pub fn get_alpha_share_pool(
Expand Down
111 changes: 110 additions & 1 deletion pallets/subtensor/src/tests/move_stake.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::*;
use approx::assert_abs_diff_eq;
use frame_support::{assert_err, assert_noop, assert_ok};
use sp_core::{Get, U256};
use substrate_fixed::types::I96F32;
use substrate_fixed::types::{I96F32, U64F64};

// 1. test_do_move_success
// Description: Test a successful move of stake between two hotkeys in the same subnet
Expand Down Expand Up @@ -1641,3 +1641,112 @@ fn test_stake_transfers_disabled_validate() {
assert_ok!(result3);
});
}

#[test]
// RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::staking::test_move_stake_specific_stake_into_subnet_fail --exact --show-output
fn test_move_stake_specific_stake_into_subnet_fail() {
new_test_ext(1).execute_with(|| {
let sn_owner_coldkey = U256::from(55453);

let hotkey_account_id = U256::from(533453);
let coldkey_account_id = U256::from(55454);
let hotkey_owner_account_id = U256::from(533454);

let existing_shares: U64F64 =
U64F64::from_num(161_986_254).saturating_div(U64F64::from_num(u64::MAX));
let existing_stake = 36_711_495_953;

let tao_in = 2_409_892_148_947;
let alpha_in = 15_358_708_513_716;

let tao_staked = 200_000_000;

//add network
let netuid: u16 = add_dynamic_network(&sn_owner_coldkey, &sn_owner_coldkey);

let origin_netuid: u16 = add_dynamic_network(&sn_owner_coldkey, &sn_owner_coldkey);

// Register hotkey on netuid
register_ok_neuron(netuid, hotkey_account_id, hotkey_owner_account_id, 0);
// Register hotkey on origin netuid
register_ok_neuron(origin_netuid, hotkey_account_id, hotkey_owner_account_id, 0);

// Check we have zero staked
assert_eq!(
SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id),
0
);

// Set a hotkey pool for the hotkey on destination subnet
let mut hotkey_pool = SubtensorModule::get_alpha_share_pool(hotkey_account_id, netuid);
hotkey_pool.update_value_for_one(&hotkey_owner_account_id, 1234); // Doesn't matter, will be overridden

// Adjust the total hotkey stake and shares to match the existing values
TotalHotkeyShares::<Test>::insert(hotkey_account_id, netuid, existing_shares);
TotalHotkeyAlpha::<Test>::insert(hotkey_account_id, netuid, existing_stake);

// Make the hotkey a delegate
Delegates::<Test>::insert(hotkey_account_id, 0);

// Setup Subnet pool
SubnetAlphaIn::<Test>::insert(netuid, alpha_in);
SubnetTAO::<Test>::insert(netuid, tao_in);

// Give TAO balance to coldkey
SubtensorModule::add_balance_to_coldkey_account(
&coldkey_account_id,
tao_staked + 1_000_000_000,
);

// Setup Subnet pool for origin netuid
SubnetAlphaIn::<Test>::insert(origin_netuid, alpha_in + 10_000_000);
SubnetTAO::<Test>::insert(origin_netuid, tao_in + 10_000_000);

// Add stake as new hotkey
assert_ok!(SubtensorModule::add_stake(
RuntimeOrigin::signed(coldkey_account_id),
hotkey_account_id,
origin_netuid,
tao_staked,
),);
let alpha_to_move = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_account_id,
&coldkey_account_id,
origin_netuid,
);

// Move stake to destination subnet
assert_ok!(SubtensorModule::move_stake(
RuntimeOrigin::signed(coldkey_account_id),
hotkey_account_id,
hotkey_account_id,
origin_netuid,
netuid,
alpha_to_move,
));

// Check that the stake has been moved
assert_eq!(
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_account_id,
&coldkey_account_id,
origin_netuid
),
0
);
let fee = DefaultStakingFee::<Test>::get();
let alpha_fee: I96F32 = I96F32::from_num(fee) / SubtensorModule::get_alpha_price(netuid);
let expected_value = I96F32::from_num(alpha_to_move)
* SubtensorModule::get_alpha_price(origin_netuid)
/ SubtensorModule::get_alpha_price(netuid);
assert_abs_diff_eq!(
SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet(
&hotkey_account_id,
&coldkey_account_id,
netuid
),
(expected_value - alpha_fee).to_num::<u64>(),
epsilon = (expected_value / 1000).to_num::<u64>()
);
});
}
Loading
Loading