msgfilterload.go raw

   1  package wire
   2  
   3  import (
   4  	"fmt"
   5  	"io"
   6  )
   7  
   8  // BloomUpdateType specifies how the filter is updated when a match is found
   9  type BloomUpdateType uint8
  10  
  11  const (
  12  	// BloomUpdateNone indicates the filter is not adjusted when a match is found.
  13  	BloomUpdateNone BloomUpdateType = 0
  14  	// BloomUpdateAll indicates if the filter matches any data element in a public
  15  	// key script, the outpoint is serialized and inserted into the filter.
  16  	BloomUpdateAll BloomUpdateType = 1
  17  	// BloomUpdateP2PubkeyOnly indicates if the filter matches a data element in a
  18  	// public key script and the script is of the standard pay-to-pubkey or
  19  	// multisig, the outpoint is serialized and inserted into the filter.
  20  	BloomUpdateP2PubkeyOnly BloomUpdateType = 2
  21  )
  22  const (
  23  	// MaxFilterLoadHashFuncs is the maximum number of hash functions to load into
  24  	// the Bloom filter.
  25  	MaxFilterLoadHashFuncs = 50
  26  	// MaxFilterLoadFilterSize is the maximum size in bytes a filter may be.
  27  	MaxFilterLoadFilterSize = 36000
  28  )
  29  
  30  // MsgFilterLoad implements the Message interface and represents a bitcoin
  31  // filterload message which is used to reset a Bloom filter. This message was
  32  // not added until protocol version BIP0037Version.
  33  type MsgFilterLoad struct {
  34  	Filter    []byte
  35  	HashFuncs uint32
  36  	Tweak     uint32
  37  	Flags     BloomUpdateType
  38  }
  39  
  40  // BtcDecode decodes r using the bitcoin protocol encoding into the receiver.
  41  // This is part of the Message interface implementation.
  42  func (msg *MsgFilterLoad) BtcDecode(r io.Reader, pver uint32, enc MessageEncoding) (e error) {
  43  	if pver < BIP0037Version {
  44  		str := fmt.Sprintf("filterload message invalid for protocol version %d", pver)
  45  		return messageError("MsgFilterLoad.BtcDecode", str)
  46  	}
  47  	if msg.Filter, e = ReadVarBytes(r, pver, MaxFilterLoadFilterSize, "filterload filter size"); E.Chk(e) {
  48  		return
  49  	}
  50  	if e = readElements(r, &msg.HashFuncs, &msg.Tweak, &msg.Flags); E.Chk(e) {
  51  		return
  52  	}
  53  	if msg.HashFuncs > MaxFilterLoadHashFuncs {
  54  		str := fmt.Sprintf(
  55  			"too many filter hash functions for message [count %v, max %v]",
  56  			msg.HashFuncs, MaxFilterLoadHashFuncs,
  57  		)
  58  		return messageError("MsgFilterLoad.BtcDecode", str)
  59  	}
  60  	return
  61  }
  62  
  63  // BtcEncode encodes the receiver to w using the bitcoin protocol encoding. This is part of the Message interface
  64  // implementation.
  65  func (msg *MsgFilterLoad) BtcEncode(w io.Writer, pver uint32, enc MessageEncoding) (e error) {
  66  	if pver < BIP0037Version {
  67  		str := fmt.Sprintf(
  68  			"filterload message invalid for protocol "+
  69  				"version %d", pver,
  70  		)
  71  		return messageError("MsgFilterLoad.BtcEncode", str)
  72  	}
  73  	size := len(msg.Filter)
  74  	if size > MaxFilterLoadFilterSize {
  75  		str := fmt.Sprintf(
  76  			"filterload filter size too large for message "+
  77  				"[size %v, max %v]", size, MaxFilterLoadFilterSize,
  78  		)
  79  		return messageError("MsgFilterLoad.BtcEncode", str)
  80  	}
  81  	if msg.HashFuncs > MaxFilterLoadHashFuncs {
  82  		str := fmt.Sprintf(
  83  			"too many filter hash functions for message "+
  84  				"[count %v, max %v]", msg.HashFuncs, MaxFilterLoadHashFuncs,
  85  		)
  86  		return messageError("MsgFilterLoad.BtcEncode", str)
  87  	}
  88  	if e = WriteVarBytes(w, pver, msg.Filter); E.Chk(e) {
  89  		return
  90  	}
  91  	return writeElements(w, msg.HashFuncs, msg.Tweak, msg.Flags)
  92  }
  93  
  94  // Command returns the protocol command string for the message. This is part of the Message interface implementation.
  95  func (msg *MsgFilterLoad) Command() string {
  96  	return CmdFilterLoad
  97  }
  98  
  99  // MaxPayloadLength returns the maximum length the payload can be for the receiver. This is part of the Message
 100  // interface implementation.
 101  func (msg *MsgFilterLoad) MaxPayloadLength(pver uint32) uint32 {
 102  	// Num filter bytes (varInt) + filter + 4 bytes hash funcs + 4 bytes tweak + 1 byte flags.
 103  	return uint32(VarIntSerializeSize(MaxFilterLoadFilterSize)) +
 104  		MaxFilterLoadFilterSize + 9
 105  }
 106  
 107  // NewMsgFilterLoad returns a new bitcoin filterload message that conforms to the Message interface. See MsgFilterLoad
 108  // for details.
 109  func NewMsgFilterLoad(filter []byte, hashFuncs uint32, tweak uint32, flags BloomUpdateType) *MsgFilterLoad {
 110  	return &MsgFilterLoad{
 111  		Filter:    filter,
 112  		HashFuncs: hashFuncs,
 113  		Tweak:     tweak,
 114  		Flags:     flags,
 115  	}
 116  }
 117