Skip to content

Commit

Permalink
fix: guard m_can_tx_relay behind m_tx_relay_mutex; make it private; a…
Browse files Browse the repository at this point in the history
…dd additional annotations

Originally introduced in pr 6365; this datarace was discovered using tsan locally, and running feature_llmq_chainlocks 5 times. 1 out of 5 times failed
  • Loading branch information
PastaPastaPasta committed Nov 19, 2024
1 parent 018d80a commit f39c1e6
Showing 1 changed file with 9 additions and 7 deletions.
16 changes: 9 additions & 7 deletions src/net_processing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,21 +309,23 @@ struct Peer {
/**
* (Bitcoin) Initializes a TxRelay struct for this peer. Can be called at most once for a peer.
* (Dash) Enables the flag that allows GetTxRelay() to return m_tx_relay */
TxRelay* SetTxRelay()
TxRelay* SetTxRelay() LOCKS_EXCLUDED(m_tx_relay_mutex)
{
LOCK(m_tx_relay_mutex);
Assume(!m_can_tx_relay);
m_can_tx_relay = true;
return WITH_LOCK(m_tx_relay_mutex, return m_tx_relay.get());
return m_tx_relay.get();
};

TxRelay* GetInvRelay()
TxRelay* GetInvRelay() LOCKS_EXCLUDED(m_tx_relay_mutex)
{
return WITH_LOCK(m_tx_relay_mutex, return m_tx_relay.get());
}

TxRelay* GetTxRelay()
TxRelay* GetTxRelay() LOCKS_EXCLUDED(m_tx_relay_mutex)
{
return m_can_tx_relay ? WITH_LOCK(m_tx_relay_mutex, return m_tx_relay.get()) : nullptr;
LOCK(m_tx_relay_mutex);
return m_can_tx_relay ? m_tx_relay.get() : nullptr;
};

/** A vector of addresses to send to the peer, limited to MAX_ADDR_TO_SEND. */
Expand Down Expand Up @@ -353,8 +355,6 @@ struct Peer {
* This field must correlate with whether m_addr_known has been
* initialized.*/
std::atomic_bool m_addr_relay_enabled{false};
/** Whether a peer can relay transactions */
bool m_can_tx_relay{false};
/** Whether a getaddr request to this peer is outstanding. */
bool m_getaddr_sent GUARDED_BY(NetEventsInterface::g_msgproc_mutex){false};
/** Guards address sending timers. */
Expand Down Expand Up @@ -406,6 +406,8 @@ struct Peer {
* (non-transaction relay should use GetInvRelay(), which will provide
* unconditional access) */
std::unique_ptr<TxRelay> m_tx_relay GUARDED_BY(m_tx_relay_mutex){std::make_unique<TxRelay>()};
/** Whether a peer can relay transactions */
bool m_can_tx_relay GUARDED_BY(m_tx_relay_mutex) {false};
};

using PeerRef = std::shared_ptr<Peer>;
Expand Down

0 comments on commit f39c1e6

Please sign in to comment.