Skip to content

Commit 0936f35

Browse files
author
MarcoFalke
committed
Merge #15842: refactor: replace isPotentialtip/waitForNotifications by higher method
4226779 refactor: replace isPotentialtip/waitForNotifications by higher method (Antoine Riard) edfe943 Add WITH_LOCK macro: run code while locking a mutex (Antoine Riard) Pull request description: In Chain interface, instead of a isPotentialTip and a WaitForNotifications method, both used only once in CWallet::BlockUntilSyncedToCurrentChain, combine them in a higher WaitForNotificationsUpToTip method. Semantic should be unchanged, wallet wait for pending notifications to be processed unless block hash points to the current chain tip or a descendant. ACKs for commit 422677: jnewbery: ACK 4226779 ryanofsky: utACK 4226779. Only change is adding the cs_wallet lock annotation. Tree-SHA512: 2834ff0218795ef607543fae822e5cce25d759c1a9cfcb1f896a4af03071faed5276fbe0966e0c6ed65dc0e88af161899c5b2ca358a2d24fe70969a550000bf2
2 parents 12aa2ac + 4226779 commit 0936f35

File tree

5 files changed

+29
-37
lines changed

5 files changed

+29
-37
lines changed

src/interfaces/chain.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,6 @@ class LockImpl : public Chain::Lock
122122
}
123123
return nullopt;
124124
}
125-
bool isPotentialTip(const uint256& hash) override
126-
{
127-
if (::chainActive.Tip()->GetBlockHash() == hash) return true;
128-
CBlockIndex* block = LookupBlockIndex(hash);
129-
return block && block->GetAncestor(::chainActive.Height()) == ::chainActive.Tip();
130-
}
131125
CBlockLocator getTipLocator() override { return ::chainActive.GetLocator(); }
132126
Optional<int> findLocatorFork(const CBlockLocator& locator) override
133127
{
@@ -343,7 +337,16 @@ class ChainImpl : public Chain
343337
{
344338
return MakeUnique<NotificationsHandlerImpl>(*this, notifications);
345339
}
346-
void waitForNotifications() override { SyncWithValidationInterfaceQueue(); }
340+
void waitForNotificationsIfNewBlocksConnected(const uint256& old_tip) override
341+
{
342+
if (!old_tip.IsNull()) {
343+
LOCK(::cs_main);
344+
if (old_tip == ::chainActive.Tip()->GetBlockHash()) return;
345+
CBlockIndex* block = LookupBlockIndex(old_tip);
346+
if (block && block->GetAncestor(::chainActive.Height()) == ::chainActive.Tip()) return;
347+
}
348+
SyncWithValidationInterfaceQueue();
349+
}
347350
std::unique_ptr<Handler> handleRpc(const CRPCCommand& command) override
348351
{
349352
return MakeUnique<RpcHandlerImpl>(command);

src/interfaces/chain.h

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,6 @@ class Wallet;
4343
//! asynchronously
4444
//! (https://github.com/bitcoin/bitcoin/pull/10973#issuecomment-380101269).
4545
//!
46-
//! * The isPotentialTip() and waitForNotifications() methods are too low-level
47-
//! and should be replaced with a higher level
48-
//! waitForNotificationsUpTo(block_hash) method that the wallet can call
49-
//! instead
50-
//! (https://github.com/bitcoin/bitcoin/pull/10973#discussion_r266995234).
51-
//!
5246
//! * The relayTransactions() and submitToMemoryPool() methods could be replaced
5347
//! with a higher-level broadcastTransaction method
5448
//! (https://github.com/bitcoin/bitcoin/pull/14978#issuecomment-459373984).
@@ -123,11 +117,6 @@ class Chain
123117
//! information is desired).
124118
virtual Optional<int> findFork(const uint256& hash, Optional<int>* height) = 0;
125119

126-
//! Return true if block hash points to the current chain tip, or to a
127-
//! possible descendant of the current chain tip that isn't currently
128-
//! connected.
129-
virtual bool isPotentialTip(const uint256& hash) = 0;
130-
131120
//! Get locator for the current chain tip.
132121
virtual CBlockLocator getTipLocator() = 0;
133122

@@ -256,8 +245,10 @@ class Chain
256245
//! Register handler for notifications.
257246
virtual std::unique_ptr<Handler> handleNotifications(Notifications& notifications) = 0;
258247

259-
//! Wait for pending notifications to be handled.
260-
virtual void waitForNotifications() = 0;
248+
//! Wait for pending notifications to be processed unless block hash points to the current
249+
//! chain tip, or to a possible descendant of the current chain tip that isn't currently
250+
//! connected.
251+
virtual void waitForNotificationsIfNewBlocksConnected(const uint256& old_tip) = 0;
261252

262253
//! Register handler for RPC. Command is not copied, so reference
263254
//! needs to remain valid until Handler is disconnected.

src/sync.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,16 @@ using DebugLock = UniqueLock<typename std::remove_reference<typename std::remove
198198
LeaveCritical(); \
199199
}
200200

201+
//! Run code while locking a mutex.
202+
//!
203+
//! Examples:
204+
//!
205+
//! WITH_LOCK(cs, shared_val = shared_val + 1);
206+
//!
207+
//! int val = WITH_LOCK(cs, return shared_val);
208+
//!
209+
#define WITH_LOCK(cs, code) [&] { LOCK(cs); code; }()
210+
201211
class CSemaphore
202212
{
203213
private:

src/wallet/wallet.cpp

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,24 +1287,12 @@ void CWallet::UpdatedBlockTip()
12871287

12881288
void CWallet::BlockUntilSyncedToCurrentChain() {
12891289
AssertLockNotHeld(cs_wallet);
1290-
1291-
{
1292-
// Skip the queue-draining stuff if we know we're caught up with
1293-
// chainActive.Tip()...
1294-
// We could also take cs_wallet here, and call m_last_block_processed
1295-
// protected by cs_wallet instead of cs_main, but as long as we need
1296-
// cs_main here anyway, it's easier to just call it cs_main-protected.
1297-
auto locked_chain = chain().lock();
1298-
1299-
if (!m_last_block_processed.IsNull() && locked_chain->isPotentialTip(m_last_block_processed)) {
1300-
return;
1301-
}
1302-
}
1303-
1304-
// ...otherwise put a callback in the validation interface queue and wait
1290+
// Skip the queue-draining stuff if we know we're caught up with
1291+
// chainActive.Tip(), otherwise put a callback in the validation interface queue and wait
13051292
// for the queue to drain enough to execute it (indicating we are caught up
13061293
// at least with the time we entered this function).
1307-
chain().waitForNotifications();
1294+
uint256 last_block_hash = WITH_LOCK(cs_wallet, return m_last_block_processed);
1295+
chain().waitForNotificationsIfNewBlocksConnected(last_block_hash);
13081296
}
13091297

13101298

src/wallet/wallet.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -693,7 +693,7 @@ class CWallet final : public CCryptoKeyStore, private interfaces::Chain::Notific
693693
* to have seen all transactions in the chain, but is only used to track
694694
* live BlockConnected callbacks.
695695
*/
696-
uint256 m_last_block_processed;
696+
uint256 m_last_block_processed GUARDED_BY(cs_wallet);
697697

698698
public:
699699
/*

0 commit comments

Comments
 (0)