github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/wire/msgtx.go (about)

     1  // Copyright (c) 2013-2015 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package wire
     7  
     8  import (
     9  	"bytes"
    10  	"fmt"
    11  	"io"
    12  	"strconv"
    13  )
    14  
    15  const (
    16  	// TxVersion is the current latest supported transaction version.
    17  	TxVersion = 1
    18  
    19  	// MaxTxInSequenceNum is the maximum sequence number the sequence field
    20  	// of a transaction input can be.
    21  	MaxTxInSequenceNum uint32 = 0xffffffff
    22  
    23  	// MaxPrevOutIndex is the maximum index the index field of a previous
    24  	// outpoint can be.
    25  	MaxPrevOutIndex uint32 = 0xffffffff
    26  )
    27  
    28  const (
    29  	// defaultTxInOutAlloc is the default size used for the backing array
    30  	// for transaction inputs and outputs.  The array will dynamically grow
    31  	// as needed, but this figure is intended to provide enough space for
    32  	// the number of inputs and outputs in a typical transaction without
    33  	// needing to grow the backing array multiple times.
    34  	defaultTxInOutAlloc = 15
    35  
    36  	// minTxInPayload is the minimum payload size for a transaction input.
    37  	// PreviousOutPoint.Hash + PreviousOutPoint.Index 4 bytes + Varint for
    38  	// SignatureScript length 1 byte + Sequence 4 bytes.
    39  	minTxInPayload = 9 + HashSize
    40  
    41  	// maxTxInPerMessage is the maximum number of transactions inputs that
    42  	// a transaction which fits into a message could possibly have.
    43  	maxTxInPerMessage = (MaxMessagePayload / minTxInPayload) + 1
    44  
    45  	// minTxOutPayload is the minimum payload size for a transaction output.
    46  	// Value 8 bytes + Varint for PkScript length 1 byte.
    47  	minTxOutPayload = 9
    48  
    49  	// maxTxOutPerMessage is the maximum number of transactions outputs that
    50  	// a transaction which fits into a message could possibly have.
    51  	maxTxOutPerMessage = (MaxMessagePayload / minTxOutPayload) + 1
    52  
    53  	// minTxPayload is the minimum payload size for a transaction.  Note
    54  	// that any realistically usable transaction must have at least one
    55  	// input or output, but that is a rule enforced at a higher layer, so
    56  	// it is intentionally not included here.
    57  	// Version 4 bytes + Varint number of transaction inputs 1 byte + Varint
    58  	// number of transaction outputs 1 byte + LockTime 4 bytes + min input
    59  	// payload + min output payload.
    60  	minTxPayload = 10
    61  
    62  	// freeListMaxScriptSize is the size of each buffer in the free list
    63  	// that	is used for deserializing scripts from the wire before they are
    64  	// concatenated into a single contiguous buffers.  This value was chosen
    65  	// because it is slightly more than twice the size of the vast majority
    66  	// of all "standard" scripts.  Larger scripts are still deserialized
    67  	// properly as the free list will simply be bypassed for them.
    68  	freeListMaxScriptSize = 512
    69  
    70  	// freeListMaxItems is the number of buffers to keep in the free list
    71  	// to use for script deserialization.  This value allows up to 100
    72  	// scripts per transaction being simultaneously deserialized by 125
    73  	// peers.  Thus, the peak usage of the free list is 12,500 * 512 =
    74  	// 6,400,000 bytes.
    75  	freeListMaxItems = 12500
    76  )
    77  
    78  // scriptFreeList defines a free list of byte slices (up to the maximum number
    79  // defined by the freeListMaxItems constant) that have a cap according to the
    80  // freeListMaxScriptSize constant.  It is used to provide temporary buffers for
    81  // deserializing scripts in order to greatly reduce the number of allocations
    82  // required.
    83  //
    84  // The caller can obtain a buffer from the free list by calling the Borrow
    85  // function and should return it via the Return function when done using it.
    86  type scriptFreeList chan []byte
    87  
    88  // Borrow returns a byte slice from the free list with a length according the
    89  // provided size.  A new buffer is allocated if there are any items available.
    90  //
    91  // When the size is larger than the max size allowed for items on the free list
    92  // a new buffer of the appropriate size is allocated and returned.  It is safe
    93  // to attempt to return said buffer via the Return function as it will be
    94  // ignored and allowed to go the garbage collector.
    95  func (c scriptFreeList) Borrow(size uint64) []byte {
    96  	if size > freeListMaxScriptSize {
    97  		return make([]byte, size, size)
    98  	}
    99  
   100  	var buf []byte
   101  	select {
   102  	case buf = <-c:
   103  	default:
   104  		buf = make([]byte, freeListMaxScriptSize)
   105  	}
   106  	return buf[:size]
   107  }
   108  
   109  // Return puts the provided byte slice back on the free list when it has a cap
   110  // of the expected length.  The buffer is expected to have been obtained via
   111  // the Borrow function.  Any slices that are not of the appropriate size, such
   112  // as those whose size is greater than the largest allowed free list item size
   113  // are simply ignored so they can go to the garbage collector.
   114  func (c scriptFreeList) Return(buf []byte) {
   115  	// Ignore any buffers returned that aren't the expected size for the
   116  	// free list.
   117  	if cap(buf) != freeListMaxScriptSize {
   118  		return
   119  	}
   120  
   121  	// Return the buffer to the free list when it's not full.  Otherwise let
   122  	// it be garbage collected.
   123  	select {
   124  	case c <- buf:
   125  	default:
   126  		// Let it go to the garbage collector.
   127  	}
   128  }
   129  
   130  // Create the concurrent safe free list to use for script deserialization.  As
   131  // previously described, this free list is maintained to significantly reduce
   132  // the number of allocations.
   133  var scriptPool scriptFreeList = make(chan []byte, freeListMaxItems)
   134  
   135  // OutPoint defines a bitcoin data type that is used to track previous
   136  // transaction outputs.
   137  type OutPoint struct {
   138  	Hash  ShaHash
   139  	Index uint32
   140  }
   141  
   142  // NewOutPoint returns a new bitcoin transaction outpoint point with the
   143  // provided hash and index.
   144  func NewOutPoint(hash *ShaHash, index uint32) *OutPoint {
   145  	return &OutPoint{
   146  		Hash:  *hash,
   147  		Index: index,
   148  	}
   149  }
   150  
   151  // String returns the OutPoint in the human-readable form "hash:index".
   152  func (o OutPoint) String() string {
   153  	// Allocate enough for hash string, colon, and 10 digits.  Although
   154  	// at the time of writing, the number of digits can be no greater than
   155  	// the length of the decimal representation of maxTxOutPerMessage, the
   156  	// maximum message payload may increase in the future and this
   157  	// optimization may go unnoticed, so allocate space for 10 decimal
   158  	// digits, which will fit any uint32.
   159  	buf := make([]byte, 2*HashSize+1, 2*HashSize+1+10)
   160  	copy(buf, o.Hash.String())
   161  	buf[2*HashSize] = ':'
   162  	buf = strconv.AppendUint(buf, uint64(o.Index), 10)
   163  	return string(buf)
   164  }
   165  
   166  // TxIn defines a bitcoin transaction input.
   167  type TxIn struct {
   168  	PreviousOutPoint OutPoint
   169  	SignatureScript  []byte
   170  	Sequence         uint32
   171  }
   172  
   173  // SerializeSize returns the number of bytes it would take to serialize the
   174  // the transaction input.
   175  func (t *TxIn) SerializeSize() int {
   176  	// Outpoint Hash 32 bytes + Outpoint Index 4 bytes + Sequence 4 bytes +
   177  	// serialized varint size for the length of SignatureScript +
   178  	// SignatureScript bytes.
   179  	return 40 + VarIntSerializeSize(uint64(len(t.SignatureScript))) +
   180  		len(t.SignatureScript)
   181  }
   182  
   183  // NewTxIn returns a new bitcoin transaction input with the provided
   184  // previous outpoint point and signature script with a default sequence of
   185  // MaxTxInSequenceNum.
   186  func NewTxIn(prevOut *OutPoint, signatureScript []byte) *TxIn {
   187  	return &TxIn{
   188  		PreviousOutPoint: *prevOut,
   189  		SignatureScript:  signatureScript,
   190  		Sequence:         MaxTxInSequenceNum,
   191  	}
   192  }
   193  
   194  // TxOut defines a bitcoin transaction output.
   195  type TxOut struct {
   196  	Value    int64
   197  	PkScript []byte
   198  }
   199  
   200  // SerializeSize returns the number of bytes it would take to serialize the
   201  // the transaction output.
   202  func (t *TxOut) SerializeSize() int {
   203  	// Value 8 bytes + serialized varint size for the length of PkScript +
   204  	// PkScript bytes.
   205  	return 8 + VarIntSerializeSize(uint64(len(t.PkScript))) + len(t.PkScript)
   206  }
   207  
   208  // NewTxOut returns a new bitcoin transaction output with the provided
   209  // transaction value and public key script.
   210  func NewTxOut(value int64, pkScript []byte) *TxOut {
   211  	return &TxOut{
   212  		Value:    value,
   213  		PkScript: pkScript,
   214  	}
   215  }
   216  
   217  // MsgTx implements the Message interface and represents a bitcoin tx message.
   218  // It is used to deliver transaction information in response to a getdata
   219  // message (MsgGetData) for a given transaction.
   220  //
   221  // Use the AddTxIn and AddTxOut functions to build up the list of transaction
   222  // inputs and outputs.
   223  type MsgTx struct {
   224  	Version  int32
   225  	TxIn     []*TxIn
   226  	TxOut    []*TxOut
   227  	LockTime uint32
   228  }
   229  
   230  // AddTxIn adds a transaction input to the message.
   231  func (msg *MsgTx) AddTxIn(ti *TxIn) {
   232  	msg.TxIn = append(msg.TxIn, ti)
   233  }
   234  
   235  // AddTxOut adds a transaction output to the message.
   236  func (msg *MsgTx) AddTxOut(to *TxOut) {
   237  	msg.TxOut = append(msg.TxOut, to)
   238  }
   239  
   240  // TxSha generates the ShaHash name for the transaction.
   241  func (msg *MsgTx) TxSha() ShaHash {
   242  	// Encode the transaction and calculate double sha256 on the result.
   243  	// Ignore the error returns since the only way the encode could fail
   244  	// is being out of memory or due to nil pointers, both of which would
   245  	// cause a run-time panic.
   246  	buf := bytes.NewBuffer(make([]byte, 0, msg.SerializeSize()))
   247  	_ = msg.Serialize(buf)
   248  	return DoubleSha256SH(buf.Bytes())
   249  }
   250  
   251  // Copy creates a deep copy of a transaction so that the original does not get
   252  // modified when the copy is manipulated.
   253  func (msg *MsgTx) Copy() *MsgTx {
   254  	// Create new tx and start by copying primitive values and making space
   255  	// for the transaction inputs and outputs.
   256  	newTx := MsgTx{
   257  		Version:  msg.Version,
   258  		TxIn:     make([]*TxIn, 0, len(msg.TxIn)),
   259  		TxOut:    make([]*TxOut, 0, len(msg.TxOut)),
   260  		LockTime: msg.LockTime,
   261  	}
   262  
   263  	// Deep copy the old TxIn data.
   264  	for _, oldTxIn := range msg.TxIn {
   265  		// Deep copy the old previous outpoint.
   266  		oldOutPoint := oldTxIn.PreviousOutPoint
   267  		newOutPoint := OutPoint{}
   268  		newOutPoint.Hash.SetBytes(oldOutPoint.Hash[:])
   269  		newOutPoint.Index = oldOutPoint.Index
   270  
   271  		// Deep copy the old signature script.
   272  		var newScript []byte
   273  		oldScript := oldTxIn.SignatureScript
   274  		oldScriptLen := len(oldScript)
   275  		if oldScriptLen > 0 {
   276  			newScript = make([]byte, oldScriptLen, oldScriptLen)
   277  			copy(newScript, oldScript[:oldScriptLen])
   278  		}
   279  
   280  		// Create new txIn with the deep copied data and append it to
   281  		// new Tx.
   282  		newTxIn := TxIn{
   283  			PreviousOutPoint: newOutPoint,
   284  			SignatureScript:  newScript,
   285  			Sequence:         oldTxIn.Sequence,
   286  		}
   287  		newTx.TxIn = append(newTx.TxIn, &newTxIn)
   288  	}
   289  
   290  	// Deep copy the old TxOut data.
   291  	for _, oldTxOut := range msg.TxOut {
   292  		// Deep copy the old PkScript
   293  		var newScript []byte
   294  		oldScript := oldTxOut.PkScript
   295  		oldScriptLen := len(oldScript)
   296  		if oldScriptLen > 0 {
   297  			newScript = make([]byte, oldScriptLen, oldScriptLen)
   298  			copy(newScript, oldScript[:oldScriptLen])
   299  		}
   300  
   301  		// Create new txOut with the deep copied data and append it to
   302  		// new Tx.
   303  		newTxOut := TxOut{
   304  			Value:    oldTxOut.Value,
   305  			PkScript: newScript,
   306  		}
   307  		newTx.TxOut = append(newTx.TxOut, &newTxOut)
   308  	}
   309  
   310  	return &newTx
   311  }
   312  
   313  // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
   314  // This is part of the Message interface implementation.
   315  // See Deserialize for decoding transactions stored to disk, such as in a
   316  // database, as opposed to decoding transactions from the wire.
   317  func (msg *MsgTx) BtcDecode(r io.Reader, pver uint32) error {
   318  	version, err := binarySerializer.Uint32(r, littleEndian)
   319  	if err != nil {
   320  		return err
   321  	}
   322  	msg.Version = int32(version)
   323  
   324  	count, err := ReadVarInt(r, pver)
   325  	if err != nil {
   326  		return err
   327  	}
   328  
   329  	// Prevent more input transactions than could possibly fit into a
   330  	// message.  It would be possible to cause memory exhaustion and panics
   331  	// without a sane upper bound on this count.
   332  	if count > uint64(maxTxInPerMessage) {
   333  		str := fmt.Sprintf("too many input transactions to fit into "+
   334  			"max message size [count %d, max %d]", count,
   335  			maxTxInPerMessage)
   336  		return messageError("MsgTx.BtcDecode", str)
   337  	}
   338  
   339  	// returnScriptBuffers is a closure that returns any script buffers that
   340  	// were borrowed from the pool when there are any deserialization
   341  	// errors.  This is only valid to call before the final step which
   342  	// replaces the scripts with the location in a contiguous buffer and
   343  	// returns them.
   344  	returnScriptBuffers := func() {
   345  		for _, txIn := range msg.TxIn {
   346  			if txIn == nil || txIn.SignatureScript == nil {
   347  				continue
   348  			}
   349  			scriptPool.Return(txIn.SignatureScript)
   350  		}
   351  		for _, txOut := range msg.TxOut {
   352  			if txOut == nil || txOut.PkScript == nil {
   353  				continue
   354  			}
   355  			scriptPool.Return(txOut.PkScript)
   356  		}
   357  	}
   358  
   359  	// Deserialize the inputs.
   360  	var totalScriptSize uint64
   361  	txIns := make([]TxIn, count)
   362  	msg.TxIn = make([]*TxIn, count)
   363  	for i := uint64(0); i < count; i++ {
   364  		// The pointer is set now in case a script buffer is borrowed
   365  		// and needs to be returned to the pool on error.
   366  		ti := &txIns[i]
   367  		msg.TxIn[i] = ti
   368  		err = readTxIn(r, pver, msg.Version, ti)
   369  		if err != nil {
   370  			returnScriptBuffers()
   371  			return err
   372  		}
   373  		totalScriptSize += uint64(len(ti.SignatureScript))
   374  	}
   375  
   376  	count, err = ReadVarInt(r, pver)
   377  	if err != nil {
   378  		returnScriptBuffers()
   379  		return err
   380  	}
   381  
   382  	// Prevent more output transactions than could possibly fit into a
   383  	// message.  It would be possible to cause memory exhaustion and panics
   384  	// without a sane upper bound on this count.
   385  	if count > uint64(maxTxOutPerMessage) {
   386  		returnScriptBuffers()
   387  		str := fmt.Sprintf("too many output transactions to fit into "+
   388  			"max message size [count %d, max %d]", count,
   389  			maxTxOutPerMessage)
   390  		return messageError("MsgTx.BtcDecode", str)
   391  	}
   392  
   393  	// Deserialize the outputs.
   394  	txOuts := make([]TxOut, count)
   395  	msg.TxOut = make([]*TxOut, count)
   396  	for i := uint64(0); i < count; i++ {
   397  		// The pointer is set now in case a script buffer is borrowed
   398  		// and needs to be returned to the pool on error.
   399  		to := &txOuts[i]
   400  		msg.TxOut[i] = to
   401  		err = readTxOut(r, pver, msg.Version, to)
   402  		if err != nil {
   403  			returnScriptBuffers()
   404  			return err
   405  		}
   406  		totalScriptSize += uint64(len(to.PkScript))
   407  	}
   408  
   409  	msg.LockTime, err = binarySerializer.Uint32(r, littleEndian)
   410  	if err != nil {
   411  		returnScriptBuffers()
   412  		return err
   413  	}
   414  
   415  	// Create a single allocation to house all of the scripts and set each
   416  	// input signature script and output public key script to the
   417  	// appropriate subslice of the overall contiguous buffer.  Then, return
   418  	// each individual script buffer back to the pool so they can be reused
   419  	// for future deserializations.  This is done because it significantly
   420  	// reduces the number of allocations the garbage collector needs to
   421  	// track, which in turn improves performance and drastically reduces the
   422  	// amount of runtime overhead that would otherwise be needed to keep
   423  	// track of millions of small allocations.
   424  	//
   425  	// NOTE: It is no longer valid to call the returnScriptBuffers closure
   426  	// after these blocks of code run because it is already done and the
   427  	// scripts in the transaction inputs and outputs no longer point to the
   428  	// buffers.
   429  	var offset uint64
   430  	scripts := make([]byte, totalScriptSize)
   431  	for i := 0; i < len(msg.TxIn); i++ {
   432  		// Copy the signature script into the contiguous buffer at the
   433  		// appropriate offset.
   434  		signatureScript := msg.TxIn[i].SignatureScript
   435  		copy(scripts[offset:], signatureScript)
   436  
   437  		// Reset the signature script of the transaction input to the
   438  		// slice of the contiguous buffer where the script lives.
   439  		scriptSize := uint64(len(signatureScript))
   440  		end := offset + scriptSize
   441  		msg.TxIn[i].SignatureScript = scripts[offset:end:end]
   442  		offset += scriptSize
   443  
   444  		// Return the temporary script buffer to the pool.
   445  		scriptPool.Return(signatureScript)
   446  	}
   447  	for i := 0; i < len(msg.TxOut); i++ {
   448  		// Copy the public key script into the contiguous buffer at the
   449  		// appropriate offset.
   450  		pkScript := msg.TxOut[i].PkScript
   451  		copy(scripts[offset:], pkScript)
   452  
   453  		// Reset the public key script of the transaction output to the
   454  		// slice of the contiguous buffer where the script lives.
   455  		scriptSize := uint64(len(pkScript))
   456  		end := offset + scriptSize
   457  		msg.TxOut[i].PkScript = scripts[offset:end:end]
   458  		offset += scriptSize
   459  
   460  		// Return the temporary script buffer to the pool.
   461  		scriptPool.Return(pkScript)
   462  	}
   463  
   464  	return nil
   465  }
   466  
   467  // Deserialize decodes a transaction from r into the receiver using a format
   468  // that is suitable for long-term storage such as a database while respecting
   469  // the Version field in the transaction.  This function differs from BtcDecode
   470  // in that BtcDecode decodes from the bitcoin wire protocol as it was sent
   471  // across the network.  The wire encoding can technically differ depending on
   472  // the protocol version and doesn't even really need to match the format of a
   473  // stored transaction at all.  As of the time this comment was written, the
   474  // encoded transaction is the same in both instances, but there is a distinct
   475  // difference and separating the two allows the API to be flexible enough to
   476  // deal with changes.
   477  func (msg *MsgTx) Deserialize(r io.Reader) error {
   478  	// At the current time, there is no difference between the wire encoding
   479  	// at protocol version 0 and the stable long-term storage format.  As
   480  	// a result, make use of BtcDecode.
   481  	return msg.BtcDecode(r, 0)
   482  }
   483  
   484  // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
   485  // This is part of the Message interface implementation.
   486  // See Serialize for encoding transactions to be stored to disk, such as in a
   487  // database, as opposed to encoding transactions for the wire.
   488  func (msg *MsgTx) BtcEncode(w io.Writer, pver uint32) error {
   489  	err := binarySerializer.PutUint32(w, littleEndian, uint32(msg.Version))
   490  	if err != nil {
   491  		return err
   492  	}
   493  
   494  	count := uint64(len(msg.TxIn))
   495  	err = WriteVarInt(w, pver, count)
   496  	if err != nil {
   497  		return err
   498  	}
   499  
   500  	for _, ti := range msg.TxIn {
   501  		err = writeTxIn(w, pver, msg.Version, ti)
   502  		if err != nil {
   503  			return err
   504  		}
   505  	}
   506  
   507  	count = uint64(len(msg.TxOut))
   508  	err = WriteVarInt(w, pver, count)
   509  	if err != nil {
   510  		return err
   511  	}
   512  
   513  	for _, to := range msg.TxOut {
   514  		err = writeTxOut(w, pver, msg.Version, to)
   515  		if err != nil {
   516  			return err
   517  		}
   518  	}
   519  
   520  	err = binarySerializer.PutUint32(w, littleEndian, msg.LockTime)
   521  	if err != nil {
   522  		return err
   523  	}
   524  
   525  	return nil
   526  }
   527  
   528  // Serialize encodes the transaction to w using a format that suitable for
   529  // long-term storage such as a database while respecting the Version field in
   530  // the transaction.  This function differs from BtcEncode in that BtcEncode
   531  // encodes the transaction to the bitcoin wire protocol in order to be sent
   532  // across the network.  The wire encoding can technically differ depending on
   533  // the protocol version and doesn't even really need to match the format of a
   534  // stored transaction at all.  As of the time this comment was written, the
   535  // encoded transaction is the same in both instances, but there is a distinct
   536  // difference and separating the two allows the API to be flexible enough to
   537  // deal with changes.
   538  func (msg *MsgTx) Serialize(w io.Writer) error {
   539  	// At the current time, there is no difference between the wire encoding
   540  	// at protocol version 0 and the stable long-term storage format.  As
   541  	// a result, make use of BtcEncode.
   542  	return msg.BtcEncode(w, 0)
   543  
   544  }
   545  
   546  // SerializeSize returns the number of bytes it would take to serialize the
   547  // the transaction.
   548  func (msg *MsgTx) SerializeSize() int {
   549  	// Version 4 bytes + LockTime 4 bytes + Serialized varint size for the
   550  	// number of transaction inputs and outputs.
   551  	n := 8 + VarIntSerializeSize(uint64(len(msg.TxIn))) +
   552  		VarIntSerializeSize(uint64(len(msg.TxOut)))
   553  
   554  	for _, txIn := range msg.TxIn {
   555  		n += txIn.SerializeSize()
   556  	}
   557  
   558  	for _, txOut := range msg.TxOut {
   559  		n += txOut.SerializeSize()
   560  	}
   561  
   562  	return n
   563  }
   564  
   565  // Command returns the protocol command string for the message.  This is part
   566  // of the Message interface implementation.
   567  func (msg *MsgTx) Command() string {
   568  	return CmdTx
   569  }
   570  
   571  // MaxPayloadLength returns the maximum length the payload can be for the
   572  // receiver.  This is part of the Message interface implementation.
   573  func (msg *MsgTx) MaxPayloadLength(pver uint32) uint32 {
   574  	return MaxBlockPayload
   575  }
   576  
   577  // PkScriptLocs returns a slice containing the start of each public key script
   578  // within the raw serialized transaction.  The caller can easily obtain the
   579  // length of each script by using len on the script available via the
   580  // appropriate transaction output entry.
   581  func (msg *MsgTx) PkScriptLocs() []int {
   582  	numTxOut := len(msg.TxOut)
   583  	if numTxOut == 0 {
   584  		return nil
   585  	}
   586  
   587  	// The starting offset in the serialized transaction of the first
   588  	// transaction output is:
   589  	//
   590  	// Version 4 bytes + serialized varint size for the number of
   591  	// transaction inputs and outputs + serialized size of each transaction
   592  	// input.
   593  	n := 4 + VarIntSerializeSize(uint64(len(msg.TxIn))) +
   594  		VarIntSerializeSize(uint64(numTxOut))
   595  	for _, txIn := range msg.TxIn {
   596  		n += txIn.SerializeSize()
   597  	}
   598  
   599  	// Calculate and set the appropriate offset for each public key script.
   600  	pkScriptLocs := make([]int, numTxOut)
   601  	for i, txOut := range msg.TxOut {
   602  		// The offset of the script in the transaction output is:
   603  		//
   604  		// Value 8 bytes + serialized varint size for the length of
   605  		// PkScript.
   606  		n += 8 + VarIntSerializeSize(uint64(len(txOut.PkScript)))
   607  		pkScriptLocs[i] = n
   608  		n += len(txOut.PkScript)
   609  	}
   610  
   611  	return pkScriptLocs
   612  }
   613  
   614  // NewMsgTx returns a new bitcoin tx message that conforms to the Message
   615  // interface.  The return instance has a default version of TxVersion and there
   616  // are no transaction inputs or outputs.  Also, the lock time is set to zero
   617  // to indicate the transaction is valid immediately as opposed to some time in
   618  // future.
   619  func NewMsgTx() *MsgTx {
   620  	return &MsgTx{
   621  		Version: TxVersion,
   622  		TxIn:    make([]*TxIn, 0, defaultTxInOutAlloc),
   623  		TxOut:   make([]*TxOut, 0, defaultTxInOutAlloc),
   624  	}
   625  }
   626  
   627  // readOutPoint reads the next sequence of bytes from r as an OutPoint.
   628  func readOutPoint(r io.Reader, pver uint32, version int32, op *OutPoint) error {
   629  	_, err := io.ReadFull(r, op.Hash[:])
   630  	if err != nil {
   631  		return err
   632  	}
   633  
   634  	op.Index, err = binarySerializer.Uint32(r, littleEndian)
   635  	if err != nil {
   636  		return err
   637  	}
   638  
   639  	return nil
   640  }
   641  
   642  // writeOutPoint encodes op to the bitcoin protocol encoding for an OutPoint
   643  // to w.
   644  func writeOutPoint(w io.Writer, pver uint32, version int32, op *OutPoint) error {
   645  	_, err := w.Write(op.Hash[:])
   646  	if err != nil {
   647  		return err
   648  	}
   649  
   650  	err = binarySerializer.PutUint32(w, littleEndian, op.Index)
   651  	if err != nil {
   652  		return err
   653  	}
   654  	return nil
   655  }
   656  
   657  // readScript reads a variable length byte array that represents a transaction
   658  // script.  It is encoded as a varInt containing the length of the array
   659  // followed by the bytes themselves.  An error is returned if the length is
   660  // greater than the passed maxAllowed parameter which helps protect against
   661  // memory exhuastion attacks and forced panics thorugh malformed messages.  The
   662  // fieldName parameter is only used for the error message so it provides more
   663  // context in the error.
   664  func readScript(r io.Reader, pver uint32, maxAllowed uint32, fieldName string) ([]byte, error) {
   665  	count, err := ReadVarInt(r, pver)
   666  	if err != nil {
   667  		return nil, err
   668  	}
   669  
   670  	// Prevent byte array larger than the max message size.  It would
   671  	// be possible to cause memory exhaustion and panics without a sane
   672  	// upper bound on this count.
   673  	if count > uint64(maxAllowed) {
   674  		str := fmt.Sprintf("%s is larger than the max allowed size "+
   675  			"[count %d, max %d]", fieldName, count, maxAllowed)
   676  		return nil, messageError("readScript", str)
   677  	}
   678  
   679  	b := scriptPool.Borrow(count)
   680  	_, err = io.ReadFull(r, b)
   681  	if err != nil {
   682  		scriptPool.Return(b)
   683  		return nil, err
   684  	}
   685  	return b, nil
   686  }
   687  
   688  // readTxIn reads the next sequence of bytes from r as a transaction input
   689  // (TxIn).
   690  func readTxIn(r io.Reader, pver uint32, version int32, ti *TxIn) error {
   691  	err := readOutPoint(r, pver, version, &ti.PreviousOutPoint)
   692  	if err != nil {
   693  		return err
   694  	}
   695  
   696  	ti.SignatureScript, err = readScript(r, pver, MaxMessagePayload,
   697  		"transaction input signature script")
   698  	if err != nil {
   699  		return err
   700  	}
   701  
   702  	err = readElement(r, &ti.Sequence)
   703  	if err != nil {
   704  		return err
   705  	}
   706  
   707  	return nil
   708  }
   709  
   710  // writeTxIn encodes ti to the bitcoin protocol encoding for a transaction
   711  // input (TxIn) to w.
   712  func writeTxIn(w io.Writer, pver uint32, version int32, ti *TxIn) error {
   713  	err := writeOutPoint(w, pver, version, &ti.PreviousOutPoint)
   714  	if err != nil {
   715  		return err
   716  	}
   717  
   718  	err = WriteVarBytes(w, pver, ti.SignatureScript)
   719  	if err != nil {
   720  		return err
   721  	}
   722  
   723  	err = binarySerializer.PutUint32(w, littleEndian, ti.Sequence)
   724  	if err != nil {
   725  		return err
   726  	}
   727  
   728  	return nil
   729  }
   730  
   731  // readTxOut reads the next sequence of bytes from r as a transaction output
   732  // (TxOut).
   733  func readTxOut(r io.Reader, pver uint32, version int32, to *TxOut) error {
   734  	err := readElement(r, &to.Value)
   735  	if err != nil {
   736  		return err
   737  	}
   738  
   739  	to.PkScript, err = readScript(r, pver, MaxMessagePayload,
   740  		"transaction output public key script")
   741  	if err != nil {
   742  		return err
   743  	}
   744  
   745  	return nil
   746  }
   747  
   748  // writeTxOut encodes to into the bitcoin protocol encoding for a transaction
   749  // output (TxOut) to w.
   750  func writeTxOut(w io.Writer, pver uint32, version int32, to *TxOut) error {
   751  	err := binarySerializer.PutUint64(w, littleEndian, uint64(to.Value))
   752  	if err != nil {
   753  		return err
   754  	}
   755  
   756  	err = WriteVarBytes(w, pver, to.PkScript)
   757  	if err != nil {
   758  		return err
   759  	}
   760  	return nil
   761  }