lnd+rpcserver: allow customized timeout in ConnectPeer

This commit is contained in:
yyforyongyu committed 2020-09-16 11:50:04 +08:00
1 parent ef38b12fda
commit 469aba9282
8 files changed
+754 -668

No files matched your search

+18 -2
View File
@@ -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)
+17 -15
View File
@@ -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
View File
File diff suppressed because it is too large. Load diff
+6
View File
@@ -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 {
} }
+5
View File
@@ -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
View File
@@ -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
} }
+3
View File
@@ -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}
+37 -12
View File
@@ -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 {