Resolves Sapling nullifier persistence issue when importing a key.
During a rescan, a CWalletTx was persisted to disk before it had its note data set. This meant that upon restart, the CWalletTx would potentially be missing its nullifiers causing the wallet's balance to include notes which had already been spent. The resolution is to ensure that after a rescan, a CWalletTx is persisted after it has had its nullifiers set correctly. Co-authored-by: Eirik Ogilvie-Wigley <eirik@z.cash>
This commit is contained in:
parent
807fb7497f
commit
cd10562c73
|
@ -2398,6 +2398,9 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
||||||
const CChainParams& chainParams = Params();
|
const CChainParams& chainParams = Params();
|
||||||
|
|
||||||
CBlockIndex* pindex = pindexStart;
|
CBlockIndex* pindex = pindexStart;
|
||||||
|
|
||||||
|
std::vector<uint256> myTxHashes;
|
||||||
|
|
||||||
{
|
{
|
||||||
LOCK2(cs_main, cs_wallet);
|
LOCK2(cs_main, cs_wallet);
|
||||||
|
|
||||||
|
@ -2418,8 +2421,10 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
||||||
ReadBlockFromDisk(block, pindex);
|
ReadBlockFromDisk(block, pindex);
|
||||||
BOOST_FOREACH(CTransaction& tx, block.vtx)
|
BOOST_FOREACH(CTransaction& tx, block.vtx)
|
||||||
{
|
{
|
||||||
if (AddToWalletIfInvolvingMe(tx, &block, fUpdate))
|
if (AddToWalletIfInvolvingMe(tx, &block, fUpdate)) {
|
||||||
|
myTxHashes.push_back(tx.GetHash());
|
||||||
ret++;
|
ret++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SproutMerkleTree sproutTree;
|
SproutMerkleTree sproutTree;
|
||||||
|
@ -2441,6 +2446,19 @@ int CWallet::ScanForWalletTransactions(CBlockIndex* pindexStart, bool fUpdate)
|
||||||
LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
|
LogPrintf("Still rescanning. At block %d. Progress=%f\n", pindex->nHeight, Checkpoints::GuessVerificationProgress(chainParams.Checkpoints(), pindex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// After rescanning, persist Sapling note data that might have changed, e.g. nullifiers.
|
||||||
|
// Do not flush the wallet here for performance reasons.
|
||||||
|
CWalletDB walletdb(strWalletFile, "r+", false);
|
||||||
|
for (auto hash : myTxHashes) {
|
||||||
|
CWalletTx wtx = mapWallet[hash];
|
||||||
|
if (!wtx.mapSaplingNoteData.empty()) {
|
||||||
|
if (!wtx.WriteToDisk(&walletdb)) {
|
||||||
|
LogPrintf("Rescanning... WriteToDisk failed to update Sapling note data for: %s\n", hash.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
|
ShowProgress(_("Rescanning..."), 100); // hide progress dialog in GUI
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
Loading…
Reference in New Issue