fuzz: handle missing SendTx* message events in chanmon_consistency
What changed, and why it matters
This commit fixes a fuzz testing harness so it can handle four new types of message events related to the experimental splicing feature. Previously, the harness would panic with 'Unhandled message event' when these messages appeared during automated fuzzing. This is a test-only fix and does not change the production Lightning protocol code that real nodes run.
No production action required. This is a test-only fix. Reviewers may want to confirm that the new splicing message handlers are covered by other tests and that no additional fuzz targets have similar unhandled variant gaps.
Security signals we found
Panic in fuzz target due to unhandled MessageSendEvent variants
Splicing-related message events (SendTxInitRbf, SendTxAckRbf, SendTxRemoveInput, SendTxRemoveOutput) were reachable but unmatched
Fix is confined to fuzz testing harness; production code paths unchanged
Evidence from the diff
The chanmon_consistency fuzz target in fuzz/src/chanmon_consistency.rs had wildcard match arms that panicked on unhandled MessageSendEvent variants. After splicing support was added in commit 5873660a0, the variants SendTxInitRbf, SendTxAckRbf, SendTxRemoveInput, and SendTxRemoveOutput became reachable during fuzzing but were not matched. The patch adds match arms for these variants in two places: one that filters messages by destination node, and one that delivers the messages to the appropriate peer’s handler. This is purely a fuzzing/infrastructure change; no runtime consensus or networking logic is modified.
Changed components
fuzz/src/chanmon_consistency.rsInspect captured patch +32 / −0
diff --git a/fuzz/src/chanmon_consistency.rs b/fuzz/src/chanmon_consistency.rs
index 45e9a68..228439f 100644
--- a/fuzz/src/chanmon_consistency.rs
+++ b/fuzz/src/chanmon_consistency.rs
@@ -1515,6 +1515,14 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
*node_id == a_id
},
+ MessageSendEvent::SendTxRemoveInput { ref node_id, .. } => {
+ if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
+ *node_id == a_id
+ },
+ MessageSendEvent::SendTxRemoveOutput { ref node_id, .. } => {
+ if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
+ *node_id == a_id
+ },
MessageSendEvent::SendTxComplete { ref node_id, .. } => {
if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
*node_id == a_id
@@ -1523,6 +1531,14 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
*node_id == a_id
},
+ MessageSendEvent::SendTxInitRbf { ref node_id, .. } => {
+ if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
+ *node_id == a_id
+ },
+ MessageSendEvent::SendTxAckRbf { ref node_id, .. } => {
+ if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
+ *node_id == a_id
+ },
MessageSendEvent::SendTxSignatures { ref node_id, .. } => {
if Some(*node_id) == expect_drop_id { panic!("peer_disconnected should drop msgs bound for the disconnected peer"); }
*node_id == a_id
@@ -1715,6 +1731,22 @@ pub fn do_test<Out: Output + MaybeSend + MaybeSync>(
}
}
},
+ MessageSendEvent::SendTxInitRbf { ref node_id, ref msg } => {
+ for (idx, dest) in nodes.iter().enumerate() {
+ if dest.get_our_node_id() == *node_id {
+ out.locked_write(format!("Delivering tx_init_rbf from node {} to node {}.\n", $node, idx).as_bytes());
+ dest.handle_tx_init_rbf(nodes[$node].get_our_node_id(), msg);
+ }
+ }
+ },
+ MessageSendEvent::SendTxAckRbf { ref node_id, ref msg } => {
+ for (idx, dest) in nodes.iter().enumerate() {
+ if dest.get_our_node_id() == *node_id {
+ out.locked_write(format!("Delivering tx_ack_rbf from node {} to node {}.\n", $node, idx).as_bytes());
+ dest.handle_tx_ack_rbf(nodes[$node].get_our_node_id(), msg);
+ }
+ }
+ },
MessageSendEvent::SendTxSignatures { ref node_id, ref msg } => {
for (idx, dest) in nodes.iter().enumerate() {
if dest.get_our_node_id() == *node_id {
Why this scored 17/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.