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.
This commit is contained in:
Jack Grigg 2022-07-06 00:08:23 +00:00
parent 903f5f9269
commit e8a7b7253a
2 changed files with 5 additions and 8 deletions

View File

@ -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;
}

View File

@ -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;
}