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)
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