@@ -11684,3 +11684,293 @@ fn test_funding_signed_event() {
1168411684 nodes[1].node.get_and_clear_pending_msg_events();
1168511685}
1168611686
11687+ #[test]
11688+ pub fn test_dust_limit_fee_accounting() {
11689+ do_test_dust_limit_fee_accounting(false);
11690+ do_test_dust_limit_fee_accounting(true);
11691+ }
11692+
11693+ pub fn do_test_dust_limit_fee_accounting(can_afford: bool) {
11694+ // Test that when a channel funder sends HTLCs exactly on the dust limit
11695+ // of the funder, the fundee correctly accounts for the additional fee on the
11696+ // funder's commitment transaction due to those additional non-dust HTLCs when
11697+ // checking for any infrigements on the funder's reserve.
11698+
11699+ let channel_type = ChannelTypeFeatures::anchors_zero_htlc_fee_and_dependencies();
11700+
11701+ let chanmon_cfgs = create_chanmon_cfgs(2);
11702+
11703+ let mut default_config = test_default_channel_config();
11704+ default_config.channel_handshake_config.negotiate_anchors_zero_fee_htlc_tx = true;
11705+ default_config.manually_accept_inbound_channels = true;
11706+
11707+ let node_cfgs = create_node_cfgs(2, &chanmon_cfgs);
11708+ let node_chanmgrs =
11709+ create_node_chanmgrs(2, &node_cfgs, &[Some(default_config.clone()), Some(default_config)]);
11710+
11711+ let mut nodes = create_network(2, &node_cfgs, &node_chanmgrs);
11712+
11713+ let node_a_id = nodes[0].node.get_our_node_id();
11714+
11715+ // Set a HTLC amount that is equal to the dust limit of the funder
11716+ const HTLC_AMT_SAT: u64 = 354;
11717+
11718+ const CHANNEL_VALUE_SAT: u64 = 100_000;
11719+
11720+ const FEERATE_PER_KW: u32 = 253;
11721+
11722+ let commit_tx_fee_sat =
11723+ chan_utils::commit_tx_fee_sat(FEERATE_PER_KW, MIN_AFFORDABLE_HTLC_COUNT, &channel_type);
11724+
11725+ // By default the reserve is set to 1% or 1000sat, whichever is higher
11726+ let channel_reserve_satoshis = 1_000;
11727+
11728+ // Set node 0's balance to pay for exactly MIN_AFFORDABLE_HTLC_COUNT non-dust HTLCs on the channel, minus some offset
11729+ let node_0_balance_sat = commit_tx_fee_sat
11730+ + channel_reserve_satoshis
11731+ + 2 * crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI
11732+ + MIN_AFFORDABLE_HTLC_COUNT as u64 * HTLC_AMT_SAT
11733+ - if can_afford { 0 } else { 1 };
11734+ let mut node_1_balance_sat = CHANNEL_VALUE_SAT - node_0_balance_sat;
11735+
11736+ let chan_id = create_chan_between_nodes_with_value(
11737+ &nodes[0],
11738+ &nodes[1],
11739+ CHANNEL_VALUE_SAT,
11740+ node_1_balance_sat * 1000,
11741+ )
11742+ .3;
11743+
11744+ {
11745+ // Double check the reserve that node 0 has to maintain here
11746+ let per_peer_state_lock;
11747+ let mut peer_state_lock;
11748+ let chan =
11749+ get_channel_ref!(nodes[1], nodes[0], per_peer_state_lock, peer_state_lock, chan_id);
11750+ assert_eq!(
11751+ chan.context().holder_selected_channel_reserve_satoshis,
11752+ channel_reserve_satoshis
11753+ );
11754+ }
11755+ {
11756+ // Double check the dust limit on node 0's commitment transactions; when node 0
11757+ // adds a HTLC, node 1 will check that the fee on node 0's commitment transaction
11758+ // does not dip under the node 1 selected reserve.
11759+ let per_peer_state_lock;
11760+ let mut peer_state_lock;
11761+ let chan =
11762+ get_channel_ref!(nodes[0], nodes[1], per_peer_state_lock, peer_state_lock, chan_id);
11763+ assert_eq!(chan.context().holder_dust_limit_satoshis, HTLC_AMT_SAT);
11764+ }
11765+
11766+ // Precompute the route to skip any router complaints when sending the last HTLC
11767+ let (route_0_1, payment_hash_0_1, _, payment_secret_0_1) =
11768+ get_route_and_payment_hash!(nodes[0], nodes[1], HTLC_AMT_SAT * 1000);
11769+
11770+ let mut htlcs = Vec::new();
11771+ for _ in 0..MIN_AFFORDABLE_HTLC_COUNT - 1 {
11772+ let (_payment_preimage, payment_hash, ..) =
11773+ route_payment(&nodes[0], &[&nodes[1]], HTLC_AMT_SAT * 1000);
11774+ // Grab a snapshot of these HTLCs to manually build the commitment transaction later...
11775+ let accepted_htlc = chan_utils::HTLCOutputInCommitment {
11776+ offered: false,
11777+ amount_msat: HTLC_AMT_SAT * 1000,
11778+ // Hard-coded to match the expected value
11779+ cltv_expiry: 81,
11780+ payment_hash,
11781+ transaction_output_index: None,
11782+ };
11783+ htlcs.push((accepted_htlc, ()));
11784+ }
11785+
11786+ // Need to manually create the update_add_htlc message to go around the channel reserve check in send_htlc()
11787+ let secp_ctx = Secp256k1::new();
11788+ let session_priv = SecretKey::from_slice(&[42; 32]).expect("RNG is bad!");
11789+
11790+ let cur_height = nodes[1].node.best_block.read().unwrap().height + 1;
11791+
11792+ let onion_keys =
11793+ onion_utils::construct_onion_keys(&secp_ctx, &route_0_1.paths[0], &session_priv).unwrap();
11794+ let recipient_onion_fields = RecipientOnionFields::secret_only(payment_secret_0_1);
11795+ let (onion_payloads, amount_msat, cltv_expiry) = onion_utils::build_onion_payloads(
11796+ &route_0_1.paths[0],
11797+ HTLC_AMT_SAT * 1000,
11798+ &recipient_onion_fields,
11799+ cur_height,
11800+ &None,
11801+ None,
11802+ )
11803+ .unwrap();
11804+ let onion_routing_packet =
11805+ onion_utils::construct_onion_packet(onion_payloads, onion_keys, [0; 32], &payment_hash_0_1)
11806+ .unwrap();
11807+ // Double check the hard-coded value
11808+ assert_eq!(cltv_expiry, 81);
11809+ let msg = msgs::UpdateAddHTLC {
11810+ channel_id: chan_id,
11811+ htlc_id: MIN_AFFORDABLE_HTLC_COUNT as u64 - 1,
11812+ amount_msat,
11813+ payment_hash: payment_hash_0_1,
11814+ cltv_expiry,
11815+ onion_routing_packet,
11816+ skimmed_fee_msat: None,
11817+ blinding_point: None,
11818+ };
11819+
11820+ nodes[1].node.handle_update_add_htlc(node_a_id, &msg);
11821+
11822+ if !can_afford {
11823+ let err = "Remote HTLC add would put them under remote reserve value".to_string();
11824+ nodes[1].logger.assert_log_contains("lightning::ln::channelmanager", &err, 3);
11825+ let events = nodes[1].node.get_and_clear_pending_msg_events();
11826+ assert_eq!(events.len(), 2);
11827+ let reason = ClosureReason::ProcessingError { err };
11828+ check_closed_event(&nodes[1], 1, reason, false, &[node_a_id], CHANNEL_VALUE_SAT);
11829+ check_added_monitors(&nodes[1], 1);
11830+ } else {
11831+ // Now manually create the commitment_signed message corresponding to the update_add
11832+ // nodes[0] just sent. In the code for construction of this message, "local" refers
11833+ // to the sender of the message, and "remote" refers to the receiver.
11834+
11835+ const INITIAL_COMMITMENT_NUMBER: u64 = (1 << 48) - 1;
11836+
11837+ let (local_secret, next_local_point) = {
11838+ let per_peer_lock;
11839+ let mut peer_state_lock;
11840+
11841+ let channel =
11842+ get_channel_ref!(nodes[0], nodes[1], per_peer_lock, peer_state_lock, chan_id);
11843+ let local_chan = if let ChannelPhase::Funded(chan) = &*channel {
11844+ chan
11845+ } else {
11846+ panic!();
11847+ };
11848+ let chan_signer = local_chan.get_signer();
11849+ // Make the signer believe we validated another commitment, so we can release the secret
11850+ chan_signer.as_ecdsa().unwrap().get_enforcement_state().last_holder_commitment -= 1;
11851+
11852+ (
11853+ chan_signer
11854+ .as_ref()
11855+ .release_commitment_secret(
11856+ INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64 + 1,
11857+ )
11858+ .unwrap(),
11859+ chan_signer
11860+ .as_ref()
11861+ .get_per_commitment_point(
11862+ INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64,
11863+ &secp_ctx,
11864+ )
11865+ .unwrap(),
11866+ )
11867+ };
11868+
11869+ // Build the remote commitment transaction so we can sign it, and then later use the
11870+ // signature for the commitment_signed message.
11871+ let local_chan_balance = node_0_balance_sat
11872+ - HTLC_AMT_SAT * MIN_AFFORDABLE_HTLC_COUNT as u64
11873+ - 2 * crate::ln::channel::ANCHOR_OUTPUT_VALUE_SATOSHI
11874+ - chan_utils::commit_tx_fee_sat(
11875+ FEERATE_PER_KW,
11876+ MIN_AFFORDABLE_HTLC_COUNT,
11877+ &channel_type,
11878+ );
11879+
11880+ let accepted_htlc_info = chan_utils::HTLCOutputInCommitment {
11881+ offered: false,
11882+ amount_msat: HTLC_AMT_SAT * 1000,
11883+ cltv_expiry,
11884+ payment_hash: payment_hash_0_1,
11885+ transaction_output_index: None,
11886+ };
11887+ htlcs.push((accepted_htlc_info, ()));
11888+
11889+ let commitment_number = INITIAL_COMMITMENT_NUMBER - MIN_AFFORDABLE_HTLC_COUNT as u64;
11890+
11891+ let res = {
11892+ let per_peer_lock;
11893+ let mut peer_state_lock;
11894+
11895+ let channel =
11896+ get_channel_ref!(nodes[0], nodes[1], per_peer_lock, peer_state_lock, chan_id);
11897+ let chan_signer = if let ChannelPhase::Funded(chan) = &*channel {
11898+ chan.get_signer()
11899+ } else {
11900+ panic!();
11901+ };
11902+
11903+ let commitment_tx = CommitmentTransaction::new_with_auxiliary_htlc_data(
11904+ commitment_number,
11905+ node_1_balance_sat,
11906+ local_chan_balance,
11907+ channel.context().channel_transaction_parameters.counterparty_parameters.as_ref().unwrap().pubkeys.funding_pubkey,
11908+ channel.context().channel_transaction_parameters.holder_pubkeys.funding_pubkey,
11909+ channel.context().build_remote_transaction_keys(),
11910+ FEERATE_PER_KW,
11911+ &mut htlcs,
11912+ &channel.context().channel_transaction_parameters.as_counterparty_broadcastable(),
11913+ );
11914+ chan_signer
11915+ .as_ecdsa()
11916+ .unwrap()
11917+ .sign_counterparty_commitment(
11918+ &commitment_tx,
11919+ Vec::new(),
11920+ Vec::new(),
11921+ &secp_ctx,
11922+ )
11923+ .unwrap()
11924+ };
11925+
11926+ let commit_signed_msg = msgs::CommitmentSigned {
11927+ channel_id: chan_id,
11928+ signature: res.0,
11929+ htlc_signatures: res.1,
11930+ batch: None,
11931+ #[cfg(taproot)]
11932+ partial_signature_with_nonce: None,
11933+ };
11934+
11935+ // Send the commitment_signed message to the nodes[1].
11936+ nodes[1].node.handle_commitment_signed(node_a_id, &commit_signed_msg);
11937+ let _ = nodes[1].node.get_and_clear_pending_msg_events();
11938+
11939+ // Send the RAA to nodes[1].
11940+ let raa_msg = msgs::RevokeAndACK {
11941+ channel_id: chan_id,
11942+ per_commitment_secret: local_secret,
11943+ next_per_commitment_point: next_local_point,
11944+ #[cfg(taproot)]
11945+ next_local_nonce: None,
11946+ };
11947+ nodes[1].node.handle_revoke_and_ack(node_a_id, &raa_msg);
11948+
11949+ // The HTLC actually fails here in `fn validate_commitment_signed` due to a fee spike buffer
11950+ // violation. It nonetheless passed all checks in `fn validate_update_add_htlc`.
11951+
11952+ //expect_pending_htlcs_forwardable!(nodes[1]);
11953+ expect_htlc_handling_failed_destinations!(
11954+ nodes[1].node.get_and_clear_pending_events(),
11955+ &[HTLCDestination::FailedPayment { payment_hash: payment_hash_0_1 }]
11956+ );
11957+
11958+ let events = nodes[1].node.get_and_clear_pending_msg_events();
11959+ assert_eq!(events.len(), 1);
11960+ // Make sure the HTLC failed in the way we expect.
11961+ match events[0] {
11962+ MessageSendEvent::UpdateHTLCs {
11963+ updates: msgs::CommitmentUpdate { ref update_fail_htlcs, .. },
11964+ ..
11965+ } => {
11966+ assert_eq!(update_fail_htlcs.len(), 1);
11967+ update_fail_htlcs[0].clone()
11968+ },
11969+ _ => panic!("Unexpected event"),
11970+ };
11971+ nodes[1].logger.assert_log("lightning::ln::channel",
11972+ format!("Attempting to fail HTLC due to fee spike buffer violation in channel {}. Rebalancing is required.", raa_msg.channel_id), 1);
11973+
11974+ check_added_monitors(&nodes[1], 2);
11975+ }
11976+ }
0 commit comments