Skip to content

Commit 44de156

Browse files
ryanofskyEmpact
andcommitted
Remove remaining chainActive references from CWallet
This commit does not change behavior. Co-authored-by: Ben Woosley <[email protected]>
1 parent db21f02 commit 44de156

File tree

4 files changed

+67
-23
lines changed

4 files changed

+67
-23
lines changed

src/interfaces/chain.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ class LockImpl : public Chain::Lock
6060
assert(block != nullptr);
6161
return block->GetMedianTimePast();
6262
}
63+
bool haveBlockOnDisk(int height) override
64+
{
65+
CBlockIndex* block = ::chainActive[height];
66+
return block && ((block->nStatus & BLOCK_HAVE_DATA) != 0) && block->nTx > 0;
67+
}
6368
Optional<int> findFirstBlockWithTime(int64_t time, uint256* hash) override
6469
{
6570
CBlockIndex* block = ::chainActive.FindEarliestAtLeast(time);
@@ -112,6 +117,21 @@ class LockImpl : public Chain::Lock
112117
}
113118
return nullopt;
114119
}
120+
bool isPotentialTip(const uint256& hash) override
121+
{
122+
if (::chainActive.Tip()->GetBlockHash() == hash) return true;
123+
CBlockIndex* block = LookupBlockIndex(hash);
124+
return block && block->GetAncestor(::chainActive.Height()) == ::chainActive.Tip();
125+
}
126+
CBlockLocator getLocator() override { return ::chainActive.GetLocator(); }
127+
Optional<int> findLocatorFork(const CBlockLocator& locator) override
128+
{
129+
LockAnnotation lock(::cs_main);
130+
if (CBlockIndex* fork = FindForkInGlobalIndex(::chainActive, locator)) {
131+
return fork->nHeight;
132+
}
133+
return nullopt;
134+
}
115135
};
116136

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

src/interfaces/chain.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
class CBlock;
1616
class CScheduler;
1717
class uint256;
18+
struct CBlockLocator;
1819

1920
namespace interfaces {
2021

@@ -58,6 +59,10 @@ class Chain
5859
//! will abort.
5960
virtual int64_t getBlockMedianTimePast(int height) = 0;
6061

62+
//! Check that the block is available on disk (i.e. has not been
63+
//! pruned), and contains transactions.
64+
virtual bool haveBlockOnDisk(int height) = 0;
65+
6166
//! Return height of the first block in the chain with timestamp equal
6267
//! or greater than the given time, or nullopt if there is no block with
6368
//! a high enough timestamp. Also return the block hash as an optional
@@ -84,6 +89,19 @@ class Chain
8489
//! parameter (to avoid the cost of a second hash lookup in case this
8590
//! information is desired).
8691
virtual Optional<int> findFork(const uint256& hash, Optional<int>* height) = 0;
92+
93+
//! Return true if block hash points to the current chain tip, or to a
94+
//! possible descendant of the current chain tip that isn't currently
95+
//! connected.
96+
virtual bool isPotentialTip(const uint256& hash) = 0;
97+
98+
//! Get locator for the current chain tip.
99+
virtual CBlockLocator getLocator() = 0;
100+
101+
//! Return height of the latest block common to locator and chain, which
102+
//! is guaranteed to be an ancestor of the block used to create the
103+
//! locator.
104+
virtual Optional<int> findLocatorFork(const CBlockLocator& locator) = 0;
87105
};
88106

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

src/wallet/wallet.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,7 +1166,7 @@ void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const
11661166
TransactionRemovedFromMempool(pblock->vtx[i]);
11671167
}
11681168

1169-
m_last_block_processed = pindex;
1169+
m_last_block_processed = pindex->GetBlockHash();
11701170
}
11711171

11721172
void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) {
@@ -1191,9 +1191,8 @@ void CWallet::BlockUntilSyncedToCurrentChain() {
11911191
// protected by cs_wallet instead of cs_main, but as long as we need
11921192
// cs_main here anyway, it's easier to just call it cs_main-protected.
11931193
auto locked_chain = chain().lock();
1194-
const CBlockIndex* initialChainTip = chainActive.Tip();
11951194

1196-
if (m_last_block_processed && m_last_block_processed->GetAncestor(initialChainTip->nHeight) == initialChainTip) {
1195+
if (!m_last_block_processed.IsNull() && locked_chain->isPotentialTip(m_last_block_processed)) {
11971196
return;
11981197
}
11991198
}
@@ -4074,7 +4073,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
40744073
}
40754074

40764075
auto locked_chain = chain.assumeLocked(); // Temporary. Removed in upcoming lock cleanup
4077-
walletInstance->ChainStateFlushed(chainActive.GetLocator());
4076+
walletInstance->ChainStateFlushed(locked_chain->getLocator());
40784077
} else if (wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS) {
40794078
// Make it impossible to disable private keys after creation
40804079
InitError(strprintf(_("Error loading %s: Private keys can only be disabled during creation"), walletFile));
@@ -4161,57 +4160,67 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
41614160
// Try to top up keypool. No-op if the wallet is locked.
41624161
walletInstance->TopUpKeyPool();
41634162

4164-
LockAnnotation lock(::cs_main); // Temporary, for FindForkInGlobalIndex below. Removed in upcoming commit.
41654163
auto locked_chain = chain.lock();
41664164
LOCK(walletInstance->cs_wallet);
41674165

4168-
CBlockIndex *pindexRescan = chainActive.Genesis();
4166+
int rescan_height = 0;
41694167
if (!gArgs.GetBoolArg("-rescan", false))
41704168
{
41714169
WalletBatch batch(*walletInstance->database);
41724170
CBlockLocator locator;
4173-
if (batch.ReadBestBlock(locator))
4174-
pindexRescan = FindForkInGlobalIndex(chainActive, locator);
4171+
if (batch.ReadBestBlock(locator)) {
4172+
if (const Optional<int> fork_height = locked_chain->findLocatorFork(locator)) {
4173+
rescan_height = *fork_height;
4174+
}
4175+
}
41754176
}
41764177

4177-
walletInstance->m_last_block_processed = chainActive.Tip();
4178+
const Optional<int> tip_height = locked_chain->getHeight();
4179+
if (tip_height) {
4180+
walletInstance->m_last_block_processed = locked_chain->getBlockHash(*tip_height);
4181+
} else {
4182+
walletInstance->m_last_block_processed.SetNull();
4183+
}
41784184

4179-
if (chainActive.Tip() && chainActive.Tip() != pindexRescan)
4185+
if (tip_height && *tip_height != rescan_height)
41804186
{
41814187
//We can't rescan beyond non-pruned blocks, stop and throw an error
41824188
//this might happen if a user uses an old wallet within a pruned node
41834189
// or if he ran -disablewallet for a longer time, then decided to re-enable
41844190
if (fPruneMode)
41854191
{
4186-
CBlockIndex *block = chainActive.Tip();
4187-
while (block && block->pprev && (block->pprev->nStatus & BLOCK_HAVE_DATA) && block->pprev->nTx > 0 && pindexRescan != block)
4188-
block = block->pprev;
4192+
int block_height = *tip_height;
4193+
while (block_height > 0 && locked_chain->haveBlockOnDisk(block_height - 1) && rescan_height != block_height) {
4194+
--block_height;
4195+
}
41894196

4190-
if (pindexRescan != block) {
4197+
if (rescan_height != block_height) {
41914198
InitError(_("Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node)"));
41924199
return nullptr;
41934200
}
41944201
}
41954202

41964203
uiInterface.InitMessage(_("Rescanning..."));
4197-
walletInstance->WalletLogPrintf("Rescanning last %i blocks (from block %i)...\n", chainActive.Height() - pindexRescan->nHeight, pindexRescan->nHeight);
4204+
walletInstance->WalletLogPrintf("Rescanning last %i blocks (from block %i)...\n", *tip_height - rescan_height, rescan_height);
41984205

41994206
// No need to read and scan block if block was created before
42004207
// our wallet birthday (as adjusted for block time variability)
4201-
while (pindexRescan && walletInstance->nTimeFirstKey && (pindexRescan->GetBlockTime() < (walletInstance->nTimeFirstKey - TIMESTAMP_WINDOW))) {
4202-
pindexRescan = chainActive.Next(pindexRescan);
4208+
if (walletInstance->nTimeFirstKey) {
4209+
if (Optional<int> first_block = locked_chain->findFirstBlockWithTimeAndHeight(walletInstance->nTimeFirstKey - TIMESTAMP_WINDOW, rescan_height)) {
4210+
rescan_height = *first_block;
4211+
}
42034212
}
42044213

42054214
nStart = GetTimeMillis();
42064215
{
42074216
WalletRescanReserver reserver(walletInstance.get());
4208-
if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(pindexRescan->GetBlockHash(), {} /* stop block */, reserver, true /* update */).status)) {
4217+
if (!reserver.reserve() || (ScanResult::SUCCESS != walletInstance->ScanForWalletTransactions(locked_chain->getBlockHash(rescan_height), {} /* stop block */, reserver, true /* update */).status)) {
42094218
InitError(_("Failed to rescan the wallet during initialization"));
42104219
return nullptr;
42114220
}
42124221
}
42134222
walletInstance->WalletLogPrintf("Rescan completed in %15dms\n", GetTimeMillis() - nStart);
4214-
walletInstance->ChainStateFlushed(chainActive.GetLocator());
4223+
walletInstance->ChainStateFlushed(locked_chain->getLocator());
42154224
walletInstance->database->IncrementUpdateCounter();
42164225

42174226
// Restore wallet transaction metadata after -zapwallettxes=1

src/wallet/wallet.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ static const bool DEFAULT_DISABLE_WALLET = false;
9595
//! Pre-calculated constants for input size estimation in *virtual size*
9696
static constexpr size_t DUMMY_NESTED_P2WPKH_INPUT_SIZE = 91;
9797

98-
class CBlockIndex;
9998
class CCoinControl;
10099
class COutput;
101100
class CReserveKey;
@@ -723,10 +722,8 @@ class CWallet final : public CCryptoKeyStore, public CValidationInterface
723722
* Note that this is *not* how far we've processed, we may need some rescan
724723
* to have seen all transactions in the chain, but is only used to track
725724
* live BlockConnected callbacks.
726-
*
727-
* Protected by cs_main (see BlockUntilSyncedToCurrentChain)
728725
*/
729-
const CBlockIndex* m_last_block_processed = nullptr;
726+
uint256 m_last_block_processed;
730727

731728
public:
732729
/*

0 commit comments

Comments
 (0)