@@ -13,6 +13,13 @@ use lightning::{log_debug, log_error, log_trace};
13
13
use bitcoin:: block:: Header ;
14
14
use bitcoin:: { BlockHash , Script , Transaction , Txid } ;
15
15
16
+ use bitcoin:: hashes:: Hash as BitcoinHash ;
17
+ use electrum_client:: bitcoin:: hashes:: Hash as ElectrumHash ;
18
+
19
+ use bitcoin:: consensus:: { Decodable as BitcoinDecodable , Encodable as BitcoinEncodable } ;
20
+ use electrum_client:: bitcoin:: consensus:: {
21
+ Decodable as ElectrumDecodable , Encodable as ElectrumEncodable ,
22
+ } ;
16
23
use std:: collections:: HashSet ;
17
24
use std:: ops:: Deref ;
18
25
use std:: sync:: Mutex ;
@@ -92,12 +99,15 @@ where
92
99
while let Some ( _) = self . client . block_headers_pop ( ) ? { }
93
100
94
101
let tip_notification = self . client . block_headers_subscribe ( ) ?;
95
- let mut tip_header = tip_notification. header ;
102
+ let tip_header = tip_notification. header ;
96
103
let mut tip_height = tip_notification. height as u32 ;
97
104
98
105
loop {
99
106
let pending_registrations = self . queue . lock ( ) . unwrap ( ) . process_queues ( & mut sync_state) ;
100
- let tip_is_new = Some ( tip_header. block_hash ( ) ) != sync_state. last_sync_hash ;
107
+ let tip_is_new = Some ( tip_header. block_hash ( ) )
108
+ != sync_state
109
+ . last_sync_hash
110
+ . map ( |h| electrum_client:: bitcoin:: BlockHash :: from_slice ( h. as_ref ( ) ) . unwrap ( ) ) ;
101
111
102
112
// We loop until any registered transactions have been processed at least once, or the
103
113
// tip hasn't been updated during the last iteration.
@@ -112,7 +122,18 @@ where
112
122
Ok ( unconfirmed_txs) => {
113
123
// Double-check the tip hash. If it changed, a reorg happened since
114
124
// we started syncing and we need to restart last-minute.
115
- match self . check_update_tip ( & mut tip_header, & mut tip_height) {
125
+
126
+ let mut header_buffer = Vec :: new ( ) ;
127
+ tip_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
128
+ let mut header_slice = & header_buffer[ ..] ;
129
+ let header_reader =
130
+ & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new (
131
+ & mut header_slice,
132
+ ) ;
133
+ let mut bitcoin_header =
134
+ bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
135
+
136
+ match self . check_update_tip ( & mut bitcoin_header, & mut tip_height) {
116
137
Ok ( false ) => {
117
138
num_unconfirmed += unconfirmed_txs. len ( ) ;
118
139
sync_state. sync_unconfirmed_transactions (
@@ -150,9 +171,17 @@ where
150
171
} ,
151
172
}
152
173
174
+ let mut header_buffer = Vec :: new ( ) ;
175
+ tip_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
176
+ let mut header_slice = & header_buffer[ ..] ;
177
+ let header_reader =
178
+ & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut header_slice) ;
179
+ let bitcoin_header =
180
+ bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
181
+
153
182
// Update the best block.
154
183
for c in & confirmables {
155
- c. best_block_updated ( & tip_header , tip_height) ;
184
+ c. best_block_updated ( & bitcoin_header , tip_height) ;
156
185
}
157
186
158
187
// Prune any sufficiently confirmed output spends
@@ -161,9 +190,17 @@ where
161
190
162
191
match self . get_confirmed_transactions ( & sync_state) {
163
192
Ok ( confirmed_txs) => {
193
+ let mut header_buffer = Vec :: new ( ) ;
194
+ tip_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
195
+ let mut header_slice = & header_buffer[ ..] ;
196
+ let header_reader =
197
+ & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut header_slice) ;
198
+ let mut bitcoin_header =
199
+ bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
200
+
164
201
// Double-check the tip hash. If it changed, a reorg happened since
165
202
// we started syncing and we need to restart last-minute.
166
- match self . check_update_tip ( & mut tip_header , & mut tip_height) {
203
+ match self . check_update_tip ( & mut bitcoin_header , & mut tip_height) {
167
204
Ok ( false ) => {
168
205
num_confirmed += confirmed_txs. len ( ) ;
169
206
sync_state
@@ -207,7 +244,8 @@ where
207
244
return Err ( TxSyncError :: from ( err) ) ;
208
245
} ,
209
246
}
210
- sync_state. last_sync_hash = Some ( tip_header. block_hash ( ) ) ;
247
+ sync_state. last_sync_hash =
248
+ Some ( bitcoin:: BlockHash :: from_slice ( tip_header. block_hash ( ) . as_ref ( ) ) . unwrap ( ) ) ;
211
249
sync_state. pending_sync = false ;
212
250
}
213
251
}
@@ -240,15 +278,26 @@ where
240
278
// Restart if either the tip changed or we got some divergent tip
241
279
// change notification since we started. In the latter case we
242
280
// make sure we clear the queue before continuing.
243
- let mut restart_sync = check_tip_hash != cur_tip_header. block_hash ( ) ;
281
+ let mut restart_sync = check_tip_hash
282
+ != electrum_client:: bitcoin:: BlockHash :: from_slice (
283
+ cur_tip_header. block_hash ( ) . as_ref ( ) ,
284
+ )
285
+ . unwrap ( ) ;
244
286
while let Some ( queued_notif) = self . client . block_headers_pop ( ) ? {
245
287
if queued_notif. header . block_hash ( ) != check_tip_hash {
246
288
restart_sync = true
247
289
}
248
290
}
249
291
250
292
if restart_sync {
251
- * cur_tip_header = check_notification. header ;
293
+ let mut header_buffer = Vec :: new ( ) ;
294
+ check_notification. header . consensus_encode ( & mut header_buffer) . unwrap ( ) ;
295
+ let mut header_slice = & header_buffer[ ..] ;
296
+ let header_reader =
297
+ & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut header_slice) ;
298
+ let bitcoin_header = bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
299
+
300
+ * cur_tip_header = bitcoin_header;
252
301
* cur_tip_height = check_notification. height as u32 ;
253
302
Ok ( true )
254
303
} else {
@@ -268,7 +317,9 @@ where
268
317
let mut watched_txs = Vec :: with_capacity ( sync_state. watched_transactions . len ( ) ) ;
269
318
270
319
for txid in & sync_state. watched_transactions {
271
- match self . client . transaction_get ( & txid) {
320
+ match self . client . transaction_get (
321
+ & electrum_client:: bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) ,
322
+ ) {
272
323
Ok ( tx) => {
273
324
// Bitcoin Core's Merkle tree implementation has no way to discern between
274
325
// internal and leaf node entries. As a consequence it is susceptible to an
@@ -308,7 +359,9 @@ where
308
359
debug_assert_eq ! ( num_tx_lookups, watched_txs. len( ) ) ;
309
360
310
361
for output in sync_state. watched_outputs . values ( ) {
311
- watched_script_pubkeys. push ( output. script_pubkey . clone ( ) ) ;
362
+ watched_script_pubkeys. push ( electrum_client:: bitcoin:: ScriptBuf :: from_bytes (
363
+ output. script_pubkey . to_bytes ( ) ,
364
+ ) ) ;
312
365
}
313
366
314
367
let num_output_spend_lookups = watched_script_pubkeys. len ( ) - num_tx_lookups;
@@ -325,11 +378,22 @@ where
325
378
if confirmed_txs. iter ( ) . any ( |ctx| ctx. txid == * * txid) {
326
379
continue ;
327
380
}
328
- let mut filtered_history =
329
- script_history. iter ( ) . filter ( |h| h. tx_hash == * * txid) ;
381
+ let mut filtered_history = script_history. iter ( ) . filter ( |h| {
382
+ h. tx_hash
383
+ == electrum_client:: bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( )
384
+ } ) ;
330
385
if let Some ( history) = filtered_history. next ( ) {
386
+ let mut tx_buffer = Vec :: new ( ) ;
387
+ tx. consensus_encode ( & mut tx_buffer) . unwrap ( ) ;
388
+ let mut tx_slice = & tx_buffer[ ..] ;
389
+ let tx_reader =
390
+ & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut tx_slice) ;
391
+ let bitcoin_transaction =
392
+ bitcoin:: Transaction :: consensus_decode ( tx_reader) . unwrap ( ) ;
393
+
331
394
let prob_conf_height = history. height as u32 ;
332
- let confirmed_tx = self . get_confirmed_tx ( tx, prob_conf_height) ?;
395
+ let confirmed_tx =
396
+ self . get_confirmed_tx ( & bitcoin_transaction, prob_conf_height) ?;
333
397
confirmed_txs. push ( confirmed_tx) ;
334
398
}
335
399
debug_assert ! ( filtered_history. next( ) . is_none( ) ) ;
@@ -344,7 +408,9 @@ where
344
408
}
345
409
346
410
let txid = possible_output_spend. tx_hash ;
347
- if confirmed_txs. iter ( ) . any ( |ctx| ctx. txid == txid) {
411
+ if confirmed_txs. iter ( ) . any ( |ctx| {
412
+ ctx. txid == bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( )
413
+ } ) {
348
414
continue ;
349
415
}
350
416
@@ -354,7 +420,19 @@ where
354
420
for txin in & tx. input {
355
421
let watched_outpoint =
356
422
watched_output. outpoint . into_bitcoin_outpoint ( ) ;
357
- if txin. previous_output == watched_outpoint {
423
+
424
+ let mut outpoint_buffer = Vec :: new ( ) ;
425
+ watched_outpoint
426
+ . consensus_encode ( & mut outpoint_buffer)
427
+ . unwrap ( ) ;
428
+ let mut outpoint_slice = & outpoint_buffer[ ..] ;
429
+ let esplora_outpoint =
430
+ electrum_client:: bitcoin:: OutPoint :: consensus_decode (
431
+ & mut outpoint_slice,
432
+ )
433
+ . unwrap ( ) ;
434
+
435
+ if txin. previous_output == esplora_outpoint {
358
436
is_spend = true ;
359
437
break ;
360
438
}
@@ -365,7 +443,19 @@ where
365
443
}
366
444
367
445
let prob_conf_height = possible_output_spend. height as u32 ;
368
- let confirmed_tx = self . get_confirmed_tx ( & tx, prob_conf_height) ?;
446
+
447
+ let mut tx_buffer = Vec :: new ( ) ;
448
+ tx. consensus_encode ( & mut tx_buffer) . unwrap ( ) ;
449
+ let mut tx_slice = & tx_buffer[ ..] ;
450
+ let tx_reader =
451
+ & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new (
452
+ & mut tx_slice,
453
+ ) ;
454
+ let bitcoin_transaction =
455
+ bitcoin:: Transaction :: consensus_decode ( tx_reader) . unwrap ( ) ;
456
+
457
+ let confirmed_tx =
458
+ self . get_confirmed_tx ( & bitcoin_transaction, prob_conf_height) ?;
369
459
confirmed_txs. push ( confirmed_tx) ;
370
460
} ,
371
461
Err ( e) => {
@@ -414,7 +504,9 @@ where
414
504
for ( txid, conf_height, block_hash_opt) in relevant_txids {
415
505
if let Some ( block_hash) = block_hash_opt {
416
506
let block_header = self . client . block_header ( conf_height as usize ) ?;
417
- if block_header. block_hash ( ) == block_hash {
507
+ if block_header. block_hash ( )
508
+ == electrum_client:: bitcoin:: BlockHash :: from_slice ( block_hash. as_ref ( ) ) . unwrap ( )
509
+ {
418
510
// Skip if the tx is still confirmed in the block in question.
419
511
continue ;
420
512
}
@@ -432,25 +524,41 @@ where
432
524
fn get_confirmed_tx (
433
525
& self , tx : & Transaction , prob_conf_height : u32 ,
434
526
) -> Result < ConfirmedTx , InternalError > {
435
- let txid = tx. txid ( ) ;
436
- match self . client . transaction_get_merkle ( & txid, prob_conf_height as usize ) {
527
+ let txid = tx. compute_txid ( ) ;
528
+ match self . client . transaction_get_merkle (
529
+ & electrum_client:: bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) ,
530
+ prob_conf_height as usize ,
531
+ ) {
437
532
Ok ( merkle_res) => {
438
533
debug_assert_eq ! ( prob_conf_height, merkle_res. block_height as u32 ) ;
439
534
match self . client . block_header ( prob_conf_height as usize ) {
440
535
Ok ( block_header) => {
441
536
let pos = merkle_res. pos ;
442
- if !validate_merkle_proof ( & txid, & block_header. merkle_root , & merkle_res) {
537
+ if !validate_merkle_proof (
538
+ & electrum_client:: bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) ,
539
+ & block_header. merkle_root ,
540
+ & merkle_res,
541
+ ) {
443
542
log_trace ! (
444
543
self . logger,
445
544
"Inconsistency: Block {} was unconfirmed during syncing." ,
446
545
block_header. block_hash( )
447
546
) ;
448
547
return Err ( InternalError :: Inconsistency ) ;
449
548
}
549
+
550
+ let mut header_buffer = Vec :: new ( ) ;
551
+ block_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
552
+ let mut header_slice = & header_buffer[ ..] ;
553
+ let header_reader =
554
+ & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut header_slice) ;
555
+ let bitcoin_header =
556
+ bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
557
+
450
558
let confirmed_tx = ConfirmedTx {
451
559
tx : tx. clone ( ) ,
452
560
txid,
453
- block_header,
561
+ block_header : bitcoin_header ,
454
562
block_height : prob_conf_height,
455
563
pos,
456
564
} ;
0 commit comments