Skip to content

Commit 679deef

Browse files
committed
Correctly handle sending announcement sigs on public 0conf channels
1 parent f9a1549 commit 679deef

File tree

4 files changed

+124
-54
lines changed

4 files changed

+124
-54
lines changed

lightning/src/ln/channel.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4657,12 +4657,11 @@ impl<Signer: Sign> Channel<Signer> {
46574657
pub fn transactions_confirmed<L: Deref>(&mut self, block_hash: &BlockHash, height: u32,
46584658
txdata: &TransactionData, genesis_block_hash: BlockHash, node_pk: PublicKey, logger: &L)
46594659
-> Result<(Option<msgs::FundingLocked>, Option<msgs::AnnouncementSignatures>), ClosureReason> where L::Target: Logger {
4660-
let non_shutdown_state = self.channel_state & (!MULTI_STATE_FLAGS);
46614660
if let Some(funding_txo) = self.get_funding_txo() {
46624661
for &(index_in_block, tx) in txdata.iter() {
4663-
// If we haven't yet sent a funding_locked, but are in FundingSent (ignoring
4664-
// whether they've sent a funding_locked or not), check if we should send one.
4665-
if non_shutdown_state & !(ChannelState::TheirFundingLocked as u32) == ChannelState::FundingSent as u32 {
4662+
// Check if the transaction is the expected funding transaction, and if it is,
4663+
// check that it pays the right amount to the right script.
4664+
if self.funding_tx_confirmation_height == 0 {
46664665
if tx.txid() == funding_txo.txid {
46674666
let txo_idx = funding_txo.index as usize;
46684667
if txo_idx >= tx.output.len() || tx.output[txo_idx].script_pubkey != self.get_funding_redeemscript().to_v0_p2wsh() ||

lightning/src/ln/functional_test_utils.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ use ln::features::{InitFeatures, InvoiceFeatures};
2121
use ln::msgs;
2222
use ln::msgs::{ChannelMessageHandler,RoutingMessageHandler};
2323
use util::enforcing_trait_impls::EnforcingSigner;
24+
use util::scid_utils;
2425
use util::test_utils;
2526
use util::test_utils::{panicking, TestChainMonitor};
2627
use util::events::{Event, MessageSendEvent, MessageSendEventsProvider, PaymentPurpose};
@@ -48,9 +49,13 @@ pub const CHAN_CONFIRM_DEPTH: u32 = 10;
4849

4950
/// Mine the given transaction in the next block and then mine CHAN_CONFIRM_DEPTH - 1 blocks on
5051
/// top, giving the given transaction CHAN_CONFIRM_DEPTH confirmations.
51-
pub fn confirm_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
52-
confirm_transaction_at(node, tx, node.best_block_info().1 + 1);
52+
///
53+
/// Returns the SCID a channel confirmed in the given transaction will have, assuming the funding
54+
/// output is the 1st output in the transaction.
55+
pub fn confirm_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) -> u64 {
56+
let scid = confirm_transaction_at(node, tx, node.best_block_info().1 + 1);
5357
connect_blocks(node, CHAN_CONFIRM_DEPTH - 1);
58+
scid
5459
}
5560
/// Mine a signle block containing the given transaction
5661
pub fn mine_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction) {
@@ -59,7 +64,10 @@ pub fn mine_transaction<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transac
5964
}
6065
/// Mine the given transaction at the given height, mining blocks as required to build to that
6166
/// height
62-
pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction, conf_height: u32) {
67+
///
68+
/// Returns the SCID a channel confirmed in the given transaction will have, assuming the funding
69+
/// output is the 1st output in the transaction.
70+
pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &Transaction, conf_height: u32) -> u64 {
6371
let first_connect_height = node.best_block_info().1 + 1;
6472
assert!(first_connect_height <= conf_height);
6573
if conf_height > first_connect_height {
@@ -74,6 +82,7 @@ pub fn confirm_transaction_at<'a, 'b, 'c, 'd>(node: &'a Node<'b, 'c, 'd>, tx: &T
7482
}
7583
block.txdata.push(tx.clone());
7684
connect_block(node, &block);
85+
scid_utils::scid_from_parts(conf_height as u64, block.txdata.len() as u64 - 1, 0).unwrap()
7786
}
7887

7988
/// The possible ways we may notify a ChannelManager of a new block

lightning/src/ln/functional_tests.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9222,7 +9222,11 @@ fn test_duplicate_chan_id() {
92229222

92239223
let funding_created = {
92249224
let mut a_channel_lock = nodes[0].node.channel_state.lock().unwrap();
9225-
let mut as_chan = a_channel_lock.by_id.get_mut(&open_chan_2_msg.temporary_channel_id).unwrap();
9225+
// Once we call `get_outbound_funding_created` the channel has a duplicate channel_id as
9226+
// another channel in the ChannelManager - an invalid state. Thus, we'd panic later when we
9227+
// try to create another channel. Instead, we drop the channel entirely here (leaving the
9228+
// channelmanager in a possibly nonsense state instead).
9229+
let mut as_chan = a_channel_lock.by_id.remove(&open_chan_2_msg.temporary_channel_id).unwrap();
92269230
let logger = test_utils::TestLogger::new();
92279231
as_chan.get_outbound_funding_created(tx.clone(), funding_outpoint, &&logger).unwrap()
92289232
};
@@ -9260,7 +9264,7 @@ fn test_duplicate_chan_id() {
92609264
let events_4 = nodes[0].node.get_and_clear_pending_events();
92619265
assert_eq!(events_4.len(), 0);
92629266
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
9263-
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0].txid(), funding_output.txid);
9267+
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap()[0], tx);
92649268

92659269
let (funding_locked, _) = create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &tx);
92669270
let (announcement, as_update, bs_update) = create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_locked);

lightning/src/ln/priv_short_conf_tests.rs

Lines changed: 103 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -565,80 +565,87 @@ fn test_scid_alias_returned() {
565565
.blamed_chan_closed(false).expected_htlc_error_data(0x1000|12, &err_data));
566566
}
567567

568-
#[test]
569-
fn test_simple_0conf_channel() {
570-
// If our peer tells us they will accept our channel with 0 confs, and we funded the channel,
571-
// we should trust the funding won't be double-spent (assuming `trust_own_funding_0conf` is
572-
// set)!
573-
// Further, if we `accept_inbound_channel_from_trusted_peer_0conf`, funding locked messages
574-
// should fly immediately and the channel should be available for use as soon as they are
575-
// received.
568+
// Receiver must have been initialized with manually_accept_inbound_channels set to true.
569+
fn open_zero_conf_channel<'a, 'b, 'c, 'd>(initiator: &'a Node<'b, 'c, 'd>, receiver: &'a Node<'b, 'c, 'd>, initiator_config: Option<UserConfig>) -> bitcoin::Transaction {
570+
initiator.node.create_channel(receiver.node.get_our_node_id(), 100_000, 10_001, 42, initiator_config).unwrap();
571+
let open_channel = get_event_msg!(initiator, MessageSendEvent::SendOpenChannel, receiver.node.get_our_node_id());
576572

577-
let chanmon_cfgs = create_chanmon_cfgs(2);
578-
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
579-
let mut chan_config = test_default_channel_config();
580-
chan_config.manually_accept_inbound_channels = true;
581-
582-
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(chan_config)]);
583-
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
584-
585-
nodes[0].node.create_channel(nodes[1].node.get_our_node_id(), 100000, 10001, 42, None).unwrap();
586-
let open_channel = get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, nodes[1].node.get_our_node_id());
587-
588-
nodes[1].node.handle_open_channel(&nodes[0].node.get_our_node_id(), InitFeatures::known(), &open_channel);
589-
let events = nodes[1].node.get_and_clear_pending_events();
573+
receiver.node.handle_open_channel(&initiator.node.get_our_node_id(), InitFeatures::known(), &open_channel);
574+
let events = receiver.node.get_and_clear_pending_events();
590575
assert_eq!(events.len(), 1);
591576
match events[0] {
592577
Event::OpenChannelRequest { temporary_channel_id, .. } => {
593-
nodes[1].node.accept_inbound_channel_from_trusted_peer_0conf(&temporary_channel_id, &nodes[0].node.get_our_node_id(), 0).unwrap();
578+
receiver.node.accept_inbound_channel_from_trusted_peer_0conf(&temporary_channel_id, &initiator.node.get_our_node_id(), 0).unwrap();
594579
},
595580
_ => panic!("Unexpected event"),
596581
};
597582

598-
let mut accept_channel = get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, nodes[0].node.get_our_node_id());
583+
let mut accept_channel = get_event_msg!(receiver, MessageSendEvent::SendAcceptChannel, initiator.node.get_our_node_id());
599584
assert_eq!(accept_channel.minimum_depth, 0);
600-
nodes[0].node.handle_accept_channel(&nodes[1].node.get_our_node_id(), InitFeatures::known(), &accept_channel);
585+
initiator.node.handle_accept_channel(&receiver.node.get_our_node_id(), InitFeatures::known(), &accept_channel);
601586

602-
let (temporary_channel_id, tx, _) = create_funding_transaction(&nodes[0], &nodes[1].node.get_our_node_id(), 100000, 42);
603-
nodes[0].node.funding_transaction_generated(&temporary_channel_id, &nodes[1].node.get_our_node_id(), tx.clone()).unwrap();
604-
let funding_created = get_event_msg!(nodes[0], MessageSendEvent::SendFundingCreated, nodes[1].node.get_our_node_id());
587+
let (temporary_channel_id, tx, _) = create_funding_transaction(&initiator, &receiver.node.get_our_node_id(), 100_000, 42);
588+
initiator.node.funding_transaction_generated(&temporary_channel_id, &receiver.node.get_our_node_id(), tx.clone()).unwrap();
589+
let funding_created = get_event_msg!(initiator, MessageSendEvent::SendFundingCreated, receiver.node.get_our_node_id());
605590

606-
nodes[1].node.handle_funding_created(&nodes[0].node.get_our_node_id(), &funding_created);
607-
check_added_monitors!(nodes[1], 1);
608-
let bs_signed_locked = nodes[1].node.get_and_clear_pending_msg_events();
591+
receiver.node.handle_funding_created(&initiator.node.get_our_node_id(), &funding_created);
592+
check_added_monitors!(receiver, 1);
593+
let bs_signed_locked = receiver.node.get_and_clear_pending_msg_events();
609594
assert_eq!(bs_signed_locked.len(), 2);
610595
let as_funding_locked;
611596
match &bs_signed_locked[0] {
612597
MessageSendEvent::SendFundingSigned { node_id, msg } => {
613-
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
614-
nodes[0].node.handle_funding_signed(&nodes[1].node.get_our_node_id(), &msg);
615-
check_added_monitors!(nodes[0], 1);
598+
assert_eq!(*node_id, initiator.node.get_our_node_id());
599+
initiator.node.handle_funding_signed(&receiver.node.get_our_node_id(), &msg);
600+
check_added_monitors!(initiator, 1);
616601

617-
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
618-
assert_eq!(nodes[0].tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0)[0], tx);
602+
assert_eq!(initiator.tx_broadcaster.txn_broadcasted.lock().unwrap().len(), 1);
603+
assert_eq!(initiator.tx_broadcaster.txn_broadcasted.lock().unwrap().split_off(0)[0], tx);
619604

620-
as_funding_locked = get_event_msg!(nodes[0], MessageSendEvent::SendFundingLocked, nodes[1].node.get_our_node_id());
605+
as_funding_locked = get_event_msg!(initiator, MessageSendEvent::SendFundingLocked, receiver.node.get_our_node_id());
621606
}
622607
_ => panic!("Unexpected event"),
623608
}
624609
match &bs_signed_locked[1] {
625610
MessageSendEvent::SendFundingLocked { node_id, msg } => {
626-
assert_eq!(*node_id, nodes[0].node.get_our_node_id());
627-
nodes[0].node.handle_funding_locked(&nodes[1].node.get_our_node_id(), &msg);
611+
assert_eq!(*node_id, initiator.node.get_our_node_id());
612+
initiator.node.handle_funding_locked(&receiver.node.get_our_node_id(), &msg);
628613
}
629614
_ => panic!("Unexpected event"),
630615
}
631616

632-
nodes[1].node.handle_funding_locked(&nodes[0].node.get_our_node_id(), &as_funding_locked);
617+
receiver.node.handle_funding_locked(&initiator.node.get_our_node_id(), &as_funding_locked);
633618

634-
let as_channel_update = get_event_msg!(nodes[0], MessageSendEvent::SendChannelUpdate, nodes[1].node.get_our_node_id());
635-
let bs_channel_update = get_event_msg!(nodes[1], MessageSendEvent::SendChannelUpdate, nodes[0].node.get_our_node_id());
619+
let as_channel_update = get_event_msg!(initiator, MessageSendEvent::SendChannelUpdate, receiver.node.get_our_node_id());
620+
let bs_channel_update = get_event_msg!(receiver, MessageSendEvent::SendChannelUpdate, initiator.node.get_our_node_id());
636621

637-
nodes[0].node.handle_channel_update(&nodes[1].node.get_our_node_id(), &bs_channel_update);
638-
nodes[1].node.handle_channel_update(&nodes[0].node.get_our_node_id(), &as_channel_update);
622+
initiator.node.handle_channel_update(&receiver.node.get_our_node_id(), &bs_channel_update);
623+
receiver.node.handle_channel_update(&initiator.node.get_our_node_id(), &as_channel_update);
639624

640-
assert_eq!(nodes[0].node.list_usable_channels().len(), 1);
641-
assert_eq!(nodes[1].node.list_usable_channels().len(), 1);
625+
assert_eq!(initiator.node.list_usable_channels().len(), 1);
626+
assert_eq!(receiver.node.list_usable_channels().len(), 1);
627+
628+
tx
629+
}
630+
631+
#[test]
632+
fn test_simple_0conf_channel() {
633+
// If our peer tells us they will accept our channel with 0 confs, and we funded the channel,
634+
// we should trust the funding won't be double-spent (assuming `trust_own_funding_0conf` is
635+
// set)!
636+
// Further, if we `accept_inbound_channel_from_trusted_peer_0conf`, funding locked messages
637+
// should fly immediately and the channel should be available for use as soon as they are
638+
// received.
639+
640+
let chanmon_cfgs = create_chanmon_cfgs(2);
641+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
642+
let mut chan_config = test_default_channel_config();
643+
chan_config.manually_accept_inbound_channels = true;
644+
645+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(chan_config)]);
646+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
647+
648+
open_zero_conf_channel(&nodes[0], &nodes[1], None);
642649

643650
send_payment(&nodes[0], &[&nodes[1]], 100_000);
644651
}
@@ -790,3 +797,54 @@ fn test_0conf_channel_with_async_monitor() {
790797

791798
send_payment(&nodes[0], &[&nodes[1]], 100_000);
792799
}
800+
801+
#[test]
802+
fn test_public_0conf_channel() {
803+
// Tests that we will announce a public channel (after confirmation) even if its 0conf.
804+
let chanmon_cfgs = create_chanmon_cfgs(2);
805+
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
806+
let mut chan_config = test_default_channel_config();
807+
chan_config.manually_accept_inbound_channels = true;
808+
809+
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, Some(chan_config)]);
810+
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
811+
812+
// This is the default but we force it on anyway
813+
chan_config.channel_options.announced_channel = true;
814+
let tx = open_zero_conf_channel(&nodes[0], &nodes[1], Some(chan_config));
815+
816+
// We can use the channel immediately, but we can't announce it until we get 6+ confirmations
817+
send_payment(&nodes[0], &[&nodes[1]], 100_000);
818+
819+
let scid = confirm_transaction(&nodes[0], &tx);
820+
let as_announcement_sigs = get_event_msg!(nodes[0], MessageSendEvent::SendAnnouncementSignatures, nodes[1].node.get_our_node_id());
821+
assert_eq!(confirm_transaction(&nodes[1], &tx), scid);
822+
let bs_announcement_sigs = get_event_msg!(nodes[1], MessageSendEvent::SendAnnouncementSignatures, nodes[0].node.get_our_node_id());
823+
824+
nodes[1].node.handle_announcement_signatures(&nodes[0].node.get_our_node_id(), &as_announcement_sigs);
825+
nodes[0].node.handle_announcement_signatures(&nodes[1].node.get_our_node_id(), &bs_announcement_sigs);
826+
827+
let bs_announcement = nodes[1].node.get_and_clear_pending_msg_events();
828+
assert_eq!(bs_announcement.len(), 1);
829+
let announcement;
830+
let bs_update;
831+
match bs_announcement[0] {
832+
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
833+
announcement = msg.clone();
834+
bs_update = update_msg.clone();
835+
},
836+
_ => panic!("Unexpected event"),
837+
};
838+
839+
let as_announcement = nodes[0].node.get_and_clear_pending_msg_events();
840+
assert_eq!(as_announcement.len(), 1);
841+
match as_announcement[0] {
842+
MessageSendEvent::BroadcastChannelAnnouncement { ref msg, ref update_msg } => {
843+
assert!(announcement == *msg);
844+
assert_eq!(update_msg.contents.short_channel_id, scid);
845+
assert_eq!(update_msg.contents.short_channel_id, announcement.contents.short_channel_id);
846+
assert_eq!(update_msg.contents.short_channel_id, bs_update.contents.short_channel_id);
847+
},
848+
_ => panic!("Unexpected event"),
849+
};
850+
}

0 commit comments

Comments
 (0)