mirror of https://github.com/BTCPrivate/lnd.git
lnd: newChainControlFromConfig can now create light client backed chainControl
This commit finishes up the implementation of newChainControlFromConfig in order to properly initiate the members of the chainControl struct when the new light client mode (neutrino). With this lnd is now able to switch over to either mode with a simple configuration change.
This commit is contained in:
parent
33decbe6ab
commit
593ba7c8f0
|
@ -13,12 +13,14 @@ import (
|
||||||
"github.com/lightninglabs/neutrino"
|
"github.com/lightninglabs/neutrino"
|
||||||
"github.com/lightningnetwork/lnd/chainntnfs"
|
"github.com/lightningnetwork/lnd/chainntnfs"
|
||||||
"github.com/lightningnetwork/lnd/chainntnfs/btcdnotify"
|
"github.com/lightningnetwork/lnd/chainntnfs/btcdnotify"
|
||||||
|
"github.com/lightningnetwork/lnd/chainntnfs/neutrinonotify"
|
||||||
"github.com/lightningnetwork/lnd/channeldb"
|
"github.com/lightningnetwork/lnd/channeldb"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet"
|
"github.com/lightningnetwork/lnd/lnwallet"
|
||||||
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
|
"github.com/lightningnetwork/lnd/lnwallet/btcwallet"
|
||||||
"github.com/lightningnetwork/lnd/routing/chainview"
|
"github.com/lightningnetwork/lnd/routing/chainview"
|
||||||
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
"github.com/roasbeef/btcd/chaincfg/chainhash"
|
||||||
"github.com/roasbeef/btcrpcclient"
|
"github.com/roasbeef/btcrpcclient"
|
||||||
|
"github.com/roasbeef/btcwallet/chain"
|
||||||
"github.com/roasbeef/btcwallet/walletdb"
|
"github.com/roasbeef/btcwallet/walletdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -65,8 +67,11 @@ type chainControl struct {
|
||||||
wallet *lnwallet.LightningWallet
|
wallet *lnwallet.LightningWallet
|
||||||
}
|
}
|
||||||
|
|
||||||
// newChainControlFromConfig....
|
// newChainControlFromConfig attempts to create a chainControl instance
|
||||||
func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB) (*chainControl, error) {
|
// according to the parameters in the passed lnd configuration. Currently two
|
||||||
|
// branches of chainControl instances exist: one backed by a running btcd
|
||||||
|
// full-node, and the other backed by a running neutrino light client instance.
|
||||||
|
func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB) (*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.
|
||||||
homeChainConfig := cfg.Bitcoin
|
homeChainConfig := cfg.Bitcoin
|
||||||
|
@ -89,21 +94,24 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB) (*chainControl
|
||||||
|
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
|
cleanUp func()
|
||||||
)
|
)
|
||||||
|
|
||||||
// If spv mode is active, then we'll be using a distimnct set of
|
// If spv mode is active, then we'll be using a distimnct set of
|
||||||
// chainControl interfaces that interface directly with the p2p network
|
// chainControl interfaces that interface directly with the p2p network
|
||||||
// of the selected chain.
|
// of the selected chain.
|
||||||
if cfg.SpvMode.Active {
|
if cfg.SpvMode.Active {
|
||||||
// TODO(roasbeef): create dest for database of chain
|
// First we'll open the database file for neutrino, creating
|
||||||
// * where to place???
|
// the database if needed.
|
||||||
|
|
||||||
dbName := filepath.Join(cfg.DataDir, "neutrino.db")
|
dbName := filepath.Join(cfg.DataDir, "neutrino.db")
|
||||||
nodeDatabase, err := walletdb.Create("bdb", dbName)
|
nodeDatabase, err := walletdb.Create("bdb", dbName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// With the database open, we can now create an instance of the
|
||||||
|
// neutrino light client. We pass in relevant configuration
|
||||||
|
// parameters required.
|
||||||
config := neutrino.Config{
|
config := neutrino.Config{
|
||||||
DataDir: cfg.DataDir,
|
DataDir: cfg.DataDir,
|
||||||
Database: nodeDatabase,
|
Database: nodeDatabase,
|
||||||
|
@ -111,28 +119,34 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB) (*chainControl
|
||||||
AddPeers: cfg.SpvMode.AddPeers,
|
AddPeers: cfg.SpvMode.AddPeers,
|
||||||
ConnectPeers: cfg.SpvMode.ConnectPeers,
|
ConnectPeers: cfg.SpvMode.ConnectPeers,
|
||||||
}
|
}
|
||||||
|
|
||||||
neutrino.WaitForMoreCFHeaders = time.Second * 1
|
neutrino.WaitForMoreCFHeaders = time.Second * 1
|
||||||
neutrino.MaxPeers = 8
|
neutrino.MaxPeers = 8
|
||||||
neutrino.BanDuration = 5 * time.Second
|
neutrino.BanDuration = 5 * time.Second
|
||||||
svc, err := neutrino.NewChainService(config)
|
svc, err := neutrino.NewChainService(config)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("unable to create neutrino: %v", err)
|
return nil, nil, fmt.Errorf("unable to create neutrino: %v", err)
|
||||||
}
|
}
|
||||||
svc.Start()
|
svc.Start()
|
||||||
|
|
||||||
ltndLog.Infof("WAITING!!!!!")
|
// Next we'll create the instances of the ChainNotifier and
|
||||||
m := make(chan struct{})
|
// FilteredChainView interface which is backed by the neutrino
|
||||||
<-m
|
// light client.
|
||||||
|
cc.chainNotifier, err = neutrinonotify.New(svc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
cc.chainView, err = chainview.NewCfFilteredChainView(svc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(roasbeef): return clean up func in closure to stop spvc
|
// Finally, we'll set the chain source for btcwallet, and
|
||||||
// and rest?
|
// create our clean up function which simply closes the
|
||||||
// defer db.Close()
|
// database.
|
||||||
// svc.Stop
|
walletConfig.ChainSource = chain.NewSPVChain(svc)
|
||||||
|
cleanUp = func() {
|
||||||
// TODO(roasbeef): need to modify to base things off of
|
defer nodeDatabase.Close()
|
||||||
// ChainService
|
}
|
||||||
//walletConfig.ChainService = svc
|
|
||||||
} else {
|
} else {
|
||||||
// Otherwise, we'll be speaking directly via RPC to a node.
|
// Otherwise, we'll be speaking directly via RPC to a node.
|
||||||
//
|
//
|
||||||
|
@ -144,19 +158,19 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB) (*chainControl
|
||||||
if homeChainConfig.RawRPCCert != "" {
|
if homeChainConfig.RawRPCCert != "" {
|
||||||
rpcCert, err = hex.DecodeString(homeChainConfig.RawRPCCert)
|
rpcCert, err = hex.DecodeString(homeChainConfig.RawRPCCert)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
certFile, err := os.Open(homeChainConfig.RPCCert)
|
certFile, err := os.Open(homeChainConfig.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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,13 +188,6 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB) (*chainControl
|
||||||
|
|
||||||
btcdUser := homeChainConfig.RPCUser
|
btcdUser := homeChainConfig.RPCUser
|
||||||
btcdPass := homeChainConfig.RPCPass
|
btcdPass := homeChainConfig.RPCPass
|
||||||
|
|
||||||
// TODO(roasbeef): set chain service for wallet?
|
|
||||||
walletConfig.RPCHost = btcdHost
|
|
||||||
walletConfig.RPCUser = homeChainConfig.RPCUser
|
|
||||||
walletConfig.RPCPass = homeChainConfig.RPCPass
|
|
||||||
walletConfig.CACert = rpcCert
|
|
||||||
|
|
||||||
rpcConfig := &btcrpcclient.ConnConfig{
|
rpcConfig := &btcrpcclient.ConnConfig{
|
||||||
Host: btcdHost,
|
Host: btcdHost,
|
||||||
Endpoint: "ws",
|
Endpoint: "ws",
|
||||||
|
@ -193,7 +200,7 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB) (*chainControl
|
||||||
}
|
}
|
||||||
cc.chainNotifier, err = btcdnotify.New(rpcConfig)
|
cc.chainNotifier, err = btcdnotify.New(rpcConfig)
|
||||||
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
|
||||||
|
@ -201,14 +208,24 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB) (*chainControl
|
||||||
cc.chainView, err = chainview.NewBtcdFilteredChainView(*rpcConfig)
|
cc.chainView, err = chainview.NewBtcdFilteredChainView(*rpcConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srvrLog.Errorf("unable to create chain view: %v", err)
|
srvrLog.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
|
||||||
|
// by the wallet for notifications, calls, etc.
|
||||||
|
chainRpc, err := chain.NewRPCClient(activeNetParams.Params, btcdHost,
|
||||||
|
btcdUser, btcdPass, rpcCert, false, 20)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
walletConfig.ChainSource = chainRpc
|
||||||
}
|
}
|
||||||
|
|
||||||
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, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cc.msgSigner = wc
|
cc.msgSigner = wc
|
||||||
|
@ -221,18 +238,18 @@ func newChainControlFromConfig(cfg *config, chanDB *channeldb.DB) (*chainControl
|
||||||
cc.signer, cc.chainIO, cc.feeEstimator, activeNetParams.Params)
|
cc.signer, cc.chainIO, cc.feeEstimator, activeNetParams.Params)
|
||||||
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, nil, err
|
||||||
}
|
}
|
||||||
if err := wallet.Startup(); err != nil {
|
if err := wallet.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, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ltndLog.Info("LightningWallet opened")
|
ltndLog.Info("LightningWallet opened")
|
||||||
|
|
||||||
cc.wallet = wallet
|
cc.wallet = wallet
|
||||||
|
|
||||||
return cc, nil
|
return cc, cleanUp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
|
5
lnd.go
5
lnd.go
|
@ -64,11 +64,14 @@ func lndMain() error {
|
||||||
// With the information parsed from the configuration, create valid
|
// With the information parsed from the configuration, create valid
|
||||||
// instances of the paertinent interfaces required to operate the
|
// instances of the paertinent interfaces required to operate the
|
||||||
// Lightning Network Daemon.
|
// Lightning Network Daemon.
|
||||||
activeChainControl, err := newChainControlFromConfig(cfg, chanDB)
|
activeChainControl, chainCleanUp, err := newChainControlFromConfig(cfg, chanDB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("unable to create chain control: %v\n", err)
|
fmt.Printf("unable to create chain control: %v\n", err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if chainCleanUp != nil {
|
||||||
|
defer chainCleanUp()
|
||||||
|
}
|
||||||
|
|
||||||
// Finally before we start the server, we'll register the "holy
|
// Finally before we start the server, we'll register the "holy
|
||||||
// trinity" of interface for our current "home chain" with the active
|
// trinity" of interface for our current "home chain" with the active
|
||||||
|
|
Loading…
Reference in New Issue