From 8f27ca7c9500607a2c3e2c43d74dfee0bc0bbef2 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 23 Aug 2023 15:38:36 -0400 Subject: [PATCH 1/5] create stakeinfo runtimeapi --- pallets/subtensor/runtime-api/src/lib.rs | 5 ++ pallets/subtensor/src/stake_info.rs | 64 ++++++++++++++++++++++++ runtime/src/lib.rs | 13 +++++ 3 files changed, 82 insertions(+) create mode 100644 pallets/subtensor/src/stake_info.rs diff --git a/pallets/subtensor/runtime-api/src/lib.rs b/pallets/subtensor/runtime-api/src/lib.rs index 333f5c164f..94f312b728 100644 --- a/pallets/subtensor/runtime-api/src/lib.rs +++ b/pallets/subtensor/runtime-api/src/lib.rs @@ -22,4 +22,9 @@ sp_api::decl_runtime_apis! { fn get_subnet_info(netuid: u16) -> Vec; fn get_subnets_info() -> Vec; } + + pub trait StakeInfoRuntimeApi { + fn get_stake_info_for_coldkey( coldkey_account_vec: Vec ) -> Vec; + fn get_stake_info_for_coldkeys( coldkey_account_vecs: Vec> ) -> Vec; + } } diff --git a/pallets/subtensor/src/stake_info.rs b/pallets/subtensor/src/stake_info.rs new file mode 100644 index 0000000000..935d268ba4 --- /dev/null +++ b/pallets/subtensor/src/stake_info.rs @@ -0,0 +1,64 @@ +use super::*; +use frame_support::storage::IterableStorageDoubleMap; +use frame_support::pallet_prelude::{Decode, Encode}; +extern crate alloc; +use alloc::vec::Vec; +use codec::Compact; + +#[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] +pub struct StakeInfo { + hotkey: T::AccountId, + coldkey: T::AccountId, + stake: Compact, +} + +impl Pallet { + fn _get_stake_info_for_coldkeys(coldkeys: Vec) -> Vec> { + if coldkeys.len() == 0 { + return Vec::new(); // No coldkeys to check + } + + let mut stake_info: Vec> = Vec::new(); + for (hotkey, coldkey, stake) in < Stake as IterableStorageDoubleMap >::iter() { + if coldkeys.contains(&coldkey) { + stake_info.push(StakeInfo { + hotkey, + coldkey, + stake: Compact(stake), + }); + } + } + return stake_info; + } + + pub fn get_stake_info_for_coldkeys(coldkey_account_vecs: Vec>) -> Vec> { + let mut coldkeys: Vec = Vec::new(); + for coldkey_account_vec in coldkey_account_vecs { + if coldkey_account_vec.len() != 32 { + continue; // Invalid coldkey + } + let coldkey: AccountIdOf = T::AccountId::decode( &mut coldkey_account_vec.as_bytes_ref() ).unwrap(); + coldkeys.push(coldkey); + } + + if coldkeys.len() == 0 { + return Vec::new(); // Invalid coldkey + } + + let stake_info = Self::_get_stake_info_for_coldkeys(coldkeys); + + return stake_info; + } + + pub fn get_stake_info_for_coldkey(coldkey_account_vec: Vec) -> Vec> { + if coldkey_account_vec.len() != 32 { + return Vec::new(); // Invalid coldkey + } + + let coldkey: AccountIdOf = T::AccountId::decode( &mut coldkey_account_vec.as_bytes_ref() ).unwrap(); + let stake_info = Self::_get_stake_info_for_coldkeys(vec![coldkey]); + + return stake_info; + } +} + diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 55cc1813a0..b0c4130fe4 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -997,6 +997,19 @@ impl_runtime_apis! { result.encode() } } + + impl subtensor_custom_rpc_runtime_api::StakeInfoRuntimeApi for Runtime { + fn get_stake_info_for_coldkey( coldkey_account_vec: Vec ) -> Vec { + let _result = SubtensorModule::get_stake_info_for_coldkey( coldkey_account_vec ); + let result = _result.expect("Could not get StakeInfo"); + result.encode() + } + + fn get_stake_info_for_coldkeys( coldkey_account_vecs: Vec> ) -> Vec { + let result = SubtensorModule::get_stake_info_for_coldkeys( coldkey_account_vecs ); + result.encode() + } + } } #[cfg(test)] From 9b740a3c3ae3d398ef11e23ea4ae60ed78e18769 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 23 Aug 2023 15:40:06 -0400 Subject: [PATCH 2/5] make sure to use module --- pallets/subtensor/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index d614781605..c8a6fbb064 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -48,6 +48,7 @@ mod weights; pub mod delegate_info; pub mod neuron_info; pub mod subnet_info; +pub mod stake_info; // apparently this is stabilized since rust 1.36 extern crate alloc; From e46c0d2995cb08d311f78391b2c0cca9c4203227 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 23 Aug 2023 15:41:16 -0400 Subject: [PATCH 3/5] add import for as bytes ref --- pallets/subtensor/src/stake_info.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/pallets/subtensor/src/stake_info.rs b/pallets/subtensor/src/stake_info.rs index 935d268ba4..69175419d5 100644 --- a/pallets/subtensor/src/stake_info.rs +++ b/pallets/subtensor/src/stake_info.rs @@ -4,6 +4,7 @@ use frame_support::pallet_prelude::{Decode, Encode}; extern crate alloc; use alloc::vec::Vec; use codec::Compact; +use sp_core::hexdisplay::AsBytesRef; #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug)] pub struct StakeInfo { From 9c8a23f514d6519a4277a0848fe8e8dc6257549f Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 23 Aug 2023 15:41:29 -0400 Subject: [PATCH 4/5] result is not an option --- runtime/src/lib.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index b0c4130fe4..7e2ff3e651 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1000,8 +1000,7 @@ impl_runtime_apis! { impl subtensor_custom_rpc_runtime_api::StakeInfoRuntimeApi for Runtime { fn get_stake_info_for_coldkey( coldkey_account_vec: Vec ) -> Vec { - let _result = SubtensorModule::get_stake_info_for_coldkey( coldkey_account_vec ); - let result = _result.expect("Could not get StakeInfo"); + let result = SubtensorModule::get_stake_info_for_coldkey( coldkey_account_vec ); result.encode() } From 1e453fdc14b01da992455e7267af954e3e4e55bb Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 23 Aug 2023 17:38:00 -0400 Subject: [PATCH 5/5] return tuples for stake info --- pallets/subtensor/src/stake_info.rs | 36 ++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/pallets/subtensor/src/stake_info.rs b/pallets/subtensor/src/stake_info.rs index 69175419d5..173bf554b6 100644 --- a/pallets/subtensor/src/stake_info.rs +++ b/pallets/subtensor/src/stake_info.rs @@ -1,5 +1,4 @@ use super::*; -use frame_support::storage::IterableStorageDoubleMap; use frame_support::pallet_prelude::{Decode, Encode}; extern crate alloc; use alloc::vec::Vec; @@ -14,25 +13,32 @@ pub struct StakeInfo { } impl Pallet { - fn _get_stake_info_for_coldkeys(coldkeys: Vec) -> Vec> { + fn _get_stake_info_for_coldkeys(coldkeys: Vec) -> Vec<(T::AccountId, Vec>)> { if coldkeys.len() == 0 { return Vec::new(); // No coldkeys to check } - let mut stake_info: Vec> = Vec::new(); - for (hotkey, coldkey, stake) in < Stake as IterableStorageDoubleMap >::iter() { - if coldkeys.contains(&coldkey) { - stake_info.push(StakeInfo { - hotkey, - coldkey, - stake: Compact(stake), - }); - } + let mut stake_info: Vec<(T::AccountId, Vec>)> = Vec::new(); + for coldkey_ in coldkeys { + let mut stake_info_for_coldkey: Vec> = Vec::new(); + + for (hotkey, coldkey, stake) in >::iter() { + if coldkey == coldkey_ { + stake_info_for_coldkey.push(StakeInfo { + hotkey, + coldkey, + stake: stake.into(), + }); + } + } + + stake_info.push((coldkey_, stake_info_for_coldkey)); } + return stake_info; } - pub fn get_stake_info_for_coldkeys(coldkey_account_vecs: Vec>) -> Vec> { + pub fn get_stake_info_for_coldkeys(coldkey_account_vecs: Vec>) -> Vec<(T::AccountId, Vec>)> { let mut coldkeys: Vec = Vec::new(); for coldkey_account_vec in coldkey_account_vecs { if coldkey_account_vec.len() != 32 { @@ -59,7 +65,11 @@ impl Pallet { let coldkey: AccountIdOf = T::AccountId::decode( &mut coldkey_account_vec.as_bytes_ref() ).unwrap(); let stake_info = Self::_get_stake_info_for_coldkeys(vec![coldkey]); - return stake_info; + if stake_info.len() == 0 { + return Vec::new(); // Invalid coldkey + } else { + return stake_info.get(0).unwrap().1.clone(); + } } }