Skip to content

Commit d8ea102

Browse files
committed
rebase pr
2 parents 682cb0d + a207d0b commit d8ea102

File tree

5 files changed

+137
-5
lines changed

5 files changed

+137
-5
lines changed

pallets/subtensor/src/coinbase/run_coinbase.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -510,11 +510,12 @@ impl<T: Config> Pallet<T> {
510510
);
511511
continue;
512512
}
513-
514-
// Increase stake for miner.
513+
let destination: T::AccountId;
514+
let owner: T::AccountId = Owner::<T>::get(&hotkey);
515+
destination = AutoStakeDestination::<T>::get(&owner).unwrap_or(hotkey.clone());
515516
Self::increase_stake_for_hotkey_and_coldkey_on_subnet(
516-
&hotkey.clone(),
517-
&Owner::<T>::get(hotkey.clone()),
517+
&destination,
518+
&owner,
518519
netuid,
519520
incentive,
520521
);

pallets/subtensor/src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1092,6 +1092,9 @@ pub mod pallet {
10921092
#[pallet::storage] // --- MAP ( cold ) --> Vec<hot> | Returns the vector of hotkeys controlled by this coldkey.
10931093
pub type OwnedHotkeys<T: Config> =
10941094
StorageMap<_, Blake2_128Concat, T::AccountId, Vec<T::AccountId>, ValueQuery>;
1095+
#[pallet::storage] // --- MAP ( cold ) --> hot | Returns the hotkey a coldkey will autostake to with mining rewards.
1096+
pub type AutoStakeDestination<T: Config> =
1097+
StorageMap<_, Blake2_128Concat, T::AccountId, T::AccountId, OptionQuery>;
10951098

10961099
#[pallet::storage] // --- DMAP ( cold ) --> (block_expected, new_coldkey) | Maps coldkey to the block to swap at and new coldkey.
10971100
pub type ColdkeySwapScheduled<T: Config> = StorageMap<

pallets/subtensor/src/macros/dispatches.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -854,7 +854,7 @@ mod dispatches {
854854
/// Weight is calculated based on the number of database reads and writes.
855855
#[pallet::call_index(71)]
856856
#[pallet::weight((Weight::from_parts(161_700_000, 0)
857-
.saturating_add(T::DbWeight::get().reads(14))
857+
.saturating_add(T::DbWeight::get().reads(15_u64))
858858
.saturating_add(T::DbWeight::get().writes(9)), DispatchClass::Operational, Pays::No))]
859859
pub fn swap_coldkey(
860860
origin: OriginFor<T>,
@@ -2049,5 +2049,30 @@ mod dispatches {
20492049
commit_reveal_version,
20502050
)
20512051
}
2052+
2053+
/// Set the autostake destination hotkey for a coldkey.
2054+
///
2055+
/// The caller selects a hotkey where all future rewards
2056+
/// will be automatically staked.
2057+
///
2058+
/// # Args:
2059+
/// * `origin` - (<T as frame_system::Config>::Origin):
2060+
/// - The signature of the caller's coldkey.
2061+
///
2062+
/// * `hotkey` (T::AccountId):
2063+
/// - The hotkey account to designate as the autostake destination.
2064+
#[pallet::call_index(114)]
2065+
#[pallet::weight((Weight::from_parts(64_530_000, 0)
2066+
.saturating_add(T::DbWeight::get().reads(7_u64))
2067+
.saturating_add(T::DbWeight::get().writes(2)), DispatchClass::Normal, Pays::Yes))]
2068+
pub fn set_coldkey_auto_stake_hotkey(
2069+
origin: T::RuntimeOrigin,
2070+
hotkey: T::AccountId,
2071+
) -> DispatchResult {
2072+
let coldkey = ensure_signed(origin)?;
2073+
log::debug!("set_coldkey_auto_stake_hotkey( origin:{coldkey:?} hotkey:{hotkey:?} )");
2074+
AutoStakeDestination::<T>::insert(coldkey, hotkey.clone());
2075+
Ok(())
2076+
}
20522077
}
20532078
}

pallets/subtensor/src/swap/swap_coldkey.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ impl<T: Config> Pallet<T> {
178178
weight.saturating_accrue(T::DbWeight::get().reads_writes(2, 2));
179179
}
180180

181+
if let Some(old_auto_stake_hotkey) = AutoStakeDestination::<T>::get(old_coldkey) {
182+
AutoStakeDestination::<T>::remove(old_coldkey);
183+
AutoStakeDestination::<T>::insert(new_coldkey, old_auto_stake_hotkey);
184+
}
185+
181186
// 4. Swap TotalColdkeyAlpha (DEPRECATED)
182187
// for netuid in Self::get_all_subnet_netuids() {
183188
// let old_alpha_stake: u64 = TotalColdkeyAlpha::<T>::get(old_coldkey, netuid);

pallets/subtensor/src/tests/coinbase.rs

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2822,3 +2822,101 @@ fn test_drain_alpha_childkey_parentkey_with_burn() {
28222822
);
28232823
});
28242824
}
2825+
2826+
#[test]
2827+
fn test_incentive_is_autostaked_to_owner_destination() {
2828+
new_test_ext(1).execute_with(|| {
2829+
let subnet_owner_ck = U256::from(0);
2830+
let subnet_owner_hk = U256::from(1);
2831+
2832+
let miner_ck = U256::from(10);
2833+
let miner_hk = U256::from(11);
2834+
let dest_hk = U256::from(12);
2835+
2836+
Owner::<Test>::insert(miner_hk, miner_ck);
2837+
Owner::<Test>::insert(dest_hk, miner_ck);
2838+
OwnedHotkeys::<Test>::insert(miner_ck, vec![miner_hk, dest_hk]);
2839+
2840+
let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
2841+
2842+
Uids::<Test>::insert(netuid, miner_hk, 1);
2843+
Uids::<Test>::insert(netuid, dest_hk, 2);
2844+
2845+
// Set autostake destination for the miner's coldkey
2846+
AutoStakeDestination::<Test>::insert(miner_ck, dest_hk);
2847+
2848+
assert_eq!(
2849+
SubtensorModule::get_stake_for_hotkey_on_subnet(&miner_hk, netuid),
2850+
0.into()
2851+
);
2852+
assert_eq!(
2853+
SubtensorModule::get_stake_for_hotkey_on_subnet(&dest_hk, netuid),
2854+
0.into()
2855+
);
2856+
2857+
// Distribute an incentive to the miner hotkey
2858+
let mut incentives: BTreeMap<U256, AlphaCurrency> = BTreeMap::new();
2859+
let incentive: AlphaCurrency = 10_000_000u64.into();
2860+
incentives.insert(miner_hk, incentive);
2861+
2862+
SubtensorModule::distribute_dividends_and_incentives(
2863+
netuid,
2864+
AlphaCurrency::ZERO, // owner_cut
2865+
incentives,
2866+
BTreeMap::new(), // alpha_dividends
2867+
BTreeMap::new(), // tao_dividends
2868+
);
2869+
2870+
// Expect the stake to land on the destination hotkey (not the original miner hotkey)
2871+
assert_eq!(
2872+
SubtensorModule::get_stake_for_hotkey_on_subnet(&miner_hk, netuid),
2873+
0.into()
2874+
);
2875+
assert_eq!(
2876+
SubtensorModule::get_stake_for_hotkey_on_subnet(&dest_hk, netuid),
2877+
incentive
2878+
);
2879+
});
2880+
}
2881+
2882+
#[test]
2883+
fn test_incentive_goes_to_hotkey_when_no_autostake_destination() {
2884+
new_test_ext(1).execute_with(|| {
2885+
let subnet_owner_ck = U256::from(0);
2886+
let subnet_owner_hk = U256::from(1);
2887+
2888+
let miner_ck = U256::from(20);
2889+
let miner_hk = U256::from(21);
2890+
2891+
Owner::<Test>::insert(miner_hk, miner_ck);
2892+
OwnedHotkeys::<Test>::insert(miner_ck, vec![miner_hk]);
2893+
2894+
let netuid = add_dynamic_network(&subnet_owner_hk, &subnet_owner_ck);
2895+
2896+
Uids::<Test>::insert(netuid, miner_hk, 1);
2897+
2898+
assert_eq!(
2899+
SubtensorModule::get_stake_for_hotkey_on_subnet(&miner_hk, netuid),
2900+
0.into()
2901+
);
2902+
2903+
// Distribute an incentive to the miner hotkey
2904+
let mut incentives: BTreeMap<U256, AlphaCurrency> = BTreeMap::new();
2905+
let incentive: AlphaCurrency = 5_000_000u64.into();
2906+
incentives.insert(miner_hk, incentive);
2907+
2908+
SubtensorModule::distribute_dividends_and_incentives(
2909+
netuid,
2910+
AlphaCurrency::ZERO, // owner_cut
2911+
incentives,
2912+
BTreeMap::new(), // alpha_dividends
2913+
BTreeMap::new(), // tao_dividends
2914+
);
2915+
2916+
// With no autostake destination, the incentive should be staked to the original hotkey
2917+
assert_eq!(
2918+
SubtensorModule::get_stake_for_hotkey_on_subnet(&miner_hk, netuid),
2919+
incentive
2920+
);
2921+
});
2922+
}

0 commit comments

Comments
 (0)