@@ -74,6 +74,8 @@ use frame_support::{
7474} ;
7575use frame_system:: RawOrigin ;
7676use impl_trait_for_tuples:: impl_for_tuples;
77+ use scale_codec:: { Decode , Encode } ;
78+ use scale_info:: TypeInfo ;
7779use sp_core:: { Hasher , H160 , H256 , U256 } ;
7880use sp_runtime:: {
7981 traits:: { BadOrigin , Saturating , UniqueSaturatedInto , Zero } ,
@@ -155,6 +157,9 @@ pub mod pallet {
155157 /// Find author for the current block.
156158 type FindAuthor : FindAuthor < H160 > ;
157159
160+ /// Origin allowed to modify Precompiles
161+ type PrecompileModifierOrigin : EnsureOrigin < Self :: RuntimeOrigin > ;
162+
158163 /// EVM config used in the module.
159164 fn config ( ) -> & ' static EvmConfig {
160165 & LONDON_CONFIG
@@ -404,6 +409,37 @@ pub mod pallet {
404409 pays_fee : Pays :: No ,
405410 } )
406411 }
412+
413+ /// Add a precompile to storage
414+ #[ pallet:: call_index( 4 ) ]
415+ #[ pallet:: weight( T :: DbWeight :: get( ) . reads_writes( 0 , 1 ) ) ]
416+ pub fn add_precompile (
417+ origin : OriginFor < T > ,
418+ address : H160 ,
419+ label : PrecompileLabel ,
420+ ) -> DispatchResult {
421+ T :: PrecompileModifierOrigin :: ensure_origin ( origin) ?;
422+
423+ Self :: do_add_precompile ( & address, label) ;
424+
425+ Ok ( ( ) )
426+ }
427+
428+ /// Remove a precompile from storage
429+ #[ pallet:: call_index( 5 ) ]
430+ #[ pallet:: weight( T :: DbWeight :: get( ) . reads_writes( 0 , 1 ) ) ]
431+ pub fn remove_precompile (
432+ origin : OriginFor < T > ,
433+ address : H160 ,
434+ ) -> DispatchResult {
435+ T :: PrecompileModifierOrigin :: ensure_origin ( origin) ?;
436+
437+ ensure ! ( Precompiles :: <T >:: contains_key( address) , Error :: <T >:: PrecompileDoesNotExist ) ;
438+
439+ Self :: do_remove_precompile ( & address) ;
440+
441+ Ok ( ( ) )
442+ }
407443 }
408444
409445 #[ pallet:: event]
@@ -445,6 +481,8 @@ pub mod pallet {
445481 Reentrancy ,
446482 /// EIP-3607,
447483 TransactionMustComeFromEOA ,
484+ /// Precompile does not exist in storage
485+ PrecompileDoesNotExist ,
448486 }
449487
450488 impl < T > From < InvalidEvmTransactionError > for Error < T > {
@@ -467,7 +505,7 @@ pub mod pallet {
467505 #[ cfg_attr( feature = "std" , derive( Default ) ) ]
468506 pub struct GenesisConfig {
469507 pub accounts : std:: collections:: BTreeMap < H160 , GenesisAccount > ,
470- pub precompiles : Vec < ( Vec < u8 > , H160 ) > ,
508+ pub precompiles : Vec < ( H160 , PrecompileLabel ) > ,
471509 }
472510
473511 #[ pallet:: genesis_build]
@@ -499,8 +537,8 @@ pub mod pallet {
499537 }
500538 }
501539
502- for ( label , address ) in & self . precompiles {
503- Pallet :: < T > :: add_precompile ( label , address ) ;
540+ for ( address , label ) in & self . precompiles {
541+ Pallet :: < T > :: do_add_precompile ( address , label . clone ( ) ) ;
504542 }
505543 }
506544 }
@@ -515,15 +553,21 @@ pub mod pallet {
515553 StorageDoubleMap < _ , Blake2_128Concat , H160 , Blake2_128Concat , H256 , H256 , ValueQuery > ;
516554
517555 /// Allows for precompiles to have arbitrary addresses, potentially more than one.
518- /// `k1 `: precompile label, e.g.: `b"Sha3FIPS256".to_vec()`
519- /// `k2 `: precompile address
520- ///
556+ /// `key `: precompile `H160` address
557+ /// `value `: precompile label, e.g.: `PrecompileLabel { label: b"Sha3FIPS256".to_vec() }`
558+
521559 /// Please note that adding a new precompile label here is not enough to guarantee its execution
522- /// It is also required to list the new label on the implementation of `PrecompileSet::execute()`
560+ /// It is also required to list new labels on the implementation of `PrecompileSet::execute()`
523561 #[ pallet:: storage]
524562 #[ pallet:: getter( fn precompiles) ]
525563 pub type Precompiles < T : Config > =
526- StorageDoubleMap < _ , Blake2_128Concat , Vec < u8 > , Blake2_128Concat , H160 , ( ) , OptionQuery > ;
564+ StorageMap < _ , Blake2_128Concat , H160 , PrecompileLabel , ValueQuery > ;
565+ }
566+
567+ #[ derive( Decode , Encode , Default , TypeInfo , Clone , PartialEq , Debug ) ]
568+ #[ cfg_attr( feature = "std" , derive( serde:: Serialize , serde:: Deserialize ) ) ]
569+ pub struct PrecompileLabel {
570+ pub label : Vec < u8 > ,
527571}
528572
529573/// Type alias for currency balance.
@@ -688,13 +732,13 @@ static LONDON_CONFIG: EvmConfig = EvmConfig::london();
688732
689733impl < T : Config > Pallet < T > {
690734 /// Add a precompile to storage
691- pub fn add_precompile ( label : & Vec < u8 > , address : & H160 ) {
692- Precompiles :: < T > :: set ( label , address, Some ( ( ) ) ) ;
735+ pub fn do_add_precompile ( address : & H160 , label : PrecompileLabel ) {
736+ Precompiles :: < T > :: set ( address, label ) ;
693737 }
694738
695739 /// Remove a precompile from storage
696- pub fn remove_precompile ( label : & Vec < u8 > , address : & H160 ) {
697- Precompiles :: < T > :: remove ( label , address) ;
740+ pub fn do_remove_precompile ( address : & H160 ) {
741+ Precompiles :: < T > :: remove ( address) ;
698742 }
699743
700744 /// Check whether an account is empty.
0 commit comments