@@ -16,7 +16,7 @@ use std::thread;
1616
1717use electrs_macros:: trace;
1818
19- use crate :: chain:: { Block , BlockHash } ;
19+ use crate :: chain:: { Block , BlockHash , Txid } ;
2020use crate :: daemon:: Daemon ;
2121use crate :: errors:: * ;
2222use crate :: util:: { spawn_thread, HeaderEntry , SyncChannel } ;
@@ -45,6 +45,8 @@ pub struct BlockEntry {
4545 pub block : Block ,
4646 pub entry : HeaderEntry ,
4747 pub size : u32 ,
48+ /// Pre-computed txids, must always correspond 1:1 with block.txdata
49+ pub txids : Vec < Txid > ,
4850}
4951
5052type SizedBlock = ( Block , u32 ) ;
@@ -106,10 +108,14 @@ fn bitcoind_fetcher(
106108 let block_entries: Vec < BlockEntry > = blocks
107109 . into_iter ( )
108110 . zip ( entries)
109- . map ( |( block, entry) | BlockEntry {
110- entry : entry. clone ( ) , // TODO: remove this clone()
111- size : block. total_size ( ) as u32 ,
112- block,
111+ . map ( |( block, entry) | {
112+ let txids = block. txdata . iter ( ) . map ( |tx| tx. compute_txid ( ) ) . collect ( ) ;
113+ BlockEntry {
114+ entry : entry. clone ( ) , // TODO: remove this clone()
115+ size : block. total_size ( ) as u32 ,
116+ txids,
117+ block,
118+ }
113119 } )
114120 . collect ( ) ;
115121 assert_eq ! ( block_entries. len( ) , entries. len( ) ) ;
@@ -156,7 +162,10 @@ fn blkfiles_fetcher(
156162 let blockhash = block. block_hash ( ) ;
157163 entry_map
158164 . remove ( & blockhash)
159- . map ( |entry| BlockEntry { block, entry, size } )
165+ . map ( |entry| {
166+ let txids = block. txdata . iter ( ) . map ( |tx| tx. compute_txid ( ) ) . collect ( ) ;
167+ BlockEntry { block, entry, size, txids }
168+ } )
160169 . or_else ( || {
161170 trace ! ( "skipping block {}" , blockhash) ;
162171 None
@@ -224,9 +233,14 @@ fn blkfiles_parser(blobs: Fetcher<Vec<u8>>, magic: u32) -> Fetcher<Vec<SizedBloc
224233 Fetcher :: from (
225234 chan. into_receiver ( ) ,
226235 spawn_thread ( "blkfiles_parser" , move || {
236+ let pool = rayon:: ThreadPoolBuilder :: new ( )
237+ . num_threads ( 0 ) // CPU-bound
238+ . thread_name ( |i| format ! ( "parse-blocks-{}" , i) )
239+ . build ( )
240+ . unwrap ( ) ;
227241 blobs. map ( |blob| {
228242 trace ! ( "parsing {} bytes" , blob. len( ) ) ;
229- let blocks = parse_blocks ( blob, magic) . expect ( "failed to parse blk*.dat file" ) ;
243+ let blocks = parse_blocks ( & pool , blob, magic) . expect ( "failed to parse blk*.dat file" ) ;
230244 sender
231245 . send ( blocks)
232246 . expect ( "failed to send blocks from blk*.dat file" ) ;
@@ -236,7 +250,7 @@ fn blkfiles_parser(blobs: Fetcher<Vec<u8>>, magic: u32) -> Fetcher<Vec<SizedBloc
236250}
237251
238252#[ trace]
239- fn parse_blocks ( blob : Vec < u8 > , magic : u32 ) -> Result < Vec < SizedBlock > > {
253+ fn parse_blocks ( pool : & rayon :: ThreadPool , blob : Vec < u8 > , magic : u32 ) -> Result < Vec < SizedBlock > > {
240254 let mut cursor = Cursor :: new ( & blob) ;
241255 let mut slices = vec ! [ ] ;
242256 let max_pos = blob. len ( ) as u64 ;
@@ -273,11 +287,6 @@ fn parse_blocks(blob: Vec<u8>, magic: u32) -> Result<Vec<SizedBlock>> {
273287 cursor. set_position ( end as u64 ) ;
274288 }
275289
276- let pool = rayon:: ThreadPoolBuilder :: new ( )
277- . num_threads ( 0 ) // CPU-bound
278- . thread_name ( |i| format ! ( "parse-blocks-{}" , i) )
279- . build ( )
280- . unwrap ( ) ;
281290 Ok ( pool. install ( || {
282291 slices
283292 . into_par_iter ( )
0 commit comments