Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/blocksync/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ func makePeerManager(peers map[types.NodeID]testPeer) *p2p.PeerManager {
MaxConnectedUpgrade: 2,
}, p2p.NopMetrics())
for nodeId := range peers {
_, err := peerManager.Add(p2p.NodeAddress{Protocol: "memory", NodeID: nodeId})
_, err := peerManager.Add(p2p.NodeAddress{NodeID: nodeId, Hostname: "a.com", Port: 1234})
peerManager.MarkReadyConnected(nodeId)
if err != nil {
panic(err)
Expand Down
74 changes: 8 additions & 66 deletions internal/p2p/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,8 @@ var (
// is expected to contain a node ID.
type NodeAddress struct {
NodeID types.NodeID
Protocol Protocol
Hostname string
Port uint16
Path string
}

// ParseNodeAddress parses a node address URL into a NodeAddress, normalizing
Expand All @@ -47,15 +45,13 @@ func ParseNodeAddress(urlString string) (NodeAddress, error) {
url, err := url.Parse(urlString)
if (err != nil || url.Scheme == "") &&
(!stringHasScheme(urlString) || reSchemeIsHost.MatchString(urlString)) {
url, err = url.Parse(string(defaultProtocol) + "://" + urlString)
url, err = url.Parse("mconn://" + urlString)
}
if err != nil {
return NodeAddress{}, fmt.Errorf("invalid node address %q: %w", urlString, err)
}

address := NodeAddress{
Protocol: Protocol(strings.ToLower(url.Scheme)),
}
address := NodeAddress{}

// Opaque URLs are expected to contain only a node ID.
if url.Opaque != "" {
Expand All @@ -77,45 +73,12 @@ func ParseNodeAddress(urlString string) (NodeAddress, error) {
}
address.Port = uint16(port64)
}

address.Path = url.Path
if url.RawQuery != "" {
address.Path += "?" + url.RawQuery
}
if url.Fragment != "" {
address.Path += "#" + url.Fragment
}
if address.Path != "" {
switch address.Path[0] {
case '/', '#', '?':
default:
address.Path = "/" + address.Path
}
}

return address, address.Validate()
}

// Resolve resolves a NodeAddress into a set of Endpoints, by expanding
// out a DNS hostname to IP addresses.
func (a NodeAddress) Resolve(ctx context.Context) ([]Endpoint, error) {
if a.Protocol == "" {
return nil, errors.New("address has no protocol")
}

// If there is no hostname, this is an opaque URL in the form
// "scheme:opaque", and the opaque part is assumed to be node ID used as
// Path.
if a.Hostname == "" {
if a.NodeID == "" {
return nil, errors.New("local address has no node ID")
}
return []Endpoint{{
Protocol: a.Protocol,
Path: string(a.NodeID),
}}, nil
}

ips, err := net.DefaultResolver.LookupIP(ctx, "ip", a.Hostname)
if err != nil {
return nil, err
Expand All @@ -126,48 +89,27 @@ func (a NodeAddress) Resolve(ctx context.Context) ([]Endpoint, error) {
if !ok {
return nil, fmt.Errorf("LookupIP returned invalid IP %q", ip)
}
endpoints[i] = Endpoint{
Protocol: a.Protocol,
Addr: netip.AddrPortFrom(ip, a.Port),
Path: a.Path,
}
endpoints[i] = Endpoint{netip.AddrPortFrom(ip, a.Port)}
}
return endpoints, nil
}

// String formats the address as a URL string.
func (a NodeAddress) String() string {
u := url.URL{Scheme: string(a.Protocol)}
u := url.URL{Scheme: "mconn"}
if a.NodeID != "" {
u.User = url.User(string(a.NodeID))
}
switch {
case a.Hostname != "":
if a.Port > 0 {
u.Host = net.JoinHostPort(a.Hostname, strconv.Itoa(int(a.Port)))
} else {
u.Host = a.Hostname
}
u.Path = a.Path

case a.Protocol != "" && (a.Path == "" || a.Path == string(a.NodeID)):
u.User = nil
u.Opaque = string(a.NodeID) // e.g. memory:id

case a.Path != "" && a.Path[0] != '/':
u.Path = "/" + a.Path // e.g. some/path

default:
u.Path = a.Path // e.g. /some/path
if a.Port > 0 {
u.Host = net.JoinHostPort(a.Hostname, strconv.Itoa(int(a.Port)))
} else {
u.Host = a.Hostname
}
return strings.TrimPrefix(u.String(), "//")
}

// Validate validates a NodeAddress.
func (a NodeAddress) Validate() error {
if a.Protocol == "" {
return errors.New("no protocol")
}
if a.NodeID == "" {
return errors.New("no peer ID")
} else if err := a.NodeID.Validate(); err != nil {
Expand Down
Loading