Skip to content

Commit 3d846d3

Browse files
committed
address comments
reduce ln_init changes start migration of CLN to REST
1 parent 10531d5 commit 3d846d3

File tree

12 files changed

+131
-185
lines changed

12 files changed

+131
-185
lines changed

.github/workflows/test.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ jobs:
4141
- graph_test.py
4242
- logging_test.py
4343
- ln_basic_test.py
44-
- ln_mixed_test.py
4544
- ln_test.py
4645
- rpc_test.py
4746
- services_test.py

resources/charts/bitcoincore/charts/cln/templates/_helpers.tpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ If release name contains chart name it will be used as a full name.
2323
Expand the name of the chart.
2424
*/}}
2525
{{- define "cln.name" -}}
26-
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
26+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}-ln
2727
{{- end }}
2828

2929
{{/*
@@ -35,7 +35,7 @@ If release name contains chart name it will be used as a full name.
3535
{{- if .Values.fullnameOverride }}
3636
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
3737
{{- else }}
38-
{{- printf "%s-ln" .Release.Name | trunc 63 | trimSuffix "-" }}
38+
{{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" }}-ln
3939
{{- end }}
4040
{{- end }}
4141

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ data:
2020
bitcoin-retry-timeout=600
2121
grpc-port={{ .Values.RPCPort }}
2222
grpc-host=0.0.0.0
23+
clnrest-host=0.0.0.0
24+
clnrest-port=3010
2325
---
2426
apiVersion: v1
2527
kind: ConfigMap

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@ spec:
3434
- name: rpc
3535
containerPort: {{ .Values.RPCPort }}
3636
protocol: TCP
37+
- name: rest
38+
containerPort: {{ .Values.RestPort }}
39+
protocol: TCP
3740
command:
3841
- /bin/sh
3942
- -c

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,9 @@ spec:
1616
targetPort: rpc
1717
protocol: TCP
1818
name: rpc
19+
- port: {{ .Values.RestPort }}
20+
targetPort: rest
21+
protocol: TCP
22+
name: rest
1923
selector:
2024
{{- include "cln.selectorLabels" . | nindent 4 }}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ service:
3333

3434
P2PPort: 9735
3535
RPCPort: 9736
36+
RestPort: 3010
3637

3738
# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/
3839
ingress:

resources/charts/bitcoincore/charts/lnd/templates/_helpers.tpl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ If release name contains chart name it will be used as a full name.
2323
Expand the name of the chart.
2424
*/}}
2525
{{- define "lnd.name" -}}
26-
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
26+
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}-ln
2727
{{- end }}
2828

2929
{{/*
@@ -35,7 +35,7 @@ If release name contains chart name it will be used as a full name.
3535
{{- if .Values.fullnameOverride }}
3636
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
3737
{{- else }}
38-
{{- printf "%s-ln" .Release.Name | trunc 63 | trimSuffix "-" }}
38+
{{- printf "%s" .Release.Name | trunc 63 | trimSuffix "-" }}-ln
3939
{{- end }}
4040
{{- end }}
4141

resources/plugins/simln/charts/simln/values.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@ image:
44
tag: "0.2.3"
55
pullPolicy: IfNotPresent
66

7-
restartPolicy: Never
8-
97
workingVolume:
108
name: working-volume
119
mountPath: /working

resources/scenarios/commander.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,6 @@ def setup(self):
228228
self.tanks[tank["tank"]] = node
229229

230230
for ln in WARNET["lightning"]:
231-
ln.setLogger(self.log)
232231
self.lns[ln.name] = ln
233232

234233
self.num_nodes = len(self.nodes)

resources/scenarios/ln_framework/ln.py

Lines changed: 102 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import base64
22
import http.client
33
import json
4+
import logging
45
import os
56
import ssl
67
from abc import ABC, abstractmethod
@@ -112,12 +113,14 @@ def to_lnd_chanpolicy(self, capacity):
112113

113114
class LNNode(ABC):
114115
@abstractmethod
115-
def __init__(self, pod_name, logger=None):
116-
self.log = logger
116+
def __init__(self, pod_name):
117117
self.name = pod_name
118-
119-
def setLogger(self, logger):
120-
self.log = logger
118+
self.log = logging.getLogger(pod_name)
119+
handler = logging.StreamHandler()
120+
formatter = logging.Formatter(f'%(name)-8s - %(levelname)s: %(message)s')
121+
handler.setFormatter(formatter)
122+
self.log.addHandler(handler)
123+
self.log.setLevel(logging.INFO)
121124

122125
@staticmethod
123126
def param_dict_to_list(params: dict) -> list[str]:
@@ -164,11 +167,78 @@ def update(self, txid_hex: str, policy: dict, capacity: int) -> dict:
164167

165168

166169
class CLN(LNNode):
167-
def __init__(self, pod_name, logger=None):
168-
super().__init__(pod_name, logger)
170+
def __init__(self, pod_name):
171+
super().__init__(pod_name)
172+
self.conn = http.client.HTTPSConnection(
173+
host=pod_name, port=8080, timeout=5, context=INSECURE_CONTEXT
174+
)
169175
self.headers = {}
170176
self.impl = "cln"
171177

178+
def reset_connection(self):
179+
self.conn = http.client.HTTPSConnection(
180+
host=self.name, port=3010, timeout=5, context=INSECURE_CONTEXT
181+
)
182+
183+
def setRune(self, rune):
184+
self.headers = {
185+
"Rune": rune
186+
}
187+
188+
def get(self, uri):
189+
attempt = 0
190+
while True:
191+
try:
192+
self.log.warning(f"headers: {self.headers}")
193+
self.conn.request(
194+
method="GET",
195+
url=uri,
196+
headers=self.headers,
197+
)
198+
return self.conn.getresponse().read().decode("utf8")
199+
except Exception as e:
200+
self.reset_connection()
201+
attempt += 1
202+
if attempt > 5:
203+
self.log.error(f"Error CLN GET, Abort: {e}")
204+
return None
205+
sleep(1)
206+
207+
def post(self, uri, data={}):
208+
body = json.dumps(data)
209+
post_header = self.headers
210+
post_header["Content-Length"] = str(len(body))
211+
post_header["Content-Type"] = "application/json"
212+
attempt = 0
213+
while True:
214+
try:
215+
self.conn.request(
216+
method="POST",
217+
url=uri,
218+
body=body,
219+
headers=post_header,
220+
)
221+
# Stream output, otherwise we get a timeout error
222+
res = self.conn.getresponse()
223+
stream = ""
224+
while True:
225+
try:
226+
data = res.read(1)
227+
if len(data) == 0:
228+
break
229+
else:
230+
stream += data.decode("utf8")
231+
except Exception:
232+
break
233+
return stream
234+
except Exception as e:
235+
self.reset_connection()
236+
attempt += 1
237+
if attempt > 5:
238+
self.log.error(f"Error CLN POST, Abort: {e}")
239+
return None
240+
sleep(1)
241+
172242
def rpc(
173243
self,
174244
method: str,
@@ -191,12 +261,26 @@ def rpc(
191261
self.log.error(f"CLN rpc error: {e}, wait and retry...")
192262
sleep(2)
193263
return None
264+
265+
def createrune(self, max_tries=2):
266+
attempt = 0
267+
while attempt < max_tries:
268+
attempt += 1
269+
response = self.rpc("createrune")
270+
if not response:
271+
sleep(2)
272+
continue
273+
res = json.loads(response)
274+
self.setRune(res["rune"])
275+
return
276+
raise Exception(f"Unable to fetch rune from {self.name}")
194277

195278
def newaddress(self, max_tries=2):
279+
self.createrune()
196280
attempt = 0
197281
while attempt < max_tries:
198282
attempt += 1
199-
response = self.rpc("newaddr")
283+
response = self.post("/v1/newaddr")
200284
if not response:
201285
sleep(2)
202286
continue
@@ -211,7 +295,7 @@ def newaddress(self, max_tries=2):
211295
return False, ""
212296

213297
def uri(self):
214-
res = json.loads(self.rpc("getinfo"))
298+
res = json.loads(self.post("/v1/getinfo"))
215299
if len(res["address"]) < 1:
216300
return None
217301
return f"{res['id']}@{res['address'][0]['address']}:{res['address'][0]['port']}"
@@ -220,7 +304,7 @@ def walletbalance(self, max_tries=2) -> int:
220304
attempt = 0
221305
while attempt < max_tries:
222306
attempt += 1
223-
response = self.rpc("listfunds")
307+
response = self.post("/v1/listfunds")
224308
if not response:
225309
sleep(2)
226310
continue
@@ -232,7 +316,7 @@ def channelbalance(self, max_tries=2) -> int:
232316
attempt = 0
233317
while attempt < max_tries:
234318
attempt += 1
235-
response = self.rpc("listfunds")
319+
response = self.post("/v1/listfunds")
236320
if not response:
237321
sleep(2)
238322
continue
@@ -244,7 +328,7 @@ def connect(self, target_uri, max_tries=5) -> dict:
244328
attempt = 0
245329
while attempt < max_tries:
246330
attempt += 1
247-
response = self.rpc("connect", [target_uri])
331+
response = self.post("/v1/connect", {"id": target_uri})
248332
if response:
249333
res = json.loads(response)
250334
if "id" in res:
@@ -269,7 +353,7 @@ def channel(self, pk, capacity, push_amt, fee_rate, max_tries=5) -> dict:
269353
attempt = 0
270354
while attempt < max_tries:
271355
attempt += 1
272-
response = self.rpc("fundchannel", self.param_dict_to_list(data))
356+
response = self.post("/v1/fundchannel", data)
273357
if response:
274358
res = json.loads(response)
275359
if "txid" in res:
@@ -283,14 +367,14 @@ def channel(self, pk, capacity, push_amt, fee_rate, max_tries=5) -> dict:
283367
return None
284368

285369
def createinvoice(self, sats, label, description="new invoice") -> str:
286-
response = self.rpc("invoice", [sats * 1000, label, description])
370+
response = self.post("invoice", {"amount_msat": sats * 1000, "label": label, "description": description})
287371
if response:
288372
res = json.loads(response)
289373
return res["bolt11"]
290374
return None
291375

292376
def payinvoice(self, payment_request) -> str:
293-
response = self.rpc("pay", [payment_request])
377+
response = self.rpc("pay", {"bolt11": payment_request})
294378
if response:
295379
res = json.loads(response)
296380
if "code" in res:
@@ -303,7 +387,7 @@ def graph(self, max_tries=2) -> dict:
303387
attempt = 0
304388
while attempt < max_tries:
305389
attempt += 1
306-
response = self.rpc("listchannels")
390+
response = self.post("/v1/listchannels")
307391
if response:
308392
res = json.loads(response)
309393
if "channels" in res:
@@ -329,8 +413,8 @@ def update(self, txid_hex: str, policy: dict, capacity: int, max_tries=2) -> dic
329413

330414

331415
class LND(LNNode):
332-
def __init__(self, pod_name, logger=None):
333-
super().__init__(pod_name, logger)
416+
def __init__(self, pod_name):
417+
super().__init__(pod_name)
334418
self.conn = http.client.HTTPSConnection(
335419
host=pod_name, port=8080, timeout=5, context=INSECURE_CONTEXT
336420
)

0 commit comments

Comments
 (0)