mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-03 12:25:54 +02:00
net_processing: handle ConnectionType::PRIVATE_BROADCAST connections
For connections of type `ConnectionType::PRIVATE_BROADCAST`: * After receiving VERACK, send a transaction from the list of transactions for private broadcast and disconnect * Don't process any messages after VERACK (modulo `GETDATA` and `PONG`) * Don't send any messages other than the minimum required for the transaction send - `INV`, `TX`, `PING`.
This commit is contained in:
27
src/net.cpp
27
src/net.cpp
@@ -354,7 +354,16 @@ bool CConnman::CheckIncomingNonce(uint64_t nonce)
|
||||
{
|
||||
LOCK(m_nodes_mutex);
|
||||
for (const CNode* pnode : m_nodes) {
|
||||
if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && pnode->GetLocalNonce() == nonce)
|
||||
// Omit private broadcast connections from this check to prevent this privacy attack:
|
||||
// - We connect to a peer in an attempt to privately broadcast a transaction. From our
|
||||
// VERSION message the peer deducts that this is a short-lived connection for
|
||||
// broadcasting a transaction, takes our nonce and delays their VERACK.
|
||||
// - The peer starts connecting to (clearnet) nodes and sends them a VERSION message
|
||||
// which contains our nonce. If the peer manages to connect to us we would disconnect.
|
||||
// - Upon a disconnect, the peer knows our clearnet address. They go back to the short
|
||||
// lived privacy broadcast connection and continue with VERACK.
|
||||
if (!pnode->fSuccessfullyConnected && !pnode->IsInboundConn() && !pnode->IsPrivateBroadcastConn() &&
|
||||
pnode->GetLocalNonce() == nonce)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -4048,10 +4057,26 @@ bool CConnman::NodeFullyConnected(const CNode* pnode)
|
||||
return pnode && pnode->fSuccessfullyConnected && !pnode->fDisconnect;
|
||||
}
|
||||
|
||||
/// Private broadcast connections only need to send certain message types.
|
||||
/// Other messages are not needed and may degrade privacy.
|
||||
static bool IsOutboundMessageAllowedInPrivateBroadcast(std::string_view type) noexcept
|
||||
{
|
||||
return type == NetMsgType::VERSION ||
|
||||
type == NetMsgType::VERACK ||
|
||||
type == NetMsgType::INV ||
|
||||
type == NetMsgType::TX ||
|
||||
type == NetMsgType::PING;
|
||||
}
|
||||
|
||||
void CConnman::PushMessage(CNode* pnode, CSerializedNetMsg&& msg)
|
||||
{
|
||||
AssertLockNotHeld(m_total_bytes_sent_mutex);
|
||||
|
||||
if (pnode->IsPrivateBroadcastConn() && !IsOutboundMessageAllowedInPrivateBroadcast(msg.m_type)) {
|
||||
LogDebug(BCLog::PRIVBROADCAST, "Omitting send of message '%s', peer=%d%s", msg.m_type, pnode->GetId(), pnode->LogIP(fLogIPs));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!m_private_broadcast.m_outbound_tor_ok_at_least_once.load() && !pnode->IsInboundConn() &&
|
||||
pnode->addr.IsTor() && msg.m_type == NetMsgType::VERACK) {
|
||||
// If we are sending the peer VERACK that means we successfully sent
|
||||
|
||||
Reference in New Issue
Block a user