Defer inserting into maprelay until just before relaying.
This reduces the rate of not founds by better matching the far end expectations, it also improves privacy by removing the ability to use getdata to probe for a node having a txn before it has been relayed.
This commit is contained in:
parent
862fd24b40
commit
4d8993b346
3 changed files with 30 additions and 31 deletions
39
src/main.cpp
39
src/main.cpp
|
@ -80,6 +80,10 @@ uint64_t nPruneTarget = 0;
|
||||||
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
|
int64_t nMaxTipAge = DEFAULT_MAX_TIP_AGE;
|
||||||
bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT;
|
bool fEnableReplacement = DEFAULT_ENABLE_REPLACEMENT;
|
||||||
|
|
||||||
|
std::map<uint256, CTransaction> mapRelay;
|
||||||
|
std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
|
||||||
|
CCriticalSection cs_mapRelay;
|
||||||
|
|
||||||
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
|
CFeeRate minRelayTxFee = CFeeRate(DEFAULT_MIN_RELAY_TX_FEE);
|
||||||
CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
|
CAmount maxTxFee = DEFAULT_TRANSACTION_MAXFEE;
|
||||||
|
|
||||||
|
@ -4501,27 +4505,28 @@ void static ProcessGetData(CNode* pfrom, const Consensus::Params& consensusParam
|
||||||
}
|
}
|
||||||
else if (inv.IsKnownType())
|
else if (inv.IsKnownType())
|
||||||
{
|
{
|
||||||
|
CTransaction tx;
|
||||||
// Send stream from relay memory
|
// Send stream from relay memory
|
||||||
bool pushed = false;
|
bool push = false;
|
||||||
{
|
{
|
||||||
LOCK(cs_mapRelay);
|
LOCK(cs_mapRelay);
|
||||||
map<uint256, CTransaction>::iterator mi = mapRelay.find(inv.hash);
|
map<uint256, CTransaction>::iterator mi = mapRelay.find(inv.hash);
|
||||||
if (mi != mapRelay.end()) {
|
if (mi != mapRelay.end()) {
|
||||||
pfrom->PushMessage(inv.GetCommand(), (*mi).second);
|
tx = (*mi).second;
|
||||||
pushed = true;
|
push = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pushed && inv.type == MSG_TX) {
|
if (!push && inv.type == MSG_TX) {
|
||||||
CTransaction tx;
|
|
||||||
int64_t txtime;
|
int64_t txtime;
|
||||||
// To protect privacy, do not answer getdata using the mempool when
|
// To protect privacy, do not answer getdata using the mempool when
|
||||||
// that TX couldn't have been INVed in reply to a MEMPOOL request.
|
// that TX couldn't have been INVed in reply to a MEMPOOL request.
|
||||||
if (mempool.lookup(inv.hash, tx, txtime) && txtime <= pfrom->timeLastMempoolReq) {
|
if (mempool.lookup(inv.hash, tx, txtime) && txtime <= pfrom->timeLastMempoolReq) {
|
||||||
pfrom->PushMessage(NetMsgType::TX, tx);
|
push = true;
|
||||||
pushed = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pushed) {
|
if (push) {
|
||||||
|
pfrom->PushMessage(inv.GetCommand(), tx);
|
||||||
|
} else {
|
||||||
vNotFound.push_back(inv);
|
vNotFound.push_back(inv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5958,14 +5963,26 @@ bool SendMessages(CNode* pto)
|
||||||
if (filterrate && feeRate.GetFeePerK() < filterrate) {
|
if (filterrate && feeRate.GetFeePerK() < filterrate) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (pto->pfilter) {
|
|
||||||
CTransaction tx;
|
CTransaction tx;
|
||||||
if (!mempool.lookup(hash, tx)) continue;
|
if (!mempool.lookup(hash, tx)) continue;
|
||||||
if (!pto->pfilter->IsRelevantAndUpdate(tx)) continue;
|
if (pto->pfilter && !pto->pfilter->IsRelevantAndUpdate(tx)) continue;
|
||||||
}
|
|
||||||
// Send
|
// Send
|
||||||
vInv.push_back(CInv(MSG_TX, hash));
|
vInv.push_back(CInv(MSG_TX, hash));
|
||||||
nRelayedTransactions++;
|
nRelayedTransactions++;
|
||||||
|
{
|
||||||
|
LOCK(cs_mapRelay);
|
||||||
|
// Expire old relay messages
|
||||||
|
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
|
||||||
|
{
|
||||||
|
mapRelay.erase(vRelayExpiration.front().second);
|
||||||
|
vRelayExpiration.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto ret = mapRelay.insert(std::make_pair(hash, tx));
|
||||||
|
if (ret.second) {
|
||||||
|
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, hash));
|
||||||
|
}
|
||||||
|
}
|
||||||
if (vInv.size() == MAX_INV_SZ) {
|
if (vInv.size() == MAX_INV_SZ) {
|
||||||
pto->PushMessage(NetMsgType::INV, vInv);
|
pto->PushMessage(NetMsgType::INV, vInv);
|
||||||
vInv.clear();
|
vInv.clear();
|
||||||
|
|
15
src/net.cpp
15
src/net.cpp
|
@ -90,9 +90,6 @@ std::string strSubVersion;
|
||||||
|
|
||||||
std::vector<CNode*> vNodes;
|
std::vector<CNode*> vNodes;
|
||||||
CCriticalSection cs_vNodes;
|
CCriticalSection cs_vNodes;
|
||||||
std::map<uint256, CTransaction> mapRelay;
|
|
||||||
std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
|
|
||||||
CCriticalSection cs_mapRelay;
|
|
||||||
limitedmap<uint256, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
|
limitedmap<uint256, int64_t> mapAlreadyAskedFor(MAX_INV_SZ);
|
||||||
|
|
||||||
static std::deque<std::string> vOneShots;
|
static std::deque<std::string> vOneShots;
|
||||||
|
@ -2081,18 +2078,6 @@ instance_of_cnetcleanup;
|
||||||
void RelayTransaction(const CTransaction& tx)
|
void RelayTransaction(const CTransaction& tx)
|
||||||
{
|
{
|
||||||
CInv inv(MSG_TX, tx.GetHash());
|
CInv inv(MSG_TX, tx.GetHash());
|
||||||
{
|
|
||||||
LOCK(cs_mapRelay);
|
|
||||||
// Expire old relay messages
|
|
||||||
while (!vRelayExpiration.empty() && vRelayExpiration.front().first < GetTime())
|
|
||||||
{
|
|
||||||
mapRelay.erase(vRelayExpiration.front().second);
|
|
||||||
vRelayExpiration.pop_front();
|
|
||||||
}
|
|
||||||
|
|
||||||
mapRelay.insert(std::make_pair(inv.hash, tx));
|
|
||||||
vRelayExpiration.push_back(std::make_pair(GetTime() + 15 * 60, inv.hash));
|
|
||||||
}
|
|
||||||
LOCK(cs_vNodes);
|
LOCK(cs_vNodes);
|
||||||
BOOST_FOREACH(CNode* pnode, vNodes)
|
BOOST_FOREACH(CNode* pnode, vNodes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -162,9 +162,6 @@ extern int nMaxConnections;
|
||||||
|
|
||||||
extern std::vector<CNode*> vNodes;
|
extern std::vector<CNode*> vNodes;
|
||||||
extern CCriticalSection cs_vNodes;
|
extern CCriticalSection cs_vNodes;
|
||||||
extern std::map<uint256, CTransaction> mapRelay;
|
|
||||||
extern std::deque<std::pair<int64_t, uint256> > vRelayExpiration;
|
|
||||||
extern CCriticalSection cs_mapRelay;
|
|
||||||
extern limitedmap<uint256, int64_t> mapAlreadyAskedFor;
|
extern limitedmap<uint256, int64_t> mapAlreadyAskedFor;
|
||||||
|
|
||||||
extern std::vector<std::string> vAddedNodes;
|
extern std::vector<std::string> vAddedNodes;
|
||||||
|
|
Loading…
Reference in a new issue