Skip to content
This repository was archived by the owner on Jun 25, 2024. It is now read-only.

Commit 747161a

Browse files
committed
lnd: add config option for specifying particular peers to connect to
1 parent 3133154 commit 747161a

File tree

4 files changed

+67
-14
lines changed

4 files changed

+67
-14
lines changed

config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ type Config struct {
293293
WSPingInterval time.Duration `long:"ws-ping-interval" description:"The ping interval for REST based WebSocket connections, set to 0 to disable sending ping messages from the server side"`
294294
WSPongWait time.Duration `long:"ws-pong-wait" description:"The time we wait for a pong response message on REST based WebSocket connections before the connection is closed as inactive"`
295295
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"`
296+
AddPeers []string `long:"addpeer" description:"Specify peers to connect to first"`
296297
MinBackoff time.Duration `long:"minbackoff" description:"Shortest backoff when reconnecting to persistent peers. Valid time units are {s, m, h}."`
297298
MaxBackoff time.Duration `long:"maxbackoff" description:"Longest backoff when reconnecting to persistent peers. Valid time units are {s, m, h}."`
298299
ConnectionTimeout time.Duration `long:"connectiontimeout" description:"The timeout value for network connections. Valid time units are {ms, s, m, h}."`

lncfg/address.go

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -278,12 +278,33 @@ func ParseAddressString(strAddress string, defaultPort string,
278278
func ParseLNAddressString(strAddress string, defaultPort string,
279279
tcpResolver TCPResolver) (*lnwire.NetAddress, error) {
280280

281+
pubKey, parsedAddr, err := ParseLNAddressPubkey(strAddress)
282+
if err != nil {
283+
return nil, err
284+
}
285+
286+
// Finally, parse the address string using our generic address parser.
287+
addr, err := ParseAddressString(parsedAddr, defaultPort, tcpResolver)
288+
if err != nil {
289+
return nil, fmt.Errorf("invalid lightning address address: %v", err)
290+
}
291+
292+
return &lnwire.NetAddress{
293+
IdentityKey: pubKey,
294+
Address: addr,
295+
}, nil
296+
}
297+
298+
// ParseLNAddressPubkey converts a string of the form <pubkey>@<addr> into two
299+
// pieces: the pubkey bytes and an addr string. It validates that the pubkey
300+
// is of a valid form.
301+
func ParseLNAddressPubkey(strAddress string) (*btcec.PublicKey, string, error) {
281302
// Split the address string around the @ sign.
282303
parts := strings.Split(strAddress, "@")
283304

284305
// The string is malformed if there are not exactly two parts.
285306
if len(parts) != 2 {
286-
return nil, fmt.Errorf("invalid lightning address %s: "+
307+
return nil, "", fmt.Errorf("invalid lightning address %s: "+
287308
"must be of the form <pubkey-hex>@<addr>", strAddress)
288309
}
289310

@@ -294,32 +315,23 @@ func ParseLNAddressString(strAddress string, defaultPort string,
294315
// Decode the hex pubkey to get the raw compressed pubkey bytes.
295316
pubKeyBytes, err := hex.DecodeString(parsedPubKey)
296317
if err != nil {
297-
return nil, fmt.Errorf("invalid lightning address pubkey: %v", err)
318+
return nil, "", fmt.Errorf("invalid lightning address pubkey: %v", err)
298319
}
299320

300321
// The compressed pubkey should have a length of exactly 33 bytes.
301322
if len(pubKeyBytes) != 33 {
302-
return nil, fmt.Errorf("invalid lightning address pubkey: "+
323+
return nil, "", fmt.Errorf("invalid lightning address pubkey: "+
303324
"length must be 33 bytes, found %d", len(pubKeyBytes))
304325
}
305326

306327
// Parse the pubkey bytes to verify that it corresponds to valid public
307328
// key on the secp256k1 curve.
308329
pubKey, err := btcec.ParsePubKey(pubKeyBytes)
309330
if err != nil {
310-
return nil, fmt.Errorf("invalid lightning address pubkey: %v", err)
311-
}
312-
313-
// Finally, parse the address string using our generic address parser.
314-
addr, err := ParseAddressString(parsedAddr, defaultPort, tcpResolver)
315-
if err != nil {
316-
return nil, fmt.Errorf("invalid lightning address address: %v", err)
331+
return nil, "", fmt.Errorf("invalid lightning address pubkey: %v", err)
317332
}
318333

319-
return &lnwire.NetAddress{
320-
IdentityKey: pubKey,
321-
Address: addr,
322-
}, nil
334+
return pubKey, parsedAddr, nil
323335
}
324336

325337
// verifyPort makes sure that an address string has both a host and a port. If

sample-lnd.conf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,9 @@
183183
; Disable TLS for the REST API.
184184
; no-rest-tls=true
185185

186+
; Specify peer(s) to connect to first.
187+
; addpeer=
188+
186189
; The ping interval for REST based WebSocket connections, set to 0 to disable
187190
; sending ping messages from the server side. Valid time units are {s, m, h}.
188191
; ws-ping-interval=30s

server.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1905,6 +1905,43 @@ func (s *server) Start() error {
19051905
return nil
19061906
})
19071907

1908+
// If peers are specified as a config option, we'll add those
1909+
// peers first.
1910+
for _, peerAddrCfg := range s.cfg.AddPeers {
1911+
parsedPubkey, parsedHost, err := lncfg.ParseLNAddressPubkey(
1912+
peerAddrCfg,
1913+
)
1914+
if err != nil {
1915+
startErr = fmt.Errorf("unable to parse peer "+
1916+
"pubkey from config: %v", err)
1917+
return
1918+
}
1919+
addr, err := parseAddr(parsedHost, s.cfg.net)
1920+
if err != nil {
1921+
startErr = fmt.Errorf("unable to parse peer "+
1922+
"address provided as a config option: "+
1923+
"%v", err)
1924+
return
1925+
}
1926+
1927+
peerAddr := &lnwire.NetAddress{
1928+
IdentityKey: parsedPubkey,
1929+
Address: addr,
1930+
ChainNet: s.cfg.ActiveNetParams.Net,
1931+
}
1932+
1933+
err = s.ConnectToPeer(
1934+
peerAddr, true,
1935+
s.cfg.ConnectionTimeout,
1936+
)
1937+
if err != nil {
1938+
startErr = fmt.Errorf("unable to connect to "+
1939+
"peer address provided as a config "+
1940+
"option: %v", err)
1941+
return
1942+
}
1943+
}
1944+
19081945
// Subscribe to NodeAnnouncements that advertise new addresses
19091946
// our persistent peers.
19101947
if err := s.updatePersistentPeerAddrs(); err != nil {

0 commit comments

Comments
 (0)