1111import ssl
1212import sys
1313import tempfile
14+ import time
1415from typing import Dict
1516
1617from kubernetes import client , config
5556 "rpc_port" : int (pod .metadata .labels ["RPCPort" ]),
5657 "rpc_user" : "user" ,
5758 "rpc_password" : pod .metadata .labels ["rpcpassword" ],
59+ "init_peers" : pod .metadata .annotations ["init_peers" ]
5860 }
5961 )
6062
@@ -82,41 +84,106 @@ def auth_proxy_request(self, method, path, postdata):
8284
8385class LND :
8486 def __init__ (self , pod_name ):
87+ self .name = pod_name
8588 self .conn = http .client .HTTPSConnection (
8689 host = pod_name , port = 8080 , timeout = 5 , context = INSECURE_CONTEXT
8790 )
8891
8992 def get (self , uri ):
90- self .conn .request (
91- method = "GET" , url = uri , headers = {"Grpc-Metadata-macaroon" : ADMIN_MACAROON_HEX }
92- )
93- return self .conn .getresponse ().read ().decode ("utf8" )
93+ while True :
94+ try :
95+ self .conn .request (
96+ method = "GET" ,
97+ url = uri ,
98+ headers = {
99+ "Grpc-Metadata-macaroon" : ADMIN_MACAROON_HEX ,
100+ "Connection" : "close"
101+ }
102+ )
103+ return self .conn .getresponse ().read ().decode ("utf8" )
104+ except Exception :
105+ time .sleep (1 )
94106
95107 def post (self , uri , data ):
96108 body = json .dumps (data )
97- self .conn .request (
98- method = "POST" ,
99- url = uri ,
100- body = body ,
101- headers = {
102- "Content-Type" : "application/json" ,
103- "Content-Length" : str (len (body )),
104- "Grpc-Metadata-macaroon" : ADMIN_MACAROON_HEX ,
105- },
106- )
107- # Stream output, otherwise we get a timeout error
108- res = self .conn .getresponse ()
109- stream = ""
109+ attempt = 0
110110 while True :
111+ attempt += 1
111112 try :
112- data = res .read (1 )
113- if len (data ) == 0 :
114- break
115- else :
116- stream += data .decode ("utf8" )
113+ self .conn .request (
114+ method = "POST" ,
115+ url = uri ,
116+ body = body ,
117+ headers = {
118+ "Content-Type" : "application/json" ,
119+ "Content-Length" : str (len (body )),
120+ "Grpc-Metadata-macaroon" : ADMIN_MACAROON_HEX ,
121+ "Connection" : "close"
122+ },
123+ )
124+ # Stream output, otherwise we get a timeout error
125+ res = self .conn .getresponse ()
126+ stream = ""
127+ while True :
128+ try :
129+ data = res .read (1 )
130+ if len (data ) == 0 :
131+ break
132+ else :
133+ stream += data .decode ("utf8" )
134+ except Exception :
135+ break
136+ return stream
117137 except Exception :
118- break
119- return stream
138+ time .sleep (1 )
139+
140+ def newaddress (self ):
141+ res = self .get (
142+ "/v1/newaddress"
143+ )
144+ return json .loads (res )
145+
146+ def walletbalance (self ):
147+ res = self .get (
148+ "/v1/balance/blockchain"
149+ )
150+ return int (json .loads (res )["confirmed_balance" ])
151+
152+ def uri (self ):
153+ res = self .get (
154+ "/v1/getinfo"
155+ )
156+ info = json .loads (res )
157+ if "uris" not in info or len (info ["uris" ]) == 0 :
158+ return None
159+ return info ["uris" ][0 ]
160+
161+ def connect (self , target_uri ):
162+ pk , host = target_uri .split ("@" )
163+ res = self .post (
164+ "/v1/peers" ,
165+ data = {
166+ "addr" : {
167+ "pubkey" : pk ,
168+ "host" : host
169+ }
170+ }
171+ )
172+ return json .loads (res )
173+
174+ def channel (self , pk , local_amt , push_amt , fee_rate ):
175+ res = self .post (
176+ "/v1/channels/stream" ,
177+ data = {
178+ "local_funding_amount" : local_amt ,
179+ "push_sat" : push_amt ,
180+ "node_pubkey" : pk ,
181+ "sat_per_vbyte" : fee_rate
182+ }
183+ )
184+ return json .loads (res )
185+
186+
120187
121188
122189class Commander (BitcoinTestFramework ):
@@ -139,6 +206,13 @@ def ensure_miner(node):
139206 def hex_to_b64 (hex ):
140207 return base64 .b64encode (bytes .fromhex (hex )).decode ()
141208
209+ @staticmethod
210+ def b64_to_hex (b64 , reverse = False ):
211+ if reverse :
212+ return base64 .b64decode (b64 )[::- 1 ].hex ()
213+ else :
214+ return base64 .b64decode (b64 ).hex ()
215+
142216 def handle_sigterm (self , signum , frame ):
143217 print ("SIGTERM received, stopping..." )
144218 self .shutdown ()
@@ -193,6 +267,7 @@ def setup(self):
193267 coveragedir = self .options .coveragedir ,
194268 )
195269 node .rpc_connected = True
270+ node .init_peers = int (tank ["init_peers" ])
196271
197272 self .nodes .append (node )
198273 self .tanks [tank ["tank" ]] = node
0 commit comments