Skip to content

Commit 990e5fe

Browse files
committed
[WIP] askrene benchmark
Signed-off-by: Lagrang3 <[email protected]>
1 parent 67432c7 commit 990e5fe

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

tests/test_askrene_bench.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
from fixtures import * # noqa: F401,F403
2+
from hashlib import sha256
3+
from pyln.client import RpcError
4+
from pyln.testing.utils import SLOW_MACHINE
5+
from utils import (
6+
only_one, first_scid, GenChannel, generate_gossip_store,
7+
sync_blockheight, wait_for, TEST_NETWORK, TIMEOUT
8+
)
9+
import os
10+
import pytest
11+
import subprocess
12+
import time
13+
import tempfile
14+
import random
15+
import json
16+
17+
@pytest.mark.slow_test
18+
def test_real_data(node_factory, bitcoind):
19+
outfile = tempfile.NamedTemporaryFile(prefix='gossip-store-')
20+
nodeids = subprocess.check_output(['devtools/gossmap-compress',
21+
'decompress',
22+
'tests/data/gossip-store-2024-09-22.compressed',
23+
outfile.name]).decode('utf-8').splitlines()
24+
25+
# This is in msat, but is also the size of channel we create.
26+
AMOUNT = 100000000
27+
28+
l1 = node_factory.line_graph(1, fundamount=AMOUNT,
29+
opts=[{'gossip_store_file': outfile.name,
30+
'allow_warning': True,
31+
'dev-throttle-gossip': None}])[0]
32+
33+
# node selection
34+
all_nodes = []
35+
all_chans = l1.rpc.listchannels()["channels"]
36+
37+
node_dict = {}
38+
for c in all_chans:
39+
n = c["source"]
40+
if n not in node_dict:
41+
node_dict[n] = {"id": n, "num_chans": 0, "capacity": 0}
42+
node_dict[n]["num_chans"] += 1
43+
node_dict[n]["capacity"] += c["amount_msat"]
44+
45+
all_nodes = [ data for n, data in node_dict.items() ]
46+
47+
# def big_node(n):
48+
# return n['num_chans']>=50 and n['num_chans']<=100 \
49+
# and n['capacity']<=2*1e11 and n['capacity']>=1*1e11
50+
#
51+
# def small_node(n):
52+
# return n['num_chans']>=2 and n['num_chans']<=5 \
53+
# and n['capacity']<=0.2*1e11 and n['capacity']>=0.1*1e11
54+
#
55+
# all_big = [n for n in all_nodes if big_node(n)]
56+
# all_small = [n for n in all_nodes if small_node(n)]
57+
58+
all_nodes.sort(key=lambda n: n["capacity"])
59+
print(all_nodes[:10])
60+
61+
N = len(all_nodes)
62+
all_small = all_nodes[int(0.10*N): int(0.35 * N)]
63+
all_big = all_nodes[int(0.65*N): int(0.90*N)]
64+
65+
print("big nodes:", len(all_big))
66+
print("small nodes:", len(all_small))
67+
68+
# cts.sort()
69+
# min_val = cts[0]
70+
# max_val = cts[-1]
71+
# freq = np.zeros(max_val+1, dtype=int)
72+
# for i in cts:
73+
# freq[i] += 1
74+
# print(list(freq))
75+
# plt.hist(cts, bins=20, range=(10, 100))
76+
# plt.savefig('foo.png')
77+
78+
random.seed(42)
79+
amounts = [100, 1000, 10000, 100000, 1000000]
80+
num_samples = 100
81+
datapoints = []
82+
83+
def routes_fee(routes):
84+
pay = 0
85+
deliver = 0
86+
for r in routes["routes"]:
87+
deliver += r["amount_msat"]
88+
pay += r["path"][0]["amount_msat"]
89+
return pay - deliver
90+
91+
def run_sim(node_set, amt_msat, repeat, version, sample_name, data):
92+
for _ in range(repeat):
93+
# 0.5% or 5sat is the norm
94+
MAX_FEE = max(amt_msat // 200, 5000)
95+
src_index = random.randint(0, len(node_set)-1)
96+
dst_index = src_index
97+
while dst_index==src_index:
98+
dst_index = random.randint(0, len(node_set)-1)
99+
try:
100+
resp = l1.rpc.getroutes(source=nodeids[src_index],
101+
destination=nodeids[dst_index],
102+
amount_msat=amt_msat,
103+
layers=[],
104+
maxfee_msat=MAX_FEE,
105+
final_cltv=18)
106+
success = True
107+
except RpcError as e:
108+
success = False
109+
resp = e.error
110+
line = l1.daemon.wait_for_log(
111+
"plugin-cln-askrene.*notify msg.*get_routes (completed|failed)")
112+
runtime = int(line.split()[-2])
113+
this_data = {"runtime_msec": runtime, "amount_msat": amt_msat,
114+
"version": version,
115+
"sample": sample_name, "success": success}
116+
if success:
117+
this_data["probability"] = resp["probability_ppm"] * 1e-6
118+
this_data["fee_msat"] = routes_fee(resp)
119+
else:
120+
this_data["probability"] = 0.0
121+
this_data["fee_msat"] = 0
122+
print(resp)
123+
data.append(this_data)
124+
for amt_sat in amounts:
125+
run_sim(all_big, amt_sat*1000, num_samples, "default", "big", datapoints)
126+
run_sim(all_small, amt_sat*1000, num_samples, "default", "small", datapoints)
127+
with open("default_bench.json", "w") as fd:
128+
json.dump(datapoints, fd)

0 commit comments

Comments
 (0)