From 088e38d3bbea9694b319bc34e0d2e70d210c38b4 Mon Sep 17 00:00:00 2001 From: Sebastian Falbesoner Date: Tue, 23 Aug 2022 16:10:59 +0200 Subject: [PATCH] add chain interface methods for using BIP 157 block filters This is useful for speeding up wallet rescans and is based on an earlier version from PR #15845 ("wallet: Fast rescan with BIP157 block filters"), which was never merged. Co-authored-by: MacroFake --- src/interfaces/chain.h | 8 ++++++++ src/node/interfaces.cpp | 16 ++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index 5fc0e540a94..7a3d88b18f5 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -5,6 +5,7 @@ #ifndef BITCOIN_INTERFACES_CHAIN_H #define BITCOIN_INTERFACES_CHAIN_H +#include #include // For CTransactionRef #include // For util::SettingsValue @@ -143,6 +144,13 @@ public: //! or one of its ancestors. virtual std::optional findLocatorFork(const CBlockLocator& locator) = 0; + //! Returns whether a block filter index is available. + virtual bool hasBlockFilterIndex(BlockFilterType filter_type) = 0; + + //! Returns whether any of the elements match the block via a BIP 157 block filter + //! or std::nullopt if the block filter for this block couldn't be found. + virtual std::optional blockFilterMatchesAny(BlockFilterType filter_type, const uint256& block_hash, const GCSFilter::ElementSet& filter_set) = 0; + //! Return whether node has the block and optionally return block metadata //! or contents. virtual bool findBlock(const uint256& hash, const FoundBlock& block={}) = 0; diff --git a/src/node/interfaces.cpp b/src/node/interfaces.cpp index 8a0011a629e..979c6254633 100644 --- a/src/node/interfaces.cpp +++ b/src/node/interfaces.cpp @@ -4,10 +4,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -536,6 +538,20 @@ public: } return std::nullopt; } + bool hasBlockFilterIndex(BlockFilterType filter_type) override + { + return GetBlockFilterIndex(filter_type) != nullptr; + } + std::optional blockFilterMatchesAny(BlockFilterType filter_type, const uint256& block_hash, const GCSFilter::ElementSet& filter_set) override + { + const BlockFilterIndex* block_filter_index{GetBlockFilterIndex(filter_type)}; + if (!block_filter_index) return std::nullopt; + + BlockFilter filter; + const CBlockIndex* index{WITH_LOCK(::cs_main, return chainman().m_blockman.LookupBlockIndex(block_hash))}; + if (index == nullptr || !block_filter_index->LookupFilter(index, filter)) return std::nullopt; + return filter.GetFilter().MatchAny(filter_set); + } bool findBlock(const uint256& hash, const FoundBlock& block) override { WAIT_LOCK(cs_main, lock);