github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/wire/bench_test.go (about)

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