From 9fececb2cbabc52cc375b84bf840fac018cc8121 Mon Sep 17 00:00:00 2001 From: Matt Corallo Date: Tue, 17 Jan 2017 16:44:25 -0500 Subject: Remove CValidationInterface::UpdatedTransaction This removes another callback from block connection logic, making it easier to reason about the wallet-RPCs-returns-stale-info issue. UpdatedTransaction was previously used by the GUI to display coinbase transactions only after they have a block built on top of them. This worked fine for in most cases, but only worked due to a corner case if the user received a coinbase payout in a block immediately prior to restart. In that case, the normal process of caching the most recent coinbase transaction's hash would not work, and instead it would only work because of the on-load -checkblocks calling DisconnectBlock and ConnectBlock on the current tip. In order to make this more robust, a full mapWallet loop after the first block which is connected after restart was added. --- src/wallet/wallet.cpp | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) (limited to 'src/wallet/wallet.cpp') diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b0aa74342..e9d23e459 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -1155,6 +1155,33 @@ void CWallet::BlockConnected(const std::shared_ptr& pblock, const for (size_t i = 0; i < pblock->vtx.size(); i++) { SyncTransaction(pblock->vtx[i], pindex, i); } + + // The GUI expects a NotifyTransactionChanged when a coinbase tx + // which is in our wallet moves from in-the-best-block to + // 2-confirmations (as it only displays them at that time). + // We do that here. + if (hashPrevBestCoinbase.IsNull()) { + // Immediately after restart we have no idea what the coinbase + // transaction from the previous block is. + // For correctness we scan over the entire wallet, looking for + // the previous block's coinbase, just in case it is ours, so + // that we can notify the UI that it should now be displayed. + if (pindex->pprev) { + for (const std::pair& p : mapWallet) { + if (p.second.IsCoinBase() && p.second.hashBlock == pindex->pprev->GetBlockHash()) { + NotifyTransactionChanged(this, p.first, CT_UPDATED); + break; + } + } + } + } else { + std::map::const_iterator mi = mapWallet.find(hashPrevBestCoinbase); + if (mi != mapWallet.end()) { + NotifyTransactionChanged(this, hashPrevBestCoinbase, CT_UPDATED); + } + } + + hashPrevBestCoinbase = pblock->vtx[0]->GetHash(); } void CWallet::BlockDisconnected(const std::shared_ptr& pblock) { @@ -3386,17 +3413,6 @@ void CWallet::GetAllReserveKeys(std::set& setAddress) const } } -void CWallet::UpdatedTransaction(const uint256 &hashTx) -{ - { - LOCK(cs_wallet); - // Only notify UI if this transaction is in this wallet - std::map::const_iterator mi = mapWallet.find(hashTx); - if (mi != mapWallet.end()) - NotifyTransactionChanged(this, hashTx, CT_UPDATED); - } -} - void CWallet::GetScriptForMining(std::shared_ptr &script) { std::shared_ptr rKey = std::make_shared(this); -- cgit v1.2.3