@ -1166,7 +1166,7 @@ void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const
TransactionRemovedFromMempool ( pblock - > vtx [ i ] ) ;
TransactionRemovedFromMempool ( pblock - > vtx [ i ] ) ;
}
}
m_last_block_processed = pindex ;
m_last_block_processed = pindex - > GetBlockHash ( ) ;
}
}
void CWallet : : BlockDisconnected ( const std : : shared_ptr < const CBlock > & pblock ) {
void CWallet : : BlockDisconnected ( const std : : shared_ptr < const CBlock > & pblock ) {
@ -1191,9 +1191,8 @@ void CWallet::BlockUntilSyncedToCurrentChain() {
// protected by cs_wallet instead of cs_main, but as long as we need
// protected by cs_wallet instead of cs_main, but as long as we need
// cs_main here anyway, it's easier to just call it cs_main-protected.
// cs_main here anyway, it's easier to just call it cs_main-protected.
auto locked_chain = chain ( ) . lock ( ) ;
auto locked_chain = chain ( ) . lock ( ) ;
const CBlockIndex * initialChainTip = chainActive . Tip ( ) ;
if ( m_last_block_processed & & m_last_block_processed - > GetAncestor ( initialChainTip - > nHeight ) = = initialChainTip ) {
if ( ! m_last_block_processed . IsNull ( ) & & locked_chain - > isPotentialTip ( m_last_block_processed ) ) {
return ;
return ;
}
}
}
}
@ -4074,7 +4073,7 @@ std::shared_ptr<CWallet> CWallet::CreateWalletFromFile(interfaces::Chain& chain,
}
}
auto locked_chain = chain . assumeLocked ( ) ; // Temporary. Removed in upcoming lock cleanup
auto locked_chain = chain . assumeLocked ( ) ; // Temporary. Removed in upcoming lock cleanup
walletInstance - > ChainStateFlushed ( chainActive. G etLocator( ) ) ;
walletInstance - > ChainStateFlushed ( locked_chain- > g etLocator( ) ) ;
} else if ( wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS ) {
} else if ( wallet_creation_flags & WALLET_FLAG_DISABLE_PRIVATE_KEYS ) {
// Make it impossible to disable private keys after creation
// Make it impossible to disable private keys after creation
InitError ( strprintf ( _ ( " Error loading %s: Private keys can only be disabled during creation " ) , walletFile ) ) ;
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,
// Try to top up keypool. No-op if the wallet is locked.
// Try to top up keypool. No-op if the wallet is locked.
walletInstance - > TopUpKeyPool ( ) ;
walletInstance - > TopUpKeyPool ( ) ;
LockAnnotation lock ( : : cs_main ) ; // Temporary, for FindForkInGlobalIndex below. Removed in upcoming commit.
auto locked_chain = chain . lock ( ) ;
auto locked_chain = chain . lock ( ) ;
LOCK ( walletInstance - > cs_wallet ) ;
LOCK ( walletInstance - > cs_wallet ) ;
CBlockIndex * pindexRescan = chainActive . Genesis ( ) ;
int rescan_height = 0 ;
if ( ! gArgs . GetBoolArg ( " -rescan " , false ) )
if ( ! gArgs . GetBoolArg ( " -rescan " , false ) )
{
{
WalletBatch batch ( * walletInstance - > database ) ;
WalletBatch batch ( * walletInstance - > database ) ;
CBlockLocator locator ;
CBlockLocator locator ;
if ( batch . ReadBestBlock ( locator ) )
if ( batch . ReadBestBlock ( locator ) ) {
pindexRescan = FindForkInGlobalIndex ( chainActive , locator ) ;
if ( const Optional < int > fork_height = locked_chain - > findLocatorFork ( locator ) ) {
rescan_height = * fork_height ;
}
}
}
}
walletInstance - > m_last_block_processed = chainActive . Tip ( ) ;
const Optional < int > tip_height = locked_chain - > getHeight ( ) ;
if ( tip_height ) {
walletInstance - > m_last_block_processed = locked_chain - > getBlockHash ( * tip_height ) ;
} else {
walletInstance - > m_last_block_processed . SetNull ( ) ;
}
if ( chainActive . Tip ( ) & & chainActive . Tip ( ) ! = pindexRescan )
if ( tip_height & & * tip_height ! = rescan_height )
{
{
//We can't rescan beyond non-pruned blocks, stop and throw an error
//We can't rescan beyond non-pruned blocks, stop and throw an error
//this might happen if a user uses an old wallet within a pruned node
//this might happen if a user uses an old wallet within a pruned node
// or if he ran -disablewallet for a longer time, then decided to re-enable
// or if he ran -disablewallet for a longer time, then decided to re-enable
if ( fPruneMode )
if ( fPruneMode )
{
{
CBlockIndex * block = chainActive . Tip ( ) ;
int block_height = * tip_height ;
while ( block & & block - > pprev & & ( block - > pprev - > nStatus & BLOCK_HAVE_DATA ) & & block - > pprev - > nTx > 0 & & pindexRescan ! = block )
while ( block_height > 0 & & locked_chain - > haveBlockOnDisk ( block_height - 1 ) & & rescan_height ! = block_height ) {
block = block - > pprev ;
- - block_height ;
}
if ( pindexRescan ! = block ) {
if ( rescan_height ! = block_height ) {
InitError ( _ ( " Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) " ) ) ;
InitError ( _ ( " Prune: last wallet synchronisation goes beyond pruned data. You need to -reindex (download the whole blockchain again in case of pruned node) " ) ) ;
return nullptr ;
return nullptr ;
}
}
}
}
uiInterface . InitMessage ( _ ( " Rescanning... " ) ) ;
uiInterface . InitMessage ( _ ( " Rescanning... " ) ) ;
walletInstance - > WalletLogPrintf ( " Rescanning last %i blocks (from block %i)... \n " , chainActive . Height ( ) - pindexRescan - > nHeight , pindexRescan - > nH eight) ;
walletInstance - > WalletLogPrintf ( " Rescanning last %i blocks (from block %i)... \n " , * tip_height - rescan_height , rescan_h eight) ;
// No need to read and scan block if block was created before
// No need to read and scan block if block was created before
// our wallet birthday (as adjusted for block time variability)
// our wallet birthday (as adjusted for block time variability)
while ( pindexRescan & & walletInstance - > nTimeFirstKey & & ( pindexRescan - > GetBlockTime ( ) < ( walletInstance - > nTimeFirstKey - TIMESTAMP_WINDOW ) ) ) {
if ( walletInstance - > nTimeFirstKey ) {
pindexRescan = chainActive . Next ( pindexRescan ) ;
if ( Optional < int > first_block = locked_chain - > findFirstBlockWithTimeAndHeight ( walletInstance - > nTimeFirstKey - TIMESTAMP_WINDOW , rescan_height ) ) {
rescan_height = * first_block ;
}
}
}
nStart = GetTimeMillis ( ) ;
nStart = GetTimeMillis ( ) ;
{
{
WalletRescanReserver reserver ( walletInstance . get ( ) ) ;
WalletRescanReserver reserver ( walletInstance . get ( ) ) ;
if ( ! reserver . reserve ( ) | | ( ScanResult : : SUCCESS ! = walletInstance - > ScanForWalletTransactions ( pindexRescan- > GetBlockHash ( ) , { } /* stop block */ , reserver , true /* update */ ) . status ) ) {
if ( ! reserver . reserve ( ) | | ( ScanResult : : SUCCESS ! = walletInstance - > ScanForWalletTransactions ( locked_chain- > getBlockHash ( rescan_height ) , { } /* stop block */ , reserver , true /* update */ ) . status ) ) {
InitError ( _ ( " Failed to rescan the wallet during initialization " ) ) ;
InitError ( _ ( " Failed to rescan the wallet during initialization " ) ) ;
return nullptr ;
return nullptr ;
}
}
}
}
walletInstance - > WalletLogPrintf ( " Rescan completed in %15dms \n " , GetTimeMillis ( ) - nStart ) ;
walletInstance - > WalletLogPrintf ( " Rescan completed in %15dms \n " , GetTimeMillis ( ) - nStart ) ;
walletInstance - > ChainStateFlushed ( chainActive. G etLocator( ) ) ;
walletInstance - > ChainStateFlushed ( locked_chain- > g etLocator( ) ) ;
walletInstance - > database - > IncrementUpdateCounter ( ) ;
walletInstance - > database - > IncrementUpdateCounter ( ) ;
// Restore wallet transaction metadata after -zapwallettxes=1
// Restore wallet transaction metadata after -zapwallettxes=1