Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/peermanager.cpp
Show First 20 Lines • Show All 182 Lines • ▼ Show 20 Lines | for (const ProofRef &proof : proofs) { | ||||
if (it != peersView.end()) { | if (it != peersView.end()) { | ||||
removePeer(it->peerid); | removePeer(it->peerid); | ||||
} | } | ||||
conflictingProofPool.addProofIfPreferred(proof); | conflictingProofPool.addProofIfPreferred(proof); | ||||
} | } | ||||
} | } | ||||
template <typename Callable> | |||||
void PeerManager::forEachConflictingProof(const ProofRef &proof, | |||||
Callable &&func) { | |||||
for (const SignedStake &ss : proof->getStakes()) { | |||||
const ProofRef conflictingProof = | |||||
conflictingProofPool.getProof(ss.getStake().getUTXO()); | |||||
if (!conflictingProof) { | |||||
continue; | |||||
} | |||||
func(conflictingProof); | |||||
} | |||||
} | |||||
bool PeerManager::registerProof(const ProofRef &proof, | bool PeerManager::registerProof(const ProofRef &proof, | ||||
ProofRegistrationState ®istrationState, | ProofRegistrationState ®istrationState, | ||||
RegistrationMode mode) { | RegistrationMode mode) { | ||||
assert(proof); | assert(proof); | ||||
const ProofId &proofid = proof->getId(); | const ProofId &proofid = proof->getId(); | ||||
auto invalidate = [&](ProofRegistrationResult result, | auto invalidate = [&](ProofRegistrationResult result, | ||||
Show All 21 Lines | if (!WITH_LOCK(cs_main, | ||||
orphanProofPool.addProofIfPreferred(proof); | orphanProofPool.addProofIfPreferred(proof); | ||||
return invalidate(ProofRegistrationResult::ORPHAN, "orphan-proof"); | return invalidate(ProofRegistrationResult::ORPHAN, "orphan-proof"); | ||||
} | } | ||||
// Reject invalid proof. | // Reject invalid proof. | ||||
return invalidate(ProofRegistrationResult::INVALID, "invalid-proof"); | return invalidate(ProofRegistrationResult::INVALID, "invalid-proof"); | ||||
} | } | ||||
// If we're at the valid proof limit, only attempt to register proofs that | |||||
// score better or equal to the lowest scoring proof. | |||||
ProofRef lowestScoringProof; | |||||
if (validProofPool.countProofs() >= AVALANCHE_MAX_VALID_PROOFS) { | |||||
lowestScoringProof = validProofPool.getLowestScoreProof(); | |||||
if (proof->getScore() < lowestScoringProof->getScore()) { | |||||
return invalidate(ProofRegistrationResult::SCORE_TOO_LOW, | |||||
"score-too-low"); | |||||
} | |||||
} | |||||
auto now = GetTime<std::chrono::seconds>(); | auto now = GetTime<std::chrono::seconds>(); | ||||
auto nextCooldownTimePoint = | auto nextCooldownTimePoint = | ||||
now + std::chrono::seconds( | now + std::chrono::seconds( | ||||
gArgs.GetArg("-avalancheconflictingproofcooldown", | gArgs.GetArg("-avalancheconflictingproofcooldown", | ||||
AVALANCHE_DEFAULT_CONFLICTING_PROOF_COOLDOWN)); | AVALANCHE_DEFAULT_CONFLICTING_PROOF_COOLDOWN)); | ||||
ProofPool::ConflictingProofSet conflictingProofs; | ProofPool::ConflictingProofSet conflictingProofs; | ||||
switch (validProofPool.addProofIfNoConflict(proof, conflictingProofs)) { | switch (validProofPool.addProofIfNoConflict(proof, conflictingProofs)) { | ||||
▲ Show 20 Lines • Show All 56 Lines • ▼ Show 20 Lines | switch (validProofPool.addProofIfNoConflict(proof, conflictingProofs)) { | ||||
break; | break; | ||||
} | } | ||||
case ProofPool::AddProofStatus::DUPLICATED: | case ProofPool::AddProofStatus::DUPLICATED: | ||||
// If the proof was already in the pool, don't duplicate the peer. | // If the proof was already in the pool, don't duplicate the peer. | ||||
return invalidate(ProofRegistrationResult::ALREADY_REGISTERED, | return invalidate(ProofRegistrationResult::ALREADY_REGISTERED, | ||||
"proof-already-registered"); | "proof-already-registered"); | ||||
case ProofPool::AddProofStatus::SUCCEED: | case ProofPool::AddProofStatus::SUCCEED: | ||||
// If we're at the valid proof limit, kick out the lowest scoring | |||||
// proof. The new proof replaces it. | |||||
if (lowestScoringProof != nullptr) { | |||||
// First ensure any conflicting proofs are removed so they are | |||||
// not pulled back into the valid pool once the lowest scoring | |||||
// proof is removed. | |||||
forEachConflictingProof(lowestScoringProof, | |||||
[&](const ProofRef &conflictingProof) { | |||||
conflictingProofPool.removeProof( | |||||
conflictingProof->getId()); | |||||
}); | |||||
// Now remove the lowest scoring proof, making room for the new | |||||
// proof that was recently registered successfully. | |||||
rejectProof(lowestScoringProof->getId(), | |||||
RejectionMode::INVALIDATE); | |||||
} | |||||
break; | break; | ||||
// No default case, so the compiler can warn about missing cases | // No default case, so the compiler can warn about missing cases | ||||
} | } | ||||
// At this stage we are going to create a peer so the proof should never | // At this stage we are going to create a peer so the proof should never | ||||
// exist in the conflicting pool, but use belt and suspenders. | // exist in the conflicting pool, but use belt and suspenders. | ||||
conflictingProofPool.removeProof(proofid); | conflictingProofPool.removeProof(proofid); | ||||
▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | bool PeerManager::rejectProof(const ProofId &proofid, RejectionMode mode) { | ||||
const ProofRef proof = it->proof; | const ProofRef proof = it->proof; | ||||
if (!removePeer(it->peerid)) { | if (!removePeer(it->peerid)) { | ||||
return false; | return false; | ||||
} | } | ||||
// If there was conflicting proofs, attempt to pull them back | // If there was conflicting proofs, attempt to pull them back | ||||
for (const SignedStake &ss : proof->getStakes()) { | forEachConflictingProof(proof, [&](const ProofRef &conflictingProof) { | ||||
const ProofRef conflictingProof = | |||||
conflictingProofPool.getProof(ss.getStake().getUTXO()); | |||||
if (!conflictingProof) { | |||||
continue; | |||||
} | |||||
conflictingProofPool.removeProof(conflictingProof->getId()); | conflictingProofPool.removeProof(conflictingProof->getId()); | ||||
registerProof(conflictingProof); | registerProof(conflictingProof); | ||||
} | }); | ||||
if (mode == RejectionMode::DEFAULT) { | if (mode == RejectionMode::DEFAULT) { | ||||
conflictingProofPool.addProofIfPreferred(proof); | conflictingProofPool.addProofIfPreferred(proof); | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 376 Lines • Show Last 20 Lines |