// TestNetAddressWire tests the NetAddress wire encode and decode for various // protocol versions and timestamp flag combinations. func TestNetAddressWire(t *testing.T) { // baseNetAddr is used in the various tests as a baseline NetAddress. baseNetAddr := wire.NetAddress{ Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: wire.SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), Port: 8333, } // baseNetAddrNoTS is baseNetAddr with a zero value for the timestamp. baseNetAddrNoTS := baseNetAddr baseNetAddrNoTS.Timestamp = time.Time{} // baseNetAddrEncoded is the wire encoded bytes of baseNetAddr. baseNetAddrEncoded := []byte{ 0x29, 0xab, 0x5f, 0x49, // Timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 0x20, 0x8d, // Port 8333 in big-endian } // baseNetAddrNoTSEncoded is the wire encoded bytes of baseNetAddrNoTS. baseNetAddrNoTSEncoded := []byte{ // No timestamp 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1 0x20, 0x8d, // Port 8333 in big-endian } tests := []struct { in wire.NetAddress // NetAddress to encode out wire.NetAddress // Expected decoded NetAddress ts bool // Include timestamp? buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding }{ // Latest protocol version without ts flag. { baseNetAddr, baseNetAddrNoTS, false, baseNetAddrNoTSEncoded, wire.ProtocolVersion, }, // Latest protocol version with ts flag. { baseNetAddr, baseNetAddr, true, baseNetAddrEncoded, wire.ProtocolVersion, }, // Protocol version NetAddressTimeVersion without ts flag. { baseNetAddr, baseNetAddrNoTS, false, baseNetAddrNoTSEncoded, wire.NetAddressTimeVersion, }, // Protocol version NetAddressTimeVersion with ts flag. { baseNetAddr, baseNetAddr, true, baseNetAddrEncoded, wire.NetAddressTimeVersion, }, // Protocol version NetAddressTimeVersion-1 without ts flag. { baseNetAddr, baseNetAddrNoTS, false, baseNetAddrNoTSEncoded, wire.NetAddressTimeVersion - 1, }, // Protocol version NetAddressTimeVersion-1 with timestamp. // Even though the timestamp flag is set, this shouldn't have a // timestamp since it is a protocol version before it was // added. { baseNetAddr, baseNetAddrNoTS, true, baseNetAddrNoTSEncoded, wire.NetAddressTimeVersion - 1, }, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. var buf bytes.Buffer err := wire.TstWriteNetAddress(&buf, test.pver, &test.in, test.ts) if err != nil { t.Errorf("writeNetAddress #%d error %v", i, err) continue } if !bytes.Equal(buf.Bytes(), test.buf) { t.Errorf("writeNetAddress #%d\n got: %s want: %s", i, spew.Sdump(buf.Bytes()), spew.Sdump(test.buf)) continue } // Decode the message from wire format. var na wire.NetAddress rbuf := bytes.NewReader(test.buf) err = wire.TstReadNetAddress(rbuf, test.pver, &na, test.ts) if err != nil { t.Errorf("readNetAddress #%d error %v", i, err) continue } if !reflect.DeepEqual(na, test.out) { t.Errorf("readNetAddress #%d\n got: %s want: %s", i, spew.Sdump(na), spew.Sdump(test.out)) continue } } }
// TestNetAddressWireErrors performs negative tests against wire encode and // decode NetAddress to confirm error paths work correctly. func TestNetAddressWireErrors(t *testing.T) { pver := wire.ProtocolVersion pverNAT := wire.NetAddressTimeVersion - 1 // baseNetAddr is used in the various tests as a baseline NetAddress. baseNetAddr := wire.NetAddress{ Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST Services: wire.SFNodeNetwork, IP: net.ParseIP("127.0.0.1"), Port: 8333, } tests := []struct { in *wire.NetAddress // Value to encode buf []byte // Wire encoding pver uint32 // Protocol version for wire encoding ts bool // Include timestamp flag max int // Max size of fixed buffer to induce errors writeErr error // Expected write error readErr error // Expected read error }{ // Latest protocol version with timestamp and intentional // read/write errors. // Force errors on timestamp. {&baseNetAddr, []byte{}, pver, true, 0, io.ErrShortWrite, io.EOF}, // Force errors on services. {&baseNetAddr, []byte{}, pver, true, 4, io.ErrShortWrite, io.EOF}, // Force errors on ip. {&baseNetAddr, []byte{}, pver, true, 12, io.ErrShortWrite, io.EOF}, // Force errors on port. {&baseNetAddr, []byte{}, pver, true, 28, io.ErrShortWrite, io.EOF}, // Latest protocol version with no timestamp and intentional // read/write errors. // Force errors on services. {&baseNetAddr, []byte{}, pver, false, 0, io.ErrShortWrite, io.EOF}, // Force errors on ip. {&baseNetAddr, []byte{}, pver, false, 8, io.ErrShortWrite, io.EOF}, // Force errors on port. {&baseNetAddr, []byte{}, pver, false, 24, io.ErrShortWrite, io.EOF}, // Protocol version before NetAddressTimeVersion with timestamp // flag set (should not have timestamp due to old protocol // version) and intentional read/write errors. // Force errors on services. {&baseNetAddr, []byte{}, pverNAT, true, 0, io.ErrShortWrite, io.EOF}, // Force errors on ip. {&baseNetAddr, []byte{}, pverNAT, true, 8, io.ErrShortWrite, io.EOF}, // Force errors on port. {&baseNetAddr, []byte{}, pverNAT, true, 24, io.ErrShortWrite, io.EOF}, } t.Logf("Running %d tests", len(tests)) for i, test := range tests { // Encode to wire format. w := newFixedWriter(test.max) err := wire.TstWriteNetAddress(w, test.pver, test.in, test.ts) if err != test.writeErr { t.Errorf("writeNetAddress #%d wrong error got: %v, want: %v", i, err, test.writeErr) continue } // Decode from wire format. var na wire.NetAddress r := newFixedReader(test.max, test.buf) err = wire.TstReadNetAddress(r, test.pver, &na, test.ts) if err != test.readErr { t.Errorf("readNetAddress #%d wrong error got: %v, want: %v", i, err, test.readErr) continue } } }