@@ -340,6 +340,10 @@ pub mod pallet {
340
340
#[ pallet:: getter( fn block_hash) ]
341
341
pub ( super ) type BlockHash < T : Config > = StorageMap < _ , Twox64Concat , U256 , H256 , ValueQuery > ;
342
342
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
+
343
347
#[ pallet:: genesis_config]
344
348
#[ derive( Default ) ]
345
349
pub struct GenesisConfig { }
@@ -647,6 +651,69 @@ impl<T: Config> Pallet<T> {
647
651
} )
648
652
}
649
653
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
+
650
717
/// Get current block hash
651
718
pub fn current_block_hash ( ) -> Option < H256 > {
652
719
Self :: current_block ( ) . map ( |block| block. header . hash ( ) )
@@ -946,3 +1013,45 @@ impl From<InvalidEvmTransactionError> for InvalidTransactionWrapper {
946
1013
}
947
1014
}
948
1015
}
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