github.com/btcsuite/btcd@v0.24.0/wire/netaddress_test.go (about) 1 // Copyright (c) 2013-2016 The btcsuite developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package wire 6 7 import ( 8 "bytes" 9 "io" 10 "net" 11 "reflect" 12 "testing" 13 "time" 14 15 "github.com/davecgh/go-spew/spew" 16 ) 17 18 // TestNetAddress tests the NetAddress API. 19 func TestNetAddress(t *testing.T) { 20 ip := net.ParseIP("127.0.0.1") 21 port := 8333 22 23 // Test NewNetAddress. 24 na := NewNetAddress(&net.TCPAddr{IP: ip, Port: port}, 0) 25 26 // Ensure we get the same ip, port, and services back out. 27 if !na.IP.Equal(ip) { 28 t.Errorf("NetNetAddress: wrong ip - got %v, want %v", na.IP, ip) 29 } 30 if na.Port != uint16(port) { 31 t.Errorf("NetNetAddress: wrong port - got %v, want %v", na.Port, 32 port) 33 } 34 if na.Services != 0 { 35 t.Errorf("NetNetAddress: wrong services - got %v, want %v", 36 na.Services, 0) 37 } 38 if na.HasService(SFNodeNetwork) { 39 t.Errorf("HasService: SFNodeNetwork service is set") 40 } 41 42 // Ensure adding the full service node flag works. 43 na.AddService(SFNodeNetwork) 44 if na.Services != SFNodeNetwork { 45 t.Errorf("AddService: wrong services - got %v, want %v", 46 na.Services, SFNodeNetwork) 47 } 48 if !na.HasService(SFNodeNetwork) { 49 t.Errorf("HasService: SFNodeNetwork service not set") 50 } 51 52 // Ensure max payload is expected value for latest protocol version. 53 pver := ProtocolVersion 54 wantPayload := uint32(30) 55 maxPayload := maxNetAddressPayload(ProtocolVersion) 56 if maxPayload != wantPayload { 57 t.Errorf("maxNetAddressPayload: wrong max payload length for "+ 58 "protocol version %d - got %v, want %v", pver, 59 maxPayload, wantPayload) 60 } 61 62 // Protocol version before NetAddressTimeVersion when timestamp was 63 // added. Ensure max payload is expected value for it. 64 pver = NetAddressTimeVersion - 1 65 wantPayload = 26 66 maxPayload = maxNetAddressPayload(pver) 67 if maxPayload != wantPayload { 68 t.Errorf("maxNetAddressPayload: wrong max payload length for "+ 69 "protocol version %d - got %v, want %v", pver, 70 maxPayload, wantPayload) 71 } 72 } 73 74 // TestNetAddressWire tests the NetAddress wire encode and decode for various 75 // protocol versions and timestamp flag combinations. 76 func TestNetAddressWire(t *testing.T) { 77 // baseNetAddr is used in the various tests as a baseline NetAddress. 78 baseNetAddr := NetAddress{ 79 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST 80 Services: SFNodeNetwork, 81 IP: net.ParseIP("127.0.0.1"), 82 Port: 8333, 83 } 84 85 // baseNetAddrNoTS is baseNetAddr with a zero value for the timestamp. 86 baseNetAddrNoTS := baseNetAddr 87 baseNetAddrNoTS.Timestamp = time.Time{} 88 89 // baseNetAddrEncoded is the wire encoded bytes of baseNetAddr. 90 baseNetAddrEncoded := []byte{ 91 0x29, 0xab, 0x5f, 0x49, // Timestamp 92 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 93 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 94 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 95 0x20, 0x8d, // Port 8333 in big-endian 96 } 97 98 // baseNetAddrNoTSEncoded is the wire encoded bytes of baseNetAddrNoTS. 99 baseNetAddrNoTSEncoded := []byte{ 100 // No timestamp 101 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 103 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 104 0x20, 0x8d, // Port 8333 in big-endian 105 } 106 107 tests := []struct { 108 in NetAddress // NetAddress to encode 109 out NetAddress // Expected decoded NetAddress 110 ts bool // Include timestamp? 111 buf []byte // Wire encoding 112 pver uint32 // Protocol version for wire encoding 113 }{ 114 // Latest protocol version without ts flag. 115 { 116 baseNetAddr, 117 baseNetAddrNoTS, 118 false, 119 baseNetAddrNoTSEncoded, 120 ProtocolVersion, 121 }, 122 123 // Latest protocol version with ts flag. 124 { 125 baseNetAddr, 126 baseNetAddr, 127 true, 128 baseNetAddrEncoded, 129 ProtocolVersion, 130 }, 131 132 // Protocol version NetAddressTimeVersion without ts flag. 133 { 134 baseNetAddr, 135 baseNetAddrNoTS, 136 false, 137 baseNetAddrNoTSEncoded, 138 NetAddressTimeVersion, 139 }, 140 141 // Protocol version NetAddressTimeVersion with ts flag. 142 { 143 baseNetAddr, 144 baseNetAddr, 145 true, 146 baseNetAddrEncoded, 147 NetAddressTimeVersion, 148 }, 149 150 // Protocol version NetAddressTimeVersion-1 without ts flag. 151 { 152 baseNetAddr, 153 baseNetAddrNoTS, 154 false, 155 baseNetAddrNoTSEncoded, 156 NetAddressTimeVersion - 1, 157 }, 158 159 // Protocol version NetAddressTimeVersion-1 with timestamp. 160 // Even though the timestamp flag is set, this shouldn't have a 161 // timestamp since it is a protocol version before it was 162 // added. 163 { 164 baseNetAddr, 165 baseNetAddrNoTS, 166 true, 167 baseNetAddrNoTSEncoded, 168 NetAddressTimeVersion - 1, 169 }, 170 } 171 172 t.Logf("Running %d tests", len(tests)) 173 for i, test := range tests { 174 // Encode to wire format. 175 var buf bytes.Buffer 176 err := writeNetAddress(&buf, test.pver, &test.in, test.ts) 177 if err != nil { 178 t.Errorf("writeNetAddress #%d error %v", i, err) 179 continue 180 } 181 if !bytes.Equal(buf.Bytes(), test.buf) { 182 t.Errorf("writeNetAddress #%d\n got: %s want: %s", i, 183 spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) 184 continue 185 } 186 187 // Decode the message from wire format. 188 var na NetAddress 189 rbuf := bytes.NewReader(test.buf) 190 err = readNetAddress(rbuf, test.pver, &na, test.ts) 191 if err != nil { 192 t.Errorf("readNetAddress #%d error %v", i, err) 193 continue 194 } 195 if !reflect.DeepEqual(na, test.out) { 196 t.Errorf("readNetAddress #%d\n got: %s want: %s", i, 197 spew.Sdump(na), spew.Sdump(test.out)) 198 continue 199 } 200 } 201 } 202 203 // TestNetAddressWireErrors performs negative tests against wire encode and 204 // decode NetAddress to confirm error paths work correctly. 205 func TestNetAddressWireErrors(t *testing.T) { 206 pver := ProtocolVersion 207 pverNAT := NetAddressTimeVersion - 1 208 209 // baseNetAddr is used in the various tests as a baseline NetAddress. 210 baseNetAddr := NetAddress{ 211 Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST 212 Services: SFNodeNetwork, 213 IP: net.ParseIP("127.0.0.1"), 214 Port: 8333, 215 } 216 217 tests := []struct { 218 in *NetAddress // Value to encode 219 buf []byte // Wire encoding 220 pver uint32 // Protocol version for wire encoding 221 ts bool // Include timestamp flag 222 max int // Max size of fixed buffer to induce errors 223 writeErr error // Expected write error 224 readErr error // Expected read error 225 }{ 226 // Latest protocol version with timestamp and intentional 227 // read/write errors. 228 // Force errors on timestamp. 229 {&baseNetAddr, []byte{}, pver, true, 0, io.ErrShortWrite, io.EOF}, 230 // Force errors on services. 231 {&baseNetAddr, []byte{}, pver, true, 4, io.ErrShortWrite, io.EOF}, 232 // Force errors on ip. 233 {&baseNetAddr, []byte{}, pver, true, 12, io.ErrShortWrite, io.EOF}, 234 // Force errors on port. 235 {&baseNetAddr, []byte{}, pver, true, 28, io.ErrShortWrite, io.EOF}, 236 237 // Latest protocol version with no timestamp and intentional 238 // read/write errors. 239 // Force errors on services. 240 {&baseNetAddr, []byte{}, pver, false, 0, io.ErrShortWrite, io.EOF}, 241 // Force errors on ip. 242 {&baseNetAddr, []byte{}, pver, false, 8, io.ErrShortWrite, io.EOF}, 243 // Force errors on port. 244 {&baseNetAddr, []byte{}, pver, false, 24, io.ErrShortWrite, io.EOF}, 245 246 // Protocol version before NetAddressTimeVersion with timestamp 247 // flag set (should not have timestamp due to old protocol 248 // version) and intentional read/write errors. 249 // Force errors on services. 250 {&baseNetAddr, []byte{}, pverNAT, true, 0, io.ErrShortWrite, io.EOF}, 251 // Force errors on ip. 252 {&baseNetAddr, []byte{}, pverNAT, true, 8, io.ErrShortWrite, io.EOF}, 253 // Force errors on port. 254 {&baseNetAddr, []byte{}, pverNAT, true, 24, io.ErrShortWrite, io.EOF}, 255 } 256 257 t.Logf("Running %d tests", len(tests)) 258 for i, test := range tests { 259 // Encode to wire format. 260 w := newFixedWriter(test.max) 261 err := writeNetAddress(w, test.pver, test.in, test.ts) 262 if err != test.writeErr { 263 t.Errorf("writeNetAddress #%d wrong error got: %v, want: %v", 264 i, err, test.writeErr) 265 continue 266 } 267 268 // Decode from wire format. 269 var na NetAddress 270 r := newFixedReader(test.max, test.buf) 271 err = readNetAddress(r, test.pver, &na, test.ts) 272 if err != test.readErr { 273 t.Errorf("readNetAddress #%d wrong error got: %v, want: %v", 274 i, err, test.readErr) 275 continue 276 } 277 } 278 }