diff --git a/lnd.go b/lnd.go index c478fdba..efcb9a1d 100644 --- a/lnd.go +++ b/lnd.go @@ -14,9 +14,11 @@ import ( "google.golang.org/grpc" + "github.com/lightningnetwork/lnd/chainntnfs/btcdnotify" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnrpc" "github.com/lightningnetwork/lnd/lnwallet" + "github.com/roasbeef/btcrpcclient" ) var ( @@ -94,9 +96,29 @@ func lndMain() error { return err } - // Create, and start the lnwallet, which handles the core payment channel - // logic, and exposes control via proxy state machines. - config := &lnwallet.Config{ + btcdHost := fmt.Sprintf("%v:%v", loadedConfig.RPCHost, activeNetParams.rpcPort) + btcdUser := loadedConfig.RPCUser + btcdPass := loadedConfig.RPCPass + + // TODO(roasbeef): parse config here and select chosen notifier instead + rpcConfig := &btcrpcclient.ConnConfig{ + Host: btcdHost, + Endpoint: "ws", + User: btcdUser, + Pass: btcdPass, + Certificates: rpcCert, + DisableTLS: false, + DisableConnectOnNew: true, + DisableAutoReconnect: false, + } + notifier, err := btcdnotify.New(rpcConfig) + if err != nil { + return err + } + + // Create, and start the lnwallet, which handles the core payment + // channel logic, and exposes control via proxy state machines. + walletConfig := &lnwallet.Config{ PrivatePass: []byte("hello"), DataDir: filepath.Join(loadedConfig.DataDir, "lnwallet"), RpcHost: fmt.Sprintf("%v:%v", rpcIP[0], activeNetParams.rpcPort), @@ -105,7 +127,7 @@ func lndMain() error { CACert: rpcCert, NetParams: activeNetParams.Params, } - wallet, err := lnwallet.NewLightningWallet(config, chanDB) + wallet, err := lnwallet.NewLightningWallet(walletConfig, chanDB, notifier) if err != nil { fmt.Printf("unable to create wallet: %v\n", err) return err @@ -124,12 +146,15 @@ func lndMain() error { defaultListenAddrs := []string{ net.JoinHostPort("", strconv.Itoa(loadedConfig.PeerPort)), } - server, err := newServer(defaultListenAddrs, wallet, chanDB) + server, err := newServer(defaultListenAddrs, notifier, wallet, chanDB) if err != nil { srvrLog.Errorf("unable to create server: %v\n", err) return err } - server.Start() + if err := server.Start(); err != nil { + srvrLog.Errorf("unable to create to start: %v\n", err) + return err + } addInterruptHandler(func() { ltndLog.Infof("Gracefully shutting down the server...") diff --git a/log.go b/log.go index cdb52210..07a56b50 100644 --- a/log.go +++ b/log.go @@ -6,7 +6,7 @@ import ( "github.com/btcsuite/btclog" "github.com/btcsuite/seelog" - "github.com/lightningnetwork/lnd/chainntfs" + "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lnwallet" ) diff --git a/peer.go b/peer.go index f70fee94..a5f73ceb 100644 --- a/peer.go +++ b/peer.go @@ -218,7 +218,7 @@ func (p *peer) loadActiveChannels(chans []*channeldb.OpenChannel) error { for _, dbChan := range chans { chanID := dbChan.ChanID lnChan, err := lnwallet.NewLightningChannel(p.server.lnwallet, - p.server.lnwallet.ChainNotifier, p.server.chanDB, dbChan) + p.server.chainNotifier, p.server.chanDB, dbChan) if err != nil { return err } @@ -673,8 +673,7 @@ func (p *peer) handleLocalClose(req *closeLinkReq) { // confirmation. go func() { // TODO(roasbeef): add param for num needed confs - notifier := p.server.lnwallet.ChainNotifier - confNtfn, err := notifier.RegisterConfirmationsNtfn(txid, 1) + confNtfn, err := p.server.chainNotifier.RegisterConfirmationsNtfn(txid, 1) if err != nil { req.err <- err return diff --git a/server.go b/server.go index 29b9869d..e8c591e2 100644 --- a/server.go +++ b/server.go @@ -8,6 +8,7 @@ import ( "sync/atomic" "github.com/btcsuite/fastsha256" + "github.com/lightningnetwork/lnd/chainntnfs" "github.com/lightningnetwork/lnd/channeldb" "github.com/lightningnetwork/lnd/lndc" "github.com/lightningnetwork/lnd/lnrpc" @@ -40,9 +41,9 @@ type server struct { listeners []net.Listener peers map[int32]*peer - rpcServer *rpcServer - // TODO(roasbeef): add chan notifier also - lnwallet *lnwallet.LightningWallet + rpcServer *rpcServer + chainNotifier chainntnfs.ChainNotifier + lnwallet *lnwallet.LightningWallet // TODO(roasbeef): add to constructor fundingMgr *fundingManager @@ -63,8 +64,8 @@ type server struct { // newServer creates a new instance of the server which is to listen using the // passed listener address. -func newServer(listenAddrs []string, wallet *lnwallet.LightningWallet, - chanDB *channeldb.DB) (*server, error) { +func newServer(listenAddrs []string, notifier chainntnfs.ChainNotifier, + wallet *lnwallet.LightningWallet, chanDB *channeldb.DB) (*server, error) { privKey, err := getIdentityPrivKey(chanDB, wallet) if err != nil { @@ -81,19 +82,20 @@ func newServer(listenAddrs []string, wallet *lnwallet.LightningWallet, serializedPubKey := privKey.PubKey().SerializeCompressed() s := &server{ - chanDB: chanDB, - fundingMgr: newFundingManager(wallet), - htlcSwitch: newHtlcSwitch(), - invoices: newInvoiceRegistry(), - lnwallet: wallet, - identityPriv: privKey, - lightningID: fastsha256.Sum256(serializedPubKey), - listeners: listeners, - peers: make(map[int32]*peer), - newPeers: make(chan *peer, 100), - donePeers: make(chan *peer, 100), - queries: make(chan interface{}), - quit: make(chan struct{}), + chainNotifier: notifier, + chanDB: chanDB, + fundingMgr: newFundingManager(wallet), + htlcSwitch: newHtlcSwitch(), + invoices: newInvoiceRegistry(), + lnwallet: wallet, + identityPriv: privKey, + lightningID: fastsha256.Sum256(serializedPubKey), + listeners: listeners, + peers: make(map[int32]*peer), + newPeers: make(chan *peer, 100), + donePeers: make(chan *peer, 100), + queries: make(chan interface{}), + quit: make(chan struct{}), } // TODO(roasbeef): remove @@ -110,10 +112,10 @@ func newServer(listenAddrs []string, wallet *lnwallet.LightningWallet, // Start starts the main daemon server, all requested listeners, and any helper // goroutines. -func (s *server) Start() { +func (s *server) Start() error { // Already running? if atomic.AddInt32(&s.started, 1) != 1 { - return + return nil } // Start all the listeners. @@ -122,12 +124,30 @@ func (s *server) Start() { go s.listener(l) } - s.fundingMgr.Start() - s.htlcSwitch.Start() + // Start the notification server. This is used so channel managment + // goroutines can be notified when a funding transaction reaches a + // sufficient number of confirmations, or when the input for the + // funding transaction is spent in an attempt at an uncooperative + // close by the counter party. + if err := s.chainNotifier.Start(); err != nil { + return err + } + + if err := s.rpcServer.Start(); err != nil { + return err + } + if err := s.fundingMgr.Start(); err != nil { + return err + } + if err := s.htlcSwitch.Start(); err != nil { + return err + } s.routingMgr.Start() s.wg.Add(1) go s.queryHandler() + + return nil } // Stop gracefully shutsdown the main daemon server. This function will signal @@ -146,10 +166,14 @@ func (s *server) Stop() error { } } + // Shutdown the wallet, funding manager, and the rpc server. + s.chainNotifier.Stop() s.rpcServer.Stop() - s.lnwallet.Shutdown() s.fundingMgr.Stop() s.routingMgr.Stop() + s.htlcSwitch.Stop() + + s.lnwallet.Shutdown() // Signal all the lingering goroutines to quit. close(s.quit)