@@ -16,20 +16,22 @@ pub mod pallet {
1616 use super :: * ;
1717 use codec:: Encode ;
1818 use frame_support:: {
19- dispatch:: { GetDispatchInfo , PostDispatchInfo } ,
19+ dispatch:: { DispatchInfo , GetDispatchInfo , PostDispatchInfo } ,
2020 pallet_prelude:: * ,
2121 traits:: ConstU32 ,
22+ traits:: IsSubType ,
2223 weights:: Weight ,
2324 } ;
2425 use frame_system:: pallet_prelude:: * ;
2526 use sp_consensus_aura:: sr25519:: AuthorityId as AuraAuthorityId ;
2627 use sp_core:: ByteArray ;
27- use sp_runtime:: transaction_validity:: {
28- InvalidTransaction , TransactionSource , ValidTransaction ,
29- } ;
3028 use sp_runtime:: {
3129 AccountId32 , DispatchErrorWithPostInfo , RuntimeDebug , Saturating ,
32- traits:: { BadOrigin , Hash } ,
30+ traits:: {
31+ BadOrigin , DispatchInfoOf , DispatchOriginOf , Dispatchable , Hash , Implication ,
32+ TransactionExtension ,
33+ } ,
34+ transaction_validity:: { InvalidTransaction , TransactionSource , ValidTransaction } ,
3335 } ;
3436 use sp_std:: { marker:: PhantomData , prelude:: * } ;
3537 use subtensor_macros:: freeze_struct;
@@ -279,8 +281,8 @@ pub mod pallet {
279281 /// Client‑side:
280282 ///
281283 /// 1. Read `NextKey` (ML‑KEM public key bytes) from storage.
282- /// 2. Sign your extrinsic so that it can be executed when added to the pool,
283- /// i.e. you may need to increment the nonce if you submit using the same account.
284+ /// 2. Sign your extrinsic so that it can be executed when added to the pool,
285+ /// i.e. you may need to increment the nonce if you submit using the same account.
284286 /// 3. `commitment = Hashing::hash(signed_extrinsic)`.
285287 /// 4. Encrypt:
286288 ///
@@ -382,4 +384,93 @@ pub mod pallet {
382384 }
383385 }
384386 }
387+
388+ #[ freeze_struct( "51f74eb54f5ab1fe" ) ]
389+ #[ derive( Default , Encode , Decode , DecodeWithMemTracking , Clone , Eq , PartialEq , TypeInfo ) ]
390+ pub struct MevShieldDecryptionFilter < T : Config + Send + Sync + TypeInfo > ( pub PhantomData < T > ) ;
391+
392+ impl < T : Config + Send + Sync + TypeInfo > sp_std:: fmt:: Debug for MevShieldDecryptionFilter < T > {
393+ fn fmt ( & self , f : & mut sp_std:: fmt:: Formatter ) -> sp_std:: fmt:: Result {
394+ write ! ( f, "MevShieldDecryptionFilter" )
395+ }
396+ }
397+
398+ impl < T : Config + Send + Sync + TypeInfo > MevShieldDecryptionFilter < T > {
399+ pub fn new ( ) -> Self {
400+ Self ( PhantomData )
401+ }
402+
403+ #[ inline]
404+ fn mev_failed_priority ( ) -> TransactionPriority {
405+ 1u64
406+ }
407+ }
408+
409+ impl < T : Config + Send + Sync + TypeInfo > TransactionExtension < RuntimeCallFor < T > >
410+ for MevShieldDecryptionFilter < T >
411+ where
412+ <T as frame_system:: Config >:: RuntimeCall :
413+ Dispatchable < Info = DispatchInfo , PostInfo = PostDispatchInfo > ,
414+ <T as frame_system:: Config >:: RuntimeCall : IsSubType < Call < T > > ,
415+ {
416+ const IDENTIFIER : & ' static str = "MevShieldDecryptionFilter" ;
417+
418+ type Implicit = ( ) ;
419+ type Val = ( ) ;
420+ type Pre = ( ) ;
421+
422+ fn weight ( & self , _call : & RuntimeCallFor < T > ) -> Weight {
423+ // Only does light pattern matching; treat as free.
424+ Weight :: zero ( )
425+ }
426+
427+ fn validate (
428+ & self ,
429+ origin : DispatchOriginOf < RuntimeCallFor < T > > ,
430+ call : & RuntimeCallFor < T > ,
431+ _info : & DispatchInfoOf < RuntimeCallFor < T > > ,
432+ _len : usize ,
433+ _self_implicit : Self :: Implicit ,
434+ _inherited_implication : & impl Implication ,
435+ source : TransactionSource ,
436+ ) -> ValidateResult < Self :: Val , RuntimeCallFor < T > > {
437+ match call. is_sub_type ( ) {
438+ Some ( Call :: mark_decryption_failed { id, .. } ) => {
439+ match source {
440+ TransactionSource :: Local | TransactionSource :: InBlock => {
441+ let validity_res =
442+ ValidTransaction :: with_tag_prefix ( "mev-shield-failed" )
443+ . priority ( Self :: mev_failed_priority ( ) )
444+ . longevity ( 64 )
445+ . and_provides ( id)
446+ . propagate ( false )
447+ . build ( ) ;
448+
449+ match validity_res {
450+ Ok ( validity) => Ok ( ( validity, ( ) , origin) ) ,
451+ Err ( e) => Err ( e) ,
452+ }
453+ }
454+
455+ // Anything coming from the outside world (including *signed*
456+ // transactions) is rejected at the pool boundary.
457+ _ => Err ( InvalidTransaction :: Call . into ( ) ) ,
458+ }
459+ }
460+
461+ _ => Ok ( ( Default :: default ( ) , ( ) , origin) ) ,
462+ }
463+ }
464+
465+ fn prepare (
466+ self ,
467+ _val : Self :: Val ,
468+ _origin : & DispatchOriginOf < RuntimeCallFor < T > > ,
469+ _call : & RuntimeCallFor < T > ,
470+ _info : & DispatchInfoOf < RuntimeCallFor < T > > ,
471+ _len : usize ,
472+ ) -> Result < Self :: Pre , TransactionValidityError > {
473+ Ok ( ( ) )
474+ }
475+ }
385476}
0 commit comments