@@ -2436,6 +2436,113 @@ def test_lockup_drain(node_factory, bitcoind):
24362436 l2 .pay (l1 , total // 2 )
24372437
24382438
2439+ @pytest .mark .developer ("needs DEVELOPER=1 for dev_ignore_htlcs" )
2440+ def test_htlc_too_dusty_outgoing (node_factory , bitcoind , chainparams ):
2441+ """ Try to hit the 'too much dust' limit, should fail the HTLC """
2442+ feerate = 10000
2443+
2444+ # elements txs are bigger so they become dusty faster
2445+ max_dust_limit_sat = 100000 if chainparams ['elements' ] else 50000
2446+ non_dust_htlc_val_sat = 20000 if chainparams ['elements' ] else 10000
2447+ htlc_val_sat = 10000 if chainparams ['elements' ] else 5000
2448+
2449+ l1 , l2 = node_factory .line_graph (2 , opts = {'may_reconnect' : True ,
2450+ 'feerates' : (feerate , feerate , feerate , feerate ),
2451+ 'max-dust-htlc-exposure-msat' : '{}sat' .format (max_dust_limit_sat ),
2452+ 'allow_warning' : True })
2453+
2454+ # l2 holds all of l1's htlcs hostage
2455+ l2 .rpc .dev_ignore_htlcs (id = l1 .info ['id' ], ignore = True )
2456+
2457+ # l2's max dust limit is set to 100k
2458+ htlc_val_msat = htlc_val_sat * 1000
2459+ num_dusty_htlcs = max_dust_limit_sat // htlc_val_sat
2460+
2461+ # add a some non-dusty htlcs, these will fail when we raise the dust limit
2462+ route = l1 .rpc .getroute (l2 .info ['id' ], non_dust_htlc_val_sat * 1000 , 1 )['route' ]
2463+ for i in range (0 , 3 ):
2464+ inv = l2 .rpc .invoice ((non_dust_htlc_val_sat * 1000 ), str (i + 100 ), str (i + 100 ))
2465+ l1 .rpc .sendpay (route , inv ['payment_hash' ], payment_secret = inv ['payment_secret' ])
2466+ l2 .daemon .wait_for_log (r'their htlc .* dev_ignore_htlcs' )
2467+ res = only_one (l1 .rpc .listsendpays (payment_hash = inv ['payment_hash' ])['payments' ])
2468+ assert res ['status' ] == 'pending'
2469+
2470+ # add some dusty-htlcs
2471+ route = l1 .rpc .getroute (l2 .info ['id' ], htlc_val_msat , 1 )['route' ]
2472+ for i in range (0 , num_dusty_htlcs ):
2473+ inv = l2 .rpc .invoice (htlc_val_msat , str (i ), str (i ))
2474+ l1 .rpc .sendpay (route , inv ['payment_hash' ], payment_secret = inv ['payment_secret' ])
2475+ l2 .daemon .wait_for_log (r'their htlc .* dev_ignore_htlcs' )
2476+ res = only_one (l1 .rpc .listsendpays (payment_hash = inv ['payment_hash' ])['payments' ])
2477+ assert res ['status' ] == 'pending'
2478+
2479+ # one more should tip it over, and return a payment failure
2480+ inv = l2 .rpc .invoice (htlc_val_msat , str (num_dusty_htlcs ), str (num_dusty_htlcs ))
2481+ l1 .rpc .sendpay (route , inv ['payment_hash' ], payment_secret = inv ['payment_secret' ])
2482+ l1 .daemon .wait_for_log ('CHANNEL_ERR_DUST_FAILURE' )
2483+ wait_for (lambda : only_one (l1 .rpc .listsendpays (payment_hash = inv ['payment_hash' ])['payments' ])['status' ] == 'failed' )
2484+
2485+ # but we can still add a non dust htlc
2486+ route = l1 .rpc .getroute (l2 .info ['id' ], non_dust_htlc_val_sat * 1000 , 1 )['route' ]
2487+ inv = l2 .rpc .invoice ((10000 * 1000 ), str (120 ), str (120 ))
2488+ l1 .rpc .sendpay (route , inv ['payment_hash' ], payment_secret = inv ['payment_secret' ])
2489+ l2 .daemon .wait_for_log (r'their htlc .* dev_ignore_htlcs' )
2490+ res = only_one (l1 .rpc .listsendpays (payment_hash = inv ['payment_hash' ])['payments' ])
2491+ assert res ['status' ] == 'pending'
2492+
2493+ # Ok, adjust our feerate upward, so the non-dust htlcs are now dust
2494+ # note that this is above the buffer we've been keeping, so the channel
2495+ # should automatically fail
2496+ l1 .set_feerates ([feerate * 2 ] * 4 , False )
2497+ l1 .restart ()
2498+
2499+ # the channel should fail -- too much dust
2500+ inv = l2 .rpc .invoice (htlc_val_msat , str (num_dusty_htlcs + 1 ), str (num_dusty_htlcs + 1 ))
2501+ with pytest .raises (RpcError , match = r'WIRE_UNKNOWN_NEXT_PEER' ):
2502+ l1 .rpc .sendpay (route , inv ['payment_hash' ], payment_secret = inv ['payment_secret' ])
2503+
2504+
2505+ @pytest .mark .developer ("needs DEVELOPER=1 for dev_ignore_htlcs" )
2506+ def test_htlc_too_dusty_incoming (node_factory , bitcoind ):
2507+ """ Try to hit the 'too much dust' limit, should fail the HTLC """
2508+ feerate = 30000
2509+ l1 , l2 , l3 = node_factory .line_graph (3 , opts = [{'may_reconnect' : True ,
2510+ 'feerates' : (feerate , feerate , feerate , feerate ),
2511+ 'max-dust-htlc-exposure-msat' : '200000sat' },
2512+ {'may_reconnect' : True ,
2513+ 'feerates' : (feerate , feerate , feerate , feerate ),
2514+ 'max-dust-htlc-exposure-msat' : '100000sat' ,
2515+ 'fee-base' : 0 ,
2516+ 'fee-per-satoshi' : 0 },
2517+ {'max-dust-htlc-exposure-msat' : '500000sat' }],
2518+ wait_for_announce = True )
2519+
2520+ # on the l2->l3, and l3 holds all the htlcs hostage
2521+ # have l3 hold onto all the htlcs and not fulfill them
2522+ l3 .rpc .dev_ignore_htlcs (id = l2 .info ['id' ], ignore = True )
2523+
2524+ # l2's max dust limit is set to 100k
2525+ max_dust_limit_sat = 100000
2526+ htlc_val_sat = 10000
2527+ htlc_val_msat = htlc_val_sat * 1000
2528+ num_dusty_htlcs = max_dust_limit_sat // htlc_val_sat
2529+ route = l1 .rpc .getroute (l3 .info ['id' ], htlc_val_msat , 1 )['route' ]
2530+
2531+ # l1 sends as much money as it can
2532+ for i in range (0 , num_dusty_htlcs ):
2533+ inv = l3 .rpc .invoice (htlc_val_msat , str (i ), str (i ))
2534+ l1 .rpc .sendpay (route , inv ['payment_hash' ], payment_secret = inv ['payment_secret' ])
2535+ l3 .daemon .wait_for_log (r'their htlc .* dev_ignore_htlcs' )
2536+ res = only_one (l1 .rpc .listsendpays (payment_hash = inv ['payment_hash' ])['payments' ])
2537+ assert res ['status' ] == 'pending'
2538+
2539+ # one more should tip it over, and return a payment failure
2540+ inv = l3 .rpc .invoice (htlc_val_msat , str (num_dusty_htlcs ), str (num_dusty_htlcs ))
2541+ l1 .rpc .sendpay (route , inv ['payment_hash' ], payment_secret = inv ['payment_secret' ])
2542+ l2 .daemon .wait_for_log ('failing immediately, as requested' )
2543+ wait_for (lambda : only_one (l1 .rpc .listsendpays (payment_hash = inv ['payment_hash' ])['payments' ])['status' ] == 'failed' )
2544+
2545+
24392546def test_error_returns_blockheight (node_factory , bitcoind ):
24402547 """Test that incorrect_or_unknown_payment_details returns block height"""
24412548 l1 , l2 = node_factory .line_graph (2 )
0 commit comments