github.com/btcsuite/btcd@v0.24.0/wire/msgfilterload.go (about)

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