From 3d4edcf7646bf3889b7c58078a6772a9576a1c13 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 7 Jan 2025 23:36:51 +0800 Subject: [PATCH 1/9] extrinsic to enable disable precompile --- pallets/admin-utils/src/lib.rs | 66 +++++++++++++++++++++++- pallets/admin-utils/src/tests/mock.rs | 1 + pallets/admin-utils/src/tests/mod.rs | 72 +++++++++++++++++++++++++++ runtime/src/precompiles/mod.rs | 49 ++++++++++++++++-- 4 files changed, 182 insertions(+), 6 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index d709c70c5d..e91a4b88a7 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -23,9 +23,9 @@ mod tests; #[frame_support::pallet] pub mod pallet { use super::*; - use frame_support::dispatch::DispatchResult; use frame_support::pallet_prelude::*; use frame_support::traits::tokens::Balance; + use frame_support::{dispatch::DispatchResult, pallet_prelude::StorageMap}; use frame_system::pallet_prelude::*; use pallet_evm_chain_id::{self, ChainId}; use sp_runtime::BoundedVec; @@ -69,7 +69,16 @@ pub mod pallet { } #[pallet::event] - pub enum Event {} + #[pallet::generate_deposit(pub(super) fn deposit_event)] + pub enum Event { + /// Event emitted when a precompile operation is updated. + PrecompileUpdated { + /// The type of precompile operation being updated. + precompile_id: PrecompileEnum, + /// Indicates if the precompile operation is enabled or not. + enabled: bool, + }, + } // Errors inform users that something went wrong. #[pallet::error] @@ -81,6 +90,39 @@ pub mod pallet { /// The maximum number of subnet validators must be more than the current number of UIDs already in the subnet. MaxAllowedUIdsLessThanCurrentUIds, } + /// Enum for specifying the type of precompile operation. + #[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq, Debug, Copy)] + pub enum PrecompileEnum { + /// Enum for balance transfer precompile + BalanceTransfer, + /// Enum for staking precompile + Staking, + /// Enum for subnet precompile + Subnet, + /// Enum for metagraph precompile + Metagraph, + /// Enum for subnets precompile + Subnets, + /// Enum for neurons precompile + Neurons, + } + + #[pallet::type_value] + /// Default value for precompile enable + pub fn DefaultPrecompileEnabled() -> bool { + true + } + + #[pallet::storage] + /// Map PrecompileEnum --> enabled + pub type PrecompileEnable = StorageMap< + _, + Blake2_128Concat, + PrecompileEnum, + bool, + ValueQuery, + DefaultPrecompileEnabled, + >; /// Dispatchable functions allows users to interact with the pallet and invoke state changes. #[pallet::call] @@ -1276,6 +1318,26 @@ pub mod pallet { ensure_root(origin)?; T::Grandpa::schedule_change(next_authorities, in_blocks, forced) } + + /// A public interface for `pallet_grandpa::Pallet::schedule_grandpa_change`. + #[pallet::call_index(60)] + #[pallet::weight(Weight::from_parts(46_000_000, 0))] + pub fn sudo_toggle_evm_precompile( + origin: OriginFor, + precompile_id: PrecompileEnum, + enabled: bool, + ) -> DispatchResult { + ensure_root(origin)?; + if PrecompileEnable::::get(precompile_id) != enabled { + PrecompileEnable::::insert(precompile_id, enabled); + Self::deposit_event(Event::PrecompileUpdated { + precompile_id, + enabled, + }); + } + // T::Grandpa::schedule_change(next_authorities, in_blocks, forced) + Ok(()) + } } } diff --git a/pallets/admin-utils/src/tests/mock.rs b/pallets/admin-utils/src/tests/mock.rs index 8c9110e6e5..18de6e6afa 100644 --- a/pallets/admin-utils/src/tests/mock.rs +++ b/pallets/admin-utils/src/tests/mock.rs @@ -390,6 +390,7 @@ pub(crate) fn run_to_block(n: u64) { while System::block_number() < n { SubtensorModule::on_finalize(System::block_number()); System::on_finalize(System::block_number()); + System::reset_events(); System::set_block_number(System::block_number() + 1); System::on_initialize(System::block_number()); SubtensorModule::on_initialize(System::block_number()); diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 9bdf133f54..94c72d104d 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -10,6 +10,7 @@ use pallet_subtensor::{migrations, Event}; use sp_consensus_grandpa::AuthorityId as GrandpaId; use sp_core::{ed25519, Pair, U256}; +use crate::pallet::PrecompileEnable; use crate::Error; use mock::*; @@ -1490,3 +1491,74 @@ fn test_schedule_grandpa_change() { assert_eq!(Grandpa::grandpa_authorities(), vec![(bob, 1)]); }); } + +#[test] +fn test_sudo_toggle_evm_precompile() { + new_test_ext().execute_with(|| { + let precompile_id = crate::PrecompileEnum::BalanceTransfer; + let initial_enabled = PrecompileEnable::::get(precompile_id); + assert_eq!(initial_enabled, true); // Assuming the default is true + + run_to_block(1); + + assert_eq!( + AdminUtils::sudo_toggle_evm_precompile( + <::RuntimeOrigin>::signed(U256::from(0)), + precompile_id, + false + ), + Err(DispatchError::BadOrigin) + ); + + assert_ok!(AdminUtils::sudo_toggle_evm_precompile( + RuntimeOrigin::root(), + precompile_id, + false + )); + + assert_eq!( + System::events() + .iter() + .filter(|r| r.event + == RuntimeEvent::AdminUtils(crate::Event::PrecompileUpdated { + precompile_id, + enabled: false + })) + .count(), + 1 + ); + + let updated_enabled = PrecompileEnable::::get(precompile_id); + assert_eq!(updated_enabled, false); + + run_to_block(2); + + assert_ok!(AdminUtils::sudo_toggle_evm_precompile( + RuntimeOrigin::root(), + precompile_id, + false + )); + + // no event without status change + assert_eq!( + System::events() + .iter() + .filter(|r| r.event + == RuntimeEvent::AdminUtils(crate::Event::PrecompileUpdated { + precompile_id, + enabled: false + })) + .count(), + 0 + ); + + assert_ok!(AdminUtils::sudo_toggle_evm_precompile( + RuntimeOrigin::root(), + precompile_id, + true + )); + + let final_enabled = PrecompileEnable::::get(precompile_id); + assert_eq!(final_enabled, true); + }); +} diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index e13516e958..524c252f08 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -10,6 +10,9 @@ use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; +use crate::Runtime; +use pallet_admin_utils::{PrecompileEnable, PrecompileEnum}; + // Include custom precompiles mod balance_transfer; mod ed25519; @@ -70,14 +73,52 @@ where // Non-Frontier specific nor Ethereum precompiles : a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), - a if a == hash(EDVERIFY_PRECOMPILE_INDEX) => Some(Ed25519Verify::execute(handle)), + + a if a == hash(EDVERIFY_PRECOMPILE_INDEX) => { + if PrecompileEnable::::get(PrecompileEnum::BalanceTransfer) { + Some(Ed25519Verify::execute(handle)) + } else { + Some(Err(PrecompileFailure::Error { + exit_status: ExitError::Other( + "Precompile Ed25519Verify is disabled".into(), + ), + })) + } + } // Subtensor specific precompiles : a if a == hash(BALANCE_TRANSFER_INDEX) => { - Some(BalanceTransferPrecompile::execute(handle)) + if PrecompileEnable::::get(PrecompileEnum::BalanceTransfer) { + Some(BalanceTransferPrecompile::execute(handle)) + } else { + Some(Err(PrecompileFailure::Error { + exit_status: ExitError::Other( + "Precompile Balance Transfer is disabled".into(), + ), + })) + } } - a if a == hash(STAKING_PRECOMPILE_INDEX) => Some(StakingPrecompile::execute(handle)), + a if a == hash(STAKING_PRECOMPILE_INDEX) => { + if PrecompileEnable::::get(PrecompileEnum::Staking) { + Some(StakingPrecompile::execute(handle)) + } else { + Some(Err(PrecompileFailure::Error { + exit_status: ExitError::Other( + "Precompile Balance Transfer is disabled".into(), + ), + })) + } + } + a if a == hash(METAGRAPH_PRECOMPILE_INDEX) => { - Some(MetagraphPrecompile::execute(handle)) + if PrecompileEnable::::get(PrecompileEnum::Metagraph) { + Some(MetagraphPrecompile::execute(handle)) + } else { + Some(Err(PrecompileFailure::Error { + exit_status: ExitError::Other( + "Precompile Balance Transfer is disabled".into(), + ), + })) + } } _ => None, From b2e216e3fa20eb47d7793753e083e2d48f6b343c Mon Sep 17 00:00:00 2001 From: open-junius Date: Sat, 11 Jan 2025 00:03:03 +0800 Subject: [PATCH 2/9] fix clippy --- pallets/admin-utils/src/lib.rs | 1 - pallets/admin-utils/src/tests/mod.rs | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 2de97d7450..09a4ce0c8f 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -1321,7 +1321,6 @@ pub mod pallet { enabled, }); } - // T::Grandpa::schedule_change(next_authorities, in_blocks, forced) Ok(()) } } diff --git a/pallets/admin-utils/src/tests/mod.rs b/pallets/admin-utils/src/tests/mod.rs index 77bce472be..e970ddee40 100644 --- a/pallets/admin-utils/src/tests/mod.rs +++ b/pallets/admin-utils/src/tests/mod.rs @@ -1469,7 +1469,7 @@ fn test_sudo_toggle_evm_precompile() { new_test_ext().execute_with(|| { let precompile_id = crate::PrecompileEnum::BalanceTransfer; let initial_enabled = PrecompileEnable::::get(precompile_id); - assert_eq!(initial_enabled, true); // Assuming the default is true + assert!(initial_enabled); // Assuming the default is true run_to_block(1); @@ -1501,7 +1501,7 @@ fn test_sudo_toggle_evm_precompile() { ); let updated_enabled = PrecompileEnable::::get(precompile_id); - assert_eq!(updated_enabled, false); + assert!(!updated_enabled); run_to_block(2); @@ -1531,6 +1531,6 @@ fn test_sudo_toggle_evm_precompile() { )); let final_enabled = PrecompileEnable::::get(precompile_id); - assert_eq!(final_enabled, true); + assert!(final_enabled); }); } From 335f9b2af13723ae5fa26a2169c9f77e45ff6f6d Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 13 Jan 2025 14:47:56 +0800 Subject: [PATCH 3/9] update doc and weigths --- pallets/admin-utils/src/lib.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 09a4ce0c8f..01106daf96 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -1305,9 +1305,20 @@ pub mod pallet { T::Grandpa::schedule_change(next_authorities, in_blocks, forced) } - /// A public interface for `pallet_grandpa::Pallet::schedule_grandpa_change`. + /// Toggles the enablement of an EVM precompile. + /// + /// # Arguments + /// * `origin` - The origin of the call, which must be the root account. + /// * `precompile_id` - The identifier of the EVM precompile to toggle. + /// * `enabled` - The new enablement state of the precompile. + /// + /// # Errors + /// * `BadOrigin` - If the caller is not the root account. + /// + /// # Weight + /// Weight is handled by the `#[pallet::weight]` attribute. #[pallet::call_index(60)] - #[pallet::weight(Weight::from_parts(46_000_000, 0))] + #[pallet::weight((0, DispatchClass::Operational, Pays::No))] pub fn sudo_toggle_evm_precompile( origin: OriginFor, precompile_id: PrecompileEnum, From d03bea9dc8487c8e3a826ab42a2d909b8196091c Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 17 Jan 2025 23:22:06 +0800 Subject: [PATCH 4/9] remove subnets --- pallets/admin-utils/src/lib.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 01106daf96..4223067c4e 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -101,10 +101,8 @@ pub mod pallet { Subnet, /// Enum for metagraph precompile Metagraph, - /// Enum for subnets precompile - Subnets, - /// Enum for neurons precompile - Neurons, + /// Enum for neuron precompile + Neuron, } #[pallet::type_value] From eed6e18643b6d910da86d9be9302cbfea79dc9cb Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 12 Feb 2025 00:04:32 +0800 Subject: [PATCH 5/9] bump runtime version --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 26bf16206f..815beaeb44 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -229,7 +229,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: 233, + spec_version: 234, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 894a5185829e9b0ece8deac3a3353ecadc70ba1a Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Fri, 14 Feb 2025 12:51:34 -0500 Subject: [PATCH 6/9] provide an identity for github action to prevent failure --- .github/workflows/require-clean-merges.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/require-clean-merges.yml b/.github/workflows/require-clean-merges.yml index 532a411549..c00a4b47e2 100644 --- a/.github/workflows/require-clean-merges.yml +++ b/.github/workflows/require-clean-merges.yml @@ -46,6 +46,10 @@ jobs: git checkout $PR_BRANCH git reset --hard origin/$PR_BRANCH + # Configure a temporary Git identity to allow merging + git config --local user.email "github-actions@github.com" + git config --local user.name "GitHub Actions" + for branch in $MERGE_BRANCHES; do echo "Checking merge from $branch into $PR_BRANCH..." From 0485ab6bb92fe239d635228508f6a4a1265ef33c Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 14 Feb 2025 13:18:19 -0500 Subject: [PATCH 7/9] Add serve_axon extrinsic validation --- pallets/subtensor/src/lib.rs | 50 ++++++++++++++ pallets/subtensor/src/subnets/serving.rs | 86 ++++++++++++++++++------ pallets/subtensor/src/tests/serving.rs | 59 +++++++++++++++- 3 files changed, 173 insertions(+), 22 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 0ad75ea200..7242575ef8 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1674,6 +1674,10 @@ pub enum CustomTransactionError { InsufficientLiquidity, SlippageTooHigh, TransferDisallowed, + HotKeyNotRegisteredInNetwork, + InvalidIpAddress, + ServingRateLimitExceeded, + InvalidPort, BadRequest, } @@ -1690,6 +1694,10 @@ impl From for u8 { CustomTransactionError::InsufficientLiquidity => 7, CustomTransactionError::SlippageTooHigh => 8, CustomTransactionError::TransferDisallowed => 9, + CustomTransactionError::HotKeyNotRegisteredInNetwork => 10, + CustomTransactionError::InvalidIpAddress => 11, + CustomTransactionError::ServingRateLimitExceeded => 12, + CustomTransactionError::InvalidPort => 13, CustomTransactionError::BadRequest => 255, } } @@ -1773,6 +1781,22 @@ where CustomTransactionError::TransferDisallowed.into(), ) .into()), + Error::::HotKeyNotRegisteredInNetwork => Err(InvalidTransaction::Custom( + CustomTransactionError::HotKeyNotRegisteredInNetwork.into(), + ) + .into()), + Error::::InvalidIpAddress => Err(InvalidTransaction::Custom( + CustomTransactionError::InvalidIpAddress.into(), + ) + .into()), + Error::::ServingRateLimitExceeded => Err(InvalidTransaction::Custom( + CustomTransactionError::ServingRateLimitExceeded.into(), + ) + .into()), + Error::::InvalidPort => Err(InvalidTransaction::Custom( + CustomTransactionError::InvalidPort.into(), + ) + .into()), _ => Err( InvalidTransaction::Custom(CustomTransactionError::BadRequest.into()).into(), ), @@ -2175,6 +2199,32 @@ where }) } } + Some(Call::serve_axon { + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + }) => { + // Fully validate the user input + Self::result_to_validity( + Pallet::::validate_serve_axon( + who, + *netuid, + *version, + *ip, + *port, + *ip_type, + *protocol, + *placeholder1, + *placeholder2, + ), + Self::get_priority_vanilla(), + ) + } _ => { if let Some( BalancesCall::transfer_keep_alive { .. } diff --git a/pallets/subtensor/src/subnets/serving.rs b/pallets/subtensor/src/subnets/serving.rs index 647b328cce..de76d821f7 100644 --- a/pallets/subtensor/src/subnets/serving.rs +++ b/pallets/subtensor/src/subnets/serving.rs @@ -69,28 +69,20 @@ impl Pallet { // We check the callers (hotkey) signature. let hotkey_id = ensure_signed(origin)?; - // Ensure the hotkey is registered somewhere. - ensure!( - Self::is_hotkey_registered_on_any_network(&hotkey_id), - Error::::HotKeyNotRegisteredInNetwork - ); - - // Check the ip signature validity. - ensure!(Self::is_valid_ip_type(ip_type), Error::::InvalidIpType); - ensure!( - Self::is_valid_ip_address(ip_type, ip), - Error::::InvalidIpAddress - ); - - // Get the previous axon information. - let mut prev_axon = Self::get_axon_info(netuid, &hotkey_id); - let current_block: u64 = Self::get_current_block_as_u64(); - ensure!( - Self::axon_passes_rate_limit(netuid, &prev_axon, current_block), - Error::::ServingRateLimitExceeded - ); + // Validate user input + Self::validate_serve_axon( + &hotkey_id, + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + )?; - // Check certificate + // Check+insert certificate if let Some(certificate) = certificate { if let Ok(certificate) = NeuronCertificateOf::try_from(certificate) { NeuronCertificates::::insert(netuid, hotkey_id.clone(), certificate) @@ -98,6 +90,7 @@ impl Pallet { } // We insert the axon meta. + let mut prev_axon = Self::get_axon_info(netuid, &hotkey_id); prev_axon.block = Self::get_current_block_as_u64(); prev_axon.version = version; prev_axon.ip = ip; @@ -332,4 +325,55 @@ impl Pallet { Ok(true) } + + pub fn validate_serve_axon( + hotkey_id: &T::AccountId, + netuid: u16, + version: u32, + ip: u128, + port: u16, + ip_type: u8, + protocol: u8, + placeholder1: u8, + placeholder2: u8, + ) -> Result<(), Error> { + // Ensure the hotkey is registered somewhere. + ensure!( + Self::is_hotkey_registered_on_any_network(hotkey_id), + Error::::HotKeyNotRegisteredInNetwork + ); + + // Check the ip signature validity. + ensure!(Self::is_valid_ip_type(ip_type), Error::::InvalidIpType); + ensure!( + Self::is_valid_ip_address(ip_type, ip), + Error::::InvalidIpAddress + ); + + // Get the previous axon information. + let mut prev_axon = Self::get_axon_info(netuid, hotkey_id); + let current_block: u64 = Self::get_current_block_as_u64(); + ensure!( + Self::axon_passes_rate_limit(netuid, &prev_axon, current_block), + Error::::ServingRateLimitExceeded + ); + + // Validate axon data with delegate func + prev_axon.block = Self::get_current_block_as_u64(); + prev_axon.version = version; + prev_axon.ip = ip; + prev_axon.port = port; + prev_axon.ip_type = ip_type; + prev_axon.protocol = protocol; + prev_axon.placeholder1 = placeholder1; + prev_axon.placeholder2 = placeholder2; + + let axon_validated = Self::validate_axon_data(&prev_axon); + ensure!( + axon_validated.is_ok(), + axon_validated.err().unwrap_or(Error::::InvalidPort) + ); + + Ok(()) + } } diff --git a/pallets/subtensor/src/tests/serving.rs b/pallets/subtensor/src/tests/serving.rs index 52b8f8b08f..5d5858a313 100644 --- a/pallets/subtensor/src/tests/serving.rs +++ b/pallets/subtensor/src/tests/serving.rs @@ -2,8 +2,8 @@ use super::mock::*; use crate::Error; use crate::*; -use frame_support::assert_noop; use frame_support::pallet_prelude::Weight; +use frame_support::{assert_err, assert_noop}; use frame_support::{ assert_ok, dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}, @@ -1257,3 +1257,60 @@ fn test_set_subnet_identity_dispatch_info_ok() { assert_eq!(dispatch_info.pays_fee, Pays::Yes); }); } + +// cargo test --package pallet-subtensor --lib -- tests::serving::test_serve_axon_validate --exact --show-output +#[test] +fn test_serve_axon_validate() { + // Testing the signed extension validate function + // correctly filters the `serve_axon` transaction. + + new_test_ext(0).execute_with(|| { + let hotkey = U256::from(1); + let netuid: u16 = 1; + let version: u32 = 2; + let ip: u128 = 1676056785; + let port: u16 = 128; + let ip_type: u8 = 4; + let protocol: u8 = 0; + let placeholder1: u8 = 0; + let placeholder2: u8 = 0; + + // Serve axon bad call + let call = RuntimeCall::SubtensorModule(SubtensorCall::serve_axon { + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + }); + + let info: crate::DispatchInfo = + crate::DispatchInfoOf::<::RuntimeCall>::default(); + + let extension = crate::SubtensorSignedExtension::::new(); + // Submit to the signed extension validate function + let result_bad = extension.validate(&hotkey, &call.clone(), &info, 10); + + // Should fail due to insufficient stake + assert_err!( + result_bad, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::HotKeyNotRegisteredInNetwork.into() + )) + ); + + // Register the hotkey in the subnet and try again + let coldkey = U256::from(1); + add_network(netuid, 13, 0); + register_ok_neuron(netuid, hotkey, coldkey, 0); + + // Submit to the signed extension validate function + let result_ok = extension.validate(&hotkey, &call.clone(), &info, 10); + + // Now the call passes + assert_ok!(result_ok); + }); +} From 1238e0385a47014b34b59c659021d3e5f881e68a Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 14 Feb 2025 13:29:55 -0500 Subject: [PATCH 8/9] Bump spec version --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index f0c0715132..28f4fabc54 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -229,7 +229,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: 235, + spec_version: 236, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From f111118990b0b21b7375b56564da7f066a138290 Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Fri, 14 Feb 2025 14:16:05 -0500 Subject: [PATCH 9/9] Check IP validity in serve_axon validation first --- pallets/subtensor/src/subnets/serving.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pallets/subtensor/src/subnets/serving.rs b/pallets/subtensor/src/subnets/serving.rs index de76d821f7..c8c89bc011 100644 --- a/pallets/subtensor/src/subnets/serving.rs +++ b/pallets/subtensor/src/subnets/serving.rs @@ -169,12 +169,6 @@ impl Pallet { // We check the callers (hotkey) signature. let hotkey_id = ensure_signed(origin)?; - // Ensure the hotkey is registered somewhere. - ensure!( - Self::is_hotkey_registered_on_any_network(&hotkey_id), - Error::::HotKeyNotRegisteredInNetwork - ); - // Check the ip signature validity. ensure!(Self::is_valid_ip_type(ip_type), Error::::InvalidIpType); ensure!( @@ -182,6 +176,12 @@ impl Pallet { Error::::InvalidIpAddress ); + // Ensure the hotkey is registered somewhere. + ensure!( + Self::is_hotkey_registered_on_any_network(&hotkey_id), + Error::::HotKeyNotRegisteredInNetwork + ); + // We get the previous axon info assoicated with this ( netuid, uid ) let mut prev_prometheus = Self::get_prometheus_info(netuid, &hotkey_id); let current_block: u64 = Self::get_current_block_as_u64();