parent
47bd8c9fe5
commit
c53d36291f
@ -0,0 +1,3 @@
|
||||
[submodule "src/xmregcore"]
|
||||
path = src/xmregcore
|
||||
url = git@github.com:moneroexamples/xmregcore.git
|
@ -1,77 +0,0 @@
|
||||
#------------------------------------------------------------------------------
|
||||
# CMake helper for the majority of the cpp-ethereum modules.
|
||||
#
|
||||
# This module defines
|
||||
# Monero_XXX_LIBRARIES, the libraries needed to use ethereum.
|
||||
# Monero_FOUND, If false, do not try to use ethereum.
|
||||
#
|
||||
# File addetped from cpp-ethereum
|
||||
#
|
||||
# The documentation for cpp-ethereum is hosted at http://cpp-ethereum.org
|
||||
#
|
||||
# ------------------------------------------------------------------------------
|
||||
# This file is part of cpp-ethereum.
|
||||
#
|
||||
# cpp-ethereum is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# cpp-ethereum is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>
|
||||
#
|
||||
# (c) 2014-2016 cpp-ethereum contributors.
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
set(LIBS common;blocks;cryptonote_basic;cryptonote_core;
|
||||
cryptonote_protocol;daemonizer;mnemonics;epee;lmdb;device;
|
||||
blockchain_db;ringct;wallet;cncrypto;easylogging;version;checkpoints)
|
||||
|
||||
set(Xmr_INCLUDE_DIRS "${CPP_MONERO_DIR}")
|
||||
|
||||
# if the project is a subset of main cpp-ethereum project
|
||||
# use same pattern for variables as Boost uses
|
||||
|
||||
foreach (l ${LIBS})
|
||||
|
||||
string(TOUPPER ${l} L)
|
||||
|
||||
find_library(Xmr_${L}_LIBRARY
|
||||
NAMES ${l}
|
||||
PATHS ${CMAKE_LIBRARY_PATH}
|
||||
PATH_SUFFIXES "/src/${l}" "/src/" "/external/db_drivers/lib${l}" "/lib" "/src/crypto" "/contrib/epee/src" "/external/easylogging++/"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
set(Xmr_${L}_LIBRARIES ${Xmr_${L}_LIBRARY})
|
||||
|
||||
message(STATUS FindMonero " Xmr_${L}_LIBRARIES ${Xmr_${L}_LIBRARY}")
|
||||
|
||||
add_library(${l} STATIC IMPORTED)
|
||||
set_property(TARGET ${l} PROPERTY IMPORTED_LOCATION ${Xmr_${L}_LIBRARIES})
|
||||
|
||||
endforeach()
|
||||
|
||||
|
||||
if (EXISTS ${MONERO_BUILD_DIR}/src/ringct/libringct_basic.a)
|
||||
message(STATUS FindMonero " found libringct_basic.a")
|
||||
add_library(ringct_basic STATIC IMPORTED)
|
||||
set_property(TARGET ringct_basic
|
||||
PROPERTY IMPORTED_LOCATION ${MONERO_BUILD_DIR}/src/ringct/libringct_basic.a)
|
||||
endif()
|
||||
|
||||
message(STATUS ${MONERO_SOURCE_DIR}/build)
|
||||
|
||||
# include monero headers
|
||||
include_directories(
|
||||
${MONERO_SOURCE_DIR}/src
|
||||
${MONERO_SOURCE_DIR}/external
|
||||
${MONERO_SOURCE_DIR}/build
|
||||
${MONERO_SOURCE_DIR}/external/easylogging++
|
||||
${MONERO_SOURCE_DIR}/contrib/epee/include
|
||||
${MONERO_SOURCE_DIR}/external/db_drivers/liblmdb)
|
@ -1,99 +0,0 @@
|
||||
|
||||
macro(configure_files srcDir destDir)
|
||||
message(STATUS "Configuring directory ${destDir}")
|
||||
make_directory(${destDir})
|
||||
|
||||
file(GLOB templateFiles RELATIVE ${srcDir} ${srcDir}/*)
|
||||
foreach(templateFile ${templateFiles})
|
||||
set(srcTemplatePath ${srcDir}/${templateFile})
|
||||
if(NOT IS_DIRECTORY ${srcTemplatePath})
|
||||
message(STATUS "Configuring file ${templateFile}")
|
||||
configure_file(
|
||||
${srcTemplatePath}
|
||||
${destDir}/${templateFile}
|
||||
@ONLY)
|
||||
endif(NOT IS_DIRECTORY ${srcTemplatePath})
|
||||
endforeach(templateFile)
|
||||
endmacro(configure_files)
|
||||
|
||||
macro(create_git_version)
|
||||
# Get the current working branch
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_BRANCH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# http://xit0.org/2013/04/cmake-use-git-branch-and-commit-details-in-project/
|
||||
# Get the latest abbreviated commit hash of the working branch
|
||||
execute_process(
|
||||
COMMAND git log -1 --format=%h
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT_HASH
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Get the date and time of last commit
|
||||
execute_process(
|
||||
COMMAND git log -1 --format=%cd --date=short
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_COMMIT_DATETIME
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Get current branch name
|
||||
execute_process(
|
||||
COMMAND git rev-parse --abbrev-ref HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_BRANCH_NAME
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_SOURCE_DIR}/src/version.h.in
|
||||
${CMAKE_BINARY_DIR}/gen/version.h
|
||||
)
|
||||
|
||||
include_directories(${CMAKE_BINARY_DIR}/gen)
|
||||
|
||||
endmacro(create_git_version)
|
||||
|
||||
|
||||
|
||||
macro(resource_dir srcDir)
|
||||
# Scan through resource folder for updated files and copy if none existing or changed
|
||||
file (GLOB_RECURSE resources "${srcDir}/*.*")
|
||||
|
||||
foreach(resource ${resources})
|
||||
get_filename_component(filename ${resource} NAME)
|
||||
get_filename_component(dir ${resource} DIRECTORY)
|
||||
get_filename_component(dirname ${dir} NAME)
|
||||
|
||||
# message("${dirname} ${srcDir}")
|
||||
|
||||
set(topdir ${dirname})
|
||||
|
||||
set(output "")
|
||||
|
||||
while(NOT ${dirname} STREQUAL ${srcDir})
|
||||
get_filename_component(path_component ${dir} NAME)
|
||||
set (output "${path_component}/${output}")
|
||||
get_filename_component(dir ${dir} DIRECTORY)
|
||||
get_filename_component(dirname ${dir} NAME)
|
||||
endwhile()
|
||||
|
||||
set(output "${CMAKE_CURRENT_BINARY_DIR}/${topdir}/${filename}")
|
||||
|
||||
add_custom_command(
|
||||
COMMENT "Moving updated resource-file '${filename}' to ${output}"
|
||||
OUTPUT ${output}
|
||||
DEPENDS ${resource}
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
${resource}
|
||||
${output}
|
||||
)
|
||||
add_custom_target("${dirname}${filename}" ALL DEPENDS ${resource} ${output})
|
||||
|
||||
endforeach()
|
||||
endmacro(resource_dir)
|
File diff suppressed because it is too large
Load Diff
@ -1,243 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 5/11/15.
|
||||
//
|
||||
|
||||
#include "MicroCore.h"
|
||||
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
/**
|
||||
* The constructor is interesting, as
|
||||
* m_mempool and m_blockchain_storage depend
|
||||
* on each other.
|
||||
*
|
||||
* So basically m_mempool is initialized with
|
||||
* reference to Blockchain (i.e., Blockchain&)
|
||||
* and m_blockchain_storage is initialized with
|
||||
* reference to m_mempool (i.e., tx_memory_pool&)
|
||||
*
|
||||
* The same is done in cryptonode::core.
|
||||
*/
|
||||
MicroCore::MicroCore():
|
||||
m_mempool(core_storage),
|
||||
core_storage(m_mempool),
|
||||
m_device {&hw::get_device("default")}
|
||||
{
|
||||
|
||||
}
|
||||
/**
|
||||
* Initialized the MicroCore object.
|
||||
*
|
||||
* Create BlockchainLMDB on the heap.
|
||||
* Open database files located in blockchain_path.
|
||||
* Initialize m_blockchain_storage with the BlockchainLMDB object.
|
||||
*/
|
||||
bool
|
||||
MicroCore::init(const string& _blockchain_path, network_type nt)
|
||||
{
|
||||
blockchain_path = _blockchain_path;
|
||||
|
||||
nettype = nt;
|
||||
|
||||
std::unique_ptr<BlockchainDB> db = std::make_unique<BlockchainLMDB>();
|
||||
|
||||
try
|
||||
{
|
||||
// try opening lmdb database files
|
||||
db->open(blockchain_path, DBF_RDONLY);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
cerr << "Error opening database: " << e.what();
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if the blockchain database
|
||||
// is successful opened
|
||||
if(!db->is_open())
|
||||
return false;
|
||||
|
||||
// initialize Blockchain object to manage
|
||||
// the database.
|
||||
if (!core_storage.init(db.release(), nettype))
|
||||
{
|
||||
cerr << "Error opening database: core_storage->init(db, nettype)\n" ;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!m_mempool.init())
|
||||
{
|
||||
cerr << "Error opening database: m_mempool.init()\n" ;
|
||||
return false;
|
||||
}
|
||||
|
||||
initialization_succeded = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get m_blockchain_storage.
|
||||
* Initialize m_blockchain_storage with the BlockchainLMDB object.
|
||||
*/
|
||||
Blockchain const&
|
||||
MicroCore::get_core() const
|
||||
{
|
||||
return core_storage;
|
||||
}
|
||||
|
||||
tx_memory_pool const&
|
||||
MicroCore::get_mempool() const
|
||||
{
|
||||
return m_mempool;
|
||||
}
|
||||
|
||||
bool
|
||||
MicroCore::get_block_from_height(uint64_t height, block& blk) const
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
blk = core_storage.get_db().get_block_from_height(height);
|
||||
}
|
||||
catch (const exception& e)
|
||||
{
|
||||
cerr << e.what() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MicroCore::get_block_complete_entry(block const& b, block_complete_entry& bce)
|
||||
{
|
||||
bce.block = cryptonote::block_to_blob(b);
|
||||
|
||||
for (const auto &tx_hash: b.tx_hashes)
|
||||
{
|
||||
transaction tx;
|
||||
|
||||
if (!get_tx(tx_hash, tx))
|
||||
return false;
|
||||
|
||||
cryptonote::blobdata txblob = tx_to_blob(tx);
|
||||
|
||||
bce.txs.push_back(txblob);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MicroCore::get_tx(crypto::hash const& tx_hash, transaction& tx) const
|
||||
{
|
||||
|
||||
if (core_storage.have_tx(tx_hash))
|
||||
{
|
||||
// get transaction with given hash
|
||||
tx = core_storage.get_db().get_tx(tx_hash);
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MicroCore::get_output_histogram(
|
||||
vector<uint64_t> const& amounts,
|
||||
uint64_t min_count,
|
||||
histogram_map& histogram,
|
||||
bool unlocked,
|
||||
uint64_t recent_cutoff) const
|
||||
{
|
||||
try
|
||||
{
|
||||
histogram = core_storage.get_output_histogram(
|
||||
amounts,
|
||||
unlocked,
|
||||
recent_cutoff,
|
||||
min_count);
|
||||
}
|
||||
catch (std::exception const& e)
|
||||
{
|
||||
cerr << e.what() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MicroCore::get_output_histogram(
|
||||
COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request const& req,
|
||||
COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res) const
|
||||
{
|
||||
// based on bool core_rpc_server::on_get_output_histogram(const ...
|
||||
|
||||
MicroCore::histogram_map histogram;
|
||||
|
||||
if (!get_output_histogram(req.amounts,
|
||||
req.min_count,
|
||||
histogram,
|
||||
req.unlocked,
|
||||
req.recent_cutoff))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
res.histogram.clear();
|
||||
res.histogram.reserve(histogram.size());
|
||||
|
||||
for (auto const& i: histogram)
|
||||
{
|
||||
if (std::get<0>(i.second)
|
||||
>= req.min_count
|
||||
&& (std::get<0>(i.second) <= req.max_count
|
||||
|| req.max_count == 0))
|
||||
res.histogram.push_back(
|
||||
COMMAND_RPC_GET_OUTPUT_HISTOGRAM::entry(
|
||||
i.first,
|
||||
std::get<0>(i.second),
|
||||
std::get<1>(i.second),
|
||||
std::get<2>(i.second)));
|
||||
}
|
||||
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
hw::device* const
|
||||
MicroCore::get_device() const
|
||||
{
|
||||
return m_device;
|
||||
}
|
||||
|
||||
bool
|
||||
MicroCore::init_success() const
|
||||
{
|
||||
return initialization_succeded;
|
||||
}
|
||||
|
||||
//MicroCore::~MicroCore()
|
||||
//{
|
||||
// //cout << "\n\nMicroCore::~MicroCore()\n\n";
|
||||
|
||||
// if (initialization_succeded)
|
||||
// {
|
||||
// //core_storage.get_db().safesyncmode(true);
|
||||
// if (core_storage.get_db().is_open())
|
||||
// core_storage.get_db().close();
|
||||
// //cout << "\n\n core_storage.get_db().close();;\n\n";
|
||||
// }
|
||||
|
||||
//}
|
||||
|
||||
|
||||
}
|
@ -1,245 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 5/11/15.
|
||||
//
|
||||
|
||||
#ifndef XMREG01_MICROCORE_H
|
||||
#define XMREG01_MICROCORE_H
|
||||
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
|
||||
#include "monero_headers.h"
|
||||
#include "tools.h"
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
using namespace cryptonote;
|
||||
using namespace crypto;
|
||||
using namespace std;
|
||||
|
||||
/**
|
||||
* Micro version of cryptonode::core class
|
||||
* Micro version of constructor,
|
||||
* init and destructor are implemted.
|
||||
*
|
||||
* Just enough to read the blockchain
|
||||
* database for use in the example.
|
||||
*/
|
||||
class MicroCore {
|
||||
|
||||
string blockchain_path;
|
||||
|
||||
tx_memory_pool m_mempool;
|
||||
Blockchain core_storage;
|
||||
|
||||
hw::device* m_device;
|
||||
|
||||
network_type nettype;
|
||||
|
||||
bool initialization_succeded {false};
|
||||
|
||||
public:
|
||||
|
||||
// <amoumt,
|
||||
// tuple<total_instances, unlocked_instances, recent_instances>
|
||||
using histogram_map = std::map<uint64_t,
|
||||
std::tuple<uint64_t, uint64_t, uint64_t>>;
|
||||
|
||||
MicroCore();
|
||||
|
||||
/**
|
||||
* Initialized the MicroCore object.
|
||||
*
|
||||
* Create BlockchainLMDB on the heap.
|
||||
* Open database files located in blockchain_path.
|
||||
* Initialize m_blockchain_storage with the BlockchainLMDB object.
|
||||
*/
|
||||
virtual bool
|
||||
init(const string& _blockchain_path, network_type nt);
|
||||
|
||||
virtual Blockchain const&
|
||||
get_core() const;
|
||||
|
||||
virtual tx_memory_pool const&
|
||||
get_mempool() const;
|
||||
|
||||
virtual hw::device* const
|
||||
get_device() const;
|
||||
|
||||
virtual void
|
||||
get_output_key(uint64_t amount,
|
||||
vector<uint64_t> const& absolute_offsets,
|
||||
vector<cryptonote::output_data_t>& outputs)
|
||||
{
|
||||
core_storage.get_db()
|
||||
.get_output_key(epee::span<const uint64_t>(&amount, 1),
|
||||
absolute_offsets, outputs);
|
||||
}
|
||||
|
||||
virtual output_data_t
|
||||
get_output_key(uint64_t amount,
|
||||
uint64_t global_amount_index)
|
||||
{
|
||||
return core_storage.get_db()
|
||||
.get_output_key(amount, global_amount_index);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
get_transactions(
|
||||
const std::vector<crypto::hash>& txs_ids,
|
||||
std::vector<transaction>& txs,
|
||||
std::vector<crypto::hash>& missed_txs) const
|
||||
{
|
||||
return core_storage.get_transactions(txs_ids, txs, missed_txs);
|
||||
}
|
||||
|
||||
virtual std::vector<block>
|
||||
get_blocks_range(const uint64_t& h1, const uint64_t& h2) const
|
||||
{
|
||||
return core_storage.get_db().get_blocks_range(h1, h2);
|
||||
}
|
||||
|
||||
//virtual std::vector<block>
|
||||
//get_blocks_range(const uint64_t& h1, const uint64_t& h2) const
|
||||
//{
|
||||
//std::vector<std::pair<cryptonote::blobdata,block>> blobblocks;
|
||||
//std::vector<blobdata> txs;
|
||||
//vector<block> blocks;
|
||||
|
||||
//{
|
||||
//std::lock_guard<std::mutex> lock(mtx1);
|
||||
//cout << "tid: " << std::this_thread::get_id() << endl;;
|
||||
//core_storage.get_blocks(h1, h2-h1+1, blobblocks, txs);
|
||||
//}
|
||||
|
||||
//blocks.reserve(blobblocks.size());
|
||||
|
||||
//for (auto const& bpair: blobblocks)
|
||||
//blocks.push_back(std::move(bpair.second));
|
||||
|
||||
//return blocks;
|
||||
//}
|
||||
|
||||
virtual uint64_t
|
||||
get_tx_unlock_time(crypto::hash const& tx_hash) const
|
||||
{
|
||||
return core_storage.get_db().get_tx_unlock_time(tx_hash);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
have_tx(crypto::hash const& tx_hash) const
|
||||
{
|
||||
return core_storage.have_tx(tx_hash);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
tx_exists(crypto::hash const& tx_hash, uint64_t& tx_id) const
|
||||
{
|
||||
return core_storage.get_db().tx_exists(tx_hash, tx_id);
|
||||
}
|
||||
|
||||
virtual tx_out_index
|
||||
get_output_tx_and_index(uint64_t const& amount, uint64_t const& index) const
|
||||
{
|
||||
return core_storage.get_db().get_output_tx_and_index(amount, index);
|
||||
}
|
||||
|
||||
virtual uint64_t
|
||||
get_tx_block_height(crypto::hash const& tx_hash) const
|
||||
{
|
||||
return core_storage.get_db().get_tx_block_height(tx_hash);
|
||||
}
|
||||
|
||||
virtual std::vector<uint64_t>
|
||||
get_tx_amount_output_indices(uint64_t const& tx_id) const
|
||||
{
|
||||
return core_storage.get_db()
|
||||
.get_tx_amount_output_indices(tx_id).front();
|
||||
}
|
||||
|
||||
virtual bool
|
||||
get_mempool_txs(
|
||||
std::vector<tx_info>& tx_infos,
|
||||
std::vector<spent_key_image_info>& key_image_infos) const
|
||||
{
|
||||
return m_mempool.get_transactions_and_spent_keys_info(
|
||||
tx_infos, key_image_infos);
|
||||
}
|
||||
|
||||
virtual uint64_t
|
||||
get_current_blockchain_height() const
|
||||
{
|
||||
return core_storage.get_current_blockchain_height();
|
||||
}
|
||||
|
||||
virtual void
|
||||
get_output_tx_and_index(
|
||||
const uint64_t& amount,
|
||||
const std::vector<uint64_t>& offsets,
|
||||
std::vector<tx_out_index>& indices) const
|
||||
{
|
||||
// tx_hash , index in tx
|
||||
// tx_out_index is std::pair<crypto::hash, uint64_t>;
|
||||
core_storage.get_db().get_output_tx_and_index(
|
||||
amount, offsets, indices);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
get_output_histogram(
|
||||
vector<uint64_t> const& amounts,
|
||||
uint64_t min_count,
|
||||
histogram_map& histogram,
|
||||
bool unlocked = true,
|
||||
uint64_t recent_cutoff = 0) const;
|
||||
|
||||
|
||||
// mimicks core_rpc_server::on_get_output_histogram(..)
|
||||
virtual bool
|
||||
get_output_histogram(
|
||||
COMMAND_RPC_GET_OUTPUT_HISTOGRAM::request const& req,
|
||||
COMMAND_RPC_GET_OUTPUT_HISTOGRAM::response& res) const;
|
||||
|
||||
|
||||
virtual bool
|
||||
get_outs(COMMAND_RPC_GET_OUTPUTS_BIN::request const& req,
|
||||
COMMAND_RPC_GET_OUTPUTS_BIN::response& res) const
|
||||
{
|
||||
return core_storage.get_outs(req, res);
|
||||
}
|
||||
|
||||
virtual uint64_t
|
||||
get_dynamic_base_fee_estimate(uint64_t const& grace_blocks) const
|
||||
{
|
||||
return core_storage.get_dynamic_base_fee_estimate(grace_blocks);
|
||||
}
|
||||
|
||||
bool
|
||||
get_block_complete_entry(block const& b, block_complete_entry& bce);
|
||||
|
||||
virtual bool
|
||||
get_block_from_height(uint64_t height, block& blk) const;
|
||||
|
||||
virtual bool
|
||||
get_tx(crypto::hash const& tx_hash, transaction& tx) const;
|
||||
|
||||
virtual bool
|
||||
decrypt_payment_id(crypto::hash8& payment_id,
|
||||
public_key const& public_key,
|
||||
secret_key const& secret_key)
|
||||
{
|
||||
return m_device->decrypt_payment_id(payment_id,
|
||||
public_key,
|
||||
secret_key);
|
||||
}
|
||||
|
||||
virtual bool
|
||||
init_success() const;
|
||||
|
||||
virtual ~MicroCore() = default;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif //XMREG01_MICROCORE_H
|
@ -1,127 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "om_log.h"
|
||||
#include "OutputInputIdentification.h"
|
||||
#include "UniversalIdentifier.hpp"
|
||||
|
||||
#include <map>
|
||||
#include <utility>
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
|
||||
class PaymentSearcherException: public std::runtime_error
|
||||
{
|
||||
using std::runtime_error::runtime_error;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class for searching transactions having given payment_id
|
||||
* This is primarly used to check if a payment was made
|
||||
* for importing wallet
|
||||
*/
|
||||
template<typename Hash_T>
|
||||
class PaymentSearcher
|
||||
{
|
||||
|
||||
public:
|
||||
PaymentSearcher(
|
||||
address_parse_info const& _address_info,
|
||||
secret_key const& _viewkey):
|
||||
address_info {_address_info},
|
||||
viewkey {_viewkey}
|
||||
{}
|
||||
|
||||
|
||||
template<template<typename T,
|
||||
typename A = std::allocator<T>>
|
||||
class Cont_T>
|
||||
std::pair<uint64_t, typename Cont_T<transaction>::const_iterator>
|
||||
search(Hash_T const& expected_payment_id,
|
||||
Cont_T<transaction> const& txs,
|
||||
bool skip_coinbase = true)
|
||||
{
|
||||
|
||||
//auto null_hash = null_hash_T();
|
||||
|
||||
uint64_t found_amount {0};
|
||||
|
||||
Hash_T null_hash {};
|
||||
|
||||
// iterator to last txs that we found containing
|
||||
// our payment
|
||||
auto found_tx_it = std::cend(txs);
|
||||
|
||||
for (auto it = std::cbegin(txs);
|
||||
it != std::cend(txs); ++it)
|
||||
{
|
||||
auto const& tx = *it;
|
||||
|
||||
bool is_coinbase_tx = is_coinbase(tx);
|
||||
|
||||
if (skip_coinbase && is_coinbase_tx)
|
||||
continue;
|
||||
|
||||
auto identifier = make_identifier(tx,
|
||||
make_unique<Output>(&address_info, &viewkey),
|
||||
make_unique<IntegratedPaymentID>(&address_info, &viewkey));
|
||||
|
||||
|
||||
auto tx_pub_key = identifier.get_tx_pub_key();
|
||||
|
||||
identifier.template get<IntegratedPaymentID>()
|
||||
->identify(tx, tx_pub_key);
|
||||
|
||||
auto pay_id = identifier.template get<IntegratedPaymentID>()
|
||||
->get();
|
||||
|
||||
// we have pay_id. it can be crypto::hash8 or crypto:hash
|
||||
// so naw we need to perform comparison of the pay_id found
|
||||
// with the expected value of payment_id
|
||||
// for hash8 we need to do decoding of the pay_id, as it is
|
||||
// encoded
|
||||
|
||||
if (pay_id != expected_payment_id)
|
||||
continue;
|
||||
|
||||
// if everything ok with payment id, we proceed with
|
||||
// checking how much xmr we got in that tx.
|
||||
|
||||
// for each output, in a tx, check if it belongs
|
||||
// to the given account of specific address and viewkey
|
||||
|
||||
identifier.template get<Output>()->identify(tx, tx_pub_key);
|
||||
|
||||
auto const& outputs_found
|
||||
= identifier.template get<Output>()->get();
|
||||
|
||||
if (!outputs_found.empty())
|
||||
{ // nothing was found
|
||||
make_pair(found_amount, found_tx_it);
|
||||
}
|
||||
|
||||
// now add the found outputs into Outputs tables
|
||||
for (auto& out_info: outputs_found)
|
||||
found_amount += out_info.amount;
|
||||
|
||||
if (found_amount > 0)
|
||||
found_tx_it = it;
|
||||
}
|
||||
|
||||
return make_pair(found_amount, found_tx_it);
|
||||
}
|
||||
|
||||
virtual ~PaymentSearcher() = default;
|
||||
|
||||
private:
|
||||
address_parse_info const& address_info;
|
||||
secret_key const& viewkey;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
@ -1,352 +0,0 @@
|
||||
#include "UniversalIdentifier.hpp"
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
void
|
||||
Output::identify(transaction const& tx,
|
||||
public_key const& tx_pub_key,
|
||||
vector<public_key> const& additional_tx_pub_keys)
|
||||
{
|
||||
auto tx_is_coinbase = is_coinbase(tx);
|
||||
|
||||
key_derivation derivation;
|
||||
|
||||
if (!generate_key_derivation(tx_pub_key,
|
||||
*get_viewkey(), derivation))
|
||||
{
|
||||
throw std::runtime_error("generate_key_derivation failed");
|
||||
}
|
||||
|
||||
// since introduction of subaddresses, a tx can
|
||||
// have extra public keys, thus we need additional
|
||||
// derivations
|
||||
|
||||
vector<key_derivation> additional_derivations;
|
||||
|
||||
if (!additional_tx_pub_keys.empty())
|
||||
{
|
||||
additional_derivations.resize(additional_tx_pub_keys.size());
|
||||
|
||||
for (size_t i = 0; i < additional_tx_pub_keys.size(); ++i)
|
||||
{
|
||||
if (!generate_key_derivation(additional_tx_pub_keys[i],
|
||||
*get_viewkey(),
|
||||
additional_derivations[i]))
|
||||
{
|
||||
throw std::runtime_error("additional generate_key_derivation failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto i = 0u; i < tx.vout.size(); ++i)
|
||||
{
|
||||
// i will act as output indxes in the tx
|
||||
|
||||
if (tx.vout[i].target.type() != typeid(txout_to_key))
|
||||
continue;
|
||||
|
||||
// get tx input key
|
||||
txout_to_key const& txout_key
|
||||
= boost::get<txout_to_key>(tx.vout[i].target);
|
||||
|
||||
uint64_t amount = tx.vout[i].amount;
|
||||
|
||||
// get the tx output public key
|
||||
// that normally would be generated for us,
|
||||
// if someone had sent us some xmr.
|
||||
public_key generated_tx_pubkey;
|
||||
|
||||
derive_public_key(derivation,
|
||||
i,
|
||||
get_address()->address.m_spend_public_key,
|
||||
generated_tx_pubkey);
|
||||
|
||||
// cout << pod_to_hex(derivation) << ", " << i << ", "
|
||||
// << pod_to_hex(get_address()->address.m_spend_public_key) << ", "
|
||||
// << pod_to_hex(txout_key.key) << " == "
|
||||
// << pod_to_hex(generated_tx_pubkey) << '\n' << '\n';
|
||||
|
||||
// check if generated public key matches the current output's key
|
||||
bool mine_output = (txout_key.key == generated_tx_pubkey);
|
||||
|
||||
auto with_additional = false;
|
||||
|
||||
if (!mine_output && !additional_tx_pub_keys.empty())
|
||||
{
|
||||
// check for output using additional tx public keys
|
||||
derive_public_key(additional_derivations[i],
|
||||
i,
|
||||
get_address()->address.m_spend_public_key,
|
||||
generated_tx_pubkey);
|
||||
|
||||
|
||||
mine_output = (txout_key.key == generated_tx_pubkey);
|
||||
|
||||
with_additional = true;
|
||||
}
|
||||
|
||||
// placeholder variable for ringct outputs info
|
||||
// that we need to save in database
|
||||
|
||||
rct::key rtc_outpk {0};
|
||||
rct::key rtc_mask {0};
|
||||
rct::key rtc_amount {0};
|
||||
|
||||
// if mine output has RingCT, i.e., tx version is 2
|
||||
// need to decode its amount. otherwise its zero.
|
||||
if (mine_output && tx.version == 2)
|
||||
{
|
||||
// initialize with regular amount value
|
||||
// for ringct, except coinbase, it will be 0
|
||||
uint64_t rct_amount_val = amount;
|
||||
|
||||
// cointbase txs have amounts in plain sight.
|
||||
// so use amount from ringct, only for non-coinbase txs
|
||||
if (!tx_is_coinbase)
|
||||
{
|
||||
// for ringct non-coinbase txs, these values are given
|
||||
// with txs.
|
||||
// coinbase ringctx dont have this information. we will provide
|
||||
// them only when needed, in get_unspent_outputs. So go there
|
||||
// to see how we deal with ringct coinbase txs when we spent
|
||||
// them
|
||||
// go to CurrentBlockchainStatus::construct_output_rct_field
|
||||
// to see how we deal with coinbase ringct that are used
|
||||
// as mixins
|
||||
|
||||
rtc_outpk = tx.rct_signatures.outPk[i].mask;
|
||||
rtc_mask = tx.rct_signatures.ecdhInfo[i].mask;
|
||||
rtc_amount = tx.rct_signatures.ecdhInfo[i].amount;
|
||||
|
||||
rct::key mask = tx.rct_signatures
|
||||
.ecdhInfo[i].mask;
|
||||
|
||||
auto r = decode_ringct(tx.rct_signatures,
|
||||
!with_additional ? derivation
|
||||
: additional_derivations[i],
|
||||
i,
|
||||
mask,
|
||||
rct_amount_val);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
throw std::runtime_error(
|
||||
"Cant decode ringCT!");
|
||||
}
|
||||
|
||||
amount = rct_amount_val;
|
||||
|
||||
} // if (!tx_is_coinbase)
|
||||
|
||||
} // if (mine_output && tx.version == 2)
|
||||
|
||||
if (mine_output)
|
||||
{
|
||||
total_received += amount;
|
||||
|
||||
identified_outputs.emplace_back(
|
||||
info{
|
||||
txout_key.key, amount, i, derivation,
|
||||
rtc_outpk, rtc_mask, rtc_amount
|
||||
});
|
||||
|
||||
total_xmr += amount;
|
||||
|
||||
} // if (mine_output)
|
||||
|
||||
} // for (uint64_t i = 0; i < tx.vout.size(); ++i)
|
||||
}
|
||||
|
||||
void Input::identify(transaction const& tx,
|
||||
public_key const& tx_pub_key,
|
||||
vector<public_key> const& additional_tx_pub_keys)
|
||||
{
|
||||
auto search_misses {0};
|
||||
|
||||
auto input_no = tx.vin.size();
|
||||
|
||||
for (auto i = 0u; i < input_no; ++i)
|
||||
{
|
||||
if(tx.vin[i].type() != typeid(txin_to_key))
|
||||
continue;
|
||||
|
||||
// get tx input key
|
||||
txin_to_key const& in_key
|
||||
= boost::get<txin_to_key>(tx.vin[i]);
|
||||
|
||||
// get absolute offsets of mixins
|
||||
vector<uint64_t> absolute_offsets
|
||||
= relative_output_offsets_to_absolute(
|
||||
in_key.key_offsets);
|
||||
|
||||
// get public keys of outputs used in the mixins that
|
||||
// match to the offests
|
||||
vector<output_data_t> mixin_outputs;
|
||||
|
||||
// this can THROW if no outputs are found
|
||||
mcore->get_output_key(in_key.amount,
|
||||
absolute_offsets,
|
||||
mixin_outputs);
|
||||
|
||||
// indicates whether we found any matching mixin in the current input
|
||||
auto found_a_match {false};
|
||||
|
||||
// for each found output public key check if its ours or not
|
||||
for (auto count = 0u; count < absolute_offsets.size(); ++count)
|
||||
{
|
||||
// get basic information about mixn's output
|
||||
output_data_t const& output_data
|
||||
= mixin_outputs.at(count);
|
||||
|
||||
// before going to the mysql, check our known outputs cash
|
||||
// if the key exists. Its much faster than going to mysql
|
||||
// for this.
|
||||
|
||||
auto it = known_outputs->find(output_data.pubkey);
|
||||
|
||||
if (it != known_outputs->end())
|
||||
{
|
||||
// this seems to be our mixin.
|
||||
// save it into identified_inputs vector
|
||||
|
||||
identified_inputs.push_back(info {
|
||||
in_key.k_image,
|
||||
it->second, // amount
|
||||
output_data.pubkey});
|
||||
|
||||
total_xmr += it->second;
|
||||
|
||||
found_a_match = true;
|
||||
}
|
||||
|
||||
} // for (const cryptonote::output_data_t& output_data: outputs)
|
||||
|
||||
if (found_a_match == false)
|
||||
{
|
||||
// if we didnt find any match, break of the look.
|
||||
// there is no reason to check remaining key images
|
||||
// as when we spent something, our outputs should be
|
||||
// in all inputs in a given txs. Thus, if a single input
|
||||
// is without our output, we can assume this tx does
|
||||
// not contain any of our spendings.
|
||||
|
||||
// just to be sure before we break out of this loop,
|
||||
// do it only after two misses
|
||||
|
||||
if (++search_misses > 2)
|
||||
break;
|
||||
}
|
||||
|
||||
} // for (auto i = 0u; i < input_no; ++i)
|
||||
}
|
||||
|
||||
|
||||
void RealInput::identify(transaction const& tx,
|
||||
public_key const& tx_pub_key,
|
||||
vector<public_key> const& additional_tx_pub_keys)
|
||||
{
|
||||
auto search_misses {0};
|
||||
|
||||
auto input_no = tx.vin.size();
|
||||
|
||||
for (auto i = 0u; i < input_no; ++i)
|
||||
{
|
||||
if(tx.vin[i].type() != typeid(txin_to_key))
|
||||
continue;
|
||||
|
||||
// get tx input key
|
||||
txin_to_key const& in_key
|
||||
= boost::get<cryptonote::txin_to_key>(tx.vin[i]);
|
||||
|
||||
// get absolute offsets of mixins
|
||||
auto absolute_offsets
|
||||
= relative_output_offsets_to_absolute(
|
||||
in_key.key_offsets);
|
||||
|
||||
|
||||
//tx_out_index is pair::<transaction hash, output index>
|
||||
vector<tx_out_index> indices;
|
||||
|
||||
// get tx hashes and indices in the txs for the
|
||||
// given outputs of mixins
|
||||
// this cant THROW DB_EXCEPTION
|
||||
mcore->get_output_tx_and_index(
|
||||
in_key.amount, absolute_offsets, indices);
|
||||
|
||||
// placeholder for information about key image that
|
||||
// we will find as ours
|
||||
unique_ptr<info> key_image_info {nullptr};
|
||||
|
||||
// for each found mixin tx, check if any key image
|
||||
// generated using our outputs in the mixin tx
|
||||
// matches the given key image in the current tx
|
||||
for (auto const& txi : indices)
|
||||
{
|
||||
auto const& mixin_tx_hash = txi.first;
|
||||
auto const& output_index_in_tx = txi.second;
|
||||
|
||||
transaction mixin_tx;
|
||||
|
||||
if (!mcore->get_tx(mixin_tx_hash, mixin_tx))
|
||||
{
|
||||
throw std::runtime_error("Cant get tx: "
|
||||
+ pod_to_hex(mixin_tx_hash));
|
||||
}
|
||||
|
||||
// use Output universal identifier to identify our outputs
|
||||
// in a mixin tx
|
||||
auto identifier = make_identifier(
|
||||
mixin_tx,
|
||||
make_unique<Output>(get_address(), get_viewkey()));
|
||||
|
||||
identifier.identify();
|
||||
|
||||
for (auto const& found_output: identifier.get<Output>()->get())
|
||||
{
|
||||
// generate key_image using this output
|
||||
// to check for sure if the given key image is ours
|
||||
// or not
|
||||
crypto::key_image key_img_generated;
|
||||
|
||||
if (!xmreg::generate_key_image(found_output.derivation,
|
||||
found_output.idx_in_tx, /* position in the tx */
|
||||
*spendkey,
|
||||
get_address()->address.m_spend_public_key,
|
||||
key_img_generated))
|
||||
{
|
||||
throw std::runtime_error("Cant generate key image for output: "
|
||||
+ pod_to_hex(found_output.pub_key));
|
||||
}
|
||||
|
||||
// now check if current key image in the tx which we
|
||||
// analyze matches generated key image
|
||||
if (in_key.k_image == key_img_generated)
|
||||
{
|
||||
// this is our key image if they are equal!
|
||||
key_image_info.reset(new info {key_img_generated,
|
||||
found_output.amount,
|
||||
found_output.pub_key});
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
} // auto const& found_output: identifier.get<Output>()->get_outputs()
|
||||
|
||||
// if key_image_info has been populated, there is no
|
||||
// reason to keep check remaning outputs in the mixin tx
|
||||
// instead add its info to identified_inputs and move on
|
||||
// to the next key image
|
||||
if (key_image_info)
|
||||
{
|
||||
identified_inputs.push_back(*key_image_info);
|
||||
total_xmr += key_image_info->amount;
|
||||
break;
|
||||
}
|
||||
|
||||
} // for (auto const& txi : indices)
|
||||
|
||||
} // for (auto i = 0u; i < input_no; ++i)
|
||||
}
|
||||
|
||||
}
|
@ -1,332 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "om_log.h"
|
||||
#include "tools.h"
|
||||
#include "MicroCore.h"
|
||||
|
||||
#include <tuple>
|
||||
#include <utility>
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
using namespace std;
|
||||
|
||||
|
||||
class AbstractIdentifier
|
||||
{
|
||||
public:
|
||||
virtual void identify(transaction const& tx,
|
||||
public_key const& tx_pub_key,
|
||||
vector<public_key> const& additional_tx_pub_keys
|
||||
= vector<public_key>{}) = 0;
|
||||
};
|
||||
|
||||
|
||||
class BaseIdentifier : public AbstractIdentifier
|
||||
{
|
||||
public:
|
||||
BaseIdentifier(
|
||||
address_parse_info const* _address,
|
||||
secret_key const* _viewkey)
|
||||
: address_info {_address}, viewkey {_viewkey}
|
||||
{}
|
||||
|
||||
virtual void identify(transaction const& tx,
|
||||
public_key const& tx_pub_key,
|
||||
vector<public_key> const& additional_tx_pub_keys
|
||||
= vector<public_key>{}) = 0;
|
||||
|
||||
inline auto get_address() const {return address_info;}
|
||||
inline auto get_viewkey() const {return viewkey;}
|
||||
inline auto get_total() const {return total_xmr;}
|
||||
|
||||
virtual ~BaseIdentifier() = default;
|
||||
|
||||
protected:
|
||||
address_parse_info const* address_info {nullptr};
|
||||
secret_key const* viewkey {nullptr};
|
||||
uint64_t total_xmr {0};
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Output class identifies our
|
||||
* outputs in a given tx
|
||||
*/
|
||||
class Output : public BaseIdentifier
|
||||
{
|
||||
public:
|
||||
|
||||
Output(address_parse_info const* _address,
|
||||
secret_key const* _viewkey)
|
||||
: BaseIdentifier(_address, _viewkey)
|
||||
{}
|
||||
|
||||
void identify(transaction const& tx,
|
||||
public_key const& tx_pub_key,
|
||||
vector<public_key> const& additional_tx_pub_keys
|
||||
= vector<public_key>{}) override;
|
||||
|
||||
inline auto get() const
|
||||
{
|
||||
return identified_outputs;
|
||||
}
|
||||
|
||||
struct info
|
||||
{
|
||||
public_key pub_key;
|
||||
uint64_t amount;
|
||||
uint64_t idx_in_tx;
|
||||
key_derivation derivation;
|
||||
rct::key rtc_outpk;
|
||||
rct::key rtc_mask;
|
||||
rct::key rtc_amount;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, info const& _info);
|
||||
};
|
||||
|
||||
protected:
|
||||
|
||||
uint64_t total_received {0};
|
||||
vector<info> identified_outputs;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The Input class identifies our possible
|
||||
* inputs (key images) in a given tx
|
||||
*/
|
||||
class Input : public BaseIdentifier
|
||||
{
|
||||
public:
|
||||
//output_pubk , amount
|
||||
using known_outputs_t = unordered_map<public_key, uint64_t>;
|
||||
|
||||
Input(address_parse_info const* _a,
|
||||
secret_key const* _viewkey,
|
||||
known_outputs_t const* _known_outputs,
|
||||
MicroCore* _mcore)
|
||||
: BaseIdentifier(_a, _viewkey),
|
||||
known_outputs {_known_outputs},
|
||||
mcore {_mcore}
|
||||
{}
|
||||
|
||||
void identify(transaction const& tx,
|
||||
public_key const& tx_pub_key,
|
||||
vector<public_key> const& additional_tx_pub_keys
|
||||
= vector<public_key>{}) override;
|
||||
|
||||
inline auto get() const
|
||||
{
|
||||
return identified_inputs;
|
||||
}
|
||||
|
||||
|
||||
struct info
|
||||
{
|
||||
key_image key_img;
|
||||
uint64_t amount;
|
||||
public_key out_pub_key;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os, info const& _info);
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
secret_key const* viewkey {nullptr};
|
||||
known_outputs_t const* known_outputs {nullptr};
|
||||
MicroCore* mcore {nullptr};
|
||||
vector<info> identified_inputs;
|
||||
};
|
||||
|
||||
/**
|
||||
* Spendkey is optional. But if we have it,
|
||||
* we can for sure determine which key images
|
||||
* are ours or not. This is especially useful
|
||||
* in unit testing, since we can compare wether
|
||||
* guessed key images do contain all our key images
|
||||
*/
|
||||
class RealInput : public Input
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
RealInput(address_parse_info const* _a,
|
||||
secret_key const* _viewkey,
|
||||
secret_key const* _spendkey,
|
||||
MicroCore* _mcore)
|
||||
: Input(_a, _viewkey, nullptr, _mcore),
|
||||
spendkey {_spendkey}
|
||||
{}
|
||||
|
||||
void identify(transaction const& tx,
|
||||
public_key const& tx_pub_key,
|
||||
vector<public_key> const& additional_tx_pub_keys
|
||||
= vector<public_key>{}) override;
|
||||
|
||||
|
||||
protected:
|
||||
secret_key const* spendkey {nullptr};
|
||||
};
|
||||
|
||||
|
||||
template <typename HashT>
|
||||
class PaymentID : public BaseIdentifier
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
PaymentID(address_parse_info const* _address,
|
||||
secret_key const* _viewkey)
|
||||
: BaseIdentifier(_address, _viewkey)
|
||||
{}
|
||||
|
||||
void identify(transaction const& tx,
|
||||
public_key const& tx_pub_key,
|
||||
vector<public_key> const& additional_tx_pub_keys
|
||||
= vector<public_key>{}) override
|
||||
{
|
||||
cout << "PaymentID decryption: "
|
||||
+ pod_to_hex(payment_id) << endl;
|
||||
|
||||
// get payment id. by default we are intrested
|
||||
// in short ids from integrated addresses
|
||||
auto payment_id_tuple = xmreg::get_payment_id(tx);
|
||||
|
||||
payment_id = std::get<HashT>(payment_id_tuple);
|
||||
|
||||
// if no payment_id found, return
|
||||
if (payment_id == null_hash)
|
||||
return;
|
||||
|
||||
// decrypt integrated payment id. if its legacy payment id
|
||||
// nothing will happen.
|
||||
if (!decrypt(payment_id, tx_pub_key))
|
||||
{
|
||||
throw std::runtime_error("Cant decrypt pay_id: "
|
||||
+ pod_to_hex(payment_id));
|
||||
}
|
||||
}
|
||||
|
||||
inline bool
|
||||
decrypt(crypto::hash& p_id,
|
||||
public_key const& tx_pub_key) const
|
||||
{
|
||||
// don't need to do anything for legacy payment ids
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
decrypt(crypto::hash8& p_id,
|
||||
public_key const& tx_pub_key) const
|
||||
{
|
||||
// overload for short payment id,
|
||||
// the we are going to decrypt
|
||||
return xmreg::encrypt_payment_id(
|
||||
p_id, tx_pub_key, *get_viewkey());
|
||||
}
|
||||
|
||||
inline auto get() const {return payment_id;}
|
||||
|
||||
private:
|
||||
HashT payment_id {};
|
||||
HashT null_hash {};
|
||||
};
|
||||
|
||||
using LegacyPaymentID = PaymentID<crypto::hash>;
|
||||
using IntegratedPaymentID = PaymentID<crypto::hash8>;
|
||||
|
||||
|
||||
template<typename... T>
|
||||
class ModularIdentifier
|
||||
{
|
||||
public:
|
||||
tuple<unique_ptr<T>...> identifiers;
|
||||
|
||||
ModularIdentifier(transaction const& _tx,
|
||||
unique_ptr<T>... args)
|
||||
: identifiers {move(args)...},
|
||||
tx {_tx}
|
||||
{
|
||||
// having tx public key is very common for all identifiers
|
||||
// so we can get it here, instead of just obtaining it
|
||||
// for each identifier seprately
|
||||
tx_pub_key = get_tx_pub_key_from_received_outs(tx);
|
||||
|
||||
// multi-output txs can have some additional public keys
|
||||
// in the extra field. So we also get them, just in case
|
||||
additional_tx_pub_keys = get_additional_tx_pub_keys_from_extra(tx);
|
||||
}
|
||||
|
||||
void identify()
|
||||
{
|
||||
auto b = {(std::get<unique_ptr<T>>(
|
||||
identifiers)->identify(
|
||||
tx, tx_pub_key, additional_tx_pub_keys),
|
||||
true)...};
|
||||
(void) b;
|
||||
}
|
||||
|
||||
// overload to get value from tuple by type
|
||||
template <typename U>
|
||||
auto* const get()
|
||||
{
|
||||
return std::get<unique_ptr<U>>(identifiers).get();
|
||||
}
|
||||
|
||||
|
||||
// overload to get value from tuple by number
|
||||
template <size_t No>
|
||||
auto* const get()
|
||||
{
|
||||
return std::get<No>(identifiers).get();
|
||||
}
|
||||
|
||||
inline auto get_tx_pub_key() const {return tx_pub_key;}
|
||||
|
||||
private:
|
||||
transaction const& tx;
|
||||
public_key tx_pub_key;
|
||||
vector<public_key> additional_tx_pub_keys;
|
||||
};
|
||||
|
||||
/**
|
||||
* A helper function to create ModularIdentifier object
|
||||
*/
|
||||
template<typename... T>
|
||||
auto make_identifier(transaction const& tx, T&&... identifiers)
|
||||
{
|
||||
return ModularIdentifier<typename T::element_type...>(
|
||||
tx, std::forward<T>(identifiers)...);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
auto
|
||||
calc_total_xmr(T&& infos)
|
||||
{
|
||||
uint64_t total_xmr {0};
|
||||
|
||||
for (auto const& info: infos)
|
||||
total_xmr += info.amount;
|
||||
|
||||
return total_xmr;
|
||||
}
|
||||
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, xmreg::Output::info const& _info)
|
||||
{
|
||||
return os << _info.idx_in_tx << ", "
|
||||
<< pod_to_hex(_info.pub_key) << ", "
|
||||
<< _info.amount;
|
||||
}
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(std::ostream& os, xmreg::Input::info const& _info)
|
||||
{
|
||||
return os << pod_to_hex(_info.key_img) << ", "
|
||||
<< pod_to_hex(_info.out_pub_key) << ", "
|
||||
<< _info.amount;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,45 +0,0 @@
|
||||
//
|
||||
// Created by mwo on 5/11/15.
|
||||
//
|
||||
|
||||
#ifndef XMREG01_MONERO_HEADERS_H_H
|
||||
#define XMREG01_MONERO_HEADERS_H_H
|
||||
|
||||
#define DB_LMDB 2
|
||||
#define BLOCKCHAIN_DB DB_LMDB
|
||||
|
||||
|
||||
#define UNSIGNED_TX_PREFIX "Monero unsigned tx set\003"
|
||||
#define SIGNED_TX_PREFIX "Monero signed tx set\003"
|
||||
#define KEY_IMAGE_EXPORT_FILE_MAGIC "Monero key image export\002"
|
||||
#define OUTPUT_EXPORT_FILE_MAGIC "Monero output export\003"
|
||||
|
||||
#define FEE_ESTIMATE_GRACE_BLOCKS 10
|
||||
#define RECENT_OUTPUT_ZONE ((time_t)(RECENT_OUTPUT_DAYS * 86400))
|
||||
|
||||
#include "version.h"
|
||||
|
||||
#include "net/http_client.h"
|
||||
#include "storages/http_abstract_invoke.h"
|
||||
|
||||
#include "cryptonote_core/tx_pool.h"
|
||||
#include "cryptonote_core/blockchain.h"
|
||||
#include "blockchain_db/lmdb/db_lmdb.h"
|
||||
|
||||
#include "wallet/wallet2.h"
|
||||
|
||||
#include "serialization/binary_utils.h"
|
||||
|
||||
#include "ringct/rctTypes.h"
|
||||
#include "ringct/rctOps.h"
|
||||
#include "ringct/rctSigs.h"
|
||||
|
||||
#include "easylogging++.h"
|
||||
|
||||
#include "common/base58.h"
|
||||
|
||||
#include "string_coding.h"
|
||||
|
||||
|
||||
#endif //XMREG01_MONERO_HEADERS_H_H
|
||||
|
@ -0,0 +1 @@
|
||||
Subproject commit 2ddec82f0d617eb8860c013eda5011e1428f23ca
|
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue