From eabc2ac7b133e6ad41a022f92161ad468349148d Mon Sep 17 00:00:00 2001 From: teor Date: Fri, 17 Jan 2025 12:27:47 +1000 Subject: [PATCH] Use a custom error value for contract allow list failures --- domains/runtime/evm/src/lib.rs | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/domains/runtime/evm/src/lib.rs b/domains/runtime/evm/src/lib.rs index 0adaf95026..68779548a9 100644 --- a/domains/runtime/evm/src/lib.rs +++ b/domains/runtime/evm/src/lib.rs @@ -148,6 +148,10 @@ pub type Executive = domain_pallet_executive::Executive< AllPalletsWithSystem, >; +/// The custom error value returned when a user tries to create a contract, but their account is +/// not on the allow list. +pub const ERR_CONTRACT_CREATION_NOT_ALLOWED_BY_USER: u8 = 0xCC; + const MAX_CONTRACT_RECURSION_DEPTH: u16 = 5; /// Rejects contracts that can't be created under the current allow list. @@ -210,6 +214,9 @@ pub fn is_create_contract(call: &RuntimeCall, mut recursion_depth_left: u16) -> #[derive(Debug, Encode, Decode, Clone, Eq, PartialEq, Default, TypeInfo)] pub struct CheckContractCreation; +// Unsigned calls can't create contracts. Only pallet-evm and pallet-ethereum can create contracts. +// For pallet-evm all contracts are signed extrinsics, for pallet-ethereum there is only one +// extrinsic that is self-contained. impl SignedExtension for CheckContractCreation { const IDENTIFIER: &'static str = "CheckContractCreation"; type AccountId = ::AccountId; @@ -230,7 +237,7 @@ impl SignedExtension for CheckContractCreation { ) -> TransactionValidity { // Reject contract creation unless the account is in the allow list. if !is_create_contract_allowed(call, who) { - InvalidTransaction::Call.into() + InvalidTransaction::Custom(ERR_CONTRACT_CREATION_NOT_ALLOWED_BY_USER).into() } else { Ok(ValidTransaction::default()) } @@ -246,8 +253,6 @@ impl SignedExtension for CheckContractCreation { self.validate(who, call, info, len)?; Ok(()) } - - // TODO: can unsigned calls create contracts? } impl fp_self_contained::SelfContainedCall for RuntimeCall { @@ -274,8 +279,10 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option { if !is_create_contract_allowed(self, &(*info).into()) { - // TODO: should this be Custom() instead? - return Some(Err(InvalidTransaction::Call.into())); + return Some(Err(InvalidTransaction::Custom( + ERR_CONTRACT_CREATION_NOT_ALLOWED_BY_USER, + ) + .into())); } match self { @@ -303,8 +310,10 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { len: usize, ) -> Option> { if !is_create_contract_allowed(self, &(*info).into()) { - // TODO: should this be Custom() instead? - return Some(Err(InvalidTransaction::Call.into())); + return Some(Err(InvalidTransaction::Custom( + ERR_CONTRACT_CREATION_NOT_ALLOWED_BY_USER, + ) + .into())); } match self {