Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/proofpool.cpp
// Copyright (c) 2021 The Bitcoin developers | // Copyright (c) 2021 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/proofpool.h> | #include <avalanche/proofpool.h> | ||||
#include <avalanche/peermanager.h> | #include <avalanche/peermanager.h> | ||||
#include <avalanche/proofcomparator.h> | #include <avalanche/proofcomparator.h> | ||||
#include <util/time.h> | |||||
namespace avalanche { | namespace avalanche { | ||||
ProofPool::AddProofStatus | ProofPool::AddProofStatus | ||||
ProofPool::addProofIfNoConflict(const ProofRef &proof, | ProofPool::addProofIfNoConflict(const ProofRef &proof, | ||||
ConflictingProofSet &conflictingProofs) { | ConflictingProofSet &conflictingProofs) { | ||||
const ProofId &proofid = proof->getId(); | const ProofId &proofid = proof->getId(); | ||||
Show All 24 Lines | if (conflictingProofs.size() > 0) { | ||||
if (it->proof->getId() == proofid) { | if (it->proof->getId() == proofid) { | ||||
pool.erase(it); | pool.erase(it); | ||||
} | } | ||||
} | } | ||||
return AddProofStatus::REJECTED; | return AddProofStatus::REJECTED; | ||||
} | } | ||||
registrationTime.emplace(proofid, GetTime<std::chrono::seconds>()); | |||||
return AddProofStatus::SUCCEED; | return AddProofStatus::SUCCEED; | ||||
} | } | ||||
ProofPool::AddProofStatus | ProofPool::AddProofStatus | ||||
ProofPool::addProofIfPreferred(const ProofRef &proof, | ProofPool::addProofIfPreferred(const ProofRef &proof, | ||||
ConflictingProofSet &conflictingProofs) { | ConflictingProofSet &conflictingProofs) { | ||||
auto added = addProofIfNoConflict(proof, conflictingProofs); | auto added = addProofIfNoConflict(proof, conflictingProofs); | ||||
Show All 12 Lines | ProofPool::addProofIfPreferred(const ProofRef &proof, | ||||
return added; | return added; | ||||
} | } | ||||
// Having the ProofRef passed by reference is risky because the proof could be | // Having the ProofRef passed by reference is risky because the proof could be | ||||
// deleted during the erasure loop, so we pass it by value. Since it's a shared | // deleted during the erasure loop, so we pass it by value. Since it's a shared | ||||
// pointer, the copy is cheap enough and should not have any significant impact | // pointer, the copy is cheap enough and should not have any significant impact | ||||
// on performance. | // on performance. | ||||
bool ProofPool::removeProof(ProofRef proof) { | bool ProofPool::removeProof(ProofRef proof) { | ||||
const ProofId &proofid = proof->getId(); | |||||
registrationTime.erase(proofid); | |||||
auto &poolView = pool.get<by_proofid>(); | auto &poolView = pool.get<by_proofid>(); | ||||
return poolView.erase(proof->getId()); | return poolView.erase(proofid); | ||||
} | } | ||||
void ProofPool::rescan(PeerManager &peerManager) { | void ProofPool::rescan(PeerManager &peerManager) { | ||||
auto previousPool = std::move(pool); | auto previousPool = std::move(pool); | ||||
pool.clear(); | pool.clear(); | ||||
for (auto &entry : previousPool) { | for (auto &entry : previousPool) { | ||||
peerManager.registerProof(entry.proof); | peerManager.registerProof(entry.proof); | ||||
// If the registration caused the proof to be removed from the pool, we | |||||
// need to delete its registration time. | |||||
const ProofId &proofid = entry.proof->getId(); | |||||
if (!getProof(proofid)) { | |||||
registrationTime.erase(proofid); | |||||
} | |||||
} | } | ||||
} | } | ||||
ProofRef ProofPool::getProof(const ProofId &proofid) const { | ProofRef ProofPool::getProof(const ProofId &proofid) const { | ||||
auto &poolView = pool.get<by_proofid>(); | auto &poolView = pool.get<by_proofid>(); | ||||
auto it = poolView.find(proofid); | auto it = poolView.find(proofid); | ||||
return it == poolView.end() ? nullptr : it->proof; | return it == poolView.end() ? nullptr : it->proof; | ||||
} | } | ||||
ProofRef ProofPool::getProof(const COutPoint &outpoint) const { | ProofRef ProofPool::getProof(const COutPoint &outpoint) const { | ||||
auto it = pool.find(outpoint); | auto it = pool.find(outpoint); | ||||
return it == pool.end() ? nullptr : it->proof; | return it == pool.end() ? nullptr : it->proof; | ||||
} | } | ||||
std::chrono::seconds | |||||
ProofPool::getRegistrationTime(const ProofId &proofid) const { | |||||
auto it = registrationTime.find(proofid); | |||||
return it == registrationTime.end() ? std::chrono::seconds::max() | |||||
: it->second; | |||||
} | |||||
} // namespace avalanche | } // namespace avalanche |