Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/peermanager.cpp
// Copyright (c) 2020 The Bitcoin developers | // Copyright (c) 2020 The Bitcoin developers | ||||
// Distributed under the MIT software license, see the accompanying | // Distributed under the MIT software license, see the accompanying | ||||
// file COPYING or http://www.opensource.org/licenses/mit-license.php. | // file COPYING or http://www.opensource.org/licenses/mit-license.php. | ||||
#include <avalanche/peermanager.h> | #include <avalanche/peermanager.h> | ||||
#include <avalanche/avalanche.h> | |||||
#include <avalanche/delegation.h> | #include <avalanche/delegation.h> | ||||
#include <avalanche/validation.h> | #include <avalanche/validation.h> | ||||
#include <random.h> | #include <random.h> | ||||
#include <validation.h> // For ChainstateActive() | #include <validation.h> // For ChainstateActive() | ||||
#include <algorithm> | #include <algorithm> | ||||
#include <cassert> | #include <cassert> | ||||
▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | if (!valid) { | ||||
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"); | ||||
} | } | ||||
auto now = GetTime<std::chrono::seconds>(); | |||||
auto nextCooldownTimePoint = | |||||
now + std::chrono::seconds( | |||||
gArgs.GetArg("-avalancheconflictingproofcooldown", | |||||
AVALANCHE_DEFAULT_CONFLICTING_PROOF_COOLDOWN)); | |||||
ProofPool::ConflictingProofSet conflictingProofs; | ProofPool::ConflictingProofSet conflictingProofs; | ||||
switch (validProofPool.addProofIfNoConflict(proof, conflictingProofs)) { | switch (validProofPool.addProofIfNoConflict(proof, conflictingProofs)) { | ||||
case ProofPool::AddProofStatus::REJECTED: { | case ProofPool::AddProofStatus::REJECTED: { | ||||
if (mode != RegistrationMode::FORCE_ACCEPT) { | if (mode != RegistrationMode::FORCE_ACCEPT) { | ||||
auto bestPossibleConflictTime = std::chrono::seconds(); | |||||
auto &pview = peers.get<by_proofid>(); | |||||
for (auto &conflictingProof : conflictingProofs) { | |||||
auto it = pview.find(conflictingProof->getId()); | |||||
assert(it != pview.end()); | |||||
// Search the most recent time over the peers | |||||
bestPossibleConflictTime = std::max( | |||||
bestPossibleConflictTime, it->nextPossibleConflictTime); | |||||
updateNextPossibleConflictTime(it->peerid, | |||||
nextCooldownTimePoint); | |||||
} | |||||
if (bestPossibleConflictTime > now) { | |||||
// Cooldown not elapsed, reject the proof. | |||||
return invalidate( | |||||
ProofRegistrationResult::COOLDOWN_NOT_ELAPSED, | |||||
"cooldown-not-elapsed"); | |||||
} | |||||
// The proof has conflicts, move it to the conflicting proof | // The proof has conflicts, move it to the conflicting proof | ||||
// pool so it can be pulled back if the conflicting ones are | // pool so it can be pulled back if the conflicting ones are | ||||
// invalidated. | // invalidated. | ||||
return conflictingProofPool.addProofIfPreferred(proof) == | return conflictingProofPool.addProofIfPreferred(proof) == | ||||
ProofPool::AddProofStatus::REJECTED | ProofPool::AddProofStatus::REJECTED | ||||
? invalidate(ProofRegistrationResult::REJECTED, | ? invalidate(ProofRegistrationResult::REJECTED, | ||||
"rejected-proof") | "rejected-proof") | ||||
: invalidate(ProofRegistrationResult::CONFLICTING, | : invalidate(ProofRegistrationResult::CONFLICTING, | ||||
Show All 32 Lines | bool PeerManager::registerProof(const ProofRef &proof, | ||||
// 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); | ||||
// New peer means new peerid! | // New peer means new peerid! | ||||
const PeerId peerid = nextPeerId++; | const PeerId peerid = nextPeerId++; | ||||
// We have no peer for this proof, time to create it. | // We have no peer for this proof, time to create it. | ||||
auto inserted = peers.emplace(peerid, proof); | auto inserted = peers.emplace(peerid, proof, nextCooldownTimePoint); | ||||
assert(inserted.second); | assert(inserted.second); | ||||
// If there are nodes waiting for this proof, add them | // If there are nodes waiting for this proof, add them | ||||
auto &pendingNodesView = pendingNodes.get<by_proofid>(); | auto &pendingNodesView = pendingNodes.get<by_proofid>(); | ||||
auto range = pendingNodesView.equal_range(proofid); | auto range = pendingNodesView.equal_range(proofid); | ||||
// We want to update the nodes then remove them from the pending set. That | // We want to update the nodes then remove them from the pending set. That | ||||
// will invalidate the range iterators, so we need to save the node ids | // will invalidate the range iterators, so we need to save the node ids | ||||
▲ Show 20 Lines • Show All 364 Lines • Show Last 20 Lines |