mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-02-22 15:04:44 +01:00
Merge bitcoin/bitcoin#25148: refactor: Remove NO_THREAD_SAFETY_ANALYSIS
from non-test/benchmarking code
a55db4ea1c
Add more proper thread safety annotations (Hennadii Stepanov)8cfe93e3fc
Add proper thread safety annotation to `CWallet::GetTxConflicts()` (Hennadii Stepanov)ca446f2c59
Add proper thread safety annotation to `CachedTxGetAvailableCredit()` (Hennadii Stepanov) Pull request description: In non-test/benchmarking code, there are three cases of the `NO_THREAD_SAFETY_ANALYSIS` annotation which are accompanied with `TODO` comments. This PR adds proper thread safety annotations instead of `NO_THREAD_SAFETY_ANALYSIS`. ACKs for top commit: laanwj: Code review ACKa55db4ea1c
Tree-SHA512: 806d72eebc1edf088bfa435c8cd11465be0de6789798dd92abd008425516768acb864a73d834a49d412bb10f7fccfb47473f998cb72739dab6caeef6bcfaf191
This commit is contained in:
commit
629e250cbd
6 changed files with 44 additions and 33 deletions
|
@ -80,7 +80,10 @@ WalletTx MakeWalletTx(CWallet& wallet, const CWalletTx& wtx)
|
||||||
|
|
||||||
//! Construct wallet tx status struct.
|
//! Construct wallet tx status struct.
|
||||||
WalletTxStatus MakeWalletTxStatus(const CWallet& wallet, const CWalletTx& wtx)
|
WalletTxStatus MakeWalletTxStatus(const CWallet& wallet, const CWalletTx& wtx)
|
||||||
|
EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(wallet.cs_wallet);
|
||||||
|
|
||||||
WalletTxStatus result;
|
WalletTxStatus result;
|
||||||
result.block_height =
|
result.block_height =
|
||||||
wtx.state<TxStateConfirmed>() ? wtx.state<TxStateConfirmed>()->confirmed_block_height :
|
wtx.state<TxStateConfirmed>() ? wtx.state<TxStateConfirmed>()->confirmed_block_height :
|
||||||
|
|
|
@ -123,6 +123,8 @@ static CAmount GetCachableAmount(const CWallet& wallet, const CWalletTx& wtx, CW
|
||||||
|
|
||||||
CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter)
|
CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(wallet.cs_wallet);
|
||||||
|
|
||||||
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
// Must wait until coinbase is safely deep enough in the chain before valuing it
|
||||||
if (wallet.IsTxImmatureCoinBase(wtx))
|
if (wallet.IsTxImmatureCoinBase(wtx))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -164,6 +166,8 @@ CAmount CachedTxGetChange(const CWallet& wallet, const CWalletTx& wtx)
|
||||||
|
|
||||||
CAmount CachedTxGetImmatureCredit(const CWallet& wallet, const CWalletTx& wtx, bool fUseCache)
|
CAmount CachedTxGetImmatureCredit(const CWallet& wallet, const CWalletTx& wtx, bool fUseCache)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(wallet.cs_wallet);
|
||||||
|
|
||||||
if (wallet.IsTxImmatureCoinBase(wtx) && wallet.IsTxInMainChain(wtx)) {
|
if (wallet.IsTxImmatureCoinBase(wtx) && wallet.IsTxInMainChain(wtx)) {
|
||||||
return GetCachableAmount(wallet, wtx, CWalletTx::IMMATURE_CREDIT, ISMINE_SPENDABLE, !fUseCache);
|
return GetCachableAmount(wallet, wtx, CWalletTx::IMMATURE_CREDIT, ISMINE_SPENDABLE, !fUseCache);
|
||||||
}
|
}
|
||||||
|
@ -173,6 +177,8 @@ CAmount CachedTxGetImmatureCredit(const CWallet& wallet, const CWalletTx& wtx, b
|
||||||
|
|
||||||
CAmount CachedTxGetImmatureWatchOnlyCredit(const CWallet& wallet, const CWalletTx& wtx, const bool fUseCache)
|
CAmount CachedTxGetImmatureWatchOnlyCredit(const CWallet& wallet, const CWalletTx& wtx, const bool fUseCache)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(wallet.cs_wallet);
|
||||||
|
|
||||||
if (wallet.IsTxImmatureCoinBase(wtx) && wallet.IsTxInMainChain(wtx)) {
|
if (wallet.IsTxImmatureCoinBase(wtx) && wallet.IsTxInMainChain(wtx)) {
|
||||||
return GetCachableAmount(wallet, wtx, CWalletTx::IMMATURE_CREDIT, ISMINE_WATCH_ONLY, !fUseCache);
|
return GetCachableAmount(wallet, wtx, CWalletTx::IMMATURE_CREDIT, ISMINE_WATCH_ONLY, !fUseCache);
|
||||||
}
|
}
|
||||||
|
@ -182,6 +188,8 @@ CAmount CachedTxGetImmatureWatchOnlyCredit(const CWallet& wallet, const CWalletT
|
||||||
|
|
||||||
CAmount CachedTxGetAvailableCredit(const CWallet& wallet, const CWalletTx& wtx, bool fUseCache, const isminefilter& filter)
|
CAmount CachedTxGetAvailableCredit(const CWallet& wallet, const CWalletTx& wtx, bool fUseCache, const isminefilter& filter)
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(wallet.cs_wallet);
|
||||||
|
|
||||||
// Avoid caching ismine for NO or ALL cases (could remove this check and simplify in the future).
|
// Avoid caching ismine for NO or ALL cases (could remove this check and simplify in the future).
|
||||||
bool allow_cache = (filter & ISMINE_ALL) && (filter & ISMINE_ALL) != ISMINE_ALL;
|
bool allow_cache = (filter & ISMINE_ALL) && (filter & ISMINE_ALL) != ISMINE_ALL;
|
||||||
|
|
||||||
|
|
|
@ -24,17 +24,17 @@ bool OutputIsChange(const CWallet& wallet, const CTxOut& txout) EXCLUSIVE_LOCKS_
|
||||||
CAmount OutputGetChange(const CWallet& wallet, const CTxOut& txout) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
CAmount OutputGetChange(const CWallet& wallet, const CTxOut& txout) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||||
CAmount TxGetChange(const CWallet& wallet, const CTransaction& tx);
|
CAmount TxGetChange(const CWallet& wallet, const CTransaction& tx);
|
||||||
|
|
||||||
CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter);
|
CAmount CachedTxGetCredit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter)
|
||||||
|
EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||||
//! filter decides which addresses will count towards the debit
|
//! filter decides which addresses will count towards the debit
|
||||||
CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter);
|
CAmount CachedTxGetDebit(const CWallet& wallet, const CWalletTx& wtx, const isminefilter& filter);
|
||||||
CAmount CachedTxGetChange(const CWallet& wallet, const CWalletTx& wtx);
|
CAmount CachedTxGetChange(const CWallet& wallet, const CWalletTx& wtx);
|
||||||
CAmount CachedTxGetImmatureCredit(const CWallet& wallet, const CWalletTx& wtx, bool fUseCache = true);
|
CAmount CachedTxGetImmatureCredit(const CWallet& wallet, const CWalletTx& wtx, bool fUseCache = true)
|
||||||
CAmount CachedTxGetImmatureWatchOnlyCredit(const CWallet& wallet, const CWalletTx& wtx, const bool fUseCache = true);
|
EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||||
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
|
CAmount CachedTxGetImmatureWatchOnlyCredit(const CWallet& wallet, const CWalletTx& wtx, const bool fUseCache = true)
|
||||||
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The
|
EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||||
// annotation "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid
|
CAmount CachedTxGetAvailableCredit(const CWallet& wallet, const CWalletTx& wtx, bool fUseCache = true, const isminefilter& filter = ISMINE_SPENDABLE)
|
||||||
// having to resolve the issue of member access into incomplete type CWallet.
|
EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet);
|
||||||
CAmount CachedTxGetAvailableCredit(const CWallet& wallet, const CWalletTx& wtx, bool fUseCache = true, const isminefilter& filter = ISMINE_SPENDABLE) NO_THREAD_SAFETY_ANALYSIS;
|
|
||||||
struct COutputEntry
|
struct COutputEntry
|
||||||
{
|
{
|
||||||
CTxDestination destination;
|
CTxDestination destination;
|
||||||
|
|
|
@ -15,6 +15,7 @@ using interfaces::FoundBlock;
|
||||||
|
|
||||||
namespace wallet {
|
namespace wallet {
|
||||||
static void WalletTxToJSON(const CWallet& wallet, const CWalletTx& wtx, UniValue& entry)
|
static void WalletTxToJSON(const CWallet& wallet, const CWalletTx& wtx, UniValue& entry)
|
||||||
|
EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
|
||||||
{
|
{
|
||||||
interfaces::Chain& chain = wallet.chain();
|
interfaces::Chain& chain = wallet.chain();
|
||||||
int confirms = wallet.GetTxDepthInMainChain(wtx);
|
int confirms = wallet.GetTxDepthInMainChain(wtx);
|
||||||
|
|
|
@ -1841,6 +1841,8 @@ void CWallet::ReacceptWalletTransactions()
|
||||||
|
|
||||||
bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string, bool relay) const
|
bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string, bool relay) const
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet);
|
||||||
|
|
||||||
// Can't relay if wallet is not broadcasting
|
// Can't relay if wallet is not broadcasting
|
||||||
if (!GetBroadcastTransactions()) return false;
|
if (!GetBroadcastTransactions()) return false;
|
||||||
// Don't relay abandoned transactions
|
// Don't relay abandoned transactions
|
||||||
|
@ -1869,12 +1871,11 @@ bool CWallet::SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string
|
||||||
|
|
||||||
std::set<uint256> CWallet::GetTxConflicts(const CWalletTx& wtx) const
|
std::set<uint256> CWallet::GetTxConflicts(const CWalletTx& wtx) const
|
||||||
{
|
{
|
||||||
std::set<uint256> result;
|
AssertLockHeld(cs_wallet);
|
||||||
{
|
|
||||||
uint256 myHash = wtx.GetHash();
|
const uint256 myHash{wtx.GetHash()};
|
||||||
result = GetConflicts(myHash);
|
std::set<uint256> result{GetConflicts(myHash)};
|
||||||
result.erase(myHash);
|
result.erase(myHash);
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3128,8 +3129,11 @@ int CWallet::GetTxDepthInMainChain(const CWalletTx& wtx) const
|
||||||
|
|
||||||
int CWallet::GetTxBlocksToMaturity(const CWalletTx& wtx) const
|
int CWallet::GetTxBlocksToMaturity(const CWalletTx& wtx) const
|
||||||
{
|
{
|
||||||
if (!wtx.IsCoinBase())
|
AssertLockHeld(cs_wallet);
|
||||||
|
|
||||||
|
if (!wtx.IsCoinBase()) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
int chain_depth = GetTxDepthInMainChain(wtx);
|
int chain_depth = GetTxDepthInMainChain(wtx);
|
||||||
assert(chain_depth >= 0); // coinbase tx should not be conflicted
|
assert(chain_depth >= 0); // coinbase tx should not be conflicted
|
||||||
return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
|
return std::max(0, (COINBASE_MATURITY+1) - chain_depth);
|
||||||
|
@ -3137,6 +3141,8 @@ int CWallet::GetTxBlocksToMaturity(const CWalletTx& wtx) const
|
||||||
|
|
||||||
bool CWallet::IsTxImmatureCoinBase(const CWalletTx& wtx) const
|
bool CWallet::IsTxImmatureCoinBase(const CWalletTx& wtx) const
|
||||||
{
|
{
|
||||||
|
AssertLockHeld(cs_wallet);
|
||||||
|
|
||||||
// note GetBlocksToMaturity is 0 for non-coinbase tx
|
// note GetBlocksToMaturity is 0 for non-coinbase tx
|
||||||
return GetTxBlocksToMaturity(wtx) > 0;
|
return GetTxBlocksToMaturity(wtx) > 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -415,13 +415,7 @@ public:
|
||||||
|
|
||||||
const CWalletTx* GetWalletTx(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
const CWalletTx* GetWalletTx(const uint256& hash) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
|
|
||||||
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
|
std::set<uint256> GetTxConflicts(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
|
|
||||||
// "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid having to
|
|
||||||
// resolve the issue of member access into incomplete type CWallet. Note
|
|
||||||
// that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
|
|
||||||
// in place.
|
|
||||||
std::set<uint256> GetTxConflicts(const CWalletTx& wtx) const NO_THREAD_SAFETY_ANALYSIS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return depth of transaction in blockchain:
|
* Return depth of transaction in blockchain:
|
||||||
|
@ -429,22 +423,20 @@ public:
|
||||||
* 0 : in memory pool, waiting to be included in a block
|
* 0 : in memory pool, waiting to be included in a block
|
||||||
* >=1 : this many blocks deep in the main chain
|
* >=1 : this many blocks deep in the main chain
|
||||||
*/
|
*/
|
||||||
// TODO: Remove "NO_THREAD_SAFETY_ANALYSIS" and replace it with the correct
|
int GetTxDepthInMainChain(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
// annotation "EXCLUSIVE_LOCKS_REQUIRED(pwallet->cs_wallet)". The annotation
|
bool IsTxInMainChain(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet)
|
||||||
// "NO_THREAD_SAFETY_ANALYSIS" was temporarily added to avoid having to
|
{
|
||||||
// resolve the issue of member access into incomplete type CWallet. Note
|
AssertLockHeld(cs_wallet);
|
||||||
// that we still have the runtime check "AssertLockHeld(pwallet->cs_wallet)"
|
return GetTxDepthInMainChain(wtx) > 0;
|
||||||
// in place.
|
}
|
||||||
int GetTxDepthInMainChain(const CWalletTx& wtx) const NO_THREAD_SAFETY_ANALYSIS;
|
|
||||||
bool IsTxInMainChain(const CWalletTx& wtx) const { return GetTxDepthInMainChain(wtx) > 0; }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return number of blocks to maturity for this transaction:
|
* @return number of blocks to maturity for this transaction:
|
||||||
* 0 : is not a coinbase transaction, or is a mature coinbase transaction
|
* 0 : is not a coinbase transaction, or is a mature coinbase transaction
|
||||||
* >0 : is a coinbase transaction which matures in this many blocks
|
* >0 : is a coinbase transaction which matures in this many blocks
|
||||||
*/
|
*/
|
||||||
int GetTxBlocksToMaturity(const CWalletTx& wtx) const;
|
int GetTxBlocksToMaturity(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
bool IsTxImmatureCoinBase(const CWalletTx& wtx) const;
|
bool IsTxImmatureCoinBase(const CWalletTx& wtx) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
|
|
||||||
//! check whether we support the named feature
|
//! check whether we support the named feature
|
||||||
bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); return IsFeatureSupported(nWalletVersion, wf); }
|
bool CanSupportFeature(enum WalletFeature wf) const override EXCLUSIVE_LOCKS_REQUIRED(cs_wallet) { AssertLockHeld(cs_wallet); return IsFeatureSupported(nWalletVersion, wf); }
|
||||||
|
@ -584,7 +576,8 @@ public:
|
||||||
void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm);
|
void CommitTransaction(CTransactionRef tx, mapValue_t mapValue, std::vector<std::pair<std::string, std::string>> orderForm);
|
||||||
|
|
||||||
/** Pass this transaction to node for mempool insertion and relay to peers if flag set to true */
|
/** Pass this transaction to node for mempool insertion and relay to peers if flag set to true */
|
||||||
bool SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string, bool relay) const;
|
bool SubmitTxMemoryPoolAndRelay(CWalletTx& wtx, std::string& err_string, bool relay) const
|
||||||
|
EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
|
||||||
|
|
||||||
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, const CCoinControl* coin_control = nullptr) const
|
bool DummySignTx(CMutableTransaction &txNew, const std::set<CTxOut> &txouts, const CCoinControl* coin_control = nullptr) const
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue