Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
Show First 20 Lines • Show All 1,757 Lines • ▼ Show 20 Lines | static bool AlreadyHave(const CInv &inv, const CTxMemPool &mempool) | ||||
return true; | return true; | ||||
} | } | ||||
void RelayTransaction(const TxId &txid, const CConnman &connman) { | void RelayTransaction(const TxId &txid, const CConnman &connman) { | ||||
connman.ForEachNode( | connman.ForEachNode( | ||||
[&txid](CNode *pnode) { pnode->PushTxInventory(txid); }); | [&txid](CNode *pnode) { pnode->PushTxInventory(txid); }); | ||||
} | } | ||||
void RelayProof(const avalanche::ProofId &proofid, const CConnman &connman) { | |||||
connman.ForEachNode( | |||||
[&proofid](CNode *pnode) { pnode->PushProofInventory(proofid); }); | |||||
} | |||||
static void RelayAddress(const CAddress &addr, bool fReachable, | static void RelayAddress(const CAddress &addr, bool fReachable, | ||||
const CConnman &connman) { | const CConnman &connman) { | ||||
// Limited relaying of addresses outside our network(s) | // Limited relaying of addresses outside our network(s) | ||||
unsigned int nRelayNodes = fReachable ? 2 : 1; | unsigned int nRelayNodes = fReachable ? 2 : 1; | ||||
// Relay to a limited number of other nodes. | // Relay to a limited number of other nodes. | ||||
// Use deterministic randomness to send to the same nodes for 24 hours at a | // Use deterministic randomness to send to the same nodes for 24 hours at a | ||||
// time so the m_addr_knowns of the chosen nodes prevent repeats | // time so the m_addr_knowns of the chosen nodes prevent repeats | ||||
▲ Show 20 Lines • Show All 2,238 Lines • ▼ Show 20 Lines | |||||
if (msg_type == NetMsgType::AVAPROOF) { | if (msg_type == NetMsgType::AVAPROOF) { | ||||
// Read the proof. | // Read the proof. | ||||
avalanche::Proof proof; | avalanche::Proof proof; | ||||
vRecv >> proof; | vRecv >> proof; | ||||
pfrom.AddKnownProof(proof.getId()); | pfrom.AddKnownProof(proof.getId()); | ||||
if (!g_avalanche->addProof(std::move(proof)) && | if (g_avalanche->addProof(std::move(proof))) { | ||||
!g_avalanche->getProof(proof.getId())) { | // It was successfuly verified and we didn't already have it | ||||
RelayProof(proof.getId(), m_connman); | |||||
} else if (!g_avalanche->getProof(proof.getId())) { | |||||
// We didn't add it, and it is not because we already have it. | // We didn't add it, and it is not because we already have it. | ||||
// It must be bad. | // It must be bad. | ||||
Misbehaving(pfrom, 100, "invalid-proof"); | Misbehaving(pfrom, 100, "invalid-proof"); | ||||
} | } | ||||
// Else we already had it, and there is nothing to do | |||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::AVAPOLL) { | if (msg_type == NetMsgType::AVAPOLL) { | ||||
auto now = std::chrono::steady_clock::now(); | auto now = std::chrono::steady_clock::now(); | ||||
int64_t cooldown = | int64_t cooldown = | ||||
gArgs.GetArg("-avacooldown", AVALANCHE_DEFAULT_COOLDOWN); | gArgs.GetArg("-avacooldown", AVALANCHE_DEFAULT_COOLDOWN); | ||||
▲ Show 20 Lines • Show All 1,311 Lines • ▼ Show 20 Lines | if (pingSend) { | ||||
m_connman.PushMessage( | m_connman.PushMessage( | ||||
pto, msgMaker.Make(NetMsgType::INV, vInv)); | pto, msgMaker.Make(NetMsgType::INV, vInv)); | ||||
vInv.clear(); | vInv.clear(); | ||||
} | } | ||||
pto->m_tx_relay->filterInventoryKnown.insert(txid); | pto->m_tx_relay->filterInventoryKnown.insert(txid); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
// Send avaproof inventories | |||||
if (pto->m_proof_relay != nullptr) { | |||||
LOCK(pto->m_proof_relay->cs_proof_inventory); | |||||
// Check whether periodic sends should happen | |||||
bool fSendTrickle = pto->HasPermission(PF_NOBAN); | |||||
if (pto->m_proof_relay->nNextInvSend < current_time) { | |||||
fSendTrickle = true; | |||||
if (pto->IsInboundConn()) { | |||||
pto->m_proof_relay->nNextInvSend = | |||||
std::chrono::microseconds{ | |||||
m_connman.PoissonNextSendInbound( | |||||
nNow, INVENTORY_BROADCAST_INTERVAL)}; | |||||
} else { | |||||
// Skip delay for outbound peers, as there is less | |||||
// privacy concern for them. | |||||
pto->m_tx_relay->nNextInvSend = current_time; | |||||
} | |||||
} | |||||
// Determine proofs to relay | |||||
if (fSendTrickle) { | |||||
// Produce a vector with all candidates for sending | |||||
std::vector<avalanche::ProofId> vInvProof; | |||||
vInvProof.reserve( | |||||
pto->m_proof_relay->setInventoryProofsToSend.size()); | |||||
for (auto &it : | |||||
pto->m_proof_relay->setInventoryProofsToSend) { | |||||
vInvProof.push_back(it); | |||||
} | |||||
// Topologically sort the inventory we send for privacy | |||||
// reasons. A heap is used so that not | |||||
// all items need sorting if only a few are being sent. | |||||
std::make_heap(vInvProof.begin(), vInvProof.end()); | |||||
// No reason to drain out at many times the network's | |||||
// capacity, especially since we have many peers and some | |||||
// will draw much shorter delays. | |||||
unsigned int nRelayedProofs = 0; | |||||
LOCK(pto->m_proof_relay->cs_filter); | |||||
while (!vInvProof.empty() && | |||||
nRelayedProofs < INVENTORY_BROADCAST_MAX_PER_MB * | |||||
config.GetMaxBlockSize() / | |||||
1000000) { | |||||
// Fetch the top element from the heap | |||||
std::pop_heap(vInvProof.begin(), vInvProof.end()); | |||||
const avalanche::ProofId proofid = vInvProof.back(); | |||||
vInvProof.pop_back(); | |||||
// Remove it from the to-be-sent set | |||||
pto->m_proof_relay->setInventoryProofsToSend.erase( | |||||
proofid); | |||||
// Check if not in the filter already | |||||
if (pto->m_proof_relay->filterInventoryKnown.contains( | |||||
proofid)) { | |||||
continue; | |||||
} | |||||
// Not in the set of valid or orphan proofs anymore? | |||||
// Don't bother sending it. | |||||
avalanche::Proof proof = | |||||
*g_avalanche->getProof(proofid); | |||||
// Send | |||||
vInv.push_back(CInv(MSG_AVA_PROOF, proofid)); | |||||
nRelayedProofs++; | |||||
if (vInv.size() == MAX_INV_SZ) { | |||||
m_connman.PushMessage( | |||||
pto, msgMaker.Make(NetMsgType::INV, vInv)); | |||||
vInv.clear(); | |||||
} | |||||
pto->m_proof_relay->filterInventoryKnown.insert( | |||||
proofid); | |||||
} | |||||
} | |||||
} | |||||
} | } | ||||
if (!vInv.empty()) { | if (!vInv.empty()) { | ||||
m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv)); | m_connman.PushMessage(pto, msgMaker.Make(NetMsgType::INV, vInv)); | ||||
} | } | ||||
// Detect whether we're stalling | // Detect whether we're stalling | ||||
current_time = GetTime<std::chrono::microseconds>(); | current_time = GetTime<std::chrono::microseconds>(); | ||||
// nNow is the current system time (GetTimeMicros is not mockable) and | // nNow is the current system time (GetTimeMicros is not mockable) and | ||||
▲ Show 20 Lines • Show All 260 Lines • Show Last 20 Lines |