github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/wire/msgnotfound.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  	"fmt"
    10  	"io"
    11  )
    12  
    13  // MsgNotFound defines a bitcoin notfound message which is sent in response to
    14  // a getdata message if any of the requested data in not available on the peer.
    15  // Each message is limited to a maximum number of inventory vectors, which is
    16  // currently 50,000.
    17  //
    18  // Use the AddInvVect function to build up the list of inventory vectors when
    19  // sending a notfound message to another peer.
    20  type MsgNotFound struct {
    21  	InvList []*InvVect
    22  }
    23  
    24  // AddInvVect adds an inventory vector to the message.
    25  func (msg *MsgNotFound) AddInvVect(iv *InvVect) error {
    26  	if len(msg.InvList)+1 > MaxInvPerMsg {
    27  		str := fmt.Sprintf("too many invvect in message [max %v]",
    28  			MaxInvPerMsg)
    29  		return messageError("MsgNotFound.AddInvVect", str)
    30  	}
    31  
    32  	msg.InvList = append(msg.InvList, iv)
    33  	return nil
    34  }
    35  
    36  // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
    37  // This is part of the Message interface implementation.
    38  func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32) error {
    39  	count, err := ReadVarInt(r, pver)
    40  	if err != nil {
    41  		return err
    42  	}
    43  
    44  	// Limit to max inventory vectors per message.
    45  	if count > MaxInvPerMsg {
    46  		str := fmt.Sprintf("too many invvect in message [%v]", count)
    47  		return messageError("MsgNotFound.BtcDecode", str)
    48  	}
    49  
    50  	// Create a contiguous slice of inventory vectors to deserialize into in
    51  	// order to reduce the number of allocations.
    52  	invList := make([]InvVect, count)
    53  	msg.InvList = make([]*InvVect, 0, count)
    54  	for i := uint64(0); i < count; i++ {
    55  		iv := &invList[i]
    56  		err := readInvVect(r, pver, iv)
    57  		if err != nil {
    58  			return err
    59  		}
    60  		msg.AddInvVect(iv)
    61  	}
    62  
    63  	return nil
    64  }
    65  
    66  // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
    67  // This is part of the Message interface implementation.
    68  func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32) error {
    69  	// Limit to max inventory vectors per message.
    70  	count := len(msg.InvList)
    71  	if count > MaxInvPerMsg {
    72  		str := fmt.Sprintf("too many invvect in message [%v]", count)
    73  		return messageError("MsgNotFound.BtcEncode", str)
    74  	}
    75  
    76  	err := WriteVarInt(w, pver, uint64(count))
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	for _, iv := range msg.InvList {
    82  		err := writeInvVect(w, pver, iv)
    83  		if err != nil {
    84  			return err
    85  		}
    86  	}
    87  
    88  	return nil
    89  }
    90  
    91  // Command returns the protocol command string for the message.  This is part
    92  // of the Message interface implementation.
    93  func (msg *MsgNotFound) Command() string {
    94  	return CmdNotFound
    95  }
    96  
    97  // MaxPayloadLength returns the maximum length the payload can be for the
    98  // receiver.  This is part of the Message interface implementation.
    99  func (msg *MsgNotFound) MaxPayloadLength(pver uint32) uint32 {
   100  	// Max var int 9 bytes + max InvVects at 36 bytes each.
   101  	// Num inventory vectors (varInt) + max allowed inventory vectors.
   102  	return MaxVarIntPayload + (MaxInvPerMsg * maxInvVectPayload)
   103  }
   104  
   105  // NewMsgNotFound returns a new bitcoin notfound message that conforms to the
   106  // Message interface.  See MsgNotFound for details.
   107  func NewMsgNotFound() *MsgNotFound {
   108  	return &MsgNotFound{
   109  		InvList: make([]*InvVect, 0, defaultInvListAlloc),
   110  	}
   111  }