Browse Source

Clear witness cache when re-witnessing notes

Closes #1378
pull/4/head
Jack Grigg 8 years ago
parent
commit
878c4b1b50
No known key found for this signature in database GPG Key ID: 6A6914DAFBEA00DA
  1. 8
      src/wallet/gtest/test_wallet.cpp
  2. 16
      src/wallet/wallet.cpp

8
src/wallet/gtest/test_wallet.cpp

@ -734,6 +734,14 @@ TEST(wallet_tests, cached_witnesses_chain_tip) {
wallet.GetNoteWitnesses(notes, witnesses, anchor4);
EXPECT_TRUE((bool) witnesses[0]);
EXPECT_EQ(anchor2, anchor4);
// Incrementing with the same block again should not change the cache
uint256 anchor5;
wallet.IncrementNoteWitnesses(&index2, &block2, tree);
std::vector<boost::optional<ZCIncrementalWitness>> witnesses5;
wallet.GetNoteWitnesses(notes, witnesses5, anchor5);
EXPECT_EQ(witnesses, witnesses5);
EXPECT_EQ(anchor4, anchor5);
}
}

16
src/wallet/wallet.cpp

@ -699,7 +699,21 @@ void CWallet::IncrementNoteWitnesses(const CBlockIndex* pindex,
JSOutPoint jsoutpt {hash, i, j};
if (mapWallet[hash].mapNoteData.count(jsoutpt)) {
CNoteData* nd = &(mapWallet[hash].mapNoteData[jsoutpt]);
assert(nd->witnesses.size() == 0);
if (nd->witnesses.size() > 0) {
// We think this can happen because we write out the
// witness cache state after every block increment or
// decrement, but the block index itself is written in
// batches. So if the node crashes in between these two
// operations, it is possible for IncrementNoteWitnesses
// to be called again on previously-cached blocks. This
// doesn't affect existing cached notes because of the
// CNoteData::witnessHeight checks. See #1378 for details.
LogPrintf("Inconsistent witness cache state found for %s\n- Cache size: %d\n- Top: %s\n- New: %s\n",
jsoutpt.ToString(), nd->witnesses.size(),
nd->witnesses.front().root().GetHex(),
tree.witness().root().GetHex());
nd->witnesses.clear();
}
nd->witnesses.push_front(tree.witness());
// Set height to one less than pindex so it gets incremented
nd->witnessHeight = pindex->nHeight - 1;

Loading…
Cancel
Save