Skip to content

Commit 27223fd

Browse files
committed
Clear duplicate monitor-pending RAA on signer resend
The `chanmon_consistency` fuzz target found a reconnect ordering where `signer_pending_revoke_and_ack` and `monitor_pending_revoke_and_ack` could both describe the same owed `revoke_and_ack`. The channel first received a `commitment_signed` whose monitor update completed, but the signer could not provide the next point or secret, leaving `signer_pending_revoke_and_ack` set. Later, receiving the peer `revoke_and_ack` freed holding-cell HTLCs and produced a held monitor update. While that monitor update was still blocked, `channel_reestablish` saw the peer one state behind and recorded `monitor_pending_revoke_and_ack`, plus the corresponding monitor-pending `commitment_signed`, so the messages could be replayed once monitor updating was restored. If the signer unblocked before the held monitor update was released, `signer_maybe_unblocked` generated and sent the already monitor-safe RAA using `signer_pending_revoke_and_ack`. The monitor-pending flag was not cleared at that point, so `monitor_updating_restored` later generated the same RAA again when the held update completed. The peer had already advanced after accepting the signer-unblocked RAA, so it rejected the duplicate secret as not corresponding to its current pubkey and force-closed. Fix this by clearing `monitor_pending_revoke_and_ack` in the signer-resume path only once a signer-pending RAA is actually being returned.
1 parent 2344577 commit 27223fd

2 files changed

Lines changed: 213 additions & 1 deletion

File tree

lightning/src/ln/async_signer_tests.rs

Lines changed: 206 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use bitcoin::{Amount, TxOut};
1818

1919
use crate::chain::channelmonitor::LATENCY_GRACE_PERIOD_BLOCKS;
2020
use crate::chain::ChannelMonitorUpdateStatus;
21-
use crate::events::{ClosureReason, Event};
21+
use crate::events::{ClosureReason, Event, HTLCHandlingFailureType};
2222
use crate::ln::chan_utils::ClosingTransaction;
2323
use crate::ln::channel::DISCONNECT_PEER_AWAITING_RESPONSE_TICKS;
2424
use crate::ln::channel_state::{ChannelDetails, ChannelShutdownState};
@@ -498,6 +498,211 @@ fn test_async_raa_peer_disconnect() {
498498
do_test_async_raa_peer_disconnect(UnblockSignerAcrossDisconnectCase::BeforeReestablish, false);
499499
}
500500

501+
#[test]
502+
fn test_signer_unblocked_clears_monitor_pending_raa_after_reestablish() {
503+
let chanmon_cfgs = create_chanmon_cfgs(3);
504+
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
505+
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
506+
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
507+
508+
let node_a_id = nodes[0].node.get_our_node_id();
509+
let node_b_id = nodes[1].node.get_our_node_id();
510+
let node_c_id = nodes[2].node.get_our_node_id();
511+
512+
create_announced_chan_between_nodes(&nodes, 0, 1);
513+
let chan_bc = create_announced_chan_between_nodes(&nodes, 1, 2);
514+
515+
// Rebalance so that node C can send a payment back through node B later in the test.
516+
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 5_000_000);
517+
518+
// Put the B-C channel into AwaitingRAA by having C fail a payment backwards and retaining C's
519+
// final RAA instead of delivering it to B immediately.
520+
let (_, payment_hash_1, ..) = route_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1_000_000);
521+
nodes[2].node.fail_htlc_backwards(&payment_hash_1);
522+
expect_and_process_pending_htlcs_and_htlc_handling_failed(
523+
&nodes[2],
524+
&[HTLCHandlingFailureType::Receive { payment_hash: payment_hash_1 }],
525+
);
526+
check_added_monitors(&nodes[2], 1);
527+
528+
let updates = get_htlc_update_msgs(&nodes[2], &node_b_id);
529+
assert!(updates.update_add_htlcs.is_empty());
530+
assert_eq!(updates.update_fail_htlcs.len(), 1);
531+
assert!(updates.update_fail_malformed_htlcs.is_empty());
532+
assert!(updates.update_fee.is_none());
533+
nodes[1].node.handle_update_fail_htlc(node_c_id, &updates.update_fail_htlcs[0]);
534+
535+
let pending_c_raa =
536+
commitment_signed_dance_return_raa(&nodes[1], &nodes[2], &updates.commitment_signed, false);
537+
check_added_monitors(&nodes[0], 0);
538+
539+
// While B is waiting for C's RAA, forward another A-to-C payment. B accepts it on the A-B
540+
// channel, but cannot forward it over B-C yet, so it is held in B's holding cell.
541+
let (route, payment_hash_2, _payment_preimage_2, payment_secret_2) =
542+
get_route_and_payment_hash!(nodes[0], nodes[2], 1_000_000);
543+
let onion_2 = RecipientOnionFields::secret_only(payment_secret_2, 1_000_000);
544+
let id_2 = PaymentId(payment_hash_2.0);
545+
nodes[0].node.send_payment_with_route(route, payment_hash_2, onion_2, id_2).unwrap();
546+
check_added_monitors(&nodes[0], 1);
547+
548+
let send_event = SendEvent::from_node(&nodes[0]);
549+
assert_eq!(send_event.node_id, node_b_id);
550+
assert_eq!(send_event.msgs.len(), 1);
551+
nodes[1].node.handle_update_add_htlc(node_a_id, &send_event.msgs[0]);
552+
do_commitment_signed_dance(&nodes[1], &nodes[0], &send_event.commitment_msg, false, false);
553+
554+
expect_and_process_pending_htlcs(&nodes[1], false);
555+
check_added_monitors(&nodes[1], 0);
556+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
557+
558+
// Now make B owe C an RAA whose monitor update has already completed, but whose RAA cannot be
559+
// constructed because B's signer is unavailable.
560+
let (route, payment_hash_3, _payment_preimage_3, payment_secret_3) =
561+
get_route_and_payment_hash!(nodes[2], nodes[0], 1_000_000);
562+
let onion_3 = RecipientOnionFields::secret_only(payment_secret_3, 1_000_000);
563+
let id_3 = PaymentId(payment_hash_3.0);
564+
nodes[2].node.send_payment_with_route(route, payment_hash_3, onion_3, id_3).unwrap();
565+
check_added_monitors(&nodes[2], 1);
566+
567+
let send_event = SendEvent::from_node(&nodes[2]);
568+
assert_eq!(send_event.node_id, node_b_id);
569+
assert_eq!(send_event.msgs.len(), 1);
570+
nodes[1].node.handle_update_add_htlc(node_c_id, &send_event.msgs[0]);
571+
nodes[1].disable_channel_signer_op(&node_c_id, &chan_bc.2, SignerOp::ReleaseCommitmentSecret);
572+
nodes[1].node.handle_commitment_signed_batch_test(node_c_id, &send_event.commitment_msg);
573+
check_added_monitors(&nodes[1], 1);
574+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
575+
576+
// Deliver C's earlier RAA to B while monitor updating is blocked. This frees B's holding-cell
577+
// HTLC and leaves a monitor update in flight.
578+
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::InProgress);
579+
nodes[1].node.handle_revoke_and_ack(node_c_id, &pending_c_raa);
580+
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
581+
assert!(nodes[1].node.get_and_clear_pending_events().is_empty());
582+
check_added_monitors(&nodes[1], 1);
583+
584+
nodes[1].node.peer_disconnected(node_c_id);
585+
nodes[2].node.peer_disconnected(node_b_id);
586+
587+
let init_msg = msgs::Init {
588+
features: nodes[2].node.init_features(),
589+
networks: None,
590+
remote_network_address: None,
591+
};
592+
nodes[1].node.peer_connected(node_c_id, &init_msg, true).unwrap();
593+
let bs_reestablish = get_chan_reestablish_msgs!(nodes[1], nodes[2]);
594+
assert_eq!(bs_reestablish.len(), 1);
595+
let init_msg = msgs::Init {
596+
features: nodes[1].node.init_features(),
597+
networks: None,
598+
remote_network_address: None,
599+
};
600+
nodes[2].node.peer_connected(node_b_id, &init_msg, false).unwrap();
601+
let cs_reestablish = get_chan_reestablish_msgs!(nodes[2], nodes[1]);
602+
assert_eq!(cs_reestablish.len(), 1);
603+
604+
nodes[1].node.handle_channel_reestablish(node_c_id, &cs_reestablish[0]);
605+
606+
// The signer-pending path now generates the owed RAA before the held monitor update
607+
// completes.
608+
nodes[1].enable_channel_signer_op(&node_c_id, &chan_bc.2, SignerOp::ReleaseCommitmentSecret);
609+
nodes[1].node.signer_unblocked(Some((node_c_id, chan_bc.2)));
610+
let (_, signer_revoke_and_ack, signer_commitment_update, _, _, _, _, _) =
611+
handle_chan_reestablish_msgs!(nodes[1], nodes[2]);
612+
assert!(signer_revoke_and_ack.is_some());
613+
614+
// Once the held monitor update completes, B must not generate the same RAA a second time via
615+
// the monitor-pending path.
616+
chanmon_cfgs[1].persister.set_update_ret(ChannelMonitorUpdateStatus::Completed);
617+
let (latest_update, _) = nodes[1].chain_monitor.get_latest_mon_update_id(chan_bc.2);
618+
nodes[1].chain_monitor.chain_monitor.force_channel_monitor_updated(chan_bc.2, latest_update);
619+
check_added_monitors(&nodes[1], 0);
620+
let (_, duplicate_revoke_and_ack, monitor_commitment_update, _, _, _, _, _) =
621+
handle_chan_reestablish_msgs!(nodes[1], nodes[2]);
622+
assert!(duplicate_revoke_and_ack.is_none());
623+
624+
nodes[2].node.handle_channel_reestablish(node_b_id, &bs_reestablish[0]);
625+
let (_, c_revoke_and_ack, c_commitment_update, _, _, _, _, _) =
626+
handle_chan_reestablish_msgs!(nodes[2], nodes[1]);
627+
assert!(c_revoke_and_ack.is_none());
628+
assert!(c_commitment_update.is_none());
629+
630+
nodes[2].node.handle_revoke_and_ack(node_b_id, &signer_revoke_and_ack.unwrap());
631+
check_added_monitors(&nodes[2], 1);
632+
633+
let commitment_update = signer_commitment_update.or(monitor_commitment_update);
634+
if let Some(commitment_update) = commitment_update {
635+
let send_event = SendEvent::from_commitment_update(node_c_id, chan_bc.2, commitment_update);
636+
assert_eq!(send_event.node_id, node_c_id);
637+
for update_add in send_event.msgs {
638+
nodes[2].node.handle_update_add_htlc(node_b_id, &update_add);
639+
}
640+
nodes[2].node.handle_commitment_signed_batch_test(node_b_id, &send_event.commitment_msg);
641+
check_added_monitors(&nodes[2], 1);
642+
let (c_raa, c_commitment_signed) = get_revoke_commit_msgs(&nodes[2], &node_b_id);
643+
nodes[1].node.handle_revoke_and_ack(node_c_id, &c_raa);
644+
check_added_monitors(&nodes[1], 1);
645+
nodes[1].node.handle_commitment_signed_batch_test(node_c_id, &c_commitment_signed);
646+
check_added_monitors(&nodes[1], 1);
647+
let b_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, node_c_id);
648+
nodes[2].node.handle_revoke_and_ack(node_b_id, &b_raa);
649+
check_added_monitors(&nodes[2], 1);
650+
}
651+
652+
let (route, final_payment_hash, _final_payment_preimage, final_payment_secret) =
653+
get_route_and_payment_hash!(nodes[1], nodes[2], 100_000);
654+
let final_payment_id = PaymentId(final_payment_hash.0);
655+
nodes[1]
656+
.node
657+
.send_payment_with_route(
658+
route,
659+
final_payment_hash,
660+
RecipientOnionFields::secret_only(final_payment_secret, 100_000),
661+
final_payment_id,
662+
)
663+
.unwrap();
664+
check_added_monitors(&nodes[1], 1);
665+
let final_payment_event = nodes[1].node.get_and_clear_pending_msg_events().remove(0);
666+
match &final_payment_event {
667+
MessageSendEvent::UpdateHTLCs { node_id, .. } => assert_eq!(*node_id, node_c_id),
668+
_ => panic!("Unexpected event"),
669+
}
670+
do_pass_along_path(
671+
PassAlongPathArgs::new(
672+
&nodes[1],
673+
&[&nodes[2]],
674+
100_000,
675+
final_payment_hash,
676+
final_payment_event,
677+
)
678+
.with_payment_secret(final_payment_secret)
679+
.without_clearing_recipient_events(),
680+
);
681+
682+
let claimable_events = nodes[2].node.get_and_clear_pending_events();
683+
let final_claimable = claimable_events
684+
.iter()
685+
.find(|event| {
686+
matches!(
687+
event,
688+
Event::PaymentClaimable { payment_hash, .. } if *payment_hash == final_payment_hash
689+
)
690+
})
691+
.unwrap();
692+
check_payment_claimable(
693+
final_claimable,
694+
final_payment_hash,
695+
final_payment_secret,
696+
100_000,
697+
None,
698+
node_c_id,
699+
);
700+
expect_htlc_failure_conditions(
701+
nodes[1].node.get_and_clear_pending_events(),
702+
&[HTLCHandlingFailureType::Forward { node_id: Some(node_c_id), channel_id: chan_bc.2 }],
703+
);
704+
}
705+
501706
fn do_test_async_raa_peer_disconnect(
502707
test_case: UnblockSignerAcrossDisconnectCase, raa_blocked_by_commit_point: bool,
503708
) {

lightning/src/ln/channel.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10259,6 +10259,13 @@ where
1025910259
self.context.signer_pending_commitment_update = true;
1026010260
commitment_update = None;
1026110261
}
10262+
if revoke_and_ack.is_some() {
10263+
// If signer-pending state regenerated an RAA, the monitor update for that RAA was
10264+
// already persisted before we set `signer_pending_revoke_and_ack`. Thus, if reconnect
10265+
// also marked the same RAA monitor-pending while another monitor update was in flight,
10266+
// the RAA we're returning here satisfies that monitor-pending resend.
10267+
self.context.monitor_pending_revoke_and_ack = false;
10268+
}
1026210269

1026310270
let (closing_signed, signed_closing_tx, shutdown_result) = if self.context.signer_pending_closing {
1026410271
debug_assert!(self.context.last_sent_closing_fee.is_some());

0 commit comments

Comments
 (0)