From 7893ddc72184fb1495fd7e19880527fa425012b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Tigerstr=C3=B6m?= <11711198+ViktorTigerstrom@users.noreply.github.com> Date: Fri, 13 May 2022 23:43:25 +0200 Subject: [PATCH 1/6] Add `counterparty_node_id` to `FundingGenerationReady` --- fuzz/src/full_stack.rs | 8 ++++---- lightning-background-processor/src/lib.rs | 2 +- lightning/src/ln/chanmon_update_fail_tests.rs | 2 +- lightning/src/ln/channelmanager.rs | 1 + lightning/src/ln/functional_test_utils.rs | 9 +++++---- lightning/src/ln/functional_tests.rs | 18 +++++++++--------- lightning/src/ln/priv_short_conf_tests.rs | 2 +- lightning/src/util/events.rs | 9 ++++++++- 8 files changed, 30 insertions(+), 21 deletions(-) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 330124f8a89..2da065151d3 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -408,7 +408,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { let mut should_forward = false; let mut payments_received: Vec = Vec::new(); let mut payments_sent = 0; - let mut pending_funding_generation: Vec<([u8; 32], u64, Script)> = Vec::new(); + let mut pending_funding_generation: Vec<([u8; 32], PublicKey, u64, Script)> = Vec::new(); let mut pending_funding_signatures = HashMap::new(); loop { @@ -556,7 +556,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { 10 => { 'outer_loop: for funding_generation in pending_funding_generation.drain(..) { let mut tx = Transaction { version: 0, lock_time: 0, input: Vec::new(), output: vec![TxOut { - value: funding_generation.1, script_pubkey: funding_generation.2, + value: funding_generation.2, script_pubkey: funding_generation.3, }] }; let funding_output = 'search_loop: loop { let funding_txid = tx.txid(); @@ -632,8 +632,8 @@ pub fn do_test(data: &[u8], logger: &Arc) { loss_detector.handler.process_events(); for event in loss_detector.manager.get_and_clear_pending_events() { match event { - Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, output_script, .. } => { - pending_funding_generation.push((temporary_channel_id, channel_value_satoshis, output_script)); + Event::FundingGenerationReady { temporary_channel_id, counterparty_node_id, channel_value_satoshis, output_script, .. } => { + pending_funding_generation.push((temporary_channel_id, counterparty_node_id, channel_value_satoshis, output_script)); }, Event::PaymentReceived { payment_hash, .. } => { //TODO: enhance by fetching random amounts from fuzz input? diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index 107f65f9b74..a0ac265ea6b 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -540,7 +540,7 @@ mod tests { macro_rules! handle_funding_generation_ready { ($event: expr, $channel_value: expr) => {{ match $event { - &Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, ref output_script, user_channel_id } => { + &Event::FundingGenerationReady { temporary_channel_id, channel_value_satoshis, ref output_script, user_channel_id, .. } => { assert_eq!(channel_value_satoshis, $channel_value); assert_eq!(user_channel_id, 42); diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 58fe30ba261..15ad15d5b54 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -1809,7 +1809,7 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id())); nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id())); - let (temporary_channel_id, funding_tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 43); + let (temporary_channel_id, funding_tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 43); nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_tx.clone()).unwrap(); check_added_monitors!(nodes[0], 0); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 2ce466c9ac6..5cc3e71931b 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4212,6 +4212,7 @@ impl ChannelMana let mut pending_events = self.pending_events.lock().unwrap(); pending_events.push(events::Event::FundingGenerationReady { temporary_channel_id: msg.temporary_channel_id, + counterparty_node_id: *counterparty_node_id, channel_value_satoshis: value, output_script, user_channel_id: user_id, diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index b4807ea6886..010a64f5668 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -553,13 +553,14 @@ macro_rules! check_added_monitors { } } -pub fn create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, expected_chan_value: u64, expected_user_chan_id: u64) -> ([u8; 32], Transaction, OutPoint) { +pub fn create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, expected_counterparty_node_id: &PublicKey, expected_chan_value: u64, expected_user_chan_id: u64) -> ([u8; 32], Transaction, OutPoint) { let chan_id = *node.network_chan_count.borrow(); let events = node.node.get_and_clear_pending_events(); assert_eq!(events.len(), 1); match events[0] { - Event::FundingGenerationReady { ref temporary_channel_id, ref channel_value_satoshis, ref output_script, user_channel_id } => { + Event::FundingGenerationReady { ref temporary_channel_id, ref counterparty_node_id, ref channel_value_satoshis, ref output_script, user_channel_id } => { + assert_eq!(counterparty_node_id, expected_counterparty_node_id); assert_eq!(*channel_value_satoshis, expected_chan_value); assert_eq!(user_channel_id, expected_user_chan_id); @@ -573,7 +574,7 @@ pub fn create_funding_transaction<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, expected_ } } pub fn sign_funding_transaction<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: &Node<'a, 'b, 'c>, channel_value: u64, expected_temporary_channel_id: [u8; 32]) -> Transaction { - let (temporary_channel_id, tx, funding_output) = create_funding_transaction(node_a, channel_value, 42); + let (temporary_channel_id, tx, funding_output) = create_funding_transaction(node_a, &node_b.node.get_our_node_id(), channel_value, 42); assert_eq!(temporary_channel_id, expected_temporary_channel_id); assert!(node_a.node.funding_transaction_generated(&temporary_channel_id, tx.clone()).is_ok()); @@ -722,7 +723,7 @@ pub fn create_unannounced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: & let accept_channel = get_event_msg!(nodes[b], MessageSendEvent::SendAcceptChannel, nodes[a].node.get_our_node_id()); nodes[a].node.handle_accept_channel(&nodes[b].node.get_our_node_id(), b_flags, &accept_channel); - let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[a], channel_value, 42); + let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[a], &nodes[b].node.get_our_node_id(), channel_value, 42); nodes[a].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); nodes[b].node.handle_funding_created(&nodes[a].node.get_our_node_id(), &get_event_msg!(nodes[a], MessageSendEvent::SendFundingCreated, nodes[b].node.get_our_node_id())); check_added_monitors!(nodes[b], 1); diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index aa68454063a..49e06dab2d1 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -515,7 +515,7 @@ fn do_test_sanity_on_in_flight_opens(steps: u8) { if steps & 0x0f == 2 { return; } nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel); - let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 42); + let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); if steps & 0x0f == 3 { return; } nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); @@ -3506,7 +3506,7 @@ fn test_peer_disconnected_before_funding_broadcasted() { let accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id()); nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel); - let (temporary_channel_id, tx, _funding_output) = create_funding_transaction(&nodes[0], 1_000_000, 42); + let (temporary_channel_id, tx, _funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 1_000_000, 42); assert_eq!(temporary_channel_id, expected_temporary_channel_id); assert!(nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).is_ok()); @@ -4426,7 +4426,7 @@ fn test_manager_serialize_deserialize_events() { node_b.node.handle_open_channel(&node_a.node.get_our_node_id(), a_flags, &get_event_msg!(node_a, MessageSendEvent::SendOpenChannel, node_b.node.get_our_node_id())); node_a.node.handle_accept_channel(&node_b.node.get_our_node_id(), b_flags, &get_event_msg!(node_b, MessageSendEvent::SendAcceptChannel, node_a.node.get_our_node_id())); - let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&node_a, channel_value, 42); + let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&node_a, &node_b.node.get_our_node_id(), channel_value, 42); node_a.node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); check_added_monitors!(node_a, 0); @@ -8388,7 +8388,7 @@ fn test_reject_funding_before_inbound_channel_accepted() { nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_chan_msg); } - let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], 100000, 42); + let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); @@ -8875,7 +8875,7 @@ fn test_pre_lockin_no_chan_closed_update() { nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_chan_msg); // Move the first channel through the funding flow... - let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], 100000, 42); + let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); check_added_monitors!(nodes[0], 0); @@ -9164,7 +9164,7 @@ fn test_duplicate_chan_id() { } // Move the first channel through the funding flow... - let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], 100000, 42); + let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); check_added_monitors!(nodes[0], 0); @@ -9209,7 +9209,7 @@ fn test_duplicate_chan_id() { let open_chan_2_msg = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id()); nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_chan_2_msg); nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id())); - create_funding_transaction(&nodes[0], 100000, 42); // Get and check the FundingGenerationReady event + create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); // Get and check the FundingGenerationReady event let funding_created = { let mut a_channel_lock = nodes[0].node.channel_state.lock().unwrap(); @@ -9342,7 +9342,7 @@ fn test_invalid_funding_tx() { nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id())); nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id())); - let (temporary_channel_id, mut tx, _) = create_funding_transaction(&nodes[0], 100_000, 42); + let (temporary_channel_id, mut tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100_000, 42); for output in tx.output.iter_mut() { // Make the confirmed funding transaction have a bogus script_pubkey output.script_pubkey = bitcoin::Script::new(); @@ -9878,7 +9878,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e let opt_anchors = false; - let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], 1_000_000, 42); + let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 1_000_000, 42); if on_holder_tx { if let Some(mut chan) = nodes[0].node.channel_state.lock().unwrap().by_id.get_mut(&temporary_channel_id) { diff --git a/lightning/src/ln/priv_short_conf_tests.rs b/lightning/src/ln/priv_short_conf_tests.rs index d7b940eb90e..598262d90f9 100644 --- a/lightning/src/ln/priv_short_conf_tests.rs +++ b/lightning/src/ln/priv_short_conf_tests.rs @@ -389,7 +389,7 @@ fn test_inbound_scid_privacy() { let accept_channel = get_event_msg!(nodes[2], MessageSendEvent::SendAcceptChannel, nodes[1].node.get_our_node_id()); nodes[1].node.handle_accept_channel(&nodes[2].node.get_our_node_id(), InitFeatures::known(), &accept_channel); - let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[1], 100_000, 42); + let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[1], &nodes[2].node.get_our_node_id(), 100_000, 42); nodes[1].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); nodes[2].node.handle_funding_created(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingCreated, nodes[2].node.get_our_node_id())); check_added_monitors!(nodes[2], 1); diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index b67c2ec77b3..bebc75baf9b 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -162,8 +162,15 @@ pub enum Event { /// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated FundingGenerationReady { /// The random channel_id we picked which you'll need to pass into - /// ChannelManager::funding_transaction_generated. + /// [`ChannelManager::funding_transaction_generated`]. + /// + /// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated temporary_channel_id: [u8; 32], + /// The counterparty's node_id, which you'll need to pass back into + /// [`ChannelManager::funding_transaction_generated`]. + /// + /// [`ChannelManager::funding_transaction_generated`]: crate::ln::channelmanager::ChannelManager::funding_transaction_generated + counterparty_node_id: PublicKey, /// The value, in satoshis, that the output should have. channel_value_satoshis: u64, /// The script which should be used in the transaction output. From 84a6e7bc51f27f6be035989d1bb4012821952909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Tigerstr=C3=B6m?= <11711198+ViktorTigerstrom@users.noreply.github.com> Date: Thu, 12 May 2022 22:31:29 +0200 Subject: [PATCH 2/6] Pass `counterparty_node_id` to `close_channel` functions --- fuzz/src/full_stack.rs | 2 +- lightning/src/ln/chanmon_update_fail_tests.rs | 6 ++-- lightning/src/ln/channelmanager.rs | 19 +++++----- lightning/src/ln/functional_test_utils.rs | 2 +- lightning/src/ln/monitor_tests.rs | 2 +- lightning/src/ln/shutdown_tests.rs | 36 +++++++++---------- 6 files changed, 34 insertions(+), 33 deletions(-) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 2da065151d3..e1510b998e3 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -516,7 +516,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { let channel_id = get_slice!(1)[0] as usize; if channel_id >= channels.len() { return; } channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) }); - if channelmanager.close_channel(&channels[channel_id].channel_id).is_err() { return; } + if channelmanager.close_channel(&channels[channel_id].channel_id, &channels[channel_id].counterparty.node_id).is_err() { return; } }, 7 => { if should_forward { diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 15ad15d5b54..517277dd8e5 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -2538,7 +2538,7 @@ fn test_temporary_error_during_shutdown() { chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)); chanmon_cfgs[1].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)); - nodes[0].node.close_channel(&channel_id).unwrap(); + nodes[0].node.close_channel(&channel_id, &nodes[1].node.get_our_node_id()).unwrap(); nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id())); check_added_monitors!(nodes[1], 1); @@ -2591,7 +2591,7 @@ fn test_permanent_error_during_sending_shutdown() { let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2; chanmon_cfgs[0].persister.set_update_ret(Err(ChannelMonitorUpdateErr::PermanentFailure)); - assert!(nodes[0].node.close_channel(&channel_id).is_ok()); + assert!(nodes[0].node.close_channel(&channel_id, &nodes[1].node.get_our_node_id()).is_ok()); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 2); check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: "ChannelMonitor storage failure".to_string() }); @@ -2612,7 +2612,7 @@ fn test_permanent_error_during_handling_shutdown() { let channel_id = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()).2; chanmon_cfgs[1].persister.set_update_ret(Err(ChannelMonitorUpdateErr::PermanentFailure)); - assert!(nodes[0].node.close_channel(&channel_id).is_ok()); + assert!(nodes[0].node.close_channel(&channel_id, &nodes[1].node.get_our_node_id()).is_ok()); let shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()); nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &shutdown); check_closed_broadcast!(nodes[1], true); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index 5cc3e71931b..e365b582e60 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1769,17 +1769,18 @@ impl ChannelMana }); } - fn close_channel_internal(&self, channel_id: &[u8; 32], target_feerate_sats_per_1000_weight: Option) -> Result<(), APIError> { + fn close_channel_internal(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey, target_feerate_sats_per_1000_weight: Option) -> Result<(), APIError> { let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier); - let counterparty_node_id; let mut failed_htlcs: Vec<(HTLCSource, PaymentHash)>; let result: Result<(), _> = loop { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; match channel_state.by_id.entry(channel_id.clone()) { hash_map::Entry::Occupied(mut chan_entry) => { - counterparty_node_id = chan_entry.get().get_counterparty_node_id(); + if *counterparty_node_id != chan_entry.get().get_counterparty_node_id(){ + return Err(APIError::APIMisuseError { err: "The passed counterparty_node_id doesn't match the channel's counterparty node_id".to_owned() }); + } let per_peer_state = self.per_peer_state.read().unwrap(); let (shutdown_msg, monitor_update, htlcs) = match per_peer_state.get(&counterparty_node_id) { Some(peer_state) => { @@ -1804,7 +1805,7 @@ impl ChannelMana } channel_state.pending_msg_events.push(events::MessageSendEvent::SendShutdown { - node_id: counterparty_node_id, + node_id: *counterparty_node_id, msg: shutdown_msg }); @@ -1827,7 +1828,7 @@ impl ChannelMana self.fail_htlc_backwards_internal(self.channel_state.lock().unwrap(), htlc_source.0, &htlc_source.1, HTLCFailReason::Reason { failure_code: 0x4000 | 8, data: Vec::new() }); } - let _ = handle_error!(self, result, counterparty_node_id); + let _ = handle_error!(self, result, *counterparty_node_id); Ok(()) } @@ -1848,8 +1849,8 @@ impl ChannelMana /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`]: crate::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis /// [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background /// [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal - pub fn close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError> { - self.close_channel_internal(channel_id, None) + pub fn close_channel(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey) -> Result<(), APIError> { + self.close_channel_internal(channel_id, counterparty_node_id, None) } /// Begins the process of closing a channel. After this call (plus some timeout), no new HTLCs @@ -1871,8 +1872,8 @@ impl ChannelMana /// [`ChannelConfig::force_close_avoidance_max_fee_satoshis`]: crate::util::config::ChannelConfig::force_close_avoidance_max_fee_satoshis /// [`Background`]: crate::chain::chaininterface::ConfirmationTarget::Background /// [`Normal`]: crate::chain::chaininterface::ConfirmationTarget::Normal - pub fn close_channel_with_target_feerate(&self, channel_id: &[u8; 32], target_feerate_sats_per_1000_weight: u32) -> Result<(), APIError> { - self.close_channel_internal(channel_id, Some(target_feerate_sats_per_1000_weight)) + pub fn close_channel_with_target_feerate(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey, target_feerate_sats_per_1000_weight: u32) -> Result<(), APIError> { + self.close_channel_internal(channel_id, counterparty_node_id, Some(target_feerate_sats_per_1000_weight)) } #[inline] diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index 010a64f5668..ae3179be3d5 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -969,7 +969,7 @@ pub fn close_channel<'a, 'b, 'c>(outbound_node: &Node<'a, 'b, 'c>, inbound_node: let (node_b, broadcaster_b, struct_b) = if close_inbound_first { (&outbound_node.node, &outbound_node.tx_broadcaster, outbound_node) } else { (&inbound_node.node, &inbound_node.tx_broadcaster, inbound_node) }; let (tx_a, tx_b); - node_a.close_channel(channel_id).unwrap(); + node_a.close_channel(channel_id, &node_b.get_our_node_id()).unwrap(); node_b.handle_shutdown(&node_a.get_our_node_id(), &InitFeatures::known(), &get_event_msg!(struct_a, MessageSendEvent::SendShutdown, node_b.get_our_node_id())); let events_1 = node_b.get_and_clear_pending_msg_events(); diff --git a/lightning/src/ln/monitor_tests.rs b/lightning/src/ln/monitor_tests.rs index 6fa0aab9d31..af42644dd71 100644 --- a/lightning/src/ln/monitor_tests.rs +++ b/lightning/src/ln/monitor_tests.rs @@ -108,7 +108,7 @@ fn chanmon_claim_value_coop_close() { assert_eq!(vec![Balance::ClaimableOnChannelClose { claimable_amount_satoshis: 1_000, }], nodes[1].chain_monitor.chain_monitor.get_monitor(funding_outpoint).unwrap().get_claimable_balances()); - nodes[0].node.close_channel(&chan_id).unwrap(); + nodes[0].node.close_channel(&chan_id, &nodes[1].node.get_our_node_id()).unwrap(); let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()); nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown); let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); diff --git a/lightning/src/ln/shutdown_tests.rs b/lightning/src/ln/shutdown_tests.rs index 59004547b14..8716c7322f7 100644 --- a/lightning/src/ln/shutdown_tests.rs +++ b/lightning/src/ln/shutdown_tests.rs @@ -46,7 +46,7 @@ fn pre_funding_lock_shutdown_test() { mine_transaction(&nodes[0], &tx); mine_transaction(&nodes[1], &tx); - nodes[0].node.close_channel(&OutPoint { txid: tx.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[0].node.close_channel(&OutPoint { txid: tx.txid(), index: 0 }.to_channel_id(), &nodes[1].node.get_our_node_id()).unwrap(); let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()); nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown); let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); @@ -83,7 +83,7 @@ fn updates_shutdown_wait() { let (payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 100000); - nodes[0].node.close_channel(&chan_1.2).unwrap(); + nodes[0].node.close_channel(&chan_1.2, &nodes[1].node.get_our_node_id()).unwrap(); let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()); nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown); let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); @@ -166,7 +166,7 @@ fn htlc_fail_async_shutdown() { assert!(updates.update_fail_malformed_htlcs.is_empty()); assert!(updates.update_fee.is_none()); - nodes[1].node.close_channel(&chan_1.2).unwrap(); + nodes[1].node.close_channel(&chan_1.2, &nodes[0].node.get_our_node_id()).unwrap(); let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &InitFeatures::known(), &node_1_shutdown); let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()); @@ -232,7 +232,7 @@ fn do_test_shutdown_rebroadcast(recv_count: u8) { let (payment_preimage, _, _) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 100000); - nodes[1].node.close_channel(&chan_1.2).unwrap(); + nodes[1].node.close_channel(&chan_1.2, &nodes[0].node.get_our_node_id()).unwrap(); let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); if recv_count > 0 { nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &InitFeatures::known(), &node_1_shutdown); @@ -417,7 +417,7 @@ fn test_upfront_shutdown_script() { // We test that in case of peer committing upfront to a script, if it changes at closing, we refuse to sign let flags = InitFeatures::known(); let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone()); - nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[2].node.get_our_node_id()).unwrap(); let node_0_orig_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id()); let mut node_0_shutdown = node_0_orig_shutdown.clone(); node_0_shutdown.scriptpubkey = Builder::new().push_opcode(opcodes::all::OP_RETURN).into_script().to_p2sh(); @@ -432,7 +432,7 @@ fn test_upfront_shutdown_script() { // We test that in case of peer committing upfront to a script, if it doesn't change at closing, we sign let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 2, 1000000, 1000000, flags.clone(), flags.clone()); - nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[2].node.get_our_node_id()).unwrap(); let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id()); // We test that in case of peer committing upfront to a script, if it oesn't change at closing, we sign nodes[2].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown); @@ -446,7 +446,7 @@ fn test_upfront_shutdown_script() { // We test that if case of peer non-signaling we don't enforce committed script at channel opening let flags_no = InitFeatures::known().clear_upfront_shutdown_script(); let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags_no, flags.clone()); - nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[1].node.get_our_node_id()).unwrap(); let node_1_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()); nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_1_shutdown); check_added_monitors!(nodes[1], 1); @@ -460,7 +460,7 @@ fn test_upfront_shutdown_script() { // We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close // channel smoothly, opt-out is from channel initiator here let chan = create_announced_chan_between_nodes_with_value(&nodes, 1, 0, 1000000, 1000000, flags.clone(), flags.clone()); - nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap(); check_added_monitors!(nodes[1], 1); let node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown); @@ -474,7 +474,7 @@ fn test_upfront_shutdown_script() { //// We test that if user opt-out, we provide a zero-length script at channel opening and we are able to close //// channel smoothly let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000, flags.clone(), flags.clone()); - nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap(); check_added_monitors!(nodes[1], 1); let node_0_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); nodes[0].node.handle_shutdown(&nodes[1].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown); @@ -580,7 +580,7 @@ fn test_segwit_v0_shutdown_script() { let nodes = create_network(3, &node_cfgs, &node_chanmgrs); let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); - nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap(); check_added_monitors!(nodes[1], 1); // Use a segwit v0 script supported even without option_shutdown_anysegwit @@ -615,7 +615,7 @@ fn test_anysegwit_shutdown_script() { let nodes = create_network(3, &node_cfgs, &node_chanmgrs); let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); - nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap(); check_added_monitors!(nodes[1], 1); // Use a non-v0 segwit script supported by option_shutdown_anysegwit @@ -660,14 +660,14 @@ fn test_unsupported_anysegwit_shutdown_script() { .expect(OnGetShutdownScriptpubkey { returns: supported_shutdown_script }); let chan = create_announced_chan_between_nodes(&nodes, 0, 1, node_cfgs[0].features.clone(), node_cfgs[1].features.clone()); - match nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()) { + match nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()) { Err(APIError::IncompatibleShutdownScript { script }) => { assert_eq!(script.into_inner(), unsupported_shutdown_script.clone().into_inner()); }, Err(e) => panic!("Unexpected error: {:?}", e), Ok(_) => panic!("Expected error"), } - nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap(); check_added_monitors!(nodes[1], 1); // Use a non-v0 segwit script unsupported without option_shutdown_anysegwit @@ -692,7 +692,7 @@ fn test_invalid_shutdown_script() { let nodes = create_network(3, &node_cfgs, &node_chanmgrs); let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); - nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[1].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[0].node.get_our_node_id()).unwrap(); check_added_monitors!(nodes[1], 1); // Use a segwit v0 script with an unsupported witness program @@ -730,7 +730,7 @@ fn do_test_closing_signed_reinit_timeout(timeout_step: TimeoutStep) { send_payment(&nodes[0], &[&nodes[1]], 8_000_000); - nodes[0].node.close_channel(&chan_id).unwrap(); + nodes[0].node.close_channel(&chan_id, &nodes[1].node.get_our_node_id()).unwrap(); let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()); nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown); let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); @@ -831,7 +831,7 @@ fn do_simple_legacy_shutdown_test(high_initiator_fee: bool) { *feerate_lock *= 10; } - nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[0].node.close_channel(&OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(), &nodes[1].node.get_our_node_id()).unwrap(); let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()); nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown); let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); @@ -873,9 +873,9 @@ fn simple_target_feerate_shutdown() { let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); let chan_id = OutPoint { txid: chan.3.txid(), index: 0 }.to_channel_id(); - nodes[0].node.close_channel_with_target_feerate(&chan_id, 253 * 10).unwrap(); + nodes[0].node.close_channel_with_target_feerate(&chan_id, &nodes[1].node.get_our_node_id(), 253 * 10).unwrap(); let node_0_shutdown = get_event_msg!(nodes[0], MessageSendEvent::SendShutdown, nodes[1].node.get_our_node_id()); - nodes[1].node.close_channel_with_target_feerate(&chan_id, 253 * 5).unwrap(); + nodes[1].node.close_channel_with_target_feerate(&chan_id, &nodes[0].node.get_our_node_id(), 253 * 5).unwrap(); let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[0].node.get_our_node_id()); nodes[1].node.handle_shutdown(&nodes[0].node.get_our_node_id(), &InitFeatures::known(), &node_0_shutdown); From 14e52cd7a6382fdd71ce090a81eac9da3b9318de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Tigerstr=C3=B6m?= <11711198+ViktorTigerstrom@users.noreply.github.com> Date: Thu, 12 May 2022 23:26:32 +0200 Subject: [PATCH 3/6] Pass `counterparty_node_id` to `force_close_channel` --- fuzz/src/full_stack.rs | 2 +- lightning-background-processor/src/lib.rs | 4 +-- lightning-persister/src/lib.rs | 6 ++-- lightning/src/ln/chanmon_update_fail_tests.rs | 2 +- lightning/src/ln/channelmanager.rs | 30 +++++++++---------- lightning/src/ln/functional_tests.rs | 24 +++++++++------ lightning/src/ln/payment_tests.rs | 2 +- 7 files changed, 37 insertions(+), 33 deletions(-) diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index e1510b998e3..83a9396b526 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -624,7 +624,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { let channel_id = get_slice!(1)[0] as usize; if channel_id >= channels.len() { return; } channels.sort_by(|a, b| { a.channel_id.cmp(&b.channel_id) }); - channelmanager.force_close_channel(&channels[channel_id].channel_id).unwrap(); + channelmanager.force_close_channel(&channels[channel_id].channel_id, &channels[channel_id].counterparty.node_id).unwrap(); }, // 15 is above _ => return, diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index a0ac265ea6b..a4c6fcacae8 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -637,7 +637,7 @@ mod tests { } // Force-close the channel. - nodes[0].node.force_close_channel(&OutPoint { txid: tx.txid(), index: 0 }.to_channel_id()).unwrap(); + nodes[0].node.force_close_channel(&OutPoint { txid: tx.txid(), index: 0 }.to_channel_id(), &nodes[1].node.get_our_node_id()).unwrap(); // Check that the force-close updates are persisted. check_persisted_data!(nodes[0].node, filepath.clone()); @@ -776,7 +776,7 @@ mod tests { let bg_processor = BackgroundProcessor::start(persister, event_handler, nodes[0].chain_monitor.clone(), nodes[0].node.clone(), nodes[0].net_graph_msg_handler.clone(), nodes[0].peer_manager.clone(), nodes[0].logger.clone(), Some(nodes[0].scorer.clone())); // Force close the channel and check that the SpendableOutputs event was handled. - nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap(); + nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id, &nodes[1].node.get_our_node_id()).unwrap(); let commitment_tx = nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().pop().unwrap(); confirm_transaction_depth(&mut nodes[0], &commitment_tx, BREAKDOWN_TIMEOUT as u32); let event = receiver diff --git a/lightning-persister/src/lib.rs b/lightning-persister/src/lib.rs index c23baf8ad34..28845150c44 100644 --- a/lightning-persister/src/lib.rs +++ b/lightning-persister/src/lib.rs @@ -213,7 +213,7 @@ mod tests { // Force close because cooperative close doesn't result in any persisted // updates. - nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap(); + nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id, &nodes[1].node.get_our_node_id()).unwrap(); check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); @@ -247,7 +247,7 @@ mod tests { let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); - nodes[1].node.force_close_channel(&chan.2).unwrap(); + nodes[1].node.force_close_channel(&chan.2, &nodes[0].node.get_our_node_id()).unwrap(); check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed); let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap(); let update_map = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap(); @@ -286,7 +286,7 @@ mod tests { let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]); let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let chan = create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); - nodes[1].node.force_close_channel(&chan.2).unwrap(); + nodes[1].node.force_close_channel(&chan.2, &nodes[0].node.get_our_node_id()).unwrap(); check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed); let mut added_monitors = nodes[1].chain_monitor.added_monitors.lock().unwrap(); let update_map = nodes[1].chain_monitor.latest_monitor_update_id.lock().unwrap(); diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 517277dd8e5..11a22569e8d 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -224,7 +224,7 @@ fn do_test_simple_monitor_temporary_update_fail(disconnect: bool) { } // ...and make sure we can force-close a frozen channel - nodes[0].node.force_close_channel(&channel_id).unwrap(); + nodes[0].node.force_close_channel(&channel_id, &nodes[1].node.get_our_node_id()).unwrap(); check_added_monitors!(nodes[0], 1); check_closed_broadcast!(nodes[0], true); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index e365b582e60..f89aef6163c 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -1892,22 +1892,18 @@ impl ChannelMana } } - /// `peer_node_id` should be set when we receive a message from a peer, but not set when the + /// `peer_msg` should be set when we receive a message from a peer, but not set when the /// user closes, which will be re-exposed as the `ChannelClosed` reason. - fn force_close_channel_with_peer(&self, channel_id: &[u8; 32], peer_node_id: Option<&PublicKey>, peer_msg: Option<&String>) -> Result { + fn force_close_channel_with_peer(&self, channel_id: &[u8; 32], peer_node_id: &PublicKey, peer_msg: Option<&String>) -> Result { let mut chan = { let mut channel_state_lock = self.channel_state.lock().unwrap(); let channel_state = &mut *channel_state_lock; if let hash_map::Entry::Occupied(chan) = channel_state.by_id.entry(channel_id.clone()) { - if let Some(node_id) = peer_node_id { - if chan.get().get_counterparty_node_id() != *node_id { - return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()}); - } + if chan.get().get_counterparty_node_id() != *peer_node_id { + return Err(APIError::ChannelUnavailable{err: "No such channel".to_owned()}); } - if peer_node_id.is_some() { - if let Some(peer_msg) = peer_msg { - self.issue_channel_close_events(chan.get(),ClosureReason::CounterpartyForceClosed { peer_msg: peer_msg.to_string() }); - } + if let Some(peer_msg) = peer_msg { + self.issue_channel_close_events(chan.get(),ClosureReason::CounterpartyForceClosed { peer_msg: peer_msg.to_string() }); } else { self.issue_channel_close_events(chan.get(),ClosureReason::HolderForceClosed); } @@ -1929,10 +1925,12 @@ impl ChannelMana } /// Force closes a channel, immediately broadcasting the latest local commitment transaction to - /// the chain and rejecting new HTLCs on the given channel. Fails if channel_id is unknown to the manager. - pub fn force_close_channel(&self, channel_id: &[u8; 32]) -> Result<(), APIError> { + /// the chain and rejecting new HTLCs on the given channel. Fails if `channel_id` is unknown to + /// the manager, or if the `counterparty_node_id` isn't the counterparty of the corresponding + /// channel. + pub fn force_close_channel(&self, channel_id: &[u8; 32], counterparty_node_id: &PublicKey) -> Result<(), APIError> { let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier); - match self.force_close_channel_with_peer(channel_id, None, None) { + match self.force_close_channel_with_peer(channel_id, counterparty_node_id, None) { Ok(counterparty_node_id) => { self.channel_state.lock().unwrap().pending_msg_events.push( events::MessageSendEvent::HandleError { @@ -1952,7 +1950,7 @@ impl ChannelMana /// for each to the chain and rejecting new HTLCs on each. pub fn force_close_all_channels(&self) { for chan in self.list_channels() { - let _ = self.force_close_channel(&chan.channel_id); + let _ = self.force_close_channel(&chan.channel_id, &chan.counterparty.node_id); } } @@ -5816,7 +5814,7 @@ impl for chan in self.list_channels() { if chan.counterparty.node_id == *counterparty_node_id { // Untrusted messages from peer, we throw away the error if id points to a non-existent channel - let _ = self.force_close_channel_with_peer(&chan.channel_id, Some(counterparty_node_id), Some(&msg.data)); + let _ = self.force_close_channel_with_peer(&chan.channel_id, counterparty_node_id, Some(&msg.data)); } } } else { @@ -5838,7 +5836,7 @@ impl } // Untrusted messages from peer, we throw away the error if id points to a non-existent channel - let _ = self.force_close_channel_with_peer(&msg.channel_id, Some(counterparty_node_id), Some(&msg.data)); + let _ = self.force_close_channel_with_peer(&msg.channel_id, counterparty_node_id, Some(&msg.data)); } } } diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 49e06dab2d1..8fe1277c977 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -3362,7 +3362,7 @@ fn test_htlc_ignore_latest_remote_commitment() { create_announced_chan_between_nodes(&nodes, 0, 1, InitFeatures::known(), InitFeatures::known()); route_payment(&nodes[0], &[&nodes[1]], 10000000); - nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap(); + nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id, &nodes[1].node.get_our_node_id()).unwrap(); connect_blocks(&nodes[0], TEST_FINAL_CLTV + LATENCY_GRACE_PERIOD_BLOCKS + 1); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); @@ -3425,7 +3425,7 @@ fn test_force_close_fail_back() { // state or updated nodes[1]' state. Now force-close and broadcast that commitment/HTLC // transaction and ensure nodes[1] doesn't fail-backwards (this was originally a bug!). - nodes[2].node.force_close_channel(&payment_event.commitment_msg.channel_id).unwrap(); + nodes[2].node.force_close_channel(&payment_event.commitment_msg.channel_id, &nodes[1].node.get_our_node_id()).unwrap(); check_closed_broadcast!(nodes[2], true); check_added_monitors!(nodes[2], 1); check_closed_event!(nodes[2], 1, ClosureReason::HolderForceClosed); @@ -4749,7 +4749,7 @@ fn test_claim_sizeable_push_msat() { let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 98_000_000, InitFeatures::known(), InitFeatures::known()); - nodes[1].node.force_close_channel(&chan.2).unwrap(); + nodes[1].node.force_close_channel(&chan.2, &nodes[0].node.get_our_node_id()).unwrap(); check_closed_broadcast!(nodes[1], true); check_added_monitors!(nodes[1], 1); check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed); @@ -4778,7 +4778,7 @@ fn test_claim_on_remote_sizeable_push_msat() { let nodes = create_network(2, &node_cfgs, &node_chanmgrs); let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, 98_000_000, InitFeatures::known(), InitFeatures::known()); - nodes[0].node.force_close_channel(&chan.2).unwrap(); + nodes[0].node.force_close_channel(&chan.2, &nodes[1].node.get_our_node_id()).unwrap(); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed); @@ -8298,7 +8298,7 @@ fn test_manually_accept_inbound_channel_request() { _ => panic!("Unexpected event"), } - nodes[1].node.force_close_channel(&temp_channel_id).unwrap(); + nodes[1].node.force_close_channel(&temp_channel_id, &nodes[0].node.get_our_node_id()).unwrap(); let close_msg_ev = nodes[1].node.get_and_clear_pending_msg_events(); assert_eq!(close_msg_ev.len(), 1); @@ -8333,7 +8333,7 @@ fn test_manually_reject_inbound_channel_request() { let events = nodes[1].node.get_and_clear_pending_events(); match events[0] { Event::OpenChannelRequest { temporary_channel_id, .. } => { - nodes[1].node.force_close_channel(&temporary_channel_id).unwrap(); + nodes[1].node.force_close_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id()).unwrap(); } _ => panic!("Unexpected event"), } @@ -8975,8 +8975,14 @@ fn do_test_onchain_htlc_settlement_after_close(broadcast_alice: bool, go_onchain // If `go_onchain_before_fufill`, broadcast the relevant commitment transaction and check that Bob // responds by (1) broadcasting a channel update and (2) adding a new ChannelMonitor. let mut force_closing_node = 0; // Alice force-closes - if !broadcast_alice { force_closing_node = 1; } // Bob force-closes - nodes[force_closing_node].node.force_close_channel(&chan_ab.2).unwrap(); + let mut counterparty_node = 1; // Bob if Alice force-closes + + // Bob force-closes + if !broadcast_alice { + force_closing_node = 1; + counterparty_node = 0; + } + nodes[force_closing_node].node.force_close_channel(&chan_ab.2, &nodes[counterparty_node].node.get_our_node_id()).unwrap(); check_closed_broadcast!(nodes[force_closing_node], true); check_added_monitors!(nodes[force_closing_node], 1); check_closed_event!(nodes[force_closing_node], 1, ClosureReason::HolderForceClosed); @@ -9406,7 +9412,7 @@ fn do_test_tx_confirmed_skipping_blocks_immediate_broadcast(test_height_before_t nodes[1].node.peer_disconnected(&nodes[2].node.get_our_node_id(), false); nodes[2].node.peer_disconnected(&nodes[1].node.get_our_node_id(), false); - nodes[1].node.force_close_channel(&channel_id).unwrap(); + nodes[1].node.force_close_channel(&channel_id, &nodes[2].node.get_our_node_id()).unwrap(); check_closed_broadcast!(nodes[1], true); check_closed_event!(nodes[1], 1, ClosureReason::HolderForceClosed); check_added_monitors!(nodes[1], 1); diff --git a/lightning/src/ln/payment_tests.rs b/lightning/src/ln/payment_tests.rs index 46d5d22b49a..336e99a5c44 100644 --- a/lightning/src/ln/payment_tests.rs +++ b/lightning/src/ln/payment_tests.rs @@ -565,7 +565,7 @@ fn do_test_dup_htlc_onchain_fails_on_reload(persist_manager_post_event: bool, co // Route a payment, but force-close the channel before the HTLC fulfill message arrives at // nodes[0]. let (payment_preimage, payment_hash, _) = route_payment(&nodes[0], &[&nodes[1]], 10000000); - nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id).unwrap(); + nodes[0].node.force_close_channel(&nodes[0].node.list_channels()[0].channel_id, &nodes[1].node.get_our_node_id()).unwrap(); check_closed_broadcast!(nodes[0], true); check_added_monitors!(nodes[0], 1); check_closed_event!(nodes[0], 1, ClosureReason::HolderForceClosed); From c581bab8bea05899fec923f1ce6fcdbb2a9e3d97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Tigerstr=C3=B6m?= <11711198+ViktorTigerstrom@users.noreply.github.com> Date: Thu, 12 May 2022 23:59:41 +0200 Subject: [PATCH 4/6] Pass `counterparty_node_id` to `funding_transaction_generated` --- fuzz/src/chanmon_consistency.rs | 2 +- fuzz/src/full_stack.rs | 2 +- lightning-background-processor/src/lib.rs | 2 +- lightning/src/ln/chanmon_update_fail_tests.rs | 2 +- lightning/src/ln/channelmanager.rs | 15 ++++++++------- lightning/src/ln/functional_test_utils.rs | 6 +++--- lightning/src/ln/functional_tests.rs | 16 ++++++++-------- lightning/src/ln/priv_short_conf_tests.rs | 2 +- 8 files changed, 24 insertions(+), 23 deletions(-) diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs index 8472f8fa627..a86f1e5e011 100644 --- a/fuzz/src/chanmon_consistency.rs +++ b/fuzz/src/chanmon_consistency.rs @@ -442,7 +442,7 @@ pub fn do_test(data: &[u8], underlying_out: Out) { value: *channel_value_satoshis, script_pubkey: output_script.clone(), }]}; funding_output = OutPoint { txid: tx.txid(), index: 0 }; - $source.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + $source.funding_transaction_generated(&temporary_channel_id, &$dest.get_our_node_id(), tx.clone()).unwrap(); channel_txn.push(tx); } else { panic!("Wrong event type"); } } diff --git a/fuzz/src/full_stack.rs b/fuzz/src/full_stack.rs index 83a9396b526..e3c8290b16e 100644 --- a/fuzz/src/full_stack.rs +++ b/fuzz/src/full_stack.rs @@ -575,7 +575,7 @@ pub fn do_test(data: &[u8], logger: &Arc) { continue 'outer_loop; } }; - if let Err(e) = channelmanager.funding_transaction_generated(&funding_generation.0, tx.clone()) { + if let Err(e) = channelmanager.funding_transaction_generated(&funding_generation.0, &funding_generation.1, tx.clone()) { // It's possible the channel has been closed in the mean time, but any other // failure may be a bug. if let APIError::ChannelUnavailable { err } = e { diff --git a/lightning-background-processor/src/lib.rs b/lightning-background-processor/src/lib.rs index a4c6fcacae8..ef37e5f9f9f 100644 --- a/lightning-background-processor/src/lib.rs +++ b/lightning-background-processor/src/lib.rs @@ -556,7 +556,7 @@ mod tests { macro_rules! end_open_channel { ($node_a: expr, $node_b: expr, $temporary_channel_id: expr, $tx: expr) => {{ - $node_a.node.funding_transaction_generated(&$temporary_channel_id, $tx.clone()).unwrap(); + $node_a.node.funding_transaction_generated(&$temporary_channel_id, &$node_b.node.get_our_node_id(), $tx.clone()).unwrap(); $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())); $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())); }} diff --git a/lightning/src/ln/chanmon_update_fail_tests.rs b/lightning/src/ln/chanmon_update_fail_tests.rs index 11a22569e8d..4001f6a9299 100644 --- a/lightning/src/ln/chanmon_update_fail_tests.rs +++ b/lightning/src/ln/chanmon_update_fail_tests.rs @@ -1811,7 +1811,7 @@ fn do_during_funding_monitor_fail(confirm_a_first: bool, restore_b_before_conf: let (temporary_channel_id, funding_tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 43); - nodes[0].node.funding_transaction_generated(&temporary_channel_id, funding_tx.clone()).unwrap(); + nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), funding_tx.clone()).unwrap(); check_added_monitors!(nodes[0], 0); chanmon_cfgs[1].persister.set_update_ret(Err(ChannelMonitorUpdateErr::TemporaryFailure)); diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index f89aef6163c..d40c3bb4c1d 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -2686,8 +2686,9 @@ impl ChannelMana /// Handles the generation of a funding transaction, optionally (for tests) with a function /// which checks the correctness of the funding transaction given the associated channel. - fn funding_transaction_generated_intern, &Transaction) -> Result> - (&self, temporary_channel_id: &[u8; 32], funding_transaction: Transaction, find_funding_output: FundingOutput) -> Result<(), APIError> { + fn funding_transaction_generated_intern, &Transaction) -> Result>( + &self, temporary_channel_id: &[u8; 32], _counterparty_node_id: &PublicKey, funding_transaction: Transaction, find_funding_output: FundingOutput + ) -> Result<(), APIError> { let (chan, msg) = { let (res, chan) = match self.channel_state.lock().unwrap().by_id.remove(temporary_channel_id) { Some(mut chan) => { @@ -2728,8 +2729,8 @@ impl ChannelMana } #[cfg(test)] - pub(crate) fn funding_transaction_generated_unchecked(&self, temporary_channel_id: &[u8; 32], funding_transaction: Transaction, output_index: u16) -> Result<(), APIError> { - self.funding_transaction_generated_intern(temporary_channel_id, funding_transaction, |_, tx| { + pub(crate) fn funding_transaction_generated_unchecked(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, funding_transaction: Transaction, output_index: u16) -> Result<(), APIError> { + self.funding_transaction_generated_intern(temporary_channel_id, counterparty_node_id, funding_transaction, |_, tx| { Ok(OutPoint { txid: tx.txid(), index: output_index }) }) } @@ -2756,7 +2757,7 @@ impl ChannelMana /// /// [`Event::FundingGenerationReady`]: crate::util::events::Event::FundingGenerationReady /// [`Event::ChannelClosed`]: crate::util::events::Event::ChannelClosed - pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_transaction: Transaction) -> Result<(), APIError> { + pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, funding_transaction: Transaction) -> Result<(), APIError> { let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier); for inp in funding_transaction.input.iter() { @@ -2766,7 +2767,7 @@ impl ChannelMana }); } } - self.funding_transaction_generated_intern(temporary_channel_id, funding_transaction, |chan, tx| { + self.funding_transaction_generated_intern(temporary_channel_id, counterparty_node_id, funding_transaction, |chan, tx| { let mut output_index = None; let expected_spk = chan.get_funding_redeemscript().to_v0_p2wsh(); for (idx, outp) in tx.output.iter().enumerate() { @@ -7424,7 +7425,7 @@ pub mod bench { tx = Transaction { version: 2, lock_time: 0, input: Vec::new(), output: vec![TxOut { value: 8_000_000, script_pubkey: output_script, }]}; - node_a.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + node_a.funding_transaction_generated(&temporary_channel_id, &node_b.get_our_node_id(), tx.clone()).unwrap(); } else { panic!(); } node_b.handle_funding_created(&node_a.get_our_node_id(), &get_event_msg!(node_a_holder, MessageSendEvent::SendFundingCreated, node_b.get_our_node_id())); diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs index ae3179be3d5..fed5fe289e7 100644 --- a/lightning/src/ln/functional_test_utils.rs +++ b/lightning/src/ln/functional_test_utils.rs @@ -577,7 +577,7 @@ pub fn sign_funding_transaction<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: & let (temporary_channel_id, tx, funding_output) = create_funding_transaction(node_a, &node_b.node.get_our_node_id(), channel_value, 42); assert_eq!(temporary_channel_id, expected_temporary_channel_id); - assert!(node_a.node.funding_transaction_generated(&temporary_channel_id, tx.clone()).is_ok()); + assert!(node_a.node.funding_transaction_generated(&temporary_channel_id, &node_b.node.get_our_node_id(), tx.clone()).is_ok()); check_added_monitors!(node_a, 0); let funding_created_msg = get_event_msg!(node_a, MessageSendEvent::SendFundingCreated, node_b.node.get_our_node_id()); @@ -606,7 +606,7 @@ pub fn sign_funding_transaction<'a, 'b, 'c>(node_a: &Node<'a, 'b, 'c>, node_b: & node_a.tx_broadcaster.txn_broadcasted.lock().unwrap().clear(); // Ensure that funding_transaction_generated is idempotent. - assert!(node_a.node.funding_transaction_generated(&temporary_channel_id, tx.clone()).is_err()); + assert!(node_a.node.funding_transaction_generated(&temporary_channel_id, &node_b.node.get_our_node_id(), tx.clone()).is_err()); assert!(node_a.node.get_and_clear_pending_msg_events().is_empty()); check_added_monitors!(node_a, 0); @@ -724,7 +724,7 @@ pub fn create_unannounced_chan_between_nodes_with_value<'a, 'b, 'c, 'd>(nodes: & nodes[a].node.handle_accept_channel(&nodes[b].node.get_our_node_id(), b_flags, &accept_channel); let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[a], &nodes[b].node.get_our_node_id(), channel_value, 42); - nodes[a].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + nodes[a].node.funding_transaction_generated(&temporary_channel_id, &nodes[b].node.get_our_node_id(), tx.clone()).unwrap(); nodes[b].node.handle_funding_created(&nodes[a].node.get_our_node_id(), &get_event_msg!(nodes[a], MessageSendEvent::SendFundingCreated, nodes[b].node.get_our_node_id())); check_added_monitors!(nodes[b], 1); diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index 8fe1277c977..f25875d2432 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -518,7 +518,7 @@ fn do_test_sanity_on_in_flight_opens(steps: u8) { let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); if steps & 0x0f == 3 { return; } - nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap(); check_added_monitors!(nodes[0], 0); let funding_created = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); @@ -3509,7 +3509,7 @@ fn test_peer_disconnected_before_funding_broadcasted() { let (temporary_channel_id, tx, _funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 1_000_000, 42); assert_eq!(temporary_channel_id, expected_temporary_channel_id); - assert!(nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).is_ok()); + assert!(nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).is_ok()); let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); assert_eq!(funding_created_msg.temporary_channel_id, expected_temporary_channel_id); @@ -4428,7 +4428,7 @@ fn test_manager_serialize_deserialize_events() { let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&node_a, &node_b.node.get_our_node_id(), channel_value, 42); - node_a.node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + node_a.node.funding_transaction_generated(&temporary_channel_id, &node_b.node.get_our_node_id(), tx.clone()).unwrap(); check_added_monitors!(node_a, 0); 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())); @@ -8390,7 +8390,7 @@ fn test_reject_funding_before_inbound_channel_accepted() { let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); - nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap(); let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); // The `funding_created_msg` should be rejected by `nodes[1]` as it hasn't accepted the channel @@ -8877,7 +8877,7 @@ fn test_pre_lockin_no_chan_closed_update() { // Move the first channel through the funding flow... let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); - nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap(); check_added_monitors!(nodes[0], 0); let funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); @@ -9172,7 +9172,7 @@ fn test_duplicate_chan_id() { // Move the first channel through the funding flow... let (temporary_channel_id, tx, funding_output) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42); - nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap(); check_added_monitors!(nodes[0], 0); let mut funding_created_msg = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id()); @@ -9354,7 +9354,7 @@ fn test_invalid_funding_tx() { output.script_pubkey = bitcoin::Script::new(); } - nodes[0].node.funding_transaction_generated_unchecked(&temporary_channel_id, tx.clone(), 0).unwrap(); + nodes[0].node.funding_transaction_generated_unchecked(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone(), 0).unwrap(); nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id())); check_added_monitors!(nodes[1], 1); @@ -9892,7 +9892,7 @@ fn do_test_max_dust_htlc_exposure(dust_outbound_balance: bool, exposure_breach_e } } - nodes[0].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap(); nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id())); check_added_monitors!(nodes[1], 1); diff --git a/lightning/src/ln/priv_short_conf_tests.rs b/lightning/src/ln/priv_short_conf_tests.rs index 598262d90f9..47e2fb33e3c 100644 --- a/lightning/src/ln/priv_short_conf_tests.rs +++ b/lightning/src/ln/priv_short_conf_tests.rs @@ -390,7 +390,7 @@ fn test_inbound_scid_privacy() { nodes[1].node.handle_accept_channel(&nodes[2].node.get_our_node_id(), InitFeatures::known(), &accept_channel); let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[1], &nodes[2].node.get_our_node_id(), 100_000, 42); - nodes[1].node.funding_transaction_generated(&temporary_channel_id, tx.clone()).unwrap(); + nodes[1].node.funding_transaction_generated(&temporary_channel_id, &nodes[2].node.get_our_node_id(), tx.clone()).unwrap(); nodes[2].node.handle_funding_created(&nodes[1].node.get_our_node_id(), &get_event_msg!(nodes[1], MessageSendEvent::SendFundingCreated, nodes[2].node.get_our_node_id())); check_added_monitors!(nodes[2], 1); From 70fa46592465e4bbdf1e2cb34346c36486baefbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Tigerstr=C3=B6m?= <11711198+ViktorTigerstrom@users.noreply.github.com> Date: Fri, 13 May 2022 00:13:39 +0200 Subject: [PATCH 5/6] Pass `counterparty_node_id` to `accept_inbound_channel` --- lightning/src/ln/channelmanager.rs | 9 +++++++-- lightning/src/ln/functional_tests.rs | 16 ++++++++-------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/lightning/src/ln/channelmanager.rs b/lightning/src/ln/channelmanager.rs index d40c3bb4c1d..8e39e87185b 100644 --- a/lightning/src/ln/channelmanager.rs +++ b/lightning/src/ln/channelmanager.rs @@ -4112,7 +4112,9 @@ impl ChannelMana /// Called to accept a request to open a channel after [`Event::OpenChannelRequest`] has been /// triggered. /// - /// The `temporary_channel_id` parameter indicates which inbound channel should be accepted. + /// The `temporary_channel_id` parameter indicates which inbound channel should be accepted, + /// and the `counterparty_node_id` parameter is the id of the peer which has requested to open + /// the channel. /// /// For inbound channels, the `user_channel_id` parameter will be provided back in /// [`Event::ChannelClosed::user_channel_id`] to allow tracking of which events correspond @@ -4120,7 +4122,7 @@ impl ChannelMana /// /// [`Event::OpenChannelRequest`]: events::Event::OpenChannelRequest /// [`Event::ChannelClosed::user_channel_id`]: events::Event::ChannelClosed::user_channel_id - pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], user_channel_id: u64) -> Result<(), APIError> { + pub fn accept_inbound_channel(&self, temporary_channel_id: &[u8; 32], counterparty_node_id: &PublicKey, user_channel_id: u64) -> Result<(), APIError> { let _persistence_guard = PersistenceNotifierGuard::notify_on_drop(&self.total_consistency_lock, &self.persistence_notifier); let mut channel_state_lock = self.channel_state.lock().unwrap(); @@ -4130,6 +4132,9 @@ impl ChannelMana if !channel.get().inbound_is_awaiting_accept() { return Err(APIError::APIMisuseError { err: "The channel isn't currently awaiting to be accepted.".to_owned() }); } + if *counterparty_node_id != channel.get().get_counterparty_node_id() { + return Err(APIError::APIMisuseError { err: "The passed counterparty_node_id doesn't match the channel's counterparty node_id".to_owned() }); + } channel_state.pending_msg_events.push(events::MessageSendEvent::SendAcceptChannel { node_id: channel.get().get_counterparty_node_id(), msg: channel.get_mut().accept_inbound_channel(user_channel_id), diff --git a/lightning/src/ln/functional_tests.rs b/lightning/src/ln/functional_tests.rs index f25875d2432..5f24314a29f 100644 --- a/lightning/src/ln/functional_tests.rs +++ b/lightning/src/ln/functional_tests.rs @@ -8283,7 +8283,7 @@ fn test_manually_accept_inbound_channel_request() { let events = nodes[1].node.get_and_clear_pending_events(); match events[0] { Event::OpenChannelRequest { temporary_channel_id, .. } => { - nodes[1].node.accept_inbound_channel(&temporary_channel_id, 23).unwrap(); + nodes[1].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 23).unwrap(); } _ => panic!("Unexpected event"), } @@ -8433,8 +8433,8 @@ fn test_can_not_accept_inbound_channel_twice() { let events = nodes[1].node.get_and_clear_pending_events(); match events[0] { Event::OpenChannelRequest { temporary_channel_id, .. } => { - nodes[1].node.accept_inbound_channel(&temporary_channel_id, 0).unwrap(); - let api_res = nodes[1].node.accept_inbound_channel(&temporary_channel_id, 0); + nodes[1].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap(); + let api_res = nodes[1].node.accept_inbound_channel(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0); match api_res { Err(APIError::APIMisuseError { err }) => { assert_eq!(err, "The channel isn't currently awaiting to be accepted."); @@ -8460,13 +8460,13 @@ fn test_can_not_accept_inbound_channel_twice() { #[test] fn test_can_not_accept_unknown_inbound_channel() { - let chanmon_cfg = create_chanmon_cfgs(1); - let node_cfg = create_node_cfgs(1, &chanmon_cfg); - let node_chanmgr = create_node_chanmgrs(1, &node_cfg, &[None]); - let node = create_network(1, &node_cfg, &node_chanmgr)[0].node; + let chanmon_cfg = create_chanmon_cfgs(2); + let node_cfg = create_node_cfgs(2, &chanmon_cfg); + let node_chanmgr = create_node_chanmgrs(2, &node_cfg, &[None, None]); + let nodes = create_network(2, &node_cfg, &node_chanmgr); let unknown_channel_id = [0; 32]; - let api_res = node.accept_inbound_channel(&unknown_channel_id, 0); + let api_res = nodes[0].node.accept_inbound_channel(&unknown_channel_id, &nodes[1].node.get_our_node_id(), 0); match api_res { Err(APIError::ChannelUnavailable { err }) => { assert_eq!(err, "Can't accept a channel that doesn't exist"); From c1798443b0de8999d4f8303faf8fcfb267c4ed78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Viktor=20Tigerstr=C3=B6m?= <11711198+ViktorTigerstrom@users.noreply.github.com> Date: Fri, 13 May 2022 23:52:20 +0200 Subject: [PATCH 6/6] Update `OpenChannelRequest` documentation As the `counterparty_node_id` is now required to be passed back to the `ChannelManager` to accept or reject an inbound channel request, the documentation is updated to reflect that. --- lightning/src/util/events.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lightning/src/util/events.rs b/lightning/src/util/events.rs index bebc75baf9b..dd97d964552 100644 --- a/lightning/src/util/events.rs +++ b/lightning/src/util/events.rs @@ -432,13 +432,21 @@ pub enum Event { /// The temporary channel ID of the channel requested to be opened. /// /// When responding to the request, the `temporary_channel_id` should be passed - /// back to the ChannelManager with [`ChannelManager::accept_inbound_channel`] to accept, - /// or to [`ChannelManager::force_close_channel`] to reject. + /// back to the ChannelManager through [`ChannelManager::accept_inbound_channel`] to accept, + /// or through [`ChannelManager::force_close_channel`] to reject. /// /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel /// [`ChannelManager::force_close_channel`]: crate::ln::channelmanager::ChannelManager::force_close_channel temporary_channel_id: [u8; 32], /// The node_id of the counterparty requesting to open the channel. + /// + /// When responding to the request, the `counterparty_node_id` should be passed + /// back to the `ChannelManager` through [`ChannelManager::accept_inbound_channel`] to + /// accept the request, or through [`ChannelManager::force_close_channel`] to reject the + /// request. + /// + /// [`ChannelManager::accept_inbound_channel`]: crate::ln::channelmanager::ChannelManager::accept_inbound_channel + /// [`ChannelManager::force_close_channel`]: crate::ln::channelmanager::ChannelManager::force_close_channel counterparty_node_id: PublicKey, /// The channel value of the requested channel. funding_satoshis: u64,