@ -2298,44 +2298,48 @@ void CWallet::GetKeyBirthTimes(std::map<CKeyID, int64_t>& mapKeyBirth) const {
AssertLockHeld ( cs_wallet ) ;
AssertLockHeld ( cs_wallet ) ;
mapKeyBirth . clear ( ) ;
mapKeyBirth . clear ( ) ;
LegacyScriptPubKeyMan * spk_man = GetLegacyScriptPubKeyMan ( ) ;
assert ( spk_man ! = nullptr ) ;
LOCK ( spk_man - > cs_KeyStore ) ;
// get birth times for keys with metadata
for ( const auto & entry : spk_man - > mapKeyMetadata ) {
if ( entry . second . nCreateTime ) {
mapKeyBirth [ entry . first ] = entry . second . nCreateTime ;
}
}
// map in which we'll infer heights of other keys
// map in which we'll infer heights of other keys
std : : map < CKeyID , const CWalletTx : : Confirmation * > mapKeyFirstBlock ;
std : : map < CKeyID , const CWalletTx : : Confirmation * > mapKeyFirstBlock ;
CWalletTx : : Confirmation max_confirm ;
CWalletTx : : Confirmation max_confirm ;
max_confirm . block_height = GetLastBlockHeight ( ) > 144 ? GetLastBlockHeight ( ) - 144 : 0 ; // the tip can be reorganized; use a 144-block safety margin
max_confirm . block_height = GetLastBlockHeight ( ) > 144 ? GetLastBlockHeight ( ) - 144 : 0 ; // the tip can be reorganized; use a 144-block safety margin
CHECK_NONFATAL ( chain ( ) . findAncestorByHeight ( GetLastBlockHash ( ) , max_confirm . block_height , FoundBlock ( ) . hash ( max_confirm . hashBlock ) ) ) ;
CHECK_NONFATAL ( chain ( ) . findAncestorByHeight ( GetLastBlockHash ( ) , max_confirm . block_height , FoundBlock ( ) . hash ( max_confirm . hashBlock ) ) ) ;
for ( const CKeyID & keyid : spk_man - > GetKeys ( ) ) {
if ( mapKeyBirth . count ( keyid ) = = 0 )
mapKeyFirstBlock [ keyid ] = & max_confirm ;
}
// if there are no such keys, we're done
{
if ( mapKeyFirstBlock . empty ( ) )
LegacyScriptPubKeyMan * spk_man = GetLegacyScriptPubKeyMan ( ) ;
return ;
assert ( spk_man ! = nullptr ) ;
LOCK ( spk_man - > cs_KeyStore ) ;
// get birth times for keys with metadata
for ( const auto & entry : spk_man - > mapKeyMetadata ) {
if ( entry . second . nCreateTime ) {
mapKeyBirth [ entry . first ] = entry . second . nCreateTime ;
}
}
// Prepare to infer birth heights for keys without metadata
for ( const CKeyID & keyid : spk_man - > GetKeys ( ) ) {
if ( mapKeyBirth . count ( keyid ) = = 0 )
mapKeyFirstBlock [ keyid ] = & max_confirm ;
}
// find first block that affects those keys, if there are any left
// if there are no such keys, we're done
for ( const auto & entry : mapWallet ) {
if ( mapKeyFirstBlock . empty ( ) )
// iterate over all wallet transactions...
return ;
const CWalletTx & wtx = entry . second ;
if ( wtx . m_confirm . status = = CWalletTx : : CONFIRMED ) {
// find first block that affects those keys, if there are any left
// ... which are already in a block
for ( const auto & entry : mapWallet ) {
for ( const CTxOut & txout : wtx . tx - > vout ) {
// iterate over all wallet transactions...
// iterate over all their outputs
const CWalletTx & wtx = entry . second ;
for ( const auto & keyid : GetAffectedKeys ( txout . scriptPubKey , * spk_man ) ) {
if ( wtx . m_confirm . status = = CWalletTx : : CONFIRMED ) {
// ... and all their affected keys
// ... which are already in a block
auto rit = mapKeyFirstBlock . find ( keyid ) ;
for ( const CTxOut & txout : wtx . tx - > vout ) {
if ( rit ! = mapKeyFirstBlock . end ( ) & & wtx . m_confirm . block_height < rit - > second - > block_height ) {
// iterate over all their outputs
rit - > second = & wtx . m_confirm ;
for ( const auto & keyid : GetAffectedKeys ( txout . scriptPubKey , * spk_man ) ) {
// ... and all their affected keys
auto rit = mapKeyFirstBlock . find ( keyid ) ;
if ( rit ! = mapKeyFirstBlock . end ( ) & & wtx . m_confirm . block_height < rit - > second - > block_height ) {
rit - > second = & wtx . m_confirm ;
}
}
}
}
}
}
}