From 46062d9a69700b607371aa0f1a85251d3de11f6c Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 11 Dec 2024 23:21:36 +0800 Subject: [PATCH 01/39] get and set all hyperparameters --- runtime/src/precompiles/solidity/subnet.abi | 80 ++-- runtime/src/precompiles/solidity/subnet.sol | 4 +- runtime/src/precompiles/subnet.rs | 421 +++++++++++++++++++- 3 files changed, 472 insertions(+), 33 deletions(-) diff --git a/runtime/src/precompiles/solidity/subnet.abi b/runtime/src/precompiles/solidity/subnet.abi index a89cf91f15..d926f23c99 100644 --- a/runtime/src/precompiles/solidity/subnet.abi +++ b/runtime/src/precompiles/solidity/subnet.abi @@ -1,32 +1,50 @@ [ - { - "inputs": [ - { - "internalType": "bytes", - "name": "subnetName", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "githubRepo", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "subnetContact", - "type": "bytes" - } - ], - "name": "registerNetwork", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "registerNetwork", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } -] \ No newline at end of file + { + "inputs": [ + { + "internalType": "bytes", + "name": "subnetName", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "githubRepo", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "subnetContact", + "type": "bytes" + } + ], + "name": "registerNetwork", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "registerNetwork", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "neruid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "servingRateLimit", + "type": "uint64" + } + ], + "name": "setServingRateLimit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } + ] \ No newline at end of file diff --git a/runtime/src/precompiles/solidity/subnet.sol b/runtime/src/precompiles/solidity/subnet.sol index e2857ad63d..fc0c3ab075 100644 --- a/runtime/src/precompiles/solidity/subnet.sol +++ b/runtime/src/precompiles/solidity/subnet.sol @@ -6,5 +6,7 @@ interface ISubnet { /// Registers a new network without specifying details. function registerNetwork() external payable; /// Registers a new network with specified subnet name, GitHub repository, and contact information. - function registerNetwork(bytes subnetName, bytes githubRepo, bytes subnetContact) external payable; + function registerNetwork(bytes memory subnetName, bytes memory githubRepo, bytes memory subnetContact) external payable; + + function setServingRateLimit(uint16 neruid, uint64 servingRateLimit) external payable; } \ No newline at end of file diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index 9230a01e9c..dc74b0a4a4 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -33,6 +33,72 @@ impl SubnetPrecompile { id if id == get_method_id("registerNetwork()") => { Self::register_network(handle, &[0_u8; 0]) } + id if id == get_method_id("setServingRateLimit(uint16,uint64)") => { + Self::set_serving_rate_limit(handle, &method_input) + } + id if id == get_method_id("setMinDifficulty(uint16,uint64)") => { + Self::set_min_difficulty(handle, &method_input) + } + id if id == get_method_id("setMaxDifficulty(uint16,uint64)") => { + Self::set_max_difficulty(handle, &method_input) + } + id if id == get_method_id("setWeightsVersionKey(uint16,uint64)") => { + Self::set_weights_version_key(handle, &method_input) + } + id if id == get_method_id("setWeightsSetRateLimit(uint16,uint64)") => { + Self::set_weights_set_rate_limit(handle, &method_input) + } + id if id == get_method_id("setServingRateLimit(uint16,uint64)") => { + Self::set_adjustment_alpha(handle, &method_input) + } + id if id == get_method_id("setServingRateLimit(uint16,uint64)") => { + Self::set_max_weight_limit(handle, &method_input) + } + id if id == get_method_id("setServingRateLimit(uint16,uint64)") => { + Self::set_immunity_period(handle, &method_input) + } + id if id == get_method_id("setMinAllowedWeights(uint16,uint16)") => { + Self::set_min_allowed_weights(handle, &method_input) + } + id if id == get_method_id("setKappa(uint16,uint16)") => { + Self::set_kappa(handle, &method_input) + } + id if id == get_method_id("setRho(uint16,uint16)") => { + Self::set_rho(handle, &method_input) + } + id if id == get_method_id("setActivityCutoff(uint16,uint16)") => { + Self::set_activity_cutoff(handle, &method_input) + } + id if id == get_method_id("set_NetworkRegistrationAllowed(uint16,bool)") => { + Self::set_network_registration_allowed(handle, &method_input) + } + id if id == get_method_id("setNetworkPowRegistrationAllowed(uint16,bool)") => { + Self::set_network_pow_registration_allowed(handle, &method_input) + } + id if id == get_method_id("setMinBurn(uint16,uint64)") => { + Self::set_min_burn(handle, &method_input) + } + id if id == get_method_id("setMaxBurn(uint16,uint64)") => { + Self::set_max_burn(handle, &method_input) + } + id if id == get_method_id("setDifficulty(uint16,uint64)") => { + Self::set_difficulty(handle, &method_input) + } + id if id == get_method_id("setBondsMovingAverage(uint16,uint64)") => { + Self::set_bonds_moving_average(handle, &method_input) + } + id if id == get_method_id("setCommitRevealWeightsEnabled(uint16,bool)") => { + Self::set_commit_reveal_weights_enabled(handle, &method_input) + } + id if id == get_method_id("setLiquidAlphaEnabled(uint16,bool)") => { + Self::set_liquid_alpha_enabled(handle, &method_input) + } + id if id == get_method_id("setAlphaValues(uint16,uint16,uint16)") => { + Self::set_alpha_values(handle, &method_input) + } + id if id == get_method_id("setCommitRevealWeightsInterval(uint16,uint64)") => { + Self::set_commit_reveal_weights_interval(handle, &method_input) + } _ => Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, }), @@ -64,7 +130,287 @@ impl SubnetPrecompile { ) }; - // Dispatch the register_network call + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_serving_rate_limit(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, serving_rate_limit) = Self::parse_netuid_u64_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_serving_rate_limit { + netuid, + serving_rate_limit, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_min_difficulty(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, min_difficulty) = Self::parse_netuid_u64_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_min_difficulty { + netuid, + min_difficulty, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_max_difficulty(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, max_difficulty) = Self::parse_netuid_u64_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_max_difficulty { + netuid, + max_difficulty, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_weights_version_key( + handle: &mut impl PrecompileHandle, + data: &[u8], + ) -> PrecompileResult { + let (netuid, weights_version_key) = Self::parse_netuid_u64_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_weights_version_key { + netuid, + weights_version_key, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_weights_set_rate_limit( + handle: &mut impl PrecompileHandle, + data: &[u8], + ) -> PrecompileResult { + let (netuid, weights_set_rate_limit) = Self::parse_netuid_u64_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_weights_set_rate_limit { + netuid, + weights_set_rate_limit, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_adjustment_alpha(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, adjustment_alpha) = Self::parse_netuid_u64_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_adjustment_alpha { + netuid, + adjustment_alpha, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_max_weight_limit(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, max_weight_limit) = Self::parse_netuid_u16_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_max_weight_limit { + netuid, + max_weight_limit, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_immunity_period(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, immunity_period) = Self::parse_netuid_u16_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_immunity_period { + netuid, + immunity_period, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_min_allowed_weights( + handle: &mut impl PrecompileHandle, + data: &[u8], + ) -> PrecompileResult { + let (netuid, min_allowed_weights) = Self::parse_netuid_u16_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_min_allowed_weights { + netuid, + min_allowed_weights, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_kappa(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, kappa) = Self::parse_netuid_u16_parameter(data)?; + let call = RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_kappa { + netuid, + kappa, + }); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_rho(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, rho) = Self::parse_netuid_u16_parameter(data)?; + let call = RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_rho { + netuid, + rho, + }); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_activity_cutoff(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, activity_cutoff) = Self::parse_netuid_u16_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_activity_cutoff { + netuid, + activity_cutoff, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_network_registration_allowed( + handle: &mut impl PrecompileHandle, + data: &[u8], + ) -> PrecompileResult { + let (netuid, registration_allowed) = Self::parse_netuid_bool_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_network_registration_allowed { + netuid, + registration_allowed, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_network_pow_registration_allowed( + handle: &mut impl PrecompileHandle, + data: &[u8], + ) -> PrecompileResult { + let (netuid, registration_allowed) = Self::parse_netuid_bool_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_network_pow_registration_allowed { + netuid, + registration_allowed, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_min_burn(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, min_burn) = Self::parse_netuid_u64_parameter(data)?; + let call = + RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_min_burn { + netuid, + min_burn, + }); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_max_burn(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, max_burn) = Self::parse_netuid_u64_parameter(data)?; + let call = + RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_max_burn { + netuid, + max_burn, + }); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_difficulty(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, difficulty) = Self::parse_netuid_u64_parameter(data)?; + let call = + RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_difficulty { + netuid, + difficulty, + }); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_bonds_moving_average( + handle: &mut impl PrecompileHandle, + data: &[u8], + ) -> PrecompileResult { + let (netuid, bonds_moving_average) = Self::parse_netuid_u64_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_bonds_moving_average { + netuid, + bonds_moving_average, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_commit_reveal_weights_enabled( + handle: &mut impl PrecompileHandle, + data: &[u8], + ) -> PrecompileResult { + let (netuid, enabled) = Self::parse_netuid_bool_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_commit_reveal_weights_enabled { + netuid, + enabled, + }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_liquid_alpha_enabled( + handle: &mut impl PrecompileHandle, + data: &[u8], + ) -> PrecompileResult { + let (netuid, enabled) = Self::parse_netuid_bool_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_liquid_alpha_enabled { netuid, enabled }, + ); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_alpha_values(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, alpha_low, alpha_high) = Self::parse_netuid_u16_u16_parameter(data)?; + let call = + RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_alpha_values { + netuid, + alpha_low, + alpha_high, + }); + + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + } + + fn set_commit_reveal_weights_interval( + handle: &mut impl PrecompileHandle, + data: &[u8], + ) -> PrecompileResult { + let (netuid, interval) = Self::parse_netuid_u64_parameter(data)?; + let call = RuntimeCall::AdminUtils( + pallet_admin_utils::Call::::sudo_set_commit_reveal_weights_interval { + netuid, + interval, + }, + ); + dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } @@ -130,4 +476,77 @@ impl SubnetPrecompile { Ok((name_vec, repo_vec, contact_vec)) } + + fn parse_netuid_u64_parameter(data: &[u8]) -> Result<(u16, u64), PrecompileFailure> { + if data.len() < 64 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut parameter_vec = [0u8; 8]; + parameter_vec.copy_from_slice(get_slice(data, 56, 64)?); + let parameter = u64::from_be_bytes(parameter_vec); + + Ok((netuid, parameter)) + } + + fn parse_netuid_u16_parameter(data: &[u8]) -> Result<(u16, u16), PrecompileFailure> { + if data.len() < 64 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut parameter_vec = [0u8; 2]; + parameter_vec.copy_from_slice(get_slice(data, 62, 64)?); + let parameter = u16::from_be_bytes(parameter_vec); + + Ok((netuid, parameter)) + } + + fn parse_netuid_u16_u16_parameter(data: &[u8]) -> Result<(u16, u16, u16), PrecompileFailure> { + if data.len() < 64 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut parameter_1_vec = [0u8; 2]; + parameter_1_vec.copy_from_slice(get_slice(data, 62, 64)?); + let parameter_1 = u16::from_be_bytes(parameter_1_vec); + + let mut parameter_2_vec = [0u8; 2]; + parameter_2_vec.copy_from_slice(get_slice(data, 94, 96)?); + let parameter_2 = u16::from_be_bytes(parameter_2_vec); + + Ok((netuid, parameter_1, parameter_2)) + } + + fn parse_netuid_bool_parameter(data: &[u8]) -> Result<(u16, bool), PrecompileFailure> { + if data.len() < 64 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut parameter_vec = [0_u8]; + parameter_vec.copy_from_slice(get_slice(data, 63, 64)?); + + let parameter = parameter_vec[0] != 0; + + Ok((netuid, parameter)) + } } From 2810551ee40f58a1ade930dba9b02ebb5ef97c85 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 12 Dec 2024 18:37:30 +0800 Subject: [PATCH 02/39] all get methods --- runtime/src/precompiles/solidity/subnet.abi | 906 ++++++++++++++++++-- runtime/src/precompiles/solidity/subnet.sol | 88 +- runtime/src/precompiles/subnet.rs | 92 +- 3 files changed, 1032 insertions(+), 54 deletions(-) diff --git a/runtime/src/precompiles/solidity/subnet.abi b/runtime/src/precompiles/solidity/subnet.abi index d926f23c99..1c80c7407d 100644 --- a/runtime/src/precompiles/solidity/subnet.abi +++ b/runtime/src/precompiles/solidity/subnet.abi @@ -1,50 +1,858 @@ [ - { - "inputs": [ - { - "internalType": "bytes", - "name": "subnetName", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "githubRepo", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "subnetContact", - "type": "bytes" - } - ], - "name": "registerNetwork", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [], - "name": "registerNetwork", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "neruid", - "type": "uint16" - }, - { - "internalType": "uint64", - "name": "servingRateLimit", - "type": "uint64" - } - ], - "name": "setServingRateLimit", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } - ] \ No newline at end of file + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getAdjustmentAlpha", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getAlphaValues", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getBondsMovingAverage", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getCommitRevealWeightsEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getDifficulty", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "getImmunityPeriod", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "getKappa", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getMaxBurn", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getMaxDifficulty", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getMaxWeightLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getMinAllowedWeights", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getMinBurn", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getMinDifficulty", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getNetworkRegistrationAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "name": "getRho", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getServingRateLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getWeightsSetRateLimit", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getWeightsVersionKey", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "subnetName", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "githubRepo", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "subnetContact", + "type": "bytes" + } + ], + "name": "registerNetwork", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "registerNetwork", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "activityCutoff", + "type": "uint16" + } + ], + "name": "setActivityCutoff", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "setActivityCutoff", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "adjustmentAlpha", + "type": "uint64" + } + ], + "name": "setAdjustmentAlpha", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "alphaLow", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "alphaHigh", + "type": "uint16" + } + ], + "name": "setAlphaValues", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "bondsMovingAverage", + "type": "uint64" + } + ], + "name": "setBondsMovingAverage", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "commitRevealWeightsEnabled", + "type": "bool" + } + ], + "name": "setCommitRevealWeightsEnabled", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "setCommitRevealWeightsInterval", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "commitRevealWeightsInterval", + "type": "uint64" + } + ], + "name": "setCommitRevealWeightsInterval", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "difficulty", + "type": "uint64" + } + ], + "name": "setDifficulty", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "immunityPeriod", + "type": "uint64" + } + ], + "name": "setImmunityPeriod", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "kappa", + "type": "uint16" + } + ], + "name": "setKappa", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "setLiquidAlphaEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "liquidAlphaEnabled", + "type": "bool" + } + ], + "name": "setLiquidAlphaEnabled", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "maxBurn", + "type": "uint64" + } + ], + "name": "setMaxBurn", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "maxDifficulty", + "type": "uint64" + } + ], + "name": "setMaxDifficulty", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "maxWeightLimit", + "type": "uint64" + } + ], + "name": "setMaxWeightLimit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "minAllowedWeights", + "type": "uint16" + } + ], + "name": "setMinAllowedWeights", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "minBurn", + "type": "uint64" + } + ], + "name": "setMinBurn", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "minDifficulty", + "type": "uint64" + } + ], + "name": "setMinDifficulty", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "setNetworkPowRegistrationAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "networkPowRegistrationAllowed", + "type": "bool" + } + ], + "name": "setNetworkPowRegistrationAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "bool", + "name": "networkRegistrationAllowed", + "type": "bool" + } + ], + "name": "setNetworkRegistrationAllowed", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint16", + "name": "rho", + "type": "uint16" + } + ], + "name": "setRho", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "servingRateLimit", + "type": "uint64" + } + ], + "name": "setServingRateLimit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "weightsSetRateLimit", + "type": "uint64" + } + ], + "name": "setWeightsSetRateLimit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint64", + "name": "weightsVersionKey", + "type": "uint64" + } + ], + "name": "setWeightsVersionKey", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } +] + + \ No newline at end of file diff --git a/runtime/src/precompiles/solidity/subnet.sol b/runtime/src/precompiles/solidity/subnet.sol index fc0c3ab075..99dac763e2 100644 --- a/runtime/src/precompiles/solidity/subnet.sol +++ b/runtime/src/precompiles/solidity/subnet.sol @@ -8,5 +8,91 @@ interface ISubnet { /// Registers a new network with specified subnet name, GitHub repository, and contact information. function registerNetwork(bytes memory subnetName, bytes memory githubRepo, bytes memory subnetContact) external payable; - function setServingRateLimit(uint16 neruid, uint64 servingRateLimit) external payable; + function getServingRateLimit(uint16 netuid) external view returns (uint64); + + function setServingRateLimit(uint16 netuid, uint64 servingRateLimit) external payable; + + function getMinDifficulty(uint16 netuid) external view returns (uint64); + + function setMinDifficulty(uint16 netuid, uint64 minDifficulty) external payable; + + function getMaxDifficulty(uint16 netuid) external view returns (uint64); + + function setMaxDifficulty(uint16 netuid,uint64 maxDifficulty) external payable; + + function getWeightsVersionKey(uint16 netuid) external view returns (uint64); + + function setWeightsVersionKey(uint16 netuid, uint64 weightsVersionKey) external payable; + + function getWeightsSetRateLimit(uint16 netuid) external view returns (uint64); + + function setWeightsSetRateLimit(uint16 netuid, uint64 weightsSetRateLimit) external payable; + + function getAdjustmentAlpha(uint16 netuid) external view returns (uint64); + + function setAdjustmentAlpha(uint16 netuid, uint64 adjustmentAlpha) external payable; + + function getMaxWeightLimit(uint16 netuid) external view returns (uint64); + + function setMaxWeightLimit(uint16 netuid, uint64 maxWeightLimit) external payable; + + function getImmunityPeriod(uint16) external view returns (uint64); + + function setImmunityPeriod(uint16 netuid, uint64 immunityPeriod) external payable; + + function getMinAllowedWeights(uint16 netuid)external view returns (uint16); + + function setMinAllowedWeights(uint16 netuid, uint16 minAllowedWeights) external payable; + + function getKappa(uint16) external view returns (uint16); + + function setKappa(uint16 netuid, uint16 kappa) external payable; + + function getRho(uint16) external view returns (uint16); + + function setRho(uint16 netuid, uint16 rho) external payable; + + function setActivityCutoff(uint16 netuid) external view returns (uint16); + + function setActivityCutoff(uint16 netuid, uint16 activityCutoff) external payable; + + function getNetworkRegistrationAllowed(uint16 netuid) external view returns (bool); + + function setNetworkRegistrationAllowed(uint16 netuid, bool networkRegistrationAllowed) external payable; + + function setNetworkPowRegistrationAllowed(uint16 netuid) external view returns (bool); + + function setNetworkPowRegistrationAllowed(uint16 netuid, bool networkPowRegistrationAllowed) external payable; + + function getMinBurn(uint16 netuid) external view returns (uint64); + + function setMinBurn(uint16 netuid, uint64 minBurn) external payable; + + function getMaxBurn(uint16 netuid) external view returns (uint64); + + function setMaxBurn(uint16 netuid, uint64 maxBurn) external payable; + + function getDifficulty(uint16 netuid) external view returns (uint64); + + function setDifficulty(uint16 netuid, uint64 difficulty) external payable; + + function getBondsMovingAverage(uint16 netuid) external view returns (uint64); + + function setBondsMovingAverage(uint16 netuid, uint64 bondsMovingAverage) external payable; + + function getCommitRevealWeightsEnabled(uint16 netuid) external view returns (bool); + + function setCommitRevealWeightsEnabled(uint16 netuid, bool commitRevealWeightsEnabled) external payable; + + function setLiquidAlphaEnabled(uint16 netuid) external view returns (bool); + + function setLiquidAlphaEnabled(uint16 netuid, bool liquidAlphaEnabled) external payable; + + function getAlphaValues(uint16 netuid) external view returns (uint16, uint16); + + function setAlphaValues(uint16 netuid, uint16 alphaLow, uint16 alphaHigh) external payable; + + function setCommitRevealWeightsInterval(uint16 netuid) external view returns (uint64); + + function setCommitRevealWeightsInterval(uint16 netuid, uint64 commitRevealWeightsInterval) external payable; } \ No newline at end of file diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index dc74b0a4a4..956efbd5ca 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -33,69 +33,153 @@ impl SubnetPrecompile { id if id == get_method_id("registerNetwork()") => { Self::register_network(handle, &[0_u8; 0]) } + + id if id == get_method_id("getServingRateLimit(uint16)") => { + Self::get_serving_rate_limit(handle, &method_input) + } id if id == get_method_id("setServingRateLimit(uint16,uint64)") => { Self::set_serving_rate_limit(handle, &method_input) } + + id if id == get_method_id("getMinDifficulty(uint16)") => { + Self::get_min_difficulty(handle, &method_input) + } id if id == get_method_id("setMinDifficulty(uint16,uint64)") => { Self::set_min_difficulty(handle, &method_input) } + + id if id == get_method_id("getMaxDifficulty(uint16)") => { + Self::get_max_difficulty(handle, &method_input) + } id if id == get_method_id("setMaxDifficulty(uint16,uint64)") => { Self::set_max_difficulty(handle, &method_input) } + + id if id == get_method_id("getWeightsVersionKey(uint16)") => { + Self::get_weights_version_key(handle, &method_input) + } id if id == get_method_id("setWeightsVersionKey(uint16,uint64)") => { Self::set_weights_version_key(handle, &method_input) } + + id if id == get_method_id("getWeightsSetRateLimit(uint16,uint64)") => { + Self::get_weights_set_rate_limit(handle, &method_input) + } id if id == get_method_id("setWeightsSetRateLimit(uint16,uint64)") => { Self::set_weights_set_rate_limit(handle, &method_input) } - id if id == get_method_id("setServingRateLimit(uint16,uint64)") => { + + id if id == get_method_id("getAdjustmentAlpha(uint16)") => { + Self::get_adjustment_alpha(handle, &method_input) + } + id if id == get_method_id("setAdjustmentAlpha(uint16,uint64)") => { Self::set_adjustment_alpha(handle, &method_input) } - id if id == get_method_id("setServingRateLimit(uint16,uint64)") => { + + id if id == get_method_id("getMaxWeightLimit(uint16)") => { + Self::get_max_weight_limit(handle, &method_input) + } + id if id == get_method_id("setMaxWeightLimit(uint16,uint64)") => { Self::set_max_weight_limit(handle, &method_input) } - id if id == get_method_id("setServingRateLimit(uint16,uint64)") => { + + id if id == get_method_id("getImmunityPeriod(uint16)") => { + Self::get_immunity_period(handle, &method_input) + } + id if id == get_method_id("setImmunityPeriod(uint16,uint64)") => { Self::set_immunity_period(handle, &method_input) } + + id if id == get_method_id("getMinAllowedWeights(uint16)") => { + Self::get_min_allowed_weights(handle, &method_input) + } id if id == get_method_id("setMinAllowedWeights(uint16,uint16)") => { Self::set_min_allowed_weights(handle, &method_input) } + + id if id == get_method_id("getKappa(uint16)") => Self::get_kappa(handle, &method_input), id if id == get_method_id("setKappa(uint16,uint16)") => { Self::set_kappa(handle, &method_input) } + + id if id == get_method_id("getRho(uint16)") => Self::get_rho(handle, &method_input), id if id == get_method_id("setRho(uint16,uint16)") => { Self::set_rho(handle, &method_input) } + + id if id == get_method_id("getActivityCutoff(uint16)") => { + Self::get_activity_cutoff(handle, &method_input) + } id if id == get_method_id("setActivityCutoff(uint16,uint16)") => { Self::set_activity_cutoff(handle, &method_input) } - id if id == get_method_id("set_NetworkRegistrationAllowed(uint16,bool)") => { + + id if id == get_method_id("getNetworkRegistrationAllowed(uint16)") => { + Self::get_network_registration_allowed(handle, &method_input) + } + id if id == get_method_id("setNetworkRegistrationAllowed(uint16,bool)") => { Self::set_network_registration_allowed(handle, &method_input) } + + id if id == get_method_id("getNetworkPowRegistrationAllowed(uint16)") => { + Self::get_network_pow_registration_allowed(handle, &method_input) + } id if id == get_method_id("setNetworkPowRegistrationAllowed(uint16,bool)") => { Self::set_network_pow_registration_allowed(handle, &method_input) } + + id if id == get_method_id("getMinBurn(uint16)") => { + Self::get_min_burn(handle, &method_input) + } id if id == get_method_id("setMinBurn(uint16,uint64)") => { Self::set_min_burn(handle, &method_input) } + + id if id == get_method_id("getMaxBurn(uint16)") => { + Self::get_max_burn(handle, &method_input) + } id if id == get_method_id("setMaxBurn(uint16,uint64)") => { Self::set_max_burn(handle, &method_input) } + + id if id == get_method_id("getDifficulty(uint16)") => { + Self::get_difficulty(handle, &method_input) + } id if id == get_method_id("setDifficulty(uint16,uint64)") => { Self::set_difficulty(handle, &method_input) } + + id if id == get_method_id("getBondsMovingAverage(uint16)") => { + Self::get_bonds_moving_average(handle, &method_input) + } id if id == get_method_id("setBondsMovingAverage(uint16,uint64)") => { Self::set_bonds_moving_average(handle, &method_input) } + + id if id == get_method_id("getCommitRevealWeightsEnabled(uint16)") => { + Self::get_commit_reveal_weights_enabled(handle, &method_input) + } id if id == get_method_id("setCommitRevealWeightsEnabled(uint16,bool)") => { Self::set_commit_reveal_weights_enabled(handle, &method_input) } + + id if id == get_method_id("getLiquidAlphaEnabled(uint16)") => { + Self::get_liquid_alpha_enabled(handle, &method_input) + } id if id == get_method_id("setLiquidAlphaEnabled(uint16,bool)") => { Self::set_liquid_alpha_enabled(handle, &method_input) } + + id if id == get_method_id("getAlphaValues(uint16)") => { + Self::get_alpha_values(handle, &method_input) + } id if id == get_method_id("setAlphaValues(uint16,uint16,uint16)") => { Self::set_alpha_values(handle, &method_input) } + + id if id == get_method_id("getCommitRevealWeightsInterval(uint16)") => { + Self::get_commit_reveal_weights_interval(handle, &method_input) + } id if id == get_method_id("setCommitRevealWeightsInterval(uint16,uint64)") => { Self::set_commit_reveal_weights_interval(handle, &method_input) } From 3913fba79de84c42a8b56e61523ae6abfc06f5cf Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 12 Dec 2024 19:19:31 +0800 Subject: [PATCH 03/39] all get set done --- runtime/src/precompiles/subnet.rs | 399 ++++++++++++++++++++++++++++-- 1 file changed, 372 insertions(+), 27 deletions(-) diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index 956efbd5ca..4b3a943a4d 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -1,6 +1,9 @@ use crate::precompiles::{dispatch, get_method_id, get_slice}; use crate::{Runtime, RuntimeCall}; -use pallet_evm::{ExitError, PrecompileFailure, PrecompileHandle, PrecompileResult}; +use pallet_evm::{ + ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, +}; +use sp_core::U256; use sp_std::vec; pub const SUBNET_PRECOMPILE_INDEX: u64 = 2051; @@ -35,150 +38,146 @@ impl SubnetPrecompile { } id if id == get_method_id("getServingRateLimit(uint16)") => { - Self::get_serving_rate_limit(handle, &method_input) + Self::get_serving_rate_limit(&method_input) } id if id == get_method_id("setServingRateLimit(uint16,uint64)") => { Self::set_serving_rate_limit(handle, &method_input) } id if id == get_method_id("getMinDifficulty(uint16)") => { - Self::get_min_difficulty(handle, &method_input) + Self::get_min_difficulty(&method_input) } id if id == get_method_id("setMinDifficulty(uint16,uint64)") => { Self::set_min_difficulty(handle, &method_input) } id if id == get_method_id("getMaxDifficulty(uint16)") => { - Self::get_max_difficulty(handle, &method_input) + Self::get_max_difficulty(&method_input) } id if id == get_method_id("setMaxDifficulty(uint16,uint64)") => { Self::set_max_difficulty(handle, &method_input) } id if id == get_method_id("getWeightsVersionKey(uint16)") => { - Self::get_weights_version_key(handle, &method_input) + Self::get_weights_version_key(&method_input) } id if id == get_method_id("setWeightsVersionKey(uint16,uint64)") => { Self::set_weights_version_key(handle, &method_input) } id if id == get_method_id("getWeightsSetRateLimit(uint16,uint64)") => { - Self::get_weights_set_rate_limit(handle, &method_input) + Self::get_weights_set_rate_limit(&method_input) } id if id == get_method_id("setWeightsSetRateLimit(uint16,uint64)") => { Self::set_weights_set_rate_limit(handle, &method_input) } id if id == get_method_id("getAdjustmentAlpha(uint16)") => { - Self::get_adjustment_alpha(handle, &method_input) + Self::get_adjustment_alpha(&method_input) } id if id == get_method_id("setAdjustmentAlpha(uint16,uint64)") => { Self::set_adjustment_alpha(handle, &method_input) } id if id == get_method_id("getMaxWeightLimit(uint16)") => { - Self::get_max_weight_limit(handle, &method_input) + Self::get_max_weight_limit(&method_input) } id if id == get_method_id("setMaxWeightLimit(uint16,uint64)") => { Self::set_max_weight_limit(handle, &method_input) } id if id == get_method_id("getImmunityPeriod(uint16)") => { - Self::get_immunity_period(handle, &method_input) + Self::get_immunity_period(&method_input) } id if id == get_method_id("setImmunityPeriod(uint16,uint64)") => { Self::set_immunity_period(handle, &method_input) } id if id == get_method_id("getMinAllowedWeights(uint16)") => { - Self::get_min_allowed_weights(handle, &method_input) + Self::get_min_allowed_weights(&method_input) } id if id == get_method_id("setMinAllowedWeights(uint16,uint16)") => { Self::set_min_allowed_weights(handle, &method_input) } - id if id == get_method_id("getKappa(uint16)") => Self::get_kappa(handle, &method_input), + id if id == get_method_id("getKappa(uint16)") => Self::get_kappa(&method_input), id if id == get_method_id("setKappa(uint16,uint16)") => { Self::set_kappa(handle, &method_input) } - id if id == get_method_id("getRho(uint16)") => Self::get_rho(handle, &method_input), + id if id == get_method_id("getRho(uint16)") => Self::get_rho(&method_input), id if id == get_method_id("setRho(uint16,uint16)") => { Self::set_rho(handle, &method_input) } id if id == get_method_id("getActivityCutoff(uint16)") => { - Self::get_activity_cutoff(handle, &method_input) + Self::get_activity_cutoff(&method_input) } id if id == get_method_id("setActivityCutoff(uint16,uint16)") => { Self::set_activity_cutoff(handle, &method_input) } id if id == get_method_id("getNetworkRegistrationAllowed(uint16)") => { - Self::get_network_registration_allowed(handle, &method_input) + Self::get_network_registration_allowed(&method_input) } id if id == get_method_id("setNetworkRegistrationAllowed(uint16,bool)") => { Self::set_network_registration_allowed(handle, &method_input) } id if id == get_method_id("getNetworkPowRegistrationAllowed(uint16)") => { - Self::get_network_pow_registration_allowed(handle, &method_input) + Self::get_network_pow_registration_allowed(&method_input) } id if id == get_method_id("setNetworkPowRegistrationAllowed(uint16,bool)") => { Self::set_network_pow_registration_allowed(handle, &method_input) } - id if id == get_method_id("getMinBurn(uint16)") => { - Self::get_min_burn(handle, &method_input) - } + id if id == get_method_id("getMinBurn(uint16)") => Self::get_min_burn(&method_input), id if id == get_method_id("setMinBurn(uint16,uint64)") => { Self::set_min_burn(handle, &method_input) } - id if id == get_method_id("getMaxBurn(uint16)") => { - Self::get_max_burn(handle, &method_input) - } + id if id == get_method_id("getMaxBurn(uint16)") => Self::get_max_burn(&method_input), id if id == get_method_id("setMaxBurn(uint16,uint64)") => { Self::set_max_burn(handle, &method_input) } id if id == get_method_id("getDifficulty(uint16)") => { - Self::get_difficulty(handle, &method_input) + Self::get_difficulty(&method_input) } id if id == get_method_id("setDifficulty(uint16,uint64)") => { Self::set_difficulty(handle, &method_input) } id if id == get_method_id("getBondsMovingAverage(uint16)") => { - Self::get_bonds_moving_average(handle, &method_input) + Self::get_bonds_moving_average(&method_input) } id if id == get_method_id("setBondsMovingAverage(uint16,uint64)") => { Self::set_bonds_moving_average(handle, &method_input) } id if id == get_method_id("getCommitRevealWeightsEnabled(uint16)") => { - Self::get_commit_reveal_weights_enabled(handle, &method_input) + Self::get_commit_reveal_weights_enabled(&method_input) } id if id == get_method_id("setCommitRevealWeightsEnabled(uint16,bool)") => { Self::set_commit_reveal_weights_enabled(handle, &method_input) } id if id == get_method_id("getLiquidAlphaEnabled(uint16)") => { - Self::get_liquid_alpha_enabled(handle, &method_input) + Self::get_liquid_alpha_enabled(&method_input) } id if id == get_method_id("setLiquidAlphaEnabled(uint16,bool)") => { Self::set_liquid_alpha_enabled(handle, &method_input) } id if id == get_method_id("getAlphaValues(uint16)") => { - Self::get_alpha_values(handle, &method_input) + Self::get_alpha_values(&method_input) } id if id == get_method_id("setAlphaValues(uint16,uint16,uint16)") => { Self::set_alpha_values(handle, &method_input) } id if id == get_method_id("getCommitRevealWeightsInterval(uint16)") => { - Self::get_commit_reveal_weights_interval(handle, &method_input) + Self::get_commit_reveal_weights_interval(&method_input) } id if id == get_method_id("setCommitRevealWeightsInterval(uint16,uint64)") => { Self::set_commit_reveal_weights_interval(handle, &method_input) @@ -217,6 +216,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_serving_rate_limit(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::ServingRateLimit::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_serving_rate_limit(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, serving_rate_limit) = Self::parse_netuid_u64_parameter(data)?; let call = RuntimeCall::AdminUtils( @@ -229,6 +243,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_min_difficulty(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::MinDifficulty::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_min_difficulty(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, min_difficulty) = Self::parse_netuid_u64_parameter(data)?; let call = RuntimeCall::AdminUtils( @@ -241,6 +270,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_max_difficulty(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::MaxDifficulty::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_max_difficulty(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, max_difficulty) = Self::parse_netuid_u64_parameter(data)?; let call = RuntimeCall::AdminUtils( @@ -253,6 +297,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_weights_version_key(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::WeightsVersionKey::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_weights_version_key( handle: &mut impl PrecompileHandle, data: &[u8], @@ -268,6 +327,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_weights_set_rate_limit(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::WeightsSetRateLimit::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_weights_set_rate_limit( handle: &mut impl PrecompileHandle, data: &[u8], @@ -283,6 +357,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_adjustment_alpha(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::AdjustmentAlpha::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_adjustment_alpha(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, adjustment_alpha) = Self::parse_netuid_u64_parameter(data)?; let call = RuntimeCall::AdminUtils( @@ -295,6 +384,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_max_weight_limit(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::MaxWeightsLimit::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_max_weight_limit(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, max_weight_limit) = Self::parse_netuid_u16_parameter(data)?; let call = RuntimeCall::AdminUtils( @@ -307,6 +411,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_immunity_period(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::ImmunityPeriod::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_immunity_period(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, immunity_period) = Self::parse_netuid_u16_parameter(data)?; let call = RuntimeCall::AdminUtils( @@ -319,6 +438,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_min_allowed_weights(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::MinAllowedWeights::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_min_allowed_weights( handle: &mut impl PrecompileHandle, data: &[u8], @@ -334,6 +468,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_kappa(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::Kappa::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_kappa(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, kappa) = Self::parse_netuid_u16_parameter(data)?; let call = RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_kappa { @@ -344,6 +493,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_rho(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::Rho::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_rho(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, rho) = Self::parse_netuid_u16_parameter(data)?; let call = RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_rho { @@ -354,6 +518,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_activity_cutoff(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::ActivityCutoff::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_activity_cutoff(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, activity_cutoff) = Self::parse_netuid_u16_parameter(data)?; let call = RuntimeCall::AdminUtils( @@ -366,6 +545,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_network_registration_allowed(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::NetworkRegistrationAllowed::::get(netuid); + + let value_u256 = if value { U256::from(1) } else { U256::from(0) }; + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_network_registration_allowed( handle: &mut impl PrecompileHandle, data: &[u8], @@ -381,6 +575,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_network_pow_registration_allowed(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::NetworkPowRegistrationAllowed::::get(netuid); + + let value_u256 = if value { U256::from(1) } else { U256::from(0) }; + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_network_pow_registration_allowed( handle: &mut impl PrecompileHandle, data: &[u8], @@ -396,6 +605,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_min_burn(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::MinBurn::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_min_burn(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, min_burn) = Self::parse_netuid_u64_parameter(data)?; let call = @@ -407,6 +631,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_max_burn(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::MaxBurn::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_max_burn(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, max_burn) = Self::parse_netuid_u64_parameter(data)?; let call = @@ -418,6 +657,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_difficulty(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::Difficulty::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_difficulty(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, difficulty) = Self::parse_netuid_u64_parameter(data)?; let call = @@ -429,6 +683,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_bonds_moving_average(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::BondsMovingAverage::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_bonds_moving_average( handle: &mut impl PrecompileHandle, data: &[u8], @@ -444,6 +713,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_commit_reveal_weights_enabled(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::CommitRevealWeightsEnabled::::get(netuid); + + let value_u256 = if value { U256::from(1) } else { U256::from(0) }; + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_commit_reveal_weights_enabled( handle: &mut impl PrecompileHandle, data: &[u8], @@ -459,6 +743,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_liquid_alpha_enabled(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::LiquidAlphaOn::::get(netuid); + + let value_u256 = if value { U256::from(1) } else { U256::from(0) }; + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_liquid_alpha_enabled( handle: &mut impl PrecompileHandle, data: &[u8], @@ -471,6 +770,24 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_alpha_values(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let (alpha_low, alpha_high) = pallet_subtensor::AlphaValues::::get(netuid); + + let mut value_u256 = U256::from(alpha_low); + let mut result = [0_u8; 64]; + U256::to_big_endian(&value_u256, &mut result[0..]); + + value_u256 = U256::from(alpha_high); + U256::to_big_endian(&value_u256, &mut result[32..]); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_alpha_values(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { let (netuid, alpha_low, alpha_high) = Self::parse_netuid_u16_u16_parameter(data)?; let call = @@ -483,6 +800,21 @@ impl SubnetPrecompile { dispatch(handle, call, STAKING_CONTRACT_ADDRESS) } + fn get_commit_reveal_weights_interval(data: &[u8]) -> PrecompileResult { + let netuid = Self::parse_netuid(data)?; + + let value = pallet_subtensor::RevealPeriodEpochs::::get(netuid); + + let value_u256 = U256::from(value); + let mut result = [0_u8; 32]; + U256::to_big_endian(&value_u256, &mut result); + + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: result.into(), + }) + } + fn set_commit_reveal_weights_interval( handle: &mut impl PrecompileHandle, data: &[u8], @@ -561,6 +893,19 @@ impl SubnetPrecompile { Ok((name_vec, repo_vec, contact_vec)) } + fn parse_netuid(data: &[u8]) -> Result { + if data.len() < 32 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + Ok(netuid) + } + fn parse_netuid_u64_parameter(data: &[u8]) -> Result<(u16, u64), PrecompileFailure> { if data.len() < 64 { return Err(PrecompileFailure::Error { From 8cefb1878fed65f2b242a908106ccb6adb8bb0e2 Mon Sep 17 00:00:00 2001 From: open-junius Date: Thu, 12 Dec 2024 23:29:14 +0800 Subject: [PATCH 04/39] fix bugs --- runtime/src/precompiles/solidity/subnet.abi | 8 ++++---- runtime/src/precompiles/solidity/subnet.sol | 8 ++++---- runtime/src/precompiles/subnet.rs | 3 ++- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/runtime/src/precompiles/solidity/subnet.abi b/runtime/src/precompiles/solidity/subnet.abi index 1c80c7407d..d930d0b88b 100644 --- a/runtime/src/precompiles/solidity/subnet.abi +++ b/runtime/src/precompiles/solidity/subnet.abi @@ -402,7 +402,7 @@ "type": "uint16" } ], - "name": "setActivityCutoff", + "name": "getActivityCutoff", "outputs": [ { "internalType": "uint16", @@ -498,7 +498,7 @@ "type": "uint16" } ], - "name": "setCommitRevealWeightsInterval", + "name": "getCommitRevealWeightsInterval", "outputs": [ { "internalType": "uint64", @@ -589,7 +589,7 @@ "type": "uint16" } ], - "name": "setLiquidAlphaEnabled", + "name": "getLiquidAlphaEnabled", "outputs": [ { "internalType": "bool", @@ -734,7 +734,7 @@ "type": "uint16" } ], - "name": "setNetworkPowRegistrationAllowed", + "name": "getNetworkPowRegistrationAllowed", "outputs": [ { "internalType": "bool", diff --git a/runtime/src/precompiles/solidity/subnet.sol b/runtime/src/precompiles/solidity/subnet.sol index 99dac763e2..5992c75352 100644 --- a/runtime/src/precompiles/solidity/subnet.sol +++ b/runtime/src/precompiles/solidity/subnet.sol @@ -52,7 +52,7 @@ interface ISubnet { function setRho(uint16 netuid, uint16 rho) external payable; - function setActivityCutoff(uint16 netuid) external view returns (uint16); + function getActivityCutoff(uint16 netuid) external view returns (uint16); function setActivityCutoff(uint16 netuid, uint16 activityCutoff) external payable; @@ -60,7 +60,7 @@ interface ISubnet { function setNetworkRegistrationAllowed(uint16 netuid, bool networkRegistrationAllowed) external payable; - function setNetworkPowRegistrationAllowed(uint16 netuid) external view returns (bool); + function getNetworkPowRegistrationAllowed(uint16 netuid) external view returns (bool); function setNetworkPowRegistrationAllowed(uint16 netuid, bool networkPowRegistrationAllowed) external payable; @@ -84,7 +84,7 @@ interface ISubnet { function setCommitRevealWeightsEnabled(uint16 netuid, bool commitRevealWeightsEnabled) external payable; - function setLiquidAlphaEnabled(uint16 netuid) external view returns (bool); + function getLiquidAlphaEnabled(uint16 netuid) external view returns (bool); function setLiquidAlphaEnabled(uint16 netuid, bool liquidAlphaEnabled) external payable; @@ -92,7 +92,7 @@ interface ISubnet { function setAlphaValues(uint16 netuid, uint16 alphaLow, uint16 alphaHigh) external payable; - function setCommitRevealWeightsInterval(uint16 netuid) external view returns (uint64); + function getCommitRevealWeightsInterval(uint16 netuid) external view returns (uint64); function setCommitRevealWeightsInterval(uint16 netuid, uint64 commitRevealWeightsInterval) external payable; } \ No newline at end of file diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index 4b3a943a4d..a57103a392 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -65,7 +65,7 @@ impl SubnetPrecompile { Self::set_weights_version_key(handle, &method_input) } - id if id == get_method_id("getWeightsSetRateLimit(uint16,uint64)") => { + id if id == get_method_id("getWeightsSetRateLimit(uint16)") => { Self::get_weights_set_rate_limit(&method_input) } id if id == get_method_id("setWeightsSetRateLimit(uint16,uint64)") => { @@ -347,6 +347,7 @@ impl SubnetPrecompile { data: &[u8], ) -> PrecompileResult { let (netuid, weights_set_rate_limit) = Self::parse_netuid_u64_parameter(data)?; + let call = RuntimeCall::AdminUtils( pallet_admin_utils::Call::::sudo_set_weights_set_rate_limit { netuid, From 7ba9fc65e21e6c357927e82a76df475273f82122 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 13 Dec 2024 20:47:24 +0800 Subject: [PATCH 05/39] remove wrong comments --- runtime/src/precompiles/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index 398a80a05a..8f726a251c 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -159,7 +159,6 @@ fn transfer_back_to_caller( account_id: &AccountId32, amount: U256, ) -> Result<(), PrecompileFailure> { - // this is staking smart contract's(0x0000000000000000000000000000000000000801) sr25519 address let smart_contract_account_id = match AccountId32::from_ss58check(smart_contract_address) { // match AccountId32::from_ss58check("5CwnBK9Ack1mhznmCnwiibCNQc174pYQVktYW3ayRpLm4K2X") { Ok(addr) => addr, From 5f22fdac87cf60384e0f6bfe2c00ea9c50e98744 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 17 Dec 2024 10:26:34 +0800 Subject: [PATCH 06/39] fix wrong contract address name --- runtime/src/precompiles/subnet.rs | 48 +++++++++++++++---------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index a57103a392..e3a375f733 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -11,7 +11,7 @@ pub const SUBNET_PRECOMPILE_INDEX: u64 = 2051; pub const MAX_PARAMETER_SIZE: usize = 3 * 1024; // this is staking smart contract's(0x0000000000000000000000000000000000000803) sr25519 address -pub const STAKING_CONTRACT_ADDRESS: &str = "5DPSUCb5mZFfizvBDSnRoAqmxV5Bmov2CS3xV773qU6VP1w2"; +pub const SUBNET_CONTRACT_ADDRESS: &str = "5DPSUCb5mZFfizvBDSnRoAqmxV5Bmov2CS3xV773qU6VP1w2"; pub struct SubnetPrecompile; @@ -213,7 +213,7 @@ impl SubnetPrecompile { ) }; - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_serving_rate_limit(data: &[u8]) -> PrecompileResult { @@ -240,7 +240,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_min_difficulty(data: &[u8]) -> PrecompileResult { @@ -267,7 +267,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_max_difficulty(data: &[u8]) -> PrecompileResult { @@ -294,7 +294,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_weights_version_key(data: &[u8]) -> PrecompileResult { @@ -324,7 +324,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_weights_set_rate_limit(data: &[u8]) -> PrecompileResult { @@ -355,7 +355,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_adjustment_alpha(data: &[u8]) -> PrecompileResult { @@ -382,7 +382,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_max_weight_limit(data: &[u8]) -> PrecompileResult { @@ -409,7 +409,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_immunity_period(data: &[u8]) -> PrecompileResult { @@ -436,7 +436,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_min_allowed_weights(data: &[u8]) -> PrecompileResult { @@ -466,7 +466,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_kappa(data: &[u8]) -> PrecompileResult { @@ -491,7 +491,7 @@ impl SubnetPrecompile { kappa, }); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_rho(data: &[u8]) -> PrecompileResult { @@ -516,7 +516,7 @@ impl SubnetPrecompile { rho, }); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_activity_cutoff(data: &[u8]) -> PrecompileResult { @@ -543,7 +543,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_network_registration_allowed(data: &[u8]) -> PrecompileResult { @@ -573,7 +573,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_network_pow_registration_allowed(data: &[u8]) -> PrecompileResult { @@ -603,7 +603,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_min_burn(data: &[u8]) -> PrecompileResult { @@ -629,7 +629,7 @@ impl SubnetPrecompile { min_burn, }); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_max_burn(data: &[u8]) -> PrecompileResult { @@ -655,7 +655,7 @@ impl SubnetPrecompile { max_burn, }); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_difficulty(data: &[u8]) -> PrecompileResult { @@ -681,7 +681,7 @@ impl SubnetPrecompile { difficulty, }); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_bonds_moving_average(data: &[u8]) -> PrecompileResult { @@ -711,7 +711,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_commit_reveal_weights_enabled(data: &[u8]) -> PrecompileResult { @@ -741,7 +741,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_liquid_alpha_enabled(data: &[u8]) -> PrecompileResult { @@ -768,7 +768,7 @@ impl SubnetPrecompile { pallet_admin_utils::Call::::sudo_set_liquid_alpha_enabled { netuid, enabled }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_alpha_values(data: &[u8]) -> PrecompileResult { @@ -798,7 +798,7 @@ impl SubnetPrecompile { alpha_high, }); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn get_commit_reveal_weights_interval(data: &[u8]) -> PrecompileResult { @@ -828,7 +828,7 @@ impl SubnetPrecompile { }, ); - dispatch(handle, call, STAKING_CONTRACT_ADDRESS) + dispatch(handle, call, SUBNET_CONTRACT_ADDRESS) } fn parse_register_network_parameters( From 8144ed0bc77c1da70aa6a1daf8462bd7a0b811ab Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 21 Jan 2025 23:55:50 +0800 Subject: [PATCH 07/39] update neuron precompile --- runtime/src/precompiles/neuron.rs | 173 ++++++++++++++++++++ runtime/src/precompiles/solidity/neuron.abi | 134 +++++++++++++++ runtime/src/precompiles/solidity/neuron.sol | 68 ++++++++ 3 files changed, 375 insertions(+) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 341683cb36..135911a823 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -23,6 +23,23 @@ impl NeuronPrecompile { id if id == get_method_id("burnedRegister(uint16,bytes32)") => { Self::burned_register(handle, &method_input) } + id if id + == get_method_id( + "serveAxon(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8)", + ) => + { + Self::serve_axon(handle, &method_input) + } + id if id + == get_method_id( + "serveAxonTls(uint16,uint32,uint128,uint16,uint8,uint8,uint8,uint8,bytes)", + ) => + { + Self::serve_axon_tls(handle, &method_input) + } + id if id == get_method_id("servePrometheus(uint16,uint32,uint128,uint16,uint8)") => { + Self::serve_prometheus(handle, &method_input) + } _ => Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, @@ -40,6 +57,53 @@ impl NeuronPrecompile { dispatch(handle, call, NEURON_CONTRACT_ADDRESS) } + pub fn serve_axon(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, version, ip, port, ip_type, protocol, placeholder1, placeholder2) = + Self::parse_serve_axon_parameters(data)?; + let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::serve_axon { + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + }); + dispatch(handle, call, NEURON_CONTRACT_ADDRESS) + } + + pub fn serve_axon_tls(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, version, ip, port, ip_type, protocol, placeholder1, placeholder2, certificate) = + Self::parse_serve_axon_tls_parameters(data)?; + let call = + RuntimeCall::SubtensorModule(pallet_subtensor::Call::::serve_axon_tls { + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + certificate, + }); + dispatch(handle, call, NEURON_CONTRACT_ADDRESS) + } + + pub fn serve_prometheus(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + let (netuid, version, ip, port, ip_type) = Self::parse_serve_prometheus_parameters(data)?; + let call = + RuntimeCall::SubtensorModule(pallet_subtensor::Call::::serve_prometheus { + netuid, + version, + ip, + port, + ip_type, + }); + dispatch(handle, call, NEURON_CONTRACT_ADDRESS) + } + fn parse_netuid_hotkey_parameter(data: &[u8]) -> Result<(u16, [u8; 32]), PrecompileFailure> { if data.len() < 64 { return Err(PrecompileFailure::Error { @@ -55,4 +119,113 @@ impl NeuronPrecompile { Ok((netuid, parameter)) } + + fn parse_serve_axon_parameters( + data: &[u8], + ) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8), PrecompileFailure> { + if data.len() < 256 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut version_vec = [0u8; 4]; + version_vec.copy_from_slice(get_slice(data, 60, 64)?); + let version = u32::from_be_bytes(version_vec); + + let mut ip_vec = [0u8; 16]; + ip_vec.copy_from_slice(get_slice(data, 80, 96)?); + let ip = u128::from_be_bytes(ip_vec); + + let mut port_vec = [0u8; 2]; + port_vec.copy_from_slice(get_slice(data, 126, 128)?); + let port = u16::from_be_bytes(port_vec); + + let ip_type = data[160]; + let protocol = data[192]; + let placeholder1 = data[224]; + let placeholder2 = data[256]; + Ok(( + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + )) + } + + fn parse_serve_axon_tls_parameters( + data: &[u8], + ) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8, vec::Vec), PrecompileFailure> { + if data.len() < 256 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut version_vec = [0u8; 4]; + version_vec.copy_from_slice(get_slice(data, 60, 64)?); + let version = u32::from_be_bytes(version_vec); + + let mut ip_vec = [0u8; 16]; + ip_vec.copy_from_slice(get_slice(data, 80, 96)?); + let ip = u128::from_be_bytes(ip_vec); + + let mut port_vec = [0u8; 2]; + port_vec.copy_from_slice(get_slice(data, 126, 128)?); + let port = u16::from_be_bytes(port_vec); + + let ip_type = data[160]; + let protocol = data[192]; + let placeholder1 = data[224]; + let placeholder2 = data[256]; + Ok(( + netuid, + version, + ip, + port, + ip_type, + protocol, + placeholder1, + placeholder2, + vec![], + )) + } + + fn parse_serve_prometheus_parameters( + data: &[u8], + ) -> Result<(u16, u32, u128, u16, u8), PrecompileFailure> { + if data.len() < 160 { + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut netuid_vec = [0u8; 2]; + netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); + let netuid = u16::from_be_bytes(netuid_vec); + + let mut version_vec = [0u8; 4]; + version_vec.copy_from_slice(get_slice(data, 60, 64)?); + let version = u32::from_be_bytes(version_vec); + + let mut ip_vec = [0u8; 16]; + ip_vec.copy_from_slice(get_slice(data, 80, 96)?); + let ip = u128::from_be_bytes(ip_vec); + + let mut port_vec = [0u8; 2]; + port_vec.copy_from_slice(get_slice(data, 126, 128)?); + let port = u16::from_be_bytes(port_vec); + + let ip_type = data[160]; + Ok((netuid, version, ip, port, ip_type)) + } } diff --git a/runtime/src/precompiles/solidity/neuron.abi b/runtime/src/precompiles/solidity/neuron.abi index 09a14eb2db..52e371fdbe 100644 --- a/runtime/src/precompiles/solidity/neuron.abi +++ b/runtime/src/precompiles/solidity/neuron.abi @@ -16,5 +16,139 @@ "outputs": [], "stateMutability": "payable", "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "version", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ip", + "type": "uint128" + }, + { + "internalType": "uint16", + "name": "port", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "ipType", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "protocol", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "placeholder1", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "placeholder2", + "type": "uint8" + } + ], + "name": "serveAxon", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "version", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ip", + "type": "uint128" + }, + { + "internalType": "uint16", + "name": "port", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "ipType", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "protocol", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "placeholder1", + "type": "uint8" + }, + { + "internalType": "uint8", + "name": "placeholder2", + "type": "uint8" + }, + { + "internalType": "bytes", + "name": "certificate", + "type": "bytes" + } + ], + "name": "serveAxonTls", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + }, + { + "internalType": "uint32", + "name": "version", + "type": "uint32" + }, + { + "internalType": "uint128", + "name": "ip", + "type": "uint128" + }, + { + "internalType": "uint16", + "name": "port", + "type": "uint16" + }, + { + "internalType": "uint8", + "name": "ipType", + "type": "uint8" + } + ], + "name": "servePrometheus", + "outputs": [], + "stateMutability": "payable", + "type": "function" } ] diff --git a/runtime/src/precompiles/solidity/neuron.sol b/runtime/src/precompiles/solidity/neuron.sol index a768423398..c4d9e5b61e 100644 --- a/runtime/src/precompiles/solidity/neuron.sol +++ b/runtime/src/precompiles/solidity/neuron.sol @@ -11,4 +11,72 @@ interface INeuron { * @param hotkey The hotkey public key (32 bytes). */ function burnedRegister(uint16 netuid, bytes32 hotkey) external payable; + + /** + * @dev Registers axon information for a neuron. + * This function is used to serve axon information, including the subnet to register to, version, IP address, port, IP type, protocol, and placeholders for future use. + * + * @param netuid The subnet to register the axon to (uint16). + * @param version The version of the axon (uint32). + * @param ip The IP address of the axon (uint128). + * @param port The port number of the axon (uint16). + * @param ipType The type of IP address (uint8). + * @param protocol The protocol used by the axon (uint8). + * @param placeholder1 Placeholder for future use (uint8). + * @param placeholder2 Placeholder for future use (uint8). + */ + function serveAxon( + uint16 netuid, + uint32 version, + uint128 ip, + uint16 port, + uint8 ipType, + uint8 protocol, + uint8 placeholder1, + uint8 placeholder2 + ) external payable; + + /** + * @dev Serves axon information for a neuron over TLS. + * This function is used to serve axon information, including the subnet to register to, version, IP address, port, IP type, protocol, and placeholders for future use. + * + * @param netuid The subnet to register the axon to (uint16). + * @param version The version of the axon (uint32). + * @param ip The IP address of the axon (uint128). + * @param port The port number of the axon (uint16). + * @param ipType The type of IP address (uint8). + * @param protocol The protocol used by the axon (uint8). + * @param placeholder1 Placeholder for future use (uint8). + * @param placeholder2 Placeholder for future use (uint8). + * @param certificate The TLS certificate for the axon (bytes). + */ + function serveAxonTls( + uint16 netuid, + uint32 version, + uint128 ip, + uint16 port, + uint8 ipType, + uint8 protocol, + uint8 placeholder1, + uint8 placeholder2, + bytes memory certificate + ) external payable; + + /** + * @dev Serves Prometheus information for a neuron. + * This function is used to serve Prometheus information, including the subnet to register to, version, IP address, port, and IP type. + * + * @param netuid The subnet to register the Prometheus information to (uint16). + * @param version The version of the Prometheus information (uint32). + * @param ip The IP address of the Prometheus information (uint128). + * @param port The port number of the Prometheus information (uint16). + * @param ipType The type of IP address (uint8). + */ + function servePrometheus( + uint16 netuid, + uint32 version, + uint128 ip, + uint16 port, + uint8 ipType + ) external payable; } From cc03f1a971043e7be8e36a0275da551c31aa3373 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 22 Jan 2025 10:43:14 +0800 Subject: [PATCH 08/39] fix bug --- runtime/src/precompiles/neuron.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 135911a823..d7b4833b6e 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -144,10 +144,10 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[160]; - let protocol = data[192]; - let placeholder1 = data[224]; - let placeholder2 = data[256]; + let ip_type = data[159]; + let protocol = data[191]; + let placeholder1 = data[223]; + let placeholder2 = data[255]; Ok(( netuid, version, @@ -184,10 +184,10 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[160]; - let protocol = data[192]; - let placeholder1 = data[224]; - let placeholder2 = data[256]; + let ip_type = data[159]; + let protocol = data[191]; + let placeholder1 = data[223]; + let placeholder2 = data[255]; Ok(( netuid, version, @@ -225,7 +225,7 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[160]; + let ip_type = data[159]; Ok((netuid, version, ip, port, ip_type)) } } From 3fd2c8314e229c0602ad350e7d30b5f8dd27ec41 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 22 Jan 2025 20:07:28 +0800 Subject: [PATCH 09/39] commit Cargo.lock --- runtime/src/precompiles/neuron.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index d7b4833b6e..f8a006e285 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -163,7 +163,7 @@ impl NeuronPrecompile { fn parse_serve_axon_tls_parameters( data: &[u8], ) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8, vec::Vec), PrecompileFailure> { - if data.len() < 256 { + if data.len() < 288 { return Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, }); @@ -188,6 +188,17 @@ impl NeuronPrecompile { let protocol = data[191]; let placeholder1 = data[223]; let placeholder2 = data[255]; + + let mut len_position_vec = [0u8; 2]; + len_position_vec.copy_from_slice(get_slice(data, 286, 288)?); + let len_position = u16::from_be_bytes(len_position_vec) as usize; + + let mut len_vec = [0u8; 2]; + len_vec.copy_from_slice(get_slice(data, len_position + 30, len_position + 32)?); + let vec_len = u16::from_be_bytes(len_vec) as usize; + + let vec_result = get_slice(data, len_position + 32, len_position + 32 + vec_len)?.to_vec(); + Ok(( netuid, version, @@ -197,7 +208,7 @@ impl NeuronPrecompile { protocol, placeholder1, placeholder2, - vec![], + vec_result, )) } From ef3af14a0b22779dc2ae9891b8b308fb8d6393bf Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 22 Jan 2025 20:14:20 +0800 Subject: [PATCH 10/39] commit Cargo.lock --- runtime/src/precompiles/mod.rs | 11 +++++++++++ runtime/src/precompiles/neuron.rs | 20 ++++++++++---------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index 3d2c19ae9d..cefa3a1653 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -232,3 +232,14 @@ fn dispatch( }), } } + +pub fn get_single_u8(data: &[u8], index: usize) -> Result { + if let Some(result) = data.get(index) { + Ok(*result) + } else { + log::error!("fail to get data from data, {:?}, at {}", &data, index); + Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }) + } +} diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index f8a006e285..cb6295c241 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -1,6 +1,6 @@ use pallet_evm::{ExitError, PrecompileFailure, PrecompileHandle, PrecompileResult}; -use crate::precompiles::{dispatch, get_method_id, get_slice}; +use crate::precompiles::{dispatch, get_method_id, get_single_u8, get_slice}; use sp_std::vec; use crate::{Runtime, RuntimeCall}; @@ -144,10 +144,10 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[159]; - let protocol = data[191]; - let placeholder1 = data[223]; - let placeholder2 = data[255]; + let ip_type = get_single_u8(data, 159)?; + let protocol = get_single_u8(data, 191)?; + let placeholder1 = get_single_u8(data, 223)?; + let placeholder2 = get_single_u8(data, 255)?; Ok(( netuid, version, @@ -184,10 +184,10 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[159]; - let protocol = data[191]; - let placeholder1 = data[223]; - let placeholder2 = data[255]; + let ip_type = get_single_u8(data, 159)?; + let protocol = get_single_u8(data, 191)?; + let placeholder1 = get_single_u8(data, 223)?; + let placeholder2 = get_single_u8(data, 255)?; let mut len_position_vec = [0u8; 2]; len_position_vec.copy_from_slice(get_slice(data, 286, 288)?); @@ -236,7 +236,7 @@ impl NeuronPrecompile { port_vec.copy_from_slice(get_slice(data, 126, 128)?); let port = u16::from_be_bytes(port_vec); - let ip_type = data[159]; + let ip_type = get_single_u8(data, 159)?; Ok((netuid, version, ip, port, ip_type)) } } From 959d981c3d5cae9fe0482554dcc35a3b78ca2613 Mon Sep 17 00:00:00 2001 From: open-junius Date: Wed, 22 Jan 2025 20:16:30 +0800 Subject: [PATCH 11/39] add document for function --- runtime/src/precompiles/mod.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index cefa3a1653..4e9c93e5a7 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -233,6 +233,14 @@ fn dispatch( } } +/// Retrieves a single u8 value from the given data slice at the specified index. +/// +/// # Args +/// * `data`: The slice of bytes from which to retrieve the u8 value. +/// * `index`: The index within the `data` slice where the u8 value is located. +/// +/// # Returns +/// A `Result` containing the u8 value at the specified index if successful, or a `PrecompileFailure` if the index is out of range. pub fn get_single_u8(data: &[u8], index: usize) -> Result { if let Some(result) = data.get(index) { Ok(*result) From 564b76d2bbc5ae879b7af2bfe99009c596e17dcf Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 31 Jan 2025 14:43:27 +0800 Subject: [PATCH 12/39] refactor code --- runtime/src/precompiles/subnet.rs | 75 ++++++++++++------------------- 1 file changed, 28 insertions(+), 47 deletions(-) diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index 5e5c34a4a7..ce6c27e961 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -10,6 +10,8 @@ use sp_core::U256; use sp_runtime::traits::BlakeTwo256; use sp_runtime::AccountId32; use sp_std::vec; + +use super::parse_netuid; pub const SUBNET_PRECOMPILE_INDEX: u64 = 2051; // bytes with max lenght 1K pub const MAX_SINGLE_PARAMETER_SIZE: usize = 1024; @@ -242,7 +244,7 @@ impl SubnetPrecompile { } fn get_serving_rate_limit(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::ServingRateLimit::::get(netuid); @@ -274,7 +276,7 @@ impl SubnetPrecompile { } fn get_min_difficulty(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::MinDifficulty::::get(netuid); @@ -306,7 +308,7 @@ impl SubnetPrecompile { } fn get_max_difficulty(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::MaxDifficulty::::get(netuid); @@ -338,7 +340,7 @@ impl SubnetPrecompile { } fn get_weights_version_key(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::WeightsVersionKey::::get(netuid); @@ -373,7 +375,7 @@ impl SubnetPrecompile { } fn get_weights_set_rate_limit(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::WeightsSetRateLimit::::get(netuid); @@ -409,7 +411,7 @@ impl SubnetPrecompile { } fn get_adjustment_alpha(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::AdjustmentAlpha::::get(netuid); @@ -441,7 +443,7 @@ impl SubnetPrecompile { } fn get_max_weight_limit(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::MaxWeightsLimit::::get(netuid); @@ -473,7 +475,7 @@ impl SubnetPrecompile { } fn get_immunity_period(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::ImmunityPeriod::::get(netuid); @@ -505,7 +507,7 @@ impl SubnetPrecompile { } fn get_min_allowed_weights(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::MinAllowedWeights::::get(netuid); @@ -540,7 +542,7 @@ impl SubnetPrecompile { } fn get_kappa(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::Kappa::::get(netuid); @@ -570,7 +572,7 @@ impl SubnetPrecompile { } fn get_rho(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::Rho::::get(netuid); @@ -600,7 +602,7 @@ impl SubnetPrecompile { } fn get_activity_cutoff(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::ActivityCutoff::::get(netuid); @@ -632,7 +634,7 @@ impl SubnetPrecompile { } fn get_network_registration_allowed(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::NetworkRegistrationAllowed::::get(netuid); @@ -667,7 +669,7 @@ impl SubnetPrecompile { } fn get_network_pow_registration_allowed(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::NetworkPowRegistrationAllowed::::get(netuid); @@ -702,7 +704,7 @@ impl SubnetPrecompile { } fn get_min_burn(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::MinBurn::::get(netuid); @@ -733,7 +735,7 @@ impl SubnetPrecompile { } fn get_max_burn(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::MaxBurn::::get(netuid); @@ -764,7 +766,7 @@ impl SubnetPrecompile { } fn get_difficulty(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::Difficulty::::get(netuid); @@ -795,7 +797,7 @@ impl SubnetPrecompile { } fn get_bonds_moving_average(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::BondsMovingAverage::::get(netuid); @@ -830,7 +832,7 @@ impl SubnetPrecompile { } fn get_commit_reveal_weights_enabled(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::CommitRevealWeightsEnabled::::get(netuid); @@ -865,7 +867,7 @@ impl SubnetPrecompile { } fn get_liquid_alpha_enabled(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::LiquidAlphaOn::::get(netuid); @@ -897,7 +899,7 @@ impl SubnetPrecompile { } fn get_alpha_values(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let (alpha_low, alpha_high) = pallet_subtensor::AlphaValues::::get(netuid); @@ -932,7 +934,7 @@ impl SubnetPrecompile { } fn get_commit_reveal_weights_interval(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; + let netuid = parse_netuid(data, 30)?; let value = pallet_subtensor::RevealPeriodEpochs::::get(netuid); @@ -1083,28 +1085,13 @@ impl SubnetPrecompile { Ok((pubkey, name_vec, repo_vec, contact_vec)) } - fn parse_netuid(data: &[u8]) -> Result { - if data.len() < 32 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); - - Ok(netuid) - } - fn parse_netuid_u64_parameter(data: &[u8]) -> Result<(u16, u64), PrecompileFailure> { if data.len() < 64 { return Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + let netuid = parse_netuid(data, 30)?; let mut parameter_vec = [0u8; 8]; parameter_vec.copy_from_slice(get_slice(data, 56, 64)?); @@ -1119,9 +1106,7 @@ impl SubnetPrecompile { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + let netuid = parse_netuid(data, 30)?; let mut parameter_vec = [0u8; 2]; parameter_vec.copy_from_slice(get_slice(data, 62, 64)?); @@ -1136,9 +1121,7 @@ impl SubnetPrecompile { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + let netuid = parse_netuid(data, 30)?; let mut parameter_1_vec = [0u8; 2]; parameter_1_vec.copy_from_slice(get_slice(data, 62, 64)?); @@ -1157,9 +1140,7 @@ impl SubnetPrecompile { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + let netuid = parse_netuid(data, 30)?; let mut parameter_vec = [0_u8]; parameter_vec.copy_from_slice(get_slice(data, 63, 64)?); From e2c5115510d550790646e4dce9042b9201589ee5 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 31 Jan 2025 14:57:34 +0800 Subject: [PATCH 13/39] reorg import --- runtime/src/precompiles/subnet.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index ce6c27e961..2d61816396 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -1,4 +1,6 @@ -use crate::precompiles::{get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call}; +use crate::precompiles::{ + get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call, +}; use crate::{Runtime, RuntimeCall}; use frame_system::RawOrigin; use pallet_evm::{ @@ -7,11 +9,9 @@ use pallet_evm::{ }; use sp_core::U256; -use sp_runtime::traits::BlakeTwo256; -use sp_runtime::AccountId32; +use sp_runtime::{traits::BlakeTwo256, AccountId32}; use sp_std::vec; -use super::parse_netuid; pub const SUBNET_PRECOMPILE_INDEX: u64 = 2051; // bytes with max lenght 1K pub const MAX_SINGLE_PARAMETER_SIZE: usize = 1024; @@ -1116,7 +1116,7 @@ impl SubnetPrecompile { } fn parse_netuid_u16_u16_parameter(data: &[u8]) -> Result<(u16, u16, u16), PrecompileFailure> { - if data.len() < 64 { + if data.len() < 96 { return Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, }); From 648cd8194541237e3d9ea8c18e60204d03528735 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 31 Jan 2025 14:59:29 +0800 Subject: [PATCH 14/39] fix wrong origin --- runtime/src/precompiles/neuron.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 97167c9009..09f86433be 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -44,7 +44,13 @@ impl NeuronPrecompile { netuid, hotkey, }); - try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?) + + let account_id = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } fn parse_netuid_hotkey_parameter(data: &[u8]) -> Result<(u16, AccountId32), PrecompileFailure> { From 79e121baed964956db62f6bdbd10f2c1f54779b3 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 31 Jan 2025 20:44:00 +0800 Subject: [PATCH 15/39] add length check --- runtime/src/precompiles/neuron.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 6a1e40b15d..52c4ca7a7d 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -194,14 +194,14 @@ impl NeuronPrecompile { fn parse_serve_axon_tls_parameters( data: &[u8], ) -> Result<(u16, u32, u128, u16, u8, u8, u8, u8, vec::Vec), PrecompileFailure> { - if data.len() < 288 { + let data_len = data.len(); + if data_len < 288 { return Err(PrecompileFailure::Error { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + + let netuid = parse_netuid(data, 30)?; let mut version_vec = [0u8; 4]; version_vec.copy_from_slice(get_slice(data, 60, 64)?); @@ -224,6 +224,17 @@ impl NeuronPrecompile { len_position_vec.copy_from_slice(get_slice(data, 286, 288)?); let len_position = u16::from_be_bytes(len_position_vec) as usize; + if len_position > data_len { + log::error!( + "the start position of certificate as {} is bigger than whole data len {}", + subnet_contact_start, + data_len + ); + return Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }); + } + let mut len_vec = [0u8; 2]; len_vec.copy_from_slice(get_slice(data, len_position + 30, len_position + 32)?); let vec_len = u16::from_be_bytes(len_vec) as usize; From c7366eb64e80258d4169eca4a0fb3c7b1f60d490 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 31 Jan 2025 20:56:09 +0800 Subject: [PATCH 16/39] fix compile --- runtime/src/precompiles/neuron.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 52c4ca7a7d..9c8d6dced3 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -227,7 +227,7 @@ impl NeuronPrecompile { if len_position > data_len { log::error!( "the start position of certificate as {} is bigger than whole data len {}", - subnet_contact_start, + len_position, data_len ); return Err(PrecompileFailure::Error { From 256e7a98103586bf975ab4831e80a123251b7060 Mon Sep 17 00:00:00 2001 From: open-junius Date: Mon, 3 Feb 2025 19:44:56 +0800 Subject: [PATCH 17/39] fix clippy --- Cargo.lock | 10 +++++----- runtime/src/precompiles/neuron.rs | 14 +++++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42522da321..2e66bfd099 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1779,7 +1779,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1145d32e826a7748b69ee8fc62d3e6355ff7f1051df53141e7048162fc90481b" dependencies = [ "data-encoding", - "syn 2.0.96", + "syn 1.0.109", ] [[package]] @@ -6126,9 +6126,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.69" +version = "0.10.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5e534d133a060a3c19daec1eb3e98ec6f4685978834f2dbadfe2ec215bab64e" +checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6" dependencies = [ "bitflags 2.8.0", "cfg-if", @@ -6167,9 +6167,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc" dependencies = [ "cc", "libc", diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 09f86433be..42532582db 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -1,17 +1,21 @@ -use pallet_evm::{ExitError, PrecompileFailure, PrecompileHandle, PrecompileResult}; +use pallet_evm::{ + AddressMapping, ExitError, HashedAddressMapping, PrecompileFailure, PrecompileHandle, + PrecompileResult, +}; use crate::precompiles::{ - contract_to_origin, get_method_id, get_pubkey, get_slice, parse_netuid, - try_dispatch_runtime_call, + get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call, }; +use crate::RawOrigin; +use crate::{Runtime, RuntimeCall}; +use sp_runtime::traits::BlakeTwo256; use sp_runtime::AccountId32; use sp_std::vec; - -use crate::{Runtime, RuntimeCall}; pub const NEURON_PRECOMPILE_INDEX: u64 = 2052; // ss58 public key i.e., the contract sends funds it received to the destination address from the // method parameter. +#[allow(dead_code)] const CONTRACT_ADDRESS_SS58: [u8; 32] = [ 0xbc, 0x46, 0x35, 0x79, 0xbc, 0x99, 0xf9, 0xee, 0x7c, 0x59, 0xed, 0xee, 0x20, 0x61, 0xa3, 0x09, 0xd2, 0x1e, 0x68, 0xd5, 0x39, 0xb6, 0x40, 0xec, 0x66, 0x46, 0x90, 0x30, 0xab, 0x74, 0xc1, 0xdb, From d3b97d31d21e8884a90718687c7abf1e0eb0fda0 Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 4 Feb 2025 08:26:17 +0800 Subject: [PATCH 18/39] safe math --- runtime/src/precompiles/neuron.rs | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 01d5cefee7..38fb701fbe 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -145,7 +145,6 @@ impl NeuronPrecompile { handle.context().caller, ); - // Dispatch the register_network call try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } @@ -167,7 +166,6 @@ impl NeuronPrecompile { handle.context().caller, ); - // Dispatch the register_network call try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } @@ -191,7 +189,6 @@ impl NeuronPrecompile { handle.context().caller, ); - // Dispatch the register_network call try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } @@ -504,9 +501,8 @@ impl NeuronPrecompile { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + + let netuid = parse_netuid(data, 30)?; let mut version_vec = [0u8; 4]; version_vec.copy_from_slice(get_slice(data, 60, 64)?); @@ -584,7 +580,12 @@ impl NeuronPrecompile { len_vec.copy_from_slice(get_slice(data, len_position + 30, len_position + 32)?); let vec_len = u16::from_be_bytes(len_vec) as usize; - let vec_result = get_slice(data, len_position + 32, len_position + 32 + vec_len)?.to_vec(); + let vec_result = get_slice( + data, + len_position + 32, + len_position.saturating_add(32).saturating_add(vec_len), + )? + .to_vec(); Ok(( netuid, @@ -607,9 +608,8 @@ impl NeuronPrecompile { exit_status: ExitError::InvalidRange, }); } - let mut netuid_vec = [0u8; 2]; - netuid_vec.copy_from_slice(get_slice(data, 30, 32)?); - let netuid = u16::from_be_bytes(netuid_vec); + + let netuid = parse_netuid(data, 30)?; let mut version_vec = [0u8; 4]; version_vec.copy_from_slice(get_slice(data, 60, 64)?); From bf1bcfbe992088c75efdf9583ddcce00dd5667df Mon Sep 17 00:00:00 2001 From: open-junius Date: Tue, 4 Feb 2025 23:44:39 +0800 Subject: [PATCH 19/39] remove duplicated function --- runtime/src/precompiles/solidity/subnet.sol | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/runtime/src/precompiles/solidity/subnet.sol b/runtime/src/precompiles/solidity/subnet.sol index b2d127f110..b6d005706f 100644 --- a/runtime/src/precompiles/solidity/subnet.sol +++ b/runtime/src/precompiles/solidity/subnet.sol @@ -165,14 +165,4 @@ interface ISubnet { uint16 netuid, uint64 commitRevealWeightsInterval ) external payable; - - /// Registers a new network without specifying details. - function registerNetwork(bytes32 hotkey) external payable; - /// Registers a new network with specified subnet name, GitHub repository, and contact information. - function registerNetwork( - bytes32 hotkey, - bytes memory subnetName, - bytes memory githubRepo, - bytes memory subnetContact - ) external payable; } From 20b53f5f82e2d33b44100bd1dca0485ef862a381 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 7 Feb 2025 11:10:25 +0800 Subject: [PATCH 20/39] fix audit --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae335a2295..2f60ebd049 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3468,9 +3468,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.15.0" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e087f84d4f86bf4b218b927129862374b72199ae7d8657835f1e89000eea4fb" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ "allocator-api2", "equivalent", @@ -3932,7 +3932,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "707907fe3c25f5424cce2cb7e1cbcafee6bdbe735ca90ef77c29e84591e5b9da" dependencies = [ "equivalent", - "hashbrown 0.15.0", + "hashbrown 0.15.2", ] [[package]] @@ -4923,7 +4923,7 @@ version = "0.12.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" dependencies = [ - "hashbrown 0.15.0", + "hashbrown 0.15.2", ] [[package]] From 1591e882f3fd4e29f03d8cd2ae0d814bacc27fa3 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 7 Feb 2025 11:35:23 +0800 Subject: [PATCH 21/39] fix audit --- Cargo.lock | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2f60ebd049..6c4349b1ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5909,9 +5909,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" [[package]] name = "openssl" -version = "0.10.68" +version = "0.10.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6174bc48f102d208783c2c84bf931bb75927a617866870de8a4ea85597f871f5" +checksum = "61cfb4e166a8bb8c9b55c500bc2308550148ece889be90f609377e58140f42c6" dependencies = [ "bitflags 2.6.0", "cfg-if", @@ -5950,9 +5950,9 @@ dependencies = [ [[package]] name = "openssl-sys" -version = "0.9.104" +version = "0.9.105" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45abf306cbf99debc8195b66b7346498d7b10c210de50418b5ccd7ceba08c741" +checksum = "8b22d5b84be05a8d6947c7cb71f7c849aa0f112acd4bf51c2a7c1c988ac0a9dc" dependencies = [ "cc", "libc", From 8231c0b231bef2076f51677357dec021ea2ef312 Mon Sep 17 00:00:00 2001 From: open-junius Date: Fri, 7 Feb 2025 16:22:25 +0800 Subject: [PATCH 22/39] fix contract --- runtime/src/precompiles/solidity/subnet.abi | 242 ++++++++++---------- runtime/src/precompiles/solidity/subnet.sol | 3 +- 2 files changed, 118 insertions(+), 127 deletions(-) diff --git a/runtime/src/precompiles/solidity/subnet.abi b/runtime/src/precompiles/solidity/subnet.abi index fc8855f20a..fd81850b74 100644 --- a/runtime/src/precompiles/solidity/subnet.abi +++ b/runtime/src/precompiles/solidity/subnet.abi @@ -1,4 +1,23 @@ [ + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getActivityCutoff", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -80,6 +99,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getCommitRevealWeightsInterval", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -137,6 +175,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getLiquidAlphaEnabled", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -251,6 +308,25 @@ "stateMutability": "view", "type": "function" }, + { + "inputs": [ + { + "internalType": "uint16", + "name": "netuid", + "type": "uint16" + } + ], + "name": "getNetworkPowRegistrationAllowed", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, { "inputs": [ { @@ -348,6 +424,24 @@ }, { "inputs": [ + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + } + ], + "name": "registerNetwork", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes32", + "name": "hotkey", + "type": "bytes32" + }, { "internalType": "bytes", "name": "subnetName", @@ -362,6 +456,26 @@ "internalType": "bytes", "name": "subnetContact", "type": "bytes" + }, + { + "internalType": "bytes", + "name": "subnetUrl", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "discord", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "description", + "type": "bytes" + }, + { + "internalType": "bytes", + "name": "additional", + "type": "bytes" } ], "name": "registerNetwork", @@ -369,13 +483,6 @@ "stateMutability": "payable", "type": "function" }, - { - "inputs": [], - "name": "registerNetwork", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, { "inputs": [ { @@ -394,25 +501,6 @@ "stateMutability": "payable", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "netuid", - "type": "uint16" - } - ], - "name": "getActivityCutoff", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -490,25 +578,6 @@ "stateMutability": "payable", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "netuid", - "type": "uint16" - } - ], - "name": "getCommitRevealWeightsInterval", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -581,25 +650,6 @@ "stateMutability": "payable", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "netuid", - "type": "uint16" - } - ], - "name": "getLiquidAlphaEnabled", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -726,25 +776,6 @@ "stateMutability": "payable", "type": "function" }, - { - "inputs": [ - { - "internalType": "uint16", - "name": "netuid", - "type": "uint16" - } - ], - "name": "getNetworkPowRegistrationAllowed", - "outputs": [ - { - "internalType": "bool", - "name": "", - "type": "bool" - } - ], - "stateMutability": "view", - "type": "function" - }, { "inputs": [ { @@ -852,46 +883,5 @@ "outputs": [], "stateMutability": "payable", "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "hotkey", - "type": "bytes32" - } - ], - "name": "registerNetwork", - "outputs": [], - "stateMutability": "payable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes32", - "name": "hotkey", - "type": "bytes32" - }, - { - "internalType": "bytes", - "name": "subnetName", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "githubRepo", - "type": "bytes" - }, - { - "internalType": "bytes", - "name": "subnetContact", - "type": "bytes" - } - ], - "name": "registerNetwork", - "outputs": [], - "stateMutability": "payable", - "type": "function" - } -] + } +] \ No newline at end of file diff --git a/runtime/src/precompiles/solidity/subnet.sol b/runtime/src/precompiles/solidity/subnet.sol index 868132811f..1afeced493 100644 --- a/runtime/src/precompiles/solidity/subnet.sol +++ b/runtime/src/precompiles/solidity/subnet.sol @@ -4,9 +4,10 @@ address constant ISUBNET_ADDRESS = 0x0000000000000000000000000000000000000803; interface ISubnet { /// Registers a new network without specifying details. - function registerNetwork() external payable; + function registerNetwork(bytes32 hotkey) external payable; /// Registers a new network with specified subnet name, GitHub repository, and contact information. function registerNetwork( + bytes32 hotkey, bytes memory subnetName, bytes memory githubRepo, bytes memory subnetContact, From 19028c44b34bd93e8416d06703b76ab5da78ef79 Mon Sep 17 00:00:00 2001 From: Prakash Date: Sun, 9 Feb 2025 04:11:33 +0530 Subject: [PATCH 23/39] update readme of support of M series macs --- README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 30f36ffab5..4d1cdf645a 100644 --- a/README.md +++ b/README.md @@ -22,9 +22,12 @@ This repository contains Bittensor's substrate-chain. Subtensor contains the tru * The binaries in ./bin/release are x86_64 binaries to be used with the Linux kernel. * Subtensor needs ~286 MiB to run. -* Architectures other than x86_64 are currently not supported. +* Supported Architectures: + - Linux: x86_64 + - MacOS: x86_64 and ARM64 (M series Macs) * OSs other than Linux and MacOS are currently not supported. + ## Architectures Subtensor support the following architectures: @@ -34,9 +37,10 @@ Requirements: * glibc 2.11+ A fresh FRAME-based [Substrate](https://www.substrate.io/) node, ready for hacking :rocket: -## MacOS x86_64 +## MacOS x86_64 & arm64 (Apple Silicon) Requirements: -* MacOS 10.7+ (Lion+) +* macOS 10.7+ (Lion+) for x86_64 +* macOS 11+ (Big Sur+) for Apple Silicon (M1, M2, and later) with arm64 architecture support. ## Network requirements * Subtensor needs access to the public internet @@ -49,7 +53,7 @@ Requirements: --- -## For Subnet Development +## For Subnet Development If you are developing and testing subnet incentive mechanism, you will need to run a local subtensor node. Follow the detailed step-by-step instructions provided in the [**Subtensor Nodes** section in Bittensor Developer Documentation](https://docs.bittensor.com/subtensor-nodes). @@ -216,7 +220,7 @@ If you want to see the multi-node consensus algorithm in action, refer to our A Substrate project such as this consists of a number of components that are spread across a few directories. -### Node Capabilities +### Node Capabilities A blockchain node is an application that allows users to participate in a blockchain network. Substrate-based blockchain nodes expose a number of capabilities: @@ -232,7 +236,7 @@ Substrate-based blockchain nodes expose a number of capabilities: **Directory structure** -There are several files in the [`node`](./node/) directory. Make a note of the following important files: +There are several files in the [`node`](./node/) directory. Make a note of the following important files: - [`chain_spec.rs`](./node/src/chain_spec.rs): A [chain specification](https://docs.substrate.io/main-docs/build/chain-spec/) is a From 795d366d1adc7cd46cd8360fe76b02b1d2ec0da4 Mon Sep 17 00:00:00 2001 From: ibraheem-opentensor Date: Tue, 11 Feb 2025 17:39:33 -0800 Subject: [PATCH 24/39] add tao_emission to stakeinfo runtime --- pallets/subtensor/src/rpc_info/stake_info.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pallets/subtensor/src/rpc_info/stake_info.rs b/pallets/subtensor/src/rpc_info/stake_info.rs index 631e3a167a..bda619596a 100644 --- a/pallets/subtensor/src/rpc_info/stake_info.rs +++ b/pallets/subtensor/src/rpc_info/stake_info.rs @@ -3,7 +3,7 @@ use frame_support::pallet_prelude::{Decode, Encode}; extern crate alloc; use codec::Compact; -#[freeze_struct("4f16c654467bc8b6")] +#[freeze_struct("5cfb3c84c3af3116")] #[derive(Decode, Encode, PartialEq, Eq, Clone, Debug, TypeInfo)] pub struct StakeInfo { hotkey: AccountId, @@ -12,6 +12,7 @@ pub struct StakeInfo { stake: Compact, locked: Compact, emission: Compact, + tao_emission: Compact, drain: Compact, is_registered: bool, } @@ -38,6 +39,7 @@ impl Pallet { continue; } let emission: u64 = AlphaDividendsPerSubnet::::get(*netuid_i, &hotkey_i); + let tao_emission: u64 = TaoDividendsPerSubnet::::get(*netuid_i, &hotkey_i); let is_registered: bool = Self::is_hotkey_registered_on_network(*netuid_i, hotkey_i); stake_info_for_coldkey.push(StakeInfo { @@ -47,6 +49,7 @@ impl Pallet { stake: alpha.into(), locked: 0.into(), emission: emission.into(), + tao_emission: tao_emission.into(), drain: 0.into(), is_registered, }); @@ -94,6 +97,7 @@ impl Pallet { netuid, ); let emission: u64 = AlphaDividendsPerSubnet::::get(netuid, &hotkey_account); + let tao_emission: u64 = TaoDividendsPerSubnet::::get(netuid, &hotkey_account); let is_registered: bool = Self::is_hotkey_registered_on_network(netuid, &hotkey_account); Some(StakeInfo { @@ -103,6 +107,7 @@ impl Pallet { stake: alpha.into(), locked: 0.into(), emission: emission.into(), + tao_emission: tao_emission.into(), drain: 0.into(), is_registered, }) From 70637f257e02d369fba6c3a0d13efd19691e66f4 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 12 Feb 2025 12:56:42 -0500 Subject: [PATCH 25/39] remove call from coinbase. already in block_step --- pallets/subtensor/src/coinbase/run_coinbase.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index d0a668f92c..0390deea4d 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -249,11 +249,6 @@ impl Pallet { BlocksSinceLastStep::::mutate(netuid, |total| *total = total.saturating_add(1)); } } - - // --- 8. Apply pending childkeys of this subnet for the next epoch - for netuid in subnets.iter() { - Self::do_set_pending_children(*netuid); - } } pub fn drain_pending_emission( From ef65dc4527d6ff0c2439a5ffb06e922422b3a12d Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 12 Feb 2025 12:59:39 -0500 Subject: [PATCH 26/39] add negation for pow-reg-allowed --- pallets/subtensor/src/coinbase/run_coinbase.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/subtensor/src/coinbase/run_coinbase.rs b/pallets/subtensor/src/coinbase/run_coinbase.rs index d0a668f92c..9930451bce 100644 --- a/pallets/subtensor/src/coinbase/run_coinbase.rs +++ b/pallets/subtensor/src/coinbase/run_coinbase.rs @@ -87,7 +87,7 @@ impl Pallet { let alpha_out_i = alpha_emission_i; // Only emit TAO if the subnetwork allows registration. if !Self::get_network_registration_allowed(*netuid_i) - && Self::get_network_pow_registration_allowed(*netuid_i) + && !Self::get_network_pow_registration_allowed(*netuid_i) { tao_in_i = asfloat!(0.0); } From a7aac95951cbdb647b119d439776b242a1e3a557 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 12 Feb 2025 16:28:34 -0500 Subject: [PATCH 27/39] only root can set min pow diff --- pallets/admin-utils/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index e8f37526e0..7bcceb8edf 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -158,7 +158,7 @@ pub mod pallet { netuid: u16, min_difficulty: u64, ) -> DispatchResult { - pallet_subtensor::Pallet::::ensure_subnet_owner_or_root(origin, netuid)?; + pallet_subtensor::Pallet::::ensure_root(origin, netuid)?; ensure!( pallet_subtensor::Pallet::::if_subnet_exist(netuid), From 4fd4757783971137bf1f5093012b617a91560f62 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 12 Feb 2025 16:29:28 -0500 Subject: [PATCH 28/39] oops --- pallets/admin-utils/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pallets/admin-utils/src/lib.rs b/pallets/admin-utils/src/lib.rs index 7bcceb8edf..9cb51e1b27 100644 --- a/pallets/admin-utils/src/lib.rs +++ b/pallets/admin-utils/src/lib.rs @@ -158,7 +158,7 @@ pub mod pallet { netuid: u16, min_difficulty: u64, ) -> DispatchResult { - pallet_subtensor::Pallet::::ensure_root(origin, netuid)?; + ensure_root(origin)?; ensure!( pallet_subtensor::Pallet::::if_subnet_exist(netuid), From e538804c28d1471066b5d89ae7db21fd31c258e8 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 12 Feb 2025 16:46:49 -0500 Subject: [PATCH 29/39] dont let ck-in-swap-sched move any stake/register --- pallets/subtensor/src/lib.rs | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 58406e516a..4399b25a31 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1885,6 +1885,12 @@ where netuid, amount_staked, }) => { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); + } // Fully validate the user input Self::result_to_validity(Pallet::::validate_add_stake( who, @@ -1902,6 +1908,13 @@ where limit_price, allow_partial, }) => { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); + } + // Calcaulate the maximum amount that can be executed with price limit let max_amount = Pallet::::get_max_amount_add(*netuid, *limit_price); @@ -1957,6 +1970,13 @@ where destination_netuid, alpha_amount, }) => { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); + } + // Fully validate the user input Self::result_to_validity(Pallet::::validate_stake_transition( who, @@ -1978,6 +1998,13 @@ where destination_netuid, alpha_amount, }) => { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); + } + // Fully validate the user input Self::result_to_validity(Pallet::::validate_stake_transition( who, @@ -1998,6 +2025,13 @@ where destination_netuid, alpha_amount, }) => { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); + } + // Fully validate the user input Self::result_to_validity(Pallet::::validate_stake_transition( who, @@ -2020,6 +2054,13 @@ where limit_price, allow_partial, }) => { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); + } + // Get the max amount possible to exchange let max_amount = Pallet::::get_max_amount_move( *origin_netuid, @@ -2042,6 +2083,13 @@ where )) } Some(Call::register { netuid, .. } | Call::burned_register { netuid, .. }) => { + if ColdkeySwapScheduled::::contains_key(who) { + return InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into(), + ) + .into(); + } + let registrations_this_interval = Pallet::::get_registrations_this_interval(*netuid); let max_registrations_per_interval = From 8f197a29cf66a72703e6014bdf50ab810e60b4f9 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 12 Feb 2025 17:32:50 -0500 Subject: [PATCH 30/39] add tests for validation filter --- pallets/subtensor/src/tests/swap_coldkey.rs | 327 +++++++++++++++++++- 1 file changed, 326 insertions(+), 1 deletion(-) diff --git a/pallets/subtensor/src/tests/swap_coldkey.rs b/pallets/subtensor/src/tests/swap_coldkey.rs index 7761005780..d7f7123341 100644 --- a/pallets/subtensor/src/tests/swap_coldkey.rs +++ b/pallets/subtensor/src/tests/swap_coldkey.rs @@ -1726,7 +1726,7 @@ fn test_schedule_swap_coldkey_duplicate() { }); } -// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --test swap_coldkey -- test_schedule_swap_coldkey_execution --exact --nocapture +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_schedule_swap_coldkey_execution --exact --show-output --nocapture #[test] fn test_schedule_swap_coldkey_execution() { new_test_ext(1).execute_with(|| { @@ -2022,3 +2022,328 @@ fn test_cant_schedule_swap_without_enough_to_burn() { ); }); } + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_coldkey_in_swap_schedule_prevents_funds_usage --exact --show-output --nocapture +#[test] +fn test_coldkey_in_swap_schedule_prevents_funds_usage() { + // Testing the signed extension validate function + // correctly filters transactions that attempt to use funds + // while a coldkey swap is scheduled. + + new_test_ext(0).execute_with(|| { + let netuid: u16 = 1; + let version_key: u64 = 0; + let coldkey = U256::from(0); + let new_coldkey = U256::from(1); + let hotkey: U256 = U256::from(2); // Add the hotkey field + assert_ne!(hotkey, coldkey); // Ensure hotkey is NOT the same as coldkey !!! + let fee = DefaultStakingFee::::get(); + + let who = coldkey; // The coldkey signs this transaction + + // Disallowed transactions are + // - add_stake + // - add_stake_limit + // - swap_stake + // - swap_stake_limit + // - move_stake + // - transfer_stake + // - balances.transfer_all + // - balances.transfer_allow_death + // - balances.transfer_keep_alive + + // Allowed transactions are: + // - remove_stake + // - remove_stake_limit + // others... + + // Create netuid + add_network(netuid, 1, 0); + // Register the hotkey + SubtensorModule::append_neuron(netuid, &hotkey, 0); + crate::Owner::::insert(hotkey, coldkey); + + SubtensorModule::add_balance_to_coldkey_account(&who, u64::MAX); + + // Set the minimum stake to 0. + SubtensorModule::set_stake_threshold(0); + // Add stake to the hotkey + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(who), + hotkey, + netuid, + 100_000_000_000 + )); + + // Schedule the coldkey for a swap + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(who), + new_coldkey + )); + + assert!(ColdkeySwapScheduled::::contains_key(who)); + + // Setup the extension + let info: crate::DispatchInfo = + crate::DispatchInfoOf::<::RuntimeCall>::default(); + let extension = crate::SubtensorSignedExtension::::new(); + + // Try each call + + // Add stake + let call = RuntimeCall::SubtensorModule(SubtensorCall::add_stake { + hotkey, + netuid, + amount_staked: 100_000_000_000, + }); + let result: Result = + extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Add stake limit + let call = RuntimeCall::SubtensorModule(SubtensorCall::add_stake_limit { + hotkey, + netuid, + amount_staked: 100_000_000_000, + limit_price: 100_000_000_000, + allow_partial: false, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Swap stake + let call = RuntimeCall::SubtensorModule(SubtensorCall::swap_stake { + hotkey, + origin_netuid: netuid, + destination_netuid: netuid, + alpha_amount: 100_000_000_000, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Swap stake limit + let call = RuntimeCall::SubtensorModule(SubtensorCall::swap_stake_limit { + hotkey, + origin_netuid: netuid, + destination_netuid: netuid, + alpha_amount: 100_000_000_000, + limit_price: 100_000_000_000, + allow_partial: false, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Move stake + let call = RuntimeCall::SubtensorModule(SubtensorCall::move_stake { + origin_hotkey: hotkey, + destination_hotkey: hotkey, + origin_netuid: netuid, + destination_netuid: netuid, + alpha_amount: 100_000_000_000, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Transfer stake + let call = RuntimeCall::SubtensorModule(SubtensorCall::transfer_stake { + destination_coldkey: new_coldkey, + hotkey, + origin_netuid: netuid, + destination_netuid: netuid, + alpha_amount: 100_000_000_000, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Transfer all + let call = RuntimeCall::Balances(BalancesCall::transfer_all { + dest: new_coldkey, + keep_alive: false, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Transfer keep alive + let call = RuntimeCall::Balances(BalancesCall::transfer_keep_alive { + dest: new_coldkey, + value: 100_000_000_000, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Transfer allow death + let call = RuntimeCall::Balances(BalancesCall::transfer_allow_death { + dest: new_coldkey, + value: 100_000_000_000, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Burned register + let call = RuntimeCall::SubtensorModule(SubtensorCall::burned_register { netuid, hotkey }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + + // Remove stake + let call = RuntimeCall::SubtensorModule(SubtensorCall::remove_stake { + hotkey, + netuid, + amount_unstaked: 1_000_000, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should pass, not in list. + assert_ok!(result); + + // Remove stake limit + let call = RuntimeCall::SubtensorModule(SubtensorCall::remove_stake_limit { + hotkey, + netuid, + amount_unstaked: 1_000_000, + limit_price: 123456789, // should be low enough + allow_partial: true, + }); + let result = extension.validate(&who, &call.clone(), &info, 10); + // Should pass, not in list. + assert_ok!(result); + }); +} + +// SKIP_WASM_BUILD=1 RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::swap_coldkey::test_coldkey_in_swap_schedule_prevents_critical_calls --exact --show-output --nocapture +#[test] +fn test_coldkey_in_swap_schedule_prevents_critical_calls() { + // Testing the signed extension validate function + // correctly filters transactions that are critical + // while a coldkey swap is scheduled. + + new_test_ext(0).execute_with(|| { + let netuid: u16 = 1; + let version_key: u64 = 0; + let coldkey = U256::from(0); + let new_coldkey = U256::from(1); + let hotkey: U256 = U256::from(2); // Add the hotkey field + assert_ne!(hotkey, coldkey); // Ensure hotkey is NOT the same as coldkey !!! + let fee = DefaultStakingFee::::get(); + + let who = coldkey; // The coldkey signs this transaction + + // Disallowed transactions are + // - dissolve_network + + // Create netuid + add_network(netuid, 1, 0); + // Register the hotkey + SubtensorModule::append_neuron(netuid, &hotkey, 0); + crate::Owner::::insert(hotkey, coldkey); + + SubtensorModule::add_balance_to_coldkey_account(&who, u64::MAX); + + // Set the minimum stake to 0. + SubtensorModule::set_stake_threshold(0); + // Add stake to the hotkey + assert_ok!(SubtensorModule::add_stake( + <::RuntimeOrigin>::signed(who), + hotkey, + netuid, + 100_000_000_000 + )); + + // Schedule the coldkey for a swap + assert_ok!(SubtensorModule::schedule_swap_coldkey( + <::RuntimeOrigin>::signed(who), + new_coldkey + )); + + assert!(ColdkeySwapScheduled::::contains_key(who)); + + // Setup the extension + let info: crate::DispatchInfo = + crate::DispatchInfoOf::<::RuntimeCall>::default(); + let extension = crate::SubtensorSignedExtension::::new(); + + // Try each call + + // Dissolve network + let call = + RuntimeCall::SubtensorModule(SubtensorCall::dissolve_network { netuid, coldkey }); + let result: Result = + extension.validate(&who, &call.clone(), &info, 10); + // Should fail + assert_err!( + // Should get an invalid transaction error + result, + crate::TransactionValidityError::Invalid(crate::InvalidTransaction::Custom( + CustomTransactionError::ColdkeyInSwapSchedule.into() + )) + ); + }); +} From 5b3d4e66e37831932450debd47fd1a6276c58763 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 12 Feb 2025 17:33:21 -0500 Subject: [PATCH 31/39] add transfer stake to call nontransfer proxy filter --- runtime/src/lib.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 26bf16206f..f3b7535b55 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -726,7 +726,15 @@ impl InstanceFilter for ProxyType { fn filter(&self, c: &RuntimeCall) -> bool { match self { ProxyType::Any => true, - ProxyType::NonTransfer => !matches!(c, RuntimeCall::Balances(..)), + ProxyType::NonTransfer => !matches!( + c, + RuntimeCall::Balances(..) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::transfer_stake { .. }) + | RuntimeCall::SubtensorModule( + pallet_subtensor::Call::schedule_swap_coldkey { .. } + ) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::swap_coldkey { .. }) + ), ProxyType::NonFungibile => !matches!( c, RuntimeCall::Balances(..) From 45a67fcd88c56de47a3ce6539a0654a8e013e01c Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 12 Feb 2025 17:40:06 -0500 Subject: [PATCH 32/39] also add proxy filters for new calls --- runtime/src/lib.rs | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index f3b7535b55..b8c48d3802 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -739,12 +739,25 @@ impl InstanceFilter for ProxyType { c, RuntimeCall::Balances(..) | RuntimeCall::SubtensorModule(pallet_subtensor::Call::add_stake { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::add_stake_limit { .. }) | RuntimeCall::SubtensorModule(pallet_subtensor::Call::remove_stake { .. }) + | RuntimeCall::SubtensorModule( + pallet_subtensor::Call::remove_stake_limit { .. } + ) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::unstake_all { .. }) + | RuntimeCall::SubtensorModule( + pallet_subtensor::Call::unstake_all_alpha { .. } + ) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::swap_stake { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::swap_stake_limit { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::move_stake { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::transfer_stake { .. }) | RuntimeCall::SubtensorModule(pallet_subtensor::Call::burned_register { .. }) | RuntimeCall::SubtensorModule(pallet_subtensor::Call::root_register { .. }) | RuntimeCall::SubtensorModule( pallet_subtensor::Call::schedule_swap_coldkey { .. } ) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::swap_coldkey { .. }) | RuntimeCall::SubtensorModule(pallet_subtensor::Call::swap_hotkey { .. }) ), ProxyType::Transfer => matches!( @@ -752,6 +765,7 @@ impl InstanceFilter for ProxyType { RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { .. }) | RuntimeCall::Balances(pallet_balances::Call::transfer_allow_death { .. }) | RuntimeCall::Balances(pallet_balances::Call::transfer_all { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::transfer_stake { .. }) ), ProxyType::SmallTransfer => match c { RuntimeCall::Balances(pallet_balances::Call::transfer_keep_alive { @@ -761,6 +775,10 @@ impl InstanceFilter for ProxyType { value, .. }) => *value < SMALL_TRANSFER_LIMIT, + RuntimeCall::SubtensorModule(pallet_subtensor::Call::transfer_stake { + alpha_amount, + .. + }) => *alpha_amount < SMALL_TRANSFER_LIMIT, _ => false, }, ProxyType::Owner => matches!(c, RuntimeCall::AdminUtils(..)), @@ -788,6 +806,17 @@ impl InstanceFilter for ProxyType { c, RuntimeCall::SubtensorModule(pallet_subtensor::Call::add_stake { .. }) | RuntimeCall::SubtensorModule(pallet_subtensor::Call::remove_stake { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::unstake_all { .. }) + | RuntimeCall::SubtensorModule( + pallet_subtensor::Call::unstake_all_alpha { .. } + ) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::swap_stake { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::swap_stake_limit { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::move_stake { .. }) + | RuntimeCall::SubtensorModule(pallet_subtensor::Call::add_stake_limit { .. }) + | RuntimeCall::SubtensorModule( + pallet_subtensor::Call::remove_stake_limit { .. } + ) ), ProxyType::Registration => matches!( c, From bf1933c503fec69bd382e8cef9f2e2996b37cd1f Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:40:18 -0800 Subject: [PATCH 33/39] update staking priority --- pallets/subtensor/src/lib.rs | 217 ++++++++++++------- pallets/subtensor/src/staking/stake_utils.rs | 10 + 2 files changed, 145 insertions(+), 82 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 58406e516a..b7243ae5e0 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1550,6 +1550,18 @@ pub mod pallet { pub type RevealPeriodEpochs = StorageMap<_, Twox64Concat, u16, u64, ValueQuery, DefaultRevealPeriodEpochs>; + #[pallet::storage] + /// --- Map (coldkey, hotkey) --> u64 the last block at which stake was added/removed. + pub type LastColdkeyHotkeyStakeBlock = StorageDoubleMap< + _, + Twox64Concat, + T::AccountId, + Twox64Concat, + T::AccountId, + u64, + OptionQuery, + >; + /// ================== /// ==== Genesis ===== /// ================== @@ -1588,6 +1600,19 @@ pub mod pallet { 0 } + /// Returns the transaction priority for stake operations. + pub fn get_priority_staking(coldkey: &T::AccountId, hotkey: &T::AccountId) -> u64 { + match LastColdkeyHotkeyStakeBlock::::get(coldkey, hotkey) { + Some(last_stake_block) => { + let current_block_number = Self::get_current_block_as_u64(); + let default_priority = current_block_number.saturating_sub(last_stake_block); + + default_priority.saturating_add(u32::MAX as u64) + } + None => 0, + } + } + /// Is the caller allowed to set weights pub fn check_weights_min_stake(hotkey: &T::AccountId, netuid: u16) -> bool { // Blacklist weights transactions for low stake peers. @@ -1705,11 +1730,15 @@ where Pallet::::get_priority_set_weights(who, netuid) } + pub fn get_priority_staking(coldkey: &T::AccountId, hotkey: &T::AccountId) -> u64 { + Pallet::::get_priority_staking(coldkey, hotkey) + } + pub fn check_weights_min_stake(who: &T::AccountId, netuid: u16) -> bool { Pallet::::check_weights_min_stake(who, netuid) } - pub fn result_to_validity(result: Result<(), Error>) -> TransactionValidity { + pub fn result_to_validity(result: Result<(), Error>, priority: u64) -> TransactionValidity { if let Err(err) = result { match err { Error::::AmountTooLow => Err(InvalidTransaction::Custom( @@ -1750,7 +1779,7 @@ where } } else { Ok(ValidTransaction { - priority: Self::get_priority_vanilla(), + priority: priority, ..Default::default() }) } @@ -1886,14 +1915,17 @@ where amount_staked, }) => { // Fully validate the user input - Self::result_to_validity(Pallet::::validate_add_stake( - who, - hotkey, - *netuid, - *amount_staked, - *amount_staked, - false, - )) + Self::result_to_validity( + Pallet::::validate_add_stake( + who, + hotkey, + *netuid, + *amount_staked, + *amount_staked, + false, + ), + Self::get_priority_staking(who, hotkey), + ) } Some(Call::add_stake_limit { hotkey, @@ -1906,14 +1938,17 @@ where let max_amount = Pallet::::get_max_amount_add(*netuid, *limit_price); // Fully validate the user input - Self::result_to_validity(Pallet::::validate_add_stake( - who, - hotkey, - *netuid, - *amount_staked, - max_amount, - *allow_partial, - )) + Self::result_to_validity( + Pallet::::validate_add_stake( + who, + hotkey, + *netuid, + *amount_staked, + max_amount, + *allow_partial, + ), + Self::get_priority_vanilla(), + ) } Some(Call::remove_stake { hotkey, @@ -1921,14 +1956,17 @@ where amount_unstaked, }) => { // Fully validate the user input - Self::result_to_validity(Pallet::::validate_remove_stake( - who, - hotkey, - *netuid, - *amount_unstaked, - *amount_unstaked, - false, - )) + Self::result_to_validity( + Pallet::::validate_remove_stake( + who, + hotkey, + *netuid, + *amount_unstaked, + *amount_unstaked, + false, + ), + Self::get_priority_staking(who, hotkey), + ) } Some(Call::remove_stake_limit { hotkey, @@ -1941,14 +1979,17 @@ where let max_amount = Pallet::::get_max_amount_remove(*netuid, *limit_price); // Fully validate the user input - Self::result_to_validity(Pallet::::validate_remove_stake( - who, - hotkey, - *netuid, - *amount_unstaked, - max_amount, - *allow_partial, - )) + Self::result_to_validity( + Pallet::::validate_remove_stake( + who, + hotkey, + *netuid, + *amount_unstaked, + max_amount, + *allow_partial, + ), + Self::get_priority_vanilla(), + ) } Some(Call::move_stake { origin_hotkey, @@ -1958,18 +1999,21 @@ where alpha_amount, }) => { // Fully validate the user input - Self::result_to_validity(Pallet::::validate_stake_transition( - who, - who, - origin_hotkey, - destination_hotkey, - *origin_netuid, - *destination_netuid, - *alpha_amount, - *alpha_amount, - None, - false, - )) + Self::result_to_validity( + Pallet::::validate_stake_transition( + who, + who, + origin_hotkey, + destination_hotkey, + *origin_netuid, + *destination_netuid, + *alpha_amount, + *alpha_amount, + None, + false, + ), + Self::get_priority_vanilla(), + ) } Some(Call::transfer_stake { destination_coldkey, @@ -1979,18 +2023,21 @@ where alpha_amount, }) => { // Fully validate the user input - Self::result_to_validity(Pallet::::validate_stake_transition( - who, - destination_coldkey, - hotkey, - hotkey, - *origin_netuid, - *destination_netuid, - *alpha_amount, - *alpha_amount, - None, - true, - )) + Self::result_to_validity( + Pallet::::validate_stake_transition( + who, + destination_coldkey, + hotkey, + hotkey, + *origin_netuid, + *destination_netuid, + *alpha_amount, + *alpha_amount, + None, + true, + ), + Self::get_priority_vanilla(), + ) } Some(Call::swap_stake { hotkey, @@ -1999,18 +2046,21 @@ where alpha_amount, }) => { // Fully validate the user input - Self::result_to_validity(Pallet::::validate_stake_transition( - who, - who, - hotkey, - hotkey, - *origin_netuid, - *destination_netuid, - *alpha_amount, - *alpha_amount, - None, - false, - )) + Self::result_to_validity( + Pallet::::validate_stake_transition( + who, + who, + hotkey, + hotkey, + *origin_netuid, + *destination_netuid, + *alpha_amount, + *alpha_amount, + None, + false, + ), + Self::get_priority_vanilla(), + ) } Some(Call::swap_stake_limit { hotkey, @@ -2028,18 +2078,21 @@ where ); // Fully validate the user input - Self::result_to_validity(Pallet::::validate_stake_transition( - who, - who, - hotkey, - hotkey, - *origin_netuid, - *destination_netuid, - *alpha_amount, - max_amount, - Some(*allow_partial), - false, - )) + Self::result_to_validity( + Pallet::::validate_stake_transition( + who, + who, + hotkey, + hotkey, + *origin_netuid, + *destination_netuid, + *alpha_amount, + max_amount, + Some(*allow_partial), + false, + ), + Self::get_priority_vanilla(), + ) } Some(Call::register { netuid, .. } | Call::burned_register { netuid, .. }) => { let registrations_this_interval = diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index 1be858529d..cf55f9f5e0 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -748,6 +748,11 @@ impl Pallet { TotalStake::::mutate(|total| { *total = total.saturating_add(actual_fee); }); + LastColdkeyHotkeyStakeBlock::::insert( + &coldkey, + &hotkey, + Self::get_current_block_as_u64(), + ); // Step 5. Deposit and log the unstaking event. Self::deposit_event(Event::StakeRemoved( @@ -807,6 +812,11 @@ impl Pallet { TotalStake::::mutate(|total| { *total = total.saturating_add(actual_fee); }); + LastColdkeyHotkeyStakeBlock::::insert( + &coldkey, + &hotkey, + Self::get_current_block_as_u64(), + ); // Step 6. Deposit and log the staking event. Self::deposit_event(Event::StakeAdded( From 9dce4e73c26a8bbed86838a44088d105f0d36340 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Wed, 12 Feb 2025 17:43:09 -0500 Subject: [PATCH 34/39] bump spec --- 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 b05e21304d8915d16e5f8e41e0a8ed4846c5f3a6 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:58:29 -0800 Subject: [PATCH 35/39] use get_priority_staking for all stake operations --- pallets/subtensor/src/lib.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index b7243ae5e0..7aadfd39c6 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1947,7 +1947,7 @@ where max_amount, *allow_partial, ), - Self::get_priority_vanilla(), + Self::get_priority_staking(who, hotkey), ) } Some(Call::remove_stake { @@ -1988,7 +1988,7 @@ where max_amount, *allow_partial, ), - Self::get_priority_vanilla(), + Self::get_priority_staking(who, hotkey), ) } Some(Call::move_stake { @@ -2012,7 +2012,7 @@ where None, false, ), - Self::get_priority_vanilla(), + Self::get_priority_staking(who, origin_hotkey), ) } Some(Call::transfer_stake { @@ -2036,7 +2036,7 @@ where None, true, ), - Self::get_priority_vanilla(), + Self::get_priority_staking(who, hotkey), ) } Some(Call::swap_stake { @@ -2059,7 +2059,7 @@ where None, false, ), - Self::get_priority_vanilla(), + Self::get_priority_staking(who, hotkey), ) } Some(Call::swap_stake_limit { @@ -2091,7 +2091,7 @@ where Some(*allow_partial), false, ), - Self::get_priority_vanilla(), + Self::get_priority_staking(who, hotkey), ) } Some(Call::register { netuid, .. } | Call::burned_register { netuid, .. }) => { From f5d4708ee217242c3efb11868fe6de09ba9971f2 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 12 Feb 2025 14:59:23 -0800 Subject: [PATCH 36/39] bump spec --- 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 1916e1cb089ea5f2ae18d2e8e7b44f820269ba11 Mon Sep 17 00:00:00 2001 From: John Reed <87283488+JohnReedV@users.noreply.github.com> Date: Wed, 12 Feb 2025 15:02:13 -0800 Subject: [PATCH 37/39] clippy --- pallets/subtensor/src/lib.rs | 2 +- pallets/subtensor/src/staking/stake_utils.rs | 12 ++---------- 2 files changed, 3 insertions(+), 11 deletions(-) diff --git a/pallets/subtensor/src/lib.rs b/pallets/subtensor/src/lib.rs index 7aadfd39c6..b0a927c91b 100644 --- a/pallets/subtensor/src/lib.rs +++ b/pallets/subtensor/src/lib.rs @@ -1779,7 +1779,7 @@ where } } else { Ok(ValidTransaction { - priority: priority, + priority, ..Default::default() }) } diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index cf55f9f5e0..3543c1a232 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -748,11 +748,7 @@ impl Pallet { TotalStake::::mutate(|total| { *total = total.saturating_add(actual_fee); }); - LastColdkeyHotkeyStakeBlock::::insert( - &coldkey, - &hotkey, - Self::get_current_block_as_u64(), - ); + LastColdkeyHotkeyStakeBlock::::insert(coldkey, hotkey, Self::get_current_block_as_u64()); // Step 5. Deposit and log the unstaking event. Self::deposit_event(Event::StakeRemoved( @@ -812,11 +808,7 @@ impl Pallet { TotalStake::::mutate(|total| { *total = total.saturating_add(actual_fee); }); - LastColdkeyHotkeyStakeBlock::::insert( - &coldkey, - &hotkey, - Self::get_current_block_as_u64(), - ); + LastColdkeyHotkeyStakeBlock::::insert(coldkey, hotkey, Self::get_current_block_as_u64()); // Step 6. Deposit and log the staking event. Self::deposit_event(Event::StakeAdded( From 185841b7fc7e37fa09a1081305c4c0fbabe1211d Mon Sep 17 00:00:00 2001 From: Greg Zaitsev Date: Wed, 12 Feb 2025 18:02:34 -0500 Subject: [PATCH 38/39] Remove ownership check from transition stake validation --- pallets/subtensor/src/staking/stake_utils.rs | 6 ---- pallets/subtensor/src/tests/move_stake.rs | 38 ++++++++++++++++++-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index 1be858529d..03c288ebef 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -960,12 +960,6 @@ impl Pallet { Error::::HotKeyAccountNotExists ); - // Ensure origin coldkey owns the origin hotkey. - ensure!( - Self::coldkey_owns_hotkey(origin_coldkey, origin_hotkey), - Error::::NonAssociatedColdKey - ); - // Ensure there is enough stake in the origin subnet. let origin_alpha = Self::get_stake_for_hotkey_and_coldkey_on_subnet( origin_hotkey, diff --git a/pallets/subtensor/src/tests/move_stake.rs b/pallets/subtensor/src/tests/move_stake.rs index ce0ce37fce..15832b93fe 100644 --- a/pallets/subtensor/src/tests/move_stake.rs +++ b/pallets/subtensor/src/tests/move_stake.rs @@ -541,7 +541,7 @@ fn test_do_move_wrong_origin() { netuid, alpha, ), - Error::::NonAssociatedColdKey + Error::::NotEnoughStakeToWithdraw ); // Check that no stake was moved @@ -981,7 +981,7 @@ fn test_do_transfer_wrong_origin() { netuid, stake_amount ), - Error::::NonAssociatedColdKey + Error::::NotEnoughStakeToWithdraw ); }); } @@ -1245,7 +1245,7 @@ fn test_do_swap_wrong_origin() { netuid2, stake_amount ), - Error::::NonAssociatedColdKey + Error::::NotEnoughStakeToWithdraw ); }); } @@ -1486,6 +1486,38 @@ fn test_do_swap_multiple_times() { }); } +// cargo test --package pallet-subtensor --lib -- tests::move_stake::test_do_swap_allows_non_owned_hotkey --exact --show-output +#[test] +fn test_do_swap_allows_non_owned_hotkey() { + new_test_ext(1).execute_with(|| { + let subnet_owner_coldkey = U256::from(1001); + let subnet_owner_hotkey = U256::from(1002); + let origin_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + let destination_netuid = add_dynamic_network(&subnet_owner_hotkey, &subnet_owner_coldkey); + + let coldkey = U256::from(1); + let hotkey = U256::from(2); + let foreign_coldkey = U256::from(3); + let stake_amount = DefaultMinStake::::get() * 10; + + SubtensorModule::create_account_if_non_existent(&foreign_coldkey, &hotkey); + SubtensorModule::stake_into_subnet(&hotkey, &coldkey, origin_netuid, stake_amount, 0); + let alpha_before = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey, + &coldkey, + origin_netuid, + ); + + assert_ok!(SubtensorModule::do_swap_stake( + RuntimeOrigin::signed(coldkey), + hotkey, + origin_netuid, + destination_netuid, + alpha_before, + )); + }); +} + // cargo test --package pallet-subtensor --lib -- tests::move_stake::test_swap_stake_limit_validate --exact --show-output #[test] fn test_swap_stake_limit_validate() { From 3bcf42890a0fc99938c6e8be1a4551f63b41d7f8 Mon Sep 17 00:00:00 2001 From: Cameron Fairchild Date: Thu, 13 Feb 2025 15:14:14 -0500 Subject: [PATCH 39/39] max the price for EMA calc at 1.0 --- pallets/subtensor/src/staking/stake_utils.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index a8b7a1cedb..854fb07cb9 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -59,7 +59,8 @@ impl Pallet { pub fn update_moving_price(netuid: u16) { let alpha: I96F32 = SubnetMovingAlpha::::get(); let minus_alpha: I96F32 = I96F32::saturating_from_num(1.0).saturating_sub(alpha); - let current_price: I96F32 = alpha.saturating_mul(Self::get_alpha_price(netuid)); + let current_price: I96F32 = alpha + .saturating_mul(Self::get_alpha_price(netuid).min(I96F32::saturating_from_num(1.0))); let current_moving: I96F32 = minus_alpha.saturating_mul(Self::get_moving_alpha_price(netuid)); let new_moving: I96F32 = current_price.saturating_add(current_moving);