Skip to content

Commit ddc9331

Browse files
committed
allow undefined channel policy
1 parent 41a3643 commit ddc9331

File tree

4 files changed

+132
-42
lines changed

4 files changed

+132
-42
lines changed

.github/workflows/test.yml

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ jobs:
4444
- dag_connection_test.py
4545
- graph_test.py
4646
- logging_test.py
47+
- ln_basic_test.py
4748
- ln_test.py
4849
- rpc_test.py
4950
- services_test.py

resources/scenarios/ln_init.py

+5
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,11 @@ def matching_graph(self, expected, ln):
369369
# We assert this because it isn't updated as part of policy.
370370
# If this fails we have a bigger issue
371371
assert int(actual_ch["capacity"]) == capacity
372+
373+
# Policies were not defined in network.yaml
374+
if "source_policy" not in expected_ch or "target_policy" not in expected_ch:
375+
continue
376+
372377
# policy actual/expected source/target
373378
polas = Policy.from_lnd_describegraph(actual_ch["node1_policy"])
374379
polat = Policy.from_lnd_describegraph(actual_ch["node2_policy"])

resources/scenarios/test_scenarios/ln_basic.py

-42
This file was deleted.

test/ln_basic_test.py

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#!/usr/bin/env python3
2+
3+
import json
4+
import os
5+
from pathlib import Path
6+
from time import sleep
7+
8+
from test_base import TestBase
9+
10+
from warnet.process import stream_command
11+
12+
13+
class LNBasicTest(TestBase):
14+
def __init__(self):
15+
super().__init__()
16+
self.network_dir = Path(os.path.dirname(__file__)) / "data" / "ln"
17+
self.scen_dir = Path(os.path.dirname(__file__)).parent / "resources" / "scenarios"
18+
self.lns = [
19+
"tank-0000-ln",
20+
"tank-0001-ln",
21+
"tank-0002-ln",
22+
"tank-0003-ln",
23+
"tank-0004-ln",
24+
"tank-0005-ln",
25+
]
26+
27+
def run_test(self):
28+
try:
29+
# Wait for all nodes to wake up. ln_init will start automatically
30+
self.setup_network()
31+
32+
# Send a payment across channels opened automatically by ln_init
33+
self.pay_invoice(sender="tank-0005-ln", recipient="tank-0003-ln")
34+
35+
# Manually open two more channels between first three nodes
36+
# and send a payment using warnet RPC
37+
self.manual_open_channels()
38+
self.wait_for_gossip_sync(self.lns[:3], 2 + 2)
39+
self.pay_invoice(sender="tank-0000-ln", recipient="tank-0002-ln")
40+
41+
finally:
42+
self.cleanup()
43+
44+
def setup_network(self):
45+
self.log.info("Setting up network")
46+
stream_command(f"warnet deploy {self.network_dir}")
47+
48+
def fund_wallets(self):
49+
outputs = ""
50+
for lnd in self.lns:
51+
addr = json.loads(self.warnet(f"ln rpc {lnd} newaddress p2wkh"))["address"]
52+
outputs += f',"{addr}":10'
53+
# trim first comma
54+
outputs = outputs[1:]
55+
56+
self.warnet("bitcoin rpc tank-0000 sendmany '' '{" + outputs + "}'")
57+
self.warnet("bitcoin rpc tank-0000 -generate 1")
58+
59+
def wait_for_two_txs(self):
60+
self.wait_for_predicate(
61+
lambda: json.loads(self.warnet("bitcoin rpc tank-0000 getmempoolinfo"))["size"] == 2
62+
)
63+
64+
def manual_open_channels(self):
65+
# 0 -> 1 -> 2
66+
pk1 = self.warnet("ln pubkey tank-0001-ln")
67+
pk2 = self.warnet("ln pubkey tank-0002-ln")
68+
69+
host1 = ""
70+
host2 = ""
71+
72+
while not host1 or not host2:
73+
if not host1:
74+
host1 = self.warnet("ln host tank-0001-ln")
75+
if not host2:
76+
host2 = self.warnet("ln host tank-0002-ln")
77+
sleep(1)
78+
79+
print(
80+
self.warnet(
81+
f"ln rpc tank-0000-ln openchannel --node_key {pk1} --local_amt 100000 --connect {host1}"
82+
)
83+
)
84+
print(
85+
self.warnet(
86+
f"ln rpc tank-0001-ln openchannel --node_key {pk2} --local_amt 100000 --connect {host2}"
87+
)
88+
)
89+
90+
self.wait_for_two_txs()
91+
92+
self.warnet("bitcoin rpc tank-0000 -generate 10")
93+
94+
def wait_for_gossip_sync(self, nodes, expected):
95+
while len(nodes) > 0:
96+
for node in nodes:
97+
chs = json.loads(self.warnet(f"ln rpc {node} describegraph"))["edges"]
98+
if len(chs) >= expected:
99+
nodes.remove(node)
100+
sleep(1)
101+
102+
def pay_invoice(self, sender: str, recipient: str):
103+
init_balance = int(json.loads(self.warnet(f"ln rpc {recipient} channelbalance"))["balance"])
104+
inv = json.loads(self.warnet(f"ln rpc {recipient} addinvoice --amt 1000"))
105+
print(inv)
106+
print(self.warnet(f"ln rpc {sender} payinvoice -f {inv['payment_request']}"))
107+
108+
def wait_for_success():
109+
return (
110+
int(json.loads(self.warnet(f"ln rpc {recipient} channelbalance"))["balance"])
111+
== init_balance + 1000
112+
)
113+
114+
self.wait_for_predicate(wait_for_success)
115+
116+
def scenario_open_channels(self):
117+
# 2 -> 3
118+
# connecting all six ln nodes in the graph
119+
scenario_file = self.scen_dir / "test_scenarios" / "ln_init.py"
120+
self.log.info(f"Running scenario from: {scenario_file}")
121+
self.warnet(f"run {scenario_file} --source_dir={self.scen_dir} --debug")
122+
123+
124+
if __name__ == "__main__":
125+
test = LNBasicTest()
126+
test.run_test()

0 commit comments

Comments
 (0)