diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -175,12 +175,26 @@ virtual bool findBlock(const BlockHash &hash, const FoundBlock &block = {}) = 0; + //! Find ancestor of block at specified height and optionally return + //! ancestor information. + virtual bool findAncestorByHeight(const BlockHash &block_hash, + int ancestor_height, + const FoundBlock &ancestor_out = {}) = 0; + //! Return whether block descends from a specified ancestor, and //! optionally return ancestor information. virtual bool findAncestorByHash(const BlockHash &block_hash, const BlockHash &ancestor_hash, const FoundBlock &ancestor_out = {}) = 0; + //! Find most recent common ancestor between two blocks and optionally + //! return block information. + virtual bool findCommonAncestor(const BlockHash &block_hash1, + const BlockHash &block_hash2, + const FoundBlock &ancestor_out = {}, + const FoundBlock &block1_out = {}, + const FoundBlock &block2_out = {}) = 0; + //! Look up unspent output information. Returns coins in the mempool and in //! the current chain UTXO set. Iterates through all the keys in the map and //! populates the values. diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -283,6 +283,18 @@ WAIT_LOCK(cs_main, lock); return FillBlock(LookupBlockIndex(hash), block, lock); } + bool findAncestorByHeight(const BlockHash &block_hash, + int ancestor_height, + const FoundBlock &ancestor_out) override { + WAIT_LOCK(cs_main, lock); + if (const CBlockIndex *block = LookupBlockIndex(block_hash)) { + if (const CBlockIndex *ancestor = + block->GetAncestor(ancestor_height)) { + return FillBlock(ancestor, ancestor_out, lock); + } + } + return FillBlock(nullptr, ancestor_out, lock); + } bool findAncestorByHash(const BlockHash &block_hash, const BlockHash &ancestor_hash, const FoundBlock &ancestor_out) override { @@ -295,6 +307,20 @@ } return FillBlock(ancestor, ancestor_out, lock); } + bool findCommonAncestor(const BlockHash &block_hash1, + const BlockHash &block_hash2, + const FoundBlock &ancestor_out, + const FoundBlock &block1_out, + const FoundBlock &block2_out) override { + WAIT_LOCK(cs_main, lock); + const CBlockIndex *block1 = LookupBlockIndex(block_hash1); + const CBlockIndex *block2 = LookupBlockIndex(block_hash2); + const CBlockIndex *ancestor = + block1 && block2 ? LastCommonAncestor(block1, block2) : nullptr; + return FillBlock(ancestor, ancestor_out, lock) & + FillBlock(block1, block1_out, lock) & + FillBlock(block2, block2_out, lock); + } void findCoins(std::map &coins) override { return FindCoins(coins); } diff --git a/src/test/interfaces_tests.cpp b/src/test/interfaces_tests.cpp --- a/src/test/interfaces_tests.cpp +++ b/src/test/interfaces_tests.cpp @@ -3,7 +3,10 @@ // file COPYING or http://www.opensource.org/licenses/mit-license.php. #include +#include +#include #include +#include