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	"compress/bzip2"
10	"fmt"
11	"io/ioutil"
12	"net"
13	"os"
14	"testing"
15
16	"github.com/btcsuite/btcd/chaincfg/chainhash"
17)
18
19// genesisCoinbaseTx is the coinbase transaction for the genesis blocks for
20// the main network, regression test network, and test network (version 3).
21var genesisCoinbaseTx = MsgTx{
22	Version: 1,
23	TxIn: []*TxIn{
24		{
25			PreviousOutPoint: OutPoint{
26				Hash:  chainhash.Hash{},
27				Index: 0xffffffff,
28			},
29			SignatureScript: []byte{
30				0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */
31				0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */
32				0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */
33				0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */
34				0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */
35				0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */
36				0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/
37				0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */
38				0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/
39				0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */
40			},
41			Sequence: 0xffffffff,
42		},
43	},
44	TxOut: []*TxOut{
45		{
46			Value: 0x12a05f200,
47			PkScript: []byte{
48				0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */
49				0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */
50				0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */
51				0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */
52				0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */
53				0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */
54				0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */
55				0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */
56				0x1d, 0x5f, 0xac, /* |._.| */
57			},
58		},
59	},
60	LockTime: 0,
61}
62
63// BenchmarkWriteVarInt1 performs a benchmark on how long it takes to write
64// a single byte variable length integer.
65func BenchmarkWriteVarInt1(b *testing.B) {
66	for i := 0; i < b.N; i++ {
67		WriteVarInt(ioutil.Discard, 0, 1)
68	}
69}
70
71// BenchmarkWriteVarInt3 performs a benchmark on how long it takes to write
72// a three byte variable length integer.
73func BenchmarkWriteVarInt3(b *testing.B) {
74	for i := 0; i < b.N; i++ {
75		WriteVarInt(ioutil.Discard, 0, 65535)
76	}
77}
78
79// BenchmarkWriteVarInt5 performs a benchmark on how long it takes to write
80// a five byte variable length integer.
81func BenchmarkWriteVarInt5(b *testing.B) {
82	for i := 0; i < b.N; i++ {
83		WriteVarInt(ioutil.Discard, 0, 4294967295)
84	}
85}
86
87// BenchmarkWriteVarInt9 performs a benchmark on how long it takes to write
88// a nine byte variable length integer.
89func BenchmarkWriteVarInt9(b *testing.B) {
90	for i := 0; i < b.N; i++ {
91		WriteVarInt(ioutil.Discard, 0, 18446744073709551615)
92	}
93}
94
95// BenchmarkReadVarInt1 performs a benchmark on how long it takes to read
96// a single byte variable length integer.
97func BenchmarkReadVarInt1(b *testing.B) {
98	buf := []byte{0x01}
99	r := bytes.NewReader(buf)
100	for i := 0; i < b.N; i++ {
101		r.Seek(0, 0)
102		ReadVarInt(r, 0)
103	}
104}
105
106// BenchmarkReadVarInt3 performs a benchmark on how long it takes to read
107// a three byte variable length integer.
108func BenchmarkReadVarInt3(b *testing.B) {
109	buf := []byte{0x0fd, 0xff, 0xff}
110	r := bytes.NewReader(buf)
111	for i := 0; i < b.N; i++ {
112		r.Seek(0, 0)
113		ReadVarInt(r, 0)
114	}
115}
116
117// BenchmarkReadVarInt5 performs a benchmark on how long it takes to read
118// a five byte variable length integer.
119func BenchmarkReadVarInt5(b *testing.B) {
120	buf := []byte{0xfe, 0xff, 0xff, 0xff, 0xff}
121	r := bytes.NewReader(buf)
122	for i := 0; i < b.N; i++ {
123		r.Seek(0, 0)
124		ReadVarInt(r, 0)
125	}
126}
127
128// BenchmarkReadVarInt9 performs a benchmark on how long it takes to read
129// a nine byte variable length integer.
130func BenchmarkReadVarInt9(b *testing.B) {
131	buf := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}
132	r := bytes.NewReader(buf)
133	for i := 0; i < b.N; i++ {
134		r.Seek(0, 0)
135		ReadVarInt(r, 0)
136	}
137}
138
139// BenchmarkReadVarStr4 performs a benchmark on how long it takes to read a
140// four byte variable length string.
141func BenchmarkReadVarStr4(b *testing.B) {
142	buf := []byte{0x04, 't', 'e', 's', 't'}
143	r := bytes.NewReader(buf)
144	for i := 0; i < b.N; i++ {
145		r.Seek(0, 0)
146		ReadVarString(r, 0)
147	}
148}
149
150// BenchmarkReadVarStr10 performs a benchmark on how long it takes to read a
151// ten byte variable length string.
152func BenchmarkReadVarStr10(b *testing.B) {
153	buf := []byte{0x0a, 't', 'e', 's', 't', '0', '1', '2', '3', '4', '5'}
154	r := bytes.NewReader(buf)
155	for i := 0; i < b.N; i++ {
156		r.Seek(0, 0)
157		ReadVarString(r, 0)
158	}
159}
160
161// BenchmarkWriteVarStr4 performs a benchmark on how long it takes to write a
162// four byte variable length string.
163func BenchmarkWriteVarStr4(b *testing.B) {
164	for i := 0; i < b.N; i++ {
165		WriteVarString(ioutil.Discard, 0, "test")
166	}
167}
168
169// BenchmarkWriteVarStr10 performs a benchmark on how long it takes to write a
170// ten byte variable length string.
171func BenchmarkWriteVarStr10(b *testing.B) {
172	for i := 0; i < b.N; i++ {
173		WriteVarString(ioutil.Discard, 0, "test012345")
174	}
175}
176
177// BenchmarkReadOutPoint performs a benchmark on how long it takes to read a
178// transaction output point.
179func BenchmarkReadOutPoint(b *testing.B) {
180	buf := []byte{
181		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
182		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
183		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
184		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
185		0xff, 0xff, 0xff, 0xff, // Previous output index
186	}
187	r := bytes.NewReader(buf)
188	var op OutPoint
189	for i := 0; i < b.N; i++ {
190		r.Seek(0, 0)
191		readOutPoint(r, 0, 0, &op)
192	}
193}
194
195// BenchmarkWriteOutPoint performs a benchmark on how long it takes to write a
196// transaction output point.
197func BenchmarkWriteOutPoint(b *testing.B) {
198	op := &OutPoint{
199		Hash:  chainhash.Hash{},
200		Index: 0,
201	}
202	for i := 0; i < b.N; i++ {
203		writeOutPoint(ioutil.Discard, 0, 0, op)
204	}
205}
206
207// BenchmarkReadTxOut performs a benchmark on how long it takes to read a
208// transaction output.
209func BenchmarkReadTxOut(b *testing.B) {
210	buf := []byte{
211		0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount
212		0x43, // Varint for length of pk script
213		0x41, // OP_DATA_65
214		0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
215		0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
216		0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
217		0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
218		0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
219		0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
220		0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
221		0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
222		0xee, // 65-byte signature
223		0xac, // OP_CHECKSIG
224	}
225	r := bytes.NewReader(buf)
226	var txOut TxOut
227	for i := 0; i < b.N; i++ {
228		r.Seek(0, 0)
229		readTxOut(r, 0, 0, &txOut)
230		scriptPool.Return(txOut.PkScript)
231	}
232}
233
234// BenchmarkWriteTxOut performs a benchmark on how long it takes to write
235// a transaction output.
236func BenchmarkWriteTxOut(b *testing.B) {
237	txOut := blockOne.Transactions[0].TxOut[0]
238	for i := 0; i < b.N; i++ {
239		WriteTxOut(ioutil.Discard, 0, 0, txOut)
240	}
241}
242
243// BenchmarkReadTxIn performs a benchmark on how long it takes to read a
244// transaction input.
245func BenchmarkReadTxIn(b *testing.B) {
246	buf := []byte{
247		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
248		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
249		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
250		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash
251		0xff, 0xff, 0xff, 0xff, // Previous output index
252		0x07,                                     // Varint for length of signature script
253		0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script
254		0xff, 0xff, 0xff, 0xff, // Sequence
255	}
256	r := bytes.NewReader(buf)
257	var txIn TxIn
258	for i := 0; i < b.N; i++ {
259		r.Seek(0, 0)
260		readTxIn(r, 0, 0, &txIn)
261		scriptPool.Return(txIn.SignatureScript)
262	}
263}
264
265// BenchmarkWriteTxIn performs a benchmark on how long it takes to write
266// a transaction input.
267func BenchmarkWriteTxIn(b *testing.B) {
268	txIn := blockOne.Transactions[0].TxIn[0]
269	for i := 0; i < b.N; i++ {
270		writeTxIn(ioutil.Discard, 0, 0, txIn)
271	}
272}
273
274// BenchmarkDeserializeTx performs a benchmark on how long it takes to
275// deserialize a small transaction.
276func BenchmarkDeserializeTxSmall(b *testing.B) {
277	buf := []byte{
278		0x01, 0x00, 0x00, 0x00, // Version
279		0x01, // Varint for number of input transactions
280		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
281		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
282		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
283		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //  // Previous output hash
284		0xff, 0xff, 0xff, 0xff, // Prevous output index
285		0x07,                                     // Varint for length of signature script
286		0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script
287		0xff, 0xff, 0xff, 0xff, // Sequence
288		0x01,                                           // Varint for number of output transactions
289		0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount
290		0x43, // Varint for length of pk script
291		0x41, // OP_DATA_65
292		0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c,
293		0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16,
294		0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c,
295		0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c,
296		0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4,
297		0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6,
298		0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e,
299		0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58,
300		0xee,                   // 65-byte signature
301		0xac,                   // OP_CHECKSIG
302		0x00, 0x00, 0x00, 0x00, // Lock time
303	}
304
305	r := bytes.NewReader(buf)
306	var tx MsgTx
307	for i := 0; i < b.N; i++ {
308		r.Seek(0, 0)
309		tx.Deserialize(r)
310	}
311}
312
313// BenchmarkDeserializeTxLarge performs a benchmark on how long it takes to
314// deserialize a very large transaction.
315func BenchmarkDeserializeTxLarge(b *testing.B) {
316	// tx bb41a757f405890fb0f5856228e23b715702d714d59bf2b1feb70d8b2b4e3e08
317	// from the main block chain.
318	fi, err := os.Open("testdata/megatx.bin.bz2")
319	if err != nil {
320		b.Fatalf("Failed to read transaction data: %v", err)
321	}
322	defer fi.Close()
323	buf, err := ioutil.ReadAll(bzip2.NewReader(fi))
324	if err != nil {
325		b.Fatalf("Failed to read transaction data: %v", err)
326	}
327
328	r := bytes.NewReader(buf)
329	var tx MsgTx
330	for i := 0; i < b.N; i++ {
331		r.Seek(0, 0)
332		tx.Deserialize(r)
333	}
334}
335
336// BenchmarkSerializeTx performs a benchmark on how long it takes to serialize
337// a transaction.
338func BenchmarkSerializeTx(b *testing.B) {
339	tx := blockOne.Transactions[0]
340	for i := 0; i < b.N; i++ {
341		tx.Serialize(ioutil.Discard)
342
343	}
344}
345
346// BenchmarkReadBlockHeader performs a benchmark on how long it takes to
347// deserialize a block header.
348func BenchmarkReadBlockHeader(b *testing.B) {
349	buf := []byte{
350		0x01, 0x00, 0x00, 0x00, // Version 1
351		0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72,
352		0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f,
353		0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c,
354		0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock
355		0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2,
356		0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61,
357		0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32,
358		0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot
359		0x29, 0xab, 0x5f, 0x49, // Timestamp
360		0xff, 0xff, 0x00, 0x1d, // Bits
361		0xf3, 0xe0, 0x01, 0x00, // Nonce
362		0x00, // TxnCount Varint
363	}
364	r := bytes.NewReader(buf)
365	var header BlockHeader
366	for i := 0; i < b.N; i++ {
367		r.Seek(0, 0)
368		readBlockHeader(r, 0, &header)
369	}
370}
371
372// BenchmarkWriteBlockHeader performs a benchmark on how long it takes to
373// serialize a block header.
374func BenchmarkWriteBlockHeader(b *testing.B) {
375	header := blockOne.Header
376	for i := 0; i < b.N; i++ {
377		writeBlockHeader(ioutil.Discard, 0, &header)
378	}
379}
380
381// BenchmarkDecodeGetHeaders performs a benchmark on how long it takes to
382// decode a getheaders message with the maximum number of block locator hashes.
383func BenchmarkDecodeGetHeaders(b *testing.B) {
384	// Create a message with the maximum number of block locators.
385	pver := ProtocolVersion
386	var m MsgGetHeaders
387	for i := 0; i < MaxBlockLocatorsPerMsg; i++ {
388		hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
389		if err != nil {
390			b.Fatalf("NewHashFromStr: unexpected error: %v", err)
391		}
392		m.AddBlockLocatorHash(hash)
393	}
394
395	// Serialize it so the bytes are available to test the decode below.
396	var bb bytes.Buffer
397	if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil {
398		b.Fatalf("MsgGetHeaders.BtcEncode: unexpected error: %v", err)
399	}
400	buf := bb.Bytes()
401
402	r := bytes.NewReader(buf)
403	var msg MsgGetHeaders
404	b.ResetTimer()
405	for i := 0; i < b.N; i++ {
406		r.Seek(0, 0)
407		msg.BtcDecode(r, pver, LatestEncoding)
408	}
409}
410
411// BenchmarkDecodeHeaders performs a benchmark on how long it takes to
412// decode a headers message with the maximum number of headers.
413func BenchmarkDecodeHeaders(b *testing.B) {
414	// Create a message with the maximum number of headers.
415	pver := ProtocolVersion
416	var m MsgHeaders
417	for i := 0; i < MaxBlockHeadersPerMsg; i++ {
418		hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
419		if err != nil {
420			b.Fatalf("NewHashFromStr: unexpected error: %v", err)
421		}
422		m.AddBlockHeader(NewBlockHeader(1, hash, hash, 0, uint32(i)))
423	}
424
425	// Serialize it so the bytes are available to test the decode below.
426	var bb bytes.Buffer
427	if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil {
428		b.Fatalf("MsgHeaders.BtcEncode: unexpected error: %v", err)
429	}
430	buf := bb.Bytes()
431
432	r := bytes.NewReader(buf)
433	var msg MsgHeaders
434	b.ResetTimer()
435	for i := 0; i < b.N; i++ {
436		r.Seek(0, 0)
437		msg.BtcDecode(r, pver, LatestEncoding)
438	}
439}
440
441// BenchmarkDecodeGetBlocks performs a benchmark on how long it takes to
442// decode a getblocks message with the maximum number of block locator hashes.
443func BenchmarkDecodeGetBlocks(b *testing.B) {
444	// Create a message with the maximum number of block locators.
445	pver := ProtocolVersion
446	var m MsgGetBlocks
447	for i := 0; i < MaxBlockLocatorsPerMsg; i++ {
448		hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
449		if err != nil {
450			b.Fatalf("NewHashFromStr: unexpected error: %v", err)
451		}
452		m.AddBlockLocatorHash(hash)
453	}
454
455	// Serialize it so the bytes are available to test the decode below.
456	var bb bytes.Buffer
457	if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil {
458		b.Fatalf("MsgGetBlocks.BtcEncode: unexpected error: %v", err)
459	}
460	buf := bb.Bytes()
461
462	r := bytes.NewReader(buf)
463	var msg MsgGetBlocks
464	b.ResetTimer()
465	for i := 0; i < b.N; i++ {
466		r.Seek(0, 0)
467		msg.BtcDecode(r, pver, LatestEncoding)
468	}
469}
470
471// BenchmarkDecodeAddr performs a benchmark on how long it takes to decode an
472// addr message with the maximum number of addresses.
473func BenchmarkDecodeAddr(b *testing.B) {
474	// Create a message with the maximum number of addresses.
475	pver := ProtocolVersion
476	ip := net.ParseIP("127.0.0.1")
477	ma := NewMsgAddr()
478	for port := uint16(0); port < MaxAddrPerMsg; port++ {
479		ma.AddAddress(NewNetAddressIPPort(ip, port, SFNodeNetwork))
480	}
481
482	// Serialize it so the bytes are available to test the decode below.
483	var bb bytes.Buffer
484	if err := ma.BtcEncode(&bb, pver, LatestEncoding); err != nil {
485		b.Fatalf("MsgAddr.BtcEncode: unexpected error: %v", err)
486	}
487	buf := bb.Bytes()
488
489	r := bytes.NewReader(buf)
490	var msg MsgAddr
491	b.ResetTimer()
492	for i := 0; i < b.N; i++ {
493		r.Seek(0, 0)
494		msg.BtcDecode(r, pver, LatestEncoding)
495	}
496}
497
498// BenchmarkDecodeInv performs a benchmark on how long it takes to decode an inv
499// message with the maximum number of entries.
500func BenchmarkDecodeInv(b *testing.B) {
501	// Create a message with the maximum number of entries.
502	pver := ProtocolVersion
503	var m MsgInv
504	for i := 0; i < MaxInvPerMsg; i++ {
505		hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
506		if err != nil {
507			b.Fatalf("NewHashFromStr: unexpected error: %v", err)
508		}
509		m.AddInvVect(NewInvVect(InvTypeBlock, hash))
510	}
511
512	// Serialize it so the bytes are available to test the decode below.
513	var bb bytes.Buffer
514	if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil {
515		b.Fatalf("MsgInv.BtcEncode: unexpected error: %v", err)
516	}
517	buf := bb.Bytes()
518
519	r := bytes.NewReader(buf)
520	var msg MsgInv
521	b.ResetTimer()
522	for i := 0; i < b.N; i++ {
523		r.Seek(0, 0)
524		msg.BtcDecode(r, pver, LatestEncoding)
525	}
526}
527
528// BenchmarkDecodeNotFound performs a benchmark on how long it takes to decode
529// a notfound message with the maximum number of entries.
530func BenchmarkDecodeNotFound(b *testing.B) {
531	// Create a message with the maximum number of entries.
532	pver := ProtocolVersion
533	var m MsgNotFound
534	for i := 0; i < MaxInvPerMsg; i++ {
535		hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
536		if err != nil {
537			b.Fatalf("NewHashFromStr: unexpected error: %v", err)
538		}
539		m.AddInvVect(NewInvVect(InvTypeBlock, hash))
540	}
541
542	// Serialize it so the bytes are available to test the decode below.
543	var bb bytes.Buffer
544	if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil {
545		b.Fatalf("MsgNotFound.BtcEncode: unexpected error: %v", err)
546	}
547	buf := bb.Bytes()
548
549	r := bytes.NewReader(buf)
550	var msg MsgNotFound
551	b.ResetTimer()
552	for i := 0; i < b.N; i++ {
553		r.Seek(0, 0)
554		msg.BtcDecode(r, pver, LatestEncoding)
555	}
556}
557
558// BenchmarkDecodeMerkleBlock performs a benchmark on how long it takes to
559// decode a reasonably sized merkleblock message.
560func BenchmarkDecodeMerkleBlock(b *testing.B) {
561	// Create a message with random data.
562	pver := ProtocolVersion
563	var m MsgMerkleBlock
564	hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", 10000))
565	if err != nil {
566		b.Fatalf("NewHashFromStr: unexpected error: %v", err)
567	}
568	m.Header = *NewBlockHeader(1, hash, hash, 0, uint32(10000))
569	for i := 0; i < 105; i++ {
570		hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i))
571		if err != nil {
572			b.Fatalf("NewHashFromStr: unexpected error: %v", err)
573		}
574		m.AddTxHash(hash)
575		if i%8 == 0 {
576			m.Flags = append(m.Flags, uint8(i))
577		}
578	}
579
580	// Serialize it so the bytes are available to test the decode below.
581	var bb bytes.Buffer
582	if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil {
583		b.Fatalf("MsgMerkleBlock.BtcEncode: unexpected error: %v", err)
584	}
585	buf := bb.Bytes()
586
587	r := bytes.NewReader(buf)
588	var msg MsgMerkleBlock
589	b.ResetTimer()
590	for i := 0; i < b.N; i++ {
591		r.Seek(0, 0)
592		msg.BtcDecode(r, pver, LatestEncoding)
593	}
594}
595
596// BenchmarkTxHash performs a benchmark on how long it takes to hash a
597// transaction.
598func BenchmarkTxHash(b *testing.B) {
599	for i := 0; i < b.N; i++ {
600		genesisCoinbaseTx.TxHash()
601	}
602}
603
604// BenchmarkDoubleHashB performs a benchmark on how long it takes to perform a
605// double hash returning a byte slice.
606func BenchmarkDoubleHashB(b *testing.B) {
607	var buf bytes.Buffer
608	if err := genesisCoinbaseTx.Serialize(&buf); err != nil {
609		b.Errorf("Serialize: unexpected error: %v", err)
610		return
611	}
612	txBytes := buf.Bytes()
613
614	b.ResetTimer()
615	for i := 0; i < b.N; i++ {
616		_ = chainhash.DoubleHashB(txBytes)
617	}
618}
619
620// BenchmarkDoubleHashH performs a benchmark on how long it takes to perform
621// a double hash returning a chainhash.Hash.
622func BenchmarkDoubleHashH(b *testing.B) {
623	var buf bytes.Buffer
624	if err := genesisCoinbaseTx.Serialize(&buf); err != nil {
625		b.Errorf("Serialize: unexpected error: %v", err)
626		return
627	}
628	txBytes := buf.Bytes()
629
630	b.ResetTimer()
631	for i := 0; i < b.N; i++ {
632		_ = chainhash.DoubleHashH(txBytes)
633	}
634}
635