Skip to content

Commit 5fe2cf5

Browse files
authored
Merge pull request #1407 from opentensor/feat/dyn-staking-fee-api
add runtimeAPI for new dyn staking fee
2 parents 10d9843 + ec4ff92 commit 5fe2cf5

File tree

4 files changed

+176
-1
lines changed

4 files changed

+176
-1
lines changed

pallets/subtensor/runtime-api/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ sp_api::decl_runtime_apis! {
4646
fn get_stake_info_for_coldkey( coldkey_account: AccountId32 ) -> Vec<StakeInfo<AccountId32>>;
4747
fn get_stake_info_for_coldkeys( coldkey_accounts: Vec<AccountId32> ) -> Vec<(AccountId32, Vec<StakeInfo<AccountId32>>)>;
4848
fn get_stake_info_for_hotkey_coldkey_netuid( hotkey_account: AccountId32, coldkey_account: AccountId32, netuid: u16 ) -> Option<StakeInfo<AccountId32>>;
49+
fn get_stake_fee( origin: Option<(AccountId32, u16)>, origin_coldkey_account: AccountId32, destination: Option<(AccountId32, u16)>, destination_coldkey_account: AccountId32, amount: u64 ) -> u64;
4950
}
5051

5152
pub trait SubnetRegistrationRuntimeApi {

pallets/subtensor/src/rpc_info/stake_info.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use super::*;
22
use frame_support::pallet_prelude::{Decode, Encode};
33
extern crate alloc;
44
use codec::Compact;
5+
use substrate_fixed::types::I96F32;
56

67
#[freeze_struct("5cfb3c84c3af3116")]
78
#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)]
@@ -112,4 +113,24 @@ impl<T: Config> Pallet<T> {
112113
is_registered,
113114
})
114115
}
116+
117+
pub fn get_stake_fee(
118+
origin: Option<(T::AccountId, u16)>,
119+
_origin_coldkey_account: T::AccountId,
120+
_destination: Option<(T::AccountId, u16)>,
121+
_destination_coldkey_account: T::AccountId,
122+
amount: u64,
123+
) -> u64 {
124+
match origin {
125+
Some((origin_hotkey_account, origin_netuid)) => Self::calculate_staking_fee(
126+
origin_netuid,
127+
&origin_hotkey_account,
128+
I96F32::saturating_from_num(amount),
129+
),
130+
None => {
131+
// Adding stake (comes from no netuid)
132+
DefaultStakingFee::<T>::get()
133+
}
134+
}
135+
}
115136
}

pallets/subtensor/src/tests/staking2.rs

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,3 +623,152 @@ fn test_try_associate_hotkey() {
623623
assert_eq!(SubtensorModule::get_owned_hotkeys(&coldkey2).len(), 0);
624624
});
625625
}
626+
627+
#[test]
628+
fn test_stake_fee_api() {
629+
new_test_ext(1).execute_with(|| {
630+
let hotkey1 = U256::from(1);
631+
let coldkey1 = U256::from(2);
632+
let hotkey2 = U256::from(3);
633+
let coldkey2 = U256::from(4);
634+
635+
let netuid0 = 1;
636+
let netuid1 = 2;
637+
let root_netuid = SubtensorModule::get_root_netuid();
638+
639+
let alpha_divs = 100_000_000_000;
640+
let total_hotkey_alpha = 100_000_000_000;
641+
let tao_in = 100_000_000_000; // 100 TAO
642+
let reciprocal_price = 2; // 1 / price
643+
let stake_amount = 100_000_000_000;
644+
645+
let default_fee = DefaultStakingFee::<Test>::get();
646+
647+
// Setup alpha out
648+
SubnetAlphaOut::<Test>::insert(netuid0, 100_000_000_000);
649+
SubnetAlphaOut::<Test>::insert(netuid1, 100_000_000_000);
650+
// Set pools using price
651+
SubnetAlphaIn::<Test>::insert(netuid0, tao_in * reciprocal_price);
652+
SubnetTAO::<Test>::insert(netuid0, tao_in);
653+
SubnetAlphaIn::<Test>::insert(netuid1, tao_in * reciprocal_price);
654+
SubnetTAO::<Test>::insert(netuid1, tao_in);
655+
656+
// Setup alpha divs for hotkey1
657+
AlphaDividendsPerSubnet::<Test>::insert(netuid0, hotkey1, alpha_divs);
658+
AlphaDividendsPerSubnet::<Test>::insert(netuid1, hotkey1, alpha_divs);
659+
660+
// Setup total hotkey alpha for hotkey1
661+
TotalHotkeyAlpha::<Test>::insert(hotkey1, netuid0, total_hotkey_alpha);
662+
TotalHotkeyAlpha::<Test>::insert(hotkey1, netuid1, total_hotkey_alpha);
663+
664+
// Test stake fee for add_stake
665+
let stake_fee_0 = SubtensorModule::get_stake_fee(
666+
None,
667+
coldkey1,
668+
Some((hotkey1, netuid0)),
669+
coldkey1,
670+
stake_amount,
671+
); // Default for adding stake
672+
assert_eq!(stake_fee_0, default_fee);
673+
674+
// Test stake fee for remove on root
675+
let stake_fee_1 = SubtensorModule::get_stake_fee(
676+
Some((hotkey1, root_netuid)),
677+
coldkey1,
678+
None,
679+
coldkey1,
680+
stake_amount,
681+
); // Default for removing stake from root
682+
assert_eq!(stake_fee_1, default_fee);
683+
684+
// Test stake fee for move from root to non-root
685+
let stake_fee_2 = SubtensorModule::get_stake_fee(
686+
Some((hotkey1, root_netuid)),
687+
coldkey1,
688+
Some((hotkey1, netuid0)),
689+
coldkey1,
690+
stake_amount,
691+
); // Default for moving stake from root to non-root
692+
assert_eq!(stake_fee_2, default_fee);
693+
694+
// Test stake fee for move between hotkeys on root
695+
let stake_fee_3 = SubtensorModule::get_stake_fee(
696+
Some((hotkey1, root_netuid)),
697+
coldkey1,
698+
Some((hotkey2, root_netuid)),
699+
coldkey1,
700+
stake_amount,
701+
); // Default for moving stake between hotkeys on root
702+
assert_eq!(stake_fee_3, default_fee);
703+
704+
// Test stake fee for move between coldkeys on root
705+
let stake_fee_4 = SubtensorModule::get_stake_fee(
706+
Some((hotkey1, root_netuid)),
707+
coldkey1,
708+
Some((hotkey1, root_netuid)),
709+
coldkey2,
710+
stake_amount,
711+
); // Default for moving stake between coldkeys on root
712+
assert_eq!(stake_fee_4, default_fee);
713+
714+
// Test stake fee for *swap* from non-root to root
715+
let stake_fee_5 = SubtensorModule::get_stake_fee(
716+
Some((hotkey1, netuid0)),
717+
coldkey1,
718+
Some((hotkey1, root_netuid)),
719+
coldkey1,
720+
stake_amount,
721+
); // Charged a dynamic fee
722+
let dynamic_fee_5 = SubtensorModule::calculate_staking_fee(
723+
netuid0,
724+
&hotkey1,
725+
I96F32::from_num(stake_amount),
726+
);
727+
assert_eq!(stake_fee_5, dynamic_fee_5);
728+
729+
// Test stake fee for move between hotkeys on non-root
730+
let stake_fee_6 = SubtensorModule::get_stake_fee(
731+
Some((hotkey1, netuid0)),
732+
coldkey1,
733+
Some((hotkey2, netuid0)),
734+
coldkey1,
735+
stake_amount,
736+
); // Charged a dynamic fee
737+
let dynamic_fee_6 = SubtensorModule::calculate_staking_fee(
738+
netuid0,
739+
&hotkey1,
740+
I96F32::from_num(stake_amount),
741+
);
742+
assert_eq!(stake_fee_6, dynamic_fee_6);
743+
744+
// Test stake fee for move between coldkeys on non-root
745+
let stake_fee_7 = SubtensorModule::get_stake_fee(
746+
Some((hotkey1, netuid0)),
747+
coldkey1,
748+
Some((hotkey1, netuid0)),
749+
coldkey2,
750+
stake_amount,
751+
); // Charged a dynamic fee
752+
let dynamic_fee_7 = SubtensorModule::calculate_staking_fee(
753+
netuid0,
754+
&hotkey1,
755+
I96F32::from_num(stake_amount),
756+
);
757+
assert_eq!(stake_fee_7, dynamic_fee_7);
758+
759+
// Test stake fee for *swap* from non-root to non-root
760+
let stake_fee_8 = SubtensorModule::get_stake_fee(
761+
Some((hotkey1, netuid0)),
762+
coldkey1,
763+
Some((hotkey1, netuid1)),
764+
coldkey1,
765+
stake_amount,
766+
); // Charged a dynamic fee
767+
let dynamic_fee_8 = SubtensorModule::calculate_staking_fee(
768+
netuid0,
769+
&hotkey1,
770+
I96F32::from_num(stake_amount),
771+
);
772+
assert_eq!(stake_fee_8, dynamic_fee_8);
773+
});
774+
}

runtime/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion {
205205
// `spec_version`, and `authoring_version` are the same between Wasm and native.
206206
// This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use
207207
// the compatible custom types.
208-
spec_version: 248,
208+
spec_version: 249,
209209
impl_version: 1,
210210
apis: RUNTIME_API_VERSIONS,
211211
transaction_version: 1,
@@ -2066,6 +2066,10 @@ impl_runtime_apis! {
20662066
fn get_stake_info_for_hotkey_coldkey_netuid( hotkey_account: AccountId32, coldkey_account: AccountId32, netuid: u16 ) -> Option<StakeInfo<AccountId32>> {
20672067
SubtensorModule::get_stake_info_for_hotkey_coldkey_netuid( hotkey_account, coldkey_account, netuid )
20682068
}
2069+
2070+
fn get_stake_fee( origin: Option<(AccountId32, u16)>, origin_coldkey_account: AccountId32, destination: Option<(AccountId32, u16)>, destination_coldkey_account: AccountId32, amount: u64 ) -> u64 {
2071+
SubtensorModule::get_stake_fee( origin, origin_coldkey_account, destination, destination_coldkey_account, amount )
2072+
}
20692073
}
20702074

20712075
impl subtensor_custom_rpc_runtime_api::SubnetRegistrationRuntimeApi<Block> for Runtime {

0 commit comments

Comments
 (0)