Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extrinsic to enable disable precompile #1131

Open
wants to merge 6 commits into
base: devnet-ready
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 72 additions & 2 deletions pallets/admin-utils/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ mod tests;
#[frame_support::pallet]
pub mod pallet {
use super::*;
use frame_support::dispatch::DispatchResult;
use frame_support::pallet_prelude::*;
use frame_support::traits::tokens::Balance;
use frame_support::{dispatch::DispatchResult, pallet_prelude::StorageMap};
use frame_system::pallet_prelude::*;
use pallet_evm_chain_id::{self, ChainId};
use sp_runtime::BoundedVec;
Expand Down Expand Up @@ -69,7 +69,16 @@ pub mod pallet {
}

#[pallet::event]
pub enum Event<T: Config> {}
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Event emitted when a precompile operation is updated.
PrecompileUpdated {
/// The type of precompile operation being updated.
precompile_id: PrecompileEnum,
/// Indicates if the precompile operation is enabled or not.
enabled: bool,
},
}

// Errors inform users that something went wrong.
#[pallet::error]
Expand All @@ -81,6 +90,37 @@ pub mod pallet {
/// The maximum number of subnet validators must be more than the current number of UIDs already in the subnet.
MaxAllowedUIdsLessThanCurrentUIds,
}
/// Enum for specifying the type of precompile operation.
#[derive(Encode, Decode, TypeInfo, Clone, PartialEq, Eq, Debug, Copy)]
pub enum PrecompileEnum {
/// Enum for balance transfer precompile
BalanceTransfer,
/// Enum for staking precompile
Staking,
/// Enum for subnet precompile
Subnet,
/// Enum for metagraph precompile
Metagraph,
/// Enum for neuron precompile
Neuron,
}

#[pallet::type_value]
/// Default value for precompile enable
pub fn DefaultPrecompileEnabled<T: Config>() -> bool {
true
}

#[pallet::storage]
/// Map PrecompileEnum --> enabled
pub type PrecompileEnable<T: Config> = StorageMap<
_,
Blake2_128Concat,
PrecompileEnum,
bool,
ValueQuery,
DefaultPrecompileEnabled<T>,
>;

/// Dispatchable functions allows users to interact with the pallet and invoke state changes.
#[pallet::call]
Expand Down Expand Up @@ -1262,6 +1302,36 @@ pub mod pallet {
ensure_root(origin)?;
T::Grandpa::schedule_change(next_authorities, in_blocks, forced)
}

/// Toggles the enablement of an EVM precompile.
///
/// # Arguments
/// * `origin` - The origin of the call, which must be the root account.
/// * `precompile_id` - The identifier of the EVM precompile to toggle.
/// * `enabled` - The new enablement state of the precompile.
///
/// # Errors
/// * `BadOrigin` - If the caller is not the root account.
///
/// # Weight
/// Weight is handled by the `#[pallet::weight]` attribute.
#[pallet::call_index(60)]
#[pallet::weight((0, DispatchClass::Operational, Pays::No))]
pub fn sudo_toggle_evm_precompile(
origin: OriginFor<T>,
precompile_id: PrecompileEnum,
enabled: bool,
) -> DispatchResult {
ensure_root(origin)?;
if PrecompileEnable::<T>::get(precompile_id) != enabled {
PrecompileEnable::<T>::insert(precompile_id, enabled);
Self::deposit_event(Event::PrecompileUpdated {
precompile_id,
enabled,
});
}
Ok(())
}
}
}

Expand Down
1 change: 1 addition & 0 deletions pallets/admin-utils/src/tests/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -390,6 +390,7 @@ pub(crate) fn run_to_block(n: u64) {
while System::block_number() < n {
SubtensorModule::on_finalize(System::block_number());
System::on_finalize(System::block_number());
System::reset_events();
System::set_block_number(System::block_number() + 1);
System::on_initialize(System::block_number());
SubtensorModule::on_initialize(System::block_number());
Expand Down
72 changes: 72 additions & 0 deletions pallets/admin-utils/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use pallet_subtensor::Event;
use sp_consensus_grandpa::AuthorityId as GrandpaId;
use sp_core::{ed25519, Pair, U256};

use crate::pallet::PrecompileEnable;
use crate::Error;
use mock::*;

Expand Down Expand Up @@ -1332,3 +1333,74 @@ fn test_schedule_grandpa_change() {
assert_eq!(Grandpa::grandpa_authorities(), vec![(bob, 1)]);
});
}

#[test]
fn test_sudo_toggle_evm_precompile() {
new_test_ext().execute_with(|| {
let precompile_id = crate::PrecompileEnum::BalanceTransfer;
let initial_enabled = PrecompileEnable::<Test>::get(precompile_id);
assert!(initial_enabled); // Assuming the default is true

run_to_block(1);

assert_eq!(
AdminUtils::sudo_toggle_evm_precompile(
<<Test as Config>::RuntimeOrigin>::signed(U256::from(0)),
precompile_id,
false
),
Err(DispatchError::BadOrigin)
);

assert_ok!(AdminUtils::sudo_toggle_evm_precompile(
RuntimeOrigin::root(),
precompile_id,
false
));

assert_eq!(
System::events()
.iter()
.filter(|r| r.event
== RuntimeEvent::AdminUtils(crate::Event::PrecompileUpdated {
precompile_id,
enabled: false
}))
.count(),
1
);

let updated_enabled = PrecompileEnable::<Test>::get(precompile_id);
assert!(!updated_enabled);

run_to_block(2);

assert_ok!(AdminUtils::sudo_toggle_evm_precompile(
RuntimeOrigin::root(),
precompile_id,
false
));

// no event without status change
assert_eq!(
System::events()
.iter()
.filter(|r| r.event
== RuntimeEvent::AdminUtils(crate::Event::PrecompileUpdated {
precompile_id,
enabled: false
}))
.count(),
0
);

assert_ok!(AdminUtils::sudo_toggle_evm_precompile(
RuntimeOrigin::root(),
precompile_id,
true
));

let final_enabled = PrecompileEnable::<Test>::get(precompile_id);
assert!(final_enabled);
});
}
49 changes: 45 additions & 4 deletions runtime/src/precompiles/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ use pallet_evm_precompile_modexp::Modexp;
use pallet_evm_precompile_sha3fips::Sha3FIPS256;
use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256};

use crate::Runtime;
use pallet_admin_utils::{PrecompileEnable, PrecompileEnum};

// Include custom precompiles
mod balance_transfer;
mod ed25519;
Expand Down Expand Up @@ -70,14 +73,52 @@ 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(EDVERIFY_PRECOMPILE_INDEX) => {
if PrecompileEnable::<Runtime>::get(PrecompileEnum::BalanceTransfer) {
Some(Ed25519Verify::execute(handle))
} else {
Some(Err(PrecompileFailure::Error {
exit_status: ExitError::Other(
"Precompile Ed25519Verify is disabled".into(),
),
}))
}
}
// Subtensor specific precompiles :
a if a == hash(BALANCE_TRANSFER_INDEX) => {
Some(BalanceTransferPrecompile::execute(handle))
if PrecompileEnable::<Runtime>::get(PrecompileEnum::BalanceTransfer) {
Some(BalanceTransferPrecompile::execute(handle))
} else {
Some(Err(PrecompileFailure::Error {
exit_status: ExitError::Other(
"Precompile Balance Transfer is disabled".into(),
),
}))
}
}
a if a == hash(STAKING_PRECOMPILE_INDEX) => Some(StakingPrecompile::execute(handle)),
a if a == hash(STAKING_PRECOMPILE_INDEX) => {
if PrecompileEnable::<Runtime>::get(PrecompileEnum::Staking) {
Some(StakingPrecompile::execute(handle))
} else {
Some(Err(PrecompileFailure::Error {
exit_status: ExitError::Other(
"Precompile Balance Transfer is disabled".into(),
),
}))
}
}

a if a == hash(METAGRAPH_PRECOMPILE_INDEX) => {
Some(MetagraphPrecompile::execute(handle))
if PrecompileEnable::<Runtime>::get(PrecompileEnum::Metagraph) {
Some(MetagraphPrecompile::execute(handle))
} else {
Some(Err(PrecompileFailure::Error {
exit_status: ExitError::Other(
"Precompile Balance Transfer is disabled".into(),
),
}))
}
}

_ => None,
Expand Down
Loading