Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/processor.cpp
Show First 20 Lines • Show All 103 Lines • ▼ Show 20 Lines | static bool VerifyDelegation(const Delegation &dg, | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
struct Processor::PeerData { | struct Processor::PeerData { | ||||
std::shared_ptr<Proof> proof; | std::shared_ptr<Proof> proof; | ||||
Delegation delegation; | Delegation delegation; | ||||
PeerId peerid; | |||||
PeerData() : peerid(NO_PEER) {} | |||||
}; | }; | ||||
class Processor::NotificationsHandler | class Processor::NotificationsHandler | ||||
: public interfaces::Chain::Notifications { | : public interfaces::Chain::Notifications { | ||||
Processor *m_processor; | Processor *m_processor; | ||||
public: | public: | ||||
NotificationsHandler(Processor *p) : m_processor(p) {} | NotificationsHandler(Processor *p) : m_processor(p) {} | ||||
void updatedBlockTip() override { | void updatedBlockTip() override { | ||||
LOCK(m_processor->cs_peerManager); | LOCK(m_processor->cs_peerManager); | ||||
m_processor->peerManager->updatedBlockTip(); | |||||
// Fetch or create a peer id for our local proof and cache it. | |||||
// This needs to happen after the peer manager updatedBlockTip() in | |||||
// order to get the correct peerid in the case our proof just left the | |||||
// orphan pool. | |||||
if (m_processor->peerData && m_processor->peerData->proof) { | if (m_processor->peerData && m_processor->peerData->proof) { | ||||
m_processor->peerManager->registerProof( | m_processor->peerData->peerid = m_processor->peerManager->getPeerId( | ||||
m_processor->peerData->proof); | m_processor->peerData->proof); | ||||
} | } | ||||
m_processor->peerManager->updatedBlockTip(); | |||||
} | } | ||||
}; | }; | ||||
class Processor::ConflictingProofHandler | class Processor::ConflictingProofHandler | ||||
: public PeerManager::ConflictingProofHandler { | : public PeerManager::ConflictingProofHandler { | ||||
Processor *m_processor; | Processor *m_processor; | ||||
public: | public: | ||||
ConflictingProofHandler(Processor *p) : m_processor(p) {} | ConflictingProofHandler(Processor *p) : m_processor(p) {} | ||||
void onConflictingProof(const std::shared_ptr<Proof> &proof, | void | ||||
onConflictingProof(const std::shared_ptr<Proof> &proof, | |||||
const std::unordered_set<PeerId> &conflictingPeerIds, | |||||
bool accepted) override { | bool accepted) override { | ||||
m_processor->addProofToReconcile(proof, accepted); | m_processor->addProofToReconcile(proof, conflictingPeerIds, accepted); | ||||
} | } | ||||
}; | }; | ||||
Processor::Processor(interfaces::Chain &chain, CConnman *connmanIn, | Processor::Processor(interfaces::Chain &chain, CConnman *connmanIn, | ||||
std::unique_ptr<PeerData> peerDataIn, CKey sessionKeyIn) | std::unique_ptr<PeerData> peerDataIn, CKey sessionKeyIn) | ||||
: connman(connmanIn), queryTimeoutDuration(AVALANCHE_DEFAULT_QUERY_TIMEOUT), | : connman(connmanIn), queryTimeoutDuration(AVALANCHE_DEFAULT_QUERY_TIMEOUT), | ||||
round(0), peerManager(std::make_unique<PeerManager>()), | round(0), peerManager(std::make_unique<PeerManager>()), | ||||
peerData(std::move(peerDataIn)), sessionKey(std::move(sessionKeyIn)) { | peerData(std::move(peerDataIn)), sessionKey(std::move(sessionKeyIn)) { | ||||
▲ Show 20 Lines • Show All 121 Lines • ▼ Show 20 Lines | bool isAccepted; | ||||
isAccepted = ::ChainActive().Contains(pindex); | isAccepted = ::ChainActive().Contains(pindex); | ||||
} | } | ||||
return vote_records.getWriteView() | return vote_records.getWriteView() | ||||
->insert(std::make_pair(pindex, VoteRecord(isAccepted))) | ->insert(std::make_pair(pindex, VoteRecord(isAccepted))) | ||||
.second; | .second; | ||||
} | } | ||||
void Processor::addProofToReconcile(const std::shared_ptr<Proof> &proof, | void Processor::addProofToReconcile( | ||||
bool isAccepted) { | const std::shared_ptr<Proof> &proof, | ||||
const std::unordered_set<PeerId> &conflictingPeerIds, bool isAccepted) { | |||||
// TODO We don't want to accept an infinite number of conflicting proofs. | // TODO We don't want to accept an infinite number of conflicting proofs. | ||||
// They should be some rules to make them expensive and/or limited by | // They should be some rules to make them expensive and/or limited by | ||||
// design. | // design. | ||||
proofsVoteRecords.getWriteView()->insert( | proofsVoteRecords.getWriteView()->insert(std::make_pair( | ||||
std::make_pair(proof, VoteRecord(isAccepted))); | proof, | ||||
VoteRecord(isAccepted && !conflictingPeerIds.count( | |||||
peerData ? peerData->peerid : NO_PEER)))); | |||||
} | } | ||||
bool Processor::isAccepted(const CBlockIndex *pindex) const { | bool Processor::isAccepted(const CBlockIndex *pindex) const { | ||||
auto r = vote_records.getReadView(); | auto r = vote_records.getReadView(); | ||||
auto it = r->find(pindex); | auto it = r->find(pindex); | ||||
if (it == r.end()) { | if (it == r.end()) { | ||||
return false; | return false; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 376 Lines • ▼ Show 20 Lines | do { | ||||
peerManager->removeNode(nodeid); | peerManager->removeNode(nodeid); | ||||
} | } | ||||
// Get next suitable node to try again | // Get next suitable node to try again | ||||
nodeid = getSuitableNodeToQuery(); | nodeid = getSuitableNodeToQuery(); | ||||
} while (nodeid != NO_NODE); | } while (nodeid != NO_NODE); | ||||
} | } | ||||
void Processor::setPeerData(const std::shared_ptr<Proof> proof, | |||||
const Delegation &dg, PeerId peerid) { | |||||
if (!peerData) { | |||||
peerData = std::make_unique<PeerData>(); | |||||
} | |||||
peerData->proof = proof; | |||||
peerData->delegation = dg; | |||||
peerData->peerid = peerid; | |||||
} | |||||
} // namespace avalanche | } // namespace avalanche |