mirror of
https://github.com/btcsuite/btcd.git
synced 2024-11-19 09:50:08 +01:00
wire: Treat NetAddress more like immutable
Replace assignments to individual fields of wire.NetAddress with creating the entire object at once, as one would do if the type was immutable. In some places this replaces the creation of a NetAddress with a high-precision timestamp with a call to a 'constructor' that converts the timestamp to single second precision. For consistency, the tests have also been changed to use single-precision timestamps. Lastly, the number of allocations in readNetAddress have been reduced by reading the services directly into the NetAddress instead of first into a temporary variable.
This commit is contained in:
parent
712399c0db
commit
c5751b75a9
@ -596,18 +596,16 @@ func (a *AddrManager) AddAddressByIP(addrIP string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// Put it in wire.Netaddress
|
// Put it in wire.Netaddress
|
||||||
var na wire.NetAddress
|
ip := net.ParseIP(addr)
|
||||||
na.Timestamp = time.Now()
|
if ip == nil {
|
||||||
na.IP = net.ParseIP(addr)
|
|
||||||
if na.IP == nil {
|
|
||||||
return fmt.Errorf("invalid ip address %s", addr)
|
return fmt.Errorf("invalid ip address %s", addr)
|
||||||
}
|
}
|
||||||
port, err := strconv.ParseUint(portStr, 10, 0)
|
port, err := strconv.ParseUint(portStr, 10, 0)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("invalid port %s: %v", portStr, err)
|
return fmt.Errorf("invalid port %s: %v", portStr, err)
|
||||||
}
|
}
|
||||||
na.Port = uint16(port)
|
na := wire.NewNetAddressIPPort(ip, uint16(port), 0)
|
||||||
a.AddAddress(&na, &na) // XXX use correct src address
|
a.AddAddress(na, na) // XXX use correct src address
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1069,16 +1067,13 @@ func (a *AddrManager) GetBestLocalAddress(remoteAddr *wire.NetAddress) *wire.Net
|
|||||||
remoteAddr.Port)
|
remoteAddr.Port)
|
||||||
|
|
||||||
// Send something unroutable if nothing suitable.
|
// Send something unroutable if nothing suitable.
|
||||||
bestAddress = &wire.NetAddress{
|
var ip net.IP
|
||||||
Timestamp: time.Now(),
|
|
||||||
Services: wire.SFNodeNetwork,
|
|
||||||
Port: 0,
|
|
||||||
}
|
|
||||||
if !IsIPv4(remoteAddr) && !IsOnionCatTor(remoteAddr) {
|
if !IsIPv4(remoteAddr) && !IsOnionCatTor(remoteAddr) {
|
||||||
bestAddress.IP = net.IPv6zero
|
ip = net.IPv6zero
|
||||||
} else {
|
} else {
|
||||||
bestAddress.IP = net.IPv4zero
|
ip = net.IPv4zero
|
||||||
}
|
}
|
||||||
|
bestAddress = wire.NewNetAddressIPPort(ip, 0, wire.SFNodeNetwork)
|
||||||
}
|
}
|
||||||
|
|
||||||
return bestAddress
|
return bestAddress
|
||||||
|
@ -93,12 +93,7 @@ func addNaTests() {
|
|||||||
|
|
||||||
func addNaTest(ip string, port uint16, want string) {
|
func addNaTest(ip string, port uint16, want string) {
|
||||||
nip := net.ParseIP(ip)
|
nip := net.ParseIP(ip)
|
||||||
na := wire.NetAddress{
|
na := *wire.NewNetAddressIPPort(nip, port, wire.SFNodeNetwork)
|
||||||
Timestamp: time.Now(),
|
|
||||||
Services: wire.SFNodeNetwork,
|
|
||||||
IP: nip,
|
|
||||||
Port: port,
|
|
||||||
}
|
|
||||||
test := naTest{na, want}
|
test := naTest{na, want}
|
||||||
naTests = append(naTests, test)
|
naTests = append(naTests, test)
|
||||||
}
|
}
|
||||||
@ -245,7 +240,8 @@ func TestConnected(t *testing.T) {
|
|||||||
}
|
}
|
||||||
ka := n.GetAddress()
|
ka := n.GetAddress()
|
||||||
na := ka.NetAddress()
|
na := ka.NetAddress()
|
||||||
na.Timestamp = time.Now().Add(time.Hour * -1) // make it an hour ago
|
// make it an hour ago
|
||||||
|
na.Timestamp = time.Unix(time.Now().Add(time.Hour*-1).Unix(), 0)
|
||||||
|
|
||||||
n.Connected(na)
|
n.Connected(na)
|
||||||
|
|
||||||
@ -262,7 +258,6 @@ func TestNeedMoreAddresses(t *testing.T) {
|
|||||||
t.Errorf("Expected that we need more addresses")
|
t.Errorf("Expected that we need more addresses")
|
||||||
}
|
}
|
||||||
addrs := make([]*wire.NetAddress, addrsToAdd)
|
addrs := make([]*wire.NetAddress, addrsToAdd)
|
||||||
now := time.Now()
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < addrsToAdd; i++ {
|
for i := 0; i < addrsToAdd; i++ {
|
||||||
@ -273,12 +268,7 @@ func TestNeedMoreAddresses(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srcAddr := &wire.NetAddress{
|
srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0)
|
||||||
Timestamp: now,
|
|
||||||
Services: 0,
|
|
||||||
IP: net.IPv4(173, 144, 173, 111),
|
|
||||||
Port: 8333,
|
|
||||||
}
|
|
||||||
|
|
||||||
n.AddAddresses(addrs, srcAddr)
|
n.AddAddresses(addrs, srcAddr)
|
||||||
numAddrs := n.NumAddresses()
|
numAddrs := n.NumAddresses()
|
||||||
@ -296,7 +286,6 @@ func TestGood(t *testing.T) {
|
|||||||
n := addrmgr.New("testgood", lookupFunc)
|
n := addrmgr.New("testgood", lookupFunc)
|
||||||
addrsToAdd := 64 * 64
|
addrsToAdd := 64 * 64
|
||||||
addrs := make([]*wire.NetAddress, addrsToAdd)
|
addrs := make([]*wire.NetAddress, addrsToAdd)
|
||||||
now := time.Now()
|
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < addrsToAdd; i++ {
|
for i := 0; i < addrsToAdd; i++ {
|
||||||
@ -307,12 +296,7 @@ func TestGood(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
srcAddr := &wire.NetAddress{
|
srcAddr := wire.NewNetAddressIPPort(net.IPv4(173, 144, 173, 111), 8333, 0)
|
||||||
Timestamp: now,
|
|
||||||
Services: 0,
|
|
||||||
IP: net.IPv4(173, 144, 173, 111),
|
|
||||||
Port: 8333,
|
|
||||||
}
|
|
||||||
|
|
||||||
n.AddAddresses(addrs, srcAddr)
|
n.AddAddresses(addrs, srcAddr)
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
|
@ -14,33 +14,34 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestChance(t *testing.T) {
|
func TestChance(t *testing.T) {
|
||||||
|
now := time.Unix(time.Now().Unix(), 0)
|
||||||
var tests = []struct {
|
var tests = []struct {
|
||||||
addr *addrmgr.KnownAddress
|
addr *addrmgr.KnownAddress
|
||||||
expected float64
|
expected float64
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
//Test normal case
|
//Test normal case
|
||||||
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: time.Now().Add(-35 * time.Second)},
|
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: now.Add(-35 * time.Second)},
|
||||||
0, time.Now().Add(-30*time.Minute), time.Now(), false, 0),
|
0, time.Now().Add(-30*time.Minute), time.Now(), false, 0),
|
||||||
1.0,
|
1.0,
|
||||||
}, {
|
}, {
|
||||||
//Test case in which lastseen < 0
|
//Test case in which lastseen < 0
|
||||||
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: time.Now().Add(20 * time.Second)},
|
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: now.Add(20 * time.Second)},
|
||||||
0, time.Now().Add(-30*time.Minute), time.Now(), false, 0),
|
0, time.Now().Add(-30*time.Minute), time.Now(), false, 0),
|
||||||
1.0,
|
1.0,
|
||||||
}, {
|
}, {
|
||||||
//Test case in which lastattempt < 0
|
//Test case in which lastattempt < 0
|
||||||
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: time.Now().Add(-35 * time.Second)},
|
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: now.Add(-35 * time.Second)},
|
||||||
0, time.Now().Add(30*time.Minute), time.Now(), false, 0),
|
0, time.Now().Add(30*time.Minute), time.Now(), false, 0),
|
||||||
1.0 * .01,
|
1.0 * .01,
|
||||||
}, {
|
}, {
|
||||||
//Test case in which lastattempt < ten minutes
|
//Test case in which lastattempt < ten minutes
|
||||||
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: time.Now().Add(-35 * time.Second)},
|
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: now.Add(-35 * time.Second)},
|
||||||
0, time.Now().Add(-5*time.Minute), time.Now(), false, 0),
|
0, time.Now().Add(-5*time.Minute), time.Now(), false, 0),
|
||||||
1.0 * .01,
|
1.0 * .01,
|
||||||
}, {
|
}, {
|
||||||
//Test case with several failed attempts.
|
//Test case with several failed attempts.
|
||||||
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: time.Now().Add(-35 * time.Second)},
|
addrmgr.TstNewKnownAddress(&wire.NetAddress{Timestamp: now.Add(-35 * time.Second)},
|
||||||
2, time.Now().Add(-30*time.Minute), time.Now(), false, 0),
|
2, time.Now().Add(-30*time.Minute), time.Now(), false, 0),
|
||||||
1 / 1.5 / 1.5,
|
1 / 1.5 / 1.5,
|
||||||
},
|
},
|
||||||
@ -56,11 +57,12 @@ func TestChance(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIsBad(t *testing.T) {
|
func TestIsBad(t *testing.T) {
|
||||||
future := time.Now().Add(35 * time.Minute)
|
now := time.Unix(time.Now().Unix(), 0)
|
||||||
monthOld := time.Now().Add(-43 * time.Hour * 24)
|
future := now.Add(35 * time.Minute)
|
||||||
secondsOld := time.Now().Add(-2 * time.Second)
|
monthOld := now.Add(-43 * time.Hour * 24)
|
||||||
minutesOld := time.Now().Add(-27 * time.Minute)
|
secondsOld := now.Add(-2 * time.Second)
|
||||||
hoursOld := time.Now().Add(-5 * time.Hour)
|
minutesOld := now.Add(-27 * time.Minute)
|
||||||
|
hoursOld := now.Add(-5 * time.Hour)
|
||||||
zeroTime := time.Time{}
|
zeroTime := time.Time{}
|
||||||
|
|
||||||
futureNa := &wire.NetAddress{Timestamp: future}
|
futureNa := &wire.NetAddress{Timestamp: future}
|
||||||
|
@ -7,7 +7,6 @@ package addrmgr_test
|
|||||||
import (
|
import (
|
||||||
"net"
|
"net"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/btcsuite/btcd/addrmgr"
|
"github.com/btcsuite/btcd/addrmgr"
|
||||||
"github.com/btcsuite/btcd/wire"
|
"github.com/btcsuite/btcd/wire"
|
||||||
@ -40,12 +39,7 @@ func TestIPTypes(t *testing.T) {
|
|||||||
rfc4193, rfc4380, rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598,
|
rfc4193, rfc4380, rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598,
|
||||||
local, valid, routable bool) ipTest {
|
local, valid, routable bool) ipTest {
|
||||||
nip := net.ParseIP(ip)
|
nip := net.ParseIP(ip)
|
||||||
na := wire.NetAddress{
|
na := *wire.NewNetAddressIPPort(nip, 8333, wire.SFNodeNetwork)
|
||||||
Timestamp: time.Now(),
|
|
||||||
Services: wire.SFNodeNetwork,
|
|
||||||
IP: nip,
|
|
||||||
Port: 8333,
|
|
||||||
}
|
|
||||||
test := ipTest{na, rfc1918, rfc2544, rfc3849, rfc3927, rfc3964, rfc4193, rfc4380,
|
test := ipTest{na, rfc1918, rfc2544, rfc3849, rfc3927, rfc3964, rfc4193, rfc4380,
|
||||||
rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598, local, valid, routable}
|
rfc4843, rfc4862, rfc5737, rfc6052, rfc6145, rfc6598, local, valid, routable}
|
||||||
return test
|
return test
|
||||||
@ -198,12 +192,7 @@ func TestGroupKey(t *testing.T) {
|
|||||||
|
|
||||||
for i, test := range tests {
|
for i, test := range tests {
|
||||||
nip := net.ParseIP(test.ip)
|
nip := net.ParseIP(test.ip)
|
||||||
na := wire.NetAddress{
|
na := *wire.NewNetAddressIPPort(nip, 8333, wire.SFNodeNetwork)
|
||||||
Timestamp: time.Now(),
|
|
||||||
Services: wire.SFNodeNetwork,
|
|
||||||
IP: nip,
|
|
||||||
Port: 8333,
|
|
||||||
}
|
|
||||||
if key := addrmgr.GroupKey(&na); key != test.expected {
|
if key := addrmgr.GroupKey(&na); key != test.expected {
|
||||||
t.Errorf("TestGroupKey #%d (%s): unexpected group key "+
|
t.Errorf("TestGroupKey #%d (%s): unexpected group key "+
|
||||||
"- got '%s', want '%s'", i, test.name,
|
"- got '%s', want '%s'", i, test.name,
|
||||||
|
@ -60,14 +60,13 @@ func SeedFromDNS(chainParams *chaincfg.Params, reqServices wire.ServiceFlag,
|
|||||||
// if this errors then we have *real* problems
|
// if this errors then we have *real* problems
|
||||||
intPort, _ := strconv.Atoi(chainParams.DefaultPort)
|
intPort, _ := strconv.Atoi(chainParams.DefaultPort)
|
||||||
for i, peer := range seedpeers {
|
for i, peer := range seedpeers {
|
||||||
addresses[i] = new(wire.NetAddress)
|
addresses[i] = wire.NewNetAddressTimestamp(
|
||||||
addresses[i].SetAddress(peer, uint16(intPort))
|
// bitcoind seeds with addresses from
|
||||||
// bitcoind seeds with addresses from
|
// a time randomly selected between 3
|
||||||
// a time randomly selected between 3
|
// and 7 days ago.
|
||||||
// and 7 days ago.
|
time.Now().Add(-1*time.Second*time.Duration(secondsIn3Days+
|
||||||
addresses[i].Timestamp = time.Now().Add(-1 *
|
randSource.Int31n(secondsIn4Days))),
|
||||||
time.Second * time.Duration(secondsIn3Days+
|
0, peer, uint16(intPort))
|
||||||
randSource.Int31n(secondsIn4Days)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
seedFn(addresses)
|
seedFn(addresses)
|
||||||
|
@ -775,10 +775,7 @@ func (p *Peer) localVersionMsg() (*wire.MsgVersion, error) {
|
|||||||
proxyaddress, _, err := net.SplitHostPort(p.cfg.Proxy)
|
proxyaddress, _, err := net.SplitHostPort(p.cfg.Proxy)
|
||||||
// invalid proxy means poorly configured, be on the safe side.
|
// invalid proxy means poorly configured, be on the safe side.
|
||||||
if err != nil || p.na.IP.String() == proxyaddress {
|
if err != nil || p.na.IP.String() == proxyaddress {
|
||||||
theirNA = &wire.NetAddress{
|
theirNA = wire.NewNetAddressIPPort(net.IP([]byte{0, 0, 0, 0}), 0, 0)
|
||||||
Timestamp: time.Now(),
|
|
||||||
IP: net.IP([]byte{0, 0, 0, 0}),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,20 +57,21 @@ func (na *NetAddress) AddService(service ServiceFlag) {
|
|||||||
na.Services |= service
|
na.Services |= service
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAddress is a convenience function to set the IP address and port in one
|
|
||||||
// call.
|
|
||||||
func (na *NetAddress) SetAddress(ip net.IP, port uint16) {
|
|
||||||
na.IP = ip
|
|
||||||
na.Port = port
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewNetAddressIPPort returns a new NetAddress using the provided IP, port, and
|
// NewNetAddressIPPort returns a new NetAddress using the provided IP, port, and
|
||||||
// supported services with defaults for the remaining fields.
|
// supported services with defaults for the remaining fields.
|
||||||
func NewNetAddressIPPort(ip net.IP, port uint16, services ServiceFlag) *NetAddress {
|
func NewNetAddressIPPort(ip net.IP, port uint16, services ServiceFlag) *NetAddress {
|
||||||
|
return NewNetAddressTimestamp(time.Now(), services, ip, port)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewNetAddressTimestamp returns a new NetAddress using the provided
|
||||||
|
// timestamp, IP, port, and supported services. The timestamp is rounded to
|
||||||
|
// single second precision.
|
||||||
|
func NewNetAddressTimestamp(
|
||||||
|
timestamp time.Time, services ServiceFlag, ip net.IP, port uint16) *NetAddress {
|
||||||
// Limit the timestamp to one second precision since the protocol
|
// Limit the timestamp to one second precision since the protocol
|
||||||
// doesn't support better.
|
// doesn't support better.
|
||||||
na := NetAddress{
|
na := NetAddress{
|
||||||
Timestamp: time.Unix(time.Now().Unix(), 0),
|
Timestamp: time.Unix(timestamp.Unix(), 0),
|
||||||
Services: services,
|
Services: services,
|
||||||
IP: ip,
|
IP: ip,
|
||||||
Port: port,
|
Port: port,
|
||||||
@ -88,7 +89,6 @@ func NewNetAddress(addr *net.TCPAddr, services ServiceFlag) *NetAddress {
|
|||||||
// version and whether or not the timestamp is included per ts. Some messages
|
// version and whether or not the timestamp is included per ts. Some messages
|
||||||
// like version do not include the timestamp.
|
// like version do not include the timestamp.
|
||||||
func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
|
func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
|
||||||
var services ServiceFlag
|
|
||||||
var ip [16]byte
|
var ip [16]byte
|
||||||
|
|
||||||
// NOTE: The bitcoin protocol uses a uint32 for the timestamp so it will
|
// NOTE: The bitcoin protocol uses a uint32 for the timestamp so it will
|
||||||
@ -101,7 +101,7 @@ func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err := readElements(r, &services, &ip)
|
err := readElements(r, &na.Services, &ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -111,8 +111,12 @@ func readNetAddress(r io.Reader, pver uint32, na *NetAddress, ts bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
na.Services = services
|
*na = NetAddress{
|
||||||
na.SetAddress(net.IP(ip[:]), port)
|
Timestamp: na.Timestamp,
|
||||||
|
Services: na.Services,
|
||||||
|
IP: net.IP(ip[:]),
|
||||||
|
Port: port,
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user