github.com/BlockABC/godash@v0.0.0-20191112120524-f4aa3a32c566/wire/msgfilterload.go (about)

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