msgaddr_test.go raw

   1  package wire
   2  
   3  import (
   4  	"bytes"
   5  	"io"
   6  	"net"
   7  	"reflect"
   8  	"testing"
   9  	"time"
  10  	
  11  	"github.com/davecgh/go-spew/spew"
  12  )
  13  
  14  // TestAddr tests the MsgAddr API.
  15  func TestAddr(t *testing.T) {
  16  	pver := ProtocolVersion
  17  	// Ensure the command is expected value.
  18  	wantCmd := "addr"
  19  	msg := NewMsgAddr()
  20  	if cmd := msg.Command(); cmd != wantCmd {
  21  		t.Errorf("NewMsgAddr: wrong command - got %v want %v",
  22  			cmd, wantCmd,
  23  		)
  24  	}
  25  	// Ensure max payload is expected value for latest protocol version. Num addresses (varInt) + max allowed addresses.
  26  	wantPayload := uint32(30009)
  27  	maxPayload := msg.MaxPayloadLength(pver)
  28  	if maxPayload != wantPayload {
  29  		t.Errorf("MaxPayloadLength: wrong max payload length for "+
  30  			"protocol version %d - got %v, want %v", pver,
  31  			maxPayload, wantPayload,
  32  		)
  33  	}
  34  	// Ensure NetAddresses are added properly.
  35  	tcpAddr := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 11047}
  36  	na := NewNetAddress(tcpAddr, SFNodeNetwork)
  37  	e := msg.AddAddress(na)
  38  	if e != nil {
  39  		t.Errorf("AddAddress: %v", e)
  40  	}
  41  	if msg.AddrList[0] != na {
  42  		t.Errorf("AddAddress: wrong address added - got %v, want %v",
  43  			spew.Sprint(msg.AddrList[0]), spew.Sprint(na),
  44  		)
  45  	}
  46  	// Ensure the address list is cleared properly.
  47  	msg.ClearAddresses()
  48  	if len(msg.AddrList) != 0 {
  49  		t.Errorf("ClearAddresses: address list is not empty - "+
  50  			"got %v [%v], want %v", len(msg.AddrList),
  51  			spew.Sprint(msg.AddrList[0]), 0,
  52  		)
  53  	}
  54  	// Ensure adding more than the max allowed addresses per message returns error.
  55  	for i := 0; i < MaxAddrPerMsg+1; i++ {
  56  		e = msg.AddAddress(na)
  57  	}
  58  	if e == nil {
  59  		t.Errorf("AddAddress: expected error on too many addresses " +
  60  			"not received",
  61  		)
  62  	}
  63  	e = msg.AddAddresses(na)
  64  	if e == nil {
  65  		t.Errorf("AddAddresses: expected error on too many addresses " +
  66  			"not received",
  67  		)
  68  	}
  69  	// Ensure max payload is expected value for protocol versions before timestamp was added to NetAddress. Num
  70  	// addresses (varInt) + max allowed addresses.
  71  	pver = NetAddressTimeVersion - 1
  72  	wantPayload = uint32(26009)
  73  	maxPayload = msg.MaxPayloadLength(pver)
  74  	if maxPayload != wantPayload {
  75  		t.Errorf("MaxPayloadLength: wrong max payload length for "+
  76  			"protocol version %d - got %v, want %v", pver,
  77  			maxPayload, wantPayload,
  78  		)
  79  	}
  80  	// Ensure max payload is expected value for protocol versions before multiple addresses were allowed. Num addresses
  81  	// (varInt) + a single net addresses.
  82  	pver = MultipleAddressVersion - 1
  83  	wantPayload = uint32(35)
  84  	maxPayload = msg.MaxPayloadLength(pver)
  85  	if maxPayload != wantPayload {
  86  		t.Errorf("MaxPayloadLength: wrong max payload length for "+
  87  			"protocol version %d - got %v, want %v", pver,
  88  			maxPayload, wantPayload,
  89  		)
  90  	}
  91  }
  92  
  93  // TestAddrWire tests the MsgAddr wire encode and decode for various numbers of addresses and protocol versions.
  94  func TestAddrWire(t *testing.T) {
  95  	// A couple of NetAddresses to use for testing.
  96  	na := &NetAddress{
  97  		Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
  98  		Services:  SFNodeNetwork,
  99  		IP:        net.ParseIP("127.0.0.1"),
 100  		Port:      11047,
 101  	}
 102  	na2 := &NetAddress{
 103  		Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
 104  		Services:  SFNodeNetwork,
 105  		IP:        net.ParseIP("192.168.0.1"),
 106  		Port:      11048,
 107  	}
 108  	// Empty address message.
 109  	noAddr := NewMsgAddr()
 110  	noAddrEncoded := []byte{
 111  		0x00, // Varint for number of addresses
 112  	}
 113  	// Address message with multiple addresses.
 114  	multiAddr := NewMsgAddr()
 115  	_ = multiAddr.AddAddresses(na, na2)
 116  	multiAddrEncoded := []byte{
 117  		0x02,                   // Varint for number of addresses
 118  		0x29, 0xab, 0x5f, 0x49, // Timestamp
 119  		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
 120  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 121  		0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
 122  		0x2b, 0x27, // Port 11047 in big-endian
 123  		0x29, 0xab, 0x5f, 0x49, // Timestamp
 124  		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
 125  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 126  		0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
 127  		0x2b, 0x28, // Port 11048 in big-endian
 128  	}
 129  	tests := []struct {
 130  		in   *MsgAddr        // Message to encode
 131  		out  *MsgAddr        // Expected decoded message
 132  		buf  []byte          // Wire encoding
 133  		pver uint32          // Protocol version for wire encoding
 134  		enc  MessageEncoding // Message encoding format
 135  	}{
 136  		// Latest protocol version with no addresses.
 137  		{
 138  			noAddr,
 139  			noAddr,
 140  			noAddrEncoded,
 141  			ProtocolVersion,
 142  			BaseEncoding,
 143  		},
 144  		// Latest protocol version with multiple addresses.
 145  		{
 146  			multiAddr,
 147  			multiAddr,
 148  			multiAddrEncoded,
 149  			ProtocolVersion,
 150  			BaseEncoding,
 151  		},
 152  		// Protocol version MultipleAddressVersion-1 with no addresses.
 153  		{
 154  			noAddr,
 155  			noAddr,
 156  			noAddrEncoded,
 157  			MultipleAddressVersion - 1,
 158  			BaseEncoding,
 159  		},
 160  	}
 161  	t.Logf("Running %d tests", len(tests))
 162  	for i, test := range tests {
 163  		// Encode the message to wire format.
 164  		var buf bytes.Buffer
 165  		e := test.in.BtcEncode(&buf, test.pver, test.enc)
 166  		if e != nil {
 167  			t.Errorf("BtcEncode #%d error %v", i, e)
 168  			continue
 169  		}
 170  		if !bytes.Equal(buf.Bytes(), test.buf) {
 171  			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
 172  				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf),
 173  			)
 174  			continue
 175  		}
 176  		// Decode the message from wire format.
 177  		var msg MsgAddr
 178  		rbuf := bytes.NewReader(test.buf)
 179  		e = msg.BtcDecode(rbuf, test.pver, test.enc)
 180  		if e != nil {
 181  			t.Errorf("BtcDecode #%d error %v", i, e)
 182  			continue
 183  		}
 184  		if !reflect.DeepEqual(&msg, test.out) {
 185  			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
 186  				spew.Sdump(msg), spew.Sdump(test.out),
 187  			)
 188  			continue
 189  		}
 190  	}
 191  }
 192  
 193  // TestAddrWireErrors performs negative tests against wire encode and decode of MsgAddr to confirm error paths work correctly.
 194  func TestAddrWireErrors(t *testing.T) {
 195  	pver := ProtocolVersion
 196  	pverMA := MultipleAddressVersion
 197  	wireErr := &MessageError{}
 198  	// A couple of NetAddresses to use for testing.
 199  	na := &NetAddress{
 200  		Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
 201  		Services:  SFNodeNetwork,
 202  		IP:        net.ParseIP("127.0.0.1"),
 203  		Port:      11047,
 204  	}
 205  	na2 := &NetAddress{
 206  		Timestamp: time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
 207  		Services:  SFNodeNetwork,
 208  		IP:        net.ParseIP("192.168.0.1"),
 209  		Port:      11048,
 210  	}
 211  	// Address message with multiple addresses.
 212  	baseAddr := NewMsgAddr()
 213  	e := baseAddr.AddAddresses(na, na2)
 214  	if e != nil {
 215  		t.Log(e)
 216  	}
 217  	baseAddrEncoded := []byte{
 218  		0x02,                   // Varint for number of addresses
 219  		0x29, 0xab, 0x5f, 0x49, // Timestamp
 220  		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
 221  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 222  		0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
 223  		0x2b, 0x27, // Port 11047 in big-endian
 224  		0x29, 0xab, 0x5f, 0x49, // Timestamp
 225  		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
 226  		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 227  		0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
 228  		0x2b, 0x28, // Port 11048 in big-endian
 229  	}
 230  	// Message that forces an error by having more than the max allowed addresses.
 231  	maxAddr := NewMsgAddr()
 232  	for i := 0; i < MaxAddrPerMsg; i++ {
 233  		e := maxAddr.AddAddress(na)
 234  		if e != nil {
 235  			t.Log(e)
 236  		}
 237  	}
 238  	maxAddr.AddrList = append(maxAddr.AddrList, na)
 239  	maxAddrEncoded := []byte{
 240  		0xfd, 0x03, 0xe9, // Varint for number of addresses (1001)
 241  	}
 242  	tests := []struct {
 243  		in       *MsgAddr        // value to encode
 244  		buf      []byte          // Wire encoding
 245  		pver     uint32          // Protocol version for wire encoding
 246  		enc      MessageEncoding // Message encoding format
 247  		max      int             // Max size of fixed buffer to induce errors
 248  		writeErr error           // Expected write error
 249  		readErr  error           // Expected read error
 250  	}{
 251  		// Latest protocol version with intentional read/write errors.
 252  		// Force error in addresses count
 253  		{baseAddr, baseAddrEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
 254  		// Force error in address list.
 255  		{baseAddr, baseAddrEncoded, pver, BaseEncoding, 1, io.ErrShortWrite, io.EOF},
 256  		// Force error with greater than max inventory vectors.
 257  		{maxAddr, maxAddrEncoded, pver, BaseEncoding, 3, wireErr, wireErr},
 258  		// Force error with greater than max inventory vectors for protocol versions before multiple addresses were
 259  		// allowed.
 260  		{maxAddr, maxAddrEncoded, pverMA - 1, BaseEncoding, 3, wireErr, wireErr},
 261  	}
 262  	t.Logf("Running %d tests", len(tests))
 263  	for i, test := range tests {
 264  		// Encode to wire format.
 265  		w := newFixedWriter(test.max)
 266  		e := test.in.BtcEncode(w, test.pver, test.enc)
 267  		if reflect.TypeOf(e) != reflect.TypeOf(test.writeErr) {
 268  			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
 269  				i, e, test.writeErr,
 270  			)
 271  			continue
 272  		}
 273  		// For errors which are not of type MessageError, check them for equality.
 274  		if _, ok := e.(*MessageError); !ok {
 275  			if e != test.writeErr {
 276  				t.Errorf("BtcEncode #%d wrong error got: %v, "+
 277  					"want: %v", i, e, test.writeErr,
 278  				)
 279  				continue
 280  			}
 281  		}
 282  		// Decode from wire format.
 283  		var msg MsgAddr
 284  		r := newFixedReader(test.max, test.buf)
 285  		e = msg.BtcDecode(r, test.pver, test.enc)
 286  		if reflect.TypeOf(e) != reflect.TypeOf(test.readErr) {
 287  			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
 288  				i, e, test.readErr,
 289  			)
 290  			continue
 291  		}
 292  		// For errors which are not of type MessageError, check them for equality.
 293  		if _, ok := e.(*MessageError); !ok {
 294  			if e != test.readErr {
 295  				t.Errorf("BtcDecode #%d wrong error got: %v, "+
 296  					"want: %v", i, e, test.readErr,
 297  				)
 298  				continue
 299  			}
 300  		}
 301  	}
 302  }
 303