Support capturing `tx_abort` send within channel reestablish tests
What changed, and why it matters
This commit only changes internal test helper code in the Lightning Dev Kit repository. It extends a test macro and a test reconnection helper so that automated tests can optionally capture and forward a `tx_abort` message during channel re-establishment scenarios. No production code is modified, and there is no indication this fixes or introduces a security issue.
No security action required. Treat as a normal test-maintenance commit.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The diff updates lightning/src/ln/functional_test_utils.rs and lightning/src/ln/async_signer_tests.rs. It adds an eighth tuple element (tx_abort) to the handle_chan_reestablish_msgs! macro return value, updates ReconnectArgs with a send_tx_abort field, and threads that field through reconnect_nodes. Corresponding test call sites are updated to destructure the new tuple element and assert it is None in existing tests. The change is purely test infrastructure for the tx_abort protocol message handling path.
Changed components
lightning/src/ln/functional_test_utils.rs (test utilities)lightning/src/ln/async_signer_tests.rs (tests)Inspect captured patch +36 / −7
diff --git a/lightning/src/ln/async_signer_tests.rs b/lightning/src/ln/async_signer_tests.rs
index 7182108..03728e2 100644
--- a/lightning/src/ln/async_signer_tests.rs
+++ b/lightning/src/ln/async_signer_tests.rs
@@ -596,7 +596,7 @@ fn do_test_async_raa_peer_disconnect(
}
// Expect the RAA
- let (_, revoke_and_ack, commitment_signed, resend_order, _, _, _) =
+ let (_, revoke_and_ack, commitment_signed, resend_order, _, _, _, _) =
handle_chan_reestablish_msgs!(dst, src);
if test_case == UnblockSignerAcrossDisconnectCase::AtEnd {
assert!(revoke_and_ack.is_none());
@@ -612,14 +612,14 @@ fn do_test_async_raa_peer_disconnect(
dst.node.signer_unblocked(Some((src_node_id, chan_id)));
if test_case == UnblockSignerAcrossDisconnectCase::AtEnd {
- let (_, revoke_and_ack, commitment_signed, resend_order, _, _, _) =
+ let (_, revoke_and_ack, commitment_signed, resend_order, _, _, _, _) =
handle_chan_reestablish_msgs!(dst, src);
assert!(revoke_and_ack.is_some());
assert!(commitment_signed.is_some());
assert!(resend_order == RAACommitmentOrder::RevokeAndACKFirst);
} else {
// Make sure we don't double send the RAA.
- let (_, revoke_and_ack, commitment_signed, _, _, _, _) =
+ let (_, revoke_and_ack, commitment_signed, _, _, _, _, _) =
handle_chan_reestablish_msgs!(dst, src);
assert!(revoke_and_ack.is_none());
assert!(commitment_signed.is_none());
@@ -746,7 +746,7 @@ fn do_test_async_commitment_signature_peer_disconnect(
}
// Expect the RAA
- let (_, revoke_and_ack, commitment_signed, _, _, _, _) =
+ let (_, revoke_and_ack, commitment_signed, _, _, _, _, _) =
handle_chan_reestablish_msgs!(dst, src);
assert!(revoke_and_ack.is_some());
if test_case == UnblockSignerAcrossDisconnectCase::AtEnd {
@@ -760,11 +760,11 @@ fn do_test_async_commitment_signature_peer_disconnect(
dst.node.signer_unblocked(Some((src_node_id, chan_id)));
if test_case == UnblockSignerAcrossDisconnectCase::AtEnd {
- let (_, _, commitment_signed, _, _, _, _) = handle_chan_reestablish_msgs!(dst, src);
+ let (_, _, commitment_signed, _, _, _, _, _) = handle_chan_reestablish_msgs!(dst, src);
assert!(commitment_signed.is_some());
} else {
// Make sure we don't double send the CS.
- let (_, _, commitment_signed, _, _, _, _) = handle_chan_reestablish_msgs!(dst, src);
+ let (_, _, commitment_signed, _, _, _, _, _) = handle_chan_reestablish_msgs!(dst, src);
assert!(commitment_signed.is_none());
}
}
@@ -882,6 +882,7 @@ fn do_test_async_commitment_signature_ordering(monitor_update_failure: bool) {
assert!(as_resp.4.is_none());
assert!(as_resp.5.is_none());
assert!(as_resp.6.is_none());
+ assert!(as_resp.7.is_none());
if monitor_update_failure {
chanmon_cfgs[0].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
@@ -904,6 +905,7 @@ fn do_test_async_commitment_signature_ordering(monitor_update_failure: bool) {
assert!(as_resp.4.is_none());
assert!(as_resp.5.is_none());
assert!(as_resp.6.is_none());
+ assert!(as_resp.7.is_none());
nodes[0].enable_channel_signer_op(&node_b_id, &chan_id, SignerOp::SignCounterpartyCommitment);
nodes[0].node.signer_unblocked(Some((node_b_id, chan_id)));
@@ -929,6 +931,9 @@ fn do_test_async_commitment_signature_ordering(monitor_update_failure: bool) {
assert!(as_resp.6.is_none());
assert!(bs_resp.6.is_none());
+ assert!(as_resp.7.is_none());
+ assert!(bs_resp.7.is_none());
+
// Now that everything is restored, get the CS + RAA and handle them.
nodes[1]
.node
diff --git a/lightning/src/ln/functional_test_utils.rs b/lightning/src/ln/functional_test_utils.rs
index 45c8e07..271d458 100644
--- a/lightning/src/ln/functional_test_utils.rs
+++ b/lightning/src/ln/functional_test_utils.rs
@@ -4996,9 +4996,17 @@ macro_rules! handle_chan_reestablish_msgs {
($src_node: expr, $dst_node: expr) => {{
let msg_events = $src_node.node.get_and_clear_pending_msg_events();
let mut idx = 0;
+
+ let mut tx_abort = None;
+ if let Some(&MessageSendEvent::SendTxAbort { ref node_id, ref msg }) = msg_events.get(idx) {
+ idx += 1;
+ assert_eq!(*node_id, $dst_node.node.get_our_node_id());
+ tx_abort = Some(msg.clone());
+ }
+
let channel_ready =
if let Some(&MessageSendEvent::SendChannelReady { ref node_id, ref msg }) =
- msg_events.get(0)
+ msg_events.get(idx)
{
idx += 1;
assert_eq!(*node_id, $dst_node.node.get_our_node_id());
@@ -5115,6 +5123,7 @@ macro_rules! handle_chan_reestablish_msgs {
announcement_sigs,
tx_signatures,
stfu,
+ tx_abort,
)
}};
}
@@ -5127,6 +5136,7 @@ pub struct ReconnectArgs<'a, 'b, 'c, 'd> {
pub send_stfu: (bool, bool),
pub send_interactive_tx_commit_sig: (bool, bool),
pub send_interactive_tx_sigs: (bool, bool),
+ pub send_tx_abort: (bool, bool),
pub expect_renegotiated_funding_locked_monitor_update: (bool, bool),
pub pending_responding_commitment_signed: (bool, bool),
/// Indicates that the pending responding commitment signed will be a dup for the recipient,
@@ -5150,6 +5160,7 @@ impl<'a, 'b, 'c, 'd> ReconnectArgs<'a, 'b, 'c, 'd> {
send_stfu: (false, false),
send_interactive_tx_commit_sig: (false, false),
send_interactive_tx_sigs: (false, false),
+ send_tx_abort: (false, false),
expect_renegotiated_funding_locked_monitor_update: (false, false),
pending_responding_commitment_signed: (false, false),
pending_responding_commitment_signed_dup_monitor: (false, false),
@@ -5174,6 +5185,7 @@ pub fn reconnect_nodes<'a, 'b, 'c, 'd>(args: ReconnectArgs<'a, 'b, 'c, 'd>) {
send_stfu,
send_interactive_tx_commit_sig,
send_interactive_tx_sigs,
+ send_tx_abort,
expect_renegotiated_funding_locked_monitor_update,
pending_htlc_adds,
pending_htlc_claims,
@@ -5305,6 +5317,12 @@ pub fn reconnect_nodes<'a, 'b, 'c, 'd>(args: ReconnectArgs<'a, 'b, 'c, 'd>) {
&commitment_update.commitment_signed,
)
}
+ if send_tx_abort.0 {
+ let tx_abort = chan_msgs.7.take().unwrap();
+ node_a.node.handle_tx_abort(node_b_id, &tx_abort);
+ } else {
+ assert!(chan_msgs.7.is_none());
+ }
if send_interactive_tx_sigs.0 {
let tx_signatures = chan_msgs.5.take().unwrap();
node_a.node.handle_tx_signatures(node_b_id, &tx_signatures);
@@ -5417,6 +5435,12 @@ pub fn reconnect_nodes<'a, 'b, 'c, 'd>(args: ReconnectArgs<'a, 'b, 'c, 'd>) {
&commitment_update.commitment_signed,
)
}
+ if send_tx_abort.1 {
+ let tx_abort = chan_msgs.7.take().unwrap();
+ node_a.node.handle_tx_abort(node_b_id, &tx_abort);
+ } else {
+ assert!(chan_msgs.7.is_none());
+ }
if send_interactive_tx_sigs.1 {
let tx_signatures = chan_msgs.5.take().unwrap();
node_b.node.handle_tx_signatures(node_a_id, &tx_signatures);
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.