18
18
19
19
mod aux_schema;
20
20
21
- pub use crate :: aux_schema:: { load_block_hash, load_transaction_metadata} ;
21
+ pub use crate :: aux_schema:: { load_block_hash, load_transaction_metadata, load_logs } ;
22
22
23
23
use std:: sync:: Arc ;
24
24
use std:: collections:: HashMap ;
25
25
use std:: marker:: PhantomData ;
26
+ use codec:: Decode ;
26
27
use frontier_consensus_primitives:: { FRONTIER_ENGINE_ID , ConsensusLog } ;
27
- use sc_client_api:: { BlockOf , backend:: AuxStore } ;
28
+ use sc_client_api:: { BlockOf , backend:: AuxStore , StorageProvider , Backend , StateBackend } ;
28
29
use sp_blockchain:: { HeaderBackend , ProvideCache , well_known_cache_keys:: Id as CacheKeyId } ;
29
30
use sp_block_builder:: BlockBuilder as BlockBuilderApi ;
30
- use sp_runtime:: generic:: OpaqueDigestItemId ;
31
- use sp_runtime:: traits:: { Block as BlockT , Header as HeaderT } ;
31
+ use sp_runtime:: generic:: { OpaqueDigestItemId , BlockId } ;
32
+ use sp_runtime:: traits:: { Block as BlockT , Header as HeaderT , BlakeTwo256 , UniqueSaturatedInto , Saturating , One } ;
32
33
use sp_api:: ProvideRuntimeApi ;
34
+ use sp_core:: { H256 , storage:: StorageKey } ;
35
+ use sp_io:: hashing:: twox_128;
33
36
use sp_consensus:: {
34
37
BlockImportParams , Error as ConsensusError , BlockImport ,
35
38
BlockCheckParams , ImportResult ,
36
39
} ;
40
+ use frontier_rpc_primitives:: TransactionStatus ;
37
41
use log:: * ;
38
42
use sc_client_api;
39
43
@@ -57,14 +61,14 @@ impl std::convert::From<Error> for ConsensusError {
57
61
}
58
62
}
59
63
60
- pub struct FrontierBlockImport < B : BlockT , I , C > {
64
+ pub struct FrontierBlockImport < B : BlockT , I , C , BE > {
61
65
inner : I ,
62
66
client : Arc < C > ,
63
67
enabled : bool ,
64
- _marker : PhantomData < B > ,
68
+ _marker : PhantomData < ( B , BE ) > ,
65
69
}
66
70
67
- impl < Block : BlockT , I : Clone + BlockImport < Block > , C > Clone for FrontierBlockImport < Block , I , C > {
71
+ impl < Block : BlockT , I : Clone + BlockImport < Block > , C , BE > Clone for FrontierBlockImport < Block , I , C , BE > {
68
72
fn clone ( & self ) -> Self {
69
73
FrontierBlockImport {
70
74
inner : self . inner . clone ( ) ,
@@ -75,11 +79,13 @@ impl<Block: BlockT, I: Clone + BlockImport<Block>, C> Clone for FrontierBlockImp
75
79
}
76
80
}
77
81
78
- impl < B , I , C > FrontierBlockImport < B , I , C > where
82
+ impl < B , I , C , BE > FrontierBlockImport < B , I , C , BE > where
79
83
B : BlockT ,
84
+ BE : Backend < B > ,
85
+ BE :: State : StateBackend < BlakeTwo256 > ,
80
86
I : BlockImport < B , Transaction = sp_api:: TransactionFor < C , B > > + Send + Sync ,
81
87
I :: Error : Into < ConsensusError > ,
82
- C : ProvideRuntimeApi < B > + Send + Sync + HeaderBackend < B > + AuxStore + ProvideCache < B > + BlockOf ,
88
+ C : ProvideRuntimeApi < B > + Send + Sync + HeaderBackend < B > + AuxStore + ProvideCache < B > + BlockOf + StorageProvider < B , BE > ,
83
89
C :: Api : BlockBuilderApi < B , Error = sp_blockchain:: Error > ,
84
90
{
85
91
pub fn new (
@@ -96,11 +102,13 @@ impl<B, I, C> FrontierBlockImport<B, I, C> where
96
102
}
97
103
}
98
104
99
- impl < B , I , C > BlockImport < B > for FrontierBlockImport < B , I , C > where
105
+ impl < B , I , C , BE > BlockImport < B > for FrontierBlockImport < B , I , C , BE > where
100
106
B : BlockT ,
107
+ BE : Backend < B > ,
108
+ BE :: State : StateBackend < BlakeTwo256 > ,
101
109
I : BlockImport < B , Transaction = sp_api:: TransactionFor < C , B > > + Send + Sync ,
102
110
I :: Error : Into < ConsensusError > ,
103
- C : ProvideRuntimeApi < B > + Send + Sync + HeaderBackend < B > + AuxStore + ProvideCache < B > + BlockOf ,
111
+ C : ProvideRuntimeApi < B > + Send + Sync + HeaderBackend < B > + AuxStore + ProvideCache < B > + BlockOf + StorageProvider < B , BE > ,
104
112
C :: Api : BlockBuilderApi < B , Error = sp_blockchain:: Error > ,
105
113
{
106
114
type Error = ConsensusError ;
@@ -145,6 +153,20 @@ impl<B, I, C> BlockImport<B> for FrontierBlockImport<B, I, C> where
145
153
insert_closure ! ( ) ,
146
154
) ;
147
155
}
156
+
157
+ // Store already processed TransactionStatus by block number.
158
+ if * block. header . number ( ) > One :: one ( ) {
159
+ let number = UniqueSaturatedInto :: < u32 > :: unique_saturated_into (
160
+ block. header . number ( ) . saturating_sub ( One :: one ( ) )
161
+ ) ;
162
+ if let Some ( data) = logs ( client. as_ref ( ) , number) {
163
+ aux_schema:: write_logs (
164
+ number,
165
+ data,
166
+ insert_closure ! ( )
167
+ ) ;
168
+ }
169
+ }
148
170
} ,
149
171
}
150
172
}
@@ -170,3 +192,33 @@ fn find_frontier_log<B: BlockT>(
170
192
171
193
Ok ( frontier_log. ok_or ( Error :: NoPostRuntimeLog ) ?)
172
194
}
195
+
196
+ fn logs < B , BE , C > (
197
+ client : & C ,
198
+ block_number : u32 ,
199
+ ) -> Option < ( H256 , Vec < TransactionStatus > ) > where
200
+ B : BlockT ,
201
+ BE : Backend < B > ,
202
+ BE :: State : StateBackend < BlakeTwo256 > ,
203
+ C : HeaderBackend < B > + StorageProvider < B , BE > ,
204
+ {
205
+ if let Ok ( Some ( header) ) = client. header ( BlockId :: Number ( block_number. into ( ) ) )
206
+ {
207
+ if let Ok ( ConsensusLog :: EndBlock { block_hash, .. } ) = find_frontier_log :: < B > ( & header) {
208
+ if let Ok ( Some ( data) ) = client. storage (
209
+ & BlockId :: Number ( block_number. into ( ) ) ,
210
+ & StorageKey (
211
+ storage_prefix_build ( b"Ethereum" , b"CurrentTransactionStatuses" )
212
+ )
213
+ ) {
214
+ let statuses: Vec < TransactionStatus > = Decode :: decode ( & mut & data. 0 [ ..] ) . unwrap ( ) ;
215
+ return Some ( ( block_hash, statuses) )
216
+ }
217
+ }
218
+ }
219
+ None
220
+ }
221
+
222
+ fn storage_prefix_build ( module : & [ u8 ] , storage : & [ u8 ] ) -> Vec < u8 > {
223
+ [ twox_128 ( module) , twox_128 ( storage) ] . concat ( ) . to_vec ( )
224
+ }
0 commit comments