github.com/palcoin-project/palcd@v1.0.0/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/palcoin-project/palcd/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 }