26 template <
typename OStream>
32 int nbits = q <= 64 ? static_cast<int>(q) : 64;
33 bitwriter.
Write(~0ULL, nbits);
36 bitwriter.
Write(0, 1);
40 bitwriter.
Write(x, P);
43 template <
typename IStream>
48 while (bitreader.
Read(1) == 1) {
52 uint64_t r = bitreader.
Read(P);
64 #ifdef __SIZEOF_INT128__ 65 return (static_cast<unsigned __int128>(x) *
66 static_cast<unsigned __int128>(n)) >>
74 uint64_t x_hi = x >> 32;
75 uint64_t x_lo = x & 0xFFFFFFFF;
76 uint64_t n_hi = n >> 32;
77 uint64_t n_lo = n & 0xFFFFFFFF;
79 uint64_t ac = x_hi * n_hi;
80 uint64_t ad = x_hi * n_lo;
81 uint64_t bc = x_lo * n_hi;
82 uint64_t bd = x_lo * n_lo;
84 uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF);
85 uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32);
92 .
Write(element.data(), element.size())
99 std::vector<uint64_t> hashed_elements;
100 hashed_elements.reserve(elements.size());
101 for (
const Element &element : elements) {
104 std::sort(hashed_elements.begin(), hashed_elements.end());
105 return hashed_elements;
116 m_N =
static_cast<uint32_t
>(N);
118 throw std::ios_base::failure(
"N must be <2^32");
126 for (uint64_t i = 0; i <
m_N; ++i) {
129 if (!stream.
empty()) {
130 throw std::ios_base::failure(
"encoded_filter contains excess data");
136 size_t N = elements.size();
137 m_N =
static_cast<uint32_t
>(N);
139 throw std::invalid_argument(
"N must be <2^32");
147 if (elements.empty()) {
153 uint64_t last_value = 0;
155 uint64_t delta = value - last_value;
174 size_t hashes_index = 0;
175 for (uint32_t i = 0; i <
m_N; ++i) {
180 if (hashes_index == size) {
182 }
else if (element_hashes[hashes_index] == value) {
184 }
else if (element_hashes[hashes_index] > value) {
206 static std::string unknown_retval =
"";
214 if (entry.second == name) {
215 filter_type = entry.first;
223 static std::set<BlockFilterType> types;
225 static std::once_flag flag;
226 std::call_once(flag, []() {
228 types.insert(entry.first);
236 static std::string type_list;
238 static std::once_flag flag;
239 std::call_once(flag, []() {
240 std::stringstream ret;
249 type_list = ret.str();
260 for (
const CTxOut &txout : tx->vout) {
265 elements.emplace(script.
begin(), script.
end());
272 if (script.
empty()) {
275 elements.emplace(script.
begin(), script.
end());
284 std::vector<uint8_t> filter)
285 : m_filter_type(filter_type), m_block_hash(block_hash) {
288 throw std::invalid_argument(
"unknown filter_type");
298 throw std::invalid_argument(
"unknown filter_type");
332 .Write(prev_header.
begin(), prev_header.
size())
333 .Finalize(result.
begin());
std::shared_ptr< const CTransaction > CTransactionRef
std::vector< Coin > vprevout
static void GolombRiceEncode(BitStreamWriter< OStream > &bitwriter, uint8_t P, uint64_t x)
constexpr uint32_t BASIC_FILTER_M
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data.
uint64_t ReadCompactSize(Stream &is)
bool BlockFilterTypeByName(const std::string &name, BlockFilterType &filter_type)
Find a filter type by its human-readable name.
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
constexpr uint8_t BASIC_FILTER_P
bool MatchAny(const ElementSet &elements) const
Checks if any of the given elements may be in the set.
const std::set< BlockFilterType > & AllBlockFilterTypes()
Get a list of known filter types.
A hasher class for Bitcoin's 256-bit hash (double SHA-256).
std::vector< uint64_t > BuildHashedSet(const ElementSet &elements) const
void Write(uint64_t data, int nbits)
Write the nbits least significant bits of a 64-bit int to the output stream.
static const std::map< BlockFilterType, std::string > g_filter_types
uint256 GetHash() const
Compute the filter hash.
bool Match(const Element &element) const
Checks if the element may be in the set.
GCSFilter(const Params ¶ms=Params())
Constructs an empty filter.
const std::vector< uint8_t > & GetEncodedFilter() const
bool MatchInternal(const uint64_t *sorted_element_hashes, size_t size) const
Helper method used to implement Match and MatchAny.
const std::string & ListBlockFilterTypes()
Get a comma-separated list of known filter type names.
Minimal stream for reading from an existing vector by reference.
std::vector< uint8_t > m_encoded
static unsigned char elements[DATACOUNT][DATALEN]
uint64_t HashToRange(const Element &element) const
Hash a data element to an integer in the range [0, N * M).
An output of a transaction.
unsigned int size() const
uint64_t Read(int nbits)
Read the specified number of bits from the stream.
static uint64_t GolombRiceDecode(BitStreamReader< IStream > &bitreader, uint8_t P)
static GCSFilter::ElementSet BasicFilterElements(const CBlock &block, const CBlockUndo &block_undo)
This implements a Golomb-coded set as defined in BIP 158.
void Flush()
Flush any unwritten bits to the output stream, padding with 0's to the next byte boundary.
std::unordered_set< Element, ByteVectorHash > ElementSet
CHash256 & Write(const uint8_t *data, size_t len)
uint32_t m_M
Inverse false positive rate.
uint256 ComputeHeader(const uint256 &prev_header) const
Compute the filter header given the previous one.
std::vector< uint8_t > Element
uint8_t m_P
Golomb-Rice coding parameter.
std::vector< CTransactionRef > vtx
static constexpr int GCS_SER_TYPE
SerType used to serialize parameters in GCS filter encoding.
A BlockHash is a unqiue identifier for a block.
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
Restore the UTXO in a Coin at a given COutPoint.
BlockFilterType m_filter_type
static constexpr int GCS_SER_VERSION
Protocol version used to serialize parameters in GCS filter encoding.
Minimal stream for overwriting and/or appending to an existing byte vector.
uint32_t m_N
Number of elements in the filter.
uint64_t GetUint64(int pos) const
std::vector< CTxUndo > vtxundo
uint64_t m_F
Range of element hashes, F = N * M.
bool BuildParams(GCSFilter::Params ¶ms) const
static uint64_t MapIntoRange(uint64_t x, uint64_t n)
const std::string & BlockFilterTypeName(BlockFilterType filter_type)
Get the human-readable name for a filter type.