lnd/channeldb/addr_source.go

84 lines
2.4 KiB
Go
Raw Normal View History

package channeldb
import (
"errors"
"net"
"github.com/btcsuite/btcd/btcec/v2"
)
// AddrSource is an interface that allow us to get the addresses for a target
// node. It may combine the results of multiple address sources.
type AddrSource interface {
// AddrsForNode returns all known addresses for the target node public
// key. The returned boolean must indicate if the given node is unknown
// to the backing source.
AddrsForNode(nodePub *btcec.PublicKey) (bool, []net.Addr, error)
}
// multiAddrSource is an implementation of AddrSource which gathers all the
// known addresses for a given node from multiple backends and de-duplicates the
// results.
type multiAddrSource struct {
sources []AddrSource
}
// NewMultiAddrSource constructs a new AddrSource which will query all the
// provided sources for a node's addresses and will then de-duplicate the
// results.
func NewMultiAddrSource(sources ...AddrSource) AddrSource {
return &multiAddrSource{
sources: sources,
}
}
// AddrsForNode returns all known addresses for the target node public key. It
// queries all the address sources provided and de-duplicates the results. The
// returned boolean is false only if none of the backing sources know of the
// node.
//
// NOTE: this implements the AddrSource interface.
func (c *multiAddrSource) AddrsForNode(nodePub *btcec.PublicKey) (bool,
[]net.Addr, error) {
if len(c.sources) == 0 {
return false, nil, errors.New("no address sources")
}
// The multiple address sources will likely contain duplicate addresses,
// so we use a map here to de-dup them.
dedupedAddrs := make(map[string]net.Addr)
// known will be set to true if any backing source is aware of the node.
var known bool
// Iterate over all the address sources and query each one for the
// addresses it has for the node in question.
for _, src := range c.sources {
isKnown, addrs, err := src.AddrsForNode(nodePub)
if err != nil {
return false, nil, err
}
if isKnown {
known = true
}
for _, addr := range addrs {
dedupedAddrs[addr.String()] = addr
}
}
// Convert the map into a list we can return.
addrs := make([]net.Addr, 0, len(dedupedAddrs))
for _, addr := range dedupedAddrs {
addrs = append(addrs, addr)
}
return known, addrs, nil
}
// A compile-time check to ensure that multiAddrSource implements the AddrSource
// interface.
var _ AddrSource = (*multiAddrSource)(nil)