parent
90cb73f711
commit
001eb33daf
@ -0,0 +1,57 @@
|
||||
//
|
||||
// Created by mwo on 24/05/15.
|
||||
//
|
||||
// source: http://codereview.stackexchange.com/questions/13176/infix-iterator-code
|
||||
|
||||
// infix_iterator.h
|
||||
#if !defined(INFIX_ITERATOR_H_)
|
||||
#define INFIX_ITERATOR_H_
|
||||
#include <ostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
|
||||
template <class T, class charT=char, class traits=std::char_traits<charT> >
|
||||
class infix_ostream_iterator :
|
||||
public std::iterator<std::output_iterator_tag, void, void, void, void>
|
||||
{
|
||||
std::basic_ostream<charT,traits> *os;
|
||||
std::basic_string<charT> delimiter;
|
||||
std::basic_string<charT> real_delim;
|
||||
|
||||
public:
|
||||
|
||||
typedef charT char_type;
|
||||
typedef traits traits_type;
|
||||
typedef std::basic_ostream<charT, traits> ostream_type;
|
||||
|
||||
infix_ostream_iterator(ostream_type &s)
|
||||
: os(&s)
|
||||
{}
|
||||
|
||||
infix_ostream_iterator(ostream_type &s, charT const *d)
|
||||
: os(&s),
|
||||
real_delim(d)
|
||||
{}
|
||||
|
||||
infix_ostream_iterator<T, charT, traits> &operator=(T const &item)
|
||||
{
|
||||
*os << delimiter << item;
|
||||
delimiter = real_delim;
|
||||
return *this;
|
||||
}
|
||||
|
||||
infix_ostream_iterator<T, charT, traits> &operator*() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
infix_ostream_iterator<T, charT, traits> &operator++() {
|
||||
return *this;
|
||||
}
|
||||
|
||||
infix_ostream_iterator<T, charT, traits> &operator++(int) {
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
|
||||
project(myxrm)
|
||||
|
||||
set(SOURCE_FILES
|
||||
MicroCore.cpp
|
||||
tools.cpp
|
||||
CmdLineOptions.cpp)
|
||||
|
||||
# make static library called libmyxrm
|
||||
# that we are going to link to
|
||||
# in the root CMakeLists.txt file
|
||||
add_library(myxrm
|
||||
STATIC
|
||||
${SOURCE_FILES})
|
@ -0,0 +1,82 @@
|
||||
//
|
||||
// Created by mwo on 6/11/15.
|
||||
//
|
||||
|
||||
#include "CmdLineOptions.h"
|
||||
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
/**
|
||||
* Take the acc and *avv[] from the main() and check and parse
|
||||
* all the options given
|
||||
*/
|
||||
CmdLineOptions::CmdLineOptions(int acc, const char *avv[]) {
|
||||
|
||||
positional_options_description p;
|
||||
|
||||
p.add("txhash", -1);
|
||||
|
||||
options_description desc(
|
||||
"xmrblocks, start Onion Monero Blockchain Explorer");
|
||||
|
||||
desc.add_options()
|
||||
("help,h", value<bool>()->default_value(false)->implicit_value(true),
|
||||
"produce help message")
|
||||
("testnet,t", value<bool>()->default_value(false)->implicit_value(true),
|
||||
"use testnet blockchain")
|
||||
("enable-pusher", value<bool>()->default_value(false)->implicit_value(true),
|
||||
"enable pushing signed tx")
|
||||
("port,p", value<string>()->default_value("8081"),
|
||||
"default port")
|
||||
("bc-path,b", value<string>(),
|
||||
"path to lmdb blockchain")
|
||||
("custom-db-path,c", value<string>(),
|
||||
"path to the custom lmdb database used for searching things")
|
||||
("deamon-url,d", value<string>()->default_value("http:://127.0.0.1:18081"),
|
||||
"monero address string");
|
||||
|
||||
|
||||
store(command_line_parser(acc, avv)
|
||||
.options(desc)
|
||||
.positional(p)
|
||||
.run(), vm);
|
||||
|
||||
notify(vm);
|
||||
|
||||
if (vm.count("help"))
|
||||
{
|
||||
if (vm["help"].as<bool>())
|
||||
cout << desc << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the argument passed to the program
|
||||
* in wrapped around boost::optional
|
||||
*/
|
||||
template<typename T>
|
||||
boost::optional<T>
|
||||
CmdLineOptions::get_option(const string & opt_name) const
|
||||
{
|
||||
|
||||
if (!vm.count(opt_name))
|
||||
{
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
return vm[opt_name].as<T>();
|
||||
}
|
||||
|
||||
|
||||
// explicit instantiations of get_option template function
|
||||
template boost::optional<string>
|
||||
CmdLineOptions::get_option<string>(const string & opt_name) const;
|
||||
|
||||
template boost::optional<bool>
|
||||
CmdLineOptions::get_option<bool>(const string & opt_name) const;
|
||||
|
||||
template boost::optional<size_t>
|
||||
CmdLineOptions::get_option<size_t>(const string & opt_name) const;
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
//
|
||||
// Created by mwo on 6/11/15.
|
||||
//
|
||||
|
||||
#ifndef XMREG01_CMDLINEOPTIONS_H
|
||||
#define XMREG01_CMDLINEOPTIONS_H
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
using namespace std;
|
||||
using namespace boost::program_options;
|
||||
|
||||
/**
|
||||
* Manages program options of this example program.
|
||||
*
|
||||
* Basically a wrapper for boost::program_options
|
||||
*/
|
||||
class CmdLineOptions {
|
||||
variables_map vm;
|
||||
|
||||
public:
|
||||
CmdLineOptions(int acc, const char *avv[]);
|
||||
|
||||
template<typename T>
|
||||
boost::optional<T> get_option(const string & opt_name) const;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif //XMREG01_CMDLINEOPTIONS_H
|
@ -0,0 +1,353 @@
|
||||
//
|
||||
// Created by mwo on 5/11/15.
|
||||
//
|
||||
|
||||
#include "MicroCore.h"
|
||||
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
// NOTE: These values should match blockchain.cpp
|
||||
// TODO: Refactor
|
||||
const uint64_t mainnet_hard_fork_version_1_till = 1009826;
|
||||
const uint64_t testnet_hard_fork_version_1_till = 624633;
|
||||
}
|
||||
|
||||
|
||||
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(m_blockchain_storage),
|
||||
m_blockchain_storage(m_mempool)
|
||||
{}
|
||||
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
int db_flags = 0;
|
||||
|
||||
blockchain_path = _blockchain_path;
|
||||
|
||||
//db_flags |= MDB_RDONLY;
|
||||
db_flags |= MDB_NOLOCK;
|
||||
//db_flags |= MDB_SYNC;
|
||||
|
||||
// uint64_t DEFAULT_FLAGS = MDB_NOMETASYNC | MDB_NORDAHEAD;
|
||||
|
||||
//db_flags = DEFAULT_FLAGS;
|
||||
|
||||
HardFork* m_hardfork = nullptr;
|
||||
|
||||
BlockchainDB* db = nullptr;
|
||||
db = new BlockchainLMDB();
|
||||
|
||||
bool use_testnet {false};
|
||||
|
||||
uint64_t hard_fork_version_1_till = use_testnet ? testnet_hard_fork_version_1_till : mainnet_hard_fork_version_1_till;
|
||||
|
||||
m_hardfork = new HardFork(*db, 1, hard_fork_version_1_till);
|
||||
|
||||
try
|
||||
{
|
||||
// try opening lmdb database files
|
||||
db->open(blockchain_path, db_flags);
|
||||
}
|
||||
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.
|
||||
return m_blockchain_storage.init(db, m_hardfork, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get m_blockchain_storage.
|
||||
* Initialize m_blockchain_storage with the BlockchainLMDB object.
|
||||
*/
|
||||
Blockchain&
|
||||
MicroCore::get_core()
|
||||
{
|
||||
return m_blockchain_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get block by its height
|
||||
*
|
||||
* returns true if success
|
||||
*/
|
||||
bool
|
||||
MicroCore::get_block_by_height(const uint64_t& height, block& blk)
|
||||
{
|
||||
|
||||
crypto::hash block_id;
|
||||
|
||||
try
|
||||
{
|
||||
block_id = m_blockchain_storage.get_block_id_by_height(height);
|
||||
}
|
||||
catch (const exception& e)
|
||||
{
|
||||
cerr << e.what() << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!m_blockchain_storage.get_block_by_hash(block_id, blk))
|
||||
{
|
||||
cerr << "Block with hash " << block_id
|
||||
<< "and height " << height << " not found!"
|
||||
<< endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get transaction tx from the blockchain using it hash
|
||||
*/
|
||||
bool
|
||||
MicroCore::get_tx(const crypto::hash& tx_hash, transaction& tx)
|
||||
{
|
||||
if (m_blockchain_storage.have_tx(tx_hash))
|
||||
{
|
||||
// get transaction with given hash
|
||||
tx = m_blockchain_storage.get_db().get_tx(tx_hash);
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "MicroCore::get_tx tx does not exist in blockchain: " << tx_hash << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
MicroCore::get_tx(const string& tx_hash_str, transaction& tx)
|
||||
{
|
||||
|
||||
// parse tx hash string to hash object
|
||||
crypto::hash tx_hash;
|
||||
|
||||
if (!xmreg::parse_str_secret_key(tx_hash_str, tx_hash))
|
||||
{
|
||||
cerr << "Cant parse tx hash: " << tx_hash_str << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!get_tx(tx_hash, tx))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Find output with given public key in a given transaction
|
||||
*/
|
||||
bool
|
||||
MicroCore::find_output_in_tx(const transaction& tx,
|
||||
const public_key& output_pubkey,
|
||||
tx_out& out,
|
||||
size_t& output_index)
|
||||
{
|
||||
|
||||
size_t idx {0};
|
||||
|
||||
|
||||
// search in the ouputs for an output which
|
||||
// public key matches to what we want
|
||||
auto it = std::find_if(tx.vout.begin(), tx.vout.end(),
|
||||
[&](const tx_out& o)
|
||||
{
|
||||
const txout_to_key& tx_in_to_key
|
||||
= boost::get<txout_to_key>(o.target);
|
||||
|
||||
++idx;
|
||||
|
||||
return tx_in_to_key.key == output_pubkey;
|
||||
});
|
||||
|
||||
if (it != tx.vout.end())
|
||||
{
|
||||
// we found the desired public key
|
||||
out = *it;
|
||||
output_index = idx > 0 ? idx - 1 : idx;
|
||||
|
||||
//cout << idx << " " << output_index << endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns tx hash in a given block which
|
||||
* contains given output's public key
|
||||
*/
|
||||
bool
|
||||
MicroCore::get_tx_hash_from_output_pubkey(const public_key& output_pubkey,
|
||||
const uint64_t& block_height,
|
||||
crypto::hash& tx_hash,
|
||||
cryptonote::transaction& tx_found)
|
||||
{
|
||||
|
||||
tx_hash = null_hash;
|
||||
|
||||
// get block of given height
|
||||
block blk;
|
||||
if (!get_block_by_height(block_height, blk))
|
||||
{
|
||||
cerr << "Cant get block of height: " << block_height << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// get all transactions in the block found
|
||||
// initialize the first list with transaction for solving
|
||||
// the block i.e. coinbase.
|
||||
list<transaction> txs {blk.miner_tx};
|
||||
list<crypto::hash> missed_txs;
|
||||
|
||||
if (!m_blockchain_storage.get_transactions(blk.tx_hashes, txs, missed_txs))
|
||||
{
|
||||
cerr << "Cant find transcations in block: " << block_height << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!missed_txs.empty())
|
||||
{
|
||||
cerr << "Transactions not found in blk: " << block_height << endl;
|
||||
|
||||
for (const crypto::hash& h : missed_txs)
|
||||
{
|
||||
cerr << " - tx hash: " << h << endl;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// search outputs in each transactions
|
||||
// until output with pubkey of interest is found
|
||||
for (const transaction& tx : txs)
|
||||
{
|
||||
|
||||
tx_out found_out;
|
||||
|
||||
// we dont need here output_index
|
||||
size_t output_index;
|
||||
|
||||
if (find_output_in_tx(tx, output_pubkey, found_out, output_index))
|
||||
{
|
||||
// we found the desired public key
|
||||
tx_hash = get_transaction_hash(tx);
|
||||
tx_found = tx;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
uint64_t
|
||||
MicroCore::get_blk_timestamp(uint64_t blk_height)
|
||||
{
|
||||
cryptonote::block blk;
|
||||
|
||||
if (!get_block_by_height(blk_height, blk))
|
||||
{
|
||||
cerr << "Cant get block by height: " << blk_height << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return blk.timestamp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* De-initialized Blockchain.
|
||||
*
|
||||
* since blockchain is opened as MDB_RDONLY
|
||||
* need to manually free memory taken on heap
|
||||
* by BlockchainLMDB
|
||||
*/
|
||||
MicroCore::~MicroCore()
|
||||
{
|
||||
delete &m_blockchain_storage.get_db();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
init_blockchain(const string& path,
|
||||
MicroCore& mcore,
|
||||
Blockchain*& core_storage)
|
||||
{
|
||||
|
||||
// initialize the core using the blockchain path
|
||||
if (!mcore.init(path))
|
||||
{
|
||||
cerr << "Error accessing blockchain." << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// get the high level Blockchain object to interact
|
||||
// with the blockchain lmdb database
|
||||
core_storage = &(mcore.get_core());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
string
|
||||
MicroCore::get_blkchain_path()
|
||||
{
|
||||
return blockchain_path;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
//
|
||||
// Created by mwo on 5/11/15.
|
||||
//
|
||||
|
||||
#ifndef XMREG01_MICROCORE_H
|
||||
#define XMREG01_MICROCORE_H
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#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 m_blockchain_storage;
|
||||
|
||||
public:
|
||||
MicroCore();
|
||||
|
||||
bool
|
||||
init(const string& _blockchain_path);
|
||||
|
||||
Blockchain&
|
||||
get_core();
|
||||
|
||||
bool
|
||||
get_block_by_height(const uint64_t& height, block& blk);
|
||||
|
||||
bool
|
||||
get_tx(const crypto::hash& tx_hash, transaction& tx);
|
||||
|
||||
bool
|
||||
get_tx(const string& tx_hash, transaction& tx);
|
||||
|
||||
bool
|
||||
find_output_in_tx(const transaction& tx,
|
||||
const public_key& output_pubkey,
|
||||
tx_out& out,
|
||||
size_t& output_index);
|
||||
|
||||
bool
|
||||
get_tx_hash_from_output_pubkey(const public_key& output_pubkey,
|
||||
const uint64_t& block_height,
|
||||
crypto::hash& tx_hash,
|
||||
transaction& tx_found);
|
||||
|
||||
uint64_t
|
||||
get_blk_timestamp(uint64_t blk_height);
|
||||
|
||||
string
|
||||
get_blkchain_path();
|
||||
|
||||
|
||||
virtual ~MicroCore();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
bool
|
||||
init_blockchain(const string& path,
|
||||
MicroCore& mcore,
|
||||
Blockchain*& core_storage);
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //XMREG01_MICROCORE_H
|
@ -0,0 +1,215 @@
|
||||
//
|
||||
// Created by mwo on 8/12/16.
|
||||
//
|
||||
|
||||
#ifndef RESTBED_XMR_YOURMONEROREQUESTS_H
|
||||
#define RESTBED_XMR_YOURMONEROREQUESTS_H
|
||||
|
||||
#include <iostream>
|
||||
#include <functional>
|
||||
|
||||
#include "tools.h"
|
||||
|
||||
#include "../ext/restbed/source/restbed"
|
||||
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
using namespace std;
|
||||
using namespace restbed;
|
||||
using namespace nlohmann;
|
||||
|
||||
|
||||
string
|
||||
get_current_time(const char* format = "%a, %d %b %Y %H:%M:%S %Z")
|
||||
{
|
||||
|
||||
auto current_time = date::make_zoned(
|
||||
date::current_zone(),
|
||||
date::floor<chrono::seconds>(std::chrono::system_clock::now())
|
||||
);
|
||||
|
||||
return date::format(format, current_time);
|
||||
}
|
||||
|
||||
|
||||
multimap<string, string>
|
||||
make_headers(const multimap<string, string>& extra_headers = multimap<string, string>())
|
||||
{
|
||||
multimap<string, string> headers {
|
||||
{"Date", get_current_time()},
|
||||
{"Access-Control-Allow-Origin", "http://127.0.0.1"},
|
||||
{"access-control-allow-headers", "*, DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Set-Cookie"},
|
||||
{"access-control-max-age", "86400, 1728000"},
|
||||
{"access-control-allow-methods", "GET, POST, OPTIONS"},
|
||||
{"access-control-allow-credentials", "true"},
|
||||
{"Content-Type", "application/json"}
|
||||
};
|
||||
|
||||
headers.insert(extra_headers.begin(), extra_headers.end());
|
||||
|
||||
return headers;
|
||||
};
|
||||
|
||||
struct handel_
|
||||
{
|
||||
|
||||
using fetch_func_t = function< void ( const shared_ptr< Session >, const Bytes& ) >;
|
||||
|
||||
fetch_func_t request_callback;
|
||||
|
||||
handel_(const fetch_func_t& callback):
|
||||
request_callback {callback}
|
||||
{}
|
||||
|
||||
|
||||
void operator()(const shared_ptr< Session > session)
|
||||
{
|
||||
const auto request = session->get_request( );
|
||||
|
||||
size_t content_length = request->get_header( "Content-Length", 0);
|
||||
|
||||
cout << "post_get_address_info_handler" << endl;
|
||||
|
||||
session->fetch(content_length, this->request_callback);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
class YourMoneroRequests
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
static bool show_logs;
|
||||
|
||||
YourMoneroRequests()
|
||||
{}
|
||||
|
||||
void
|
||||
login(const shared_ptr< Session > session, const Bytes & body)
|
||||
{
|
||||
json j_request = body_to_json(body);
|
||||
|
||||
if (show_logs)
|
||||
print_json_log("login request: ", j_request);
|
||||
|
||||
json j_response {{"new_address", true}};
|
||||
|
||||
string response_body = j_response.dump();
|
||||
|
||||
auto response_headers = make_headers({{ "Content-Length", to_string(response_body.size())}});
|
||||
|
||||
session->close( OK, response_body, response_headers);
|
||||
}
|
||||
|
||||
void
|
||||
get_address_txs(const shared_ptr< Session > session, const Bytes & body)
|
||||
{
|
||||
json j_request = body_to_json(body);
|
||||
|
||||
if (show_logs)
|
||||
print_json_log("get_address_txs request: ", j_request);
|
||||
|
||||
json j_response {
|
||||
{ "total_received", "0"},
|
||||
{ "scanned_height", 2012455},
|
||||
{ "scanned_block_height", 1195848},
|
||||
{ "start_height", 2012455},
|
||||
{ "transaction_height", 2012455},
|
||||
{ "blockchain_height", 1195848}
|
||||
};
|
||||
|
||||
string response_body = j_response.dump();
|
||||
|
||||
auto response_headers = make_headers({{ "Content-Length", to_string(response_body.size())}});
|
||||
|
||||
session->close( OK, response_body, response_headers);
|
||||
}
|
||||
|
||||
void
|
||||
get_address_info(const shared_ptr< Session > session, const Bytes & body)
|
||||
{
|
||||
json j_request = body_to_json(body);
|
||||
|
||||
if (show_logs)
|
||||
print_json_log("get_address_info request: ", j_request);
|
||||
|
||||
json j_response {
|
||||
{"locked_funds", "0"},
|
||||
{"total_received", "0"},
|
||||
{"total_sent", "0"},
|
||||
{"scanned_height", 2012470},
|
||||
{"scanned_block_height", 1195850},
|
||||
{"start_height", 2012470},
|
||||
{"transaction_height", 2012470},
|
||||
{"blockchain_height", 1195850},
|
||||
{"spent_outputs", nullptr}
|
||||
};
|
||||
|
||||
string response_body = j_response.dump();
|
||||
|
||||
auto response_headers = make_headers({{ "Content-Length", to_string(response_body.size())}});
|
||||
|
||||
session->close( OK, response_body, response_headers);
|
||||
}
|
||||
|
||||
shared_ptr<Resource>
|
||||
make_resource(function< void (YourMoneroRequests&, const shared_ptr< Session >, const Bytes& ) > handle_func,
|
||||
const string& path)
|
||||
{
|
||||
auto a_request = std::bind(handle_func, *this, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
shared_ptr<Resource> resource_ptr = make_shared<Resource>();
|
||||
|
||||
resource_ptr->set_path(path);
|
||||
resource_ptr->set_method_handler( "OPTIONS", generic_options_handler);
|
||||
resource_ptr->set_method_handler( "POST" , handel_(a_request) );
|
||||
|
||||
return resource_ptr;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
generic_options_handler( const shared_ptr< Session > session )
|
||||
{
|
||||
const auto request = session->get_request( );
|
||||
|
||||
size_t content_length = request->get_header( "Content-Length", 0);
|
||||
|
||||
//cout << "generic_options_handler" << endl;
|
||||
|
||||
session->fetch(content_length, [](const shared_ptr< Session > session, const Bytes & body)
|
||||
{
|
||||
session->close( OK, string{}, make_headers());
|
||||
});
|
||||
}
|
||||
|
||||
static void
|
||||
print_json_log(const string& text, const json& j)
|
||||
{
|
||||
cout << text << '\n' << j.dump(4) << endl;
|
||||
}
|
||||
|
||||
|
||||
static inline string
|
||||
body_to_string(const Bytes & body)
|
||||
{
|
||||
return string(reinterpret_cast<const char *>(body.data()), body.size());
|
||||
}
|
||||
|
||||
static inline json
|
||||
body_to_json(const Bytes & body)
|
||||
{
|
||||
json j = json::parse(body_to_string(body));
|
||||
return j;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
bool YourMoneroRequests::show_logs = false;
|
||||
|
||||
}
|
||||
#endif //RESTBED_XMR_YOURMONEROREQUESTS_H
|
@ -0,0 +1,42 @@
|
||||
//
|
||||
// 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\002"
|
||||
#define SIGNED_TX_PREFIX "Monero signed tx set\002"
|
||||
#define KEY_IMAGE_EXPORT_FILE_MAGIC "Monero key image export\002"
|
||||
#define OUTPUT_EXPORT_FILE_MAGIC "Monero output export\002"
|
||||
|
||||
|
||||
#include "net/http_base.h"
|
||||
#include "net/http_server_handlers_map2.h"
|
||||
#include "net/http_client.h"
|
||||
#include "storages/http_abstract_invoke.h"
|
||||
|
||||
#include "cryptonote_core/cryptonote_basic.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 "common/base58.h"
|
||||
|
||||
#include "string_coding.h"
|
||||
|
||||
|
||||
#endif //XMREG01_MONERO_HEADERS_H_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,283 @@
|
||||
//
|
||||
// Created by mwo on 5/11/15.
|
||||
//
|
||||
|
||||
#ifndef XMREG01_TOOLS_H
|
||||
#define XMREG01_TOOLS_H
|
||||
|
||||
#define PATH_SEPARARTOR '/'
|
||||
|
||||
#define XMR_AMOUNT(value) \
|
||||
static_cast<double>(value) / 1e12
|
||||
|
||||
#define REMOVE_HASH_BRAKETS(a_hash) \
|
||||
a_hash.substr(1, a_hash.size()-2)
|
||||
|
||||
#include "monero_headers.h"
|
||||
|
||||
#include "../ext/infix_iterator.h"
|
||||
#include "../ext/date/tz.h"
|
||||
#include "../ext/format.h"
|
||||
#include "../ext/json.hpp"
|
||||
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/date_time/posix_time/posix_time.hpp>
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <array>
|
||||
|
||||
/**
|
||||
* Some helper functions that might or might not be useful in this project.
|
||||
* Names are rather self-explanatory, so I think
|
||||
* there is no reason for any detailed explanations here
|
||||
*/
|
||||
namespace xmreg
|
||||
{
|
||||
|
||||
using namespace cryptonote;
|
||||
using namespace crypto;
|
||||
using namespace std;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
namespace pt = boost::posix_time;
|
||||
namespace gt = boost::gregorian;
|
||||
namespace lt = boost::local_time;
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
parse_str_secret_key(const string& key_str, T& secret_key);
|
||||
|
||||
|
||||
bool
|
||||
get_tx_pub_key_from_str_hash(Blockchain& core_storage,
|
||||
const string& hash_str,
|
||||
transaction& tx);
|
||||
|
||||
bool
|
||||
parse_str_address(const string& address_str,
|
||||
account_public_address& address,
|
||||
bool testnet = false);
|
||||
|
||||
inline bool
|
||||
is_separator(char c);
|
||||
|
||||
string
|
||||
print_address(const account_public_address& address,
|
||||
bool testnet = false);
|
||||
|
||||
string
|
||||
print_sig (const signature& sig);
|
||||
|
||||
string
|
||||
remove_trailing_path_separator(const string& in_path);
|
||||
|
||||
bf::path
|
||||
remove_trailing_path_separator(const bf::path& in_path);
|
||||
|
||||
string
|
||||
timestamp_to_str(time_t timestamp, const char* format = "%F %T");
|
||||
|
||||
string
|
||||
timestamp_to_str_local(time_t timestamp, const char* format = "%F %T");
|
||||
|
||||
ostream&
|
||||
operator<< (ostream& os, const account_public_address& addr);
|
||||
|
||||
|
||||
string
|
||||
get_default_lmdb_folder(bool testnet = false);
|
||||
|
||||
bool
|
||||
generate_key_image(const crypto::key_derivation& derivation,
|
||||
const std::size_t output_index,
|
||||
const crypto::secret_key& sec_key,
|
||||
const crypto::public_key& pub_key,
|
||||
crypto::key_image& key_img);
|
||||
|
||||
bool
|
||||
get_blockchain_path(const boost::optional<string>& bc_path,
|
||||
bf::path& blockchain_path,
|
||||
bool testnet = false);
|
||||
|
||||
uint64_t
|
||||
sum_money_in_outputs(const transaction& tx);
|
||||
|
||||
pair<uint64_t, uint64_t>
|
||||
sum_money_in_outputs(const string& json_str);
|
||||
|
||||
uint64_t
|
||||
sum_money_in_inputs(const transaction& tx);
|
||||
|
||||
pair<uint64_t, uint64_t>
|
||||
sum_money_in_inputs(const string& json_str);
|
||||
|
||||
array<uint64_t, 2>
|
||||
sum_money_in_tx(const transaction& tx);
|
||||
|
||||
array<uint64_t, 2>
|
||||
sum_money_in_txs(const vector<transaction>& txs);
|
||||
|
||||
uint64_t
|
||||
sum_fees_in_txs(const vector<transaction>& txs);
|
||||
|
||||
uint64_t
|
||||
get_mixin_no(const transaction& tx);
|
||||
|
||||
vector<uint64_t>
|
||||
get_mixin_no(const string& json_str);
|
||||
|
||||
vector<uint64_t>
|
||||
get_mixin_no_in_txs(const vector<transaction>& txs);
|
||||
|
||||
vector<pair<txout_to_key, uint64_t>>
|
||||
get_ouputs(const transaction& tx);
|
||||
|
||||
vector<tuple<txout_to_key, uint64_t, uint64_t>>
|
||||
get_ouputs_tuple(const transaction& tx);
|
||||
|
||||
vector<txin_to_key>
|
||||
get_key_images(const transaction& tx);
|
||||
|
||||
|
||||
bool
|
||||
get_payment_id(const vector<uint8_t>& extra,
|
||||
crypto::hash& payment_id,
|
||||
crypto::hash8& payment_id8);
|
||||
|
||||
bool
|
||||
get_payment_id(const transaction& tx,
|
||||
crypto::hash& payment_id,
|
||||
crypto::hash8& payment_id8);
|
||||
|
||||
|
||||
inline void
|
||||
enable_monero_log() {
|
||||
uint32_t log_level = 0;
|
||||
epee::log_space::get_set_log_detalisation_level(true, log_level);
|
||||
epee::log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
inline double
|
||||
get_xmr(uint64_t core_amount)
|
||||
{
|
||||
return static_cast<double>(core_amount) / 1e12;
|
||||
}
|
||||
|
||||
array<size_t, 5>
|
||||
timestamp_difference(uint64_t t1, uint64_t t2);
|
||||
|
||||
string
|
||||
read(string filename);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* prints an iterable such as vector
|
||||
*/
|
||||
template<typename T>
|
||||
void print_iterable(const T & elems) {
|
||||
|
||||
infix_ostream_iterator<typename T::value_type>
|
||||
oiter(std::cout, ",");
|
||||
|
||||
std::cout << "[";
|
||||
std::copy(elems.begin(), elems.end(),oiter);
|
||||
std::cout << "]" << std::endl;
|
||||
}
|
||||
|
||||
pair<string, double>
|
||||
timestamps_time_scale(const vector<uint64_t>& timestamps,
|
||||
uint64_t timeN, uint64_t resolution = 80,
|
||||
uint64_t time0 = 1397818193 /* timestamp of the second block */);
|
||||
|
||||
|
||||
time_t
|
||||
ptime_to_time_t(const pt::ptime& in_ptime);
|
||||
|
||||
bool
|
||||
decode_ringct(const rct::rctSig & rv,
|
||||
const crypto::public_key pub,
|
||||
const crypto::secret_key &sec,
|
||||
unsigned int i,
|
||||
rct::key & mask,
|
||||
uint64_t & amount);
|
||||
|
||||
bool
|
||||
url_decode(const std::string& in, std::string& out);
|
||||
|
||||
map<std::string, std::string>
|
||||
parse_crow_post_data(const string& req_body);
|
||||
|
||||
// from wallet2::decrypt
|
||||
string
|
||||
decrypt(const std::string &ciphertext,
|
||||
const crypto::secret_key &skey,
|
||||
bool authenticated = true);
|
||||
|
||||
// based on
|
||||
// crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::wallet2::transfer_details &td) const
|
||||
public_key
|
||||
get_tx_pub_key_from_received_outs(const transaction &tx);
|
||||
|
||||
date::sys_seconds
|
||||
parse(const std::string& str, string format="%Y-%m-%d %H:%M:%S");
|
||||
|
||||
static
|
||||
string
|
||||
xmr_amount_to_str(const uint64_t& xmr_amount, string format="{:0.12f}")
|
||||
{
|
||||
return fmt::format("{:0.12f}", XMR_AMOUNT(xmr_amount));
|
||||
}
|
||||
|
||||
bool
|
||||
is_output_ours(const size_t& output_index,
|
||||
const transaction& tx,
|
||||
const public_key& pub_tx_key,
|
||||
const secret_key& private_view_key,
|
||||
const public_key& public_spend_key);
|
||||
|
||||
bool
|
||||
get_real_output_for_key_image(const key_image& ki,
|
||||
const transaction& tx,
|
||||
const secret_key& private_view_key,
|
||||
const public_key& public_spend_key,
|
||||
uint64_t output_idx,
|
||||
public_key output_pub_key);
|
||||
|
||||
// based on http://stackoverflow.com/a/9943098/248823
|
||||
template<typename Iterator, typename Func>
|
||||
void chunks(Iterator begin,
|
||||
Iterator end,
|
||||
iterator_traits<string::iterator>::difference_type k,
|
||||
Func f)
|
||||
{
|
||||
Iterator chunk_begin;
|
||||
Iterator chunk_end;
|
||||
chunk_end = chunk_begin = begin;
|
||||
|
||||
do
|
||||
{
|
||||
if(std::distance(chunk_end, end) < k)
|
||||
chunk_end = end;
|
||||
else
|
||||
std::advance(chunk_end, k);
|
||||
f(chunk_begin,chunk_end);
|
||||
chunk_begin = chunk_end;
|
||||
}
|
||||
while(std::distance(chunk_begin,end) > 0);
|
||||
}
|
||||
|
||||
bool
|
||||
make_tx_from_json(const string& json_str, transaction& tx);
|
||||
|
||||
}
|
||||
|
||||
#endif //XMREG01_TOOLS_H
|
Loading…
Reference in new issue