Write witness caches when writing the best block

For steady-state operation, this reduces the average time between wallet disk
writes from once per block to once per hour.

On -rescan, witness caches are only written out at the end along with the best
block, increasing speed while ensuring that on-disk state is kept consistent.

Witness caches are now never recreated during a -reindex, on the assumption that
the blocks themselves are not changing (the chain is just being reconstructed),
and so the witnesses will remain valid.

Part of #1749.
This commit is contained in:
Jack Grigg
2016-11-30 14:04:37 +13:00
parent c29ab1fbb7
commit 03f83b9b0d
5 changed files with 56 additions and 30 deletions

View File

@@ -636,35 +636,40 @@ protected:
void DecrementNoteWitnesses(const CBlockIndex* pindex);
template <typename WalletDB>
void WriteWitnessCache(WalletDB& walletdb) {
void SetBestChainINTERNAL(WalletDB& walletdb, const CBlockLocator& loc) {
if (!walletdb.TxnBegin()) {
// This needs to be done atomically, so don't do it at all
LogPrintf("WriteWitnessCache(): Couldn't start atomic write\n");
LogPrintf("SetBestChain(): Couldn't start atomic write\n");
return;
}
try {
for (std::pair<const uint256, CWalletTx>& wtxItem : mapWallet) {
if (!walletdb.WriteTx(wtxItem.first, wtxItem.second)) {
LogPrintf("WriteWitnessCache(): Failed to write CWalletTx, aborting atomic write\n");
LogPrintf("SetBestChain(): Failed to write CWalletTx, aborting atomic write\n");
walletdb.TxnAbort();
return;
}
}
if (!walletdb.WriteWitnessCacheSize(nWitnessCacheSize)) {
LogPrintf("WriteWitnessCache(): Failed to write nWitnessCacheSize, aborting atomic write\n");
LogPrintf("SetBestChain(): Failed to write nWitnessCacheSize, aborting atomic write\n");
walletdb.TxnAbort();
return;
}
if (!walletdb.WriteBestBlock(loc)) {
LogPrintf("SetBestChain(): Failed to write best block, aborting atomic write\n");
walletdb.TxnAbort();
return;
}
} catch (const std::exception &exc) {
// Unexpected failure
LogPrintf("WriteWitnessCache(): Unexpected error during atomic write:\n");
LogPrintf("SetBestChain(): Unexpected error during atomic write:\n");
LogPrintf("%s\n", exc.what());
walletdb.TxnAbort();
return;
}
if (!walletdb.TxnCommit()) {
// Couldn't commit all to db, but in-memory state is fine
LogPrintf("WriteWitnessCache(): Couldn't commit atomic write\n");
LogPrintf("SetBestChain(): Couldn't commit atomic write\n");
return;
}
}