Skip to content

Commit 38f6df2

Browse files
committed
Clear monitor-pending RAA once regenerated
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 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` whenever `get_last_revoke_and_ack` successfully constructs an RAA, alongside `signer_pending_revoke_and_ack`. All resend paths regenerate RAAs through this helper, so successful generation through either pending path satisfies the other pending record. If generation fails, pending signer state is still left set and monitor-pending state remains available for monitor restoration to retry.
1 parent 2344577 commit 38f6df2

2 files changed

Lines changed: 207 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: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10343,6 +10343,7 @@ where
1034310343
}
1034410344

1034510345
self.context.signer_pending_revoke_and_ack = false;
10346+
self.context.monitor_pending_revoke_and_ack = false;
1034610347
return Some(msgs::RevokeAndACK {
1034710348
channel_id: self.context.channel_id,
1034810349
per_commitment_secret,

0 commit comments

Comments
 (0)