From e8a7b7253a2d66784cea75336670298297c1533a Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Wed, 6 Jul 2022 00:08:23 +0000 Subject: [PATCH] Move "previous coinbase" UI monitoring into ThreadNotifyWallets When the wallet notification logic was moved into a separate thread, most wallet notifications were transferred across. This one was missed, and it is particularly pernicious: all it does is ask the wallet to tell the UI that a particular transaction had been updated. We don't actually _have_ any UI connected in zcashd, but there is a side-effect: the callback blocks on acquiring `cs_wallet`, in the main thread that already holds `cs_main`. For particularly large wallets, this can cause the main thread to block on `ThreadNotifyWallets`, which in turn means that anything waiting on `cs_main` (e.g. RPC calls) is blocked. We solve this by moving the callback into `ThreadNotifyWallets`. We don't technically need it for `zcashd`, but we maintain it in case a downstream fork has reconnected a UI. --- src/main.cpp | 8 -------- src/validationinterface.cpp | 5 +++++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 37b991bd6..4d8b37976 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3618,14 +3618,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin int64_t nTime3 = GetTimeMicros(); nTimeIndex += nTime3 - nTime2; LogPrint("bench", " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime3 - nTime2), nTimeIndex * 0.000001); - // Watch for changes to the previous coinbase transaction. - static uint256 hashPrevBestCoinBase; - GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); - hashPrevBestCoinBase = block.vtx[0].GetHash(); - - int64_t nTime4 = GetTimeMicros(); nTimeCallbacks += nTime4 - nTime3; - LogPrint("bench", " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime4 - nTime3), nTimeCallbacks * 0.000001); - return true; } diff --git a/src/validationinterface.cpp b/src/validationinterface.cpp index a53efd9f2..52db414c8 100644 --- a/src/validationinterface.cpp +++ b/src/validationinterface.cpp @@ -250,6 +250,11 @@ void ThreadNotifyWallets(CBlockIndex *pindexLastTip) // exploitable as a timing channel. GetMainSignals().ChainTip(blockData.pindex, &block, blockData.oldTrees); + // Notify UI to display prev block's coinbase if it was ours. + static uint256 hashPrevBestCoinBase; + GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase); + hashPrevBestCoinBase = block.vtx[0].GetHash(); + // This block is done! pindexLastTip = blockData.pindex; }