From 83eee64fda9453f037f0b00a45630843f93bc08a Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 11 Oct 2024 21:30:40 +1030 Subject: [PATCH] pytest: test askrene with worse maxfee argument. We ask it again, but reduce fees by 1msat from the previous answer. This is really nasty, as it frequently exercises the case where we only go over fee when we do the refinement step. Signed-off-by: Rusty Russell --- plugins/askrene/askrene.c | 3 ++ tests/test_askrene.py | 82 +++++++++++++++++++++++++++++++++------ 2 files changed, 73 insertions(+), 12 deletions(-) diff --git a/plugins/askrene/askrene.c b/plugins/askrene/askrene.c index a035e83b4..722f574c8 100644 --- a/plugins/askrene/askrene.c +++ b/plugins/askrene/askrene.c @@ -433,6 +433,9 @@ too_expensive: goto too_expensive; } + rq_log(tmpctx, rq, LOG_DBG, "Final answer has %zu flows with mu=%u", + tal_count(flows), mu); + /* Convert back into routes, with delay and other information fixed */ *routes = tal_arr(ctx, struct route *, tal_count(flows)); *amounts = tal_arr(ctx, struct amount_msat, tal_count(flows)); diff --git a/tests/test_askrene.py b/tests/test_askrene.py index 7f17c1f60..aa3db5805 100644 --- a/tests/test_askrene.py +++ b/tests/test_askrene.py @@ -899,10 +899,15 @@ def test_real_data(node_factory, bitcoind): 'tests/data/gossip-store-2024-09-22.compressed', outfile.name]).decode('utf-8').splitlines() - # l2 complains being given bad gossip from l1 - l1, l2 = node_factory.line_graph(2, + # This is in msat, but is also the size of channel we create. + AMOUNT = 100000000 + + # l2 complains being given bad gossip from l1, throttle to reduce + # the sheer amount of log noise. + l1, l2 = node_factory.line_graph(2, fundamount=AMOUNT, opts=[{'gossip_store_file': outfile.name, - 'allow_warning': True}, + 'allow_warning': True, + 'dev-throttle-gossip': None}, {'allow_warning': True}]) # These were obviously having a bad day at the time of the snapshot: @@ -917,21 +922,74 @@ def test_real_data(node_factory, bitcoind): # 97:034a5fdb2df3ce1bfd2c2aca205ce9cfeef1a5f4af21b0b5e81c453080c30d7683:🚶LightningTransact 97: r"We could not find a usable set of paths\. The shortest path is 103x1x0->0x3301x1646->0x1281x2323->97x1281x33241, but 97x1281x33241/1 isn't big enough to carry 100000000msat\.", } + + fees = {} for n in range(0, 100): + print(f"XXX: {n}") + # 0.5% is the norm + MAX_FEE = AMOUNT // 200 + if n in badnodes: with pytest.raises(RpcError, match=badnodes[n]): l1.rpc.getroutes(source=l1.info['id'], destination=nodeids[n], - amount_msat=100000000, + amount_msat=AMOUNT, layers=['auto.sourcefree', 'auto.localchans'], - maxfee_msat=10000000, + maxfee_msat=MAX_FEE, final_cltv=18) + fees[n] = [] continue - routes = l1.rpc.getroutes(source=l1.info['id'], - destination=nodeids[n], - amount_msat=100000000, - layers=['auto.sourcefree', 'auto.localchans'], - maxfee_msat=10000000, - final_cltv=18) - print(f"{n} route has {len(routes['routes'])} paths") + try: + prev = l1.rpc.getroutes(source=l1.info['id'], + destination=nodeids[n], + amount_msat=AMOUNT, + layers=['auto.sourcefree', 'auto.localchans'], + maxfee_msat=MAX_FEE, + final_cltv=18) + except RpcError: + fees[n] = [] + continue + + # Now stress it, by asking it to spend 1msat less! + fees[n] = [sum([r['path'][0]['amount_msat'] for r in prev['routes']]) - AMOUNT] + + while True: + # Keep making it harder... + try: + routes = l1.rpc.getroutes(source=l1.info['id'], + destination=nodeids[n], + amount_msat=AMOUNT, + layers=['auto.sourcefree', 'auto.localchans'], + maxfee_msat=fees[n][-1] - 1, + final_cltv=18) + except RpcError: + break + + fee = sum([r['path'][0]['amount_msat'] for r in routes['routes']]) - AMOUNT + # Should get less expensive + assert fee < fees[n][-1] + + # Should get less likely (Note! This is violated because once we care + # about fees, the total is reduced, leading to better prob!). +# assert routes['probability_ppm'] < prev['probability_ppm'] + + fees[n].append(fee) + prev = routes + + # Which succeeded in improving + improved = [n for n in fees if len(fees[n]) > 1] + total_first_fee = sum([fees[n][0] for n in improved]) + total_final_fee = sum([fees[n][-1] for n in improved]) + + if total_first_fee != 0: + percent_fee_reduction = 100 - int(total_final_fee * 100 / total_first_fee) + else: + percent_fee_reduction = 0 + + best = 0 + for n in fees: + if len(fees[n]) > len(fees[best]): + best = n + + assert (len(fees[best]), len(improved), total_first_fee, total_final_fee, percent_fee_reduction) == (9, 91, 20917688, 5254665, 75)