@@ -74,6 +74,8 @@ use frame_support::{
74
74
} ;
75
75
use frame_system:: RawOrigin ;
76
76
use impl_trait_for_tuples:: impl_for_tuples;
77
+ use scale_codec:: { Decode , Encode } ;
78
+ use scale_info:: TypeInfo ;
77
79
use sp_core:: { Hasher , H160 , H256 , U256 } ;
78
80
use sp_runtime:: {
79
81
traits:: { BadOrigin , Saturating , UniqueSaturatedInto , Zero } ,
@@ -155,6 +157,9 @@ pub mod pallet {
155
157
/// Find author for the current block.
156
158
type FindAuthor : FindAuthor < H160 > ;
157
159
160
+ /// Origin allowed to modify Precompiles
161
+ type PrecompileModifierOrigin : EnsureOrigin < Self :: RuntimeOrigin > ;
162
+
158
163
/// EVM config used in the module.
159
164
fn config ( ) -> & ' static EvmConfig {
160
165
& LONDON_CONFIG
@@ -404,6 +409,37 @@ pub mod pallet {
404
409
pays_fee : Pays :: No ,
405
410
} )
406
411
}
412
+
413
+ /// Add a precompile to storage
414
+ #[ pallet:: call_index( 4 ) ]
415
+ #[ pallet:: weight( 0 ) ]
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( 0 ) ]
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
+ }
407
443
}
408
444
409
445
#[ pallet:: event]
@@ -445,6 +481,8 @@ pub mod pallet {
445
481
Reentrancy ,
446
482
/// EIP-3607,
447
483
TransactionMustComeFromEOA ,
484
+ /// Precompile does not exist in storage
485
+ PrecompileDoesNotExist ,
448
486
}
449
487
450
488
impl < T > From < InvalidEvmTransactionError > for Error < T > {
@@ -467,7 +505,7 @@ pub mod pallet {
467
505
#[ cfg_attr( feature = "std" , derive( Default ) ) ]
468
506
pub struct GenesisConfig {
469
507
pub accounts : std:: collections:: BTreeMap < H160 , GenesisAccount > ,
470
- pub precompiles : Vec < ( Vec < u8 > , H160 ) > ,
508
+ pub precompiles : Vec < ( H160 , PrecompileLabel ) > ,
471
509
}
472
510
473
511
#[ pallet:: genesis_build]
@@ -499,8 +537,8 @@ pub mod pallet {
499
537
}
500
538
}
501
539
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 ( ) ) ;
504
542
}
505
543
}
506
544
}
@@ -515,15 +553,21 @@ pub mod pallet {
515
553
StorageDoubleMap < _ , Blake2_128Concat , H160 , Blake2_128Concat , H256 , H256 , ValueQuery > ;
516
554
517
555
/// 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
+
521
559
/// 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()`
523
561
#[ pallet:: storage]
524
562
#[ pallet:: getter( fn precompiles) ]
525
563
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 > ,
527
571
}
528
572
529
573
/// Type alias for currency balance.
@@ -688,13 +732,13 @@ static LONDON_CONFIG: EvmConfig = EvmConfig::london();
688
732
689
733
impl < T : Config > Pallet < T > {
690
734
/// 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 ) ;
693
737
}
694
738
695
739
/// 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) ;
698
742
}
699
743
700
744
/// Check whether an account is empty.
0 commit comments