@@ -30,6 +30,7 @@ def __init__(
3030 data_folder = "" ,
3131 ):
3232 self .nodes = {}
33+ # Dict is sth. like: {'nigiri_regtest': <Node name=Nigiri regtest fullpath=...>, 'default': <Node name=Bitcoin Core fullpath=...>}
3334 self .data_folder = data_folder
3435 self ._active_node = active_node
3536 self .proxy_url = proxy_url
@@ -51,22 +52,23 @@ def load_from_disk(self, data_folder=None):
5152 # creating folders if they don't exist
5253 if not os .path .isdir (data_folder ):
5354 os .mkdir (data_folder )
54- nodes_files = load_jsons (self .data_folder , key = "name " )
55+ nodes_files = load_jsons (self .data_folder , key = "alias " )
5556 for node_alias in nodes_files :
5657 try :
57- self .nodes [
58- nodes_files [node_alias ]["name" ]
59- ] = PersistentObject .from_json (
58+ self .nodes [node_alias ] = PersistentObject .from_json (
6059 nodes_files [node_alias ],
6160 self ,
62- default_alias = node_alias ,
61+ default_alias = nodes_files [ node_alias ][ "alias" ] ,
6362 default_fullpath = calc_fullpath (self .data_folder , node_alias ),
6463 )
6564 except SpecterInternalException as e :
6665 logger .error (f"Skipping node { node_alias } due to { e } " )
6766
6867 if not self .nodes :
6968 if os .environ .get ("ELM_RPC_USER" ):
69+ logger .debug (
70+ "Creating an external Elements node with the initial configuration."
71+ )
7072 self .add_external_node (
7173 node_type = "ELM" ,
7274 name = "Blockstream Liquid" ,
@@ -79,7 +81,9 @@ def load_from_disk(self, data_folder=None):
7981 protocol = "http" ,
8082 default_alias = self .DEFAULT_ALIAS ,
8183 )
82- logger .info ("Creating initial node-configuration" )
84+ logger .debug (
85+ "Creating an external BTC node with the initial configuration."
86+ )
8387 self .add_external_node (
8488 node_type = "BTC" ,
8589 name = "Bitcoin Core" ,
@@ -93,46 +97,56 @@ def load_from_disk(self, data_folder=None):
9397 default_alias = self .DEFAULT_ALIAS ,
9498 )
9599
96- # Just to be sure here ....
100+ # Make sure we always have the default node
101+ # (needed for the rpc-as-pin-authentication used on Raspiblitz)
97102 has_default_node = False
98- for name , node in self .nodes .items ():
103+ for node in self .nodes .values ():
99104 if node .alias == self .DEFAULT_ALIAS :
100- return
101- # Make sure we always have a default node
102- # (needed for the rpc-as-pin-authentication, created and used for raspiblitz)
103- self .add_external_node (
104- node_type = "BTC" ,
105- name = "Bitcoin Core" ,
106- autodetect = True ,
107- datadir = get_default_datadir (),
108- user = "" ,
109- password = "" ,
110- port = 8332 ,
111- host = "localhost" ,
112- protocol = "http" ,
113- default_alias = self .DEFAULT_ALIAS ,
114- )
105+ has_default_node = True
106+ # Recreate the default node if it doesn't exist anymore
107+ if not has_default_node :
108+ logger .debug ("Recreating the default node." )
109+ self .add_external_node (
110+ node_type = "BTC" ,
111+ name = "Bitcoin Core" ,
112+ autodetect = True ,
113+ datadir = get_default_datadir (),
114+ user = "" ,
115+ password = "" ,
116+ port = 8332 ,
117+ host = "localhost" ,
118+ protocol = "http" ,
119+ default_alias = self .DEFAULT_ALIAS ,
120+ )
115121
116122 @property
117- def active_node (self ):
123+ def active_node (self ) -> Node :
118124 return self .get_by_alias (self ._active_node )
119125
120126 @property
121- def nodes_names (self ):
122- return sorted (self .nodes .keys ())
127+ def nodes_names (self ) -> list :
128+ """Returns a list of the names (not the aliases) of the nodes"""
129+ return [node .name for node in self .nodes .values ()]
123130
124- def switch_node (self , node_alias ):
125- # this will throw an error if the node doesn't exist
131+ def switch_node (self , node_alias : str ):
132+ # This will throw an error if the node doesn't exist
133+ logger .debug (f"Switching from { self ._active_node } to { node_alias } ." )
126134 self ._active_node = self .get_by_alias (node_alias ).alias
127135
128- def default_node (self ):
136+ def default_node (self ) -> Node :
129137 return self .get_by_alias (self .DEFAULT_ALIAS )
130138
131- def get_by_alias (self , alias ):
132- for node_name in self .nodes :
133- if self .nodes [node_name ] and self .nodes [node_name ].alias == alias :
134- return self .nodes [node_name ]
135- raise SpecterError ("Node %s does not exist!" % alias )
139+ def get_by_alias (self , alias : str ) -> Node :
140+ for node in self .nodes .values ():
141+ if node .alias == alias :
142+ return node
143+ raise SpecterError ("Node alias %s does not exist!" % alias )
144+
145+ def get_by_name (self , name : str ) -> Node :
146+ for node in self .nodes .values ():
147+ if node .name == name :
148+ return node
149+ raise SpecterError ("Node name %s does not exist!" % name )
136150
137151 def update_bitcoind_version (self , specter , version ):
138152 stopped_nodes = []
@@ -168,7 +182,7 @@ def add_external_node(
168182 """Adding a node. Params:
169183 :param node_type: only valid for autodetect. Either BTC or ELM
170184 This should only be used for an external node. Use add_internal_node for internal node
171- and if you have defined your own node- type, use save_node directly. to save the node (and create it yourself)
185+ and if you have defined your own node type, use save_node directly to save the node (and create it yourself)
172186 """
173187 if not default_alias :
174188 node_alias = alias (name )
@@ -195,20 +209,19 @@ def add_external_node(
195209 node_type ,
196210 self ,
197211 )
198- logger .info (f"persisting { node } in add_external_node" )
199- self .nodes [name ] = node
200- return self .save_node (node )
212+ logger .debug (f"Persisting { node_alias } from an add_external_node call." )
213+ self .nodes [node_alias ] = node
214+ self .save_node (node )
215+ return node
201216
202217 def save_node (self , node ):
203218 fullpath = (
204219 node .fullpath
205220 if hasattr (node , "fullpath" )
206- else calc_fullpath (self .data_folder , node .name )
221+ else calc_fullpath (self .data_folder , node .alias )
207222 )
208223 write_node (node , fullpath )
209-
210224 logger .info ("Added new node {}" .format (node .alias ))
211- return node
212225
213226 def add_internal_node (
214227 self ,
@@ -251,15 +264,22 @@ def add_internal_node(
251264 network ,
252265 self .internal_bitcoind_version ,
253266 )
254- self .nodes [name ] = node
255- return self . save_node ( node )
267+ self .nodes [node_alias ] = node
268+ return node
256269
257270 def delete_node (self , node , specter ):
258271 logger .info ("Deleting {}" .format (node .alias ))
259- # Delete files
260- delete_file (node .fullpath )
261- delete_file (node .fullpath + ".bkp" )
262- if self ._active_node == node .alias :
263- specter .update_active_node (next (iter (self .nodes .values ())).alias )
264- del self .nodes [node .name ]
265- logger .info ("Node {} was deleted successfully" .format (node .alias ))
272+ try :
273+ # Delete from wallet manager
274+ del self .nodes [node .alias ]
275+ # Delete files
276+ delete_file (node .fullpath )
277+ delete_file (node .fullpath + ".bkp" )
278+ # Update the active node
279+ if self ._active_node == node .alias :
280+ specter .update_active_node (
281+ next (iter (self .nodes .values ())).alias
282+ ) # This switches to the first node in the node list, which is usually the default node
283+ logger .info ("Node {} was deleted successfully" .format (node .alias ))
284+ except KeyError :
285+ raise SpecterError (f"{ node .name } not found, node could not be deleted." )
0 commit comments