Skip to content

Commit 8088e4b

Browse files
authored
Merge pull request #856 from TheBlueMatt/2021-03-check-tx
Take the full funding transaction from the user on generation
2 parents b77b547 + 3f2efcd commit 8088e4b

File tree

9 files changed

+148
-151
lines changed

9 files changed

+148
-151
lines changed

background-processor/src/lib.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -215,21 +215,20 @@ mod tests {
215215
$node_a.node.handle_accept_channel(&$node_b.node.get_our_node_id(), InitFeatures::known(), &get_event_msg!($node_b, MessageSendEvent::SendAcceptChannel, $node_a.node.get_our_node_id()));
216216
let events = $node_a.node.get_and_clear_pending_events();
217217
assert_eq!(events.len(), 1);
218-
let (temporary_channel_id, tx, funding_output) = match events[0] {
218+
let (temporary_channel_id, tx) = match events[0] {
219219
Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, ref output_script, user_channel_id } => {
220220
assert_eq!(*channel_value_satoshis, $channel_value);
221221
assert_eq!(user_channel_id, 42);
222222

223223
let tx = Transaction { version: 1 as i32, lock_time: 0, input: Vec::new(), output: vec![TxOut {
224224
value: *channel_value_satoshis, script_pubkey: output_script.clone(),
225225
}]};
226-
let funding_outpoint = OutPoint { txid: tx.txid(), index: 0 };
227-
(*temporary_channel_id, tx, funding_outpoint)
226+
(*temporary_channel_id, tx)
228227
},
229228
_ => panic!("Unexpected event"),
230229
};
231230

232-
$node_a.node.funding_transaction_generated(&temporary_channel_id, funding_output);
231+
$node_a.node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap();
233232
$node_b.node.handle_funding_created(&$node_a.node.get_our_node_id(), &get_event_msg!($node_a, MessageSendEvent::SendFundingCreated, $node_b.node.get_our_node_id()));
234233
$node_a.node.handle_funding_signed(&$node_b.node.get_our_node_id(), &get_event_msg!($node_b, MessageSendEvent::SendFundingSigned, $node_a.node.get_our_node_id()));
235234
tx

fuzz/src/chanmon_consistency.rs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
397397
value: *channel_value_satoshis, script_pubkey: output_script.clone(),
398398
}]};
399399
funding_output = OutPoint { txid: tx.txid(), index: 0 };
400-
$source.funding_transaction_generated(&temporary_channel_id, funding_output);
400+
$source.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap();
401401
channel_txn.push(tx);
402402
} else { panic!("Wrong event type"); }
403403
}
@@ -420,12 +420,6 @@ pub fn do_test<Out: test_logger::Output>(data: &[u8], out: Out) {
420420
};
421421
$source.handle_funding_signed(&$dest.get_our_node_id(), &funding_signed);
422422

423-
{
424-
let events = $source.get_and_clear_pending_events();
425-
assert_eq!(events.len(), 1);
426-
if let events::Event::FundingBroadcastSafe { .. } = events[0] {
427-
} else { panic!("Wrong event type"); }
428-
}
429423
funding_output
430424
} }
431425
}

fuzz/src/full_stack.rs

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ use bitcoin::secp256k1::Secp256k1;
5252
use std::cell::RefCell;
5353
use std::collections::{HashMap, hash_map};
5454
use std::cmp;
55-
use std::sync::Arc;
55+
use std::sync::{Arc, Mutex};
5656
use std::sync::atomic::{AtomicU64,AtomicUsize,Ordering};
5757

5858
#[inline]
@@ -117,9 +117,13 @@ impl FeeEstimator for FuzzEstimator {
117117
}
118118
}
119119

120-
struct TestBroadcaster {}
120+
struct TestBroadcaster {
121+
txn_broadcasted: Mutex<Vec<Transaction>>,
122+
}
121123
impl BroadcasterInterface for TestBroadcaster {
122-
fn broadcast_transaction(&self, _tx: &Transaction) {}
124+
fn broadcast_transaction(&self, tx: &Transaction) {
125+
self.txn_broadcasted.lock().unwrap().push(tx.clone());
126+
}
123127
}
124128

125129
#[derive(Clone)]
@@ -342,7 +346,7 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
342346
Err(_) => return,
343347
};
344348

345-
let broadcast = Arc::new(TestBroadcaster{});
349+
let broadcast = Arc::new(TestBroadcaster{ txn_broadcasted: Mutex::new(Vec::new()) });
346350
let monitor = Arc::new(chainmonitor::ChainMonitor::new(None, broadcast.clone(), Arc::clone(&logger), fee_est.clone(), Arc::new(TestPersister{})));
347351

348352
let keys_manager = Arc::new(KeyProvider { node_secret: our_network_key.clone(), counter: AtomicU64::new(0) });
@@ -372,7 +376,6 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
372376
let mut payments_sent = 0;
373377
let mut pending_funding_generation: Vec<([u8; 32], u64, Script)> = Vec::new();
374378
let mut pending_funding_signatures = HashMap::new();
375-
let mut pending_funding_relay = Vec::new();
376379

377380
loop {
378381
match get_slice!(1)[0] {
@@ -515,18 +518,19 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
515518
continue 'outer_loop;
516519
}
517520
};
518-
channelmanager.funding_transaction_generated(&funding_generation.0, funding_output.clone());
521+
channelmanager.funding_transaction_generated(&funding_generation.0, tx.clone()).unwrap();
519522
pending_funding_signatures.insert(funding_output, tx);
520523
}
521524
},
522525
11 => {
523-
if !pending_funding_relay.is_empty() {
524-
loss_detector.connect_block(&pending_funding_relay[..]);
526+
let mut txn = broadcast.txn_broadcasted.lock().unwrap();
527+
if !txn.is_empty() {
528+
loss_detector.connect_block(&txn[..]);
525529
for _ in 2..100 {
526530
loss_detector.connect_block(&[]);
527531
}
528532
}
529-
for tx in pending_funding_relay.drain(..) {
533+
for tx in txn.drain(..) {
530534
loss_detector.funding_txn.push(tx);
531535
}
532536
},
@@ -568,9 +572,6 @@ pub fn do_test(data: &[u8], logger: &Arc<dyn Logger>) {
568572
Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, output_script, .. } => {
569573
pending_funding_generation.push((temporary_channel_id, channel_value_satoshis, output_script));
570574
},
571-
Event::FundingBroadcastSafe { funding_txo, .. } => {
572-
pending_funding_relay.push(pending_funding_signatures.remove(&funding_txo).unwrap());
573-
},
574575
Event::PaymentReceived { payment_hash, payment_secret, amt } => {
575576
//TODO: enhance by fetching random amounts from fuzz input?
576577
payments_received.push((payment_hash, payment_secret, amt));

lightning/src/ln/chanmon_update_fail_tests.rs

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,7 +1825,7 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
18251825

18261826
let (temporary_channel_id, funding_tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 43);
18271827

1828-
nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_output);
1828+
nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_tx.clone()).unwrap();
18291829
check_added_monitors!(nodes[0], 0);
18301830

18311831
*nodes[1].chain_monitor.update_ret.lock().unwrap() = Some(Err(ChannelMonitorUpdateErr::TemporaryFailure));
@@ -1846,14 +1846,9 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf:
18461846
check_added_monitors!(nodes[0], 0);
18471847

18481848
let events = nodes[0].node.get_and_clear_pending_events();
1849-
assert_eq!(events.len(), 1);
1850-
match events[0] {
1851-
Event::FundingBroadcastSafe { ref funding_txo, user_channel_id } => {
1852-
assert_eq!(user_channel_id, 43);
1853-
assert_eq!(*funding_txo, funding_output);
1854-
},
1855-
_ => panic!("Unexpected event"),
1856-
};
1849+
assert_eq!(events.len(), 0);
1850+
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
1851+
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0)[0].txid(), funding_output.txid);
18571852

18581853
if confirm_a_first {
18591854
confirm_transaction(&nodes[0], &funding_tx);

lightning/src/ln/channel.rs

Lines changed: 29 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -405,9 +405,9 @@ pub(super) struct Channel<Signer: Sign> {
405405
counterparty_forwarding_info: Option<CounterpartyForwardingInfo>,
406406

407407
pub(crate) channel_transaction_parameters: ChannelTransactionParameters,
408+
funding_transaction: Option<Transaction>,
408409

409410
counterparty_cur_commitment_point: Option<PublicKey>,
410-
411411
counterparty_prev_commitment_point: Option<PublicKey>,
412412
counterparty_node_id: PublicKey,
413413

@@ -595,8 +595,9 @@ impl<Signer: Sign> Channel<Signer> {
595595
counterparty_parameters: None,
596596
funding_outpoint: None
597597
},
598-
counterparty_cur_commitment_point: None,
598+
funding_transaction: None,
599599

600+
counterparty_cur_commitment_point: None,
600601
counterparty_prev_commitment_point: None,
601602
counterparty_node_id,
602603

@@ -836,8 +837,9 @@ impl<Signer: Sign> Channel<Signer> {
836837
}),
837838
funding_outpoint: None
838839
},
839-
counterparty_cur_commitment_point: Some(msg.first_per_commitment_point),
840+
funding_transaction: None,
840841

842+
counterparty_cur_commitment_point: Some(msg.first_per_commitment_point),
841843
counterparty_prev_commitment_point: None,
842844
counterparty_node_id,
843845

@@ -1600,7 +1602,7 @@ impl<Signer: Sign> Channel<Signer> {
16001602

16011603
/// Handles a funding_signed message from the remote end.
16021604
/// If this call is successful, broadcast the funding transaction (and not before!)
1603-
pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, last_block_hash: BlockHash, logger: &L) -> Result<ChannelMonitor<Signer>, ChannelError> where L::Target: Logger {
1605+
pub fn funding_signed<L: Deref>(&mut self, msg: &msgs::FundingSigned, last_block_hash: BlockHash, logger: &L) -> Result<(ChannelMonitor<Signer>, Transaction), ChannelError> where L::Target: Logger {
16041606
if !self.is_outbound() {
16051607
return Err(ChannelError::Close("Received funding_signed for an inbound channel?".to_owned()));
16061608
}
@@ -1662,7 +1664,7 @@ impl<Signer: Sign> Channel<Signer> {
16621664
self.cur_holder_commitment_transaction_number -= 1;
16631665
self.cur_counterparty_commitment_transaction_number -= 1;
16641666

1665-
Ok(channel_monitor)
1667+
Ok((channel_monitor, self.funding_transaction.as_ref().cloned().unwrap()))
16661668
}
16671669

16681670
pub fn funding_locked(&mut self, msg: &msgs::FundingLocked) -> Result<(), ChannelError> {
@@ -2763,20 +2765,21 @@ impl<Signer: Sign> Channel<Signer> {
27632765
/// Indicates that the latest ChannelMonitor update has been committed by the client
27642766
/// successfully and we should restore normal operation. Returns messages which should be sent
27652767
/// to the remote side.
2766-
pub fn monitor_updating_restored<L: Deref>(&mut self, logger: &L) -> (Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, RAACommitmentOrder, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, bool, Option<msgs::FundingLocked>) where L::Target: Logger {
2768+
pub fn monitor_updating_restored<L: Deref>(&mut self, logger: &L) -> (Option<msgs::RevokeAndACK>, Option<msgs::CommitmentUpdate>, RAACommitmentOrder, Vec<(PendingHTLCInfo, u64)>, Vec<(HTLCSource, PaymentHash, HTLCFailReason)>, Option<Transaction>, Option<msgs::FundingLocked>) where L::Target: Logger {
27672769
assert_eq!(self.channel_state & ChannelState::MonitorUpdateFailed as u32, ChannelState::MonitorUpdateFailed as u32);
27682770
self.channel_state &= !(ChannelState::MonitorUpdateFailed as u32);
27692771

2770-
let needs_broadcast_safe = self.channel_state & (ChannelState::FundingSent as u32) != 0 && self.is_outbound();
2772+
let funding_broadcastable = if self.channel_state & (ChannelState::FundingSent as u32) != 0 && self.is_outbound() {
2773+
self.funding_transaction.take()
2774+
} else { None };
27712775

2772-
// Because we will never generate a FundingBroadcastSafe event when we're in
2773-
// MonitorUpdateFailed, if we assume the user only broadcast the funding transaction when
2774-
// they received the FundingBroadcastSafe event, we can only ever hit
2775-
// monitor_pending_funding_locked when we're an inbound channel which failed to persist the
2776-
// monitor on funding_created, and we even got the funding transaction confirmed before the
2777-
// monitor was persisted.
2776+
// We will never broadcast the funding transaction when we're in MonitorUpdateFailed (and
2777+
// we assume the user never directly broadcasts the funding transaction and waits for us to
2778+
// do it). Thus, we can only ever hit monitor_pending_funding_locked when we're an inbound
2779+
// channel which failed to persist the monitor on funding_created, and we got the funding
2780+
// transaction confirmed before the monitor was persisted.
27782781
let funding_locked = if self.monitor_pending_funding_locked {
2779-
assert!(!self.is_outbound(), "Funding transaction broadcast without FundingBroadcastSafe!");
2782+
assert!(!self.is_outbound(), "Funding transaction broadcast by the local client before it should have - LDK didn't do it!");
27802783
self.monitor_pending_funding_locked = false;
27812784
let next_per_commitment_point = self.holder_signer.get_per_commitment_point(self.cur_holder_commitment_transaction_number, &self.secp_ctx);
27822785
Some(msgs::FundingLocked {
@@ -2793,7 +2796,7 @@ impl<Signer: Sign> Channel<Signer> {
27932796
if self.channel_state & (ChannelState::PeerDisconnected as u32) != 0 {
27942797
self.monitor_pending_revoke_and_ack = false;
27952798
self.monitor_pending_commitment_signed = false;
2796-
return (None, None, RAACommitmentOrder::RevokeAndACKFirst, forwards, failures, needs_broadcast_safe, funding_locked);
2799+
return (None, None, RAACommitmentOrder::RevokeAndACKFirst, forwards, failures, funding_broadcastable, funding_locked);
27972800
}
27982801

27992802
let raa = if self.monitor_pending_revoke_and_ack {
@@ -2807,11 +2810,11 @@ impl<Signer: Sign> Channel<Signer> {
28072810
self.monitor_pending_commitment_signed = false;
28082811
let order = self.resend_order.clone();
28092812
log_trace!(logger, "Restored monitor updating resulting in {}{} commitment update and {} RAA, with {} first",
2810-
if needs_broadcast_safe { "a funding broadcast safe, " } else { "" },
2813+
if funding_broadcastable.is_some() { "a funding broadcastable, " } else { "" },
28112814
if commitment_update.is_some() { "a" } else { "no" },
28122815
if raa.is_some() { "an" } else { "no" },
28132816
match order { RAACommitmentOrder::CommitmentFirst => "commitment", RAACommitmentOrder::RevokeAndACKFirst => "RAA"});
2814-
(raa, commitment_update, order, forwards, failures, needs_broadcast_safe, funding_locked)
2817+
(raa, commitment_update, order, forwards, failures, funding_broadcastable, funding_locked)
28152818
}
28162819

28172820
pub fn update_fee<F: Deref>(&mut self, fee_estimator: &F, msg: &msgs::UpdateFee) -> Result<(), ChannelError>
@@ -3764,7 +3767,7 @@ impl<Signer: Sign> Channel<Signer> {
37643767
/// Note that channel_id changes during this call!
37653768
/// Do NOT broadcast the funding transaction until after a successful funding_signed call!
37663769
/// If an Err is returned, it is a ChannelError::Close.
3767-
pub fn get_outbound_funding_created<L: Deref>(&mut self, funding_txo: OutPoint, logger: &L) -> Result<msgs::FundingCreated, ChannelError> where L::Target: Logger {
3770+
pub fn get_outbound_funding_created<L: Deref>(&mut self, funding_transaction: Transaction, funding_txo: OutPoint, logger: &L) -> Result<msgs::FundingCreated, ChannelError> where L::Target: Logger {
37683771
if !self.is_outbound() {
37693772
panic!("Tried to create outbound funding_created message on an inbound channel!");
37703773
}
@@ -3795,6 +3798,7 @@ impl<Signer: Sign> Channel<Signer> {
37953798

37963799
self.channel_state = ChannelState::FundingCreated as u32;
37973800
self.channel_id = funding_txo.to_channel_id();
3801+
self.funding_transaction = Some(funding_transaction);
37983802

37993803
Ok(msgs::FundingCreated {
38003804
temporary_channel_id,
@@ -4519,8 +4523,9 @@ impl<Signer: Sign> Writeable for Channel<Signer> {
45194523
}
45204524

45214525
self.channel_transaction_parameters.write(writer)?;
4522-
self.counterparty_cur_commitment_point.write(writer)?;
4526+
self.funding_transaction.write(writer)?;
45234527

4528+
self.counterparty_cur_commitment_point.write(writer)?;
45244529
self.counterparty_prev_commitment_point.write(writer)?;
45254530
self.counterparty_node_id.write(writer)?;
45264531

@@ -4689,6 +4694,8 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
46894694
};
46904695

46914696
let channel_parameters = Readable::read(reader)?;
4697+
let funding_transaction = Readable::read(reader)?;
4698+
46924699
let counterparty_cur_commitment_point = Readable::read(reader)?;
46934700

46944701
let counterparty_prev_commitment_point = Readable::read(reader)?;
@@ -4761,8 +4768,9 @@ impl<'a, Signer: Sign, K: Deref> ReadableArgs<&'a K> for Channel<Signer>
47614768
counterparty_forwarding_info,
47624769

47634770
channel_transaction_parameters: channel_parameters,
4764-
counterparty_cur_commitment_point,
4771+
funding_transaction,
47654772

4773+
counterparty_cur_commitment_point,
47664774
counterparty_prev_commitment_point,
47674775
counterparty_node_id,
47684776

@@ -5030,7 +5038,7 @@ mod tests {
50305038
value: 10000000, script_pubkey: output_script.clone(),
50315039
}]};
50325040
let funding_outpoint = OutPoint{ txid: tx.txid(), index: 0 };
5033-
let funding_created_msg = node_a_chan.get_outbound_funding_created(funding_outpoint, &&logger).unwrap();
5041+
let funding_created_msg = node_a_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap();
50345042
let (funding_signed_msg, _) = node_b_chan.funding_created(&funding_created_msg, last_block_hash, &&logger).unwrap();
50355043

50365044
// Node B --> Node A: funding signed

0 commit comments

Comments
 (0)