@@ -660,3 +660,72 @@ fn mark_decryption_failed_removes_submission_and_emits_event() {
660660 assert_noop ! ( res, pallet_mev_shield:: Error :: <Test >:: MissingSubmission ) ;
661661 } ) ;
662662}
663+
664+ #[ test]
665+ fn announce_next_key_charges_then_refunds_fee ( ) {
666+ new_test_ext ( ) . execute_with ( || {
667+ const KYBER_PK_LEN : usize = 1184 ;
668+
669+ // ---------------------------------------------------------------------
670+ // 1. Seed Aura authorities with a single validator and derive account.
671+ // ---------------------------------------------------------------------
672+ let validator_pair = test_sr25519_pair ( ) ;
673+ let validator_account: AccountId32 = validator_pair. public ( ) . into ( ) ;
674+ let validator_aura_id: <Test as pallet_aura:: Config >:: AuthorityId =
675+ validator_pair. public ( ) . into ( ) ;
676+
677+ let authorities: BoundedVec <
678+ <Test as pallet_aura:: Config >:: AuthorityId ,
679+ <Test as pallet_aura:: Config >:: MaxAuthorities ,
680+ > = BoundedVec :: truncate_from ( vec ! [ validator_aura_id] ) ;
681+ pallet_aura:: Authorities :: < Test > :: put ( authorities) ;
682+
683+ // ---------------------------------------------------------------------
684+ // 2. Build a valid Kyber public key and the corresponding RuntimeCall.
685+ // ---------------------------------------------------------------------
686+ let pk_bytes = vec ! [ 42u8 ; KYBER_PK_LEN ] ;
687+ let bounded_pk: BoundedVec < u8 , FrameConstU32 < 2048 > > =
688+ BoundedVec :: truncate_from ( pk_bytes. clone ( ) ) ;
689+
690+ let runtime_call = RuntimeCall :: MevShield ( MevShieldCall :: < Test > :: announce_next_key {
691+ public_key : bounded_pk. clone ( ) ,
692+ } ) ;
693+
694+ // ---------------------------------------------------------------------
695+ // 3. Pre-dispatch: DispatchInfo must say Pays::Yes.
696+ // ---------------------------------------------------------------------
697+ let pre_info = <RuntimeCall as frame_support:: dispatch:: GetDispatchInfo >:: get_dispatch_info (
698+ & runtime_call,
699+ ) ;
700+
701+ assert_eq ! (
702+ pre_info. pays_fee,
703+ frame_support:: dispatch:: Pays :: Yes ,
704+ "announce_next_key must be declared as fee-paying at pre-dispatch"
705+ ) ;
706+
707+ // ---------------------------------------------------------------------
708+ // 4. Dispatch via the pallet function.
709+ // ---------------------------------------------------------------------
710+ let post = MevShield :: announce_next_key (
711+ RuntimeOrigin :: signed ( validator_account. clone ( ) ) ,
712+ bounded_pk. clone ( ) ,
713+ )
714+ . expect ( "announce_next_key should succeed for an Aura validator" ) ;
715+
716+ // Post-dispatch info should switch pays_fee from Yes -> No (refund).
717+ assert_eq ! (
718+ post. pays_fee,
719+ frame_support:: dispatch:: Pays :: No ,
720+ "announce_next_key must refund the previously chargeable fee"
721+ ) ;
722+
723+ // And we don't override the actual weight (None => use pre-dispatch weight).
724+ assert ! (
725+ post. actual_weight. is_none( ) ,
726+ "announce_next_key should not override actual_weight in PostDispatchInfo"
727+ ) ;
728+ let next = NextKey :: < Test > :: get ( ) . expect ( "NextKey should be set by announce_next_key" ) ;
729+ assert_eq ! ( next, pk_bytes) ;
730+ } ) ;
731+ }
0 commit comments