Skip to content

Commit d93c4c1

Browse files
ryanofskyEmpact
andcommitted
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 <[email protected]>
1 parent 700c42b commit d93c4c1

File tree

5 files changed

+43
-17
lines changed

5 files changed

+43
-17
lines changed

src/interfaces/chain.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,18 @@ class LockImpl : public Chain::Lock
4646
assert(block != nullptr);
4747
return block->GetBlockHash();
4848
}
49+
int64_t getBlockTime(int height) override
50+
{
51+
CBlockIndex* block = ::chainActive[height];
52+
assert(block != nullptr);
53+
return block->GetBlockTime();
54+
}
55+
int64_t getBlockMedianTimePast(int height) override
56+
{
57+
CBlockIndex* block = ::chainActive[height];
58+
assert(block != nullptr);
59+
return block->GetMedianTimePast();
60+
}
4961
};
5062

5163
class LockingStateImpl : public LockImpl, public UniqueLock<CCriticalSection>

src/interfaces/chain.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <optional.h>
99

1010
#include <memory>
11+
#include <stdint.h>
1112
#include <string>
1213
#include <vector>
1314

@@ -48,6 +49,13 @@ class Chain
4849

4950
//! Get block hash. Height must be valid or this function will abort.
5051
virtual uint256 getBlockHash(int height) = 0;
52+
53+
//! Get block time. Height must be valid or this function will abort.
54+
virtual int64_t getBlockTime(int height) = 0;
55+
56+
//! Get block median time past. Height must be valid or this function
57+
//! will abort.
58+
virtual int64_t getBlockMedianTimePast(int height) = 0;
5159
};
5260

5361
//! Return Lock interface. Chain is locked when this is called, and

src/interfaces/wallet.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,13 @@ class WalletImpl : public Wallet
333333
if (mi == m_wallet.mapWallet.end()) {
334334
return false;
335335
}
336-
num_blocks = locked_chain->getHeight().value_or(-1);
337-
block_time = ::chainActive.Tip()->GetBlockTime();
336+
if (Optional<int> height = locked_chain->getHeight()) {
337+
num_blocks = *height;
338+
block_time = locked_chain->getBlockTime(*height);
339+
} else {
340+
num_blocks = -1;
341+
block_time = -1;
342+
}
338343
tx_status = MakeWalletTxStatus(*locked_chain, mi->second);
339344
return true;
340345
}

src/wallet/rpcdump.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,8 @@ UniValue importwallet(const JSONRPCRequest& request)
569569
if (!file.is_open()) {
570570
throw JSONRPCError(RPC_INVALID_PARAMETER, "Cannot open wallet dump file");
571571
}
572-
nTimeBegin = chainActive.Tip()->GetBlockTime();
572+
Optional<int> tip_height = locked_chain->getHeight();
573+
nTimeBegin = tip_height ? locked_chain->getBlockTime(*tip_height) : 0;
573574

574575
int64_t nFilesize = std::max((int64_t)1, (int64_t)file.tellg());
575576
file.seekg(0, file.beg);
@@ -774,7 +775,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
774775
file << strprintf("# * Created on %s\n", FormatISO8601DateTime(GetTime()));
775776
const Optional<int> tip_height = locked_chain->getHeight();
776777
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)");
777-
file << strprintf("# mined on %s\n", FormatISO8601DateTime(chainActive.Tip()->GetBlockTime()));
778+
file << strprintf("# mined on %s\n", tip_height ? FormatISO8601DateTime(locked_chain->getBlockTime(*tip_height)) : "(missing block time)");
778779
file << "\n";
779780

780781
// add the base58check encoded extended master if the wallet uses HD
@@ -1232,15 +1233,16 @@ UniValue importmulti(const JSONRPCRequest& mainRequest)
12321233
EnsureWalletIsUnlocked(pwallet);
12331234

12341235
// Verify all timestamps are present before importing any keys.
1235-
now = chainActive.Tip() ? chainActive.Tip()->GetMedianTimePast() : 0;
1236+
const Optional<int> tip_height = locked_chain->getHeight();
1237+
now = tip_height ? locked_chain->getBlockMedianTimePast(*tip_height) : 0;
12361238
for (const UniValue& data : requests.getValues()) {
12371239
GetImportTimestamp(data, now);
12381240
}
12391241

12401242
const int64_t minimumTimestamp = 1;
12411243

1242-
if (fRescan && chainActive.Tip()) {
1243-
nLowestTimestamp = chainActive.Tip()->GetBlockTime();
1244+
if (fRescan && tip_height) {
1245+
nLowestTimestamp = locked_chain->getBlockTime(*tip_height);
12441246
} else {
12451247
fRescan = false;
12461248
}

src/wallet/wallet.cpp

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3715,11 +3715,12 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<C
37153715
}
37163716

37173717
// map in which we'll infer heights of other keys
3718-
CBlockIndex *pindexMax = chainActive[std::max(0, chainActive.Height() - 144)]; // the tip can be reorganized; use a 144-block safety margin
3719-
std::map<CKeyID, CBlockIndex*> mapKeyFirstBlock;
3718+
const Optional<int> tip_height = locked_chain.getHeight();
3719+
const int max_height = tip_height && *tip_height > 144 ? *tip_height - 144 : 0; // the tip can be reorganized; use a 144-block safety margin
3720+
std::map<CKeyID, int> mapKeyFirstBlock;
37203721
for (const CKeyID &keyid : GetKeys()) {
37213722
if (mapKeyBirth.count(keyid) == 0)
3722-
mapKeyFirstBlock[keyid] = pindexMax;
3723+
mapKeyFirstBlock[keyid] = max_height;
37233724
}
37243725

37253726
// if there are no such keys, we're done
@@ -3730,25 +3731,23 @@ void CWallet::GetKeyBirthTimes(interfaces::Chain::Lock& locked_chain, std::map<C
37303731
for (const auto& entry : mapWallet) {
37313732
// iterate over all wallet transactions...
37323733
const CWalletTx &wtx = entry.second;
3733-
CBlockIndex* pindex = LookupBlockIndex(wtx.hashBlock);
3734-
if (pindex && chainActive.Contains(pindex)) {
3734+
if (Optional<int> height = locked_chain.getBlockHeight(wtx.hashBlock)) {
37353735
// ... which are already in a block
3736-
int nHeight = pindex->nHeight;
37373736
for (const CTxOut &txout : wtx.tx->vout) {
37383737
// iterate over all their outputs
37393738
for (const auto &keyid : GetAffectedKeys(txout.scriptPubKey, *this)) {
37403739
// ... and all their affected keys
3741-
std::map<CKeyID, CBlockIndex*>::iterator rit = mapKeyFirstBlock.find(keyid);
3742-
if (rit != mapKeyFirstBlock.end() && nHeight < rit->second->nHeight)
3743-
rit->second = pindex;
3740+
std::map<CKeyID, int>::iterator rit = mapKeyFirstBlock.find(keyid);
3741+
if (rit != mapKeyFirstBlock.end() && *height < rit->second)
3742+
rit->second = *height;
37443743
}
37453744
}
37463745
}
37473746
}
37483747

37493748
// Extract block timestamps for those keys
37503749
for (const auto& entry : mapKeyFirstBlock)
3751-
mapKeyBirth[entry.first] = entry.second->GetBlockTime() - TIMESTAMP_WINDOW; // block times can be 2h off
3750+
mapKeyBirth[entry.first] = locked_chain.getBlockTime(entry.second) - TIMESTAMP_WINDOW; // block times can be 2h off
37523751
}
37533752

37543753
/**

0 commit comments

Comments
 (0)