github.com/palcoin-project/palcd@v1.0.0/wire/msgnotfound.go (about)

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