1from pyln.client import Gossmap, GossmapNode, GossmapNodeId
2
3import os.path
4import lzma
5
6
7def unxz_data_tmp(src, tmp_path, dst, wmode):
8    fulldst = os.path.join(tmp_path, dst)
9    with open(fulldst, wmode) as out:
10        with lzma.open(os.path.join(os.path.dirname(__file__), "data", src), "rb")as f:
11            out.write(f.read())
12    return fulldst
13
14
15def test_gossmap(tmp_path):
16    sfile = unxz_data_tmp("gossip_store-part1.xz", tmp_path, "gossip_store", "xb")
17    g = Gossmap(sfile)
18
19    chans = len(g.channels)
20    nodes = len(g.nodes)
21
22    g.refresh()
23    assert chans == len(g.channels)
24    assert nodes == len(g.nodes)
25
26    # Now append.
27    unxz_data_tmp("gossip_store-part2.xz", tmp_path, "gossip_store", "ab")
28
29    g.refresh()
30
31    # This actually deletes a channel, which deletes a node.
32    assert g.get_channel("686386x1093x1") is None
33    assert g.get_node('029deaf9d2fba868fe0a124050f0a13e021519a12f41bea34f391fe7533fb3166d') is None
34    # The other node is untouched
35    assert g.get_node('02e0af3c70bf42343316513e54683b10c01d906c04a05dfcd9479b90d7beed9129')
36
37    # It will notice the new ones.
38    assert chans < len(g.channels)
39    assert nodes < len(g.nodes)
40
41    # Whole load at the same time gives the same results.
42    g2 = Gossmap(sfile)
43    assert set(g.channels.keys()) == set(g2.channels.keys())
44    assert set(g.nodes.keys()) == set(g2.nodes.keys())
45
46    # Check some details
47    channel2 = g.get_channel("686200x1137x0")
48    assert g.get_channel("686386x1093x1") is None
49    assert channel2.satoshis == 3000000
50
51
52def test_gossmap_halfchannel(tmp_path):
53    """ this test a simple [l1->l2] gossip store that was created by the pyln-testing framework """
54    sfile = unxz_data_tmp("gossip_store.simple.xz", tmp_path, "gossip_store", "xb")
55    g = Gossmap(sfile)
56
57    l1id = "022d223620a359a47ff7f7ac447c85c46c923da53389221a0054c11c1e3ca31d59"
58    l2id = "0266e4598d1d3c415f572a8488830b60f7e744ed9235eb0b1ba93283b315c03518"
59
60    # check structure parsed correctly
61    assert(len(g.nodes) == 2)
62    n1 = g.get_node(l1id)
63    n2 = g.get_node(l2id)
64    assert n1
65    assert n2
66
67    chan = g.get_channel("103x1x1")
68    assert chan
69    assert chan.node1 == n1
70    assert chan.node2 == n2
71
72    half0 = chan.get_direction(0)
73    half1 = chan.get_direction(1)
74    assert half0
75    assert half1
76    assert half0.direction == 0
77    assert half1.direction == 1
78    assert half0.channel == chan
79    assert half1.channel == chan
80    assert half0.source == n1
81    assert half0.destination == n2
82    assert half1.source == n2
83    assert half1.destination == n1
84
85    # check metadata
86    assert half0.timestamp == 1631005020
87    assert half1.timestamp == 1631005020
88    assert half0.cltv_expiry_delta == 6
89    assert half1.cltv_expiry_delta == 6
90    assert half0.htlc_minimum_msat == 0
91    assert half1.htlc_minimum_msat == 0
92    assert half0.htlc_maximum_msat == 990000000
93    assert half1.htlc_maximum_msat == 990000000
94    assert half0.fee_base_msat == 1
95    assert half1.fee_base_msat == 1
96    assert half0.fee_proportional_millionths == 10
97
98
99def test_objects():
100    boltz = "026165850492521f4ac8abd9bd8088123446d126f648ca35e60f88177dc149ceb2"
101    acinq = "03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f"
102
103    boltz_id = GossmapNodeId(bytes.fromhex(boltz))
104    acinq_id = GossmapNodeId(bytes.fromhex(acinq))
105    assert boltz_id == GossmapNodeId(boltz)
106
107    assert boltz_id < acinq_id
108    assert acinq_id > boltz_id
109    assert boltz_id != acinq_id
110    assert acinq_id != boltz_id
111    assert not boltz_id > acinq_id
112    assert not acinq_id < boltz_id
113    assert not boltz_id == acinq_id
114    assert not acinq_id == boltz_id
115
116    boltz_node = GossmapNode(boltz_id)
117    acinq_node = GossmapNode(acinq_id)
118    assert boltz_node == GossmapNode(boltz)
119    assert boltz_node < acinq_node
120    assert acinq_node > boltz_node
121    assert boltz_node != acinq_node
122