@@ -24,6 +24,7 @@ import (
24
24
"github.com/btcsuite/btcd/chaincfg/chainhash"
25
25
"github.com/btcsuite/btcd/wire"
26
26
"github.com/lightninglabs/faraday/frdrpc"
27
+ "github.com/lightninglabs/lightning-terminal/litrpc"
27
28
"github.com/lightninglabs/loop/looprpc"
28
29
"github.com/lightninglabs/pool/poolrpc"
29
30
"github.com/lightningnetwork/lnd/lnrpc"
@@ -231,9 +232,13 @@ type HarnessNode struct {
231
232
// methods SignMessage and VerifyMessage.
232
233
SignerClient signrpc.SignerClient
233
234
234
- // conn is the underlying connection to the grpc endpoint of the node.
235
+ // conn is the underlying connection to the lnd grpc endpoint of the
236
+ // node.
235
237
conn * grpc.ClientConn
236
238
239
+ // litConn is the underlying connection to Lit's grpc endpoint.
240
+ litConn * grpc.ClientConn
241
+
237
242
// RouterClient, WalletKitClient, WatchtowerClient cannot be embedded,
238
243
// because a name collision would occur with LightningClient.
239
244
RouterClient routerrpc.RouterClient
@@ -578,7 +583,22 @@ func (hn *HarnessNode) start(litdBinary string, litdError chan<- error,
578
583
return nil
579
584
}
580
585
581
- return hn .initLightningClient (conn )
586
+ err = hn .initLightningClient (conn )
587
+ if err != nil {
588
+ return fmt .Errorf ("could not init Lightning Client: %w" , err )
589
+ }
590
+
591
+ // Also connect to Lit's RPC port for any Litd specific calls.
592
+ litConn , err := connectLitRPC (
593
+ context .Background (), hn .Cfg .LitAddr (), hn .Cfg .LitTLSCertPath ,
594
+ hn .Cfg .LitMacPath ,
595
+ )
596
+ if err != nil {
597
+ return fmt .Errorf ("could not connect to Lit RPC: %w" , err )
598
+ }
599
+ hn .litConn = litConn
600
+
601
+ return nil
582
602
}
583
603
584
604
// WaitUntilStarted waits until the wallet state flips from "WAITING_TO_START".
@@ -1044,6 +1064,14 @@ func (hn *HarnessNode) SetExtraArgs(extraArgs []string) {
1044
1064
1045
1065
// cleanup cleans up all the temporary files created by the node's process.
1046
1066
func (hn * HarnessNode ) cleanup () error {
1067
+ if hn .Cfg .RemoteMode {
1068
+ err := hn .RemoteLnd .Shutdown ()
1069
+ if err != nil {
1070
+ return fmt .Errorf ("unable to shutdown remote lnd " +
1071
+ "dir: %v" , err )
1072
+ }
1073
+ }
1074
+
1047
1075
if hn .backupDbDir != "" {
1048
1076
err := os .RemoveAll (hn .backupDbDir )
1049
1077
if err != nil {
@@ -1054,7 +1082,7 @@ func (hn *HarnessNode) cleanup() error {
1054
1082
return os .RemoveAll (hn .Cfg .BaseDir )
1055
1083
}
1056
1084
1057
- // Stop attempts to stop the active lnd process.
1085
+ // Stop attempts to stop the active litd process.
1058
1086
func (hn * HarnessNode ) stop () error {
1059
1087
// Do nothing if the process is not running.
1060
1088
if hn .processExit == nil {
@@ -1063,9 +1091,9 @@ func (hn *HarnessNode) stop() error {
1063
1091
1064
1092
// If start() failed before creating a client, we will just wait for the
1065
1093
// child process to die.
1066
- if hn .LightningClient != nil {
1067
- // Don't watch for error because sometimes the RPC connection gets
1068
- // closed before a response is returned.
1094
+ if ! hn . Cfg . RemoteMode && hn .LightningClient != nil {
1095
+ // Don't watch for error because sometimes the RPC connection
1096
+ // gets closed before a response is returned.
1069
1097
req := lnrpc.StopRequest {}
1070
1098
ctx := context .Background ()
1071
1099
@@ -1086,9 +1114,22 @@ func (hn *HarnessNode) stop() error {
1086
1114
if err != nil {
1087
1115
return err
1088
1116
}
1117
+ } else if hn .Cfg .RemoteMode {
1118
+ // If lit is running in remote mode, then calling LNDs
1119
+ // StopDaemon method will not shut down Lit, and so we need to
1120
+ // explicitly request lit to shut down.
1121
+ ctx , cancel := context .WithTimeout (
1122
+ context .Background (), lntest .DefaultTimeout ,
1123
+ )
1124
+ litConn := litrpc .NewProxyClient (hn .litConn )
1125
+ _ , err := litConn .StopDaemon (ctx , & litrpc.StopDaemonRequest {})
1126
+ cancel ()
1127
+ if err != nil {
1128
+ return err
1129
+ }
1089
1130
}
1090
1131
1091
- // Wait for lnd process and other goroutines to exit.
1132
+ // Wait for litd process and other goroutines to exit.
1092
1133
select {
1093
1134
case <- hn .processExit :
1094
1135
case <- time .After (lntest .DefaultTimeout * 2 ):
@@ -1116,10 +1157,6 @@ func (hn *HarnessNode) stop() error {
1116
1157
}
1117
1158
}
1118
1159
1119
- if hn .Cfg .RemoteMode {
1120
- return hn .RemoteLnd .Shutdown ()
1121
- }
1122
-
1123
1160
return nil
1124
1161
}
1125
1162
@@ -1782,3 +1819,40 @@ func (hn *HarnessNode) getChannelPolicies(include bool) policyUpdateMap {
1782
1819
1783
1820
return policyUpdates
1784
1821
}
1822
+
1823
+ // connectLitRPC can be used to connect to the lit rpc server.
1824
+ func connectLitRPC (ctx context.Context , hostPort , tlsCertPath ,
1825
+ macPath string ) (* grpc.ClientConn , error ) {
1826
+
1827
+ tlsCreds , err := credentials .NewClientTLSFromFile (tlsCertPath , "" )
1828
+ if err != nil {
1829
+ return nil , err
1830
+ }
1831
+
1832
+ opts := []grpc.DialOption {
1833
+ grpc .WithBlock (),
1834
+ grpc .WithTransportCredentials (tlsCreds ),
1835
+ }
1836
+
1837
+ if macPath != "" {
1838
+ macBytes , err := ioutil .ReadFile (macPath )
1839
+ if err != nil {
1840
+ return nil , err
1841
+ }
1842
+
1843
+ mac := & macaroon.Macaroon {}
1844
+ if err = mac .UnmarshalBinary (macBytes ); err != nil {
1845
+ return nil , fmt .Errorf ("error unmarshalling macaroon " +
1846
+ "file: %v" , err )
1847
+ }
1848
+
1849
+ macCred , err := macaroons .NewMacaroonCredential (mac )
1850
+ if err != nil {
1851
+ return nil , fmt .Errorf ("error cloning mac: %v" , err )
1852
+ }
1853
+
1854
+ opts = append (opts , grpc .WithPerRPCCredentials (macCred ))
1855
+ }
1856
+
1857
+ return grpc .DialContext (ctx , hostPort , opts ... )
1858
+ }
0 commit comments