github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/wire/common.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 "crypto/rand" 10 "encoding/binary" 11 "fmt" 12 "io" 13 "math" 14 "time" 15 16 "github.com/btcsuite/fastsha256" 17 ) 18 19 const ( 20 // MaxVarIntPayload is the maximum payload size for a variable length integer. 21 MaxVarIntPayload = 9 22 23 // binaryFreeListMaxItems is the number of buffers to keep in the free 24 // list to use for binary serialization and deserialization. 25 binaryFreeListMaxItems = 1024 26 ) 27 28 var ( 29 // littleEndian is a convenience variable since binary.LittleEndian is 30 // quite long. 31 littleEndian = binary.LittleEndian 32 33 // bigEndian is a convenience variable since binary.BigEndian is quite 34 // long. 35 bigEndian = binary.BigEndian 36 ) 37 38 // binaryFreeList defines a concurrent safe free list of byte slices (up to the 39 // maximum number defined by the binaryFreeListMaxItems constant) that have a 40 // cap of 8 (thus it supports up to a uint64). It is used to provide temporary 41 // buffers for serializing and deserializing primitive numbers to and from their 42 // binary encoding in order to greatly reduce the number of allocations 43 // required. 44 // 45 // For convenience, functions are provided for each of the primitive unsigned 46 // integers that automatically obtain a buffer from the free list, perform the 47 // necessary binary conversion, read from or write to the given io.Reader or 48 // io.Writer, and return the buffer to the free list. 49 type binaryFreeList chan []byte 50 51 // Borrow returns a byte slice from the free list with a length of 8. A new 52 // buffer is allocated if there are not any available on the free list. 53 func (l binaryFreeList) Borrow() []byte { 54 var buf []byte 55 select { 56 case buf = <-l: 57 default: 58 buf = make([]byte, 8) 59 } 60 return buf[:8] 61 } 62 63 // Return puts the provided byte slice back on the free list. The buffer MUST 64 // have been obtained via the Borrow function and therefore have a cap of 8. 65 func (l binaryFreeList) Return(buf []byte) { 66 select { 67 case l <- buf: 68 default: 69 // Let it go to the garbage collector. 70 } 71 } 72 73 // Uint8 reads a single byte from the provided reader using a buffer from the 74 // free list and returns it as a uint8. 75 func (l binaryFreeList) Uint8(r io.Reader) (uint8, error) { 76 buf := l.Borrow()[:1] 77 if _, err := io.ReadFull(r, buf); err != nil { 78 l.Return(buf) 79 return 0, err 80 } 81 rv := buf[0] 82 l.Return(buf) 83 return rv, nil 84 } 85 86 // Uint16 reads two bytes from the provided reader using a buffer from the 87 // free list, converts it to a number using the provided byte order, and returns 88 // the resulting uint16. 89 func (l binaryFreeList) Uint16(r io.Reader, byteOrder binary.ByteOrder) (uint16, error) { 90 buf := l.Borrow()[:2] 91 if _, err := io.ReadFull(r, buf); err != nil { 92 l.Return(buf) 93 return 0, err 94 } 95 rv := byteOrder.Uint16(buf) 96 l.Return(buf) 97 return rv, nil 98 } 99 100 // Uint32 reads four bytes from the provided reader using a buffer from the 101 // free list, converts it to a number using the provided byte order, and returns 102 // the resulting uint32. 103 func (l binaryFreeList) Uint32(r io.Reader, byteOrder binary.ByteOrder) (uint32, error) { 104 buf := l.Borrow()[:4] 105 if _, err := io.ReadFull(r, buf); err != nil { 106 l.Return(buf) 107 return 0, err 108 } 109 rv := byteOrder.Uint32(buf) 110 l.Return(buf) 111 return rv, nil 112 } 113 114 // Uint64 reads eight bytes from the provided reader using a buffer from the 115 // free list, converts it to a number using the provided byte order, and returns 116 // the resulting uint64. 117 func (l binaryFreeList) Uint64(r io.Reader, byteOrder binary.ByteOrder) (uint64, error) { 118 buf := l.Borrow()[:8] 119 if _, err := io.ReadFull(r, buf); err != nil { 120 l.Return(buf) 121 return 0, err 122 } 123 rv := byteOrder.Uint64(buf) 124 l.Return(buf) 125 return rv, nil 126 } 127 128 // PutUint8 copies the provided uint8 into a buffer from the free list and 129 // writes the resulting byte to the given writer. 130 func (l binaryFreeList) PutUint8(w io.Writer, val uint8) error { 131 buf := l.Borrow()[:1] 132 buf[0] = val 133 _, err := w.Write(buf) 134 l.Return(buf) 135 return err 136 } 137 138 // PutUint16 serializes the provided uint16 using the given byte order into a 139 // buffer from the free list and writes the resulting two bytes to the given 140 // writer. 141 func (l binaryFreeList) PutUint16(w io.Writer, byteOrder binary.ByteOrder, val uint16) error { 142 buf := l.Borrow()[:2] 143 byteOrder.PutUint16(buf, val) 144 _, err := w.Write(buf) 145 l.Return(buf) 146 return err 147 } 148 149 // PutUint32 serializes the provided uint32 using the given byte order into a 150 // buffer from the free list and writes the resulting four bytes to the given 151 // writer. 152 func (l binaryFreeList) PutUint32(w io.Writer, byteOrder binary.ByteOrder, val uint32) error { 153 buf := l.Borrow()[:4] 154 byteOrder.PutUint32(buf, val) 155 _, err := w.Write(buf) 156 l.Return(buf) 157 return err 158 } 159 160 // PutUint64 serializes the provided uint64 using the given byte order into a 161 // buffer from the free list and writes the resulting eight bytes to the given 162 // writer. 163 func (l binaryFreeList) PutUint64(w io.Writer, byteOrder binary.ByteOrder, val uint64) error { 164 buf := l.Borrow()[:8] 165 byteOrder.PutUint64(buf, val) 166 _, err := w.Write(buf) 167 l.Return(buf) 168 return err 169 } 170 171 // binarySerializer provides a free list of buffers to use for serializing and 172 // deserializing primitive integer values to and from io.Readers and io.Writers. 173 var binarySerializer binaryFreeList = make(chan []byte, binaryFreeListMaxItems) 174 175 // errNonCanonicalVarInt is the common format string used for non-canonically 176 // encoded variable length integer errors. 177 var errNonCanonicalVarInt = "non-canonical varint %x - discriminant %x must " + 178 "encode a value greater than %x" 179 180 // uint32Time represents a unix timestamp encoded with a uint32. It is used as 181 // a way to signal the readElement function how to decode a timestamp into a Go 182 // time.Time since it is otherwise ambiguous. 183 type uint32Time time.Time 184 185 // int64Time represents a unix timestamp encoded with an int64. It is used as 186 // a way to signal the readElement function how to decode a timestamp into a Go 187 // time.Time since it is otherwise ambiguous. 188 type int64Time time.Time 189 190 // readElement reads the next sequence of bytes from r using little endian 191 // depending on the concrete type of element pointed to. 192 func readElement(r io.Reader, element interface{}) error { 193 // Attempt to read the element based on the concrete type via fast 194 // type assertions first. 195 switch e := element.(type) { 196 case *int32: 197 rv, err := binarySerializer.Uint32(r, littleEndian) 198 if err != nil { 199 return err 200 } 201 *e = int32(rv) 202 return nil 203 204 case *uint32: 205 rv, err := binarySerializer.Uint32(r, littleEndian) 206 if err != nil { 207 return err 208 } 209 *e = rv 210 return nil 211 212 case *int64: 213 rv, err := binarySerializer.Uint64(r, littleEndian) 214 if err != nil { 215 return err 216 } 217 *e = int64(rv) 218 return nil 219 220 case *uint64: 221 rv, err := binarySerializer.Uint64(r, littleEndian) 222 if err != nil { 223 return err 224 } 225 *e = rv 226 return nil 227 228 case *bool: 229 rv, err := binarySerializer.Uint8(r) 230 if err != nil { 231 return err 232 } 233 if rv == 0x00 { 234 *e = false 235 } else { 236 *e = true 237 } 238 return nil 239 240 // Unix timestamp encoded as a uint32. 241 case *uint32Time: 242 rv, err := binarySerializer.Uint32(r, binary.LittleEndian) 243 if err != nil { 244 return err 245 } 246 *e = uint32Time(time.Unix(int64(rv), 0)) 247 return nil 248 249 // Unix timestamp encoded as an int64. 250 case *int64Time: 251 rv, err := binarySerializer.Uint64(r, binary.LittleEndian) 252 if err != nil { 253 return err 254 } 255 *e = int64Time(time.Unix(int64(rv), 0)) 256 return nil 257 258 // Message header checksum. 259 case *[4]byte: 260 _, err := io.ReadFull(r, e[:]) 261 if err != nil { 262 return err 263 } 264 return nil 265 266 // Message header command. 267 case *[CommandSize]uint8: 268 _, err := io.ReadFull(r, e[:]) 269 if err != nil { 270 return err 271 } 272 return nil 273 274 // IP address. 275 case *[16]byte: 276 _, err := io.ReadFull(r, e[:]) 277 if err != nil { 278 return err 279 } 280 return nil 281 282 case *ShaHash: 283 _, err := io.ReadFull(r, e[:]) 284 if err != nil { 285 return err 286 } 287 return nil 288 289 case *ServiceFlag: 290 rv, err := binarySerializer.Uint64(r, littleEndian) 291 if err != nil { 292 return err 293 } 294 *e = ServiceFlag(rv) 295 return nil 296 297 case *InvType: 298 rv, err := binarySerializer.Uint32(r, littleEndian) 299 if err != nil { 300 return err 301 } 302 *e = InvType(rv) 303 return nil 304 305 case *BitcoinNet: 306 rv, err := binarySerializer.Uint32(r, littleEndian) 307 if err != nil { 308 return err 309 } 310 *e = BitcoinNet(rv) 311 return nil 312 313 case *BloomUpdateType: 314 rv, err := binarySerializer.Uint8(r) 315 if err != nil { 316 return err 317 } 318 *e = BloomUpdateType(rv) 319 return nil 320 321 case *RejectCode: 322 rv, err := binarySerializer.Uint8(r) 323 if err != nil { 324 return err 325 } 326 *e = RejectCode(rv) 327 return nil 328 } 329 330 // Fall back to the slower binary.Read if a fast path was not available 331 // above. 332 return binary.Read(r, littleEndian, element) 333 } 334 335 // readElements reads multiple items from r. It is equivalent to multiple 336 // calls to readElement. 337 func readElements(r io.Reader, elements ...interface{}) error { 338 for _, element := range elements { 339 err := readElement(r, element) 340 if err != nil { 341 return err 342 } 343 } 344 return nil 345 } 346 347 // writeElement writes the little endian representation of element to w. 348 func writeElement(w io.Writer, element interface{}) error { 349 // Attempt to write the element based on the concrete type via fast 350 // type assertions first. 351 switch e := element.(type) { 352 case int32: 353 err := binarySerializer.PutUint32(w, littleEndian, uint32(e)) 354 if err != nil { 355 return err 356 } 357 return nil 358 359 case uint32: 360 err := binarySerializer.PutUint32(w, littleEndian, e) 361 if err != nil { 362 return err 363 } 364 return nil 365 366 case int64: 367 err := binarySerializer.PutUint64(w, littleEndian, uint64(e)) 368 if err != nil { 369 return err 370 } 371 return nil 372 373 case uint64: 374 err := binarySerializer.PutUint64(w, littleEndian, e) 375 if err != nil { 376 return err 377 } 378 return nil 379 380 case bool: 381 var err error 382 if e == true { 383 err = binarySerializer.PutUint8(w, 0x01) 384 } else { 385 err = binarySerializer.PutUint8(w, 0x00) 386 } 387 if err != nil { 388 return err 389 } 390 return nil 391 392 // Message header checksum. 393 case [4]byte: 394 _, err := w.Write(e[:]) 395 if err != nil { 396 return err 397 } 398 return nil 399 400 // Message header command. 401 case [CommandSize]uint8: 402 _, err := w.Write(e[:]) 403 if err != nil { 404 return err 405 } 406 return nil 407 408 // IP address. 409 case [16]byte: 410 _, err := w.Write(e[:]) 411 if err != nil { 412 return err 413 } 414 return nil 415 416 case *ShaHash: 417 _, err := w.Write(e[:]) 418 if err != nil { 419 return err 420 } 421 return nil 422 423 case ServiceFlag: 424 err := binarySerializer.PutUint64(w, littleEndian, uint64(e)) 425 if err != nil { 426 return err 427 } 428 return nil 429 430 case InvType: 431 err := binarySerializer.PutUint32(w, littleEndian, uint32(e)) 432 if err != nil { 433 return err 434 } 435 return nil 436 437 case BitcoinNet: 438 err := binarySerializer.PutUint32(w, littleEndian, uint32(e)) 439 if err != nil { 440 return err 441 } 442 return nil 443 444 case BloomUpdateType: 445 err := binarySerializer.PutUint8(w, uint8(e)) 446 if err != nil { 447 return err 448 } 449 return nil 450 451 case RejectCode: 452 err := binarySerializer.PutUint8(w, uint8(e)) 453 if err != nil { 454 return err 455 } 456 return nil 457 } 458 459 // Fall back to the slower binary.Write if a fast path was not available 460 // above. 461 return binary.Write(w, littleEndian, element) 462 } 463 464 // writeElements writes multiple items to w. It is equivalent to multiple 465 // calls to writeElement. 466 func writeElements(w io.Writer, elements ...interface{}) error { 467 for _, element := range elements { 468 err := writeElement(w, element) 469 if err != nil { 470 return err 471 } 472 } 473 return nil 474 } 475 476 // ReadVarInt reads a variable length integer from r and returns it as a uint64. 477 func ReadVarInt(r io.Reader, pver uint32) (uint64, error) { 478 discriminant, err := binarySerializer.Uint8(r) 479 if err != nil { 480 return 0, err 481 } 482 483 var rv uint64 484 switch discriminant { 485 case 0xff: 486 sv, err := binarySerializer.Uint64(r, littleEndian) 487 if err != nil { 488 return 0, err 489 } 490 rv = sv 491 492 // The encoding is not canonical if the value could have been 493 // encoded using fewer bytes. 494 min := uint64(0x100000000) 495 if rv < min { 496 return 0, messageError("ReadVarInt", fmt.Sprintf( 497 errNonCanonicalVarInt, rv, discriminant, min)) 498 } 499 500 case 0xfe: 501 sv, err := binarySerializer.Uint32(r, littleEndian) 502 if err != nil { 503 return 0, err 504 } 505 rv = uint64(sv) 506 507 // The encoding is not canonical if the value could have been 508 // encoded using fewer bytes. 509 min := uint64(0x10000) 510 if rv < min { 511 return 0, messageError("ReadVarInt", fmt.Sprintf( 512 errNonCanonicalVarInt, rv, discriminant, min)) 513 } 514 515 case 0xfd: 516 sv, err := binarySerializer.Uint16(r, littleEndian) 517 if err != nil { 518 return 0, err 519 } 520 rv = uint64(sv) 521 522 // The encoding is not canonical if the value could have been 523 // encoded using fewer bytes. 524 min := uint64(0xfd) 525 if rv < min { 526 return 0, messageError("ReadVarInt", fmt.Sprintf( 527 errNonCanonicalVarInt, rv, discriminant, min)) 528 } 529 530 default: 531 rv = uint64(discriminant) 532 } 533 534 return rv, nil 535 } 536 537 // WriteVarInt serializes val to w using a variable number of bytes depending 538 // on its value. 539 func WriteVarInt(w io.Writer, pver uint32, val uint64) error { 540 if val < 0xfd { 541 return binarySerializer.PutUint8(w, uint8(val)) 542 } 543 544 if val <= math.MaxUint16 { 545 err := binarySerializer.PutUint8(w, 0xfd) 546 if err != nil { 547 return err 548 } 549 return binarySerializer.PutUint16(w, littleEndian, uint16(val)) 550 } 551 552 if val <= math.MaxUint32 { 553 err := binarySerializer.PutUint8(w, 0xfe) 554 if err != nil { 555 return err 556 } 557 return binarySerializer.PutUint32(w, littleEndian, uint32(val)) 558 } 559 560 err := binarySerializer.PutUint8(w, 0xff) 561 if err != nil { 562 return err 563 } 564 return binarySerializer.PutUint64(w, littleEndian, val) 565 } 566 567 // VarIntSerializeSize returns the number of bytes it would take to serialize 568 // val as a variable length integer. 569 func VarIntSerializeSize(val uint64) int { 570 // The value is small enough to be represented by itself, so it's 571 // just 1 byte. 572 if val < 0xfd { 573 return 1 574 } 575 576 // Discriminant 1 byte plus 2 bytes for the uint16. 577 if val <= math.MaxUint16 { 578 return 3 579 } 580 581 // Discriminant 1 byte plus 4 bytes for the uint32. 582 if val <= math.MaxUint32 { 583 return 5 584 } 585 586 // Discriminant 1 byte plus 8 bytes for the uint64. 587 return 9 588 } 589 590 // ReadVarString reads a variable length string from r and returns it as a Go 591 // string. A variable length string is encoded as a variable length integer 592 // containing the length of the string followed by the bytes that represent the 593 // string itself. An error is returned if the length is greater than the 594 // maximum block payload size since it helps protect against memory exhaustion 595 // attacks and forced panics through malformed messages. 596 func ReadVarString(r io.Reader, pver uint32) (string, error) { 597 count, err := ReadVarInt(r, pver) 598 if err != nil { 599 return "", err 600 } 601 602 // Prevent variable length strings that are larger than the maximum 603 // message size. It would be possible to cause memory exhaustion and 604 // panics without a sane upper bound on this count. 605 if count > MaxMessagePayload { 606 str := fmt.Sprintf("variable length string is too long "+ 607 "[count %d, max %d]", count, MaxMessagePayload) 608 return "", messageError("ReadVarString", str) 609 } 610 611 buf := make([]byte, count) 612 _, err = io.ReadFull(r, buf) 613 if err != nil { 614 return "", err 615 } 616 return string(buf), nil 617 } 618 619 // WriteVarString serializes str to w as a variable length integer containing 620 // the length of the string followed by the bytes that represent the string 621 // itself. 622 func WriteVarString(w io.Writer, pver uint32, str string) error { 623 err := WriteVarInt(w, pver, uint64(len(str))) 624 if err != nil { 625 return err 626 } 627 _, err = w.Write([]byte(str)) 628 if err != nil { 629 return err 630 } 631 return nil 632 } 633 634 // ReadVarBytes reads a variable length byte array. A byte array is encoded 635 // as a varInt containing the length of the array followed by the bytes 636 // themselves. An error is returned if the length is greater than the 637 // passed maxAllowed parameter which helps protect against memory exhuastion 638 // attacks and forced panics thorugh malformed messages. The fieldName 639 // parameter is only used for the error message so it provides more context in 640 // the error. 641 func ReadVarBytes(r io.Reader, pver uint32, maxAllowed uint32, 642 fieldName string) ([]byte, error) { 643 644 count, err := ReadVarInt(r, pver) 645 if err != nil { 646 return nil, err 647 } 648 649 // Prevent byte array larger than the max message size. It would 650 // be possible to cause memory exhaustion and panics without a sane 651 // upper bound on this count. 652 if count > uint64(maxAllowed) { 653 str := fmt.Sprintf("%s is larger than the max allowed size "+ 654 "[count %d, max %d]", fieldName, count, maxAllowed) 655 return nil, messageError("ReadVarBytes", str) 656 } 657 658 b := make([]byte, count) 659 _, err = io.ReadFull(r, b) 660 if err != nil { 661 return nil, err 662 } 663 return b, nil 664 } 665 666 // WriteVarBytes serializes a variable length byte array to w as a varInt 667 // containing the number of bytes, followed by the bytes themselves. 668 func WriteVarBytes(w io.Writer, pver uint32, bytes []byte) error { 669 slen := uint64(len(bytes)) 670 err := WriteVarInt(w, pver, slen) 671 if err != nil { 672 return err 673 } 674 675 _, err = w.Write(bytes) 676 if err != nil { 677 return err 678 } 679 return nil 680 } 681 682 // randomUint64 returns a cryptographically random uint64 value. This 683 // unexported version takes a reader primarily to ensure the error paths 684 // can be properly tested by passing a fake reader in the tests. 685 func randomUint64(r io.Reader) (uint64, error) { 686 rv, err := binarySerializer.Uint64(r, bigEndian) 687 if err != nil { 688 return 0, err 689 } 690 return rv, nil 691 } 692 693 // RandomUint64 returns a cryptographically random uint64 value. 694 func RandomUint64() (uint64, error) { 695 return randomUint64(rand.Reader) 696 } 697 698 // DoubleSha256 calculates sha256(sha256(b)) and returns the resulting bytes. 699 func DoubleSha256(b []byte) []byte { 700 first := fastsha256.Sum256(b) 701 second := fastsha256.Sum256(first[:]) 702 return second[:] 703 } 704 705 // DoubleSha256SH calculates sha256(sha256(b)) and returns the resulting bytes 706 // as a ShaHash. 707 func DoubleSha256SH(b []byte) ShaHash { 708 first := fastsha256.Sum256(b) 709 return ShaHash(fastsha256.Sum256(first[:])) 710 }