server: add watchtower client
This commit is contained in:
parent
fb8214b808
commit
d2f3d5ef6c
17
lnd.go
17
lnd.go
@ -51,6 +51,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/macaroons"
|
"github.com/lightningnetwork/lnd/macaroons"
|
||||||
"github.com/lightningnetwork/lnd/signal"
|
"github.com/lightningnetwork/lnd/signal"
|
||||||
"github.com/lightningnetwork/lnd/walletunlocker"
|
"github.com/lightningnetwork/lnd/walletunlocker"
|
||||||
|
"github.com/lightningnetwork/lnd/watchtower/wtdb"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -313,11 +314,23 @@ func Main() error {
|
|||||||
"is proxying over Tor as well", cfg.Tor.StreamIsolation)
|
"is proxying over Tor as well", cfg.Tor.StreamIsolation)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the watchtower client should be active, open the client database.
|
||||||
|
// This is done here so that Close always executes when lndMain returns.
|
||||||
|
var towerClientDB *wtdb.ClientDB
|
||||||
|
if cfg.WtClient.IsActive() {
|
||||||
|
var err error
|
||||||
|
towerClientDB, err = wtdb.OpenClientDB(graphDir)
|
||||||
|
if err != nil {
|
||||||
|
ltndLog.Errorf("Unable to open watchtower client db: %v", err)
|
||||||
|
}
|
||||||
|
defer towerClientDB.Close()
|
||||||
|
}
|
||||||
|
|
||||||
// Set up the core server which will listen for incoming peer
|
// Set up the core server which will listen for incoming peer
|
||||||
// connections.
|
// connections.
|
||||||
server, err := newServer(
|
server, err := newServer(
|
||||||
cfg.Listeners, chanDB, activeChainControl, idPrivKey,
|
cfg.Listeners, chanDB, towerClientDB, activeChainControl,
|
||||||
walletInitParams.ChansToRestore,
|
idPrivKey, walletInitParams.ChansToRestore,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srvrLog.Errorf("unable to create server: %v\n", err)
|
srvrLog.Errorf("unable to create server: %v\n", err)
|
||||||
|
55
server.go
55
server.go
@ -50,6 +50,9 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/ticker"
|
"github.com/lightningnetwork/lnd/ticker"
|
||||||
"github.com/lightningnetwork/lnd/tor"
|
"github.com/lightningnetwork/lnd/tor"
|
||||||
"github.com/lightningnetwork/lnd/walletunlocker"
|
"github.com/lightningnetwork/lnd/walletunlocker"
|
||||||
|
"github.com/lightningnetwork/lnd/watchtower/wtclient"
|
||||||
|
"github.com/lightningnetwork/lnd/watchtower/wtdb"
|
||||||
|
"github.com/lightningnetwork/lnd/watchtower/wtpolicy"
|
||||||
"github.com/lightningnetwork/lnd/zpay32"
|
"github.com/lightningnetwork/lnd/zpay32"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -204,6 +207,8 @@ type server struct {
|
|||||||
|
|
||||||
sphinx *htlcswitch.OnionProcessor
|
sphinx *htlcswitch.OnionProcessor
|
||||||
|
|
||||||
|
towerClient wtclient.Client
|
||||||
|
|
||||||
connMgr *connmgr.ConnManager
|
connMgr *connmgr.ConnManager
|
||||||
|
|
||||||
sigPool *lnwallet.SigPool
|
sigPool *lnwallet.SigPool
|
||||||
@ -282,7 +287,8 @@ func noiseDial(idPriv *btcec.PrivateKey) func(net.Addr) (net.Conn, error) {
|
|||||||
|
|
||||||
// newServer creates a new instance of the server which is to listen using the
|
// newServer creates a new instance of the server which is to listen using the
|
||||||
// passed listener address.
|
// passed listener address.
|
||||||
func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
|
func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB,
|
||||||
|
towerClientDB *wtdb.ClientDB, cc *chainControl,
|
||||||
privKey *btcec.PrivateKey,
|
privKey *btcec.PrivateKey,
|
||||||
chansToRestore walletunlocker.ChannelsToRecover) (*server, error) {
|
chansToRestore walletunlocker.ChannelsToRecover) (*server, error) {
|
||||||
|
|
||||||
@ -1056,6 +1062,39 @@ func newServer(listenAddrs []net.Addr, chanDB *channeldb.DB, cc *chainControl,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.WtClient.IsActive() {
|
||||||
|
policy := wtpolicy.DefaultPolicy()
|
||||||
|
|
||||||
|
if cfg.WtClient.SweepFeeRate != 0 {
|
||||||
|
// We expose the sweep fee rate in sat/byte, but the
|
||||||
|
// tower protocol operations on sat/kw.
|
||||||
|
sweepRateSatPerByte := lnwallet.SatPerKVByte(
|
||||||
|
1000 * cfg.WtClient.SweepFeeRate,
|
||||||
|
)
|
||||||
|
policy.SweepFeeRate = sweepRateSatPerByte.FeePerKWeight()
|
||||||
|
}
|
||||||
|
|
||||||
|
s.towerClient, err = wtclient.New(&wtclient.Config{
|
||||||
|
Signer: cc.wallet.Cfg.Signer,
|
||||||
|
NewAddress: func() ([]byte, error) {
|
||||||
|
return newSweepPkScript(cc.wallet)
|
||||||
|
},
|
||||||
|
SecretKeyRing: s.cc.keyRing,
|
||||||
|
Dial: cfg.net.Dial,
|
||||||
|
AuthDial: wtclient.AuthDial,
|
||||||
|
DB: towerClientDB,
|
||||||
|
Policy: wtpolicy.DefaultPolicy(),
|
||||||
|
PrivateTower: cfg.WtClient.PrivateTowers[0],
|
||||||
|
ChainHash: *activeNetParams.GenesisHash,
|
||||||
|
MinBackoff: 10 * time.Second,
|
||||||
|
MaxBackoff: 5 * time.Minute,
|
||||||
|
ForceQuitDelay: wtclient.DefaultForceQuitDelay,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Create the connection manager which will be responsible for
|
// Create the connection manager which will be responsible for
|
||||||
// maintaining persistent outbound connections and also accepting new
|
// maintaining persistent outbound connections and also accepting new
|
||||||
// incoming connections
|
// incoming connections
|
||||||
@ -1128,6 +1167,12 @@ func (s *server) Start() error {
|
|||||||
startErr = err
|
startErr = err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if s.towerClient != nil {
|
||||||
|
if err := s.towerClient.Start(); err != nil {
|
||||||
|
startErr = err
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
if err := s.htlcSwitch.Start(); err != nil {
|
if err := s.htlcSwitch.Start(); err != nil {
|
||||||
startErr = err
|
startErr = err
|
||||||
return
|
return
|
||||||
@ -1290,6 +1335,14 @@ func (s *server) Stop() error {
|
|||||||
s.DisconnectPeer(peer.addr.IdentityKey)
|
s.DisconnectPeer(peer.addr.IdentityKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now that all connections have been torn down, stop the tower
|
||||||
|
// client which will reliably flush all queued states to the
|
||||||
|
// tower. If this is halted for any reason, the force quit timer
|
||||||
|
// will kick in and abort to allow this method to return.
|
||||||
|
if s.towerClient != nil {
|
||||||
|
s.towerClient.Stop()
|
||||||
|
}
|
||||||
|
|
||||||
// Wait for all lingering goroutines to quit.
|
// Wait for all lingering goroutines to quit.
|
||||||
s.wg.Wait()
|
s.wg.Wait()
|
||||||
|
|
||||||
|
@ -29,6 +29,11 @@ const (
|
|||||||
// DefaultStatInterval specifies the default interval between logging
|
// DefaultStatInterval specifies the default interval between logging
|
||||||
// metrics about the client's operation.
|
// metrics about the client's operation.
|
||||||
DefaultStatInterval = 30 * time.Second
|
DefaultStatInterval = 30 * time.Second
|
||||||
|
|
||||||
|
// DefaultForceQuitDelay specifies the default duration after which the
|
||||||
|
// client should abandon any pending updates or session negotiations
|
||||||
|
// before terminating.
|
||||||
|
DefaultForceQuitDelay = 10 * time.Second
|
||||||
)
|
)
|
||||||
|
|
||||||
// Client is the primary interface used by the daemon to control a client's
|
// Client is the primary interface used by the daemon to control a client's
|
||||||
|
Loading…
Reference in New Issue
Block a user