CheckForkWarningConditionsOnNewFork(vpindexToConnect.back());
else
CheckForkWarningConditions();
-
+
+ // if we need to, rescan wallets
+ RescanWallets();
+
return true;
}
g_signals.SyncTransaction.connect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
g_signals.EraseTransaction.connect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
+ g_signals.RescanWallet.connect(boost::bind(&CValidationInterface::RescanWallet, pwalletIn));
g_signals.ChainTip.connect(boost::bind(&CValidationInterface::ChainTip, pwalletIn, _1, _2, _3, _4, _5));
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
g_signals.EraseTransaction.disconnect(boost::bind(&CValidationInterface::EraseFromWallet, pwalletIn, _1));
g_signals.SyncTransaction.disconnect(boost::bind(&CValidationInterface::SyncTransaction, pwalletIn, _1, _2));
+ g_signals.RescanWallet.disconnect(boost::bind(&CValidationInterface::RescanWallet, pwalletIn));
g_signals.UpdatedBlockTip.disconnect(boost::bind(&CValidationInterface::UpdatedBlockTip, pwalletIn, _1));
}
g_signals.UpdatedTransaction.disconnect_all_slots();
g_signals.EraseTransaction.disconnect_all_slots();
g_signals.SyncTransaction.disconnect_all_slots();
+ g_signals.RescanWallet.disconnect_all_slots();
g_signals.UpdatedBlockTip.disconnect_all_slots();
}
void EraseFromWallets(const uint256 &hash) {
g_signals.EraseTransaction(hash);
}
+
+void RescanWallets() {
+ g_signals.RescanWallet();
+}
\ No newline at end of file
void SyncWithWallets(const CTransaction& tx, const CBlock* pblock = NULL);
/** Erase a transaction from all registered wallets */
void EraseFromWallets(const uint256 &hash);
+/** Rescan all registered wallets */
+void RescanWallets();
class CValidationInterface {
protected:
virtual void UpdatedBlockTip(const CBlockIndex *pindex) {}
virtual void SyncTransaction(const CTransaction &tx, const CBlock *pblock) {}
virtual void EraseFromWallet(const uint256 &hash) {}
+ virtual void RescanWallet() {}
virtual void ChainTip(const CBlockIndex *pindex, const CBlock *pblock, SproutMerkleTree sproutTree, SaplingMerkleTree saplingTree, bool added) {}
virtual void SetBestChain(const CBlockLocator &locator) {}
virtual void UpdatedTransaction(const uint256 &hash) {}
boost::signals2::signal<void (const CBlockIndex *)> UpdatedBlockTip;
/** Notifies listeners of updated transaction data (transaction, and optionally the block it is found in. */
boost::signals2::signal<void (const CTransaction &, const CBlock *)> SyncTransaction;
- /** Notifies listeners of an erased transaction (currently disabled, requires transaction replacement). */
+ /** Notifies listeners of an erased transaction. */
boost::signals2::signal<void (const uint256 &)> EraseTransaction;
+ /** Notifies listeners of the need to rescan the wallet. */
+ boost::signals2::signal<void ()> RescanWallet;
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
/** Notifies listeners of a change to the tip of the active block chain. */
}
template<typename NoteDataMap>
-void DecrementNoteWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize)
+bool DecrementNoteWitnesses(NoteDataMap& noteDataMap, int indexHeight, int64_t nWitnessCacheSize)
{
extern int32_t KOMODO_REWIND;
// Witnesses being decremented should always be either -1
// (never incremented or decremented) or equal to the height
// of the block being removed (indexHeight)
- assert((nd->witnessHeight == -1) || (nd->witnessHeight == indexHeight));
+ if (!((nd->witnessHeight == -1) || (nd->witnessHeight == indexHeight)))
+ {
+ printf("at height %d\n", indexHeight);
+ return false;
+ }
if (nd->witnesses.size() > 0) {
nd->witnesses.pop_front();
}
}
}
assert(KOMODO_REWIND != 0 || nWitnessCacheSize > 0);
+ return true;
}
void CWallet::DecrementNoteWitnesses(const CBlockIndex* pindex)
{
LOCK(cs_wallet);
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
- ::DecrementNoteWitnesses(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize);
- ::DecrementNoteWitnesses(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize);
+ if (!::DecrementNoteWitnesses(wtxItem.second.mapSproutNoteData, pindex->GetHeight(), nWitnessCacheSize))
+ needsRescan = true;
+ if (!::DecrementNoteWitnesses(wtxItem.second.mapSaplingNoteData, pindex->GetHeight(), nWitnessCacheSize))
+ needsRescan = true;
}
nWitnessCacheSize -= 1;
// TODO: If nWitnessCache is zero, we need to regenerate the caches (#1302)
return;
}
+void CWallet::RescanWallet()
+{
+ if (needsRescan)
+ {
+ CBlockIndex *start = chainActive.Height() > 0 ? chainActive[1] : NULL;
+ if (start)
+ ScanForWalletTransactions(start, true);
+ needsRescan = false;
+ }
+}
+
/**
* Returns a nullifier if the SpendingKey is available
// Sort them in chronological order
multimap<unsigned int, CWalletTx*> mapSorted;
uint32_t now = (uint32_t)time(NULL);
+ std::vector<uint256> vwtxh;
BOOST_FOREACH(PAIRTYPE(const uint256, CWalletTx)& item, mapWallet)
{
CWalletTx& wtx = item.second;
if ( wtx.nLockTime >= LOCKTIME_THRESHOLD && wtx.nLockTime < now-KOMODO_MAXMEMPOOLTIME )
{
LogPrintf("skip Relaying wtx %s nLockTime %u vs now.%u\n", wtx.GetHash().ToString(),(uint32_t)wtx.nLockTime,now);
- //TODO: EraseFromWallet(wtx.GetHash()); //should be erased, but this creates issues, likely better to create
- // vector and do it outside of this loop, but for later
+ vwtxh.push_back(wtx.GetHash());
continue;
}
}
result.push_back(wtx.GetHash());
}
}
+ for (auto hash : vwtxh)
+ {
+ EraseFromWallet(hash);
+ }
return result;
}
* incremental witness cache in any transaction in mapWallet.
*/
int64_t nWitnessCacheSize;
+ bool needsRescan = false;
void ClearNoteWitnessCache();
bool AddToWallet(const CWalletTx& wtxIn, bool fFromLoadWallet, CWalletDB* pwalletdb);
void EraseFromWallet(const uint256 &hash);
void SyncTransaction(const CTransaction& tx, const CBlock* pblock);
+ void RescanWallet();
bool AddToWalletIfInvolvingMe(const CTransaction& tx, const CBlock* pblock, bool fUpdate);
void WitnessNoteCommitment(
std::vector<uint256> commitments,