+ $crate::ln::functional_test_utils::do_commitment_signed_dance(&$node_a, &$node_b, &$commitment_signed, $fail_backwards, false);
+ }
+}
+
+/// Runs the commitment_signed dance after the initial commitment_signed is delivered through to
+/// the initiator's `revoke_and_ack` response. i.e. [`do_main_commitment_signed_dance`] plus the
+/// `revoke_and_ack` response to it.
+///
+/// An HTLC claim on one channel blocks the RAA channel monitor update for the outbound edge
+/// channel until the inbound edge channel preimage monitor update completes. Thus, when checking
+/// for channel monitor updates, we need to know if an `update_fulfill_htlc` was included in the
+/// the commitment we're exchanging. `includes_claim` provides that information.
+///
+/// Returns any additional message `node_b` generated in addition to the `revoke_and_ack` response.
+pub fn commitment_signed_dance_through_cp_raa(node_a: &Node<'_, '_, '_>, node_b: &Node<'_, '_, '_>, fail_backwards: bool, includes_claim: bool) -> Option<MessageSendEvent> {
+ let (extra_msg_option, bs_revoke_and_ack) = do_main_commitment_signed_dance(node_a, node_b, fail_backwards);
+ node_a.node.handle_revoke_and_ack(&node_b.node.get_our_node_id(), &bs_revoke_and_ack);
+ check_added_monitors(node_a, if includes_claim { 0 } else { 1 });
+ extra_msg_option
+}
+
+/// Does the main logic in the commitment_signed dance. After the first `commitment_signed` has
+/// been delivered, this method picks up and delivers the response `revoke_and_ack` and
+/// `commitment_signed`, returning the recipient's `revoke_and_ack` and any extra message it may
+/// have included.
+pub fn do_main_commitment_signed_dance(node_a: &Node<'_, '_, '_>, node_b: &Node<'_, '_, '_>, fail_backwards: bool) -> (Option<MessageSendEvent>, msgs::RevokeAndACK) {
+ let (as_revoke_and_ack, as_commitment_signed) = get_revoke_commit_msgs!(node_a, node_b.node.get_our_node_id());
+ check_added_monitors!(node_b, 0);
+ assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
+ node_b.node.handle_revoke_and_ack(&node_a.node.get_our_node_id(), &as_revoke_and_ack);
+ assert!(node_b.node.get_and_clear_pending_msg_events().is_empty());
+ check_added_monitors!(node_b, 1);
+ node_b.node.handle_commitment_signed(&node_a.node.get_our_node_id(), &as_commitment_signed);
+ let (bs_revoke_and_ack, extra_msg_option) = {
+ let mut events = node_b.node.get_and_clear_pending_msg_events();
+ assert!(events.len() <= 2);
+ let node_a_event = remove_first_msg_event_to_node(&node_a.node.get_our_node_id(), &mut events);
+ (match node_a_event {
+ MessageSendEvent::SendRevokeAndACK { ref node_id, ref msg } => {
+ assert_eq!(*node_id, node_a.node.get_our_node_id());
+ (*msg).clone()
+ },
+ _ => panic!("Unexpected event"),
+ }, events.get(0).map(|e| e.clone()))
+ };
+ check_added_monitors!(node_b, 1);
+ if fail_backwards {
+ assert!(node_a.node.get_and_clear_pending_events().is_empty());
+ assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
+ }
+ (extra_msg_option, bs_revoke_and_ack)
+}
+
+/// Runs a full commitment_signed dance, delivering a commitment_signed, the responding
+/// `revoke_and_ack` and `commitment_signed`, and then the final `revoke_and_ack` response.
+///
+/// If `skip_last_step` is unset, also checks for the payment failure update for the previous hop
+/// on failure or that no new messages are left over on success.
+pub fn do_commitment_signed_dance(node_a: &Node<'_, '_, '_>, node_b: &Node<'_, '_, '_>, commitment_signed: &msgs::CommitmentSigned, fail_backwards: bool, skip_last_step: bool) {
+ check_added_monitors!(node_a, 0);
+ assert!(node_a.node.get_and_clear_pending_msg_events().is_empty());
+ node_a.node.handle_commitment_signed(&node_b.node.get_our_node_id(), commitment_signed);
+ check_added_monitors!(node_a, 1);
+
+ // If this commitment signed dance was due to a claim, don't check for an RAA monitor update.
+ let got_claim = node_a.node.test_raa_monitor_updates_held(node_b.node.get_our_node_id(), commitment_signed.channel_id);
+ if fail_backwards { assert!(!got_claim); }
+ commitment_signed_dance!(node_a, node_b, (), fail_backwards, true, false, got_claim);
+
+ if skip_last_step { return; }
+
+ if fail_backwards {
+ expect_pending_htlcs_forwardable_and_htlc_handling_failed!(node_a,
+ vec![crate::events::HTLCDestination::NextHopChannel{ node_id: Some(node_b.node.get_our_node_id()), channel_id: commitment_signed.channel_id }]);
+ check_added_monitors!(node_a, 1);
+
+ let node_a_per_peer_state = node_a.node.per_peer_state.read().unwrap();
+ let mut number_of_msg_events = 0;
+ for (cp_id, peer_state_mutex) in node_a_per_peer_state.iter() {
+ let peer_state = peer_state_mutex.lock().unwrap();
+ let cp_pending_msg_events = &peer_state.pending_msg_events;
+ number_of_msg_events += cp_pending_msg_events.len();
+ if cp_pending_msg_events.len() == 1 {
+ if let MessageSendEvent::UpdateHTLCs { .. } = cp_pending_msg_events[0] {
+ assert_ne!(*cp_id, node_b.node.get_our_node_id());