github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/wire/msgheaders.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  	"fmt"
     9  	"io"
    10  )
    11  
    12  // MaxBlockHeadersPerMsg is the maximum number of block headers that can be in
    13  // a single bitcoin headers message.
    14  const MaxBlockHeadersPerMsg = 2000
    15  
    16  // MsgHeaders implements the Message interface and represents a bitcoin headers
    17  // message.  It is used to deliver block header information in response
    18  // to a getheaders message (MsgGetHeaders).  The maximum number of block headers
    19  // per message is currently 2000.  See MsgGetHeaders for details on requesting
    20  // the headers.
    21  type MsgHeaders struct {
    22  	Headers []*BlockHeader
    23  }
    24  
    25  // AddBlockHeader adds a new block header to the message.
    26  func (msg *MsgHeaders) AddBlockHeader(bh *BlockHeader) error {
    27  	if len(msg.Headers)+1 > MaxBlockHeadersPerMsg {
    28  		str := fmt.Sprintf("too many block headers in message [max %v]",
    29  			MaxBlockHeadersPerMsg)
    30  		return messageError("MsgHeaders.AddBlockHeader", str)
    31  	}
    32  
    33  	msg.Headers = append(msg.Headers, bh)
    34  	return nil
    35  }
    36  
    37  // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
    38  // This is part of the Message interface implementation.
    39  func (msg *MsgHeaders) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) error {
    40  	count, err := ReadVarInt(r, pver)
    41  	if err != nil {
    42  		return err
    43  	}
    44  
    45  	// Limit to max block headers per message.
    46  	if count > MaxBlockHeadersPerMsg {
    47  		str := fmt.Sprintf("too many block headers for message "+
    48  			"[count %v, max %v]", count, MaxBlockHeadersPerMsg)
    49  		return messageError("MsgHeaders.BtcDecode", str)
    50  	}
    51  
    52  	// Create a contiguous slice of headers to deserialize into in order to
    53  	// reduce the number of allocations.
    54  	headers := make([]BlockHeader, count)
    55  	msg.Headers = make([]*BlockHeader, 0, count)
    56  	for i := uint64(0); i < count; i++ {
    57  		bh := &headers[i]
    58  		err := readBlockHeader(r, pver, bh)
    59  		if err != nil {
    60  			return err
    61  		}
    62  
    63  		txCount, err := ReadVarInt(r, pver)
    64  		if err != nil {
    65  			return err
    66  		}
    67  
    68  		// Ensure the transaction count is zero for headers.
    69  
    70  		if txCount > 0 {
    71  			// remove for bc2
    72  			//			str := fmt.Sprintf("block headers may not contain "+
    73  			//				"transactions [count %v]", txCount)
    74  			//			return messageError("MsgHeaders.BtcDecode", str)
    75  		}
    76  
    77  		msg.AddBlockHeader(bh)
    78  	}
    79  
    80  	return nil
    81  }
    82  
    83  // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
    84  // This is part of the Message interface implementation.
    85  func (msg *MsgHeaders) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) error {
    86  	// Limit to max block headers per message.
    87  	count := len(msg.Headers)
    88  	if count > MaxBlockHeadersPerMsg {
    89  		str := fmt.Sprintf("too many block headers for message "+
    90  			"[count %v, max %v]", count, MaxBlockHeadersPerMsg)
    91  		return messageError("MsgHeaders.BtcEncode", str)
    92  	}
    93  
    94  	err := WriteVarInt(w, pver, uint64(count))
    95  	if err != nil {
    96  		return err
    97  	}
    98  
    99  	for _, bh := range msg.Headers {
   100  		err := WriteBlockHeader(w, pver, bh)
   101  		if err != nil {
   102  			return err
   103  		}
   104  
   105  		// The wire protocol encoding always includes a 0 for the number
   106  		// of transactions on header messages.  This is really just an
   107  		// artifact of the way the original implementation serializes
   108  		// block headers, but it is required.
   109  		err = WriteVarInt(w, pver, 0)
   110  		if err != nil {
   111  			return err
   112  		}
   113  	}
   114  
   115  	return nil
   116  }
   117  
   118  // Command returns the protocol command string for the message.  This is part
   119  // of the Message interface implementation.
   120  func (msg *MsgHeaders) Command() string {
   121  	return CmdHeaders
   122  }
   123  
   124  // MaxPayloadLength returns the maximum length the payload can be for the
   125  // receiver.  This is part of the Message interface implementation.
   126  func (msg *MsgHeaders) MaxPayloadLength(pver uint32) uint32 {
   127  	// Num headers (varInt) + max allowed headers (header length + 1 byte
   128  	// for the number of transactions which is always 0).
   129  	return MaxVarIntPayload + ((MaxBlockHeaderPayload + 1) *
   130  		MaxBlockHeadersPerMsg)
   131  }
   132  
   133  // NewMsgHeaders returns a new bitcoin headers message that conforms to the
   134  // Message interface.  See MsgHeaders for details.
   135  func NewMsgHeaders() *MsgHeaders {
   136  	return &MsgHeaders{
   137  		Headers: make([]*BlockHeader, 0, MaxBlockHeadersPerMsg),
   138  	}
   139  }