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	"reflect"
11	"testing"
12
13	"github.com/davecgh/go-spew/spew"
14)
15
16// TestHeaders tests the MsgHeaders API.
17func TestHeaders(t *testing.T) {
18	pver := uint32(60002)
19
20	// Ensure the command is expected value.
21	wantCmd := "headers"
22	msg := NewMsgHeaders()
23	if cmd := msg.Command(); cmd != wantCmd {
24		t.Errorf("NewMsgHeaders: wrong command - got %v want %v",
25			cmd, wantCmd)
26	}
27
28	// Ensure max payload is expected value for latest protocol version.
29	// Num headers (varInt) + max allowed headers (header length + 1 byte
30	// for the number of transactions which is always 0).
31	wantPayload := uint32(162009)
32	maxPayload := msg.MaxPayloadLength(pver)
33	if maxPayload != wantPayload {
34		t.Errorf("MaxPayloadLength: wrong max payload length for "+
35			"protocol version %d - got %v, want %v", pver,
36			maxPayload, wantPayload)
37	}
38
39	// Ensure headers are added properly.
40	bh := &blockOne.Header
41	msg.AddBlockHeader(bh)
42	if !reflect.DeepEqual(msg.Headers[0], bh) {
43		t.Errorf("AddHeader: wrong header - got %v, want %v",
44			spew.Sdump(msg.Headers),
45			spew.Sdump(bh))
46	}
47
48	// Ensure adding more than the max allowed headers per message returns
49	// error.
50	var err error
51	for i := 0; i < MaxBlockHeadersPerMsg+1; i++ {
52		err = msg.AddBlockHeader(bh)
53	}
54	if reflect.TypeOf(err) != reflect.TypeOf(&MessageError{}) {
55		t.Errorf("AddBlockHeader: expected error on too many headers " +
56			"not received")
57	}
58}
59
60// TestHeadersWire tests the MsgHeaders wire encode and decode for various
61// numbers of headers and protocol versions.
62func TestHeadersWire(t *testing.T) {
63	hash := mainNetGenesisHash
64	merkleHash := blockOne.Header.MerkleRoot
65	bits := uint32(0x1d00ffff)
66	nonce := uint32(0x9962e301)
67	bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce)
68	bh.Version = blockOne.Header.Version
69	bh.Timestamp = blockOne.Header.Timestamp
70
71	// Empty headers message.
72	noHeaders := NewMsgHeaders()
73	noHeadersEncoded := []byte{
74		0x00, // Varint for number of headers
75	}
76
77	// Headers message with one header.
78	oneHeader := NewMsgHeaders()
79	oneHeader.AddBlockHeader(bh)
80	oneHeaderEncoded := []byte{
81		0x01,                   // VarInt for number of headers.
82		0x01, 0x00, 0x00, 0x00, // Version 1
83		0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
84		0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
85		0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
86		0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
87		0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
88		0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
89		0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
90		0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
91		0x61, 0xbc, 0x66, 0x49, // Timestamp
92		0xff, 0xff, 0x00, 0x1d, // Bits
93		0x01, 0xe3, 0x62, 0x99, // Nonce
94		0x00, // TxnCount (0 for headers message)
95	}
96
97	tests := []struct {
98		in   *MsgHeaders     // Message to encode
99		out  *MsgHeaders     // Expected decoded message
100		buf  []byte          // Wire encoding
101		pver uint32          // Protocol version for wire encoding
102		enc  MessageEncoding // Message encoding format
103	}{
104		// Latest protocol version with no headers.
105		{
106			noHeaders,
107			noHeaders,
108			noHeadersEncoded,
109			ProtocolVersion,
110			BaseEncoding,
111		},
112
113		// Latest protocol version with one header.
114		{
115			oneHeader,
116			oneHeader,
117			oneHeaderEncoded,
118			ProtocolVersion,
119			BaseEncoding,
120		},
121
122		// Protocol version BIP0035Version with no headers.
123		{
124			noHeaders,
125			noHeaders,
126			noHeadersEncoded,
127			BIP0035Version,
128			BaseEncoding,
129		},
130
131		// Protocol version BIP0035Version with one header.
132		{
133			oneHeader,
134			oneHeader,
135			oneHeaderEncoded,
136			BIP0035Version,
137			BaseEncoding,
138		},
139
140		// Protocol version BIP0031Version with no headers.
141		{
142			noHeaders,
143			noHeaders,
144			noHeadersEncoded,
145			BIP0031Version,
146			BaseEncoding,
147		},
148
149		// Protocol version BIP0031Version with one header.
150		{
151			oneHeader,
152			oneHeader,
153			oneHeaderEncoded,
154			BIP0031Version,
155			BaseEncoding,
156		},
157		// Protocol version NetAddressTimeVersion with no headers.
158		{
159			noHeaders,
160			noHeaders,
161			noHeadersEncoded,
162			NetAddressTimeVersion,
163			BaseEncoding,
164		},
165
166		// Protocol version NetAddressTimeVersion with one header.
167		{
168			oneHeader,
169			oneHeader,
170			oneHeaderEncoded,
171			NetAddressTimeVersion,
172			BaseEncoding,
173		},
174
175		// Protocol version MultipleAddressVersion with no headers.
176		{
177			noHeaders,
178			noHeaders,
179			noHeadersEncoded,
180			MultipleAddressVersion,
181			BaseEncoding,
182		},
183
184		// Protocol version MultipleAddressVersion with one header.
185		{
186			oneHeader,
187			oneHeader,
188			oneHeaderEncoded,
189			MultipleAddressVersion,
190			BaseEncoding,
191		},
192	}
193
194	t.Logf("Running %d tests", len(tests))
195	for i, test := range tests {
196		// Encode the message to wire format.
197		var buf bytes.Buffer
198		err := test.in.BtcEncode(&buf, test.pver, test.enc)
199		if err != nil {
200			t.Errorf("BtcEncode #%d error %v", i, err)
201			continue
202		}
203		if !bytes.Equal(buf.Bytes(), test.buf) {
204			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
205				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
206			continue
207		}
208
209		// Decode the message from wire format.
210		var msg MsgHeaders
211		rbuf := bytes.NewReader(test.buf)
212		err = msg.BtcDecode(rbuf, test.pver, test.enc)
213		if err != nil {
214			t.Errorf("BtcDecode #%d error %v", i, err)
215			continue
216		}
217		if !reflect.DeepEqual(&msg, test.out) {
218			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
219				spew.Sdump(&msg), spew.Sdump(test.out))
220			continue
221		}
222	}
223}
224
225// TestHeadersWireErrors performs negative tests against wire encode and decode
226// of MsgHeaders to confirm error paths work correctly.
227func TestHeadersWireErrors(t *testing.T) {
228	pver := ProtocolVersion
229	wireErr := &MessageError{}
230
231	hash := mainNetGenesisHash
232	merkleHash := blockOne.Header.MerkleRoot
233	bits := uint32(0x1d00ffff)
234	nonce := uint32(0x9962e301)
235	bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce)
236	bh.Version = blockOne.Header.Version
237	bh.Timestamp = blockOne.Header.Timestamp
238
239	// Headers message with one header.
240	oneHeader := NewMsgHeaders()
241	oneHeader.AddBlockHeader(bh)
242	oneHeaderEncoded := []byte{
243		0x01,                   // VarInt for number of headers.
244		0x01, 0x00, 0x00, 0x00, // Version 1
245		0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
246		0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
247		0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
248		0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
249		0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
250		0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
251		0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
252		0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
253		0x61, 0xbc, 0x66, 0x49, // Timestamp
254		0xff, 0xff, 0x00, 0x1d, // Bits
255		0x01, 0xe3, 0x62, 0x99, // Nonce
256		0x00, // TxnCount (0 for headers message)
257	}
258
259	// Message that forces an error by having more than the max allowed
260	// headers.
261	maxHeaders := NewMsgHeaders()
262	for i := 0; i < MaxBlockHeadersPerMsg; i++ {
263		maxHeaders.AddBlockHeader(bh)
264	}
265	maxHeaders.Headers = append(maxHeaders.Headers, bh)
266	maxHeadersEncoded := []byte{
267		0xfd, 0xd1, 0x07, // Varint for number of addresses (2001)7D1
268	}
269
270	// Intentionally invalid block header that has a transaction count used
271	// to force errors.
272	bhTrans := NewBlockHeader(1, &hash, &merkleHash, bits, nonce)
273	bhTrans.Version = blockOne.Header.Version
274	bhTrans.Timestamp = blockOne.Header.Timestamp
275
276	transHeader := NewMsgHeaders()
277	transHeader.AddBlockHeader(bhTrans)
278	transHeaderEncoded := []byte{
279		0x01,                   // VarInt for number of headers.
280		0x01, 0x00, 0x00, 0x00, // Version 1
281		0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
282		0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
283		0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
284		0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
285		0x98, 0x20, 0x51, 0xfd, 0x1e, 0x4b, 0xa7, 0x44,
286		0xbb, 0xbe, 0x68, 0x0e, 0x1f, 0xee, 0x14, 0x67,
287		0x7b, 0xa1, 0xa3, 0xc3, 0x54, 0x0b, 0xf7, 0xb1,
288		0xcd, 0xb6, 0x06, 0xe8, 0x57, 0x23, 0x3e, 0x0e, // MerkleRoot
289		0x61, 0xbc, 0x66, 0x49, // Timestamp
290		0xff, 0xff, 0x00, 0x1d, // Bits
291		0x01, 0xe3, 0x62, 0x99, // Nonce
292		0x01, // TxnCount (should be 0 for headers message, but 1 to force error)
293	}
294
295	tests := []struct {
296		in       *MsgHeaders     // Value to encode
297		buf      []byte          // Wire encoding
298		pver     uint32          // Protocol version for wire encoding
299		enc      MessageEncoding // Message encoding format
300		max      int             // Max size of fixed buffer to induce errors
301		writeErr error           // Expected write error
302		readErr  error           // Expected read error
303	}{
304		// Latest protocol version with intentional read/write errors.
305		// Force error in header count.
306		{oneHeader, oneHeaderEncoded, pver, BaseEncoding, 0, io.ErrShortWrite, io.EOF},
307		// Force error in block header.
308		{oneHeader, oneHeaderEncoded, pver, BaseEncoding, 5, io.ErrShortWrite, io.EOF},
309		// Force error with greater than max headers.
310		{maxHeaders, maxHeadersEncoded, pver, BaseEncoding, 3, wireErr, wireErr},
311		// Force error with number of transactions.
312		{transHeader, transHeaderEncoded, pver, BaseEncoding, 81, io.ErrShortWrite, io.EOF},
313		// Force error with included transactions.
314		{transHeader, transHeaderEncoded, pver, BaseEncoding, len(transHeaderEncoded), nil, wireErr},
315	}
316
317	t.Logf("Running %d tests", len(tests))
318	for i, test := range tests {
319		// Encode to wire format.
320		w := newFixedWriter(test.max)
321		err := test.in.BtcEncode(w, test.pver, test.enc)
322		if reflect.TypeOf(err) != reflect.TypeOf(test.writeErr) {
323			t.Errorf("BtcEncode #%d wrong error got: %v, want: %v",
324				i, err, test.writeErr)
325			continue
326		}
327
328		// For errors which are not of type MessageError, check them for
329		// equality.
330		if _, ok := err.(*MessageError); !ok {
331			if err != test.writeErr {
332				t.Errorf("BtcEncode #%d wrong error got: %v, "+
333					"want: %v", i, err, test.writeErr)
334				continue
335			}
336		}
337
338		// Decode from wire format.
339		var msg MsgHeaders
340		r := newFixedReader(test.max, test.buf)
341		err = msg.BtcDecode(r, test.pver, test.enc)
342		if reflect.TypeOf(err) != reflect.TypeOf(test.readErr) {
343			t.Errorf("BtcDecode #%d wrong error got: %v, want: %v",
344				i, err, test.readErr)
345			continue
346		}
347
348		// For errors which are not of type MessageError, check them for
349		// equality.
350		if _, ok := err.(*MessageError); !ok {
351			if err != test.readErr {
352				t.Errorf("BtcDecode #%d wrong error got: %v, "+
353					"want: %v", i, err, test.readErr)
354				continue
355			}
356		}
357
358	}
359}
360