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	"reflect"
10	"testing"
11	"time"
12
13	"github.com/davecgh/go-spew/spew"
14)
15
16// TestBlockHeader tests the BlockHeader API.
17func TestBlockHeader(t *testing.T) {
18	nonce64, err := RandomUint64()
19	if err != nil {
20		t.Errorf("RandomUint64: Error generating nonce: %v", err)
21	}
22	nonce := uint32(nonce64)
23
24	hash := mainNetGenesisHash
25	merkleHash := mainNetGenesisMerkleRoot
26	bits := uint32(0x1d00ffff)
27	bh := NewBlockHeader(1, &hash, &merkleHash, bits, nonce)
28
29	// Ensure we get the same data back out.
30	if !bh.PrevBlock.IsEqual(&hash) {
31		t.Errorf("NewBlockHeader: wrong prev hash - got %v, want %v",
32			spew.Sprint(bh.PrevBlock), spew.Sprint(hash))
33	}
34	if !bh.MerkleRoot.IsEqual(&merkleHash) {
35		t.Errorf("NewBlockHeader: wrong merkle root - got %v, want %v",
36			spew.Sprint(bh.MerkleRoot), spew.Sprint(merkleHash))
37	}
38	if bh.Bits != bits {
39		t.Errorf("NewBlockHeader: wrong bits - got %v, want %v",
40			bh.Bits, bits)
41	}
42	if bh.Nonce != nonce {
43		t.Errorf("NewBlockHeader: wrong nonce - got %v, want %v",
44			bh.Nonce, nonce)
45	}
46}
47
48// TestBlockHeaderWire tests the BlockHeader wire encode and decode for various
49// protocol versions.
50func TestBlockHeaderWire(t *testing.T) {
51	nonce := uint32(123123) // 0x1e0f3
52	pver := uint32(70001)
53
54	// baseBlockHdr is used in the various tests as a baseline BlockHeader.
55	bits := uint32(0x1d00ffff)
56	baseBlockHdr := &BlockHeader{
57		Version:    1,
58		PrevBlock:  mainNetGenesisHash,
59		MerkleRoot: mainNetGenesisMerkleRoot,
60		Timestamp:  time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
61		Bits:       bits,
62		Nonce:      nonce,
63	}
64
65	// baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr.
66	baseBlockHdrEncoded := []byte{
67		0x01, 0x00, 0x00, 0x00, // Version 1
68		0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
69		0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
70		0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
71		0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
72		0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
73		0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
74		0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
75		0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot
76		0x29, 0xab, 0x5f, 0x49, // Timestamp
77		0xff, 0xff, 0x00, 0x1d, // Bits
78		0xf3, 0xe0, 0x01, 0x00, // Nonce
79	}
80
81	tests := []struct {
82		in   *BlockHeader    // Data to encode
83		out  *BlockHeader    // Expected decoded data
84		buf  []byte          // Wire encoding
85		pver uint32          // Protocol version for wire encoding
86		enc  MessageEncoding // Message encoding variant to use
87	}{
88		// Latest protocol version.
89		{
90			baseBlockHdr,
91			baseBlockHdr,
92			baseBlockHdrEncoded,
93			ProtocolVersion,
94			BaseEncoding,
95		},
96
97		// Protocol version BIP0035Version.
98		{
99			baseBlockHdr,
100			baseBlockHdr,
101			baseBlockHdrEncoded,
102			BIP0035Version,
103			BaseEncoding,
104		},
105
106		// Protocol version BIP0031Version.
107		{
108			baseBlockHdr,
109			baseBlockHdr,
110			baseBlockHdrEncoded,
111			BIP0031Version,
112			BaseEncoding,
113		},
114
115		// Protocol version NetAddressTimeVersion.
116		{
117			baseBlockHdr,
118			baseBlockHdr,
119			baseBlockHdrEncoded,
120			NetAddressTimeVersion,
121			BaseEncoding,
122		},
123
124		// Protocol version MultipleAddressVersion.
125		{
126			baseBlockHdr,
127			baseBlockHdr,
128			baseBlockHdrEncoded,
129			MultipleAddressVersion,
130			BaseEncoding,
131		},
132	}
133
134	t.Logf("Running %d tests", len(tests))
135	for i, test := range tests {
136		// Encode to wire format.
137		var buf bytes.Buffer
138		err := writeBlockHeader(&buf, test.pver, test.in)
139		if err != nil {
140			t.Errorf("writeBlockHeader #%d error %v", i, err)
141			continue
142		}
143		if !bytes.Equal(buf.Bytes(), test.buf) {
144			t.Errorf("writeBlockHeader #%d\n got: %s want: %s", i,
145				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
146			continue
147		}
148
149		buf.Reset()
150		err = test.in.BtcEncode(&buf, pver, 0)
151		if err != nil {
152			t.Errorf("BtcEncode #%d error %v", i, err)
153			continue
154		}
155		if !bytes.Equal(buf.Bytes(), test.buf) {
156			t.Errorf("BtcEncode #%d\n got: %s want: %s", i,
157				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
158			continue
159		}
160
161		// Decode the block header from wire format.
162		var bh BlockHeader
163		rbuf := bytes.NewReader(test.buf)
164		err = readBlockHeader(rbuf, test.pver, &bh)
165		if err != nil {
166			t.Errorf("readBlockHeader #%d error %v", i, err)
167			continue
168		}
169		if !reflect.DeepEqual(&bh, test.out) {
170			t.Errorf("readBlockHeader #%d\n got: %s want: %s", i,
171				spew.Sdump(&bh), spew.Sdump(test.out))
172			continue
173		}
174
175		rbuf = bytes.NewReader(test.buf)
176		err = bh.BtcDecode(rbuf, pver, test.enc)
177		if err != nil {
178			t.Errorf("BtcDecode #%d error %v", i, err)
179			continue
180		}
181		if !reflect.DeepEqual(&bh, test.out) {
182			t.Errorf("BtcDecode #%d\n got: %s want: %s", i,
183				spew.Sdump(&bh), spew.Sdump(test.out))
184			continue
185		}
186	}
187}
188
189// TestBlockHeaderSerialize tests BlockHeader serialize and deserialize.
190func TestBlockHeaderSerialize(t *testing.T) {
191	nonce := uint32(123123) // 0x1e0f3
192
193	// baseBlockHdr is used in the various tests as a baseline BlockHeader.
194	bits := uint32(0x1d00ffff)
195	baseBlockHdr := &BlockHeader{
196		Version:    1,
197		PrevBlock:  mainNetGenesisHash,
198		MerkleRoot: mainNetGenesisMerkleRoot,
199		Timestamp:  time.Unix(0x495fab29, 0), // 2009-01-03 12:15:05 -0600 CST
200		Bits:       bits,
201		Nonce:      nonce,
202	}
203
204	// baseBlockHdrEncoded is the wire encoded bytes of baseBlockHdr.
205	baseBlockHdrEncoded := []byte{
206		0x01, 0x00, 0x00, 0x00, // Version 1
207		0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
208		0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
209		0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
210		0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
211		0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
212		0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
213		0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
214		0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot
215		0x29, 0xab, 0x5f, 0x49, // Timestamp
216		0xff, 0xff, 0x00, 0x1d, // Bits
217		0xf3, 0xe0, 0x01, 0x00, // Nonce
218	}
219
220	tests := []struct {
221		in  *BlockHeader // Data to encode
222		out *BlockHeader // Expected decoded data
223		buf []byte       // Serialized data
224	}{
225		{
226			baseBlockHdr,
227			baseBlockHdr,
228			baseBlockHdrEncoded,
229		},
230	}
231
232	t.Logf("Running %d tests", len(tests))
233	for i, test := range tests {
234		// Serialize the block header.
235		var buf bytes.Buffer
236		err := test.in.Serialize(&buf)
237		if err != nil {
238			t.Errorf("Serialize #%d error %v", i, err)
239			continue
240		}
241		if !bytes.Equal(buf.Bytes(), test.buf) {
242			t.Errorf("Serialize #%d\n got: %s want: %s", i,
243				spew.Sdump(buf.Bytes()), spew.Sdump(test.buf))
244			continue
245		}
246
247		// Deserialize the block header.
248		var bh BlockHeader
249		rbuf := bytes.NewReader(test.buf)
250		err = bh.Deserialize(rbuf)
251		if err != nil {
252			t.Errorf("Deserialize #%d error %v", i, err)
253			continue
254		}
255		if !reflect.DeepEqual(&bh, test.out) {
256			t.Errorf("Deserialize #%d\n got: %s want: %s", i,
257				spew.Sdump(&bh), spew.Sdump(test.out))
258			continue
259		}
260	}
261}
262