Increment witnesses for new transactions on rescan

Closes #1400
This commit is contained in:
Jack Grigg
2016-10-13 01:02:13 -05:00
parent fd23341f1e
commit b6961fc112
6 changed files with 60 additions and 16 deletions

View File

@@ -636,7 +636,7 @@ void CWallet::ClearNoteWitnessCache()
void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
const CBlock* pblockIn,
ZCIncrementalMerkleTree tree)
ZCIncrementalMerkleTree& tree)
{
{
LOCK(cs_wallet);
@@ -645,12 +645,19 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
CNoteData* nd = &(item.second);
// Check the validity of the cache
assert(nWitnessCacheSize >= nd->witnesses.size());
// Copy the witness for the previous block if we have one
if (nd->witnesses.size() > 0) {
nd->witnesses.push_front(nd->witnesses.front());
}
if (nd->witnesses.size() > WITNESS_CACHE_SIZE) {
nd->witnesses.pop_back();
// Only increment witnesses that are behind the current height
if (nd->witnessHeight < pindex->nHeight) {
// Witnesses being incremented should always be either -1
// (never incremented) or one below pindex
assert((nd->witnessHeight == -1) ||
(nd->witnessHeight == pindex->nHeight - 1));
// Copy the witness for the previous block if we have one
if (nd->witnesses.size() > 0) {
nd->witnesses.push_front(nd->witnesses.front());
}
if (nd->witnesses.size() > WITNESS_CACHE_SIZE) {
nd->witnesses.pop_back();
}
}
}
}
@@ -680,7 +687,8 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
CNoteData* nd = &(item.second);
// Check the validity of the cache
assert(nWitnessCacheSize >= nd->witnesses.size());
if (nd->witnesses.size() > 0) {
if (nd->witnessHeight < pindex->nHeight &&
nd->witnesses.size() > 0) {
nd->witnesses.front().append(note_commitment);
}
}
@@ -693,6 +701,8 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
CNoteData* nd = &(mapWallet[hash].mapNoteData[jsoutpt]);
assert(nd->witnesses.size() == 0);
nd->witnesses.push_front(tree.witness());
// Set height to one less than pindex so it gets incremented
nd->witnessHeight = pindex->nHeight - 1;
// Check the validity of the cache
assert(nWitnessCacheSize >= nd->witnesses.size());
}
@@ -700,13 +710,19 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
}
}
}
// Update witness heights
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
for (mapNoteData_t::value_type& item : wtxItem.second.mapNoteData) {
CNoteData* nd = &(item.second);
if (nd->witnessHeight < pindex->nHeight) {
nd->witnessHeight = pindex->nHeight;
}
// Check the validity of the cache
assert(nWitnessCacheSize >= nd->witnesses.size());
}
}
if (fFileBacked) {
CWalletDB walletdb(strWalletFile);
WriteWitnessCache(walletdb);
@@ -726,6 +742,7 @@ void CWallet::DecrementNoteWitnesses()
if (nd->witnesses.size() > 0) {
nd->witnesses.pop_front();
}
nd->witnessHeight -= 1;
}
}
nWitnessCacheSize -= 1;
@@ -1716,6 +1733,14 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
ret++;
}
ZCIncrementalMerkleTree tree;
// This should never fail: we should always be able to get the tree
// state on the path to the tip of our chain
assert(pcoinsTip->GetAnchorAt(pindex->hashAnchor, tree));
// Increment note witness caches
IncrementNoteWitnesses(pindex, &block, tree);
pindex = chainActive.Next(pindex);
if (GetTime() >= nNow + 60) {
nNow = GetTime();