Skip to content

Commit c4d23bc

Browse files
authored
Merge pull request #3651 from jkczyz/2025-03-multiple-funding-scopes
Batch `commitment_signed` messages for splicing
2 parents 42ab42a + 80e3235 commit c4d23bc

28 files changed

+739
-364
lines changed

fuzz/src/chanmon_consistency.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
10891089
for event in &mut events_iter {
10901090
had_events = true;
10911091
match event {
1092-
MessageSendEvent::UpdateHTLCs { node_id, updates: CommitmentUpdate { update_add_htlcs, update_fail_htlcs, update_fulfill_htlcs, update_fail_malformed_htlcs, update_fee, commitment_signed } } => {
1092+
MessageSendEvent::UpdateHTLCs { node_id, channel_id, updates: CommitmentUpdate { update_add_htlcs, update_fail_htlcs, update_fulfill_htlcs, update_fail_malformed_htlcs, update_fee, commitment_signed } } => {
10931093
for (idx, dest) in nodes.iter().enumerate() {
10941094
if dest.get_our_node_id() == node_id {
10951095
for update_add in update_add_htlcs.iter() {
@@ -1127,7 +1127,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
11271127
!update_fail_htlcs.is_empty() || !update_fail_malformed_htlcs.is_empty();
11281128
if $limit_events != ProcessMessages::AllMessages && processed_change {
11291129
// If we only want to process some messages, don't deliver the CS until later.
1130-
extra_ev = Some(MessageSendEvent::UpdateHTLCs { node_id, updates: CommitmentUpdate {
1130+
extra_ev = Some(MessageSendEvent::UpdateHTLCs { node_id, channel_id, updates: CommitmentUpdate {
11311131
update_add_htlcs: Vec::new(),
11321132
update_fail_htlcs: Vec::new(),
11331133
update_fulfill_htlcs: Vec::new(),
@@ -1138,7 +1138,7 @@ pub fn do_test<Out: Output>(data: &[u8], underlying_out: Out, anchors: bool) {
11381138
break;
11391139
}
11401140
out.locked_write(format!("Delivering commitment_signed from node {} to node {}.\n", $node, idx).as_bytes());
1141-
dest.handle_commitment_signed(nodes[$node].get_our_node_id(), &commitment_signed);
1141+
dest.handle_commitment_signed_batch_test(nodes[$node].get_our_node_id(), &commitment_signed);
11421142
break;
11431143
}
11441144
}

fuzz/src/full_stack.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1639,13 +1639,13 @@ mod tests {
16391639
// 5
16401640
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling SendRevokeAndACK event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&4));
16411641
// 6
1642-
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 with 0 adds, 0 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3));
1642+
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 with 0 adds, 0 fulfills, 0 fails, 1 commits for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3));
16431643
// 7
1644-
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails for channel 3a00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3));
1644+
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030200000000000000000000000000000000000000000000000000000000000000 with 1 adds, 0 fulfills, 0 fails, 1 commits for channel 3a00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&3));
16451645
// 8
1646-
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 with 0 adds, 1 fulfills, 0 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1));
1646+
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 with 0 adds, 1 fulfills, 0 fails, 1 commits for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&1));
16471647
// 9
1648-
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 with 0 adds, 0 fulfills, 1 fails for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&2));
1648+
assert_eq!(log_entries.get(&("lightning::ln::peer_handler".to_string(), "Handling UpdateHTLCs event in peer_handler for node 030000000000000000000000000000000000000000000000000000000000000002 with 0 adds, 0 fulfills, 1 fails, 1 commits for channel 3d00000000000000000000000000000000000000000000000000000000000000".to_string())), Some(&2));
16491649
// 10
16501650
assert_eq!(log_entries.get(&("lightning::chain::channelmonitor".to_string(), "Input spending counterparty commitment tx (0000000000000000000000000000000000000000000000000000000000000073:0) in 0000000000000000000000000000000000000000000000000000000000000067 resolves outbound HTLC with payment hash ff00000000000000000000000000000000000000000000000000000000000000 with timeout".to_string())), Some(&1));
16511651
}

lightning-net-tokio/src/lib.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -622,15 +622,17 @@ impl Hash for SocketDescriptor {
622622
mod tests {
623623
use bitcoin::constants::ChainHash;
624624
use bitcoin::secp256k1::{PublicKey, Secp256k1, SecretKey};
625-
use bitcoin::Network;
625+
use bitcoin::{Network, Txid};
626626
use lightning::ln::msgs::*;
627627
use lightning::ln::peer_handler::{IgnoringMessageHandler, MessageHandler, PeerManager};
628+
use lightning::ln::types::ChannelId;
628629
use lightning::routing::gossip::NodeId;
629630
use lightning::types::features::*;
630631
use lightning::util::test_utils::TestNodeSigner;
631632

632633
use tokio::sync::mpsc;
633634

635+
use std::collections::BTreeMap;
634636
use std::mem;
635637
use std::sync::atomic::{AtomicBool, Ordering};
636638
use std::sync::{Arc, Mutex};
@@ -723,6 +725,11 @@ mod tests {
723725
) {
724726
}
725727
fn handle_commitment_signed(&self, _their_node_id: PublicKey, _msg: &CommitmentSigned) {}
728+
fn handle_commitment_signed_batch(
729+
&self, _their_node_id: PublicKey, _channel_id: ChannelId,
730+
_batch: BTreeMap<Txid, CommitmentSigned>,
731+
) {
732+
}
726733
fn handle_revoke_and_ack(&self, _their_node_id: PublicKey, _msg: &RevokeAndACK) {}
727734
fn handle_update_fee(&self, _their_node_id: PublicKey, _msg: &UpdateFee) {}
728735
fn handle_announcement_signatures(

lightning/src/chain/chainmonitor.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1008,20 +1008,20 @@ mod tests {
10081008
let updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
10091009
nodes[0].node.handle_update_fulfill_htlc(nodes[1].node.get_our_node_id(), &updates.update_fulfill_htlcs[0]);
10101010
expect_payment_sent(&nodes[0], payment_preimage_1, None, false, false);
1011-
nodes[0].node.handle_commitment_signed(nodes[1].node.get_our_node_id(), &updates.commitment_signed);
1011+
nodes[0].node.handle_commitment_signed_batch_test(nodes[1].node.get_our_node_id(), &updates.commitment_signed);
10121012
check_added_monitors!(nodes[0], 1);
10131013
let (as_first_raa, as_first_update) = get_revoke_commit_msgs!(nodes[0], nodes[1].node.get_our_node_id());
10141014

10151015
nodes[1].node.handle_revoke_and_ack(nodes[0].node.get_our_node_id(), &as_first_raa);
10161016
check_added_monitors!(nodes[1], 1);
10171017
let bs_second_updates = get_htlc_update_msgs!(nodes[1], nodes[0].node.get_our_node_id());
1018-
nodes[1].node.handle_commitment_signed(nodes[0].node.get_our_node_id(), &as_first_update);
1018+
nodes[1].node.handle_commitment_signed_batch_test(nodes[0].node.get_our_node_id(), &as_first_update);
10191019
check_added_monitors!(nodes[1], 1);
10201020
let bs_first_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
10211021

10221022
nodes[0].node.handle_update_fulfill_htlc(nodes[1].node.get_our_node_id(), &bs_second_updates.update_fulfill_htlcs[0]);
10231023
expect_payment_sent(&nodes[0], payment_preimage_2, None, false, false);
1024-
nodes[0].node.handle_commitment_signed(nodes[1].node.get_our_node_id(), &bs_second_updates.commitment_signed);
1024+
nodes[0].node.handle_commitment_signed_batch_test(nodes[1].node.get_our_node_id(), &bs_second_updates.commitment_signed);
10251025
check_added_monitors!(nodes[0], 1);
10261026
nodes[0].node.handle_revoke_and_ack(nodes[1].node.get_our_node_id(), &bs_first_raa);
10271027
expect_payment_path_successful!(nodes[0]);
@@ -1030,7 +1030,7 @@ mod tests {
10301030

10311031
nodes[1].node.handle_revoke_and_ack(nodes[0].node.get_our_node_id(), &as_second_raa);
10321032
check_added_monitors!(nodes[1], 1);
1033-
nodes[1].node.handle_commitment_signed(nodes[0].node.get_our_node_id(), &as_second_update);
1033+
nodes[1].node.handle_commitment_signed_batch_test(nodes[0].node.get_our_node_id(), &as_second_update);
10341034
check_added_monitors!(nodes[1], 1);
10351035
let bs_second_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
10361036

lightning/src/chain/onchaintx.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ impl<'a, 'b, ES: EntropySource, SP: SignerProvider> ReadableArgs<(&'a ES, &'b SP
368368
let prev_holder_commitment = Readable::read(reader)?;
369369
let _prev_holder_htlc_sigs: Option<Vec<Option<(usize, Signature)>>> = Readable::read(reader)?;
370370

371-
let channel_parameters = ReadableArgs::<u64>::read(reader, channel_value_satoshis)?;
371+
let channel_parameters = ReadableArgs::<Option<u64>>::read(reader, Some(channel_value_satoshis))?;
372372

373373
// Read the serialized signer bytes, but don't deserialize them, as we'll obtain our signer
374374
// by re-deriving the private key material.

lightning/src/ln/async_signer_tests.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ fn do_test_async_commitment_signature_for_commitment_signed_revoke_and_ack(enabl
262262
dst.disable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::GetPerCommitmentPoint);
263263
dst.disable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::ReleaseCommitmentSecret);
264264
dst.disable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::SignCounterpartyCommitment);
265-
dst.node.handle_commitment_signed(src.node.get_our_node_id(), &payment_event.commitment_msg);
265+
dst.node.handle_commitment_signed_batch_test(src.node.get_our_node_id(), &payment_event.commitment_msg);
266266
check_added_monitors(dst, 1);
267267

268268
let mut enabled_signer_ops = new_hash_set();
@@ -456,7 +456,7 @@ fn do_test_async_raa_peer_disconnect(test_case: UnblockSignerAcrossDisconnectCas
456456
// Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
457457
// `commitment_signed` of its own to offer, it should publish a `revoke_and_ack`.
458458
dst.disable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, block_raa_signer_op);
459-
dst.node.handle_commitment_signed(src.node.get_our_node_id(), &payment_event.commitment_msg);
459+
dst.node.handle_commitment_signed_batch_test(src.node.get_our_node_id(), &payment_event.commitment_msg);
460460
check_added_monitors(dst, 1);
461461

462462
let events = dst.node.get_and_clear_pending_msg_events();
@@ -580,7 +580,7 @@ fn do_test_async_commitment_signature_peer_disconnect(test_case: UnblockSignerAc
580580
// Mark dst's signer as unavailable and handle src's commitment_signed: while dst won't yet have a
581581
// `commitment_signed` of its own to offer, it should publish a `revoke_and_ack`.
582582
dst.disable_channel_signer_op(&src.node.get_our_node_id(), &chan_id, SignerOp::SignCounterpartyCommitment);
583-
dst.node.handle_commitment_signed(src.node.get_our_node_id(), &payment_event.commitment_msg);
583+
dst.node.handle_commitment_signed_batch_test(src.node.get_our_node_id(), &payment_event.commitment_msg);
584584
check_added_monitors(dst, 1);
585585

586586
if test_case != UnblockSignerAcrossDisconnectCase::BeforeMonitorRestored {
@@ -690,13 +690,13 @@ fn do_test_async_commitment_signature_ordering(monitor_update_failure: bool) {
690690
let events_2 = nodes[1].node.get_and_clear_pending_msg_events();
691691
assert_eq!(events_2.len(), 1);
692692
match events_2[0] {
693-
MessageSendEvent::UpdateHTLCs { node_id: _, updates: msgs::CommitmentUpdate { ref update_fulfill_htlcs, ref commitment_signed, .. } } => {
693+
MessageSendEvent::UpdateHTLCs { node_id: _, channel_id: _, updates: msgs::CommitmentUpdate { ref update_fulfill_htlcs, ref commitment_signed, .. } } => {
694694
nodes[0].node.handle_update_fulfill_htlc(nodes[1].node.get_our_node_id(), &update_fulfill_htlcs[0]);
695695
expect_payment_sent(&nodes[0], payment_preimage_1, None, false, false);
696696
if monitor_update_failure {
697697
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
698698
}
699-
nodes[0].node.handle_commitment_signed(nodes[1].node.get_our_node_id(), commitment_signed);
699+
nodes[0].node.handle_commitment_signed_batch_test(nodes[1].node.get_our_node_id(), commitment_signed);
700700
if monitor_update_failure {
701701
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
702702
} else {
@@ -766,7 +766,7 @@ fn do_test_async_commitment_signature_ordering(monitor_update_failure: bool) {
766766

767767
// Now that everything is restored, get the CS + RAA and handle them.
768768
nodes[1].node.handle_update_add_htlc(nodes[0].node.get_our_node_id(), &as_resp.2.as_ref().unwrap().update_add_htlcs[0]);
769-
nodes[1].node.handle_commitment_signed(nodes[0].node.get_our_node_id(), &as_resp.2.as_ref().unwrap().commitment_signed);
769+
nodes[1].node.handle_commitment_signed_batch_test(nodes[0].node.get_our_node_id(), &as_resp.2.as_ref().unwrap().commitment_signed);
770770
nodes[1].node.handle_revoke_and_ack(nodes[0].node.get_our_node_id(), as_resp.1.as_ref().unwrap());
771771
let (bs_revoke_and_ack, bs_second_commitment_signed) = get_revoke_commit_msgs(&nodes[1], &nodes[0].node.get_our_node_id());
772772
check_added_monitors!(nodes[1], 2);
@@ -777,12 +777,12 @@ fn do_test_async_commitment_signature_ordering(monitor_update_failure: bool) {
777777
let as_commitment_signed = get_htlc_update_msgs!(nodes[0], nodes[1].node.get_our_node_id());
778778
check_added_monitors!(nodes[0], 1);
779779

780-
nodes[0].node.handle_commitment_signed(nodes[1].node.get_our_node_id(), &bs_second_commitment_signed);
780+
nodes[0].node.handle_commitment_signed_batch_test(nodes[1].node.get_our_node_id(), &bs_second_commitment_signed);
781781
let as_revoke_and_ack = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, nodes[1].node.get_our_node_id());
782782
// No commitment_signed so get_event_msg's assert(len == 1) passes
783783
check_added_monitors!(nodes[0], 1);
784784

785-
nodes[1].node.handle_commitment_signed(nodes[0].node.get_our_node_id(), &as_commitment_signed.commitment_signed);
785+
nodes[1].node.handle_commitment_signed_batch_test(nodes[0].node.get_our_node_id(), &as_commitment_signed.commitment_signed);
786786
let bs_second_revoke_and_ack = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, nodes[0].node.get_our_node_id());
787787
// No commitment_signed so get_event_msg's assert(len == 1) passes
788788
check_added_monitors!(nodes[1], 1);

lightning/src/ln/blinded_payment_tests.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,7 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
10091009
let node_1_shutdown = get_event_msg!(nodes[1], MessageSendEvent::SendShutdown, nodes[2].node.get_our_node_id());
10101010

10111011
nodes[2].node.handle_update_add_htlc(nodes[1].node.get_our_node_id(), &payment_event_1_2.msgs[0]);
1012-
nodes[2].node.handle_commitment_signed(nodes[1].node.get_our_node_id(), &payment_event_1_2.commitment_msg);
1012+
nodes[2].node.handle_commitment_signed_batch_test(nodes[1].node.get_our_node_id(), &payment_event_1_2.commitment_msg);
10131013
check_added_monitors!(nodes[2], 1);
10141014

10151015
nodes[2].node.handle_shutdown(nodes[1].node.get_our_node_id(), &node_1_shutdown);
@@ -1051,7 +1051,7 @@ fn do_multi_hop_receiver_fail(check: ReceiveCheckFail) {
10511051
assert_eq!(events.len(), 2);
10521052
events.into_iter().find_map(|ev| {
10531053
match ev {
1054-
MessageSendEvent:: UpdateHTLCs { node_id, updates } => {
1054+
MessageSendEvent::UpdateHTLCs { node_id, channel_id: _, updates } => {
10551055
assert_eq!(node_id, nodes[0].node.get_our_node_id());
10561056
return Some(updates)
10571057
},

lightning/src/ln/chan_utils.rs

+13-6
Original file line numberDiff line numberDiff line change
@@ -1034,8 +1034,8 @@ impl Writeable for ChannelTransactionParameters {
10341034
}
10351035
}
10361036

1037-
impl ReadableArgs<u64> for ChannelTransactionParameters {
1038-
fn read<R: io::Read>(reader: &mut R, read_args: u64) -> Result<Self, DecodeError> {
1037+
impl ReadableArgs<Option<u64>> for ChannelTransactionParameters {
1038+
fn read<R: io::Read>(reader: &mut R, read_args: Option<u64>) -> Result<Self, DecodeError> {
10391039
let mut holder_pubkeys = RequiredWrapper(None);
10401040
let mut holder_selected_contest_delay = RequiredWrapper(None);
10411041
let mut is_outbound_from_holder = RequiredWrapper(None);
@@ -1058,10 +1058,17 @@ impl ReadableArgs<u64> for ChannelTransactionParameters {
10581058
(13, channel_value_satoshis, option),
10591059
});
10601060

1061-
let channel_value_satoshis = channel_value_satoshis.unwrap_or(read_args);
1062-
if channel_value_satoshis != read_args {
1063-
return Err(DecodeError::InvalidValue);
1064-
}
1061+
let channel_value_satoshis = match read_args {
1062+
None => channel_value_satoshis.ok_or(DecodeError::InvalidValue)?,
1063+
Some(expected_value) => {
1064+
let channel_value_satoshis = channel_value_satoshis.unwrap_or(expected_value);
1065+
if channel_value_satoshis == expected_value {
1066+
channel_value_satoshis
1067+
} else {
1068+
return Err(DecodeError::InvalidValue);
1069+
}
1070+
},
1071+
};
10651072

10661073
let mut additional_features = ChannelTypeFeatures::empty();
10671074
additional_features.set_anchors_nonzero_fee_htlc_tx_required();

0 commit comments

Comments
 (0)