@@ -11,6 +11,7 @@ use crate::ln::channel::{
1111 FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE , MIN_AFFORDABLE_HTLC_COUNT ,
1212 MIN_CHAN_DUST_LIMIT_SATOSHIS ,
1313} ;
14+ use crate :: ln:: channel_state:: ChannelDetails ;
1415use crate :: ln:: channelmanager:: { PaymentId , RAACommitmentOrder , TrustedChannelFeatures } ;
1516use crate :: ln:: functional_test_utils:: * ;
1617use crate :: ln:: msgs:: { self , BaseMessageHandler , ChannelMessageHandler , MessageSendEvent } ;
@@ -3406,3 +3407,145 @@ fn test_0reserve_zero_conf_combined() {
34063407 assert_eq ! ( node_1_max_htlc, node_0_max_htlc - node_1_reserve * 1000 ) ;
34073408 send_payment ( & nodes[ 1 ] , & [ & nodes[ 0 ] ] , node_1_max_htlc) ;
34083409}
3410+
3411+ #[ xtest( feature = "_externalize_tests" ) ]
3412+ fn test_outbound_vs_available_capacity_outbound_htlc_limit_spiked_feerate ( ) {
3413+ let mut config = test_default_channel_config ( ) ;
3414+ config. channel_handshake_config . negotiate_anchors_zero_fee_htlc_tx = false ;
3415+ config. channel_handshake_config . negotiate_anchor_zero_fee_commitments = false ;
3416+
3417+ let chanmon_cfgs = create_chanmon_cfgs ( 2 ) ;
3418+ let node_cfgs = create_node_cfgs ( 2 , & chanmon_cfgs) ;
3419+ config. channel_handshake_config . announced_channel_max_inbound_htlc_value_in_flight_percentage =
3420+ 100 ;
3421+
3422+ let channel_type = ChannelTypeFeatures :: only_static_remote_key ( ) ;
3423+
3424+ let node_chanmgrs = create_node_chanmgrs ( 2 , & node_cfgs, & [ Some ( config. clone ( ) ) , Some ( config) ] ) ;
3425+ let nodes = create_network ( 2 , & node_cfgs, & node_chanmgrs) ;
3426+
3427+ let _node_a_id = nodes[ 0 ] . node . get_our_node_id ( ) ;
3428+ let _node_b_id = nodes[ 1 ] . node . get_our_node_id ( ) ;
3429+
3430+ const FEERATE : u32 = 253 ;
3431+ const MULTIPLE : u32 = FEE_SPIKE_BUFFER_FEE_INCREASE_MULTIPLE as u32 ;
3432+ const SPIKED_FEERATE : u32 = FEERATE * MULTIPLE ;
3433+ const DUST_LIMIT_MSAT : u64 = 354 * 1000 ;
3434+ const CHANNEL_VALUE_MSAT : u64 = 10_000 * 1000 ;
3435+ const NODE_0_VALUE_TO_SELF_MSAT : u64 = 5000 * 1000 ;
3436+ const NODE_1_VALUE_TO_SELF_MSAT : u64 = 5000 * 1000 ;
3437+ const CHANNEL_RESERVE_MSAT : u64 = 1000 * 1000 ;
3438+
3439+ // Find the HTLC amount that will be non-dust at the current feerate, but dust at the spiked feerate
3440+ const SPIKED_DUST_HTLC_MSAT : u64 = 688 * 1000 ;
3441+ const HTLC_SPIKE_DUST_LIMIT_MSAT : u64 = 689 * 1000 ;
3442+ let htlc_timeout_spike_tx_fee_msat =
3443+ second_stage_tx_fees_sat ( & channel_type, SPIKED_FEERATE ) . 1 * 1000 ;
3444+ assert_eq ! ( HTLC_SPIKE_DUST_LIMIT_MSAT , DUST_LIMIT_MSAT + htlc_timeout_spike_tx_fee_msat) ;
3445+
3446+ let channel_id =
3447+ create_announced_chan_between_nodes_with_value ( & nodes, 0 , 1 , CHANNEL_VALUE_MSAT / 1000 , 0 )
3448+ . 2 ;
3449+ assert_eq ! ( nodes[ 0 ] . node. list_channels( ) [ 0 ] . channel_type. as_ref( ) . unwrap( ) , & channel_type) ;
3450+ {
3451+ // Quick double-check on the dust limit to make sure HTLCs would be dust at 2x the
3452+ // feerate...
3453+ let mut per_peer_lock;
3454+ let mut peer_state_lock;
3455+
3456+ let channel =
3457+ get_channel_ref ! ( nodes[ 0 ] , nodes[ 1 ] , per_peer_lock, peer_state_lock, channel_id) ;
3458+ assert_eq ! ( channel. context( ) . holder_dust_limit_satoshis * 1000 , DUST_LIMIT_MSAT ) ;
3459+ }
3460+
3461+ // Balance the channel so each side has 5_000 sats
3462+ send_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , NODE_1_VALUE_TO_SELF_MSAT ) ;
3463+
3464+ let count_total_htlcs = |details : & ChannelDetails | {
3465+ details. pending_outbound_htlcs . len ( ) + details. pending_inbound_htlcs . len ( )
3466+ } ;
3467+ let count_node_0_nondust_htlcs = || {
3468+ let mut txs = get_local_commitment_txn ! ( nodes[ 0 ] , channel_id) ;
3469+ let commitment_tx = & txs[ 0 ] ;
3470+ commitment_tx
3471+ . output
3472+ . iter ( )
3473+ . filter ( |output| output. value . to_sat ( ) * 1000 == SPIKED_DUST_HTLC_MSAT )
3474+ . count ( )
3475+ } ;
3476+ let count_node_1_nondust_htlcs = || {
3477+ let mut txs = get_local_commitment_txn ! ( nodes[ 1 ] , channel_id) ;
3478+ let commitment_tx = & txs[ 0 ] ;
3479+ commitment_tx
3480+ . output
3481+ . iter ( )
3482+ . filter ( |output| output. value . to_sat ( ) * 1000 == SPIKED_DUST_HTLC_MSAT )
3483+ . count ( )
3484+ } ;
3485+
3486+ // Sanity check
3487+ {
3488+ let reserved_fee_sat = commit_tx_fee_sat ( SPIKED_FEERATE , 2 , & channel_type) ;
3489+ let node_0_outbound_capacity_msat = NODE_0_VALUE_TO_SELF_MSAT - CHANNEL_RESERVE_MSAT ;
3490+ let node_0_available_capacity_msat =
3491+ node_0_outbound_capacity_msat - reserved_fee_sat * 1000 ;
3492+ let node_0_details = & nodes[ 0 ] . node . list_channels ( ) [ 0 ] ;
3493+ assert_eq ! ( node_0_details. outbound_capacity_msat, node_0_outbound_capacity_msat) ;
3494+ assert_eq ! ( node_0_details. next_outbound_htlc_limit_msat, node_0_available_capacity_msat) ;
3495+ assert_eq ! ( count_total_htlcs( & node_0_details) , 0 ) ;
3496+ assert_eq ! ( count_node_0_nondust_htlcs( ) , 0 ) ;
3497+ }
3498+
3499+ // Route 2 688sat HTLCs from node 0 to node 1
3500+ for i in 1 ..3 {
3501+ route_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] ] , SPIKED_DUST_HTLC_MSAT ) ;
3502+
3503+ let max_reserved_fee_msat = commit_tx_fee_sat ( SPIKED_FEERATE , 2 + i, & channel_type) * 1000 ;
3504+ let node_0_outbound_capacity_msat =
3505+ NODE_0_VALUE_TO_SELF_MSAT - SPIKED_DUST_HTLC_MSAT * i as u64 - CHANNEL_RESERVE_MSAT ;
3506+ let node_0_available_capacity_msat = node_0_outbound_capacity_msat - max_reserved_fee_msat;
3507+ // Node 0 can send non-dust HTLCs throughout
3508+ assert ! ( node_0_available_capacity_msat >= HTLC_SPIKE_DUST_LIMIT_MSAT ) ;
3509+ let node_0_details = & nodes[ 0 ] . node . list_channels ( ) [ 0 ] ;
3510+ assert_eq ! ( node_0_details. outbound_capacity_msat, node_0_outbound_capacity_msat) ;
3511+ assert_eq ! ( node_0_details. next_outbound_htlc_limit_msat, node_0_available_capacity_msat) ;
3512+ assert_eq ! ( count_total_htlcs( & node_0_details) , i) ;
3513+ assert_eq ! ( count_node_0_nondust_htlcs( ) , i) ;
3514+ }
3515+
3516+ let node_0_details = & nodes[ 0 ] . node . list_channels ( ) [ 0 ] ;
3517+ let local_nondust_htlc_count = 2 ;
3518+ assert_eq ! ( count_total_htlcs( & node_0_details) , local_nondust_htlc_count) ;
3519+ assert_eq ! ( count_node_0_nondust_htlcs( ) , local_nondust_htlc_count) ;
3520+ assert_eq ! ( count_node_1_nondust_htlcs( ) , local_nondust_htlc_count) ;
3521+
3522+ let node_0_outbound_capacity_msat = node_0_details. outbound_capacity_msat ;
3523+
3524+ // Route 2 688sat HTLCs from node 1 to node 0
3525+ for i in 1 ..3 {
3526+ route_payment ( & nodes[ 1 ] , & [ & nodes[ 0 ] ] , SPIKED_DUST_HTLC_MSAT ) ;
3527+
3528+ let node_1_outbound_capacity_msat =
3529+ NODE_1_VALUE_TO_SELF_MSAT - SPIKED_DUST_HTLC_MSAT * i as u64 - CHANNEL_RESERVE_MSAT ;
3530+ assert ! ( node_1_outbound_capacity_msat >= HTLC_SPIKE_DUST_LIMIT_MSAT ) ;
3531+ let node_1_details = & nodes[ 1 ] . node . list_channels ( ) [ 0 ] ;
3532+ assert_eq ! ( node_1_details. outbound_capacity_msat, node_1_outbound_capacity_msat) ;
3533+ assert_eq ! ( node_1_details. next_outbound_htlc_limit_msat, node_1_outbound_capacity_msat) ;
3534+
3535+ let nondust_htlc_count = 2 + i;
3536+ // At the current feerate, 688sat HTLCs are present on both commitments
3537+ assert_eq ! ( count_node_0_nondust_htlcs( ) , nondust_htlc_count) ;
3538+ assert_eq ! ( count_node_1_nondust_htlcs( ) , nondust_htlc_count) ;
3539+
3540+ assert_eq ! (
3541+ nodes[ 0 ] . node. list_channels( ) [ 0 ] . outbound_capacity_msat,
3542+ node_0_outbound_capacity_msat
3543+ ) ;
3544+ let max_reserved_fee_msat =
3545+ commit_tx_fee_sat ( SPIKED_FEERATE , nondust_htlc_count + 2 , & channel_type) * 1000 ;
3546+ assert_eq ! (
3547+ nodes[ 0 ] . node. list_channels( ) [ 0 ] . next_outbound_htlc_limit_msat,
3548+ node_0_outbound_capacity_msat - max_reserved_fee_msat
3549+ ) ;
3550+ }
3551+ }
0 commit comments