commit
a3bef31ed6
|
@ -8,3 +8,4 @@
|
||||||
tests/
|
tests/
|
||||||
build/
|
build/
|
||||||
cmake-build-debug/
|
cmake-build-debug/
|
||||||
|
.ycm_extra_conf.py
|
||||||
|
|
29
README.md
29
README.md
|
@ -94,30 +94,17 @@ Note: `devel` branch of the explorer follows `master` branch of the monero.
|
||||||
|
|
||||||
## Compilation on Ubuntu 16.04/18.04
|
## Compilation on Ubuntu 16.04/18.04
|
||||||
|
|
||||||
##### Compile latest Monero version (0.14.0.0)
|
|
||||||
|
|
||||||
Download and compile recent Monero into your home folder:
|
#### Monero download and compilation
|
||||||
|
|
||||||
```bash
|
To download and compile recent Monero follow instructions
|
||||||
# first install monero dependecines
|
in the following link:
|
||||||
sudo apt update
|
|
||||||
|
|
||||||
sudo apt install git build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libcurl4-openssl-dev libgtest-dev libreadline-dev libzmq3-dev libsodium-dev libhidapi-dev libhidapi-libusb0
|
https://github.com/moneroexamples/monero-compilation/blob/master/README.md
|
||||||
|
|
||||||
# go to home folder
|
|
||||||
cd ~
|
|
||||||
|
|
||||||
# download monero sourced for branch release-v0.13
|
|
||||||
git clone --recursive -b release-v0.13 https://github.com/monero-project/monero.git
|
|
||||||
|
|
||||||
cd monero/
|
|
||||||
|
|
||||||
USE_SINGLE_BUILDDIR=1 make
|
|
||||||
```
|
|
||||||
|
|
||||||
##### Compile and run the explorer
|
##### Compile and run the explorer
|
||||||
|
|
||||||
Once the Monero is compiles, the explorer can be downloaded and compiled
|
Once the Monero compiles, the explorer can be downloaded and compiled
|
||||||
as follows:
|
as follows:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
|
@ -136,12 +123,6 @@ mkdir build && cd build
|
||||||
# create the makefile
|
# create the makefile
|
||||||
cmake ..
|
cmake ..
|
||||||
|
|
||||||
# altearnatively can use: cmake -DMONERO_DIR=/path/to/monero_folder ..
|
|
||||||
# if monero is not in ~/monero
|
|
||||||
#
|
|
||||||
# also can build with ASAN (sanitizers), for example
|
|
||||||
# cmake -DSANITIZE_ADDRESS=On ..
|
|
||||||
|
|
||||||
# compile
|
# compile
|
||||||
make
|
make
|
||||||
```
|
```
|
||||||
|
|
143
main.cpp
143
main.cpp
|
@ -17,7 +17,16 @@ using namespace std;
|
||||||
|
|
||||||
namespace myxmr
|
namespace myxmr
|
||||||
{
|
{
|
||||||
struct jsonresponse: crow::response
|
struct htmlresponse: public crow::response
|
||||||
|
{
|
||||||
|
htmlresponse(string&& _body)
|
||||||
|
: crow::response {std::move(_body)}
|
||||||
|
{
|
||||||
|
add_header("Content-Type", "text/html; charset=utf-8");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct jsonresponse: public crow::response
|
||||||
{
|
{
|
||||||
jsonresponse(const nlohmann::json& _body)
|
jsonresponse(const nlohmann::json& _body)
|
||||||
: crow::response {_body.dump()}
|
: crow::response {_body.dump()}
|
||||||
|
@ -66,6 +75,7 @@ main(int ac, const char* av[])
|
||||||
auto enable_json_api_opt = opts.get_option<bool>("enable-json-api");
|
auto enable_json_api_opt = opts.get_option<bool>("enable-json-api");
|
||||||
auto enable_as_hex_opt = opts.get_option<bool>("enable-as-hex");
|
auto enable_as_hex_opt = opts.get_option<bool>("enable-as-hex");
|
||||||
auto enable_tx_cache_opt = opts.get_option<bool>("enable-tx-cache");
|
auto enable_tx_cache_opt = opts.get_option<bool>("enable-tx-cache");
|
||||||
|
auto concurrency_opt = opts.get_option<size_t>("concurrency");
|
||||||
auto enable_block_cache_opt = opts.get_option<bool>("enable-block-cache");
|
auto enable_block_cache_opt = opts.get_option<bool>("enable-block-cache");
|
||||||
auto show_cache_times_opt = opts.get_option<bool>("show-cache-times");
|
auto show_cache_times_opt = opts.get_option<bool>("show-cache-times");
|
||||||
auto enable_emission_monitor_opt = opts.get_option<bool>("enable-emission-monitor");
|
auto enable_emission_monitor_opt = opts.get_option<bool>("enable-emission-monitor");
|
||||||
|
@ -182,12 +192,13 @@ main(int ac, const char* av[])
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
mempool_info_timeout = boost::lexical_cast<uint64_t>(*mempool_info_timeout_opt);
|
mempool_info_timeout = boost::lexical_cast<uint64_t>(
|
||||||
|
*mempool_info_timeout_opt);
|
||||||
}
|
}
|
||||||
catch (boost::bad_lexical_cast &e)
|
catch (boost::bad_lexical_cast &e)
|
||||||
{
|
{
|
||||||
cout << "Cant cast " << (*mempool_info_timeout_opt) <<" into numbers. Using default values."
|
cout << "Cant cast " << (*mempool_info_timeout_opt)
|
||||||
<< endl;
|
<<" into numbers. Using default values.\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t mempool_refresh_time {10};
|
uint64_t mempool_refresh_time {10};
|
||||||
|
@ -291,59 +302,68 @@ main(int ac, const char* av[])
|
||||||
|
|
||||||
CROW_ROUTE(app, "/")
|
CROW_ROUTE(app, "/")
|
||||||
([&]() {
|
([&]() {
|
||||||
return crow::response(xmrblocks.index2());
|
return myxmr::htmlresponse(xmrblocks.index2());
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/page/<uint>")
|
CROW_ROUTE(app, "/page/<uint>")
|
||||||
([&](size_t page_no) {
|
([&](size_t page_no) {
|
||||||
return xmrblocks.index2(page_no);
|
return myxmr::htmlresponse(xmrblocks.index2(page_no));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/block/<uint>")
|
CROW_ROUTE(app, "/block/<uint>")
|
||||||
([&](size_t block_height) {
|
([&](size_t block_height) {
|
||||||
return crow::response(xmrblocks.show_block(block_height));
|
return myxmr::htmlresponse(xmrblocks.show_block(block_height));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/block/<string>")
|
CROW_ROUTE(app, "/block/<string>")
|
||||||
([&](string block_hash) {
|
([&](string block_hash) {
|
||||||
return crow::response(xmrblocks.show_block(remove_bad_chars(block_hash)));
|
return myxmr::htmlresponse(
|
||||||
|
xmrblocks.show_block(remove_bad_chars(block_hash)));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/tx/<string>")
|
CROW_ROUTE(app, "/tx/<string>")
|
||||||
([&](string tx_hash) {
|
([&](string tx_hash) {
|
||||||
return crow::response(xmrblocks.show_tx(remove_bad_chars(tx_hash)));
|
return myxmr::htmlresponse(
|
||||||
|
xmrblocks.show_tx(remove_bad_chars(tx_hash)));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (enable_as_hex)
|
if (enable_as_hex)
|
||||||
{
|
{
|
||||||
CROW_ROUTE(app, "/txhex/<string>")
|
CROW_ROUTE(app, "/txhex/<string>")
|
||||||
([&](string tx_hash) {
|
([&](string tx_hash) {
|
||||||
return crow::response(xmrblocks.show_tx_hex(remove_bad_chars(tx_hash)));
|
return crow::response(
|
||||||
|
xmrblocks.show_tx_hex(remove_bad_chars(tx_hash)));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/ringmembershex/<string>")
|
CROW_ROUTE(app, "/ringmembershex/<string>")
|
||||||
([&](string tx_hash) {
|
([&](string tx_hash) {
|
||||||
return crow::response(xmrblocks.show_ringmembers_hex(remove_bad_chars(tx_hash)));
|
return crow::response(
|
||||||
|
xmrblocks.show_ringmembers_hex(remove_bad_chars(tx_hash)));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/blockhex/<uint>")
|
CROW_ROUTE(app, "/blockhex/<uint>")
|
||||||
([&](size_t block_height) {
|
([&](size_t block_height) {
|
||||||
return crow::response(xmrblocks.show_block_hex(block_height, false));
|
return crow::response(
|
||||||
|
xmrblocks.show_block_hex(block_height, false));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/blockhexcomplete/<uint>")
|
CROW_ROUTE(app, "/blockhexcomplete/<uint>")
|
||||||
([&](size_t block_height) {
|
([&](size_t block_height) {
|
||||||
return crow::response(xmrblocks.show_block_hex(block_height, true));
|
return crow::response(
|
||||||
|
xmrblocks.show_block_hex(block_height, true));
|
||||||
});
|
});
|
||||||
|
|
||||||
// CROW_ROUTE(app, "/ringmemberstxhex/<string>")
|
// CROW_ROUTE(app, "/ringmemberstxhex/<string>")
|
||||||
// ([&](string tx_hash) {
|
// ([&](string tx_hash) {
|
||||||
// return crow::response(xmrblocks.show_ringmemberstx_hex(remove_bad_chars(tx_hash)));
|
// return crow::response(
|
||||||
|
// xmrblocks.show_ringmemberstx_hex(remove_bad_chars(tx_hash)));
|
||||||
// });
|
// });
|
||||||
|
|
||||||
CROW_ROUTE(app, "/ringmemberstxhex/<string>")
|
CROW_ROUTE(app, "/ringmemberstxhex/<string>")
|
||||||
([&](string tx_hash) {
|
([&](string tx_hash) {
|
||||||
return myxmr::jsonresponse {xmrblocks.show_ringmemberstx_jsonhex(remove_bad_chars(tx_hash))};
|
return myxmr::jsonresponse {
|
||||||
|
xmrblocks.show_ringmemberstx_jsonhex(
|
||||||
|
remove_bad_chars(tx_hash))};
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -351,11 +371,13 @@ main(int ac, const char* av[])
|
||||||
CROW_ROUTE(app, "/tx/<string>/<uint>")
|
CROW_ROUTE(app, "/tx/<string>/<uint>")
|
||||||
([&](string tx_hash, uint16_t with_ring_signatures)
|
([&](string tx_hash, uint16_t with_ring_signatures)
|
||||||
{
|
{
|
||||||
return xmrblocks.show_tx(remove_bad_chars(tx_hash), with_ring_signatures);
|
return myxmr::htmlresponse(
|
||||||
|
xmrblocks.show_tx(remove_bad_chars(tx_hash),
|
||||||
|
with_ring_signatures));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/myoutputs").methods("POST"_method)
|
CROW_ROUTE(app, "/myoutputs").methods("POST"_method)
|
||||||
([&](const crow::request& req)
|
([&](const crow::request& req) -> myxmr::htmlresponse
|
||||||
{
|
{
|
||||||
|
|
||||||
map<std::string, std::string> post_body
|
map<std::string, std::string> post_body
|
||||||
|
@ -378,9 +400,12 @@ main(int ac, const char* av[])
|
||||||
|
|
||||||
string domain = get_domain(req);
|
string domain = get_domain(req);
|
||||||
|
|
||||||
return xmrblocks.show_my_outputs(tx_hash, xmr_address,
|
string response = xmrblocks.show_my_outputs(
|
||||||
|
tx_hash, xmr_address,
|
||||||
viewkey, raw_tx_data,
|
viewkey, raw_tx_data,
|
||||||
domain);
|
domain);
|
||||||
|
|
||||||
|
return myxmr::htmlresponse(std::move(response));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/myoutputs/<string>/<string>/<string>")
|
CROW_ROUTE(app, "/myoutputs/<string>/<string>/<string>")
|
||||||
|
@ -390,15 +415,17 @@ main(int ac, const char* av[])
|
||||||
|
|
||||||
string domain = get_domain(req);
|
string domain = get_domain(req);
|
||||||
|
|
||||||
return xmrblocks.show_my_outputs(remove_bad_chars(tx_hash),
|
return myxmr::htmlresponse(xmrblocks.show_my_outputs(
|
||||||
|
remove_bad_chars(tx_hash),
|
||||||
remove_bad_chars(xmr_address),
|
remove_bad_chars(xmr_address),
|
||||||
remove_bad_chars(viewkey),
|
remove_bad_chars(viewkey),
|
||||||
string {},
|
string {},
|
||||||
domain);
|
domain));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/prove").methods("POST"_method)
|
CROW_ROUTE(app, "/prove").methods("POST"_method)
|
||||||
([&](const crow::request& req) {
|
([&](const crow::request& req) -> myxmr::htmlresponse
|
||||||
|
{
|
||||||
|
|
||||||
map<std::string, std::string> post_body
|
map<std::string, std::string> post_body
|
||||||
= xmreg::parse_crow_post_data(req.body);
|
= xmreg::parse_crow_post_data(req.body);
|
||||||
|
@ -421,41 +448,45 @@ main(int ac, const char* av[])
|
||||||
|
|
||||||
string domain = get_domain(req);
|
string domain = get_domain(req);
|
||||||
|
|
||||||
return xmrblocks.show_prove(tx_hash,
|
return myxmr::htmlresponse(xmrblocks.show_prove(tx_hash,
|
||||||
xmr_address,
|
xmr_address,
|
||||||
tx_prv_key,
|
tx_prv_key,
|
||||||
raw_tx_data,
|
raw_tx_data,
|
||||||
domain);
|
domain));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
CROW_ROUTE(app, "/prove/<string>/<string>/<string>")
|
CROW_ROUTE(app, "/prove/<string>/<string>/<string>")
|
||||||
([&](const crow::request& req, string tx_hash,
|
([&](const crow::request& req, string tx_hash,
|
||||||
string xmr_address, string tx_prv_key) {
|
string xmr_address, string tx_prv_key)
|
||||||
|
{
|
||||||
|
|
||||||
string domain = get_domain(req);
|
string domain = get_domain(req);
|
||||||
|
|
||||||
return xmrblocks.show_prove(remove_bad_chars(tx_hash),
|
return myxmr::htmlresponse(xmrblocks.show_prove(
|
||||||
|
remove_bad_chars(tx_hash),
|
||||||
remove_bad_chars(xmr_address),
|
remove_bad_chars(xmr_address),
|
||||||
remove_bad_chars(tx_prv_key),
|
remove_bad_chars(tx_prv_key),
|
||||||
string {},
|
string {},
|
||||||
domain);
|
domain));
|
||||||
});
|
});
|
||||||
|
|
||||||
if (enable_pusher)
|
if (enable_pusher)
|
||||||
{
|
{
|
||||||
CROW_ROUTE(app, "/rawtx")
|
CROW_ROUTE(app, "/rawtx")
|
||||||
([&]() {
|
([&]() {
|
||||||
return xmrblocks.show_rawtx();
|
return myxmr::htmlresponse(xmrblocks.show_rawtx());
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/checkandpush").methods("POST"_method)
|
CROW_ROUTE(app, "/checkandpush").methods("POST"_method)
|
||||||
([&](const crow::request& req) {
|
([&](const crow::request& req) -> myxmr::htmlresponse
|
||||||
|
{
|
||||||
|
|
||||||
map<std::string, std::string> post_body
|
map<std::string, std::string> post_body
|
||||||
= xmreg::parse_crow_post_data(req.body);
|
= xmreg::parse_crow_post_data(req.body);
|
||||||
|
|
||||||
if (post_body.count("rawtxdata") == 0 || post_body.count("action") == 0)
|
if (post_body.count("rawtxdata") == 0
|
||||||
|
|| post_body.count("action") == 0)
|
||||||
{
|
{
|
||||||
return string("Raw tx data or action not provided");
|
return string("Raw tx data or action not provided");
|
||||||
}
|
}
|
||||||
|
@ -464,9 +495,11 @@ main(int ac, const char* av[])
|
||||||
string action = remove_bad_chars(post_body["action"]);
|
string action = remove_bad_chars(post_body["action"]);
|
||||||
|
|
||||||
if (action == "check")
|
if (action == "check")
|
||||||
return xmrblocks.show_checkrawtx(raw_tx_data, action);
|
return myxmr::htmlresponse(
|
||||||
|
xmrblocks.show_checkrawtx(raw_tx_data, action));
|
||||||
else if (action == "push")
|
else if (action == "push")
|
||||||
return xmrblocks.show_pushrawtx(raw_tx_data, action);
|
return myxmr::htmlresponse(
|
||||||
|
xmrblocks.show_pushrawtx(raw_tx_data, action));
|
||||||
return string("Provided action is neither check nor push");
|
return string("Provided action is neither check nor push");
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@ -476,11 +509,12 @@ main(int ac, const char* av[])
|
||||||
{
|
{
|
||||||
CROW_ROUTE(app, "/rawkeyimgs")
|
CROW_ROUTE(app, "/rawkeyimgs")
|
||||||
([&]() {
|
([&]() {
|
||||||
return xmrblocks.show_rawkeyimgs();
|
return myxmr::htmlresponse(xmrblocks.show_rawkeyimgs());
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/checkrawkeyimgs").methods("POST"_method)
|
CROW_ROUTE(app, "/checkrawkeyimgs").methods("POST"_method)
|
||||||
([&](const crow::request& req) {
|
([&](const crow::request& req) -> myxmr::htmlresponse
|
||||||
|
{
|
||||||
|
|
||||||
map<std::string, std::string> post_body
|
map<std::string, std::string> post_body
|
||||||
= xmreg::parse_crow_post_data(req.body);
|
= xmreg::parse_crow_post_data(req.body);
|
||||||
|
@ -498,7 +532,8 @@ main(int ac, const char* av[])
|
||||||
string raw_data = remove_bad_chars(post_body["rawkeyimgsdata"]);
|
string raw_data = remove_bad_chars(post_body["rawkeyimgsdata"]);
|
||||||
string viewkey = remove_bad_chars(post_body["viewkey"]);
|
string viewkey = remove_bad_chars(post_body["viewkey"]);
|
||||||
|
|
||||||
return xmrblocks.show_checkrawkeyimgs(raw_data, viewkey);
|
return myxmr::htmlresponse(
|
||||||
|
xmrblocks.show_checkrawkeyimgs(raw_data, viewkey));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -507,11 +542,12 @@ main(int ac, const char* av[])
|
||||||
{
|
{
|
||||||
CROW_ROUTE(app, "/rawoutputkeys")
|
CROW_ROUTE(app, "/rawoutputkeys")
|
||||||
([&]() {
|
([&]() {
|
||||||
return xmrblocks.show_rawoutputkeys();
|
return myxmr::htmlresponse(xmrblocks.show_rawoutputkeys());
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/checkrawoutputkeys").methods("POST"_method)
|
CROW_ROUTE(app, "/checkrawoutputkeys").methods("POST"_method)
|
||||||
([&](const crow::request& req) {
|
([&](const crow::request& req) -> myxmr::htmlresponse
|
||||||
|
{
|
||||||
|
|
||||||
map<std::string, std::string> post_body
|
map<std::string, std::string> post_body
|
||||||
= xmreg::parse_crow_post_data(req.body);
|
= xmreg::parse_crow_post_data(req.body);
|
||||||
|
@ -530,25 +566,29 @@ main(int ac, const char* av[])
|
||||||
string raw_data = remove_bad_chars(post_body["rawoutputkeysdata"]);
|
string raw_data = remove_bad_chars(post_body["rawoutputkeysdata"]);
|
||||||
string viewkey = remove_bad_chars(post_body["viewkey"]);
|
string viewkey = remove_bad_chars(post_body["viewkey"]);
|
||||||
|
|
||||||
return xmrblocks.show_checkcheckrawoutput(raw_data, viewkey);
|
return myxmr::htmlresponse(
|
||||||
|
xmrblocks.show_checkcheckrawoutput(raw_data, viewkey));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CROW_ROUTE(app, "/search").methods("GET"_method)
|
CROW_ROUTE(app, "/search").methods("GET"_method)
|
||||||
([&](const crow::request& req) {
|
([&](const crow::request& req) {
|
||||||
return xmrblocks.search(remove_bad_chars(string(req.url_params.get("value"))));
|
return myxmr::htmlresponse(
|
||||||
|
xmrblocks.search(
|
||||||
|
remove_bad_chars(
|
||||||
|
string(req.url_params.get("value")))));
|
||||||
});
|
});
|
||||||
|
|
||||||
CROW_ROUTE(app, "/mempool")
|
CROW_ROUTE(app, "/mempool")
|
||||||
([&]() {
|
([&]() {
|
||||||
return xmrblocks.mempool(true);
|
return myxmr::htmlresponse(xmrblocks.mempool(true));
|
||||||
});
|
});
|
||||||
|
|
||||||
// alias to "/mempool"
|
// alias to "/mempool"
|
||||||
CROW_ROUTE(app, "/txpool")
|
CROW_ROUTE(app, "/txpool")
|
||||||
([&]() {
|
([&]() {
|
||||||
return xmrblocks.mempool(true);
|
return myxmr::htmlresponse(xmrblocks.mempool(true));
|
||||||
});
|
});
|
||||||
|
|
||||||
// CROW_ROUTE(app, "/altblocks")
|
// CROW_ROUTE(app, "/altblocks")
|
||||||
|
@ -773,13 +813,16 @@ main(int ac, const char* av[])
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
in_mempool_aswell = regex_search(req.raw_url, regex {"mempool=[01]"}) ?
|
in_mempool_aswell = regex_search(
|
||||||
boost::lexical_cast<bool>(req.url_params.get("mempool")) :
|
req.raw_url, regex {"mempool=[01]"}) ?
|
||||||
|
boost::lexical_cast<bool>(
|
||||||
|
req.url_params.get("mempool")) :
|
||||||
false;
|
false;
|
||||||
}
|
}
|
||||||
catch (const boost::bad_lexical_cast &e)
|
catch (const boost::bad_lexical_cast &e)
|
||||||
{
|
{
|
||||||
cerr << "Cant parse tx_prove as bool. Using default value" << endl;
|
cerr << "Cant parse tx_prove as bool. Using default value"
|
||||||
|
<< endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
myxmr::jsonresponse r{xmrblocks.json_outputsblocks(
|
myxmr::jsonresponse r{xmrblocks.json_outputsblocks(
|
||||||
|
@ -816,16 +859,24 @@ main(int ac, const char* av[])
|
||||||
if (use_ssl)
|
if (use_ssl)
|
||||||
{
|
{
|
||||||
cout << "Staring in ssl mode" << endl;
|
cout << "Staring in ssl mode" << endl;
|
||||||
app.bindaddr(bindaddr).port(app_port).ssl_file(ssl_crt_file, ssl_key_file)
|
app.bindaddr(bindaddr).port(app_port).ssl_file(
|
||||||
|
ssl_crt_file, ssl_key_file)
|
||||||
.multithreaded().run();
|
.multithreaded().run();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cout << "Staring in non-ssl mode" << endl;
|
cout << "Staring in non-ssl mode" << endl;
|
||||||
app.bindaddr(bindaddr).port(app_port).multithreaded().run();
|
if (*concurrency_opt == 0)
|
||||||
|
{
|
||||||
|
app.bindaddr(bindaddr).port(app_port).multithreaded().run();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
app.bindaddr(bindaddr).port(app_port)
|
||||||
|
.concurrency(*concurrency_opt).run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (enable_emission_monitor == true)
|
if (enable_emission_monitor == true)
|
||||||
{
|
{
|
||||||
// finish Emission monitoring thread in a cotrolled manner.
|
// finish Emission monitoring thread in a cotrolled manner.
|
||||||
|
|
|
@ -67,6 +67,8 @@ namespace xmreg
|
||||||
"maximum time, in milliseconds, to wait for mempool data for the front page")
|
"maximum time, in milliseconds, to wait for mempool data for the front page")
|
||||||
("mempool-refresh-time", value<string>()->default_value("5"),
|
("mempool-refresh-time", value<string>()->default_value("5"),
|
||||||
"time, in seconds, for each refresh of mempool state")
|
"time, in seconds, for each refresh of mempool state")
|
||||||
|
("concurrency,c", value<size_t>()->default_value(0),
|
||||||
|
"number of threads handling http queries. Default is 0 which means it is based you on the cpu")
|
||||||
("bc-path,b", value<string>(),
|
("bc-path,b", value<string>(),
|
||||||
"path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb")
|
"path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb")
|
||||||
("ssl-crt-file", value<string>(),
|
("ssl-crt-file", value<string>(),
|
||||||
|
|
146
src/page.h
146
src/page.h
|
@ -35,7 +35,7 @@
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <future>
|
#include <future>
|
||||||
|
#include <type_traits>
|
||||||
|
|
||||||
|
|
||||||
#define TMPL_DIR "./templates"
|
#define TMPL_DIR "./templates"
|
||||||
|
@ -103,6 +103,43 @@ struct tx_info_cache
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// helper to ignore any number of template parametrs
|
||||||
|
template<typename...> using VoidT = void;
|
||||||
|
|
||||||
|
// primary template;
|
||||||
|
template<typename, typename = VoidT<>>
|
||||||
|
struct HasSpanInGetOutputKeyT: std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
//partial specialization (myy be SFINAEed away)
|
||||||
|
template <typename T>
|
||||||
|
struct HasSpanInGetOutputKeyT<
|
||||||
|
T,
|
||||||
|
VoidT<decltype(std::declval<T>()
|
||||||
|
.get_output_key(
|
||||||
|
std::declval<const epee::span<const uint64_t>&>(),
|
||||||
|
std::declval<const std::vector<uint64_t>&>(),
|
||||||
|
std::declval<std::vector<cryptonote::output_data_t>&>()))
|
||||||
|
>>: std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
|
||||||
|
// primary template;
|
||||||
|
template<typename, typename = VoidT<>>
|
||||||
|
struct OutputIndicesReturnVectOfVectT : std::false_type
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
struct OutputIndicesReturnVectOfVectT<
|
||||||
|
T,
|
||||||
|
VoidT<decltype(std::declval<T>()
|
||||||
|
.get_tx_amount_output_indices(
|
||||||
|
uint64_t{}, size_t{})
|
||||||
|
.front().front())
|
||||||
|
>>: std::true_type
|
||||||
|
{};
|
||||||
|
|
||||||
// indect overload of hash for tx_info_cache::key
|
// indect overload of hash for tx_info_cache::key
|
||||||
namespace std
|
namespace std
|
||||||
{
|
{
|
||||||
|
@ -466,7 +503,6 @@ page(MicroCore* _mcore,
|
||||||
testnet = nettype == cryptonote::network_type::TESTNET;
|
testnet = nettype == cryptonote::network_type::TESTNET;
|
||||||
stagenet = nettype == cryptonote::network_type::STAGENET;
|
stagenet = nettype == cryptonote::network_type::STAGENET;
|
||||||
|
|
||||||
|
|
||||||
no_of_mempool_tx_of_frontpage = 25;
|
no_of_mempool_tx_of_frontpage = 25;
|
||||||
|
|
||||||
// read template files for all the pages
|
// read template files for all the pages
|
||||||
|
@ -1255,7 +1291,7 @@ show_block(uint64_t _blk_height)
|
||||||
// initalise page tempate map with basic info about blockchain
|
// initalise page tempate map with basic info about blockchain
|
||||||
|
|
||||||
string blk_pow_hash_str = pod_to_hex(get_block_longhash(blk, _blk_height));
|
string blk_pow_hash_str = pod_to_hex(get_block_longhash(blk, _blk_height));
|
||||||
uint64_t blk_difficulty = core_storage->get_db().get_block_difficulty(_blk_height);
|
cryptonote::difficulty_type blk_difficulty = core_storage->get_db().get_block_difficulty(_blk_height);
|
||||||
|
|
||||||
mstch::map context {
|
mstch::map context {
|
||||||
{"testnet" , testnet},
|
{"testnet" , testnet},
|
||||||
|
@ -1276,7 +1312,8 @@ show_block(uint64_t _blk_height)
|
||||||
{"delta_time" , delta_time},
|
{"delta_time" , delta_time},
|
||||||
{"blk_nonce" , blk.nonce},
|
{"blk_nonce" , blk.nonce},
|
||||||
{"blk_pow_hash" , blk_pow_hash_str},
|
{"blk_pow_hash" , blk_pow_hash_str},
|
||||||
{"blk_difficulty" , blk_difficulty},
|
{"blk_difficulty_lo" , (blk_difficulty << 64 >> 64).convert_to<uint64_t>()},
|
||||||
|
{"blk_difficulty_hi" , (blk_difficulty >> 64).convert_to<uint64_t>()},
|
||||||
{"age_format" , age.second},
|
{"age_format" , age.second},
|
||||||
{"major_ver" , std::to_string(blk.major_version)},
|
{"major_ver" , std::to_string(blk.major_version)},
|
||||||
{"minor_ver" , std::to_string(blk.minor_version)},
|
{"minor_ver" , std::to_string(blk.minor_version)},
|
||||||
|
@ -1720,9 +1757,12 @@ show_ringmembers_hex(string const& tx_hash_str)
|
||||||
== false)
|
== false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
core_storage->get_db().get_output_key(in_key.amount,
|
//core_storage->get_db().get_output_key(in_key.amount,
|
||||||
absolute_offsets,
|
// absolute_offsets,
|
||||||
mixin_outputs);
|
// mixin_outputs);
|
||||||
|
get_output_key<BlockchainDB>(in_key.amount,
|
||||||
|
absolute_offsets,
|
||||||
|
mixin_outputs);
|
||||||
}
|
}
|
||||||
catch (OUTPUT_DNE const& e)
|
catch (OUTPUT_DNE const& e)
|
||||||
{
|
{
|
||||||
|
@ -2008,10 +2048,14 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str)
|
||||||
in_key.amount, absolute_offsets, indices);
|
in_key.amount, absolute_offsets, indices);
|
||||||
|
|
||||||
// get mining ouput info
|
// get mining ouput info
|
||||||
core_storage->get_db().get_output_key(
|
//core_storage->get_db().get_output_key(
|
||||||
in_key.amount,
|
//in_key.amount,
|
||||||
absolute_offsets,
|
//absolute_offsets,
|
||||||
mixin_outputs);
|
//mixin_outputs);
|
||||||
|
|
||||||
|
get_output_key<BlockchainDB>(in_key.amount,
|
||||||
|
absolute_offsets,
|
||||||
|
mixin_outputs);
|
||||||
}
|
}
|
||||||
catch (exception const& e)
|
catch (exception const& e)
|
||||||
{
|
{
|
||||||
|
@ -2288,8 +2332,8 @@ show_my_outputs(string tx_hash_str,
|
||||||
string pid_str = pod_to_hex(txd.payment_id);
|
string pid_str = pod_to_hex(txd.payment_id);
|
||||||
string pid8_str = pod_to_hex(txd.payment_id8);
|
string pid8_str = pod_to_hex(txd.payment_id8);
|
||||||
|
|
||||||
string shortcut_url = domain
|
string shortcut_url = tx_prove
|
||||||
+ (tx_prove ? "/prove" : "/myoutputs")
|
? string("/prove") : string("/myoutputs")
|
||||||
+ '/' + tx_hash_str
|
+ '/' + tx_hash_str
|
||||||
+ '/' + xmr_address_str
|
+ '/' + xmr_address_str
|
||||||
+ '/' + viewkey_str;
|
+ '/' + viewkey_str;
|
||||||
|
@ -2323,6 +2367,7 @@ show_my_outputs(string tx_hash_str,
|
||||||
{"payment_id8" , pid8_str},
|
{"payment_id8" , pid8_str},
|
||||||
{"decrypted_payment_id8", string{}},
|
{"decrypted_payment_id8", string{}},
|
||||||
{"tx_prove" , tx_prove},
|
{"tx_prove" , tx_prove},
|
||||||
|
{"domain_url" , domain},
|
||||||
{"shortcut_url" , shortcut_url}
|
{"shortcut_url" , shortcut_url}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2524,9 +2569,13 @@ show_my_outputs(string tx_hash_str,
|
||||||
if (are_absolute_offsets_good(absolute_offsets, in_key) == false)
|
if (are_absolute_offsets_good(absolute_offsets, in_key) == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
core_storage->get_db().get_output_key(in_key.amount,
|
//core_storage->get_db().get_output_key(in_key.amount,
|
||||||
absolute_offsets,
|
//absolute_offsets,
|
||||||
mixin_outputs);
|
//mixin_outputs);
|
||||||
|
|
||||||
|
get_output_key<BlockchainDB>(in_key.amount,
|
||||||
|
absolute_offsets,
|
||||||
|
mixin_outputs);
|
||||||
}
|
}
|
||||||
catch (const OUTPUT_DNE& e)
|
catch (const OUTPUT_DNE& e)
|
||||||
{
|
{
|
||||||
|
@ -4687,9 +4736,13 @@ json_transaction(string tx_hash_str)
|
||||||
if (are_absolute_offsets_good(absolute_offsets, in_key) == false)
|
if (are_absolute_offsets_good(absolute_offsets, in_key) == false)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
core_storage->get_db().get_output_key(in_key.amount,
|
//core_storage->get_db().get_output_key(in_key.amount,
|
||||||
absolute_offsets,
|
//absolute_offsets,
|
||||||
outputs);
|
//outputs);
|
||||||
|
|
||||||
|
get_output_key<BlockchainDB>(in_key.amount,
|
||||||
|
absolute_offsets,
|
||||||
|
outputs);
|
||||||
}
|
}
|
||||||
catch (const OUTPUT_DNE &e)
|
catch (const OUTPUT_DNE &e)
|
||||||
{
|
{
|
||||||
|
@ -6363,9 +6416,13 @@ construct_tx_context(transaction tx, uint16_t with_ring_signatures = 0)
|
||||||
|
|
||||||
// offsets seems good, so try to get the outputs for the amount and
|
// offsets seems good, so try to get the outputs for the amount and
|
||||||
// offsets given
|
// offsets given
|
||||||
core_storage->get_db().get_output_key(in_key.amount,
|
//core_storage->get_db().get_output_key(in_key.amount,
|
||||||
absolute_offsets,
|
//absolute_offsets,
|
||||||
outputs);
|
//outputs);
|
||||||
|
|
||||||
|
get_output_key<BlockchainDB>(in_key.amount,
|
||||||
|
absolute_offsets,
|
||||||
|
outputs);
|
||||||
}
|
}
|
||||||
catch (const std::exception& e)
|
catch (const std::exception& e)
|
||||||
{
|
{
|
||||||
|
@ -6575,8 +6632,11 @@ construct_tx_context(transaction tx, uint16_t with_ring_signatures = 0)
|
||||||
|
|
||||||
if (core_storage->get_db().tx_exists(txd.hash, tx_index))
|
if (core_storage->get_db().tx_exists(txd.hash, tx_index))
|
||||||
{
|
{
|
||||||
out_amount_indices = core_storage->get_db()
|
//out_amount_indices = core_storage->get_db()
|
||||||
.get_tx_amount_output_indices(tx_index);
|
//.get_tx_amount_output_indices(tx_index).front();
|
||||||
|
get_tx_amount_output_indices<BlockchainDB>(
|
||||||
|
out_amount_indices,
|
||||||
|
tx_index);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -7080,9 +7140,45 @@ add_js_files(mstch::map& context)
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
typename std::enable_if<
|
||||||
|
HasSpanInGetOutputKeyT<T>::value, void>::type
|
||||||
|
get_output_key(uint64_t amount, Args&&... args)
|
||||||
|
{
|
||||||
|
core_storage->get_db().get_output_key(
|
||||||
|
epee::span<const uint64_t>(&amount, 1),
|
||||||
|
std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
typename std::enable_if<
|
||||||
|
!HasSpanInGetOutputKeyT<T>::value, void>::type
|
||||||
|
get_output_key(uint64_t amount, Args&&... args)
|
||||||
|
{
|
||||||
|
core_storage->get_db().get_output_key(
|
||||||
|
amount, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
typename std::enable_if<
|
||||||
|
!OutputIndicesReturnVectOfVectT<T>::value, void>::type
|
||||||
|
get_tx_amount_output_indices(vector<uint64_t>& out_amount_indices, Args&&... args)
|
||||||
|
{
|
||||||
|
out_amount_indices = core_storage->get_db()
|
||||||
|
.get_tx_amount_output_indices(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename... Args>
|
||||||
|
typename std::enable_if<
|
||||||
|
OutputIndicesReturnVectOfVectT<T>::value, void>::type
|
||||||
|
get_tx_amount_output_indices(vector<uint64_t>& out_amount_indices, Args&&... args)
|
||||||
|
{
|
||||||
|
out_amount_indices = core_storage->get_db()
|
||||||
|
.get_tx_amount_output_indices(std::forward<Args>(args)...).front();
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //CROWXMR_PAGE_H
|
#endif //CROWXMR_PAGE_H
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ rpccalls::rpccalls(string _deamon_url,
|
||||||
|
|
||||||
m_http_client.set_server(
|
m_http_client.set_server(
|
||||||
deamon_url,
|
deamon_url,
|
||||||
boost::optional<epee::net_utils::http::login>{});
|
boost::optional<epee::net_utils::http::login>{}, epee::net_utils::ssl_support_t::e_ssl_support_disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>PoW hash:</td><td>{{blk_pow_hash}}</td>
|
<td>PoW hash:</td><td>{{blk_pow_hash}}</td>
|
||||||
<td>Difficulty:</td><td>{{blk_difficulty}}</td>
|
<td>Difficulty (hi64, lo64):</td><td>{{blk_difficulty_hi}}, {{blk_difficulty_lo}}</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
|
<link rel="shortcut icon" href="about:blank">
|
||||||
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
|
<META HTTP-EQUIV="CACHE-CONTROL" CONTENT="NO-CACHE">
|
||||||
{{#refresh}}
|
{{#refresh}}
|
||||||
<meta http-equiv="refresh" content="10">
|
<meta http-equiv="refresh" content="10">
|
||||||
|
|
|
@ -78,7 +78,7 @@
|
||||||
{{/found_our_outputs}}
|
{{/found_our_outputs}}
|
||||||
</h3>
|
</h3>
|
||||||
<h4>
|
<h4>
|
||||||
<a href="{{shortcut_url}}" target="_blank">link to this page</a>
|
<a href="{{domain_url}}{{shortcut_url}}" target="_blank">link to this page</a>
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue