Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/processor.cpp
Show First 20 Lines • Show All 130 Lines • ▼ Show 20 Lines | static bool IsWorthPolling(const CBlockIndex *pindex) { | ||||
if (::ChainstateActive().IsBlockFinalized(pindex)) { | if (::ChainstateActive().IsBlockFinalized(pindex)) { | ||||
// There is no point polling finalized block. | // There is no point polling finalized block. | ||||
return false; | return false; | ||||
} | } | ||||
return true; | return true; | ||||
} | } | ||||
struct Processor::PeerData { | |||||
Proof proof; | |||||
Delegation delegation; | |||||
}; | |||||
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); | ||||
if (m_processor->mustRegisterProof && | if (m_processor->mustRegisterProof && | ||||
!::ChainstateActive().IsInitialBlockDownload()) { | !::ChainstateActive().IsInitialBlockDownload()) { | ||||
m_processor->peerManager->getPeerId(m_processor->peerData->proof); | m_processor->peerManager->getPeerId( | ||||
m_processor->peerData.proof.value()); | |||||
m_processor->mustRegisterProof = false; | m_processor->mustRegisterProof = false; | ||||
} | } | ||||
m_processor->peerManager->updatedBlockTip(); | m_processor->peerManager->updatedBlockTip(); | ||||
} | } | ||||
}; | }; | ||||
Processor::Processor(interfaces::Chain &chain, CConnman *connmanIn, | Processor::Processor(interfaces::Chain &chain, CConnman *connmanIn, | ||||
NodePeerManager *nodePeerManagerIn) | NodePeerManager *nodePeerManagerIn) | ||||
: connman(connmanIn), nodePeerManager(nodePeerManagerIn), | : connman(connmanIn), nodePeerManager(nodePeerManagerIn), | ||||
queryTimeoutDuration(AVALANCHE_DEFAULT_QUERY_TIMEOUT), round(0), | queryTimeoutDuration(AVALANCHE_DEFAULT_QUERY_TIMEOUT), round(0), | ||||
peerManager(std::make_unique<PeerManager>()) { | peerManager(std::make_unique<PeerManager>()) { | ||||
if (gArgs.IsArgSet("-avasessionkey")) { | if (gArgs.IsArgSet("-avasessionkey")) { | ||||
sessionKey = DecodeSecret(gArgs.GetArg("-avasessionkey", "")); | sessionKey = DecodeSecret(gArgs.GetArg("-avasessionkey", "")); | ||||
} else { | } else { | ||||
// Pick a random key for the session. | // Pick a random key for the session. | ||||
sessionKey.MakeNewKey(true); | sessionKey.MakeNewKey(true); | ||||
} | } | ||||
if (gArgs.IsArgSet("-avaproof")) { | if (gArgs.IsArgSet("-avaproof")) { | ||||
peerData = std::make_unique<PeerData>(); | |||||
{ | { | ||||
// The proof. | // The proof. | ||||
CDataStream stream(ParseHex(gArgs.GetArg("-avaproof", "")), | CDataStream stream(ParseHex(gArgs.GetArg("-avaproof", "")), | ||||
SER_NETWORK, 0); | SER_NETWORK, 0); | ||||
stream >> peerData->proof; | Proof proof; | ||||
stream >> proof; | |||||
peerData.proof = proof; | |||||
// Schedule proof registration at the first new block after IBD. | // Schedule proof registration at the first new block after IBD. | ||||
mustRegisterProof = true; | mustRegisterProof = true; | ||||
} | } | ||||
// Generate the delegation to the session key. | // Generate the delegation to the session key. | ||||
DelegationBuilder dgb(peerData->proof); | DelegationBuilder dgb(peerData.proof.value()); | ||||
if (sessionKey.GetPubKey() != peerData->proof.getMaster()) { | if (sessionKey.GetPubKey() != peerData.proof->getMaster()) { | ||||
dgb.addLevel(DecodeSecret(gArgs.GetArg("-avamasterkey", "")), | dgb.addLevel(DecodeSecret(gArgs.GetArg("-avamasterkey", "")), | ||||
sessionKey.GetPubKey()); | sessionKey.GetPubKey()); | ||||
} | } | ||||
peerData->delegation = dgb.build(); | peerData.delegation = dgb.build(); | ||||
} | } | ||||
// Make sure we get notified of chain state changes. | // Make sure we get notified of chain state changes. | ||||
chainNotificationsHandler = | chainNotificationsHandler = | ||||
chain.handleNotifications(std::make_shared<NotificationsHandler>(this)); | chain.handleNotifications(std::make_shared<NotificationsHandler>(this)); | ||||
} | } | ||||
Processor::~Processor() { | Processor::~Processor() { | ||||
▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
CPubKey Processor::getSessionPubKey() const { | CPubKey Processor::getSessionPubKey() const { | ||||
return sessionKey.GetPubKey(); | return sessionKey.GetPubKey(); | ||||
} | } | ||||
uint256 Processor::buildLocalSighash(CNode *pfrom) const { | uint256 Processor::buildLocalSighash(CNode *pfrom) const { | ||||
CHashWriter hasher(SER_GETHASH, 0); | CHashWriter hasher(SER_GETHASH, 0); | ||||
hasher << peerData->delegation.getId(); | hasher << peerData.delegation->getId(); | ||||
hasher << pfrom->GetLocalNonce(); | hasher << pfrom->GetLocalNonce(); | ||||
hasher << pfrom->nRemoteHostNonce; | hasher << pfrom->nRemoteHostNonce; | ||||
hasher << pfrom->GetLocalExtraEntropy(); | hasher << pfrom->GetLocalExtraEntropy(); | ||||
hasher << pfrom->nRemoteExtraEntropy; | hasher << pfrom->nRemoteExtraEntropy; | ||||
return hasher.GetHash(); | return hasher.GetHash(); | ||||
} | } | ||||
uint256 Processor::buildRemoteSighash(CNode *pfrom) const { | uint256 Processor::buildRemoteSighash(CNode *pfrom) const { | ||||
CHashWriter hasher(SER_GETHASH, 0); | CHashWriter hasher(SER_GETHASH, 0); | ||||
hasher << pfrom->m_avalanche_state->delegation.getId(); | hasher << pfrom->m_avalanche_state->delegation.getId(); | ||||
hasher << pfrom->nRemoteHostNonce; | hasher << pfrom->nRemoteHostNonce; | ||||
hasher << pfrom->GetLocalNonce(); | hasher << pfrom->GetLocalNonce(); | ||||
hasher << pfrom->nRemoteExtraEntropy; | hasher << pfrom->nRemoteExtraEntropy; | ||||
hasher << pfrom->GetLocalExtraEntropy(); | hasher << pfrom->GetLocalExtraEntropy(); | ||||
return hasher.GetHash(); | return hasher.GetHash(); | ||||
} | } | ||||
bool Processor::sendHello(CNode *pfrom) const { | bool Processor::sendHello(CNode *pfrom) const { | ||||
if (!peerData) { | if (!peerData.delegation) { | ||||
// We do not have a delegation to advertise. | // We do not have a delegation to advertise. | ||||
return false; | return false; | ||||
} | } | ||||
// Now let's sign! | // Now let's sign! | ||||
SchnorrSig sig; | SchnorrSig sig; | ||||
{ | { | ||||
const uint256 hash = buildLocalSighash(pfrom); | const uint256 hash = buildLocalSighash(pfrom); | ||||
if (!sessionKey.SignSchnorr(hash, sig)) { | if (!sessionKey.SignSchnorr(hash, sig)) { | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
connman->PushMessage(pfrom, CNetMsgMaker(pfrom->GetCommonVersion()) | connman->PushMessage(pfrom, | ||||
CNetMsgMaker(pfrom->GetCommonVersion()) | |||||
.Make(NetMsgType::AVAHELLO, | .Make(NetMsgType::AVAHELLO, | ||||
Hello(peerData->delegation, sig))); | Hello(peerData.delegation.value(), sig))); | ||||
return true; | return true; | ||||
} | } | ||||
const Proof Processor::getProof() const { | const std::optional<Proof> &Processor::getLocalProof() const { | ||||
if (!peerData) { | return peerData.proof; | ||||
throw std::runtime_error("proof not set"); | |||||
} | |||||
return peerData->proof; | |||||
} | } | ||||
bool Processor::startEventLoop(CScheduler &scheduler) { | bool Processor::startEventLoop(CScheduler &scheduler) { | ||||
return eventLoop.startEventLoop( | return eventLoop.startEventLoop( | ||||
scheduler, [this]() { this->runEventLoop(); }, AVALANCHE_TIME_STEP); | scheduler, [this]() { this->runEventLoop(); }, AVALANCHE_TIME_STEP); | ||||
} | } | ||||
bool Processor::stopEventLoop() { | bool Processor::stopEventLoop() { | ||||
▲ Show 20 Lines • Show All 170 Lines • Show Last 20 Lines |