Changeset View
Changeset View
Standalone View
Standalone View
src/avalanche/processor.cpp
// Copyright (c) 2018-2019 The Bitcoin developers | // Copyright (c) 2018-2019 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/processor.h> | #include <avalanche/processor.h> | ||||
#include <avalanche/delegationbuilder.h> | #include <avalanche/delegationbuilder.h> | ||||
#include <avalanche/peermanager.h> | #include <avalanche/peermanager.h> | ||||
#include <avalanche/validation.h> | #include <avalanche/validation.h> | ||||
#include <chain.h> | #include <chain.h> | ||||
#include <key_io.h> // For DecodeSecret | #include <key_io.h> // For DecodeSecret | ||||
#include <net_processing.h> // For ::PeerManager | #include <net_processing.h> // For ::PeerManager | ||||
#include <netmessagemaker.h> | #include <netmessagemaker.h> | ||||
#include <reverse_iterator.h> | #include <reverse_iterator.h> | ||||
#include <scheduler.h> | #include <scheduler.h> | ||||
#include <util/bitmanip.h> | #include <util/bitmanip.h> | ||||
#include <util/translation.h> | |||||
#include <validation.h> | #include <validation.h> | ||||
#include <chrono> | #include <chrono> | ||||
#include <tuple> | #include <tuple> | ||||
/** | /** | ||||
* Run the avalanche event loop every 10ms. | * Run the avalanche event loop every 10ms. | ||||
*/ | */ | ||||
▲ Show 20 Lines • Show All 143 Lines • ▼ Show 20 Lines | : connman(connmanIn), nodePeerManager(nodePeerManagerIn), | ||||
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 avalanche is enabled and a proof is supplied, make sure it does | |||||
// not contain garbage. At this point the validity of the utxos cannot | |||||
// be checked, so only basic verification is performed. | |||||
if (gArgs.IsArgSet("-avaproof")) { | if (gArgs.IsArgSet("-avaproof")) { | ||||
peerData = std::make_unique<PeerData>(); | peerData = std::make_unique<PeerData>(); | ||||
{ | |||||
// The proof. | // The proof. | ||||
CDataStream stream(ParseHex(gArgs.GetArg("-avaproof", "")), | CDataStream stream(ParseHex(gArgs.GetArg("-avaproof", "")), SER_NETWORK, | ||||
SER_NETWORK, 0); | 0); | ||||
stream >> peerData->proof; | stream >> peerData->proof; | ||||
// Schedule proof registration at the first new block after IBD. | ProofValidationState proof_state; | ||||
mustRegisterProof = true; | if (!peerData->proof.verify(proof_state)) { | ||||
LogPrintfToBeContinued("Failed basic avaproof verification: "); | |||||
switch (proof_state.GetResult()) { | |||||
case avalanche::ProofValidationResult::NO_STAKE: | |||||
LogPrintf("the avalanche proof has no stake\n"); | |||||
break; | |||||
case avalanche::ProofValidationResult::DUST_THRESOLD: | |||||
LogPrintf("the avalanche proof stake is too low\n"); | |||||
break; | |||||
case avalanche::ProofValidationResult::DUPLICATE_STAKE: | |||||
LogPrintf("the avalanche proof has duplicated stake\n"); | |||||
break; | |||||
case avalanche::ProofValidationResult::INVALID_SIGNATURE: | |||||
LogPrintf("the avalanche proof has invalid stake " | |||||
"signatures\n"); | |||||
break; | |||||
case avalanche::ProofValidationResult::TOO_MANY_UTXOS: | |||||
LogPrintf("the avalanche proof has too many utxos " | |||||
"(max: %u)\n", | |||||
AVALANCHE_MAX_PROOF_STAKES); | |||||
break; | |||||
default: | |||||
LogPrintf("the avalanche proof is invalid\n"); | |||||
} | } | ||||
throw std::runtime_error("Failed basic avaproof verification"); | |||||
} else { | |||||
// Schedule proof registration at first new block after IBD. | |||||
mustRegisterProof = true; | |||||
// Generate the delegation to the session key. | // Generate the delegation to the session key. | ||||
DelegationBuilder dgb(peerData->proof); | DelegationBuilder dgb(peerData->proof); | ||||
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() { | ||||
chainNotificationsHandler.reset(); | chainNotificationsHandler.reset(); | ||||
▲ Show 20 Lines • Show All 234 Lines • ▼ Show 20 Lines | bool Processor::sendHello(CNode *pfrom) const { | ||||
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, sig))); | ||||
return true; | return true; | ||||
} | } | ||||
const Proof Processor::getProof() const { | bool Processor::hasLocalProof() const { | ||||
if (!peerData) { | if (!peerData) { | ||||
throw std::runtime_error("proof not set"); | return false; | ||||
} | } | ||||
return peerData->proof; | return true; | ||||
} | } | ||||
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 165 Lines • Show Last 20 Lines |