github.com/lbryio/lbcd@v0.22.119/wire/msgcfilter.go (about)

     1  // Copyright (c) 2017 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  	"github.com/lbryio/lbcd/chaincfg/chainhash"
    12  )
    13  
    14  // FilterType is used to represent a filter type.
    15  type FilterType uint8
    16  
    17  const (
    18  	// GCSFilterRegular is the regular filter type.
    19  	GCSFilterRegular FilterType = iota
    20  )
    21  
    22  const (
    23  	// MaxCFilterDataSize is the maximum byte size of a committed filter.
    24  	// The maximum size is currently defined as 256KiB.
    25  	MaxCFilterDataSize = 256 * 1024
    26  )
    27  
    28  // MsgCFilter implements the Message interface and represents a bitcoin cfilter
    29  // message. It is used to deliver a committed filter in response to a
    30  // getcfilters (MsgGetCFilters) message.
    31  type MsgCFilter struct {
    32  	FilterType FilterType
    33  	BlockHash  chainhash.Hash
    34  	Data       []byte
    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 *MsgCFilter) BtcDecode(r io.Reader, pver uint32, _ MessageEncoding) error {
    40  	// Read filter type
    41  	err := readElement(r, &msg.FilterType)
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	// Read the hash of the filter's block
    47  	err = readElement(r, &msg.BlockHash)
    48  	if err != nil {
    49  		return err
    50  	}
    51  
    52  	// Read filter data
    53  	msg.Data, err = ReadVarBytes(r, pver, MaxCFilterDataSize,
    54  		"cfilter data")
    55  	return err
    56  }
    57  
    58  // BtcEncode encodes the receiver to w using the bitcoin protocol encoding.
    59  // This is part of the Message interface implementation.
    60  func (msg *MsgCFilter) BtcEncode(w io.Writer, pver uint32, _ MessageEncoding) error {
    61  	size := len(msg.Data)
    62  	if size > MaxCFilterDataSize {
    63  		str := fmt.Sprintf("cfilter size too large for message "+
    64  			"[size %v, max %v]", size, MaxCFilterDataSize)
    65  		return messageError("MsgCFilter.BtcEncode", str)
    66  	}
    67  
    68  	err := writeElement(w, msg.FilterType)
    69  	if err != nil {
    70  		return err
    71  	}
    72  
    73  	err = writeElement(w, msg.BlockHash)
    74  	if err != nil {
    75  		return err
    76  	}
    77  
    78  	return WriteVarBytes(w, pver, msg.Data)
    79  }
    80  
    81  // Deserialize decodes a filter from r into the receiver using a format that is
    82  // suitable for long-term storage such as a database. This function differs
    83  // from BtcDecode in that BtcDecode decodes from the bitcoin wire protocol as
    84  // it was sent across the network.  The wire encoding can technically differ
    85  // depending on the protocol version and doesn't even really need to match the
    86  // format of a stored filter at all. As of the time this comment was written,
    87  // the encoded filter is the same in both instances, but there is a distinct
    88  // difference and separating the two allows the API to be flexible enough to
    89  // deal with changes.
    90  func (msg *MsgCFilter) Deserialize(r io.Reader) error {
    91  	// At the current time, there is no difference between the wire encoding
    92  	// and the stable long-term storage format.  As a result, make use of
    93  	// BtcDecode.
    94  	return msg.BtcDecode(r, 0, BaseEncoding)
    95  }
    96  
    97  // Command returns the protocol command string for the message.  This is part
    98  // of the Message interface implementation.
    99  func (msg *MsgCFilter) Command() string {
   100  	return CmdCFilter
   101  }
   102  
   103  // MaxPayloadLength returns the maximum length the payload can be for the
   104  // receiver.  This is part of the Message interface implementation.
   105  func (msg *MsgCFilter) MaxPayloadLength(pver uint32) uint32 {
   106  	return uint32(VarIntSerializeSize(MaxCFilterDataSize)) +
   107  		MaxCFilterDataSize + chainhash.HashSize + 1
   108  }
   109  
   110  // NewMsgCFilter returns a new bitcoin cfilter message that conforms to the
   111  // Message interface. See MsgCFilter for details.
   112  func NewMsgCFilter(filterType FilterType, blockHash *chainhash.Hash,
   113  	data []byte) *MsgCFilter {
   114  	return &MsgCFilter{
   115  		FilterType: filterType,
   116  		BlockHash:  *blockHash,
   117  		Data:       data,
   118  	}
   119  }