Skip to content

Commit 30130eb

Browse files
authored
Merge pull request #741 from pinheadmz/cln-taproot
Use taproot outputs to fund lightning channels
2 parents 455222c + 8a1cf1e commit 30130eb

File tree

5 files changed

+62
-30
lines changed

5 files changed

+62
-30
lines changed

resources/charts/bitcoincore/charts/cln/templates/pod.yaml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,7 @@ spec:
4040
command:
4141
- /bin/sh
4242
- -c
43-
- |
44-
lightningd --conf=/root/.lightning/config &
45-
sleep 1
46-
lightning-cli createrune > /working/rune.json
47-
echo "Here is the rune file contents"
48-
cat /working/rune.json
49-
wait
43+
- lightningd --conf=/root/.lightning/config
5044
livenessProbe:
5145
{{- toYaml .Values.livenessProbe | nindent 8 }}
5246
readinessProbe:

resources/charts/bitcoincore/charts/cln/values.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ readinessProbe:
7171
- "/bin/sh"
7272
- "-c"
7373
- "lightning-cli getinfo 2>/dev/null | grep -q 'id' || exit 1"
74+
startupProbe:
75+
failureThreshold: 10
76+
periodSeconds: 30
77+
successThreshold: 1
78+
timeoutSeconds: 60
79+
exec:
80+
command:
81+
- "/bin/sh"
82+
- "-c"
83+
- "lightning-cli createrune > /working/rune.json"
7484

7585
# Additional volumes on the output Deployment definition.
7686
volumes:

resources/scenarios/ln_framework/ln.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def __init__(self, pod_name, ip_address):
161161

162162
def reset_connection(self):
163163
self.conn = http.client.HTTPSConnection(
164-
host=self.name, port=3010, timeout=5, context=INSECURE_CONTEXT
164+
host=self.name, port=3010, timeout=60, context=INSECURE_CONTEXT
165165
)
166166

167167
def setRune(self, rune):
@@ -185,7 +185,6 @@ def post(self, uri, data=None):
185185
post_header["Content-Length"] = str(len(body))
186186
post_header["Content-Type"] = "application/json"
187187
self.reset_connection()
188-
self.log.info(f"CLN POST headers: {post_header}")
189188
self.conn.request(
190189
method="POST",
191190
url=uri,
@@ -220,9 +219,11 @@ def createrune(self):
220219

221220
def newaddress(self):
222221
self.createrune()
223-
response = self.post("/v1/newaddr")
222+
response = self.post("/v1/newaddr", data={"addresstype": "p2tr"})
224223
res = json.loads(response)
225-
return res["bech32"]
224+
if "p2tr" in res:
225+
return res["p2tr"]
226+
raise Exception(res)
226227

227228
def uri(self):
228229
res = json.loads(self.post("/v1/getinfo"))
@@ -298,7 +299,7 @@ def __init__(self, pod_name, ip_address, admin_macaroon_hex):
298299

299300
def reset_connection(self):
300301
self.conn = http.client.HTTPSConnection(
301-
host=self.name, port=8080, timeout=5, context=INSECURE_CONTEXT
302+
host=self.name, port=8080, timeout=60, context=INSECURE_CONTEXT
302303
)
303304

304305
def get(self, uri):
@@ -337,9 +338,14 @@ def post(self, uri, data):
337338
return stream
338339

339340
def newaddress(self):
340-
response = self.get("/v1/newaddress")
341+
# Taproot signatures are a fixed length which improves
342+
# the accuracy of fee estimation, and therefore our
343+
# channel ID determinism.
344+
response = self.get("/v1/newaddress?type=TAPROOT_PUBKEY")
341345
res = json.loads(response)
342-
return res["address"]
346+
if "address" in res:
347+
return res["address"]
348+
raise Exception(res)
343349

344350
def walletbalance(self) -> int:
345351
res = self.get("/v1/balance/blockchain")

test/data/ln/network.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ nodes:
22
- name: tank-0000
33
addnode:
44
- tank-0001
5+
ln:
6+
lnd: false
7+
cln: true
58
- name: tank-0001
69
addnode:
710
- tank-0002

test/ln_basic_test.py

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -61,28 +61,24 @@ def test_admin_macaroons(self):
6161
# These tanks all use the same default macaroon root key, meaning the macaroons
6262
# generated at ~/.lnd/.../admin.macaroon in each lnd container are authorized
6363
# to make requests to each other.
64-
info = json.loads(
65-
self.warnet("ln rpc tank-0000-ln --rpcserver=tank-0001-ln.default:10009 getinfo")
66-
)
67-
info["alias"] = "tank-0001-ln"
6864
info = json.loads(
6965
self.warnet("ln rpc tank-0001-ln --rpcserver=tank-0002-ln.default:10009 getinfo")
7066
)
71-
info["alias"] = "tank-0002-ln"
67+
assert info["alias"] == "tank-0002-ln"
7268
info = json.loads(
7369
self.warnet("ln rpc tank-0002-ln --rpcserver=tank-0005-ln.default:10009 getinfo")
7470
)
75-
info["alias"] = "tank-0005-ln"
71+
assert info["alias"] == "tank-0005-ln"
7672

7773
self.log.info("Testing lnd nodes with unique macaroon root key can NOT query each other")
7874
# These tanks are configured with unique macaroon root keys
7975
try:
80-
self.warnet("ln rpc tank-0000-ln --rpcserver=tank-0003-ln.default:10009 getinfo")
76+
self.warnet("ln rpc tank-0001-ln --rpcserver=tank-0003-ln.default:10009 getinfo")
8177
raise AssertionError("That should not have worked!")
8278
except Exception as e:
8379
assert "verification failed: signature mismatch after caveat verification" in str(e)
8480
try:
85-
self.warnet("ln rpc tank-0000-ln --rpcserver=tank-0004-ln.default:10009 getinfo")
81+
self.warnet("ln rpc tank-0001-ln --rpcserver=tank-0004-ln.default:10009 getinfo")
8682
raise AssertionError("That should not have worked!")
8783
except Exception as e:
8884
assert "verification failed: signature mismatch after caveat verification" in str(e)
@@ -94,13 +90,27 @@ def test_admin_macaroons(self):
9490

9591
def fund_wallets(self):
9692
for ln in self.lns:
97-
addr = json.loads(self.warnet(f"ln rpc {ln} newaddress p2wkh"))["address"]
93+
if ln == "tank-0000-ln":
94+
# cln
95+
addr = json.loads(self.warnet(f"ln rpc {ln} newaddr p2tr"))["p2tr"]
96+
else:
97+
# lnd
98+
addr = json.loads(self.warnet(f"ln rpc {ln} newaddress p2tr"))["address"]
9899
self.warnet(f"bitcoin rpc tank-0000 sendtoaddress {addr} 10")
99100
self.wait_for_predicate(
100101
lambda: json.loads(self.warnet("bitcoin rpc tank-0000 getmempoolinfo"))["size"]
101102
== len(self.lns)
102103
)
103104
self.warnet("bitcoin rpc tank-0000 -generate 1")
105+
# cln takes a long time to register its own balance?
106+
self.wait_for_predicate(
107+
lambda: len(
108+
json.loads(self.warnet("ln rpc tank-0000-ln bkpr-listbalances"))["accounts"][0][
109+
"balances"
110+
]
111+
)
112+
> 0
113+
)
104114

105115
def manual_open_channels(self):
106116
self.fund_wallets()
@@ -118,11 +128,9 @@ def manual_open_channels(self):
118128
host2 = self.warnet("ln host tank-0002-ln")
119129
sleep(1)
120130

121-
print(
122-
self.warnet(
123-
f"ln rpc tank-0000-ln openchannel --node_key {pk1} --local_amt 100000 --connect {host1}"
124-
)
125-
)
131+
print(self.warnet(f"ln rpc tank-0000-ln connect {pk1} {host1}"))
132+
print(self.warnet(f"ln rpc tank-0000-ln fundchannel {pk1} 100000"))
133+
126134
print(
127135
self.warnet(
128136
f"ln rpc tank-0001-ln openchannel --node_key {pk2} --local_amt 100000 --connect {host2}"
@@ -138,7 +146,13 @@ def manual_open_channels(self):
138146
def wait_for_gossip_sync(self, nodes, expected):
139147
while len(nodes) > 0:
140148
for node in nodes:
141-
chs = json.loads(self.warnet(f"ln rpc {node} describegraph"))["edges"]
149+
if node == "tank-0000-ln":
150+
# cln
151+
chs = json.loads(self.warnet(f"ln rpc {node} listchannels"))["channels"]
152+
chs = [ch for ch in chs if ch["direction"] == 1]
153+
else:
154+
# lnd
155+
chs = json.loads(self.warnet(f"ln rpc {node} describegraph"))["edges"]
142156
if len(chs) >= expected:
143157
nodes.remove(node)
144158
sleep(1)
@@ -147,7 +161,12 @@ def pay_invoice(self, sender: str, recipient: str):
147161
init_balance = int(json.loads(self.warnet(f"ln rpc {recipient} channelbalance"))["balance"])
148162
inv = json.loads(self.warnet(f"ln rpc {recipient} addinvoice --amt 1000"))
149163
print(inv)
150-
print(self.warnet(f"ln rpc {sender} payinvoice -f {inv['payment_request']}"))
164+
if sender == "tank-0000-ln":
165+
# cln
166+
print(self.warnet(f"ln rpc {sender} pay {inv['payment_request']}"))
167+
else:
168+
# lnd
169+
print(self.warnet(f"ln rpc {sender} payinvoice -f {inv['payment_request']}"))
151170

152171
def wait_for_success():
153172
return (

0 commit comments

Comments
 (0)