@@ -16,6 +16,10 @@ use esplora_client::Builder;
16
16
17
17
use core:: ops:: Deref ;
18
18
use std:: collections:: HashSet ;
19
+ use bitcoin:: consensus:: Decodable ;
20
+ use bitcoin:: hashes:: Hash as BitcoinHash ;
21
+ use electrum_client:: bitcoin:: hashes:: Hash as ElectrumHash ;
22
+ use electrum_client:: bitcoin:: consensus:: Encodable ;
19
23
20
24
/// Synchronizes LDK with a given [`Esplora`] server.
21
25
///
99
103
100
104
loop {
101
105
let pending_registrations = self . queue . lock ( ) . unwrap ( ) . process_queues ( & mut sync_state) ;
102
- let tip_is_new = Some ( tip_hash) != sync_state. last_sync_hash ;
106
+ let tip_is_new = Some ( tip_hash) != sync_state. last_sync_hash . map ( |hash| esplora_client :: BlockHash :: from_slice ( hash . as_ref ( ) ) . unwrap ( ) ) ;
103
107
104
108
// We loop until any registered transactions have been processed at least once, or the
105
109
// tip hasn't been updated during the last iteration.
@@ -156,7 +160,7 @@ where
156
160
match maybe_await ! ( self . sync_best_block_updated(
157
161
& confirmables,
158
162
& mut sync_state,
159
- & tip_hash
163
+ & BlockHash :: from_slice ( tip_hash. as_ref ( ) ) . unwrap ( )
160
164
) ) {
161
165
Ok ( ( ) ) => { } ,
162
166
Err ( InternalError :: Inconsistency ) => {
@@ -231,7 +235,7 @@ where
231
235
return Err ( TxSyncError :: from ( err) ) ;
232
236
} ,
233
237
}
234
- sync_state. last_sync_hash = Some ( tip_hash) ;
238
+ sync_state. last_sync_hash = Some ( BlockHash :: from_slice ( tip_hash. as_ref ( ) ) . unwrap ( ) ) ;
235
239
sync_state. pending_sync = false ;
236
240
}
237
241
}
@@ -263,12 +267,20 @@ where
263
267
C :: Target : Confirm ,
264
268
{
265
269
// Inform the interface of the new block.
266
- let tip_header = maybe_await ! ( self . client. get_header_by_hash( tip_hash) ) ?;
267
- let tip_status = maybe_await ! ( self . client. get_block_status( & tip_hash) ) ?;
270
+ let esplora_tip_hash = esplora_client:: BlockHash :: from_slice ( tip_hash. as_ref ( ) ) . unwrap ( ) ;
271
+ let tip_status = maybe_await ! ( self . client. get_block_status( & esplora_tip_hash) ) ?;
272
+
273
+ let tip_header: electrum_client:: bitcoin:: block:: Header = maybe_await ! ( self . client. get_header_by_hash( & esplora_tip_hash) ) ?;
274
+ let mut header_buffer = Vec :: new ( ) ;
275
+ tip_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
276
+ let mut header_slice = & header_buffer[ ..] ;
277
+ let header_reader = & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut header_slice) ;
278
+ let bitcoin_header = bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
279
+
268
280
if tip_status. in_best_chain {
269
281
if let Some ( tip_height) = tip_status. height {
270
282
for c in confirmables {
271
- c. best_block_updated ( & tip_header , tip_height) ;
283
+ c. best_block_updated ( & bitcoin_header , tip_height) ;
272
284
}
273
285
274
286
// Prune any sufficiently confirmed output spends
@@ -301,11 +313,12 @@ where
301
313
for ( _, output) in & sync_state. watched_outputs {
302
314
if let Some ( output_status) = maybe_await ! ( self
303
315
. client
304
- . get_output_status( & output. outpoint. txid, output. outpoint. index as u64 ) ) ?
316
+ . get_output_status( & esplora_client :: Txid :: from_slice ( output. outpoint. txid. as_ref ( ) ) . unwrap ( ) , output. outpoint. index as u64 ) ) ?
305
317
{
306
318
if let Some ( spending_txid) = output_status. txid {
319
+ let bitcoin_tx_id = bitcoin:: Txid :: from_slice ( spending_txid. as_ref ( ) ) . unwrap ( ) ;
307
320
if let Some ( spending_tx_status) = output_status. status {
308
- if confirmed_txs. iter ( ) . any ( |ctx| ctx. txid == spending_txid ) {
321
+ if confirmed_txs. iter ( ) . any ( |ctx| ctx. txid == bitcoin_tx_id ) {
309
322
if spending_tx_status. confirmed {
310
323
// Skip inserting duplicate ConfirmedTx entry
311
324
continue ;
@@ -316,8 +329,8 @@ where
316
329
}
317
330
318
331
if let Some ( confirmed_tx) = maybe_await ! ( self . get_confirmed_tx(
319
- spending_txid ,
320
- spending_tx_status. block_hash,
332
+ bitcoin_tx_id ,
333
+ spending_tx_status. block_hash. map ( |h| BlockHash :: from_slice ( h . as_ref ( ) ) . unwrap ( ) ) ,
321
334
spending_tx_status. block_height,
322
335
) ) ? {
323
336
confirmed_txs. push ( confirmed_tx) ;
@@ -340,11 +353,11 @@ where
340
353
fn get_confirmed_tx (
341
354
& self , txid : Txid , expected_block_hash : Option < BlockHash > , known_block_height : Option < u32 > ,
342
355
) -> Result < Option < ConfirmedTx > , InternalError > {
343
- if let Some ( merkle_block) = maybe_await ! ( self . client. get_merkle_block( & txid) ) ? {
356
+ if let Some ( merkle_block) = maybe_await ! ( self . client. get_merkle_block( & esplora_client :: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) ) ) ? {
344
357
let block_header = merkle_block. header ;
345
358
let block_hash = block_header. block_hash ( ) ;
346
359
if let Some ( expected_block_hash) = expected_block_hash {
347
- if expected_block_hash != block_hash {
360
+ if expected_block_hash != bitcoin :: BlockHash :: from_slice ( block_hash. as_ref ( ) ) . unwrap ( ) {
348
361
log_trace ! (
349
362
self . logger,
350
363
"Inconsistency: Tx {} expected in block {}, but is confirmed in {}" ,
@@ -359,27 +372,53 @@ where
359
372
let mut matches = Vec :: new ( ) ;
360
373
let mut indexes = Vec :: new ( ) ;
361
374
let _ = merkle_block. txn . extract_matches ( & mut matches, & mut indexes) ;
362
- if indexes. len ( ) != 1 || matches. len ( ) != 1 || matches[ 0 ] != txid {
375
+ if indexes. len ( ) != 1 || matches. len ( ) != 1 || matches[ 0 ] != esplora_client :: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) {
363
376
log_error ! ( self . logger, "Retrieved Merkle block for txid {} doesn't match expectations. This should not happen. Please verify server integrity." , txid) ;
364
377
return Err ( InternalError :: Failed ) ;
365
378
}
366
379
367
380
// unwrap() safety: len() > 0 is checked above
368
381
let pos = * indexes. first ( ) . unwrap ( ) as usize ;
369
- if let Some ( tx) = maybe_await ! ( self . client. get_tx( & txid) ) ? {
370
- if tx. txid ( ) != txid {
382
+ if let Some ( tx) = maybe_await ! ( self . client. get_tx( & esplora_client :: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) ) ) ? {
383
+ if tx. txid ( ) != electrum_client :: bitcoin :: Txid :: from_slice ( txid. as_ref ( ) ) . unwrap ( ) {
371
384
log_error ! ( self . logger, "Retrieved transaction for txid {} doesn't match expectations. This should not happen. Please verify server integrity." , txid) ;
372
385
return Err ( InternalError :: Failed ) ;
373
386
}
374
387
375
388
if let Some ( block_height) = known_block_height {
389
+
390
+ let mut tx_buffer = Vec :: new ( ) ;
391
+ tx. consensus_encode ( & mut tx_buffer) . unwrap ( ) ;
392
+ let mut tx_slice = & tx_buffer[ ..] ;
393
+ let tx_reader = & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut tx_slice) ;
394
+ let bitcoin_transaction = bitcoin:: Transaction :: consensus_decode ( tx_reader) . unwrap ( ) ;
395
+
396
+ let mut header_buffer = Vec :: new ( ) ;
397
+ block_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
398
+ let mut header_slice = & header_buffer[ ..] ;
399
+ let header_reader = & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut header_slice) ;
400
+ let bitcoin_header = bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
401
+
376
402
// We can take a shortcut here if a previous call already gave us the height.
377
- return Ok ( Some ( ConfirmedTx { tx, txid, block_header, pos, block_height } ) ) ;
403
+ return Ok ( Some ( ConfirmedTx { tx : bitcoin_transaction , txid, block_header : bitcoin_header , pos, block_height } ) ) ;
378
404
}
379
405
380
406
let block_status = maybe_await ! ( self . client. get_block_status( & block_hash) ) ?;
381
407
if let Some ( block_height) = block_status. height {
382
- return Ok ( Some ( ConfirmedTx { tx, txid, block_header, pos, block_height } ) ) ;
408
+
409
+ let mut tx_buffer = Vec :: new ( ) ;
410
+ tx. consensus_encode ( & mut tx_buffer) . unwrap ( ) ;
411
+ let mut tx_slice = & tx_buffer[ ..] ;
412
+ let tx_reader = & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut tx_slice) ;
413
+ let bitcoin_transaction = bitcoin:: Transaction :: consensus_decode ( tx_reader) . unwrap ( ) ;
414
+
415
+ let mut header_buffer = Vec :: new ( ) ;
416
+ block_header. consensus_encode ( & mut header_buffer) . unwrap ( ) ;
417
+ let mut header_slice = & header_buffer[ ..] ;
418
+ let header_reader = & mut lightning:: util:: ser:: BufReader :: < _ , 4096 > :: new ( & mut header_slice) ;
419
+ let bitcoin_header = bitcoin:: block:: Header :: consensus_decode ( header_reader) . unwrap ( ) ;
420
+
421
+ return Ok ( Some ( ConfirmedTx { tx : bitcoin_transaction, txid, block_header : bitcoin_header, pos, block_height } ) ) ;
383
422
} else {
384
423
// If any previously-confirmed block suddenly is no longer confirmed, we found
385
424
// an inconsistency and should start over.
@@ -413,7 +452,7 @@ where
413
452
414
453
for ( txid, _conf_height, block_hash_opt) in relevant_txids {
415
454
if let Some ( block_hash) = block_hash_opt {
416
- let block_status = maybe_await ! ( self . client. get_block_status( & block_hash) ) ?;
455
+ let block_status = maybe_await ! ( self . client. get_block_status( & electrum_client :: bitcoin :: BlockHash :: from_slice ( block_hash. as_ref ( ) ) . unwrap ( ) ) ) ?;
417
456
if block_status. in_best_chain {
418
457
// Skip if the block in question is still confirmed.
419
458
continue ;
0 commit comments