bench_test.go raw

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