mirror of
https://codeberg.org/wownero/onion-wownero-blockchain-explorer-themefork.git
synced 2026-10-17 05:41:27 +02:00
Rewowify using d7853cc48c on current xmrblocks codebase
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
.DS_Store
|
||||
.vscode
|
||||
.sass-cache
|
||||
*.*~
|
||||
*.user
|
||||
|
||||
+6
-7
@@ -6,7 +6,7 @@ set(PROJECT_NAME
|
||||
|
||||
project(${PROJECT_NAME})
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
if (WIN32)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -O3")
|
||||
@@ -14,7 +14,7 @@ endif()
|
||||
|
||||
|
||||
if (NOT MONERO_DIR)
|
||||
set(MONERO_DIR ~/wownero)
|
||||
set(MONERO_DIR ~/src/wownero)
|
||||
endif()
|
||||
|
||||
message(STATUS MONERO_DIR ": ${MONERO_DIR}")
|
||||
@@ -49,7 +49,6 @@ list(APPEND CMAKE_MODULE_PATH "${MY_CMAKE_DIR}")
|
||||
|
||||
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${MONERO_BUILD_DIR}"
|
||||
CACHE PATH "Add Monero directory for library searching")
|
||||
|
||||
include(MyUtils)
|
||||
|
||||
find_package(Monero)
|
||||
@@ -139,12 +138,13 @@ set(LIBRARIES
|
||||
myext
|
||||
mstch
|
||||
wallet
|
||||
cryptonote_core
|
||||
cryptonote_basic
|
||||
cryptonote_protocol
|
||||
cryptonote_format_utils_basic
|
||||
blockchain_db
|
||||
device
|
||||
${WALLET_CRYPTO}
|
||||
cryptonote_core
|
||||
cryptonote_protocol
|
||||
cryptonote_basic
|
||||
multisig
|
||||
daemonizer
|
||||
blocks
|
||||
@@ -165,7 +165,6 @@ set(LIBRARIES
|
||||
${Boost_LIBRARIES}
|
||||
pthread
|
||||
unbound
|
||||
curl
|
||||
crypto
|
||||
ssl)
|
||||
|
||||
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
# Use ubuntu:latest as base for builder stage image
|
||||
FROM ubuntu:latest as builder
|
||||
|
||||
# Set Monero branch/tag to be used for monerod compilation
|
||||
ARG MONERO_BRANCH=v0.18.4.0
|
||||
|
||||
# Added DEBIAN_FRONTEND=noninteractive to workaround tzdata prompt on installation
|
||||
ENV DEBIAN_FRONTEND="noninteractive"
|
||||
|
||||
# Install dependencies for monerod and xmrblocks compilation
|
||||
RUN apt-get update \
|
||||
&& apt-get upgrade -y \
|
||||
&& apt-get install -y --no-install-recommends \
|
||||
git \
|
||||
build-essential \
|
||||
cmake \
|
||||
miniupnpc \
|
||||
graphviz \
|
||||
doxygen \
|
||||
pkg-config \
|
||||
ca-certificates \
|
||||
zip \
|
||||
libboost-all-dev \
|
||||
libunbound-dev \
|
||||
libunwind8-dev \
|
||||
libssl-dev \
|
||||
libcurl4-openssl-dev \
|
||||
libgtest-dev \
|
||||
libreadline-dev \
|
||||
libzmq3-dev \
|
||||
libsodium-dev \
|
||||
libhidapi-dev \
|
||||
libhidapi-libusb0 \
|
||||
&& apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# Set compilation environment variables
|
||||
ENV CFLAGS='-fPIC'
|
||||
ENV CXXFLAGS='-fPIC'
|
||||
ENV USE_SINGLE_BUILDDIR=1
|
||||
ENV BOOST_DEBUG=1
|
||||
|
||||
WORKDIR /root
|
||||
|
||||
# Clone and compile monerod with all available threads
|
||||
ARG NPROC
|
||||
RUN git clone --recursive --branch ${MONERO_BRANCH} \
|
||||
--depth 1 --shallow-submodules https://github.com/monero-project/monero.git \
|
||||
&& cd monero \
|
||||
&& test -z "$NPROC" && nproc > /nproc || echo -n "$NPROC" > /nproc && make -j"$(cat /nproc)"
|
||||
|
||||
# Copy and cmake/make xmrblocks with all available threads
|
||||
COPY . /root/onion-monero-blockchain-explorer/
|
||||
WORKDIR /root/onion-monero-blockchain-explorer/build
|
||||
RUN cmake .. && make -j"$(cat /nproc)"
|
||||
|
||||
# Use ldd and awk to bundle up dynamic libraries for the final image
|
||||
RUN zip /lib.zip $(ldd xmrblocks | grep -E '/[^\ ]*' -o)
|
||||
|
||||
# Use ubuntu:latest as base for final image
|
||||
FROM ubuntu:latest AS final
|
||||
|
||||
# Added DEBIAN_FRONTEND=noninteractive to workaround tzdata prompt on installation
|
||||
ENV DEBIAN_FRONTEND="noninteractive"
|
||||
|
||||
# Update Ubuntu packages and install unzip to handle bundled libs from builder stage
|
||||
RUN apt-get update \
|
||||
&& apt-get upgrade -y \
|
||||
&& apt-get install -y --no-install-recommends unzip \
|
||||
&& apt clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
COPY --from=builder /lib.zip .
|
||||
RUN unzip -o lib.zip \
|
||||
&& rm -rf lib.zip \
|
||||
&& apt purge -y unzip
|
||||
|
||||
# Add user and setup directories for monerod and xmrblocks
|
||||
RUN touch /var/mail/ubuntu && chown ubuntu /var/mail/ubuntu && userdel -r ubuntu \
|
||||
&& useradd -ms /bin/bash monero \
|
||||
&& mkdir -p /home/monero/.bitmonero \
|
||||
&& chown -R monero:monero /home/monero/.bitmonero
|
||||
USER monero
|
||||
|
||||
# Switch to home directory and install newly built xmrblocks binary
|
||||
WORKDIR /home/monero
|
||||
COPY --chown=monero:monero --from=builder /root/onion-monero-blockchain-explorer/build/xmrblocks .
|
||||
COPY --chown=monero:monero --from=builder /root/onion-monero-blockchain-explorer/build/templates ./templates/
|
||||
|
||||
# Expose volume used for lmdb access by xmrblocks
|
||||
VOLUME /home/monero/.bitmonero
|
||||
|
||||
# Expose default explorer http port
|
||||
EXPOSE 8081
|
||||
|
||||
ENTRYPOINT ["/bin/sh", "-c"]
|
||||
|
||||
# Set sane defaults that are overridden if the user passes any commands
|
||||
CMD ["./xmrblocks --enable-json-api --enable-autorefresh-option --enable-pusher"]
|
||||
@@ -45,7 +45,7 @@ foreach (l ${LIBS})
|
||||
find_library(Xmr_${L}_LIBRARY
|
||||
NAMES ${l}
|
||||
PATHS ${CMAKE_LIBRARY_PATH}
|
||||
PATH_SUFFIXES "/src/${l}" "/src/" "/external/db_drivers/lib${l}" "/lib" "/src/crypto" "/src/crypto/wallet" "/contrib/epee/src" "/external/easylogging++/" "/external/${l}" "external/miniupnp/miniupnpc" "/external/RandomWOW"
|
||||
PATH_SUFFIXES "/src/${l}" "/src/" "/external/db_drivers/lib${l}" "/lib" "/src/crypto" "/src/crypto/wallet" "/contrib/epee/src" "/external/easylogging++/" "/external/${l}" "external/miniupnp/miniupnpc" "/external/randomwow"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
@@ -67,6 +67,13 @@ if (EXISTS ${MONERO_BUILD_DIR}/src/ringct/libringct_basic.a)
|
||||
PROPERTY IMPORTED_LOCATION ${MONERO_BUILD_DIR}/src/ringct/libringct_basic.a)
|
||||
endif()
|
||||
|
||||
if (EXISTS ${MONERO_BUILD_DIR}/src/cryptonote_basic/libcryptonote_format_utils_basic.a)
|
||||
message(STATUS FindMonero " found libcryptonote_format_utils_basic.a")
|
||||
add_library(cryptonote_format_utils_basic STATIC IMPORTED)
|
||||
set_property(TARGET cryptonote_format_utils_basic
|
||||
PROPERTY IMPORTED_LOCATION ${MONERO_BUILD_DIR}/src/cryptonote_basic/libcryptonote_format_utils_basic.a)
|
||||
endif()
|
||||
|
||||
|
||||
message(STATUS ${MONERO_SOURCE_DIR}/build)
|
||||
|
||||
@@ -76,7 +83,7 @@ include_directories(
|
||||
${MONERO_SOURCE_DIR}/src/crypto
|
||||
${MONERO_SOURCE_DIR}/src/crypto/wallet
|
||||
${MONERO_SOURCE_DIR}/external
|
||||
${MONERO_SOURCE_DIR}/external/RandomWOW/src
|
||||
${MONERO_SOURCE_DIR}/external/randomwow/src
|
||||
${MONERO_SOURCE_DIR}/build
|
||||
${MONERO_SOURCE_DIR}/external/easylogging++
|
||||
${MONERO_SOURCE_DIR}/contrib/epee/include
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
From d7853cc48ca87e3a4a8e08bf96139b40e87a4cfc Mon Sep 17 00:00:00 2001
|
||||
From: wowario <wowario@protonmail.com>
|
||||
Date: Tue, 11 Dec 2018 18:43:06 +0300
|
||||
Subject: [PATCH] wowified
|
||||
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
cmake/FindMonero.cmake | 4 ++--
|
||||
main.cpp | 10 ++++-----
|
||||
src/CmdLineOptions.cpp | 6 +++---
|
||||
src/CurrentBlockchainStatus.cpp | 4 ++--
|
||||
src/MempoolStatus.cpp | 4 ++--
|
||||
src/page.h | 10 ++++-----
|
||||
src/rpccalls.h | 2 +-
|
||||
src/templates/checkrawoutputkeys.html | 2 +-
|
||||
src/templates/footer.html | 2 +-
|
||||
src/templates/header.html | 4 ++--
|
||||
src/templates/index2.html | 2 +-
|
||||
src/templates/js/config.js | 30 ++++++++++++++++++++++++++
|
||||
src/templates/my_outputs.html | 6 +++---
|
||||
src/templates/partials/tx_details.html | 16 +++++++-------
|
||||
src/templates/rawtx.html | 6 +++---
|
||||
src/tools.h | 4 ++--
|
||||
17 files changed, 72 insertions(+), 42 deletions(-)
|
||||
create mode 100755 src/templates/js/config.js
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 34ff718..6c7e633 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -14,7 +14,7 @@ endif()
|
||||
|
||||
|
||||
if (NOT MONERO_DIR)
|
||||
- set(MONERO_DIR ~/monero)
|
||||
+ set(MONERO_DIR ~/wownero)
|
||||
endif()
|
||||
|
||||
message(STATUS MONERO_DIR ": ${MONERO_DIR}")
|
||||
diff --git a/cmake/FindMonero.cmake b/cmake/FindMonero.cmake
|
||||
index f9b73ae..9b91ecf 100644
|
||||
--- a/cmake/FindMonero.cmake
|
||||
+++ b/cmake/FindMonero.cmake
|
||||
@@ -45,7 +45,7 @@ foreach (l ${LIBS})
|
||||
find_library(Xmr_${L}_LIBRARY
|
||||
NAMES ${l}
|
||||
PATHS ${CMAKE_LIBRARY_PATH}
|
||||
- PATH_SUFFIXES "/src/${l}" "/src/" "/external/db_drivers/lib${l}" "/lib" "/src/crypto" "/src/crypto/wallet" "/contrib/epee/src" "/external/easylogging++/" "/external/${l}" "external/miniupnp/miniupnpc"
|
||||
+ PATH_SUFFIXES "/src/${l}" "/src/" "/external/db_drivers/lib${l}" "/lib" "/src/crypto" "/src/crypto/wallet" "/contrib/epee/src" "/external/easylogging++/" "/external/${l}" "external/miniupnp/miniupnpc" "/external/RandomWOW"
|
||||
NO_DEFAULT_PATH
|
||||
)
|
||||
|
||||
@@ -76,7 +76,7 @@ include_directories(
|
||||
${MONERO_SOURCE_DIR}/src/crypto
|
||||
${MONERO_SOURCE_DIR}/src/crypto/wallet
|
||||
${MONERO_SOURCE_DIR}/external
|
||||
- ${MONERO_SOURCE_DIR}/external/randomx/src
|
||||
+ ${MONERO_SOURCE_DIR}/external/randomwow/src
|
||||
${MONERO_SOURCE_DIR}/build
|
||||
${MONERO_SOURCE_DIR}/external/easylogging++
|
||||
${MONERO_SOURCE_DIR}/contrib/epee/include
|
||||
diff --git a/main.cpp b/main.cpp
|
||||
index 016363f..d317e4f 100644
|
||||
--- a/main.cpp
|
||||
+++ b/main.cpp
|
||||
@@ -207,9 +207,9 @@ main(int ac, const char* av[])
|
||||
|
||||
string deamon_url {*deamon_url_opt};
|
||||
|
||||
- if (testnet && deamon_url == "http:://127.0.0.1:18081")
|
||||
- deamon_url = "http:://127.0.0.1:28081";
|
||||
- if (stagenet && deamon_url == "http:://127.0.0.1:18081")
|
||||
+ if (testnet && deamon_url == "http:://127.0.0.1:34568")
|
||||
+ deamon_url = "http:://127.0.0.1:11181";
|
||||
+ if (stagenet && deamon_url == "http:://127.0.0.1:34568")
|
||||
deamon_url = "http:://127.0.0.1:38081";
|
||||
|
||||
uint64_t mempool_info_timeout {5000};
|
||||
@@ -435,7 +435,7 @@ main(int ac, const char* av[])
|
||||
|| post_body.count("viewkey") == 0
|
||||
|| post_body.count("tx_hash") == 0)
|
||||
{
|
||||
- return string("xmr address, viewkey or tx hash not provided");
|
||||
+ return string("wow address, viewkey or tx hash not provided");
|
||||
}
|
||||
|
||||
string tx_hash = remove_bad_chars(post_body["tx_hash"]);
|
||||
@@ -482,7 +482,7 @@ main(int ac, const char* av[])
|
||||
|| post_body.count("txprvkey") == 0
|
||||
|| post_body.count("txhash") == 0)
|
||||
{
|
||||
- return string("xmr address, tx private key or "
|
||||
+ return string("wow address, tx private key or "
|
||||
"tx hash not provided");
|
||||
}
|
||||
|
||||
diff --git a/src/CmdLineOptions.cpp b/src/CmdLineOptions.cpp
|
||||
index 4304fc1..46e1cde 100644
|
||||
--- a/src/CmdLineOptions.cpp
|
||||
+++ b/src/CmdLineOptions.cpp
|
||||
@@ -18,7 +18,7 @@ namespace xmreg
|
||||
p.add("txhash", -1);
|
||||
|
||||
options_description desc(
|
||||
- "xmrblocks, Onion Monero Blockchain Explorer");
|
||||
+ "xmrblocks, Wownero Blockchain Explorer");
|
||||
|
||||
desc.add_options()
|
||||
("help,h", value<bool>()->default_value(false)->implicit_value(true),
|
||||
@@ -44,7 +44,7 @@ namespace xmreg
|
||||
("enable-autorefresh-option", value<bool>()->default_value(false)->implicit_value(true),
|
||||
"enable users to have the index page on autorefresh")
|
||||
("enable-emission-monitor", value<bool>()->default_value(false)->implicit_value(true),
|
||||
- "enable Monero total emission monitoring thread")
|
||||
+ "enable Wownero total emission monitoring thread")
|
||||
("port,p", value<string>()->default_value("8081"),
|
||||
"default explorer port")
|
||||
("bindaddr,x", value<string>()->default_value("0.0.0.0"),
|
||||
@@ -64,7 +64,7 @@ namespace xmreg
|
||||
("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>(),
|
||||
- "path to lmdb folder of the blockchain, e.g., ~/.bitmonero/lmdb")
|
||||
+ "path to lmdb folder of the blockchain, e.g., ~/.wownero/lmdb")
|
||||
("ssl-crt-file", value<string>(),
|
||||
"path to crt file for ssl (https) functionality")
|
||||
("ssl-key-file", value<string>(),
|
||||
diff --git a/src/CurrentBlockchainStatus.cpp b/src/CurrentBlockchainStatus.cpp
|
||||
index 040f01d..05c411a 100644
|
||||
--- a/src/CurrentBlockchainStatus.cpp
|
||||
+++ b/src/CurrentBlockchainStatus.cpp
|
||||
@@ -297,13 +297,13 @@ CurrentBlockchainStatus::is_thread_running()
|
||||
return is_running;
|
||||
}
|
||||
|
||||
-bf::path CurrentBlockchainStatus::blockchain_path {"/home/mwo/.bitmonero/lmdb"};
|
||||
+bf::path CurrentBlockchainStatus::blockchain_path {"/home/mwo/.wownero/lmdb"};
|
||||
|
||||
cryptonote::network_type CurrentBlockchainStatus::nettype {cryptonote::network_type::MAINNET};
|
||||
|
||||
string CurrentBlockchainStatus::output_file {"emission_amount.txt"};
|
||||
|
||||
-string CurrentBlockchainStatus::deamon_url {"http:://127.0.0.1:18081"};
|
||||
+string CurrentBlockchainStatus::deamon_url {"http:://127.0.0.1:34568"};
|
||||
|
||||
uint64_t CurrentBlockchainStatus::blockchain_chunk_size {10000};
|
||||
|
||||
diff --git a/src/MempoolStatus.cpp b/src/MempoolStatus.cpp
|
||||
index b55b312..05c228f 100644
|
||||
--- a/src/MempoolStatus.cpp
|
||||
+++ b/src/MempoolStatus.cpp
|
||||
@@ -325,8 +325,8 @@ MempoolStatus::is_thread_running()
|
||||
return is_running;
|
||||
}
|
||||
|
||||
-bf::path MempoolStatus::blockchain_path {"/home/mwo/.bitmonero/lmdb"};
|
||||
-string MempoolStatus::deamon_url {"http:://127.0.0.1:18081"};
|
||||
+bf::path MempoolStatus::blockchain_path {"/home/mwo/.wownero/lmdb"};
|
||||
+string MempoolStatus::deamon_url {"http:://127.0.0.1:34568"};
|
||||
cryptonote::network_type MempoolStatus::nettype {cryptonote::network_type::MAINNET};
|
||||
atomic<bool> MempoolStatus::is_running {false};
|
||||
boost::thread MempoolStatus::m_thread;
|
||||
diff --git a/src/page.h b/src/page.h
|
||||
index 77a047c..6113a3a 100644
|
||||
--- a/src/page.h
|
||||
+++ b/src/page.h
|
||||
@@ -2103,7 +2103,7 @@ show_my_outputs(string tx_hash_str,
|
||||
{"blk_height" , tx_blk_height_str},
|
||||
{"tx_size" , fmt::format("{:0.4f}",
|
||||
static_cast<double>(txd.size) / 1024.0)},
|
||||
- {"tx_fee" , xmreg::xmr_amount_to_str(txd.fee, "{:0.12f}", true)},
|
||||
+ {"tx_fee" , xmreg::xmr_amount_to_str(txd.fee, "{:0.11f}", true)},
|
||||
{"blk_timestamp" , blk_timestamp},
|
||||
{"delta_time" , age.first},
|
||||
{"outputs_no" , static_cast<uint64_t>(txd.output_pub_keys.size())},
|
||||
@@ -2663,7 +2663,7 @@ show_my_outputs(string tx_hash_str,
|
||||
context["show_inputs"] = show_key_images;
|
||||
context["inputs_no"] = static_cast<uint64_t>(inputs.size());
|
||||
context["sum_mixin_xmr"] = xmreg::xmr_amount_to_str(
|
||||
- sum_mixin_xmr, "{:0.12f}", false);
|
||||
+ sum_mixin_xmr, "{:0.11f}", false);
|
||||
|
||||
|
||||
uint64_t possible_spending {0};
|
||||
@@ -2696,7 +2696,7 @@ show_my_outputs(string tx_hash_str,
|
||||
}
|
||||
|
||||
context["possible_spending"] = xmreg::xmr_amount_to_str(
|
||||
- possible_spending, "{:0.12f}", false);
|
||||
+ possible_spending, "{:0.11f}", false);
|
||||
|
||||
add_css_style(context);
|
||||
|
||||
@@ -6060,9 +6060,9 @@ construct_tx_context(transaction tx, uint16_t with_ring_signatures = 0)
|
||||
{"blk_height" , tx_blk_height_str},
|
||||
{"tx_blk_height" , tx_blk_height},
|
||||
{"tx_size" , fmt::format("{:0.4f}", tx_size)},
|
||||
- {"tx_fee" , xmreg::xmr_amount_to_str(txd.fee, "{:0.12f}", false)},
|
||||
+ {"tx_fee" , xmreg::xmr_amount_to_str(txd.fee, "{:0.11f}", false)},
|
||||
{"tx_fee_micro" , xmreg::xmr_amount_to_str(txd.fee*1e6, "{:0.4f}", false)},
|
||||
- {"payed_for_kB" , fmt::format("{:0.12f}", payed_for_kB)},
|
||||
+ {"payed_for_kB" , fmt::format("{:0.11f}", payed_for_kB)},
|
||||
{"tx_version" , static_cast<uint64_t>(txd.version)},
|
||||
{"blk_timestamp" , blk_timestamp},
|
||||
{"blk_timestamp_uint" , blk.timestamp},
|
||||
diff --git a/src/rpccalls.h b/src/rpccalls.h
|
||||
index 17a2d2c..a693e75 100644
|
||||
--- a/src/rpccalls.h
|
||||
+++ b/src/rpccalls.h
|
||||
@@ -85,7 +85,7 @@ public:
|
||||
|
||||
using login_opt = boost::optional<epee::net_utils::http::login>;
|
||||
|
||||
- rpccalls(string _deamon_url = "http:://127.0.0.1:18081",
|
||||
+ rpccalls(string _deamon_url = "http:://127.0.0.1:34568",
|
||||
login_opt _login = login_opt {},
|
||||
uint64_t _timeout = 200000);
|
||||
|
||||
diff --git a/src/templates/checkrawoutputkeys.html b/src/templates/checkrawoutputkeys.html
|
||||
index 572bbdc..c12d66d 100644
|
||||
--- a/src/templates/checkrawoutputkeys.html
|
||||
+++ b/src/templates/checkrawoutputkeys.html
|
||||
@@ -15,7 +15,7 @@
|
||||
<h4>Output keys for address: {{address}}</h4>
|
||||
<h4>Viewkey: {{viewkey}}</h4>
|
||||
{{#has_total_xmr}}
|
||||
- <h4>Total xmr: {{total_xmr}}</h4>
|
||||
+ <h4>Total wow: {{total_xmr}}</h4>
|
||||
{{/has_total_xmr}}
|
||||
|
||||
<div class="center">
|
||||
diff --git a/src/templates/footer.html b/src/templates/footer.html
|
||||
index 4e0cbe6..682d09a 100644
|
||||
--- a/src/templates/footer.html
|
||||
+++ b/src/templates/footer.html
|
||||
@@ -2,7 +2,7 @@
|
||||
<h6 style="margin-top:10px">
|
||||
<a href="https://github.com/moneroexamples/onion-monero-blockchain-explorer">source code</a>
|
||||
| explorer version (api): {{git_branch_name}}-{{last_git_commit_date}}-{{last_git_commit_hash}} ({{api}})
|
||||
- | monero version: {{monero_version_full}}
|
||||
+ | wownero version: {{monero_version_full}}
|
||||
</h6>
|
||||
</div>
|
||||
</body>
|
||||
diff --git a/src/templates/header.html b/src/templates/header.html
|
||||
index 55fe829..9eb518f 100644
|
||||
--- a/src/templates/header.html
|
||||
+++ b/src/templates/header.html
|
||||
@@ -7,7 +7,7 @@
|
||||
{{#refresh}}
|
||||
<meta http-equiv="refresh" content="10">
|
||||
{{/refresh}}
|
||||
- <title>Onion Monero Blockchain Explorer</title>
|
||||
+ <title>Wownero Blockchain Explorer</title>
|
||||
<!--<link rel="stylesheet" type="text/css" href="/css/style.css">-->
|
||||
<style type="text/css">
|
||||
{{#css_styles}}{{/css_styles}}
|
||||
@@ -18,7 +18,7 @@
|
||||
<div>
|
||||
|
||||
<div class="center">
|
||||
- <h1 class="center"><a href="/">Onion Monero Blockchain Explorer</a></h1>
|
||||
+ <h1 class="center"><a href="/">Onion Wownero Blockchain Explorer</a></h1>
|
||||
<h4 style="font-size: 15px; margin: 0px">(no javascript - no cookies - no web analytics trackers - no images - open sourced)</h4>
|
||||
</div>
|
||||
|
||||
diff --git a/src/templates/index2.html b/src/templates/index2.html
|
||||
index f2c6a4c..842a941 100644
|
||||
--- a/src/templates/index2.html
|
||||
+++ b/src/templates/index2.html
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
{{#emission}}
|
||||
<h3 style="font-size: 12px; margin-top: 2px">
|
||||
- Monero emission (fees) is {{amount}} ({{fee_amount}}) as of {{blk_no}} block
|
||||
+ Wownero emission is {{amount}} ({{fee_amount}} fees) as of {{blk_no}} block
|
||||
</h3>
|
||||
{{/emission}}
|
||||
|
||||
diff --git a/src/templates/js/config.js b/src/templates/js/config.js
|
||||
new file mode 100755
|
||||
index 0000000..f109246
|
||||
--- /dev/null
|
||||
+++ b/src/templates/js/config.js
|
||||
@@ -0,0 +1,30 @@
|
||||
+var config = {
|
||||
+ testnet: false, // this is adjusted page.h if needed. dont need to change manually
|
||||
+ stagenet: false, // this is adjusted page.h if needed. dont need to change manually
|
||||
+ coinUnitPlaces: 11,
|
||||
+ txMinConfirms: 4, // corresponds to CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE in Monero
|
||||
+ txCoinbaseMinConfirms: 60, // corresponds to CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW in Monero
|
||||
+ coinSymbol: 'WOW',
|
||||
+ openAliasPrefix: "wow",
|
||||
+ coinName: 'Wownero',
|
||||
+ coinUriPrefix: 'wownero:',
|
||||
+ addressPrefix: 4146,
|
||||
+ integratedAddressPrefix: 6810,
|
||||
+ subAddressPrefix: 12208,
|
||||
+ addressPrefixTestnet: 53,
|
||||
+ integratedAddressPrefixTestnet: 54,
|
||||
+ subAddressPrefixTestnet: 63,
|
||||
+ addressPrefixStagenet: 24,
|
||||
+ integratedAddressPrefixStagenet: 25,
|
||||
+ subAddressPrefixStagenet: 36,
|
||||
+ feePerKB: new JSBigInt('2000000000'),//20^10 - for testnet its not used, as fee is dynamic.
|
||||
+ dustThreshold: new JSBigInt('1000000000'),//10^10 used for choosing outputs/change - we decompose all the way down if the receiver wants now regardless of threshold
|
||||
+ txChargeRatio: 0.5,
|
||||
+ defaultMixin: 21, // minimum mixin for hardfork v9
|
||||
+ txChargeAddress: '',
|
||||
+ idleTimeout: 30,
|
||||
+ idleWarningDuration: 20,
|
||||
+ maxBlockNumber: 500000000,
|
||||
+ avgBlockTime: 300,
|
||||
+ debugMode: false
|
||||
+};
|
||||
diff --git a/src/templates/my_outputs.html b/src/templates/my_outputs.html
|
||||
index ea46014..5d277bf 100644
|
||||
--- a/src/templates/my_outputs.html
|
||||
+++ b/src/templates/my_outputs.html
|
||||
@@ -69,7 +69,7 @@
|
||||
</table>
|
||||
|
||||
<h3>
|
||||
- Sum XMR from matched outputs (i.e., incoming XMR):
|
||||
+ Sum WOW from matched outputs (i.e., incoming WOW):
|
||||
{{#found_our_outputs}}
|
||||
{{sum_xmr}}
|
||||
{{/found_our_outputs}}
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
</div>
|
||||
<h3>
|
||||
- Sum XMR from matched and marked by * ring member's outputs: {{sum_mixin_xmr}}
|
||||
+ Sum WOW from matched and marked by * ring member's outputs: {{sum_mixin_xmr}}
|
||||
<br/>
|
||||
<span style="font-size: 16px"> Possible spending is:
|
||||
{{possible_spending}} (tx fee included)
|
||||
@@ -155,7 +155,7 @@
|
||||
<br/>
|
||||
<span style="font-size: 14px">
|
||||
Number of possible our mixins is {{no_all_possible_mixins}}
|
||||
- for {{all_possible_mixins_amount}} xmr
|
||||
+ for {{all_possible_mixins_amount}} wow
|
||||
(amount as uint64).
|
||||
</span>
|
||||
</h3>
|
||||
diff --git a/src/templates/partials/tx_details.html b/src/templates/partials/tx_details.html
|
||||
index ef217fc..abf30c1 100644
|
||||
--- a/src/templates/partials/tx_details.html
|
||||
+++ b/src/templates/partials/tx_details.html
|
||||
@@ -55,7 +55,7 @@
|
||||
</table>
|
||||
|
||||
|
||||
- <h3>{{outputs_no}} output(s) for total of {{outputs_xmr_sum}} xmr</h3>
|
||||
+ <h3>{{outputs_no}} output(s) for total of {{outputs_xmr_sum}} wow</h3>
|
||||
<div class="center">
|
||||
<table class="center">
|
||||
<tr>
|
||||
@@ -81,7 +81,7 @@
|
||||
<input type="radio" id="tab-1" name="tab-group-1" checked>
|
||||
<label for="tab-1">Decode outputs</label>
|
||||
<div class="content">
|
||||
- <h4 style="margin: 0px">Check which outputs belong to given Monero address/subaddress and viewkey</h4>
|
||||
+ <h4 style="margin: 0px">Check which outputs belong to given Wownero address/subaddress and viewkey</h4>
|
||||
<h5 style="margin: 0px">
|
||||
For RingCT transactions, outputs' amounts are also decoded
|
||||
<br/>
|
||||
@@ -89,7 +89,7 @@
|
||||
</h5>
|
||||
<form action="/myoutputs" method="post" style="width:100%; margin-top:2px" class="style-1">
|
||||
<input type="hidden" name="tx_hash" value="{{tx_hash}}"><br/>
|
||||
- <input type="text" name="xmr_address" size="110" placeholder="Monero address/subaddress"><br/>
|
||||
+ <input type="text" name="xmr_address" size="110" placeholder="Wownero address/subaddress"><br/>
|
||||
<input type="text" name="viewkey" size="110" placeholder="Private viewkey" style="margin-top:5px"><br/>
|
||||
<input type="hidden" name="raw_tx_data" value="{{raw_tx_data}}">
|
||||
<!--above raw_tx_data field only used when checking raw tx data through tx pusher-->
|
||||
@@ -103,10 +103,10 @@
|
||||
<label for="tab-2">Prove sending</label>
|
||||
|
||||
<div class="content">
|
||||
- <h4 style="margin: 0px">Prove to someone that you have sent them Monero in this transaction</h4>
|
||||
+ <h4 style="margin: 0px">Prove to someone that you have sent them Wownero in this transaction</h4>
|
||||
<h5 style="margin: 0px">
|
||||
Tx private key can be obtained using <i>get_tx_key</i>
|
||||
- command in <i>monero-wallet-cli</i> command line tool
|
||||
+ command in <i>wownero-wallet-cli</i> command line tool
|
||||
<br/>
|
||||
Note: address/subaddress and tx private key are sent to the server, as the calculations are done on the server side
|
||||
</h5>
|
||||
@@ -140,14 +140,14 @@
|
||||
{{/enable_mixins_details}}
|
||||
|
||||
{{^inputs_xmr_sum_not_zero}}
|
||||
- <h3>{{inputs_no}} input(s) for total of {{inputs_xmr_sum}} xmr</h3>
|
||||
+ <h3>{{inputs_no}} input(s) for total of {{inputs_xmr_sum}} wow</h3>
|
||||
{{/inputs_xmr_sum_not_zero}}
|
||||
{{#inputs_xmr_sum_not_zero}}
|
||||
{{^have_any_unknown_amount}}
|
||||
- <h3>{{inputs_no}} inputs(s) for total of {{inputs_xmr_sum}} xmr</h3>
|
||||
+ <h3>{{inputs_no}} inputs(s) for total of {{inputs_xmr_sum}} wow</h3>
|
||||
{{/have_any_unknown_amount}}
|
||||
{{#have_any_unknown_amount}}
|
||||
- <h3>{{inputs_no}} inputs(s) for total of at least {{inputs_xmr_sum}} xmr</h3>
|
||||
+ <h3>{{inputs_no}} inputs(s) for total of at least {{inputs_xmr_sum}} wow</h3>
|
||||
{{/have_any_unknown_amount}}
|
||||
{{/inputs_xmr_sum_not_zero}}
|
||||
|
||||
diff --git a/src/templates/rawtx.html b/src/templates/rawtx.html
|
||||
index 6419c9f..058b034 100644
|
||||
--- a/src/templates/rawtx.html
|
||||
+++ b/src/templates/rawtx.html
|
||||
@@ -9,12 +9,12 @@
|
||||
<div class="center">
|
||||
<form action="/checkandpush" method="post" style="width:100%; margin-top:15px" class="style-1">
|
||||
Paste here either a hex string of raw transaction<br/>
|
||||
- (the <i>tx_blob</i> response in the wallet RPC, or the <i>raw_monero_tx</i>
|
||||
+ (the <i>tx_blob</i> response in the wallet RPC, or the <i>raw_wownero_tx</i>
|
||||
file saved by the wallet CLI with <i>--do-not-relay</i> option specified),<br/>
|
||||
or base64 encoded, unsigned or signed transaction data<br/>
|
||||
<br/>
|
||||
- (In Linux, can get the raw tx data: <i>cat raw_monero_tx | xclip -selection clipboard</i>)<br/>
|
||||
- (In Windows, can get the raw tx data: <i>certutil.exe -encode -f raw_monero_tx encoded.txt & type "encoded.txt" | clip</i>)<br/>
|
||||
+ (In Linux, can get the raw tx data: <i>cat raw_wownero_tx | xclip -selection clipboard</i>)<br/>
|
||||
+ (In Windows, can get the raw tx data: <i>certutil.exe -encode -f raw_wownero_tx encoded.txt & type "encoded.txt" | clip</i>)<br/>
|
||||
|
||||
<textarea name="rawtxdata" rows="20" cols="80"></textarea>
|
||||
<br/>
|
||||
diff --git a/src/tools.h b/src/tools.h
|
||||
index d511e1b..725c9bb 100644
|
||||
--- a/src/tools.h
|
||||
+++ b/src/tools.h
|
||||
@@ -8,7 +8,7 @@
|
||||
#define PATH_SEPARARTOR '/'
|
||||
|
||||
#define XMR_AMOUNT(value) \
|
||||
- static_cast<double>(value) / 1e12
|
||||
+ static_cast<double>(value) / 1e11
|
||||
|
||||
#define REMOVE_HASH_BRAKETS(a_hash) \
|
||||
a_hash.substr(1, a_hash.size()-2)
|
||||
@@ -224,7 +224,7 @@ get_payment_id(const transaction& tx,
|
||||
inline double
|
||||
get_xmr(uint64_t core_amount)
|
||||
{
|
||||
- return static_cast<double>(core_amount) / 1e12;
|
||||
+ return static_cast<double>(core_amount) / 1e11;
|
||||
}
|
||||
|
||||
array<size_t, 5>
|
||||
+11495
File diff suppressed because it is too large
Load Diff
@@ -1,9 +1,9 @@
|
||||
#define CROW_ENABLE_SSL
|
||||
|
||||
#define CROW_MAIN
|
||||
|
||||
#include "src/page.h"
|
||||
|
||||
#include "ext/crow/crow.h"
|
||||
#include "ext/crow_all.h"
|
||||
#include "src/CmdLineOptions.h"
|
||||
#include "src/MicroCore.h"
|
||||
|
||||
@@ -56,7 +56,7 @@ main(int ac, const char* av[])
|
||||
auto port_opt = opts.get_option<string>("port");
|
||||
auto bindaddr_opt = opts.get_option<string>("bindaddr");
|
||||
auto bc_path_opt = opts.get_option<string>("bc-path");
|
||||
auto deamon_url_opt = opts.get_option<string>("deamon-url");
|
||||
auto daemon_url_opt = opts.get_option<string>("daemon-url");
|
||||
auto ssl_crt_file_opt = opts.get_option<string>("ssl-crt-file");
|
||||
auto ssl_key_file_opt = opts.get_option<string>("ssl-key-file");
|
||||
auto no_blocks_on_index_opt = opts.get_option<string>("no-blocks-on-index");
|
||||
@@ -76,6 +76,7 @@ main(int ac, const char* av[])
|
||||
auto enable_mixin_details_opt = opts.get_option<bool>("enable-mixin-details");
|
||||
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_mixin_guess_opt = opts.get_option<bool>("enable-mixin-guess");
|
||||
auto concurrency_opt = opts.get_option<size_t>("concurrency");
|
||||
auto enable_emission_monitor_opt = opts.get_option<bool>("enable-emission-monitor");
|
||||
|
||||
@@ -99,10 +100,16 @@ main(int ac, const char* av[])
|
||||
bool enable_autorefresh_option {*enable_autorefresh_option_opt};
|
||||
bool enable_output_key_checker {*enable_output_key_checker_opt};
|
||||
bool enable_mixin_details {*enable_mixin_details_opt};
|
||||
bool enable_mixin_guess {*enable_mixin_guess_opt};
|
||||
bool enable_json_api {*enable_json_api_opt};
|
||||
bool enable_as_hex {*enable_as_hex_opt};
|
||||
bool enable_emission_monitor {*enable_emission_monitor_opt};
|
||||
|
||||
//temprorary disable randomx
|
||||
if (enable_randomx == true) {
|
||||
cout << "Support for randomx code is disabled due to issues with it"<< endl;
|
||||
enable_randomx = false;
|
||||
}
|
||||
|
||||
// set monero log output level
|
||||
uint32_t log_level = 0;
|
||||
@@ -205,12 +212,12 @@ main(int ac, const char* av[])
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
string deamon_url {*deamon_url_opt};
|
||||
string daemon_url {*daemon_url_opt};
|
||||
|
||||
if (testnet && deamon_url == "http:://127.0.0.1:34568")
|
||||
deamon_url = "http:://127.0.0.1:11181";
|
||||
if (stagenet && deamon_url == "http:://127.0.0.1:34568")
|
||||
deamon_url = "http:://127.0.0.1:38081";
|
||||
if (testnet && daemon_url == "127.0.0.1:34568")
|
||||
daemon_url = "127.0.0.1:11181";
|
||||
if (stagenet && daemon_url == "127.0.0.1:34568")
|
||||
daemon_url = "127.0.0.1:38081";
|
||||
|
||||
uint64_t mempool_info_timeout {5000};
|
||||
|
||||
@@ -247,8 +254,8 @@ main(int ac, const char* av[])
|
||||
= blockchain_path;
|
||||
xmreg::CurrentBlockchainStatus::nettype
|
||||
= nettype;
|
||||
xmreg::CurrentBlockchainStatus::deamon_url
|
||||
= deamon_url;
|
||||
xmreg::CurrentBlockchainStatus::daemon_url
|
||||
= daemon_url;
|
||||
xmreg::CurrentBlockchainStatus::set_blockchain_variables(
|
||||
&mcore, core_storage);
|
||||
|
||||
@@ -264,8 +271,8 @@ main(int ac, const char* av[])
|
||||
= blockchain_path;
|
||||
xmreg::MempoolStatus::nettype
|
||||
= nettype;
|
||||
xmreg::MempoolStatus::deamon_url
|
||||
= deamon_url;
|
||||
xmreg::MempoolStatus::daemon_url
|
||||
= daemon_url;
|
||||
xmreg::MempoolStatus::login
|
||||
= daemon_rpc_login;
|
||||
xmreg::MempoolStatus::set_blockchain_variables(
|
||||
@@ -299,7 +306,7 @@ main(int ac, const char* av[])
|
||||
// contains logic for the website
|
||||
xmreg::page xmrblocks(&mcore,
|
||||
core_storage,
|
||||
deamon_url,
|
||||
daemon_url,
|
||||
nettype,
|
||||
enable_pusher,
|
||||
enable_randomx,
|
||||
@@ -308,6 +315,7 @@ main(int ac, const char* av[])
|
||||
enable_output_key_checker,
|
||||
enable_autorefresh_option,
|
||||
enable_mixin_details,
|
||||
enable_mixin_guess,
|
||||
no_blocks_on_index,
|
||||
mempool_info_timeout,
|
||||
*testnet_url,
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace xmreg
|
||||
p.add("txhash", -1);
|
||||
|
||||
options_description desc(
|
||||
"xmrblocks, Wownero Blockchain Explorer");
|
||||
"xmrblocks, Onion Wownero Blockchain Explorer");
|
||||
|
||||
desc.add_options()
|
||||
("help,h", value<bool>()->default_value(false)->implicit_value(true),
|
||||
@@ -71,8 +71,10 @@ namespace xmreg
|
||||
"path to key file for ssl (https) functionality")
|
||||
("daemon-login", value<string>(),
|
||||
"Specify username[:password] for daemon RPC client")
|
||||
("deamon-url,d", value<string>()->default_value("http:://127.0.0.1:18081"),
|
||||
"Monero daemon url");
|
||||
("daemon-url,d", value<string>()->default_value("127.0.0.1:18081"),
|
||||
"Monero daemon url")
|
||||
("enable-mixin-guess", value<bool>()->default_value(false)->implicit_value(true),
|
||||
"enable guessing real outputs in key images based on viewkey");
|
||||
|
||||
|
||||
store(command_line_parser(acc, avv)
|
||||
|
||||
@@ -303,7 +303,7 @@ cryptonote::network_type CurrentBlockchainStatus::nettype {cryptonote::network_t
|
||||
|
||||
string CurrentBlockchainStatus::output_file {"emission_amount.txt"};
|
||||
|
||||
string CurrentBlockchainStatus::deamon_url {"http:://127.0.0.1:34568"};
|
||||
string CurrentBlockchainStatus::daemon_url {"http:://127.0.0.1:34568"};
|
||||
|
||||
uint64_t CurrentBlockchainStatus::blockchain_chunk_size {10000};
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ struct CurrentBlockchainStatus
|
||||
|
||||
static string output_file;
|
||||
|
||||
static string deamon_url;
|
||||
static string daemon_url;
|
||||
|
||||
// how many blocks to read before thread goes to sleep
|
||||
static uint64_t blockchain_chunk_size;
|
||||
|
||||
@@ -96,7 +96,7 @@ MempoolStatus::start_mempool_status_thread()
|
||||
bool
|
||||
MempoolStatus::read_mempool()
|
||||
{
|
||||
rpccalls rpc {deamon_url, login};
|
||||
rpccalls rpc {daemon_url, login};
|
||||
|
||||
string error_msg;
|
||||
|
||||
@@ -170,7 +170,7 @@ MempoolStatus::read_mempool()
|
||||
vector<txin_to_key> input_key_imgs;
|
||||
|
||||
// public keys and xmr amount of outputs
|
||||
vector<pair<txout_to_key, uint64_t>> output_pub_keys;
|
||||
vector<output_tuple_with_tag> output_pub_keys;
|
||||
|
||||
// sum xmr in inputs and ouputs in the given tx
|
||||
const array<uint64_t, 4>& sum_data = summary_of_in_out_rct(
|
||||
@@ -222,12 +222,15 @@ MempoolStatus::read_mempool()
|
||||
bool
|
||||
MempoolStatus::read_network_info()
|
||||
{
|
||||
rpccalls rpc {deamon_url, login};
|
||||
rpccalls rpc {daemon_url, login};
|
||||
|
||||
COMMAND_RPC_GET_INFO::response rpc_network_info;
|
||||
|
||||
if (!rpc.get_network_info(rpc_network_info))
|
||||
{
|
||||
cerr << "rpc.get_network_info(rpc_network_info) failed";
|
||||
return false;
|
||||
}
|
||||
|
||||
uint64_t fee_estimated;
|
||||
|
||||
@@ -326,7 +329,7 @@ MempoolStatus::is_thread_running()
|
||||
}
|
||||
|
||||
bf::path MempoolStatus::blockchain_path {"/home/mwo/.wownero/lmdb"};
|
||||
string MempoolStatus::deamon_url {"http:://127.0.0.1:34568"};
|
||||
string MempoolStatus::daemon_url {"http:://127.0.0.1:34568"};
|
||||
cryptonote::network_type MempoolStatus::nettype {cryptonote::network_type::MAINNET};
|
||||
atomic<bool> MempoolStatus::is_running {false};
|
||||
boost::thread MempoolStatus::m_thread;
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@ struct MempoolStatus
|
||||
static atomic<uint64_t> mempool_size; // size in bytes.
|
||||
|
||||
static bf::path blockchain_path;
|
||||
static string deamon_url;
|
||||
static string daemon_url;
|
||||
static cryptonote::network_type nettype;
|
||||
|
||||
static rpccalls::login_opt login;
|
||||
|
||||
+4
-18
@@ -211,12 +211,13 @@ MicroCore::find_output_in_tx(const transaction& tx,
|
||||
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);
|
||||
public_key found_output_pubkey;
|
||||
cryptonote::get_output_public_key(
|
||||
o, found_output_pubkey);
|
||||
|
||||
++idx;
|
||||
|
||||
return tx_in_to_key.key == output_pubkey;
|
||||
return found_output_pubkey == output_pubkey;
|
||||
});
|
||||
|
||||
if (it != tx.vout.end())
|
||||
@@ -248,21 +249,6 @@ MicroCore::get_blk_timestamp(uint64_t blk_height)
|
||||
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()
|
||||
{
|
||||
//m_blockchain_storage.get_db().close();
|
||||
delete &m_blockchain_storage.get_db();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
init_blockchain(const string& path,
|
||||
MicroCore& mcore,
|
||||
|
||||
@@ -73,8 +73,6 @@ namespace xmreg
|
||||
|
||||
hw::device* const
|
||||
get_device() const;
|
||||
|
||||
virtual ~MicroCore();
|
||||
};
|
||||
|
||||
|
||||
|
||||
+395
-232
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2019, The Monero Project
|
||||
// Copyright (c) 2019-2022, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "randomx.h"
|
||||
#include "c_threads.h"
|
||||
@@ -42,31 +43,38 @@
|
||||
|
||||
#define RX_LOGCAT "randomx"
|
||||
|
||||
static CTHR_RWLOCK_TYPE main_dataset_lock = CTHR_RWLOCK_INIT;
|
||||
static CTHR_RWLOCK_TYPE main_cache_lock = CTHR_RWLOCK_INIT;
|
||||
|
||||
static randomx_dataset *main_dataset = NULL;
|
||||
static randomx_cache *main_cache = NULL;
|
||||
static char main_seedhash[HASH_SIZE];
|
||||
static int main_seedhash_set = 0;
|
||||
|
||||
static CTHR_RWLOCK_TYPE secondary_cache_lock = CTHR_RWLOCK_INIT;
|
||||
|
||||
static randomx_cache *secondary_cache = NULL;
|
||||
static char secondary_seedhash[HASH_SIZE];
|
||||
static int secondary_seedhash_set = 0;
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define THREADV __declspec(thread)
|
||||
#else
|
||||
#define THREADV __thread
|
||||
#endif
|
||||
|
||||
typedef struct rx_state {
|
||||
CTHR_MUTEX_TYPE rs_mutex;
|
||||
char rs_hash[32];
|
||||
uint64_t rs_height;
|
||||
randomx_cache *rs_cache;
|
||||
} rx_state;
|
||||
THREADV randomx_vm *main_vm_full = NULL;
|
||||
static THREADV randomx_vm *main_vm_light = NULL;
|
||||
static THREADV randomx_vm *secondary_vm_light = NULL;
|
||||
|
||||
static CTHR_MUTEX_TYPE rx_mutex = CTHR_MUTEX_INIT;
|
||||
static CTHR_MUTEX_TYPE rx_dataset_mutex = CTHR_MUTEX_INIT;
|
||||
static THREADV uint32_t miner_thread = 0;
|
||||
|
||||
static rx_state rx_s[2] = {{CTHR_MUTEX_INIT,{0},0,0},{CTHR_MUTEX_INIT,{0},0,0}};
|
||||
|
||||
static randomx_dataset *rx_dataset;
|
||||
static uint64_t rx_dataset_height;
|
||||
THREADV randomx_vm *rx_vm = NULL;
|
||||
static THREADV int rx_toggle;
|
||||
static bool is_main(const char* seedhash) { return main_seedhash_set && (memcmp(seedhash, main_seedhash, HASH_SIZE) == 0); }
|
||||
static bool is_secondary(const char* seedhash) { return secondary_seedhash_set && (memcmp(seedhash, secondary_seedhash, HASH_SIZE) == 0); }
|
||||
|
||||
static void local_abort(const char *msg)
|
||||
{
|
||||
merror(RX_LOGCAT, "%s", msg);
|
||||
fprintf(stderr, "%s\n", msg);
|
||||
#ifdef NDEBUG
|
||||
_exit(1);
|
||||
@@ -75,108 +83,196 @@ static void local_abort(const char *msg)
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief uses cpuid to determine if the CPU supports the AES instructions
|
||||
* @return true if the CPU supports AES, false otherwise
|
||||
*/
|
||||
|
||||
static inline int force_software_aes(void)
|
||||
{
|
||||
static int use = -1;
|
||||
|
||||
if (use != -1)
|
||||
return use;
|
||||
|
||||
const char *env = getenv("MONERO_USE_SOFTWARE_AES");
|
||||
if (!env) {
|
||||
use = 0;
|
||||
static void hash2hex(const char* hash, char* hex) {
|
||||
const char* d = "0123456789abcdef";
|
||||
for (int i = 0; i < HASH_SIZE; ++i) {
|
||||
const uint8_t b = hash[i];
|
||||
hex[i * 2 + 0] = d[b >> 4];
|
||||
hex[i * 2 + 1] = d[b & 15];
|
||||
}
|
||||
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
|
||||
use = 0;
|
||||
hex[HASH_SIZE * 2] = '\0';
|
||||
}
|
||||
|
||||
static inline int disabled_flags(void) {
|
||||
static int flags = -1;
|
||||
|
||||
if (flags != -1) {
|
||||
return flags;
|
||||
}
|
||||
|
||||
const char *env = getenv("MONERO_RANDOMX_UMASK");
|
||||
if (!env) {
|
||||
flags = 0;
|
||||
}
|
||||
else {
|
||||
use = 1;
|
||||
char* endptr;
|
||||
long int value = strtol(env, &endptr, 0);
|
||||
if (endptr != env && value >= 0 && value < INT_MAX) {
|
||||
flags = value;
|
||||
}
|
||||
else {
|
||||
flags = 0;
|
||||
}
|
||||
}
|
||||
return use;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void cpuid(int CPUInfo[4], int InfoType)
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
__asm __volatile__
|
||||
(
|
||||
"cpuid":
|
||||
"=a" (CPUInfo[0]),
|
||||
"=b" (CPUInfo[1]),
|
||||
"=c" (CPUInfo[2]),
|
||||
"=d" (CPUInfo[3]) :
|
||||
"a" (InfoType), "c" (0)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
static inline int check_aes_hw(void)
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
int cpuid_results[4];
|
||||
static int supported = -1;
|
||||
static inline int enabled_flags(void) {
|
||||
static int flags = -1;
|
||||
|
||||
if(supported >= 0)
|
||||
return supported;
|
||||
|
||||
cpuid(cpuid_results,1);
|
||||
return supported = cpuid_results[2] & (1 << 25);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static volatile int use_rx_jit_flag = -1;
|
||||
|
||||
static inline int use_rx_jit(void)
|
||||
{
|
||||
#if defined(__x86_64__)
|
||||
|
||||
if (use_rx_jit_flag != -1)
|
||||
return use_rx_jit_flag;
|
||||
|
||||
const char *env = getenv("MONERO_USE_RX_JIT");
|
||||
if (!env) {
|
||||
use_rx_jit_flag = 1;
|
||||
if (flags != -1) {
|
||||
return flags;
|
||||
}
|
||||
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
|
||||
use_rx_jit_flag = 0;
|
||||
}
|
||||
else {
|
||||
use_rx_jit_flag = 1;
|
||||
}
|
||||
return use_rx_jit_flag;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
flags = randomx_get_flags();
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
#define SEEDHASH_EPOCH_BLOCKS 2048 /* Must be same as BLOCKS_SYNCHRONIZING_MAX_COUNT in cryptonote_config.h */
|
||||
#define SEEDHASH_EPOCH_LAG 64
|
||||
|
||||
void me_rx_reorg(const uint64_t split_height) {
|
||||
int i;
|
||||
CTHR_MUTEX_LOCK(rx_mutex);
|
||||
for (i=0; i<2; i++) {
|
||||
if (split_height < rx_s[i].rs_height)
|
||||
rx_s[i].rs_height = 1; /* set to an invalid seed height */
|
||||
static inline int is_power_of_2(uint64_t n) { return n && (n & (n-1)) == 0; }
|
||||
|
||||
static int get_seedhash_epoch_lag(void)
|
||||
{
|
||||
static unsigned int lag = (unsigned int)-1;
|
||||
if (lag != (unsigned int)-1)
|
||||
return lag;
|
||||
const char *e = getenv("SEEDHASH_EPOCH_LAG");
|
||||
if (e)
|
||||
{
|
||||
lag = atoi(e);
|
||||
if (lag > SEEDHASH_EPOCH_LAG || !is_power_of_2(lag))
|
||||
lag = SEEDHASH_EPOCH_LAG;
|
||||
}
|
||||
CTHR_MUTEX_UNLOCK(rx_mutex);
|
||||
else
|
||||
{
|
||||
lag = SEEDHASH_EPOCH_LAG;
|
||||
}
|
||||
return lag;
|
||||
}
|
||||
|
||||
static unsigned int get_seedhash_epoch_blocks(void)
|
||||
{
|
||||
static unsigned int blocks = (unsigned int)-1;
|
||||
if (blocks != (unsigned int)-1)
|
||||
return blocks;
|
||||
const char *e = getenv("SEEDHASH_EPOCH_BLOCKS");
|
||||
if (e)
|
||||
{
|
||||
blocks = atoi(e);
|
||||
if (blocks < 2 || blocks > SEEDHASH_EPOCH_BLOCKS || !is_power_of_2(blocks))
|
||||
blocks = SEEDHASH_EPOCH_BLOCKS;
|
||||
}
|
||||
else
|
||||
{
|
||||
blocks = SEEDHASH_EPOCH_BLOCKS;
|
||||
}
|
||||
return blocks;
|
||||
}
|
||||
|
||||
uint64_t me_rx_seedheight(const uint64_t height) {
|
||||
uint64_t s_height = (height <= SEEDHASH_EPOCH_BLOCKS+SEEDHASH_EPOCH_LAG) ? 0 :
|
||||
(height - SEEDHASH_EPOCH_LAG - 1) & ~(SEEDHASH_EPOCH_BLOCKS-1);
|
||||
const uint64_t seedhash_epoch_lag = get_seedhash_epoch_lag();
|
||||
const uint64_t seedhash_epoch_blocks = get_seedhash_epoch_blocks();
|
||||
uint64_t s_height = (height <= seedhash_epoch_blocks+seedhash_epoch_lag) ? 0 :
|
||||
(height - seedhash_epoch_lag - 1) & ~(seedhash_epoch_blocks-1);
|
||||
return s_height;
|
||||
}
|
||||
|
||||
void me_rx_seedheights(const uint64_t height, uint64_t *seedheight, uint64_t *nextheight) {
|
||||
*seedheight = me_rx_seedheight(height);
|
||||
*nextheight = me_rx_seedheight(height + SEEDHASH_EPOCH_LAG);
|
||||
*nextheight = me_rx_seedheight(height + get_seedhash_epoch_lag());
|
||||
}
|
||||
|
||||
static void rx_alloc_dataset(randomx_flags flags, randomx_dataset** dataset, int ignore_env)
|
||||
{
|
||||
if (*dataset) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (disabled_flags() & RANDOMX_FLAG_FULL_MEM) {
|
||||
static int shown = 0;
|
||||
if (!shown) {
|
||||
shown = 1;
|
||||
minfo(RX_LOGCAT, "RandomX dataset is disabled by MONERO_RANDOMX_UMASK environment variable.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ignore_env && !getenv("MONERO_RANDOMX_FULL_MEM")) {
|
||||
static int shown = 0;
|
||||
if (!shown) {
|
||||
shown = 1;
|
||||
minfo(RX_LOGCAT, "RandomX dataset is not enabled by default. Use MONERO_RANDOMX_FULL_MEM environment variable to enable it.");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
*dataset = randomx_alloc_dataset((flags | RANDOMX_FLAG_LARGE_PAGES) & ~disabled_flags());
|
||||
if (!*dataset) {
|
||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomX dataset using large pages");
|
||||
*dataset = randomx_alloc_dataset(flags & ~disabled_flags());
|
||||
if (!*dataset) {
|
||||
merror(RX_LOGCAT, "Couldn't allocate RandomX dataset");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_alloc_cache(randomx_flags flags, randomx_cache** cache)
|
||||
{
|
||||
if (*cache) {
|
||||
return;
|
||||
}
|
||||
|
||||
*cache = randomx_alloc_cache((flags | RANDOMX_FLAG_LARGE_PAGES) & ~disabled_flags());
|
||||
if (!*cache) {
|
||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomX cache using large pages");
|
||||
*cache = randomx_alloc_cache(flags & ~disabled_flags());
|
||||
if (!*cache) local_abort("Couldn't allocate RandomX cache");
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_init_full_vm(randomx_flags flags, randomx_vm** vm)
|
||||
{
|
||||
if (*vm || !main_dataset || (disabled_flags() & RANDOMX_FLAG_FULL_MEM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((flags & RANDOMX_FLAG_JIT) && !miner_thread) {
|
||||
flags |= RANDOMX_FLAG_SECURE;
|
||||
}
|
||||
|
||||
*vm = randomx_create_vm((flags | RANDOMX_FLAG_LARGE_PAGES | RANDOMX_FLAG_FULL_MEM) & ~disabled_flags(), NULL, main_dataset);
|
||||
if (!*vm) {
|
||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomX full VM using large pages");
|
||||
*vm = randomx_create_vm((flags | RANDOMX_FLAG_FULL_MEM) & ~disabled_flags(), NULL, main_dataset);
|
||||
if (!*vm) {
|
||||
merror(RX_LOGCAT, "Couldn't allocate RandomX full VM");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void rx_init_light_vm(randomx_flags flags, randomx_vm** vm, randomx_cache* cache)
|
||||
{
|
||||
if (*vm) {
|
||||
randomx_vm_set_cache(*vm, cache);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((flags & RANDOMX_FLAG_JIT) && !miner_thread) {
|
||||
flags |= RANDOMX_FLAG_SECURE;
|
||||
}
|
||||
|
||||
flags &= ~RANDOMX_FLAG_FULL_MEM;
|
||||
|
||||
*vm = randomx_create_vm((flags | RANDOMX_FLAG_LARGE_PAGES) & ~disabled_flags(), cache, NULL);
|
||||
if (!*vm) {
|
||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomX light VM using large pages");
|
||||
*vm = randomx_create_vm(flags & ~disabled_flags(), cache, NULL);
|
||||
if (!*vm) local_abort("Couldn't allocate RandomX light VM");
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct seedinfo {
|
||||
@@ -185,165 +281,232 @@ typedef struct seedinfo {
|
||||
unsigned long si_count;
|
||||
} seedinfo;
|
||||
|
||||
static CTHR_THREAD_RTYPE rx_seedthread(void *arg) {
|
||||
static CTHR_THREAD_RTYPE me_rx_seedthread(void *arg) {
|
||||
seedinfo *si = arg;
|
||||
randomx_init_dataset(rx_dataset, si->si_cache, si->si_start, si->si_count);
|
||||
randomx_init_dataset(main_dataset, si->si_cache, si->si_start, si->si_count);
|
||||
CTHR_THREAD_RETURN;
|
||||
}
|
||||
|
||||
static void rx_initdata(randomx_cache *rs_cache, const int miners, const uint64_t seedheight) {
|
||||
if (miners > 1) {
|
||||
unsigned long delta = randomx_dataset_item_count() / miners;
|
||||
unsigned long start = 0;
|
||||
int i;
|
||||
seedinfo *si;
|
||||
CTHR_THREAD_TYPE *st;
|
||||
si = malloc(miners * sizeof(seedinfo));
|
||||
if (si == NULL)
|
||||
local_abort("Couldn't allocate RandomX mining threadinfo");
|
||||
st = malloc(miners * sizeof(CTHR_THREAD_TYPE));
|
||||
if (st == NULL) {
|
||||
free(si);
|
||||
local_abort("Couldn't allocate RandomX mining threadlist");
|
||||
}
|
||||
for (i=0; i<miners-1; i++) {
|
||||
si[i].si_cache = rs_cache;
|
||||
si[i].si_start = start;
|
||||
si[i].si_count = delta;
|
||||
start += delta;
|
||||
}
|
||||
si[i].si_cache = rs_cache;
|
||||
static void me_rx_init_dataset(size_t max_threads) {
|
||||
if (!main_dataset) {
|
||||
return;
|
||||
}
|
||||
|
||||
// leave 2 CPU cores for other tasks
|
||||
const size_t num_threads = (max_threads < 4) ? 1 : (max_threads - 2);
|
||||
seedinfo* si = malloc(num_threads * sizeof(seedinfo));
|
||||
if (!si) local_abort("Couldn't allocate RandomX mining threadinfo");
|
||||
|
||||
const uint32_t delta = randomx_dataset_item_count() / num_threads;
|
||||
uint32_t start = 0;
|
||||
|
||||
const size_t n1 = num_threads - 1;
|
||||
for (size_t i = 0; i < n1; ++i) {
|
||||
si[i].si_cache = main_cache;
|
||||
si[i].si_start = start;
|
||||
si[i].si_count = randomx_dataset_item_count() - start;
|
||||
for (i=1; i<miners; i++) {
|
||||
CTHR_THREAD_CREATE(st[i], rx_seedthread, &si[i]);
|
||||
}
|
||||
randomx_init_dataset(rx_dataset, rs_cache, 0, si[0].si_count);
|
||||
for (i=1; i<miners; i++) {
|
||||
CTHR_THREAD_JOIN(st[i]);
|
||||
}
|
||||
free(st);
|
||||
free(si);
|
||||
} else {
|
||||
randomx_init_dataset(rx_dataset, rs_cache, 0, randomx_dataset_item_count());
|
||||
si[i].si_count = delta;
|
||||
start += delta;
|
||||
}
|
||||
rx_dataset_height = seedheight;
|
||||
|
||||
si[n1].si_cache = main_cache;
|
||||
si[n1].si_start = start;
|
||||
si[n1].si_count = randomx_dataset_item_count() - start;
|
||||
|
||||
CTHR_THREAD_TYPE *st = malloc(num_threads * sizeof(CTHR_THREAD_TYPE));
|
||||
if (!st) local_abort("Couldn't allocate RandomX mining threadlist");
|
||||
|
||||
CTHR_RWLOCK_LOCK_READ(main_cache_lock);
|
||||
for (size_t i = 0; i < n1; ++i) {
|
||||
if (!CTHR_THREAD_CREATE(st[i], me_rx_seedthread, &si[i])) {
|
||||
local_abort("Couldn't start RandomX seed thread");
|
||||
}
|
||||
}
|
||||
me_rx_seedthread(&si[n1]);
|
||||
for (size_t i = 0; i < n1; ++i) CTHR_THREAD_JOIN(st[i]);
|
||||
CTHR_RWLOCK_UNLOCK_READ(main_cache_lock);
|
||||
|
||||
free(st);
|
||||
free(si);
|
||||
|
||||
minfo(RX_LOGCAT, "RandomX dataset initialized");
|
||||
}
|
||||
|
||||
void me_rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, size_t length,
|
||||
char *hash, int miners, int is_alt) {
|
||||
uint64_t s_height = me_rx_seedheight(mainheight);
|
||||
int changed = 0;
|
||||
int toggle = is_alt ? s_height : seedheight;
|
||||
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
|
||||
rx_state *rx_sp;
|
||||
randomx_cache *cache;
|
||||
typedef struct thread_info {
|
||||
char seedhash[HASH_SIZE];
|
||||
size_t max_threads;
|
||||
} thread_info;
|
||||
|
||||
toggle = (toggle & SEEDHASH_EPOCH_BLOCKS) != 0;
|
||||
CTHR_MUTEX_LOCK(rx_mutex);
|
||||
static CTHR_THREAD_RTYPE me_rx_set_main_seedhash_thread(void *arg) {
|
||||
thread_info* info = arg;
|
||||
|
||||
/* if alt block but with same seed as mainchain, no need for alt cache */
|
||||
if (is_alt && s_height == seedheight && !memcmp(rx_s[toggle].rs_hash, seedhash, sizeof(rx_s[toggle].rs_hash)))
|
||||
is_alt = 0;
|
||||
CTHR_RWLOCK_LOCK_WRITE(main_dataset_lock);
|
||||
CTHR_RWLOCK_LOCK_WRITE(main_cache_lock);
|
||||
|
||||
/* RPC could request an earlier block on mainchain */
|
||||
if (!is_alt && s_height > seedheight)
|
||||
is_alt = 1;
|
||||
|
||||
toggle ^= (is_alt != 0);
|
||||
if (toggle != rx_toggle)
|
||||
changed = 1;
|
||||
rx_toggle = toggle;
|
||||
|
||||
rx_sp = &rx_s[toggle];
|
||||
CTHR_MUTEX_LOCK(rx_sp->rs_mutex);
|
||||
CTHR_MUTEX_UNLOCK(rx_mutex);
|
||||
|
||||
cache = rx_sp->rs_cache;
|
||||
if (cache == NULL) {
|
||||
if (use_rx_jit())
|
||||
flags |= RANDOMX_FLAG_JIT;
|
||||
if (cache == NULL) {
|
||||
cache = randomx_alloc_cache(flags | RANDOMX_FLAG_LARGE_PAGES);
|
||||
if (cache == NULL) {
|
||||
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomX cache");
|
||||
cache = randomx_alloc_cache(flags);
|
||||
}
|
||||
if (cache == NULL)
|
||||
local_abort("Couldn't allocate RandomX cache");
|
||||
}
|
||||
// Double check that seedhash wasn't already updated
|
||||
if (is_main(info->seedhash)) {
|
||||
CTHR_RWLOCK_UNLOCK_WRITE(main_cache_lock);
|
||||
CTHR_RWLOCK_UNLOCK_WRITE(main_dataset_lock);
|
||||
free(info);
|
||||
CTHR_THREAD_RETURN;
|
||||
}
|
||||
if (rx_sp->rs_height != seedheight || rx_sp->rs_cache == NULL || memcmp(seedhash, rx_sp->rs_hash, sizeof(rx_sp->rs_hash))) {
|
||||
randomx_init_cache(cache, seedhash, 32);
|
||||
rx_sp->rs_cache = cache;
|
||||
rx_sp->rs_height = seedheight;
|
||||
memcpy(rx_sp->rs_hash, seedhash, sizeof(rx_sp->rs_hash));
|
||||
changed = 1;
|
||||
memcpy(main_seedhash, info->seedhash, HASH_SIZE);
|
||||
main_seedhash_set = 1;
|
||||
|
||||
char buf[HASH_SIZE * 2 + 1];
|
||||
hash2hex(main_seedhash, buf);
|
||||
minfo(RX_LOGCAT, "RandomX new main seed hash is %s", buf);
|
||||
|
||||
const randomx_flags flags = enabled_flags() & ~disabled_flags();
|
||||
rx_alloc_dataset(flags, &main_dataset, 0);
|
||||
rx_alloc_cache(flags, &main_cache);
|
||||
|
||||
randomx_init_cache(main_cache, info->seedhash, HASH_SIZE);
|
||||
minfo(RX_LOGCAT, "RandomX main cache initialized");
|
||||
|
||||
CTHR_RWLOCK_UNLOCK_WRITE(main_cache_lock);
|
||||
|
||||
// From this point, rx_slow_hash can calculate hashes in light mode, but dataset is not initialized yet
|
||||
me_rx_init_dataset(info->max_threads);
|
||||
|
||||
CTHR_RWLOCK_UNLOCK_WRITE(main_dataset_lock);
|
||||
|
||||
free(info);
|
||||
CTHR_THREAD_RETURN;
|
||||
}
|
||||
|
||||
void me_rx_set_main_seedhash(const char *seedhash, size_t max_dataset_init_threads) {
|
||||
// Early out if seedhash didn't change
|
||||
if (is_main(seedhash)) {
|
||||
return;
|
||||
}
|
||||
if (rx_vm == NULL) {
|
||||
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
|
||||
if (use_rx_jit()) {
|
||||
flags |= RANDOMX_FLAG_JIT;
|
||||
if (!miners)
|
||||
flags |= RANDOMX_FLAG_SECURE;
|
||||
}
|
||||
if(!force_software_aes() && check_aes_hw())
|
||||
flags |= RANDOMX_FLAG_HARD_AES;
|
||||
if (miners) {
|
||||
CTHR_MUTEX_LOCK(rx_dataset_mutex);
|
||||
if (rx_dataset == NULL) {
|
||||
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_LARGE_PAGES);
|
||||
if (rx_dataset == NULL) {
|
||||
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomX dataset");
|
||||
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_DEFAULT);
|
||||
|
||||
// Update main cache and dataset in the background
|
||||
thread_info* info = malloc(sizeof(thread_info));
|
||||
if (!info) local_abort("Couldn't allocate RandomX mining threadinfo");
|
||||
|
||||
memcpy(info->seedhash, seedhash, HASH_SIZE);
|
||||
info->max_threads = max_dataset_init_threads;
|
||||
|
||||
CTHR_THREAD_TYPE t;
|
||||
if (!CTHR_THREAD_CREATE(t, me_rx_set_main_seedhash_thread, info)) {
|
||||
local_abort("Couldn't start RandomX seed thread");
|
||||
}
|
||||
}
|
||||
|
||||
void me_rx_slow_hash(const char *seedhash, const void *data, size_t length, char *result_hash) {
|
||||
const randomx_flags flags = enabled_flags() & ~disabled_flags();
|
||||
int success = 0;
|
||||
|
||||
// Fast path (seedhash == main_seedhash)
|
||||
// Multiple threads can run in parallel in fast or light mode, 1-2 ms or 10-15 ms per hash per thread
|
||||
if (is_main(seedhash)) {
|
||||
// If CTHR_RWLOCK_TRYLOCK_READ fails it means dataset is being initialized now, so use the light mode
|
||||
if (main_dataset && CTHR_RWLOCK_TRYLOCK_READ(main_dataset_lock)) {
|
||||
// Double check that main_seedhash didn't change
|
||||
if (is_main(seedhash)) {
|
||||
rx_init_full_vm(flags, &main_vm_full);
|
||||
if (main_vm_full) {
|
||||
randomx_calculate_hash(main_vm_full, data, length, result_hash);
|
||||
success = 1;
|
||||
}
|
||||
if (rx_dataset != NULL)
|
||||
rx_initdata(rx_sp->rs_cache, miners, seedheight);
|
||||
}
|
||||
if (rx_dataset != NULL)
|
||||
flags |= RANDOMX_FLAG_FULL_MEM;
|
||||
else {
|
||||
miners = 0;
|
||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomX dataset for miner");
|
||||
CTHR_RWLOCK_UNLOCK_READ(main_dataset_lock);
|
||||
} else {
|
||||
CTHR_RWLOCK_LOCK_READ(main_cache_lock);
|
||||
// Double check that main_seedhash didn't change
|
||||
if (is_main(seedhash)) {
|
||||
rx_init_light_vm(flags, &main_vm_light, main_cache);
|
||||
randomx_calculate_hash(main_vm_light, data, length, result_hash);
|
||||
success = 1;
|
||||
}
|
||||
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
|
||||
CTHR_RWLOCK_UNLOCK_READ(main_cache_lock);
|
||||
}
|
||||
rx_vm = randomx_create_vm(flags | RANDOMX_FLAG_LARGE_PAGES, rx_sp->rs_cache, rx_dataset);
|
||||
if(rx_vm == NULL) { //large pages failed
|
||||
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomX VM");
|
||||
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, rx_dataset);
|
||||
}
|
||||
if(rx_vm == NULL) {//fallback if everything fails
|
||||
flags = RANDOMX_FLAG_DEFAULT | (miners ? RANDOMX_FLAG_FULL_MEM : 0);
|
||||
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, rx_dataset);
|
||||
}
|
||||
if (rx_vm == NULL)
|
||||
local_abort("Couldn't allocate RandomX VM");
|
||||
} else if (miners) {
|
||||
CTHR_MUTEX_LOCK(rx_dataset_mutex);
|
||||
if (rx_dataset != NULL && rx_dataset_height != seedheight)
|
||||
rx_initdata(cache, miners, seedheight);
|
||||
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
|
||||
} else if (changed) {
|
||||
randomx_vm_set_cache(rx_vm, rx_sp->rs_cache);
|
||||
}
|
||||
/* mainchain users can run in parallel */
|
||||
if (!is_alt)
|
||||
CTHR_MUTEX_UNLOCK(rx_sp->rs_mutex);
|
||||
randomx_calculate_hash(rx_vm, data, length, hash);
|
||||
/* altchain slot users always get fully serialized */
|
||||
if (is_alt)
|
||||
CTHR_MUTEX_UNLOCK(rx_sp->rs_mutex);
|
||||
|
||||
if (success) {
|
||||
return;
|
||||
}
|
||||
|
||||
char buf[HASH_SIZE * 2 + 1];
|
||||
|
||||
// Slow path (seedhash != main_seedhash, but seedhash == secondary_seedhash)
|
||||
// Multiple threads can run in parallel in light mode, 10-15 ms per hash per thread
|
||||
if (!secondary_cache) {
|
||||
CTHR_RWLOCK_LOCK_WRITE(secondary_cache_lock);
|
||||
if (!secondary_cache) {
|
||||
hash2hex(seedhash, buf);
|
||||
minfo(RX_LOGCAT, "RandomX new secondary seed hash is %s", buf);
|
||||
|
||||
rx_alloc_cache(flags, &secondary_cache);
|
||||
randomx_init_cache(secondary_cache, seedhash, HASH_SIZE);
|
||||
minfo(RX_LOGCAT, "RandomX secondary cache updated");
|
||||
memcpy(secondary_seedhash, seedhash, HASH_SIZE);
|
||||
secondary_seedhash_set = 1;
|
||||
}
|
||||
CTHR_RWLOCK_UNLOCK_WRITE(secondary_cache_lock);
|
||||
}
|
||||
|
||||
CTHR_RWLOCK_LOCK_READ(secondary_cache_lock);
|
||||
if (is_secondary(seedhash)) {
|
||||
rx_init_light_vm(flags, &secondary_vm_light, secondary_cache);
|
||||
randomx_calculate_hash(secondary_vm_light, data, length, result_hash);
|
||||
success = 1;
|
||||
}
|
||||
CTHR_RWLOCK_UNLOCK_READ(secondary_cache_lock);
|
||||
|
||||
if (success) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Slowest path (seedhash != main_seedhash, seedhash != secondary_seedhash)
|
||||
// Only one thread runs at a time and updates secondary_seedhash if needed, up to 200-500 ms per hash
|
||||
CTHR_RWLOCK_LOCK_WRITE(secondary_cache_lock);
|
||||
if (!is_secondary(seedhash)) {
|
||||
hash2hex(seedhash, buf);
|
||||
minfo(RX_LOGCAT, "RandomX new secondary seed hash is %s", buf);
|
||||
|
||||
randomx_init_cache(secondary_cache, seedhash, HASH_SIZE);
|
||||
minfo(RX_LOGCAT, "RandomX secondary cache updated");
|
||||
memcpy(secondary_seedhash, seedhash, HASH_SIZE);
|
||||
secondary_seedhash_set = 1;
|
||||
}
|
||||
rx_init_light_vm(flags, &secondary_vm_light, secondary_cache);
|
||||
randomx_calculate_hash(secondary_vm_light, data, length, result_hash);
|
||||
CTHR_RWLOCK_UNLOCK_WRITE(secondary_cache_lock);
|
||||
}
|
||||
|
||||
void me_rx_slow_hash_allocate_state(void) {
|
||||
void me_rx_set_miner_thread(uint32_t value, size_t max_dataset_init_threads) {
|
||||
miner_thread = value;
|
||||
|
||||
// If dataset is not allocated yet, try to allocate and initialize it
|
||||
CTHR_RWLOCK_LOCK_WRITE(main_dataset_lock);
|
||||
if (main_dataset) {
|
||||
CTHR_RWLOCK_UNLOCK_WRITE(main_dataset_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
const randomx_flags flags = enabled_flags() & ~disabled_flags();
|
||||
rx_alloc_dataset(flags, &main_dataset, 1);
|
||||
me_rx_init_dataset(max_dataset_init_threads);
|
||||
|
||||
CTHR_RWLOCK_UNLOCK_WRITE(main_dataset_lock);
|
||||
}
|
||||
|
||||
void me_rx_slow_hash_free_state(void) {
|
||||
if (rx_vm != NULL) {
|
||||
randomx_destroy_vm(rx_vm);
|
||||
rx_vm = NULL;
|
||||
uint32_t me_rx_get_miner_thread() {
|
||||
return miner_thread;
|
||||
}
|
||||
|
||||
void me_rx_slow_hash_allocate_state() {}
|
||||
|
||||
static void me_rx_destroy_vm(randomx_vm** vm) {
|
||||
if (*vm) {
|
||||
randomx_destroy_vm(*vm);
|
||||
*vm = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void me_rx_slow_hash_free_state() {
|
||||
me_rx_destroy_vm(&main_vm_full);
|
||||
me_rx_destroy_vm(&main_vm_light);
|
||||
me_rx_destroy_vm(&secondary_vm_light);
|
||||
}
|
||||
|
||||
+582
-517
File diff suppressed because it is too large
Load Diff
+64
-37
@@ -9,26 +9,26 @@ namespace xmreg
|
||||
|
||||
|
||||
rpccalls::rpccalls(
|
||||
string _deamon_url,
|
||||
string _daemon_url,
|
||||
login_opt login,
|
||||
uint64_t _timeout)
|
||||
: deamon_url {_deamon_url},
|
||||
: daemon_url {_daemon_url},
|
||||
timeout_time {_timeout}
|
||||
{
|
||||
epee::net_utils::parse_url(deamon_url, url);
|
||||
epee::net_utils::parse_url(daemon_url, url);
|
||||
|
||||
port = std::to_string(url.port);
|
||||
|
||||
timeout_time_ms = std::chrono::milliseconds {timeout_time};
|
||||
|
||||
m_http_client.set_server(
|
||||
deamon_url,
|
||||
m_http_client.set_server(
|
||||
daemon_url,
|
||||
login,
|
||||
epee::net_utils::ssl_support_t::e_ssl_support_disabled);
|
||||
}
|
||||
|
||||
bool
|
||||
rpccalls::connect_to_monero_deamon()
|
||||
rpccalls::connect_to_monero_daemon()
|
||||
{
|
||||
//std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||
|
||||
@@ -40,6 +40,33 @@ rpccalls::connect_to_monero_deamon()
|
||||
return m_http_client.connect(timeout_time_ms);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
rpccalls::get_base_fee_estimate(uint64_t grace_blocks,
|
||||
uint64_t& fee_estimate) {
|
||||
|
||||
cryptonote::COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request req;
|
||||
cryptonote::COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response res;
|
||||
|
||||
req.grace_blocks = grace_blocks;
|
||||
|
||||
if (!connect_to_monero_daemon())
|
||||
{
|
||||
cerr << "get_base_fee_estimate: not connected to daemon" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool r = epee::net_utils::invoke_http_json(
|
||||
"/get_fee_estimate",
|
||||
req, res, m_http_client, timeout_time_ms);
|
||||
|
||||
fee_estimate = res.fee;
|
||||
|
||||
return r;
|
||||
|
||||
|
||||
}
|
||||
|
||||
uint64_t
|
||||
rpccalls::get_current_height()
|
||||
{
|
||||
@@ -48,9 +75,9 @@ rpccalls::get_current_height()
|
||||
|
||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||
|
||||
if (!connect_to_monero_deamon())
|
||||
if (!connect_to_monero_daemon())
|
||||
{
|
||||
cerr << "get_current_height: not connected to deamon" << endl;
|
||||
cerr << "get_current_height: not connected to daemon" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -60,8 +87,8 @@ rpccalls::get_current_height()
|
||||
|
||||
if (!r)
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon at "
|
||||
<< deamon_url << endl;
|
||||
cerr << "Error connecting to Monero daemon at "
|
||||
<< daemon_url << endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -80,9 +107,9 @@ rpccalls::get_mempool(vector<tx_info>& mempool_txs)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||
|
||||
if (!connect_to_monero_deamon())
|
||||
if (!connect_to_monero_daemon())
|
||||
{
|
||||
cerr << "get_mempool: not connected to deamon" << endl;
|
||||
cerr << "get_mempool: not connected to daemon" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -93,8 +120,8 @@ rpccalls::get_mempool(vector<tx_info>& mempool_txs)
|
||||
|
||||
if (!r || res.status != CORE_RPC_STATUS_OK)
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon at "
|
||||
<< deamon_url << endl;
|
||||
cerr << "Error connecting to Monero daemon at "
|
||||
<< daemon_url << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -127,9 +154,9 @@ rpccalls::commit_tx(tools::wallet2::pending_tx& ptx, string& error_msg)
|
||||
|
||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||
|
||||
if (!connect_to_monero_deamon())
|
||||
if (!connect_to_monero_daemon())
|
||||
{
|
||||
cerr << "commit_tx: not connected to deamon" << endl;
|
||||
cerr << "commit_tx: not connected to daemon" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -166,9 +193,9 @@ rpccalls::get_network_info(COMMAND_RPC_GET_INFO::response& response)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||
|
||||
if (!connect_to_monero_deamon())
|
||||
if (!connect_to_monero_daemon())
|
||||
{
|
||||
cerr << "get_network_info: not connected to deamon" << endl;
|
||||
cerr << "get_network_info: not connected to daemon" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -183,7 +210,7 @@ rpccalls::get_network_info(COMMAND_RPC_GET_INFO::response& response)
|
||||
{
|
||||
if (resp_t.result.status == CORE_RPC_STATUS_BUSY)
|
||||
{
|
||||
err = "daemon is busy. Please try again later.";
|
||||
err = "Daemon is busy. Please try again later.";
|
||||
}
|
||||
else if (resp_t.result.status != CORE_RPC_STATUS_OK)
|
||||
{
|
||||
@@ -192,15 +219,15 @@ rpccalls::get_network_info(COMMAND_RPC_GET_INFO::response& response)
|
||||
|
||||
if (!err.empty())
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon due to "
|
||||
cerr << "Error connecting to Monero daemon due to "
|
||||
<< err << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon at "
|
||||
<< deamon_url << endl;
|
||||
cerr << "Error connecting to Monero daemon at "
|
||||
<< daemon_url << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -226,9 +253,9 @@ rpccalls::get_hardfork_info(COMMAND_RPC_HARD_FORK_INFO::response& response)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||
|
||||
if (!connect_to_monero_deamon())
|
||||
if (!connect_to_monero_daemon())
|
||||
{
|
||||
cerr << "get_hardfork_info: not connected to deamon" << endl;
|
||||
cerr << "get_hardfork_info: not connected to daemon" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -253,15 +280,15 @@ rpccalls::get_hardfork_info(COMMAND_RPC_HARD_FORK_INFO::response& response)
|
||||
|
||||
if (!err.empty())
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon due to "
|
||||
cerr << "Error connecting to Monero daemon due to "
|
||||
<< err << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon at "
|
||||
<< deamon_url << endl;
|
||||
cerr << "Error connecting to Monero daemon at "
|
||||
<< daemon_url << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -294,9 +321,9 @@ rpccalls::get_dynamic_per_kb_fee_estimate(
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||
|
||||
if (!connect_to_monero_deamon())
|
||||
if (!connect_to_monero_daemon())
|
||||
{
|
||||
cerr << "get_dynamic_per_kb_fee_estimate: not connected to deamon" << endl;
|
||||
cerr << "get_dynamic_per_kb_fee_estimate: not connected to daemon" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -321,15 +348,15 @@ rpccalls::get_dynamic_per_kb_fee_estimate(
|
||||
|
||||
if (!err.empty())
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon due to "
|
||||
cerr << "Error connecting to Monero daemon due to "
|
||||
<< err << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon at "
|
||||
<< deamon_url << endl;
|
||||
cerr << "Error connecting to Monero daemon at "
|
||||
<< daemon_url << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -357,9 +384,9 @@ rpccalls::get_block(string const& blk_hash, block& blk, string& error_msg)
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||
|
||||
if (!connect_to_monero_deamon())
|
||||
if (!connect_to_monero_daemon())
|
||||
{
|
||||
cerr << "get_block: not connected to deamon" << endl;
|
||||
cerr << "get_block: not connected to daemon" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -384,15 +411,15 @@ rpccalls::get_block(string const& blk_hash, block& blk, string& error_msg)
|
||||
|
||||
if (!err.empty())
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon due to "
|
||||
cerr << "Error connecting to Monero daemon due to "
|
||||
<< err << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "get_block: error connecting to Monero deamon at "
|
||||
<< deamon_url << endl;
|
||||
cerr << "get_block: error connecting to Monero daemon at "
|
||||
<< daemon_url << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+12
-8
@@ -69,7 +69,7 @@ using namespace std;
|
||||
|
||||
class rpccalls
|
||||
{
|
||||
string deamon_url ;
|
||||
string daemon_url ;
|
||||
uint64_t timeout_time;
|
||||
|
||||
std::chrono::milliseconds timeout_time_ms;
|
||||
@@ -77,6 +77,7 @@ class rpccalls
|
||||
epee::net_utils::http::url_content url;
|
||||
|
||||
epee::net_utils::http::http_simple_client m_http_client;
|
||||
|
||||
std::mutex m_daemon_rpc_mutex;
|
||||
|
||||
string port;
|
||||
@@ -85,12 +86,12 @@ public:
|
||||
|
||||
using login_opt = boost::optional<epee::net_utils::http::login>;
|
||||
|
||||
rpccalls(string _deamon_url = "http:://127.0.0.1:34568",
|
||||
rpccalls(string _daemon_url = "http:://127.0.0.1:34568",
|
||||
login_opt _login = login_opt {},
|
||||
uint64_t _timeout = 200000);
|
||||
|
||||
bool
|
||||
connect_to_monero_deamon();
|
||||
connect_to_monero_daemon();
|
||||
|
||||
uint64_t
|
||||
get_current_height();
|
||||
@@ -104,6 +105,9 @@ public:
|
||||
bool
|
||||
get_network_info(COMMAND_RPC_GET_INFO::response& info);
|
||||
|
||||
bool
|
||||
get_base_fee_estimate(uint64_t grace_blocks, uint64_t& fee_estimate);
|
||||
|
||||
bool
|
||||
get_hardfork_info( COMMAND_RPC_HARD_FORK_INFO::response& res);
|
||||
|
||||
@@ -135,9 +139,9 @@ public:
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
||||
|
||||
if (!connect_to_monero_deamon())
|
||||
if (!connect_to_monero_daemon())
|
||||
{
|
||||
cerr << "get_alt_blocks: not connected to deamon" << endl;
|
||||
cerr << "get_alt_blocks: not connected to daemon" << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -161,15 +165,15 @@ public:
|
||||
|
||||
if (!err.empty())
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon due to "
|
||||
cerr << "Error connecting to Monero daemon due to "
|
||||
<< err << endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "Error connecting to Monero deamon at "
|
||||
<< deamon_url << endl;
|
||||
cerr << "Error connecting to Monero daemon at "
|
||||
<< daemon_url << endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
|
||||
<table class="center">
|
||||
<tr>
|
||||
<td>Timestamp [UCT] (epoch):</td><td>{{blk_timestamp}} ({{blk_timestamp_epoch}})</td>
|
||||
<td>Timestamp [UTC] (epoch):</td><td>{{blk_timestamp}} ({{blk_timestamp_epoch}})</td>
|
||||
<td>Age {{age_format}}:</td><td>{{blk_age}}</td>
|
||||
<td>Δ [h:m:s]:</td><td>{{delta_time}}</td>
|
||||
</tr>
|
||||
|
||||
@@ -29,6 +29,7 @@ tr, li, #pages, .info {
|
||||
|
||||
td {
|
||||
text-align: center;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
a:link {
|
||||
@@ -70,7 +71,7 @@ form {
|
||||
|
||||
.tabs {
|
||||
position: relative;
|
||||
min-height: 220px; /* This part sucks */
|
||||
min-height: 240px;
|
||||
clear: both;
|
||||
margin: 25px 0;
|
||||
}
|
||||
@@ -101,6 +102,7 @@ form {
|
||||
bottom: 0;
|
||||
padding: 20px;
|
||||
border: 1px solid #ccc;
|
||||
display: none;
|
||||
}
|
||||
|
||||
[type=radio]:checked ~ label {
|
||||
@@ -113,6 +115,11 @@ form {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#tab-1:checked ~ .content.tab-1,
|
||||
#tab-2:checked ~ .content.tab-2 {
|
||||
display: block;
|
||||
}
|
||||
|
||||
input#toggle-1[type=checkbox] {
|
||||
position: absolute;
|
||||
/*top: -9999px;*/
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
{{#refresh}}
|
||||
<meta http-equiv="refresh" content="10">
|
||||
{{/refresh}}
|
||||
<title>Wownero Blockchain Explorer</title>
|
||||
<title>Onion Wownero Blockchain Explorer</title>
|
||||
<!--<link rel="stylesheet" type="text/css" href="/css/style.css">-->
|
||||
<style type="text/css">
|
||||
{{#css_styles}}{{/css_styles}}
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
|
||||
{{#emission}}
|
||||
<h3 style="font-size: 12px; margin-top: 2px">
|
||||
Wownero emission is {{amount}} ({{fee_amount}} fees) as of {{blk_no}} block
|
||||
Wownero emission (fees) is {{amount}} ({{fee_amount}}) as of {{blk_no}} block
|
||||
</h3>
|
||||
{{/emission}}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
<table class="center" style="width: 80%; margin-top:10px">
|
||||
<tr>
|
||||
<td>Block: {{blk_height}}</td>
|
||||
<td>Timestamp [UCT]: {{blk_timestamp}}</td>
|
||||
<td>Timestamp [UTC]: {{blk_timestamp}}</td>
|
||||
<td>Age [y:d:h:m:s]: {{delta_time}}</td>
|
||||
<td>Fee: {{tx_fee}}</td>
|
||||
<td>Tx size: {{tx_size}} kB</td>
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
{{^have_raw_tx}}
|
||||
<tr>
|
||||
<td>Timestamp: {{blk_timestamp_uint}}</td>
|
||||
<td>Timestamp [UCT]: {{blk_timestamp}}</td>
|
||||
<td>Timestamp [UTC]: {{blk_timestamp}}</td>
|
||||
<td>Age [y:d:h:m:s]: {{delta_time}}</td>
|
||||
</tr>
|
||||
{{/have_raw_tx}}
|
||||
@@ -62,12 +62,14 @@
|
||||
<td>stealth address</td>
|
||||
<td>amount</td>
|
||||
<td>amount idx</td>
|
||||
<td>tag</td>
|
||||
</tr>
|
||||
{{#outputs}}
|
||||
<tr>
|
||||
<td>{{output_idx}}: {{out_pub_key}}</td>
|
||||
<td>{{amount}}</td>
|
||||
<td>{{amount_idx}} of {{num_outputs}}</td>
|
||||
<td>{{output_tag}}</td>
|
||||
</tr>
|
||||
{{/outputs}}
|
||||
</table>
|
||||
@@ -80,7 +82,7 @@
|
||||
<div class="tab">
|
||||
<input type="radio" id="tab-1" name="tab-group-1" checked>
|
||||
<label for="tab-1">Decode outputs</label>
|
||||
<div class="content">
|
||||
<div class="content tab-1">
|
||||
<h4 style="margin: 0px">Check which outputs belong to given Wownero address/subaddress and viewkey</h4>
|
||||
<h5 style="margin: 0px">
|
||||
For RingCT transactions, outputs' amounts are also decoded
|
||||
@@ -89,7 +91,7 @@
|
||||
</h5>
|
||||
<form action="/myoutputs" method="post" style="width:100%; margin-top:2px" class="style-1">
|
||||
<input type="hidden" name="tx_hash" value="{{tx_hash}}"><br/>
|
||||
<input type="text" name="xmr_address" size="110" placeholder="Wownero address/subaddress"><br/>
|
||||
<input type="text" name="xmr_address" size="110" placeholder="Monero address/subaddress"><br/>
|
||||
<input type="text" name="viewkey" size="110" placeholder="Private viewkey" style="margin-top:5px"><br/>
|
||||
<input type="hidden" name="raw_tx_data" value="{{raw_tx_data}}">
|
||||
<!--above raw_tx_data field only used when checking raw tx data through tx pusher-->
|
||||
@@ -102,7 +104,7 @@
|
||||
<input type="radio" id="tab-2" name="tab-group-1">
|
||||
<label for="tab-2">Prove sending</label>
|
||||
|
||||
<div class="content">
|
||||
<div class="content tab-2">
|
||||
<h4 style="margin: 0px">Prove to someone that you have sent them Wownero in this transaction</h4>
|
||||
<h5 style="margin: 0px">
|
||||
Tx private key can be obtained using <i>get_tx_key</i>
|
||||
|
||||
+52
-35
@@ -345,7 +345,7 @@ sum_money_in_outputs(const json& _json)
|
||||
array<uint64_t, 4>
|
||||
summary_of_in_out_rct(
|
||||
const transaction& tx,
|
||||
vector<pair<txout_to_key, uint64_t>>& output_pub_keys,
|
||||
vector<output_tuple_with_tag>& output_pub_keys,
|
||||
vector<txin_to_key>& input_key_imgs)
|
||||
{
|
||||
|
||||
@@ -357,18 +357,28 @@ summary_of_in_out_rct(
|
||||
|
||||
for (const tx_out& txout: tx.vout)
|
||||
{
|
||||
if (txout.target.type() != typeid(txout_to_key))
|
||||
public_key output_pub_key;
|
||||
if (!cryptonote::get_output_public_key(txout, output_pub_key))
|
||||
{
|
||||
// push empty pair.
|
||||
output_pub_keys.push_back(pair<txout_to_key, uint64_t>{});
|
||||
output_pub_keys.push_back(output_tuple_with_tag {
|
||||
public_key{},
|
||||
uint64_t{},
|
||||
boost::none
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// get tx input key
|
||||
const txout_to_key& txout_key
|
||||
= boost::get<cryptonote::txout_to_key>(txout.target);
|
||||
boost::optional<view_tag> output_tag;
|
||||
|
||||
output_pub_keys.push_back(make_pair(txout_key, txout.amount));
|
||||
if (txout.target.type() == typeid(txout_to_tagged_key)) {
|
||||
output_tag = boost::get< txout_to_tagged_key >(txout.target).view_tag;
|
||||
}
|
||||
|
||||
output_pub_keys.push_back(
|
||||
make_tuple(output_pub_key,
|
||||
txout.amount,
|
||||
output_tag));
|
||||
|
||||
xmr_outputs += txout.amount;
|
||||
}
|
||||
@@ -617,51 +627,56 @@ sum_fees_in_txs(const vector<transaction>& txs)
|
||||
return fees_sum;
|
||||
}
|
||||
|
||||
|
||||
|
||||
vector<pair<txout_to_key, uint64_t>>
|
||||
vector<output_tuple_with_tag>
|
||||
get_ouputs(const transaction& tx)
|
||||
{
|
||||
vector<pair<txout_to_key, uint64_t>> outputs;
|
||||
vector<output_tuple_with_tag> outputs;
|
||||
|
||||
for (const tx_out& txout: tx.vout)
|
||||
{
|
||||
if (txout.target.type() != typeid(txout_to_key))
|
||||
public_key output_pub_key;
|
||||
if (!cryptonote::get_output_public_key(txout, output_pub_key))
|
||||
{
|
||||
// push empty pair.
|
||||
outputs.push_back(pair<txout_to_key, uint64_t>{});
|
||||
// push empty tuple.
|
||||
outputs.push_back(output_tuple_with_tag {
|
||||
public_key{},
|
||||
uint64_t{},
|
||||
boost::none
|
||||
});
|
||||
continue;
|
||||
}
|
||||
|
||||
// get tx input key
|
||||
const txout_to_key& txout_key
|
||||
= boost::get<cryptonote::txout_to_key>(txout.target);
|
||||
boost::optional<view_tag> output_tag;
|
||||
|
||||
outputs.push_back(make_pair(txout_key, txout.amount));
|
||||
if (txout.target.type() == typeid(txout_to_tagged_key)) {
|
||||
output_tag = boost::get< txout_to_tagged_key >(txout.target)
|
||||
.view_tag;
|
||||
}
|
||||
|
||||
outputs.push_back(make_tuple(output_pub_key,
|
||||
txout.amount,
|
||||
output_tag));
|
||||
}
|
||||
|
||||
return outputs;
|
||||
|
||||
};
|
||||
|
||||
vector<tuple<txout_to_key, uint64_t, uint64_t>>
|
||||
vector<tuple<public_key, uint64_t, uint64_t>>
|
||||
get_ouputs_tuple(const transaction& tx)
|
||||
{
|
||||
vector<tuple<txout_to_key, uint64_t, uint64_t>> outputs;
|
||||
vector<tuple<public_key, uint64_t, uint64_t>> outputs;
|
||||
|
||||
for (uint64_t n = 0; n < tx.vout.size(); ++n)
|
||||
{
|
||||
|
||||
if (tx.vout[n].target.type() != typeid(txout_to_key))
|
||||
public_key output_pub_key;
|
||||
if (!cryptonote::get_output_public_key(tx.vout[n], output_pub_key))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// get tx input key
|
||||
const txout_to_key& txout_key
|
||||
= boost::get<cryptonote::txout_to_key>(tx.vout[n].target);
|
||||
|
||||
outputs.push_back(make_tuple(txout_key, tx.vout[n].amount, n));
|
||||
outputs.push_back(make_tuple(output_pub_key, tx.vout[n].amount, n));
|
||||
}
|
||||
|
||||
return outputs;
|
||||
@@ -938,6 +953,7 @@ decode_ringct(rct::rctSig const& rv,
|
||||
case rct::RCTTypeBulletproof:
|
||||
case rct::RCTTypeBulletproof2:
|
||||
case rct::RCTTypeCLSAG:
|
||||
case rct::RCTTypeBulletproofPlus:
|
||||
amount = rct::decodeRctSimple(rv,
|
||||
rct::sk2rct(scalar1),
|
||||
i,
|
||||
@@ -946,11 +962,11 @@ decode_ringct(rct::rctSig const& rv,
|
||||
break;
|
||||
case rct::RCTTypeFull:
|
||||
amount = rct::decodeRct(rv,
|
||||
rct::sk2rct(scalar1),
|
||||
i,
|
||||
mask,
|
||||
hw::get_device("default"));
|
||||
break;
|
||||
rct::sk2rct(scalar1),
|
||||
i,
|
||||
mask,
|
||||
hw::get_device("default"));
|
||||
break;
|
||||
default:
|
||||
cerr << "Unsupported rct type: " << rv.type << '\n';
|
||||
return false;
|
||||
@@ -1147,7 +1163,8 @@ is_output_ours(const size_t& output_index,
|
||||
{
|
||||
cerr << "Cant get dervied key for: " << "\n"
|
||||
<< "pub_tx_key: " << pub_tx_key << " and "
|
||||
<< "prv_view_key" << private_view_key << endl;
|
||||
<< "prv_view_key" << epee::string_tools::pod_to_hex(unwrap(unwrap(private_view_key)))
|
||||
<< endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -1166,11 +1183,11 @@ is_output_ours(const size_t& output_index,
|
||||
//cout << "\n" << tx.vout.size() << " " << output_index << endl;
|
||||
|
||||
// get tx output public key
|
||||
const txout_to_key tx_out_to_key
|
||||
= boost::get<txout_to_key>(tx.vout[output_index].target);
|
||||
public_key output_pub_key;
|
||||
cryptonote::get_output_public_key(tx.vout[output_index], output_pub_key);
|
||||
|
||||
|
||||
if (tx_out_to_key.key == pubkey)
|
||||
if (output_pub_key == pubkey)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
+7
-3
@@ -49,6 +49,10 @@ namespace bf = boost::filesystem;
|
||||
|
||||
using json = nlohmann::json;
|
||||
|
||||
using output_tuple_with_tag = tuple<public_key,
|
||||
uint64_t,
|
||||
boost::optional<view_tag>>;
|
||||
|
||||
struct outputs_visitor
|
||||
{
|
||||
std::vector<crypto::public_key >& m_output_keys;
|
||||
@@ -154,7 +158,7 @@ sum_money_in_outputs(const json& _json);
|
||||
array<uint64_t, 4>
|
||||
summary_of_in_out_rct(
|
||||
const transaction& tx,
|
||||
vector<pair<txout_to_key, uint64_t>>& output_pub_keys,
|
||||
vector<output_tuple_with_tag>& output_pub_keys,
|
||||
vector<txin_to_key>& input_key_imgs);
|
||||
|
||||
// this version for mempool txs from json
|
||||
@@ -200,10 +204,10 @@ get_mixin_no(const json& _json);
|
||||
vector<uint64_t>
|
||||
get_mixin_no_in_txs(const vector<transaction>& txs);
|
||||
|
||||
vector<pair<txout_to_key, uint64_t>>
|
||||
vector<output_tuple_with_tag>
|
||||
get_ouputs(const transaction& tx);
|
||||
|
||||
vector<tuple<txout_to_key, uint64_t, uint64_t>>
|
||||
vector<tuple<public_key, uint64_t, uint64_t>>
|
||||
get_ouputs_tuple(const transaction& tx);
|
||||
|
||||
vector<txin_to_key>
|
||||
|
||||
Reference in New Issue
Block a user