Changeset View
Changeset View
Standalone View
Standalone View
src/net_processing.cpp
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
Show First 20 Lines • Show All 3,255 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
bool IsAvalancheMessageType(const std::string &msg_type) { | bool IsAvalancheMessageType(const std::string &msg_type) { | ||||
return msg_type == NetMsgType::AVAHELLO || | return msg_type == NetMsgType::AVAHELLO || | ||||
msg_type == NetMsgType::AVAPOLL || | msg_type == NetMsgType::AVAPOLL || | ||||
msg_type == NetMsgType::AVARESPONSE || | msg_type == NetMsgType::AVARESPONSE || | ||||
msg_type == NetMsgType::AVAPROOF || | msg_type == NetMsgType::AVAPROOF || | ||||
msg_type == NetMsgType::GETAVAADDR || | msg_type == NetMsgType::GETAVAADDR || | ||||
msg_type == NetMsgType::GETAVAPROOFS; | msg_type == NetMsgType::GETAVAPROOFS || | ||||
msg_type == NetMsgType::AVAPROOFS; | |||||
} | } | ||||
uint32_t PeerManagerImpl::GetAvalancheVoteForBlock(const BlockHash &hash) { | uint32_t PeerManagerImpl::GetAvalancheVoteForBlock(const BlockHash &hash) { | ||||
AssertLockHeld(cs_main); | AssertLockHeld(cs_main); | ||||
const CBlockIndex *pindex = m_chainman.m_blockman.LookupBlockIndex(hash); | const CBlockIndex *pindex = m_chainman.m_blockman.LookupBlockIndex(hash); | ||||
// Unknown block. | // Unknown block. | ||||
▲ Show 20 Lines • Show All 1,874 Lines • ▼ Show 20 Lines | if (msg_type == NetMsgType::GETAVAPROOFS) { | ||||
avalanche::CompactProofs compactProofs( | avalanche::CompactProofs compactProofs( | ||||
pfrom.m_proof_relay->sharedProofs); | pfrom.m_proof_relay->sharedProofs); | ||||
m_connman.PushMessage( | m_connman.PushMessage( | ||||
&pfrom, msgMaker.Make(NetMsgType::AVAPROOFS, compactProofs)); | &pfrom, msgMaker.Make(NetMsgType::AVAPROOFS, compactProofs)); | ||||
return; | return; | ||||
} | } | ||||
if (msg_type == NetMsgType::AVAPROOFS) { | |||||
// Only process the compact proofs if we requested them | |||||
if (!gArgs.GetBoolArg("-acceptunsollicitedavaproofs", false) && | |||||
!pfrom.m_proof_relay->compactproofs_requested) { | |||||
LogPrint(BCLog::AVALANCHE, "Ignoring unsollicited avaproofs\n"); | |||||
return; | |||||
} | |||||
pfrom.m_proof_relay->compactproofs_requested = false; | |||||
avalanche::CompactProofs compactProofs; | |||||
vRecv >> compactProofs; | |||||
std::vector<avalanche::ProofRef> proofsAvailable; | |||||
proofsAvailable.resize(compactProofs.size()); | |||||
// If there are prefilled proofs, process them first | |||||
std::set<uint32_t> prefilledIndexes; | |||||
for (const auto &prefilledProof : compactProofs.getPrefilledProofs()) { | |||||
if (prefilledProof.index >= compactProofs.size()) { | |||||
Misbehaving(pfrom, 100, "avaproofs-index-out-of-bound"); | |||||
return; | |||||
} | |||||
if (!ReceivedAvalancheProof(pfrom, prefilledProof.proof)) { | |||||
// If we got an invalid proof, the peer is getting banned and we | |||||
// can bail out. | |||||
return; | |||||
} | |||||
proofsAvailable[prefilledProof.index] = prefilledProof.proof; | |||||
} | |||||
const auto &shortproofids = compactProofs.getShortIDs(); | |||||
// Build a map of shortids -> index and check for what we have (or | |||||
// don't). | |||||
std::unordered_map<uint64_t, uint32_t> shortIdMap(shortproofids.size()); | |||||
uint32_t index_offset = 0; | |||||
for (size_t i = 0; i < shortproofids.size(); i++) { | |||||
while (proofsAvailable[i + index_offset]) { | |||||
index_offset++; | |||||
} | |||||
// TODO: In the case of a shortid-collision, we should instead | |||||
// request both proofs which collided. | |||||
shortIdMap[shortproofids[i]] = i + index_offset; | |||||
} | |||||
std::vector<bool> haveProof(proofsAvailable.size()); | |||||
const auto &proofs = | |||||
g_avalanche->withPeerManager([&](const avalanche::PeerManager &pm) { | |||||
return pm.getShareableProofsSnapshot(); | |||||
}); | |||||
size_t proofCount = 0; | |||||
proofs.forEachLeaf([&](const avalanche::ProofRef &proof) { | |||||
uint64_t shortid = compactProofs.getShortID(proof->getId()); | |||||
decltype(shortIdMap)::iterator idit = shortIdMap.find(shortid); | |||||
if (idit != shortIdMap.end()) { | |||||
if (!haveProof[idit->second]) { | |||||
proofsAvailable[idit->second] = proof; | |||||
haveProof[idit->second] = true; | |||||
proofCount++; | |||||
} else if (proofsAvailable[idit->second]) { | |||||
// If we find two proofs that match the short id, just | |||||
// request both. | |||||
proofsAvailable[idit->second] = avalanche::ProofRef(); | |||||
proofCount--; | |||||
} | |||||
} | |||||
// Though ideally we'd continue scanning for the | |||||
// two-proofs-match-shortid case, the performance win of an early | |||||
// exit here is too good to pass up and worth the extra risk. | |||||
return proofCount != shortIdMap.size(); | |||||
}); | |||||
avalanche::ProofsRequest req; | |||||
for (size_t i = 0; i < compactProofs.size(); i++) { | |||||
if (proofsAvailable[i] == nullptr) { | |||||
req.indices.push_back(i); | |||||
} | |||||
} | |||||
m_connman.PushMessage(&pfrom, | |||||
msgMaker.Make(NetMsgType::AVAPROOFSREQ, req)); | |||||
return; | |||||
} | |||||
if (msg_type == NetMsgType::GETADDR) { | if (msg_type == NetMsgType::GETADDR) { | ||||
// This asymmetric behavior for inbound and outbound connections was | // This asymmetric behavior for inbound and outbound connections was | ||||
// introduced to prevent a fingerprinting attack: an attacker can send | // introduced to prevent a fingerprinting attack: an attacker can send | ||||
// specific fake addresses to users' AddrMan and later request them by | // specific fake addresses to users' AddrMan and later request them by | ||||
// sending getaddr messages. Making nodes which are behind NAT and can | // sending getaddr messages. Making nodes which are behind NAT and can | ||||
// only make outgoing connections ignore the getaddr message mitigates | // only make outgoing connections ignore the getaddr message mitigates | ||||
// the attack. | // the attack. | ||||
if (!pfrom.IsInboundConn()) { | if (!pfrom.IsInboundConn()) { | ||||
▲ Show 20 Lines • Show All 1,738 Lines • Show Last 20 Lines |