@@ -11684,3 +11684,293 @@ fn test_funding_signed_event() {
11684
11684
nodes[1].node.get_and_clear_pending_msg_events();
11685
11685
}
11686
11686
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