Skip to content

Commit ab3e7c3

Browse files
committed
pytest: rework test_real_data and test_real_biases to be parallel.
This speeds them up, and exercises the askrene parallel code. Before: test_real_data: 348s test_real_biases: 105s After: test_real_data: 133s test_real_biases: 106s And this is because much of the time is spent uncompressing the gossmap and startup. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
1 parent d5c2c48 commit ab3e7c3

1 file changed

Lines changed: 65 additions & 47 deletions

File tree

tests/test_askrene.py

Lines changed: 65 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,7 +1442,7 @@ def test_min_htlc_after_excess(node_factory, bitcoind):
14421442

14431443

14441444
@pytest.mark.slow_test
1445-
def test_real_data(node_factory, bitcoind):
1445+
def test_real_data(node_factory, bitcoind, executor):
14461446
# Route from Rusty's node to the top nodes
14471447
# From tests/data/gossip-store-2026-02-03-node-map.xz:
14481448
# Me: 2134:024b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605:BLUEIRON
@@ -1475,58 +1475,62 @@ def test_real_data(node_factory, bitcoind):
14751475
limit = 100
14761476
expected = (11, 95, 8026484, 925406, 89)
14771477

1478-
fees = {}
1478+
# 0.5% is the norm
1479+
MAX_FEE = AMOUNT // 200
1480+
1481+
# Do these in parallel.
1482+
futs = {}
14791483
for n in range(0, limit):
1480-
# 0.5% is the norm
1481-
MAX_FEE = AMOUNT // 200
1484+
futs[n] = executor.submit(l1.rpc.getroutes,
1485+
source=l1.info['id'],
1486+
destination=nodeids[n],
1487+
amount_msat=AMOUNT,
1488+
layers=['auto.sourcefree', 'auto.localchans'],
1489+
maxfee_msat=MAX_FEE,
1490+
final_cltv=18)
14821491

1492+
fees = {}
1493+
prevs = {}
1494+
for n in range(0, limit):
1495+
fees[n] = []
14831496
if n in canned_gossmap_badnodes:
14841497
with pytest.raises(RpcError, match=canned_gossmap_badnodes[n]):
1485-
l1.rpc.getroutes(source=l1.info['id'],
1486-
destination=nodeids[n],
1487-
amount_msat=AMOUNT,
1488-
layers=['auto.sourcefree', 'auto.localchans'],
1489-
maxfee_msat=MAX_FEE,
1490-
final_cltv=18)
1491-
fees[n] = []
1492-
continue
1493-
1494-
try:
1495-
prev = l1.rpc.getroutes(source=l1.info['id'],
1496-
destination=nodeids[n],
1497-
amount_msat=AMOUNT,
1498-
layers=['auto.sourcefree', 'auto.localchans'],
1499-
maxfee_msat=MAX_FEE,
1500-
final_cltv=18)
1501-
except RpcError:
1502-
fees[n] = []
1498+
futs[n].result(TIMEOUT)
15031499
continue
15041500

1505-
# Now stress it, by asking it to spend 1msat less!
1506-
fees[n] = [sum([r['path'][0]['amount_msat'] for r in prev['routes']]) - AMOUNT]
1501+
prevs[n] = futs[n].result(TIMEOUT)
1502+
1503+
# Stress it by asking harder for each one which succeeded
1504+
while prevs != {}:
1505+
futs = {}
1506+
for n, prev in prevs.items():
1507+
# Record fees
1508+
fees[n].append(sum([r['path'][0]['amount_msat'] for r in prev['routes']]) - AMOUNT)
1509+
# Now stress it, by asking it to spend 1msat less!
1510+
futs[n] = executor.submit(l1.rpc.getroutes,
1511+
source=l1.info['id'],
1512+
destination=nodeids[n],
1513+
amount_msat=AMOUNT,
1514+
layers=['auto.sourcefree', 'auto.localchans'],
1515+
maxfee_msat=fees[n][-1] - 1,
1516+
final_cltv=18)
15071517

1508-
while True:
1509-
# Keep making it harder...
1518+
for n, fut in futs.items():
15101519
try:
1511-
routes = l1.rpc.getroutes(source=l1.info['id'],
1512-
destination=nodeids[n],
1513-
amount_msat=AMOUNT,
1514-
layers=['auto.sourcefree', 'auto.localchans'],
1515-
maxfee_msat=fees[n][-1] - 1,
1516-
final_cltv=18)
1520+
routes = fut.result(TIMEOUT)
15171521
except RpcError:
1518-
break
1522+
# Too much, this one is one.
1523+
del prevs[n]
1524+
continue
15191525

15201526
fee = sum([r['path'][0]['amount_msat'] for r in routes['routes']]) - AMOUNT
15211527
# Should get less expensive
15221528
assert fee < fees[n][-1]
15231529

15241530
# Should get less likely (Note! This is violated because once we care
15251531
# about fees, the total is reduced, leading to better prob!).
1526-
# assert routes['probability_ppm'] < prev['probability_ppm']
1527-
1528-
fees[n].append(fee)
1529-
prev = routes
1532+
# assert routes['probability_ppm'] < prevs[n]['probability_ppm']
1533+
prevs[n] = routes
15301534

15311535
# Which succeeded in improving
15321536
improved = [n for n in fees if len(fees[n]) > 1]
@@ -1544,10 +1548,12 @@ def test_real_data(node_factory, bitcoind):
15441548
best = n
15451549

15461550
assert (len(fees[best]), len(improved), total_first_fee, total_final_fee, percent_fee_reduction) == expected
1551+
# askrene will have restricted how many we run
1552+
assert l1.daemon.is_in_log(r"Too many running at once \(4 vs 4\): waiting")
15471553

15481554

15491555
@pytest.mark.slow_test
1550-
def test_real_biases(node_factory, bitcoind):
1556+
def test_real_biases(node_factory, bitcoind, executor):
15511557
# Route from Rusty's node to the top 100.
15521558
# From tests/data/gossip-store-2026-02-03-node-map.xz:
15531559
# Me: 2134:024b9a1fa8e006f1e3937f65f66c408e6da8e1ca728ea43222a7381df1cc449605:BLUEIRON
@@ -1582,22 +1588,34 @@ def test_real_biases(node_factory, bitcoind):
15821588
num_changed = {}
15831589
bias_ineffective = 0
15841590

1585-
for bias in (1, 2, 4, 8, 16, 32, 64, 100):
1586-
num_changed[bias] = 0
1587-
for n in range(0, limit):
1588-
# 0.5% is the norm
1589-
MAX_FEE = AMOUNT // 200
1590-
1591-
if n in canned_gossmap_badnodes:
1592-
continue
1591+
# 0.5% is the norm
1592+
MAX_FEE = AMOUNT // 200
15931593

1594-
route = l1.rpc.getroutes(source=l1.info['id'],
1594+
# To exercise parallelism, do bases all at once.
1595+
futures = {}
1596+
for n in range(0, limit):
1597+
if n in canned_gossmap_badnodes:
1598+
continue
1599+
futures[n] = executor.submit(l1.rpc.getroutes,
1600+
source=l1.info['id'],
15951601
destination=nodeids[n],
15961602
amount_msat=AMOUNT,
15971603
layers=['auto.sourcefree', 'auto.localchans'],
15981604
maxfee_msat=MAX_FEE,
15991605
final_cltv=18)
16001606

1607+
base_routes = {}
1608+
for n in range(0, limit):
1609+
if n in canned_gossmap_badnodes:
1610+
continue
1611+
base_routes[n] = futures[n].result(TIMEOUT)
1612+
1613+
for bias in (1, 2, 4, 8, 16, 32, 64, 100):
1614+
num_changed[bias] = 0
1615+
for n in range(0, limit):
1616+
if n in canned_gossmap_badnodes:
1617+
continue
1618+
route = base_routes[n]
16011619
# Now add bias against final channel, see if it changes.
16021620
chan = route['routes'][0]['path'][-1]['short_channel_id_dir']
16031621

0 commit comments

Comments
 (0)