Skip to content

Commit

Permalink
fix(net): Extend blocks-relay-only to also ignore some Dash-specific …
Browse files Browse the repository at this point in the history
…messages/invs (#4888)

* fix(net): Extend blocks-relay-only to also ignore some Dash-specific messages/invs

* Clarify few things
  • Loading branch information
UdjinM6 committed Jul 7, 2022
1 parent e98929a commit a483122
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 115 deletions.
2 changes: 1 addition & 1 deletion src/llmq/instantsend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1526,7 +1526,7 @@ void CInstantSendManager::AskNodesForLockedTx(const uint256& txid, const CConnma
if (nodesToAskFor.size() >= 4) {
return;
}
if (pnode->m_tx_relay != nullptr) {
if (!pnode->m_block_relay_only_peer) {
LOCK(pnode->m_tx_relay->cs_tx_inventory);
if (pnode->m_tx_relay->filterInventoryKnown.contains(txid)) {
pnode->AddRef();
Expand Down
2 changes: 1 addition & 1 deletion src/masternode/sync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ void CMasternodeSync::ProcessTick(CConnman& connman)
// Now that the blockchain is synced request the mempool from the connected outbound nodes if possible
for (auto pNodeTmp : vNodesCopy) {
bool fRequestedEarlier = netfulfilledman.HasFulfilledRequest(pNodeTmp->addr, "mempool-sync");
if (pNodeTmp->nVersion >= 70216 && !pNodeTmp->fInbound && !fRequestedEarlier) {
if (pNodeTmp->nVersion >= 70216 && !pNodeTmp->fInbound && !fRequestedEarlier && !pNodeTmp->IsBlockRelayOnly()) {
netfulfilledman.AddFulfilledRequest(pNodeTmp->addr, "mempool-sync");
connman.PushMessage(pNodeTmp, msgMaker.Make(NetMsgType::MEMPOOL));
LogPrint(BCLog::MNSYNC, "CMasternodeSync::ProcessTick -- nTick %d nCurrentAsset %d -- syncing mempool from peer=%d\n", nTick, nCurrentAsset, pNodeTmp->GetId());
Expand Down
38 changes: 22 additions & 16 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,7 @@ void CNode::copyStats(CNodeStats &stats, const std::vector<bool> &m_asmap)
X(addr);
X(addrBind);
stats.m_mapped_as = addr.GetMappedAS(m_asmap);
if (m_tx_relay != nullptr) {
if (!m_block_relay_only_peer) {
LOCK(m_tx_relay->cs_filter);
stats.fRelayTxes = m_tx_relay->fRelayTxes;
} else {
Expand Down Expand Up @@ -947,7 +947,7 @@ bool CConnman::AttemptToEvictConnection()

bool peer_relay_txes = false;
bool peer_filter_not_null = false;
if (node->m_tx_relay != nullptr) {
if (!node->m_block_relay_only_peer) {
LOCK(node->m_tx_relay->cs_filter);
peer_relay_txes = node->m_tx_relay->fRelayTxes;
peer_filter_not_null = node->m_tx_relay->pfilter != nullptr;
Expand Down Expand Up @@ -2159,7 +2159,7 @@ void CConnman::ThreadOpenConnections(const std::vector<std::string> connect)
// also have the added issue that they're attacker controlled and could be used
// to prevent us from connecting to particular hosts if we used them here.
setConnected.insert(pnode->addr.GetGroup(addrman.m_asmap));
if (pnode->m_tx_relay == nullptr) {
if (pnode->m_block_relay_only_peer) {
nOutboundBlockRelay++;
} else if (!pnode->fFeeler) {
nOutboundFullRelay++;
Expand Down Expand Up @@ -3492,12 +3492,17 @@ void CConnman::RelayInvFiltered(CInv &inv, const CTransaction& relatedTx, const
{
LOCK(cs_vNodes);
for (const auto& pnode : vNodes) {
if (pnode->nVersion < minProtoVersion || !pnode->CanRelay())
if (pnode->nVersion < minProtoVersion || !pnode->CanRelay() || pnode->m_block_relay_only_peer) {
continue;
if (pnode->m_tx_relay != nullptr) {
}
{
LOCK(pnode->m_tx_relay->cs_filter);
if(pnode->m_tx_relay->pfilter && !pnode->m_tx_relay->pfilter->IsRelevantAndUpdate(relatedTx))
if (!pnode->m_tx_relay->fRelayTxes) {
continue;
}
if (pnode->m_tx_relay->pfilter && !pnode->m_tx_relay->pfilter->IsRelevantAndUpdate(relatedTx)) {
continue;
}
}
pnode->PushInventory(inv);
}
Expand All @@ -3507,11 +3512,17 @@ void CConnman::RelayInvFiltered(CInv &inv, const uint256& relatedTxHash, const i
{
LOCK(cs_vNodes);
for (const auto& pnode : vNodes) {
if (pnode->nVersion < minProtoVersion || !pnode->CanRelay())
if (pnode->nVersion < minProtoVersion || !pnode->CanRelay() || pnode->m_block_relay_only_peer) {
continue;
if (pnode->m_tx_relay != nullptr) {
}
{
LOCK(pnode->m_tx_relay->cs_filter);
if(pnode->m_tx_relay->pfilter && !pnode->m_tx_relay->pfilter->contains(relatedTxHash)) continue;
if (!pnode->m_tx_relay->fRelayTxes) {
continue;
}
if (pnode->m_tx_relay->pfilter && !pnode->m_tx_relay->pfilter->contains(relatedTxHash)) {
continue;
}
}
pnode->PushInventory(inv);
}
Expand Down Expand Up @@ -3653,10 +3664,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
fInbound(fInboundIn),
nKeyedNetGroup(nKeyedNetGroupIn),
addrKnown(5000, 0.001),
// Don't relay addr messages to peers that we connect to as block-relay-only
// peers (to prevent adversaries from inferring these links from addr
// traffic).
m_addr_relay_peer(!block_relay_only),
m_block_relay_only_peer(block_relay_only),
id(idIn),
nLocalHostNonce(nLocalHostNonceIn),
nLocalServices(nLocalServicesIn),
Expand All @@ -3665,9 +3673,7 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
hSocket = hSocketIn;
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
hashContinue = uint256();
if (!block_relay_only) {
m_tx_relay = MakeUnique<TxRelay>();
}
m_tx_relay = MakeUnique<TxRelay>();

for (const std::string &msg : getAllNetMessageTypes())
mapRecvBytesPerMsgCmd[msg] = 0;
Expand Down
75 changes: 34 additions & 41 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -1028,15 +1028,25 @@ class CNode
int64_t nNextAddrSend GUARDED_BY(cs_sendProcessing){0};
int64_t nNextLocalAddrSend GUARDED_BY(cs_sendProcessing){0};

const bool m_addr_relay_peer;
bool IsAddrRelayPeer() const { return m_addr_relay_peer; }
const bool m_block_relay_only_peer;

// Don't relay addr messages to peers that we connect to as block-relay-only
// peers (to prevent adversaries from inferring these links from addr
// traffic).
bool IsAddrRelayPeer() const { return !m_block_relay_only_peer; }

bool IsBlockRelayOnly() const
{
// Stop processing non-block data early if
// 1) We are in blocks only mode and peer has no relay permission
// 2) This peer is a block-relay-only peer
return (!g_relay_txes && !HasPermission(PF_RELAY)) || m_block_relay_only_peer;
}

// List of block ids we still have announce.
// There is no final sorting before sending, as they are always sent immediately
// and in the order requested.
std::vector<uint256> vInventoryBlockToSend GUARDED_BY(cs_inventory);
// List of non-tx/non-block inventory items
std::vector<CInv> vInventoryOtherToSend;
CCriticalSection cs_inventory;
/** UNIX epoch time of the last block received from this peer that we had
* not yet seen (e.g. not already received from another peer), that passed
Expand Down Expand Up @@ -1066,15 +1076,18 @@ class CNode
CRollingBloomFilter filterInventoryKnown GUARDED_BY(cs_tx_inventory){50000, 0.000001};
// Set of transaction ids we still have to announce.
// They are sorted by the mempool before relay, so the order is not important.
std::set<uint256> setInventoryTxToSend;
std::set<uint256> setInventoryTxToSend GUARDED_BY(cs_tx_inventory);
// List of non-tx/non-block inventory items
std::vector<CInv> vInventoryOtherToSend GUARDED_BY(cs_tx_inventory);
// Used for BIP35 mempool sending, also protected by cs_tx_inventory
bool fSendMempool GUARDED_BY(cs_tx_inventory){false};
// Last time a "MEMPOOL" request was serviced.
std::atomic<int64_t> timeLastMempoolReq{0};
std::chrono::microseconds nNextInvSend{0};
};

// m_tx_relay == nullptr if we're not relaying transactions with this peer
// in bitcoin: m_tx_relay == nullptr if we're not relaying transactions with this peer
// in dash: m_tx_relay should never be nullptr, use m_block_relay_only_peer == true instead
std::unique_ptr<TxRelay> m_tx_relay;

// Used for headers announcements - unfiltered blocks to relay
Expand Down Expand Up @@ -1234,49 +1247,29 @@ class CNode

void AddInventoryKnown(const uint256& hash)
{
if (m_tx_relay != nullptr) {
LOCK(m_tx_relay->cs_tx_inventory);
m_tx_relay->filterInventoryKnown.insert(hash);
}
LOCK(m_tx_relay->cs_tx_inventory);
m_tx_relay->filterInventoryKnown.insert(hash);
}

void PushInventory(const CInv& inv)
{
if (inv.type == MSG_TX || inv.type == MSG_DSTX) {
if (m_tx_relay != nullptr) {
LOCK(m_tx_relay->cs_tx_inventory);
if (!m_tx_relay->filterInventoryKnown.contains(inv.hash)) {
LogPrint(BCLog::NET, "%s -- adding new inv: %s peer=%d\n", __func__, inv.ToString(), id);
LOCK(m_tx_relay->cs_filter);
m_tx_relay->setInventoryTxToSend.insert(inv.hash);
} else {
LogPrint(BCLog::NET, "%s -- skipping known inv: %s peer=%d\n", __func__, inv.ToString(), id);
}
} else {
LogPrint(BCLog::NET, "%s -- skipping unknown inv: %s peer=%d\n", __func__, inv.ToString(), id);
}
} else if (inv.type == MSG_BLOCK) {
if (inv.type == MSG_BLOCK) {
LogPrint(BCLog::NET, "%s -- adding new inv: %s peer=%d\n", __func__, inv.ToString(), id);
LOCK(cs_inventory);
vInventoryBlockToSend.push_back(inv.hash);
} else {
LOCK(cs_inventory);
if (m_tx_relay != nullptr) {
LOCK(m_tx_relay->cs_tx_inventory);
if (!m_tx_relay->filterInventoryKnown.contains(inv.hash)) {
LogPrint(BCLog::NET, "%s -- adding new inv: %s peer=%d\n", __func__, inv.ToString(), id);
vInventoryOtherToSend.push_back(inv);
} else {
LogPrint(BCLog::NET, "%s -- skipping known inv: %s peer=%d\n", __func__, inv.ToString(), id);
}
} else {
// TODO KNST for this case we don't use inventory
// accordingly #2292 it can increase size of transmitted data.
// Should be added dedicated bloom filter
LogPrint(BCLog::NET, "%s -- adding new inv: %s peer=%d\n", __func__, inv.ToString(), id);
vInventoryOtherToSend.push_back(inv);
}
return;
}
LOCK(m_tx_relay->cs_tx_inventory);
if (m_tx_relay->filterInventoryKnown.contains(inv.hash)) {
LogPrint(BCLog::NET, "%s -- skipping known inv: %s peer=%d\n", __func__, inv.ToString(), id);
return;
}
LogPrint(BCLog::NET, "%s -- adding new inv: %s peer=%d\n", __func__, inv.ToString(), id);
if (inv.type == MSG_TX || inv.type == MSG_DSTX) {
m_tx_relay->setInventoryTxToSend.insert(inv.hash);
return;
}
m_tx_relay->vInventoryOtherToSend.push_back(inv);
}

void PushBlockHash(const uint256 &hash)
Expand Down
Loading

0 comments on commit a483122

Please sign in to comment.