From 506e78078ee24c9edf9377eaf9ad5542c711ec67 Mon Sep 17 00:00:00 2001 From: Andreea Popescu Date: Thu, 8 Aug 2024 15:55:34 +0100 Subject: [PATCH 01/11] add neuron certificate handling --- pallets/subtensor/rpc/src/lib.rs | 22 ++++- pallets/subtensor/runtime-api/src/lib.rs | 1 + pallets/subtensor/src/lib.rs | 24 ++++++ pallets/subtensor/src/macros/dispatches.rs | 85 ++++++++++++++++++- pallets/subtensor/src/rpc_info/neuron_info.rs | 17 ++++ pallets/subtensor/src/subnets/serving.rs | 17 ++++ pallets/subtensor/tests/serving.rs | 50 +++++++++++ runtime/src/lib.rs | 46 +++------- 8 files changed, 224 insertions(+), 38 deletions(-) diff --git a/pallets/subtensor/rpc/src/lib.rs b/pallets/subtensor/rpc/src/lib.rs index 2445a5eda..ebf7dcc35 100644 --- a/pallets/subtensor/rpc/src/lib.rs +++ b/pallets/subtensor/rpc/src/lib.rs @@ -41,7 +41,13 @@ pub trait SubtensorCustomApi { fn get_neurons(&self, netuid: u16, at: Option) -> RpcResult>; #[method(name = "neuronInfo_getNeuron")] fn get_neuron(&self, netuid: u16, uid: u16, at: Option) -> RpcResult>; - + #[method(name = "neuronInfo_getNeuronCertificate")] + fn get_neuron_certificate( + &self, + netuid: u16, + uid: u16, + at: Option, + ) -> RpcResult>; #[method(name = "subnetInfo_getSubnetInfo")] fn get_subnet_info(&self, netuid: u16, at: Option) -> RpcResult>; #[method(name = "subnetInfo_getSubnetsInfo")] @@ -187,6 +193,20 @@ where .map_err(|e| Error::RuntimeError(format!("Unable to get neuron info: {:?}", e)).into()) } + fn get_neuron_certificate( + &self, + netuid: u16, + uid: u16, + at: Option<::Hash>, + ) -> RpcResult> { + let api = self.client.runtime_api(); + let at = at.unwrap_or_else(|| self.client.info().best_hash); + + api.get_neuron_certificate(at, netuid, uid).map_err(|e| { + Error::RuntimeError(format!("Unable to get neuron certificate: {:?}", e)).into() + }) + } + fn get_subnet_info( &self, netuid: u16, diff --git a/pallets/subtensor/runtime-api/src/lib.rs b/pallets/subtensor/runtime-api/src/lib.rs index ca43384b8..d2b6ca1fd 100644 --- a/pallets/subtensor/runtime-api/src/lib.rs +++ b/pallets/subtensor/runtime-api/src/lib.rs @@ -14,6 +14,7 @@ sp_api::decl_runtime_apis! { pub trait NeuronInfoRuntimeApi { fn get_neurons(netuid: u16) -> Vec; fn get_neuron(netuid: u16, uid: u16) -> Vec; + fn get_neuron_certificate(netuid: u16, uid: u16) -> Vec; fn get_neurons_lite(netuid: u16) -> Vec; fn get_neuron_lite(netuid: u16, uid: u16) -> Vec; } diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 2985736c8..6b6a8d62d 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -129,6 +129,15 @@ pub mod pallet { pub placeholder2: u8, } + /// Struct for NeuronCertificate. + pub type NeuronCertificateOf = NeuronCertificate; + /// Data structure for NeuronCertificate information. + #[derive(Decode, Encode, Default, TypeInfo, PartialEq, Eq, Clone, Debug)] + pub struct NeuronCertificate { + /// The neuron certificate. + pub certificate: Vec, + } + /// Struct for Prometheus. pub type PrometheusInfoOf = PrometheusInfo; @@ -1162,6 +1171,17 @@ pub mod pallet { /// --- MAP ( netuid, hotkey ) --> axon_info pub type Axons = StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, AxonInfoOf, OptionQuery>; + /// --- MAP ( netuid, hotkey ) --> certificate + #[pallet::storage] + pub(super) type NeuronCertificates = StorageDoubleMap< + _, + Identity, + u16, + Blake2_128Concat, + T::AccountId, + NeuronCertificateOf, + OptionQuery, + >; #[pallet::storage] /// --- MAP ( netuid, hotkey ) --> prometheus_info pub type Prometheus = StorageDoubleMap< @@ -1538,6 +1558,10 @@ where let transaction_fee = 0; Ok((CallType::Serve, transaction_fee, who.clone())) } + Some(Call::serve_axon_tls { .. }) => { + let transaction_fee = 0; + Ok((CallType::Serve, transaction_fee, who.clone())) + } Some(Call::register_network { .. }) => { let transaction_fee = 0; Ok((CallType::RegisterNetwork, transaction_fee, who.clone())) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index a97e4494d..378c0c721 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -435,7 +435,7 @@ mod dispatches { Self::do_remove_stake(origin, hotkey, amount_unstaked) } - /// Serves or updates axon /promethteus information for the neuron associated with the caller. If the caller is + /// Serves or updates axon /prometheus information for the neuron associated with the caller. If the caller is /// already registered the metadata is updated. If the caller is not registered this call throws NotRegistered. /// /// # Args: @@ -511,6 +511,89 @@ mod dispatches { protocol, placeholder1, placeholder2, + None, + ) + } + + /// Same as `serve_axon` but takes a certificate as an extra optional argument. + /// Serves or updates axon /prometheus information for the neuron associated with the caller. If the caller is + /// already registered the metadata is updated. If the caller is not registered this call throws NotRegistered. + /// + /// # Args: + /// * 'origin': (Origin): + /// - The signature of the caller. + /// + /// * 'netuid' (u16): + /// - The u16 network identifier. + /// + /// * 'version' (u64): + /// - The bittensor version identifier. + /// + /// * 'ip' (u64): + /// - The endpoint ip information as a u128 encoded integer. + /// + /// * 'port' (u16): + /// - The endpoint port information as a u16 encoded integer. + /// + /// * 'ip_type' (u8): + /// - The endpoint ip version as a u8, 4 or 6. + /// + /// * 'protocol' (u8): + /// - UDP:1 or TCP:0 + /// + /// * 'placeholder1' (u8): + /// - Placeholder for further extra params. + /// + /// * 'placeholder2' (u8): + /// - Placeholder for further extra params. + /// + /// # Event: + /// * AxonServed; + /// - On successfully serving the axon info. + /// + /// # Raises: + /// * 'SubNetworkDoesNotExist': + /// - Attempting to set weights on a non-existent network. + /// + /// * 'NotRegistered': + /// - Attempting to set weights from a non registered account. + /// + /// * 'InvalidIpType': + /// - The ip type is not 4 or 6. + /// + /// * 'InvalidIpAddress': + /// - The numerically encoded ip address does not resolve to a proper ip. + /// + /// * 'ServingRateLimitExceeded': + /// - Attempting to set prometheus information withing the rate limit min. + /// + #[pallet::call_index(40)] + #[pallet::weight((Weight::from_parts(46_000_000, 0) + .saturating_add(T::DbWeight::get().reads(4)) + .saturating_add(T::DbWeight::get().writes(1)), DispatchClass::Normal, Pays::No))] + pub fn serve_axon_tls( + origin: OriginFor, + netuid: u16, + version: u32, + ip: u128, + port: u16, + ip_type: u8, + protocol: u8, + placeholder1: u8, + placeholder2: u8, + certificate: Vec, + ) -> DispatchResult { + Self::do_serve_axon( + origin, + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + Some(certificate), ) } diff --git a/pallets/subtensor/src/rpc_info/neuron_info.rs b/pallets/subtensor/src/rpc_info/neuron_info.rs index cadd4b6e3..065855b04 100644 --- a/pallets/subtensor/src/rpc_info/neuron_info.rs +++ b/pallets/subtensor/src/rpc_info/neuron_info.rs @@ -147,6 +147,23 @@ impl Pallet { Some(neuron) } + pub fn get_neuron_certificate(netuid: u16, uid: u16) -> Option { + if !Self::if_subnet_exist(netuid) { + return None; + } + + let hotkey = match Self::get_hotkey_for_net_and_uid(netuid, uid) { + Ok(h) => h, + Err(_) => return None, + }; + + if Self::has_neuron_certificate(netuid, &hotkey) { + NeuronCertificates::::get(netuid, hotkey) + } else { + None + } + } + pub fn get_neuron(netuid: u16, uid: u16) -> Option> { if !Self::if_subnet_exist(netuid) { return None; diff --git a/pallets/subtensor/src/subnets/serving.rs b/pallets/subtensor/src/subnets/serving.rs index 1a9240c36..469478dd2 100644 --- a/pallets/subtensor/src/subnets/serving.rs +++ b/pallets/subtensor/src/subnets/serving.rs @@ -31,6 +31,9 @@ impl Pallet { /// * 'placeholder2' (u8): /// - Placeholder for further extra params. /// + /// * 'certificate' (Option>): + /// - Certificate for mutual Tls connection between neurons + /// /// # Event: /// * AxonServed; /// - On successfully serving the axon info. @@ -61,6 +64,7 @@ impl Pallet { protocol: u8, placeholder1: u8, placeholder2: u8, + certificate: Option>, ) -> dispatch::DispatchResult { // We check the callers (hotkey) signature. let hotkey_id = ensure_signed(origin)?; @@ -86,6 +90,15 @@ impl Pallet { Error::::ServingRateLimitExceeded ); + // Check certificate + if let Some(certificate) = certificate { + NeuronCertificates::::insert( + netuid, + hotkey_id.clone(), + NeuronCertificate { certificate }, + ) + } + // We insert the axon meta. prev_axon.block = Self::get_current_block_as_u64(); prev_axon.version = version; @@ -239,6 +252,10 @@ impl Pallet { Axons::::contains_key(netuid, hotkey) } + pub fn has_neuron_certificate(netuid: u16, hotkey: &T::AccountId) -> bool { + return NeuronCertificates::::contains_key(netuid, hotkey); + } + pub fn has_prometheus_info(netuid: u16, hotkey: &T::AccountId) -> bool { Prometheus::::contains_key(netuid, hotkey) } diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index 49a963951..b2d3b4e55 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -99,6 +99,56 @@ fn test_serving_ok() { }); } +#[test] +fn test_serving_tls_ok() { + new_test_ext().execute_with(|| { + let hotkey_account_id = U256::from(1); + let uid: u16 = 0; + let netuid: u16 = 1; + let tempo: u16 = 13; + let version: u32 = 2; + let ip: u128 = 1676056785; + let port: u16 = 128; + let ip_type: u8 = 4; + let modality: u16 = 0; + let protocol: u8 = 0; + let placeholder1: u8 = 0; + let placeholder2: u8 = 0; + let certificate: Vec = "CERT".as_bytes().to_vec(); + add_network(netuid, tempo, modality); + register_ok_neuron(netuid, hotkey_account_id, U256::from(66), 0); + assert_ok!(SubtensorModule::serve_axon_tls( + <::RuntimeOrigin>::signed(hotkey_account_id), + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + certificate.clone() + )); + let stored_certificate = SubtensorModule::get_neuron_certificate(netuid, uid); + assert_eq!(stored_certificate.unwrap().certificate, certificate); + let new_certificate = "UPDATED_CERT".as_bytes().to_vec(); + assert_ok!(SubtensorModule::serve_axon_tls( + <::RuntimeOrigin>::signed(hotkey_account_id), + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + new_certificate.clone() + )); + let stored_certificate = SubtensorModule::get_neuron_certificate(netuid, uid); + assert_eq!(stored_certificate.unwrap().certificate, new_certificate) + }); +} + #[test] fn test_serving_set_metadata_update() { new_test_ext(1).execute_with(|| { diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index ca8f83911..186d95911 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -142,7 +142,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 195, + spec_version: 196, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, @@ -1363,13 +1363,7 @@ impl_runtime_apis! { } fn get_delegate(delegate_account_vec: Vec) -> Vec { - let _result = SubtensorModule::get_delegate(delegate_account_vec); - if _result.is_some() { - let result = _result.expect("Could not get DelegateInfo"); - result.encode() - } else { - vec![] - } + SubtensorModule::get_delegate(delegate_account_vec).map(|r| r.encode()).unwrap_or(vec![]) } fn get_delegated(delegatee_account_vec: Vec) -> Vec { @@ -1385,13 +1379,7 @@ impl_runtime_apis! { } fn get_neuron_lite(netuid: u16, uid: u16) -> Vec { - let _result = SubtensorModule::get_neuron_lite(netuid, uid); - if _result.is_some() { - let result = _result.expect("Could not get NeuronInfoLite"); - result.encode() - } else { - vec![] - } + SubtensorModule::get_neuron_lite(netuid, uid).map(|r| r.encode()).unwrap_or(vec![]) } fn get_neurons(netuid: u16) -> Vec { @@ -1400,25 +1388,17 @@ impl_runtime_apis! { } fn get_neuron(netuid: u16, uid: u16) -> Vec { - let _result = SubtensorModule::get_neuron(netuid, uid); - if _result.is_some() { - let result = _result.expect("Could not get NeuronInfo"); - result.encode() - } else { - vec![] - } + SubtensorModule::get_neuron(netuid, uid).map(|r| r.encode()).unwrap_or(vec![]) + } + + fn get_neuron_certificate(netuid: u16, uid: u16) -> Vec { + SubtensorModule::get_neuron_certificate(netuid, uid).map(|r| r.encode()).unwrap_or(vec![]) } } impl subtensor_custom_rpc_runtime_api::SubnetInfoRuntimeApi for Runtime { fn get_subnet_info(netuid: u16) -> Vec { - let _result = SubtensorModule::get_subnet_info(netuid); - if _result.is_some() { - let result = _result.expect("Could not get SubnetInfo"); - result.encode() - } else { - vec![] - } + SubtensorModule::get_subnet_info(netuid).map(|r| r.encode()).unwrap_or(vec![]) } fn get_subnets_info() -> Vec { @@ -1442,13 +1422,7 @@ impl_runtime_apis! { } fn get_subnet_hyperparams(netuid: u16) -> Vec { - let _result = SubtensorModule::get_subnet_hyperparams(netuid); - if _result.is_some() { - let result = _result.expect("Could not get SubnetHyperparams"); - result.encode() - } else { - vec![] - } + SubtensorModule::get_subnet_hyperparams(netuid).map(|r| r.encode()).unwrap_or(vec![]) } } From dbbd79af8eeeeb23fd41267fb331c3f73a79838c Mon Sep 17 00:00:00 2001 From: Andreea Popescu Date: Mon, 26 Aug 2024 22:38:22 +0800 Subject: [PATCH 02/11] add missing argument description --- pallets/subtensor/src/macros/dispatches.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pallets/subtensor/src/macros/dispatches.rs b/pallets/subtensor/src/macros/dispatches.rs index 378c0c721..c4b985a49 100644 --- a/pallets/subtensor/src/macros/dispatches.rs +++ b/pallets/subtensor/src/macros/dispatches.rs @@ -547,6 +547,9 @@ mod dispatches { /// * 'placeholder2' (u8): /// - Placeholder for further extra params. /// + /// * 'certificate' (Vec): + /// - TLS certificate for inter neuron communitation. + /// /// # Event: /// * AxonServed; /// - On successfully serving the axon info. From 51df2e410d0fbf1805fe7c71d95ec326fcb6faff Mon Sep 17 00:00:00 2001 From: Andreea Popescu Date: Mon, 26 Aug 2024 23:28:28 +0800 Subject: [PATCH 03/11] remove rpc call --- pallets/subtensor/rpc/src/lib.rs | 21 --------------------- pallets/subtensor/runtime-api/src/lib.rs | 1 - pallets/subtensor/tests/serving.rs | 2 +- runtime/src/lib.rs | 4 ---- 4 files changed, 1 insertion(+), 27 deletions(-) diff --git a/pallets/subtensor/rpc/src/lib.rs b/pallets/subtensor/rpc/src/lib.rs index ebf7dcc35..d99388193 100644 --- a/pallets/subtensor/rpc/src/lib.rs +++ b/pallets/subtensor/rpc/src/lib.rs @@ -41,13 +41,6 @@ pub trait SubtensorCustomApi { fn get_neurons(&self, netuid: u16, at: Option) -> RpcResult>; #[method(name = "neuronInfo_getNeuron")] fn get_neuron(&self, netuid: u16, uid: u16, at: Option) -> RpcResult>; - #[method(name = "neuronInfo_getNeuronCertificate")] - fn get_neuron_certificate( - &self, - netuid: u16, - uid: u16, - at: Option, - ) -> RpcResult>; #[method(name = "subnetInfo_getSubnetInfo")] fn get_subnet_info(&self, netuid: u16, at: Option) -> RpcResult>; #[method(name = "subnetInfo_getSubnetsInfo")] @@ -193,20 +186,6 @@ where .map_err(|e| Error::RuntimeError(format!("Unable to get neuron info: {:?}", e)).into()) } - fn get_neuron_certificate( - &self, - netuid: u16, - uid: u16, - at: Option<::Hash>, - ) -> RpcResult> { - let api = self.client.runtime_api(); - let at = at.unwrap_or_else(|| self.client.info().best_hash); - - api.get_neuron_certificate(at, netuid, uid).map_err(|e| { - Error::RuntimeError(format!("Unable to get neuron certificate: {:?}", e)).into() - }) - } - fn get_subnet_info( &self, netuid: u16, diff --git a/pallets/subtensor/runtime-api/src/lib.rs b/pallets/subtensor/runtime-api/src/lib.rs index d2b6ca1fd..ca43384b8 100644 --- a/pallets/subtensor/runtime-api/src/lib.rs +++ b/pallets/subtensor/runtime-api/src/lib.rs @@ -14,7 +14,6 @@ sp_api::decl_runtime_apis! { pub trait NeuronInfoRuntimeApi { fn get_neurons(netuid: u16) -> Vec; fn get_neuron(netuid: u16, uid: u16) -> Vec; - fn get_neuron_certificate(netuid: u16, uid: u16) -> Vec; fn get_neurons_lite(netuid: u16) -> Vec; fn get_neuron_lite(netuid: u16, uid: u16) -> Vec; } diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index b2d3b4e55..a6a26a690 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -101,7 +101,7 @@ fn test_serving_ok() { #[test] fn test_serving_tls_ok() { - new_test_ext().execute_with(|| { + new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(1); let uid: u16 = 0; let netuid: u16 = 1; diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 186d95911..d41a82186 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1390,10 +1390,6 @@ impl_runtime_apis! { fn get_neuron(netuid: u16, uid: u16) -> Vec { SubtensorModule::get_neuron(netuid, uid).map(|r| r.encode()).unwrap_or(vec![]) } - - fn get_neuron_certificate(netuid: u16, uid: u16) -> Vec { - SubtensorModule::get_neuron_certificate(netuid, uid).map(|r| r.encode()).unwrap_or(vec![]) - } } impl subtensor_custom_rpc_runtime_api::SubnetInfoRuntimeApi for Runtime { From 1b7402df35704e24d1aa50a59cfe3bdd39febaae Mon Sep 17 00:00:00 2001 From: Andreea Popescu Date: Tue, 27 Aug 2024 19:10:50 +0800 Subject: [PATCH 04/11] clear neuron --- pallets/subtensor/src/lib.rs | 2 ++ pallets/subtensor/src/subnets/uids.rs | 3 +++ pallets/subtensor/src/swap/swap_hotkey.rs | 12 ++++++++++++ 3 files changed, 17 insertions(+) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 6b6a8d62d..2c3a618d1 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -73,6 +73,7 @@ pub mod pallet { use sp_runtime::traits::{Dispatchable, TrailingZeroInput}; use sp_std::vec; use sp_std::vec::Vec; + use subtensor_macros::freeze_struct; #[cfg(not(feature = "std"))] use alloc::boxed::Box; @@ -132,6 +133,7 @@ pub mod pallet { /// Struct for NeuronCertificate. pub type NeuronCertificateOf = NeuronCertificate; /// Data structure for NeuronCertificate information. + #[freeze_struct("e6193a76002d491")] #[derive(Decode, Encode, Default, TypeInfo, PartialEq, Eq, Clone, Debug)] pub struct NeuronCertificate { /// The neuron certificate. diff --git a/pallets/subtensor/src/subnets/uids.rs b/pallets/subtensor/src/subnets/uids.rs index fff358f1c..2a5ceedb4 100644 --- a/pallets/subtensor/src/subnets/uids.rs +++ b/pallets/subtensor/src/subnets/uids.rs @@ -45,6 +45,9 @@ impl Pallet { Uids::::insert(netuid, new_hotkey.clone(), uid_to_replace); // Make uid - hotkey association. BlockAtRegistration::::insert(netuid, uid_to_replace, block_number); // Fill block at registration. IsNetworkMember::::insert(new_hotkey.clone(), netuid, true); // Fill network is member. + + // 4. Clear neuron certificates + NeuronCertificates::::remove(netuid, old_hotkey.clone()); } /// Appends the uid to the network. diff --git a/pallets/subtensor/src/swap/swap_hotkey.rs b/pallets/subtensor/src/swap/swap_hotkey.rs index 793e34bff..ca3d0b5a7 100644 --- a/pallets/subtensor/src/swap/swap_hotkey.rs +++ b/pallets/subtensor/src/swap/swap_hotkey.rs @@ -276,6 +276,18 @@ impl Pallet { weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); } } + + // 9.7. Swap neuron TLS certificates. + // NeuronCertificates( netuid, hotkey ) -> Vec -- the neuron certificate for the hotkey. + if is_network_member { + if let Ok(old_neuron_certificates) = + NeuronCertificates::::try_get(netuid, old_hotkey) + { + NeuronCertificates::::remove(netuid, old_hotkey); + NeuronCertificates::::insert(netuid, new_hotkey, old_neuron_certificates); + weight.saturating_accrue(T::DbWeight::get().reads_writes(1, 2)); + } + } } // 10. Swap Stake. From b5d7c0e97ec5ce40f39e481db92779f82e563ab8 Mon Sep 17 00:00:00 2001 From: Andreea Popescu Date: Wed, 28 Aug 2024 16:28:17 +0800 Subject: [PATCH 05/11] clippy tests --- pallets/subtensor/src/lib.rs | 4 +-- pallets/subtensor/src/subnets/serving.rs | 6 ++--- pallets/subtensor/tests/serving.rs | 10 ++++--- pallets/subtensor/tests/swap_hotkey.rs | 34 ++++++++++++++++++++++++ pallets/subtensor/tests/uids.rs | 11 ++++++++ 5 files changed, 56 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 2c3a618d1..4f553ed7a 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -73,7 +73,7 @@ pub mod pallet { use sp_runtime::traits::{Dispatchable, TrailingZeroInput}; use sp_std::vec; use sp_std::vec::Vec; - use subtensor_macros::freeze_struct; + use subtensor_macros::freeze_struct; #[cfg(not(feature = "std"))] use alloc::boxed::Box; @@ -1175,7 +1175,7 @@ pub mod pallet { StorageDoubleMap<_, Identity, u16, Blake2_128Concat, T::AccountId, AxonInfoOf, OptionQuery>; /// --- MAP ( netuid, hotkey ) --> certificate #[pallet::storage] - pub(super) type NeuronCertificates = StorageDoubleMap< + pub type NeuronCertificates = StorageDoubleMap< _, Identity, u16, diff --git a/pallets/subtensor/src/subnets/serving.rs b/pallets/subtensor/src/subnets/serving.rs index 469478dd2..e6c1a62d7 100644 --- a/pallets/subtensor/src/subnets/serving.rs +++ b/pallets/subtensor/src/subnets/serving.rs @@ -31,8 +31,8 @@ impl Pallet { /// * 'placeholder2' (u8): /// - Placeholder for further extra params. /// - /// * 'certificate' (Option>): - /// - Certificate for mutual Tls connection between neurons + /// * 'certificate' (Option>): + /// - Certificate for mutual Tls connection between neurons /// /// # Event: /// * AxonServed; @@ -253,7 +253,7 @@ impl Pallet { } pub fn has_neuron_certificate(netuid: u16, hotkey: &T::AccountId) -> bool { - return NeuronCertificates::::contains_key(netuid, hotkey); + NeuronCertificates::::contains_key(netuid, hotkey) } pub fn has_prometheus_info(netuid: u16, hotkey: &T::AccountId) -> bool { diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index a6a26a690..a0988fc02 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -129,8 +129,9 @@ fn test_serving_tls_ok() { placeholder2, certificate.clone() )); - let stored_certificate = SubtensorModule::get_neuron_certificate(netuid, uid); - assert_eq!(stored_certificate.unwrap().certificate, certificate); + let stored_certificate = + SubtensorModule::get_neuron_certificate(netuid, uid).expect("Certificate should exist"); + assert_eq!(stored_certificate.certificate, certificate); let new_certificate = "UPDATED_CERT".as_bytes().to_vec(); assert_ok!(SubtensorModule::serve_axon_tls( <::RuntimeOrigin>::signed(hotkey_account_id), @@ -144,8 +145,9 @@ fn test_serving_tls_ok() { placeholder2, new_certificate.clone() )); - let stored_certificate = SubtensorModule::get_neuron_certificate(netuid, uid); - assert_eq!(stored_certificate.unwrap().certificate, new_certificate) + let stored_certificate = + SubtensorModule::get_neuron_certificate(netuid, uid).expect("Certificate should exist"); + assert_eq!(stored_certificate.certificate, new_certificate) }); } diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index bff738b86..845338be9 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -311,6 +311,40 @@ fn test_swap_axons() { }); } +// SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_certificates --exact --nocapture +#[test] +fn test_swap_certificates() { + new_test_ext(1).execute_with(|| { + let old_hotkey = U256::from(1); + let new_hotkey = U256::from(2); + let coldkey = U256::from(3); + let netuid = 0u16; + let certificate = NeuronCertificate { + certificate: vec![1, 2, 3], + }; + let mut weight = Weight::zero(); + + add_network(netuid, 0, 1); + IsNetworkMember::::insert(old_hotkey, netuid, true); + NeuronCertificates::::insert(netuid, old_hotkey, certificate.clone()); + + assert_ok!(SubtensorModule::perform_hotkey_swap( + &old_hotkey, + &new_hotkey, + &coldkey, + &mut weight + )); + + assert!(!NeuronCertificates::::contains_key( + netuid, old_hotkey + )); + assert_eq!( + NeuronCertificates::::get(netuid, new_hotkey), + Some(certificate) + ); + }); +} + // SKIP_WASM_BUILD=1 RUST_LOG=debug cargo test --test swap_hotkey -- test_swap_weight_commits --exact --nocapture #[test] fn test_swap_weight_commits() { diff --git a/pallets/subtensor/tests/uids.rs b/pallets/subtensor/tests/uids.rs index 82adc6b8a..743471b5d 100644 --- a/pallets/subtensor/tests/uids.rs +++ b/pallets/subtensor/tests/uids.rs @@ -3,6 +3,7 @@ use crate::mock::*; use frame_support::assert_ok; use frame_system::Config; +use pallet_subtensor::*; use sp_core::U256; mod mock; @@ -32,6 +33,9 @@ fn test_replace_neuron() { let new_hotkey_account_id = U256::from(2); let _new_colkey_account_id = U256::from(12345); + let certificate = NeuronCertificate { + certificate: vec![1, 2, 3], + }; //add network add_network(netuid, tempo, 0); @@ -51,6 +55,9 @@ fn test_replace_neuron() { let neuron_uid = SubtensorModule::get_uid_for_net_and_hotkey(netuid, &hotkey_account_id); assert_ok!(neuron_uid); + // Set a neuron certificate for it + NeuronCertificates::::insert(netuid, hotkey_account_id, certificate); + // Replace the neuron. SubtensorModule::replace_neuron( netuid, @@ -77,6 +84,10 @@ fn test_replace_neuron() { &new_hotkey_account_id )); assert_eq!(curr_hotkey.unwrap(), new_hotkey_account_id); + + // Check neuron certificate was reset + let certificate = SubtensorModule::get_neuron_certificate(netuid, neuron_uid.unwrap()); + assert_eq!(certificate, None); }); } From 05d0d8de412def161fb22ed051e8607582544182 Mon Sep 17 00:00:00 2001 From: Andreea Popescu Date: Sat, 31 Aug 2024 15:48:43 +0800 Subject: [PATCH 06/11] rebase clippy --- runtime/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index d41a82186..0d952c2bb 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1363,7 +1363,7 @@ impl_runtime_apis! { } fn get_delegate(delegate_account_vec: Vec) -> Vec { - SubtensorModule::get_delegate(delegate_account_vec).map(|r| r.encode()).unwrap_or(vec![]) + SubtensorModule::get_delegate(delegate_account_vec).map(|r| r.encode()).unwrap_or_default() } fn get_delegated(delegatee_account_vec: Vec) -> Vec { @@ -1379,7 +1379,7 @@ impl_runtime_apis! { } fn get_neuron_lite(netuid: u16, uid: u16) -> Vec { - SubtensorModule::get_neuron_lite(netuid, uid).map(|r| r.encode()).unwrap_or(vec![]) + SubtensorModule::get_neuron_lite(netuid, uid).map(|r| r.encode()).unwrap_or_default() } fn get_neurons(netuid: u16) -> Vec { @@ -1388,13 +1388,13 @@ impl_runtime_apis! { } fn get_neuron(netuid: u16, uid: u16) -> Vec { - SubtensorModule::get_neuron(netuid, uid).map(|r| r.encode()).unwrap_or(vec![]) + SubtensorModule::get_neuron(netuid, uid).map(|r| r.encode()).unwrap_or_default() } } impl subtensor_custom_rpc_runtime_api::SubnetInfoRuntimeApi for Runtime { fn get_subnet_info(netuid: u16) -> Vec { - SubtensorModule::get_subnet_info(netuid).map(|r| r.encode()).unwrap_or(vec![]) + SubtensorModule::get_subnet_info(netuid).map(|r| r.encode()).unwrap_or_default() } fn get_subnets_info() -> Vec { @@ -1418,7 +1418,7 @@ impl_runtime_apis! { } fn get_subnet_hyperparams(netuid: u16) -> Vec { - SubtensorModule::get_subnet_hyperparams(netuid).map(|r| r.encode()).unwrap_or(vec![]) + SubtensorModule::get_subnet_hyperparams(netuid).map(|r| r.encode()).unwrap_or_default() } } From 2aad6fe60e4c6f77841452bea46717dcb0f9f1e3 Mon Sep 17 00:00:00 2001 From: Andreea Popescu Date: Mon, 2 Sep 2024 21:20:00 +0800 Subject: [PATCH 07/11] cleanup get_neuron_certificate --- pallets/subtensor/src/rpc_info/neuron_info.rs | 17 ----------------- pallets/subtensor/src/subnets/serving.rs | 4 ---- pallets/subtensor/tests/serving.rs | 10 +++++----- pallets/subtensor/tests/uids.rs | 2 +- 4 files changed, 6 insertions(+), 27 deletions(-) diff --git a/pallets/subtensor/src/rpc_info/neuron_info.rs b/pallets/subtensor/src/rpc_info/neuron_info.rs index 065855b04..cadd4b6e3 100644 --- a/pallets/subtensor/src/rpc_info/neuron_info.rs +++ b/pallets/subtensor/src/rpc_info/neuron_info.rs @@ -147,23 +147,6 @@ impl Pallet { Some(neuron) } - pub fn get_neuron_certificate(netuid: u16, uid: u16) -> Option { - if !Self::if_subnet_exist(netuid) { - return None; - } - - let hotkey = match Self::get_hotkey_for_net_and_uid(netuid, uid) { - Ok(h) => h, - Err(_) => return None, - }; - - if Self::has_neuron_certificate(netuid, &hotkey) { - NeuronCertificates::::get(netuid, hotkey) - } else { - None - } - } - pub fn get_neuron(netuid: u16, uid: u16) -> Option> { if !Self::if_subnet_exist(netuid) { return None; diff --git a/pallets/subtensor/src/subnets/serving.rs b/pallets/subtensor/src/subnets/serving.rs index e6c1a62d7..22550fb93 100644 --- a/pallets/subtensor/src/subnets/serving.rs +++ b/pallets/subtensor/src/subnets/serving.rs @@ -252,10 +252,6 @@ impl Pallet { Axons::::contains_key(netuid, hotkey) } - pub fn has_neuron_certificate(netuid: u16, hotkey: &T::AccountId) -> bool { - NeuronCertificates::::contains_key(netuid, hotkey) - } - pub fn has_prometheus_info(netuid: u16, hotkey: &T::AccountId) -> bool { Prometheus::::contains_key(netuid, hotkey) } diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index a0988fc02..17b8d2144 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -103,7 +103,6 @@ fn test_serving_ok() { fn test_serving_tls_ok() { new_test_ext(1).execute_with(|| { let hotkey_account_id = U256::from(1); - let uid: u16 = 0; let netuid: u16 = 1; let tempo: u16 = 13; let version: u32 = 2; @@ -129,8 +128,9 @@ fn test_serving_tls_ok() { placeholder2, certificate.clone() )); - let stored_certificate = - SubtensorModule::get_neuron_certificate(netuid, uid).expect("Certificate should exist"); + + let stored_certificate = NeuronCertificates::::get(netuid, hotkey_account_id) + .expect("Certificate should exist"); assert_eq!(stored_certificate.certificate, certificate); let new_certificate = "UPDATED_CERT".as_bytes().to_vec(); assert_ok!(SubtensorModule::serve_axon_tls( @@ -145,8 +145,8 @@ fn test_serving_tls_ok() { placeholder2, new_certificate.clone() )); - let stored_certificate = - SubtensorModule::get_neuron_certificate(netuid, uid).expect("Certificate should exist"); + let stored_certificate = NeuronCertificates::::get(netuid, hotkey_account_id) + .expect("Certificate should exist"); assert_eq!(stored_certificate.certificate, new_certificate) }); } diff --git a/pallets/subtensor/tests/uids.rs b/pallets/subtensor/tests/uids.rs index 743471b5d..827d4ec1a 100644 --- a/pallets/subtensor/tests/uids.rs +++ b/pallets/subtensor/tests/uids.rs @@ -86,7 +86,7 @@ fn test_replace_neuron() { assert_eq!(curr_hotkey.unwrap(), new_hotkey_account_id); // Check neuron certificate was reset - let certificate = SubtensorModule::get_neuron_certificate(netuid, neuron_uid.unwrap()); + let certificate = NeuronCertificates::::get(netuid, hotkey_account_id); assert_eq!(certificate, None); }); } From 6b89f64c4d14fa52f8e091696c0b00472ae7cafa Mon Sep 17 00:00:00 2001 From: Andreea Popescu Date: Fri, 6 Sep 2024 22:26:59 +0800 Subject: [PATCH 08/11] bounded vec --- pallets/subtensor/src/lib.rs | 27 +++++++++++++++++++++--- pallets/subtensor/src/subnets/serving.rs | 8 +++---- pallets/subtensor/tests/serving.rs | 4 ++-- pallets/subtensor/tests/swap_hotkey.rs | 4 +--- pallets/subtensor/tests/uids.rs | 27 ++++++++++++++++++++---- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 4f553ed7a..cc3d7d025 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -67,6 +67,7 @@ pub mod pallet { traits::{ tokens::fungible, OriginTrait, QueryPreimage, StorePreimage, UnfilteredDispatchable, }, + BoundedVec, }; use frame_system::pallet_prelude::*; use sp_core::H256; @@ -133,11 +134,31 @@ pub mod pallet { /// Struct for NeuronCertificate. pub type NeuronCertificateOf = NeuronCertificate; /// Data structure for NeuronCertificate information. - #[freeze_struct("e6193a76002d491")] + #[freeze_struct("1c232be200d9ec6c")] #[derive(Decode, Encode, Default, TypeInfo, PartialEq, Eq, Clone, Debug)] pub struct NeuronCertificate { - /// The neuron certificate. - pub certificate: Vec, + /// The neuron TLS public key + pub public_key: BoundedVec>, + /// The algorithm used to generate the public key + pub algorithm: u8, + } + + impl TryFrom> for NeuronCertificate { + type Error = (); + + fn try_from(value: Vec) -> Result { + if value.len() > 65 { + return Err(()); + } + // take the first byte as the algorithm + let algorithm = value.first().ok_or(())?; + // and the rest as the public_key + let certificate = value.get(1..).ok_or(())?.to_vec(); + Ok(Self { + public_key: BoundedVec::try_from(certificate).map_err(|_| ())?, + algorithm: *algorithm, + }) + } } /// Struct for Prometheus. diff --git a/pallets/subtensor/src/subnets/serving.rs b/pallets/subtensor/src/subnets/serving.rs index 22550fb93..7e2b9a0f0 100644 --- a/pallets/subtensor/src/subnets/serving.rs +++ b/pallets/subtensor/src/subnets/serving.rs @@ -92,11 +92,9 @@ impl Pallet { // Check certificate if let Some(certificate) = certificate { - NeuronCertificates::::insert( - netuid, - hotkey_id.clone(), - NeuronCertificate { certificate }, - ) + if let Ok(certificate) = NeuronCertificateOf::try_from(certificate) { + NeuronCertificates::::insert(netuid, hotkey_id.clone(), certificate) + } } // We insert the axon meta. diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index 17b8d2144..4516c3b05 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -131,7 +131,7 @@ fn test_serving_tls_ok() { let stored_certificate = NeuronCertificates::::get(netuid, hotkey_account_id) .expect("Certificate should exist"); - assert_eq!(stored_certificate.certificate, certificate); + assert_eq!(stored_certificate.public_key.clone().into_inner(), certificate.get(1..).expect("Certificate should exist")); let new_certificate = "UPDATED_CERT".as_bytes().to_vec(); assert_ok!(SubtensorModule::serve_axon_tls( <::RuntimeOrigin>::signed(hotkey_account_id), @@ -147,7 +147,7 @@ fn test_serving_tls_ok() { )); let stored_certificate = NeuronCertificates::::get(netuid, hotkey_account_id) .expect("Certificate should exist"); - assert_eq!(stored_certificate.certificate, new_certificate) + assert_eq!(stored_certificate.public_key.clone().into_inner(), new_certificate.get(1..).expect("Certificate should exist")); }); } diff --git a/pallets/subtensor/tests/swap_hotkey.rs b/pallets/subtensor/tests/swap_hotkey.rs index 845338be9..89938e3eb 100644 --- a/pallets/subtensor/tests/swap_hotkey.rs +++ b/pallets/subtensor/tests/swap_hotkey.rs @@ -319,9 +319,7 @@ fn test_swap_certificates() { let new_hotkey = U256::from(2); let coldkey = U256::from(3); let netuid = 0u16; - let certificate = NeuronCertificate { - certificate: vec![1, 2, 3], - }; + let certificate = NeuronCertificate::try_from(vec![1, 2, 3]).unwrap(); let mut weight = Weight::zero(); add_network(netuid, 0, 1); diff --git a/pallets/subtensor/tests/uids.rs b/pallets/subtensor/tests/uids.rs index 827d4ec1a..6b4c00328 100644 --- a/pallets/subtensor/tests/uids.rs +++ b/pallets/subtensor/tests/uids.rs @@ -1,7 +1,7 @@ #![allow(clippy::unwrap_used)] use crate::mock::*; -use frame_support::assert_ok; +use frame_support::{assert_err, assert_ok}; use frame_system::Config; use pallet_subtensor::*; use sp_core::U256; @@ -33,9 +33,7 @@ fn test_replace_neuron() { let new_hotkey_account_id = U256::from(2); let _new_colkey_account_id = U256::from(12345); - let certificate = NeuronCertificate { - certificate: vec![1, 2, 3], - }; + let certificate = NeuronCertificate::try_from(vec![1, 2, 3]).unwrap(); //add network add_network(netuid, tempo, 0); @@ -382,3 +380,24 @@ fn test_replace_neuron_multiple_subnets_unstake_all() { ); }); } + +#[test] +fn test_neuron_certificate() { + new_test_ext(1).execute_with(|| { + // 512 bits key + let mut data = [0; 65].to_vec(); + assert_ok!(NeuronCertificate::try_from(data)); + + // 256 bits key + data = [1; 33].to_vec(); + assert_ok!(NeuronCertificate::try_from(data)); + + // too much data + data = [8; 88].to_vec(); + assert_err!(NeuronCertificate::try_from(data), ()); + + // no data + data = vec![]; + assert_err!(NeuronCertificate::try_from(data), ()); + }); +} From 162453ecb636dc028a682428b2a8837dc3a5a3a4 Mon Sep 17 00:00:00 2001 From: Andreea Popescu Date: Mon, 9 Sep 2024 14:04:20 +0800 Subject: [PATCH 09/11] spec version and fmt --- pallets/subtensor/tests/serving.rs | 10 ++++++++-- runtime/src/lib.rs | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/pallets/subtensor/tests/serving.rs b/pallets/subtensor/tests/serving.rs index 4516c3b05..6bc30c76f 100644 --- a/pallets/subtensor/tests/serving.rs +++ b/pallets/subtensor/tests/serving.rs @@ -131,7 +131,10 @@ fn test_serving_tls_ok() { let stored_certificate = NeuronCertificates::::get(netuid, hotkey_account_id) .expect("Certificate should exist"); - assert_eq!(stored_certificate.public_key.clone().into_inner(), certificate.get(1..).expect("Certificate should exist")); + assert_eq!( + stored_certificate.public_key.clone().into_inner(), + certificate.get(1..).expect("Certificate should exist") + ); let new_certificate = "UPDATED_CERT".as_bytes().to_vec(); assert_ok!(SubtensorModule::serve_axon_tls( <::RuntimeOrigin>::signed(hotkey_account_id), @@ -147,7 +150,10 @@ fn test_serving_tls_ok() { )); let stored_certificate = NeuronCertificates::::get(netuid, hotkey_account_id) .expect("Certificate should exist"); - assert_eq!(stored_certificate.public_key.clone().into_inner(), new_certificate.get(1..).expect("Certificate should exist")); + assert_eq!( + stored_certificate.public_key.clone().into_inner(), + new_certificate.get(1..).expect("Certificate should exist") + ); }); } diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 0d952c2bb..884c9d85c 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -142,7 +142,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { // `spec_version`, and `authoring_version` are the same between Wasm and native. // This value is set to 100 to notify Polkadot-JS App (https://polkadot.js.org/apps) to use // the compatible custom types. - spec_version: 196, + spec_version: 197, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 961419308245a085669d1b0c00c46fc80a6ff755 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Polewicz?= Date: Wed, 25 Sep 2024 22:32:33 +0200 Subject: [PATCH 10/11] backport clippy silencing as instructed by formalized_tensor --- Cargo.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Cargo.toml b/Cargo.toml index f9a7968b9..4f162ca6b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -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 } From eacda1edec13e3d44c9cb486bd7706d7e0553f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Polewicz?= Date: Thu, 26 Sep 2024 11:26:50 +0300 Subject: [PATCH 11/11] Remove a small refactor in runtime/src/lib.rs --- runtime/src/lib.rs | 40 +++++++++++++++++++++++++++++++++++----- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 6696259a3..b7a347c46 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -1369,7 +1369,13 @@ impl_runtime_apis! { } fn get_delegate(delegate_account_vec: Vec) -> Vec { - SubtensorModule::get_delegate(delegate_account_vec).map(|r| r.encode()).unwrap_or_default() + let _result = SubtensorModule::get_delegate(delegate_account_vec); + if _result.is_some() { + let result = _result.expect("Could not get DelegateInfo"); + result.encode() + } else { + vec![] + } } fn get_delegated(delegatee_account_vec: Vec) -> Vec { @@ -1385,7 +1391,13 @@ impl_runtime_apis! { } fn get_neuron_lite(netuid: u16, uid: u16) -> Vec { - SubtensorModule::get_neuron_lite(netuid, uid).map(|r| r.encode()).unwrap_or_default() + let _result = SubtensorModule::get_neuron_lite(netuid, uid); + if _result.is_some() { + let result = _result.expect("Could not get NeuronInfoLite"); + result.encode() + } else { + vec![] + } } fn get_neurons(netuid: u16) -> Vec { @@ -1394,13 +1406,25 @@ impl_runtime_apis! { } fn get_neuron(netuid: u16, uid: u16) -> Vec { - SubtensorModule::get_neuron(netuid, uid).map(|r| r.encode()).unwrap_or_default() + let _result = SubtensorModule::get_neuron(netuid, uid); + if _result.is_some() { + let result = _result.expect("Could not get NeuronInfo"); + result.encode() + } else { + vec![] + } } } impl subtensor_custom_rpc_runtime_api::SubnetInfoRuntimeApi for Runtime { fn get_subnet_info(netuid: u16) -> Vec { - SubtensorModule::get_subnet_info(netuid).map(|r| r.encode()).unwrap_or_default() + let _result = SubtensorModule::get_subnet_info(netuid); + if _result.is_some() { + let result = _result.expect("Could not get SubnetInfo"); + result.encode() + } else { + vec![] + } } fn get_subnets_info() -> Vec { @@ -1424,7 +1448,13 @@ impl_runtime_apis! { } fn get_subnet_hyperparams(netuid: u16) -> Vec { - SubtensorModule::get_subnet_hyperparams(netuid).map(|r| r.encode()).unwrap_or_default() + let _result = SubtensorModule::get_subnet_hyperparams(netuid); + if _result.is_some() { + let result = _result.expect("Could not get SubnetHyperparams"); + result.encode() + } else { + vec![] + } } }