@@ -340,6 +340,10 @@ pub mod pallet {
340340 #[ pallet:: getter( fn block_hash) ]
341341 pub ( super ) type BlockHash < T : Config > = StorageMap < _ , Twox64Concat , U256 , H256 , ValueQuery > ;
342342
343+ /// Injected transactions should have unique nonce, here we store current
344+ #[ pallet:: storage]
345+ pub ( super ) type InjectedNonce < T : Config > = StorageValue < _ , U256 , ValueQuery > ;
346+
343347 #[ pallet:: genesis_config]
344348 #[ derive( Default ) ]
345349 pub struct GenesisConfig { }
@@ -647,6 +651,69 @@ impl<T: Config> Pallet<T> {
647651 } )
648652 }
649653
654+ pub fn flush_injected_transaction ( ) {
655+ use ethereum:: {
656+ EIP658ReceiptData , EnvelopedEncodable , TransactionSignature , TransactionV0 ,
657+ } ;
658+
659+ assert ! (
660+ fp_consensus:: find_pre_log( & frame_system:: Pallet :: <T >:: digest( ) ) . is_err( ) ,
661+ "this method is supposed to be called only from other pallets" ,
662+ ) ;
663+
664+ let logs = <CurrentLogs < T > >:: take ( ) ;
665+ if logs. is_empty ( ) {
666+ return ;
667+ }
668+
669+ let nonce = <InjectedNonce < T > >:: get ( )
670+ . checked_add ( 1u32 . into ( ) )
671+ . expect ( "u256 should be enough" ) ;
672+ <InjectedNonce < T > >:: set ( nonce) ;
673+
674+ let transaction = Transaction :: Legacy ( TransactionV0 {
675+ nonce,
676+ gas_price : 0 . into ( ) ,
677+ gas_limit : 0 . into ( ) ,
678+ action : TransactionAction :: Call ( H160 ( [ 0 ; 20 ] ) ) ,
679+ value : 0 . into ( ) ,
680+ // zero selector, this transaction always has same sender, so all data should be acquired from logs
681+ input : Vec :: from ( [ 0 , 0 , 0 , 0 ] ) ,
682+ // if v is not 27 - then we need to pass some other validity checks
683+ signature : TransactionSignature :: new ( 27 , H256 ( [ 0x88 ; 32 ] ) , H256 ( [ 0x88 ; 32 ] ) ) . unwrap ( ) ,
684+ } ) ;
685+
686+ let transaction_hash = H256 :: from_slice (
687+ sp_io:: hashing:: keccak_256 ( & EnvelopedEncodable :: encode ( & transaction) ) . as_slice ( ) ,
688+ ) ;
689+ let transaction_index = <Pending < T > >:: get ( ) . len ( ) as u32 ;
690+
691+ let logs_bloom = {
692+ let mut bloom: Bloom = Bloom :: default ( ) ;
693+ Self :: logs_bloom ( & logs, & mut bloom) ;
694+ bloom
695+ } ;
696+
697+ let status = TransactionStatus {
698+ transaction_hash,
699+ transaction_index,
700+ from : H160 :: default ( ) ,
701+ to : None ,
702+ contract_address : None ,
703+ logs_bloom,
704+ logs : logs. clone ( ) ,
705+ } ;
706+
707+ let receipt = Receipt :: Legacy ( EIP658ReceiptData {
708+ status_code : 1 ,
709+ used_gas : 0u32 . into ( ) ,
710+ logs_bloom,
711+ logs,
712+ } ) ;
713+
714+ <Pending < T > >:: append ( ( transaction, status, receipt) ) ;
715+ }
716+
650717 /// Get current block hash
651718 pub fn current_block_hash ( ) -> Option < H256 > {
652719 Self :: current_block ( ) . map ( |block| block. header . hash ( ) )
@@ -946,3 +1013,45 @@ impl From<InvalidEvmTransactionError> for InvalidTransactionWrapper {
9461013 }
9471014 }
9481015}
1016+
1017+ #[ derive( TypeInfo , PartialEq , Eq , Clone , Debug , Encode , Decode ) ]
1018+ pub struct FakeTransactionFinalizer < T > ( PhantomData < T > ) ;
1019+
1020+ impl < T : Config + TypeInfo + core:: fmt:: Debug + Send + Sync > sp_runtime:: traits:: SignedExtension
1021+ for FakeTransactionFinalizer < T >
1022+ {
1023+ const IDENTIFIER : & ' static str = "FakeTransactionFinalizer" ;
1024+
1025+ type AccountId = T :: AccountId ;
1026+
1027+ type Call = T :: RuntimeCall ;
1028+
1029+ type AdditionalSigned = ( ) ;
1030+
1031+ type Pre = ( ) ;
1032+
1033+ fn additional_signed ( & self ) -> Result < Self :: AdditionalSigned , TransactionValidityError > {
1034+ Ok ( ( ) )
1035+ }
1036+
1037+ fn pre_dispatch (
1038+ self ,
1039+ _who : & Self :: AccountId ,
1040+ _call : & Self :: Call ,
1041+ _info : & DispatchInfoOf < Self :: Call > ,
1042+ _len : usize ,
1043+ ) -> Result < Self :: Pre , TransactionValidityError > {
1044+ Ok ( ( ) )
1045+ }
1046+
1047+ fn post_dispatch (
1048+ _pre : Option < Self :: Pre > ,
1049+ _info : & DispatchInfoOf < Self :: Call > ,
1050+ _post_info : & sp_runtime:: traits:: PostDispatchInfoOf < Self :: Call > ,
1051+ _len : usize ,
1052+ _result : & sp_runtime:: DispatchResult ,
1053+ ) -> Result < ( ) , TransactionValidityError > {
1054+ <Pallet < T > >:: flush_injected_transaction ( ) ;
1055+ Ok ( ( ) )
1056+ }
1057+ }
0 commit comments