From 758776017d3e7818f5af23db359a028c0342d7df Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 9 Feb 2026 01:49:09 -0600 Subject: [PATCH 1/8] server: Consolidate address ver selection logic. This consolidates the logic for choosing which version address message to send to the remote peers based on the protocol version to a single function and updates the callers to make use of it. --- server.go | 72 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 37 insertions(+), 35 deletions(-) diff --git a/server.go b/server.go index 4bc0ad2ec..adb2b1668 100644 --- a/server.go +++ b/server.go @@ -1039,9 +1039,9 @@ func addrmgrToWireNetAddressV2(netAddr *addrmgr.NetAddress) wire.NetAddressV2 { netAddr.Timestamp, netAddr.Services) } -// pushAddrMsg sends an addr message to the connected peer using the provided -// addresses. -func (sp *serverPeer) pushAddrMsg(addresses []*addrmgr.NetAddress) { +// pushAddrV1Msg sends a legacy version 1 addr message to the connected peer +// using the provided addresses. +func (sp *serverPeer) pushAddrV1Msg(addresses []*addrmgr.NetAddress) { // Filter addresses already known to the peer. addrs := make([]*wire.NetAddress, 0, len(addresses)) for _, addr := range addresses { @@ -1061,6 +1061,36 @@ func (sp *serverPeer) pushAddrMsg(addresses []*addrmgr.NetAddress) { sp.addKnownAddresses(knownNetAddrs) } +// pushAddrV2Msg sends an addrv2 message to the connected peer using the +// provided addresses. +func (sp *serverPeer) pushAddrV2Msg(addresses []*addrmgr.NetAddress) { + // Filter addresses already known to the peer. + addrs := make([]wire.NetAddressV2, 0, len(addresses)) + for _, addr := range addresses { + if !sp.addressKnown(addr) { + wireNetAddr := addrmgrToWireNetAddressV2(addr) + addrs = append(addrs, wireNetAddr) + } + } + known := sp.PushAddrV2Msg(addrs) + knownNetAddrs, err := wireToAddrmgrNetAddressesV2(known) + if err != nil { + peerLog.Errorf("Failed to convert known addresses: %v", err) + return + } + sp.addKnownAddresses(knownNetAddrs) +} + +// pushAddrMsg sends an appropriate version address message to the connected +// peer using the provided addresses depending on the protocol version. +func (sp *serverPeer) pushAddrMsg(pver uint32, addresses []*addrmgr.NetAddress) { + if pver >= wire.AddrV2Version { + sp.pushAddrV2Msg(addresses) + return + } + sp.pushAddrV1Msg(addresses) +} + // addBanScore increases the persistent and decaying ban score fields by the // provided values unless banning is disabled. // @@ -1130,26 +1160,6 @@ func natfSupported(pver uint32) addrmgr.NetAddressTypeFilter { return isSupportedNetAddressTypeV2 } -// pushAddrV2Msg sends an addrv2 message to the connected peer using the -// provided addresses. -func (sp *serverPeer) pushAddrV2Msg(addresses []*addrmgr.NetAddress) { - // Filter addresses already known to the peer. - addrs := make([]wire.NetAddressV2, 0, len(addresses)) - for _, addr := range addresses { - if !sp.addressKnown(addr) { - wireNetAddr := addrmgrToWireNetAddressV2(addr) - addrs = append(addrs, wireNetAddr) - } - } - known := sp.PushAddrV2Msg(addrs) - knownNetAddrs, err := wireToAddrmgrNetAddressesV2(known) - if err != nil { - peerLog.Errorf("Failed to convert known addresses: %v", err) - return - } - sp.addKnownAddresses(knownNetAddrs) -} - // NA returns the address manager network address for the peer. // // This method shadows the embedded peer.Peer.NA() method to provide the @@ -1258,16 +1268,12 @@ func (sp *serverPeer) OnVersion(_ *peer.Peer, msg *wire.MsgVersion) { // known tip. if !cfg.DisableListen && sp.server.syncManager.IsCurrent() { // Get address that best matches. - msgProtocolVersion := uint32(msg.ProtocolVersion) - addrTypeFilter := natfSupported(msgProtocolVersion) + pver := uint32(msg.ProtocolVersion) + addrTypeFilter := natfSupported(pver) lna := addrManager.GetBestLocalAddress(remoteAddr, addrTypeFilter) if lna.IsRoutable() { addresses := []*addrmgr.NetAddress{lna} - if msgProtocolVersion >= wire.AddrV2Version { - sp.pushAddrV2Msg(addresses) - } else { - sp.pushAddrMsg(addresses) - } + sp.pushAddrMsg(pver, addresses) } else { srvrLog.Debugf("Local address %s is not routable and will not "+ "be broadcast to outbound peer %v", lna.Key(), sp.Addr()) @@ -1863,11 +1869,7 @@ func (sp *serverPeer) OnGetAddr(_ *peer.Peer, msg *wire.MsgGetAddr) { addrCache := sp.server.addrManager.AddressCache(addrTypeFilter) // Push addresses using version-appropriate message type. - if pver >= wire.AddrV2Version { - sp.pushAddrV2Msg(addrCache) - } else { - sp.pushAddrMsg(addrCache) - } + sp.pushAddrMsg(pver, addrCache) } // OnAddr is invoked when a peer receives an addr wire message and is used to From 5fac911d8791c5702cc20eee6da38a1037e831cc Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 9 Feb 2026 01:50:30 -0600 Subject: [PATCH 2/8] multi: Remove several MsgAddrV2 methods. The vast majority of the code in the wire package was written nearly a decade and a half ago when Go was still quite new and many of the patterns are less than ideal as a result. For example, methods that add items one at a time along with a conditional check are inefficient and realistically unnecessary because the caller is already expected to make use of the exported constants to avoid errors to begin with and the messages will fail to encode and decode if they exceed the max allowed anyway. Not only that, in order to allow those types of methods and avoid a bunch of additional allocations due to multiple appends, the constructors have to create a slice with a large capacity with no information as to what a good guess would be which is rather wasteful. So, in practice, callers are much better off just creating the list with the exact size they know they need and set it at message creation time. Unfortunately, since the wire package is used as the base of virtually every single other package, changing the API in a breaking way that would cause a major module version bump would be a massive undertaking and thus care has been taken to avoid requiring one. However, the new MsgAddrV2 type was just added and a new version has not been tagged yet, so it is safe to modify the API for the message in a breaking way. With the aforementioned in mind, this removes the AddAddress, AddAddresses, and ClearAddresses methods from the newly introduced MsgAddrV2 type. --- peer/peer.go | 7 ++---- peer/peer_test.go | 9 ++++---- wire/message_test.go | 8 +++---- wire/msgaddrv2.go | 48 ++++++++---------------------------------- wire/msgaddrv2_test.go | 46 +++++----------------------------------- 5 files changed, 25 insertions(+), 93 deletions(-) diff --git a/peer/peer.go b/peer/peer.go index 679544b70..36e5fac49 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -1,5 +1,5 @@ // Copyright (c) 2013-2016 The btcsuite developers -// Copyright (c) 2016-2025 The Decred developers +// Copyright (c) 2016-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -898,10 +898,7 @@ func (p *Peer) PushAddrV2Msg(addresses []wire.NetAddressV2) []wire.NetAddressV2 addrs = addrs[:wire.MaxAddrPerV2Msg] } - msg := wire.NewMsgAddrV2() - msg.AddrList = addrs - - p.QueueMessage(msg, nil) + p.QueueMessage(wire.NewMsgAddrV2(addrs), nil) return addrs } diff --git a/peer/peer_test.go b/peer/peer_test.go index 2fae203f1..ea08f87b9 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2015-2016 The btcsuite developers -// Copyright (c) 2016-2025 The Decred developers +// Copyright (c) 2016-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -477,9 +477,10 @@ func TestPeerListeners(t *testing.T) { }, { listener: "OnAddrV2", msg: func() *wire.MsgAddrV2 { - msg := wire.NewMsgAddrV2() - msg.AddAddress(wire.NewNetAddressV2(wire.IPv4Address, - net.ParseIP("127.0.0.1").To4(), 8333, time.Now(), wire.SFNodeNetwork)) + ipv4Localhost := net.ParseIP("127.0.0.1").To4() + addr := wire.NewNetAddressV2(wire.IPv4Address, ipv4Localhost, 8333, + time.Now(), wire.SFNodeNetwork) + msg := wire.NewMsgAddrV2([]wire.NetAddressV2{addr}) return msg }(), pver: pver, diff --git a/wire/message_test.go b/wire/message_test.go index 43f55a2bc..58ad7bbe6 100644 --- a/wire/message_test.go +++ b/wire/message_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2013-2016 The btcsuite developers -// Copyright (c) 2015-2025 The Decred developers +// Copyright (c) 2015-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -59,9 +59,9 @@ func TestMessage(t *testing.T) { msgVerack := NewMsgVerAck() msgGetAddr := NewMsgGetAddr() msgAddr := NewMsgAddr() - msgAddrV2 := NewMsgAddrV2() - msgAddrV2.AddAddress(NewNetAddressV2IPPort(net.ParseIP("127.0.0.1").To4(), - 8333, SFNodeNetwork)) + v2Addr := NewNetAddressV2IPPort(net.ParseIP("127.0.0.1").To4(), 8333, + SFNodeNetwork) + msgAddrV2 := NewMsgAddrV2([]NetAddressV2{v2Addr}) msgGetBlocks := NewMsgGetBlocks(&chainhash.Hash{}) msgBlock := &testBlock msgInv := NewMsgInv() diff --git a/wire/msgaddrv2.go b/wire/msgaddrv2.go index a30cc1b2e..17757ab62 100644 --- a/wire/msgaddrv2.go +++ b/wire/msgaddrv2.go @@ -1,4 +1,4 @@ -// Copyright (c) 2025 The Decred developers +// Copyright (c) 2025-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -22,43 +22,11 @@ const MaxAddrPerV2Msg = 1000 // addresses. type MsgAddrV2 struct { // AddrList contains the addresses that will be sent to or have been - // received from a peer. Instead of manually appending addresses to this - // field directly, consumers should use the convenience functions on an - // instance of this message to add addresses. + // received from a peer. This MUST have a maximum of [MaxAddrPerV2Msg] + // entries or the message will error during encode and decode. AddrList []NetAddressV2 } -// AddAddress adds a known address to the message. If the maximum number of -// addresses has been reached, then an error is returned. -func (msg *MsgAddrV2) AddAddress(na NetAddressV2) error { - const op = "MsgAddrV2.AddAddress" - if len(msg.AddrList)+1 > MaxAddrPerV2Msg { - msg := fmt.Sprintf("too many addresses in message [max %v]", - MaxAddrPerV2Msg) - return messageError(op, ErrTooManyAddrs, msg) - } - - msg.AddrList = append(msg.AddrList, na) - return nil -} - -// AddAddresses adds multiple known addresses to the message. If the number of -// addresses exceeds the maximum allowed then an error is returned. -func (msg *MsgAddrV2) AddAddresses(netAddrs ...NetAddressV2) error { - for _, na := range netAddrs { - err := msg.AddAddress(na) - if err != nil { - return err - } - } - return nil -} - -// ClearAddresses removes all addresses from the message. -func (msg *MsgAddrV2) ClearAddresses() { - msg.AddrList = []NetAddressV2{} -} - // readNetAddressV2 reads an encoded version 2 wire network address from the // provided reader into the provided NetAddressV2. func readNetAddressV2(op string, r io.Reader, pver uint32, na *NetAddressV2) error { @@ -307,8 +275,10 @@ func (msg *MsgAddrV2) MaxPayloadLength(pver uint32) uint32 { // NewMsgAddrV2 returns a new wire addrv2 message that conforms to the // Message interface. See MsgAddrV2 for details. -func NewMsgAddrV2() *MsgAddrV2 { - return &MsgAddrV2{ - AddrList: make([]NetAddressV2, 0, MaxAddrPerV2Msg), - } +// +// The provided slice is expected to have a minimum of one address and a maximum +// of [MaxAddrPerV2Msg]. The message will fail to decode and encode if it does +// not satisfy those requirements at the time of decoding and encoding. +func NewMsgAddrV2(addrs []NetAddressV2) *MsgAddrV2 { + return &MsgAddrV2{addrs} } diff --git a/wire/msgaddrv2_test.go b/wire/msgaddrv2_test.go index b342cf56c..beda12892 100644 --- a/wire/msgaddrv2_test.go +++ b/wire/msgaddrv2_test.go @@ -1,4 +1,4 @@ -// Copyright (c) 2025 The Decred developers +// Copyright (c) 2025-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -99,7 +99,7 @@ func TestAddrV2MaxPayloadLength(t *testing.T) { for _, test := range tests { // Ensure max payload is expected value for latest protocol version. - msg := NewMsgAddrV2() + msg := NewMsgAddrV2(nil) result := msg.MaxPayloadLength(test.pver) if result != test.want { t.Errorf("%s: wrong max payload length - got %v, want %d", @@ -122,45 +122,11 @@ func TestAddrV2MaxPayloadLength(t *testing.T) { func TestAddrV2(t *testing.T) { // Ensure the command is expected value. wantCmd := "addrv2" - msg := NewMsgAddrV2() + msg := NewMsgAddrV2(nil) if cmd := msg.Command(); cmd != wantCmd { t.Errorf("NewMsgAddrV2: wrong command - got %v want %v", cmd, wantCmd) } - - // Ensure NetAddresses are added properly. - err := msg.AddAddress(ipv4NetAddress) - if err != nil { - t.Errorf("AddAddress: %v", err) - } - if !reflect.DeepEqual(msg.AddrList[0], ipv4NetAddress) { - t.Errorf("AddAddress: wrong address added - got %v, want %v", - spew.Sprint(msg.AddrList[0]), spew.Sprint(ipv4NetAddress)) - } - - // Ensure the address list is cleared properly. - msg.ClearAddresses() - if len(msg.AddrList) != 0 { - t.Errorf("ClearAddresses: address list is not empty - "+ - "got %v [%v], want %v", len(msg.AddrList), - spew.Sprint(msg.AddrList[0]), 0) - } - - // Ensure adding more than the max allowed addresses per message returns - // error. - for i := 0; i < MaxAddrPerV2Msg+1; i++ { - err = msg.AddAddress(ipv4NetAddress) - } - if !errors.Is(err, ErrTooManyAddrs) { - t.Errorf("AddAddress: expected ErrTooManyAddrs, got %v", err) - } - - // Make sure adding multiple addresses also returns an error when the - // message is at max capacity. - err = msg.AddAddresses(ipv4NetAddress) - if !errors.Is(err, ErrTooManyAddrs) { - t.Errorf("AddAddresses: expected ErrTooManyAddrs, got %v", err) - } } // TestAddrV2Wire tests the MsgAddrV2 wire encode and decode for various @@ -213,8 +179,7 @@ func TestAddrV2Wire(t *testing.T) { t.Logf("Running %d tests", len(tests)) for i, test := range tests { - subject := NewMsgAddrV2() - subject.AddAddresses(test.addrs...) + subject := NewMsgAddrV2(test.addrs) // Encode the message to the wire format and ensure it serializes // correctly. @@ -448,8 +413,7 @@ func TestAddrV2BtcEncode(t *testing.T) { }} for _, test := range tests { - msg := NewMsgAddrV2() - msg.AddrList = test.addrs + msg := NewMsgAddrV2(test.addrs) ioLimit := int(msg.MaxPayloadLength(test.pver)) // Encode to wire format. From 9fb66c9841e3cdbc7188752c396a9aaa2874320f Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 9 Feb 2026 01:51:04 -0600 Subject: [PATCH 3/8] wire: Rename NetAddressV2 IP field. This renames the IP field of the new wire.NetAddressV2 struct to EncodedAddr to more accurately reflect its use. This is a breaking API change and thus ordinarily would not be allowed, but since the struct was recently introduced and a new version of the wire modules has not been tagged yet, it is safe to modify the API in a breaking way. --- peer/peer.go | 4 +-- server.go | 7 +++-- wire/msgaddrv2.go | 32 +++++++++---------- wire/msgaddrv2_test.go | 70 +++++++++++++++++++++--------------------- wire/netaddressv2.go | 36 +++++++++++----------- 5 files changed, 75 insertions(+), 74 deletions(-) diff --git a/peer/peer.go b/peer/peer.go index 36e5fac49..b1e05f164 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -2074,14 +2074,14 @@ func (p *Peer) localVersionMsg() (*wire.MsgVersion, error) { if p.cfg.Proxy != "" { proxyaddress, _, err := net.SplitHostPort(p.cfg.Proxy) // invalid proxy means poorly configured, be on the safe side. - if err != nil || net.IP(p.na.IP).String() == proxyaddress { + if err != nil || net.IP(p.na.EncodedAddr).String() == proxyaddress { theirNA = wire.NewNetAddressIPPort(net.IP([]byte{0, 0, 0, 0}), 0, peerNA.Services) } } if theirNA == nil { theirNA = wire.NewNetAddressTimestamp(peerNA.Timestamp, peerNA.Services, - peerNA.IP, peerNA.Port) + peerNA.EncodedAddr, peerNA.Port) } // Create a wire.NetAddress with only the services set to use as the diff --git a/server.go b/server.go index adb2b1668..d8fdde682 100644 --- a/server.go +++ b/server.go @@ -1014,8 +1014,9 @@ func wireToAddrmgrNetAddressesV2(netAddrs []wire.NetAddressV2) ([]*addrmgr.NetAd for i := range netAddrs { wireAddr := &netAddrs[i] addrType := wireToAddrmgrNetAddressType(wireAddr.Type) - addr, err := addrmgr.NewNetAddressFromParams(addrType, wireAddr.IP, - wireAddr.Port, wireAddr.Timestamp, wireAddr.Services) + addr, err := addrmgr.NewNetAddressFromParams(addrType, + wireAddr.EncodedAddr, wireAddr.Port, wireAddr.Timestamp, + wireAddr.Services) if err != nil { return nil, err } @@ -1175,7 +1176,7 @@ func (sp *serverPeer) NA() *addrmgr.NetAddress { return &addrmgr.NetAddress{ Type: wireToAddrmgrNetAddressType(wireNA.Type), - IP: wireNA.IP, + IP: wireNA.EncodedAddr, Port: wireNA.Port, Timestamp: wireNA.Timestamp, Services: wireNA.Services, diff --git a/wire/msgaddrv2.go b/wire/msgaddrv2.go index 17757ab62..5d2900f82 100644 --- a/wire/msgaddrv2.go +++ b/wire/msgaddrv2.go @@ -55,7 +55,7 @@ func readNetAddressV2(op string, r io.Reader, pver uint32, na *NetAddressV2) err if err != nil { return err } - na.IP = ip[:] + na.EncodedAddr = ip[:] case IPv6Address: var ip [16]byte @@ -63,7 +63,7 @@ func readNetAddressV2(op string, r io.Reader, pver uint32, na *NetAddressV2) err if err != nil { return err } - na.IP = ip[:] + na.EncodedAddr = ip[:] case TORv3Address: if pver < TORv3Version { @@ -71,12 +71,12 @@ func readNetAddressV2(op string, r io.Reader, pver uint32, na *NetAddressV2) err "or higher", TORv3Version) return messageError(op, ErrMsgInvalidForPVer, msg) } - var ip [32]byte - err := readElement(r, &ip) + var addr [32]byte + err := readElement(r, &addr) if err != nil { return err } - na.IP = ip[:] + na.EncodedAddr = addr[:] default: msg := fmt.Sprintf("cannot decode unknown network address type %v", @@ -92,8 +92,8 @@ func readNetAddressV2(op string, r io.Reader, pver uint32, na *NetAddressV2) err return nil } -// writeNetAddressV2 serializes an address manager network address to the -// provided writer. +// writeNetAddressV2 serializes a version 2 network address to the provided +// writer. func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) error { err := writeElement(w, uint64(na.Timestamp.Unix())) if err != nil { @@ -105,8 +105,8 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) err return err } - netAddrIP := na.IP - addrLen := len(netAddrIP) + encodedAddr := na.EncodedAddr + addrLen := len(encodedAddr) switch na.Type { case IPv4Address: @@ -115,7 +115,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) err return messageError(op, ErrInvalidMsg, msg) } var ip [4]byte - copy(ip[:], netAddrIP) + copy(ip[:], encodedAddr) err = writeElement(w, ip) if err != nil { return err @@ -127,7 +127,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) err return messageError(op, ErrInvalidMsg, msg) } var ip [16]byte - copy(ip[:], net.IP(netAddrIP).To16()) + copy(ip[:], net.IP(encodedAddr).To16()) err = writeElement(w, ip) if err != nil { return err @@ -139,13 +139,13 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) err "or higher", TORv3Version) return messageError(op, ErrMsgInvalidForPVer, msg) } - if len(netAddrIP) != 32 { - msg := fmt.Sprintf("invalid TORv3 address length: %d", len(netAddrIP)) + if len(encodedAddr) != 32 { + msg := fmt.Sprintf("invalid TORv3 address length: %d", len(encodedAddr)) return messageError(op, ErrInvalidMsg, msg) } - var ip [32]byte - copy(ip[:], netAddrIP) - err = writeElement(w, ip) + var addr [32]byte + copy(addr[:], encodedAddr) + err = writeElement(w, addr) if err != nil { return err } diff --git a/wire/msgaddrv2_test.go b/wire/msgaddrv2_test.go index beda12892..fb55de0e2 100644 --- a/wire/msgaddrv2_test.go +++ b/wire/msgaddrv2_test.go @@ -60,17 +60,17 @@ var ( 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Services 0x00, // Type (Unknown) - 0x7f, 0x00, 0x00, 0x01, // IP + 0x7f, 0x00, 0x00, 0x01, // EncodedAddr 0x8d, 0x20, // Port 8333 (little-endian) } serializedTORv3NetAddressBytes = []byte{ 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // Type (TORv3) - 0xb8, 0x39, 0x1d, 0x20, 0x03, 0xbb, 0x3b, 0xd2, // IP - 0x85, 0xb0, 0x35, 0xac, 0x8e, 0xb3, 0x0c, 0x80, // IP - 0xc4, 0xe2, 0xa2, 0x9b, 0xb7, 0xa2, 0xf0, 0xce, // IP - 0x0d, 0xf8, 0x74, 0x3c, 0x37, 0xec, 0x35, 0x93, // IP + 0xb8, 0x39, 0x1d, 0x20, 0x03, 0xbb, 0x3b, 0xd2, // EncodedAddr + 0x85, 0xb0, 0x35, 0xac, 0x8e, 0xb3, 0x0c, 0x80, // EncodedAddr + 0xc4, 0xe2, 0xa2, 0x9b, 0xb7, 0xa2, 0xf0, 0xce, // EncodedAddr + 0x0d, 0xf8, 0x74, 0x3c, 0x37, 0xec, 0x35, 0x93, // EncodedAddr 0x8d, 0x20, // Port 8333 (little-endian) } ) @@ -338,11 +338,11 @@ func TestAddrV2BtcEncode(t *testing.T) { name: "addrv2 message invalid for pver 11", pver: AddrV2Version - 1, addrs: []NetAddressV2{{ - Timestamp: time.Unix(0x495fab29, 0), - Services: SFNodeNetwork, - Type: IPv4Address, - IP: ipv4IpBytes, - Port: 8333, + Timestamp: time.Unix(0x495fab29, 0), + Services: SFNodeNetwork, + Type: IPv4Address, + EncodedAddr: ipv4IpBytes, + Port: 8333, }}, wantErr: ErrMsgInvalidForPVer, }, { @@ -359,55 +359,55 @@ func TestAddrV2BtcEncode(t *testing.T) { name: "message with wrong size IPv4 address", pver: pver, addrs: []NetAddressV2{{ - Timestamp: time.Unix(0x495fab29, 0), - Services: SFNodeNetwork, - Type: IPv4Address, - IP: make([]byte, 1), - Port: 8333, + Timestamp: time.Unix(0x495fab29, 0), + Services: SFNodeNetwork, + Type: IPv4Address, + EncodedAddr: make([]byte, 1), + Port: 8333, }}, wantErr: ErrInvalidMsg, }, { name: "message with wrong size IPv6 address", pver: pver, addrs: []NetAddressV2{{ - Timestamp: time.Unix(0x495fab29, 0), - Services: SFNodeNetwork, - Type: IPv6Address, - IP: make([]byte, 1), - Port: 8333, + Timestamp: time.Unix(0x495fab29, 0), + Services: SFNodeNetwork, + Type: IPv6Address, + EncodedAddr: make([]byte, 1), + Port: 8333, }}, wantErr: ErrInvalidMsg, }, { name: "message with wrong size TORv3 address", pver: pver, addrs: []NetAddressV2{{ - Timestamp: time.Unix(0x495fab29, 0), - Services: SFNodeNetwork, - Type: TORv3Address, - IP: make([]byte, 1), - Port: 8333, + Timestamp: time.Unix(0x495fab29, 0), + Services: SFNodeNetwork, + Type: TORv3Address, + EncodedAddr: make([]byte, 1), + Port: 8333, }}, wantErr: ErrInvalidMsg, }, { name: "message with TORv3 address invalid on pver 12", pver: AddrV2Version, addrs: []NetAddressV2{{ - Timestamp: time.Unix(0x495fab29, 0), - Services: SFNodeNetwork, - Type: TORv3Address, - IP: torV3IpBytes, - Port: 8333, + Timestamp: time.Unix(0x495fab29, 0), + Services: SFNodeNetwork, + Type: TORv3Address, + EncodedAddr: torV3IpBytes, + Port: 8333, }}, wantErr: ErrMsgInvalidForPVer, }, { name: "message with unknown address type", pver: pver, addrs: []NetAddressV2{{ - Timestamp: time.Unix(0x495fab29, 0), - Services: SFNodeNetwork, - Type: UnknownAddressType, - IP: make([]byte, 1), - Port: 8333, + Timestamp: time.Unix(0x495fab29, 0), + Services: SFNodeNetwork, + Type: UnknownAddressType, + EncodedAddr: make([]byte, 1), + Port: 8333, }}, wantErr: ErrUnknownNetAddrType, }} diff --git a/wire/netaddressv2.go b/wire/netaddressv2.go index 251d20e1f..5e2d41521 100644 --- a/wire/netaddressv2.go +++ b/wire/netaddressv2.go @@ -1,4 +1,4 @@ -// Copyright (c) 2025 The Decred developers +// Copyright (c) 2025-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -32,24 +32,24 @@ type NetAddressV2 struct { // Type represents the type of network that the network address belongs to. Type NetAddressType - // IP address of the peer. It is defined as a byte array to support various - // address types that are not standard to the net package and therefore not - // entirely appropriate to store as a net.IP. - IP []byte + // EncodedAddr is the encoded network address. Its contents varies + // depending on the address type discriminator. + EncodedAddr []byte - // Port is the port of the remote peer. + // Port is the port of the remote peer. It will be 0 if a port does not + // apply for the specified address type discriminator. Port uint16 } -// NewNetAddressV2 creates a new network address using the provided -// parameters without validation. +// NewNetAddressV2 creates a new network address using the provided parameters +// without validation. func NewNetAddressV2(netAddressType NetAddressType, addrBytes []byte, port uint16, timestamp time.Time, services ServiceFlag) NetAddressV2 { return NetAddressV2{ - Timestamp: timestamp, - Services: services, - Type: netAddressType, - IP: addrBytes, - Port: port, + Timestamp: timestamp, + Services: services, + Type: netAddressType, + EncodedAddr: addrBytes, + Port: port, } } @@ -72,10 +72,10 @@ func NewNetAddressV2IPPort(ip net.IP, port uint16, services ServiceFlag) NetAddr // doesn't support better. timestamp := time.Unix(time.Now().Unix(), 0) return NetAddressV2{ - Timestamp: timestamp, - Services: services, - Type: addrType, - IP: addrBytes, - Port: port, + Timestamp: timestamp, + Services: services, + Type: addrType, + EncodedAddr: addrBytes, + Port: port, } } From f4afba8ecf9c11d962f4477aec2391a5d2625b65 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 9 Feb 2026 01:51:42 -0600 Subject: [PATCH 4/8] wire: Misc cleanup of recently added addrv2 code. This contains some basic housekeeping and does not make any functional changes: - Use nil instead of empty instances to avoid some allocs - Use standard formatting in some of the tests - Remove unnecessary checks for nil slices on len checks since taking the length of a nil slice is already 0 - Correct a wire comment regarding network addresses --- addrmgr/addrmanager_test.go | 4 +- peer/peer_test.go | 123 +++++++++++++++++------------------- wire/msgaddrv2.go | 21 +++--- wire/msgaddrv2_test.go | 14 ++-- 4 files changed, 79 insertions(+), 83 deletions(-) diff --git a/addrmgr/addrmanager_test.go b/addrmgr/addrmanager_test.go index 2310ec957..27fe068b1 100644 --- a/addrmgr/addrmanager_test.go +++ b/addrmgr/addrmanager_test.go @@ -1,5 +1,5 @@ // Copyright (c) 2013-2014 The btcsuite developers -// Copyright (c) 2015-2025 The Decred developers +// Copyright (c) 2015-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -1136,7 +1136,7 @@ func TestGetAddressWithFilter(t *testing.T) { wantNil: true, }, { name: "returns nil when address manager empty", - addresses: []*NetAddress{}, + addresses: nil, filter: natfAny, wantNil: true, }} diff --git a/peer/peer_test.go b/peer/peer_test.go index ea08f87b9..03d88fac8 100644 --- a/peer/peer_test.go +++ b/peer/peer_test.go @@ -571,31 +571,30 @@ func TestPeerListeners(t *testing.T) { listener: "OnCFilterV2", msg: wire.NewMsgCFilterV2(&chainhash.Hash{}, nil, 0, nil), pver: pver, - }, + }, { // only one version message is allowed // only one verack message is allowed - { - listener: "OnSendHeaders", - msg: wire.NewMsgSendHeaders(), - pver: pver, - }, { - listener: "OnGetInitState", - msg: wire.NewMsgGetInitState(), - pver: pver, - }, { - listener: "OnInitState", - msg: wire.NewMsgInitState(), - pver: pver, - }, { - listener: "OnGetCFiltersV2", - msg: wire.NewMsgGetCFsV2(&chainhash.Hash{}, &chainhash.Hash{}), - pver: pver, - }, { - listener: "OnCFiltersV2", - msg: wire.NewMsgCFiltersV2([]wire.MsgCFilterV2{}), - pver: pver, - }, - } + listener: "OnSendHeaders", + msg: wire.NewMsgSendHeaders(), + pver: pver, + }, { + listener: "OnGetInitState", + msg: wire.NewMsgGetInitState(), + pver: pver, + }, { + listener: "OnInitState", + msg: wire.NewMsgInitState(), + pver: pver, + }, { + listener: "OnGetCFiltersV2", + msg: wire.NewMsgGetCFsV2(&chainhash.Hash{}, &chainhash.Hash{}), + pver: pver, + }, { + listener: "OnCFiltersV2", + msg: wire.NewMsgCFiltersV2([]wire.MsgCFilterV2{}), + pver: pver, + }} + t.Logf("Running %d tests", len(tests)) for _, test := range tests { testPver := test.pver @@ -963,41 +962,39 @@ func TestPushAddrV2Msg(t *testing.T) { name string addrs []wire.NetAddressV2 wantSentLen int - }{ - { - name: "nil address list", - addrs: nil, - wantSentLen: 0, - }, { - name: "empty address list", - addrs: []wire.NetAddressV2{}, - wantSentLen: 0, - }, { - name: "single address", - addrs: []wire.NetAddressV2{addr}, - wantSentLen: 1, - }, { - name: "multiple addresses under limit", - addrs: func() []wire.NetAddressV2 { - addrs := make([]wire.NetAddressV2, 10) - for i := range addrs { - addrs[i] = addr - } - return addrs - }(), - wantSentLen: 10, - }, { - name: "addresses over MaxAddrPerV2Msg limit", - addrs: func() []wire.NetAddressV2 { - addrs := make([]wire.NetAddressV2, wire.MaxAddrPerV2Msg+100) - for i := range addrs { - addrs[i] = addr - } - return addrs - }(), - wantSentLen: wire.MaxAddrPerV2Msg, - }, - } + }{{ + name: "nil address list", + addrs: nil, + wantSentLen: 0, + }, { + name: "empty address list", + addrs: []wire.NetAddressV2{}, + wantSentLen: 0, + }, { + name: "single address", + addrs: []wire.NetAddressV2{addr}, + wantSentLen: 1, + }, { + name: "multiple addresses under limit", + addrs: func() []wire.NetAddressV2 { + addrs := make([]wire.NetAddressV2, 10) + for i := range addrs { + addrs[i] = addr + } + return addrs + }(), + wantSentLen: 10, + }, { + name: "addresses over MaxAddrPerV2Msg limit", + addrs: func() []wire.NetAddressV2 { + addrs := make([]wire.NetAddressV2, wire.MaxAddrPerV2Msg+100) + for i := range addrs { + addrs[i] = addr + } + return addrs + }(), + wantSentLen: wire.MaxAddrPerV2Msg, + }} // Create a mock connection. inConn, outConn := pipe( @@ -1018,13 +1015,9 @@ func TestPushAddrV2Msg(t *testing.T) { sent := peer.PushAddrV2Msg(test.addrs) // Check the number of addresses sent. - gotSentLen := 0 - if sent != nil { - gotSentLen = len(sent) - } - if gotSentLen != test.wantSentLen { - t.Errorf("%s: expected %d addresses sent, got %d", - test.name, test.wantSentLen, gotSentLen) + if got := len(sent); got != test.wantSentLen { + t.Errorf("%s: expected %d addresses sent, got %d", test.name, + test.wantSentLen, got) } } diff --git a/wire/msgaddrv2.go b/wire/msgaddrv2.go index 5d2900f82..44cc9413b 100644 --- a/wire/msgaddrv2.go +++ b/wire/msgaddrv2.go @@ -177,9 +177,10 @@ func (msg *MsgAddrV2) BtcDecode(r io.Reader, pver uint32) error { return err } + // Require at least one address per message. if count == 0 { - return messageError(op, ErrTooFewAddrs, - "no addresses for message [count 0, min 1]") + const msg = "no addresses for message [count 0, min 1]" + return messageError(op, ErrTooFewAddrs, msg) } // Limit to max addresses per message. @@ -211,18 +212,20 @@ func (msg *MsgAddrV2) BtcEncode(w io.Writer, pver uint32) error { return messageError(op, ErrMsgInvalidForPVer, msg) } + // Require at least one address per message. count := len(msg.AddrList) + if count == 0 { + const msg = "no addresses for message [count 0, min 1]" + return messageError(op, ErrTooFewAddrs, msg) + } + + // Limit to max addresses per message. if count > MaxAddrPerV2Msg { msg := fmt.Sprintf("too many addresses for message [count %v, max %v]", count, MaxAddrPerV2Msg) return messageError(op, ErrTooManyAddrs, msg) } - if count == 0 { - return messageError(op, ErrTooFewAddrs, - "no addresses for message [count 0, min 1]") - } - err := WriteVarInt(w, pver, uint64(count)) if err != nil { return err @@ -244,8 +247,8 @@ func (msg *MsgAddrV2) Command() string { return CmdAddrV2 } -// maxNetAddressPayloadV2 returns the max payload size for an address manager -// network address based on the protocol version. +// maxNetAddressPayloadV2 returns the max payload size for a network address +// based on the protocol version. func maxNetAddressPayloadV2(pver uint32) uint32 { const ( timestampSize = 8 diff --git a/wire/msgaddrv2_test.go b/wire/msgaddrv2_test.go index fb55de0e2..cc1472ed0 100644 --- a/wire/msgaddrv2_test.go +++ b/wire/msgaddrv2_test.go @@ -145,7 +145,7 @@ func TestAddrV2Wire(t *testing.T) { wantBytes: bytes.Join([][]byte{ {0x01}, serializedIPv4NetAddressBytes, - }, []byte{}), + }, nil), }, { name: "latest protocol version with multiple addresses", addrs: []NetAddressV2{ @@ -158,7 +158,7 @@ func TestAddrV2Wire(t *testing.T) { serializedIPv4NetAddressBytes, serializedIPv6NetAddressBytes, serializedTORv3NetAddressBytes, - }, []byte{}), + }, nil), }, { name: "latest protocol version with maximum addresses", addrs: func() []NetAddressV2 { @@ -173,7 +173,7 @@ func TestAddrV2Wire(t *testing.T) { for i := 0; i < MaxAddrPerV2Msg; i++ { parts = append(parts, serializedIPv6NetAddressBytes) } - return bytes.Join(parts, []byte{}) + return bytes.Join(parts, nil) }(), }} @@ -228,7 +228,7 @@ func TestAddrV2BtcDecode(t *testing.T) { wireBytes: bytes.Join([][]byte{ {0x01}, serializedIPv4NetAddressBytes, - }, []byte{}), + }, nil), wantAddrs: nil, wantErr: ErrMsgInvalidForPVer, }, { @@ -277,7 +277,7 @@ func TestAddrV2BtcDecode(t *testing.T) { serializedIPv6NetAddressBytes, serializedTORv3NetAddressBytes, serializedUnknownNetAddressBytes, - }, []byte{}), + }, nil), wantAddrs: nil, wantErr: ErrUnknownNetAddrType, }, { @@ -286,7 +286,7 @@ func TestAddrV2BtcDecode(t *testing.T) { wireBytes: bytes.Join([][]byte{ {0x01}, serializedTORv3NetAddressBytes, - }, []byte{}), + }, nil), wantAddrs: nil, wantErr: ErrMsgInvalidForPVer, }, { @@ -297,7 +297,7 @@ func TestAddrV2BtcDecode(t *testing.T) { serializedIPv4NetAddressBytes, serializedIPv6NetAddressBytes, serializedTORv3NetAddressBytes, - }, []byte{}), + }, nil), wantAddrs: []NetAddressV2{ ipv4NetAddress, ipv6NetAddress, From 91766bafa767ba0d5dae3ccf061d45d969f9f6a9 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 9 Feb 2026 01:52:17 -0600 Subject: [PATCH 5/8] multi: Keep TorV3 support as part of addrv2 pver. This removes the additional TORv3Version protocol version bump in favor of keeping the TorV3 additions as part of the AddrV2Version protool bump. This is a breaking API change and thus ordinarily would not be allowed, but since the struct was recently introduced and a new version of the wire modules has not been tagged yet, it is safe to modify the API in a breaking way. --- peer/peer.go | 2 +- server.go | 4 ++-- wire/msgaddrv2.go | 24 +++++------------------- wire/msgaddrv2_test.go | 25 +++---------------------- wire/protocol.go | 8 ++------ 5 files changed, 13 insertions(+), 50 deletions(-) diff --git a/peer/peer.go b/peer/peer.go index b1e05f164..c3bd3fca1 100644 --- a/peer/peer.go +++ b/peer/peer.go @@ -30,7 +30,7 @@ import ( const ( // MaxProtocolVersion is the max protocol version the peer supports. - MaxProtocolVersion = wire.TORv3Version + MaxProtocolVersion = wire.AddrV2Version // outputBufferSize is the number of elements the output channels use. outputBufferSize = 5000 diff --git a/server.go b/server.go index d8fdde682..e3380a011 100644 --- a/server.go +++ b/server.go @@ -77,7 +77,7 @@ const ( connectionRetryInterval = time.Second * 5 // maxProtocolVersion is the max protocol version the server supports. - maxProtocolVersion = wire.TORv3Version + maxProtocolVersion = wire.AddrV2Version // These fields are used to track known addresses on a per-peer basis. // @@ -1155,7 +1155,7 @@ func isSupportedNetAddressTypeV2(addrType addrmgr.NetAddressType) bool { // protocol version. func natfSupported(pver uint32) addrmgr.NetAddressTypeFilter { switch { - case pver <= wire.AddrV2Version: + case pver < wire.AddrV2Version: return isSupportedNetAddrTypeV1 } return isSupportedNetAddressTypeV2 diff --git a/wire/msgaddrv2.go b/wire/msgaddrv2.go index 44cc9413b..ce7ea4fc6 100644 --- a/wire/msgaddrv2.go +++ b/wire/msgaddrv2.go @@ -66,11 +66,6 @@ func readNetAddressV2(op string, r io.Reader, pver uint32, na *NetAddressV2) err na.EncodedAddr = ip[:] case TORv3Address: - if pver < TORv3Version { - msg := fmt.Sprintf("TORv3 addresses require protocol version %d "+ - "or higher", TORv3Version) - return messageError(op, ErrMsgInvalidForPVer, msg) - } var addr [32]byte err := readElement(r, &addr) if err != nil { @@ -134,11 +129,6 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) err } case TORv3Address: - if pver < TORv3Version { - msg := fmt.Sprintf("TORv3 addresses require protocol version %d "+ - "or higher", TORv3Version) - return messageError(op, ErrMsgInvalidForPVer, msg) - } if len(encodedAddr) != 32 { msg := fmt.Sprintf("invalid TORv3 address length: %d", len(encodedAddr)) return messageError(op, ErrInvalidMsg, msg) @@ -249,7 +239,7 @@ func (msg *MsgAddrV2) Command() string { // maxNetAddressPayloadV2 returns the max payload size for a network address // based on the protocol version. -func maxNetAddressPayloadV2(pver uint32) uint32 { +func maxNetAddressPayloadV2() uint32 { const ( timestampSize = 8 servicesSize = 8 @@ -257,13 +247,9 @@ func maxNetAddressPayloadV2(pver uint32) uint32 { portSize = 2 ) - maxAddressSize := uint32(16) // IPv6 is 16 bytes - if pver >= TORv3Version { - maxAddressSize = 32 - } - - return timestampSize + servicesSize + addressTypeSize + - maxAddressSize + portSize + const maxAddressSize = 32 // TorV3 is a 32-byte pubkey + return timestampSize + servicesSize + addressTypeSize + maxAddressSize + + portSize } // MaxPayloadLength returns the maximum length the payload can be for the @@ -273,7 +259,7 @@ func (msg *MsgAddrV2) MaxPayloadLength(pver uint32) uint32 { return 0 } return uint32(VarIntSerializeSize(MaxAddrPerV2Msg)) + - (MaxAddrPerV2Msg * maxNetAddressPayloadV2(pver)) + (MaxAddrPerV2Msg * maxNetAddressPayloadV2()) } // NewMsgAddrV2 returns a new wire addrv2 message that conforms to the diff --git a/wire/msgaddrv2_test.go b/wire/msgaddrv2_test.go index cc1472ed0..04a469893 100644 --- a/wire/msgaddrv2_test.go +++ b/wire/msgaddrv2_test.go @@ -90,7 +90,7 @@ func TestAddrV2MaxPayloadLength(t *testing.T) { }, { name: "protocol version 12", pver: AddrV2Version, - want: 35003, + want: 51003, }, { name: "latest protocol version", pver: ProtocolVersion, @@ -280,15 +280,6 @@ func TestAddrV2BtcDecode(t *testing.T) { }, nil), wantAddrs: nil, wantErr: ErrUnknownNetAddrType, - }, { - name: "message with TORv3 address invalid on pver 12", - pver: AddrV2Version, - wireBytes: bytes.Join([][]byte{ - {0x01}, - serializedTORv3NetAddressBytes, - }, nil), - wantAddrs: nil, - wantErr: ErrMsgInvalidForPVer, }, { name: "message with multiple valid addresses", pver: pver, @@ -312,7 +303,8 @@ func TestAddrV2BtcDecode(t *testing.T) { err := msg.BtcDecode(rbuf, test.pver) if !errors.Is(err, test.wantErr) { - t.Errorf("%q: wrong error - got: %v, want: %v", test.name, err, test.wantErr) + t.Errorf("%q: wrong error - got: %v, want: %v", test.name, err, + test.wantErr) continue } @@ -388,17 +380,6 @@ func TestAddrV2BtcEncode(t *testing.T) { Port: 8333, }}, wantErr: ErrInvalidMsg, - }, { - name: "message with TORv3 address invalid on pver 12", - pver: AddrV2Version, - addrs: []NetAddressV2{{ - Timestamp: time.Unix(0x495fab29, 0), - Services: SFNodeNetwork, - Type: TORv3Address, - EncodedAddr: torV3IpBytes, - Port: 8333, - }}, - wantErr: ErrMsgInvalidForPVer, }, { name: "message with unknown address type", pver: pver, diff --git a/wire/protocol.go b/wire/protocol.go index ab779d913..0c02d6b68 100644 --- a/wire/protocol.go +++ b/wire/protocol.go @@ -1,5 +1,5 @@ // Copyright (c) 2013-2016 The btcsuite developers -// Copyright (c) 2015-2025 The Decred developers +// Copyright (c) 2015-2026 The Decred developers // Use of this source code is governed by an ISC // license that can be found in the LICENSE file. @@ -17,7 +17,7 @@ const ( InitialProcotolVersion uint32 = 1 // ProtocolVersion is the latest protocol version this package supports. - ProtocolVersion uint32 = 13 + ProtocolVersion uint32 = 12 // NodeBloomVersion is the protocol version which added the SFNodeBloom // service flag (unused). @@ -61,10 +61,6 @@ const ( // AddrV2Version is the protocol version which adds the addrv2 message. AddrV2Version uint32 = 12 - - // TORv3Version is the protocol version which adds support for TORv3 - // network addresses to the addrv2 message. - TORv3Version uint32 = 13 ) // ServiceFlag identifies services supported by a Decred peer. From 3c15c1157f62ecb15243cca5f8274bff05a9f0a4 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Mon, 9 Feb 2026 22:07:33 -0600 Subject: [PATCH 6/8] wire: Reduce allocs in MsgAddrV2 writes. This converts the encoding logic for the new MsgAddrV2 to avoid allocations by using pointers to the data to be written and also introduces fast paths in the writeElement function for the new types. --- wire/common.go | 22 ++++++++++++++++++++++ wire/msgaddrv2.go | 18 +++++++++--------- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/wire/common.go b/wire/common.go index 3fc667a78..bae3ea45e 100644 --- a/wire/common.go +++ b/wire/common.go @@ -492,6 +492,13 @@ func writeElement(w io.Writer, element interface{}) error { } return nil + case *NetAddressType: + err := writeUint8(w, uint8(*e)) + if err != nil { + return err + } + return nil + case *uint16: err := writeUint16LE(w, *e) if err != nil { @@ -499,6 +506,14 @@ func writeElement(w io.Writer, element interface{}) error { } return nil + // IPv4 address. + case *[4]byte: + _, err := w.Write(e[:]) + if err != nil { + return err + } + return nil + case *int32: err := writeUint32LE(w, uint32(*e)) if err != nil { @@ -527,6 +542,13 @@ func writeElement(w io.Writer, element interface{}) error { } return nil + case *uint64Time: + err := writeUint64LE(w, uint64(time.Time(*e).Unix())) + if err != nil { + return err + } + return nil + case *bool: var err error if *e { diff --git a/wire/msgaddrv2.go b/wire/msgaddrv2.go index ce7ea4fc6..ec3d315d2 100644 --- a/wire/msgaddrv2.go +++ b/wire/msgaddrv2.go @@ -89,13 +89,13 @@ func readNetAddressV2(op string, r io.Reader, pver uint32, na *NetAddressV2) err // writeNetAddressV2 serializes a version 2 network address to the provided // writer. -func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) error { - err := writeElement(w, uint64(na.Timestamp.Unix())) +func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) error { + err := writeElement(w, (*uint64Time)(&na.Timestamp)) if err != nil { return err } - err = writeElements(w, na.Services, na.Type) + err = writeElements(w, &na.Services, &na.Type) if err != nil { return err } @@ -111,7 +111,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) err } var ip [4]byte copy(ip[:], encodedAddr) - err = writeElement(w, ip) + err = writeElement(w, &ip) if err != nil { return err } @@ -123,7 +123,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) err } var ip [16]byte copy(ip[:], net.IP(encodedAddr).To16()) - err = writeElement(w, ip) + err = writeElement(w, &ip) if err != nil { return err } @@ -135,7 +135,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) err } var addr [32]byte copy(addr[:], encodedAddr) - err = writeElement(w, addr) + err = writeElement(w, &addr) if err != nil { return err } @@ -146,7 +146,7 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na NetAddressV2) err return messageError(op, ErrUnknownNetAddrType, msg) } - return writeElement(w, na.Port) + return writeElement(w, &na.Port) } // BtcDecode decodes r using the wire protocol encoding into the receiver. @@ -221,8 +221,8 @@ func (msg *MsgAddrV2) BtcEncode(w io.Writer, pver uint32) error { return err } - for _, na := range msg.AddrList { - err = writeNetAddressV2(op, w, pver, na) + for i := range msg.AddrList { + err = writeNetAddressV2(op, w, pver, &msg.AddrList[i]) if err != nil { return err } From 43d917607729439738b8a6a46390cf079f2f3e28 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 10 Feb 2026 20:56:44 -0600 Subject: [PATCH 7/8] wire: Simplify write logic for v2 net addr. This modifies the logic for serializing version 2 network addresses to avoid additional copies into local arrays for the various address types by directly writing the encoded address after the switch that verifies the encoded address is the right size for the type. --- wire/common.go | 8 -------- wire/msgaddrv2.go | 24 +++++------------------- 2 files changed, 5 insertions(+), 27 deletions(-) diff --git a/wire/common.go b/wire/common.go index bae3ea45e..4f9dd35ab 100644 --- a/wire/common.go +++ b/wire/common.go @@ -506,14 +506,6 @@ func writeElement(w io.Writer, element interface{}) error { } return nil - // IPv4 address. - case *[4]byte: - _, err := w.Write(e[:]) - if err != nil { - return err - } - return nil - case *int32: err := writeUint32LE(w, uint32(*e)) if err != nil { diff --git a/wire/msgaddrv2.go b/wire/msgaddrv2.go index ec3d315d2..aed4779c1 100644 --- a/wire/msgaddrv2.go +++ b/wire/msgaddrv2.go @@ -7,7 +7,6 @@ package wire import ( "fmt" "io" - "net" ) // MaxAddrPerV2Msg is the maximum number of addresses that can be in a single @@ -109,36 +108,18 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er msg := fmt.Sprintf("invalid IPv4 address length: %d", addrLen) return messageError(op, ErrInvalidMsg, msg) } - var ip [4]byte - copy(ip[:], encodedAddr) - err = writeElement(w, &ip) - if err != nil { - return err - } case IPv6Address: if addrLen != 16 { msg := fmt.Sprintf("invalid IPv6 address length: %d", addrLen) return messageError(op, ErrInvalidMsg, msg) } - var ip [16]byte - copy(ip[:], net.IP(encodedAddr).To16()) - err = writeElement(w, &ip) - if err != nil { - return err - } case TORv3Address: if len(encodedAddr) != 32 { msg := fmt.Sprintf("invalid TORv3 address length: %d", len(encodedAddr)) return messageError(op, ErrInvalidMsg, msg) } - var addr [32]byte - copy(addr[:], encodedAddr) - err = writeElement(w, &addr) - if err != nil { - return err - } default: msg := fmt.Sprintf("cannot encode unknown network address type %v", @@ -146,6 +127,11 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er return messageError(op, ErrUnknownNetAddrType, msg) } + _, err = w.Write(encodedAddr) + if err != nil { + return err + } + return writeElement(w, &na.Port) } From fd39805c9ca21b05350e20b1c289af259f2fc427 Mon Sep 17 00:00:00 2001 From: Dave Collins Date: Tue, 10 Feb 2026 21:07:04 -0600 Subject: [PATCH 8/8] multi: Rename TORv3 to TorV3. This renames all mentions of TORv3 to the more canonical TorV3. All references to Tor on the main project site, and basically everywhere else, refer to the network as "Tor", not "TOR". --- addrmgr/addrmanager.go | 42 ++++++++++++++++++------------------- addrmgr/addrmanager_test.go | 20 +++++++++--------- addrmgr/netaddress.go | 10 ++++----- addrmgr/netaddress_test.go | 6 +++--- addrmgr/network.go | 16 +++++++------- addrmgr/network_test.go | 2 +- server.go | 14 ++++++------- server_test.go | 2 +- wire/msgaddrv2.go | 6 +++--- wire/msgaddrv2_test.go | 16 +++++++------- wire/netaddressv2.go | 2 +- 11 files changed, 68 insertions(+), 68 deletions(-) diff --git a/addrmgr/addrmanager.go b/addrmgr/addrmanager.go index 402e43300..6bb97d8ac 100644 --- a/addrmgr/addrmanager.go +++ b/addrmgr/addrmanager.go @@ -110,14 +110,14 @@ type AddrManager struct { type addrTypeFilter struct { wantIPv4 bool wantIPv6 bool - wantTORv3 bool + wantTorV3 bool } // bucketStats tracks the number of addresses by type within a single bucket. type bucketStats struct { numIPv4 uint16 numIPv6 uint16 - numTORv3 uint16 + numTorV3 uint16 } // serializedKnownAddress is used to represent the serializable state of a @@ -249,8 +249,8 @@ func (bs *bucketStats) increment(addrType NetAddressType) { bs.numIPv4++ case IPv6Address: bs.numIPv6++ - case TORv3Address: - bs.numTORv3++ + case TorV3Address: + bs.numTorV3++ } } @@ -261,8 +261,8 @@ func (bs *bucketStats) decrement(addrType NetAddressType) { bs.numIPv4-- case IPv6Address: bs.numIPv6-- - case TORv3Address: - bs.numTORv3-- + case TorV3Address: + bs.numTorV3-- } } @@ -275,8 +275,8 @@ func (bs *bucketStats) total(filter addrTypeFilter) int { if filter.wantIPv6 { sum += int(bs.numIPv6) } - if filter.wantTORv3 { - sum += int(bs.numTORv3) + if filter.wantTorV3 { + sum += int(bs.numTorV3) } return sum } @@ -285,14 +285,14 @@ func (bs *bucketStats) total(filter addrTypeFilter) int { func (bs *bucketStats) matches(filter addrTypeFilter) bool { return (filter.wantIPv4 && bs.numIPv4 > 0) || (filter.wantIPv6 && bs.numIPv6 > 0) || - (filter.wantTORv3 && bs.numTORv3 > 0) + (filter.wantTorV3 && bs.numTorV3 > 0) } // matches returns true if the address type matches the filter criteria. func (f addrTypeFilter) matches(addrType NetAddressType) bool { return (f.wantIPv4 && addrType == IPv4Address) || (f.wantIPv6 && addrType == IPv6Address) || - (f.wantTORv3 && addrType == TORv3Address) + (f.wantTorV3 && addrType == TorV3Address) } // addOrUpdateAddress is a helper function to either update an address already known @@ -829,16 +829,16 @@ func (a *AddrManager) reset() { // returns the result. If the host string is not recognized as any known type, // then an unknown address type is returned without error. func EncodeHost(host string) (NetAddressType, []byte) { - // Check if this is a valid TORv3 address. + // Check if this is a valid TorV3 address. if len(host) == 62 && strings.HasSuffix(host, ".onion") { - // TORv3 addresses tend to be lowercase by convention, but + // TorV3 addresses tend to be lowercase by convention, but // Go's base32.StdEncoding.DecodeString expects uppercase // input. Convert to uppercase for successful decoding. torAddressBytes, err := base32.StdEncoding.DecodeString( strings.ToUpper(host[:56])) if err == nil { - if pubkey, valid := isTORv3(torAddressBytes); valid { - return TORv3Address, pubkey[:] + if pubkey, valid := isTorV3(torAddressBytes); valid { + return TorV3Address, pubkey[:] } } } @@ -872,10 +872,10 @@ func (a *AddrManager) GetAddress(filterFn NetAddressTypeFilter) *KnownAddress { filter := addrTypeFilter{ wantIPv4: filterFn(IPv4Address), wantIPv6: filterFn(IPv6Address), - wantTORv3: filterFn(TORv3Address), + wantTorV3: filterFn(TorV3Address), } - if !filter.wantIPv4 && !filter.wantIPv6 && !filter.wantTORv3 { + if !filter.wantIPv4 && !filter.wantIPv6 && !filter.wantTorV3 { return nil } @@ -1241,7 +1241,7 @@ const ( // Ipv6Strong represents a connection state between two IPv6 addresses. Ipv6Strong - // Private represents a connection state between two TORv3 addresses. + // Private represents a connection state between two TorV3 addresses. Private ) @@ -1254,9 +1254,9 @@ func getRemoteReachabilityFromLocal(localAddr, remoteAddr *NetAddress) NetAddres case !remoteAddr.IsRoutable(): return Unreachable - case remoteAddr.Type == TORv3Address: + case remoteAddr.Type == TorV3Address: switch { - case localAddr.Type == TORv3Address: + case localAddr.Type == TorV3Address: return Private case localAddr.IsRoutable() && localAddr.Type == IPv4Address: return Ipv4 @@ -1280,7 +1280,7 @@ func getRemoteReachabilityFromLocal(localAddr, remoteAddr *NetAddress) NetAddres switch { case localAddr.IsRoutable() && localAddr.Type == IPv4Address: return Ipv4 - case localAddr.Type == TORv3Address: + case localAddr.Type == TorV3Address: return Ipv4 default: return Unreachable @@ -1294,7 +1294,7 @@ func getRemoteReachabilityFromLocal(localAddr, remoteAddr *NetAddress) NetAddres return Teredo case localAddr.Type == IPv4Address: return Ipv4 - case localAddr.Type == TORv3Address: + case localAddr.Type == TorV3Address: return Ipv6Strong // Is our IPv6 tunneled? diff --git a/addrmgr/addrmanager_test.go b/addrmgr/addrmanager_test.go index 27fe068b1..94919a114 100644 --- a/addrmgr/addrmanager_test.go +++ b/addrmgr/addrmanager_test.go @@ -41,9 +41,9 @@ func natfOnlyIPv6(addrType NetAddressType) bool { return addrType == IPv6Address } -// natfOnlyTORv3 defines a filter that will only allow TORv3 netAddrs. -func natfOnlyTORv3(addrType NetAddressType) bool { - return addrType == TORv3Address +// natfOnlyTorV3 defines a filter that will only allow TorV3 netAddrs. +func natfOnlyTorV3(addrType NetAddressType) bool { + return addrType == TorV3Address } // addAddressByIP is a convenience function that adds an address to the @@ -708,7 +708,7 @@ func TestAddLocalAddress(t *testing.T) { priority: InterfacePrio, valid: true, }, { - name: "routable TORv3 address", + name: "routable TorV3 address", host: torv3Host, priority: ManualPrio, valid: true, @@ -787,12 +787,12 @@ func TestGetBestLocalAddress(t *testing.T) { newAddressFromIP(net.ParseIP("2001:470::1")), } - // TORv3 address. + // TorV3 address. torAddrType, torAddrBytes := EncodeHost(torv3Host) torAddr, err := NewNetAddressFromParams(torAddrType, torAddrBytes, 0, time.Unix(time.Now().Unix(), 0), wire.SFNodeNetwork) if err != nil { - t.Fatalf("failed to create TORv3 NetAddress: %v", err) + t.Fatalf("failed to create TorV3 NetAddress: %v", err) } var tests = []struct { @@ -892,7 +892,7 @@ func TestGetBestLocalAddress(t *testing.T) { } } - // Test4: Add TORv3 address with ManualPrio + // Test4: Add TorV3 address with ManualPrio amgr.AddLocalAddress(torAddr, ManualPrio) for x, test := range tests { remoteAddr := test.remoteAddr @@ -1120,10 +1120,10 @@ func TestGetAddressWithFilter(t *testing.T) { filter: natfOnlyIPv6, wantType: IPv6Address, }, { - name: "returns address matching TORv3 filter", + name: "returns address matching TorV3 filter", addresses: []*NetAddress{ipv4Addr, ipv6Addr, torv3Addr}, - filter: natfOnlyTORv3, - wantType: TORv3Address, + filter: natfOnlyTorV3, + wantType: TorV3Address, }, { name: "returns nil when no matching IPv4 addresses", addresses: []*NetAddress{ipv6Addr}, diff --git a/addrmgr/netaddress.go b/addrmgr/netaddress.go index 9ceaa9886..4380bb147 100644 --- a/addrmgr/netaddress.go +++ b/addrmgr/netaddress.go @@ -38,7 +38,7 @@ type NetAddress struct { // IsRoutable returns a boolean indicating whether the network address is // routable. func (netAddr *NetAddress) IsRoutable() bool { - if netAddr.Type == TORv3Address { + if netAddr.Type == TorV3Address { return true } return IsRoutable(netAddr.IP) @@ -53,10 +53,10 @@ func (netAddr *NetAddress) ipString() string { return net.IP(netIP).String() case IPv4Address: return net.IP(netIP).String() - case TORv3Address: + case TorV3Address: var publicKey [32]byte copy(publicKey[:], netIP) - checksum := calcTORv3Checksum(publicKey) + checksum := calcTorV3Checksum(publicKey) var torAddressBytes [35]byte copy(torAddressBytes[:32], publicKey[:]) copy(torAddressBytes[32:34], checksum[:]) @@ -105,8 +105,8 @@ func deriveNetAddressType(claimedType NetAddressType, addrBytes []byte) (NetAddr return IPv4Address, nil case len == 16: return IPv6Address, nil - case len == 32 && claimedType == TORv3Address: - return TORv3Address, nil + case len == 32 && claimedType == TorV3Address: + return TorV3Address, nil } str := fmt.Sprintf("unable to determine address type from raw network "+ "address bytes: %v", addrBytes) diff --git a/addrmgr/netaddress_test.go b/addrmgr/netaddress_test.go index b70ad8890..8008b21b4 100644 --- a/addrmgr/netaddress_test.go +++ b/addrmgr/netaddress_test.go @@ -110,7 +110,7 @@ func TestKey(t *testing.T) { {host: "fee2::3:3", port: 8335, want: "[fee2::3:3]:8335"}, {host: "fef3::4:4", port: 8336, want: "[fef3::4:4]:8336"}, - // TORv3 + // TorV3 {host: torAddress, port: 8333, want: torAddress + ":8333"}, } @@ -220,14 +220,14 @@ func TestNewNetAddressFromParams(t *testing.T) { }, { name: "32 byte torv3 address stored in 32 bytes", - addrType: TORv3Address, + addrType: TorV3Address, addrBytes: torAddressBytes, want: &NetAddress{ IP: torAddressBytes, Port: port, Services: services, Timestamp: timestamp, - Type: TORv3Address, + Type: TorV3Address, }, error_expected: false, }, diff --git a/addrmgr/network.go b/addrmgr/network.go index 14ae95353..92b9f46a7 100644 --- a/addrmgr/network.go +++ b/addrmgr/network.go @@ -112,7 +112,7 @@ const ( IPv4Address NetAddressType = 1 IPv6Address NetAddressType = 2 // TorV2Address NetAddressType = 3 // No longer supported - TORv3Address NetAddressType = 4 + TorV3Address NetAddressType = 4 ) // NetAddressTypeFilter represents a function that returns whether a particular @@ -212,9 +212,9 @@ func isRFC6598(netIP net.IP) bool { return rfc6598Net.Contains(netIP) } -// calcTORv3Checksum returns the checksum bytes given a 32 byte -// TORv3 public key. -func calcTORv3Checksum(publicKey [32]byte) [2]byte { +// calcTorV3Checksum returns the checksum bytes given a 32-byte TorV3 public +// key. +func calcTorV3Checksum(publicKey [32]byte) [2]byte { const ( prefix = ".onion checksum" prefixLen = len(prefix) @@ -231,10 +231,10 @@ func calcTORv3Checksum(publicKey [32]byte) [2]byte { return result } -// isTORv3 returns whether or not the passed address is a valid TORv3 address +// isTorV3 returns whether or not the passed address is a valid TorV3 address // with the checksum and version bytes. If it is valid, it also returns the // public key of the tor v3 address. -func isTORv3(addressBytes []byte) ([32]byte, bool) { +func isTorV3(addressBytes []byte) ([32]byte, bool) { var publicKey [32]byte if len(addressBytes) != 35 { return publicKey, false @@ -246,7 +246,7 @@ func isTORv3(addressBytes []byte) ([32]byte, bool) { } copy(publicKey[:], addressBytes[:32]) - computedChecksum := calcTORv3Checksum(publicKey) + computedChecksum := calcTorV3Checksum(publicKey) var checksum [2]byte copy(checksum[:], addressBytes[32:34]) @@ -284,7 +284,7 @@ func IsRoutable(netIP net.IP) bool { // address. func (na *NetAddress) GroupKey() string { netIP := net.IP(na.IP) - if na.Type == TORv3Address { + if na.Type == TorV3Address { // Group is keyed off the first 4 bits of the public key. return fmt.Sprintf("torv3:%d", netIP[0]&0xf) } diff --git a/addrmgr/network_test.go b/addrmgr/network_test.go index bc22f0946..970f3c994 100644 --- a/addrmgr/network_test.go +++ b/addrmgr/network_test.go @@ -184,7 +184,7 @@ func TestGroupKey(t *testing.T) { {name: "ipv6 hurricane electric", host: "2001:470:1f10:a1::2", expected: "2001:470:1000::"}, {name: "ipv6 hurricane electric 2", host: "2001:0470:1f10:a1::2", expected: "2001:470:1000::"}, - // TORv3 + // TorV3 { name: "torv3", host: "xa4r2iadxm55fbnqgwwi5mymqdcofiu3w6rpbtqn7b2dyn7mgwj64jyd.onion", diff --git a/server.go b/server.go index e3380a011..a354c5130 100644 --- a/server.go +++ b/server.go @@ -967,8 +967,8 @@ func wireToAddrmgrNetAddressType(addrType wire.NetAddressType) addrmgr.NetAddres return addrmgr.IPv4Address case wire.IPv6Address: return addrmgr.IPv6Address - case wire.TORv3Address: - return addrmgr.TORv3Address + case wire.TorV3Address: + return addrmgr.TorV3Address } return addrmgr.UnknownAddressType } @@ -981,8 +981,8 @@ func addrmgrToWireNetAddressType(addrType addrmgr.NetAddressType) wire.NetAddres return wire.IPv4Address case addrmgr.IPv6Address: return wire.IPv6Address - case addrmgr.TORv3Address: - return wire.TORv3Address + case addrmgr.TorV3Address: + return wire.TorV3Address } return wire.UnknownAddressType } @@ -1145,7 +1145,7 @@ func isSupportedNetAddrTypeV1(addrType addrmgr.NetAddressType) bool { // network address type is supported by the addrv2 wire message. func isSupportedNetAddressTypeV2(addrType addrmgr.NetAddressType) bool { switch addrType { - case addrmgr.IPv4Address, addrmgr.IPv6Address, addrmgr.TORv3Address: + case addrmgr.IPv4Address, addrmgr.IPv6Address, addrmgr.TorV3Address: return true } return false @@ -4416,7 +4416,7 @@ func newServer(ctx context.Context, profiler *profileServer, switch addrType { case addrmgr.IPv4Address, addrmgr.IPv6Address: return true - case addrmgr.TORv3Address: + case addrmgr.TorV3Address: // Require .onion reachability. return !cfg.NoOnion && (cfg.Proxy != "" || cfg.OnionProxy != "") } @@ -4676,7 +4676,7 @@ func addrStringToNetAddr(addr string) (net.Addr, error) { // a DNS lookup should not be performed for the address. addrType, _ := addrmgr.EncodeHost(host) switch addrType { - case addrmgr.TORv3Address: + case addrmgr.TorV3Address: return &simpleAddr{ net: "tcp", addr: addr, diff --git a/server_test.go b/server_test.go index 36fd29044..ce0d644bd 100644 --- a/server_test.go +++ b/server_test.go @@ -32,7 +32,7 @@ func TestHostToNetAddress(t *testing.T) { wantErr bool want *addrmgr.NetAddress }{{ - name: "valid TORv3 address", + name: "valid TorV3 address", host: torv3Host, port: 9108, lookupFunc: nil, diff --git a/wire/msgaddrv2.go b/wire/msgaddrv2.go index aed4779c1..cda7ec64c 100644 --- a/wire/msgaddrv2.go +++ b/wire/msgaddrv2.go @@ -64,7 +64,7 @@ func readNetAddressV2(op string, r io.Reader, pver uint32, na *NetAddressV2) err } na.EncodedAddr = ip[:] - case TORv3Address: + case TorV3Address: var addr [32]byte err := readElement(r, &addr) if err != nil { @@ -115,9 +115,9 @@ func writeNetAddressV2(op string, w io.Writer, pver uint32, na *NetAddressV2) er return messageError(op, ErrInvalidMsg, msg) } - case TORv3Address: + case TorV3Address: if len(encodedAddr) != 32 { - msg := fmt.Sprintf("invalid TORv3 address length: %d", len(encodedAddr)) + msg := fmt.Sprintf("invalid TorV3 address length: %d", len(encodedAddr)) return messageError(op, ErrInvalidMsg, msg) } diff --git a/wire/msgaddrv2_test.go b/wire/msgaddrv2_test.go index 04a469893..664480426 100644 --- a/wire/msgaddrv2_test.go +++ b/wire/msgaddrv2_test.go @@ -39,7 +39,7 @@ var ( ipv4NetAddress = newNetAddressV2(IPv4Address, ipv4IpBytes, 8333) ipv6NetAddress = newNetAddressV2(IPv6Address, ipv6IpBytes, 8333) - torv3NetAddress = newNetAddressV2(TORv3Address, torV3IpBytes, 8333) + torv3NetAddress = newNetAddressV2(TorV3Address, torV3IpBytes, 8333) serializedIPv4NetAddressBytes = []byte{ 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // Timestamp @@ -63,10 +63,10 @@ var ( 0x7f, 0x00, 0x00, 0x01, // EncodedAddr 0x8d, 0x20, // Port 8333 (little-endian) } - serializedTORv3NetAddressBytes = []byte{ + serializedTorV3NetAddressBytes = []byte{ 0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x03, // Type (TORv3) + 0x03, // Type (TorV3) 0xb8, 0x39, 0x1d, 0x20, 0x03, 0xbb, 0x3b, 0xd2, // EncodedAddr 0x85, 0xb0, 0x35, 0xac, 0x8e, 0xb3, 0x0c, 0x80, // EncodedAddr 0xc4, 0xe2, 0xa2, 0x9b, 0xb7, 0xa2, 0xf0, 0xce, // EncodedAddr @@ -157,7 +157,7 @@ func TestAddrV2Wire(t *testing.T) { {0x03}, serializedIPv4NetAddressBytes, serializedIPv6NetAddressBytes, - serializedTORv3NetAddressBytes, + serializedTorV3NetAddressBytes, }, nil), }, { name: "latest protocol version with maximum addresses", @@ -275,7 +275,7 @@ func TestAddrV2BtcDecode(t *testing.T) { {0x04}, serializedIPv4NetAddressBytes, serializedIPv6NetAddressBytes, - serializedTORv3NetAddressBytes, + serializedTorV3NetAddressBytes, serializedUnknownNetAddressBytes, }, nil), wantAddrs: nil, @@ -287,7 +287,7 @@ func TestAddrV2BtcDecode(t *testing.T) { {0x03}, serializedIPv4NetAddressBytes, serializedIPv6NetAddressBytes, - serializedTORv3NetAddressBytes, + serializedTorV3NetAddressBytes, }, nil), wantAddrs: []NetAddressV2{ ipv4NetAddress, @@ -370,12 +370,12 @@ func TestAddrV2BtcEncode(t *testing.T) { }}, wantErr: ErrInvalidMsg, }, { - name: "message with wrong size TORv3 address", + name: "message with wrong size TorV3 address", pver: pver, addrs: []NetAddressV2{{ Timestamp: time.Unix(0x495fab29, 0), Services: SFNodeNetwork, - Type: TORv3Address, + Type: TorV3Address, EncodedAddr: make([]byte, 1), Port: 8333, }}, diff --git a/wire/netaddressv2.go b/wire/netaddressv2.go index 5e2d41521..ecbaffa93 100644 --- a/wire/netaddressv2.go +++ b/wire/netaddressv2.go @@ -16,7 +16,7 @@ const ( UnknownAddressType NetAddressType = 0 IPv4Address NetAddressType = 1 IPv6Address NetAddressType = 2 - TORv3Address NetAddressType = 3 + TorV3Address NetAddressType = 3 ) // NetAddressV2 defines information about a peer on the network.