mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-03-06 14:19:59 -05:00
Make sanity check in GCSFilter constructor optional
BlockFilterIndex will perform the cheaper check of verifying the filter hash when reading the filter from disk.
This commit is contained in:
parent
2b5a741e98
commit
b0a53d50d9
4 changed files with 18 additions and 11 deletions
|
@ -47,7 +47,7 @@ GCSFilter::GCSFilter(const Params& params)
|
|||
: m_params(params), m_N(0), m_F(0), m_encoded{0}
|
||||
{}
|
||||
|
||||
GCSFilter::GCSFilter(const Params& params, std::vector<unsigned char> encoded_filter)
|
||||
GCSFilter::GCSFilter(const Params& params, std::vector<unsigned char> encoded_filter, bool skip_decode_check)
|
||||
: m_params(params), m_encoded(std::move(encoded_filter))
|
||||
{
|
||||
SpanReader stream{GCS_SER_TYPE, GCS_SER_VERSION, m_encoded};
|
||||
|
@ -59,6 +59,8 @@ GCSFilter::GCSFilter(const Params& params, std::vector<unsigned char> encoded_fi
|
|||
}
|
||||
m_F = static_cast<uint64_t>(m_N) * static_cast<uint64_t>(m_params.m_M);
|
||||
|
||||
if (skip_decode_check) return;
|
||||
|
||||
// Verify that the encoded filter contains exactly N elements. If it has too much or too little
|
||||
// data, a std::ios_base::failure exception will be raised.
|
||||
BitStreamReader<SpanReader> bitreader{stream};
|
||||
|
@ -219,14 +221,14 @@ static GCSFilter::ElementSet BasicFilterElements(const CBlock& block,
|
|||
}
|
||||
|
||||
BlockFilter::BlockFilter(BlockFilterType filter_type, const uint256& block_hash,
|
||||
std::vector<unsigned char> filter)
|
||||
std::vector<unsigned char> filter, bool skip_decode_check)
|
||||
: m_filter_type(filter_type), m_block_hash(block_hash)
|
||||
{
|
||||
GCSFilter::Params params;
|
||||
if (!BuildParams(params)) {
|
||||
throw std::invalid_argument("unknown filter_type");
|
||||
}
|
||||
m_filter = GCSFilter(params, std::move(filter));
|
||||
m_filter = GCSFilter(params, std::move(filter), skip_decode_check);
|
||||
}
|
||||
|
||||
BlockFilter::BlockFilter(BlockFilterType filter_type, const CBlock& block, const CBlockUndo& block_undo)
|
||||
|
|
|
@ -59,7 +59,7 @@ public:
|
|||
explicit GCSFilter(const Params& params = Params());
|
||||
|
||||
/** Reconstructs an already-created filter from an encoding. */
|
||||
GCSFilter(const Params& params, std::vector<unsigned char> encoded_filter);
|
||||
GCSFilter(const Params& params, std::vector<unsigned char> encoded_filter, bool skip_decode_check);
|
||||
|
||||
/** Builds a new filter from the params and set of elements. */
|
||||
GCSFilter(const Params& params, const ElementSet& elements);
|
||||
|
@ -122,7 +122,7 @@ public:
|
|||
|
||||
//! Reconstruct a BlockFilter from parts.
|
||||
BlockFilter(BlockFilterType filter_type, const uint256& block_hash,
|
||||
std::vector<unsigned char> filter);
|
||||
std::vector<unsigned char> filter, bool skip_decode_check);
|
||||
|
||||
//! Construct a new BlockFilter of the specified type from a block.
|
||||
BlockFilter(BlockFilterType filter_type, const CBlock& block, const CBlockUndo& block_undo);
|
||||
|
@ -164,7 +164,7 @@ public:
|
|||
if (!BuildParams(params)) {
|
||||
throw std::ios_base::failure("unknown filter_type");
|
||||
}
|
||||
m_filter = GCSFilter(params, std::move(encoded_filter));
|
||||
m_filter = GCSFilter(params, std::move(encoded_filter), /*skip_decode_check=*/false);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include <map>
|
||||
|
||||
#include <dbwrapper.h>
|
||||
#include <hash.h>
|
||||
#include <index/blockfilterindex.h>
|
||||
#include <node/blockstorage.h>
|
||||
#include <util/system.h>
|
||||
|
@ -143,18 +144,22 @@ bool BlockFilterIndex::CommitInternal(CDBBatch& batch)
|
|||
return BaseIndex::CommitInternal(batch);
|
||||
}
|
||||
|
||||
bool BlockFilterIndex::ReadFilterFromDisk(const FlatFilePos& pos, BlockFilter& filter) const
|
||||
bool BlockFilterIndex::ReadFilterFromDisk(const FlatFilePos& pos, const uint256& hash, BlockFilter& filter) const
|
||||
{
|
||||
CAutoFile filein(m_filter_fileseq->Open(pos, true), SER_DISK, CLIENT_VERSION);
|
||||
if (filein.IsNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check that the hash of the encoded_filter matches the one stored in the db.
|
||||
uint256 block_hash;
|
||||
std::vector<uint8_t> encoded_filter;
|
||||
try {
|
||||
filein >> block_hash >> encoded_filter;
|
||||
filter = BlockFilter(GetFilterType(), block_hash, std::move(encoded_filter));
|
||||
uint256 result;
|
||||
CHash256().Write(encoded_filter).Finalize(result);
|
||||
if (result != hash) return error("Checksum mismatch in filter decode.");
|
||||
filter = BlockFilter(GetFilterType(), block_hash, std::move(encoded_filter), /*skip_decode_check=*/true);
|
||||
}
|
||||
catch (const std::exception& e) {
|
||||
return error("%s: Failed to deserialize block filter from disk: %s", __func__, e.what());
|
||||
|
@ -381,7 +386,7 @@ bool BlockFilterIndex::LookupFilter(const CBlockIndex* block_index, BlockFilter&
|
|||
return false;
|
||||
}
|
||||
|
||||
return ReadFilterFromDisk(entry.pos, filter_out);
|
||||
return ReadFilterFromDisk(entry.pos, entry.hash, filter_out);
|
||||
}
|
||||
|
||||
bool BlockFilterIndex::LookupFilterHeader(const CBlockIndex* block_index, uint256& header_out)
|
||||
|
@ -425,7 +430,7 @@ bool BlockFilterIndex::LookupFilterRange(int start_height, const CBlockIndex* st
|
|||
filters_out.resize(entries.size());
|
||||
auto filter_pos_it = filters_out.begin();
|
||||
for (const auto& entry : entries) {
|
||||
if (!ReadFilterFromDisk(entry.pos, *filter_pos_it)) {
|
||||
if (!ReadFilterFromDisk(entry.pos, entry.hash, *filter_pos_it)) {
|
||||
return false;
|
||||
}
|
||||
++filter_pos_it;
|
||||
|
|
|
@ -31,7 +31,7 @@ private:
|
|||
FlatFilePos m_next_filter_pos;
|
||||
std::unique_ptr<FlatFileSeq> m_filter_fileseq;
|
||||
|
||||
bool ReadFilterFromDisk(const FlatFilePos& pos, BlockFilter& filter) const;
|
||||
bool ReadFilterFromDisk(const FlatFilePos& pos, const uint256& hash, BlockFilter& filter) const;
|
||||
size_t WriteFilterToDisk(FlatFilePos& pos, const BlockFilter& filter);
|
||||
|
||||
Mutex m_cs_headers_cache;
|
||||
|
|
Loading…
Add table
Reference in a new issue