@@ -79,6 +79,7 @@ def env(name, default=None):
7979SLOW_MACHINE = env ("SLOW_MACHINE" , "0" ) == "1"
8080DEPRECATED_APIS = env ("DEPRECATED_APIS" , "0" ) == "1"
8181TIMEOUT = int (env ("TIMEOUT" , 180 if SLOW_MACHINE else 60 ))
82+ SUBDAEMON = env ("SUBDAEMON" , "" )
8283EXPERIMENTAL_DUAL_FUND = env ("EXPERIMENTAL_DUAL_FUND" , "0" ) == "1"
8384
8485
@@ -529,6 +530,40 @@ def getnewaddress(self):
529530 return info ['unconfidential' ]
530531
531532
533+ class ValidatingLightningSignerD (TailableProc ):
534+ def __init__ (self , vlsd_dir , vlsd_port ):
535+ TailableProc .__init__ (self , vlsd_dir )
536+ self .executable = env ("REMOTE_SIGNER_CMD" , 'vlsd' )
537+ self .opts = [
538+ '--log-level-console=DEBUG' ,
539+ '--log-level-disk=DEBUG' ,
540+ '--network={}' .format (TEST_NETWORK ),
541+ '--datadir={}' .format (vlsd_dir ),
542+ '--port={}' .format (vlsd_port ),
543+ '--initial-allowlist-file={}' .format (env ('REMOTE_SIGNER_ALLOWLIST' ,
544+ 'contrib/remote_hsmd/TESTING_ALLOWLIST' )),
545+ ]
546+ self .prefix = 'vlsd'
547+ self .vlsd_port = vlsd_port
548+
549+ @property
550+ def cmd_line (self ):
551+ return [self .executable ] + self .opts
552+
553+ def start (self , stdin = None , stdout = None , stderr = None ,
554+ wait_for_initialized = True ):
555+ TailableProc .start (self , stdin , stdout , stderr )
556+ # We need to always wait for initialization
557+ self .wait_for_log ("vlsd [0-9]* ready on .*:{}" .format (self .vlsd_port ))
558+ logging .info ("vlsd started" )
559+
560+ def stop (self , timeout = 10 ):
561+ logging .info ("stopping vlsd" )
562+ rc = TailableProc .stop (self , timeout )
563+ logging .info ("vlsd stopped" )
564+ return rc
565+
566+
532567class LightningD (TailableProc ):
533568 def __init__ (self , lightning_dir , bitcoindproxy , port = 9735 , random_hsm = False , node_id = 0 ):
534569 TailableProc .__init__ (self , lightning_dir )
@@ -537,6 +572,9 @@ def __init__(self, lightning_dir, bitcoindproxy, port=9735, random_hsm=False, no
537572 self .port = port
538573 self .cmd_prefix = []
539574 self .disconnect_file = None
575+ self .lightning_dir = lightning_dir
576+ self .use_vlsd = False ;
577+ self .vlsd_dir = os .path .join (lightning_dir , "vlsd" )
540578
541579 self .rpcproxy = bitcoindproxy
542580
@@ -555,12 +593,21 @@ def __init__(self, lightning_dir, bitcoindproxy, port=9735, random_hsm=False, no
555593 'bitcoin-datadir' : lightning_dir ,
556594 }
557595
596+ if SUBDAEMON :
597+ opts ['subdaemon' ] = SUBDAEMON
598+ if SUBDAEMON == 'hsmd:remote_hsmd' :
599+ self .use_vlsd = True
600+
558601 for k , v in opts .items ():
559602 self .opts [k ] = v
560603
561604 if not os .path .exists (os .path .join (lightning_dir , TEST_NETWORK )):
562605 os .makedirs (os .path .join (lightning_dir , TEST_NETWORK ))
563606
607+ if self .use_vlsd :
608+ if not os .path .exists (self .vlsd_dir ):
609+ os .makedirs (self .vlsd_dir )
610+
564611 # Last 32-bytes of final part of dir -> seed.
565612 seed = (bytes (re .search ('([^/]+)/*$' , lightning_dir ).group (1 ), encoding = 'utf-8' ) + bytes (32 ))[:32 ]
566613 if not random_hsm :
@@ -572,6 +619,11 @@ def __init__(self, lightning_dir, bitcoindproxy, port=9735, random_hsm=False, no
572619 self .prefix = 'lightningd-%d' % (node_id )
573620
574621 def cleanup (self ):
622+ if self .use_vlsd :
623+ if self .use_vlsd :
624+ # Make sure the remotesigner is shutdown
625+ self .vlsd .stop ()
626+
575627 # To force blackhole to exit, disconnect file must be truncated!
576628 if self .disconnect_file :
577629 with open (self .disconnect_file , "w" ) as f :
@@ -594,11 +646,38 @@ def cmd_line(self):
594646
595647 def start (self , stdin = None , stdout = None , stderr = None ,
596648 wait_for_initialized = True ):
597- self .opts ['bitcoin-rpcport' ] = self .rpcproxy .rpcport
598- TailableProc .start (self , stdin , stdout , stderr )
599- if wait_for_initialized :
600- self .wait_for_log ("Server started with public key" )
601- logging .info ("LightningD started" )
649+ try :
650+ if self .use_vlsd :
651+ # Start the remote signer first
652+ vlsd_port = reserve ()
653+ self .vlsd = ValidatingLightningSignerD (self .vlsd_dir , vlsd_port )
654+ self .vlsd .start (stdin , stdout , stderr , wait_for_initialized )
655+
656+ # We can't do this in the constructor because we need a new port on each restart.
657+ self .env ['REMOTE_HSMD_ENDPOINT' ] = '127.0.0.1:{}' .format (vlsd_port )
658+
659+ self .opts ['bitcoin-rpcport' ] = self .rpcproxy .rpcport
660+ TailableProc .start (self , stdin , stdout , stderr )
661+ if wait_for_initialized :
662+ self .wait_for_log ("Server started with public key" )
663+ logging .info ("LightningD started" )
664+ except Exception :
665+ if self .use_vlsd :
666+ # LightningD didn't start, stop the remotesigner
667+ self .vlsd .stop ()
668+ raise
669+
670+ def stop (self , timeout = 10 ):
671+ if self .use_vlsd :
672+ # Stop the remote signer first
673+ self .vlsd .stop (timeout )
674+ return TailableProc .stop (self , timeout )
675+
676+ def kill (self ):
677+ if self .use_vlsd :
678+ # Kill the remote signer first
679+ self .vlsd .kill ()
680+ TailableProc .kill (self )
602681
603682 def wait (self , timeout = 10 ):
604683 """Wait for the daemon to stop for up to timeout seconds
0 commit comments