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 <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 <util/translation.h> | ||||
#include <validation.h> | #include <validation.h> | ||||
#include <chrono> | #include <chrono> | ||||
▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | void updatedBlockTip() override { | ||||
m_processor->peerData->proof); | m_processor->peerData->proof); | ||||
} | } | ||||
m_processor->peerManager->updatedBlockTip(); | m_processor->peerManager->updatedBlockTip(); | ||||
} | } | ||||
}; | }; | ||||
Processor::Processor(interfaces::Chain &chain, CConnman *connmanIn, | Processor::Processor(interfaces::Chain &chain, CConnman *connmanIn, | ||||
NodePeerManager *nodePeerManagerIn, | |||||
std::unique_ptr<PeerData> peerDataIn, CKey sessionKeyIn) | std::unique_ptr<PeerData> peerDataIn, CKey sessionKeyIn) | ||||
: connman(connmanIn), nodePeerManager(nodePeerManagerIn), | : connman(connmanIn), queryTimeoutDuration(AVALANCHE_DEFAULT_QUERY_TIMEOUT), | ||||
queryTimeoutDuration(AVALANCHE_DEFAULT_QUERY_TIMEOUT), round(0), | round(0), peerManager(std::make_unique<PeerManager>()), | ||||
peerManager(std::make_unique<PeerManager>()), | |||||
peerData(std::move(peerDataIn)), sessionKey(std::move(sessionKeyIn)) { | peerData(std::move(peerDataIn)), sessionKey(std::move(sessionKeyIn)) { | ||||
// 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(); | ||||
stopEventLoop(); | stopEventLoop(); | ||||
} | } | ||||
std::unique_ptr<Processor> | std::unique_ptr<Processor> Processor::MakeProcessor(const ArgsManager &argsman, | ||||
Processor::MakeProcessor(const ArgsManager &argsman, interfaces::Chain &chain, | interfaces::Chain &chain, | ||||
CConnman *connman, NodePeerManager *nodePeerManager, | CConnman *connman, | ||||
bilingual_str &error) { | bilingual_str &error) { | ||||
std::unique_ptr<PeerData> peerData; | std::unique_ptr<PeerData> peerData; | ||||
CKey masterKey; | CKey masterKey; | ||||
CKey sessionKey; | CKey sessionKey; | ||||
if (argsman.IsArgSet("-avasessionkey")) { | if (argsman.IsArgSet("-avasessionkey")) { | ||||
sessionKey = DecodeSecret(argsman.GetArg("-avasessionkey", "")); | sessionKey = DecodeSecret(argsman.GetArg("-avasessionkey", "")); | ||||
if (!sessionKey.IsValid()) { | if (!sessionKey.IsValid()) { | ||||
error = _("The avalanche session key is invalid."); | error = _("The avalanche session key is invalid."); | ||||
▲ Show 20 Lines • Show All 75 Lines • ▼ Show 20 Lines | if (argsman.IsArgSet("-avaproof")) { | ||||
if (!VerifyDelegation(peerData->delegation, sessionPubKey, error)) { | if (!VerifyDelegation(peerData->delegation, sessionPubKey, error)) { | ||||
// error is set by VerifyDelegation | // error is set by VerifyDelegation | ||||
return nullptr; | return nullptr; | ||||
} | } | ||||
} | } | ||||
// We can't use std::make_unique with a private constructor | // We can't use std::make_unique with a private constructor | ||||
return std::unique_ptr<Processor>( | return std::unique_ptr<Processor>(new Processor( | ||||
new Processor(chain, connman, nodePeerManager, std::move(peerData), | chain, connman, std::move(peerData), std::move(sessionKey))); | ||||
std::move(sessionKey))); | |||||
} | } | ||||
bool Processor::addBlockToReconcile(const CBlockIndex *pindex) { | bool Processor::addBlockToReconcile(const CBlockIndex *pindex) { | ||||
bool isAccepted; | bool isAccepted; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
if (!IsWorthPolling(pindex)) { | if (!IsWorthPolling(pindex)) { | ||||
▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | |||||
void Processor::sendResponse(CNode *pfrom, Response response) const { | void Processor::sendResponse(CNode *pfrom, Response response) const { | ||||
connman->PushMessage( | connman->PushMessage( | ||||
pfrom, CNetMsgMaker(pfrom->GetCommonVersion()) | pfrom, CNetMsgMaker(pfrom->GetCommonVersion()) | ||||
.Make(NetMsgType::AVARESPONSE, | .Make(NetMsgType::AVARESPONSE, | ||||
TCPResponse(std::move(response), sessionKey))); | TCPResponse(std::move(response), sessionKey))); | ||||
} | } | ||||
bool Processor::registerVotes(NodeId nodeid, const Response &response, | bool Processor::registerVotes(NodeId nodeid, const Response &response, | ||||
std::vector<BlockUpdate> &updates) { | std::vector<BlockUpdate> &updates, int &banscore, | ||||
std::string &error) { | |||||
{ | { | ||||
// Save the time at which we can query again. | // Save the time at which we can query again. | ||||
LOCK(cs_peerManager); | LOCK(cs_peerManager); | ||||
// FIXME: This will override the time even when we received an old stale | // FIXME: This will override the time even when we received an old stale | ||||
// message. This should check that the message is indeed the most up to | // message. This should check that the message is indeed the most up to | ||||
// date one before updating the time. | // date one before updating the time. | ||||
peerManager->updateNextRequestTime( | peerManager->updateNextRequestTime( | ||||
nodeid, std::chrono::steady_clock::now() + | nodeid, std::chrono::steady_clock::now() + | ||||
std::chrono::milliseconds(response.getCooldown())); | std::chrono::milliseconds(response.getCooldown())); | ||||
} | } | ||||
std::vector<CInv> invs; | std::vector<CInv> invs; | ||||
{ | { | ||||
// Check that the query exists. | // Check that the query exists. | ||||
auto w = queries.getWriteView(); | auto w = queries.getWriteView(); | ||||
auto it = w->find(std::make_tuple(nodeid, response.getRound())); | auto it = w->find(std::make_tuple(nodeid, response.getRound())); | ||||
if (it == w.end()) { | if (it == w.end()) { | ||||
nodePeerManager->Misbehaving(nodeid, 2, "unexpected-ava-response"); | banscore = 2; | ||||
error = "unexpected-ava-response"; | |||||
return false; | return false; | ||||
} | } | ||||
invs = std::move(it->invs); | invs = std::move(it->invs); | ||||
w->erase(it); | w->erase(it); | ||||
} | } | ||||
// Verify that the request and the vote are consistent. | // Verify that the request and the vote are consistent. | ||||
const std::vector<Vote> &votes = response.GetVotes(); | const std::vector<Vote> &votes = response.GetVotes(); | ||||
size_t size = invs.size(); | size_t size = invs.size(); | ||||
if (votes.size() != size) { | if (votes.size() != size) { | ||||
nodePeerManager->Misbehaving(nodeid, 100, "invalid-ava-response-size"); | banscore = 100; | ||||
error = "invalid-ava-response-size"; | |||||
return false; | return false; | ||||
} | } | ||||
for (size_t i = 0; i < size; i++) { | for (size_t i = 0; i < size; i++) { | ||||
if (invs[i].hash != votes[i].GetHash()) { | if (invs[i].hash != votes[i].GetHash()) { | ||||
nodePeerManager->Misbehaving(nodeid, 100, | banscore = 100; | ||||
"invalid-ava-response-content"); | error = "invalid-ava-response-content"; | ||||
return false; | return false; | ||||
} | } | ||||
} | } | ||||
std::map<CBlockIndex *, Vote> responseIndex; | std::map<CBlockIndex *, Vote> responseIndex; | ||||
{ | { | ||||
LOCK(cs_main); | LOCK(cs_main); | ||||
▲ Show 20 Lines • Show All 268 Lines • Show Last 20 Lines |