danicoin/src/Miner/BlockchainMonitor.cpp
2016-01-18 15:33:29 +00:00

93 lines
2.8 KiB
C++

// Copyright (c) 2011-2016 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include "BlockchainMonitor.h"
#include "Common/StringTools.h"
#include <System/EventLock.h>
#include <System/Timer.h>
#include <System/InterruptedException.h>
#include "Rpc/CoreRpcServerCommandsDefinitions.h"
#include "Rpc/JsonRpc.h"
#include "Rpc/HttpClient.h"
BlockchainMonitor::BlockchainMonitor(System::Dispatcher& dispatcher, const std::string& daemonHost, uint16_t daemonPort, size_t pollingInterval, Logging::ILogger& logger):
m_dispatcher(dispatcher),
m_daemonHost(daemonHost),
m_daemonPort(daemonPort),
m_pollingInterval(pollingInterval),
m_stopped(false),
m_httpEvent(dispatcher),
m_sleepingContext(dispatcher),
m_logger(logger, "BlockchainMonitor") {
m_httpEvent.set();
}
void BlockchainMonitor::waitBlockchainUpdate() {
m_logger(Logging::DEBUGGING) << "Waiting for blockchain updates";
m_stopped = false;
Crypto::Hash lastBlockHash = requestLastBlockHash();
while(!m_stopped) {
m_sleepingContext.spawn([this] () {
System::Timer timer(m_dispatcher);
timer.sleep(std::chrono::seconds(m_pollingInterval));
});
m_sleepingContext.wait();
if (lastBlockHash != requestLastBlockHash()) {
m_logger(Logging::DEBUGGING) << "Blockchain has been updated";
break;
}
}
if (m_stopped) {
m_logger(Logging::DEBUGGING) << "Blockchain monitor has been stopped";
throw System::InterruptedException();
}
}
void BlockchainMonitor::stop() {
m_logger(Logging::DEBUGGING) << "Sending stop signal to blockchain monitor";
m_stopped = true;
m_sleepingContext.interrupt();
m_sleepingContext.wait();
}
Crypto::Hash BlockchainMonitor::requestLastBlockHash() {
m_logger(Logging::DEBUGGING) << "Requesting last block hash";
try {
CryptoNote::HttpClient client(m_dispatcher, m_daemonHost, m_daemonPort);
CryptoNote::COMMAND_RPC_GET_LAST_BLOCK_HEADER::request request;
CryptoNote::COMMAND_RPC_GET_LAST_BLOCK_HEADER::response response;
System::EventLock lk(m_httpEvent);
CryptoNote::JsonRpc::invokeJsonRpcCommand(client, "getlastblockheader", request, response);
if (response.status != CORE_RPC_STATUS_OK) {
throw std::runtime_error("Core responded with wrong status: " + response.status);
}
Crypto::Hash blockHash;
if (!Common::podFromHex(response.block_header.hash, blockHash)) {
throw std::runtime_error("Couldn't parse block hash: " + response.block_header.hash);
}
m_logger(Logging::DEBUGGING) << "Last block hash: " << Common::podToHex(blockHash);
return blockHash;
} catch (std::exception& e) {
m_logger(Logging::ERROR) << "Failed to request last block hash: " << e.what();
throw;
}
}