@@ -1441,7 +1441,40 @@ bool CWallet::AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlockIndex
1441
1441
}
1442
1442
}
1443
1443
}
1444
- }
1444
+ } // if tx.nversion END
1445
+ else {
1446
+ BOOST_FOREACH (const CTxOut& txout, tx.vout ) {
1447
+ CScript scriptPubKey = txout.scriptPubKey ;
1448
+ CTxDestination address1;
1449
+ bool ReserveKey = true ;
1450
+
1451
+ if (!ExtractDestination (scriptPubKey, address1)) {
1452
+ ReserveKey = false ;
1453
+ }
1454
+
1455
+ CDynamicAddress address2 (address1);
1456
+ CKeyID keyID;
1457
+
1458
+ if (!address2.GetKeyID (keyID)) {
1459
+ ReserveKey = false ;
1460
+ }
1461
+ CKey vchSecret;
1462
+ if (!GetKey (keyID, vchSecret)) {
1463
+ ReserveKey = false ;
1464
+ }
1465
+
1466
+ CPubKey retrievePubKey;
1467
+
1468
+ if (ReserveKey) {
1469
+ retrievePubKey = vchSecret.GetPubKey ();
1470
+ if (ReserveKeyForTransactions (retrievePubKey)) {
1471
+ TopUpKeyPoolCombo (0 ,true );
1472
+ fNeedToRescanTransactions = true ;
1473
+ }
1474
+ }
1475
+
1476
+ } // BOOST_FOREACH END
1477
+ }
1445
1478
1446
1479
CWalletTx wtx (this , ptx);
1447
1480
@@ -1595,7 +1628,7 @@ void CWallet::SyncTransaction(const CTransaction& tx, const CBlockIndex* pindex,
1595
1628
fAnonymizableTallyCachedNonDenom = false ;
1596
1629
1597
1630
if (fNeedToUpdateKeyPools ) {
1598
- TopUpKeyPoolCombo ();
1631
+ TopUpKeyPoolCombo (0 , true );
1599
1632
fNeedToUpdateKeyPools = false ;
1600
1633
}
1601
1634
@@ -2119,10 +2152,15 @@ CBlockIndex* CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool f
2119
2152
CBlock block;
2120
2153
if (ReadBlockFromDisk (block, pindex, Params ().GetConsensus ())) {
2121
2154
for (size_t posInBlock = 0 ; posInBlock < block.vtx .size (); ++posInBlock) {
2122
- AddToWalletIfInvolvingMe (*block.vtx [posInBlock], pindex, posInBlock, fUpdate );
2155
+ AddToWalletIfInvolvingMe (*block.vtx [posInBlock], pindex, posInBlock, fUpdate );
2156
+
2157
+ if (SaveRescanIndex) {
2158
+ rescan_index = pindex;
2159
+ SaveRescanIndex = false ;
2160
+ }
2123
2161
2124
2162
if (fNeedToUpdateKeyPools ) {
2125
- TopUpKeyPoolCombo ();
2163
+ TopUpKeyPoolCombo (0 , true );
2126
2164
fNeedToUpdateKeyPools = false ;
2127
2165
}
2128
2166
@@ -4581,7 +4619,7 @@ bool CWallet::SyncEdKeyPool()
4581
4619
4582
4620
} // SyncEdKeyPool
4583
4621
4584
- bool CWallet::TopUpKeyPoolCombo (unsigned int kpSize)
4622
+ bool CWallet::TopUpKeyPoolCombo (unsigned int kpSize, bool fIncreaseSize )
4585
4623
{
4586
4624
{
4587
4625
LOCK (cs_wallet);
@@ -4593,8 +4631,9 @@ bool CWallet::TopUpKeyPoolCombo(unsigned int kpSize)
4593
4631
unsigned int nTargetSize;
4594
4632
if (kpSize > 0 )
4595
4633
nTargetSize = kpSize;
4596
- else
4634
+ else {
4597
4635
nTargetSize = std::max (GetArg (" -keypool" , DEFAULT_KEYPOOL_SIZE), (int64_t )0 );
4636
+ }
4598
4637
4599
4638
// count amount of available keys (internal, external)
4600
4639
// make sure the keypool of external and internal keys fits the user selected target (-keypool)
@@ -4603,6 +4642,11 @@ bool CWallet::TopUpKeyPoolCombo(unsigned int kpSize)
4603
4642
int64_t missingExternal = std::max (std::max ((int64_t )nTargetSize, (int64_t )1 ) - amountExternal, (int64_t )0 );
4604
4643
int64_t missingInternal = std::max (std::max ((int64_t )nTargetSize, (int64_t )1 ) - amountInternal, (int64_t )0 );
4605
4644
4645
+ if (fIncreaseSize ) {
4646
+ missingExternal = missingExternal + 2 ;
4647
+ missingInternal = missingInternal + 2 ;
4648
+ }
4649
+
4606
4650
if (!IsHDEnabled ()) {
4607
4651
// don't create extra internal keys
4608
4652
missingInternal = 0 ;
@@ -4661,6 +4705,9 @@ bool CWallet::TopUpKeyPoolCombo(unsigned int kpSize)
4661
4705
4662
4706
void CWallet::UpdateKeyPoolsFromTransactions (const std::string& strOpType, const std::vector<std::vector<unsigned char >>& vvchOpParameters)
4663
4707
{
4708
+ if (vvchOpParameters.size () <= 1 )
4709
+ return ;
4710
+
4664
4711
std::vector<unsigned char > key0 = vvchOpParameters[0 ];
4665
4712
std::vector<unsigned char > key1 = vvchOpParameters[1 ];
4666
4713
@@ -4748,6 +4795,7 @@ void CWallet::ReserveEdKeyForTransactions(const std::vector<unsigned char>& pubK
4748
4795
fNeedToUpdateKeyPools = true ;
4749
4796
EraseIndex = true ;
4750
4797
IndexToErase = nIndex;
4798
+ ReserveKeyCount++;
4751
4799
}
4752
4800
it++;
4753
4801
}
@@ -4763,6 +4811,50 @@ void CWallet::ReserveEdKeyForTransactions(const std::vector<unsigned char>& pubK
4763
4811
4764
4812
} // ReserveEdKeyForTransactions
4765
4813
4814
+ bool CWallet::ReserveKeyForTransactions (const CPubKey pubKeyToReserve)
4815
+ {
4816
+ bool foundPubKey = false ;
4817
+
4818
+ CWalletDB walletdb (strWalletFile);
4819
+ CKeyPool keypool;
4820
+ CPubKey PubKey;
4821
+ std::vector<int64_t > keypoolIndexes;
4822
+ bool EraseIndex = false ;
4823
+ int64_t IndexToErase = 0 ;
4824
+ int64_t nIndex = 0 ;
4825
+ std::set<std::int64_t >::iterator it = setExternalKeyPool.begin ();
4826
+
4827
+ while ((it != setExternalKeyPool.end ()) && (!EraseIndex)) {
4828
+ nIndex = *it;
4829
+ if (!walletdb.ReadPool (nIndex, keypool)) {
4830
+ throw std::runtime_error (std::string (__func__) + " : read failed" );
4831
+ }
4832
+ PubKey = keypool.vchPubKey ;
4833
+
4834
+ if (pubKeyToReserve == PubKey) {
4835
+ foundPubKey = true ;
4836
+ KeepKey (nIndex);
4837
+ EraseIndex = true ;
4838
+ IndexToErase = nIndex;
4839
+ ReserveKeyCount++;
4840
+ SaveRescanIndex = true ;
4841
+ }
4842
+ it++;
4843
+ }
4844
+
4845
+ if (EraseIndex) {
4846
+ std::set<int64_t >::iterator eraseIndexEd = setExternalEdKeyPool.find (IndexToErase);
4847
+ std::set<int64_t >::iterator eraseIndex = setExternalKeyPool.find (IndexToErase);
4848
+ if (eraseIndexEd != setExternalKeyPool.end ())
4849
+ setExternalEdKeyPool.erase (eraseIndexEd);
4850
+ if (eraseIndex != setExternalKeyPool.end ())
4851
+ setExternalKeyPool.erase (eraseIndex);
4852
+ }
4853
+
4854
+ return foundPubKey;
4855
+
4856
+ } // ReserveKeyForTransactions
4857
+
4766
4858
void CWallet::KeepKey (int64_t nIndex)
4767
4859
{
4768
4860
// Remove from key pool
@@ -5537,6 +5629,20 @@ CWallet* CWallet::CreateWalletFromFile(const std::string walletFile, const bool
5537
5629
LogPrintf (" Rescanning last %i blocks (from block %i)...\n " , chainActive.Height () - pindexRescan->nHeight , pindexRescan->nHeight );
5538
5630
nStart = GetTimeMillis ();
5539
5631
walletInstance->ScanForWalletTransactions (pindexRescan, true );
5632
+
5633
+ // rescan if boolean is set. go back 100 transactions from most recent transaction involving me.
5634
+ while ((walletInstance->fNeedToRescanTransactions ) && (walletInstance->ReserveKeyCount > DEFAULT_RESCAN_THRESHOLD)) {
5635
+ // initialize values
5636
+ walletInstance->fNeedToRescanTransactions = false ;
5637
+ walletInstance->ReserveKeyCount = 0 ;
5638
+
5639
+ CBlockIndex* computed_rescan_index = walletInstance->rescan_index ;
5640
+ if (computed_rescan_index->nHeight > 100 ) {
5641
+ computed_rescan_index = chainActive[computed_rescan_index->nHeight - 100 ];
5642
+ }
5643
+ walletInstance->ScanForWalletTransactions (computed_rescan_index, true );
5644
+ }
5645
+
5540
5646
LogPrintf (" rescan %15dms\n " , GetTimeMillis () - nStart);
5541
5647
walletInstance->SetBestChain (chainActive.GetLocator ());
5542
5648
CWalletDB::IncrementUpdateCounter ();
0 commit comments