github.com/btcsuite/btcd@v0.24.0/wire/bench_test.go (about) 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 5 package wire 6 7 import ( 8 "bytes" 9 "compress/bzip2" 10 "fmt" 11 "io" 12 "io/ioutil" 13 "net" 14 "os" 15 "testing" 16 17 "github.com/btcsuite/btcd/chaincfg/chainhash" 18 ) 19 20 // genesisCoinbaseTx is the coinbase transaction for the genesis blocks for 21 // the main network, regression test network, and test network (version 3). 22 var genesisCoinbaseTx = MsgTx{ 23 Version: 1, 24 TxIn: []*TxIn{ 25 { 26 PreviousOutPoint: OutPoint{ 27 Hash: chainhash.Hash{}, 28 Index: 0xffffffff, 29 }, 30 SignatureScript: []byte{ 31 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x45, /* |.......E| */ 32 0x54, 0x68, 0x65, 0x20, 0x54, 0x69, 0x6d, 0x65, /* |The Time| */ 33 0x73, 0x20, 0x30, 0x33, 0x2f, 0x4a, 0x61, 0x6e, /* |s 03/Jan| */ 34 0x2f, 0x32, 0x30, 0x30, 0x39, 0x20, 0x43, 0x68, /* |/2009 Ch| */ 35 0x61, 0x6e, 0x63, 0x65, 0x6c, 0x6c, 0x6f, 0x72, /* |ancellor| */ 36 0x20, 0x6f, 0x6e, 0x20, 0x62, 0x72, 0x69, 0x6e, /* | on brin| */ 37 0x6b, 0x20, 0x6f, 0x66, 0x20, 0x73, 0x65, 0x63, /* |k of sec|*/ 38 0x6f, 0x6e, 0x64, 0x20, 0x62, 0x61, 0x69, 0x6c, /* |ond bail| */ 39 0x6f, 0x75, 0x74, 0x20, 0x66, 0x6f, 0x72, 0x20, /* |out for |*/ 40 0x62, 0x61, 0x6e, 0x6b, 0x73, /* |banks| */ 41 }, 42 Sequence: 0xffffffff, 43 }, 44 }, 45 TxOut: []*TxOut{ 46 { 47 Value: 0x12a05f200, 48 PkScript: []byte{ 49 0x41, 0x04, 0x67, 0x8a, 0xfd, 0xb0, 0xfe, 0x55, /* |A.g....U| */ 50 0x48, 0x27, 0x19, 0x67, 0xf1, 0xa6, 0x71, 0x30, /* |H'.g..q0| */ 51 0xb7, 0x10, 0x5c, 0xd6, 0xa8, 0x28, 0xe0, 0x39, /* |..\..(.9| */ 52 0x09, 0xa6, 0x79, 0x62, 0xe0, 0xea, 0x1f, 0x61, /* |..yb...a| */ 53 0xde, 0xb6, 0x49, 0xf6, 0xbc, 0x3f, 0x4c, 0xef, /* |..I..?L.| */ 54 0x38, 0xc4, 0xf3, 0x55, 0x04, 0xe5, 0x1e, 0xc1, /* |8..U....| */ 55 0x12, 0xde, 0x5c, 0x38, 0x4d, 0xf7, 0xba, 0x0b, /* |..\8M...| */ 56 0x8d, 0x57, 0x8a, 0x4c, 0x70, 0x2b, 0x6b, 0xf1, /* |.W.Lp+k.| */ 57 0x1d, 0x5f, 0xac, /* |._.| */ 58 }, 59 }, 60 }, 61 LockTime: 0, 62 } 63 64 // BenchmarkWriteVarInt1 performs a benchmark on how long it takes to write 65 // a single byte variable length integer. 66 func BenchmarkWriteVarInt1(b *testing.B) { 67 b.ReportAllocs() 68 69 for i := 0; i < b.N; i++ { 70 WriteVarInt(io.Discard, 0, 1) 71 } 72 } 73 74 // BenchmarkWriteVarInt3 performs a benchmark on how long it takes to write 75 // a three byte variable length integer. 76 func BenchmarkWriteVarInt3(b *testing.B) { 77 b.ReportAllocs() 78 79 for i := 0; i < b.N; i++ { 80 WriteVarInt(io.Discard, 0, 65535) 81 } 82 } 83 84 // BenchmarkWriteVarInt5 performs a benchmark on how long it takes to write 85 // a five byte variable length integer. 86 func BenchmarkWriteVarInt5(b *testing.B) { 87 b.ReportAllocs() 88 89 for i := 0; i < b.N; i++ { 90 WriteVarInt(io.Discard, 0, 4294967295) 91 } 92 } 93 94 // BenchmarkWriteVarInt9 performs a benchmark on how long it takes to write 95 // a nine byte variable length integer. 96 func BenchmarkWriteVarInt9(b *testing.B) { 97 b.ReportAllocs() 98 99 for i := 0; i < b.N; i++ { 100 WriteVarInt(io.Discard, 0, 18446744073709551615) 101 } 102 } 103 104 // BenchmarkReadVarInt1 performs a benchmark on how long it takes to read 105 // a single byte variable length integer. 106 func BenchmarkReadVarInt1(b *testing.B) { 107 b.ReportAllocs() 108 109 buf := []byte{0x01} 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 // BenchmarkReadVarInt3 performs a benchmark on how long it takes to read 118 // a three byte variable length integer. 119 func BenchmarkReadVarInt3(b *testing.B) { 120 b.ReportAllocs() 121 122 buf := []byte{0x0fd, 0xff, 0xff} 123 r := bytes.NewReader(buf) 124 for i := 0; i < b.N; i++ { 125 r.Seek(0, 0) 126 ReadVarInt(r, 0) 127 } 128 } 129 130 // BenchmarkReadVarInt5 performs a benchmark on how long it takes to read 131 // a five byte variable length integer. 132 func BenchmarkReadVarInt5(b *testing.B) { 133 b.ReportAllocs() 134 135 buf := []byte{0xfe, 0xff, 0xff, 0xff, 0xff} 136 r := bytes.NewReader(buf) 137 for i := 0; i < b.N; i++ { 138 r.Seek(0, 0) 139 ReadVarInt(r, 0) 140 } 141 } 142 143 // BenchmarkReadVarInt9 performs a benchmark on how long it takes to read 144 // a nine byte variable length integer. 145 func BenchmarkReadVarInt9(b *testing.B) { 146 b.ReportAllocs() 147 148 buf := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} 149 r := bytes.NewReader(buf) 150 for i := 0; i < b.N; i++ { 151 r.Seek(0, 0) 152 ReadVarInt(r, 0) 153 } 154 } 155 156 // BenchmarkWriteVarIntBuf1 performs a benchmark on how long it takes to write 157 // a single byte variable length integer. 158 func BenchmarkWriteVarIntBuf1(b *testing.B) { 159 b.ReportAllocs() 160 161 buffer := binarySerializer.Borrow() 162 for i := 0; i < b.N; i++ { 163 WriteVarIntBuf(io.Discard, 0, 1, buffer) 164 } 165 binarySerializer.Return(buffer) 166 } 167 168 // BenchmarkWriteVarIntBuf3 performs a benchmark on how long it takes to write 169 // a three byte variable length integer. 170 func BenchmarkWriteVarIntBuf3(b *testing.B) { 171 b.ReportAllocs() 172 173 buffer := binarySerializer.Borrow() 174 for i := 0; i < b.N; i++ { 175 WriteVarIntBuf(io.Discard, 0, 65535, buffer) 176 } 177 binarySerializer.Return(buffer) 178 } 179 180 // BenchmarkWriteVarIntBuf5 performs a benchmark on how long it takes to write 181 // a five byte variable length integer. 182 func BenchmarkWriteVarIntBuf5(b *testing.B) { 183 b.ReportAllocs() 184 185 buffer := binarySerializer.Borrow() 186 for i := 0; i < b.N; i++ { 187 WriteVarIntBuf(io.Discard, 0, 4294967295, buffer) 188 } 189 binarySerializer.Return(buffer) 190 } 191 192 // BenchmarkWriteVarIntBuf9 performs a benchmark on how long it takes to write 193 // a nine byte variable length integer. 194 func BenchmarkWriteVarIntBuf9(b *testing.B) { 195 b.ReportAllocs() 196 197 buffer := binarySerializer.Borrow() 198 for i := 0; i < b.N; i++ { 199 WriteVarIntBuf(io.Discard, 0, 18446744073709551615, buffer) 200 } 201 binarySerializer.Return(buffer) 202 } 203 204 // BenchmarkReadVarIntBuf1 performs a benchmark on how long it takes to read 205 // a single byte variable length integer. 206 func BenchmarkReadVarIntBuf1(b *testing.B) { 207 b.ReportAllocs() 208 209 buffer := binarySerializer.Borrow() 210 buf := []byte{0x01} 211 r := bytes.NewReader(buf) 212 for i := 0; i < b.N; i++ { 213 r.Seek(0, 0) 214 ReadVarIntBuf(r, 0, buffer) 215 } 216 binarySerializer.Return(buffer) 217 } 218 219 // BenchmarkReadVarIntBuf3 performs a benchmark on how long it takes to read 220 // a three byte variable length integer. 221 func BenchmarkReadVarIntBuf3(b *testing.B) { 222 b.ReportAllocs() 223 224 buffer := binarySerializer.Borrow() 225 buf := []byte{0x0fd, 0xff, 0xff} 226 r := bytes.NewReader(buf) 227 for i := 0; i < b.N; i++ { 228 r.Seek(0, 0) 229 ReadVarIntBuf(r, 0, buffer) 230 } 231 binarySerializer.Return(buffer) 232 } 233 234 // BenchmarkReadVarIntBuf5 performs a benchmark on how long it takes to read 235 // a five byte variable length integer. 236 func BenchmarkReadVarIntBuf5(b *testing.B) { 237 b.ReportAllocs() 238 239 buffer := binarySerializer.Borrow() 240 buf := []byte{0xfe, 0xff, 0xff, 0xff, 0xff} 241 r := bytes.NewReader(buf) 242 for i := 0; i < b.N; i++ { 243 r.Seek(0, 0) 244 ReadVarIntBuf(r, 0, buffer) 245 } 246 binarySerializer.Return(buffer) 247 } 248 249 // BenchmarkReadVarIntBuf9 performs a benchmark on how long it takes to read 250 // a nine byte variable length integer. 251 func BenchmarkReadVarIntBuf9(b *testing.B) { 252 b.ReportAllocs() 253 254 buffer := binarySerializer.Borrow() 255 buf := []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} 256 r := bytes.NewReader(buf) 257 for i := 0; i < b.N; i++ { 258 r.Seek(0, 0) 259 ReadVarIntBuf(r, 0, buffer) 260 } 261 binarySerializer.Return(buffer) 262 } 263 264 // BenchmarkReadVarStr4 performs a benchmark on how long it takes to read a 265 // four byte variable length string. 266 func BenchmarkReadVarStr4(b *testing.B) { 267 b.ReportAllocs() 268 269 buf := []byte{0x04, 't', 'e', 's', 't'} 270 r := bytes.NewReader(buf) 271 for i := 0; i < b.N; i++ { 272 r.Seek(0, 0) 273 ReadVarString(r, 0) 274 } 275 } 276 277 // BenchmarkReadVarStr10 performs a benchmark on how long it takes to read a 278 // ten byte variable length string. 279 func BenchmarkReadVarStr10(b *testing.B) { 280 b.ReportAllocs() 281 282 buf := []byte{0x0a, 't', 'e', 's', 't', '0', '1', '2', '3', '4', '5'} 283 r := bytes.NewReader(buf) 284 for i := 0; i < b.N; i++ { 285 r.Seek(0, 0) 286 ReadVarString(r, 0) 287 } 288 } 289 290 // BenchmarkWriteVarStr4 performs a benchmark on how long it takes to write a 291 // four byte variable length string. 292 func BenchmarkWriteVarStr4(b *testing.B) { 293 b.ReportAllocs() 294 295 for i := 0; i < b.N; i++ { 296 WriteVarString(io.Discard, 0, "test") 297 } 298 } 299 300 // BenchmarkWriteVarStr10 performs a benchmark on how long it takes to write a 301 // ten byte variable length string. 302 func BenchmarkWriteVarStr10(b *testing.B) { 303 b.ReportAllocs() 304 305 for i := 0; i < b.N; i++ { 306 WriteVarString(io.Discard, 0, "test012345") 307 } 308 } 309 310 // BenchmarkReadVarStrBuf4 performs a benchmark on how long it takes to read a 311 // four byte variable length string. 312 func BenchmarkReadVarStrBuf4(b *testing.B) { 313 b.ReportAllocs() 314 315 buffer := binarySerializer.Borrow() 316 buf := []byte{0x04, 't', 'e', 's', 't'} 317 r := bytes.NewReader(buf) 318 for i := 0; i < b.N; i++ { 319 r.Seek(0, 0) 320 readVarStringBuf(r, 0, buffer) 321 } 322 binarySerializer.Return(buffer) 323 } 324 325 // BenchmarkReadVarStrBuf10 performs a benchmark on how long it takes to read a 326 // ten byte variable length string. 327 func BenchmarkReadVarStrBuf10(b *testing.B) { 328 b.ReportAllocs() 329 330 buffer := binarySerializer.Borrow() 331 buf := []byte{0x0a, 't', 'e', 's', 't', '0', '1', '2', '3', '4', '5'} 332 r := bytes.NewReader(buf) 333 for i := 0; i < b.N; i++ { 334 r.Seek(0, 0) 335 readVarStringBuf(r, 0, buf) 336 } 337 binarySerializer.Return(buffer) 338 } 339 340 // BenchmarkWriteVarStrBuf4 performs a benchmark on how long it takes to write a 341 // four byte variable length string. 342 func BenchmarkWriteVarStrBuf4(b *testing.B) { 343 b.ReportAllocs() 344 345 buf := binarySerializer.Borrow() 346 for i := 0; i < b.N; i++ { 347 writeVarStringBuf(io.Discard, 0, "test", buf) 348 } 349 binarySerializer.Return(buf) 350 } 351 352 // BenchmarkWriteVarStrBuf10 performs a benchmark on how long it takes to write 353 // a ten byte variable length string. 354 func BenchmarkWriteVarStrBuf10(b *testing.B) { 355 b.ReportAllocs() 356 357 buf := binarySerializer.Borrow() 358 for i := 0; i < b.N; i++ { 359 writeVarStringBuf(io.Discard, 0, "test012345", buf) 360 } 361 binarySerializer.Return(buf) 362 } 363 364 // BenchmarkReadOutPoint performs a benchmark on how long it takes to read a 365 // transaction output point. 366 func BenchmarkReadOutPoint(b *testing.B) { 367 b.ReportAllocs() 368 369 buffer := binarySerializer.Borrow() 370 buf := []byte{ 371 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 372 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 373 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 374 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash 375 0xff, 0xff, 0xff, 0xff, // Previous output index 376 } 377 r := bytes.NewReader(buf) 378 var op OutPoint 379 for i := 0; i < b.N; i++ { 380 r.Seek(0, 0) 381 readOutPointBuf(r, 0, 0, &op, buffer) 382 } 383 binarySerializer.Return(buffer) 384 } 385 386 // BenchmarkWriteOutPoint performs a benchmark on how long it takes to write a 387 // transaction output point. 388 func BenchmarkWriteOutPoint(b *testing.B) { 389 b.ReportAllocs() 390 391 op := &OutPoint{ 392 Hash: chainhash.Hash{}, 393 Index: 0, 394 } 395 for i := 0; i < b.N; i++ { 396 WriteOutPoint(io.Discard, 0, 0, op) 397 } 398 } 399 400 // BenchmarkWriteOutPointBuf performs a benchmark on how long it takes to write a 401 // transaction output point. 402 func BenchmarkWriteOutPointBuf(b *testing.B) { 403 b.ReportAllocs() 404 405 buf := binarySerializer.Borrow() 406 op := &OutPoint{ 407 Hash: chainhash.Hash{}, 408 Index: 0, 409 } 410 for i := 0; i < b.N; i++ { 411 writeOutPointBuf(io.Discard, 0, 0, op, buf) 412 } 413 binarySerializer.Return(buf) 414 } 415 416 // BenchmarkReadTxOut performs a benchmark on how long it takes to read a 417 // transaction output. 418 func BenchmarkReadTxOut(b *testing.B) { 419 b.ReportAllocs() 420 421 buf := []byte{ 422 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount 423 0x43, // Varint for length of pk script 424 0x41, // OP_DATA_65 425 0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c, 426 0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16, 427 0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c, 428 0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c, 429 0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4, 430 0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6, 431 0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e, 432 0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58, 433 0xee, // 65-byte signature 434 0xac, // OP_CHECKSIG 435 } 436 r := bytes.NewReader(buf) 437 var txOut TxOut 438 for i := 0; i < b.N; i++ { 439 r.Seek(0, 0) 440 ReadTxOut(r, 0, 0, &txOut) 441 } 442 } 443 444 // BenchmarkReadTxOutBuf performs a benchmark on how long it takes to read a 445 // transaction output. 446 func BenchmarkReadTxOutBuf(b *testing.B) { 447 b.ReportAllocs() 448 449 scriptBuffer := scriptPool.Borrow() 450 sbuf := scriptBuffer[:] 451 buffer := binarySerializer.Borrow() 452 buf := []byte{ 453 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount 454 0x43, // Varint for length of pk script 455 0x41, // OP_DATA_65 456 0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c, 457 0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16, 458 0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c, 459 0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c, 460 0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4, 461 0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6, 462 0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e, 463 0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58, 464 0xee, // 65-byte signature 465 0xac, // OP_CHECKSIG 466 } 467 r := bytes.NewReader(buf) 468 var txOut TxOut 469 for i := 0; i < b.N; i++ { 470 r.Seek(0, 0) 471 readTxOutBuf(r, 0, 0, &txOut, buffer, sbuf) 472 } 473 binarySerializer.Return(buffer) 474 scriptPool.Return(scriptBuffer) 475 } 476 477 // BenchmarkWriteTxOut performs a benchmark on how long it takes to write 478 // a transaction output. 479 func BenchmarkWriteTxOut(b *testing.B) { 480 b.ReportAllocs() 481 482 txOut := blockOne.Transactions[0].TxOut[0] 483 for i := 0; i < b.N; i++ { 484 WriteTxOut(io.Discard, 0, 0, txOut) 485 } 486 } 487 488 // BenchmarkWriteTxOutBuf performs a benchmark on how long it takes to write 489 // a transaction output. 490 func BenchmarkWriteTxOutBuf(b *testing.B) { 491 b.ReportAllocs() 492 493 buf := binarySerializer.Borrow() 494 txOut := blockOne.Transactions[0].TxOut[0] 495 for i := 0; i < b.N; i++ { 496 WriteTxOutBuf(io.Discard, 0, 0, txOut, buf) 497 } 498 binarySerializer.Return(buf) 499 } 500 501 // BenchmarkReadTxIn performs a benchmark on how long it takes to read a 502 // transaction input. 503 func BenchmarkReadTxIn(b *testing.B) { 504 b.ReportAllocs() 505 506 scriptBuffer := scriptPool.Borrow() 507 sbuf := scriptBuffer[:] 508 buffer := binarySerializer.Borrow() 509 buf := []byte{ 510 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 511 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 512 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 513 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Previous output hash 514 0xff, 0xff, 0xff, 0xff, // Previous output index 515 0x07, // Varint for length of signature script 516 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script 517 0xff, 0xff, 0xff, 0xff, // Sequence 518 } 519 r := bytes.NewReader(buf) 520 var txIn TxIn 521 for i := 0; i < b.N; i++ { 522 r.Seek(0, 0) 523 readTxInBuf(r, 0, 0, &txIn, buffer, sbuf) 524 } 525 binarySerializer.Return(buffer) 526 scriptPool.Return(scriptBuffer) 527 } 528 529 // BenchmarkWriteTxIn performs a benchmark on how long it takes to write 530 // a transaction input. 531 func BenchmarkWriteTxIn(b *testing.B) { 532 b.ReportAllocs() 533 534 buf := binarySerializer.Borrow() 535 txIn := blockOne.Transactions[0].TxIn[0] 536 for i := 0; i < b.N; i++ { 537 writeTxInBuf(io.Discard, 0, 0, txIn, buf) 538 } 539 binarySerializer.Return(buf) 540 } 541 542 // BenchmarkDeserializeTx performs a benchmark on how long it takes to 543 // deserialize a small transaction. 544 func BenchmarkDeserializeTxSmall(b *testing.B) { 545 buf := []byte{ 546 0x01, 0x00, 0x00, 0x00, // Version 547 0x01, // Varint for number of input transactions 548 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 549 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 550 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 551 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // // Previous output hash 552 0xff, 0xff, 0xff, 0xff, // Prevous output index 553 0x07, // Varint for length of signature script 554 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script 555 0xff, 0xff, 0xff, 0xff, // Sequence 556 0x01, // Varint for number of output transactions 557 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount 558 0x43, // Varint for length of pk script 559 0x41, // OP_DATA_65 560 0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c, 561 0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16, 562 0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c, 563 0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c, 564 0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4, 565 0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6, 566 0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e, 567 0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58, 568 0xee, // 65-byte signature 569 0xac, // OP_CHECKSIG 570 0x00, 0x00, 0x00, 0x00, // Lock time 571 } 572 573 b.ReportAllocs() 574 b.ResetTimer() 575 576 r := bytes.NewReader(buf) 577 var tx MsgTx 578 for i := 0; i < b.N; i++ { 579 r.Seek(0, 0) 580 tx.Deserialize(r) 581 } 582 } 583 584 // BenchmarkDeserializeTxLarge performs a benchmark on how long it takes to 585 // deserialize a very large transaction. 586 func BenchmarkDeserializeTxLarge(b *testing.B) { 587 588 // tx bb41a757f405890fb0f5856228e23b715702d714d59bf2b1feb70d8b2b4e3e08 589 // from the main block chain. 590 fi, err := os.Open("testdata/megatx.bin.bz2") 591 if err != nil { 592 b.Fatalf("Failed to read transaction data: %v", err) 593 } 594 defer fi.Close() 595 buf, err := ioutil.ReadAll(bzip2.NewReader(fi)) 596 if err != nil { 597 b.Fatalf("Failed to read transaction data: %v", err) 598 } 599 600 b.ReportAllocs() 601 b.ResetTimer() 602 603 r := bytes.NewReader(buf) 604 var tx MsgTx 605 for i := 0; i < b.N; i++ { 606 r.Seek(0, 0) 607 tx.Deserialize(r) 608 } 609 } 610 611 func BenchmarkDeserializeBlock(b *testing.B) { 612 buf, err := os.ReadFile( 613 "testdata/block-00000000000000000021868c2cefc52a480d173c849412fe81c4e5ab806f94ab.blk", 614 ) 615 if err != nil { 616 b.Fatalf("Failed to read block data: %v", err) 617 } 618 619 b.ReportAllocs() 620 b.ResetTimer() 621 622 r := bytes.NewReader(buf) 623 var block MsgBlock 624 for i := 0; i < b.N; i++ { 625 r.Seek(0, 0) 626 block.Deserialize(r) 627 } 628 } 629 630 func BenchmarkSerializeBlock(b *testing.B) { 631 buf, err := os.ReadFile( 632 "testdata/block-00000000000000000021868c2cefc52a480d173c849412fe81c4e5ab806f94ab.blk", 633 ) 634 if err != nil { 635 b.Fatalf("Failed to read block data: %v", err) 636 } 637 638 var block MsgBlock 639 err = block.Deserialize(bytes.NewReader(buf)) 640 if err != nil { 641 panic(err.Error()) 642 } 643 644 b.ReportAllocs() 645 b.ResetTimer() 646 647 for i := 0; i < b.N; i++ { 648 block.Serialize(io.Discard) 649 } 650 } 651 652 // BenchmarkSerializeTx performs a benchmark on how long it takes to serialize 653 // a transaction. 654 func BenchmarkSerializeTx(b *testing.B) { 655 b.ReportAllocs() 656 657 tx := blockOne.Transactions[0] 658 for i := 0; i < b.N; i++ { 659 tx.Serialize(io.Discard) 660 661 } 662 } 663 664 // BenchmarkSerializeTxSmall performs a benchmark on how long it takes to 665 // serialize a transaction. 666 func BenchmarkSerializeTxSmall(b *testing.B) { 667 buf := []byte{ 668 0x01, 0x00, 0x00, 0x00, // Version 669 0x01, // Varint for number of input transactions 670 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 671 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 672 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 673 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // // Previous output hash 674 0xff, 0xff, 0xff, 0xff, // Prevous output index 675 0x07, // Varint for length of signature script 676 0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, // Signature script 677 0xff, 0xff, 0xff, 0xff, // Sequence 678 0x01, // Varint for number of output transactions 679 0x00, 0xf2, 0x05, 0x2a, 0x01, 0x00, 0x00, 0x00, // Transaction amount 680 0x43, // Varint for length of pk script 681 0x41, // OP_DATA_65 682 0x04, 0x96, 0xb5, 0x38, 0xe8, 0x53, 0x51, 0x9c, 683 0x72, 0x6a, 0x2c, 0x91, 0xe6, 0x1e, 0xc1, 0x16, 684 0x00, 0xae, 0x13, 0x90, 0x81, 0x3a, 0x62, 0x7c, 685 0x66, 0xfb, 0x8b, 0xe7, 0x94, 0x7b, 0xe6, 0x3c, 686 0x52, 0xda, 0x75, 0x89, 0x37, 0x95, 0x15, 0xd4, 687 0xe0, 0xa6, 0x04, 0xf8, 0x14, 0x17, 0x81, 0xe6, 688 0x22, 0x94, 0x72, 0x11, 0x66, 0xbf, 0x62, 0x1e, 689 0x73, 0xa8, 0x2c, 0xbf, 0x23, 0x42, 0xc8, 0x58, 690 0xee, // 65-byte signature 691 0xac, // OP_CHECKSIG 692 0x00, 0x00, 0x00, 0x00, // Lock time 693 } 694 695 var tx MsgTx 696 tx.Deserialize(bytes.NewReader(buf)) 697 698 b.ReportAllocs() 699 b.ResetTimer() 700 701 for i := 0; i < b.N; i++ { 702 tx.Serialize(io.Discard) 703 } 704 } 705 706 // BenchmarkSerializeTxLarge performs a benchmark on how long it takes to 707 // serialize a transaction. 708 func BenchmarkSerializeTxLarge(b *testing.B) { 709 // tx bb41a757f405890fb0f5856228e23b715702d714d59bf2b1feb70d8b2b4e3e08 710 // from the main block chain. 711 fi, err := os.Open("testdata/megatx.bin.bz2") 712 if err != nil { 713 b.Fatalf("Failed to read transaction data: %v", err) 714 } 715 defer fi.Close() 716 buf, err := ioutil.ReadAll(bzip2.NewReader(fi)) 717 if err != nil { 718 b.Fatalf("Failed to read transaction data: %v", err) 719 } 720 721 var tx MsgTx 722 tx.Deserialize(bytes.NewReader(buf)) 723 724 b.ReportAllocs() 725 b.ResetTimer() 726 727 for i := 0; i < b.N; i++ { 728 tx.Serialize(io.Discard) 729 } 730 } 731 732 // BenchmarkReadBlockHeader performs a benchmark on how long it takes to 733 // deserialize a block header. 734 func BenchmarkReadBlockHeader(b *testing.B) { 735 b.ReportAllocs() 736 737 buf := []byte{ 738 0x01, 0x00, 0x00, 0x00, // Version 1 739 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 740 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 741 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 742 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock 743 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, 744 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 745 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 746 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot 747 0x29, 0xab, 0x5f, 0x49, // Timestamp 748 0xff, 0xff, 0x00, 0x1d, // Bits 749 0xf3, 0xe0, 0x01, 0x00, // Nonce 750 0x00, // TxnCount Varint 751 } 752 r := bytes.NewReader(buf) 753 var header BlockHeader 754 for i := 0; i < b.N; i++ { 755 r.Seek(0, 0) 756 readBlockHeader(r, 0, &header) 757 } 758 } 759 760 // BenchmarkReadBlockHeaderBuf performs a benchmark on how long it takes to 761 // deserialize a block header. 762 func BenchmarkReadBlockHeaderBuf(b *testing.B) { 763 b.ReportAllocs() 764 765 buffer := binarySerializer.Borrow() 766 buf := []byte{ 767 0x01, 0x00, 0x00, 0x00, // Version 1 768 0x6f, 0xe2, 0x8c, 0x0a, 0xb6, 0xf1, 0xb3, 0x72, 769 0xc1, 0xa6, 0xa2, 0x46, 0xae, 0x63, 0xf7, 0x4f, 770 0x93, 0x1e, 0x83, 0x65, 0xe1, 0x5a, 0x08, 0x9c, 771 0x68, 0xd6, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, // PrevBlock 772 0x3b, 0xa3, 0xed, 0xfd, 0x7a, 0x7b, 0x12, 0xb2, 773 0x7a, 0xc7, 0x2c, 0x3e, 0x67, 0x76, 0x8f, 0x61, 774 0x7f, 0xc8, 0x1b, 0xc3, 0x88, 0x8a, 0x51, 0x32, 775 0x3a, 0x9f, 0xb8, 0xaa, 0x4b, 0x1e, 0x5e, 0x4a, // MerkleRoot 776 0x29, 0xab, 0x5f, 0x49, // Timestamp 777 0xff, 0xff, 0x00, 0x1d, // Bits 778 0xf3, 0xe0, 0x01, 0x00, // Nonce 779 0x00, // TxnCount Varint 780 } 781 r := bytes.NewReader(buf) 782 var header BlockHeader 783 for i := 0; i < b.N; i++ { 784 r.Seek(0, 0) 785 readBlockHeaderBuf(r, 0, &header, buffer) 786 } 787 binarySerializer.Return(buffer) 788 } 789 790 // BenchmarkWriteBlockHeader performs a benchmark on how long it takes to 791 // serialize a block header. 792 func BenchmarkWriteBlockHeader(b *testing.B) { 793 b.ReportAllocs() 794 795 header := blockOne.Header 796 for i := 0; i < b.N; i++ { 797 writeBlockHeader(io.Discard, 0, &header) 798 } 799 } 800 801 // BenchmarkWriteBlockHeaderBuf performs a benchmark on how long it takes to 802 // serialize a block header. 803 func BenchmarkWriteBlockHeaderBuf(b *testing.B) { 804 b.ReportAllocs() 805 806 buf := binarySerializer.Borrow() 807 header := blockOne.Header 808 for i := 0; i < b.N; i++ { 809 writeBlockHeaderBuf(io.Discard, 0, &header, buf) 810 } 811 binarySerializer.Return(buf) 812 } 813 814 // BenchmarkDecodeGetHeaders performs a benchmark on how long it takes to 815 // decode a getheaders message with the maximum number of block locator hashes. 816 func BenchmarkDecodeGetHeaders(b *testing.B) { 817 b.ReportAllocs() 818 819 // Create a message with the maximum number of block locators. 820 pver := ProtocolVersion 821 var m MsgGetHeaders 822 for i := 0; i < MaxBlockLocatorsPerMsg; i++ { 823 hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i)) 824 if err != nil { 825 b.Fatalf("NewHashFromStr: unexpected error: %v", err) 826 } 827 m.AddBlockLocatorHash(hash) 828 } 829 830 // Serialize it so the bytes are available to test the decode below. 831 var bb bytes.Buffer 832 if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { 833 b.Fatalf("MsgGetHeaders.BtcEncode: unexpected error: %v", err) 834 } 835 buf := bb.Bytes() 836 837 r := bytes.NewReader(buf) 838 var msg MsgGetHeaders 839 b.ResetTimer() 840 for i := 0; i < b.N; i++ { 841 r.Seek(0, 0) 842 msg.BtcDecode(r, pver, LatestEncoding) 843 } 844 } 845 846 // BenchmarkDecodeHeaders performs a benchmark on how long it takes to 847 // decode a headers message with the maximum number of headers. 848 func BenchmarkDecodeHeaders(b *testing.B) { 849 b.ReportAllocs() 850 851 // Create a message with the maximum number of headers. 852 pver := ProtocolVersion 853 var m MsgHeaders 854 for i := 0; i < MaxBlockHeadersPerMsg; i++ { 855 hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i)) 856 if err != nil { 857 b.Fatalf("NewHashFromStr: unexpected error: %v", err) 858 } 859 m.AddBlockHeader(NewBlockHeader(1, hash, hash, 0, uint32(i))) 860 } 861 862 // Serialize it so the bytes are available to test the decode below. 863 var bb bytes.Buffer 864 if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { 865 b.Fatalf("MsgHeaders.BtcEncode: unexpected error: %v", err) 866 } 867 buf := bb.Bytes() 868 869 r := bytes.NewReader(buf) 870 var msg MsgHeaders 871 b.ResetTimer() 872 for i := 0; i < b.N; i++ { 873 r.Seek(0, 0) 874 msg.BtcDecode(r, pver, LatestEncoding) 875 } 876 } 877 878 // BenchmarkDecodeGetBlocks performs a benchmark on how long it takes to 879 // decode a getblocks message with the maximum number of block locator hashes. 880 func BenchmarkDecodeGetBlocks(b *testing.B) { 881 b.ReportAllocs() 882 883 // Create a message with the maximum number of block locators. 884 pver := ProtocolVersion 885 var m MsgGetBlocks 886 for i := 0; i < MaxBlockLocatorsPerMsg; i++ { 887 hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i)) 888 if err != nil { 889 b.Fatalf("NewHashFromStr: unexpected error: %v", err) 890 } 891 m.AddBlockLocatorHash(hash) 892 } 893 894 // Serialize it so the bytes are available to test the decode below. 895 var bb bytes.Buffer 896 if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { 897 b.Fatalf("MsgGetBlocks.BtcEncode: unexpected error: %v", err) 898 } 899 buf := bb.Bytes() 900 901 r := bytes.NewReader(buf) 902 var msg MsgGetBlocks 903 b.ResetTimer() 904 for i := 0; i < b.N; i++ { 905 r.Seek(0, 0) 906 msg.BtcDecode(r, pver, LatestEncoding) 907 } 908 } 909 910 // BenchmarkDecodeAddr performs a benchmark on how long it takes to decode an 911 // addr message with the maximum number of addresses. 912 func BenchmarkDecodeAddr(b *testing.B) { 913 b.ReportAllocs() 914 915 // Create a message with the maximum number of addresses. 916 pver := ProtocolVersion 917 ip := net.ParseIP("127.0.0.1") 918 ma := NewMsgAddr() 919 for port := uint16(0); port < MaxAddrPerMsg; port++ { 920 ma.AddAddress(NewNetAddressIPPort(ip, port, SFNodeNetwork)) 921 } 922 923 // Serialize it so the bytes are available to test the decode below. 924 var bb bytes.Buffer 925 if err := ma.BtcEncode(&bb, pver, LatestEncoding); err != nil { 926 b.Fatalf("MsgAddr.BtcEncode: unexpected error: %v", err) 927 } 928 buf := bb.Bytes() 929 930 r := bytes.NewReader(buf) 931 var msg MsgAddr 932 b.ResetTimer() 933 for i := 0; i < b.N; i++ { 934 r.Seek(0, 0) 935 msg.BtcDecode(r, pver, LatestEncoding) 936 } 937 } 938 939 // BenchmarkDecodeInv performs a benchmark on how long it takes to decode an inv 940 // message with the maximum number of entries. 941 func BenchmarkDecodeInv(b *testing.B) { 942 // Create a message with the maximum number of entries. 943 pver := ProtocolVersion 944 var m MsgInv 945 for i := 0; i < MaxInvPerMsg; i++ { 946 hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i)) 947 if err != nil { 948 b.Fatalf("NewHashFromStr: unexpected error: %v", err) 949 } 950 m.AddInvVect(NewInvVect(InvTypeBlock, hash)) 951 } 952 953 // Serialize it so the bytes are available to test the decode below. 954 var bb bytes.Buffer 955 if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { 956 b.Fatalf("MsgInv.BtcEncode: unexpected error: %v", err) 957 } 958 buf := bb.Bytes() 959 960 b.ReportAllocs() 961 b.ResetTimer() 962 963 r := bytes.NewReader(buf) 964 var msg MsgInv 965 b.ResetTimer() 966 for i := 0; i < b.N; i++ { 967 r.Seek(0, 0) 968 msg.BtcDecode(r, pver, LatestEncoding) 969 } 970 } 971 972 // BenchmarkDecodeNotFound performs a benchmark on how long it takes to decode 973 // a notfound message with the maximum number of entries. 974 func BenchmarkDecodeNotFound(b *testing.B) { 975 b.ReportAllocs() 976 977 // Create a message with the maximum number of entries. 978 pver := ProtocolVersion 979 var m MsgNotFound 980 for i := 0; i < MaxInvPerMsg; i++ { 981 hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i)) 982 if err != nil { 983 b.Fatalf("NewHashFromStr: unexpected error: %v", err) 984 } 985 m.AddInvVect(NewInvVect(InvTypeBlock, hash)) 986 } 987 988 // Serialize it so the bytes are available to test the decode below. 989 var bb bytes.Buffer 990 if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { 991 b.Fatalf("MsgNotFound.BtcEncode: unexpected error: %v", err) 992 } 993 buf := bb.Bytes() 994 995 r := bytes.NewReader(buf) 996 var msg MsgNotFound 997 b.ResetTimer() 998 for i := 0; i < b.N; i++ { 999 r.Seek(0, 0) 1000 msg.BtcDecode(r, pver, LatestEncoding) 1001 } 1002 } 1003 1004 // BenchmarkDecodeMerkleBlock performs a benchmark on how long it takes to 1005 // decode a reasonably sized merkleblock message. 1006 func BenchmarkDecodeMerkleBlock(b *testing.B) { 1007 b.ReportAllocs() 1008 1009 // Create a message with random data. 1010 pver := ProtocolVersion 1011 var m MsgMerkleBlock 1012 hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", 10000)) 1013 if err != nil { 1014 b.Fatalf("NewHashFromStr: unexpected error: %v", err) 1015 } 1016 m.Header = *NewBlockHeader(1, hash, hash, 0, uint32(10000)) 1017 for i := 0; i < 105; i++ { 1018 hash, err := chainhash.NewHashFromStr(fmt.Sprintf("%x", i)) 1019 if err != nil { 1020 b.Fatalf("NewHashFromStr: unexpected error: %v", err) 1021 } 1022 m.AddTxHash(hash) 1023 if i%8 == 0 { 1024 m.Flags = append(m.Flags, uint8(i)) 1025 } 1026 } 1027 1028 // Serialize it so the bytes are available to test the decode below. 1029 var bb bytes.Buffer 1030 if err := m.BtcEncode(&bb, pver, LatestEncoding); err != nil { 1031 b.Fatalf("MsgMerkleBlock.BtcEncode: unexpected error: %v", err) 1032 } 1033 buf := bb.Bytes() 1034 1035 r := bytes.NewReader(buf) 1036 var msg MsgMerkleBlock 1037 b.ResetTimer() 1038 for i := 0; i < b.N; i++ { 1039 r.Seek(0, 0) 1040 msg.BtcDecode(r, pver, LatestEncoding) 1041 } 1042 } 1043 1044 // BenchmarkTxHash performs a benchmark on how long it takes to hash a 1045 // transaction. 1046 func BenchmarkTxHash(b *testing.B) { 1047 b.ReportAllocs() 1048 1049 for i := 0; i < b.N; i++ { 1050 genesisCoinbaseTx.TxHash() 1051 } 1052 } 1053 1054 // BenchmarkDoubleHashB performs a benchmark on how long it takes to perform a 1055 // double hash returning a byte slice. 1056 func BenchmarkDoubleHashB(b *testing.B) { 1057 b.ReportAllocs() 1058 1059 var buf bytes.Buffer 1060 if err := genesisCoinbaseTx.Serialize(&buf); err != nil { 1061 b.Errorf("Serialize: unexpected error: %v", err) 1062 return 1063 } 1064 txBytes := buf.Bytes() 1065 1066 b.ResetTimer() 1067 for i := 0; i < b.N; i++ { 1068 _ = chainhash.DoubleHashB(txBytes) 1069 } 1070 } 1071 1072 // BenchmarkDoubleHashH performs a benchmark on how long it takes to perform 1073 // a double hash returning a chainhash.Hash. 1074 func BenchmarkDoubleHashH(b *testing.B) { 1075 b.ReportAllocs() 1076 1077 var buf bytes.Buffer 1078 if err := genesisCoinbaseTx.Serialize(&buf); err != nil { 1079 b.Errorf("Serialize: unexpected error: %v", err) 1080 return 1081 } 1082 txBytes := buf.Bytes() 1083 1084 b.ResetTimer() 1085 for i := 0; i < b.N; i++ { 1086 _ = chainhash.DoubleHashH(txBytes) 1087 } 1088 }