discovery: remove retries from DNS based SampleNodeAddrs, allow down seeds
In this commit, we modify the `SampleNodeAddrs` method to no longer retry itself. Instead, we'll now leave this task to the caller of the this method. Additionally, we'll no longer return with an error if we can't hit a particular seed. Instead, we'll log the error and move onto the next seed. Finally, we'll also no longer require that the DNS seed has a secondary seed in order to support a wider array of DNS seeds.
This commit is contained in:
parent
7f48ff6717
commit
9c957193cf
@ -379,135 +379,146 @@ func (d *DNSSeedBootstrapper) SampleNodeAddrs(numAddrs uint32,
|
|||||||
|
|
||||||
var netAddrs []*lnwire.NetAddress
|
var netAddrs []*lnwire.NetAddress
|
||||||
|
|
||||||
// We'll continue this loop until we reach our target address limit.
|
// We'll try all the registered DNS seeds, exiting early if one of them
|
||||||
// Each SRV query to the seed will return 25 random nodes, so we can
|
// gives us all the peers we need.
|
||||||
// continue to query until we reach our target.
|
//
|
||||||
|
// TODO(roasbeef): should combine results from both
|
||||||
search:
|
search:
|
||||||
for uint32(len(netAddrs)) < numAddrs {
|
for _, dnsSeedTuple := range d.dnsSeeds {
|
||||||
for _, dnsSeedTuple := range d.dnsSeeds {
|
// We'll first query the seed with an SRV record so we can
|
||||||
// We'll first query the seed with an SRV record so we
|
// obtain a random sample of the encoded public keys of nodes.
|
||||||
// can obtain a random sample of the encoded public
|
// We use the lndLookupSRV function for this task.
|
||||||
// keys of nodes. We use the lndLookupSRV function for
|
primarySeed := dnsSeedTuple[0]
|
||||||
// this task.
|
_, addrs, err := d.net.LookupSRV("nodes", "tcp", primarySeed)
|
||||||
primarySeed := dnsSeedTuple[0]
|
if err != nil {
|
||||||
_, addrs, err := d.net.LookupSRV("nodes", "tcp", primarySeed)
|
log.Tracef("Unable to lookup SRV records via "+
|
||||||
if err != nil {
|
"primary seed (%v): %v", primarySeed, err)
|
||||||
log.Tracef("Unable to lookup SRV records via "+
|
|
||||||
"primary seed: %v", err)
|
|
||||||
|
|
||||||
log.Trace("Falling back to secondary")
|
log.Trace("Falling back to secondary")
|
||||||
|
|
||||||
// If the host of the secondary seed is blank,
|
// If the host of the secondary seed is blank, then
|
||||||
// then we'll bail here as we can't proceed.
|
// we'll bail here as we can't proceed.
|
||||||
if dnsSeedTuple[1] == "" {
|
if dnsSeedTuple[1] == "" {
|
||||||
return nil, fmt.Errorf("Secondary seed is blank")
|
log.Tracef("DNS seed %v has no secondary, "+
|
||||||
}
|
"skipping fallback", primarySeed)
|
||||||
|
continue
|
||||||
// If we get an error when trying to query via
|
|
||||||
// the primary seed, we'll fallback to the
|
|
||||||
// secondary seed before concluding failure.
|
|
||||||
soaShim := dnsSeedTuple[1]
|
|
||||||
addrs, err = d.fallBackSRVLookup(
|
|
||||||
soaShim, primarySeed,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
log.Tracef("Successfully queried fallback DNS seed")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Tracef("Retrieved SRV records from dns seed: %v",
|
// If we get an error when trying to query via the
|
||||||
spew.Sdump(addrs))
|
// primary seed, we'll fallback to the secondary seed
|
||||||
|
// before concluding failure.
|
||||||
|
soaShim := dnsSeedTuple[1]
|
||||||
|
addrs, err = d.fallBackSRVLookup(
|
||||||
|
soaShim, primarySeed,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Tracef("Unable to query fall "+
|
||||||
|
"back dns seed (%v): %v", soaShim, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Next, we'll need to issue an A record request for
|
log.Tracef("Successfully queried fallback DNS seed")
|
||||||
// each of the nodes, skipping it if nothing comes
|
}
|
||||||
// back.
|
|
||||||
for _, nodeSrv := range addrs {
|
|
||||||
if uint32(len(netAddrs)) >= numAddrs {
|
|
||||||
break search
|
|
||||||
}
|
|
||||||
|
|
||||||
// With the SRV target obtained, we'll now
|
log.Tracef("Retrieved SRV records from dns seed: %v",
|
||||||
// perform another query to obtain the IP
|
newLogClosure(func() string {
|
||||||
// address for the matching bech32 encoded node
|
return spew.Sdump(addrs)
|
||||||
// key. We use the lndLookup function for this
|
}),
|
||||||
// task.
|
)
|
||||||
bechNodeHost := nodeSrv.Target
|
|
||||||
addrs, err := d.net.LookupHost(bechNodeHost)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(addrs) == 0 {
|
// Next, we'll need to issue an A record request for each of
|
||||||
log.Tracef("No addresses for %v, skipping",
|
// the nodes, skipping it if nothing comes back.
|
||||||
bechNodeHost)
|
for _, nodeSrv := range addrs {
|
||||||
|
if uint32(len(netAddrs)) >= numAddrs {
|
||||||
|
break search
|
||||||
|
}
|
||||||
|
|
||||||
|
// With the SRV target obtained, we'll now perform
|
||||||
|
// another query to obtain the IP address for the
|
||||||
|
// matching bech32 encoded node key. We use the
|
||||||
|
// lndLookup function for this task.
|
||||||
|
bechNodeHost := nodeSrv.Target
|
||||||
|
addrs, err := d.net.LookupHost(bechNodeHost)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(addrs) == 0 {
|
||||||
|
log.Tracef("No addresses for %v, skipping",
|
||||||
|
bechNodeHost)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Tracef("Attempting to convert: %v", bechNodeHost)
|
||||||
|
|
||||||
|
// If the host isn't correctly formatted, then we'll
|
||||||
|
// skip it.
|
||||||
|
if len(bechNodeHost) == 0 ||
|
||||||
|
!strings.Contains(bechNodeHost, ".") {
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have a set of valid addresses, then we'll need
|
||||||
|
// to parse the public key from the original bech32
|
||||||
|
// encoded string.
|
||||||
|
bechNode := strings.Split(bechNodeHost, ".")
|
||||||
|
_, nodeBytes5Bits, err := bech32.Decode(bechNode[0])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once we have the bech32 decoded pubkey, we'll need
|
||||||
|
// to convert the 5-bit word grouping into our regular
|
||||||
|
// 8-bit word grouping so we can convert it into a
|
||||||
|
// public key.
|
||||||
|
nodeBytes, err := bech32.ConvertBits(
|
||||||
|
nodeBytes5Bits, 5, 8, false,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
nodeKey, err := btcec.ParsePubKey(
|
||||||
|
nodeBytes, btcec.S256(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have an ignore list, and this node is in the
|
||||||
|
// ignore list, then we'll go to the next candidate.
|
||||||
|
if ignore != nil {
|
||||||
|
nID := autopilot.NewNodeID(nodeKey)
|
||||||
|
if _, ok := ignore[nID]; ok {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Tracef("Attempting to convert: %v", bechNodeHost)
|
|
||||||
|
|
||||||
// If we have a set of valid addresses, then
|
|
||||||
// we'll need to parse the public key from the
|
|
||||||
// original bech32 encoded string.
|
|
||||||
bechNode := strings.Split(bechNodeHost, ".")
|
|
||||||
_, nodeBytes5Bits, err := bech32.Decode(bechNode[0])
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Once we have the bech32 decoded pubkey,
|
|
||||||
// we'll need to convert the 5-bit word
|
|
||||||
// grouping into our regular 8-bit word
|
|
||||||
// grouping so we can convert it into a public
|
|
||||||
// key.
|
|
||||||
nodeBytes, err := bech32.ConvertBits(
|
|
||||||
nodeBytes5Bits, 5, 8, false,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
nodeKey, err := btcec.ParsePubKey(
|
|
||||||
nodeBytes, btcec.S256(),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have an ignore list, and this node is
|
|
||||||
// in the ignore list, then we'll go to the
|
|
||||||
// next candidate.
|
|
||||||
if ignore != nil {
|
|
||||||
nID := autopilot.NewNodeID(nodeKey)
|
|
||||||
if _, ok := ignore[nID]; ok {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally we'll convert the host:port peer to
|
|
||||||
// a proper TCP address to use within the
|
|
||||||
// lnwire.NetAddress. We don't need to use
|
|
||||||
// the lndResolveTCP function here because we
|
|
||||||
// already have the host:port peer.
|
|
||||||
addr := net.JoinHostPort(addrs[0],
|
|
||||||
strconv.FormatUint(uint64(nodeSrv.Port), 10))
|
|
||||||
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, with all the information parsed,
|
|
||||||
// we'll return this fully valid address as a
|
|
||||||
// connection attempt.
|
|
||||||
lnAddr := &lnwire.NetAddress{
|
|
||||||
IdentityKey: nodeKey,
|
|
||||||
Address: tcpAddr,
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Tracef("Obtained %v as valid reachable "+
|
|
||||||
"node", lnAddr)
|
|
||||||
|
|
||||||
netAddrs = append(netAddrs, lnAddr)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Finally we'll convert the host:port peer to a proper
|
||||||
|
// TCP address to use within the lnwire.NetAddress. We
|
||||||
|
// don't need to use the lndResolveTCP function here
|
||||||
|
// because we already have the host:port peer.
|
||||||
|
addr := net.JoinHostPort(
|
||||||
|
addrs[0],
|
||||||
|
strconv.FormatUint(uint64(nodeSrv.Port), 10),
|
||||||
|
)
|
||||||
|
tcpAddr, err := net.ResolveTCPAddr("tcp", addr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, with all the information parsed, we'll
|
||||||
|
// return this fully valid address as a connection
|
||||||
|
// attempt.
|
||||||
|
lnAddr := &lnwire.NetAddress{
|
||||||
|
IdentityKey: nodeKey,
|
||||||
|
Address: tcpAddr,
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Tracef("Obtained %v as valid reachable "+
|
||||||
|
"node", lnAddr)
|
||||||
|
|
||||||
|
netAddrs = append(netAddrs, lnAddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user