lbcd/msgnotfound.go

108 lines
3 KiB
Go
Raw Normal View History

2014-01-09 06:44:08 +01:00
// Copyright (c) 2013-2014 Conformal Systems LLC.
2013-05-08 21:31:00 +02:00
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.
package btcwire
import (
"fmt"
"io"
)
// MsgNotFound defines a bitcoin notfound message which is sent in response to
// a getdata message if any of the requested data in not available on the peer.
// Each message is limited to a maximum number of inventory vectors, which is
// currently 50,000.
//
// Use the AddInvVect function to build up the list of inventory vectors when
// sending a notfound message to another peer.
type MsgNotFound struct {
InvList []*InvVect
}
// AddInvVect adds an inventory vector to the message.
func (msg *MsgNotFound) AddInvVect(iv *InvVect) error {
if len(msg.InvList)+1 > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [max %v]",
MaxInvPerMsg)
return messageError("MsgNotFound.AddInvVect", str)
2013-05-08 21:31:00 +02:00
}
msg.InvList = append(msg.InvList, iv)
return nil
}
// BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
// This is part of the Message interface implementation.
func (msg *MsgNotFound) BtcDecode(r io.Reader, pver uint32) error {
count, err := readVarInt(r, pver)
if err != nil {
return err
}
// Limit to max inventory vectors per message.
if count > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgNotFound.BtcDecode", str)
2013-05-08 21:31:00 +02:00
}
msg.InvList = make([]*InvVect, 0, count)
2013-05-08 21:31:00 +02:00
for i := uint64(0); i < count; i++ {
iv := InvVect{}
err := readInvVect(r, pver, &iv)
if err != nil {
return err
}
msg.AddInvVect(&iv)
}
return nil
}
// BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
// This is part of the Message interface implementation.
func (msg *MsgNotFound) BtcEncode(w io.Writer, pver uint32) error {
// Limit to max inventory vectors per message.
count := len(msg.InvList)
if count > MaxInvPerMsg {
str := fmt.Sprintf("too many invvect in message [%v]", count)
return messageError("MsgNotFound.BtcEncode", str)
2013-05-08 21:31:00 +02:00
}
err := writeVarInt(w, pver, uint64(count))
if err != nil {
return err
}
for _, iv := range msg.InvList {
err := writeInvVect(w, pver, iv)
if err != nil {
return err
}
}
return nil
}
// Command returns the protocol command string for the message. This is part
// of the Message interface implementation.
func (msg *MsgNotFound) Command() string {
return cmdNotFound
}
// MaxPayloadLength returns the maximum length the payload can be for the
// receiver. This is part of the Message interface implementation.
func (msg *MsgNotFound) MaxPayloadLength(pver uint32) uint32 {
// Max var int 9 bytes + max InvVects at 36 bytes each.
// Num inventory vectors (varInt) + max allowed inventory vectors.
return maxVarIntPayload + (MaxInvPerMsg * maxInvVectPayload)
}
// NewMsgNotFound returns a new bitcoin notfound message that conforms to the
// Message interface. See MsgNotFound for details.
func NewMsgNotFound() *MsgNotFound {
return &MsgNotFound{
InvList: make([]*InvVect, 0, defaultInvListAlloc),
}
2013-05-08 21:31:00 +02:00
}