diff --git a/precompiles/src/balance_transfer.rs b/precompiles/src/balance_transfer.rs index 03e667695f..b132125f22 100644 --- a/precompiles/src/balance_transfer.rs +++ b/precompiles/src/balance_transfer.rs @@ -1,17 +1,17 @@ use core::marker::PhantomData; use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_system::RawOrigin; use pallet_evm::PrecompileHandle; use precompile_utils::EvmResult; use sp_core::{H256, U256}; use sp_runtime::traits::{Dispatchable, StaticLookup, UniqueSaturatedInto}; -use crate::parser::{contract_to_origin, parse_pubkey}; use crate::{PrecompileExt, PrecompileHandleExt}; pub(crate) struct BalanceTransferPrecompile(PhantomData); -impl PrecompileExt for BalanceTransferPrecompile +impl PrecompileExt for BalanceTransferPrecompile where R: frame_system::Config + pallet_balances::Config + pallet_evm::Config, R::AccountId: From<[u8; 32]>, @@ -24,11 +24,6 @@ where ::Balance: TryFrom, { const INDEX: u64 = 2048; - const ADDRESS_SS58: Option<[u8; 32]> = Some([ - 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] @@ -53,18 +48,13 @@ where return Ok(()); } - let dest = parse_pubkey::(address.as_bytes())?.0.into(); + let dest = R::AccountId::from(address.0).into(); let call = pallet_balances::Call::::transfer_allow_death { dest, value: amount_sub.unique_saturated_into(), }; - handle.try_dispatch_runtime_call::( - call, - contract_to_origin( - &Self::ADDRESS_SS58.expect("ADDRESS_SS58 is defined for BalanceTransferPrecompile"), - )?, - ) + handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(Self::account_id())) } } diff --git a/precompiles/src/ed25519.rs b/precompiles/src/ed25519.rs index f1e9aa1103..ae23a70e78 100644 --- a/precompiles/src/ed25519.rs +++ b/precompiles/src/ed25519.rs @@ -1,21 +1,26 @@ extern crate alloc; use alloc::vec::Vec; +use core::marker::PhantomData; use ed25519_dalek::{Signature, Verifier, VerifyingKey}; use fp_evm::{ExitError, ExitSucceed, LinearCostPrecompile, PrecompileFailure}; use crate::PrecompileExt; -use crate::parser::parse_slice; -pub(crate) struct Ed25519Verify; +pub(crate) struct Ed25519Verify(PhantomData); -impl PrecompileExt for Ed25519Verify { +impl PrecompileExt for Ed25519Verify +where + A: From<[u8; 32]>, +{ const INDEX: u64 = 1026; - const ADDRESS_SS58: Option<[u8; 32]> = None; } -impl LinearCostPrecompile for Ed25519Verify { +impl LinearCostPrecompile for Ed25519Verify +where + A: From<[u8; 32]>, +{ const BASE: u64 = 15; const WORD: u64 = 3; @@ -47,3 +52,21 @@ impl LinearCostPrecompile for Ed25519Verify { Ok((ExitSucceed::Returned, buf.to_vec())) } } + +/// Takes a slice from bytes with PrecompileFailure as Error +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) + } else { + log::error!( + "fail to get slice from data, {:?}, from {}, to {}", + &data, + from, + to + ); + Err(PrecompileFailure::Error { + exit_status: ExitError::InvalidRange, + }) + } +} diff --git a/precompiles/src/extensions.rs b/precompiles/src/extensions.rs new file mode 100644 index 0000000000..90cc85ff03 --- /dev/null +++ b/precompiles/src/extensions.rs @@ -0,0 +1,155 @@ +extern crate alloc; + +use alloc::format; + +use frame_support::dispatch::{GetDispatchInfo, Pays, PostDispatchInfo}; +use frame_system::RawOrigin; +use pallet_evm::{ + AddressMapping, BalanceConverter, ExitError, GasWeightMapping, PrecompileFailure, + PrecompileHandle, +}; +use precompile_utils::EvmResult; +use sp_core::{H160, U256, blake2_256}; +use sp_runtime::traits::Dispatchable; +use sp_std::vec::Vec; + +pub(crate) trait PrecompileHandleExt: PrecompileHandle { + fn caller_account_id(&self) -> R::AccountId + where + R: frame_system::Config + pallet_evm::Config, + ::AddressMapping: AddressMapping, + { + ::AddressMapping::into_account_id(self.context().caller) + } + + fn try_convert_apparent_value(&self) -> EvmResult + where + R: pallet_evm::Config, + { + 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(), + ), + }, + ) + } + + /// Dispatches a runtime call, but also checks and records the gas costs. + fn try_dispatch_runtime_call( + &mut self, + call: Call, + origin: RawOrigin, + ) -> EvmResult<()> + where + R: frame_system::Config + pallet_evm::Config, + R::RuntimeCall: From, + R::RuntimeCall: GetDispatchInfo + Dispatchable, + R::RuntimeOrigin: From>, + { + let call = R::RuntimeCall::from(call); + let info = GetDispatchInfo::get_dispatch_info(&call); + + 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, + }); + } + } + + self.record_external_cost( + Some(info.weight.ref_time()), + Some(info.weight.proof_size()), + None, + )?; + + match call.dispatch(R::RuntimeOrigin::from(origin)) { + 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> { + const INDEX: u64; + + // ss58 public key i.e., the contract sends funds it received to the destination address from + // the method parameter. + fn account_id() -> AccountId { + let hash = H160::from_low_u64_be(Self::INDEX); + let prefix = b"evm:"; + + // Concatenate prefix and ethereum address + let mut combined = Vec::new(); + combined.extend_from_slice(prefix); + combined.extend_from_slice(hash.as_bytes()); + + let hash = blake2_256(&combined); + + hash.into() + } +} + +#[cfg(test)] +mod test { + use super::*; + + use sp_core::crypto::AccountId32; + + #[test] + fn ss58_address_from_index_works() { + assert_eq!( + TestPrecompile::account_id(), + AccountId32::from([ + 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, + ]) + ); + } + + struct TestPrecompile; + + impl PrecompileExt for TestPrecompile { + const INDEX: u64 = 2051; + } +} diff --git a/precompiles/src/lib.rs b/precompiles/src/lib.rs index f5338853e3..66068a58bb 100644 --- a/precompiles/src/lib.rs +++ b/precompiles/src/lib.rs @@ -2,19 +2,16 @@ extern crate alloc; -use alloc::format; use core::marker::PhantomData; -use frame_support::dispatch::{GetDispatchInfo, Pays, PostDispatchInfo}; -use frame_system::RawOrigin; +use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; use pallet_evm::{ - AddressMapping, BalanceConverter, ExitError, GasWeightMapping, IsPrecompileResult, Precompile, - PrecompileFailure, PrecompileHandle, PrecompileResult, PrecompileSet, + AddressMapping, ExitError, 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::{H160, U256, crypto::ByteArray}; use sp_runtime::traits::Dispatchable; use sp_runtime::traits::StaticLookup; @@ -24,6 +21,7 @@ use pallet_admin_utils::{PrecompileEnable, PrecompileEnum}; use crate::balance_transfer::*; use crate::ed25519::*; +use crate::extensions::*; use crate::metagraph::*; use crate::neuron::*; use crate::staking::*; @@ -31,9 +29,9 @@ use crate::subnet::*; mod balance_transfer; mod ed25519; +mod extensions; mod metagraph; mod neuron; -mod parser; mod staking; mod subnet; @@ -95,7 +93,7 @@ where hash(5), hash(1024), hash(1025), - hash(Ed25519Verify::INDEX), + hash(Ed25519Verify::::INDEX), hash(BalanceTransferPrecompile::::INDEX), hash(StakingPrecompile::::INDEX), hash(SubnetPrecompile::::INDEX), @@ -135,7 +133,9 @@ 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(Ed25519Verify::INDEX) => Some(Ed25519Verify::execute(handle)), + a if a == hash(Ed25519Verify::::INDEX) => { + Some(Ed25519Verify::::execute(handle)) + } // Subtensor specific precompiles : a if a == hash(BalanceTransferPrecompile::::INDEX) => { if PrecompileEnable::::get(PrecompileEnum::BalanceTransfer) { @@ -209,106 +209,3 @@ where fn hash(a: u64) -> H160 { H160::from_low_u64_be(a) } - -trait PrecompileHandleExt: PrecompileHandle { - fn caller_account_id(&self) -> R::AccountId - where - R: frame_system::Config + pallet_evm::Config, - ::AddressMapping: AddressMapping, - { - ::AddressMapping::into_account_id(self.context().caller) - } - - fn try_convert_apparent_value(&self) -> EvmResult - where - R: pallet_evm::Config, - { - 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(), - ), - }, - ) - } - - /// Dispatches a runtime call, but also checks and records the gas costs. - fn try_dispatch_runtime_call( - &mut self, - call: Call, - origin: RawOrigin, - ) -> EvmResult<()> - where - R: frame_system::Config + pallet_evm::Config, - R::RuntimeCall: From, - R::RuntimeCall: GetDispatchInfo + Dispatchable, - R::RuntimeOrigin: From>, - { - let call = R::RuntimeCall::from(call); - let info = GetDispatchInfo::get_dispatch_info(&call); - - 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, - }); - } - } - - self.record_external_cost( - Some(info.weight.ref_time()), - Some(info.weight.proof_size()), - None, - )?; - - match call.dispatch(R::RuntimeOrigin::from(origin)) { - 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 {} - -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: Option<[u8; 32]>; -} diff --git a/precompiles/src/metagraph.rs b/precompiles/src/metagraph.rs index 061c41afb6..758ce8f8eb 100644 --- a/precompiles/src/metagraph.rs +++ b/precompiles/src/metagraph.rs @@ -10,13 +10,12 @@ use crate::PrecompileExt; pub struct MetagraphPrecompile(PhantomData); -impl PrecompileExt for MetagraphPrecompile +impl PrecompileExt for MetagraphPrecompile where R: frame_system::Config + pallet_subtensor::Config, - R::AccountId: ByteArray, + R::AccountId: From<[u8; 32]> + ByteArray, { const INDEX: u64 = 2050; - const ADDRESS_SS58: Option<[u8; 32]> = None; } #[precompile_utils::precompile] diff --git a/precompiles/src/neuron.rs b/precompiles/src/neuron.rs index e1fc65274a..cedb3a56db 100644 --- a/precompiles/src/neuron.rs +++ b/precompiles/src/neuron.rs @@ -8,12 +8,11 @@ use sp_core::H256; use sp_runtime::traits::Dispatchable; use sp_std::vec::Vec; -use crate::parser::parse_pubkey; use crate::{PrecompileExt, PrecompileHandleExt}; pub struct NeuronPrecompile(PhantomData); -impl PrecompileExt for NeuronPrecompile +impl PrecompileExt for NeuronPrecompile where R: frame_system::Config + pallet_evm::Config + pallet_subtensor::Config, R::AccountId: From<[u8; 32]>, @@ -23,11 +22,6 @@ where ::AddressMapping: AddressMapping, { const INDEX: u64 = 2052; - const ADDRESS_SS58: Option<[u8; 32]> = Some([ - 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] @@ -112,7 +106,7 @@ where hotkey: H256, ) -> EvmResult<()> { let coldkey = handle.caller_account_id::(); - let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; + let hotkey = R::AccountId::from(hotkey.0); let call = pallet_subtensor::Call::::burned_register { netuid, hotkey }; handle.try_dispatch_runtime_call::(call, RawOrigin::Signed(coldkey)) diff --git a/precompiles/src/parser.rs b/precompiles/src/parser.rs deleted file mode 100644 index 8abc96fbbe..0000000000 --- a/precompiles/src/parser.rs +++ /dev/null @@ -1,50 +0,0 @@ -extern crate alloc; - -use frame_system::RawOrigin; -use pallet_evm::{ExitError, PrecompileFailure}; -use sp_core::U256; -use sp_std::vec; - -/// Takes a slice from bytes with PrecompileFailure as Error -pub(crate) 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) - } else { - log::error!( - "fail to get slice from data, {:?}, from {}, to {}", - &data, - from, - to - ); - Err(PrecompileFailure::Error { - exit_status: ExitError::InvalidRange, - }) - } -} - -pub(crate) fn parse_pubkey>( - data: &[u8], -) -> Result<(A, vec::Vec), PrecompileFailure> { - let mut pubkey = [0u8; 32]; - pubkey.copy_from_slice(parse_slice(data, 0, 32)?); - - Ok(( - pubkey.into(), - data.get(32..) - .map_or_else(vec::Vec::new, |slice| slice.to_vec()), - )) -} - -pub(crate) fn contract_to_origin>( - contract: &[u8; 32], -) -> Result, PrecompileFailure> { - let (account_id, _) = parse_pubkey::(contract)?; - Ok(RawOrigin::Signed(account_id)) -} - -pub(crate) fn try_u16_from_u256(value: U256) -> Result { - value.try_into().map_err(|_| PrecompileFailure::Error { - exit_status: ExitError::Other("the value is outside of u16 bounds".into()), - }) -} diff --git a/precompiles/src/staking.rs b/precompiles/src/staking.rs index 03e8587f9a..9022f45a36 100644 --- a/precompiles/src/staking.rs +++ b/precompiles/src/staking.rs @@ -37,7 +37,6 @@ use sp_core::{H256, U256}; use sp_runtime::traits::{Dispatchable, StaticLookup, UniqueSaturatedInto}; use subtensor_runtime_common::ProxyType; -use crate::parser::{parse_pubkey, try_u16_from_u256}; use crate::{PrecompileExt, PrecompileHandleExt}; // Old StakingPrecompile had ETH-precision in values, which was not alligned with Substrate API. So @@ -47,7 +46,7 @@ use crate::{PrecompileExt, PrecompileHandleExt}; // All the future extensions should happen in StakingPrecompileV2. pub(crate) struct StakingPrecompileV2(PhantomData); -impl PrecompileExt for StakingPrecompileV2 +impl PrecompileExt for StakingPrecompileV2 where R: frame_system::Config + pallet_evm::Config @@ -62,7 +61,6 @@ where <::Lookup as StaticLookup>::Source: From, { const INDEX: u64 = 2053; - const ADDRESS_SS58: Option<[u8; 32]> = None; } #[precompile_utils::precompile] @@ -90,7 +88,7 @@ where ) -> EvmResult<()> { let account_id = handle.caller_account_id::(); let amount_staked = amount_rao.unique_saturated_into(); - let (hotkey, _) = parse_pubkey(address.as_bytes())?; + let hotkey = R::AccountId::from(address.0); let netuid = try_u16_from_u256(netuid)?; let call = pallet_subtensor::Call::::add_stake { hotkey, @@ -109,7 +107,7 @@ where netuid: U256, ) -> EvmResult<()> { let account_id = handle.caller_account_id::(); - let (hotkey, _) = parse_pubkey(address.as_bytes())?; + let hotkey = R::AccountId::from(address.0); let netuid = try_u16_from_u256(netuid)?; let amount_unstaked = amount_alpha.unique_saturated_into(); let call = pallet_subtensor::Call::::remove_stake { @@ -126,7 +124,7 @@ where _handle: &mut impl PrecompileHandle, coldkey: H256, ) -> EvmResult { - let (coldkey, _) = parse_pubkey(coldkey.as_bytes())?; + let coldkey = R::AccountId::from(coldkey.0); let stake = pallet_subtensor::Pallet::::get_total_stake_for_coldkey(&coldkey); Ok(stake.into()) @@ -135,9 +133,9 @@ where #[precompile::public("getTotalHotkeyStake(bytes32)")] fn get_total_hotkey_stake( _handle: &mut impl PrecompileHandle, - hotkey_h256: H256, + hotkey: H256, ) -> EvmResult { - let (hotkey, _) = parse_pubkey(hotkey_h256.as_bytes())?; + let hotkey = R::AccountId::from(hotkey.0); let stake = pallet_subtensor::Pallet::::get_total_stake_for_hotkey(&hotkey); Ok(stake.into()) @@ -151,8 +149,8 @@ where coldkey: H256, netuid: U256, ) -> EvmResult { - let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; - let (coldkey, _) = parse_pubkey(coldkey.as_bytes())?; + let hotkey = R::AccountId::from(hotkey.0); + let coldkey = R::AccountId::from(coldkey.0); let netuid = try_u16_from_u256(netuid)?; let stake = pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, netuid, @@ -164,7 +162,7 @@ where #[precompile::public("addProxy(bytes32)")] fn add_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { let account_id = handle.caller_account_id::(); - let (delegate, _) = parse_pubkey(delegate.as_bytes())?; + let delegate = R::AccountId::from(delegate.0); let delegate = ::Lookup::unlookup(delegate); let call = pallet_proxy::Call::::add_proxy { delegate, @@ -178,7 +176,7 @@ where #[precompile::public("removeProxy(bytes32)")] fn remove_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { let account_id = handle.caller_account_id::(); - let (delegate, _) = parse_pubkey(delegate.as_bytes())?; + let delegate = R::AccountId::from(delegate.0); let delegate = ::Lookup::unlookup(delegate); let call = pallet_proxy::Call::::remove_proxy { delegate, @@ -193,7 +191,7 @@ where // Deprecated, exists for backward compatibility. pub(crate) struct StakingPrecompile(PhantomData); -impl PrecompileExt for StakingPrecompile +impl PrecompileExt for StakingPrecompile where R: frame_system::Config + pallet_evm::Config @@ -211,11 +209,6 @@ where <::Lookup as StaticLookup>::Source: From, { const INDEX: u64 = 2049; - const ADDRESS_SS58: Option<[u8; 32]> = Some([ - 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] @@ -247,7 +240,7 @@ where } let amount_sub = handle.try_convert_apparent_value::()?; - let (hotkey, _) = parse_pubkey(address.as_bytes())?; + let hotkey = R::AccountId::from(address.0); let netuid = try_u16_from_u256(netuid)?; let call = pallet_subtensor::Call::::add_stake { hotkey, @@ -266,7 +259,7 @@ where netuid: U256, ) -> EvmResult<()> { let account_id = handle.caller_account_id::(); - let (hotkey, _) = parse_pubkey(address.as_bytes())?; + let hotkey = R::AccountId::from(address.0); let netuid = try_u16_from_u256(netuid)?; let amount_unstaked = ::BalanceConverter::into_substrate_balance(amount) @@ -284,9 +277,9 @@ where #[precompile::public("getTotalColdkeyStake(bytes32)")] fn get_total_coldkey_stake( _handle: &mut impl PrecompileHandle, - coldkey_h256: H256, + coldkey: H256, ) -> EvmResult { - let (coldkey, _) = parse_pubkey(coldkey_h256.as_bytes())?; + let coldkey = R::AccountId::from(coldkey.0); // get total stake of coldkey let total_stake = pallet_subtensor::Pallet::::get_total_stake_for_coldkey(&coldkey); @@ -301,9 +294,9 @@ where #[precompile::public("getTotalHotkeyStake(bytes32)")] fn get_total_hotkey_stake( _handle: &mut impl PrecompileHandle, - hotkey_h256: H256, + hotkey: H256, ) -> EvmResult { - let (hotkey, _) = parse_pubkey(hotkey_h256.as_bytes())?; + let hotkey = R::AccountId::from(hotkey.0); // get total stake of hotkey let total_stake = pallet_subtensor::Pallet::::get_total_stake_for_hotkey(&hotkey); @@ -323,8 +316,8 @@ where coldkey: H256, netuid: U256, ) -> EvmResult { - let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; - let (coldkey, _) = parse_pubkey(coldkey.as_bytes())?; + let hotkey = R::AccountId::from(hotkey.0); + let coldkey = R::AccountId::from(coldkey.0); let netuid = try_u16_from_u256(netuid)?; let stake = pallet_subtensor::Pallet::::get_stake_for_hotkey_and_coldkey_on_subnet( &hotkey, &coldkey, netuid, @@ -339,7 +332,7 @@ where #[precompile::public("addProxy(bytes32)")] fn add_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { let account_id = handle.caller_account_id::(); - let (delegate, _) = parse_pubkey(delegate.as_bytes())?; + let delegate = R::AccountId::from(delegate.0); let delegate = ::Lookup::unlookup(delegate); let call = pallet_proxy::Call::::add_proxy { delegate, @@ -353,7 +346,7 @@ where #[precompile::public("removeProxy(bytes32)")] fn remove_proxy(handle: &mut impl PrecompileHandle, delegate: H256) -> EvmResult<()> { let account_id = handle.caller_account_id::(); - let (delegate, _) = parse_pubkey(delegate.as_bytes())?; + let delegate = R::AccountId::from(delegate.0); let delegate = ::Lookup::unlookup(delegate); let call = pallet_proxy::Call::::remove_proxy { delegate, @@ -368,9 +361,6 @@ where account_id: &::AccountId, amount: U256, ) -> Result<(), PrecompileFailure> { - let smart_contract_account_id = R::AccountId::from( - Self::ADDRESS_SS58.expect("ADDRESS_SS58 is defined for StakingPrecompile"), - ); let amount_sub = ::BalanceConverter::into_substrate_balance(amount) .ok_or(ExitError::OutOfFund)?; @@ -384,8 +374,7 @@ where ); // Execute the transfer - let transfer_result = - transfer_call.dispatch(RawOrigin::Signed(smart_contract_account_id).into()); + let transfer_result = transfer_call.dispatch(RawOrigin::Signed(Self::account_id()).into()); if let Err(dispatch_error) = transfer_result { log::error!( @@ -400,3 +389,9 @@ where Ok(()) } } + +fn try_u16_from_u256(value: U256) -> Result { + value.try_into().map_err(|_| PrecompileFailure::Error { + exit_status: ExitError::Other("the value is outside of u16 bounds".into()), + }) +} diff --git a/precompiles/src/subnet.rs b/precompiles/src/subnet.rs index d3ee07d5c3..cffe82ab78 100644 --- a/precompiles/src/subnet.rs +++ b/precompiles/src/subnet.rs @@ -8,12 +8,11 @@ use precompile_utils::{EvmResult, prelude::BoundedString}; use sp_core::H256; use sp_runtime::traits::Dispatchable; -use crate::parser::parse_pubkey; use crate::{PrecompileExt, PrecompileHandleExt}; pub struct SubnetPrecompile(PhantomData); -impl PrecompileExt for SubnetPrecompile +impl PrecompileExt for SubnetPrecompile where R: frame_system::Config + pallet_evm::Config @@ -25,15 +24,8 @@ where + GetDispatchInfo + Dispatchable, ::AddressMapping: AddressMapping, - // ::Balance: From, - // <::Lookup as StaticLookup>::Source: From, { const INDEX: u64 = 2051; - const ADDRESS_SS58: Option<[u8; 32]> = Some([ - 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, - ]); } #[precompile_utils::precompile] @@ -49,13 +41,11 @@ where + GetDispatchInfo + Dispatchable, ::AddressMapping: AddressMapping, - // ::Balance: From, - // <::Lookup as StaticLookup>::Source: From, { #[precompile::public("registerNetwork(bytes32)")] #[precompile::payable] fn register_network(handle: &mut impl PrecompileHandle, hotkey: H256) -> EvmResult<()> { - let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; + let hotkey = R::AccountId::from(hotkey.0); let call = pallet_subtensor::Call::::register_network_with_identity { hotkey, identity: None, @@ -83,7 +73,7 @@ where description: BoundedString>, additional: BoundedString>, ) -> EvmResult<()> { - let (hotkey, _) = parse_pubkey(hotkey.as_bytes())?; + let hotkey = R::AccountId::from(hotkey.0); let identity = pallet_subtensor::SubnetIdentityOfV2 { subnet_name: subnet_name.into(), github_repo: github_repo.into(),