From 58ed35d0b76fdea26e51089306d22429366272fa Mon Sep 17 00:00:00 2001 From: Aliaksandr Tsurko Date: Tue, 4 Feb 2025 17:17:59 +0100 Subject: [PATCH 01/10] Rewrite balance transfer precompile with precompile utils --- Cargo.lock | 45 +++++++++++++++++++++ runtime/Cargo.toml | 2 + runtime/src/precompiles/balance_transfer.rs | 41 +++++++++---------- runtime/src/precompiles/mod.rs | 8 ++-- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 42522da321..ed9e74c9f3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1068,6 +1068,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "case" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6c0e7b807d60291f42f33f58480c0bfafe28ed08286446f45e463728cf9c1c" + [[package]] name = "cc" version = "1.2.10" @@ -5866,6 +5872,7 @@ dependencies = [ "pallet-transaction-payment-rpc-runtime-api", "pallet-utility", "parity-scale-codec", + "precompile-utils", "rand_chacha", "scale-info", "serde_json", @@ -7253,6 +7260,44 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "precompile-utils" +version = "0.1.0" +source = "git+https://github.com/opentensor/frontier?rev=635bdac882#635bdac882333afed827053f31ef56ab739f7a2e" +dependencies = [ + "environmental", + "evm", + "fp-evm", + "frame-support", + "frame-system", + "hex", + "impl-trait-for-tuples", + "log", + "num_enum", + "pallet-evm", + "parity-scale-codec", + "precompile-utils-macro", + "sp-core", + "sp-io", + "sp-runtime", + "sp-weights", + "staging-xcm", +] + +[[package]] +name = "precompile-utils-macro" +version = "0.1.0" +source = "git+https://github.com/opentensor/frontier?rev=635bdac882#635bdac882333afed827053f31ef56ab739f7a2e" +dependencies = [ + "case", + "num_enum", + "prettyplease 0.2.29", + "proc-macro2", + "quote", + "sp-crypto-hashing 0.1.0 (git+https://github.com/paritytech/polkadot-sdk.git?tag=polkadot-stable2409)", + "syn 1.0.109", +] + [[package]] name = "predicates" version = "2.1.5" diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 171ef3c477..f329fa1219 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -100,6 +100,7 @@ pallet-commitments = { default-features = false, path = "../pallets/commitments" fp-evm = { workspace = true } fp-rpc = { workspace = true } fp-self-contained = { workspace = true } +precompile-utils = { workspace = true } # Frontier FRAME pallet-base-fee = { workspace = true } @@ -164,6 +165,7 @@ std = [ "pallet-scheduler/std", "pallet-preimage/std", "pallet-commitments/std", + "precompile-utils/std", "sp-api/std", "sp-block-builder/std", "sp-consensus-aura/std", diff --git a/runtime/src/precompiles/balance_transfer.rs b/runtime/src/precompiles/balance_transfer.rs index 6154cf8a52..f0185a75e9 100644 --- a/runtime/src/precompiles/balance_transfer.rs +++ b/runtime/src/precompiles/balance_transfer.rs @@ -1,8 +1,14 @@ +use core::marker::PhantomData; + use pallet_evm::{ - BalanceConverter, ExitError, ExitSucceed, PrecompileHandle, PrecompileOutput, PrecompileResult, + BalanceConverter, ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle, + PrecompileOutput, PrecompileResult, }; +use precompile_utils::EvmResult; +use sp_core::H256; use sp_runtime::traits::UniqueSaturatedInto; -use sp_std::vec; +use sp_runtime::AccountId32; +use sp_std::vec::Vec; use crate::precompiles::{ contract_to_origin, get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call, @@ -19,20 +25,11 @@ const CONTRACT_ADDRESS_SS58: [u8; 32] = [ pub struct BalanceTransferPrecompile; +#[precompile_utils::precompile] impl BalanceTransferPrecompile { - pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { - let txdata = handle.input(); - - // Match method ID: keccak256("transfer(bytes32)") - let method = get_slice(txdata, 0, 4)?; - if get_method_id("transfer(bytes32)") != method { - return Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: vec![], - }); - } - - // Forward all received value to the destination address + #[precompile::public("transfer(bytes32)")] + #[precompile::payable] + fn transfer(handle: &mut impl PrecompileHandle, address: H256) -> EvmResult<()> { let amount = handle.context().apparent_value; // Use BalanceConverter to convert EVM amount to Substrate balance @@ -41,20 +38,18 @@ impl BalanceTransferPrecompile { .ok_or(ExitError::OutOfFund)?; if amount_sub.is_zero() { - return Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: vec![], - }); + return Ok(()); } - let address_bytes_dst = get_slice(txdata, 4, 36)?; - let (account_id_dst, _) = get_pubkey(address_bytes_dst)?; + let dest = get_pubkey(address.as_bytes())?.0.into(); let call = pallet_balances::Call::::transfer_allow_death { - dest: account_id_dst.into(), + dest, value: amount_sub.unique_saturated_into(), }; - try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?) + try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?)?; + + Ok(()) } } diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index d820f50ec3..5934ab90ab 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -4,7 +4,7 @@ use alloc::format; use core::marker::PhantomData; use frame_support::dispatch::{GetDispatchInfo, Pays}; - +use frame_system::RawOrigin; use pallet_evm::{ ExitError, ExitSucceed, GasWeightMapping, IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet, @@ -14,13 +14,10 @@ use pallet_evm_precompile_sha3fips::Sha3FIPS256; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; use sp_core::{hashing::keccak_256, H160}; use sp_runtime::{traits::Dispatchable, AccountId32}; +use sp_std::vec; use crate::{Runtime, RuntimeCall}; -use frame_system::RawOrigin; - -use sp_std::vec; - // Include custom precompiles mod balance_transfer; mod ed25519; @@ -35,6 +32,7 @@ use metagraph::*; use neuron::*; use staking::*; use subnet::*; + pub struct FrontierPrecompiles(PhantomData); impl Default for FrontierPrecompiles where From 126f78049d888c086f8f0e9dec66262710c28383 Mon Sep 17 00:00:00 2001 From: Aliaksandr Tsurko Date: Thu, 6 Feb 2025 20:49:10 +0100 Subject: [PATCH 02/10] Refactor staking and neuron precompile with precompile-utils --- runtime/src/precompiles/balance_transfer.rs | 4 +- runtime/src/precompiles/mod.rs | 16 +-- runtime/src/precompiles/neuron.rs | 67 ++++-------- runtime/src/precompiles/staking.rs | 110 ++++++++------------ runtime/src/precompiles/subnet.rs | 17 ++- 5 files changed, 90 insertions(+), 124 deletions(-) diff --git a/runtime/src/precompiles/balance_transfer.rs b/runtime/src/precompiles/balance_transfer.rs index f0185a75e9..ac4282056c 100644 --- a/runtime/src/precompiles/balance_transfer.rs +++ b/runtime/src/precompiles/balance_transfer.rs @@ -48,8 +48,6 @@ impl BalanceTransferPrecompile { value: amount_sub.unique_saturated_into(), }; - try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?)?; - - Ok(()) + try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?) } } diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index 5934ab90ab..b2a2fa595c 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -12,7 +12,8 @@ use pallet_evm::{ use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; -use sp_core::{hashing::keccak_256, H160}; +use precompile_utils::EvmResult; +use sp_core::{hashing::keccak_256, H160, U256}; use sp_runtime::{traits::Dispatchable, AccountId32}; use sp_std::vec; @@ -151,6 +152,12 @@ pub fn get_pubkey(data: &[u8]) -> Result<(AccountId32, vec::Vec), Precompile )) } +fn try_u16_from_u256(value: U256) -> Result { + u16::try_from(value.as_u32()).map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::Other("the value is outside of u16 bounds".into()), + }) +} + fn parse_netuid(data: &[u8], offset: usize) -> Result { if data.len() < offset + 2 { return Err(PrecompileFailure::Error { @@ -175,7 +182,7 @@ fn try_dispatch_runtime_call( handle: &mut impl PrecompileHandle, call: impl Into, origin: RawOrigin, -) -> PrecompileResult { +) -> EvmResult<()> { let call = Into::::into(call); let info = call.get_dispatch_info(); @@ -220,10 +227,7 @@ fn try_dispatch_runtime_call( log::info!("Dispatch succeeded. Post info: {:?}", post_info); - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: Default::default(), - }) + Ok(()) } Err(e) => { log::error!("Dispatch failed. Error: {:?}", e); diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 97167c9009..a9770241f0 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -1,62 +1,39 @@ -use pallet_evm::{ExitError, PrecompileFailure, PrecompileHandle, PrecompileResult}; - -use crate::precompiles::{ - contract_to_origin, get_method_id, get_pubkey, get_slice, parse_netuid, - try_dispatch_runtime_call, -}; +use frame_system::RawOrigin; +use pallet_evm::{AddressMapping, HashedAddressMapping, PrecompileHandle}; +use precompile_utils::EvmResult; +use sp_core::H256; +use sp_runtime::traits::BlakeTwo256; use sp_runtime::AccountId32; -use sp_std::vec; +use crate::precompiles::{get_pubkey, try_dispatch_runtime_call}; 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. -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, -]; pub struct NeuronPrecompile; +#[precompile_utils::precompile] impl NeuronPrecompile { - pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { - let txdata = handle.input(); - let method_id = get_slice(txdata, 0, 4)?; - let method_input = txdata - .get(4..) - .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts - - match method_id { - id if id == get_method_id("burnedRegister(uint16,bytes32)") => { - Self::burned_register(handle, &method_input) - } - - _ => Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }), - } - } - - pub fn burned_register(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { - let (netuid, hotkey) = Self::parse_netuid_hotkey_parameter(data)?; + #[precompile::public("burnedRegister(uint16,bytes32)")] + #[precompile::payable] + fn burned_register( + handle: &mut impl PrecompileHandle, + netuid: u16, + hotkey: H256, + ) -> EvmResult<()> { + let coldkey = + as AddressMapping>::into_account_id( + handle.context().caller, + ); + let (hotkey, _) = get_pubkey(hotkey.as_bytes())?; let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::burned_register { netuid, hotkey, }); - try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?) - } - - fn parse_netuid_hotkey_parameter(data: &[u8]) -> Result<(u16, AccountId32), PrecompileFailure> { - if data.len() < 64 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - let netuid = parse_netuid(data, 30)?; - let (hotkey, _) = get_pubkey(get_slice(data, 32, 64)?)?; + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(coldkey))?; - Ok((netuid, hotkey)) + Ok(()) } } diff --git a/runtime/src/precompiles/staking.rs b/runtime/src/precompiles/staking.rs index 8cc1c879af..3374dfbf7e 100644 --- a/runtime/src/precompiles/staking.rs +++ b/runtime/src/precompiles/staking.rs @@ -25,20 +25,23 @@ // - Precompile checks the result of do_remove_stake and, in case of a failure, reverts the transaction. // -use crate::precompiles::{ - get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call, -}; -use crate::{ProxyType, Runtime, RuntimeCall}; use frame_system::RawOrigin; use pallet_evm::{ AddressMapping, BalanceConverter, ExitError, ExitSucceed, HashedAddressMapping, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; -use sp_core::U256; +use precompile_utils::EvmResult; +use sp_core::{H256, U256}; use sp_runtime::traits::{BlakeTwo256, Dispatchable, StaticLookup, UniqueSaturatedInto}; use sp_runtime::AccountId32; use sp_std::vec; +use crate::precompiles::{ + get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call, + try_u16_from_u256, +}; +use crate::{ProxyType, Runtime, RuntimeCall}; + pub const STAKING_PRECOMPILE_INDEX: u64 = 2049; // ss58 public key i.e., the contract sends funds it received to the destination address from the @@ -50,40 +53,17 @@ const CONTRACT_ADDRESS_SS58: [u8; 32] = [ pub struct StakingPrecompile; +#[precompile_utils::precompile] impl StakingPrecompile { - pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { - let txdata = handle.input(); - let method_id = get_slice(txdata, 0, 4)?; - let method_input = txdata - .get(4..) - .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts - - if method_id == get_method_id("addStake(bytes32,uint256)") { - Self::add_stake(handle, &method_input) - } else if method_id == get_method_id("removeStake(bytes32,uint256,uint256)") { - Self::remove_stake(handle, &method_input) - } else if method_id == get_method_id("getStake(bytes32,bytes32,uint256)") { - Self::get_stake(&method_input) - } else if method_id == get_method_id("addProxy(bytes32)") { - Self::add_proxy(handle, &method_input) - } else if method_id == get_method_id("removeProxy(bytes32)") { - Self::remove_proxy(handle, &method_input) - } else { - Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }) - } - } - - fn add_stake(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + #[precompile::public("addStake(bytes32,uint256)")] + #[precompile::payable] + fn add_stake(handle: &mut impl PrecompileHandle, address: H256, netuid: U256) -> EvmResult<()> { let account_id = as AddressMapping>::into_account_id( handle.context().caller, ); - let (hotkey, _) = get_pubkey(data)?; - let amount: U256 = handle.context().apparent_value; - let netuid = parse_netuid(data, 0x3E)?; + let amount = handle.context().apparent_value; if !amount.is_zero() { Self::transfer_back_to_caller(&account_id, amount)?; @@ -93,6 +73,8 @@ impl StakingPrecompile { ::BalanceConverter::into_substrate_balance(amount) .ok_or(ExitError::OutOfFund)?; + let (hotkey, _) = get_pubkey(address.as_bytes())?; + let netuid = try_u16_from_u256(netuid)?; let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::add_stake { hotkey, netuid, @@ -102,39 +84,40 @@ impl StakingPrecompile { try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } - fn remove_stake(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + #[precompile::public("removeStake(bytes32,uint256,uint256)")] + fn remove_stake( + handle: &mut impl PrecompileHandle, + address: H256, + amount: U256, + netuid: U256, + ) -> EvmResult<()> { let account_id = as AddressMapping>::into_account_id( handle.context().caller, ); - let (hotkey, _) = get_pubkey(data)?; - let netuid = parse_netuid(data, 0x5E)?; - - // We have to treat this as uint256 (because of Solidity ABI encoding rules, it pads uint64), - // but this will never exceed 8 bytes, se we will ignore higher bytes and will only use lower - // 8 bytes. - let amount = data - .get(56..64) - .map(U256::from_big_endian) - .ok_or(ExitError::OutOfFund)?; + let amount_sub = ::BalanceConverter::into_substrate_balance(amount) .ok_or(ExitError::OutOfFund)?; + let (hotkey, _) = get_pubkey(address.as_bytes())?; + let netuid = try_u16_from_u256(netuid)?; let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::remove_stake { hotkey, netuid, amount_unstaked: amount_sub.unique_saturated_into(), }); + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } - fn add_proxy(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + #[precompile::public("addProxy(bytes32)")] + fn add_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { let account_id = as AddressMapping>::into_account_id( handle.context().caller, ); - let (delegate, _) = get_pubkey(data)?; + let (delegate, _) = get_pubkey(delegate.as_bytes())?; let delegate = ::Lookup::unlookup(delegate); let call = RuntimeCall::Proxy(pallet_proxy::Call::::add_proxy { delegate, @@ -145,12 +128,13 @@ impl StakingPrecompile { try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } - fn remove_proxy(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { + #[precompile::public("removeProxy(bytes32)")] + fn remove_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { let account_id = as AddressMapping>::into_account_id( handle.context().caller, ); - let (delegate, _) = get_pubkey(data)?; + let (delegate, _) = get_pubkey(delegate.as_bytes())?; let delegate = ::Lookup::unlookup(delegate); let call = RuntimeCall::Proxy(pallet_proxy::Call::::remove_proxy { delegate, @@ -161,29 +145,25 @@ impl StakingPrecompile { try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) } - fn get_stake(data: &[u8]) -> PrecompileResult { - let (hotkey, left_data) = get_pubkey(data)?; - let (coldkey, _) = get_pubkey(&left_data)?; - let netuid = parse_netuid(data, 0x5E)?; + #[precompile::public("getStake(bytes32,bytes32,uint256)")] + #[precompile::view] + fn get_stake( + _: &mut impl PrecompileHandle, + hotkey: H256, + coldkey: H256, + netuid: U256, + ) -> EvmResult { + let (hotkey, _) = get_pubkey(hotkey.as_bytes())?; + let (coldkey, _) = get_pubkey(coldkey.as_bytes())?; + let netuid = try_u16_from_u256(netuid)?; let stake = pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, netuid, ); // Convert to EVM decimals - let stake_u256 = U256::from(stake); - let stake_eth = - ::BalanceConverter::into_evm_balance(stake_u256) - .ok_or(ExitError::InvalidRange)?; - - // Format output - let mut result = [0_u8; 32]; - U256::to_big_endian(&stake_eth, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + ::BalanceConverter::into_evm_balance(stake.into()) + .ok_or(ExitError::InvalidRange.into()) } fn transfer_back_to_caller( diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index 9944572c51..c730de7a76 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -1,13 +1,15 @@ -use crate::precompiles::{get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call}; -use crate::{Runtime, RuntimeCall}; use frame_system::RawOrigin; use pallet_evm::{ - AddressMapping, ExitError, HashedAddressMapping, PrecompileFailure, PrecompileHandle, - PrecompileResult, + AddressMapping, ExitError, ExitSucceed, HashedAddressMapping, PrecompileFailure, + PrecompileHandle, PrecompileOutput, PrecompileResult, }; use sp_runtime::traits::BlakeTwo256; use sp_runtime::AccountId32; use sp_std::vec; + +use crate::precompiles::{get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call}; +use crate::{Runtime, RuntimeCall}; + pub const SUBNET_PRECOMPILE_INDEX: u64 = 2051; // bytes with max lenght 1K pub const MAX_SINGLE_PARAMETER_SIZE: usize = 1024; @@ -21,6 +23,7 @@ const CONTRACT_ADDRESS_SS58: [u8; 32] = [ 0x3a, 0x86, 0x18, 0xfb, 0xbb, 0x1b, 0xbc, 0x47, 0x86, 0x64, 0xff, 0x53, 0x46, 0x18, 0x0c, 0x35, 0xd0, 0x9f, 0xac, 0x26, 0xf2, 0x02, 0x70, 0x85, 0xb3, 0x1c, 0x56, 0xc1, 0x06, 0x3c, 0x1c, 0xd3, ]; + pub struct SubnetPrecompile; impl SubnetPrecompile { @@ -93,7 +96,11 @@ impl SubnetPrecompile { ); // Dispatch the register_network call - try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; + Ok(PrecompileOutput { + exit_status: ExitSucceed::Returned, + output: Default::default(), + }) } fn parse_register_network_parameters( From fc3beb29d2bca9eae6fb889d04402a663b2dfeb4 Mon Sep 17 00:00:00 2001 From: Aliaksandr Tsurko Date: Thu, 13 Feb 2025 17:56:09 +0100 Subject: [PATCH 03/10] Fix number conversion issues in staking precompile --- runtime/src/precompiles/neuron.rs | 1 - runtime/src/precompiles/staking.rs | 17 ++++++++--------- runtime/src/precompiles/subnet.rs | 1 + 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index a24b506c7b..2951f190b1 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -12,7 +12,6 @@ use sp_std::vec::Vec; use crate::precompiles::{ get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call, - try_dispatch_runtime_call, }; use crate::{Runtime, RuntimeCall}; diff --git a/runtime/src/precompiles/staking.rs b/runtime/src/precompiles/staking.rs index 3374dfbf7e..c368df6ad3 100644 --- a/runtime/src/precompiles/staking.rs +++ b/runtime/src/precompiles/staking.rs @@ -71,7 +71,11 @@ impl StakingPrecompile { let amount_sub = ::BalanceConverter::into_substrate_balance(amount) - .ok_or(ExitError::OutOfFund)?; + .ok_or(PrecompileFailure::Error { + exit_status: ExitError::Other( + "error converting balance from ETH to subtensor".into(), + ), + })?; let (hotkey, _) = get_pubkey(address.as_bytes())?; let netuid = try_u16_from_u256(netuid)?; @@ -96,16 +100,13 @@ impl StakingPrecompile { handle.context().caller, ); - let amount_sub = - ::BalanceConverter::into_substrate_balance(amount) - .ok_or(ExitError::OutOfFund)?; - let (hotkey, _) = get_pubkey(address.as_bytes())?; let netuid = try_u16_from_u256(netuid)?; + let amount_unstaked = amount.unique_saturated_into(); let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::remove_stake { hotkey, netuid, - amount_unstaked: amount_sub.unique_saturated_into(), + amount_unstaked, }); try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) @@ -161,9 +162,7 @@ impl StakingPrecompile { &hotkey, &coldkey, netuid, ); - // Convert to EVM decimals - ::BalanceConverter::into_evm_balance(stake.into()) - .ok_or(ExitError::InvalidRange.into()) + Ok(stake.into()) } fn transfer_back_to_caller( diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index 56b47335c3..dbaad74e06 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -25,6 +25,7 @@ const CONTRACT_ADDRESS_SS58: [u8; 32] = [ pub struct SubnetPrecompile; +#[precompile_utils::precompile] impl SubnetPrecompile { // pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { // let txdata = handle.input(); From 49e5336b53c71d91d4c4d3b73d0b3c7544e4a787 Mon Sep 17 00:00:00 2001 From: Aliaksandr Tsurko Date: Fri, 14 Feb 2025 16:08:48 +0100 Subject: [PATCH 04/10] Refactor neuron precompil - introduce PrecompileHandle and Precompile trait extensions --- runtime/src/precompiles/balance_transfer.rs | 30 +- runtime/src/precompiles/ed25519.rs | 14 +- runtime/src/precompiles/metagraph.rs | 144 ++++--- runtime/src/precompiles/mod.rs | 180 ++++---- runtime/src/precompiles/neuron.rs | 445 +++----------------- runtime/src/precompiles/staking.rs | 93 ++-- runtime/src/precompiles/subnet.rs | 24 +- 7 files changed, 317 insertions(+), 613 deletions(-) diff --git a/runtime/src/precompiles/balance_transfer.rs b/runtime/src/precompiles/balance_transfer.rs index ac4282056c..14966867d8 100644 --- a/runtime/src/precompiles/balance_transfer.rs +++ b/runtime/src/precompiles/balance_transfer.rs @@ -11,18 +11,10 @@ use sp_runtime::AccountId32; use sp_std::vec::Vec; use crate::precompiles::{ - contract_to_origin, get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call, + contract_to_origin, get_method_id, parse_slice, parse_pubkey, PrecompileExt, PrecompileHandleExt, }; use crate::Runtime; -pub const BALANCE_TRANSFER_INDEX: u64 = 2048; -// ss58 public key i.e., the contract sends funds it received to the destination address from the -// method parameter. -const CONTRACT_ADDRESS_SS58: [u8; 32] = [ - 0x07, 0xec, 0x71, 0x2a, 0x5d, 0x38, 0x43, 0x4d, 0xdd, 0x03, 0x3f, 0x8f, 0x02, 0x4e, 0xcd, 0xfc, - 0x4b, 0xb5, 0x95, 0x1c, 0x13, 0xc3, 0x08, 0x5c, 0x39, 0x9c, 0x8a, 0x5f, 0x62, 0x93, 0x70, 0x5d, -]; - pub struct BalanceTransferPrecompile; #[precompile_utils::precompile] @@ -30,24 +22,28 @@ impl BalanceTransferPrecompile { #[precompile::public("transfer(bytes32)")] #[precompile::payable] fn transfer(handle: &mut impl PrecompileHandle, address: H256) -> EvmResult<()> { - let amount = handle.context().apparent_value; - - // Use BalanceConverter to convert EVM amount to Substrate balance - let amount_sub = - ::BalanceConverter::into_substrate_balance(amount) - .ok_or(ExitError::OutOfFund)?; + let amount_sub = handle.try_convert_apparent_value()?; if amount_sub.is_zero() { return Ok(()); } - let dest = get_pubkey(address.as_bytes())?.0.into(); + let dest = parse_pubkey(address.as_bytes())?.0.into(); let call = pallet_balances::Call::::transfer_allow_death { dest, value: amount_sub.unique_saturated_into(), }; - try_dispatch_runtime_call(handle, call, contract_to_origin(&CONTRACT_ADDRESS_SS58)?) + handle.try_dispatch_runtime_call(call, contract_to_origin(&Self::ADDRESS_SS58)?) } } + +impl PrecompileExt for BalanceTransferPrecompile { + const INDEX: u64 = 2048; + const ADDRESS_SS58: [u8; 32] = [ + 0x07, 0xec, 0x71, 0x2a, 0x5d, 0x38, 0x43, 0x4d, 0xdd, 0x03, 0x3f, 0x8f, 0x02, 0x4e, 0xcd, + 0xfc, 0x4b, 0xb5, 0x95, 0x1c, 0x13, 0xc3, 0x08, 0x5c, 0x39, 0x9c, 0x8a, 0x5f, 0x62, 0x93, + 0x70, 0x5d, + ]; +} diff --git a/runtime/src/precompiles/ed25519.rs b/runtime/src/precompiles/ed25519.rs index 83be4ca774..6ad082029a 100644 --- a/runtime/src/precompiles/ed25519.rs +++ b/runtime/src/precompiles/ed25519.rs @@ -2,11 +2,10 @@ extern crate alloc; use alloc::vec::Vec; -use crate::precompiles::get_slice; use ed25519_dalek::{Signature, Verifier, VerifyingKey}; use fp_evm::{ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure}; -pub const EDVERIFY_PRECOMPILE_INDEX: u64 = 1026; +use crate::precompiles::{parse_slice, PrecompileExt}; pub struct Ed25519Verify; @@ -23,13 +22,13 @@ impl LinearCostPrecompile for Ed25519Verify { let mut buf = [0u8; 32]; - let msg = get_slice(input, 4, 36)?; - let pk = VerifyingKey::try_from(get_slice(input, 36, 68)?).map_err(|_| { + let msg = parse_slice(input, 4, 36)?; + let pk = VerifyingKey::try_from(parse_slice(input, 36, 68)?).map_err(|_| { PrecompileFailure::Error { exit_status: ExitError::Other("Public key recover failed".into()), } })?; - let sig = Signature::try_from(get_slice(input, 68, 132)?).map_err(|_| { + let sig = Signature::try_from(parse_slice(input, 68, 132)?).map_err(|_| { PrecompileFailure::Error { exit_status: ExitError::Other("Signature recover failed".into()), } @@ -42,3 +41,8 @@ impl LinearCostPrecompile for Ed25519Verify { Ok((ExitSucceed::Returned, buf.to_vec())) } } + +impl PrecompileExt for Ed25519Verify { + const INDEX: u64 = 1026; + const ADDRESS_SS58: [u8; 32] = [0; 32]; +} diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index ffc4cbed79..365e551441 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -1,66 +1,67 @@ -extern crate alloc; -use crate::precompiles::{get_method_id, get_slice}; -use crate::Runtime; use fp_evm::{ ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; use sp_core::{ByteArray, U256}; use sp_std::vec; -pub const METAGRAPH_PRECOMPILE_INDEX: u64 = 2050; + +use crate::precompiles::{get_method_id, parse_slice, PrecompileExt, PrecompileHandleExt}; +use crate::Runtime; + pub struct MetagraphPrecompile; const NO_HOTKEY: &str = "no hotkey"; +#[precompile_utils::precompile] impl MetagraphPrecompile { - pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { - let txdata = handle.input(); - let method_id = get_slice(txdata, 0, 4)?; - let method_input = txdata - .get(4..) - .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts - - match method_id { - id if id == get_method_id("getUidCount(uint16)") => Self::get_uid_count(&method_input), - id if id == get_method_id("getStake(uint16,uint16)") => Self::get_stake(&method_input), - id if id == get_method_id("getRank(uint16,uint16)") => Self::get_rank(&method_input), - id if id == get_method_id("getTrust(uint16,uint16)") => Self::get_trust(&method_input), - id if id == get_method_id("getConsensus(uint16,uint16)") => { - Self::get_consensus(&method_input) - } - id if id == get_method_id("getIncentive(uint16,uint16)") => { - Self::get_incentive(&method_input) - } - id if id == get_method_id("getDividends(uint16,uint16)") => { - Self::get_dividends(&method_input) - } - id if id == get_method_id("getEmission(uint16,uint16)") => { - Self::get_emission(&method_input) - } - id if id == get_method_id("getVtrust(uint16,uint16)") => { - Self::get_vtrust(&method_input) - } - id if id == get_method_id("getValidatorStatus(uint16,uint16)") => { - Self::get_validator_status(&method_input) - } - id if id == get_method_id("getLastUpdate(uint16,uint16)") => { - Self::get_last_update(&method_input) - } - id if id == get_method_id("getIsActive(uint16,uint16)") => { - Self::get_is_active(&method_input) - } - id if id == get_method_id("getAxon(uint16,uint16)") => Self::get_axon(&method_input), - id if id == get_method_id("getHotkey(uint16,uint16)") => { - Self::get_hotkey(&method_input) - } - id if id == get_method_id("getColdkey(uint16,uint16)") => { - Self::get_coldkey(&method_input) - } - - _ => Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }), - } - } + // pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { + // let txdata = handle.input(); + // let method_id = get_slice(txdata, 0, 4)?; + // let method_input = txdata + // .get(4..) + // .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts + + // match method_id { + // id if id == get_method_id("getUidCount(uint16)") => Self::get_uid_count(&method_input), + // id if id == get_method_id("getStake(uint16,uint16)") => Self::get_stake(&method_input), + // id if id == get_method_id("getRank(uint16,uint16)") => Self::get_rank(&method_input), + // id if id == get_method_id("getTrust(uint16,uint16)") => Self::get_trust(&method_input), + // id if id == get_method_id("getConsensus(uint16,uint16)") => { + // Self::get_consensus(&method_input) + // } + // id if id == get_method_id("getIncentive(uint16,uint16)") => { + // Self::get_incentive(&method_input) + // } + // id if id == get_method_id("getDividends(uint16,uint16)") => { + // Self::get_dividends(&method_input) + // } + // id if id == get_method_id("getEmission(uint16,uint16)") => { + // Self::get_emission(&method_input) + // } + // id if id == get_method_id("getVtrust(uint16,uint16)") => { + // Self::get_vtrust(&method_input) + // } + // id if id == get_method_id("getValidatorStatus(uint16,uint16)") => { + // Self::get_validator_status(&method_input) + // } + // id if id == get_method_id("getLastUpdate(uint16,uint16)") => { + // Self::get_last_update(&method_input) + // } + // id if id == get_method_id("getIsActive(uint16,uint16)") => { + // Self::get_is_active(&method_input) + // } + // id if id == get_method_id("getAxon(uint16,uint16)") => Self::get_axon(&method_input), + // id if id == get_method_id("getHotkey(uint16,uint16)") => { + // Self::get_hotkey(&method_input) + // } + // id if id == get_method_id("getColdkey(uint16,uint16)") => { + // Self::get_coldkey(&method_input) + // } + + // _ => Err(PrecompileFailure::Error { + // exit_status: ExitError::InvalidRange, + // }), + // } + // } fn get_uid_count(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; @@ -78,7 +79,7 @@ impl MetagraphPrecompile { fn get_stake(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { exit_status: ExitError::InvalidRange, @@ -97,7 +98,7 @@ impl MetagraphPrecompile { fn get_rank(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let rank = pallet_subtensor::Pallet::::get_rank_for_uid(netuid, uid); let result_u256 = U256::from(rank); @@ -112,7 +113,7 @@ impl MetagraphPrecompile { fn get_trust(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let trust = pallet_subtensor::Pallet::::get_trust_for_uid(netuid, uid); @@ -128,7 +129,7 @@ impl MetagraphPrecompile { fn get_consensus(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let consensus = pallet_subtensor::Pallet::::get_consensus_for_uid(netuid, uid); @@ -144,7 +145,7 @@ impl MetagraphPrecompile { fn get_incentive(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let incentive = pallet_subtensor::Pallet::::get_incentive_for_uid(netuid, uid); @@ -160,7 +161,7 @@ impl MetagraphPrecompile { fn get_dividends(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let dividends = pallet_subtensor::Pallet::::get_dividends_for_uid(netuid, uid); @@ -176,7 +177,7 @@ impl MetagraphPrecompile { fn get_emission(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let emission = pallet_subtensor::Pallet::::get_emission_for_uid(netuid, uid); @@ -192,7 +193,7 @@ impl MetagraphPrecompile { fn get_vtrust(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let vtrust = pallet_subtensor::Pallet::::get_validator_trust_for_uid(netuid, uid); @@ -208,7 +209,7 @@ impl MetagraphPrecompile { fn get_validator_status(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let validator_permit = pallet_subtensor::Pallet::::get_validator_permit_for_uid(netuid, uid); @@ -229,7 +230,7 @@ impl MetagraphPrecompile { fn get_last_update(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let last_update = pallet_subtensor::Pallet::::get_last_update_for_uid(netuid, uid); @@ -245,7 +246,7 @@ impl MetagraphPrecompile { fn get_is_active(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let active = pallet_subtensor::Pallet::::get_active_for_uid(netuid, uid); @@ -261,7 +262,7 @@ impl MetagraphPrecompile { fn get_axon(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { @@ -304,7 +305,7 @@ impl MetagraphPrecompile { fn get_hotkey(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { @@ -319,7 +320,7 @@ impl MetagraphPrecompile { fn get_coldkey(data: &[u8]) -> PrecompileResult { let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(get_slice(data, 32, 64)?)?; + let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { @@ -341,7 +342,7 @@ impl MetagraphPrecompile { }); } let mut netuid = [0u8; 2]; - netuid.copy_from_slice(get_slice(data, 30, 32)?); + netuid.copy_from_slice(parse_slice(data, 30, 32)?); let result = u16::from_be_bytes(netuid); Ok(result) } @@ -353,8 +354,13 @@ impl MetagraphPrecompile { }); } let mut uid = [0u8; 2]; - uid.copy_from_slice(get_slice(data, 30, 32)?); + uid.copy_from_slice(parse_slice(data, 30, 32)?); let result = u16::from_be_bytes(uid); Ok(result) } } + +impl PrecompileExt for MetagraphPrecompile { + const INDEX: u64 = 2050; + const ADDRESS_SS58: [u8; 32] = [0; 32]; +} diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index e963d6031b..76bf110d81 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -6,14 +6,16 @@ use core::marker::PhantomData; use frame_support::dispatch::{GetDispatchInfo, Pays}; use frame_system::RawOrigin; use pallet_evm::{ - ExitError, ExitSucceed, GasWeightMapping, IsPrecompileResult, Precompile, PrecompileFailure, - PrecompileHandle, PrecompileOutput, PrecompileResult, PrecompileSet, + AddressMapping, BalanceConverter, ExitError, ExitSucceed, GasWeightMapping, + HashedAddressMapping, IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle, + PrecompileOutput, PrecompileResult, PrecompileSet, }; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; use precompile_utils::EvmResult; use sp_core::{hashing::keccak_256, H160, U256}; +use sp_runtime::traits::BlakeTwo256; use sp_runtime::{traits::Dispatchable, AccountId32}; use sp_std::vec; @@ -60,12 +62,12 @@ where hash(5), hash(1024), hash(1025), - hash(EDVERIFY_PRECOMPILE_INDEX), - hash(BALANCE_TRANSFER_INDEX), - hash(STAKING_PRECOMPILE_INDEX), - hash(SUBNET_PRECOMPILE_INDEX), - hash(METAGRAPH_PRECOMPILE_INDEX), - hash(NEURON_PRECOMPILE_INDEX), + hash(Ed25519Verify::INDEX), + hash(BalanceTransferPrecompile::INDEX), + hash(StakingPrecompile::INDEX), + hash(SubnetPrecompile::INDEX), + hash(MetagraphPrecompile::INDEX), + hash(NeuronPrecompile::INDEX), ] } } @@ -84,17 +86,17 @@ where // Non-Frontier specific nor Ethereum precompiles : a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), - a if a == hash(EDVERIFY_PRECOMPILE_INDEX) => Some(Ed25519Verify::execute(handle)), + a if a == hash(Ed25519Verify::INDEX) => Some(Ed25519Verify::execute(handle)), // Subtensor specific precompiles : - a if a == hash(BALANCE_TRANSFER_INDEX) => { + a if a == hash(BalanceTransferPrecompile::INDEX) => { Some(BalanceTransferPrecompile::execute(handle)) } - a if a == hash(STAKING_PRECOMPILE_INDEX) => Some(StakingPrecompile::execute(handle)), - a if a == hash(SUBNET_PRECOMPILE_INDEX) => Some(SubnetPrecompile::execute(handle)), - a if a == hash(METAGRAPH_PRECOMPILE_INDEX) => { + a if a == hash(StakingPrecompile::INDEX) => Some(StakingPrecompile::execute(handle)), + a if a == hash(SubnetPrecompile::INDEX) => Some(SubnetPrecompile::execute(handle)), + a if a == hash(MetagraphPrecompile::INDEX) => { Some(MetagraphPrecompile::execute(handle)) } - a if a == hash(NEURON_PRECOMPILE_INDEX) => Some(NeuronPrecompile::execute(handle)), + a if a == hash(NeuronPrecompile::INDEX) => Some(NeuronPrecompile::execute(handle)), _ => None, } @@ -124,7 +126,7 @@ pub fn get_method_id(method_signature: &str) -> [u8; 4] { /// Takes a slice from bytes with PrecompileFailure as Error /// -pub fn get_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], PrecompileFailure> { +pub fn parse_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], PrecompileFailure> { let maybe_slice = data.get(from..to); if let Some(slice) = maybe_slice { Ok(slice) @@ -141,9 +143,9 @@ pub fn get_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], Precompil } } -pub fn get_pubkey(data: &[u8]) -> Result<(AccountId32, vec::Vec), PrecompileFailure> { +pub fn parse_pubkey(data: &[u8]) -> Result<(AccountId32, vec::Vec), PrecompileFailure> { let mut pubkey = [0u8; 32]; - pubkey.copy_from_slice(get_slice(data, 0, 32)?); + pubkey.copy_from_slice(parse_slice(data, 0, 32)?); Ok(( pubkey.into(), @@ -166,77 +168,107 @@ fn parse_netuid(data: &[u8], offset: usize) -> Result { } let mut netuid_bytes = [0u8; 2]; - netuid_bytes.copy_from_slice(get_slice(data, offset, offset + 2)?); + netuid_bytes.copy_from_slice(parse_slice(data, offset, offset + 2)?); let netuid: u16 = netuid_bytes[1] as u16 | ((netuid_bytes[0] as u16) << 8u16); Ok(netuid) } fn contract_to_origin(contract: &[u8; 32]) -> Result, PrecompileFailure> { - let (account_id, _) = get_pubkey(contract)?; + let (account_id, _) = parse_pubkey(contract)?; Ok(RawOrigin::Signed(account_id)) } -/// Dispatches a runtime call, but also checks and records the gas costs. -fn try_dispatch_runtime_call( - handle: &mut impl PrecompileHandle, - call: impl Into, - origin: RawOrigin, -) -> EvmResult<()> { - let call = Into::::into(call); - let info = call.get_dispatch_info(); - - let target_gas = handle.gas_limit(); - if let Some(gas) = target_gas { - let valid_weight = - ::GasWeightMapping::gas_to_weight(gas, false).ref_time(); - if info.weight.ref_time() > valid_weight { - return Err(PrecompileFailure::Error { - exit_status: ExitError::OutOfGas, - }); - } +pub(crate) trait PrecompileHandleExt: PrecompileHandle { + fn caller_account_id(&self) -> AccountId32 { + as AddressMapping>::into_account_id( + self.context().caller, + ) } - handle.record_external_cost( - Some(info.weight.ref_time()), - Some(info.weight.proof_size()), - None, - )?; - - match call.dispatch(origin.into()) { - Ok(post_info) => { - if post_info.pays_fee(&info) == Pays::Yes { - let actual_weight = post_info.actual_weight.unwrap_or(info.weight); - let cost = - ::GasWeightMapping::weight_to_gas(actual_weight); - handle.record_cost(cost)?; - - handle.refund_external_cost( - Some( - info.weight - .ref_time() - .saturating_sub(actual_weight.ref_time()), - ), - Some( - info.weight - .proof_size() - .saturating_sub(actual_weight.proof_size()), - ), - ); - } + fn try_convert_apparent_value(&self) -> EvmResult { + let amount = self.context().apparent_value; + ::BalanceConverter::into_substrate_balance(amount).ok_or( + PrecompileFailure::Error { + exit_status: ExitError::Other( + "error converting balance from ETH to subtensor".into(), + ), + }, + ) + } - log::info!("Dispatch succeeded. Post info: {:?}", post_info); + /// Dispatches a runtime call, but also checks and records the gas costs. + fn try_dispatch_runtime_call( + &mut self, + call: impl Into, + origin: RawOrigin, + ) -> EvmResult<()> { + let call = Into::::into(call); + let info = call.get_dispatch_info(); - Ok(()) + let target_gas = self.gas_limit(); + if let Some(gas) = target_gas { + let valid_weight = + ::GasWeightMapping::gas_to_weight(gas, false) + .ref_time(); + if info.weight.ref_time() > valid_weight { + return Err(PrecompileFailure::Error { + exit_status: ExitError::OutOfGas, + }); + } } - Err(e) => { - log::error!("Dispatch failed. Error: {:?}", e); - log::warn!("Returning error PrecompileFailure::Error"); - Err(PrecompileFailure::Error { - exit_status: ExitError::Other( - format!("dispatch execution failed: {}", <&'static str>::from(e)).into(), - ), - }) + + self.record_external_cost( + Some(info.weight.ref_time()), + Some(info.weight.proof_size()), + None, + )?; + + match call.dispatch(origin.into()) { + Ok(post_info) => { + if post_info.pays_fee(&info) == Pays::Yes { + let actual_weight = post_info.actual_weight.unwrap_or(info.weight); + let cost = ::GasWeightMapping::weight_to_gas( + actual_weight, + ); + self.record_cost(cost)?; + + self.refund_external_cost( + Some( + info.weight + .ref_time() + .saturating_sub(actual_weight.ref_time()), + ), + Some( + info.weight + .proof_size() + .saturating_sub(actual_weight.proof_size()), + ), + ); + } + + log::info!("Dispatch succeeded. Post info: {:?}", post_info); + + Ok(()) + } + Err(e) => { + log::error!("Dispatch failed. Error: {:?}", e); + log::warn!("Returning error PrecompileFailure::Error"); + Err(PrecompileFailure::Error { + exit_status: ExitError::Other( + format!("dispatch execution failed: {}", <&'static str>::from(e)).into(), + ), + }) + } } } } + +impl PrecompileHandleExt for T where T: PrecompileHandle {} + +pub(crate) trait PrecompileExt: Precompile { + const INDEX: u64; + // ss58 public key i.e., the contract sends funds it received to the destination address from + // the method parameter. + const ADDRESS_SS58: [u8; 32]; +} diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 2951f190b1..cb92a5dfdf 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -11,108 +11,71 @@ use sp_std::vec; use sp_std::vec::Vec; use crate::precompiles::{ - get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call, + get_method_id, parse_netuid, parse_pubkey, parse_slice, PrecompileExt, PrecompileHandleExt, }; use crate::{Runtime, RuntimeCall}; -pub const NEURON_PRECOMPILE_INDEX: u64 = 2052; // max paramter lenght 4K pub const MAX_PARAMETER_SIZE: usize = 4 * 1024; -// 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, -]; + pub struct NeuronPrecompile; #[precompile_utils::precompile] impl NeuronPrecompile { - // pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { - // let txdata = handle.input(); - // let method_id = get_slice(txdata, 0, 4)?; - // let method_input = txdata - // .get(4..) - // .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts - - // if method_input.len() > MAX_PARAMETER_SIZE { - // log::error!( - // "method parameter data length as {} is too long", - // method_input.len() - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // match method_id { - // id if id == get_method_id("setWeights(uint16,uint16[],uint16[],uint64)") => { - // Self::set_weights(handle, &method_input) - // } - // id if id == get_method_id("commitWeights(uint16,uint256)") => { - // Self::commit_weights(handle, &method_input) - // } - // id if id - // == get_method_id("revealWeights(uint16,uint16[],uint16[],uint16[],uint64)") => - // { - // Self::reveal_weights(handle, &method_input) - // } - - // _ => Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }), - // } - // } - - // pub fn set_weights(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { - // let (netuid, dests, weights, version_key) = Self::parse_netuid_dests_weights(data)?; - // let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::set_weights { - // netuid, - // dests, - // weights, - // version_key, - // }); - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) - // } + #[precompile::public("setWeights(uint16,uint16[],uint16[],uint64)")] + #[precompile::payable] + pub fn set_weights( + handle: &mut impl PrecompileHandle, + netuid: u16, + dests: Vec, + weights: Vec, + version_key: u64, + ) -> EvmResult<()> { + let call = pallet_subtensor::Call::::set_weights { + netuid, + dests, + weights, + version_key, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } - // pub fn commit_weights(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { - // let (netuid, commit_hash) = Self::parse_netuid_commit_hash(data)?; + #[precompile::public("commitWeights(uint16,uint256)")] + #[precompile::payable] + pub fn commit_weights( + handle: &mut impl PrecompileHandle, + netuid: u16, + commit_hash: H256, + ) -> EvmResult<()> { + let call = pallet_subtensor::Call::::commit_weights { + netuid, + commit_hash, + }; - // let call = - // RuntimeCall::SubtensorModule(pallet_subtensor::Call::::commit_weights { - // netuid, - // commit_hash, - // }); - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) - // } + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } - // pub fn reveal_weights(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { - // let (netuid, uids, values, salt, version_key) = - // Self::parse_netuid_dests_weights_salt(data)?; - // let call = - // RuntimeCall::SubtensorModule(pallet_subtensor::Call::::reveal_weights { - // netuid, - // uids, - // values, - // salt, - // version_key, - // }); - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) - // } + #[precompile::public("revealWeights(uint16,uint16[],uint16[],uint16[],uint64)")] + #[precompile::payable] + pub fn reveal_weights( + handle: &mut impl PrecompileHandle, + netuid: u16, + uids: Vec, + values: Vec, + salt: Vec, + version_key: u64, + ) -> EvmResult<()> { + let call = pallet_subtensor::Call::::reveal_weights { + netuid, + uids, + values, + salt, + version_key, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } #[precompile::public("burnedRegister(uint16,bytes32)")] #[precompile::payable] @@ -121,297 +84,19 @@ impl NeuronPrecompile { netuid: u16, hotkey: H256, ) -> EvmResult<()> { - let coldkey = - as AddressMapping>::into_account_id( - handle.context().caller, - ); - let (hotkey, _) = get_pubkey(hotkey.as_bytes())?; - let call = - RuntimeCall::SubtensorModule(pallet_subtensor::Call::::burned_register { - netuid, - hotkey, - }); - - try_dispatch_runtime_call(handle, call, RawOrigin::Signed(coldkey)) - } - - // fn parse_netuid_hotkey_parameter(data: &[u8]) -> Result<(u16, AccountId32), PrecompileFailure> { - // if data.len() < 64 { - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // let netuid = parse_netuid(data, 30)?; - - // Ok(()) - // } - - fn parse_netuid_dests_weights( - data: &[u8], - ) -> Result<(u16, Vec, Vec, u64), PrecompileFailure> { - let data_len = data.len(); - if data_len < 4 * 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); - - // get the neuron amount in sebnet - let subnet_size = pallet_subtensor::Pallet::::get_subnetwork_n(netuid) as usize; - - let mut first_position_vec = [0u8; 2]; - first_position_vec.copy_from_slice(get_slice(data, 62, 64)?); - let first_position = u16::from_be_bytes(first_position_vec) as usize; - - if first_position > data_len { - log::error!("position for uids data as {} is too large", first_position); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - let mut second_position_vec = [0u8; 2]; - second_position_vec.copy_from_slice(get_slice(data, 94, 96)?); - let second_position = u16::from_be_bytes(second_position_vec) as usize; - - if second_position > data_len { - log::error!("position for uids data as {} is too large", first_position); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - let mut version_key_vec = [0u8; 8]; - version_key_vec.copy_from_slice(get_slice(data, 120, 128)?); - let version_key = u64::from_be_bytes(version_key_vec); + let coldkey = handle.caller_account_id(); + let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; + let call = pallet_subtensor::Call::::burned_register { netuid, hotkey }; - let mut dests = vec![]; - let mut weights = vec![]; - - let mut dests_len_vec = [0u8; 2]; - dests_len_vec.copy_from_slice(get_slice(data, first_position + 30, first_position + 32)?); - let dests_len = u16::from_be_bytes(dests_len_vec) as usize; - - if dests_len > subnet_size { - log::error!( - "uids len as {} in set weight is more than neurons {} in subnet {}", - dests_len, - subnet_size, - netuid - ); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - for i in 0..dests_len { - let mut tmp_vec = [0u8; 2]; - let from = first_position - .saturating_add(62) - .saturating_add(i.saturating_mul(32)); - let to = from.saturating_add(2); - tmp_vec.copy_from_slice(get_slice(data, from, to)?); - let dest = u16::from_be_bytes(tmp_vec); - dests.push(dest); - } - - let mut weights_len_vec = [0u8; 2]; - weights_len_vec.copy_from_slice(get_slice( - data, - second_position + 30, - second_position + 32, - )?); - let weights_len = u16::from_be_bytes(weights_len_vec) as usize; - - if weights_len > subnet_size { - log::error!( - "weights len as {} in set weight is more than neurons {} in subnet {}", - weights_len, - subnet_size, - netuid - ); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - for i in 0..weights_len { - let mut tmp_vec = [0u8; 2]; - let from = second_position - .saturating_add(62) - .saturating_add(i.saturating_mul(32)); - let to = from.saturating_add(2); - tmp_vec.copy_from_slice(get_slice(data, from, to)?); - let weight = u16::from_be_bytes(tmp_vec); - weights.push(weight); - } - - Ok((netuid, dests, weights, version_key)) + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(coldkey)) } +} - fn parse_netuid_commit_hash(data: &[u8]) -> Result<(u16, H256), PrecompileFailure> { - if data.len() < 2 * 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); - let commit_hash = H256::from_slice(get_slice(data, 32, 64)?); - - Ok((netuid, commit_hash)) - } - - fn parse_netuid_dests_weights_salt( - data: &[u8], - ) -> Result<(u16, Vec, Vec, Vec, u64), PrecompileFailure> { - let data_len = data.len(); - if data_len < 5 * 32 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - let netuid = parse_netuid(data, 30)?; - - // get the neuron amount in sebnet - let subnet_size = pallet_subtensor::Pallet::::get_subnetwork_n(netuid) as usize; - - let mut first_position_vec = [0u8; 2]; - first_position_vec.copy_from_slice(get_slice(data, 62, 64)?); - let first_position = u16::from_be_bytes(first_position_vec) as usize; - - if first_position > data_len { - log::error!("position for uids data as {} is too large", first_position); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - let mut second_position_vec = [0u8; 2]; - second_position_vec.copy_from_slice(get_slice(data, 94, 96)?); - let second_position = u16::from_be_bytes(second_position_vec) as usize; - - if second_position > data_len { - log::error!( - "position for values data as {} is too large", - first_position - ); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - let mut third_position_vec = [0u8; 2]; - third_position_vec.copy_from_slice(get_slice(data, 126, 128)?); - let third_position = u16::from_be_bytes(third_position_vec) as usize; - - if third_position > data_len { - log::error!("position for salt data as {} is too large", first_position); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - let mut version_key_vec = [0u8; 8]; - version_key_vec.copy_from_slice(get_slice(data, 152, 160)?); - let version_key = u64::from_be_bytes(version_key_vec); - - let mut uids = vec![]; - let mut values = vec![]; - let mut salt = vec![]; - - let mut uids_len_vec = [0u8; 2]; - uids_len_vec.copy_from_slice(get_slice(data, first_position + 30, first_position + 32)?); - let uids_len = u16::from_be_bytes(uids_len_vec) as usize; - - if uids_len > subnet_size { - log::error!( - "uids len as {} in reveal weight is more than neurons {} in subnet {}", - uids_len, - subnet_size, - netuid - ); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - for i in 0..uids_len { - let mut tmp_vec = [0u8; 2]; - let from = first_position - .saturating_add(62) - .saturating_add(i.saturating_mul(32)); - let to = from.saturating_add(2); - tmp_vec.copy_from_slice(get_slice(data, from, to)?); - let uid = u16::from_be_bytes(tmp_vec); - uids.push(uid); - } - - let mut values_len_vec = [0u8; 2]; - values_len_vec.copy_from_slice(get_slice( - data, - second_position + 30, - second_position + 32, - )?); - let values_len = u16::from_be_bytes(values_len_vec) as usize; - - if values_len > subnet_size { - log::error!( - "values len as {} in reveal weight is more than neurons {} in subnet {}", - values_len, - subnet_size, - netuid - ); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - for i in 0..values_len { - let mut tmp_vec = [0u8; 2]; - let from = second_position - .saturating_add(62) - .saturating_add(i.saturating_mul(32)); - let to = from.saturating_add(2); - tmp_vec.copy_from_slice(get_slice(data, from, to)?); - let value = u16::from_be_bytes(tmp_vec); - values.push(value); - } - - let mut salt_len_vec = [0u8; 2]; - salt_len_vec.copy_from_slice(get_slice(data, third_position + 30, third_position + 32)?); - let salt_len = u16::from_be_bytes(salt_len_vec) as usize; - - if salt_len > subnet_size { - log::error!( - "salt len as {} in reveal weight is more than neurons {} in subnet {}", - salt_len, - subnet_size, - netuid - ); - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - for i in 0..salt_len { - let mut tmp_vec = [0u8; 2]; - let from = third_position - .saturating_add(62) - .saturating_add(i.saturating_mul(32)); - let to = from.saturating_add(2); - tmp_vec.copy_from_slice(get_slice(data, from, to)?); - let value = u16::from_be_bytes(tmp_vec); - salt.push(value); - } - - Ok((netuid, uids, values, salt, version_key)) - } +impl PrecompileExt for NeuronPrecompile { + const INDEX: u64 = 2052; + const 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, + ]; } diff --git a/runtime/src/precompiles/staking.rs b/runtime/src/precompiles/staking.rs index c368df6ad3..d99b0199ee 100644 --- a/runtime/src/precompiles/staking.rs +++ b/runtime/src/precompiles/staking.rs @@ -37,20 +37,11 @@ use sp_runtime::AccountId32; use sp_std::vec; use crate::precompiles::{ - get_method_id, get_pubkey, get_slice, parse_netuid, try_dispatch_runtime_call, - try_u16_from_u256, + get_method_id, parse_slice, parse_netuid, parse_pubkey, try_u16_from_u256, PrecompileExt, + PrecompileHandleExt, }; use crate::{ProxyType, Runtime, RuntimeCall}; -pub const STAKING_PRECOMPILE_INDEX: u64 = 2049; - -// ss58 public key i.e., the contract sends funds it received to the destination address from the -// method parameter. -const CONTRACT_ADDRESS_SS58: [u8; 32] = [ - 0x26, 0xf4, 0x10, 0x1e, 0x52, 0xb7, 0x57, 0x34, 0x33, 0x24, 0x5b, 0xc3, 0x0a, 0xe1, 0x8b, 0x63, - 0x99, 0x53, 0xd8, 0x41, 0x79, 0x33, 0x03, 0x61, 0x4d, 0xfa, 0xcf, 0xf0, 0x37, 0xf7, 0x12, 0x94, -]; - pub struct StakingPrecompile; #[precompile_utils::precompile] @@ -58,34 +49,23 @@ impl StakingPrecompile { #[precompile::public("addStake(bytes32,uint256)")] #[precompile::payable] fn add_stake(handle: &mut impl PrecompileHandle, address: H256, netuid: U256) -> EvmResult<()> { - let account_id = - as AddressMapping>::into_account_id( - handle.context().caller, - ); - + let account_id = handle.caller_account_id(); let amount = handle.context().apparent_value; if !amount.is_zero() { Self::transfer_back_to_caller(&account_id, amount)?; } - let amount_sub = - ::BalanceConverter::into_substrate_balance(amount) - .ok_or(PrecompileFailure::Error { - exit_status: ExitError::Other( - "error converting balance from ETH to subtensor".into(), - ), - })?; - - let (hotkey, _) = get_pubkey(address.as_bytes())?; + let amount_sub = handle.try_convert_apparent_value()?; + let (hotkey, _) = parse_pubkey(address.as_bytes())?; let netuid = try_u16_from_u256(netuid)?; - let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::add_stake { + let call = pallet_subtensor::Call::::add_stake { hotkey, netuid, amount_staked: amount_sub.unique_saturated_into(), - }); + }; - try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(account_id)) } #[precompile::public("removeStake(bytes32,uint256,uint256)")] @@ -95,55 +75,45 @@ impl StakingPrecompile { amount: U256, netuid: U256, ) -> EvmResult<()> { - let account_id = - as AddressMapping>::into_account_id( - handle.context().caller, - ); - - let (hotkey, _) = get_pubkey(address.as_bytes())?; + let account_id = handle.caller_account_id(); + let (hotkey, _) = parse_pubkey(address.as_bytes())?; let netuid = try_u16_from_u256(netuid)?; let amount_unstaked = amount.unique_saturated_into(); - let call = RuntimeCall::SubtensorModule(pallet_subtensor::Call::::remove_stake { + let call = pallet_subtensor::Call::::remove_stake { hotkey, netuid, amount_unstaked, - }); + }; - try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(account_id)) } #[precompile::public("addProxy(bytes32)")] fn add_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { - let account_id = - as AddressMapping>::into_account_id( - handle.context().caller, - ); - let (delegate, _) = get_pubkey(delegate.as_bytes())?; + let account_id = handle.caller_account_id(); + let (delegate, _) = parse_pubkey(delegate.as_bytes())?; let delegate = ::Lookup::unlookup(delegate); - let call = RuntimeCall::Proxy(pallet_proxy::Call::::add_proxy { + let call = pallet_proxy::Call::::add_proxy { delegate, proxy_type: ProxyType::Staking, delay: 0, - }); + }; - try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(account_id)) } #[precompile::public("removeProxy(bytes32)")] fn remove_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { - let account_id = - as AddressMapping>::into_account_id( - handle.context().caller, - ); - let (delegate, _) = get_pubkey(delegate.as_bytes())?; + let account_id = handle.caller_account_id(); + let (delegate, _) = parse_pubkey(delegate.as_bytes())?; let delegate = ::Lookup::unlookup(delegate); - let call = RuntimeCall::Proxy(pallet_proxy::Call::::remove_proxy { + let call = pallet_proxy::Call::::remove_proxy { delegate, proxy_type: ProxyType::Staking, delay: 0, - }); + }; - try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id)) + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(account_id)) } #[precompile::public("getStake(bytes32,bytes32,uint256)")] @@ -154,10 +124,9 @@ impl StakingPrecompile { coldkey: H256, netuid: U256, ) -> EvmResult { - let (hotkey, _) = get_pubkey(hotkey.as_bytes())?; - let (coldkey, _) = get_pubkey(coldkey.as_bytes())?; + let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; + let (coldkey, _) = parse_pubkey(coldkey.as_bytes())?; let netuid = try_u16_from_u256(netuid)?; - let stake = pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, netuid, ); @@ -169,8 +138,7 @@ impl StakingPrecompile { account_id: &AccountId32, amount: U256, ) -> Result<(), PrecompileFailure> { - let smart_contract_account_id: AccountId32 = CONTRACT_ADDRESS_SS58.into(); - + let smart_contract_account_id: AccountId32 = Self::ADDRESS_SS58.into(); let amount_sub = ::BalanceConverter::into_substrate_balance(amount) .ok_or(ExitError::OutOfFund)?; @@ -199,3 +167,12 @@ impl StakingPrecompile { Ok(()) } } + +impl PrecompileExt for StakingPrecompile { + const INDEX: u64 = 2049; + const ADDRESS_SS58: [u8; 32] = [ + 0x26, 0xf4, 0x10, 0x1e, 0x52, 0xb7, 0x57, 0x34, 0x33, 0x24, 0x5b, 0xc3, 0x0a, 0xe1, 0x8b, + 0x63, 0x99, 0x53, 0xd8, 0x41, 0x79, 0x33, 0x03, 0x61, 0x4d, 0xfa, 0xcf, 0xf0, 0x37, 0xf7, + 0x12, 0x94, + ]; +} diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index dbaad74e06..8a46cc7dc6 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -8,20 +8,15 @@ use sp_core::U256; use sp_runtime::{traits::BlakeTwo256, AccountId32, Vec}; use sp_std::vec; -use crate::precompiles::{get_method_id, get_pubkey, get_slice, try_dispatch_runtime_call}; +use crate::precompiles::{ + get_method_id, parse_slice, parse_pubkey, PrecompileExt, PrecompileHandleExt, +}; use crate::{Runtime, RuntimeCall}; -pub const SUBNET_PRECOMPILE_INDEX: u64 = 2051; // bytes with max lenght 1K -pub const MAX_SINGLE_PARAMETER_SIZE: usize = 1024; +const MAX_SINGLE_PARAMETER_SIZE: usize = 1024; // seven bytes with max lenght 1K -pub const MAX_PARAMETER_SIZE: usize = 7 * MAX_SINGLE_PARAMETER_SIZE; -// ss58 public key i.e., the contract sends funds it received to the destination address from the -#[allow(dead_code)] -const CONTRACT_ADDRESS_SS58: [u8; 32] = [ - 0x3a, 0x86, 0x18, 0xfb, 0xbb, 0x1b, 0xbc, 0x47, 0x86, 0x64, 0xff, 0x53, 0x46, 0x18, 0x0c, 0x35, - 0xd0, 0x9f, 0xac, 0x26, 0xf2, 0x02, 0x70, 0x85, 0xb3, 0x1c, 0x56, 0xc1, 0x06, 0x3c, 0x1c, 0xd3, -]; +const MAX_PARAMETER_SIZE: usize = 7 * MAX_SINGLE_PARAMETER_SIZE; pub struct SubnetPrecompile; @@ -1413,3 +1408,12 @@ impl SubnetPrecompile { // Ok((netuid, parameter)) // } } + +impl PrecompileExt for SubnetPrecompile { + const INDEX: u64 = 2051; + const ADDRESS_SS58: [u8; 32] = [ + 0x3a, 0x86, 0x18, 0xfb, 0xbb, 0x1b, 0xbc, 0x47, 0x86, 0x64, 0xff, 0x53, 0x46, 0x18, 0x0c, + 0x35, 0xd0, 0x9f, 0xac, 0x26, 0xf2, 0x02, 0x70, 0x85, 0xb3, 0x1c, 0x56, 0xc1, 0x06, 0x3c, + 0x1c, 0xd3, + ]; +} From 2cfdb41ba29174cad3ae1e46808b1f2fa8c53c12 Mon Sep 17 00:00:00 2001 From: Aliaksandr Tsurko Date: Fri, 14 Feb 2025 17:43:19 +0100 Subject: [PATCH 05/10] Refactor metagraph precompile --- runtime/src/precompiles/metagraph.rs | 418 ++++++++------------------- 1 file changed, 115 insertions(+), 303 deletions(-) diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index 365e551441..bf20f05bc0 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -1,7 +1,12 @@ +extern crate alloc; +use alloc::string::String; + use fp_evm::{ ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; -use sp_core::{ByteArray, U256}; +use pallet_subtensor::AxonInfo as SubtensorModuleAxonInfo; +use precompile_utils::{solidity::Codec, EvmResult}; +use sp_core::{ByteArray, H256, U256}; use sp_std::vec; use crate::precompiles::{get_method_id, parse_slice, PrecompileExt, PrecompileHandleExt}; @@ -9,354 +14,138 @@ use crate::Runtime; pub struct MetagraphPrecompile; -const NO_HOTKEY: &str = "no hotkey"; - #[precompile_utils::precompile] impl MetagraphPrecompile { - // pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { - // let txdata = handle.input(); - // let method_id = get_slice(txdata, 0, 4)?; - // let method_input = txdata - // .get(4..) - // .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts - - // match method_id { - // id if id == get_method_id("getUidCount(uint16)") => Self::get_uid_count(&method_input), - // id if id == get_method_id("getStake(uint16,uint16)") => Self::get_stake(&method_input), - // id if id == get_method_id("getRank(uint16,uint16)") => Self::get_rank(&method_input), - // id if id == get_method_id("getTrust(uint16,uint16)") => Self::get_trust(&method_input), - // id if id == get_method_id("getConsensus(uint16,uint16)") => { - // Self::get_consensus(&method_input) - // } - // id if id == get_method_id("getIncentive(uint16,uint16)") => { - // Self::get_incentive(&method_input) - // } - // id if id == get_method_id("getDividends(uint16,uint16)") => { - // Self::get_dividends(&method_input) - // } - // id if id == get_method_id("getEmission(uint16,uint16)") => { - // Self::get_emission(&method_input) - // } - // id if id == get_method_id("getVtrust(uint16,uint16)") => { - // Self::get_vtrust(&method_input) - // } - // id if id == get_method_id("getValidatorStatus(uint16,uint16)") => { - // Self::get_validator_status(&method_input) - // } - // id if id == get_method_id("getLastUpdate(uint16,uint16)") => { - // Self::get_last_update(&method_input) - // } - // id if id == get_method_id("getIsActive(uint16,uint16)") => { - // Self::get_is_active(&method_input) - // } - // id if id == get_method_id("getAxon(uint16,uint16)") => Self::get_axon(&method_input), - // id if id == get_method_id("getHotkey(uint16,uint16)") => { - // Self::get_hotkey(&method_input) - // } - // id if id == get_method_id("getColdkey(uint16,uint16)") => { - // Self::get_coldkey(&method_input) - // } - - // _ => Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }), - // } - // } - - fn get_uid_count(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid_count = pallet_subtensor::SubnetworkN::::get(netuid); - - let uid_count_u256 = U256::from(uid_count); - let mut result = [0_u8; 32]; - U256::to_big_endian(&uid_count_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getUidCount(uint16)")] + #[precompile::view] + fn get_uid_count(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::SubnetworkN::::get(netuid)) } - fn get_stake(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; + #[precompile::public("getStake(uint16,uint16)")] + #[precompile::view] + fn get_stake(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { exit_status: ExitError::InvalidRange, })?; - let stake = pallet_subtensor::Pallet::::get_total_stake_for_hotkey(&hotkey); - let result_u256 = U256::from(stake); - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + Ok(pallet_subtensor::Pallet::::get_total_stake_for_hotkey(&hotkey)) } - fn get_rank(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - let rank = pallet_subtensor::Pallet::::get_rank_for_uid(netuid, uid); - - let result_u256 = U256::from(rank); - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getRank(uint16,uint16)")] + #[precompile::view] + fn get_rank(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_rank_for_uid( + netuid, uid, + )) } - fn get_trust(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let trust = pallet_subtensor::Pallet::::get_trust_for_uid(netuid, uid); - - let result_u256 = U256::from(trust); - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getTrust(uint16,uint16)")] + #[precompile::view] + fn get_trust(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_trust_for_uid( + netuid, uid, + )) } - fn get_consensus(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let consensus = pallet_subtensor::Pallet::::get_consensus_for_uid(netuid, uid); - - let result_u256 = U256::from(consensus); - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getConsensus(uint16,uint16)")] + #[precompile::view] + fn get_consensus(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_consensus_for_uid( + netuid, uid, + )) } - fn get_incentive(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let incentive = pallet_subtensor::Pallet::::get_incentive_for_uid(netuid, uid); - - let result_u256 = U256::from(incentive); - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getIncentive(uint16,uint16)")] + #[precompile::view] + fn get_incentive(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_incentive_for_uid( + netuid, uid, + )) } - fn get_dividends(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let dividends = pallet_subtensor::Pallet::::get_dividends_for_uid(netuid, uid); - - let result_u256 = U256::from(dividends); - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getDividends(uint16,uint16)")] + #[precompile::view] + fn get_dividends(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_dividends_for_uid( + netuid, uid, + )) } - fn get_emission(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let emission = pallet_subtensor::Pallet::::get_emission_for_uid(netuid, uid); - - let result_u256 = U256::from(emission); - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getEmission(uint16,uint16)")] + #[precompile::view] + fn get_emission(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_emission_for_uid( + netuid, uid, + )) } - fn get_vtrust(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let vtrust = pallet_subtensor::Pallet::::get_validator_trust_for_uid(netuid, uid); - - let result_u256 = U256::from(vtrust); - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getVtrust(uint16,uint16)")] + #[precompile::view] + fn get_vtrust(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_validator_trust_for_uid(netuid, uid)) } - fn get_validator_status(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let validator_permit = - pallet_subtensor::Pallet::::get_validator_permit_for_uid(netuid, uid); - - let result_u256 = if validator_permit { - U256::from(1) - } else { - U256::from(0) - }; - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getValidatorStatus(uint16,uint16)")] + #[precompile::view] + fn get_validator_status( + handle: &mut impl PrecompileHandle, + netuid: u16, + uid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_validator_permit_for_uid(netuid, uid)) } - fn get_last_update(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let last_update = pallet_subtensor::Pallet::::get_last_update_for_uid(netuid, uid); - - let result_u256 = U256::from(last_update); - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getLastUpdate(uint16,uint16)")] + #[precompile::view] + fn get_last_update( + handle: &mut impl PrecompileHandle, + netuid: u16, + uid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_last_update_for_uid(netuid, uid)) } - fn get_is_active(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let active = pallet_subtensor::Pallet::::get_active_for_uid(netuid, uid); - - let result_u256 = if active { U256::from(1) } else { U256::from(0) }; - let mut result = [0_u8; 32]; - U256::to_big_endian(&result_u256, &mut result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + #[precompile::public("getIsActive(uint16,uint16)")] + #[precompile::view] + fn get_is_active(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + Ok(pallet_subtensor::Pallet::::get_active_for_uid( + netuid, uid, + )) } - fn get_axon(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - + #[precompile::public("getAxon(uint16,uint16)")] + #[precompile::view] + fn get_axon(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { - exit_status: ExitError::Other(sp_version::Cow::Borrowed(NO_HOTKEY)), + exit_status: ExitError::Other("hotkey not found".into()), })?; - let axon = pallet_subtensor::Pallet::::get_axon_info(netuid, &hotkey); - - let mut block_result = [0_u8; 32]; - U256::to_big_endian(&U256::from(axon.block), &mut block_result); - - let mut version_result = [0_u8; 32]; - U256::to_big_endian(&U256::from(axon.version), &mut version_result); - - let mut ip_result = [0_u8; 32]; - U256::to_big_endian(&U256::from(axon.ip), &mut ip_result); - - let mut port_result = [0_u8; 32]; - U256::to_big_endian(&U256::from(axon.port), &mut port_result); - - let mut ip_type_result = [0_u8; 32]; - U256::to_big_endian(&U256::from(axon.ip_type), &mut ip_type_result); - - let mut protocol_result = [0_u8; 32]; - U256::to_big_endian(&U256::from(axon.protocol), &mut protocol_result); - - let mut result = [0_u8; 192]; - result[..32].copy_from_slice(&block_result); - result[32..64].copy_from_slice(&version_result); - result[64..96].copy_from_slice(&ip_result); - result[96..128].copy_from_slice(&port_result); - result[128..160].copy_from_slice(&ip_type_result); - result[160..].copy_from_slice(&protocol_result); - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: result.into(), - }) + Ok(pallet_subtensor::Pallet::::get_axon_info(netuid, &hotkey).into()) } - fn get_hotkey(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - - let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + #[precompile::public("getHotkey(uint16,uint16)")] + #[precompile::view] + fn get_hotkey(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) + .map(|acc| H256::from_slice(acc.as_slice())) .map_err(|_| PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - })?; - - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: hotkey.as_slice().into(), - }) + exit_status: ExitError::InvalidRange, + }) } - fn get_coldkey(data: &[u8]) -> PrecompileResult { - let netuid = Self::parse_netuid(data)?; - let uid = Self::parse_uid(parse_slice(data, 32, 64)?)?; - + #[precompile::public("getColdkey(uint16,uint16)")] + #[precompile::view] + fn get_coldkey(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { exit_status: ExitError::InvalidRange, })?; - let coldkey = pallet_subtensor::Owner::::get(&hotkey); - Ok(PrecompileOutput { - exit_status: ExitSucceed::Returned, - output: coldkey.as_slice().into(), - }) - } - - fn parse_netuid(data: &[u8]) -> Result { - if data.len() < 32 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - let mut netuid = [0u8; 2]; - netuid.copy_from_slice(parse_slice(data, 30, 32)?); - let result = u16::from_be_bytes(netuid); - Ok(result) - } - - fn parse_uid(data: &[u8]) -> Result { - if data.len() < 32 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - let mut uid = [0u8; 2]; - uid.copy_from_slice(parse_slice(data, 30, 32)?); - let result = u16::from_be_bytes(uid); - Ok(result) + Ok(H256::from_slice(coldkey.as_slice())) } } @@ -364,3 +153,26 @@ impl PrecompileExt for MetagraphPrecompile { const INDEX: u64 = 2050; const ADDRESS_SS58: [u8; 32] = [0; 32]; } + +#[derive(Codec)] +struct AxonInfo { + block: u64, + version: u32, + ip: u128, + port: u16, + ip_type: u8, + protocol: u8, +} + +impl From for AxonInfo { + fn from(value: SubtensorModuleAxonInfo) -> Self { + Self { + block: value.block, + version: value.version, + ip: value.ip, + port: value.port, + ip_type: value.ip_type, + protocol: value.protocol, + } + } +} From 85f72d9dc4773f82019016e770238a44a89b8185 Mon Sep 17 00:00:00 2001 From: Sam Johnson Date: Sun, 16 Feb 2025 21:53:40 -0500 Subject: [PATCH 06/10] mainnet deploy 2/16/2025 (#1310) * upgrade openssl * fix clippy * address freeze_struct * rename commit_reveal_period * apply criticial openssl update to fix RUSTSEC-2025-0004 (openssl) * remove subnet_info_v3 * address lint * update register_network with identity precompile * fix merge commit * bump spec * remove SubnetInfov3 struct * rename emission_values => emission_value * bump spec * safe math * remove duplicated function * use saturating math * add cleaned coinbase * noclaim * remove complexity * non scaled tao emission * bump * fix test * clean coinbase * pre merge * no tao in for non registration * move to moving prices rather than tao reserves * price * moving alpha * bump spec * Fix tests * add moving price tests * add alpha in tests * Fix all tests * Format * Fix unsafe math * alpha tests * set tao weight * reset default staking fee * fix names * add mainnet names * cargo clippy * cargo fmt * add a global min burn and migration * add more tests for root pending etc * alpha divs * fix test for root * new test root tao * fix wrong parse function * fix test * add toggle off for transfers * delete unused workflow file * Fix validation for transfer toggle * remove duplicate tests * fix subnet creation logic * cargo fmt * add new test * bump spec version to 228 * Add test test_drain_alpha_childkey_parentkey * spec bump * fix audit * fix audit * fix contract * commit Cargo.lock * cargo clippy * cargo fmt * fix min lock * fmt * fix migration test * cargo fmt * fix root * cargo fmt * add moving price to metagraph * use correct min burn init (#1265) * use correct min brun init * fmt * no into * no into 2 * bump spec * cargo update to fix cargo audit vulnerabilities * bump spec version * moving price init from emission * cargo fmt * bump spec version * commit Cargo.lock * cargo clippy * cargo fmt * DefaultMinimumPoolLiquidity and tempos in rao migration * update readme of support of M series macs * bump runtime version * add tao_emission to stakeinfo runtime * remove call from coinbase. already in block_step * add negation for pow-reg-allowed * only root can set min pow diff * oops * dont let ck-in-swap-sched move any stake/register * add tests for validation filter * add transfer stake to call nontransfer proxy filter * also add proxy filters for new calls * update staking priority * bump spec * use get_priority_staking for all stake operations * bump spec * clippy * Remove ownership check from transition stake validation * max the price for EMA calc at 1.0 * uncommitted lockfile change * bump spec version * fix merge conflicts * add CI action that requires clean merges between all named branches * fix * fixes * try again * fix again * fix * fix * stop needless wasting of CI hours with on push triggers we don't need * provide an identity for github action to prevent failure * Add serve_axon extrinsic validation * Bump spec version * Check IP validity in serve_axon validation first * make set diff only root * add test for set diff no owner * add migration for min diff * bump spec * only allow top-stake SN owner hk to stay immune * add tests * only allow replace non-top-stake owner hk * bump spec * add tests using SubnetOwnerHotkey * add impl for replace neuron * add swap test * add neuron prune impl * add swap hotkey impl * clippy * clippy * mistake in test * add some tests * add stake ext test * add move_stake tests * cargo lock * bump spec * clpy * use bool return type * clpy * add higher liquidity on mvoe stake tests --------- Co-authored-by: open-junius Co-authored-by: Aliaksandr Tsurko Co-authored-by: JohnReedV <87283488+JohnReedV@users.noreply.github.com> Co-authored-by: Cameron Fairchild Co-authored-by: unconst Co-authored-by: Greg Zaitsev Co-authored-by: Unconst <32490803+unconst@users.noreply.github.com> Co-authored-by: camfairchild Co-authored-by: Prakash Co-authored-by: ibraheem-opentensor --- pallets/subtensor/src/staking/stake_utils.rs | 39 ++- pallets/subtensor/src/tests/staking.rs | 275 ++++++++++++++++++- primitives/share-pool/src/lib.rs | 23 ++ runtime/src/lib.rs | 2 +- 4 files changed, 332 insertions(+), 7 deletions(-) diff --git a/pallets/subtensor/src/staking/stake_utils.rs b/pallets/subtensor/src/staking/stake_utils.rs index 854fb07cb9..07be25171a 100644 --- a/pallets/subtensor/src/staking/stake_utils.rs +++ b/pallets/subtensor/src/staking/stake_utils.rs @@ -549,6 +549,15 @@ impl Pallet { alpha_share_pool.update_value_for_one(coldkey, amount as i64); } + pub fn try_increase_stake_for_hotkey_and_coldkey_on_subnet( + hotkey: &T::AccountId, + netuid: u16, + amount: u64, + ) -> bool { + let mut alpha_share_pool = Self::get_alpha_share_pool(hotkey.clone(), netuid); + alpha_share_pool.sim_update_value_for_one(amount as i64) + } + /// Sell shares in the hotkey on a given subnet /// /// The function updates share totals given current prices. @@ -877,11 +886,18 @@ impl Pallet { Error::::HotKeyAccountNotExists ); + let expected_alpha = Self::sim_swap_tao_for_alpha(netuid, stake_to_be_added); + // Ensure that we have adequate liquidity - ensure!( - Self::sim_swap_tao_for_alpha(netuid, stake_to_be_added).is_some(), - Error::::InsufficientLiquidity + ensure!(expected_alpha.is_some(), Error::::InsufficientLiquidity); + + // Ensure hotkey pool is precise enough + let try_stake_result = Self::try_increase_stake_for_hotkey_and_coldkey_on_subnet( + hotkey, + netuid, + expected_alpha.unwrap_or(0), ); + ensure!(try_stake_result, Error::::InsufficientLiquidity); Ok(()) } @@ -937,7 +953,7 @@ impl Pallet { origin_coldkey: &T::AccountId, _destination_coldkey: &T::AccountId, origin_hotkey: &T::AccountId, - _destination_hotkey: &T::AccountId, + destination_hotkey: &T::AccountId, origin_netuid: u16, destination_netuid: u16, alpha_amount: u64, @@ -975,7 +991,8 @@ impl Pallet { ); // Ensure that the stake amount to be removed is above the minimum in tao equivalent. - if let Some(tao_equivalent) = Self::sim_swap_alpha_for_tao(origin_netuid, alpha_amount) { + let tao_equivalent_result = Self::sim_swap_alpha_for_tao(origin_netuid, alpha_amount); + if let Some(tao_equivalent) = tao_equivalent_result { ensure!( tao_equivalent > DefaultMinStake::::get(), Error::::AmountTooLow @@ -992,6 +1009,18 @@ impl Pallet { } } + let expected_alpha = + Self::sim_swap_tao_for_alpha(destination_netuid, tao_equivalent_result.unwrap_or(0)) + .unwrap_or(0); + + // Ensure that the amount being staked to the new hotkey is precise enough + let try_stake_result = Self::try_increase_stake_for_hotkey_and_coldkey_on_subnet( + destination_hotkey, + destination_netuid, + expected_alpha, + ); + ensure!(try_stake_result, Error::::InsufficientLiquidity); + if check_transfer_toggle { // Ensure transfer is toggled. ensure!( diff --git a/pallets/subtensor/src/tests/staking.rs b/pallets/subtensor/src/tests/staking.rs index 5282c9941c..f97373b0b3 100644 --- a/pallets/subtensor/src/tests/staking.rs +++ b/pallets/subtensor/src/tests/staking.rs @@ -10,7 +10,7 @@ use approx::assert_abs_diff_eq; use frame_support::dispatch::{DispatchClass, DispatchInfo, GetDispatchInfo, Pays}; use frame_support::sp_runtime::DispatchError; use sp_core::{Get, H256, U256}; -use substrate_fixed::types::{I96F32, U96F32}; +use substrate_fixed::types::{I96F32, U64F64, U96F32}; /*********************************************************** staking::add_stake() tests @@ -3495,3 +3495,276 @@ fn test_remove_stake_limit_fill_or_kill() { ),); }); } + +// #[test] +// fn test_add_stake_specific() { +// new_test_ext(1).execute_with(|| { +// let sn_owner_coldkey = U256::from(55453); + +// let hotkey_account_id = U256::from(533453); +// let coldkey_account_id = U256::from(55454); +// let hotkey_owner_account_id = U256::from(533454); + +// let existing_shares: U64F64 = +// U64F64::from_num(161_986_254).saturating_div(U64F64::from_num(u64::MAX)); +// let existing_stake = 36_711_495_953; +// let amount_added = 1_274_280_132; + +// //add network +// let netuid: u16 = add_dynamic_network(&sn_owner_coldkey, &sn_owner_coldkey); + +// // Register hotkey on netuid +// register_ok_neuron(netuid, hotkey_account_id, hotkey_owner_account_id, 0); +// // Check we have zero staked +// assert_eq!( +// SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), +// 0 +// ); + +// // Set a hotkey pool for the hotkey +// let mut hotkey_pool = SubtensorModule::get_alpha_share_pool(hotkey_account_id, netuid); +// hotkey_pool.update_value_for_one(&hotkey_owner_account_id, 1234); // Doesn't matter, will be overridden + +// // Adjust the total hotkey stake and shares to match the existing values +// TotalHotkeyShares::::insert(hotkey_account_id, netuid, existing_shares); +// TotalHotkeyAlpha::::insert(hotkey_account_id, netuid, existing_stake); + +// // Make the hotkey a delegate +// Delegates::::insert(hotkey_account_id, 0); + +// // Add stake as new hotkey +// SubtensorModule::increase_stake_for_hotkey_and_coldkey_on_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid, +// amount_added, +// ); + +// // Check the stake and shares are correct +// assert!(Alpha::::get((&hotkey_account_id, &coldkey_account_id, netuid)) > 0); +// assert_eq!( +// TotalHotkeyAlpha::::get(hotkey_account_id, netuid), +// amount_added + existing_stake +// ); +// }); +// } + +// #[test] +// // RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::staking::test_add_stake_specific_stake_into_subnet --exact --show-output +// fn test_add_stake_specific_stake_into_subnet() { +// new_test_ext(1).execute_with(|| { +// let sn_owner_coldkey = U256::from(55453); + +// let hotkey_account_id = U256::from(533453); +// let coldkey_account_id = U256::from(55454); +// let hotkey_owner_account_id = U256::from(533454); + +// let existing_shares: U64F64 = +// U64F64::from_num(161_986_254).saturating_div(U64F64::from_num(u64::MAX)); +// let existing_stake = 36_711_495_953; + +// let tao_in = 2_409_892_148_947; +// let alpha_in = 15_358_708_513_716; + +// let tao_staked = 200_000_000; +// let fee = DefaultStakingFee::::get(); + +// //add network +// let netuid: u16 = add_dynamic_network(&sn_owner_coldkey, &sn_owner_coldkey); + +// // Register hotkey on netuid +// register_ok_neuron(netuid, hotkey_account_id, hotkey_owner_account_id, 0); +// // Check we have zero staked +// assert_eq!( +// SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), +// 0 +// ); + +// // Set a hotkey pool for the hotkey +// let mut hotkey_pool = SubtensorModule::get_alpha_share_pool(hotkey_account_id, netuid); +// hotkey_pool.update_value_for_one(&hotkey_owner_account_id, 1234); // Doesn't matter, will be overridden + +// // Adjust the total hotkey stake and shares to match the existing values +// TotalHotkeyShares::::insert(hotkey_account_id, netuid, existing_shares); +// TotalHotkeyAlpha::::insert(hotkey_account_id, netuid, existing_stake); + +// // Make the hotkey a delegate +// Delegates::::insert(hotkey_account_id, 0); + +// // Setup Subnet pool +// SubnetAlphaIn::::insert(netuid, alpha_in); +// SubnetTAO::::insert(netuid, tao_in); + +// // Add stake as new hotkey +// SubtensorModule::stake_into_subnet( +// &hotkey_account_id, +// &coldkey_account_id, +// netuid, +// tao_staked, +// fee, +// ); + +// // Check the stake and shares are correct +// assert!(Alpha::::get((&hotkey_account_id, &coldkey_account_id, netuid)) > 0); +// log::info!( +// "Alpha: {}", +// Alpha::::get((&hotkey_account_id, &coldkey_account_id, netuid)) +// ); +// log::info!( +// "TotalHotkeyAlpha: {}", +// TotalHotkeyAlpha::::get(hotkey_account_id, netuid) +// ); +// }); +// } + +#[test] +// RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::staking::test_add_stake_specific_stake_into_subnet_fail --exact --show-output +fn test_add_stake_specific_stake_into_subnet_fail() { + new_test_ext(1).execute_with(|| { + let sn_owner_coldkey = U256::from(55453); + + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55454); + let hotkey_owner_account_id = U256::from(533454); + + let existing_shares: U64F64 = + U64F64::from_num(161_986_254).saturating_div(U64F64::from_num(u64::MAX)); + let existing_stake = 36_711_495_953; + + let tao_in = 2_409_892_148_947; + let alpha_in = 15_358_708_513_716; + + let tao_staked = 200_000_000; + + //add network + let netuid: u16 = add_dynamic_network(&sn_owner_coldkey, &sn_owner_coldkey); + + // Register hotkey on netuid + register_ok_neuron(netuid, hotkey_account_id, hotkey_owner_account_id, 0); + // Check we have zero staked + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + 0 + ); + + // Set a hotkey pool for the hotkey + let mut hotkey_pool = SubtensorModule::get_alpha_share_pool(hotkey_account_id, netuid); + hotkey_pool.update_value_for_one(&hotkey_owner_account_id, 1234); // Doesn't matter, will be overridden + + // Adjust the total hotkey stake and shares to match the existing values + TotalHotkeyShares::::insert(hotkey_account_id, netuid, existing_shares); + TotalHotkeyAlpha::::insert(hotkey_account_id, netuid, existing_stake); + + // Make the hotkey a delegate + Delegates::::insert(hotkey_account_id, 0); + + // Setup Subnet pool + SubnetAlphaIn::::insert(netuid, alpha_in); + SubnetTAO::::insert(netuid, tao_in); + + // Give TAO balance to coldkey + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_account_id, + tao_staked + 1_000_000_000, + ); + + // Add stake as new hotkey + assert_noop!( + SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + netuid, + tao_staked, + ), + Error::::InsufficientLiquidity + ); + }); +} + +#[test] +// RUST_LOG=info cargo test --package pallet-subtensor --lib -- tests::staking::test_move_stake_specific_stake_into_subnet_fail --exact --show-output +fn test_move_stake_specific_stake_into_subnet_fail() { + new_test_ext(1).execute_with(|| { + let sn_owner_coldkey = U256::from(55453); + + let hotkey_account_id = U256::from(533453); + let coldkey_account_id = U256::from(55454); + let hotkey_owner_account_id = U256::from(533454); + + let existing_shares: U64F64 = + U64F64::from_num(161_986_254).saturating_div(U64F64::from_num(u64::MAX)); + let existing_stake = 36_711_495_953; + + let tao_in = 2_409_892_148_947; + let alpha_in = 15_358_708_513_716; + + let tao_staked = 200_000_000; + + //add network + let netuid: u16 = add_dynamic_network(&sn_owner_coldkey, &sn_owner_coldkey); + + let origin_netuid: u16 = add_dynamic_network(&sn_owner_coldkey, &sn_owner_coldkey); + + // Register hotkey on netuid + register_ok_neuron(netuid, hotkey_account_id, hotkey_owner_account_id, 0); + // Register hotkey on origin netuid + register_ok_neuron(origin_netuid, hotkey_account_id, hotkey_owner_account_id, 0); + + // Check we have zero staked + assert_eq!( + SubtensorModule::get_total_stake_for_hotkey(&hotkey_account_id), + 0 + ); + + // Set a hotkey pool for the hotkey on destination subnet + let mut hotkey_pool = SubtensorModule::get_alpha_share_pool(hotkey_account_id, netuid); + hotkey_pool.update_value_for_one(&hotkey_owner_account_id, 1234); // Doesn't matter, will be overridden + + // Adjust the total hotkey stake and shares to match the existing values + TotalHotkeyShares::::insert(hotkey_account_id, netuid, existing_shares); + TotalHotkeyAlpha::::insert(hotkey_account_id, netuid, existing_stake); + + // Make the hotkey a delegate + Delegates::::insert(hotkey_account_id, 0); + + // Setup Subnet pool + SubnetAlphaIn::::insert(netuid, alpha_in); + SubnetTAO::::insert(netuid, tao_in); + + // Give TAO balance to coldkey + SubtensorModule::add_balance_to_coldkey_account( + &coldkey_account_id, + tao_staked + 1_000_000_000, + ); + + // Setup Subnet pool for origin netuid + SubnetAlphaIn::::insert(origin_netuid, alpha_in + 10_000_000); + SubnetTAO::::insert(origin_netuid, tao_in + 10_000_000); + + // Add stake as new hotkey + assert_ok!(SubtensorModule::add_stake( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + origin_netuid, + tao_staked, + ),); + let alpha_to_move = SubtensorModule::get_stake_for_hotkey_and_coldkey_on_subnet( + &hotkey_account_id, + &coldkey_account_id, + origin_netuid, + ); + + // Move stake to destination subnet + assert_noop!( + SubtensorModule::move_stake( + RuntimeOrigin::signed(coldkey_account_id), + hotkey_account_id, + hotkey_account_id, + origin_netuid, + netuid, + alpha_to_move, + ), + Error::::InsufficientLiquidity + ); + }); +} diff --git a/primitives/share-pool/src/lib.rs b/primitives/share-pool/src/lib.rs index f3e00fca9a..8f963cfd36 100644 --- a/primitives/share-pool/src/lib.rs +++ b/primitives/share-pool/src/lib.rs @@ -75,6 +75,29 @@ where }); } + pub fn sim_update_value_for_one(&mut self, update: i64) -> bool { + let shared_value: U64F64 = self.state_ops.get_shared_value(); + let denominator: U64F64 = self.state_ops.get_denominator(); + + // Then, update this key's share + if denominator == 0 { + true + } else { + // There are already keys in the pool, set or update this key + let value_per_share: I64F64 = I64F64::saturating_from_num( + shared_value + .checked_div(denominator) // denominator is never 0 here + .unwrap_or(U64F64::saturating_from_num(0)), + ); + + let shares_per_update: I64F64 = I64F64::saturating_from_num(update) + .checked_div(value_per_share) + .unwrap_or(I64F64::saturating_from_num(0)); + + shares_per_update != 0 + } + } + /// Update the value associated with an item identified by the Key pub fn update_value_for_one(&mut self, key: &K, update: i64) { let shared_value: U64F64 = self.state_ops.get_shared_value(); diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index bc8d74dd23..8dcce09b1e 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: 238, + spec_version: 239, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From c06a4e9ccd9c1826f45fba06bfd5068bc2a34a32 Mon Sep 17 00:00:00 2001 From: Aliaksandr Tsurko Date: Mon, 17 Feb 2025 16:02:35 +0100 Subject: [PATCH 07/10] Refactor subnet precompile --- runtime/src/precompiles/balance_transfer.rs | 18 +- runtime/src/precompiles/ed25519.rs | 10 +- runtime/src/precompiles/metagraph.rs | 10 +- runtime/src/precompiles/neuron.rs | 21 +- runtime/src/precompiles/solidity/subnet.abi | 46 +- runtime/src/precompiles/solidity/subnet.sol | 20 +- runtime/src/precompiles/staking.rs | 18 +- runtime/src/precompiles/subnet.rs | 1911 +++++-------------- 8 files changed, 583 insertions(+), 1471 deletions(-) diff --git a/runtime/src/precompiles/balance_transfer.rs b/runtime/src/precompiles/balance_transfer.rs index 14966867d8..68b3edb37d 100644 --- a/runtime/src/precompiles/balance_transfer.rs +++ b/runtime/src/precompiles/balance_transfer.rs @@ -17,6 +17,15 @@ use crate::Runtime; pub struct BalanceTransferPrecompile; +impl PrecompileExt for BalanceTransferPrecompile { + const INDEX: u64 = 2048; + const ADDRESS_SS58: [u8; 32] = [ + 0x07, 0xec, 0x71, 0x2a, 0x5d, 0x38, 0x43, 0x4d, 0xdd, 0x03, 0x3f, 0x8f, 0x02, 0x4e, 0xcd, + 0xfc, 0x4b, 0xb5, 0x95, 0x1c, 0x13, 0xc3, 0x08, 0x5c, 0x39, 0x9c, 0x8a, 0x5f, 0x62, 0x93, + 0x70, 0x5d, + ]; +} + #[precompile_utils::precompile] impl BalanceTransferPrecompile { #[precompile::public("transfer(bytes32)")] @@ -38,12 +47,3 @@ impl BalanceTransferPrecompile { handle.try_dispatch_runtime_call(call, contract_to_origin(&Self::ADDRESS_SS58)?) } } - -impl PrecompileExt for BalanceTransferPrecompile { - const INDEX: u64 = 2048; - const ADDRESS_SS58: [u8; 32] = [ - 0x07, 0xec, 0x71, 0x2a, 0x5d, 0x38, 0x43, 0x4d, 0xdd, 0x03, 0x3f, 0x8f, 0x02, 0x4e, 0xcd, - 0xfc, 0x4b, 0xb5, 0x95, 0x1c, 0x13, 0xc3, 0x08, 0x5c, 0x39, 0x9c, 0x8a, 0x5f, 0x62, 0x93, - 0x70, 0x5d, - ]; -} diff --git a/runtime/src/precompiles/ed25519.rs b/runtime/src/precompiles/ed25519.rs index 6ad082029a..1a629df523 100644 --- a/runtime/src/precompiles/ed25519.rs +++ b/runtime/src/precompiles/ed25519.rs @@ -9,6 +9,11 @@ use crate::precompiles::{parse_slice, PrecompileExt}; pub struct Ed25519Verify; +impl PrecompileExt for Ed25519Verify { + const INDEX: u64 = 1026; + const ADDRESS_SS58: [u8; 32] = [0; 32]; +} + impl LinearCostPrecompile for Ed25519Verify { const BASE: u64 = 15; const WORD: u64 = 3; @@ -41,8 +46,3 @@ impl LinearCostPrecompile for Ed25519Verify { Ok((ExitSucceed::Returned, buf.to_vec())) } } - -impl PrecompileExt for Ed25519Verify { - const INDEX: u64 = 1026; - const ADDRESS_SS58: [u8; 32] = [0; 32]; -} diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index bf20f05bc0..3677ede36d 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -14,6 +14,11 @@ use crate::Runtime; pub struct MetagraphPrecompile; +impl PrecompileExt for MetagraphPrecompile { + const INDEX: u64 = 2050; + const ADDRESS_SS58: [u8; 32] = [0; 32]; +} + #[precompile_utils::precompile] impl MetagraphPrecompile { #[precompile::public("getUidCount(uint16)")] @@ -149,11 +154,6 @@ impl MetagraphPrecompile { } } -impl PrecompileExt for MetagraphPrecompile { - const INDEX: u64 = 2050; - const ADDRESS_SS58: [u8; 32] = [0; 32]; -} - #[derive(Codec)] struct AxonInfo { block: u64, diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index cb92a5dfdf..4e0c9478c0 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -15,11 +15,17 @@ use crate::precompiles::{ }; use crate::{Runtime, RuntimeCall}; -// max paramter lenght 4K -pub const MAX_PARAMETER_SIZE: usize = 4 * 1024; - pub struct NeuronPrecompile; +impl PrecompileExt for NeuronPrecompile { + const INDEX: u64 = 2052; + const 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, + ]; +} + #[precompile_utils::precompile] impl NeuronPrecompile { #[precompile::public("setWeights(uint16,uint16[],uint16[],uint64)")] @@ -91,12 +97,3 @@ impl NeuronPrecompile { handle.try_dispatch_runtime_call(call, RawOrigin::Signed(coldkey)) } } - -impl PrecompileExt for NeuronPrecompile { - const INDEX: u64 = 2052; - const 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, - ]; -} diff --git a/runtime/src/precompiles/solidity/subnet.abi b/runtime/src/precompiles/solidity/subnet.abi index fd81850b74..3cc16d9df7 100644 --- a/runtime/src/precompiles/solidity/subnet.abi +++ b/runtime/src/precompiles/solidity/subnet.abi @@ -148,9 +148,9 @@ "name": "getImmunityPeriod", "outputs": [ { - "internalType": "uint64", + "internalType": "uint16", "name": "", - "type": "uint64" + "type": "uint16" } ], "stateMutability": "view", @@ -243,9 +243,9 @@ "name": "getMaxWeightLimit", "outputs": [ { - "internalType": "uint64", + "internalType": "uint16", "name": "", - "type": "uint64" + "type": "uint16" } ], "stateMutability": "view", @@ -443,39 +443,39 @@ "type": "bytes32" }, { - "internalType": "bytes", + "internalType": "string", "name": "subnetName", - "type": "bytes" + "type": "string" }, { - "internalType": "bytes", + "internalType": "string", "name": "githubRepo", - "type": "bytes" + "type": "string" }, { - "internalType": "bytes", + "internalType": "string", "name": "subnetContact", - "type": "bytes" + "type": "string" }, { - "internalType": "bytes", + "internalType": "string", "name": "subnetUrl", - "type": "bytes" + "type": "string" }, { - "internalType": "bytes", + "internalType": "string", "name": "discord", - "type": "bytes" + "type": "string" }, { - "internalType": "bytes", + "internalType": "string", "name": "description", - "type": "bytes" + "type": "string" }, { - "internalType": "bytes", + "internalType": "string", "name": "additional", - "type": "bytes" + "type": "string" } ], "name": "registerNetwork", @@ -622,9 +622,9 @@ "type": "uint16" }, { - "internalType": "uint64", + "internalType": "uint16", "name": "immunityPeriod", - "type": "uint64" + "type": "uint16" } ], "name": "setImmunityPeriod", @@ -712,9 +712,9 @@ "type": "uint16" }, { - "internalType": "uint64", + "internalType": "uint16", "name": "maxWeightLimit", - "type": "uint64" + "type": "uint16" } ], "name": "setMaxWeightLimit", @@ -884,4 +884,4 @@ "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 1afeced493..d5ef0916d9 100644 --- a/runtime/src/precompiles/solidity/subnet.sol +++ b/runtime/src/precompiles/solidity/subnet.sol @@ -8,13 +8,13 @@ interface ISubnet { /// 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, - bytes memory subnetUrl, - bytes memory discord, - bytes memory description, - bytes memory additional + string memory subnetName, + string memory githubRepo, + string memory subnetContact, + string memory subnetUrl, + string memory discord, + string memory description, + string memory additional ) external payable; function getServingRateLimit(uint16 netuid) external view returns (uint64); @@ -61,14 +61,14 @@ interface ISubnet { uint64 adjustmentAlpha ) external payable; - function getMaxWeightLimit(uint16 netuid) external view returns (uint64); + function getMaxWeightLimit(uint16 netuid) external view returns (uint16); function setMaxWeightLimit( uint16 netuid, - uint64 maxWeightLimit + uint16 maxWeightLimit ) external payable; - function getImmunityPeriod(uint16) external view returns (uint64); + function getImmunityPeriod(uint16) external view returns (uint16); function setImmunityPeriod( uint16 netuid, diff --git a/runtime/src/precompiles/staking.rs b/runtime/src/precompiles/staking.rs index d99b0199ee..29441a21be 100644 --- a/runtime/src/precompiles/staking.rs +++ b/runtime/src/precompiles/staking.rs @@ -44,6 +44,15 @@ use crate::{ProxyType, Runtime, RuntimeCall}; pub struct StakingPrecompile; +impl PrecompileExt for StakingPrecompile { + const INDEX: u64 = 2049; + const ADDRESS_SS58: [u8; 32] = [ + 0x26, 0xf4, 0x10, 0x1e, 0x52, 0xb7, 0x57, 0x34, 0x33, 0x24, 0x5b, 0xc3, 0x0a, 0xe1, 0x8b, + 0x63, 0x99, 0x53, 0xd8, 0x41, 0x79, 0x33, 0x03, 0x61, 0x4d, 0xfa, 0xcf, 0xf0, 0x37, 0xf7, + 0x12, 0x94, + ]; +} + #[precompile_utils::precompile] impl StakingPrecompile { #[precompile::public("addStake(bytes32,uint256)")] @@ -167,12 +176,3 @@ impl StakingPrecompile { Ok(()) } } - -impl PrecompileExt for StakingPrecompile { - const INDEX: u64 = 2049; - const ADDRESS_SS58: [u8; 32] = [ - 0x26, 0xf4, 0x10, 0x1e, 0x52, 0xb7, 0x57, 0x34, 0x33, 0x24, 0x5b, 0xc3, 0x0a, 0xe1, 0x8b, - 0x63, 0x99, 0x53, 0xd8, 0x41, 0x79, 0x33, 0x03, 0x61, 0x4d, 0xfa, 0xcf, 0xf0, 0x37, 0xf7, - 0x12, 0x94, - ]; -} diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index 8a46cc7dc6..88b67527c5 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -1,1414 +1,21 @@ +use frame_support::traits::ConstU32; use frame_system::RawOrigin; use pallet_evm::{ AddressMapping, ExitError, ExitSucceed, HashedAddressMapping, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, }; - -use sp_core::U256; -use sp_runtime::{traits::BlakeTwo256, AccountId32, Vec}; +use precompile_utils::{prelude::BoundedString, EvmResult}; +use sp_core::{H256, U256}; +use sp_runtime::{traits::BlakeTwo256, AccountId32}; use sp_std::vec; use crate::precompiles::{ - get_method_id, parse_slice, parse_pubkey, PrecompileExt, PrecompileHandleExt, + get_method_id, parse_pubkey, parse_slice, PrecompileExt, PrecompileHandleExt, }; use crate::{Runtime, RuntimeCall}; -// bytes with max lenght 1K -const MAX_SINGLE_PARAMETER_SIZE: usize = 1024; -// seven bytes with max lenght 1K -const MAX_PARAMETER_SIZE: usize = 7 * MAX_SINGLE_PARAMETER_SIZE; - pub struct SubnetPrecompile; -#[precompile_utils::precompile] -impl SubnetPrecompile { - // pub fn execute(handle: &mut impl PrecompileHandle) -> PrecompileResult { - // let txdata = handle.input(); - // if txdata.len() > MAX_PARAMETER_SIZE { - // log::error!("the length of subnet call is {} ", txdata.len()); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - // let method_id = get_slice(txdata, 0, 4)?; - // let method_input = txdata - // .get(4..) - // .map_or_else(vec::Vec::new, |slice| slice.to_vec()); // Avoiding borrowing conflicts - - // match method_id { - // id if id - // == get_method_id( - // "registerNetwork(bytes32,bytes,bytes,bytes,bytes,bytes,bytes,bytes)", - // ) => - // { - // Self::register_network(handle, &method_input) - // } - // id if id == get_method_id("registerNetwork(bytes32)") => { - // Self::register_network(handle, &method_input) - // } - - // id if id == get_method_id("getServingRateLimit(uint16)") => { - // 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(&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(&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(&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)") => { - // 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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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(&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, - // }), - // } - // } - - // fn register_network(handle: &mut impl PrecompileHandle, data: &[u8]) -> PrecompileResult { - // let call = match data.len() { - // 32 => { - // let (hotkey, _) = get_pubkey(data)?; - // RuntimeCall::SubtensorModule( - // pallet_subtensor::Call::::register_network_with_identity { - // hotkey, - // identity: None, - // }, - // ) - // } - // 33.. => { - // let ( - // hotkey, - // subnet_name, - // github_repo, - // subnet_contact, - // subnet_url, - // discord, - // description, - // additional, - // ) = Self::parse_register_network_parameters(data)?; - - // let identity: pallet_subtensor::SubnetIdentityOfV2 = - // pallet_subtensor::SubnetIdentityOfV2 { - // subnet_name, - // github_repo, - // subnet_contact, - // subnet_url, - // discord, - // description, - // additional, - // }; - - // // Create the register_network callcle - // RuntimeCall::SubtensorModule( - // pallet_subtensor::Call::::register_network_with_identity { - // hotkey, - // identity: Some(identity), - // }, - // ) - // } - // _ => { - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - // }; - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // // Dispatch the register_network call - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: Default::default(), - // }) - // } - - // fn get_serving_rate_limit(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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( - // pallet_admin_utils::Call::::sudo_set_serving_rate_limit { - // netuid, - // serving_rate_limit, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: result.into(), - // }) - // } - - // fn get_min_difficulty(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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( - // pallet_admin_utils::Call::::sudo_set_min_difficulty { - // netuid, - // min_difficulty, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_max_difficulty(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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( - // pallet_admin_utils::Call::::sudo_set_max_difficulty { - // netuid, - // max_difficulty, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_weights_version_key(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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], - // ) -> 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, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_weights_set_rate_limit(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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], - // ) -> 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, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_adjustment_alpha(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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( - // pallet_admin_utils::Call::::sudo_set_adjustment_alpha { - // netuid, - // adjustment_alpha, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_max_weight_limit(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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( - // pallet_admin_utils::Call::::sudo_set_max_weight_limit { - // netuid, - // max_weight_limit, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_immunity_period(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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( - // pallet_admin_utils::Call::::sudo_set_immunity_period { - // netuid, - // immunity_period, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_min_allowed_weights(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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], - // ) -> 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, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_kappa(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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 { - // netuid, - // kappa, - // }); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_rho(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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 { - // netuid, - // rho, - // }); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_activity_cutoff(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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( - // pallet_admin_utils::Call::::sudo_set_activity_cutoff { - // netuid, - // activity_cutoff, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_network_registration_allowed(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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], - // ) -> 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, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_network_pow_registration_allowed(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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], - // ) -> 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, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_min_burn(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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 = - // RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_min_burn { - // netuid, - // min_burn, - // }); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_max_burn(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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 = - // RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_max_burn { - // netuid, - // max_burn, - // }); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_difficulty(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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 = - // RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_difficulty { - // netuid, - // difficulty, - // }); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_bonds_moving_average(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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], - // ) -> 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, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_commit_reveal_weights_enabled(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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], - // ) -> 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, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_liquid_alpha_enabled(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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], - // ) -> 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 }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_alpha_values(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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 = - // RuntimeCall::AdminUtils(pallet_admin_utils::Call::::sudo_set_alpha_values { - // netuid, - // alpha_low, - // alpha_high, - // }); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - // } - - // fn get_commit_reveal_weights_interval(data: &[u8]) -> PrecompileResult { - // let netuid = parse_netuid(data, 30)?; - - // 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], - // ) -> 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, - // }, - // ); - - // let account_id = - // as AddressMapping>::into_account_id( - // handle.context().caller, - // ); - - // try_dispatch_runtime_call(handle, call, RawOrigin::Signed(account_id))?; - // Ok(PrecompileOutput { - // exit_status: ExitSucceed::Returned, - // output: ().into(), - // }) - - // } - - // fn parse_register_network_parameters( - // data: &[u8], - // ) -> Result< - // ( - // AccountId32, - // Vec, - // Vec, - // Vec, - // Vec, - // Vec, - // Vec, - // Vec, - // ), - // PrecompileFailure, - // > { - // let (pubkey, dynamic_params) = get_pubkey(data)?; - // let dynamic_data_len = dynamic_params.len(); - - // let mut buf = [0_u8; 4]; - // // get all start points for the data items: name, repo, contact, url, discord, description, additional - // buf.copy_from_slice(get_slice(data, 60, 64)?); - // let subnet_name_start: usize = u32::from_be_bytes(buf) as usize; - // if subnet_name_start > dynamic_data_len { - // log::error!( - // "the start position of subnet name as {} is too big ", - // subnet_name_start - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // buf.copy_from_slice(get_slice(data, 92, 96)?); - // let github_repo_start: usize = u32::from_be_bytes(buf) as usize; - // if github_repo_start > dynamic_data_len { - // log::error!( - // "the start position of github repo as {} is too big ", - // github_repo_start - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // buf.copy_from_slice(get_slice(data, 124, 128)?); - // let subnet_contact_start: usize = u32::from_be_bytes(buf) as usize; - // if subnet_contact_start > dynamic_data_len { - // log::error!( - // "the start position of subnet contact as {} is too big ", - // subnet_contact_start - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // buf.copy_from_slice(get_slice(data, 156, 160)?); - // let subnet_url_start: usize = u32::from_be_bytes(buf) as usize; - // if subnet_url_start > dynamic_data_len { - // log::error!( - // "the start position of subnet_url as {} is too big ", - // subnet_url_start - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // buf.copy_from_slice(get_slice(data, 188, 192)?); - // let discord_start: usize = u32::from_be_bytes(buf) as usize; - // if discord_start > dynamic_data_len { - // log::error!( - // "the start position of discord as {} is too big ", - // discord_start - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // buf.copy_from_slice(get_slice(data, 220, 224)?); - // let description_start: usize = u32::from_be_bytes(buf) as usize; - // if description_start > dynamic_data_len { - // log::error!( - // "the start position of description as {} is too big ", - // description_start - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // buf.copy_from_slice(get_slice(data, 252, 256)?); - // let additional_start: usize = u32::from_be_bytes(buf) as usize; - // if additional_start > dynamic_data_len { - // log::error!( - // "the start position of additional as {} is too big ", - // additional_start - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // // get name - // buf.copy_from_slice(get_slice( - // data, - // subnet_name_start + 28, - // subnet_name_start + 32, - // )?); - // let subnet_name_len: usize = u32::from_be_bytes(buf) as usize; - - // if subnet_name_len > MAX_SINGLE_PARAMETER_SIZE { - // log::error!( - // "the length of subnet name as {} is too big", - // subnet_name_len - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // let mut name_vec = vec![0; subnet_name_len]; - // name_vec.copy_from_slice(get_slice( - // data, - // subnet_name_start + 32, - // subnet_name_start + subnet_name_len + 32, - // )?); - - // // get repo data - // buf.copy_from_slice(get_slice( - // data, - // github_repo_start + 28, - // github_repo_start + 32, - // )?); - // let github_repo_len: usize = u32::from_be_bytes(buf) as usize; - // if github_repo_len > MAX_SINGLE_PARAMETER_SIZE { - // log::error!( - // "the length of github repo as {} is too big", - // github_repo_len - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // let mut repo_vec = vec![0; github_repo_len]; - // repo_vec.copy_from_slice(get_slice( - // data, - // github_repo_start + 32, - // github_repo_start + github_repo_len + 32, - // )?); - - // // get contact data - // buf.copy_from_slice(get_slice( - // data, - // subnet_contact_start + 28, - // subnet_contact_start + 32, - // )?); - // let subnet_contact_len: usize = u32::from_be_bytes(buf) as usize; - // if subnet_contact_len > MAX_SINGLE_PARAMETER_SIZE { - // log::error!( - // "the length of subnet contact as {} is too big", - // subnet_contact_len - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - - // let mut contact_vec = vec![0; subnet_contact_len]; - // contact_vec.copy_from_slice(get_slice( - // data, - // subnet_contact_start + 32, - // subnet_contact_start + subnet_contact_len + 32, - // )?); - - // // get subnet_url - // buf.copy_from_slice(get_slice( - // data, - // subnet_url_start + 28, - // subnet_url_start + 32, - // )?); - // let subnet_url_len: usize = u32::from_be_bytes(buf) as usize; - // if subnet_url_len > MAX_SINGLE_PARAMETER_SIZE { - // log::error!("the length of subnet_url as {} is too big", subnet_url_len); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - // let mut url_vec = vec![0; subnet_url_len]; - // url_vec.copy_from_slice(get_slice( - // data, - // subnet_url_start + 32, - // subnet_url_start + subnet_url_len + 32, - // )?); - - // // get discord - // buf.copy_from_slice(get_slice(data, discord_start + 28, discord_start + 32)?); - // let discord_len: usize = u32::from_be_bytes(buf) as usize; - // if discord_len > MAX_SINGLE_PARAMETER_SIZE { - // log::error!("the length of discord as {} is too big", discord_len); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - // let mut discord_vec = vec![0; discord_len]; - // discord_vec.copy_from_slice(get_slice( - // data, - // discord_start + 32, - // discord_start + discord_len + 32, - // )?); - - // // get description - // buf.copy_from_slice(get_slice( - // data, - // description_start + 28, - // description_start + 32, - // )?); - // let description_len: usize = u32::from_be_bytes(buf) as usize; - // if description_len > MAX_SINGLE_PARAMETER_SIZE { - // log::error!( - // "the length of description as {} is too big", - // description_len - // ); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - // let mut description_vec = vec![0; description_len]; - // description_vec.copy_from_slice(get_slice( - // data, - // description_start + 32, - // description_start + description_len + 32, - // )?); - - // // get additional - // buf.copy_from_slice(get_slice( - // data, - // additional_start + 28, - // additional_start + 32, - // )?); - // let additional_len: usize = u32::from_be_bytes(buf) as usize; - // if additional_len > MAX_SINGLE_PARAMETER_SIZE { - // log::error!("the length of additional as {} is too big", additional_len); - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - // let mut additional_vec = vec![0; additional_len]; - // additional_vec.copy_from_slice(get_slice( - // data, - // additional_start + 32, - // additional_start + additional_len + 32, - // )?); - - // Ok(( - // pubkey, - // name_vec, - // repo_vec, - // contact_vec, - // url_vec, - // discord_vec, - // description_vec, - // additional_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 netuid = parse_netuid(data, 30)?; - - // 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 netuid = parse_netuid(data, 30)?; - - // 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() < 96 { - // return Err(PrecompileFailure::Error { - // exit_status: ExitError::InvalidRange, - // }); - // } - // let netuid = parse_netuid(data, 30)?; - - // 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 netuid = parse_netuid(data, 30)?; - - // 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)) - // } -} - impl PrecompileExt for SubnetPrecompile { const INDEX: u64 = 2051; const ADDRESS_SS58: [u8; 32] = [ @@ -1417,3 +24,511 @@ impl PrecompileExt for SubnetPrecompile { 0x1c, 0xd3, ]; } + +#[precompile_utils::precompile] +impl SubnetPrecompile { + #[precompile::public("registerNetwork(bytes32)")] + #[precompile::payable] + fn register_network(handle: &mut impl PrecompileHandle, hotkey: H256) -> EvmResult<()> { + let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; + let call = pallet_subtensor::Call::::register_network_with_identity { + hotkey, + identity: None, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public( + "registerNetwork(bytes32,string,string,string,string,string,string,string)" + )] + #[precompile::payable] + fn register_network_with_identity( + handle: &mut impl PrecompileHandle, + hotkey: H256, + subnet_name: BoundedString>, + github_repo: BoundedString>, + subnet_contact: BoundedString>, + subnet_url: BoundedString>, + discord: BoundedString>, + description: BoundedString>, + additional: BoundedString>, + ) -> EvmResult<()> { + let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; + let identity = pallet_subtensor::SubnetIdentityOfV2 { + subnet_name: subnet_name.into(), + github_repo: github_repo.into(), + subnet_contact: subnet_contact.into(), + subnet_url: subnet_url.into(), + discord: discord.into(), + description: description.into(), + additional: additional.into(), + }; + + let call = pallet_subtensor::Call::::register_network_with_identity { + hotkey, + identity: Some(identity), + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getServingRateLimit(uint16)")] + #[precompile::view] + fn get_serving_rate_limit(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::ServingRateLimit::::get(netuid)) + } + + #[precompile::public("setServingRateLimit(uint16,uint64)")] + #[precompile::payable] + fn set_serving_rate_limit( + handle: &mut impl PrecompileHandle, + netuid: u16, + serving_rate_limit: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_serving_rate_limit { + netuid, + serving_rate_limit, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getMinDifficulty(uint16)")] + #[precompile::view] + fn get_min_difficulty(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::MinDifficulty::::get(netuid)) + } + + #[precompile::public("setMinDifficulty(uint16,uint64)")] + #[precompile::payable] + fn set_min_difficulty( + handle: &mut impl PrecompileHandle, + netuid: u16, + min_difficulty: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_min_difficulty { + netuid, + min_difficulty, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getMaxDifficulty(uint16)")] + #[precompile::view] + fn get_max_difficulty(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::MaxDifficulty::::get(netuid)) + } + + #[precompile::public("setMaxDifficulty(uint16,uint64)")] + #[precompile::payable] + fn set_max_difficulty( + handle: &mut impl PrecompileHandle, + netuid: u16, + max_difficulty: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_max_difficulty { + netuid, + max_difficulty, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getWeightsVersionKey(uint16)")] + #[precompile::view] + fn get_weights_version_key(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::WeightsVersionKey::::get(netuid)) + } + + #[precompile::public("setWeightsVersionKey(uint16,uint64)")] + #[precompile::payable] + fn set_weights_version_key( + handle: &mut impl PrecompileHandle, + netuid: u16, + weights_version_key: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_weights_version_key { + netuid, + weights_version_key, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getWeightsSetRateLimit(uint16)")] + #[precompile::view] + fn get_weights_set_rate_limit( + handle: &mut impl PrecompileHandle, + netuid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::WeightsSetRateLimit::::get( + netuid, + )) + } + + #[precompile::public("setWeightsSetRateLimit(uint16,uint64)")] + #[precompile::payable] + fn set_weights_set_rate_limit( + handle: &mut impl PrecompileHandle, + netuid: u16, + weights_set_rate_limit: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_weights_set_rate_limit { + netuid, + weights_set_rate_limit, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getAdjustmentAlpha(uint16)")] + #[precompile::view] + fn get_adjustment_alpha(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::AdjustmentAlpha::::get(netuid)) + } + + #[precompile::public("setAdjustmentAlpha(uint16,uint64)")] + #[precompile::payable] + fn set_adjustment_alpha( + handle: &mut impl PrecompileHandle, + netuid: u16, + adjustment_alpha: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_adjustment_alpha { + netuid, + adjustment_alpha, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getMaxWeightLimit(uint16)")] + #[precompile::view] + fn get_max_weight_limit(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::MaxWeightsLimit::::get(netuid)) + } + + #[precompile::public("setMaxWeightLimit(uint16,uint16)")] + #[precompile::payable] + fn set_max_weight_limit( + handle: &mut impl PrecompileHandle, + netuid: u16, + max_weight_limit: u16, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_max_weight_limit { + netuid, + max_weight_limit, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getImmunityPeriod(uint16)")] + #[precompile::view] + fn get_immunity_period(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::ImmunityPeriod::::get(netuid)) + } + + #[precompile::public("setImmunityPeriod(uint16,uint16)")] + #[precompile::payable] + fn set_immunity_period( + handle: &mut impl PrecompileHandle, + netuid: u16, + immunity_period: u16, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_immunity_period { + netuid, + immunity_period, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getMinAllowedWeights(uint16)")] + #[precompile::view] + fn get_min_allowed_weights(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::MinAllowedWeights::::get(netuid)) + } + + #[precompile::public("setMinAllowedWeights(uint16,uint16)")] + #[precompile::payable] + fn set_min_allowed_weights( + handle: &mut impl PrecompileHandle, + netuid: u16, + min_allowed_weights: u16, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_min_allowed_weights { + netuid, + min_allowed_weights, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getKappa(uint16)")] + #[precompile::view] + fn get_kappa(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::Kappa::::get(netuid)) + } + + #[precompile::public("setKappa(uint16,uint16)")] + #[precompile::payable] + fn set_kappa(handle: &mut impl PrecompileHandle, netuid: u16, kappa: u16) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_kappa { netuid, kappa }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getRho(uint16)")] + #[precompile::view] + fn get_rho(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::Rho::::get(netuid)) + } + + #[precompile::public("setRho(uint16,uint16)")] + #[precompile::payable] + fn set_rho(handle: &mut impl PrecompileHandle, netuid: u16, rho: u16) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_rho { netuid, rho }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getActivityCutoff(uint16)")] + #[precompile::view] + fn get_activity_cutoff(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::ActivityCutoff::::get(netuid)) + } + + #[precompile::public("setActivityCutoff(uint16,uint16)")] + #[precompile::payable] + fn set_activity_cutoff( + handle: &mut impl PrecompileHandle, + netuid: u16, + activity_cutoff: u16, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_activity_cutoff { + netuid, + activity_cutoff, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getNetworkRegistrationAllowed(uint16)")] + #[precompile::view] + fn get_network_registration_allowed( + handle: &mut impl PrecompileHandle, + netuid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::NetworkRegistrationAllowed::::get(netuid)) + } + + #[precompile::public("setNetworkRegistrationAllowed(uint16,bool)")] + #[precompile::payable] + fn set_network_registration_allowed( + handle: &mut impl PrecompileHandle, + netuid: u16, + registration_allowed: bool, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_network_registration_allowed { + netuid, + registration_allowed, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getNetworkPowRegistrationAllowed(uint16)")] + #[precompile::view] + fn get_network_pow_registration_allowed( + handle: &mut impl PrecompileHandle, + netuid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::NetworkPowRegistrationAllowed::::get(netuid)) + } + + #[precompile::public("setNetworkPowRegistrationAllowed(uint16,bool)")] + #[precompile::payable] + fn set_network_pow_registration_allowed( + handle: &mut impl PrecompileHandle, + netuid: u16, + registration_allowed: bool, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_network_pow_registration_allowed { + netuid, + registration_allowed, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getMinBurn(uint16)")] + #[precompile::view] + fn get_min_burn(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::MinBurn::::get(netuid)) + } + + #[precompile::public("setMinBurn(uint16,uint64)")] + #[precompile::payable] + fn set_min_burn( + handle: &mut impl PrecompileHandle, + netuid: u16, + min_burn: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_min_burn { netuid, min_burn }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getMaxBurn(uint16)")] + #[precompile::view] + fn get_max_burn(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::MaxBurn::::get(netuid)) + } + + #[precompile::public("setMaxBurn(uint16,uint64)")] + #[precompile::payable] + fn set_max_burn( + handle: &mut impl PrecompileHandle, + netuid: u16, + max_burn: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_max_burn { netuid, max_burn }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getDifficulty(uint16)")] + #[precompile::view] + fn get_difficulty(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::Difficulty::::get(netuid)) + } + + #[precompile::public("setDifficulty(uint16,uint64)")] + #[precompile::payable] + fn set_difficulty( + handle: &mut impl PrecompileHandle, + netuid: u16, + difficulty: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_difficulty { netuid, difficulty }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getBondsMovingAverage(uint16)")] + #[precompile::view] + fn get_bonds_moving_average(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + Ok(pallet_subtensor::BondsMovingAverage::::get(netuid)) + } + + #[precompile::public("setBondsMovingAverage(uint16,uint64)")] + #[precompile::payable] + fn set_bonds_moving_average( + handle: &mut impl PrecompileHandle, + netuid: u16, + bonds_moving_average: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_bonds_moving_average { + netuid, + bonds_moving_average, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getCommitRevealWeightsEnabled(uint16)")] + #[precompile::view] + fn get_commit_reveal_weights_enabled( + handle: &mut impl PrecompileHandle, + netuid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::CommitRevealWeightsEnabled::::get(netuid)) + } + + #[precompile::public("setCommitRevealWeightsEnabled(uint16,bool)")] + #[precompile::payable] + fn set_commit_reveal_weights_enabled( + handle: &mut impl PrecompileHandle, + netuid: u16, + enabled: bool, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_commit_reveal_weights_enabled { + netuid, + enabled, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getLiquidAlphaEnabled(uint16)")] + #[precompile::view] + fn get_liquid_alpha_enabled( + handle: &mut impl PrecompileHandle, + netuid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::LiquidAlphaOn::::get(netuid)) + } + + #[precompile::public("setLiquidAlphaEnabled(uint16,bool)")] + #[precompile::payable] + fn set_liquid_alpha_enabled( + handle: &mut impl PrecompileHandle, + netuid: u16, + enabled: bool, + ) -> EvmResult<()> { + let call = + pallet_admin_utils::Call::::sudo_set_liquid_alpha_enabled { netuid, enabled }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getAlphaValues(uint16)")] + #[precompile::view] + fn get_alpha_values(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult<(u16, u16)> { + Ok(pallet_subtensor::AlphaValues::::get(netuid)) + } + + #[precompile::public("setAlphaValues(uint16,uint16,uint16)")] + #[precompile::payable] + fn set_alpha_values( + handle: &mut impl PrecompileHandle, + netuid: u16, + alpha_low: u16, + alpha_high: u16, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_alpha_values { + netuid, + alpha_low, + alpha_high, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } + + #[precompile::public("getCommitRevealWeightsInterval(uint16)")] + #[precompile::view] + fn get_commit_reveal_weights_interval( + handle: &mut impl PrecompileHandle, + netuid: u16, + ) -> EvmResult { + Ok(pallet_subtensor::RevealPeriodEpochs::::get(netuid)) + } + + #[precompile::public("setCommitRevealWeightsInterval(uint16,uint64)")] + #[precompile::payable] + fn set_commit_reveal_weights_interval( + handle: &mut impl PrecompileHandle, + netuid: u16, + interval: u64, + ) -> EvmResult<()> { + let call = pallet_admin_utils::Call::::sudo_set_commit_reveal_weights_interval { + netuid, + interval, + }; + + handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) + } +} From f0310f54c461d9046381672b502b6325e7ac67e1 Mon Sep 17 00:00:00 2001 From: Aliaksandr Tsurko Date: Mon, 17 Feb 2025 16:09:27 +0100 Subject: [PATCH 08/10] Reformat --- runtime/src/precompiles/balance_transfer.rs | 13 +--- runtime/src/precompiles/metagraph.rs | 43 ++++++-------- runtime/src/precompiles/mod.rs | 43 +++----------- runtime/src/precompiles/neuron.rs | 14 +---- runtime/src/precompiles/staking.rs | 13 +--- runtime/src/precompiles/subnet.rs | 66 +++++++++------------ 6 files changed, 62 insertions(+), 130 deletions(-) diff --git a/runtime/src/precompiles/balance_transfer.rs b/runtime/src/precompiles/balance_transfer.rs index 68b3edb37d..3b326bca28 100644 --- a/runtime/src/precompiles/balance_transfer.rs +++ b/runtime/src/precompiles/balance_transfer.rs @@ -1,18 +1,9 @@ -use core::marker::PhantomData; - -use pallet_evm::{ - BalanceConverter, ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle, - PrecompileOutput, PrecompileResult, -}; +use pallet_evm::PrecompileHandle; use precompile_utils::EvmResult; use sp_core::H256; use sp_runtime::traits::UniqueSaturatedInto; -use sp_runtime::AccountId32; -use sp_std::vec::Vec; -use crate::precompiles::{ - contract_to_origin, get_method_id, parse_slice, parse_pubkey, PrecompileExt, PrecompileHandleExt, -}; +use crate::precompiles::{contract_to_origin, parse_pubkey, PrecompileExt, PrecompileHandleExt}; use crate::Runtime; pub struct BalanceTransferPrecompile; diff --git a/runtime/src/precompiles/metagraph.rs b/runtime/src/precompiles/metagraph.rs index 3677ede36d..f74812cc09 100644 --- a/runtime/src/precompiles/metagraph.rs +++ b/runtime/src/precompiles/metagraph.rs @@ -1,15 +1,12 @@ extern crate alloc; use alloc::string::String; -use fp_evm::{ - ExitError, ExitSucceed, PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, -}; +use fp_evm::{ExitError, PrecompileFailure, PrecompileHandle}; use pallet_subtensor::AxonInfo as SubtensorModuleAxonInfo; use precompile_utils::{solidity::Codec, EvmResult}; -use sp_core::{ByteArray, H256, U256}; -use sp_std::vec; +use sp_core::{ByteArray, H256}; -use crate::precompiles::{get_method_id, parse_slice, PrecompileExt, PrecompileHandleExt}; +use crate::precompiles::PrecompileExt; use crate::Runtime; pub struct MetagraphPrecompile; @@ -23,13 +20,13 @@ impl PrecompileExt for MetagraphPrecompile { impl MetagraphPrecompile { #[precompile::public("getUidCount(uint16)")] #[precompile::view] - fn get_uid_count(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_uid_count(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::SubnetworkN::::get(netuid)) } #[precompile::public("getStake(uint16,uint16)")] #[precompile::view] - fn get_stake(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_stake(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { exit_status: ExitError::InvalidRange, @@ -40,7 +37,7 @@ impl MetagraphPrecompile { #[precompile::public("getRank(uint16,uint16)")] #[precompile::view] - fn get_rank(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_rank(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_rank_for_uid( netuid, uid, )) @@ -48,7 +45,7 @@ impl MetagraphPrecompile { #[precompile::public("getTrust(uint16,uint16)")] #[precompile::view] - fn get_trust(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_trust(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_trust_for_uid( netuid, uid, )) @@ -56,7 +53,7 @@ impl MetagraphPrecompile { #[precompile::public("getConsensus(uint16,uint16)")] #[precompile::view] - fn get_consensus(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_consensus(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_consensus_for_uid( netuid, uid, )) @@ -64,7 +61,7 @@ impl MetagraphPrecompile { #[precompile::public("getIncentive(uint16,uint16)")] #[precompile::view] - fn get_incentive(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_incentive(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_incentive_for_uid( netuid, uid, )) @@ -72,7 +69,7 @@ impl MetagraphPrecompile { #[precompile::public("getDividends(uint16,uint16)")] #[precompile::view] - fn get_dividends(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_dividends(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_dividends_for_uid( netuid, uid, )) @@ -80,7 +77,7 @@ impl MetagraphPrecompile { #[precompile::public("getEmission(uint16,uint16)")] #[precompile::view] - fn get_emission(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_emission(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_emission_for_uid( netuid, uid, )) @@ -88,14 +85,14 @@ impl MetagraphPrecompile { #[precompile::public("getVtrust(uint16,uint16)")] #[precompile::view] - fn get_vtrust(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_vtrust(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_validator_trust_for_uid(netuid, uid)) } #[precompile::public("getValidatorStatus(uint16,uint16)")] #[precompile::view] fn get_validator_status( - handle: &mut impl PrecompileHandle, + _: &mut impl PrecompileHandle, netuid: u16, uid: u16, ) -> EvmResult { @@ -104,17 +101,13 @@ impl MetagraphPrecompile { #[precompile::public("getLastUpdate(uint16,uint16)")] #[precompile::view] - fn get_last_update( - handle: &mut impl PrecompileHandle, - netuid: u16, - uid: u16, - ) -> EvmResult { + fn get_last_update(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_last_update_for_uid(netuid, uid)) } #[precompile::public("getIsActive(uint16,uint16)")] #[precompile::view] - fn get_is_active(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_is_active(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_active_for_uid( netuid, uid, )) @@ -122,7 +115,7 @@ impl MetagraphPrecompile { #[precompile::public("getAxon(uint16,uint16)")] #[precompile::view] - fn get_axon(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_axon(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { exit_status: ExitError::Other("hotkey not found".into()), @@ -133,7 +126,7 @@ impl MetagraphPrecompile { #[precompile::public("getHotkey(uint16,uint16)")] #[precompile::view] - fn get_hotkey(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_hotkey(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map(|acc| H256::from_slice(acc.as_slice())) .map_err(|_| PrecompileFailure::Error { @@ -143,7 +136,7 @@ impl MetagraphPrecompile { #[precompile::public("getColdkey(uint16,uint16)")] #[precompile::view] - fn get_coldkey(handle: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { + fn get_coldkey(_: &mut impl PrecompileHandle, netuid: u16, uid: u16) -> EvmResult { let hotkey = pallet_subtensor::Pallet::::get_hotkey_for_net_and_uid(netuid, uid) .map_err(|_| PrecompileFailure::Error { exit_status: ExitError::InvalidRange, diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index 76bf110d81..0e5918e4d1 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -6,15 +6,15 @@ use core::marker::PhantomData; use frame_support::dispatch::{GetDispatchInfo, Pays}; use frame_system::RawOrigin; use pallet_evm::{ - AddressMapping, BalanceConverter, ExitError, ExitSucceed, GasWeightMapping, - HashedAddressMapping, IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle, - PrecompileOutput, PrecompileResult, PrecompileSet, + AddressMapping, BalanceConverter, ExitError, GasWeightMapping, HashedAddressMapping, + IsPrecompileResult, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult, + PrecompileSet, }; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_sha3fips::Sha3FIPS256; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; use precompile_utils::EvmResult; -use sp_core::{hashing::keccak_256, H160, U256}; +use sp_core::{H160, U256}; use sp_runtime::traits::BlakeTwo256; use sp_runtime::{traits::Dispatchable, AccountId32}; use sp_std::vec; @@ -114,19 +114,8 @@ fn hash(a: u64) -> H160 { H160::from_low_u64_be(a) } -/// Returns Ethereum method ID from an str method signature -/// -pub fn get_method_id(method_signature: &str) -> [u8; 4] { - // Calculate the full Keccak-256 hash of the method signature - let hash = keccak_256(method_signature.as_bytes()); - - // Extract the first 4 bytes to get the method ID - [hash[0], hash[1], hash[2], hash[3]] -} - /// Takes a slice from bytes with PrecompileFailure as Error -/// -pub fn parse_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], PrecompileFailure> { +fn parse_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], PrecompileFailure> { let maybe_slice = data.get(from..to); if let Some(slice) = maybe_slice { Ok(slice) @@ -143,7 +132,7 @@ pub fn parse_slice(data: &[u8], from: usize, to: usize) -> Result<&[u8], Precomp } } -pub fn parse_pubkey(data: &[u8]) -> Result<(AccountId32, vec::Vec), PrecompileFailure> { +fn parse_pubkey(data: &[u8]) -> Result<(AccountId32, vec::Vec), PrecompileFailure> { let mut pubkey = [0u8; 32]; pubkey.copy_from_slice(parse_slice(data, 0, 32)?); @@ -155,31 +144,17 @@ pub fn parse_pubkey(data: &[u8]) -> Result<(AccountId32, vec::Vec), Precompi } fn try_u16_from_u256(value: U256) -> Result { - u16::try_from(value.as_u32()).map_err(|_| PrecompileFailure::Error { + value.try_into().map_err(|_| PrecompileFailure::Error { exit_status: ExitError::Other("the value is outside of u16 bounds".into()), }) } -fn parse_netuid(data: &[u8], offset: usize) -> Result { - if data.len() < offset + 2 { - return Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }); - } - - let mut netuid_bytes = [0u8; 2]; - netuid_bytes.copy_from_slice(parse_slice(data, offset, offset + 2)?); - let netuid: u16 = netuid_bytes[1] as u16 | ((netuid_bytes[0] as u16) << 8u16); - - Ok(netuid) -} - fn contract_to_origin(contract: &[u8; 32]) -> Result, PrecompileFailure> { let (account_id, _) = parse_pubkey(contract)?; Ok(RawOrigin::Signed(account_id)) } -pub(crate) trait PrecompileHandleExt: PrecompileHandle { +trait PrecompileHandleExt: PrecompileHandle { fn caller_account_id(&self) -> AccountId32 { as AddressMapping>::into_account_id( self.context().caller, @@ -266,7 +241,7 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { impl PrecompileHandleExt for T where T: PrecompileHandle {} -pub(crate) trait PrecompileExt: Precompile { +trait PrecompileExt: Precompile { const INDEX: u64; // ss58 public key i.e., the contract sends funds it received to the destination address from // the method parameter. diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 4e0c9478c0..b7dba980c0 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -1,19 +1,11 @@ use frame_system::RawOrigin; -use pallet_evm::{ - AddressMapping, ExitError, HashedAddressMapping, PrecompileFailure, PrecompileHandle, - PrecompileResult, -}; +use pallet_evm::PrecompileHandle; use precompile_utils::EvmResult; use sp_core::H256; -use sp_runtime::traits::BlakeTwo256; -use sp_runtime::AccountId32; -use sp_std::vec; use sp_std::vec::Vec; -use crate::precompiles::{ - get_method_id, parse_netuid, parse_pubkey, parse_slice, PrecompileExt, PrecompileHandleExt, -}; -use crate::{Runtime, RuntimeCall}; +use crate::precompiles::{parse_pubkey, PrecompileExt, PrecompileHandleExt}; +use crate::Runtime; pub struct NeuronPrecompile; diff --git a/runtime/src/precompiles/staking.rs b/runtime/src/precompiles/staking.rs index 29441a21be..84b2d84700 100644 --- a/runtime/src/precompiles/staking.rs +++ b/runtime/src/precompiles/staking.rs @@ -26,20 +26,13 @@ // use frame_system::RawOrigin; -use pallet_evm::{ - AddressMapping, BalanceConverter, ExitError, ExitSucceed, HashedAddressMapping, - PrecompileFailure, PrecompileHandle, PrecompileOutput, PrecompileResult, -}; +use pallet_evm::{BalanceConverter, ExitError, PrecompileFailure, PrecompileHandle}; use precompile_utils::EvmResult; use sp_core::{H256, U256}; -use sp_runtime::traits::{BlakeTwo256, Dispatchable, StaticLookup, UniqueSaturatedInto}; +use sp_runtime::traits::{Dispatchable, StaticLookup, UniqueSaturatedInto}; use sp_runtime::AccountId32; -use sp_std::vec; -use crate::precompiles::{ - get_method_id, parse_slice, parse_netuid, parse_pubkey, try_u16_from_u256, PrecompileExt, - PrecompileHandleExt, -}; +use crate::precompiles::{parse_pubkey, try_u16_from_u256, PrecompileExt, PrecompileHandleExt}; use crate::{ProxyType, Runtime, RuntimeCall}; pub struct StakingPrecompile; diff --git a/runtime/src/precompiles/subnet.rs b/runtime/src/precompiles/subnet.rs index 88b67527c5..afda39dd30 100644 --- a/runtime/src/precompiles/subnet.rs +++ b/runtime/src/precompiles/subnet.rs @@ -1,18 +1,11 @@ use frame_support::traits::ConstU32; use frame_system::RawOrigin; -use pallet_evm::{ - AddressMapping, ExitError, ExitSucceed, HashedAddressMapping, PrecompileFailure, - PrecompileHandle, PrecompileOutput, PrecompileResult, -}; +use pallet_evm::PrecompileHandle; use precompile_utils::{prelude::BoundedString, EvmResult}; -use sp_core::{H256, U256}; -use sp_runtime::{traits::BlakeTwo256, AccountId32}; -use sp_std::vec; +use sp_core::H256; -use crate::precompiles::{ - get_method_id, parse_pubkey, parse_slice, PrecompileExt, PrecompileHandleExt, -}; -use crate::{Runtime, RuntimeCall}; +use crate::precompiles::{parse_pubkey, PrecompileExt, PrecompileHandleExt}; +use crate::Runtime; pub struct SubnetPrecompile; @@ -43,6 +36,7 @@ impl SubnetPrecompile { "registerNetwork(bytes32,string,string,string,string,string,string,string)" )] #[precompile::payable] + #[allow(clippy::too_many_arguments)] fn register_network_with_identity( handle: &mut impl PrecompileHandle, hotkey: H256, @@ -75,7 +69,7 @@ impl SubnetPrecompile { #[precompile::public("getServingRateLimit(uint16)")] #[precompile::view] - fn get_serving_rate_limit(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_serving_rate_limit(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::ServingRateLimit::::get(netuid)) } @@ -96,7 +90,7 @@ impl SubnetPrecompile { #[precompile::public("getMinDifficulty(uint16)")] #[precompile::view] - fn get_min_difficulty(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_min_difficulty(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::MinDifficulty::::get(netuid)) } @@ -117,7 +111,7 @@ impl SubnetPrecompile { #[precompile::public("getMaxDifficulty(uint16)")] #[precompile::view] - fn get_max_difficulty(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_max_difficulty(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::MaxDifficulty::::get(netuid)) } @@ -138,7 +132,7 @@ impl SubnetPrecompile { #[precompile::public("getWeightsVersionKey(uint16)")] #[precompile::view] - fn get_weights_version_key(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_weights_version_key(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::WeightsVersionKey::::get(netuid)) } @@ -159,10 +153,7 @@ impl SubnetPrecompile { #[precompile::public("getWeightsSetRateLimit(uint16)")] #[precompile::view] - fn get_weights_set_rate_limit( - handle: &mut impl PrecompileHandle, - netuid: u16, - ) -> EvmResult { + fn get_weights_set_rate_limit(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::WeightsSetRateLimit::::get( netuid, )) @@ -185,7 +176,7 @@ impl SubnetPrecompile { #[precompile::public("getAdjustmentAlpha(uint16)")] #[precompile::view] - fn get_adjustment_alpha(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_adjustment_alpha(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::AdjustmentAlpha::::get(netuid)) } @@ -206,7 +197,7 @@ impl SubnetPrecompile { #[precompile::public("getMaxWeightLimit(uint16)")] #[precompile::view] - fn get_max_weight_limit(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_max_weight_limit(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::MaxWeightsLimit::::get(netuid)) } @@ -227,7 +218,7 @@ impl SubnetPrecompile { #[precompile::public("getImmunityPeriod(uint16)")] #[precompile::view] - fn get_immunity_period(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_immunity_period(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::ImmunityPeriod::::get(netuid)) } @@ -248,7 +239,7 @@ impl SubnetPrecompile { #[precompile::public("getMinAllowedWeights(uint16)")] #[precompile::view] - fn get_min_allowed_weights(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_min_allowed_weights(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::MinAllowedWeights::::get(netuid)) } @@ -269,7 +260,7 @@ impl SubnetPrecompile { #[precompile::public("getKappa(uint16)")] #[precompile::view] - fn get_kappa(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_kappa(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::Kappa::::get(netuid)) } @@ -283,7 +274,7 @@ impl SubnetPrecompile { #[precompile::public("getRho(uint16)")] #[precompile::view] - fn get_rho(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_rho(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::Rho::::get(netuid)) } @@ -297,7 +288,7 @@ impl SubnetPrecompile { #[precompile::public("getActivityCutoff(uint16)")] #[precompile::view] - fn get_activity_cutoff(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_activity_cutoff(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::ActivityCutoff::::get(netuid)) } @@ -319,7 +310,7 @@ impl SubnetPrecompile { #[precompile::public("getNetworkRegistrationAllowed(uint16)")] #[precompile::view] fn get_network_registration_allowed( - handle: &mut impl PrecompileHandle, + _: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { Ok(pallet_subtensor::NetworkRegistrationAllowed::::get(netuid)) @@ -343,7 +334,7 @@ impl SubnetPrecompile { #[precompile::public("getNetworkPowRegistrationAllowed(uint16)")] #[precompile::view] fn get_network_pow_registration_allowed( - handle: &mut impl PrecompileHandle, + _: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { Ok(pallet_subtensor::NetworkPowRegistrationAllowed::::get(netuid)) @@ -366,7 +357,7 @@ impl SubnetPrecompile { #[precompile::public("getMinBurn(uint16)")] #[precompile::view] - fn get_min_burn(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_min_burn(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::MinBurn::::get(netuid)) } @@ -384,7 +375,7 @@ impl SubnetPrecompile { #[precompile::public("getMaxBurn(uint16)")] #[precompile::view] - fn get_max_burn(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_max_burn(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::MaxBurn::::get(netuid)) } @@ -402,7 +393,7 @@ impl SubnetPrecompile { #[precompile::public("getDifficulty(uint16)")] #[precompile::view] - fn get_difficulty(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_difficulty(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::Difficulty::::get(netuid)) } @@ -420,7 +411,7 @@ impl SubnetPrecompile { #[precompile::public("getBondsMovingAverage(uint16)")] #[precompile::view] - fn get_bonds_moving_average(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { + fn get_bonds_moving_average(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::BondsMovingAverage::::get(netuid)) } @@ -442,7 +433,7 @@ impl SubnetPrecompile { #[precompile::public("getCommitRevealWeightsEnabled(uint16)")] #[precompile::view] fn get_commit_reveal_weights_enabled( - handle: &mut impl PrecompileHandle, + _: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { Ok(pallet_subtensor::CommitRevealWeightsEnabled::::get(netuid)) @@ -465,10 +456,7 @@ impl SubnetPrecompile { #[precompile::public("getLiquidAlphaEnabled(uint16)")] #[precompile::view] - fn get_liquid_alpha_enabled( - handle: &mut impl PrecompileHandle, - netuid: u16, - ) -> EvmResult { + fn get_liquid_alpha_enabled(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::LiquidAlphaOn::::get(netuid)) } @@ -487,7 +475,7 @@ impl SubnetPrecompile { #[precompile::public("getAlphaValues(uint16)")] #[precompile::view] - fn get_alpha_values(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult<(u16, u16)> { + fn get_alpha_values(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult<(u16, u16)> { Ok(pallet_subtensor::AlphaValues::::get(netuid)) } @@ -511,7 +499,7 @@ impl SubnetPrecompile { #[precompile::public("getCommitRevealWeightsInterval(uint16)")] #[precompile::view] fn get_commit_reveal_weights_interval( - handle: &mut impl PrecompileHandle, + _: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { Ok(pallet_subtensor::RevealPeriodEpochs::::get(netuid)) From b24b181b06503a4b208dbeaf95f612157976dbb2 Mon Sep 17 00:00:00 2001 From: Aliaksandr Tsurko Date: Mon, 17 Feb 2025 17:39:00 +0100 Subject: [PATCH 09/10] Update spec version --- runtime/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 8dcce09b1e..0320e89983 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: 239, + spec_version: 240, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1, From 9139bf78094178f15072d1c85bc65ce1b4c6e362 Mon Sep 17 00:00:00 2001 From: Aliaksandr Tsurko Date: Mon, 17 Feb 2025 18:36:28 +0100 Subject: [PATCH 10/10] Fix commit_hash type in Neuron::commit_weights precompile --- runtime/src/precompiles/neuron.rs | 2 +- runtime/src/precompiles/solidity/neuron.abi | 6 +++--- runtime/src/precompiles/solidity/neuron.sol | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/src/precompiles/neuron.rs b/runtime/src/precompiles/neuron.rs index 771bf0bc37..f8fd1f1586 100644 --- a/runtime/src/precompiles/neuron.rs +++ b/runtime/src/precompiles/neuron.rs @@ -39,7 +39,7 @@ impl NeuronPrecompile { handle.try_dispatch_runtime_call(call, RawOrigin::Signed(handle.caller_account_id())) } - #[precompile::public("commitWeights(uint16,uint256)")] + #[precompile::public("commitWeights(uint16,bytes32)")] #[precompile::payable] pub fn commit_weights( handle: &mut impl PrecompileHandle, diff --git a/runtime/src/precompiles/solidity/neuron.abi b/runtime/src/precompiles/solidity/neuron.abi index e12685f99f..e4ffb6fa18 100644 --- a/runtime/src/precompiles/solidity/neuron.abi +++ b/runtime/src/precompiles/solidity/neuron.abi @@ -25,9 +25,9 @@ "type": "uint16" }, { - "internalType": "uint256", + "internalType": "bytes32", "name": "commitHash", - "type": "uint256" + "type": "bytes32" } ], "name": "commitWeights", @@ -230,4 +230,4 @@ "stateMutability": "payable", "type": "function" } -] \ No newline at end of file +] diff --git a/runtime/src/precompiles/solidity/neuron.sol b/runtime/src/precompiles/solidity/neuron.sol index 772f290638..204bc3f600 100644 --- a/runtime/src/precompiles/solidity/neuron.sol +++ b/runtime/src/precompiles/solidity/neuron.sol @@ -99,9 +99,9 @@ interface INeuron { * @dev Commits the weights for a neuron. * * @param netuid The subnet to commit the weights for (uint16). - * @param commitHash The commit hash for the weights (uint256). + * @param commitHash The commit hash for the weights (bytes32). */ - function commitWeights(uint16 netuid, uint256 commitHash) external payable; + function commitWeights(uint16 netuid, bytes32 commitHash) external payable; /** * @dev Reveals the weights for a neuron.