diff --git a/Cargo.lock b/Cargo.lock index eeffdabd0f..c9ba8aede2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -18109,6 +18109,7 @@ dependencies = [ "pallet-subtensor-proxy", "pallet-subtensor-swap", "precompile-utils", + "scale-info", "sp-core", "sp-io", "sp-runtime", diff --git a/contract-tests/package.json b/contract-tests/package.json index 26136346bb..6af55b1d9e 100644 --- a/contract-tests/package.json +++ b/contract-tests/package.json @@ -1,6 +1,6 @@ { "scripts": { - "test": "mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register test/*test.ts" + "test": "TS_NODE_PREFER_TS_EXTS=1 TS_NODE_TRANSPILE_ONLY=1 mocha --timeout 999999 --retries 3 --file src/setup.ts --require ts-node/register --extension ts \"test/**/*.ts\"" }, "keywords": [], "author": "", diff --git a/contract-tests/test/neuron.precompile.reveal-weights.test.ts b/contract-tests/test/neuron.precompile.reveal-weights.test.ts index 99d608585d..5d80183ec7 100644 --- a/contract-tests/test/neuron.precompile.reveal-weights.test.ts +++ b/contract-tests/test/neuron.precompile.reveal-weights.test.ts @@ -1,5 +1,5 @@ import * as assert from "assert"; -import { getAliceSigner, getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate" +import { getAliceSigner, getDevnetApi, getRandomSubstrateKeypair, waitForTransactionWithRetry } from "../src/substrate" import { devnet } from "@polkadot-api/descriptors" import { PolkadotSigner, TypedApi } from "polkadot-api"; import { convertPublicKeyToSs58, convertH160ToSS58 } from "../src/address-utils" @@ -23,6 +23,16 @@ const values = [5]; const salt = [9]; const version_key = 0; +async function setStakeThreshold( + api: TypedApi, + alice: PolkadotSigner, + minStake: bigint, +) { + const internalCall = api.tx.AdminUtils.sudo_set_stake_threshold({ min_stake: minStake }) + const tx = api.tx.Sudo.sudo({ call: internalCall.decodedCall }) + await waitForTransactionWithRetry(api, tx, alice) +} + function getCommitHash(netuid: number, address: string) { const registry = new TypeRegistry(); let publicKey = convertH160ToPublicKey(address); @@ -53,7 +63,7 @@ describe("Test neuron precompile reveal weights", () => { const coldkey = getRandomSubstrateKeypair(); let api: TypedApi - let commitEpoch: number; + let commitEpoch: number | undefined; // sudo account alice as signer let alice: PolkadotSigner; @@ -86,11 +96,52 @@ describe("Test neuron precompile reveal weights", () => { assert.equal(uid, uids[0]) }) + async function ensureCommitEpoch(netuid: number, contract: ethers.Contract) { + if (commitEpoch !== undefined) { + return + } + + const ss58Address = convertH160ToSS58(wallet.address) + const existingCommits = await api.query.SubtensorModule.WeightCommits.getValue( + netuid, + ss58Address + ) + if (Array.isArray(existingCommits) && existingCommits.length > 0) { + const entry = existingCommits[0] + const commitBlockRaw = + Array.isArray(entry) && entry.length > 1 ? entry[1] : undefined + const commitBlock = + typeof commitBlockRaw === "bigint" + ? Number(commitBlockRaw) + : Number(commitBlockRaw ?? NaN) + if (Number.isFinite(commitBlock)) { + commitEpoch = Math.trunc(commitBlock / (100 + 1)) + return + } + } + + await setStakeThreshold(api, alice, BigInt(0)) + const commitHash = getCommitHash(netuid, wallet.address) + const tx = await contract.commitWeights(netuid, commitHash) + await tx.wait() + + const commitBlock = await api.query.System.Number.getValue() + commitEpoch = Math.trunc(commitBlock / (100 + 1)) + } + it("EVM neuron commit weights via call precompile", async () => { let totalNetworks = await api.query.SubtensorModule.TotalNetworks.getValue() const subnetId = totalNetworks - 1 const commitHash = getCommitHash(subnetId, wallet.address) const contract = new ethers.Contract(INEURON_ADDRESS, INeuronABI, wallet); + + await setStakeThreshold(api, alice, BigInt(1)) + await assert.rejects(async () => { + const tx = await contract.commitWeights(subnetId, commitHash) + await tx.wait() + }) + await setStakeThreshold(api, alice, BigInt(0)) + try { const tx = await contract.commitWeights(subnetId, commitHash) await tx.wait() @@ -120,6 +171,11 @@ describe("Test neuron precompile reveal weights", () => { // set interval epoch as 1, it is the minimum value now await setCommitRevealWeightsInterval(api, netuid, BigInt(1)) + await ensureCommitEpoch(netuid, contract) + if (commitEpoch === undefined) { + throw new Error("commitEpoch should be set before revealing weights") + } + while (true) { const currentBlock = await api.query.System.Number.getValue() const currentEpoch = Math.trunc(currentBlock / (100 + 1)) @@ -130,6 +186,19 @@ describe("Test neuron precompile reveal weights", () => { await new Promise(resolve => setTimeout(resolve, 1000)) } + await setStakeThreshold(api, alice, BigInt(1)) + await assert.rejects(async () => { + const tx = await contract.revealWeights( + netuid, + uids, + values, + salt, + version_key + ); + await tx.wait() + }) + await setStakeThreshold(api, alice, BigInt(0)) + const tx = await contract.revealWeights( netuid, uids, diff --git a/contract-tests/test/subnet.precompile.hyperparameter.test.ts b/contract-tests/test/subnet.precompile.hyperparameter.test.ts index 87968b6e9f..8598b45a81 100644 --- a/contract-tests/test/subnet.precompile.hyperparameter.test.ts +++ b/contract-tests/test/subnet.precompile.hyperparameter.test.ts @@ -1,9 +1,9 @@ import * as assert from "assert"; -import { getDevnetApi, getRandomSubstrateKeypair } from "../src/substrate" +import { getAliceSigner, getDevnetApi, getRandomSubstrateKeypair, waitForTransactionWithRetry } from "../src/substrate" import { devnet } from "@polkadot-api/descriptors" -import { TypedApi } from "polkadot-api"; -import { convertPublicKeyToSs58 } from "../src/address-utils" +import { Binary, TypedApi, getTypedCodecs } from "polkadot-api"; +import { convertH160ToSS58, convertPublicKeyToSs58 } from "../src/address-utils" import { generateRandomEthersWallet } from "../src/utils"; import { ISubnetABI, ISUBNET_ADDRESS } from "../src/contracts/subnet" import { ethers } from "ethers" @@ -545,4 +545,37 @@ describe("Test the Subnet precompile contract", () => { assert.equal(valueFromContract, newValue) assert.equal(valueFromContract, onchainValue); }) + + it("Rejects subnet precompile calls when coldkey swap is scheduled (tx extension)", async () => { + const totalNetwork = await api.query.SubtensorModule.TotalNetworks.getValue() + const contract = new ethers.Contract(ISUBNET_ADDRESS, ISubnetABI, wallet); + const netuid = totalNetwork - 1; + + const coldkeySs58 = convertH160ToSS58(wallet.address) + const newColdkeySs58 = convertPublicKeyToSs58(hotkey1.publicKey) + const currentBlock = await api.query.System.Number.getValue() + const executionBlock = currentBlock + 10 + + const codec = await getTypedCodecs(devnet); + const valueBytes = codec.query.SubtensorModule.ColdkeySwapScheduled.value.enc([ + executionBlock, + newColdkeySs58, + ]) + const key = await api.query.SubtensorModule.ColdkeySwapScheduled.getKey(coldkeySs58); + + // Use sudo + set_storage since the swap-scheduled check only exists in the tx extension. + const setStorageCall = api.tx.System.set_storage({ + items: [[Binary.fromHex(key), Binary.fromBytes(valueBytes)]], + }) + const sudoTx = api.tx.Sudo.sudo({ call: setStorageCall.decodedCall }) + await waitForTransactionWithRetry(api, sudoTx, getAliceSigner()) + + const storedValue = await api.query.SubtensorModule.ColdkeySwapScheduled.getValue(coldkeySs58) + assert.deepStrictEqual(storedValue, [executionBlock, newColdkeySs58]) + + await assert.rejects(async () => { + const tx = await contract.setServingRateLimit(netuid, 100); + await tx.wait(); + }) + }) }) diff --git a/precompiles/Cargo.toml b/precompiles/Cargo.toml index 12460dcfbb..400e1caa9f 100644 --- a/precompiles/Cargo.toml +++ b/precompiles/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/opentensor/subtensor/" targets = ["x86_64-unknown-linux-gnu"] [dependencies] +# codec.workspace = true ed25519-dalek = { workspace = true, features = ["alloc"] } fp-evm.workspace = true frame-support.workspace = true @@ -25,6 +26,7 @@ pallet-evm-precompile-simple.workspace = true pallet-evm-precompile-bn128.workspace = true pallet-subtensor-proxy.workspace = true precompile-utils.workspace = true +scale-info.workspace = true sp-core.workspace = true sp-io.workspace = true sp-runtime.workspace = true @@ -43,6 +45,7 @@ workspace = true [features] default = ["std"] std = [ + # "codec/std", "ed25519-dalek/std", "fp-evm/std", "frame-support/std", @@ -50,17 +53,18 @@ std = [ "log/std", "pallet-admin-utils/std", "pallet-balances/std", + "pallet-crowdloan/std", + "pallet-evm-precompile-bn128/std", "pallet-evm-precompile-dispatch/std", "pallet-evm-precompile-modexp/std", "pallet-evm-precompile-sha3fips/std", "pallet-evm-precompile-simple/std", - "pallet-evm-precompile-bn128/std", "pallet-evm/std", - "pallet-crowdloan/std", "pallet-subtensor-proxy/std", - "pallet-subtensor/std", "pallet-subtensor-swap/std", + "pallet-subtensor/std", "precompile-utils/std", + "scale-info/std", "sp-core/std", "sp-io/std", "sp-runtime/std", diff --git a/precompiles/src/balance_transfer.rs b/precompiles/src/balance_transfer.rs index b132125f22..c1cdab6ca5 100644 --- a/precompiles/src/balance_transfer.rs +++ b/precompiles/src/balance_transfer.rs @@ -1,11 +1,12 @@ use core::marker::PhantomData; -use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_support::dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}; +use frame_support::traits::IsSubType; 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 sp_runtime::traits::{AsSystemOriginSigner, Dispatchable, StaticLookup, UniqueSaturatedInto}; use crate::{PrecompileExt, PrecompileHandleExt}; @@ -13,13 +14,22 @@ pub(crate) struct BalanceTransferPrecompile(PhantomData); impl PrecompileExt for BalanceTransferPrecompile where - R: frame_system::Config + pallet_balances::Config + pallet_evm::Config, + R: frame_system::Config + + pallet_balances::Config + + pallet_evm::Config + + pallet_subtensor::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, - ::RuntimeCall: - GetDispatchInfo + Dispatchable, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, + ::RuntimeCall: GetDispatchInfo + + Dispatchable + + IsSubType> + + IsSubType>, ::RuntimeCall: From> + GetDispatchInfo - + Dispatchable, + + Dispatchable, <::Lookup as StaticLookup>::Source: From, ::Balance: TryFrom, { @@ -29,13 +39,22 @@ where #[precompile_utils::precompile] impl BalanceTransferPrecompile where - R: frame_system::Config + pallet_balances::Config + pallet_evm::Config, + R: frame_system::Config + + pallet_balances::Config + + pallet_evm::Config + + pallet_subtensor::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, - ::RuntimeCall: - GetDispatchInfo + Dispatchable, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, + ::RuntimeCall: GetDispatchInfo + + Dispatchable + + IsSubType> + + IsSubType>, ::RuntimeCall: From> + GetDispatchInfo - + Dispatchable, + + Dispatchable, <::Lookup as StaticLookup>::Source: From, ::Balance: TryFrom, { diff --git a/precompiles/src/crowdloan.rs b/precompiles/src/crowdloan.rs index 246c65c70c..f0971015d9 100644 --- a/precompiles/src/crowdloan.rs +++ b/precompiles/src/crowdloan.rs @@ -2,7 +2,8 @@ use alloc::string::String; use core::marker::PhantomData; use fp_evm::{ExitError, PrecompileFailure}; -use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_support::dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}; +use frame_support::traits::IsSubType; use frame_system::RawOrigin; use pallet_evm::AddressMapping; use pallet_evm::PrecompileHandle; @@ -10,7 +11,7 @@ use pallet_subtensor_proxy as pallet_proxy; use precompile_utils::prelude::Address; use precompile_utils::{EvmResult, solidity::Codec}; use sp_core::{ByteArray, H256}; -use sp_runtime::traits::{Dispatchable, UniqueSaturatedInto}; +use sp_runtime::traits::{AsSystemOriginSigner, Dispatchable, UniqueSaturatedInto}; use crate::{PrecompileExt, PrecompileHandleExt}; @@ -18,11 +19,22 @@ pub struct CrowdloanPrecompile(PhantomData); impl PrecompileExt for CrowdloanPrecompile where - R: frame_system::Config + pallet_evm::Config + pallet_crowdloan::Config + pallet_proxy::Config, + R: frame_system::Config + + pallet_balances::Config + + pallet_crowdloan::Config + + pallet_evm::Config + + pallet_proxy::Config + + pallet_subtensor::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + ByteArray, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { const INDEX: u64 = 2057; @@ -31,14 +43,25 @@ where #[precompile_utils::precompile] impl CrowdloanPrecompile where - R: frame_system::Config + pallet_evm::Config + pallet_crowdloan::Config + pallet_proxy::Config, + R: frame_system::Config + + pallet_balances::Config + + pallet_crowdloan::Config + + pallet_evm::Config + + pallet_proxy::Config + + pallet_subtensor::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + ByteArray, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::RuntimeCall: From> + GetDispatchInfo - + Dispatchable, + + Dispatchable, ::AddressMapping: AddressMapping, { #[precompile::public("getCrowdloan(uint32)")] diff --git a/precompiles/src/extensions.rs b/precompiles/src/extensions.rs index fab35a8b79..df5ebf3fa2 100644 --- a/precompiles/src/extensions.rs +++ b/precompiles/src/extensions.rs @@ -3,15 +3,25 @@ extern crate alloc; use alloc::format; use frame_support::dispatch::{DispatchInfo, GetDispatchInfo, Pays, PostDispatchInfo}; +use frame_support::traits::IsSubType; use frame_system::RawOrigin; use pallet_admin_utils::{PrecompileEnable, PrecompileEnum}; use pallet_evm::{ AddressMapping, BalanceConverter, EvmBalance, ExitError, GasWeightMapping, Precompile, PrecompileFailure, PrecompileHandle, PrecompileResult, }; +use pallet_subtensor::transaction_extension::SubtensorTransactionExtension; use precompile_utils::EvmResult; +use scale_info::TypeInfo; use sp_core::{H160, U256, blake2_256}; -use sp_runtime::traits::Dispatchable; +use sp_runtime::{ + DispatchResult, + traits::{ + AsSystemOriginSigner, Dispatchable, ExtensionPostDispatchWeightHandler, + TransactionExtension, TxBaseImplication, + }, + transaction_validity::{TransactionSource, TransactionValidityError}, +}; use sp_std::vec::Vec; pub(crate) trait PrecompileHandleExt: PrecompileHandle { @@ -44,19 +54,33 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { origin: RawOrigin, ) -> EvmResult<()> where - R: frame_system::Config + pallet_evm::Config, - R::RuntimeCall: From, - R::RuntimeCall: GetDispatchInfo + Dispatchable, - R::RuntimeOrigin: From>, + R: frame_system::Config + + pallet_balances::Config + + pallet_evm::Config + + pallet_subtensor::Config + + Send + + Sync + + TypeInfo, + ::RuntimeCall: From, + ::RuntimeCall: GetDispatchInfo + + Dispatchable + + IsSubType> + + IsSubType>, + ::RuntimeOrigin: + From> + AsSystemOriginSigner + Clone, { - let call = R::RuntimeCall::from(call); - let info = GetDispatchInfo::get_dispatch_info(&call); + let call = ::RuntimeCall::from(call); + let mut info = GetDispatchInfo::get_dispatch_info(&call); + let subtensor_extension = SubtensorTransactionExtension::::new(); + info.extension_weight = info + .extension_weight + .saturating_add(subtensor_extension.weight(&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.call_weight.ref_time() > valid_weight { + if info.total_weight().ref_time() > valid_weight { return Err(PrecompileFailure::Error { exit_status: ExitError::OutOfGas, }); @@ -64,26 +88,56 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { } self.record_external_cost( - Some(info.call_weight.ref_time()), - Some(info.call_weight.proof_size()), + Some(info.total_weight().ref_time()), + Some(info.total_weight().proof_size()), None, )?; - match call.dispatch(R::RuntimeOrigin::from(origin)) { - Ok(post_info) => { + let origin = ::RuntimeOrigin::from(origin); + let (_, val, origin) = subtensor_extension + .validate( + origin, + &call, + &info, + 0, + (), + &TxBaseImplication(()), + TransactionSource::External, + ) + .map_err(extension_error)?; + subtensor_extension + .prepare(val, &origin, &call, &info, 0) + .map_err(extension_error)?; + + match call.dispatch(origin) { + Ok(mut post_info) => { + post_info.set_extension_weight(&info); + let result: DispatchResult = Ok(()); + as TransactionExtension< + ::RuntimeCall, + >>::post_dispatch((), &info, &mut post_info, 0, &result) + .map_err(extension_error)?; log::debug!("Dispatch succeeded. Post info: {post_info:?}"); self.charge_and_refund_after_dispatch::(&info, &post_info)?; Ok(()) } Err(e) => { + let err_str: &'static str = e.into(); + let mut post_info = e.post_info; + post_info.set_extension_weight(&info); + let result: DispatchResult = Err(e.error); + as TransactionExtension< + ::RuntimeCall, + >>::post_dispatch((), &info, &mut post_info, 0, &result) + .map_err(extension_error)?; log::error!("Dispatch failed. Error: {e:?}"); log::warn!("Returning error PrecompileFailure::Error"); - self.charge_and_refund_after_dispatch::(&info, &e.post_info)?; + self.charge_and_refund_after_dispatch::(&info, &post_info)?; Err(PrecompileFailure::Error { exit_status: ExitError::Other( - format!("dispatch execution failed: {}", <&'static str>::from(e)).into(), + format!("dispatch execution failed: {err_str}").into(), ), }) } @@ -99,18 +153,18 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { R: frame_system::Config + pallet_evm::Config, { if post_info.pays_fee(info) == Pays::Yes { - let actual_weight = post_info.actual_weight.unwrap_or(info.call_weight); + let actual_weight = post_info.calc_actual_weight(info); let cost = ::GasWeightMapping::weight_to_gas(actual_weight); self.record_cost(cost)?; self.refund_external_cost( Some( - info.call_weight + info.total_weight() .ref_time() .saturating_sub(actual_weight.ref_time()), ), Some( - info.call_weight + info.total_weight() .proof_size() .saturating_sub(actual_weight.proof_size()), ), @@ -121,6 +175,12 @@ pub(crate) trait PrecompileHandleExt: PrecompileHandle { } } +fn extension_error(err: TransactionValidityError) -> PrecompileFailure { + PrecompileFailure::Error { + exit_status: ExitError::Other(format!("transaction extension rejected: {err:?}").into()), + } +} + impl PrecompileHandleExt for T where T: PrecompileHandle {} pub(crate) trait PrecompileExt>: Precompile { diff --git a/precompiles/src/leasing.rs b/precompiles/src/leasing.rs index c4d64f428a..01a8db4354 100644 --- a/precompiles/src/leasing.rs +++ b/precompiles/src/leasing.rs @@ -2,7 +2,8 @@ use alloc::{boxed::Box, string::String}; use core::marker::PhantomData; use fp_evm::{ExitError, PrecompileFailure}; -use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_support::dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}; +use frame_support::traits::IsSubType; use frame_system::RawOrigin; use pallet_evm::AddressMapping; use pallet_evm::PrecompileHandle; @@ -10,7 +11,7 @@ use precompile_utils::{EvmResult, solidity::Codec}; use sp_core::{ByteArray, H256}; use sp_runtime::{ Percent, - traits::{Dispatchable, UniqueSaturatedInto}, + traits::{AsSystemOriginSigner, Dispatchable, UniqueSaturatedInto}, }; use subtensor_runtime_common::NetUid; @@ -21,14 +22,21 @@ pub struct LeasingPrecompile(PhantomData); impl PrecompileExt for LeasingPrecompile where R: frame_system::Config + + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config - + pallet_crowdloan::Config, + + pallet_crowdloan::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + ByteArray, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { const INDEX: u64 = 2058; @@ -38,14 +46,21 @@ where impl LeasingPrecompile where R: frame_system::Config + + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config - + pallet_crowdloan::Config, + + pallet_crowdloan::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + ByteArray, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { #[precompile::public("getLease(uint32)")] diff --git a/precompiles/src/lib.rs b/precompiles/src/lib.rs index 8069a1eb92..dedeebe249 100644 --- a/precompiles/src/lib.rs +++ b/precompiles/src/lib.rs @@ -5,8 +5,9 @@ extern crate alloc; use core::marker::PhantomData; use fp_evm::{ExitError, PrecompileFailure}; +use frame_support::traits::IsSubType; use frame_support::{ - dispatch::{GetDispatchInfo, PostDispatchInfo}, + dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}, pallet_prelude::Decode, }; use pallet_evm::{ @@ -20,8 +21,7 @@ use pallet_evm_precompile_sha3fips::Sha3FIPS256; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; use pallet_subtensor_proxy as pallet_proxy; use sp_core::{H160, U256, crypto::ByteArray}; -use sp_runtime::traits::Dispatchable; -use sp_runtime::traits::StaticLookup; +use sp_runtime::traits::{AsSystemOriginSigner, Dispatchable, StaticLookup}; use subtensor_runtime_common::ProxyType; use pallet_admin_utils::PrecompileEnum; @@ -55,6 +55,7 @@ mod staking; mod storage_query; mod subnet; mod uid_lookup; + pub struct Precompiles(PhantomData); impl Default for Precompiles @@ -66,15 +67,21 @@ where + pallet_subtensor::Config + pallet_subtensor_swap::Config + pallet_proxy::Config - + pallet_crowdloan::Config, + + pallet_crowdloan::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + ByteArray + Into<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + From> + From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, ::Balance: TryFrom, <::Lookup as StaticLookup>::Source: From, @@ -93,15 +100,21 @@ where + pallet_subtensor::Config + pallet_subtensor_swap::Config + pallet_proxy::Config - + pallet_crowdloan::Config, + + pallet_crowdloan::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + ByteArray + Into<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + From> + From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, ::Balance: TryFrom, <::Lookup as StaticLookup>::Source: From, @@ -149,15 +162,21 @@ where + pallet_subtensor::Config + pallet_subtensor_swap::Config + pallet_proxy::Config - + pallet_crowdloan::Config, + + pallet_crowdloan::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + ByteArray + Into<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + From> + From> + From> + GetDispatchInfo - + Dispatchable + + Dispatchable + + IsSubType> + + IsSubType> + Decode, <::RuntimeCall as Dispatchable>::RuntimeOrigin: From>>, diff --git a/precompiles/src/neuron.rs b/precompiles/src/neuron.rs index 3e49387bb3..0b998b3c07 100644 --- a/precompiles/src/neuron.rs +++ b/precompiles/src/neuron.rs @@ -1,11 +1,12 @@ use core::marker::PhantomData; -use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_support::dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}; +use frame_support::traits::IsSubType; use frame_system::RawOrigin; use pallet_evm::{AddressMapping, PrecompileHandle}; use precompile_utils::{EvmResult, prelude::UnboundedBytes}; use sp_core::H256; -use sp_runtime::traits::Dispatchable; +use sp_runtime::traits::{AsSystemOriginSigner, Dispatchable}; use sp_std::vec::Vec; use crate::{PrecompileExt, PrecompileHandleExt}; @@ -14,11 +15,20 @@ pub struct NeuronPrecompile(PhantomData); impl PrecompileExt for NeuronPrecompile where - R: frame_system::Config + pallet_evm::Config + pallet_subtensor::Config, + R: frame_system::Config + + pallet_balances::Config + + pallet_evm::Config + + pallet_subtensor::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { const INDEX: u64 = 2052; @@ -27,11 +37,20 @@ where #[precompile_utils::precompile] impl NeuronPrecompile where - R: frame_system::Config + pallet_evm::Config + pallet_subtensor::Config, + R: frame_system::Config + + pallet_balances::Config + + pallet_evm::Config + + pallet_subtensor::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { #[precompile::public("setWeights(uint16,uint16[],uint16[],uint64)")] diff --git a/precompiles/src/proxy.rs b/precompiles/src/proxy.rs index c8396be264..5139477f00 100644 --- a/precompiles/src/proxy.rs +++ b/precompiles/src/proxy.rs @@ -4,7 +4,8 @@ use crate::{PrecompileExt, PrecompileHandleExt}; use alloc::format; use fp_evm::{ExitError, PrecompileFailure}; -use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_support::dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}; +use frame_support::traits::IsSubType; use frame_system::RawOrigin; use pallet_evm::{AddressMapping, PrecompileHandle}; use pallet_subtensor_proxy as pallet_proxy; @@ -12,7 +13,7 @@ use precompile_utils::EvmResult; use sp_core::{H256, U256}; use sp_runtime::{ codec::DecodeLimit, - traits::{Dispatchable, StaticLookup}, + traits::{AsSystemOriginSigner, Dispatchable, StaticLookup}, }; use sp_std::boxed::Box; use sp_std::convert::{TryFrom, TryInto}; @@ -25,15 +26,22 @@ const MAX_DECODE_DEPTH: u32 = 8; impl PrecompileExt for ProxyPrecompile where R: frame_system::Config + + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config - + pallet_proxy::Config, + + pallet_proxy::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + Into<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::AddressMapping: AddressMapping, ::RuntimeCall: From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, <::Lookup as StaticLookup>::Source: From, { @@ -44,15 +52,22 @@ where impl ProxyPrecompile where R: frame_system::Config + + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config - + pallet_proxy::Config, + + pallet_proxy::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + Into<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::AddressMapping: AddressMapping, ::RuntimeCall: From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, <::Lookup as StaticLookup>::Source: From, { #[precompile::public("createPureProxy(uint8,uint32,uint16)")] diff --git a/precompiles/src/staking.rs b/precompiles/src/staking.rs index 35daaf4f47..862c59219c 100644 --- a/precompiles/src/staking.rs +++ b/precompiles/src/staking.rs @@ -27,7 +27,8 @@ use alloc::vec::Vec; use core::marker::PhantomData; -use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_support::dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}; +use frame_support::traits::IsSubType; use frame_system::RawOrigin; use pallet_evm::{ AddressMapping, BalanceConverter, EvmBalance, ExitError, PrecompileFailure, PrecompileHandle, @@ -36,7 +37,7 @@ use pallet_evm::{ use pallet_subtensor_proxy as pallet_proxy; use precompile_utils::EvmResult; use sp_core::{H256, U256}; -use sp_runtime::traits::{Dispatchable, StaticLookup, UniqueSaturatedInto}; +use sp_runtime::traits::{AsSystemOriginSigner, Dispatchable, StaticLookup, UniqueSaturatedInto}; use sp_std::vec; use subtensor_runtime_common::{Currency, NetUid, ProxyType}; @@ -52,14 +53,21 @@ pub(crate) struct StakingPrecompileV2(PhantomData); impl PrecompileExt for StakingPrecompileV2 where R: frame_system::Config + + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config - + pallet_proxy::Config, + + pallet_proxy::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + Into<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, <::Lookup as StaticLookup>::Source: From, { @@ -70,14 +78,21 @@ where impl StakingPrecompileV2 where R: frame_system::Config + + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config - + pallet_proxy::Config, + + pallet_proxy::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]> + Into<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, <::Lookup as StaticLookup>::Source: From, { @@ -418,13 +433,19 @@ where + pallet_evm::Config + pallet_subtensor::Config + pallet_proxy::Config - + pallet_balances::Config, + + pallet_balances::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, ::Balance: TryFrom, <::Lookup as StaticLookup>::Source: From, @@ -439,13 +460,19 @@ where + pallet_evm::Config + pallet_subtensor::Config + pallet_proxy::Config - + pallet_balances::Config, + + pallet_balances::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, ::Balance: TryFrom, <::Lookup as StaticLookup>::Source: From, diff --git a/precompiles/src/subnet.rs b/precompiles/src/subnet.rs index b7f5cdb098..4df373c116 100644 --- a/precompiles/src/subnet.rs +++ b/precompiles/src/subnet.rs @@ -1,12 +1,13 @@ use core::marker::PhantomData; -use frame_support::dispatch::{GetDispatchInfo, PostDispatchInfo}; +use frame_support::dispatch::{DispatchInfo, GetDispatchInfo, PostDispatchInfo}; use frame_support::traits::ConstU32; +use frame_support::traits::IsSubType; use frame_system::RawOrigin; use pallet_evm::{AddressMapping, PrecompileHandle}; use precompile_utils::{EvmResult, prelude::BoundedString}; use sp_core::H256; -use sp_runtime::traits::Dispatchable; +use sp_runtime::traits::{AsSystemOriginSigner, Dispatchable}; use sp_std::vec; use subtensor_runtime_common::{Currency, NetUid}; @@ -17,14 +18,21 @@ pub struct SubnetPrecompile(PhantomData); impl PrecompileExt for SubnetPrecompile where R: frame_system::Config + + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config - + pallet_admin_utils::Config, + + pallet_admin_utils::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { const INDEX: u64 = 2051; @@ -34,14 +42,21 @@ where impl SubnetPrecompile where R: frame_system::Config + + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config - + pallet_admin_utils::Config, + + pallet_admin_utils::Config + + Send + + Sync + + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, + ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + GetDispatchInfo - + Dispatchable, + + Dispatchable + + IsSubType> + + IsSubType>, ::AddressMapping: AddressMapping, { #[precompile::public("registerNetwork(bytes32)")] diff --git a/runtime/src/lib.rs b/runtime/src/lib.rs index 52746675f9..48e49b76c9 100644 --- a/runtime/src/lib.rs +++ b/runtime/src/lib.rs @@ -241,7 +241,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: 365, + spec_version: 366, impl_version: 1, apis: RUNTIME_API_VERSIONS, transaction_version: 1,