From d93c4c1d6e0aab5f32306ecd7c1237257b26940d Mon Sep 17 00:00:00 2001 From: Russell Yanofsky Date: Mon, 7 Jan 2019 22:35:47 -0800 Subject: Add time methods 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 --- src/interfaces/chain.cpp | 12 ++++++++++++ src/interfaces/chain.h | 8 ++++++++ src/interfaces/wallet.cpp | 9 +++++++-- src/wallet/rpcdump.cpp | 12 +++++++----- src/wallet/wallet.cpp | 19 +++++++++---------- 5 files changed, 43 insertions(+), 17 deletions(-) diff --git a/src/interfaces/chain.cpp b/src/interfaces/chain.cpp index 138d1bfd5f..ca2533bb1d 100644 --- a/src/interfaces/chain.cpp +++ b/src/interfaces/chain.cpp @@ -46,6 +46,18 @@ class LockImpl : public Chain::Lock 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(); + } }; class LockingStateImpl : public LockImpl, public UniqueLock diff --git a/src/interfaces/chain.h b/src/interfaces/chain.h index 928b8af1f4..1db9d3861d 100644 --- a/src/interfaces/chain.h +++ b/src/interfaces/chain.h @@ -8,6 +8,7 @@ #include #include +#include #include #include @@ -48,6 +49,13 @@ public: //! Get block hash. Height must be valid or this function will abort. virtual uint256 getBlockHash(int height) = 0; + + //! Get block time. Height must be valid or this function will abort. + virtual int64_t getBlockTime(int height) = 0; + + //! Get block median time past. Height must be valid or this function + //! will abort. + virtual int64_t getBlockMedianTimePast(int height) = 0; }; //! Return Lock interface. Chain is locked when this is called, and diff --git a/src/interfaces/wallet.cpp b/src/interfaces/wallet.cpp index 489cf0981c..88c5db73a1 100644 --- a/src/interfaces/wallet.cpp +++ b/src/interfaces/wallet.cpp @@ -333,8 +333,13 @@ public: if (mi == m_wallet.mapWallet.end()) { return false; } - num_blocks = locked_chain->getHeight().value_or(-1); - block_time = ::chainActive.Tip()->GetBlockTime(); + if (Optional height = locked_chain->getHeight()) { + num_blocks = *height; + block_time = locked_chain->getBlockTime(*height); + } else { + num_blocks = -1; + block_time = -1; + } tx_status = MakeWalletTxStatus(*locked_chain, mi->second); return true; } diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index f2b91e7c3d..c24703968d 100644 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -569,7 +569,8 @@ UniValue importwallet(const JSONRPCRequest& request) if (!file.is_open()) { throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file"); } - nTimeBegin = chainActive.Tip()->GetBlockTime(); + Optional tip_height = locked_chain->getHeight(); + nTimeBegin = tip_height ? locked_chain->getBlockTime(*tip_height) : 0; int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg()); file.seekg(0, file.beg); @@ -774,7 +775,7 @@ UniValue dumpwallet(const JSONRPCRequest& request) file << strprintf("# * Created on %s\n", FormatISO8601DateTime(GetTime())); const Optional tip_height = locked_chain->getHeight(); file << strprintf("# * Best block at time of backup was %i (%s),\n", tip_height.value_or(-1), tip_height ? locked_chain->getBlockHash(*tip_height).ToString() : "(missing block hash)"); - file << strprintf("# mined on %s\n", FormatISO8601DateTime(chainActive.Tip()->GetBlockTime())); + file << strprintf("# mined on %s\n", tip_height ? FormatISO8601DateTime(locked_chain->getBlockTime(*tip_height)) : "(missing block time)"); file << "\n"; // add the base58check encoded extended master if the wallet uses HD @@ -1232,15 +1233,16 @@ UniValue importmulti(const JSONRPCRequest& mainRequest) EnsureWalletIsUnlocked(pwallet); // Verify all timestamps are present before importing any keys. - now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0; + const Optional tip_height = locked_chain->getHeight(); + now = tip_height ? locked_chain->getBlockMedianTimePast(*tip_height) : 0; for (const UniValue& data : requests.getValues()) { GetImportTimestamp(data, now); } const int64_t minimumTimestamp = 1; - if (fRescan && chainActive.Tip()) { - nLowestTimestamp = chainActive.Tip()->GetBlockTime(); + if (fRescan && tip_height) { + nLowestTimestamp = locked_chain->getBlockTime(*tip_height); } else { fRescan = false; } diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index c34295a11a..35660372cf 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -3715,11 +3715,12 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map mapKeyFirstBlock; + const Optional tip_height = locked_chain.getHeight(); + const int max_height = tip_height && *tip_height > 144 ? *tip_height - 144 : 0; // the tip can be reorganized; use a 144-block safety margin + std::map mapKeyFirstBlock; for (const CKeyID &keyid : GetKeys()) { if (mapKeyBirth.count(keyid) == 0) - mapKeyFirstBlock[keyid] = pindexMax; + mapKeyFirstBlock[keyid] = max_height; } // if there are no such keys, we're done @@ -3730,17 +3731,15 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map height = locked_chain.getBlockHeight(wtx.hashBlock)) { // ... which are already in a block - int nHeight = pindex->nHeight; for (const CTxOut &txout : wtx.tx->vout) { // iterate over all their outputs for (const auto &keyid : GetAffectedKeys(txout.scriptPubKey, *this)) { // ... and all their affected keys - std::map::iterator rit = mapKeyFirstBlock.find(keyid); - if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight) - rit->second = pindex; + std::map::iterator rit = mapKeyFirstBlock.find(keyid); + if (rit != mapKeyFirstBlock.end() && *height < rit->second) + rit->second = *height; } } } @@ -3748,7 +3747,7 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::mapGetBlockTime() - TIMESTAMP_WINDOW; // block times can be 2h off + mapKeyBirth[entry.first] = locked_chain.getBlockTime(entry.second) - TIMESTAMP_WINDOW; // block times can be 2h off } /** -- cgit v1.2.3