Skip to content

Commit 5198905

Browse files
committed
Fix lightning-transaction-sync warnings.
1 parent e247613 commit 5198905

File tree

5 files changed

+276
-63
lines changed

5 files changed

+276
-63
lines changed

lightning-transaction-sync/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ rustdoc-args = ["--cfg", "docsrs"]
1616
[features]
1717
default = ["time"]
1818
time = []
19-
esplora-async = ["async-interface", "esplora-client/async", "futures"]
20-
esplora-async-https = ["esplora-async", "esplora-client/async-https-rustls"]
21-
esplora-blocking = ["esplora-client/blocking"]
19+
esplora-async = ["async-interface", "esplora-client/async", "futures", "electrum-client"]
20+
esplora-async-https = ["esplora-async", "esplora-client/async-https-rustls", "electrum-client"]
21+
esplora-blocking = ["esplora-client/blocking", "electrum-client"]
2222
electrum = ["electrum-client"]
2323
async-interface = []
2424

lightning-transaction-sync/src/common.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,12 @@ impl SyncState {
7474
);
7575
}
7676

77-
self.watched_transactions.remove(&ctx.tx.txid());
77+
self.watched_transactions.remove(&ctx.tx.compute_txid());
7878

7979
for input in &ctx.tx.input {
8080
if let Some(output) = self.watched_outputs.remove(&input.previous_output) {
81-
let spent = (ctx.tx.txid(), ctx.block_height, input.previous_output, output);
81+
let spent =
82+
(ctx.tx.compute_txid(), ctx.block_height, input.previous_output, output);
8283
self.outputs_spends_pending_threshold_conf.push(spent);
8384
}
8485
}

lightning-transaction-sync/src/electrum.rs

Lines changed: 129 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,13 @@ use lightning::{log_debug, log_error, log_trace};
1313
use bitcoin::block::Header;
1414
use bitcoin::{BlockHash, Script, Transaction, Txid};
1515

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+
};
1623
use std::collections::HashSet;
1724
use std::ops::Deref;
1825
use std::sync::Mutex;
@@ -92,12 +99,15 @@ where
9299
while let Some(_) = self.client.block_headers_pop()? {}
93100

94101
let tip_notification = self.client.block_headers_subscribe()?;
95-
let mut tip_header = tip_notification.header;
102+
let tip_header = tip_notification.header;
96103
let mut tip_height = tip_notification.height as u32;
97104

98105
loop {
99106
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());
101111

102112
// We loop until any registered transactions have been processed at least once, or the
103113
// tip hasn't been updated during the last iteration.
@@ -112,7 +122,18 @@ where
112122
Ok(unconfirmed_txs) => {
113123
// Double-check the tip hash. If it changed, a reorg happened since
114124
// 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) {
116137
Ok(false) => {
117138
num_unconfirmed += unconfirmed_txs.len();
118139
sync_state.sync_unconfirmed_transactions(
@@ -150,9 +171,17 @@ where
150171
},
151172
}
152173

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+
153182
// Update the best block.
154183
for c in &confirmables {
155-
c.best_block_updated(&tip_header, tip_height);
184+
c.best_block_updated(&bitcoin_header, tip_height);
156185
}
157186

158187
// Prune any sufficiently confirmed output spends
@@ -161,9 +190,17 @@ where
161190

162191
match self.get_confirmed_transactions(&sync_state) {
163192
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+
164201
// Double-check the tip hash. If it changed, a reorg happened since
165202
// 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) {
167204
Ok(false) => {
168205
num_confirmed += confirmed_txs.len();
169206
sync_state
@@ -207,7 +244,8 @@ where
207244
return Err(TxSyncError::from(err));
208245
},
209246
}
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());
211249
sync_state.pending_sync = false;
212250
}
213251
}
@@ -240,15 +278,26 @@ where
240278
// Restart if either the tip changed or we got some divergent tip
241279
// change notification since we started. In the latter case we
242280
// 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();
244286
while let Some(queued_notif) = self.client.block_headers_pop()? {
245287
if queued_notif.header.block_hash() != check_tip_hash {
246288
restart_sync = true
247289
}
248290
}
249291

250292
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;
252301
*cur_tip_height = check_notification.height as u32;
253302
Ok(true)
254303
} else {
@@ -268,7 +317,9 @@ where
268317
let mut watched_txs = Vec::with_capacity(sync_state.watched_transactions.len());
269318

270319
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+
) {
272323
Ok(tx) => {
273324
// Bitcoin Core's Merkle tree implementation has no way to discern between
274325
// internal and leaf node entries. As a consequence it is susceptible to an
@@ -308,7 +359,9 @@ where
308359
debug_assert_eq!(num_tx_lookups, watched_txs.len());
309360

310361
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+
));
312365
}
313366

314367
let num_output_spend_lookups = watched_script_pubkeys.len() - num_tx_lookups;
@@ -325,11 +378,22 @@ where
325378
if confirmed_txs.iter().any(|ctx| ctx.txid == **txid) {
326379
continue;
327380
}
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+
});
330385
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+
331394
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)?;
333397
confirmed_txs.push(confirmed_tx);
334398
}
335399
debug_assert!(filtered_history.next().is_none());
@@ -344,7 +408,9 @@ where
344408
}
345409

346410
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+
}) {
348414
continue;
349415
}
350416

@@ -354,7 +420,19 @@ where
354420
for txin in &tx.input {
355421
let watched_outpoint =
356422
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 {
358436
is_spend = true;
359437
break;
360438
}
@@ -365,7 +443,19 @@ where
365443
}
366444

367445
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)?;
369459
confirmed_txs.push(confirmed_tx);
370460
},
371461
Err(e) => {
@@ -414,7 +504,9 @@ where
414504
for (txid, conf_height, block_hash_opt) in relevant_txids {
415505
if let Some(block_hash) = block_hash_opt {
416506
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+
{
418510
// Skip if the tx is still confirmed in the block in question.
419511
continue;
420512
}
@@ -432,25 +524,41 @@ where
432524
fn get_confirmed_tx(
433525
&self, tx: &Transaction, prob_conf_height: u32,
434526
) -> 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+
) {
437532
Ok(merkle_res) => {
438533
debug_assert_eq!(prob_conf_height, merkle_res.block_height as u32);
439534
match self.client.block_header(prob_conf_height as usize) {
440535
Ok(block_header) => {
441536
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+
) {
443542
log_trace!(
444543
self.logger,
445544
"Inconsistency: Block {} was unconfirmed during syncing.",
446545
block_header.block_hash()
447546
);
448547
return Err(InternalError::Inconsistency);
449548
}
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+
450558
let confirmed_tx = ConfirmedTx {
451559
tx: tx.clone(),
452560
txid,
453-
block_header,
561+
block_header: bitcoin_header,
454562
block_height: prob_conf_height,
455563
pos,
456564
};

0 commit comments

Comments
 (0)