aboutsummaryrefslogtreecommitdiff
path: root/src/interfaces
diff options
context:
space:
mode:
authorRussell Yanofsky <russ@yanofsky.org>2019-01-07 22:56:46 -0800
committerRussell Yanofsky <russ@yanofsky.org>2019-01-15 08:42:00 -0800
commit2ffb07929ef480bd114defdc10b6a84463f222be (patch)
tree49199da132e8043f486a6d9702b2b22bdda9a9fc /src/interfaces
parentd93c4c1d6e0aab5f32306ecd7c1237257b26940d (diff)
downloadbitcoin-2ffb07929ef480bd114defdc10b6a84463f222be.tar.xz
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>
Diffstat (limited to 'src/interfaces')
-rw-r--r--src/interfaces/chain.cpp39
-rw-r--r--src/interfaces/chain.h19
2 files changed, 58 insertions, 0 deletions
diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp
index ca2533bb1d..6e2224bc3e 100644
--- a/src/interfaces/chain.cpp
+++ b/src/interfaces/chain.cpp
@@ -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
diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h
index 1db9d3861d..8c7bd8c6ea 100644
--- a/src/interfaces/chain.h
+++ b/src/interfaces/chain.h
@@ -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