Skip to content

Commit 081accb

Browse files
committed
Pass chain locked variables where needed
This commit does not change behavior. All it does is pass new function parameters. It is easiest to review this change with: git log -p -n1 -U0 --word-diff-regex=.
1 parent 79d579f commit 081accb

File tree

8 files changed

+175
-152
lines changed

8 files changed

+175
-152
lines changed

src/interfaces/wallet.cpp

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class PendingWalletTxImpl : public PendingWalletTx
6969
};
7070

7171
//! Construct wallet tx struct.
72-
static WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
72+
WalletTx MakeWalletTx(interfaces::Chain::Lock& locked_chain, CWallet& wallet, const CWalletTx& wtx)
7373
{
7474
WalletTx result;
7575
result.tx = wtx.tx;
@@ -87,7 +87,7 @@ static WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) EXCLUSIVE_LO
8787
IsMine(wallet, result.txout_address.back()) :
8888
ISMINE_NO);
8989
}
90-
result.credit = wtx.GetCredit(ISMINE_ALL);
90+
result.credit = wtx.GetCredit(locked_chain, ISMINE_ALL);
9191
result.debit = wtx.GetDebit(ISMINE_ALL);
9292
result.change = wtx.GetChange();
9393
result.time = wtx.GetTxTime();
@@ -97,32 +97,38 @@ static WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx) EXCLUSIVE_LO
9797
}
9898

9999
//! Construct wallet tx status struct.
100-
static WalletTxStatus MakeWalletTxStatus(const CWalletTx& wtx) EXCLUSIVE_LOCKS_REQUIRED(cs_main)
100+
WalletTxStatus MakeWalletTxStatus(interfaces::Chain::Lock& locked_chain, const CWalletTx& wtx)
101101
{
102+
LockAnnotation lock(::cs_main); // Temporary, for CheckFinalTx below. Removed in upcoming commit.
103+
102104
WalletTxStatus result;
103105
auto mi = ::mapBlockIndex.find(wtx.hashBlock);
104106
CBlockIndex* block = mi != ::mapBlockIndex.end() ? mi->second : nullptr;
105107
result.block_height = (block ? block->nHeight : std::numeric_limits<int>::max());
106-
result.blocks_to_maturity = wtx.GetBlocksToMaturity();
107-
result.depth_in_main_chain = wtx.GetDepthInMainChain();
108+
result.blocks_to_maturity = wtx.GetBlocksToMaturity(locked_chain);
109+
result.depth_in_main_chain = wtx.GetDepthInMainChain(locked_chain);
108110
result.time_received = wtx.nTimeReceived;
109111
result.lock_time = wtx.tx->nLockTime;
110112
result.is_final = CheckFinalTx(*wtx.tx);
111-
result.is_trusted = wtx.IsTrusted();
113+
result.is_trusted = wtx.IsTrusted(locked_chain);
112114
result.is_abandoned = wtx.isAbandoned();
113115
result.is_coinbase = wtx.IsCoinBase();
114-
result.is_in_main_chain = wtx.IsInMainChain();
116+
result.is_in_main_chain = wtx.IsInMainChain(locked_chain);
115117
return result;
116118
}
117119

118120
//! Construct wallet TxOut struct.
119-
static WalletTxOut MakeWalletTxOut(CWallet& wallet, const CWalletTx& wtx, int n, int depth) EXCLUSIVE_LOCKS_REQUIRED(cs_main, wallet.cs_wallet)
121+
WalletTxOut MakeWalletTxOut(interfaces::Chain::Lock& locked_chain,
122+
CWallet& wallet,
123+
const CWalletTx& wtx,
124+
int n,
125+
int depth) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
120126
{
121127
WalletTxOut result;
122128
result.txout = wtx.tx->vout[n];
123129
result.time = wtx.GetTxTime();
124130
result.depth_in_main_chain = depth;
125-
result.is_spent = wallet.IsSpent(wtx.GetHash(), n);
131+
result.is_spent = wallet.IsSpent(locked_chain, wtx.GetHash(), n);
126132
return result;
127133
}
128134

@@ -242,7 +248,7 @@ class WalletImpl : public Wallet
242248
auto locked_chain = m_wallet.chain().lock();
243249
LOCK(m_wallet.cs_wallet);
244250
auto pending = MakeUnique<PendingWalletTxImpl>(m_wallet);
245-
if (!m_wallet.CreateTransaction(recipients, pending->m_tx, pending->m_key, fee, change_pos,
251+
if (!m_wallet.CreateTransaction(*locked_chain, recipients, pending->m_tx, pending->m_key, fee, change_pos,
246252
fail_reason, coin_control, sign)) {
247253
return {};
248254
}
@@ -253,7 +259,7 @@ class WalletImpl : public Wallet
253259
{
254260
auto locked_chain = m_wallet.chain().lock();
255261
LOCK(m_wallet.cs_wallet);
256-
return m_wallet.AbandonTransaction(txid);
262+
return m_wallet.AbandonTransaction(*locked_chain, txid);
257263
}
258264
bool transactionCanBeBumped(const uint256& txid) override
259265
{
@@ -295,7 +301,7 @@ class WalletImpl : public Wallet
295301
LOCK(m_wallet.cs_wallet);
296302
auto mi = m_wallet.mapWallet.find(txid);
297303
if (mi != m_wallet.mapWallet.end()) {
298-
return MakeWalletTx(m_wallet, mi->second);
304+
return MakeWalletTx(*locked_chain, m_wallet, mi->second);
299305
}
300306
return {};
301307
}
@@ -306,7 +312,7 @@ class WalletImpl : public Wallet
306312
std::vector<WalletTx> result;
307313
result.reserve(m_wallet.mapWallet.size());
308314
for (const auto& entry : m_wallet.mapWallet) {
309-
result.emplace_back(MakeWalletTx(m_wallet, entry.second));
315+
result.emplace_back(MakeWalletTx(*locked_chain, m_wallet, entry.second));
310316
}
311317
return result;
312318
}
@@ -327,7 +333,7 @@ class WalletImpl : public Wallet
327333
return false;
328334
}
329335
num_blocks = ::chainActive.Height();
330-
tx_status = MakeWalletTxStatus(mi->second);
336+
tx_status = MakeWalletTxStatus(*locked_chain, mi->second);
331337
return true;
332338
}
333339
WalletTx getWalletTxDetails(const uint256& txid,
@@ -343,8 +349,8 @@ class WalletImpl : public Wallet
343349
num_blocks = ::chainActive.Height();
344350
in_mempool = mi->second.InMempool();
345351
order_form = mi->second.vOrderForm;
346-
tx_status = MakeWalletTxStatus(mi->second);
347-
return MakeWalletTx(m_wallet, mi->second);
352+
tx_status = MakeWalletTxStatus(*locked_chain, mi->second);
353+
return MakeWalletTx(*locked_chain, m_wallet, mi->second);
348354
}
349355
return {};
350356
}
@@ -408,11 +414,11 @@ class WalletImpl : public Wallet
408414
auto locked_chain = m_wallet.chain().lock();
409415
LOCK(m_wallet.cs_wallet);
410416
CoinsList result;
411-
for (const auto& entry : m_wallet.ListCoins()) {
417+
for (const auto& entry : m_wallet.ListCoins(*locked_chain)) {
412418
auto& group = result[entry.first];
413419
for (const auto& coin : entry.second) {
414-
group.emplace_back(
415-
COutPoint(coin.tx->GetHash(), coin.i), MakeWalletTxOut(m_wallet, *coin.tx, coin.i, coin.nDepth));
420+
group.emplace_back(COutPoint(coin.tx->GetHash(), coin.i),
421+
MakeWalletTxOut(*locked_chain, m_wallet, *coin.tx, coin.i, coin.nDepth));
416422
}
417423
}
418424
return result;
@@ -427,9 +433,9 @@ class WalletImpl : public Wallet
427433
result.emplace_back();
428434
auto it = m_wallet.mapWallet.find(output.hash);
429435
if (it != m_wallet.mapWallet.end()) {
430-
int depth = it->second.GetDepthInMainChain();
436+
int depth = it->second.GetDepthInMainChain(*locked_chain);
431437
if (depth >= 0) {
432-
result.back() = MakeWalletTxOut(m_wallet, it->second, output.n, depth);
438+
result.back() = MakeWalletTxOut(*locked_chain, m_wallet, it->second, output.n, depth);
433439
}
434440
}
435441
}

src/threadsafety.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,4 +54,15 @@
5454
#define ASSERT_EXCLUSIVE_LOCK(...)
5555
#endif // __GNUC__
5656

57+
// Utility class for indicating to compiler thread analysis that a mutex is
58+
// locked (when it couldn't be determined otherwise).
59+
struct SCOPED_LOCKABLE LockAnnotation
60+
{
61+
template <typename Mutex>
62+
explicit LockAnnotation(Mutex& mutex) EXCLUSIVE_LOCK_FUNCTION(mutex)
63+
{
64+
}
65+
~LockAnnotation() UNLOCK_FUNCTION() {}
66+
};
67+
5768
#endif // BITCOIN_THREADSAFETY_H

src/wallet/feebumper.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
//! Check whether transaction has descendant in wallet or mempool, or has been
2121
//! mined, or conflicts with a mined transaction. Return a feebumper::Result.
22-
static feebumper::Result PreconditionChecks(const CWallet* wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(cs_main, wallet->cs_wallet)
22+
static feebumper::Result PreconditionChecks(interfaces::Chain::Lock& locked_chain, const CWallet* wallet, const CWalletTx& wtx, std::vector<std::string>& errors) EXCLUSIVE_LOCKS_REQUIRED(wallet->cs_wallet)
2323
{
2424
if (wallet->HasWalletSpend(wtx.GetHash())) {
2525
errors.push_back("Transaction has descendants in the wallet");
@@ -35,7 +35,7 @@ static feebumper::Result PreconditionChecks(const CWallet* wallet, const CWallet
3535
}
3636
}
3737

38-
if (wtx.GetDepthInMainChain() != 0) {
38+
if (wtx.GetDepthInMainChain(locked_chain) != 0) {
3939
errors.push_back("Transaction has been mined, or is conflicted with a mined transaction");
4040
return feebumper::Result::WALLET_ERROR;
4141
}
@@ -71,7 +71,7 @@ bool TransactionCanBeBumped(const CWallet* wallet, const uint256& txid)
7171
if (wtx == nullptr) return false;
7272

7373
std::vector<std::string> errors_dummy;
74-
feebumper::Result res = PreconditionChecks(wallet, *wtx, errors_dummy);
74+
feebumper::Result res = PreconditionChecks(*locked_chain, wallet, *wtx, errors_dummy);
7575
return res == feebumper::Result::OK;
7676
}
7777

@@ -88,7 +88,7 @@ Result CreateTransaction(const CWallet* wallet, const uint256& txid, const CCoin
8888
}
8989
const CWalletTx& wtx = it->second;
9090

91-
Result result = PreconditionChecks(wallet, wtx, errors);
91+
Result result = PreconditionChecks(*locked_chain, wallet, wtx, errors);
9292
if (result != Result::OK) {
9393
return result;
9494
}
@@ -235,7 +235,7 @@ Result CommitTransaction(CWallet* wallet, const uint256& txid, CMutableTransacti
235235
CWalletTx& oldWtx = it->second;
236236

237237
// make sure the transaction still has no descendants and hasn't been mined in the meantime
238-
Result result = PreconditionChecks(wallet, oldWtx, errors);
238+
Result result = PreconditionChecks(*locked_chain, wallet, oldWtx, errors);
239239
if (result != Result::OK) {
240240
return result;
241241
}

src/wallet/rpcdump.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ UniValue dumpwallet(const JSONRPCRequest& request)
732732

733733
std::map<CTxDestination, int64_t> mapKeyBirth;
734734
const std::map<CKeyID, int64_t>& mapKeyPool = pwallet->GetAllReserveKeys();
735-
pwallet->GetKeyBirthTimes(mapKeyBirth);
735+
pwallet->GetKeyBirthTimes(*locked_chain, mapKeyBirth);
736736

737737
std::set<CScriptID> scripts = pwallet->GetCScripts();
738738
// TODO: include scripts in GetKeyBirthTimes() output instead of separate

0 commit comments

Comments
 (0)