Skip to content

Commit

Permalink
[refactor] Move tx relay state to separate structure
Browse files Browse the repository at this point in the history
  • Loading branch information
sdaftuar committed Aug 28, 2019
1 parent 26a93bc commit 4de0dba
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 89 deletions.
15 changes: 6 additions & 9 deletions src/net.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,8 +500,8 @@ void CNode::copyStats(CNodeStats &stats)
X(addr);
X(addrBind);
{
LOCK(cs_filter);
X(fRelayTxes);
LOCK(m_tx_relay.cs_filter);
stats.fRelayTxes = m_tx_relay.fRelayTxes;
}
X(nLastSend);
X(nLastRecv);
Expand Down Expand Up @@ -529,8 +529,8 @@ void CNode::copyStats(CNodeStats &stats)
X(m_legacyWhitelisted);
X(m_permissionFlags);
{
LOCK(cs_feeFilter);
X(minFeeFilter);
LOCK(m_tx_relay.cs_feeFilter);
stats.minFeeFilter = m_tx_relay.minFeeFilter;
}

// It is common for nodes with good ping times to suddenly become lagged,
Expand Down Expand Up @@ -818,11 +818,11 @@ bool CConnman::AttemptToEvictConnection()
continue;
if (node->fDisconnect)
continue;
LOCK(node->cs_filter);
LOCK(node->m_tx_relay.cs_filter);
NodeEvictionCandidate candidate = {node->GetId(), node->nTimeConnected, node->nMinPingUsecTime,
node->nLastBlockTime, node->nLastTXTime,
HasAllDesirableServiceFlags(node->nServices),
node->fRelayTxes, node->pfilter != nullptr, node->addr, node->nKeyedNetGroup,
node->m_tx_relay.fRelayTxes, node->m_tx_relay.pfilter != nullptr, node->addr, node->nKeyedNetGroup,
node->m_prefer_evict};
vEvictionCandidates.push_back(candidate);
}
Expand Down Expand Up @@ -2625,7 +2625,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
fInbound(fInboundIn),
nKeyedNetGroup(nKeyedNetGroupIn),
addrKnown(5000, 0.001),
filterInventoryKnown(50000, 0.000001),
id(idIn),
nLocalHostNonce(nLocalHostNonceIn),
nLocalServices(nLocalServicesIn),
Expand All @@ -2634,8 +2633,6 @@ CNode::CNode(NodeId idIn, ServiceFlags nLocalServicesIn, int nMyStartingHeightIn
hSocket = hSocketIn;
addrName = addrNameIn == "" ? addr.ToStringIPPort() : addrNameIn;
hashContinue = uint256();
filterInventoryKnown.reset();
pfilter = MakeUnique<CBloomFilter>();

for (const std::string &msg : getAllNetMessageTypes())
mapRecvBytesPerMsgCmd[msg] = 0;
Expand Down
64 changes: 36 additions & 28 deletions src/net.h
Original file line number Diff line number Diff line change
Expand Up @@ -676,15 +676,8 @@ class CNode
// Setting fDisconnect to true will cause the node to be disconnected the
// next time DisconnectNodes() runs
std::atomic_bool fDisconnect{false};
// We use fRelayTxes for two purposes -
// a) it allows us to not relay tx invs before receiving the peer's version message
// b) the peer may tell us in its version message that we should not relay tx invs
// unless it loads a bloom filter.
bool fRelayTxes GUARDED_BY(cs_filter){false};
bool fSentAddr{false};
CSemaphoreGrant grantOutbound;
mutable CCriticalSection cs_filter;
std::unique_ptr<CBloomFilter> pfilter PT_GUARDED_BY(cs_filter);
std::atomic<int> nRefCount{0};

const uint64_t nKeyedNetGroup;
Expand All @@ -706,24 +699,43 @@ class CNode
int64_t nNextAddrSend GUARDED_BY(cs_sendProcessing){0};
int64_t nNextLocalAddrSend GUARDED_BY(cs_sendProcessing){0};

// inventory based relay
CRollingBloomFilter filterInventoryKnown GUARDED_BY(cs_inventory);
// 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;
// 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);
CCriticalSection cs_inventory;
int64_t nNextInvSend{0};

struct TxRelay {
TxRelay() { pfilter = MakeUnique<CBloomFilter>(); }
mutable CCriticalSection cs_filter;
// We use fRelayTxes for two purposes -
// a) it allows us to not relay tx invs before receiving the peer's version message
// b) the peer may tell us in its version message that we should not relay tx invs
// unless it loads a bloom filter.
bool fRelayTxes GUARDED_BY(cs_filter){false};
std::unique_ptr<CBloomFilter> pfilter PT_GUARDED_BY(cs_filter) GUARDED_BY(cs_filter);

mutable CCriticalSection cs_tx_inventory;
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;
// Used for BIP35 mempool sending
bool fSendMempool GUARDED_BY(cs_tx_inventory){false};
// Last time a "MEMPOOL" request was serviced.
std::atomic<int64_t> timeLastMempoolReq{0};
int64_t nNextInvSend{0};

CCriticalSection cs_feeFilter;
// Minimum fee rate with which to filter inv's to this node
CAmount minFeeFilter GUARDED_BY(cs_feeFilter){0};
CAmount lastSentFeeFilter{0};
int64_t nextSendTimeFeeFilter{0};
};

TxRelay m_tx_relay;
// Used for headers announcements - unfiltered blocks to relay
std::vector<uint256> vBlockHashesToAnnounce GUARDED_BY(cs_inventory);
// Used for BIP35 mempool sending
bool fSendMempool GUARDED_BY(cs_inventory){false};

// Last time a "MEMPOOL" request was serviced.
std::atomic<int64_t> timeLastMempoolReq{0};

// Block and TXN accept times
std::atomic<int64_t> nLastBlockTime{0};
Expand All @@ -740,11 +752,6 @@ class CNode
std::atomic<int64_t> nMinPingUsecTime{std::numeric_limits<int64_t>::max()};
// Whether a ping is requested.
std::atomic<bool> fPingQueued{false};
// Minimum fee rate with which to filter inv's to this node
CAmount minFeeFilter GUARDED_BY(cs_feeFilter){0};
CCriticalSection cs_feeFilter;
CAmount lastSentFeeFilter{0};
int64_t nextSendTimeFeeFilter{0};

std::set<uint256> orphan_work_set;

Expand Down Expand Up @@ -842,19 +849,20 @@ class CNode
void AddInventoryKnown(const CInv& inv)
{
{
LOCK(cs_inventory);
filterInventoryKnown.insert(inv.hash);
LOCK(m_tx_relay.cs_tx_inventory);
m_tx_relay.filterInventoryKnown.insert(inv.hash);
}
}

void PushInventory(const CInv& inv)
{
LOCK(cs_inventory);
if (inv.type == MSG_TX) {
if (!filterInventoryKnown.contains(inv.hash)) {
setInventoryTxToSend.insert(inv.hash);
LOCK(m_tx_relay.cs_tx_inventory);
if (!m_tx_relay.filterInventoryKnown.contains(inv.hash)) {
m_tx_relay.setInventoryTxToSend.insert(inv.hash);
}
} else if (inv.type == MSG_BLOCK) {
LOCK(cs_inventory);
vInventoryBlockToSend.push_back(inv.hash);
}
}
Expand Down
Loading

0 comments on commit 4de0dba

Please sign in to comment.