15 static constexpr
int GCS_SER_VERSION = 0;
17 template <
typename OStream>
23 int nbits = q <= 64 ? static_cast<int>(q) : 64;
24 bitwriter.
Write(~0ULL, nbits);
27 bitwriter.
Write(0, 1);
31 bitwriter.
Write(x, P);
34 template <
typename IStream>
39 while (bitreader.
Read(1) == 1) {
43 uint64_t r = bitreader.
Read(P);
53 static uint64_t MapIntoRange(uint64_t x, uint64_t n)
55 #ifdef __SIZEOF_INT128__ 56 return (static_cast<unsigned __int128>(x) * static_cast<unsigned __int128>(n)) >> 64;
63 uint64_t x_hi = x >> 32;
64 uint64_t x_lo = x & 0xFFFFFFFF;
65 uint64_t n_hi = n >> 32;
66 uint64_t n_lo = n & 0xFFFFFFFF;
68 uint64_t ac = x_hi * n_hi;
69 uint64_t ad = x_hi * n_lo;
70 uint64_t bc = x_lo * n_hi;
71 uint64_t bd = x_lo * n_lo;
73 uint64_t mid34 = (bd >> 32) + (bc & 0xFFFFFFFF) + (ad & 0xFFFFFFFF);
74 uint64_t upper64 = ac + (bc >> 32) + (ad >> 32) + (mid34 >> 32);
82 .
Write(element.data(), element.size())
84 return MapIntoRange(hash,
m_F);
89 std::vector<uint64_t> hashed_elements;
90 hashed_elements.reserve(elements.size());
91 for (
const Element& element : elements) {
94 std::sort(hashed_elements.begin(), hashed_elements.end());
95 return hashed_elements;
99 : m_siphash_k0(siphash_k0), m_siphash_k1(siphash_k1), m_P(P), m_M(M), m_N(0), m_F(0)
103 std::vector<unsigned char> encoded_filter)
104 :
GCSFilter(siphash_k0, siphash_k1, P, M)
111 m_N =
static_cast<uint32_t
>(N);
113 throw std::ios_base::failure(
"N must be <2^32");
115 m_F =
static_cast<uint64_t
>(
m_N) * static_cast<uint64_t>(
m_M);
120 for (uint64_t i = 0; i <
m_N; ++i) {
121 GolombRiceDecode(bitreader,
m_P);
123 if (!stream.
empty()) {
124 throw std::ios_base::failure(
"encoded_filter contains excess data");
130 :
GCSFilter(siphash_k0, siphash_k1, P, M)
132 size_t N = elements.size();
133 m_N =
static_cast<uint32_t
>(N);
135 throw std::invalid_argument(
"N must be <2^32");
137 m_F =
static_cast<uint64_t
>(
m_N) * static_cast<uint64_t>(
m_M);
143 if (elements.empty()) {
149 uint64_t last_value = 0;
151 uint64_t delta = value - last_value;
152 GolombRiceEncode(bitwriter,
m_P, delta);
170 size_t hashes_index = 0;
171 for (uint32_t i = 0; i <
m_N; ++i) {
172 uint64_t delta = GolombRiceDecode(bitreader,
m_P);
176 if (hashes_index == size) {
178 }
else if (element_hashes[hashes_index] == value) {
180 }
else if (element_hashes[hashes_index] > value) {
209 for (
const CTxOut& txout : tx->vout) {
212 elements.emplace(script.
begin(), script.
end());
219 if (script.
empty())
continue;
220 elements.emplace(script.
begin(), script.
end());
228 : m_filter_type(filter_type), m_block_hash(block.GetHash())
234 BasicFilterElements(block, block_undo));
238 throw std::invalid_argument(
"unknown filter_type");
258 .Write(prev_header.
begin(), prev_header.
size())
259 .Finalize(result.
begin());
std::vector< Coin > vprevout
constexpr uint32_t BASIC_FILTER_M
CSipHasher & Write(uint64_t data)
Hash a 64-bit integer worth of data It is treated as if this was the little-endian interpretation of ...
uint64_t ReadCompactSize(Stream &is)
void WriteCompactSize(CSizeComputer &os, uint64_t nSize)
CHash256 & Write(const unsigned char *data, size_t len)
CTxOut out
unspent transaction output
BlockFilter(BlockFilterType filter_type, const CBlock &block, const CBlockUndo &block_undo)
constexpr uint8_t BASIC_FILTER_P
bool MatchAny(const ElementSet &elements) const
Checks if any of the given elements may be in the set.
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.
std::shared_ptr< const CTransaction > CTransactionRef
bool Match(const Element &element) const
Checks if the element may be in the set.
bool MatchInternal(const uint64_t *sorted_element_hashes, size_t size) const
Helper method used to implement Match and MatchAny.
const std::vector< unsigned char > & GetEncodedFilter() const
GCSFilter(uint64_t siphash_k0=0, uint64_t siphash_k1=0, uint8_t P=0, uint32_t M=0)
Constructs an empty filter.
Minimal stream for reading from an existing vector by reference.
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.
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.
uint8_t m_P
Golomb-Rice coding parameter.
uint256 ComputeHeader(const uint256 &prev_header) const
std::vector< CTransactionRef > vtx
Undo information for a CBlock.
Serialized script, used inside transaction inputs and outputs.
Undo information for a CTransaction.
BlockFilterType m_filter_type
std::vector< unsigned char > Element
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.
uint32_t m_M
Inverse false positive rate.
std::set< Element > ElementSet
std::vector< unsigned char > m_encoded