diff options
Diffstat (limited to 'src/interfaces/chain.cpp')
-rw-r--r-- | src/interfaces/chain.cpp | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 2571a91031..da810bc5e6 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -4,7 +4,11 @@ #include <interfaces/chain.h> +#include <chain.h> +#include <chainparams.h> +#include <primitives/block.h> #include <sync.h> +#include <uint256.h> #include <util/system.h> #include <validation.h> @@ -16,6 +20,118 @@ namespace { class LockImpl : public Chain::Lock { + Optional<int> getHeight() override + { + int height = ::chainActive.Height(); + if (height >= 0) { + return height; + } + return nullopt; + } + Optional<int> getBlockHeight(const uint256& hash) override + { + CBlockIndex* block = LookupBlockIndex(hash); + if (block && ::chainActive.Contains(block)) { + return block->nHeight; + } + return nullopt; + } + int getBlockDepth(const uint256& hash) override + { + const Optional<int> tip_height = getHeight(); + const Optional<int> height = getBlockHeight(hash); + return tip_height && height ? *tip_height - *height + 1 : 0; + } + uint256 getBlockHash(int height) override + { + CBlockIndex* block = ::chainActive[height]; + assert(block != nullptr); + return block->GetBlockHash(); + } + int64_t getBlockTime(int height) override + { + CBlockIndex* block = ::chainActive[height]; + assert(block != nullptr); + return block->GetBlockTime(); + } + int64_t getBlockMedianTimePast(int height) override + { + CBlockIndex* block = ::chainActive[height]; + assert(block != nullptr); + return block->GetMedianTimePast(); + } + bool haveBlockOnDisk(int height) override + { + CBlockIndex* block = ::chainActive[height]; + return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0; + } + Optional<int> findFirstBlockWithTime(int64_t time, uint256* hash) override + { + CBlockIndex* block = ::chainActive.FindEarliestAtLeast(time); + if (block) { + if (hash) *hash = block->GetBlockHash(); + return block->nHeight; + } + return nullopt; + } + Optional<int> findFirstBlockWithTimeAndHeight(int64_t time, int height) override + { + // TODO: Could update CChain::FindEarliestAtLeast() to take a height + // parameter and use it with std::lower_bound() to make this + // implementation more efficient and allow combining + // findFirstBlockWithTime and findFirstBlockWithTimeAndHeight into one + // method. + for (CBlockIndex* block = ::chainActive[height]; block; block = ::chainActive.Next(block)) { + if (block->GetBlockTime() >= time) { + return block->nHeight; + } + } + return nullopt; + } + Optional<int> findPruned(int start_height, Optional<int> stop_height) override + { + if (::fPruneMode) { + CBlockIndex* block = stop_height ? ::chainActive[*stop_height] : ::chainActive.Tip(); + while (block && block->nHeight >= start_height) { + if ((block->nStatus & BLOCK_HAVE_DATA) == 0) { + return block->nHeight; + } + block = block->pprev; + } + } + return nullopt; + } + Optional<int> findFork(const uint256& hash, Optional<int>* height) override + { + const CBlockIndex* block = LookupBlockIndex(hash); + const CBlockIndex* fork = block ? ::chainActive.FindFork(block) : nullptr; + if (height) { + if (block) { + *height = block->nHeight; + } else { + height->reset(); + } + } + if (fork) { + return fork->nHeight; + } + return nullopt; + } + bool isPotentialTip(const uint256& hash) override + { + if (::chainActive.Tip()->GetBlockHash() == hash) return true; + CBlockIndex* block = LookupBlockIndex(hash); + return block && block->GetAncestor(::chainActive.Height()) == ::chainActive.Tip(); + } + CBlockLocator getTipLocator() override { return ::chainActive.GetLocator(); } + Optional<int> findLocatorFork(const CBlockLocator& locator) override + { + LockAnnotation lock(::cs_main); + if (CBlockIndex* fork = FindForkInGlobalIndex(::chainActive, locator)) { + return fork->nHeight; + } + return nullopt; + } }; class LockingStateImpl : public LockImpl, public UniqueLock<CCriticalSection> @@ -35,6 +151,32 @@ public: return std::move(result); } std::unique_ptr<Chain::Lock> assumeLocked() override { return MakeUnique<LockImpl>(); } + bool findBlock(const uint256& hash, CBlock* block, int64_t* time, int64_t* time_max) override + { + CBlockIndex* index; + { + LOCK(cs_main); + index = LookupBlockIndex(hash); + if (!index) { + return false; + } + if (time) { + *time = index->GetBlockTime(); + } + if (time_max) { + *time_max = index->GetBlockTimeMax(); + } + } + if (block && !ReadBlockFromDisk(*block, index, Params().GetConsensus())) { + block->SetNull(); + } + return true; + } + double guessVerificationProgress(const uint256& block_hash) override + { + LOCK(cs_main); + return GuessVerificationProgress(Params().TxData(), LookupBlockIndex(block_hash)); + } }; } // namespace |