Skip to content

Commit 9fececb

Browse files
committed
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.
1 parent d89f8ad commit 9fececb

File tree

5 files changed

+31
-25
lines changed

5 files changed

+31
-25
lines changed

src/validation.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1924,12 +1924,6 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd
19241924
int64_t nTime5 = GetTimeMicros(); nTimeIndex += nTime5 - nTime4;
19251925
LogPrint(BCLog::BENCH, " - Index writing: %.2fms [%.2fs]\n", 0.001 * (nTime5 - nTime4), nTimeIndex * 0.000001);
19261926

1927-
// Watch for changes to the previous coinbase transaction.
1928-
static uint256 hashPrevBestCoinBase;
1929-
GetMainSignals().UpdatedTransaction(hashPrevBestCoinBase);
1930-
hashPrevBestCoinBase = block.vtx[0]->GetHash();
1931-
1932-
19331927
int64_t nTime6 = GetTimeMicros(); nTimeCallbacks += nTime6 - nTime5;
19341928
LogPrint(BCLog::BENCH, " - Callbacks: %.2fms [%.2fs]\n", 0.001 * (nTime6 - nTime5), nTimeCallbacks * 0.000001);
19351929

src/validationinterface.cpp

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ void RegisterValidationInterface(CValidationInterface* pwalletIn) {
1717
g_signals.TransactionAddedToMempool.connect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1));
1818
g_signals.BlockConnected.connect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
1919
g_signals.BlockDisconnected.connect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1));
20-
g_signals.UpdatedTransaction.connect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
2120
g_signals.SetBestChain.connect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
2221
g_signals.Inventory.connect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
2322
g_signals.Broadcast.connect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
@@ -32,7 +31,6 @@ void UnregisterValidationInterface(CValidationInterface* pwalletIn) {
3231
g_signals.Broadcast.disconnect(boost::bind(&CValidationInterface::ResendWalletTransactions, pwalletIn, _1, _2));
3332
g_signals.Inventory.disconnect(boost::bind(&CValidationInterface::Inventory, pwalletIn, _1));
3433
g_signals.SetBestChain.disconnect(boost::bind(&CValidationInterface::SetBestChain, pwalletIn, _1));
35-
g_signals.UpdatedTransaction.disconnect(boost::bind(&CValidationInterface::UpdatedTransaction, pwalletIn, _1));
3634
g_signals.TransactionAddedToMempool.disconnect(boost::bind(&CValidationInterface::TransactionAddedToMempool, pwalletIn, _1));
3735
g_signals.BlockConnected.disconnect(boost::bind(&CValidationInterface::BlockConnected, pwalletIn, _1, _2, _3));
3836
g_signals.BlockDisconnected.disconnect(boost::bind(&CValidationInterface::BlockDisconnected, pwalletIn, _1));
@@ -46,7 +44,6 @@ void UnregisterAllValidationInterfaces() {
4644
g_signals.Broadcast.disconnect_all_slots();
4745
g_signals.Inventory.disconnect_all_slots();
4846
g_signals.SetBestChain.disconnect_all_slots();
49-
g_signals.UpdatedTransaction.disconnect_all_slots();
5047
g_signals.TransactionAddedToMempool.disconnect_all_slots();
5148
g_signals.BlockConnected.disconnect_all_slots();
5249
g_signals.BlockDisconnected.disconnect_all_slots();

src/validationinterface.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ class CValidationInterface {
3737
virtual void BlockConnected(const std::shared_ptr<const CBlock> &block, const CBlockIndex *pindex, const std::vector<CTransactionRef> &txnConflicted) {}
3838
virtual void BlockDisconnected(const std::shared_ptr<const CBlock> &block) {}
3939
virtual void SetBestChain(const CBlockLocator &locator) {}
40-
virtual void UpdatedTransaction(const uint256 &hash) {}
4140
virtual void Inventory(const uint256 &hash) {}
4241
virtual void ResendWalletTransactions(int64_t nBestBlockTime, CConnman* connman) {}
4342
virtual void BlockChecked(const CBlock&, const CValidationState&) {}
@@ -60,8 +59,6 @@ struct CMainSignals {
6059
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &, const CBlockIndex *pindex, const std::vector<CTransactionRef> &)> BlockConnected;
6160
/** Notifies listeners of a block being disconnected */
6261
boost::signals2::signal<void (const std::shared_ptr<const CBlock> &)> BlockDisconnected;
63-
/** Notifies listeners of an updated transaction without new data (for now: a coinbase potentially becoming visible). */
64-
boost::signals2::signal<void (const uint256 &)> UpdatedTransaction;
6562
/** Notifies listeners of a new active block chain. */
6663
boost::signals2::signal<void (const CBlockLocator &)> SetBestChain;
6764
/** Notifies listeners about an inventory item being seen on the network. */

src/wallet/wallet.cpp

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,6 +1155,33 @@ void CWallet::BlockConnected(const std::shared_ptr<const CBlock>& pblock, const
11551155
for (size_t i = 0; i < pblock->vtx.size(); i++) {
11561156
SyncTransaction(pblock->vtx[i], pindex, i);
11571157
}
1158+
1159+
// The GUI expects a NotifyTransactionChanged when a coinbase tx
1160+
// which is in our wallet moves from in-the-best-block to
1161+
// 2-confirmations (as it only displays them at that time).
1162+
// We do that here.
1163+
if (hashPrevBestCoinbase.IsNull()) {
1164+
// Immediately after restart we have no idea what the coinbase
1165+
// transaction from the previous block is.
1166+
// For correctness we scan over the entire wallet, looking for
1167+
// the previous block's coinbase, just in case it is ours, so
1168+
// that we can notify the UI that it should now be displayed.
1169+
if (pindex->pprev) {
1170+
for (const std::pair<uint256, CWalletTx>& p : mapWallet) {
1171+
if (p.second.IsCoinBase() && p.second.hashBlock == pindex->pprev->GetBlockHash()) {
1172+
NotifyTransactionChanged(this, p.first, CT_UPDATED);
1173+
break;
1174+
}
1175+
}
1176+
}
1177+
} else {
1178+
std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashPrevBestCoinbase);
1179+
if (mi != mapWallet.end()) {
1180+
NotifyTransactionChanged(this, hashPrevBestCoinbase, CT_UPDATED);
1181+
}
1182+
}
1183+
1184+
hashPrevBestCoinbase = pblock->vtx[0]->GetHash();
11581185
}
11591186

11601187
void CWallet::BlockDisconnected(const std::shared_ptr<const CBlock>& pblock) {
@@ -3386,17 +3413,6 @@ void CWallet::GetAllReserveKeys(std::set<CKeyID>& setAddress) const
33863413
}
33873414
}
33883415

3389-
void CWallet::UpdatedTransaction(const uint256 &hashTx)
3390-
{
3391-
{
3392-
LOCK(cs_wallet);
3393-
// Only notify UI if this transaction is in this wallet
3394-
std::map<uint256, CWalletTx>::const_iterator mi = mapWallet.find(hashTx);
3395-
if (mi != mapWallet.end())
3396-
NotifyTransactionChanged(this, hashTx, CT_UPDATED);
3397-
}
3398-
}
3399-
34003416
void CWallet::GetScriptForMining(std::shared_ptr<CReserveScript> &script)
34013417
{
34023418
std::shared_ptr<CReserveKey> rKey = std::make_shared<CReserveKey>(this);

src/wallet/wallet.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,10 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
685685
*/
686686
bool AddWatchOnly(const CScript& dest) override;
687687

688+
// Used to NotifyTransactionChanged of the previous block's coinbase when
689+
// the next block comes in
690+
uint256 hashPrevBestCoinbase;
691+
688692
public:
689693
/*
690694
* Main wallet lock.
@@ -950,8 +954,6 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface
950954

951955
bool DelAddressBook(const CTxDestination& address);
952956

953-
void UpdatedTransaction(const uint256 &hashTx) override;
954-
955957
void Inventory(const uint256 &hash) override
956958
{
957959
{

0 commit comments

Comments
 (0)