server: better way to clean chainControl resources

In this commit the location of where chain control services
are stopped is shifted to be closer to the point they are started.
Stopping of two services: "wallet" and "feeEstimator" that are started
inside the "newChainControlFromConfig" was shifted from server.go to
the cleanup function.

In addition the chainView.Stop was also removed from the server.Stop as
it is already handled by the router, where it is being started.
This commit is contained in:
Roei Erez 2021-04-08 12:58:32 +03:00
parent becae748de
commit 65ab3dbfc8
2 changed files with 45 additions and 29 deletions

View File

@ -226,7 +226,7 @@ type ChainControl struct {
// full-node, another backed by a running bitcoind full-node, and the other // full-node, another backed by a running bitcoind full-node, and the other
// backed by a running neutrino light client instance. When running with a // backed by a running neutrino light client instance. When running with a
// neutrino light client instance, `neutrinoCS` must be non-nil. // neutrino light client instance, `neutrinoCS` must be non-nil.
func NewChainControl(cfg *Config) (*ChainControl, error) { func NewChainControl(cfg *Config) (*ChainControl, func(), error) {
// Set the RPC config from the "home" chain. Multi-chain isn't yet // Set the RPC config from the "home" chain. Multi-chain isn't yet
// active, so we'll restrict usage to a particular chain for now. // active, so we'll restrict usage to a particular chain for now.
@ -264,7 +264,7 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
DefaultLitecoinStaticFeePerKW, 0, DefaultLitecoinStaticFeePerKW, 0,
) )
default: default:
return nil, fmt.Errorf("default routing policy for chain %v is "+ return nil, nil, fmt.Errorf("default routing policy for chain %v is "+
"unknown", cfg.PrimaryChain()) "unknown", cfg.PrimaryChain())
} }
@ -294,7 +294,7 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
heightHintCacheConfig, cfg.LocalChanDB, heightHintCacheConfig, cfg.LocalChanDB,
) )
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to initialize height hint "+ return nil, nil, fmt.Errorf("unable to initialize height hint "+
"cache: %v", err) "cache: %v", err)
} }
@ -311,14 +311,14 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
) )
cc.ChainView, err = chainview.NewCfFilteredChainView(cfg.NeutrinoCS) cc.ChainView, err = chainview.NewCfFilteredChainView(cfg.NeutrinoCS)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// Map the deprecated neutrino feeurl flag to the general fee // Map the deprecated neutrino feeurl flag to the general fee
// url. // url.
if cfg.NeutrinoMode.FeeURL != "" { if cfg.NeutrinoMode.FeeURL != "" {
if cfg.FeeURL != "" { if cfg.FeeURL != "" {
return nil, errors.New("feeurl and " + return nil, nil, errors.New("feeurl and " +
"neutrino.feeurl are mutually exclusive") "neutrino.feeurl are mutually exclusive")
} }
@ -358,7 +358,7 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
// this back to the btcwallet/bitcoind port. // this back to the btcwallet/bitcoind port.
rpcPort, err := strconv.Atoi(cfg.ActiveNetParams.RPCPort) rpcPort, err := strconv.Atoi(cfg.ActiveNetParams.RPCPort)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
rpcPort -= 2 rpcPort -= 2
bitcoindHost = fmt.Sprintf("%v:%d", bitcoindHost = fmt.Sprintf("%v:%d",
@ -390,11 +390,11 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
5*time.Second, 5*time.Second,
) )
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
if err := bitcoindConn.Start(); err != nil { if err := bitcoindConn.Start(); err != nil {
return nil, fmt.Errorf("unable to connect to bitcoind: "+ return nil, nil, fmt.Errorf("unable to connect to bitcoind: "+
"%v", err) "%v", err)
} }
@ -429,7 +429,7 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
fallBackFeeRate.FeePerKWeight(), fallBackFeeRate.FeePerKWeight(),
) )
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
} else if cfg.Litecoin.Active && !cfg.Litecoin.RegTest { } else if cfg.Litecoin.Active && !cfg.Litecoin.RegTest {
log.Infof("Initializing litecoind backed fee estimator in "+ log.Infof("Initializing litecoind backed fee estimator in "+
@ -445,7 +445,7 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
fallBackFeeRate.FeePerKWeight(), fallBackFeeRate.FeePerKWeight(),
) )
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
} }
@ -454,14 +454,14 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
// connection. // connection.
chainConn, err := rpcclient.New(rpcConfig, nil) chainConn, err := rpcclient.New(rpcConfig, nil)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// The api we will use for our health check depends on the // The api we will use for our health check depends on the
// bitcoind version. // bitcoind version.
cmd, err := getBitcoindHealthCheckCmd(chainConn) cmd, err := getBitcoindHealthCheckCmd(chainConn)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
cc.HealthCheck = func() error { cc.HealthCheck = func() error {
@ -487,19 +487,19 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
if btcdMode.RawRPCCert != "" { if btcdMode.RawRPCCert != "" {
rpcCert, err = hex.DecodeString(btcdMode.RawRPCCert) rpcCert, err = hex.DecodeString(btcdMode.RawRPCCert)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
} else { } else {
certFile, err := os.Open(btcdMode.RPCCert) certFile, err := os.Open(btcdMode.RPCCert)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
rpcCert, err = ioutil.ReadAll(certFile) rpcCert, err = ioutil.ReadAll(certFile)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
if err := certFile.Close(); err != nil { if err := certFile.Close(); err != nil {
return nil, err return nil, nil, err
} }
} }
@ -531,7 +531,7 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
rpcConfig, cfg.ActiveNetParams.Params, hintCache, hintCache, rpcConfig, cfg.ActiveNetParams.Params, hintCache, hintCache,
) )
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
// Finally, we'll create an instance of the default chain view to be // Finally, we'll create an instance of the default chain view to be
@ -539,7 +539,7 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
cc.ChainView, err = chainview.NewBtcdFilteredChainView(*rpcConfig) cc.ChainView, err = chainview.NewBtcdFilteredChainView(*rpcConfig)
if err != nil { if err != nil {
log.Errorf("unable to create chain view: %v", err) log.Errorf("unable to create chain view: %v", err)
return nil, err return nil, nil, err
} }
// Create a special websockets rpc client for btcd which will be used // Create a special websockets rpc client for btcd which will be used
@ -547,7 +547,7 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
chainRPC, err := chain.NewRPCClient(cfg.ActiveNetParams.Params, btcdHost, chainRPC, err := chain.NewRPCClient(cfg.ActiveNetParams.Params, btcdHost,
btcdUser, btcdPass, rpcCert, false, 20) btcdUser, btcdPass, rpcCert, false, 20)
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
walletConfig.ChainSource = chainRPC walletConfig.ChainSource = chainRPC
@ -574,11 +574,11 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
*rpcConfig, fallBackFeeRate.FeePerKWeight(), *rpcConfig, fallBackFeeRate.FeePerKWeight(),
) )
if err != nil { if err != nil {
return nil, err return nil, nil, err
} }
} }
default: default:
return nil, fmt.Errorf("unknown node type: %s", return nil, nil, fmt.Errorf("unknown node type: %s",
homeChainConfig.Node) homeChainConfig.Node)
} }
@ -589,7 +589,7 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
case cfg.FeeURL == "" && cfg.Bitcoin.MainNet && case cfg.FeeURL == "" && cfg.Bitcoin.MainNet &&
homeChainConfig.Node == "neutrino": homeChainConfig.Node == "neutrino":
return nil, fmt.Errorf("--feeurl parameter required when " + return nil, nil, fmt.Errorf("--feeurl parameter required when " +
"running neutrino on mainnet") "running neutrino on mainnet")
// Override default fee estimator if an external service is specified. // Override default fee estimator if an external service is specified.
@ -609,15 +609,29 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
) )
} }
ccCleanup := func() {
if cc.Wallet != nil {
if err := cc.Wallet.Shutdown(); err != nil {
log.Errorf("Failed to shutdown wallet: %v", err)
}
}
if cc.FeeEstimator != nil {
if err := cc.FeeEstimator.Stop(); err != nil {
log.Errorf("Failed to stop feeEstimator: %v", err)
}
}
}
// Start fee estimator. // Start fee estimator.
if err := cc.FeeEstimator.Start(); err != nil { if err := cc.FeeEstimator.Start(); err != nil {
return nil, err return nil, nil, err
} }
wc, err := btcwallet.New(*walletConfig) wc, err := btcwallet.New(*walletConfig)
if err != nil { if err != nil {
fmt.Printf("unable to create wallet controller: %v\n", err) fmt.Printf("unable to create wallet controller: %v\n", err)
return nil, err return nil, ccCleanup, err
} }
cc.MsgSigner = wc cc.MsgSigner = wc
@ -652,18 +666,17 @@ func NewChainControl(cfg *Config) (*ChainControl, error) {
lnWallet, err := lnwallet.NewLightningWallet(walletCfg) lnWallet, err := lnwallet.NewLightningWallet(walletCfg)
if err != nil { if err != nil {
fmt.Printf("unable to create wallet: %v\n", err) fmt.Printf("unable to create wallet: %v\n", err)
return nil, err return nil, ccCleanup, err
} }
if err := lnWallet.Startup(); err != nil { if err := lnWallet.Startup(); err != nil {
fmt.Printf("unable to start wallet: %v\n", err) fmt.Printf("unable to start wallet: %v\n", err)
return nil, err return nil, ccCleanup, err
} }
log.Info("LightningWallet opened") log.Info("LightningWallet opened")
cc.Wallet = lnWallet cc.Wallet = lnWallet
return cc, nil return cc, ccCleanup, nil
} }
// getBitcoindHealthCheckCmd queries bitcoind for its version to decide which // getBitcoindHealthCheckCmd queries bitcoind for its version to decide which

5
lnd.go
View File

@ -545,7 +545,10 @@ func Main(cfg *Config, lisCfg ListenerCfg, interceptor signal.Interceptor) error
FeeURL: cfg.FeeURL, FeeURL: cfg.FeeURL,
} }
activeChainControl, err := chainreg.NewChainControl(chainControlCfg) activeChainControl, cleanup, err := chainreg.NewChainControl(chainControlCfg)
if cleanup != nil {
defer cleanup()
}
if err != nil { if err != nil {
err := fmt.Errorf("unable to create chain control: %v", err) err := fmt.Errorf("unable to create chain control: %v", err)
ltndLog.Error(err) ltndLog.Error(err)