use core::marker::PhantomData; 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::{AsSystemOriginSigner, Dispatchable}; use sp_std::vec; use subtensor_runtime_common::{NetUid, Token}; use crate::{PrecompileExt, PrecompileHandleExt}; 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_shield::Config + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + GetDispatchInfo + Dispatchable + IsSubType> + IsSubType> + IsSubType> + IsSubType>, ::AddressMapping: AddressMapping, { const INDEX: u64 = 2051; } #[precompile_utils::precompile] impl SubnetPrecompile where R: frame_system::Config + pallet_balances::Config + pallet_evm::Config + pallet_subtensor::Config + pallet_shield::Config + pallet_admin_utils::Config + pallet_subtensor_proxy::Config + Send + Sync + scale_info::TypeInfo, R::AccountId: From<[u8; 32]>, ::RuntimeOrigin: AsSystemOriginSigner + Clone, ::RuntimeCall: From> + From> + GetDispatchInfo + Dispatchable + IsSubType> + IsSubType> + IsSubType> + IsSubType>, ::AddressMapping: AddressMapping, { #[precompile::public("registerNetwork(bytes32)")] #[precompile::payable] fn register_network(handle: &mut impl PrecompileHandle, hotkey: H256) -> EvmResult<()> { let hotkey = R::AccountId::from(hotkey.0); 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] #[allow(clippy::too_many_arguments)] 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 = R::AccountId::from(hotkey.0); let identity = pallet_subtensor::SubnetIdentityOfV3 { 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(), logo_url: vec![], 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( "registerNetwork(bytes32,string,string,string,string,string,string,string,string)" )] #[precompile::payable] #[allow(clippy::too_many_arguments)] fn register_network_with_identity_v2( handle: &mut impl PrecompileHandle, hotkey: H256, subnet_name: BoundedString>, github_repo: BoundedString>, subnet_contact: BoundedString>, subnet_url: BoundedString>, discord: BoundedString>, description: BoundedString>, additional: BoundedString>, logo_url: BoundedString>, ) -> EvmResult<()> { let hotkey = R::AccountId::from(hotkey.0); let identity = pallet_subtensor::SubnetIdentityOfV3 { 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(), logo_url: logo_url.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("getNetworkRegistrationBlock(uint16)")] #[precompile::view] fn get_network_registration_block( handle: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::NetworkRegisteredAt::::get( NetUid::from(netuid), )) } #[precompile::public("getServingRateLimit(uint16)")] #[precompile::view] fn get_serving_rate_limit(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::ServingRateLimit::::get(NetUid::from( 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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::MinDifficulty::::get(NetUid::from( 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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::MaxDifficulty::::get(NetUid::from( 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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::WeightsVersionKey::::get(NetUid::from( 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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::WeightsSetRateLimit::::get( NetUid::from(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<()> { // DEPRECATED. Subnet owner cannot set weight setting rate limits Ok(()) } #[precompile::public("getAdjustmentAlpha(uint16)")] #[precompile::view] fn get_adjustment_alpha(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::AdjustmentAlpha::::get(NetUid::from( 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: netuid.into(), 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(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::Pallet::::get_max_weight_limit( NetUid::from(netuid), )) } #[precompile::public("getImmunityPeriod(uint16)")] #[precompile::view] fn get_immunity_period(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::ImmunityPeriod::::get(NetUid::from( 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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::MinAllowedWeights::::get(NetUid::from( 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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::Kappa::::get(NetUid::from(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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::Rho::::get(NetUid::from(netuid))) } #[precompile::public("getAlphaSigmoidSteepness(uint16)")] #[precompile::view] fn get_alpha_sigmoid_steepness( handle: &mut impl PrecompileHandle, netuid: u16, ) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::AlphaSigmoidSteepness::::get(NetUid::from(netuid)) as u16) } #[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: netuid.into(), rho, }; handle.try_dispatch_runtime_call::( call, RawOrigin::Signed(handle.caller_account_id::()), ) } #[precompile::public("setAlphaSigmoidSteepness(uint16,uint16)")] #[precompile::payable] fn set_alpha_sigmoid_steepness( handle: &mut impl PrecompileHandle, netuid: u16, steepness: u16, ) -> EvmResult<()> { let call = pallet_admin_utils::Call::::sudo_set_alpha_sigmoid_steepness { netuid: netuid.into(), steepness: (steepness as i16), }; 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::ActivityCutoff::::get(NetUid::from( 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: netuid.into(), activity_cutoff, }; handle.try_dispatch_runtime_call::( call, RawOrigin::Signed(handle.caller_account_id::()), ) } #[precompile::public("getActivityCutoffFactor(uint16)")] #[precompile::view] fn get_activity_cutoff_factor(_: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { Ok(pallet_subtensor::ActivityCutoffFactorMilli::::get( NetUid::from(netuid), )) } #[precompile::public("setActivityCutoffFactor(uint16,uint32)")] #[precompile::payable] fn set_activity_cutoff_factor( handle: &mut impl PrecompileHandle, netuid: u16, factor_milli: u32, ) -> EvmResult<()> { let call = pallet_admin_utils::Call::::sudo_set_activity_cutoff_factor { netuid: netuid.into(), factor_milli, }; 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::NetworkRegistrationAllowed::::get( NetUid::from(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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::NetworkPowRegistrationAllowed::::get( NetUid::from(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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::MinBurn::::get(NetUid::from(netuid)).to_u64()) } #[precompile::public("setMinBurn(uint16,uint64)")] #[precompile::payable] fn set_min_burn( _handle: &mut impl PrecompileHandle, _netuid: u16, _min_burn: u64, ) -> EvmResult<()> { // DEPRECATED. The subnet owner cannot set the min burn anymore. Ok(()) } #[precompile::public("getMaxBurn(uint16)")] #[precompile::view] fn get_max_burn(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::MaxBurn::::get(NetUid::from(netuid)).to_u64()) } #[precompile::public("setMaxBurn(uint16,uint64)")] #[precompile::payable] fn set_max_burn( _handle: &mut impl PrecompileHandle, _netuid: u16, _max_burn: u64, ) -> EvmResult<()> { // DEPRECATED. The subnet owner cannot set the max burn anymore. Ok(()) } #[precompile::public("getDifficulty(uint16)")] #[precompile::view] fn get_difficulty(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::Difficulty::::get(NetUid::from(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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::BondsMovingAverage::::get( NetUid::from(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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::CommitRevealWeightsEnabled::::get( NetUid::from(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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::LiquidAlphaOn::::get(NetUid::from( 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: netuid.into(), enabled, }; handle.try_dispatch_runtime_call::( call, RawOrigin::Signed(handle.caller_account_id::()), ) } #[precompile::public("getYuma3Enabled(uint16)")] #[precompile::view] fn get_yuma3_enabled(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::Yuma3On::::get(NetUid::from(netuid))) } #[precompile::public("getBondsResetEnabled(uint16)")] #[precompile::view] fn get_bonds_reset_enabled(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::BondsResetOn::::get(NetUid::from( netuid, ))) } #[precompile::public("setYuma3Enabled(uint16,bool)")] #[precompile::payable] fn set_yuma3_enabled( handle: &mut impl PrecompileHandle, netuid: u16, enabled: bool, ) -> EvmResult<()> { let call = pallet_admin_utils::Call::::sudo_set_yuma3_enabled { netuid: netuid.into(), enabled, }; handle.try_dispatch_runtime_call::( call, RawOrigin::Signed(handle.caller_account_id::()), ) } #[precompile::public("setBondsResetEnabled(uint16,bool)")] #[precompile::payable] fn set_bonds_reset_enabled( handle: &mut impl PrecompileHandle, netuid: u16, enabled: bool, ) -> EvmResult<()> { let call = pallet_admin_utils::Call::::sudo_set_bonds_reset_enabled { netuid: netuid.into(), 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)> { handle.record_db_reads::(1)?; Ok(pallet_subtensor::AlphaValues::::get(NetUid::from( 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: netuid.into(), 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 { handle.record_db_reads::(1)?; Ok(pallet_subtensor::RevealPeriodEpochs::::get( NetUid::from(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: netuid.into(), interval, }; handle.try_dispatch_runtime_call::( call, RawOrigin::Signed(handle.caller_account_id::()), ) } #[precompile::public("toggleTransfers(uint16,bool)")] #[precompile::payable] fn toggle_transfers( handle: &mut impl PrecompileHandle, netuid: u16, toggle: bool, ) -> EvmResult<()> { let call = pallet_admin_utils::Call::::sudo_set_toggle_transfer { netuid: netuid.into(), toggle, }; handle.try_dispatch_runtime_call::( call, RawOrigin::Signed(handle.caller_account_id::()), ) } #[precompile::public("isSubnetDissolving(uint16)")] #[precompile::view] fn is_subnet_dissolving(handle: &mut impl PrecompileHandle, netuid: u16) -> EvmResult { handle.record_db_reads::(1)?; Ok(pallet_subtensor::DissolveCleanupQueue::::get().contains(&NetUid::from(netuid))) } } #[cfg(test)] mod tests { #![allow( clippy::arithmetic_side_effects, clippy::expect_used, clippy::unwrap_used )] use super::*; use crate::PrecompileExt; use crate::mock::{ AccountId, Runtime, addr_from_index, assert_static_call, mapped_account, new_test_ext, precompiles, selector_u32, }; use precompile_utils::solidity::encode_with_selector; use precompile_utils::testing::PrecompileTesterExt; use sp_core::{H160, H256, U256}; use subtensor_runtime_common::TaoBalance; const TEST_NETUID_U16: u16 = 1; const TEST_TEMPO: u16 = 100; fn setup_owner_subnet(caller: H160) -> NetUid { let netuid = NetUid::from(TEST_NETUID_U16); let owner = mapped_account(caller); let owner_hotkey = AccountId::from([0x55; 32]); pallet_subtensor::Pallet::::init_new_network(netuid, TEST_TEMPO); pallet_subtensor::SubnetOwner::::insert(netuid, owner); pallet_subtensor::SubnetOwnerHotkey::::insert(netuid, owner_hotkey); pallet_subtensor::AdminFreezeWindow::::set(0); pallet_subtensor::OwnerHyperparamRateLimit::::set(0); netuid } fn add_balance_to_coldkey_account(coldkey: &sp_core::crypto::AccountId32, tao: TaoBalance) { let credit = pallet_subtensor::Pallet::::mint_tao(tao); let _ = pallet_subtensor::Pallet::::spend_tao(coldkey, credit, tao).unwrap(); } #[test] fn subnet_precompile_registers_network_without_identity() { new_test_ext().execute_with(|| { let caller = addr_from_index(0x5000); let caller_account = mapped_account(caller); let hotkey = AccountId::from([0x44; 32]); let precompiles = precompiles::>(); let precompile_addr = addr_from_index(SubnetPrecompile::::INDEX); add_balance_to_coldkey_account(&caller_account, 1_000_000_000_000_u64.into()); let total_before = pallet_subtensor::TotalNetworks::::get(); let netuid = pallet_subtensor::Pallet::::get_next_netuid(); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("registerNetwork(bytes32)"), (H256::from_slice(hotkey.as_ref()),), ), ) .execute_returns(()); let total_after = pallet_subtensor::TotalNetworks::::get(); assert_eq!(total_after, total_before + 1); assert_eq!( pallet_subtensor::SubnetOwner::::get(netuid), caller_account ); assert!(!pallet_subtensor::SubnetIdentitiesV3::::contains_key(netuid)); }); } #[test] fn subnet_precompile_registers_network_with_identity() { new_test_ext().execute_with(|| { let caller = addr_from_index(0x5002); let caller_account = mapped_account(caller); let hotkey = AccountId::from([0x45; 32]); let precompiles = precompiles::>(); let precompile_addr = addr_from_index(SubnetPrecompile::::INDEX); add_balance_to_coldkey_account( &caller_account, 1_000_000_000_000_u64.into(), ); let total_before = pallet_subtensor::TotalNetworks::::get(); let netuid = pallet_subtensor::Pallet::::get_next_netuid(); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32( "registerNetwork(bytes32,string,string,string,string,string,string,string)", ), ( H256::from_slice(hotkey.as_ref()), precompile_utils::solidity::codec::UnboundedString::from("name"), precompile_utils::solidity::codec::UnboundedString::from("repo"), precompile_utils::solidity::codec::UnboundedString::from("contact"), precompile_utils::solidity::codec::UnboundedString::from("subnetUrl"), precompile_utils::solidity::codec::UnboundedString::from("discord"), precompile_utils::solidity::codec::UnboundedString::from("description"), precompile_utils::solidity::codec::UnboundedString::from("additional"), ), ), ) .execute_returns(()); let total_after = pallet_subtensor::TotalNetworks::::get(); assert_eq!(total_after, total_before + 1); assert_eq!(pallet_subtensor::SubnetOwner::::get(netuid), caller_account); assert!(pallet_subtensor::SubnetIdentitiesV3::::contains_key(netuid)); }); } #[test] fn subnet_precompile_sets_and_gets_owner_hyperparameters() { new_test_ext().execute_with(|| { let caller = addr_from_index(0x5001); let netuid = setup_owner_subnet(caller); let precompiles = precompiles::>(); let precompile_addr = addr_from_index(SubnetPrecompile::::INDEX); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setServingRateLimit(uint16,uint64)"), (TEST_NETUID_U16, 100_u64), ), ) .execute_returns(()); assert_eq!( pallet_subtensor::ServingRateLimit::::get(netuid), 100 ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getServingRateLimit(uint16)"), (TEST_NETUID_U16,), ), U256::from(100_u64), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setMaxDifficulty(uint16,uint64)"), (TEST_NETUID_U16, 102_u64), ), ) .execute_returns(()); assert_eq!(pallet_subtensor::MaxDifficulty::::get(netuid), 102); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector(selector_u32("getMaxDifficulty(uint16)"), (TEST_NETUID_U16,)), U256::from(102_u64), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setWeightsVersionKey(uint16,uint64)"), (TEST_NETUID_U16, 103_u64), ), ) .execute_returns(()); assert_eq!( pallet_subtensor::WeightsVersionKey::::get(netuid), 103 ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getWeightsVersionKey(uint16)"), (TEST_NETUID_U16,), ), U256::from(103_u64), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setAdjustmentAlpha(uint16,uint64)"), (TEST_NETUID_U16, 105_u64), ), ) .execute_returns(()); assert_eq!( pallet_subtensor::AdjustmentAlpha::::get(netuid), 105 ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getAdjustmentAlpha(uint16)"), (TEST_NETUID_U16,), ), U256::from(105_u64), ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getMaxWeightLimit(uint16)"), (TEST_NETUID_U16,), ), U256::from(0xFFFF_u64), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setImmunityPeriod(uint16,uint16)"), (TEST_NETUID_U16, 107_u16), ), ) .execute_returns(()); assert_eq!( pallet_subtensor::ImmunityPeriod::::get(netuid), 107 ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getImmunityPeriod(uint16)"), (TEST_NETUID_U16,), ), U256::from(107_u64), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setMinAllowedWeights(uint16,uint16)"), (TEST_NETUID_U16, 108_u16), ), ) .execute_returns(()); assert_eq!( pallet_subtensor::MinAllowedWeights::::get(netuid), 108 ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getMinAllowedWeights(uint16)"), (TEST_NETUID_U16,), ), U256::from(108_u64), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setRho(uint16,uint16)"), (TEST_NETUID_U16, 110_u16), ), ) .execute_returns(()); assert_eq!(pallet_subtensor::Rho::::get(netuid), 110); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector(selector_u32("getRho(uint16)"), (TEST_NETUID_U16,)), U256::from(110_u64), ); let activity_cutoff = pallet_subtensor::MinActivityCutoff::::get() + 1; precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setActivityCutoff(uint16,uint16)"), (TEST_NETUID_U16, activity_cutoff), ), ) .execute_returns(()); assert_eq!( pallet_subtensor::ActivityCutoff::::get(netuid), activity_cutoff ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getActivityCutoff(uint16)"), (TEST_NETUID_U16,), ), U256::from(activity_cutoff), ); let factor_milli: u32 = 1_500; precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setActivityCutoffFactor(uint16,uint32)"), (TEST_NETUID_U16, factor_milli), ), ) .execute_returns(()); assert_eq!( pallet_subtensor::ActivityCutoffFactorMilli::::get(netuid), factor_milli ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getActivityCutoffFactor(uint16)"), (TEST_NETUID_U16,), ), U256::from(factor_milli), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setBondsMovingAverage(uint16,uint64)"), (TEST_NETUID_U16, 115_u64), ), ) .execute_returns(()); assert_eq!( pallet_subtensor::BondsMovingAverage::::get(netuid), 115 ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getBondsMovingAverage(uint16)"), (TEST_NETUID_U16,), ), U256::from(115_u64), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setCommitRevealWeightsEnabled(uint16,bool)"), (TEST_NETUID_U16, true), ), ) .execute_returns(()); assert!(pallet_subtensor::CommitRevealWeightsEnabled::::get(netuid)); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getCommitRevealWeightsEnabled(uint16)"), (TEST_NETUID_U16,), ), U256::one(), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setLiquidAlphaEnabled(uint16,bool)"), (TEST_NETUID_U16, true), ), ) .execute_returns(()); assert!(pallet_subtensor::LiquidAlphaOn::::get(netuid)); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getLiquidAlphaEnabled(uint16)"), (TEST_NETUID_U16,), ), U256::one(), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setYuma3Enabled(uint16,bool)"), (TEST_NETUID_U16, true), ), ) .execute_returns(()); assert!(pallet_subtensor::Yuma3On::::get(netuid)); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector(selector_u32("getYuma3Enabled(uint16)"), (TEST_NETUID_U16,)), U256::one(), ); precompiles .prepare_test( caller, precompile_addr, encode_with_selector( selector_u32("setCommitRevealWeightsInterval(uint16,uint64)"), (TEST_NETUID_U16, 99_u64), ), ) .execute_returns(()); assert_eq!( pallet_subtensor::RevealPeriodEpochs::::get(netuid), 99 ); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getCommitRevealWeightsInterval(uint16)"), (TEST_NETUID_U16,), ), U256::from(99_u64), ); }); } #[test] fn subnet_precompile_gets_network_registered_block() { new_test_ext().execute_with(|| { let caller = addr_from_index(0x5003); let netuid = setup_owner_subnet(caller); let precompiles = precompiles::>(); let precompile_addr = addr_from_index(SubnetPrecompile::::INDEX); let registration_block: u64 = 42; pallet_subtensor::NetworkRegisteredAt::::insert(netuid, registration_block); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("getNetworkRegistrationBlock(uint16)"), (TEST_NETUID_U16,), ), U256::from(registration_block), ); }); } #[test] fn subnet_precompile_is_subnet_dissolving() { new_test_ext().execute_with(|| { let caller = addr_from_index(0x5003); let netuid = setup_owner_subnet(caller); let precompiles = precompiles::>(); let precompile_addr = addr_from_index(SubnetPrecompile::::INDEX); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("isSubnetDissolving(uint16)"), (TEST_NETUID_U16,), ), U256::zero(), ); pallet_subtensor::DissolveCleanupQueue::::set(vec![netuid]); assert_static_call( &precompiles, caller, precompile_addr, encode_with_selector( selector_u32("isSubnetDissolving(uint16)"), (TEST_NETUID_U16,), ), U256::one(), ); }); } }