lnd+rpcserver: allow customized timeout in ConnectPeer
This commit is contained in:
8 files changed
+754
-668
No files matched your search
+18
-2
@@ -496,6 +496,14 @@ var connectCommand = cli.Command{
|
|||||||
Category: "Peers",
|
Category: "Peers",
|
||||||
Usage: "Connect to a remote lnd peer.",
|
Usage: "Connect to a remote lnd peer.",
|
||||||
ArgsUsage: "<pubkey>@host",
|
ArgsUsage: "<pubkey>@host",
|
||||||
|
Description: `
|
||||||
|
Connect to a peer using its <pubkey> and host.
|
||||||
|
|
||||||
|
A custom timeout on the connection is supported. For instance, to timeout
|
||||||
|
the connection request in 30 seconds, use the following:
|
||||||
|
|
||||||
|
lncli connect <pubkey>@host --timeout 30s
|
||||||
|
`,
|
||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
cli.BoolFlag{
|
cli.BoolFlag{
|
||||||
Name: "perm",
|
Name: "perm",
|
||||||
@@ -503,6 +511,13 @@ var connectCommand = cli.Command{
|
|||||||
"connect to the target peer.\n" +
|
"connect to the target peer.\n" +
|
||||||
" If not, the call will be synchronous.",
|
" If not, the call will be synchronous.",
|
||||||
},
|
},
|
||||||
|
cli.DurationFlag{
|
||||||
|
Name: "timeout",
|
||||||
|
Usage: "The connection timeout value for current request. " +
|
||||||
|
"Valid uints are {ms, s, m, h}.\n" +
|
||||||
|
"If not set, the global connection " +
|
||||||
|
"timeout value (default to 120s) is used.",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
Action: actionDecorator(connectPeer),
|
Action: actionDecorator(connectPeer),
|
||||||
}
|
}
|
||||||
@@ -524,8 +539,9 @@ func connectPeer(ctx *cli.Context) error {
|
|||||||
Host: splitAddr[1],
|
Host: splitAddr[1],
|
||||||
}
|
}
|
||||||
req := &lnrpc.ConnectPeerRequest{
|
req := &lnrpc.ConnectPeerRequest{
|
||||||
Addr: addr,
|
Addr: addr,
|
||||||
Perm: ctx.Bool("perm"),
|
Perm: ctx.Bool("perm"),
|
||||||
|
Timeout: uint64(ctx.Duration("timeout").Seconds()),
|
||||||
}
|
}
|
||||||
|
|
||||||
lnid, err := client.ConnectPeer(ctxb, req)
|
lnid, err := client.ConnectPeer(ctxb, req)
|
||||||
|
|||||||
@@ -191,21 +191,22 @@ type Config struct {
|
|||||||
// loadConfig function. We need to expose the 'raw' strings so the
|
// loadConfig function. We need to expose the 'raw' strings so the
|
||||||
// command line library can access them.
|
// command line library can access them.
|
||||||
// Only the parsed net.Addrs should be used!
|
// Only the parsed net.Addrs should be used!
|
||||||
RawRPCListeners []string `long:"rpclisten" description:"Add an interface/port/socket to listen for RPC connections"`
|
RawRPCListeners []string `long:"rpclisten" description:"Add an interface/port/socket to listen for RPC connections"`
|
||||||
RawRESTListeners []string `long:"restlisten" description:"Add an interface/port/socket to listen for REST connections"`
|
RawRESTListeners []string `long:"restlisten" description:"Add an interface/port/socket to listen for REST connections"`
|
||||||
RawListeners []string `long:"listen" description:"Add an interface/port to listen for peer connections"`
|
RawListeners []string `long:"listen" description:"Add an interface/port to listen for peer connections"`
|
||||||
RawExternalIPs []string `long:"externalip" description:"Add an ip:port to the list of local addresses we claim to listen on to peers. If a port is not specified, the default (9735) will be used regardless of other parameters"`
|
RawExternalIPs []string `long:"externalip" description:"Add an ip:port to the list of local addresses we claim to listen on to peers. If a port is not specified, the default (9735) will be used regardless of other parameters"`
|
||||||
ExternalHosts []string `long:"externalhosts" description:"A set of hosts that should be periodically resolved to announce IPs for"`
|
ExternalHosts []string `long:"externalhosts" description:"A set of hosts that should be periodically resolved to announce IPs for"`
|
||||||
RPCListeners []net.Addr
|
RPCListeners []net.Addr
|
||||||
RESTListeners []net.Addr
|
RESTListeners []net.Addr
|
||||||
RestCORS []string `long:"restcors" description:"Add an ip:port/hostname to allow cross origin access from. To allow all origins, set as \"*\"."`
|
RestCORS []string `long:"restcors" description:"Add an ip:port/hostname to allow cross origin access from. To allow all origins, set as \"*\"."`
|
||||||
Listeners []net.Addr
|
Listeners []net.Addr
|
||||||
ExternalIPs []net.Addr
|
ExternalIPs []net.Addr
|
||||||
DisableListen bool `long:"nolisten" description:"Disable listening for incoming peer connections"`
|
DisableListen bool `long:"nolisten" description:"Disable listening for incoming peer connections"`
|
||||||
DisableRest bool `long:"norest" description:"Disable REST API"`
|
DisableRest bool `long:"norest" description:"Disable REST API"`
|
||||||
NAT bool `long:"nat" description:"Toggle NAT traversal support (using either UPnP or NAT-PMP) to automatically advertise your external IP address to the network -- NOTE this does not support devices behind multiple NATs"`
|
NAT bool `long:"nat" description:"Toggle NAT traversal support (using either UPnP or NAT-PMP) to automatically advertise your external IP address to the network -- NOTE this does not support devices behind multiple NATs"`
|
||||||
MinBackoff time.Duration `long:"minbackoff" description:"Shortest backoff when reconnecting to persistent peers. Valid time units are {s, m, h}."`
|
MinBackoff time.Duration `long:"minbackoff" description:"Shortest backoff when reconnecting to persistent peers. Valid time units are {s, m, h}."`
|
||||||
MaxBackoff time.Duration `long:"maxbackoff" description:"Longest backoff when reconnecting to persistent peers. Valid time units are {s, m, h}."`
|
MaxBackoff time.Duration `long:"maxbackoff" description:"Longest backoff when reconnecting to persistent peers. Valid time units are {s, m, h}."`
|
||||||
|
ConnectionTimeout time.Duration `long:"connectiontimeout" description:"The timeout value for network connections. Valid time units are {ms, s, m, h}."`
|
||||||
|
|
||||||
DebugLevel string `short:"d" long:"debuglevel" description:"Logging level for all subsystems {trace, debug, info, warn, error, critical} -- You may also specify <subsystem>=<level>,<subsystem2>=<level>,... to set the log level for individual subsystems -- Use show to list available subsystems"`
|
DebugLevel string `short:"d" long:"debuglevel" description:"Logging level for all subsystems {trace, debug, info, warn, error, critical} -- You may also specify <subsystem>=<level>,<subsystem2>=<level>,... to set the log level for individual subsystems -- Use show to list available subsystems"`
|
||||||
|
|
||||||
@@ -374,6 +375,7 @@ func DefaultConfig() Config {
|
|||||||
NoSeedBackup: defaultNoSeedBackup,
|
NoSeedBackup: defaultNoSeedBackup,
|
||||||
MinBackoff: defaultMinBackoff,
|
MinBackoff: defaultMinBackoff,
|
||||||
MaxBackoff: defaultMaxBackoff,
|
MaxBackoff: defaultMaxBackoff,
|
||||||
|
ConnectionTimeout: tor.DefaultConnTimeout,
|
||||||
SubRPCServers: &subRPCServerConfigs{
|
SubRPCServers: &subRPCServerConfigs{
|
||||||
SignRPC: &signrpc.Config{},
|
SignRPC: &signrpc.Config{},
|
||||||
RouterRPC: routerrpc.DefaultConfig(),
|
RouterRPC: routerrpc.DefaultConfig(),
|
||||||
|
|||||||
+649
-637
File diff suppressed because it is too large.
Load diff
@@ -969,6 +969,12 @@ message ConnectPeerRequest {
|
|||||||
/* If set, the daemon will attempt to persistently connect to the target
|
/* If set, the daemon will attempt to persistently connect to the target
|
||||||
* peer. Otherwise, the call will be synchronous. */
|
* peer. Otherwise, the call will be synchronous. */
|
||||||
bool perm = 2;
|
bool perm = 2;
|
||||||
|
|
||||||
|
/*
|
||||||
|
The connection timeout value (in seconds) for this request. It won't affect
|
||||||
|
other requests.
|
||||||
|
*/
|
||||||
|
uint64 timeout = 3;
|
||||||
}
|
}
|
||||||
message ConnectPeerResponse {
|
message ConnectPeerResponse {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3223,6 +3223,11 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"format": "boolean",
|
"format": "boolean",
|
||||||
"description": "If set, the daemon will attempt to persistently connect to the target\npeer. Otherwise, the call will be synchronous."
|
"description": "If set, the daemon will attempt to persistently connect to the target\npeer. Otherwise, the call will be synchronous."
|
||||||
|
},
|
||||||
|
"timeout": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "uint64",
|
||||||
|
"description": "The connection timeout value (in seconds) for this request. It won't affect\nother requests."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
+19
-2
@@ -1512,8 +1512,25 @@ func (r *rpcServer) ConnectPeer(ctx context.Context,
|
|||||||
rpcsLog.Debugf("[connectpeer] requested connection to %x@%s",
|
rpcsLog.Debugf("[connectpeer] requested connection to %x@%s",
|
||||||
peerAddr.IdentityKey.SerializeCompressed(), peerAddr.Address)
|
peerAddr.IdentityKey.SerializeCompressed(), peerAddr.Address)
|
||||||
|
|
||||||
if err := r.server.ConnectToPeer(peerAddr, in.Perm); err != nil {
|
// By default, we will use the global connection timeout value.
|
||||||
rpcsLog.Errorf("[connectpeer]: error connecting to peer: %v", err)
|
timeout := r.cfg.ConnectionTimeout
|
||||||
|
|
||||||
|
// Check if the connection timeout is set. If set, we will use it in our
|
||||||
|
// request.
|
||||||
|
if in.Timeout != 0 {
|
||||||
|
timeout = time.Duration(in.Timeout) * time.Second
|
||||||
|
rpcsLog.Debugf(
|
||||||
|
"[connectpeer] connection timeout is set to %v",
|
||||||
|
timeout,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := r.server.ConnectToPeer(peerAddr,
|
||||||
|
in.Perm, timeout); err != nil {
|
||||||
|
|
||||||
|
rpcsLog.Errorf(
|
||||||
|
"[connectpeer]: error connecting to peer: %v", err,
|
||||||
|
)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -158,6 +158,9 @@
|
|||||||
; support devices behind multiple NATs.
|
; support devices behind multiple NATs.
|
||||||
; nat=true
|
; nat=true
|
||||||
|
|
||||||
|
; The timeout value for network connections in seconds, default to 120 seconds.
|
||||||
|
; Valid uints are {ms, s, m, h}.
|
||||||
|
; connectiontimeout=120s
|
||||||
|
|
||||||
; Debug logging level.
|
; Debug logging level.
|
||||||
; Valid levels are {trace, debug, info, warn, error, critical}
|
; Valid levels are {trace, debug, info, warn, error, critical}
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ import (
|
|||||||
"github.com/lightningnetwork/lnd/watchtower/wtclient"
|
"github.com/lightningnetwork/lnd/watchtower/wtclient"
|
||||||
"github.com/lightningnetwork/lnd/watchtower/wtdb"
|
"github.com/lightningnetwork/lnd/watchtower/wtdb"
|
||||||
"github.com/lightningnetwork/lnd/watchtower/wtpolicy"
|
"github.com/lightningnetwork/lnd/watchtower/wtpolicy"
|
||||||
|
"github.com/lightningnetwork/lnd/watchtower/wtserver"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -325,11 +326,11 @@ func parseAddr(address string, netCfg tor.Net) (net.Addr, error) {
|
|||||||
// noiseDial is a factory function which creates a connmgr compliant dialing
|
// noiseDial is a factory function which creates a connmgr compliant dialing
|
||||||
// function by returning a closure which includes the server's identity key.
|
// function by returning a closure which includes the server's identity key.
|
||||||
func noiseDial(idKey keychain.SingleKeyECDH,
|
func noiseDial(idKey keychain.SingleKeyECDH,
|
||||||
netCfg tor.Net) func(net.Addr) (net.Conn, error) {
|
netCfg tor.Net, timeout time.Duration) func(net.Addr) (net.Conn, error) {
|
||||||
|
|
||||||
return func(a net.Addr) (net.Conn, error) {
|
return func(a net.Addr) (net.Conn, error) {
|
||||||
lnAddr := a.(*lnwire.NetAddress)
|
lnAddr := a.(*lnwire.NetAddress)
|
||||||
return brontide.Dial(idKey, lnAddr, netCfg.Dial)
|
return brontide.Dial(idKey, lnAddr, timeout, netCfg.Dial)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1234,12 +1235,23 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// authDial is the wrapper around the btrontide.Dial for the
|
||||||
|
// watchtower.
|
||||||
|
authDial := func(localKey keychain.SingleKeyECDH,
|
||||||
|
netAddr *lnwire.NetAddress,
|
||||||
|
dialer tor.DialFunc) (wtserver.Peer, error) {
|
||||||
|
|
||||||
|
return brontide.Dial(
|
||||||
|
localKey, netAddr, cfg.ConnectionTimeout, dialer,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
s.towerClient, err = wtclient.New(&wtclient.Config{
|
s.towerClient, err = wtclient.New(&wtclient.Config{
|
||||||
Signer: cc.wallet.Cfg.Signer,
|
Signer: cc.wallet.Cfg.Signer,
|
||||||
NewAddress: newSweepPkScriptGen(cc.wallet),
|
NewAddress: newSweepPkScriptGen(cc.wallet),
|
||||||
SecretKeyRing: s.cc.keyRing,
|
SecretKeyRing: s.cc.keyRing,
|
||||||
Dial: cfg.net.Dial,
|
Dial: cfg.net.Dial,
|
||||||
AuthDial: wtclient.AuthDial,
|
AuthDial: authDial,
|
||||||
DB: towerClientDB,
|
DB: towerClientDB,
|
||||||
Policy: policy,
|
Policy: policy,
|
||||||
ChainHash: *s.cfg.ActiveNetParams.GenesisHash,
|
ChainHash: *s.cfg.ActiveNetParams.GenesisHash,
|
||||||
@@ -1330,8 +1342,10 @@ func newServer(cfg *Config, listenAddrs []net.Addr,
|
|||||||
OnAccept: s.InboundPeerConnected,
|
OnAccept: s.InboundPeerConnected,
|
||||||
RetryDuration: time.Second * 5,
|
RetryDuration: time.Second * 5,
|
||||||
TargetOutbound: 100,
|
TargetOutbound: 100,
|
||||||
Dial: noiseDial(s.identityECDH, s.cfg.net),
|
Dial: noiseDial(
|
||||||
OnConnection: s.OutboundPeerConnected,
|
s.identityECDH, s.cfg.net, s.cfg.ConnectionTimeout,
|
||||||
|
),
|
||||||
|
OnConnection: s.OutboundPeerConnected,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -1845,7 +1859,7 @@ func initNetworkBootstrappers(s *server) ([]discovery.NetworkPeerBootstrapper, e
|
|||||||
"seeds: %v", dnsSeeds)
|
"seeds: %v", dnsSeeds)
|
||||||
|
|
||||||
dnsBootStrapper := discovery.NewDNSSeedBootstrapper(
|
dnsBootStrapper := discovery.NewDNSSeedBootstrapper(
|
||||||
dnsSeeds, s.cfg.net,
|
dnsSeeds, s.cfg.net, s.cfg.ConnectionTimeout,
|
||||||
)
|
)
|
||||||
bootStrappers = append(bootStrappers, dnsBootStrapper)
|
bootStrappers = append(bootStrappers, dnsBootStrapper)
|
||||||
}
|
}
|
||||||
@@ -1968,7 +1982,10 @@ func (s *server) peerBootstrapper(numTargetPeers uint32,
|
|||||||
// TODO(roasbeef): can do AS, subnet,
|
// TODO(roasbeef): can do AS, subnet,
|
||||||
// country diversity, etc
|
// country diversity, etc
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
s.connectToPeer(a, errChan)
|
s.connectToPeer(
|
||||||
|
a, errChan,
|
||||||
|
s.cfg.ConnectionTimeout,
|
||||||
|
)
|
||||||
select {
|
select {
|
||||||
case err := <-errChan:
|
case err := <-errChan:
|
||||||
if err == nil {
|
if err == nil {
|
||||||
@@ -2070,7 +2087,9 @@ func (s *server) initialPeerBootstrap(ignore map[autopilot.NodeID]struct{},
|
|||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
|
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
go s.connectToPeer(addr, errChan)
|
go s.connectToPeer(
|
||||||
|
addr, errChan, s.cfg.ConnectionTimeout,
|
||||||
|
)
|
||||||
|
|
||||||
// We'll only allow this connection attempt to
|
// We'll only allow this connection attempt to
|
||||||
// take up to 3 seconds. This allows us to move
|
// take up to 3 seconds. This allows us to move
|
||||||
@@ -3381,7 +3400,9 @@ type openChanReq struct {
|
|||||||
// connection is established, or the initial handshake process fails.
|
// connection is established, or the initial handshake process fails.
|
||||||
//
|
//
|
||||||
// NOTE: This function is safe for concurrent access.
|
// NOTE: This function is safe for concurrent access.
|
||||||
func (s *server) ConnectToPeer(addr *lnwire.NetAddress, perm bool) error {
|
func (s *server) ConnectToPeer(addr *lnwire.NetAddress,
|
||||||
|
perm bool, timeout time.Duration) error {
|
||||||
|
|
||||||
targetPub := string(addr.IdentityKey.SerializeCompressed())
|
targetPub := string(addr.IdentityKey.SerializeCompressed())
|
||||||
|
|
||||||
// Acquire mutex, but use explicit unlocking instead of defer for
|
// Acquire mutex, but use explicit unlocking instead of defer for
|
||||||
@@ -3442,7 +3463,7 @@ func (s *server) ConnectToPeer(addr *lnwire.NetAddress, perm bool) error {
|
|||||||
// the crypto negotiation breaks down, then return an error to the
|
// the crypto negotiation breaks down, then return an error to the
|
||||||
// caller.
|
// caller.
|
||||||
errChan := make(chan error, 1)
|
errChan := make(chan error, 1)
|
||||||
s.connectToPeer(addr, errChan)
|
s.connectToPeer(addr, errChan, timeout)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case err := <-errChan:
|
case err := <-errChan:
|
||||||
@@ -3455,8 +3476,12 @@ func (s *server) ConnectToPeer(addr *lnwire.NetAddress, perm bool) error {
|
|||||||
// connectToPeer establishes a connection to a remote peer. errChan is used to
|
// connectToPeer establishes a connection to a remote peer. errChan is used to
|
||||||
// notify the caller if the connection attempt has failed. Otherwise, it will be
|
// notify the caller if the connection attempt has failed. Otherwise, it will be
|
||||||
// closed.
|
// closed.
|
||||||
func (s *server) connectToPeer(addr *lnwire.NetAddress, errChan chan<- error) {
|
func (s *server) connectToPeer(addr *lnwire.NetAddress,
|
||||||
conn, err := brontide.Dial(s.identityECDH, addr, s.cfg.net.Dial)
|
errChan chan<- error, timeout time.Duration) {
|
||||||
|
|
||||||
|
conn, err := brontide.Dial(
|
||||||
|
s.identityECDH, addr, timeout, s.cfg.net.Dial,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
srvrLog.Errorf("Unable to connect to %v: %v", addr, err)
|
srvrLog.Errorf("Unable to connect to %v: %v", addr, err)
|
||||||
select {
|
select {
|
||||||
|
|||||||
Reference in new issue
Block a user