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
5package wire
6
7import (
8	"bytes"
9	"io"
10	"net"
11	"reflect"
12	"strings"
13	"testing"
14	"time"
15
16	"github.com/davecgh/go-spew/spew"
17)
18
19// TestVersion tests the MsgVersion API.
20func TestVersion(t *testing.T) {
21	pver := ProtocolVersion
22
23	// Create version message data.
24	lastBlock := int32(234234)
25	tcpAddrMe := &net.TCPAddr{IP: net.ParseIP("127.0.0.1"), Port: 8333}
26	me := NewNetAddress(tcpAddrMe, SFNodeNetwork)
27	tcpAddrYou := &net.TCPAddr{IP: net.ParseIP("192.168.0.1"), Port: 8333}
28	you := NewNetAddress(tcpAddrYou, SFNodeNetwork)
29	nonce, err := RandomUint64()
30	if err != nil {
31		t.Errorf("RandomUint64: error generating nonce: %v", err)
32	}
33
34	// Ensure we get the correct data back out.
35	msg := NewMsgVersion(me, you, nonce, lastBlock)
36	if msg.ProtocolVersion != int32(pver) {
37		t.Errorf("NewMsgVersion: wrong protocol version - got %v, want %v",
38			msg.ProtocolVersion, pver)
39	}
40	if !reflect.DeepEqual(&msg.AddrMe, me) {
41		t.Errorf("NewMsgVersion: wrong me address - got %v, want %v",
42			spew.Sdump(&msg.AddrMe), spew.Sdump(me))
43	}
44	if !reflect.DeepEqual(&msg.AddrYou, you) {
45		t.Errorf("NewMsgVersion: wrong you address - got %v, want %v",
46			spew.Sdump(&msg.AddrYou), spew.Sdump(you))
47	}
48	if msg.Nonce != nonce {
49		t.Errorf("NewMsgVersion: wrong nonce - got %v, want %v",
50			msg.Nonce, nonce)
51	}
52	if msg.UserAgent != DefaultUserAgent {
53		t.Errorf("NewMsgVersion: wrong user agent - got %v, want %v",
54			msg.UserAgent, DefaultUserAgent)
55	}
56	if msg.LastBlock != lastBlock {
57		t.Errorf("NewMsgVersion: wrong last block - got %v, want %v",
58			msg.LastBlock, lastBlock)
59	}
60	if msg.DisableRelayTx {
61		t.Errorf("NewMsgVersion: disable relay tx is not false by "+
62			"default - got %v, want %v", msg.DisableRelayTx, false)
63	}
64
65	msg.AddUserAgent("myclient", "1.2.3", "optional", "comments")
66	customUserAgent := DefaultUserAgent + "myclient:1.2.3(optional; comments)/"
67	if msg.UserAgent != customUserAgent {
68		t.Errorf("AddUserAgent: wrong user agent - got %s, want %s",
69			msg.UserAgent, customUserAgent)
70	}
71
72	msg.AddUserAgent("mygui", "3.4.5")
73	customUserAgent += "mygui:3.4.5/"
74	if msg.UserAgent != customUserAgent {
75		t.Errorf("AddUserAgent: wrong user agent - got %s, want %s",
76			msg.UserAgent, customUserAgent)
77	}
78
79	// accounting for ":", "/"
80	err = msg.AddUserAgent(strings.Repeat("t",
81		MaxUserAgentLen-len(customUserAgent)-2+1), "")
82	if _, ok := err.(*MessageError); !ok {
83		t.Errorf("AddUserAgent: expected error not received "+
84			"- got %v, want %T", err, MessageError{})
85
86	}
87
88	// Version message should not have any services set by default.
89	if msg.Services != 0 {
90		t.Errorf("NewMsgVersion: wrong default services - got %v, want %v",
91			msg.Services, 0)
92
93	}
94	if msg.HasService(SFNodeNetwork) {
95		t.Errorf("HasService: SFNodeNetwork service is set")
96	}
97
98	// Ensure the command is expected value.
99	wantCmd := "version"
100	if cmd := msg.Command(); cmd != wantCmd {
101		t.Errorf("NewMsgVersion: wrong command - got %v want %v",
102			cmd, wantCmd)
103	}
104
105	// Ensure max payload is expected value.
106	// Protocol version 4 bytes + services 8 bytes + timestamp 8 bytes +
107	// remote and local net addresses + nonce 8 bytes + length of user agent
108	// (varInt) + max allowed user agent length + last block 4 bytes +
109	// relay transactions flag 1 byte.
110	wantPayload := uint32(358)
111	maxPayload := msg.MaxPayloadLength(pver)
112	if maxPayload != wantPayload {
113		t.Errorf("MaxPayloadLength: wrong max payload length for "+
114			"protocol version %d - got %v, want %v", pver,
115			maxPayload, wantPayload)
116	}
117
118	// Ensure adding the full service node flag works.
119	msg.AddService(SFNodeNetwork)
120	if msg.Services != SFNodeNetwork {
121		t.Errorf("AddService: wrong services - got %v, want %v",
122			msg.Services, SFNodeNetwork)
123	}
124	if !msg.HasService(SFNodeNetwork) {
125		t.Errorf("HasService: SFNodeNetwork service not set")
126	}
127}
128
129// TestVersionWire tests the MsgVersion wire encode and decode for various
130// protocol versions.
131func TestVersionWire(t *testing.T) {
132	// verRelayTxFalse and verRelayTxFalseEncoded is a version message as of
133	// BIP0037Version with the transaction relay disabled.
134	baseVersionBIP0037Copy := *baseVersionBIP0037
135	verRelayTxFalse := &baseVersionBIP0037Copy
136	verRelayTxFalse.DisableRelayTx = true
137	verRelayTxFalseEncoded := make([]byte, len(baseVersionBIP0037Encoded))
138	copy(verRelayTxFalseEncoded, baseVersionBIP0037Encoded)
139	verRelayTxFalseEncoded[len(verRelayTxFalseEncoded)-1] = 0
140
141	tests := []struct {
142		in   *MsgVersion     // Message to encode
143		out  *MsgVersion     // Expected decoded message
144		buf  []byte          // Wire encoding
145		pver uint32          // Protocol version for wire encoding
146		enc  MessageEncoding // Message encoding format
147	}{
148		// Latest protocol version.
149		{
150			baseVersionBIP0037,
151			baseVersionBIP0037,
152			baseVersionBIP0037Encoded,
153			ProtocolVersion,
154			BaseEncoding,
155		},
156
157		// Protocol version BIP0037Version with relay transactions field
158		// true.
159		{
160			baseVersionBIP0037,
161			baseVersionBIP0037,
162			baseVersionBIP0037Encoded,
163			BIP0037Version,
164			BaseEncoding,
165		},
166
167		// Protocol version BIP0037Version with relay transactions field
168		// false.
169		{
170			verRelayTxFalse,
171			verRelayTxFalse,
172			verRelayTxFalseEncoded,
173			BIP0037Version,
174			BaseEncoding,
175		},
176
177		// Protocol version BIP0035Version.
178		{
179			baseVersion,
180			baseVersion,
181			baseVersionEncoded,
182			BIP0035Version,
183			BaseEncoding,
184		},
185
186		// Protocol version BIP0031Version.
187		{
188			baseVersion,
189			baseVersion,
190			baseVersionEncoded,
191			BIP0031Version,
192			BaseEncoding,
193		},
194
195		// Protocol version NetAddressTimeVersion.
196		{
197			baseVersion,
198			baseVersion,
199			baseVersionEncoded,
200			NetAddressTimeVersion,
201			BaseEncoding,
202		},
203
204		// Protocol version MultipleAddressVersion.
205		{
206			baseVersion,
207			baseVersion,
208			baseVersionEncoded,
209			MultipleAddressVersion,
210			BaseEncoding,
211		},
212	}
213
214	t.Logf("Running %d tests", len(tests))
215	for i, test := range tests {
216		// Encode the message to wire format.
217		var buf bytes.Buffer
218		err := test.in.BtcEncode(&buf, test.pver, test.enc)
219		if err != nil {
220			t.Errorf("BtcEncode #%d error %v", i, err)
221			continue
222		}
223		if !bytes.Equal(buf.Bytes(), test.buf) {
224			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
225				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
226			continue
227		}
228
229		// Decode the message from wire format.
230		var msg MsgVersion
231		rbuf := bytes.NewBuffer(test.buf)
232		err = msg.BtcDecode(rbuf, test.pver, test.enc)
233		if err != nil {
234			t.Errorf("BtcDecode #%d error %v", i, err)
235			continue
236		}
237		if !reflect.DeepEqual(&msg, test.out) {
238			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
239				spew.Sdump(msg), spew.Sdump(test.out))
240			continue
241		}
242	}
243}
244
245// TestVersionWireErrors performs negative tests against wire encode and
246// decode of MsgGetHeaders to confirm error paths work correctly.
247func TestVersionWireErrors(t *testing.T) {
248	// Use protocol version 60002 specifically here instead of the latest
249	// because the test data is using bytes encoded with that protocol
250	// version.
251	pver := uint32(60002)
252	enc := BaseEncoding
253	wireErr := &MessageError{}
254
255	// Ensure calling MsgVersion.BtcDecode with a non *bytes.Buffer returns
256	// error.
257	fr := newFixedReader(0, []byte{})
258	if err := baseVersion.BtcDecode(fr, pver, enc); err == nil {
259		t.Errorf("Did not received error when calling " +
260			"MsgVersion.BtcDecode with non *bytes.Buffer")
261	}
262
263	// Copy the base version and change the user agent to exceed max limits.
264	bvc := *baseVersion
265	exceedUAVer := &bvc
266	newUA := "/" + strings.Repeat("t", MaxUserAgentLen-8+1) + ":0.0.1/"
267	exceedUAVer.UserAgent = newUA
268
269	// Encode the new UA length as a varint.
270	var newUAVarIntBuf bytes.Buffer
271	err := WriteVarInt(&newUAVarIntBuf, pver, uint64(len(newUA)))
272	if err != nil {
273		t.Errorf("WriteVarInt: error %v", err)
274	}
275
276	// Make a new buffer big enough to hold the base version plus the new
277	// bytes for the bigger varint to hold the new size of the user agent
278	// and the new user agent string.  Then stich it all together.
279	newLen := len(baseVersionEncoded) - len(baseVersion.UserAgent)
280	newLen = newLen + len(newUAVarIntBuf.Bytes()) - 1 + len(newUA)
281	exceedUAVerEncoded := make([]byte, newLen)
282	copy(exceedUAVerEncoded, baseVersionEncoded[0:80])
283	copy(exceedUAVerEncoded[80:], newUAVarIntBuf.Bytes())
284	copy(exceedUAVerEncoded[83:], []byte(newUA))
285	copy(exceedUAVerEncoded[83+len(newUA):], baseVersionEncoded[97:100])
286
287	tests := []struct {
288		in       *MsgVersion     // Value to encode
289		buf      []byte          // Wire encoding
290		pver     uint32          // Protocol version for wire encoding
291		enc      MessageEncoding // Message encoding format
292		max      int             // Max size of fixed buffer to induce errors
293		writeErr error           // Expected write error
294		readErr  error           // Expected read error
295	}{
296		// Force error in protocol version.
297		{baseVersion, baseVersionEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
298		// Force error in services.
299		{baseVersion, baseVersionEncoded, pver, BaseEncoding, 4, io.ErrShortWrite, io.EOF},
300		// Force error in timestamp.
301		{baseVersion, baseVersionEncoded, pver, BaseEncoding, 12, io.ErrShortWrite, io.EOF},
302		// Force error in remote address.
303		{baseVersion, baseVersionEncoded, pver, BaseEncoding, 20, io.ErrShortWrite, io.EOF},
304		// Force error in local address.
305		{baseVersion, baseVersionEncoded, pver, BaseEncoding, 47, io.ErrShortWrite, io.ErrUnexpectedEOF},
306		// Force error in nonce.
307		{baseVersion, baseVersionEncoded, pver, BaseEncoding, 73, io.ErrShortWrite, io.ErrUnexpectedEOF},
308		// Force error in user agent length.
309		{baseVersion, baseVersionEncoded, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF},
310		// Force error in user agent.
311		{baseVersion, baseVersionEncoded, pver, BaseEncoding, 82, io.ErrShortWrite, io.ErrUnexpectedEOF},
312		// Force error in last block.
313		{baseVersion, baseVersionEncoded, pver, BaseEncoding, 98, io.ErrShortWrite, io.ErrUnexpectedEOF},
314		// Force error in relay tx - no read error should happen since
315		// it's optional.
316		{
317			baseVersionBIP0037, baseVersionBIP0037Encoded,
318			BIP0037Version, BaseEncoding, 101, io.ErrShortWrite, nil,
319		},
320		// Force error due to user agent too big
321		{exceedUAVer, exceedUAVerEncoded, pver, BaseEncoding, newLen, wireErr, wireErr},
322	}
323
324	t.Logf("Running %d tests", len(tests))
325	for i, test := range tests {
326		// Encode to wire format.
327		w := newFixedWriter(test.max)
328		err := test.in.BtcEncode(w, test.pver, test.enc)
329		if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
330			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
331				i, err, test.writeErr)
332			continue
333		}
334
335		// For errors which are not of type MessageError, check them for
336		// equality.
337		if _, ok := err.(*MessageError); !ok {
338			if err != test.writeErr {
339				t.Errorf("BtcEncode #%d wrong error got: %v, "+
340					"want: %v", i, err, test.writeErr)
341				continue
342			}
343		}
344
345		// Decode from wire format.
346		var msg MsgVersion
347		buf := bytes.NewBuffer(test.buf[0:test.max])
348		err = msg.BtcDecode(buf, test.pver, test.enc)
349		if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
350			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
351				i, err, test.readErr)
352			continue
353		}
354
355		// For errors which are not of type MessageError, check them for
356		// equality.
357		if _, ok := err.(*MessageError); !ok {
358			if err != test.readErr {
359				t.Errorf("BtcDecode #%d wrong error got: %v, "+
360					"want: %v", i, err, test.readErr)
361				continue
362			}
363		}
364	}
365}
366
367// TestVersionOptionalFields performs tests to ensure that an encoded version
368// messages that omit optional fields are handled correctly.
369func TestVersionOptionalFields(t *testing.T) {
370	// onlyRequiredVersion is a version message that only contains the
371	// required versions and all other values set to their default values.
372	onlyRequiredVersion := MsgVersion{
373		ProtocolVersion: 60002,
374		Services:        SFNodeNetwork,
375		Timestamp:       time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST)
376		AddrYou: NetAddress{
377			Timestamp: time.Time{}, // Zero value -- no timestamp in version
378			Services:  SFNodeNetwork,
379			IP:        net.ParseIP("192.168.0.1"),
380			Port:      8333,
381		},
382	}
383	onlyRequiredVersionEncoded := make([]byte, len(baseVersionEncoded)-55)
384	copy(onlyRequiredVersionEncoded, baseVersionEncoded)
385
386	// addrMeVersion is a version message that contains all fields through
387	// the AddrMe field.
388	addrMeVersion := onlyRequiredVersion
389	addrMeVersion.AddrMe = NetAddress{
390		Timestamp: time.Time{}, // Zero value -- no timestamp in version
391		Services:  SFNodeNetwork,
392		IP:        net.ParseIP("127.0.0.1"),
393		Port:      8333,
394	}
395	addrMeVersionEncoded := make([]byte, len(baseVersionEncoded)-29)
396	copy(addrMeVersionEncoded, baseVersionEncoded)
397
398	// nonceVersion is a version message that contains all fields through
399	// the Nonce field.
400	nonceVersion := addrMeVersion
401	nonceVersion.Nonce = 123123 // 0x1e0f3
402	nonceVersionEncoded := make([]byte, len(baseVersionEncoded)-21)
403	copy(nonceVersionEncoded, baseVersionEncoded)
404
405	// uaVersion is a version message that contains all fields through
406	// the UserAgent field.
407	uaVersion := nonceVersion
408	uaVersion.UserAgent = "/btcdtest:0.0.1/"
409	uaVersionEncoded := make([]byte, len(baseVersionEncoded)-4)
410	copy(uaVersionEncoded, baseVersionEncoded)
411
412	// lastBlockVersion is a version message that contains all fields
413	// through the LastBlock field.
414	lastBlockVersion := uaVersion
415	lastBlockVersion.LastBlock = 234234 // 0x392fa
416	lastBlockVersionEncoded := make([]byte, len(baseVersionEncoded))
417	copy(lastBlockVersionEncoded, baseVersionEncoded)
418
419	tests := []struct {
420		msg  *MsgVersion     // Expected message
421		buf  []byte          // Wire encoding
422		pver uint32          // Protocol version for wire encoding
423		enc  MessageEncoding // Message encoding format
424	}{
425		{
426			&onlyRequiredVersion,
427			onlyRequiredVersionEncoded,
428			ProtocolVersion,
429			BaseEncoding,
430		},
431		{
432			&addrMeVersion,
433			addrMeVersionEncoded,
434			ProtocolVersion,
435			BaseEncoding,
436		},
437		{
438			&nonceVersion,
439			nonceVersionEncoded,
440			ProtocolVersion,
441			BaseEncoding,
442		},
443		{
444			&uaVersion,
445			uaVersionEncoded,
446			ProtocolVersion,
447			BaseEncoding,
448		},
449		{
450			&lastBlockVersion,
451			lastBlockVersionEncoded,
452			ProtocolVersion,
453			BaseEncoding,
454		},
455	}
456
457	for i, test := range tests {
458		// Decode the message from wire format.
459		var msg MsgVersion
460		rbuf := bytes.NewBuffer(test.buf)
461		err := msg.BtcDecode(rbuf, test.pver, test.enc)
462		if err != nil {
463			t.Errorf("BtcDecode #%d error %v", i, err)
464			continue
465		}
466		if !reflect.DeepEqual(&msg, test.msg) {
467			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
468				spew.Sdump(msg), spew.Sdump(test.msg))
469			continue
470		}
471	}
472}
473
474// baseVersion is used in the various tests as a baseline MsgVersion.
475var baseVersion = &MsgVersion{
476	ProtocolVersion: 60002,
477	Services:        SFNodeNetwork,
478	Timestamp:       time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST)
479	AddrYou: NetAddress{
480		Timestamp: time.Time{}, // Zero value -- no timestamp in version
481		Services:  SFNodeNetwork,
482		IP:        net.ParseIP("192.168.0.1"),
483		Port:      8333,
484	},
485	AddrMe: NetAddress{
486		Timestamp: time.Time{}, // Zero value -- no timestamp in version
487		Services:  SFNodeNetwork,
488		IP:        net.ParseIP("127.0.0.1"),
489		Port:      8333,
490	},
491	Nonce:     123123, // 0x1e0f3
492	UserAgent: "/btcdtest:0.0.1/",
493	LastBlock: 234234, // 0x392fa
494}
495
496// baseVersionEncoded is the wire encoded bytes for baseVersion using protocol
497// version 60002 and is used in the various tests.
498var baseVersionEncoded = []byte{
499	0x62, 0xea, 0x00, 0x00, // Protocol version 60002
500	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
501	0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp
502	// AddrYou -- No timestamp for NetAddress in version message
503	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
504	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
505	0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
506	0x20, 0x8d, // Port 8333 in big-endian
507	// AddrMe -- No timestamp for NetAddress in version message
508	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
509	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
510	0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
511	0x20, 0x8d, // Port 8333 in big-endian
512	0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce
513	0x10, // Varint for user agent length
514	0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73,
515	0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent
516	0xfa, 0x92, 0x03, 0x00, // Last block
517}
518
519// baseVersionBIP0037 is used in the various tests as a baseline MsgVersion for
520// BIP0037.
521var baseVersionBIP0037 = &MsgVersion{
522	ProtocolVersion: 70001,
523	Services:        SFNodeNetwork,
524	Timestamp:       time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST)
525	AddrYou: NetAddress{
526		Timestamp: time.Time{}, // Zero value -- no timestamp in version
527		Services:  SFNodeNetwork,
528		IP:        net.ParseIP("192.168.0.1"),
529		Port:      8333,
530	},
531	AddrMe: NetAddress{
532		Timestamp: time.Time{}, // Zero value -- no timestamp in version
533		Services:  SFNodeNetwork,
534		IP:        net.ParseIP("127.0.0.1"),
535		Port:      8333,
536	},
537	Nonce:     123123, // 0x1e0f3
538	UserAgent: "/btcdtest:0.0.1/",
539	LastBlock: 234234, // 0x392fa
540}
541
542// baseVersionBIP0037Encoded is the wire encoded bytes for baseVersionBIP0037
543// using protocol version BIP0037Version and is used in the various tests.
544var baseVersionBIP0037Encoded = []byte{
545	0x71, 0x11, 0x01, 0x00, // Protocol version 70001
546	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
547	0x29, 0xab, 0x5f, 0x49, 0x00, 0x00, 0x00, 0x00, // 64-bit Timestamp
548	// AddrYou -- No timestamp for NetAddress in version message
549	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
550	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
551	0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x00, 0x01, // IP 192.168.0.1
552	0x20, 0x8d, // Port 8333 in big-endian
553	// AddrMe -- No timestamp for NetAddress in version message
554	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // SFNodeNetwork
555	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
556	0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x01, // IP 127.0.0.1
557	0x20, 0x8d, // Port 8333 in big-endian
558	0xf3, 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // Nonce
559	0x10, // Varint for user agent length
560	0x2f, 0x62, 0x74, 0x63, 0x64, 0x74, 0x65, 0x73,
561	0x74, 0x3a, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2f, // User agent
562	0xfa, 0x92, 0x03, 0x00, // Last block
563	0x01, // Relay tx
564}
565