diff --git a/lnd.go b/lnd.go index 76aeca27..7c7c80c4 100644 --- a/lnd.go +++ b/lnd.go @@ -316,6 +316,68 @@ func Main(cfg *Config, lisCfg ListenerCfg, interceptor signal.Interceptor) error } } + // Create a new RPC interceptor that we'll add to the GRPC server. This + // will be used to log the API calls invoked on the GRPC server. + interceptorChain := rpcperms.NewInterceptorChain( + rpcsLog, cfg.NoMacaroons, + ) + if err := interceptorChain.Start(); err != nil { + return err + } + defer func() { + err := interceptorChain.Stop() + if err != nil { + ltndLog.Warnf("error stopping RPC interceptor "+ + "chain: %v", err) + } + }() + + rpcServerOpts := interceptorChain.CreateServerOpts() + serverOpts = append(serverOpts, rpcServerOpts...) + + grpcServer := grpc.NewServer(serverOpts...) + defer grpcServer.Stop() + + // We'll also register the RPC interceptor chain as the StateServer, as + // it can be used to query for the current state of the wallet. + lnrpc.RegisterStateServer(grpcServer, interceptorChain) + + // Register the WalletUnlockerService with the GRPC server. + pwService := createWalletUnlockerService(cfg) + lnrpc.RegisterWalletUnlockerServer(grpcServer, pwService) + + // Initialize, and register our implementation of the gRPC interface + // exported by the rpcServer. + rpcServer := newRPCServer( + cfg, interceptorChain, lisCfg.ExternalRPCSubserverCfg, + lisCfg.ExternalRestRegistrar, + interceptor, + ) + + err = rpcServer.RegisterWithGrpcServer(grpcServer) + if err != nil { + return err + } + + // Now that both the WalletUnlocker and LightningService have been + // registered with the GRPC server, we can start listening. + err = startGrpcListen(cfg, grpcServer, grpcListeners) + if err != nil { + return err + } + + // Now start the REST proxy for our gRPC server above. We'll ensure + // we direct LND to connect to its loopback address rather than a + // wildcard to prevent certificate issues when accessing the proxy + // externally. + stopProxy, err := startRestProxy( + cfg, rpcServer, restDialOpts, restListen, + ) + if err != nil { + return err + } + defer stopProxy() + // Start leader election if we're running on etcd. Continuation will be // blocked until this instance is elected as the current leader or // shutting down. @@ -401,77 +463,17 @@ func Main(cfg *Config, lisCfg ListenerCfg, interceptor signal.Interceptor) error ) } - // We'll create the WalletUnlockerService and check whether the wallet - // already exists. - pwService := createWalletUnlockerService(cfg, - []btcwallet.LoaderOption{loaderOpt}, - ) - + pwService.SetLoaderOpts([]btcwallet.LoaderOption{loaderOpt}) walletExists, err := pwService.WalletExists() if err != nil { return err } - // Create a new RPC interceptor that we'll add to the GRPC server. This - // will be used to log the API calls invoked on the GRPC server. - interceptorChain := rpcperms.NewInterceptorChain( - rpcsLog, cfg.NoMacaroons, walletExists, - ) - if err := interceptorChain.Start(); err != nil { - return err + if !walletExists { + interceptorChain.SetWalletNotCreated() + } else { + interceptorChain.SetWalletLocked() } - defer func() { - err := interceptorChain.Stop() - if err != nil { - ltndLog.Warnf("error stopping RPC interceptor "+ - "chain: %v", err) - } - }() - - rpcServerOpts := interceptorChain.CreateServerOpts() - serverOpts = append(serverOpts, rpcServerOpts...) - - grpcServer := grpc.NewServer(serverOpts...) - defer grpcServer.Stop() - - // Register the WalletUnlockerService with the GRPC server. - lnrpc.RegisterWalletUnlockerServer(grpcServer, pwService) - - // We'll also register the RPC interceptor chain as the StateServer, as - // it can be used to query for the current state of the wallet. - lnrpc.RegisterStateServer(grpcServer, interceptorChain) - - // Initialize, and register our implementation of the gRPC interface - // exported by the rpcServer. - rpcServer := newRPCServer( - cfg, interceptorChain, lisCfg.ExternalRPCSubserverCfg, - lisCfg.ExternalRestRegistrar, - interceptor, - ) - - err = rpcServer.RegisterWithGrpcServer(grpcServer) - if err != nil { - return err - } - - // Now that both the WalletUnlocker and LightningService have been - // registered with the GRPC server, we can start listening. - err = startGrpcListen(cfg, grpcServer, grpcListeners) - if err != nil { - return err - } - - // Now start the REST proxy for our gRPC server above. We'll ensure - // we direct LND to connect to its loopback address rather than a - // wildcard to prevent certificate issues when accessing the proxy - // externally. - stopProxy, err := startRestProxy( - cfg, rpcServer, restDialOpts, restListen, - ) - if err != nil { - return err - } - defer stopProxy() // We wait until the user provides a password over RPC. In case lnd is // started with the --noseedbackup flag, we use the default password @@ -1234,9 +1236,7 @@ type WalletUnlockParams struct { // createWalletUnlockerService creates a WalletUnlockerService from the passed // config. -func createWalletUnlockerService(cfg *Config, - loaderOpts []btcwallet.LoaderOption) *walletunlocker.UnlockerService { - +func createWalletUnlockerService(cfg *Config) *walletunlocker.UnlockerService { chainConfig := cfg.Bitcoin if cfg.registeredChains.PrimaryChain() == chainreg.LitecoinChain { chainConfig = cfg.Litecoin @@ -1252,7 +1252,7 @@ func createWalletUnlockerService(cfg *Config, return walletunlocker.New( chainConfig.ChainDir, cfg.ActiveNetParams.Params, !cfg.SyncFreelist, macaroonFiles, cfg.DB.Bolt.DBTimeout, - cfg.ResetWalletTransactions, loaderOpts, + cfg.ResetWalletTransactions, nil, ) } diff --git a/lnrpc/stateservice.pb.go b/lnrpc/stateservice.pb.go index 7954e265..ca2522a2 100644 --- a/lnrpc/stateservice.pb.go +++ b/lnrpc/stateservice.pb.go @@ -32,25 +32,28 @@ const _ = proto.ProtoPackageIsVersion4 type WalletState int32 const ( - WalletState_NON_EXISTING WalletState = 0 - WalletState_LOCKED WalletState = 1 - WalletState_UNLOCKED WalletState = 2 - WalletState_RPC_ACTIVE WalletState = 3 + WalletState_NON_EXISTING WalletState = 0 + WalletState_LOCKED WalletState = 1 + WalletState_UNLOCKED WalletState = 2 + WalletState_RPC_ACTIVE WalletState = 3 + WalletState_WAITING_TO_START WalletState = 255 ) // Enum value maps for WalletState. var ( WalletState_name = map[int32]string{ - 0: "NON_EXISTING", - 1: "LOCKED", - 2: "UNLOCKED", - 3: "RPC_ACTIVE", + 0: "NON_EXISTING", + 1: "LOCKED", + 2: "UNLOCKED", + 3: "RPC_ACTIVE", + 255: "WAITING_TO_START", } WalletState_value = map[string]int32{ - "NON_EXISTING": 0, - "LOCKED": 1, - "UNLOCKED": 2, - "RPC_ACTIVE": 3, + "NON_EXISTING": 0, + "LOCKED": 1, + "UNLOCKED": 2, + "RPC_ACTIVE": 3, + "WAITING_TO_START": 255, } ) @@ -176,20 +179,22 @@ var file_stateservice_proto_rawDesc = []byte{ 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x28, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, - 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x49, 0x0a, 0x0b, 0x57, 0x61, 0x6c, 0x6c, + 0x65, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2a, 0x60, 0x0a, 0x0b, 0x57, 0x61, 0x6c, 0x6c, 0x65, 0x74, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x4e, 0x4f, 0x4e, 0x5f, 0x45, 0x58, 0x49, 0x53, 0x54, 0x49, 0x4e, 0x47, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x55, 0x4e, 0x4c, 0x4f, 0x43, 0x4b, 0x45, 0x44, 0x10, 0x02, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x50, 0x43, 0x5f, 0x41, 0x43, 0x54, 0x49, 0x56, - 0x45, 0x10, 0x03, 0x32, 0x58, 0x0a, 0x05, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0e, - 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, - 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, - 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, - 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x30, 0x01, 0x42, 0x27, 0x5a, - 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, - 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6e, 0x64, - 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x45, 0x10, 0x03, 0x12, 0x15, 0x0a, 0x10, 0x57, 0x41, 0x49, 0x54, 0x49, 0x4e, 0x47, 0x5f, 0x54, + 0x4f, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x10, 0xff, 0x01, 0x32, 0x58, 0x0a, 0x05, 0x53, 0x74, + 0x61, 0x74, 0x65, 0x12, 0x4f, 0x0a, 0x0e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x30, 0x01, 0x42, 0x27, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, + 0x6f, 0x6d, 0x2f, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x6e, 0x69, 0x6e, 0x67, 0x6e, 0x65, 0x74, 0x77, + 0x6f, 0x72, 0x6b, 0x2f, 0x6c, 0x6e, 0x64, 0x2f, 0x6c, 0x6e, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/lnrpc/stateservice.proto b/lnrpc/stateservice.proto index e7a6ecbd..07cc8e6f 100644 --- a/lnrpc/stateservice.proto +++ b/lnrpc/stateservice.proto @@ -36,6 +36,8 @@ enum WalletState { LOCKED = 1; UNLOCKED = 2; RPC_ACTIVE = 3; + + WAITING_TO_START = 255; } message SubscribeStateRequest { diff --git a/lnrpc/stateservice.swagger.json b/lnrpc/stateservice.swagger.json index c0589afe..132efffc 100644 --- a/lnrpc/stateservice.swagger.json +++ b/lnrpc/stateservice.swagger.json @@ -59,7 +59,8 @@ "NON_EXISTING", "LOCKED", "UNLOCKED", - "RPC_ACTIVE" + "RPC_ACTIVE", + "WAITING_TO_START" ], "default": "NON_EXISTING" }, diff --git a/lntest/itest/log_error_whitelist.txt b/lntest/itest/log_error_whitelist.txt index 87ac6f50..76211171 100644 --- a/lntest/itest/log_error_whitelist.txt +++ b/lntest/itest/log_error_whitelist.txt @@ -275,3 +275,4 @@