use crate::events::{ClosureReason, Event, HTLCHandlingFailureType, PaymentPurpose};
use crate::ln::chan_utils::{
self, commitment_tx_base_weight, second_stage_tx_fees_sat, CommitmentTransaction,
COMMITMENT_TX_WEIGHT_PER_HTLC,
};
use crate::ln::channel::{
get_holder_selected_channel_reserve_satoshis, Channel, FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE,
MIN_AFFORDABLE_HTLC_COUNT, MIN_CHAN_DUST_LIMIT_SATOSHIS,
};
use crate::ln::channelmanager::{PaymentId, RAACommitmentOrder};
use crate::ln::functional_test_utils::*;
use crate::ln::msgs::{self, BaseMessageHandler, ChannelMessageHandler, MessageSendEvent};
use crate::ln::onion_utils::{self, AttributionData};
use crate::ln::outbound_payment::RecipientOnionFields;
use crate::routing::router::PaymentParameters;
use crate::sign::ecdsa::EcdsaChannelSigner;
use crate::sign::tx_builder::{SpecTxBuilder, TxBuilder};
use crate::types::features::ChannelTypeFeatures;
use crate::types::payment::PaymentPreimage;
use crate::util::config::UserConfig;
use crate::util::errors::APIError;
use lightning_macros::xtest;
use bitcoin::secp256k1::{Secp256k1, SecretKey};
fn do_test_counterparty_no_reserve(send_from_initiator: bool) {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let default_config = UserConfig::default();
let mut push_amt = 100_000_000;
let feerate_per_kw = 253;
let channel_type_features = ChannelTypeFeatures::only_static_remote_key();
push_amt -= feerate_per_kw as u64
* (commitment_tx_base_weight(&channel_type_features) + 4 * COMMITMENT_TX_WEIGHT_PER_HTLC)
/ 1000 * 1000;
push_amt -= get_holder_selected_channel_reserve_satoshis(100_000, &default_config) * 1000;
let push = if send_from_initiator { 0 } else { push_amt };
let temp_channel_id =
nodes[0].node.create_channel(node_b_id, 100_000, push, 42, None, None).unwrap();
let mut open_channel_message =
get_event_msg!(nodes[0], MessageSendEvent::SendOpenChannel, node_b_id);
if !send_from_initiator {
open_channel_message.channel_reserve_satoshis = 0;
open_channel_message.common_fields.max_htlc_value_in_flight_msat = 100_000_000;
}
nodes[1].node.handle_open_channel(node_a_id, &open_channel_message);
let mut accept_channel_message =
get_event_msg!(nodes[1], MessageSendEvent::SendAcceptChannel, node_a_id);
if send_from_initiator {
accept_channel_message.channel_reserve_satoshis = 0;
accept_channel_message.common_fields.max_htlc_value_in_flight_msat = 100_000_000;
}
nodes[0].node.handle_accept_channel(node_b_id, &accept_channel_message);
{
let sender_node = if send_from_initiator { &nodes[1] } else { &nodes[0] };
let counterparty_node = if send_from_initiator { &nodes[0] } else { &nodes[1] };
let mut sender_node_per_peer_lock;
let mut sender_node_peer_state_lock;
let channel = get_channel_ref!(
sender_node,
counterparty_node,
sender_node_per_peer_lock,
sender_node_peer_state_lock,
temp_channel_id
);
assert!(channel.is_unfunded_v1());
channel.funding_mut().holder_selected_channel_reserve_satoshis = 0;
channel.context_mut().holder_max_htlc_value_in_flight_msat = 100_000_000;
}
let funding_tx = sign_funding_transaction(&nodes[0], &nodes[1], 100_000, temp_channel_id);
let funding_msgs =
create_chan_between_nodes_with_value_confirm(&nodes[0], &nodes[1], &funding_tx);
create_chan_between_nodes_with_value_b(&nodes[0], &nodes[1], &funding_msgs.0);
if send_from_initiator {
send_payment(
&nodes[0],
&[&nodes[1]],
100_000_000
- FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE * commit_tx_fee_msat(feerate_per_kw, 2, &channel_type_features),
);
} else {
send_payment(&nodes[1], &[&nodes[0]], push_amt);
}
}
#[xtest(feature = "_externalize_tests")]
pub fn test_counterparty_no_reserve() {
do_test_counterparty_no_reserve(true);
do_test_counterparty_no_reserve(false);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_channel_reserve_holding_cell_htlcs() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let mut config = test_default_channel_config();
config.channel_config.forwarding_fee_base_msat = 239;
let configs = [Some(config.clone()), Some(config.clone()), Some(config.clone())];
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &configs);
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let node_c_id = nodes[2].node.get_our_node_id();
let chan_1 = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 190000, 1001);
let chan_2 = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 190000, 1001);
let chan_2_user_id = nodes[2].node.list_channels()[0].user_channel_id;
let mut stat01 = get_channel_value_stat!(nodes[0], nodes[1], chan_1.2);
let mut stat11 = get_channel_value_stat!(nodes[1], nodes[0], chan_1.2);
let mut stat12 = get_channel_value_stat!(nodes[1], nodes[2], chan_2.2);
let mut stat22 = get_channel_value_stat!(nodes[2], nodes[1], chan_2.2);
macro_rules! expect_forward {
($node: expr) => {{
let mut events = $node.node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
check_added_monitors(&$node, 1);
let payment_event = SendEvent::from_event(events.remove(0));
payment_event
}};
}
let feemsat = 239; let total_fee_msat = (nodes.len() - 2) as u64 * feemsat;
let feerate = get_feerate!(nodes[0], nodes[1], chan_1.2);
let channel_type_features = get_channel_type_features!(nodes[0], nodes[1], chan_1.2);
let recv_value_0 = stat01.counterparty_max_htlc_value_in_flight_msat - total_fee_msat;
{
let payment_params = PaymentParameters::from_node_id(node_c_id, TEST_FINAL_CLTV)
.with_bolt11_features(nodes[2].node.bolt11_invoice_features())
.unwrap()
.with_max_channel_saturation_power_of_half(0);
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[2], payment_params, recv_value_0);
route.paths[0].hops.last_mut().unwrap().fee_msat += 1;
assert!(route.paths[0].hops.iter().rev().skip(1).all(|h| h.fee_msat == feemsat));
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[0], res, true, APIError::ChannelUnavailable { .. }, {});
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
}
loop {
let amt_msat = recv_value_0 + total_fee_msat;
let commit_tx_fee_all_htlcs =
2 * commit_tx_fee_msat(feerate, 3 + 1, &channel_type_features);
let ensure_htlc_amounts_above_dust_buffer =
3 * (stat01.counterparty_dust_limit_msat + 1000);
if stat01.value_to_self_msat
< stat01.channel_reserve_msat
+ commit_tx_fee_all_htlcs
+ ensure_htlc_amounts_above_dust_buffer
+ amt_msat
{
break;
}
let payment_params = PaymentParameters::from_node_id(node_c_id, TEST_FINAL_CLTV)
.with_bolt11_features(nodes[2].node.bolt11_invoice_features())
.unwrap()
.with_max_channel_saturation_power_of_half(0);
let route = get_route!(nodes[0], payment_params, recv_value_0).unwrap();
let (payment_preimage, ..) =
send_along_route(&nodes[0], route, &[&nodes[1], &nodes[2]], recv_value_0);
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], payment_preimage);
let (stat01_, stat11_, stat12_, stat22_) = (
get_channel_value_stat!(nodes[0], nodes[1], chan_1.2),
get_channel_value_stat!(nodes[1], nodes[0], chan_1.2),
get_channel_value_stat!(nodes[1], nodes[2], chan_2.2),
get_channel_value_stat!(nodes[2], nodes[1], chan_2.2),
);
assert_eq!(stat01_.value_to_self_msat, stat01.value_to_self_msat - amt_msat);
assert_eq!(stat11_.value_to_self_msat, stat11.value_to_self_msat + amt_msat);
assert_eq!(stat12_.value_to_self_msat, stat12.value_to_self_msat - (amt_msat - feemsat));
assert_eq!(stat22_.value_to_self_msat, stat22.value_to_self_msat + (amt_msat - feemsat));
stat01 = stat01_;
stat11 = stat11_;
stat12 = stat12_;
stat22 = stat22_;
}
let commit_tx_fee_2_htlcs = 2 * commit_tx_fee_msat(feerate, 2 + 1, &channel_type_features);
let recv_value_1 = (stat01.value_to_self_msat
- stat01.channel_reserve_msat
- total_fee_msat
- commit_tx_fee_2_htlcs)
/ 2;
let amt_msat_1 = recv_value_1 + total_fee_msat;
let (route_1, our_payment_hash_1, our_payment_preimage_1, our_payment_secret_1) =
get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_1);
let payment_event_1 = {
let route = route_1.clone();
let onion = RecipientOnionFields::secret_only(our_payment_secret_1);
let id = PaymentId(our_payment_hash_1.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash_1, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
SendEvent::from_event(events.remove(0))
};
nodes[1].node.handle_update_add_htlc(node_a_id, &payment_event_1.msgs[0]);
let recv_value_2 = stat01.value_to_self_msat
- amt_msat_1
- stat01.channel_reserve_msat
- total_fee_msat
- commit_tx_fee_2_htlcs;
{
let mut route = route_1.clone();
route.paths[0].hops.last_mut().unwrap().fee_msat = recv_value_2 + 1;
let (_, our_payment_hash, our_payment_secret) = get_payment_preimage_hash!(nodes[2]);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[0], res, true, APIError::ChannelUnavailable { .. }, {});
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
}
let commit_tx_fee_3_htlcs = 2 * commit_tx_fee_msat(feerate, 3 + 1, &channel_type_features);
let additional_htlc_cost_msat = commit_tx_fee_3_htlcs - commit_tx_fee_2_htlcs;
let recv_value_21 = recv_value_2 / 2 - additional_htlc_cost_msat / 2;
let recv_value_22 = recv_value_2 - recv_value_21 - total_fee_msat - additional_htlc_cost_msat;
{
let stat = get_channel_value_stat!(nodes[0], nodes[1], chan_1.2);
assert_eq!(
stat.value_to_self_msat
- (stat.pending_outbound_htlcs_amount_msat
+ recv_value_21 + recv_value_22
+ total_fee_msat + total_fee_msat
+ commit_tx_fee_3_htlcs),
stat.channel_reserve_msat
);
}
let (route_21, our_payment_hash_21, our_payment_preimage_21, our_payment_secret_21) =
get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_21);
let onion = RecipientOnionFields::secret_only(our_payment_secret_21);
let id = PaymentId(our_payment_hash_21.0);
nodes[0].node.send_payment_with_route(route_21, our_payment_hash_21, onion, id).unwrap();
check_added_monitors(&nodes[0], 0);
let events = nodes[0].node.get_and_clear_pending_events();
assert_eq!(events.len(), 0);
{
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_22);
route.paths[0].hops.last_mut().unwrap().fee_msat += 1;
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[0], res, true, APIError::ChannelUnavailable { .. }, {});
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
}
let (route_22, our_payment_hash_22, our_payment_preimage_22, our_payment_secret_22) =
get_route_and_payment_hash!(nodes[0], nodes[2], recv_value_22);
let onion = RecipientOnionFields::secret_only(our_payment_secret_22);
let id = PaymentId(our_payment_hash_22.0);
nodes[0].node.send_payment_with_route(route_22, our_payment_hash_22, onion, id).unwrap();
check_added_monitors(&nodes[0], 0);
assert!(nodes[0].node.get_and_clear_pending_events().is_empty());
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
nodes[1].node.handle_commitment_signed_batch_test(node_a_id, &payment_event_1.commitment_msg);
let (as_revoke_and_ack, as_commitment_signed) = get_revoke_commit_msgs!(nodes[1], node_a_id);
check_added_monitors(&nodes[1], 1);
nodes[0].node.handle_revoke_and_ack(node_b_id, &as_revoke_and_ack);
check_added_monitors(&nodes[0], 1);
let commitment_update_2 = get_htlc_update_msgs!(nodes[0], node_b_id);
nodes[0].node.handle_commitment_signed_batch_test(node_b_id, &as_commitment_signed);
let bs_revoke_and_ack = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, node_b_id);
check_added_monitors(&nodes[0], 1);
nodes[1].node.handle_revoke_and_ack(node_a_id, &bs_revoke_and_ack);
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
check_added_monitors(&nodes[1], 1);
expect_and_process_pending_htlcs(&nodes[1], false);
let ref payment_event_11 = expect_forward!(nodes[1]);
nodes[2].node.handle_update_add_htlc(node_b_id, &payment_event_11.msgs[0]);
commitment_signed_dance!(nodes[2], nodes[1], payment_event_11.commitment_msg, false);
expect_and_process_pending_htlcs(&nodes[2], false);
expect_payment_claimable!(nodes[2], our_payment_hash_1, our_payment_secret_1, recv_value_1);
assert_eq!(commitment_update_2.update_add_htlcs.len(), 2);
nodes[1].node.handle_update_add_htlc(node_a_id, &commitment_update_2.update_add_htlcs[0]);
nodes[1].node.handle_update_add_htlc(node_a_id, &commitment_update_2.update_add_htlcs[1]);
commitment_signed_dance!(nodes[1], nodes[0], &commitment_update_2.commitment_signed, false);
expect_and_process_pending_htlcs(&nodes[1], false);
let ref payment_event_3 = expect_forward!(nodes[1]);
assert_eq!(payment_event_3.msgs.len(), 2);
nodes[2].node.handle_update_add_htlc(node_b_id, &payment_event_3.msgs[0]);
nodes[2].node.handle_update_add_htlc(node_b_id, &payment_event_3.msgs[1]);
commitment_signed_dance!(nodes[2], nodes[1], &payment_event_3.commitment_msg, false);
expect_and_process_pending_htlcs(&nodes[2], false);
let events = nodes[2].node.get_and_clear_pending_events();
assert_eq!(events.len(), 2);
match events[0] {
Event::PaymentClaimable {
ref payment_hash,
ref purpose,
amount_msat,
receiver_node_id,
ref receiving_channel_ids,
..
} => {
assert_eq!(our_payment_hash_21, *payment_hash);
assert_eq!(recv_value_21, amount_msat);
assert_eq!(node_c_id, receiver_node_id.unwrap());
assert_eq!(*receiving_channel_ids, vec![(chan_2.2, Some(chan_2_user_id))]);
match &purpose {
PaymentPurpose::Bolt11InvoicePayment {
payment_preimage, payment_secret, ..
} => {
assert!(payment_preimage.is_none());
assert_eq!(our_payment_secret_21, *payment_secret);
},
_ => panic!("expected PaymentPurpose::Bolt11InvoicePayment"),
}
},
_ => panic!("Unexpected event"),
}
match events[1] {
Event::PaymentClaimable {
ref payment_hash,
ref purpose,
amount_msat,
receiver_node_id,
ref receiving_channel_ids,
..
} => {
assert_eq!(our_payment_hash_22, *payment_hash);
assert_eq!(recv_value_22, amount_msat);
assert_eq!(node_c_id, receiver_node_id.unwrap());
assert_eq!(*receiving_channel_ids, vec![(chan_2.2, Some(chan_2_user_id))]);
match &purpose {
PaymentPurpose::Bolt11InvoicePayment {
payment_preimage, payment_secret, ..
} => {
assert!(payment_preimage.is_none());
assert_eq!(our_payment_secret_22, *payment_secret);
},
_ => panic!("expected PaymentPurpose::Bolt11InvoicePayment"),
}
},
_ => panic!("Unexpected event"),
}
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], our_payment_preimage_1);
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], our_payment_preimage_21);
claim_payment(&nodes[0], &[&nodes[1], &nodes[2]], our_payment_preimage_22);
let commit_tx_fee_0_htlcs = 2 * commit_tx_fee_msat(feerate, 1, &channel_type_features);
let recv_value_3 = commit_tx_fee_2_htlcs - commit_tx_fee_0_htlcs - total_fee_msat;
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], recv_value_3);
let commit_tx_fee_1_htlc = 2 * commit_tx_fee_msat(feerate, 1 + 1, &channel_type_features);
let expected_value_to_self = stat01.value_to_self_msat
- (recv_value_1 + total_fee_msat)
- (recv_value_21 + total_fee_msat)
- (recv_value_22 + total_fee_msat)
- (recv_value_3 + total_fee_msat);
let stat0 = get_channel_value_stat!(nodes[0], nodes[1], chan_1.2);
assert_eq!(stat0.value_to_self_msat, expected_value_to_self);
assert_eq!(stat0.value_to_self_msat, stat0.channel_reserve_msat + commit_tx_fee_1_htlc);
let stat2 = get_channel_value_stat!(nodes[2], nodes[1], chan_2.2);
assert_eq!(
stat2.value_to_self_msat,
stat22.value_to_self_msat + recv_value_1 + recv_value_21 + recv_value_22 + recv_value_3
);
}
#[xtest(feature = "_externalize_tests")]
pub fn channel_reserve_in_flight_removes() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let chan_1 = create_announced_chan_between_nodes(&nodes, 0, 1);
let b_chan_values = get_channel_value_stat!(nodes[1], nodes[0], chan_1.2);
let payment_value_1 =
b_chan_values.channel_reserve_msat - b_chan_values.value_to_self_msat - 10000;
let (payment_preimage_1, payment_hash_1, ..) =
route_payment(&nodes[0], &[&nodes[1]], payment_value_1);
let (payment_preimage_2, payment_hash_2, ..) = route_payment(&nodes[0], &[&nodes[1]], 20_000);
let (route, payment_hash_3, payment_preimage_3, payment_secret_3) =
get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
let send_1 = {
let onion = RecipientOnionFields::secret_only(payment_secret_3);
let id = PaymentId(payment_hash_3.0);
nodes[0].node.send_payment_with_route(route, payment_hash_3, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
SendEvent::from_event(events.remove(0))
};
nodes[1].node.claim_funds(payment_preimage_1);
expect_payment_claimed!(nodes[1], payment_hash_1, payment_value_1);
check_added_monitors(&nodes[1], 1);
let mut bs_removes = get_htlc_update_msgs!(nodes[1], node_a_id);
nodes[1].node.claim_funds(payment_preimage_2);
expect_payment_claimed!(nodes[1], payment_hash_2, 20_000);
check_added_monitors(&nodes[1], 1);
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
nodes[0].node.handle_update_fulfill_htlc(node_b_id, bs_removes.update_fulfill_htlcs.remove(0));
nodes[0].node.handle_commitment_signed_batch_test(node_b_id, &bs_removes.commitment_signed);
check_added_monitors(&nodes[0], 1);
let as_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, node_b_id);
expect_payment_sent(&nodes[0], payment_preimage_1, None, false, false);
nodes[1].node.handle_update_add_htlc(node_a_id, &send_1.msgs[0]);
nodes[1].node.handle_commitment_signed_batch_test(node_a_id, &send_1.commitment_msg);
check_added_monitors(&nodes[1], 1);
let bs_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, node_a_id);
nodes[1].node.handle_revoke_and_ack(node_a_id, &as_raa);
check_added_monitors(&nodes[1], 1);
let mut bs_cs = get_htlc_update_msgs!(nodes[1], node_a_id);
nodes[0].node.handle_revoke_and_ack(node_b_id, &bs_raa);
check_added_monitors(&nodes[0], 1);
let as_cs = get_htlc_update_msgs!(nodes[0], node_b_id);
nodes[1].node.handle_commitment_signed_batch_test(node_a_id, &as_cs.commitment_signed);
check_added_monitors(&nodes[1], 1);
let bs_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, node_a_id);
nodes[0].node.handle_update_fulfill_htlc(node_b_id, bs_cs.update_fulfill_htlcs.remove(0));
nodes[0].node.handle_commitment_signed_batch_test(node_b_id, &bs_cs.commitment_signed);
check_added_monitors(&nodes[0], 1);
let as_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, node_b_id);
expect_payment_sent(&nodes[0], payment_preimage_2, None, false, false);
nodes[1].node.handle_revoke_and_ack(node_a_id, &as_raa);
check_added_monitors(&nodes[1], 1);
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
expect_and_process_pending_htlcs(&nodes[1], false);
expect_payment_claimable!(nodes[1], payment_hash_3, payment_secret_3, 100000);
nodes[0].node.handle_revoke_and_ack(node_b_id, &bs_raa);
check_added_monitors(&nodes[0], 1);
expect_payment_path_successful!(nodes[0]);
let as_cs = get_htlc_update_msgs!(nodes[0], node_b_id);
let (route, payment_hash_4, payment_preimage_4, payment_secret_4) =
get_route_and_payment_hash!(nodes[1], nodes[0], 10000);
let send_2 = {
let onion = RecipientOnionFields::secret_only(payment_secret_4);
let id = PaymentId(payment_hash_4.0);
nodes[1].node.send_payment_with_route(route, payment_hash_4, onion, id).unwrap();
check_added_monitors(&nodes[1], 1);
let mut events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
SendEvent::from_event(events.remove(0))
};
nodes[0].node.handle_update_add_htlc(node_b_id, &send_2.msgs[0]);
nodes[0].node.handle_commitment_signed_batch_test(node_b_id, &send_2.commitment_msg);
check_added_monitors(&nodes[0], 1);
let as_raa = get_event_msg!(nodes[0], MessageSendEvent::SendRevokeAndACK, node_b_id);
nodes[1].node.handle_commitment_signed_batch_test(node_a_id, &as_cs.commitment_signed);
check_added_monitors(&nodes[1], 1);
let bs_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, node_a_id);
nodes[1].node.handle_revoke_and_ack(node_a_id, &as_raa);
check_added_monitors(&nodes[1], 1);
nodes[0].node.handle_revoke_and_ack(node_b_id, &bs_raa);
check_added_monitors(&nodes[0], 1);
expect_payment_path_successful!(nodes[0]);
let as_cs = get_htlc_update_msgs!(nodes[0], node_b_id);
nodes[1].node.handle_commitment_signed_batch_test(node_a_id, &as_cs.commitment_signed);
check_added_monitors(&nodes[1], 1);
let bs_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, node_a_id);
nodes[0].node.handle_revoke_and_ack(node_b_id, &bs_raa);
check_added_monitors(&nodes[0], 1);
expect_and_process_pending_htlcs(&nodes[0], false);
expect_payment_claimable!(nodes[0], payment_hash_4, payment_secret_4, 10000);
claim_payment(&nodes[1], &[&nodes[0]], payment_preimage_4);
claim_payment(&nodes[0], &[&nodes[1]], payment_preimage_3);
}
#[xtest(feature = "_externalize_tests")]
pub fn holding_cell_htlc_counting() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let node_c_id = nodes[2].node.get_our_node_id();
create_announced_chan_between_nodes(&nodes, 0, 1);
let chan_2 = create_announced_chan_between_nodes(&nodes, 1, 2);
let (route, payment_hash_1, _, payment_secret_1) =
get_route_and_payment_hash!(nodes[1], nodes[2], 100000);
let mut payments = Vec::new();
for _ in 0..50 {
let (route, payment_hash, payment_preimage, payment_secret) =
get_route_and_payment_hash!(nodes[1], nodes[2], 100000);
let onion = RecipientOnionFields::secret_only(payment_secret);
let id = PaymentId(payment_hash.0);
nodes[1].node.send_payment_with_route(route, payment_hash, onion, id).unwrap();
payments.push((payment_preimage, payment_hash));
}
check_added_monitors(&nodes[1], 1);
let mut events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
let initial_payment_event = SendEvent::from_event(events.pop().unwrap());
assert_eq!(initial_payment_event.node_id, node_c_id);
{
let onion = RecipientOnionFields::secret_only(payment_secret_1);
let id = PaymentId(payment_hash_1.0);
let res = nodes[1].node.send_payment_with_route(route, payment_hash_1, onion, id);
unwrap_send_err!(nodes[1], res, true, APIError::ChannelUnavailable { .. }, {});
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
}
let (route, payment_hash_2, _, payment_secret_2) =
get_route_and_payment_hash!(nodes[0], nodes[2], 100000);
let onion = RecipientOnionFields::secret_only(payment_secret_2);
let id = PaymentId(payment_hash_2.0);
nodes[0].node.send_payment_with_route(route, payment_hash_2, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
let payment_event = SendEvent::from_event(events.pop().unwrap());
assert_eq!(payment_event.node_id, node_b_id);
nodes[1].node.handle_update_add_htlc(node_a_id, &payment_event.msgs[0]);
commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
expect_and_process_pending_htlcs(&nodes[1], true);
let fail = HTLCHandlingFailureType::Forward { node_id: Some(node_c_id), channel_id: chan_2.2 };
let events = nodes[1].node.get_and_clear_pending_events();
expect_htlc_failure_conditions(events, &[fail]);
check_added_monitors(&nodes[1], 1);
let bs_fail_updates = get_htlc_update_msgs!(nodes[1], node_a_id);
nodes[0].node.handle_update_fail_htlc(node_b_id, &bs_fail_updates.update_fail_htlcs[0]);
commitment_signed_dance!(nodes[0], nodes[1], bs_fail_updates.commitment_signed, false, true);
let failing_scid = chan_2.0.contents.short_channel_id;
expect_payment_failed_with_update!(nodes[0], payment_hash_2, false, failing_scid, false);
nodes[2].node.handle_update_add_htlc(node_b_id, &initial_payment_event.msgs[0]);
nodes[2]
.node
.handle_commitment_signed_batch_test(node_b_id, &initial_payment_event.commitment_msg);
check_added_monitors(&nodes[2], 1);
let (bs_revoke_and_ack, bs_commitment_signed) = get_revoke_commit_msgs!(nodes[2], node_b_id);
nodes[1].node.handle_revoke_and_ack(node_c_id, &bs_revoke_and_ack);
check_added_monitors(&nodes[1], 1);
let as_updates = get_htlc_update_msgs!(nodes[1], node_c_id);
nodes[1].node.handle_commitment_signed_batch_test(node_c_id, &bs_commitment_signed);
check_added_monitors(&nodes[1], 1);
let as_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, node_c_id);
for ref update in as_updates.update_add_htlcs.iter() {
nodes[2].node.handle_update_add_htlc(node_b_id, update);
}
nodes[2].node.handle_commitment_signed_batch_test(node_b_id, &as_updates.commitment_signed);
check_added_monitors(&nodes[2], 1);
nodes[2].node.handle_revoke_and_ack(node_b_id, &as_raa);
check_added_monitors(&nodes[2], 1);
let (bs_revoke_and_ack, bs_commitment_signed) = get_revoke_commit_msgs!(nodes[2], node_b_id);
nodes[1].node.handle_revoke_and_ack(node_c_id, &bs_revoke_and_ack);
check_added_monitors(&nodes[1], 1);
nodes[1].node.handle_commitment_signed_batch_test(node_c_id, &bs_commitment_signed);
check_added_monitors(&nodes[1], 1);
let as_final_raa = get_event_msg!(nodes[1], MessageSendEvent::SendRevokeAndACK, node_c_id);
nodes[2].node.handle_revoke_and_ack(node_b_id, &as_final_raa);
check_added_monitors(&nodes[2], 1);
expect_and_process_pending_htlcs(&nodes[2], false);
let events = nodes[2].node.get_and_clear_pending_events();
assert_eq!(events.len(), payments.len());
for (event, &(_, ref hash)) in events.iter().zip(payments.iter()) {
match event {
&Event::PaymentClaimable { ref payment_hash, .. } => {
assert_eq!(*payment_hash, *hash);
},
_ => panic!("Unexpected event"),
};
}
for (preimage, _) in payments.drain(..) {
claim_payment(&nodes[1], &[&nodes[2]], preimage);
}
send_payment(&nodes[0], &[&nodes[1], &nodes[2]], 1000000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_basic_channel_reserve() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
let chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
let channel_reserve = chan_stat.channel_reserve_msat;
let commit_tx_fee = 2 * commit_tx_fee_msat(
get_feerate!(nodes[0], nodes[1], chan.2),
1 + 1,
&get_channel_type_features!(nodes[0], nodes[1], chan.2),
);
let max_can_send = 5000000 - channel_reserve - commit_tx_fee;
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], max_can_send);
route.paths[0].hops.last_mut().unwrap().fee_msat += 1;
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let err = nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[0], err, true, APIError::ChannelUnavailable { .. }, {});
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
send_payment(&nodes[0], &[&nodes[1]], max_can_send);
}
#[xtest(feature = "_externalize_tests")]
fn test_fee_spike_violation_fails_htlc() {
do_test_fee_spike_buffer(None, true)
}
#[test]
fn test_zero_fee_commitments_no_fee_spike_buffer() {
let mut cfg = test_default_channel_config();
cfg.channel_handshake_config.negotiate_anchor_zero_fee_commitments = true;
cfg.manually_accept_inbound_channels = true;
do_test_fee_spike_buffer(Some(cfg), false)
}
pub fn do_test_fee_spike_buffer(cfg: Option<UserConfig>, htlc_fails: bool) {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[cfg.clone(), cfg]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let chan_amt_sat = 100000;
let push_amt_msat = 95000000;
let chan =
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, chan_amt_sat, push_amt_msat);
let (mut route, payment_hash, _, payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 3460000);
route.paths[0].hops[0].fee_msat += 1;
let secp_ctx = Secp256k1::new();
let session_priv = SecretKey::from_slice(&[42; 32]).expect("RNG is bad!");
let cur_height = nodes[1].node.best_block.read().unwrap().height + 1;
let payment_amt_msat = 3460001;
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv);
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret);
let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
&route.paths[0],
payment_amt_msat,
&recipient_onion_fields,
cur_height,
&None,
None,
None,
)
.unwrap();
let onion_packet =
onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash)
.unwrap();
let msg = msgs::UpdateAddHTLC {
channel_id: chan.2,
htlc_id: 0,
amount_msat: htlc_msat,
payment_hash,
cltv_expiry: htlc_cltv,
onion_routing_packet: onion_packet,
skimmed_fee_msat: None,
blinding_point: None,
hold_htlc: None,
};
nodes[1].node.handle_update_add_htlc(node_a_id, &msg);
let feerate_per_kw = get_feerate!(nodes[0], nodes[1], chan.2);
const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
let (local_secret, next_local_point) = {
let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
let chan_lock = per_peer_state.get(&node_b_id).unwrap().lock().unwrap();
let local_chan = chan_lock.channel_by_id.get(&chan.2).and_then(Channel::as_funded).unwrap();
let chan_signer = local_chan.get_signer();
chan_signer.as_ecdsa().unwrap().get_enforcement_state().last_holder_commitment -= 1;
(
chan_signer.as_ref().release_commitment_secret(INITIAL_COMMITMENT_NUMBER).unwrap(),
chan_signer
.as_ref()
.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 2, &secp_ctx)
.unwrap(),
)
};
let remote_point = {
let per_peer_lock;
let mut peer_state_lock;
let channel = get_channel_ref!(nodes[1], nodes[0], per_peer_lock, peer_state_lock, chan.2);
let chan_signer = channel.as_funded().unwrap().get_signer();
chan_signer
.as_ref()
.get_per_commitment_point(INITIAL_COMMITMENT_NUMBER - 1, &secp_ctx)
.unwrap()
};
let accepted_htlc_info = chan_utils::HTLCOutputInCommitment {
offered: false,
amount_msat: payment_amt_msat,
cltv_expiry: htlc_cltv,
payment_hash,
transaction_output_index: Some(1),
};
let local_chan_balance_msat = chan_amt_sat * 1000 - push_amt_msat;
let commitment_number = INITIAL_COMMITMENT_NUMBER - 1;
let res = {
let per_peer_lock;
let mut peer_state_lock;
let channel = get_channel_ref!(nodes[0], nodes[1], per_peer_lock, peer_state_lock, chan.2);
let chan_signer = channel.as_funded().unwrap().get_signer();
let (commitment_tx, _stats) = SpecTxBuilder {}.build_commitment_transaction(
false,
commitment_number,
&remote_point,
&channel.funding().channel_transaction_parameters,
&secp_ctx,
local_chan_balance_msat,
vec![accepted_htlc_info],
feerate_per_kw,
MIN_CHAN_DUST_LIMIT_SATOSHIS,
&nodes[0].logger,
);
let params = &channel.funding().channel_transaction_parameters;
chan_signer
.as_ecdsa()
.unwrap()
.sign_counterparty_commitment(params, &commitment_tx, Vec::new(), Vec::new(), &secp_ctx)
.unwrap()
};
let commit_signed_msg = msgs::CommitmentSigned {
channel_id: chan.2,
signature: res.0,
htlc_signatures: res.1,
funding_txid: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
};
nodes[1].node.handle_commitment_signed(node_a_id, &commit_signed_msg);
let _ = nodes[1].node.get_and_clear_pending_msg_events();
let raa_msg = msgs::RevokeAndACK {
channel_id: chan.2,
per_commitment_secret: local_secret,
next_per_commitment_point: next_local_point,
#[cfg(taproot)]
next_local_nonce: None,
release_htlc_message_paths: Vec::new(),
};
nodes[1].node.handle_revoke_and_ack(node_a_id, &raa_msg);
expect_and_process_pending_htlcs(&nodes[1], false);
if htlc_fails {
expect_htlc_handling_failed_destinations!(
nodes[1].node.get_and_clear_pending_events(),
&[HTLCHandlingFailureType::Receive { payment_hash }]
);
let events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
match events[0] {
MessageSendEvent::UpdateHTLCs {
updates: msgs::CommitmentUpdate { ref update_fail_htlcs, .. },
..
} => {
assert_eq!(update_fail_htlcs.len(), 1);
update_fail_htlcs[0].clone()
},
_ => panic!("Unexpected event"),
};
nodes[1].logger.assert_log("lightning::ln::channel",
format!("Attempting to fail HTLC due to fee spike buffer violation in channel {}. Rebalancing is required.", raa_msg.channel_id), 1);
check_added_monitors(&nodes[1], 3);
} else {
expect_payment_claimable!(nodes[1], payment_hash, payment_secret, payment_amt_msat);
check_added_monitors(&nodes[1], 2);
}
}
#[xtest(feature = "_externalize_tests")]
pub fn test_chan_reserve_violation_outbound_htlc_inbound_chan() {
let mut chanmon_cfgs = create_chanmon_cfgs(2);
let feerate_per_kw = *chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let default_config = UserConfig::default();
let channel_type_features = ChannelTypeFeatures::only_static_remote_key();
let mut push_amt = 100_000_000;
push_amt -= commit_tx_fee_msat(
feerate_per_kw,
MIN_AFFORDABLE_HTLC_COUNT as u64,
&channel_type_features,
);
push_amt -= get_holder_selected_channel_reserve_satoshis(100_000, &default_config) * 1000;
let _ = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, push_amt);
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[1], nodes[0], 1_000_000);
for _ in 0..MIN_AFFORDABLE_HTLC_COUNT {
route_payment(&nodes[1], &[&nodes[0]], 1_000_000);
}
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[1].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[1], res, true, APIError::ChannelUnavailable { .. }, {});
assert!(nodes[1].node.get_and_clear_pending_msg_events().is_empty());
}
#[xtest(feature = "_externalize_tests")]
pub fn test_chan_reserve_violation_inbound_htlc_outbound_channel() {
let mut chanmon_cfgs = create_chanmon_cfgs(2);
let feerate_per_kw = *chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_b_id = nodes[1].node.get_our_node_id();
let default_config = UserConfig::default();
let channel_type_features = ChannelTypeFeatures::only_static_remote_key();
let mut push_amt = 100_000_000;
push_amt -= commit_tx_fee_msat(
feerate_per_kw,
MIN_AFFORDABLE_HTLC_COUNT as u64,
&channel_type_features,
);
push_amt -= get_holder_selected_channel_reserve_satoshis(100_000, &default_config) * 1000;
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100_000, push_amt);
for _ in 0..MIN_AFFORDABLE_HTLC_COUNT {
route_payment(&nodes[1], &[&nodes[0]], 1_000_000);
}
let (mut route, payment_hash, _, payment_secret) =
get_route_and_payment_hash!(nodes[1], nodes[0], 1000);
route.paths[0].hops[0].fee_msat = 700_000;
let secp_ctx = Secp256k1::new();
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
let cur_height = nodes[1].node.best_block.read().unwrap().height + 1;
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route.paths[0], &session_priv);
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret);
let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
&route.paths[0],
700_000,
&recipient_onion_fields,
cur_height,
&None,
None,
None,
)
.unwrap();
let onion_packet =
onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash)
.unwrap();
let msg = msgs::UpdateAddHTLC {
channel_id: chan.2,
htlc_id: MIN_AFFORDABLE_HTLC_COUNT as u64,
amount_msat: htlc_msat,
payment_hash,
cltv_expiry: htlc_cltv,
onion_routing_packet: onion_packet,
skimmed_fee_msat: None,
blinding_point: None,
hold_htlc: None,
};
nodes[0].node.handle_update_add_htlc(node_b_id, &msg);
nodes[0].logger.assert_log_contains("lightning::ln::channelmanager", "Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value", 3);
assert_eq!(nodes[0].node.list_channels().len(), 0);
let err_msg = check_closed_broadcast!(nodes[0], true).unwrap();
assert_eq!(err_msg.data, "Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value");
check_added_monitors(&nodes[0], 1);
check_closed_event!(nodes[0], 1, ClosureReason::ProcessingError { err: "Cannot accept HTLC that would put our balance under counterparty-announced channel reserve value".to_string() },
[node_b_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_chan_reserve_dust_inbound_htlcs_outbound_chan() {
let mut chanmon_cfgs = create_chanmon_cfgs(2);
let feerate_per_kw = *chanmon_cfgs[0].fee_estimator.sat_per_kw.lock().unwrap();
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let default_config = UserConfig::default();
let channel_type_features = ChannelTypeFeatures::only_static_remote_key();
let mut push_amt = 100_000_000;
push_amt -= commit_tx_fee_msat(
feerate_per_kw,
MIN_AFFORDABLE_HTLC_COUNT as u64,
&channel_type_features,
);
push_amt -= get_holder_selected_channel_reserve_satoshis(100_000, &default_config) * 1000;
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, push_amt);
let (htlc_success_tx_fee_sat, _) =
second_stage_tx_fees_sat(&channel_type_features, feerate_per_kw);
let dust_amt = crate::ln::channel::MIN_CHAN_DUST_LIMIT_SATOSHIS * 1000
+ htlc_success_tx_fee_sat * 1000
- 1;
route_payment(&nodes[1], &[&nodes[0]], dust_amt);
for _ in 0..MIN_AFFORDABLE_HTLC_COUNT {
route_payment(&nodes[1], &[&nodes[0]], 1_000_000);
}
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[1], nodes[0], dust_amt);
route.paths[0].hops[0].fee_msat += 1;
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[1].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[1], res, true, APIError::ChannelUnavailable { .. }, {});
}
#[xtest(feature = "_externalize_tests")]
pub fn test_chan_reserve_dust_inbound_htlcs_inbound_chan() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 98000000);
let payment_amt = 46000;
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
route_payment(&nodes[0], &[&nodes[1]], payment_amt);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_chan_reserve_violation_inbound_htlc_inbound_chan() {
let chanmon_cfgs = create_chanmon_cfgs(3);
let node_cfgs = create_node_cfgs(3, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(3, &node_cfgs, &[None, None, None]);
let mut nodes = create_network(3, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
let _ = create_announced_chan_between_nodes_with_value(&nodes, 1, 2, 100000, 95000000);
let feemsat = 239;
let total_routing_fee_msat = (nodes.len() - 2) as u64 * feemsat;
let chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
let feerate = get_feerate!(nodes[0], nodes[1], chan.2);
let channel_type_features = get_channel_type_features!(nodes[0], nodes[1], chan.2);
let commit_tx_fee_2_htlc = 2 * commit_tx_fee_msat(feerate, 2 + 1, &channel_type_features);
let recv_value_1 = (chan_stat.value_to_self_msat
- chan_stat.channel_reserve_msat
- total_routing_fee_msat
- commit_tx_fee_2_htlc)
/ 2;
let amt_msat_1 = recv_value_1 + total_routing_fee_msat;
let (route_1, our_payment_hash_1, _, our_payment_secret_1) =
get_route_and_payment_hash!(nodes[0], nodes[2], amt_msat_1);
let payment_event_1 = {
let onion = RecipientOnionFields::secret_only(our_payment_secret_1);
let id = PaymentId(our_payment_hash_1.0);
let route = route_1.clone();
nodes[0].node.send_payment_with_route(route, our_payment_hash_1, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
SendEvent::from_event(events.remove(0))
};
nodes[1].node.handle_update_add_htlc(node_a_id, &payment_event_1.msgs[0]);
let commit_tx_fee_2_htlcs = commit_tx_fee_msat(feerate, 2, &channel_type_features);
let recv_value_2 = chan_stat.value_to_self_msat
- amt_msat_1
- chan_stat.channel_reserve_msat
- total_routing_fee_msat
- commit_tx_fee_2_htlcs
+ 1;
let amt_msat_2 = recv_value_2 + total_routing_fee_msat;
let mut route_2 = route_1.clone();
route_2.paths[0].hops.last_mut().unwrap().fee_msat = amt_msat_2;
let secp_ctx = Secp256k1::new();
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
let cur_height = nodes[0].node.best_block.read().unwrap().height + 1;
let onion_keys = onion_utils::construct_onion_keys(&secp_ctx, &route_2.paths[0], &session_priv);
let recipient_onion_fields = RecipientOnionFields::spontaneous_empty();
let (onion_payloads, htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
&route_2.paths[0],
recv_value_2,
&recipient_onion_fields,
cur_height,
&None,
None,
None,
)
.unwrap();
let onion_packet = onion_utils::construct_onion_packet(
onion_payloads,
onion_keys,
[0; 32],
&our_payment_hash_1,
)
.unwrap();
let msg = msgs::UpdateAddHTLC {
channel_id: chan.2,
htlc_id: 1,
amount_msat: htlc_msat + 1,
payment_hash: our_payment_hash_1,
cltv_expiry: htlc_cltv,
onion_routing_packet: onion_packet,
skimmed_fee_msat: None,
blinding_point: None,
hold_htlc: None,
};
nodes[1].node.handle_update_add_htlc(node_a_id, &msg);
nodes[1].logger.assert_log_contains(
"lightning::ln::channelmanager",
"Remote HTLC add would put them under remote reserve value",
3,
);
assert_eq!(nodes[1].node.list_channels().len(), 1);
let err_msg = check_closed_broadcast!(nodes[1], true).unwrap();
assert_eq!(err_msg.data, "Remote HTLC add would put them under remote reserve value");
check_added_monitors(&nodes[1], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data.clone() };
check_closed_event!(nodes[1], 1, reason, [node_a_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_payment_route_reaching_same_channel_twice() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_b_id = nodes[1].node.get_our_node_id();
let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0);
let payment_params = PaymentParameters::from_node_id(node_b_id, 0)
.with_bolt11_features(nodes[1].node.bolt11_invoice_features())
.unwrap();
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], payment_params, 100000000);
let cloned_hops = route.paths[0].hops.clone();
route.paths[0].hops.extend_from_slice(&cloned_hops);
unwrap_send_err!(nodes[0], nodes[0].node.send_payment_with_route(route, our_payment_hash,
RecipientOnionFields::secret_only(our_payment_secret), PaymentId(our_payment_hash.0)
), false, APIError::InvalidRoute { ref err },
assert_eq!(err, &"Path went through the same channel twice"));
assert!(nodes[0].node.list_recent_payments().is_empty());
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_sender_value_below_minimum_msat() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
route.paths[0].hops[0].fee_msat = 100;
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[0], res, true, APIError::ChannelUnavailable { .. }, {});
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_sender_zero_value_msat() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
route.paths[0].hops[0].fee_msat = 0;
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[0], res,
true, APIError::ChannelUnavailable { ref err },
assert_eq!(err, "Cannot send 0-msat HTLC"));
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
nodes[0].logger.assert_log_contains(
"lightning::ln::channelmanager",
"Cannot send 0-msat HTLC",
2,
);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_receiver_zero_value_msat() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], node_b_id);
updates.update_add_htlcs[0].amount_msat = 0;
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
nodes[1].logger.assert_log_contains(
"lightning::ln::channelmanager",
"Remote side tried to send a 0-msat HTLC",
3,
);
check_closed_broadcast!(nodes[1], true).unwrap();
check_added_monitors(&nodes[1], 1);
let reason = ClosureReason::ProcessingError {
err: "Remote side tried to send a 0-msat HTLC".to_string(),
};
check_closed_event!(nodes[1], 1, reason, [node_a_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_sender_cltv_expiry_too_high() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_b_id = nodes[1].node.get_our_node_id();
let _chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0);
let payment_params = PaymentParameters::from_node_id(node_b_id, 0)
.with_bolt11_features(nodes[1].node.bolt11_invoice_features())
.unwrap();
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], payment_params, 100000000);
route.paths[0].hops.last_mut().unwrap().cltv_expiry_delta = 500000001;
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[0], res, true, APIError::InvalidRoute { ref err },
assert_eq!(err, &"Channel CLTV overflowed?"));
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_num_and_htlc_id_increment() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 0);
let max_accepted_htlcs = {
let per_peer_lock;
let mut peer_state_lock;
let channel = get_channel_ref!(nodes[1], nodes[0], per_peer_lock, peer_state_lock, chan.2);
channel.context().counterparty_max_accepted_htlcs as u64
};
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
for i in 0..max_accepted_htlcs {
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 100000);
let payment_event = {
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut events = nodes[0].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
if let MessageSendEvent::UpdateHTLCs {
updates: msgs::CommitmentUpdate { update_add_htlcs: ref htlcs, .. },
..
} = events[0]
{
assert_eq!(htlcs[0].htlc_id, i);
} else {
assert!(false);
}
SendEvent::from_event(events.remove(0))
};
nodes[1].node.handle_update_add_htlc(node_a_id, &payment_event.msgs[0]);
check_added_monitors(&nodes[1], 0);
commitment_signed_dance!(nodes[1], nodes[0], payment_event.commitment_msg, false);
expect_and_process_pending_htlcs(&nodes[1], false);
expect_payment_claimable!(nodes[1], our_payment_hash, our_payment_secret, 100000);
}
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[0], res, true, APIError::ChannelUnavailable { .. }, {});
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_sender_exceed_max_htlc_value_in_flight() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let channel_value = 100000;
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, channel_value, 0);
let max_in_flight = get_channel_value_stat!(nodes[0], nodes[1], chan.2)
.counterparty_max_htlc_value_in_flight_msat;
send_payment(&nodes[0], &[&nodes[1]], max_in_flight);
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], max_in_flight);
route.paths[0].hops[0].fee_msat = max_in_flight + 1;
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
let res = nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id);
unwrap_send_err!(nodes[0], res, true, APIError::ChannelUnavailable { .. }, {});
assert!(nodes[0].node.get_and_clear_pending_msg_events().is_empty());
send_payment(&nodes[0], &[&nodes[1]], max_in_flight);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_receiver_check_amount_received_more_than_min() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
let htlc_minimum_msat = {
let per_peer_lock;
let mut peer_state_lock;
let channel = get_channel_ref!(nodes[0], nodes[1], per_peer_lock, peer_state_lock, chan.2);
channel.context().get_holder_htlc_minimum_msat()
};
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], htlc_minimum_msat);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], node_b_id);
updates.update_add_htlcs[0].amount_msat = htlc_minimum_msat - 1;
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
assert!(nodes[1].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[1], true).unwrap();
assert!(regex::Regex::new(r"Remote side tried to send less than our minimum HTLC value\. Lower limit: \(\d+\)\. Actual: \(\d+\)").unwrap().is_match(err_msg.data.as_str()));
check_added_monitors(&nodes[1], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[1], 1, reason, [node_a_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_receiver_sender_can_afford_amount_sent() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
let chan_stat = get_channel_value_stat!(nodes[0], nodes[1], chan.2);
let channel_reserve = chan_stat.channel_reserve_msat;
let feerate = get_feerate!(nodes[0], nodes[1], chan.2);
let channel_type_features = get_channel_type_features!(nodes[0], nodes[1], chan.2);
let commit_tx_fee_outbound = 2 * commit_tx_fee_msat(feerate, 1 + 1, &channel_type_features);
let max_can_send = 5000000 - channel_reserve - commit_tx_fee_outbound;
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], max_can_send);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], node_b_id);
updates.update_add_htlcs[0].amount_msat = max_can_send + commit_tx_fee_outbound + 1;
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
assert!(nodes[1].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[1], true).unwrap();
assert_eq!(err_msg.data, "Remote HTLC add would put them under remote reserve value");
check_added_monitors(&nodes[1], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[1], 1, reason, [node_a_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_receiver_check_max_htlc_limit() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
let send_amt = 3999999;
let (mut route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 1000);
route.paths[0].hops[0].fee_msat = send_amt;
let session_priv = SecretKey::from_slice(&[42; 32]).unwrap();
let cur_height = nodes[0].node.best_block.read().unwrap().height + 1;
let onion_keys = onion_utils::construct_onion_keys(
&Secp256k1::signing_only(),
&route.paths[0],
&session_priv,
);
let recipient_onion_fields = RecipientOnionFields::secret_only(our_payment_secret);
let (onion_payloads, _htlc_msat, htlc_cltv) = onion_utils::build_onion_payloads(
&route.paths[0],
send_amt,
&recipient_onion_fields,
cur_height,
&None,
None,
None,
)
.unwrap();
let onion_packet =
onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &our_payment_hash)
.unwrap();
let mut msg = msgs::UpdateAddHTLC {
channel_id: chan.2,
htlc_id: 0,
amount_msat: 1000,
payment_hash: our_payment_hash,
cltv_expiry: htlc_cltv,
onion_routing_packet: onion_packet.clone(),
skimmed_fee_msat: None,
blinding_point: None,
hold_htlc: None,
};
for i in 0..50 {
msg.htlc_id = i as u64;
nodes[1].node.handle_update_add_htlc(node_a_id, &msg);
}
msg.htlc_id = (50) as u64;
nodes[1].node.handle_update_add_htlc(node_a_id, &msg);
assert!(nodes[1].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[1], true).unwrap();
assert!(regex::Regex::new(r"Remote tried to push more than our max accepted HTLCs \(\d+\)")
.unwrap()
.is_match(err_msg.data.as_str()));
check_added_monitors(&nodes[1], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[1], 1, reason, [node_a_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_receiver_check_max_in_flight_msat() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let chan = create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], node_b_id);
updates.update_add_htlcs[0].amount_msat = get_channel_value_stat!(nodes[1], nodes[0], chan.2)
.counterparty_max_htlc_value_in_flight_msat
+ 1;
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
assert!(nodes[1].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[1], true).unwrap();
assert!(regex::Regex::new("Remote HTLC add would put them over our max HTLC value")
.unwrap()
.is_match(err_msg.data.as_str()));
check_added_monitors(&nodes[1], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[1], 1, reason, [node_a_id], 1000000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_receiver_check_cltv_expiry() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 100000, 95000000);
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
let reason = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, reason, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], node_b_id);
updates.update_add_htlcs[0].cltv_expiry = 500000000;
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
assert!(nodes[1].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[1], true).unwrap();
assert_eq!(err_msg.data, "Remote provided CLTV expiry in seconds instead of block height");
check_added_monitors(&nodes[1], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[1], 1, reason, [node_a_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_add_htlc_bolt2_receiver_check_repeated_id_ignore() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
create_announced_chan_between_nodes(&nodes, 0, 1);
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs!(nodes[0], node_b_id);
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
nodes[0].node.peer_disconnected(node_b_id);
nodes[1].node.peer_disconnected(node_a_id);
let init_msg = msgs::Init {
features: nodes[0].node.init_features(),
networks: None,
remote_network_address: None,
};
nodes[0].node.peer_connected(node_b_id, &init_msg, true).unwrap();
let reestablish_1 = get_chan_reestablish_msgs!(nodes[0], nodes[1]);
assert_eq!(reestablish_1.len(), 1);
nodes[1].node.peer_connected(node_a_id, &init_msg, false).unwrap();
let reestablish_2 = get_chan_reestablish_msgs!(nodes[1], nodes[0]);
assert_eq!(reestablish_2.len(), 1);
nodes[0].node.handle_channel_reestablish(node_b_id, &reestablish_2[0]);
handle_chan_reestablish_msgs!(nodes[0], nodes[1]);
nodes[1].node.handle_channel_reestablish(node_a_id, &reestablish_1[0]);
handle_chan_reestablish_msgs!(nodes[1], nodes[0]);
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
assert_eq!(updates.commitment_signed.len(), 1);
assert_eq!(updates.commitment_signed[0].htlc_signatures.len(), 1);
nodes[1].node.handle_commitment_signed_batch_test(node_a_id, &updates.commitment_signed);
check_added_monitors(&nodes[1], 1);
let _bs_responses = get_revoke_commit_msgs!(nodes[1], node_a_id);
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
assert!(nodes[1].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[1], true).unwrap();
assert!(regex::Regex::new(r"Remote skipped HTLC ID \(skipped ID: \d+\)")
.unwrap()
.is_match(err_msg.data.as_str()));
check_added_monitors(&nodes[1], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[1], 1, reason, [node_a_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_fulfill_htlc_bolt2_update_fulfill_htlc_before_commitment() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
let (route, our_payment_hash, our_payment_preimage, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs!(nodes[0], node_b_id);
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
let update_msg = msgs::UpdateFulfillHTLC {
channel_id: chan.2,
htlc_id: 0,
payment_preimage: our_payment_preimage,
attribution_data: None,
};
nodes[0].node.handle_update_fulfill_htlc(node_b_id, update_msg);
assert!(nodes[0].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[0], true).unwrap();
assert!(regex::Regex::new(
r"Remote tried to fulfill/fail HTLC \(\d+\) before it had been committed"
)
.unwrap()
.is_match(err_msg.data.as_str()));
check_added_monitors(&nodes[0], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[0], 1, reason, [node_b_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_fulfill_htlc_bolt2_update_fail_htlc_before_commitment() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs!(nodes[0], node_b_id);
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
let update_msg = msgs::UpdateFailHTLC {
channel_id: chan.2,
htlc_id: 0,
reason: Vec::new(),
attribution_data: Some(AttributionData::new()),
};
nodes[0].node.handle_update_fail_htlc(node_b_id, &update_msg);
assert!(nodes[0].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[0], true).unwrap();
assert!(regex::Regex::new(
r"Remote tried to fulfill/fail HTLC \(\d+\) before it had been committed"
)
.unwrap()
.is_match(err_msg.data.as_str()));
check_added_monitors(&nodes[0], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[0], 1, reason, [node_b_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_fulfill_htlc_bolt2_update_fail_malformed_htlc_before_commitment() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
let chan = create_announced_chan_between_nodes(&nodes, 0, 1);
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let updates = get_htlc_update_msgs!(nodes[0], node_b_id);
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
let update_msg = msgs::UpdateFailMalformedHTLC {
channel_id: chan.2,
htlc_id: 0,
sha256_of_onion: [1; 32],
failure_code: 0x8000,
};
nodes[0].node.handle_update_fail_malformed_htlc(node_b_id, &update_msg);
assert!(nodes[0].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[0], true).unwrap();
assert!(regex::Regex::new(
r"Remote tried to fulfill/fail HTLC \(\d+\) before it had been committed"
)
.unwrap()
.is_match(err_msg.data.as_str()));
check_added_monitors(&nodes[0], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[0], 1, reason, [node_b_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_fulfill_htlc_bolt2_incorrect_htlc_id() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_b_id = nodes[1].node.get_our_node_id();
create_announced_chan_between_nodes(&nodes, 0, 1);
let (our_payment_preimage, our_payment_hash, ..) =
route_payment(&nodes[0], &[&nodes[1]], 100_000);
nodes[1].node.claim_funds(our_payment_preimage);
check_added_monitors(&nodes[1], 1);
expect_payment_claimed!(nodes[1], our_payment_hash, 100_000);
let events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
let mut update_fulfill_msg: msgs::UpdateFulfillHTLC = {
match events[0] {
MessageSendEvent::UpdateHTLCs {
updates:
msgs::CommitmentUpdate {
ref update_add_htlcs,
ref update_fulfill_htlcs,
ref update_fail_htlcs,
ref update_fail_malformed_htlcs,
ref update_fee,
..
},
..
} => {
assert!(update_add_htlcs.is_empty());
assert_eq!(update_fulfill_htlcs.len(), 1);
assert!(update_fail_htlcs.is_empty());
assert!(update_fail_malformed_htlcs.is_empty());
assert!(update_fee.is_none());
update_fulfill_htlcs[0].clone()
},
_ => panic!("Unexpected event"),
}
};
update_fulfill_msg.htlc_id = 1;
nodes[0].node.handle_update_fulfill_htlc(node_b_id, update_fulfill_msg);
assert!(nodes[0].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[0], true).unwrap();
assert_eq!(err_msg.data, "Remote tried to fulfill/fail an HTLC we couldn't find");
check_added_monitors(&nodes[0], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[0], 1, reason, [node_b_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_fulfill_htlc_bolt2_wrong_preimage() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_b_id = nodes[1].node.get_our_node_id();
create_announced_chan_between_nodes(&nodes, 0, 1);
let (our_payment_preimage, our_payment_hash, ..) =
route_payment(&nodes[0], &[&nodes[1]], 100_000);
nodes[1].node.claim_funds(our_payment_preimage);
check_added_monitors(&nodes[1], 1);
expect_payment_claimed!(nodes[1], our_payment_hash, 100_000);
let events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
let mut update_fulfill_msg: msgs::UpdateFulfillHTLC = {
match events[0] {
MessageSendEvent::UpdateHTLCs {
updates:
msgs::CommitmentUpdate {
ref update_add_htlcs,
ref update_fulfill_htlcs,
ref update_fail_htlcs,
ref update_fail_malformed_htlcs,
ref update_fee,
..
},
..
} => {
assert!(update_add_htlcs.is_empty());
assert_eq!(update_fulfill_htlcs.len(), 1);
assert!(update_fail_htlcs.is_empty());
assert!(update_fail_malformed_htlcs.is_empty());
assert!(update_fee.is_none());
update_fulfill_htlcs[0].clone()
},
_ => panic!("Unexpected event"),
}
};
update_fulfill_msg.payment_preimage = PaymentPreimage([1; 32]);
nodes[0].node.handle_update_fulfill_htlc(node_b_id, update_fulfill_msg);
assert!(nodes[0].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[0], true).unwrap();
assert!(regex::Regex::new(r"Remote tried to fulfill HTLC \(\d+\) with an incorrect preimage")
.unwrap()
.is_match(err_msg.data.as_str()));
check_added_monitors(&nodes[0], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[0], 1, reason, [node_b_id], 100000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_update_fulfill_htlc_bolt2_missing_badonion_bit_for_malformed_htlc_message() {
let chanmon_cfgs = create_chanmon_cfgs(2);
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs = create_node_chanmgrs(2, &node_cfgs, &[None, None]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
create_announced_chan_between_nodes_with_value(&nodes, 0, 1, 1000000, 1000000);
let (route, our_payment_hash, _, our_payment_secret) =
get_route_and_payment_hash!(nodes[0], nodes[1], 1000000);
let onion = RecipientOnionFields::secret_only(our_payment_secret);
let id = PaymentId(our_payment_hash.0);
nodes[0].node.send_payment_with_route(route, our_payment_hash, onion, id).unwrap();
check_added_monitors(&nodes[0], 1);
let mut updates = get_htlc_update_msgs!(nodes[0], node_b_id);
updates.update_add_htlcs[0].onion_routing_packet.version = 1;
nodes[1].node.handle_update_add_htlc(node_a_id, &updates.update_add_htlcs[0]);
check_added_monitors(&nodes[1], 0);
commitment_signed_dance!(nodes[1], nodes[0], updates.commitment_signed, false, true);
expect_and_process_pending_htlcs(&nodes[1], false);
expect_htlc_handling_failed_destinations!(
nodes[1].node.get_and_clear_pending_events(),
&[HTLCHandlingFailureType::InvalidOnion]
);
check_added_monitors(&nodes[1], 1);
let events = nodes[1].node.get_and_clear_pending_msg_events();
let mut update_msg: msgs::UpdateFailMalformedHTLC = {
match events[0] {
MessageSendEvent::UpdateHTLCs {
updates:
msgs::CommitmentUpdate {
ref update_add_htlcs,
ref update_fulfill_htlcs,
ref update_fail_htlcs,
ref update_fail_malformed_htlcs,
ref update_fee,
..
},
..
} => {
assert!(update_add_htlcs.is_empty());
assert!(update_fulfill_htlcs.is_empty());
assert!(update_fail_htlcs.is_empty());
assert_eq!(update_fail_malformed_htlcs.len(), 1);
assert!(update_fee.is_none());
update_fail_malformed_htlcs[0].clone()
},
_ => panic!("Unexpected event"),
}
};
update_msg.failure_code &= !0x8000;
nodes[0].node.handle_update_fail_malformed_htlc(node_b_id, &update_msg);
assert!(nodes[0].node.list_channels().is_empty());
let err_msg = check_closed_broadcast!(nodes[0], true).unwrap();
assert_eq!(err_msg.data, "Got update_fail_malformed_htlc with BADONION not set");
check_added_monitors(&nodes[0], 1);
let reason = ClosureReason::ProcessingError { err: err_msg.data };
check_closed_event!(nodes[0], 1, reason, [node_b_id], 1000000);
}
#[xtest(feature = "_externalize_tests")]
pub fn test_dust_limit_fee_accounting() {
do_test_dust_limit_fee_accounting(false);
do_test_dust_limit_fee_accounting(true);
}
pub fn do_test_dust_limit_fee_accounting(can_afford: bool) {
let channel_type = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
let chanmon_cfgs = create_chanmon_cfgs(2);
let mut default_config = test_default_channel_config();
default_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
default_config.manually_accept_inbound_channels = true;
let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
let node_chanmgrs =
create_node_chanmgrs(2, &node_cfgs, &[Some(default_config.clone()), Some(default_config)]);
let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
let node_a_id = nodes[0].node.get_our_node_id();
let node_b_id = nodes[1].node.get_our_node_id();
const HTLC_AMT_SAT: u64 = 354;
const CHANNEL_VALUE_SAT: u64 = 100_000;
const FEERATE_PER_KW: u32 = 253;
let commit_tx_fee_sat =
chan_utils::commit_tx_fee_sat(FEERATE_PER_KW, MIN_AFFORDABLE_HTLC_COUNT, &channel_type);
let channel_reserve_satoshis = 1_000;
let node_0_balance_sat = commit_tx_fee_sat
+ channel_reserve_satoshis
+ 2 * crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI
+ MIN_AFFORDABLE_HTLC_COUNT as u64 * HTLC_AMT_SAT
- if can_afford { 0 } else { 1 };
let mut node_1_balance_sat = CHANNEL_VALUE_SAT - node_0_balance_sat;
let chan_id = create_chan_between_nodes_with_value(
&nodes[0],
&nodes[1],
CHANNEL_VALUE_SAT,
node_1_balance_sat * 1000,
)
.3;
{
let per_peer_state_lock;
let mut peer_state_lock;
let chan =
get_channel_ref!(nodes[1], nodes[0], per_peer_state_lock, peer_state_lock, chan_id);
assert_eq!(
chan.funding().holder_selected_channel_reserve_satoshis,
channel_reserve_satoshis
);
}
{
let per_peer_state_lock;
let mut peer_state_lock;
let chan =
get_channel_ref!(nodes[0], nodes[1], per_peer_state_lock, peer_state_lock, chan_id);
assert_eq!(chan.context().holder_dust_limit_satoshis, HTLC_AMT_SAT);
}
let (route_0_1, payment_hash_0_1, _, payment_secret_0_1) =
get_route_and_payment_hash!(nodes[0], nodes[1], HTLC_AMT_SAT * 1000);
let mut htlcs = Vec::new();
for _ in 0..MIN_AFFORDABLE_HTLC_COUNT - 1 {
let (_payment_preimage, payment_hash, ..) =
route_payment(&nodes[0], &[&nodes[1]], HTLC_AMT_SAT * 1000);
let accepted_htlc = chan_utils::HTLCOutputInCommitment {
offered: false,
amount_msat: HTLC_AMT_SAT * 1000,
cltv_expiry: 81,
payment_hash,
transaction_output_index: None,
};
htlcs.push(accepted_htlc);
}
let secp_ctx = Secp256k1::new();
let session_priv = SecretKey::from_slice(&[42; 32]).expect("RNG is bad!");
let cur_height = nodes[1].node.best_block.read().unwrap().height + 1;
let onion_keys =
onion_utils::construct_onion_keys(&secp_ctx, &route_0_1.paths[0], &session_priv);
let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret_0_1);
let (onion_payloads, amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(
&route_0_1.paths[0],
HTLC_AMT_SAT * 1000,
&recipient_onion_fields,
cur_height,
&None,
None,
None,
)
.unwrap();
let onion_routing_packet =
onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash_0_1)
.unwrap();
assert_eq!(cltv_expiry, 81);
let msg = msgs::UpdateAddHTLC {
channel_id: chan_id,
htlc_id: MIN_AFFORDABLE_HTLC_COUNT as u64 - 1,
amount_msat,
payment_hash: payment_hash_0_1,
cltv_expiry,
onion_routing_packet,
skimmed_fee_msat: None,
blinding_point: None,
hold_htlc: None,
};
nodes[1].node.handle_update_add_htlc(node_a_id, &msg);
if !can_afford {
let err = "Remote HTLC add would put them under remote reserve value".to_string();
nodes[1].logger.assert_log_contains("lightning::ln::channelmanager", &err, 3);
let events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 2);
let reason = ClosureReason::ProcessingError { err };
check_closed_event(&nodes[1], 1, reason, false, &[node_a_id], CHANNEL_VALUE_SAT);
check_added_monitors(&nodes[1], 1);
} else {
const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
let (local_secret, next_local_point) = {
let per_peer_state = nodes[0].node.per_peer_state.read().unwrap();
let chan_lock = per_peer_state.get(&node_b_id).unwrap().lock().unwrap();
let local_chan =
chan_lock.channel_by_id.get(&chan_id).and_then(Channel::as_funded).unwrap();
let chan_signer = local_chan.get_signer();
chan_signer.as_ecdsa().unwrap().get_enforcement_state().last_holder_commitment -= 1;
(
chan_signer
.as_ref()
.release_commitment_secret(
INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64 + 1,
)
.unwrap(),
chan_signer
.as_ref()
.get_per_commitment_point(
INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64,
&secp_ctx,
)
.unwrap(),
)
};
let remote_point = {
let per_peer_lock;
let mut peer_state_lock;
let channel =
get_channel_ref!(nodes[1], nodes[0], per_peer_lock, peer_state_lock, chan_id);
let chan_signer = channel.as_funded().unwrap().get_signer();
chan_signer
.as_ref()
.get_per_commitment_point(
INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64,
&secp_ctx,
)
.unwrap()
};
let local_chan_balance = node_0_balance_sat
- HTLC_AMT_SAT * MIN_AFFORDABLE_HTLC_COUNT as u64
- 2 * crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI
- chan_utils::commit_tx_fee_sat(
FEERATE_PER_KW,
MIN_AFFORDABLE_HTLC_COUNT,
&channel_type,
);
let accepted_htlc_info = chan_utils::HTLCOutputInCommitment {
offered: false,
amount_msat: HTLC_AMT_SAT * 1000,
cltv_expiry,
payment_hash: payment_hash_0_1,
transaction_output_index: None,
};
htlcs.push(accepted_htlc_info);
let commitment_number = INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64;
let res = {
let per_peer_lock;
let mut peer_state_lock;
let channel =
get_channel_ref!(nodes[0], nodes[1], per_peer_lock, peer_state_lock, chan_id);
let chan_signer = channel.as_funded().unwrap().get_signer();
let commitment_tx = CommitmentTransaction::new(
commitment_number,
&remote_point,
node_1_balance_sat,
local_chan_balance,
FEERATE_PER_KW,
htlcs,
&channel.funding().channel_transaction_parameters.as_counterparty_broadcastable(),
&secp_ctx,
);
let params = &channel.funding().channel_transaction_parameters;
chan_signer
.as_ecdsa()
.unwrap()
.sign_counterparty_commitment(
params,
&commitment_tx,
Vec::new(),
Vec::new(),
&secp_ctx,
)
.unwrap()
};
let commit_signed_msg = msgs::CommitmentSigned {
channel_id: chan_id,
signature: res.0,
htlc_signatures: res.1,
funding_txid: None,
#[cfg(taproot)]
partial_signature_with_nonce: None,
};
nodes[1].node.handle_commitment_signed(node_a_id, &commit_signed_msg);
let _ = nodes[1].node.get_and_clear_pending_msg_events();
let raa_msg = msgs::RevokeAndACK {
channel_id: chan_id,
per_commitment_secret: local_secret,
next_per_commitment_point: next_local_point,
#[cfg(taproot)]
next_local_nonce: None,
release_htlc_message_paths: Vec::new(),
};
nodes[1].node.handle_revoke_and_ack(node_a_id, &raa_msg);
expect_and_process_pending_htlcs(&nodes[1], false);
expect_htlc_handling_failed_destinations!(
nodes[1].node.get_and_clear_pending_events(),
&[HTLCHandlingFailureType::Receive { payment_hash: payment_hash_0_1 }]
);
let events = nodes[1].node.get_and_clear_pending_msg_events();
assert_eq!(events.len(), 1);
match events[0] {
MessageSendEvent::UpdateHTLCs {
updates: msgs::CommitmentUpdate { ref update_fail_htlcs, .. },
..
} => {
assert_eq!(update_fail_htlcs.len(), 1);
update_fail_htlcs[0].clone()
},
_ => panic!("Unexpected event"),
};
nodes[1].logger.assert_log("lightning::ln::channel",
format!("Attempting to fail HTLC due to fee spike buffer violation in channel {}. Rebalancing is required.", raa_msg.channel_id), 1);
check_added_monitors(&nodes[1], 3);
}
}