danicoinwallet/src/CryptoNoteWrapper.cpp

266 lines
8.1 KiB
C++
Raw Normal View History

2015-04-29 17:03:08 +00:00
// Copyright (c) 2011-2015 The Cryptonote developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
2015-09-18 12:37:30 +00:00
#include "CryptoNoteWrapper.h"
#include "CryptoNoteCore/CryptoNoteBasicImpl.h"
#include "CryptoNoteCore/CryptoNoteFormatUtils.h"
#include "CryptoNoteCore/Currency.h"
#include "NodeRpcProxy/NodeRpcProxy.h"
#include "CryptoNoteCore/CoreConfig.h"
#include "P2p/NetNodeConfig.h"
#include "CryptoNoteCore/Core.h"
#include "CryptoNoteProtocol/CryptoNoteProtocolHandler.h"
#include "InProcessNode/InProcessNode.h"
#include "P2p/NetNode.h"
#include "WalletLegacy/WalletLegacy.h"
#include "Logging/LoggerManager.h"
#include "System/Dispatcher.h"
2015-04-29 17:03:08 +00:00
namespace WalletGui {
namespace {
2015-09-18 12:37:30 +00:00
bool parsePaymentId(const std::string& payment_id_str, Crypto::Hash& payment_id) {
return CryptoNote::parsePaymentId(payment_id_str, payment_id);
2015-04-29 17:03:08 +00:00
}
std::string convertPaymentId(const std::string& paymentIdString) {
if (paymentIdString.empty()) {
return "";
}
2015-09-18 12:37:30 +00:00
Crypto::Hash paymentId;
2015-04-29 17:03:08 +00:00
if (!parsePaymentId(paymentIdString, paymentId)) {
std::stringstream errorStr;
errorStr << "Payment id has invalid format: \"" + paymentIdString + "\", expected 64-character string";
throw std::runtime_error(errorStr.str());
}
std::vector<uint8_t> extra;
2015-09-18 12:37:30 +00:00
CryptoNote::BinaryArray extraNonce;
CryptoNote::setPaymentIdToTransactionExtraNonce(extraNonce, paymentId);
if (!CryptoNote::addExtraNonceToTransactionExtra(extra, extraNonce)) {
2015-04-29 17:03:08 +00:00
std::stringstream errorStr;
errorStr << "Something went wrong with payment_id. Please check its format: \"" + paymentIdString + "\", expected 64-character string";
throw std::runtime_error(errorStr.str());
}
return std::string(extra.begin(), extra.end());
}
std::string extractPaymentId(const std::string& extra) {
2015-09-18 12:37:30 +00:00
std::vector<CryptoNote::TransactionExtraField> extraFields;
2015-04-29 17:03:08 +00:00
std::vector<uint8_t> extraVector;
std::copy(extra.begin(), extra.end(), std::back_inserter(extraVector));
2015-09-18 12:37:30 +00:00
if (!CryptoNote::parseTransactionExtra(extraVector, extraFields)) {
2015-04-29 17:03:08 +00:00
throw std::runtime_error("Can't parse extra");
}
std::string result;
2015-09-18 12:37:30 +00:00
CryptoNote::TransactionExtraNonce extraNonce;
if (CryptoNote::findTransactionExtraFieldByType(extraFields, extraNonce)) {
Crypto::Hash paymentIdHash;
if (CryptoNote::getPaymentIdFromTransactionExtraNonce(extraNonce.nonce, paymentIdHash)) {
2015-04-29 17:03:08 +00:00
unsigned char* buff = reinterpret_cast<unsigned char *>(&paymentIdHash);
for (size_t i = 0; i < sizeof(paymentIdHash); ++i) {
result.push_back("0123456789ABCDEF"[buff[i] >> 4]);
result.push_back("0123456789ABCDEF"[buff[i] & 15]);
}
}
}
return result;
}
2015-09-18 12:37:30 +00:00
2015-04-29 17:03:08 +00:00
}
Node::~Node() {
}
class RpcNode : CryptoNote::INodeObserver, public Node {
public:
2015-09-18 12:37:30 +00:00
RpcNode(const CryptoNote::Currency& currency, INodeCallback& callback, const std::string& nodeHost, unsigned short nodePort) :
2015-04-29 17:03:08 +00:00
m_callback(callback),
m_currency(currency),
m_node(nodeHost, nodePort) {
m_node.addObserver(this);
}
~RpcNode() override {
}
void init(const std::function<void(std::error_code)>& callback) override {
m_node.init(callback);
}
void deinit() override {
}
std::string convertPaymentId(const std::string& paymentIdString) override {
return WalletGui::convertPaymentId(paymentIdString);
}
std::string extractPaymentId(const std::string& extra) override {
return WalletGui::extractPaymentId(extra);
}
uint64_t getLastKnownBlockHeight() const override {
return m_node.getLastKnownBlockHeight();
}
uint64_t getLastLocalBlockHeight() const override {
return m_node.getLastLocalBlockHeight();
}
uint64_t getLastLocalBlockTimestamp() const override {
return m_node.getLastLocalBlockTimestamp();
}
uint64_t getPeerCount() const override {
return m_node.getPeerCount();
}
2015-09-18 12:37:30 +00:00
CryptoNote::IWalletLegacy* createWallet() override {
return new CryptoNote::WalletLegacy(m_currency, m_node);
2015-04-29 17:03:08 +00:00
}
private:
INodeCallback& m_callback;
2015-09-18 12:37:30 +00:00
const CryptoNote::Currency& m_currency;
CryptoNote::NodeRpcProxy m_node;
2015-04-29 17:03:08 +00:00
void peerCountUpdated(size_t count) {
m_callback.peerCountUpdated(*this, count);
}
void localBlockchainUpdated(uint64_t height) {
m_callback.localBlockchainUpdated(*this, height);
}
void lastKnownBlockHeightUpdated(uint64_t height) {
m_callback.lastKnownBlockHeightUpdated(*this, height);
}
};
class InprocessNode : CryptoNote::INodeObserver, public Node {
public:
2015-09-18 12:37:30 +00:00
InprocessNode(const CryptoNote::Currency& currency, Logging::LoggerManager& logManager, const CryptoNote::CoreConfig& coreConfig,
const CryptoNote::NetNodeConfig& netNodeConfig, INodeCallback& callback) :
m_currency(currency), m_dispatcher(),
2015-04-29 17:03:08 +00:00
m_callback(callback),
m_coreConfig(coreConfig),
2015-09-18 12:37:30 +00:00
m_netNodeConfig(netNodeConfig),
m_protocolHandler(currency, m_dispatcher, m_core, nullptr, logManager),
m_core(currency, &m_protocolHandler, logManager),
m_nodeServer(m_dispatcher, m_protocolHandler, logManager),
2015-04-29 17:03:08 +00:00
m_node(m_core, m_protocolHandler) {
m_core.set_cryptonote_protocol(&m_protocolHandler);
m_protocolHandler.set_p2p_endpoint(&m_nodeServer);
2015-09-18 12:37:30 +00:00
CryptoNote::Checkpoints checkpoints(logManager);
for (const CryptoNote::CheckpointData& checkpoint : CryptoNote::CHECKPOINTS) {
2015-04-29 17:03:08 +00:00
checkpoints.add_checkpoint(checkpoint.height, checkpoint.blockId);
}
}
~InprocessNode() override {
2015-09-18 12:37:30 +00:00
2015-04-29 17:03:08 +00:00
}
void init(const std::function<void(std::error_code)>& callback) override {
2015-09-18 12:37:30 +00:00
try {
if (!m_core.init(m_coreConfig, CryptoNote::MinerConfig(), true)) {
callback(make_error_code(CryptoNote::error::NOT_INITIALIZED));
2015-04-29 17:03:08 +00:00
return;
2015-09-18 12:37:30 +00:00
}
if (!m_nodeServer.init(m_netNodeConfig)) {
callback(make_error_code(CryptoNote::error::NOT_INITIALIZED));
2015-04-29 17:03:08 +00:00
return;
2015-09-18 12:37:30 +00:00
}
} catch (std::runtime_error& _err) {
callback(make_error_code(CryptoNote::error::NOT_INITIALIZED));
return;
2015-04-29 17:03:08 +00:00
}
2015-09-18 12:37:30 +00:00
2015-04-29 17:03:08 +00:00
m_node.init([this, callback](std::error_code ec) {
2015-09-18 12:37:30 +00:00
m_node.addObserver(this);
callback(ec);
2015-04-29 17:03:08 +00:00
});
2015-09-18 12:37:30 +00:00
2015-04-29 17:03:08 +00:00
m_nodeServer.run();
m_nodeServer.deinit();
m_node.shutdown();
}
void deinit() override {
2015-09-18 12:37:30 +00:00
m_nodeServer.sendStopSignal();
2015-04-29 17:03:08 +00:00
}
std::string convertPaymentId(const std::string& paymentIdString) override {
return WalletGui::convertPaymentId(paymentIdString);
}
std::string extractPaymentId(const std::string& extra) override {
return WalletGui::extractPaymentId(extra);
}
uint64_t getLastKnownBlockHeight() const override {
return m_node.getLastKnownBlockHeight();
}
uint64_t getLastLocalBlockHeight() const override {
return m_node.getLastLocalBlockHeight();
}
uint64_t getLastLocalBlockTimestamp() const override {
return m_node.getLastLocalBlockTimestamp();
}
uint64_t getPeerCount() const override {
return m_node.getPeerCount();
}
2015-09-18 12:37:30 +00:00
CryptoNote::IWalletLegacy* createWallet() override {
return new CryptoNote::WalletLegacy(m_currency, m_node);
2015-04-29 17:03:08 +00:00
}
private:
INodeCallback& m_callback;
2015-09-18 12:37:30 +00:00
const CryptoNote::Currency& m_currency;
System::Dispatcher m_dispatcher;
CryptoNote::CoreConfig m_coreConfig;
CryptoNote::NetNodeConfig m_netNodeConfig;
CryptoNote::core m_core;
CryptoNote::CryptoNoteProtocolHandler m_protocolHandler;
CryptoNote::NodeServer m_nodeServer;
2015-04-29 17:03:08 +00:00
CryptoNote::InProcessNode m_node;
std::future<bool> m_nodeServerFuture;
void peerCountUpdated(size_t count) {
m_callback.peerCountUpdated(*this, count);
}
void localBlockchainUpdated(uint64_t height) {
m_callback.localBlockchainUpdated(*this, height);
}
void lastKnownBlockHeightUpdated(uint64_t height) {
m_callback.lastKnownBlockHeightUpdated(*this, height);
}
};
2015-09-18 12:37:30 +00:00
Node* createRpcNode(const CryptoNote::Currency& currency, INodeCallback& callback, const std::string& nodeHost, unsigned short nodePort) {
2015-04-29 17:03:08 +00:00
return new RpcNode(currency, callback, nodeHost, nodePort);
}
2015-09-18 12:37:30 +00:00
Node* createInprocessNode(const CryptoNote::Currency& currency, Logging::LoggerManager& logManager,
const CryptoNote::CoreConfig& coreConfig, const CryptoNote::NetNodeConfig& netNodeConfig, INodeCallback& callback) {
return new InprocessNode(currency, logManager, coreConfig, netNodeConfig, callback);
2015-04-29 17:03:08 +00:00
}
}