@@ -9900,3 +9900,156 @@ pub fn test_multi_post_event_actions() {
99009900 do_test_multi_post_event_actions ( true ) ;
99019901 do_test_multi_post_event_actions ( false ) ;
99029902}
9903+
9904+ #[ xtest( feature = "_externalize_tests" ) ]
9905+ pub fn test_dust_exposure_holding_cell_assertion ( ) {
9906+ // Test that we properly move forward if we pop an HTLC-add from the holding cell but fail to
9907+ // add it to the channel. In 0.2 this cause a (harmless in prod) debug assertion failure. We
9908+ // try to ensure that this won't happen by checking that an HTLC will be able to be added
9909+ // before we add it to the holding cell, so getting into this state takes a bit of work.
9910+ //
9911+ // Here we accomplish this by using the dust exposure limit. This has the unique feature that
9912+ // node C can increase node B's dust exposure on the B <-> C channel without B doing anything.
9913+ // To exploit this, we get node B one HTLC away from being over-exposed to dust, give it one
9914+ // more HTLC in the holding cell, then have node C add an HTLC. By the time the holding-cell
9915+ // HTLC is released we are at max-dust-exposure and will fail it.
9916+
9917+ let chanmon_cfgs = create_chanmon_cfgs ( 3 ) ;
9918+ let node_cfgs = create_node_cfgs ( 3 , & chanmon_cfgs) ;
9919+
9920+ // Configure nodes with specific dust limits
9921+ let mut config = test_default_channel_config ( ) ;
9922+ // Use a fixed dust exposure limit to make the test simpler
9923+ const DUST_HTLC_VALUE_MSAT : u64 = 500_000 ;
9924+ config. channel_config . max_dust_htlc_exposure = MaxDustHTLCExposure :: FixedLimitMsat ( 5_000_000 ) ;
9925+ config. channel_handshake_config . max_inbound_htlc_value_in_flight_percent_of_channel = 100 ;
9926+
9927+ let configs = [ Some ( config. clone ( ) ) , Some ( config. clone ( ) ) , Some ( config. clone ( ) ) ] ;
9928+ let node_chanmgrs = create_node_chanmgrs ( 3 , & node_cfgs, & configs) ;
9929+ let nodes = create_network ( 3 , & node_cfgs, & node_chanmgrs) ;
9930+
9931+ let node_a_id = nodes[ 0 ] . node . get_our_node_id ( ) ;
9932+ let node_b_id = nodes[ 1 ] . node . get_our_node_id ( ) ;
9933+ let node_c_id = nodes[ 2 ] . node . get_our_node_id ( ) ;
9934+
9935+ // Create channels: A <-> B <-> C
9936+ create_announced_chan_between_nodes ( & nodes, 0 , 1 ) ;
9937+ let bc_chan_id = create_announced_chan_between_nodes ( & nodes, 1 , 2 ) . 2 ;
9938+ send_payment ( & nodes[ 0 ] , & [ & nodes[ 1 ] , & nodes[ 2 ] ] , 10_000_000 ) ;
9939+
9940+ // Send multiple dust HTLCs from B to C to approach the dust limit (including transaction fees)
9941+ for _ in 0 ..4 {
9942+ route_payment ( & nodes[ 1 ] , & [ & nodes[ 2 ] ] , DUST_HTLC_VALUE_MSAT ) ;
9943+ }
9944+
9945+ // At this point we shouldn't be over the dust limit, and should still be able to send HTLCs.
9946+ let bs_chans = nodes[ 1 ] . node . list_channels ( ) ;
9947+ let bc_chan =
9948+ bs_chans. iter ( ) . filter ( |chan| chan. counterparty . node_id == node_c_id) . next ( ) . unwrap ( ) ;
9949+ assert_eq ! (
9950+ bc_chan. next_outbound_htlc_minimum_msat,
9951+ config. channel_handshake_config. our_htlc_minimum_msat
9952+ ) ;
9953+
9954+ // Add a further HTLC from B to C, but don't deliver the send messages.
9955+ // After this we'll only have the ability to add one more HTLC, but by not delivering the send
9956+ // messages (leaving B waiting on C's RAA) the next HTLC will go into B's holding cell.
9957+ let ( route_bc, payment_hash_bc, _payment_preimage_bc, payment_secret_bc) =
9958+ get_route_and_payment_hash ! ( nodes[ 1 ] , nodes[ 2 ] , DUST_HTLC_VALUE_MSAT ) ;
9959+ let onion_bc = RecipientOnionFields :: secret_only ( payment_secret_bc) ;
9960+ let id = PaymentId ( payment_hash_bc. 0 ) ;
9961+ nodes[ 1 ] . node . send_payment_with_route ( route_bc, payment_hash_bc, onion_bc, id) . unwrap ( ) ;
9962+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
9963+ let send_bc = SendEvent :: from_node ( & nodes[ 1 ] ) ;
9964+
9965+ let bs_chans = nodes[ 1 ] . node . list_channels ( ) ;
9966+ let bc_chan =
9967+ bs_chans. iter ( ) . filter ( |chan| chan. counterparty . node_id == node_c_id) . next ( ) . unwrap ( ) ;
9968+ assert_eq ! (
9969+ bc_chan. next_outbound_htlc_minimum_msat,
9970+ config. channel_handshake_config. our_htlc_minimum_msat
9971+ ) ;
9972+
9973+ // Forward an additional HTLC from A through B to C. This will go in B's holding cell for node
9974+ // C as it is waiting on a response to the above messages.
9975+ let payment_params_ac = PaymentParameters :: from_node_id ( node_c_id, TEST_FINAL_CLTV )
9976+ . with_bolt11_features ( nodes[ 2 ] . node . bolt11_invoice_features ( ) ) . unwrap ( ) ;
9977+ let ( route_ac, payment_hash_cell, _, payment_secret_ac) =
9978+ get_route_and_payment_hash ! ( nodes[ 0 ] , nodes[ 2 ] , payment_params_ac, DUST_HTLC_VALUE_MSAT ) ;
9979+ let onion_ac = RecipientOnionFields :: secret_only ( payment_secret_ac) ;
9980+ let id = PaymentId ( payment_hash_cell. 0 ) ;
9981+ nodes[ 0 ] . node . send_payment_with_route ( route_ac, payment_hash_cell, onion_ac, id) . unwrap ( ) ;
9982+ check_added_monitors ( & nodes[ 0 ] , 1 ) ;
9983+
9984+ let send_ab = SendEvent :: from_node ( & nodes[ 0 ] ) ;
9985+ nodes[ 1 ] . node . handle_update_add_htlc ( node_a_id, & send_ab. msgs [ 0 ] ) ;
9986+ commitment_signed_dance ! ( nodes[ 1 ] , nodes[ 0 ] , send_ab. commitment_msg, false , true ) ;
9987+
9988+ // At this point when we process pending forwards the HTLC will go into the holding cell and no
9989+ // further messages will be generated. Node B will also be at its maximum dust exposure and
9990+ // will refuse to send any dust HTLCs (when it includes the holding cell HTLC).
9991+ expect_and_process_pending_htlcs ( & nodes[ 1 ] , false ) ;
9992+ assert ! ( nodes[ 1 ] . node. get_and_clear_pending_msg_events( ) . is_empty( ) ) ;
9993+
9994+ let bs_chans = nodes[ 1 ] . node . list_channels ( ) ;
9995+ let bc_chan =
9996+ bs_chans. iter ( ) . filter ( |chan| chan. counterparty . node_id == node_c_id) . next ( ) . unwrap ( ) ;
9997+ assert ! ( bc_chan. next_outbound_htlc_minimum_msat > DUST_HTLC_VALUE_MSAT ) ;
9998+
9999+ // Send an additional HTLC from C to B. This will make B unable to forward the HTLC already in
10000+ // its holding cell as it would be over-exposed to dust.
10001+ let ( route_cb, payment_hash_cb, payment_preimage_cb, payment_secret_cb) =
10002+ get_route_and_payment_hash ! ( nodes[ 2 ] , nodes[ 1 ] , DUST_HTLC_VALUE_MSAT ) ;
10003+ let onion_cb = RecipientOnionFields :: secret_only ( payment_secret_cb) ;
10004+ let id = PaymentId ( payment_hash_cb. 0 ) ;
10005+ nodes[ 2 ] . node . send_payment_with_route ( route_cb, payment_hash_cb, onion_cb, id) . unwrap ( ) ;
10006+ check_added_monitors ( & nodes[ 2 ] , 1 ) ;
10007+
10008+ // Now deliver all the messages and make sure that the HTLC is failed-back.
10009+ let send_event_cb = SendEvent :: from_node ( & nodes[ 2 ] ) ;
10010+ nodes[ 1 ] . node . handle_update_add_htlc ( node_c_id, & send_event_cb. msgs [ 0 ] ) ;
10011+ nodes[ 1 ] . node . handle_commitment_signed_batch_test ( node_c_id, & send_event_cb. commitment_msg ) ;
10012+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
10013+
10014+ nodes[ 2 ] . node . handle_update_add_htlc ( node_b_id, & send_bc. msgs [ 0 ] ) ;
10015+ nodes[ 2 ] . node . handle_commitment_signed_batch_test ( node_b_id, & send_bc. commitment_msg ) ;
10016+ check_added_monitors ( & nodes[ 2 ] , 1 ) ;
10017+
10018+ let cs_raa = get_event_msg ! ( nodes[ 2 ] , MessageSendEvent :: SendRevokeAndACK , node_b_id) ;
10019+ nodes[ 1 ] . node . handle_revoke_and_ack ( node_c_id, & cs_raa) ;
10020+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
10021+ let ( bs_raa, bs_cs) = get_revoke_commit_msgs ( & nodes[ 1 ] , & node_c_id) ;
10022+
10023+ // When we delivered the RAA above, we attempted (and failed) to add the HTLC to the channel,
10024+ // causing it to be ready to fail-back, which we do here:
10025+ let next_hop =
10026+ HTLCHandlingFailureType :: Forward { node_id : Some ( node_c_id) , channel_id : bc_chan_id } ;
10027+ expect_htlc_forwarding_fails ( & nodes[ 1 ] , & [ next_hop] ) ;
10028+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
10029+ fail_payment_along_path ( & [ & nodes[ 0 ] , & nodes[ 1 ] ] ) ;
10030+ let conditions = PaymentFailedConditions :: new ( ) ;
10031+ expect_payment_failed_conditions ( & nodes[ 0 ] , payment_hash_cell, false , conditions) ;
10032+
10033+ nodes[ 2 ] . node . handle_revoke_and_ack ( node_b_id, & bs_raa) ;
10034+ check_added_monitors ( & nodes[ 2 ] , 1 ) ;
10035+ let cs_cs = get_htlc_update_msgs ( & nodes[ 2 ] , & node_b_id) ;
10036+
10037+ nodes[ 2 ] . node . handle_commitment_signed_batch_test ( node_b_id, & bs_cs) ;
10038+ check_added_monitors ( & nodes[ 2 ] , 1 ) ;
10039+ let cs_raa = get_event_msg ! ( nodes[ 2 ] , MessageSendEvent :: SendRevokeAndACK , node_b_id) ;
10040+
10041+ nodes[ 1 ] . node . handle_commitment_signed_batch_test ( node_c_id, & cs_cs. commitment_signed ) ;
10042+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
10043+ let bs_raa = get_event_msg ! ( nodes[ 1 ] , MessageSendEvent :: SendRevokeAndACK , node_c_id) ;
10044+
10045+ nodes[ 1 ] . node . handle_revoke_and_ack ( node_c_id, & cs_raa) ;
10046+ check_added_monitors ( & nodes[ 1 ] , 1 ) ;
10047+ expect_and_process_pending_htlcs ( & nodes[ 1 ] , false ) ;
10048+ expect_payment_claimable ! ( nodes[ 1 ] , payment_hash_cb, payment_secret_cb, DUST_HTLC_VALUE_MSAT ) ;
10049+
10050+ nodes[ 2 ] . node . handle_revoke_and_ack ( node_b_id, & bs_raa) ;
10051+ check_added_monitors ( & nodes[ 2 ] , 1 ) ;
10052+
10053+ // Now that everything has settled, make sure the channels still work with a simple claim.
10054+ claim_payment ( & nodes[ 2 ] , & [ & nodes[ 1 ] ] , payment_preimage_cb) ;
10055+ }
0 commit comments