@@ -10,8 +10,8 @@ use crate::{
1010} ;
1111use alloy:: { consensus:: Header , primitives:: BlockNumber } ;
1212use signet_cold:: {
13- BlockData , BlockTag , ColdResult , ColdStorage , Confirmed , HeaderSpecifier , ReceiptSpecifier ,
14- SignetEventsSpecifier , TransactionSpecifier , ZenithHeaderSpecifier ,
13+ BlockData , ColdResult , ColdStorage , Confirmed , HeaderSpecifier , ReceiptContext ,
14+ ReceiptSpecifier , SignetEventsSpecifier , TransactionSpecifier , ZenithHeaderSpecifier ,
1515} ;
1616use signet_hot:: {
1717 KeySer , MAX_KEY_SIZE , ValSer ,
@@ -124,116 +124,111 @@ impl MdbxColdBackend {
124124 Ok ( ( ) )
125125 }
126126
127- fn resolve_tag ( & self , tag : BlockTag ) -> Result < Option < BlockNumber > , MdbxColdError > {
128- let key = match tag {
129- BlockTag :: Latest => MetadataKey :: LatestBlock ,
130- BlockTag :: Finalized => MetadataKey :: FinalizedBlock ,
131- BlockTag :: Safe => MetadataKey :: SafeBlock ,
132- BlockTag :: Earliest => MetadataKey :: EarliestBlock ,
133- } ;
134- self . get_metadata ( key)
135- }
136-
137127 fn get_metadata ( & self , key : MetadataKey ) -> Result < Option < BlockNumber > , MdbxColdError > {
138128 let tx = self . env . tx ( ) ?;
139129 Ok ( TableTraverse :: < ColdMetadata , _ > :: exact ( & mut tx. new_cursor :: < ColdMetadata > ( ) ?, & key) ?)
140130 }
141131
142- fn get_block_by_hash (
143- & self ,
144- hash : alloy:: primitives:: B256 ,
145- ) -> Result < Option < BlockNumber > , MdbxColdError > {
132+ fn get_header_inner ( & self , spec : HeaderSpecifier ) -> Result < Option < Header > , MdbxColdError > {
146133 let tx = self . env . tx ( ) ?;
147- Ok ( TableTraverse :: < ColdBlockHashIndex , _ > :: exact (
148- & mut tx. new_cursor :: < ColdBlockHashIndex > ( ) ?,
149- & hash,
134+ let block_num = match spec {
135+ HeaderSpecifier :: Number ( n) => n,
136+ HeaderSpecifier :: Hash ( h) => {
137+ let Some ( n) = TableTraverse :: < ColdBlockHashIndex , _ > :: exact (
138+ & mut tx. new_cursor :: < ColdBlockHashIndex > ( ) ?,
139+ & h,
140+ ) ?
141+ else {
142+ return Ok ( None ) ;
143+ } ;
144+ n
145+ }
146+ } ;
147+ Ok ( TableTraverse :: < ColdHeaders , _ > :: exact (
148+ & mut tx. new_cursor :: < ColdHeaders > ( ) ?,
149+ & block_num,
150150 ) ?)
151151 }
152152
153- fn get_tx_location (
153+ fn get_headers_inner (
154154 & self ,
155- hash : alloy :: primitives :: B256 ,
156- ) -> Result < Option < TxLocation > , MdbxColdError > {
155+ specs : Vec < HeaderSpecifier > ,
156+ ) -> Result < Vec < Option < Header > > , MdbxColdError > {
157157 let tx = self . env . tx ( ) ?;
158- Ok ( TableTraverse :: < ColdTxHashIndex , _ > :: exact (
159- & mut tx. new_cursor :: < ColdTxHashIndex > ( ) ?,
160- & hash,
161- ) ?)
162- }
163-
164- fn resolve_header_spec (
165- & self ,
166- spec : HeaderSpecifier ,
167- ) -> Result < Option < BlockNumber > , MdbxColdError > {
168- match spec {
169- HeaderSpecifier :: Number ( n) => Ok ( Some ( n) ) ,
170- HeaderSpecifier :: Hash ( h) => self . get_block_by_hash ( h) ,
171- HeaderSpecifier :: Tag ( tag) => self . resolve_tag ( tag) ,
172- }
158+ specs
159+ . into_iter ( )
160+ . map ( |spec| {
161+ let block_num = match spec {
162+ HeaderSpecifier :: Number ( n) => Some ( n) ,
163+ HeaderSpecifier :: Hash ( h) => TableTraverse :: < ColdBlockHashIndex , _ > :: exact (
164+ & mut tx. new_cursor :: < ColdBlockHashIndex > ( ) ?,
165+ & h,
166+ ) ?,
167+ } ;
168+ block_num
169+ . map ( |n| {
170+ TableTraverse :: < ColdHeaders , _ > :: exact (
171+ & mut tx. new_cursor :: < ColdHeaders > ( ) ?,
172+ & n,
173+ )
174+ } )
175+ . transpose ( )
176+ . map ( Option :: flatten)
177+ } )
178+ . collect :: < Result < _ , _ > > ( )
179+ . map_err ( Into :: into)
173180 }
174181
175- fn resolve_tx_spec (
182+ fn get_transaction_inner (
176183 & self ,
177184 spec : TransactionSpecifier ,
178- ) -> Result < Option < ( BlockNumber , u64 ) > , MdbxColdError > {
179- match spec {
185+ ) -> Result < Option < Confirmed < TransactionSigned > > , MdbxColdError > {
186+ let tx = self . env . tx ( ) ?;
187+ let ( block, index) = match spec {
180188 TransactionSpecifier :: Hash ( h) => {
181- self . get_tx_location ( h) . map ( |opt| opt. map ( |loc| ( loc. block , loc. index ) ) )
189+ let Some ( loc) = TableTraverse :: < ColdTxHashIndex , _ > :: exact (
190+ & mut tx. new_cursor :: < ColdTxHashIndex > ( ) ?,
191+ & h,
192+ ) ?
193+ else {
194+ return Ok ( None ) ;
195+ } ;
196+ ( loc. block , loc. index )
182197 }
183- TransactionSpecifier :: BlockAndIndex { block, index } => Ok ( Some ( ( block, index) ) ) ,
198+ TransactionSpecifier :: BlockAndIndex { block, index } => ( block, index) ,
184199 TransactionSpecifier :: BlockHashAndIndex { block_hash, index } => {
185- self . get_block_by_hash ( block_hash) . map ( |opt| opt. map ( |b| ( b, index) ) )
200+ let Some ( block) = TableTraverse :: < ColdBlockHashIndex , _ > :: exact (
201+ & mut tx. new_cursor :: < ColdBlockHashIndex > ( ) ?,
202+ & block_hash,
203+ ) ?
204+ else {
205+ return Ok ( None ) ;
206+ } ;
207+ ( block, index)
186208 }
187- }
188- }
189-
190- fn resolve_receipt_spec (
191- & self ,
192- spec : ReceiptSpecifier ,
193- ) -> Result < Option < ( BlockNumber , u64 ) > , MdbxColdError > {
194- match spec {
195- ReceiptSpecifier :: TxHash ( h) => {
196- self . get_tx_location ( h) . map ( |opt| opt. map ( |loc| ( loc. block , loc. index ) ) )
197- }
198- ReceiptSpecifier :: BlockAndIndex { block, index } => Ok ( Some ( ( block, index) ) ) ,
199- }
200- }
201-
202- fn get_header_by_number (
203- & self ,
204- block_num : BlockNumber ,
205- ) -> Result < Option < Header > , MdbxColdError > {
206- let tx = self . env . tx ( ) ?;
207- Ok ( TableTraverse :: < ColdHeaders , _ > :: exact (
208- & mut tx. new_cursor :: < ColdHeaders > ( ) ?,
209- & block_num,
210- ) ?)
211- }
212-
213- fn get_transaction_by_location (
214- & self ,
215- block : BlockNumber ,
216- index : u64 ,
217- ) -> Result < Option < TransactionSigned > , MdbxColdError > {
218- let tx = self . env . tx ( ) ?;
219- Ok ( DualTableTraverse :: < ColdTransactions , _ > :: exact_dual (
209+ } ;
210+ let Some ( signed_tx) = DualTableTraverse :: < ColdTransactions , _ > :: exact_dual (
220211 & mut tx. new_cursor :: < ColdTransactions > ( ) ?,
221212 & block,
222213 & index,
223- ) ?)
214+ ) ?
215+ else {
216+ return Ok ( None ) ;
217+ } ;
218+ let Some ( header) =
219+ TableTraverse :: < ColdHeaders , _ > :: exact ( & mut tx. new_cursor :: < ColdHeaders > ( ) ?, & block) ?
220+ else {
221+ return Ok ( None ) ;
222+ } ;
223+ let meta = ConfirmationMeta :: new ( block, header. hash_slow ( ) , index) ;
224+ Ok ( Some ( Confirmed :: new ( signed_tx, meta) ) )
224225 }
225226
226- fn get_receipt_by_location (
227+ fn get_receipt_inner (
227228 & self ,
228- block : BlockNumber ,
229- index : u64 ,
230- ) -> Result < Option < Receipt > , MdbxColdError > {
231- let tx = self . env . tx ( ) ?;
232- Ok ( DualTableTraverse :: < ColdReceipts , _ > :: exact_dual (
233- & mut tx. new_cursor :: < ColdReceipts > ( ) ?,
234- & block,
235- & index,
236- ) ?)
229+ spec : ReceiptSpecifier ,
230+ ) -> Result < Option < Confirmed < Receipt > > , MdbxColdError > {
231+ Ok ( self . get_receipt_with_context_inner ( spec) ?. map ( |ctx| ctx. receipt ) )
237232 }
238233
239234 fn get_zenith_header_by_number (
@@ -374,15 +369,6 @@ impl MdbxColdBackend {
374369 & current_latest. map_or ( block, |prev| prev. max ( block) ) ,
375370 ) ?;
376371
377- let current_earliest: Option < BlockNumber > = TableTraverse :: < ColdMetadata , _ > :: exact (
378- & mut tx. new_cursor :: < ColdMetadata > ( ) ?,
379- & MetadataKey :: EarliestBlock ,
380- ) ?;
381- tx. queue_put :: < ColdMetadata > (
382- & MetadataKey :: EarliestBlock ,
383- & current_earliest. map_or ( block, |prev| prev. min ( block) ) ,
384- ) ?;
385-
386372 tx. raw_commit ( ) ?;
387373 Ok ( ( ) )
388374 }
@@ -453,44 +439,81 @@ impl MdbxColdBackend {
453439 tx. raw_commit ( ) ?;
454440 Ok ( ( ) )
455441 }
442+
443+ fn get_receipt_with_context_inner (
444+ & self ,
445+ spec : ReceiptSpecifier ,
446+ ) -> Result < Option < ReceiptContext > , MdbxColdError > {
447+ let tx = self . env . tx ( ) ?;
448+ let ( block, index) = match spec {
449+ ReceiptSpecifier :: TxHash ( h) => {
450+ let Some ( loc) = TableTraverse :: < ColdTxHashIndex , _ > :: exact (
451+ & mut tx. new_cursor :: < ColdTxHashIndex > ( ) ?,
452+ & h,
453+ ) ?
454+ else {
455+ return Ok ( None ) ;
456+ } ;
457+ ( loc. block , loc. index )
458+ }
459+ ReceiptSpecifier :: BlockAndIndex { block, index } => ( block, index) ,
460+ } ;
461+ let Some ( header) =
462+ TableTraverse :: < ColdHeaders , _ > :: exact ( & mut tx. new_cursor :: < ColdHeaders > ( ) ?, & block) ?
463+ else {
464+ return Ok ( None ) ;
465+ } ;
466+ let Some ( receipt) = DualTableTraverse :: < ColdReceipts , _ > :: exact_dual (
467+ & mut tx. new_cursor :: < ColdReceipts > ( ) ?,
468+ & block,
469+ & index,
470+ ) ?
471+ else {
472+ return Ok ( None ) ;
473+ } ;
474+ let Some ( transaction) = DualTableTraverse :: < ColdTransactions , _ > :: exact_dual (
475+ & mut tx. new_cursor :: < ColdTransactions > ( ) ?,
476+ & block,
477+ & index,
478+ ) ?
479+ else {
480+ return Ok ( None ) ;
481+ } ;
482+
483+ let prior_cumulative_gas = index
484+ . checked_sub ( 1 )
485+ . map ( |prev| {
486+ DualTableTraverse :: < ColdReceipts , _ > :: exact_dual (
487+ & mut tx. new_cursor :: < ColdReceipts > ( ) ?,
488+ & block,
489+ & prev,
490+ )
491+ } )
492+ . transpose ( ) ?
493+ . flatten ( )
494+ . map ( |r : Receipt | r. inner . cumulative_gas_used )
495+ . unwrap_or ( 0 ) ;
496+
497+ let meta = ConfirmationMeta :: new ( block, header. hash_slow ( ) , index) ;
498+ let confirmed_receipt = Confirmed :: new ( receipt, meta) ;
499+ Ok ( Some ( ReceiptContext :: new ( header, transaction, confirmed_receipt, prior_cumulative_gas) ) )
500+ }
456501}
457502
458503impl ColdStorage for MdbxColdBackend {
459504 async fn get_header ( & self , spec : HeaderSpecifier ) -> ColdResult < Option < Header > > {
460- let Some ( block_num) = self . resolve_header_spec ( spec) ? else {
461- return Ok ( None ) ;
462- } ;
463- Ok ( self . get_header_by_number ( block_num) ?)
505+ Ok ( self . get_header_inner ( spec) ?)
464506 }
465507
466508 async fn get_headers ( & self , specs : Vec < HeaderSpecifier > ) -> ColdResult < Vec < Option < Header > > > {
467- specs
468- . into_iter ( )
469- . map ( |spec| {
470- self . resolve_header_spec ( spec) ?
471- . map ( |n| self . get_header_by_number ( n) )
472- . transpose ( )
473- . map ( Option :: flatten)
474- } )
475- . collect :: < Result < _ , MdbxColdError > > ( )
476- . map_err ( Into :: into)
509+ Ok ( self . get_headers_inner ( specs) ?)
477510 }
478511
479512 async fn get_transaction (
480513 & self ,
481514 spec : TransactionSpecifier ,
482515 ) -> ColdResult < Option < Confirmed < TransactionSigned > > > {
483- let Some ( ( block, index) ) = self . resolve_tx_spec ( spec) ? else {
484- return Ok ( None ) ;
485- } ;
486- let Some ( tx) = self . get_transaction_by_location ( block, index) ? else {
487- return Ok ( None ) ;
488- } ;
489- let Some ( header) = self . get_header_by_number ( block) ? else {
490- return Ok ( None ) ;
491- } ;
492- let meta = ConfirmationMeta :: new ( block, header. hash_slow ( ) , index) ;
493- Ok ( Some ( Confirmed :: new ( tx, meta) ) )
516+ Ok ( self . get_transaction_inner ( spec) ?)
494517 }
495518
496519 async fn get_transactions_in_block (
@@ -505,17 +528,7 @@ impl ColdStorage for MdbxColdBackend {
505528 }
506529
507530 async fn get_receipt ( & self , spec : ReceiptSpecifier ) -> ColdResult < Option < Confirmed < Receipt > > > {
508- let Some ( ( block, index) ) = self . resolve_receipt_spec ( spec) ? else {
509- return Ok ( None ) ;
510- } ;
511- let Some ( receipt) = self . get_receipt_by_location ( block, index) ? else {
512- return Ok ( None ) ;
513- } ;
514- let Some ( header) = self . get_header_by_number ( block) ? else {
515- return Ok ( None ) ;
516- } ;
517- let meta = ConfirmationMeta :: new ( block, header. hash_slow ( ) , index) ;
518- Ok ( Some ( Confirmed :: new ( receipt, meta) ) )
531+ Ok ( self . get_receipt_inner ( spec) ?)
519532 }
520533
521534 async fn get_receipts_in_block ( & self , block : BlockNumber ) -> ColdResult < Vec < Receipt > > {
@@ -565,6 +578,13 @@ impl ColdStorage for MdbxColdBackend {
565578 Ok ( self . get_metadata ( MetadataKey :: LatestBlock ) ?)
566579 }
567580
581+ async fn get_receipt_with_context (
582+ & self ,
583+ spec : ReceiptSpecifier ,
584+ ) -> ColdResult < Option < ReceiptContext > > {
585+ Ok ( self . get_receipt_with_context_inner ( spec) ?)
586+ }
587+
568588 async fn append_block ( & self , data : BlockData ) -> ColdResult < ( ) > {
569589 Ok ( self . append_block_inner ( data) ?)
570590 }
0 commit comments