Add findFork and findBlock to the Chain interface

And use them to remove uses of chainActive and mapBlockIndex in wallet code

This commit does not change behavior.

Co-authored-by: Ben Woosley <ben.woosley@gmail.com>
This commit is contained in:
Russell Yanofsky
2019-01-07 22:56:46 -08:00
parent d93c4c1d6e
commit 2ffb07929e
4 changed files with 75 additions and 19 deletions

View File

@@ -5,6 +5,8 @@
#include <interfaces/chain.h>
#include <chain.h>
#include <chainparams.h>
#include <primitives/block.h>
#include <sync.h>
#include <uint256.h>
#include <util/system.h>
@@ -58,6 +60,22 @@ class LockImpl : public Chain::Lock
assert(block != nullptr);
return block->GetMedianTimePast();
}
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;
}
};
class LockingStateImpl : public LockImpl, public UniqueLock<CCriticalSection>
@@ -77,6 +95,27 @@ 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;
}
};
} // namespace

View File

@@ -12,6 +12,7 @@
#include <string>
#include <vector>
class CBlock;
class CScheduler;
class uint256;
@@ -56,6 +57,13 @@ public:
//! Get block median time past. Height must be valid or this function
//! will abort.
virtual int64_t getBlockMedianTimePast(int height) = 0;
//! Return height of the highest block on the chain that is an ancestor
//! of the specified block, or nullopt if no common ancestor is found.
//! Also return the height of the specified block as an optional output
//! parameter (to avoid the cost of a second hash lookup in case this
//! information is desired).
virtual Optional<int> findFork(const uint256& hash, Optional<int>* height) = 0;
};
//! Return Lock interface. Chain is locked when this is called, and
@@ -66,6 +74,17 @@ public:
//! method is temporary and is only used in a few places to avoid changing
//! behavior while code is transitioned to use the Chain::Lock interface.
virtual std::unique_ptr<Lock> assumeLocked() = 0;
//! Return whether node has the block and optionally return block metadata
//! or contents.
//!
//! If a block pointer is provided to retrieve the block contents, and the
//! block exists but doesn't have data (for example due to pruning), the
//! block will be empty and all fields set to null.
virtual bool findBlock(const uint256& hash,
CBlock* block = nullptr,
int64_t* time = nullptr,
int64_t* max_time = nullptr) = 0;
};
//! Interface to let node manage chain clients (wallets, or maybe tools for