2015-12-17 03:42:52 +03:00
|
|
|
package main
|
|
|
|
|
2015-12-30 03:23:27 +03:00
|
|
|
import (
|
|
|
|
"fmt"
|
2016-03-23 04:50:11 +03:00
|
|
|
"io/ioutil"
|
2015-12-30 03:23:27 +03:00
|
|
|
"net"
|
2016-01-17 06:09:41 +03:00
|
|
|
"net/http"
|
|
|
|
_ "net/http/pprof"
|
2015-12-30 05:59:16 +03:00
|
|
|
"os"
|
2016-03-23 04:50:11 +03:00
|
|
|
"path/filepath"
|
|
|
|
"runtime"
|
2016-02-23 05:24:56 +03:00
|
|
|
"strconv"
|
2015-12-30 03:23:27 +03:00
|
|
|
|
2016-03-23 04:50:11 +03:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
|
|
|
|
"github.com/lightningnetwork/lnd/channeldb"
|
2016-01-16 21:38:48 +03:00
|
|
|
"github.com/lightningnetwork/lnd/lnrpc"
|
|
|
|
"github.com/lightningnetwork/lnd/lnwallet"
|
2015-12-30 03:23:27 +03:00
|
|
|
)
|
|
|
|
|
2016-03-23 04:50:11 +03:00
|
|
|
var (
|
|
|
|
cfg *config
|
|
|
|
shutdownChannel = make(chan struct{})
|
|
|
|
)
|
|
|
|
|
2016-07-13 03:03:29 +03:00
|
|
|
// lndMain is the true entry point for lnd. This function is required since
|
|
|
|
// defers created in the top-level scope of a main method aren't executed if
|
|
|
|
// os.Exit() is called.
|
|
|
|
func lndMain() error {
|
2016-03-23 04:50:11 +03:00
|
|
|
// Load the configuration, and parse any command line options. This
|
|
|
|
// function will also set up logging properly.
|
2016-02-23 05:24:56 +03:00
|
|
|
loadedConfig, err := loadConfig()
|
|
|
|
if err != nil {
|
2016-07-13 03:03:29 +03:00
|
|
|
return err
|
2016-02-23 05:24:56 +03:00
|
|
|
}
|
2016-03-23 04:50:11 +03:00
|
|
|
cfg = loadedConfig
|
|
|
|
defer backendLog.Flush()
|
|
|
|
|
|
|
|
// Show version at startup.
|
|
|
|
ltndLog.Infof("Version %s", version())
|
2016-02-23 05:24:56 +03:00
|
|
|
|
|
|
|
if loadedConfig.SPVMode == true {
|
2016-07-14 04:37:50 +03:00
|
|
|
shell(loadedConfig.SPVHostAdr, activeNetParams.Params)
|
2016-07-13 03:03:29 +03:00
|
|
|
return err
|
2016-02-03 10:37:29 +03:00
|
|
|
}
|
|
|
|
|
2016-06-21 07:42:07 +03:00
|
|
|
// Enable http profiling server if requested.
|
|
|
|
if cfg.Profile != "" {
|
|
|
|
go func() {
|
|
|
|
listenAddr := net.JoinHostPort("", cfg.Profile)
|
|
|
|
profileRedirect := http.RedirectHandler("/debug/pprof",
|
|
|
|
http.StatusSeeOther)
|
|
|
|
http.Handle("/", profileRedirect)
|
|
|
|
fmt.Println(http.ListenAndServe(listenAddr, nil))
|
|
|
|
}()
|
|
|
|
}
|
2016-01-17 06:01:06 +03:00
|
|
|
|
2016-03-23 04:50:11 +03:00
|
|
|
// Open the channeldb, which is dedicated to storing channel, and
|
|
|
|
// network related meta-data.
|
2016-07-14 04:37:50 +03:00
|
|
|
chanDB, err := channeldb.Open(loadedConfig.DataDir, activeNetParams.Params)
|
2016-03-23 04:50:11 +03:00
|
|
|
if err != nil {
|
|
|
|
fmt.Println("unable to open channeldb: ", err)
|
2016-07-13 03:03:29 +03:00
|
|
|
return err
|
2016-03-23 04:50:11 +03:00
|
|
|
}
|
|
|
|
defer chanDB.Close()
|
|
|
|
|
2016-07-17 03:56:28 +03:00
|
|
|
// Read btcd's rpc cert for lnwallet's convenience.
|
2016-03-23 04:50:11 +03:00
|
|
|
f, err := os.Open(loadedConfig.RPCCert)
|
|
|
|
if err != nil {
|
2016-07-13 03:03:29 +03:00
|
|
|
return err
|
2016-03-23 04:50:11 +03:00
|
|
|
}
|
|
|
|
cert, err := ioutil.ReadAll(f)
|
|
|
|
if err != nil {
|
2016-07-13 03:03:29 +03:00
|
|
|
return err
|
2016-03-23 04:50:11 +03:00
|
|
|
}
|
|
|
|
defer f.Close()
|
|
|
|
|
2015-12-30 03:23:27 +03:00
|
|
|
// Create, and start the lnwallet, which handles the core payment channel
|
|
|
|
// logic, and exposes control via proxy state machines.
|
2016-02-23 05:24:56 +03:00
|
|
|
config := &lnwallet.Config{
|
|
|
|
PrivatePass: []byte("hello"),
|
2016-03-23 04:50:11 +03:00
|
|
|
DataDir: filepath.Join(loadedConfig.DataDir, "lnwallet"),
|
2016-07-14 04:37:50 +03:00
|
|
|
RpcHost: fmt.Sprintf("%v:%v", loadedConfig.RPCHost, activeNetParams.rpcPort),
|
2016-03-23 04:50:11 +03:00
|
|
|
RpcUser: loadedConfig.RPCUser,
|
|
|
|
RpcPass: loadedConfig.RPCPass,
|
|
|
|
CACert: cert,
|
2016-07-14 04:37:50 +03:00
|
|
|
NetParams: activeNetParams.Params,
|
2016-02-23 05:24:56 +03:00
|
|
|
}
|
2016-03-25 00:32:55 +03:00
|
|
|
wallet, err := lnwallet.NewLightningWallet(config, chanDB)
|
2015-12-30 03:23:27 +03:00
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("unable to create wallet: %v\n", err)
|
2016-07-13 03:03:29 +03:00
|
|
|
return err
|
2015-12-30 03:23:27 +03:00
|
|
|
}
|
2016-03-25 00:32:55 +03:00
|
|
|
if err := wallet.Startup(); err != nil {
|
2015-12-30 03:23:27 +03:00
|
|
|
fmt.Printf("unable to start wallet: %v\n", err)
|
2016-07-13 03:03:29 +03:00
|
|
|
return err
|
2015-12-30 03:23:27 +03:00
|
|
|
}
|
2016-03-23 04:50:11 +03:00
|
|
|
ltndLog.Info("LightningWallet opened")
|
2015-12-30 05:59:16 +03:00
|
|
|
|
2016-03-25 00:32:55 +03:00
|
|
|
ec := &lnwallet.WaddrmgrEncryptorDecryptor{wallet.Manager}
|
|
|
|
chanDB.RegisterCryptoSystem(ec)
|
|
|
|
|
2016-01-17 06:09:41 +03:00
|
|
|
// Set up the core server which will listen for incoming peer
|
|
|
|
// connections.
|
2016-03-23 04:50:11 +03:00
|
|
|
defaultListenAddrs := []string{
|
|
|
|
net.JoinHostPort("", strconv.Itoa(loadedConfig.PeerPort)),
|
|
|
|
}
|
2016-03-25 00:32:55 +03:00
|
|
|
server, err := newServer(defaultListenAddrs, wallet, chanDB)
|
2016-01-17 06:09:41 +03:00
|
|
|
if err != nil {
|
2016-03-25 00:32:55 +03:00
|
|
|
srvrLog.Errorf("unable to create server: %v\n", err)
|
2016-07-13 03:03:29 +03:00
|
|
|
return err
|
2016-01-17 06:09:41 +03:00
|
|
|
}
|
|
|
|
server.Start()
|
|
|
|
|
2016-03-23 04:50:11 +03:00
|
|
|
addInterruptHandler(func() {
|
|
|
|
ltndLog.Infof("Gracefully shutting down the server...")
|
|
|
|
server.Stop()
|
|
|
|
server.WaitForShutdown()
|
|
|
|
})
|
|
|
|
|
2015-12-30 03:23:27 +03:00
|
|
|
// Initialize, and register our implementation of the gRPC server.
|
|
|
|
var opts []grpc.ServerOption
|
|
|
|
grpcServer := grpc.NewServer(opts...)
|
2016-01-17 06:09:41 +03:00
|
|
|
lnrpc.RegisterLightningServer(grpcServer, server.rpcServer)
|
2015-12-30 03:23:27 +03:00
|
|
|
|
|
|
|
// Finally, start the grpc server listening for HTTP/2 connections.
|
2016-02-23 05:24:56 +03:00
|
|
|
lis, err := net.Listen("tcp", fmt.Sprintf(":%d", loadedConfig.RPCPort))
|
2015-12-30 03:23:27 +03:00
|
|
|
if err != nil {
|
|
|
|
fmt.Printf("failed to listen: %v", err)
|
2016-07-13 03:03:29 +03:00
|
|
|
return err
|
2015-12-30 03:23:27 +03:00
|
|
|
}
|
2016-03-23 04:50:11 +03:00
|
|
|
go func() {
|
|
|
|
rpcsLog.Infof("RPC server listening on %s", lis.Addr())
|
|
|
|
grpcServer.Serve(lis)
|
|
|
|
}()
|
|
|
|
|
|
|
|
// Wait for shutdown signal from either a graceful server stop or from
|
|
|
|
// the interrupt handler.
|
|
|
|
<-shutdownChannel
|
|
|
|
ltndLog.Info("Shutdown complete")
|
2016-07-13 03:03:29 +03:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
// Use all processor cores.
|
|
|
|
// TODO(roasbeef): remove this if required version # is > 1.6?
|
|
|
|
runtime.GOMAXPROCS(runtime.NumCPU())
|
|
|
|
|
|
|
|
// Call the "real" main in a nested manner so the defers will properly
|
|
|
|
// be executed in the case of a graceful shutdown.
|
|
|
|
if err := lndMain(); err != nil {
|
2016-07-14 04:37:50 +03:00
|
|
|
fmt.Fprintln(os.Stderr, err)
|
2016-07-13 03:03:29 +03:00
|
|
|
os.Exit(1)
|
|
|
|
}
|
2015-12-17 03:42:52 +03:00
|
|
|
}
|