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  }