@@ -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,16 @@ 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 :: < _ > :: new ( & mut header_slice) ;
131
+ let mut bitcoin_header =
132
+ bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
133
+
134
+ match self . check_update_tip ( & mut bitcoin_header, & mut tip_height) {
116
135
Ok ( false ) => {
117
136
num_unconfirmed += unconfirmed_txs. len ( ) ;
118
137
sync_state. sync_unconfirmed_transactions (
@@ -150,9 +169,17 @@ where
150
169
} ,
151
170
}
152
171
172
+ let mut header_buffer = Vec :: new ( ) ;
173
+ tip_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
174
+ let mut header_slice = & header_buffer[ ..] ;
175
+ let header_reader =
176
+ & mut lightning:: util:: ser:: BufReader :: < _ > :: new ( & mut header_slice) ;
177
+ let bitcoin_header =
178
+ bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
179
+
153
180
// Update the best block.
154
181
for c in & confirmables {
155
- c. best_block_updated ( & tip_header , tip_height) ;
182
+ c. best_block_updated ( & bitcoin_header , tip_height) ;
156
183
}
157
184
158
185
// Prune any sufficiently confirmed output spends
@@ -161,9 +188,17 @@ where
161
188
162
189
match self . get_confirmed_transactions ( & sync_state) {
163
190
Ok ( confirmed_txs) => {
191
+ let mut header_buffer = Vec :: new ( ) ;
192
+ tip_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
193
+ let mut header_slice = & header_buffer[ ..] ;
194
+ let header_reader =
195
+ & mut lightning:: util:: ser:: BufReader :: < _ > :: new ( & mut header_slice) ;
196
+ let mut bitcoin_header =
197
+ bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
198
+
164
199
// Double-check the tip hash. If it changed, a reorg happened since
165
200
// we started syncing and we need to restart last-minute.
166
- match self . check_update_tip ( & mut tip_header , & mut tip_height) {
201
+ match self . check_update_tip ( & mut bitcoin_header , & mut tip_height) {
167
202
Ok ( false ) => {
168
203
num_confirmed += confirmed_txs. len ( ) ;
169
204
sync_state
@@ -207,7 +242,8 @@ where
207
242
return Err ( TxSyncError :: from ( err) ) ;
208
243
} ,
209
244
}
210
- sync_state. last_sync_hash = Some ( tip_header. block_hash ( ) ) ;
245
+ sync_state. last_sync_hash =
246
+ Some ( bitcoin:: BlockHash :: from_slice ( tip_header. block_hash ( ) . as_ref ( ) ) . unwrap ( ) ) ;
211
247
sync_state. pending_sync = false ;
212
248
}
213
249
}
@@ -240,15 +276,25 @@ where
240
276
// Restart if either the tip changed or we got some divergent tip
241
277
// change notification since we started. In the latter case we
242
278
// make sure we clear the queue before continuing.
243
- let mut restart_sync = check_tip_hash != cur_tip_header. block_hash ( ) ;
279
+ let mut restart_sync = check_tip_hash
280
+ != electrum_client:: bitcoin:: BlockHash :: from_slice (
281
+ cur_tip_header. block_hash ( ) . as_ref ( ) ,
282
+ )
283
+ . unwrap ( ) ;
244
284
while let Some ( queued_notif) = self . client . block_headers_pop ( ) ? {
245
285
if queued_notif. header . block_hash ( ) != check_tip_hash {
246
286
restart_sync = true
247
287
}
248
288
}
249
289
250
290
if restart_sync {
251
- * cur_tip_header = check_notification. header ;
291
+ let mut header_buffer = Vec :: new ( ) ;
292
+ check_notification. header . consensus_encode ( & mut header_buffer) . unwrap ( ) ;
293
+ let mut header_slice = & header_buffer[ ..] ;
294
+ let header_reader = & mut lightning:: util:: ser:: BufReader :: < _ > :: new ( & mut header_slice) ;
295
+ let bitcoin_header = bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
296
+
297
+ * cur_tip_header = bitcoin_header;
252
298
* cur_tip_height = check_notification. height as u32 ;
253
299
Ok ( true )
254
300
} else {
@@ -268,7 +314,9 @@ where
268
314
let mut watched_txs = Vec :: with_capacity ( sync_state. watched_transactions . len ( ) ) ;
269
315
270
316
for txid in & sync_state. watched_transactions {
271
- match self . client . transaction_get ( & txid) {
317
+ match self . client . transaction_get (
318
+ & electrum_client:: bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) ,
319
+ ) {
272
320
Ok ( tx) => {
273
321
// Bitcoin Core's Merkle tree implementation has no way to discern between
274
322
// internal and leaf node entries. As a consequence it is susceptible to an
@@ -308,7 +356,9 @@ where
308
356
debug_assert_eq ! ( num_tx_lookups, watched_txs. len( ) ) ;
309
357
310
358
for output in sync_state. watched_outputs . values ( ) {
311
- watched_script_pubkeys. push ( output. script_pubkey . clone ( ) ) ;
359
+ watched_script_pubkeys. push ( electrum_client:: bitcoin:: ScriptBuf :: from_bytes (
360
+ output. script_pubkey . to_bytes ( ) ,
361
+ ) ) ;
312
362
}
313
363
314
364
let num_output_spend_lookups = watched_script_pubkeys. len ( ) - num_tx_lookups;
@@ -325,11 +375,22 @@ where
325
375
if confirmed_txs. iter ( ) . any ( |ctx| ctx. txid == * * txid) {
326
376
continue ;
327
377
}
328
- let mut filtered_history =
329
- script_history. iter ( ) . filter ( |h| h. tx_hash == * * txid) ;
378
+ let mut filtered_history = script_history. iter ( ) . filter ( |h| {
379
+ h. tx_hash
380
+ == electrum_client:: bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( )
381
+ } ) ;
330
382
if let Some ( history) = filtered_history. next ( ) {
383
+ let mut tx_buffer = Vec :: new ( ) ;
384
+ tx. consensus_encode ( & mut tx_buffer) . unwrap ( ) ;
385
+ let mut tx_slice = & tx_buffer[ ..] ;
386
+ let tx_reader =
387
+ & mut lightning:: util:: ser:: BufReader :: < _ > :: new ( & mut tx_slice) ;
388
+ let bitcoin_transaction =
389
+ bitcoin:: Transaction :: consensus_decode ( tx_reader) . unwrap ( ) ;
390
+
331
391
let prob_conf_height = history. height as u32 ;
332
- let confirmed_tx = self . get_confirmed_tx ( tx, prob_conf_height) ?;
392
+ let confirmed_tx =
393
+ self . get_confirmed_tx ( & bitcoin_transaction, prob_conf_height) ?;
333
394
confirmed_txs. push ( confirmed_tx) ;
334
395
}
335
396
debug_assert ! ( filtered_history. next( ) . is_none( ) ) ;
@@ -344,7 +405,9 @@ where
344
405
}
345
406
346
407
let txid = possible_output_spend. tx_hash ;
347
- if confirmed_txs. iter ( ) . any ( |ctx| ctx. txid == txid) {
408
+ if confirmed_txs. iter ( ) . any ( |ctx| {
409
+ ctx. txid == bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( )
410
+ } ) {
348
411
continue ;
349
412
}
350
413
@@ -354,7 +417,19 @@ where
354
417
for txin in & tx. input {
355
418
let watched_outpoint =
356
419
watched_output. outpoint . into_bitcoin_outpoint ( ) ;
357
- if txin. previous_output == watched_outpoint {
420
+
421
+ let mut outpoint_buffer = Vec :: new ( ) ;
422
+ watched_outpoint
423
+ . consensus_encode ( & mut outpoint_buffer)
424
+ . unwrap ( ) ;
425
+ let mut outpoint_slice = & outpoint_buffer[ ..] ;
426
+ let esplora_outpoint =
427
+ electrum_client:: bitcoin:: OutPoint :: consensus_decode (
428
+ & mut outpoint_slice,
429
+ )
430
+ . unwrap ( ) ;
431
+
432
+ if txin. previous_output == esplora_outpoint {
358
433
is_spend = true ;
359
434
break ;
360
435
}
@@ -365,7 +440,17 @@ where
365
440
}
366
441
367
442
let prob_conf_height = possible_output_spend. height as u32 ;
368
- let confirmed_tx = self . get_confirmed_tx ( & tx, prob_conf_height) ?;
443
+
444
+ let mut tx_buffer = Vec :: new ( ) ;
445
+ tx. consensus_encode ( & mut tx_buffer) . unwrap ( ) ;
446
+ let mut tx_slice = & tx_buffer[ ..] ;
447
+ let tx_reader =
448
+ & mut lightning:: util:: ser:: BufReader :: < _ > :: new ( & mut tx_slice) ;
449
+ let bitcoin_transaction =
450
+ bitcoin:: Transaction :: consensus_decode ( tx_reader) . unwrap ( ) ;
451
+
452
+ let confirmed_tx =
453
+ self . get_confirmed_tx ( & bitcoin_transaction, prob_conf_height) ?;
369
454
confirmed_txs. push ( confirmed_tx) ;
370
455
} ,
371
456
Err ( e) => {
@@ -414,7 +499,9 @@ where
414
499
for ( txid, conf_height, block_hash_opt) in relevant_txids {
415
500
if let Some ( block_hash) = block_hash_opt {
416
501
let block_header = self . client . block_header ( conf_height as usize ) ?;
417
- if block_header. block_hash ( ) == block_hash {
502
+ if block_header. block_hash ( )
503
+ == electrum_client:: bitcoin:: BlockHash :: from_slice ( block_hash. as_ref ( ) ) . unwrap ( )
504
+ {
418
505
// Skip if the tx is still confirmed in the block in question.
419
506
continue ;
420
507
}
@@ -432,25 +519,41 @@ where
432
519
fn get_confirmed_tx (
433
520
& self , tx : & Transaction , prob_conf_height : u32 ,
434
521
) -> Result < ConfirmedTx , InternalError > {
435
- let txid = tx. txid ( ) ;
436
- match self . client . transaction_get_merkle ( & txid, prob_conf_height as usize ) {
522
+ let txid = tx. compute_txid ( ) ;
523
+ match self . client . transaction_get_merkle (
524
+ & electrum_client:: bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) ,
525
+ prob_conf_height as usize ,
526
+ ) {
437
527
Ok ( merkle_res) => {
438
528
debug_assert_eq ! ( prob_conf_height, merkle_res. block_height as u32 ) ;
439
529
match self . client . block_header ( prob_conf_height as usize ) {
440
530
Ok ( block_header) => {
441
531
let pos = merkle_res. pos ;
442
- if !validate_merkle_proof ( & txid, & block_header. merkle_root , & merkle_res) {
532
+ if !validate_merkle_proof (
533
+ & electrum_client:: bitcoin:: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) ,
534
+ & block_header. merkle_root ,
535
+ & merkle_res,
536
+ ) {
443
537
log_trace ! (
444
538
self . logger,
445
539
"Inconsistency: Block {} was unconfirmed during syncing." ,
446
540
block_header. block_hash( )
447
541
) ;
448
542
return Err ( InternalError :: Inconsistency ) ;
449
543
}
544
+
545
+ let mut header_buffer = Vec :: new ( ) ;
546
+ block_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
547
+ let mut header_slice = & header_buffer[ ..] ;
548
+ let header_reader =
549
+ & mut lightning:: util:: ser:: BufReader :: < _ > :: new ( & mut header_slice) ;
550
+ let bitcoin_header =
551
+ bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
552
+
450
553
let confirmed_tx = ConfirmedTx {
451
554
tx : tx. clone ( ) ,
452
555
txid,
453
- block_header,
556
+ block_header : bitcoin_header ,
454
557
block_height : prob_conf_height,
455
558
pos,
456
559
} ;
0 commit comments