mirror of
https://codeberg.org/wownero/onion-wownero-blockchain-explorer.git
synced 2026-10-17 05:41:26 +02:00
Rewowify using d7853cc48c on current xmrblocks codebase
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
|
.vscode
|
||||||
.sass-cache
|
.sass-cache
|
||||||
*.*~
|
*.*~
|
||||||
*.user
|
*.user
|
||||||
|
|||||||
+7
-8
@@ -6,7 +6,7 @@ set(PROJECT_NAME
|
|||||||
|
|
||||||
project(${PROJECT_NAME})
|
project(${PROJECT_NAME})
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -O3")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -O3")
|
||||||
@@ -14,7 +14,7 @@ endif()
|
|||||||
|
|
||||||
|
|
||||||
if (NOT MONERO_DIR)
|
if (NOT MONERO_DIR)
|
||||||
set(MONERO_DIR ~/wownero)
|
set(MONERO_DIR ~/src/wownero)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS MONERO_DIR ": ${MONERO_DIR}")
|
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}"
|
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${MONERO_BUILD_DIR}"
|
||||||
CACHE PATH "Add Monero directory for library searching")
|
CACHE PATH "Add Monero directory for library searching")
|
||||||
|
|
||||||
include(MyUtils)
|
include(MyUtils)
|
||||||
|
|
||||||
find_package(Monero)
|
find_package(Monero)
|
||||||
@@ -139,12 +138,13 @@ set(LIBRARIES
|
|||||||
myext
|
myext
|
||||||
mstch
|
mstch
|
||||||
wallet
|
wallet
|
||||||
|
cryptonote_core
|
||||||
|
cryptonote_basic
|
||||||
|
cryptonote_protocol
|
||||||
|
cryptonote_format_utils_basic
|
||||||
blockchain_db
|
blockchain_db
|
||||||
device
|
device
|
||||||
${WALLET_CRYPTO}
|
${WALLET_CRYPTO}
|
||||||
cryptonote_core
|
|
||||||
cryptonote_protocol
|
|
||||||
cryptonote_basic
|
|
||||||
multisig
|
multisig
|
||||||
daemonizer
|
daemonizer
|
||||||
blocks
|
blocks
|
||||||
@@ -165,7 +165,6 @@ set(LIBRARIES
|
|||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
pthread
|
pthread
|
||||||
unbound
|
unbound
|
||||||
curl
|
|
||||||
crypto
|
crypto
|
||||||
ssl)
|
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
|
find_library(Xmr_${L}_LIBRARY
|
||||||
NAMES ${l}
|
NAMES ${l}
|
||||||
PATHS ${CMAKE_LIBRARY_PATH}
|
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
|
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)
|
PROPERTY IMPORTED_LOCATION ${MONERO_BUILD_DIR}/src/ringct/libringct_basic.a)
|
||||||
endif()
|
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)
|
message(STATUS ${MONERO_SOURCE_DIR}/build)
|
||||||
|
|
||||||
@@ -76,7 +83,7 @@ include_directories(
|
|||||||
${MONERO_SOURCE_DIR}/src/crypto
|
${MONERO_SOURCE_DIR}/src/crypto
|
||||||
${MONERO_SOURCE_DIR}/src/crypto/wallet
|
${MONERO_SOURCE_DIR}/src/crypto/wallet
|
||||||
${MONERO_SOURCE_DIR}/external
|
${MONERO_SOURCE_DIR}/external
|
||||||
${MONERO_SOURCE_DIR}/external/RandomWOW/src
|
${MONERO_SOURCE_DIR}/external/randomwow/src
|
||||||
${MONERO_SOURCE_DIR}/build
|
${MONERO_SOURCE_DIR}/build
|
||||||
${MONERO_SOURCE_DIR}/external/easylogging++
|
${MONERO_SOURCE_DIR}/external/easylogging++
|
||||||
${MONERO_SOURCE_DIR}/contrib/epee/include
|
${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_ENABLE_SSL
|
||||||
|
#define CROW_MAIN
|
||||||
|
|
||||||
#include "src/page.h"
|
#include "src/page.h"
|
||||||
|
|
||||||
#include "ext/crow/crow.h"
|
#include "ext/crow_all.h"
|
||||||
#include "src/CmdLineOptions.h"
|
#include "src/CmdLineOptions.h"
|
||||||
#include "src/MicroCore.h"
|
#include "src/MicroCore.h"
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ main(int ac, const char* av[])
|
|||||||
auto port_opt = opts.get_option<string>("port");
|
auto port_opt = opts.get_option<string>("port");
|
||||||
auto bindaddr_opt = opts.get_option<string>("bindaddr");
|
auto bindaddr_opt = opts.get_option<string>("bindaddr");
|
||||||
auto bc_path_opt = opts.get_option<string>("bc-path");
|
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_crt_file_opt = opts.get_option<string>("ssl-crt-file");
|
||||||
auto ssl_key_file_opt = opts.get_option<string>("ssl-key-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");
|
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_mixin_details_opt = opts.get_option<bool>("enable-mixin-details");
|
||||||
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_mixin_guess_opt = opts.get_option<bool>("enable-mixin-guess");
|
||||||
auto concurrency_opt = opts.get_option<size_t>("concurrency");
|
auto concurrency_opt = opts.get_option<size_t>("concurrency");
|
||||||
auto enable_emission_monitor_opt = opts.get_option<bool>("enable-emission-monitor");
|
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_autorefresh_option {*enable_autorefresh_option_opt};
|
||||||
bool enable_output_key_checker {*enable_output_key_checker_opt};
|
bool enable_output_key_checker {*enable_output_key_checker_opt};
|
||||||
bool enable_mixin_details {*enable_mixin_details_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_json_api {*enable_json_api_opt};
|
||||||
bool enable_as_hex {*enable_as_hex_opt};
|
bool enable_as_hex {*enable_as_hex_opt};
|
||||||
bool enable_emission_monitor {*enable_emission_monitor_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
|
// set monero log output level
|
||||||
uint32_t log_level = 0;
|
uint32_t log_level = 0;
|
||||||
@@ -205,13 +212,13 @@ main(int ac, const char* av[])
|
|||||||
return EXIT_FAILURE;
|
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};
|
uint64_t mempool_info_timeout {5000};
|
||||||
|
|
||||||
try
|
try
|
||||||
@@ -247,8 +254,8 @@ main(int ac, const char* av[])
|
|||||||
= blockchain_path;
|
= blockchain_path;
|
||||||
xmreg::CurrentBlockchainStatus::nettype
|
xmreg::CurrentBlockchainStatus::nettype
|
||||||
= nettype;
|
= nettype;
|
||||||
xmreg::CurrentBlockchainStatus::deamon_url
|
xmreg::CurrentBlockchainStatus::daemon_url
|
||||||
= deamon_url;
|
= daemon_url;
|
||||||
xmreg::CurrentBlockchainStatus::set_blockchain_variables(
|
xmreg::CurrentBlockchainStatus::set_blockchain_variables(
|
||||||
&mcore, core_storage);
|
&mcore, core_storage);
|
||||||
|
|
||||||
@@ -264,8 +271,8 @@ main(int ac, const char* av[])
|
|||||||
= blockchain_path;
|
= blockchain_path;
|
||||||
xmreg::MempoolStatus::nettype
|
xmreg::MempoolStatus::nettype
|
||||||
= nettype;
|
= nettype;
|
||||||
xmreg::MempoolStatus::deamon_url
|
xmreg::MempoolStatus::daemon_url
|
||||||
= deamon_url;
|
= daemon_url;
|
||||||
xmreg::MempoolStatus::login
|
xmreg::MempoolStatus::login
|
||||||
= daemon_rpc_login;
|
= daemon_rpc_login;
|
||||||
xmreg::MempoolStatus::set_blockchain_variables(
|
xmreg::MempoolStatus::set_blockchain_variables(
|
||||||
@@ -299,7 +306,7 @@ main(int ac, const char* av[])
|
|||||||
// contains logic for the website
|
// contains logic for the website
|
||||||
xmreg::page xmrblocks(&mcore,
|
xmreg::page xmrblocks(&mcore,
|
||||||
core_storage,
|
core_storage,
|
||||||
deamon_url,
|
daemon_url,
|
||||||
nettype,
|
nettype,
|
||||||
enable_pusher,
|
enable_pusher,
|
||||||
enable_randomx,
|
enable_randomx,
|
||||||
@@ -308,6 +315,7 @@ main(int ac, const char* av[])
|
|||||||
enable_output_key_checker,
|
enable_output_key_checker,
|
||||||
enable_autorefresh_option,
|
enable_autorefresh_option,
|
||||||
enable_mixin_details,
|
enable_mixin_details,
|
||||||
|
enable_mixin_guess,
|
||||||
no_blocks_on_index,
|
no_blocks_on_index,
|
||||||
mempool_info_timeout,
|
mempool_info_timeout,
|
||||||
*testnet_url,
|
*testnet_url,
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace xmreg
|
|||||||
p.add("txhash", -1);
|
p.add("txhash", -1);
|
||||||
|
|
||||||
options_description desc(
|
options_description desc(
|
||||||
"xmrblocks, Wownero Blockchain Explorer");
|
"xmrblocks, Onion Wownero Blockchain Explorer");
|
||||||
|
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", value<bool>()->default_value(false)->implicit_value(true),
|
("help,h", value<bool>()->default_value(false)->implicit_value(true),
|
||||||
@@ -71,8 +71,10 @@ namespace xmreg
|
|||||||
"path to key file for ssl (https) functionality")
|
"path to key file for ssl (https) functionality")
|
||||||
("daemon-login", value<string>(),
|
("daemon-login", value<string>(),
|
||||||
"Specify username[:password] for daemon RPC client")
|
"Specify username[:password] for daemon RPC client")
|
||||||
("deamon-url,d", value<string>()->default_value("http:://127.0.0.1:18081"),
|
("daemon-url,d", value<string>()->default_value("127.0.0.1:18081"),
|
||||||
"Monero daemon url");
|
"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)
|
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::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};
|
uint64_t CurrentBlockchainStatus::blockchain_chunk_size {10000};
|
||||||
|
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ struct CurrentBlockchainStatus
|
|||||||
|
|
||||||
static string output_file;
|
static string output_file;
|
||||||
|
|
||||||
static string deamon_url;
|
static string daemon_url;
|
||||||
|
|
||||||
// how many blocks to read before thread goes to sleep
|
// how many blocks to read before thread goes to sleep
|
||||||
static uint64_t blockchain_chunk_size;
|
static uint64_t blockchain_chunk_size;
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ MempoolStatus::start_mempool_status_thread()
|
|||||||
bool
|
bool
|
||||||
MempoolStatus::read_mempool()
|
MempoolStatus::read_mempool()
|
||||||
{
|
{
|
||||||
rpccalls rpc {deamon_url, login};
|
rpccalls rpc {daemon_url, login};
|
||||||
|
|
||||||
string error_msg;
|
string error_msg;
|
||||||
|
|
||||||
@@ -170,7 +170,7 @@ MempoolStatus::read_mempool()
|
|||||||
vector<txin_to_key> input_key_imgs;
|
vector<txin_to_key> input_key_imgs;
|
||||||
|
|
||||||
// public keys and xmr amount of outputs
|
// 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
|
// sum xmr in inputs and ouputs in the given tx
|
||||||
const array<uint64_t, 4>& sum_data = summary_of_in_out_rct(
|
const array<uint64_t, 4>& sum_data = summary_of_in_out_rct(
|
||||||
@@ -222,12 +222,15 @@ MempoolStatus::read_mempool()
|
|||||||
bool
|
bool
|
||||||
MempoolStatus::read_network_info()
|
MempoolStatus::read_network_info()
|
||||||
{
|
{
|
||||||
rpccalls rpc {deamon_url, login};
|
rpccalls rpc {daemon_url, login};
|
||||||
|
|
||||||
COMMAND_RPC_GET_INFO::response rpc_network_info;
|
COMMAND_RPC_GET_INFO::response rpc_network_info;
|
||||||
|
|
||||||
if (!rpc.get_network_info(rpc_network_info))
|
if (!rpc.get_network_info(rpc_network_info))
|
||||||
|
{
|
||||||
|
cerr << "rpc.get_network_info(rpc_network_info) failed";
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t fee_estimated;
|
uint64_t fee_estimated;
|
||||||
|
|
||||||
@@ -326,7 +329,7 @@ MempoolStatus::is_thread_running()
|
|||||||
}
|
}
|
||||||
|
|
||||||
bf::path MempoolStatus::blockchain_path {"/home/mwo/.wownero/lmdb"};
|
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};
|
cryptonote::network_type MempoolStatus::nettype {cryptonote::network_type::MAINNET};
|
||||||
atomic<bool> MempoolStatus::is_running {false};
|
atomic<bool> MempoolStatus::is_running {false};
|
||||||
boost::thread MempoolStatus::m_thread;
|
boost::thread MempoolStatus::m_thread;
|
||||||
|
|||||||
+1
-1
@@ -125,7 +125,7 @@ struct MempoolStatus
|
|||||||
static atomic<uint64_t> mempool_size; // size in bytes.
|
static atomic<uint64_t> mempool_size; // size in bytes.
|
||||||
|
|
||||||
static bf::path blockchain_path;
|
static bf::path blockchain_path;
|
||||||
static string deamon_url;
|
static string daemon_url;
|
||||||
static cryptonote::network_type nettype;
|
static cryptonote::network_type nettype;
|
||||||
|
|
||||||
static rpccalls::login_opt login;
|
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(),
|
auto it = std::find_if(tx.vout.begin(), tx.vout.end(),
|
||||||
[&](const tx_out& o)
|
[&](const tx_out& o)
|
||||||
{
|
{
|
||||||
const txout_to_key& tx_in_to_key
|
public_key found_output_pubkey;
|
||||||
= boost::get<txout_to_key>(o.target);
|
cryptonote::get_output_public_key(
|
||||||
|
o, found_output_pubkey);
|
||||||
|
|
||||||
++idx;
|
++idx;
|
||||||
|
|
||||||
return tx_in_to_key.key == output_pubkey;
|
return found_output_pubkey == output_pubkey;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (it != tx.vout.end())
|
if (it != tx.vout.end())
|
||||||
@@ -248,21 +249,6 @@ MicroCore::get_blk_timestamp(uint64_t blk_height)
|
|||||||
return blk.timestamp;
|
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
|
bool
|
||||||
init_blockchain(const string& path,
|
init_blockchain(const string& path,
|
||||||
MicroCore& mcore,
|
MicroCore& mcore,
|
||||||
|
|||||||
@@ -73,8 +73,6 @@ namespace xmreg
|
|||||||
|
|
||||||
hw::device* const
|
hw::device* const
|
||||||
get_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.
|
// All rights reserved.
|
||||||
//
|
//
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <limits.h>
|
||||||
|
|
||||||
#include "randomx.h"
|
#include "randomx.h"
|
||||||
#include "c_threads.h"
|
#include "c_threads.h"
|
||||||
@@ -42,31 +43,38 @@
|
|||||||
|
|
||||||
#define RX_LOGCAT "randomx"
|
#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)
|
#if defined(_MSC_VER)
|
||||||
#define THREADV __declspec(thread)
|
#define THREADV __declspec(thread)
|
||||||
#else
|
#else
|
||||||
#define THREADV __thread
|
#define THREADV __thread
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct rx_state {
|
THREADV randomx_vm *main_vm_full = NULL;
|
||||||
CTHR_MUTEX_TYPE rs_mutex;
|
static THREADV randomx_vm *main_vm_light = NULL;
|
||||||
char rs_hash[32];
|
static THREADV randomx_vm *secondary_vm_light = NULL;
|
||||||
uint64_t rs_height;
|
|
||||||
randomx_cache *rs_cache;
|
|
||||||
} rx_state;
|
|
||||||
|
|
||||||
static CTHR_MUTEX_TYPE rx_mutex = CTHR_MUTEX_INIT;
|
static THREADV uint32_t miner_thread = 0;
|
||||||
static CTHR_MUTEX_TYPE rx_dataset_mutex = CTHR_MUTEX_INIT;
|
|
||||||
|
|
||||||
static rx_state rx_s[2] = {{CTHR_MUTEX_INIT,{0},0,0},{CTHR_MUTEX_INIT,{0},0,0}};
|
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 randomx_dataset *rx_dataset;
|
|
||||||
static uint64_t rx_dataset_height;
|
|
||||||
THREADV randomx_vm *rx_vm = NULL;
|
|
||||||
static THREADV int rx_toggle;
|
|
||||||
|
|
||||||
static void local_abort(const char *msg)
|
static void local_abort(const char *msg)
|
||||||
{
|
{
|
||||||
|
merror(RX_LOGCAT, "%s", msg);
|
||||||
fprintf(stderr, "%s\n", msg);
|
fprintf(stderr, "%s\n", msg);
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
_exit(1);
|
_exit(1);
|
||||||
@@ -75,108 +83,196 @@ static void local_abort(const char *msg)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
static void hash2hex(const char* hash, char* hex) {
|
||||||
* @brief uses cpuid to determine if the CPU supports the AES instructions
|
const char* d = "0123456789abcdef";
|
||||||
* @return true if the CPU supports AES, false otherwise
|
for (int i = 0; i < HASH_SIZE; ++i) {
|
||||||
*/
|
const uint8_t b = hash[i];
|
||||||
|
hex[i * 2 + 0] = d[b >> 4];
|
||||||
static inline int force_software_aes(void)
|
hex[i * 2 + 1] = d[b & 15];
|
||||||
{
|
|
||||||
static int use = -1;
|
|
||||||
|
|
||||||
if (use != -1)
|
|
||||||
return use;
|
|
||||||
|
|
||||||
const char *env = getenv("MONERO_USE_SOFTWARE_AES");
|
|
||||||
if (!env) {
|
|
||||||
use = 0;
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
|
hex[HASH_SIZE * 2] = '\0';
|
||||||
use = 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 {
|
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)
|
static inline int enabled_flags(void) {
|
||||||
{
|
static int flags = -1;
|
||||||
#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;
|
|
||||||
|
|
||||||
if(supported >= 0)
|
if (flags != -1) {
|
||||||
return supported;
|
return flags;
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
|
|
||||||
use_rx_jit_flag = 0;
|
flags = randomx_get_flags();
|
||||||
}
|
|
||||||
else {
|
return flags;
|
||||||
use_rx_jit_flag = 1;
|
|
||||||
}
|
|
||||||
return use_rx_jit_flag;
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SEEDHASH_EPOCH_BLOCKS 2048 /* Must be same as BLOCKS_SYNCHRONIZING_MAX_COUNT in cryptonote_config.h */
|
#define SEEDHASH_EPOCH_BLOCKS 2048 /* Must be same as BLOCKS_SYNCHRONIZING_MAX_COUNT in cryptonote_config.h */
|
||||||
#define SEEDHASH_EPOCH_LAG 64
|
#define SEEDHASH_EPOCH_LAG 64
|
||||||
|
|
||||||
void me_rx_reorg(const uint64_t split_height) {
|
static inline int is_power_of_2(uint64_t n) { return n && (n & (n-1)) == 0; }
|
||||||
int i;
|
|
||||||
CTHR_MUTEX_LOCK(rx_mutex);
|
static int get_seedhash_epoch_lag(void)
|
||||||
for (i=0; i<2; i++) {
|
{
|
||||||
if (split_height < rx_s[i].rs_height)
|
static unsigned int lag = (unsigned int)-1;
|
||||||
rx_s[i].rs_height = 1; /* set to an invalid seed height */
|
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 me_rx_seedheight(const uint64_t height) {
|
||||||
uint64_t s_height = (height <= SEEDHASH_EPOCH_BLOCKS+SEEDHASH_EPOCH_LAG) ? 0 :
|
const uint64_t seedhash_epoch_lag = get_seedhash_epoch_lag();
|
||||||
(height - SEEDHASH_EPOCH_LAG - 1) & ~(SEEDHASH_EPOCH_BLOCKS-1);
|
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;
|
return s_height;
|
||||||
}
|
}
|
||||||
|
|
||||||
void me_rx_seedheights(const uint64_t height, uint64_t *seedheight, uint64_t *nextheight) {
|
void me_rx_seedheights(const uint64_t height, uint64_t *seedheight, uint64_t *nextheight) {
|
||||||
*seedheight = me_rx_seedheight(height);
|
*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 {
|
typedef struct seedinfo {
|
||||||
@@ -185,165 +281,232 @@ typedef struct seedinfo {
|
|||||||
unsigned long si_count;
|
unsigned long si_count;
|
||||||
} seedinfo;
|
} seedinfo;
|
||||||
|
|
||||||
static CTHR_THREAD_RTYPE rx_seedthread(void *arg) {
|
static CTHR_THREAD_RTYPE me_rx_seedthread(void *arg) {
|
||||||
seedinfo *si = 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;
|
CTHR_THREAD_RETURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rx_initdata(randomx_cache *rs_cache, const int miners, const uint64_t seedheight) {
|
static void me_rx_init_dataset(size_t max_threads) {
|
||||||
if (miners > 1) {
|
if (!main_dataset) {
|
||||||
unsigned long delta = randomx_dataset_item_count() / miners;
|
return;
|
||||||
unsigned long start = 0;
|
}
|
||||||
int i;
|
|
||||||
seedinfo *si;
|
// leave 2 CPU cores for other tasks
|
||||||
CTHR_THREAD_TYPE *st;
|
const size_t num_threads = (max_threads < 4) ? 1 : (max_threads - 2);
|
||||||
si = malloc(miners * sizeof(seedinfo));
|
seedinfo* si = malloc(num_threads * sizeof(seedinfo));
|
||||||
if (si == NULL)
|
if (!si) local_abort("Couldn't allocate RandomX mining threadinfo");
|
||||||
local_abort("Couldn't allocate RandomX mining threadinfo");
|
|
||||||
st = malloc(miners * sizeof(CTHR_THREAD_TYPE));
|
const uint32_t delta = randomx_dataset_item_count() / num_threads;
|
||||||
if (st == NULL) {
|
uint32_t start = 0;
|
||||||
free(si);
|
|
||||||
local_abort("Couldn't allocate RandomX mining threadlist");
|
const size_t n1 = num_threads - 1;
|
||||||
}
|
for (size_t i = 0; i < n1; ++i) {
|
||||||
for (i=0; i<miners-1; i++) {
|
si[i].si_cache = main_cache;
|
||||||
si[i].si_cache = rs_cache;
|
|
||||||
si[i].si_start = start;
|
|
||||||
si[i].si_count = delta;
|
|
||||||
start += delta;
|
|
||||||
}
|
|
||||||
si[i].si_cache = rs_cache;
|
|
||||||
si[i].si_start = start;
|
si[i].si_start = start;
|
||||||
si[i].si_count = randomx_dataset_item_count() - start;
|
si[i].si_count = delta;
|
||||||
for (i=1; i<miners; i++) {
|
start += delta;
|
||||||
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());
|
|
||||||
}
|
}
|
||||||
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,
|
typedef struct thread_info {
|
||||||
char *hash, int miners, int is_alt) {
|
char seedhash[HASH_SIZE];
|
||||||
uint64_t s_height = me_rx_seedheight(mainheight);
|
size_t max_threads;
|
||||||
int changed = 0;
|
} thread_info;
|
||||||
int toggle = is_alt ? s_height : seedheight;
|
|
||||||
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
|
|
||||||
rx_state *rx_sp;
|
|
||||||
randomx_cache *cache;
|
|
||||||
|
|
||||||
toggle = (toggle & SEEDHASH_EPOCH_BLOCKS) != 0;
|
static CTHR_THREAD_RTYPE me_rx_set_main_seedhash_thread(void *arg) {
|
||||||
CTHR_MUTEX_LOCK(rx_mutex);
|
thread_info* info = arg;
|
||||||
|
|
||||||
/* if alt block but with same seed as mainchain, no need for alt cache */
|
CTHR_RWLOCK_LOCK_WRITE(main_dataset_lock);
|
||||||
if (is_alt && s_height == seedheight && !memcmp(rx_s[toggle].rs_hash, seedhash, sizeof(rx_s[toggle].rs_hash)))
|
CTHR_RWLOCK_LOCK_WRITE(main_cache_lock);
|
||||||
is_alt = 0;
|
|
||||||
|
|
||||||
/* RPC could request an earlier block on mainchain */
|
// Double check that seedhash wasn't already updated
|
||||||
if (!is_alt && s_height > seedheight)
|
if (is_main(info->seedhash)) {
|
||||||
is_alt = 1;
|
CTHR_RWLOCK_UNLOCK_WRITE(main_cache_lock);
|
||||||
|
CTHR_RWLOCK_UNLOCK_WRITE(main_dataset_lock);
|
||||||
toggle ^= (is_alt != 0);
|
free(info);
|
||||||
if (toggle != rx_toggle)
|
CTHR_THREAD_RETURN;
|
||||||
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");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (rx_sp->rs_height != seedheight || rx_sp->rs_cache == NULL || memcmp(seedhash, rx_sp->rs_hash, sizeof(rx_sp->rs_hash))) {
|
memcpy(main_seedhash, info->seedhash, HASH_SIZE);
|
||||||
randomx_init_cache(cache, seedhash, 32);
|
main_seedhash_set = 1;
|
||||||
rx_sp->rs_cache = cache;
|
|
||||||
rx_sp->rs_height = seedheight;
|
char buf[HASH_SIZE * 2 + 1];
|
||||||
memcpy(rx_sp->rs_hash, seedhash, sizeof(rx_sp->rs_hash));
|
hash2hex(main_seedhash, buf);
|
||||||
changed = 1;
|
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;
|
// Update main cache and dataset in the background
|
||||||
if (use_rx_jit()) {
|
thread_info* info = malloc(sizeof(thread_info));
|
||||||
flags |= RANDOMX_FLAG_JIT;
|
if (!info) local_abort("Couldn't allocate RandomX mining threadinfo");
|
||||||
if (!miners)
|
|
||||||
flags |= RANDOMX_FLAG_SECURE;
|
memcpy(info->seedhash, seedhash, HASH_SIZE);
|
||||||
}
|
info->max_threads = max_dataset_init_threads;
|
||||||
if(!force_software_aes() && check_aes_hw())
|
|
||||||
flags |= RANDOMX_FLAG_HARD_AES;
|
CTHR_THREAD_TYPE t;
|
||||||
if (miners) {
|
if (!CTHR_THREAD_CREATE(t, me_rx_set_main_seedhash_thread, info)) {
|
||||||
CTHR_MUTEX_LOCK(rx_dataset_mutex);
|
local_abort("Couldn't start RandomX seed thread");
|
||||||
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");
|
void me_rx_slow_hash(const char *seedhash, const void *data, size_t length, char *result_hash) {
|
||||||
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_DEFAULT);
|
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)
|
CTHR_RWLOCK_UNLOCK_READ(main_dataset_lock);
|
||||||
flags |= RANDOMX_FLAG_FULL_MEM;
|
} else {
|
||||||
else {
|
CTHR_RWLOCK_LOCK_READ(main_cache_lock);
|
||||||
miners = 0;
|
// Double check that main_seedhash didn't change
|
||||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomX dataset for miner");
|
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)
|
if (success) {
|
||||||
CTHR_MUTEX_UNLOCK(rx_sp->rs_mutex);
|
return;
|
||||||
randomx_calculate_hash(rx_vm, data, length, hash);
|
}
|
||||||
/* altchain slot users always get fully serialized */
|
|
||||||
if (is_alt)
|
char buf[HASH_SIZE * 2 + 1];
|
||||||
CTHR_MUTEX_UNLOCK(rx_sp->rs_mutex);
|
|
||||||
|
// 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) {
|
uint32_t me_rx_get_miner_thread() {
|
||||||
if (rx_vm != NULL) {
|
return miner_thread;
|
||||||
randomx_destroy_vm(rx_vm);
|
}
|
||||||
rx_vm = NULL;
|
|
||||||
|
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(
|
rpccalls::rpccalls(
|
||||||
string _deamon_url,
|
string _daemon_url,
|
||||||
login_opt login,
|
login_opt login,
|
||||||
uint64_t _timeout)
|
uint64_t _timeout)
|
||||||
: deamon_url {_deamon_url},
|
: daemon_url {_daemon_url},
|
||||||
timeout_time {_timeout}
|
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);
|
port = std::to_string(url.port);
|
||||||
|
|
||||||
timeout_time_ms = std::chrono::milliseconds {timeout_time};
|
timeout_time_ms = std::chrono::milliseconds {timeout_time};
|
||||||
|
|
||||||
m_http_client.set_server(
|
m_http_client.set_server(
|
||||||
deamon_url,
|
daemon_url,
|
||||||
login,
|
login,
|
||||||
epee::net_utils::ssl_support_t::e_ssl_support_disabled);
|
epee::net_utils::ssl_support_t::e_ssl_support_disabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rpccalls::connect_to_monero_deamon()
|
rpccalls::connect_to_monero_daemon()
|
||||||
{
|
{
|
||||||
//std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
//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);
|
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
|
uint64_t
|
||||||
rpccalls::get_current_height()
|
rpccalls::get_current_height()
|
||||||
{
|
{
|
||||||
@@ -48,9 +75,9 @@ rpccalls::get_current_height()
|
|||||||
|
|
||||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,8 +87,8 @@ rpccalls::get_current_height()
|
|||||||
|
|
||||||
if (!r)
|
if (!r)
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon at "
|
cerr << "Error connecting to Monero daemon at "
|
||||||
<< deamon_url << endl;
|
<< daemon_url << endl;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,9 +107,9 @@ rpccalls::get_mempool(vector<tx_info>& mempool_txs)
|
|||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,8 +120,8 @@ rpccalls::get_mempool(vector<tx_info>& mempool_txs)
|
|||||||
|
|
||||||
if (!r || res.status != CORE_RPC_STATUS_OK)
|
if (!r || res.status != CORE_RPC_STATUS_OK)
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon at "
|
cerr << "Error connecting to Monero daemon at "
|
||||||
<< deamon_url << endl;
|
<< daemon_url << endl;
|
||||||
return false;
|
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);
|
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;
|
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);
|
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;
|
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)
|
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)
|
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())
|
if (!err.empty())
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon due to "
|
cerr << "Error connecting to Monero daemon due to "
|
||||||
<< err << endl;
|
<< err << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon at "
|
cerr << "Error connecting to Monero daemon at "
|
||||||
<< deamon_url << endl;
|
<< daemon_url << endl;
|
||||||
return false;
|
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);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,15 +280,15 @@ rpccalls::get_hardfork_info(COMMAND_RPC_HARD_FORK_INFO::response& response)
|
|||||||
|
|
||||||
if (!err.empty())
|
if (!err.empty())
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon due to "
|
cerr << "Error connecting to Monero daemon due to "
|
||||||
<< err << endl;
|
<< err << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon at "
|
cerr << "Error connecting to Monero daemon at "
|
||||||
<< deamon_url << endl;
|
<< daemon_url << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -294,9 +321,9 @@ rpccalls::get_dynamic_per_kb_fee_estimate(
|
|||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,15 +348,15 @@ rpccalls::get_dynamic_per_kb_fee_estimate(
|
|||||||
|
|
||||||
if (!err.empty())
|
if (!err.empty())
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon due to "
|
cerr << "Error connecting to Monero daemon due to "
|
||||||
<< err << endl;
|
<< err << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon at "
|
cerr << "Error connecting to Monero daemon at "
|
||||||
<< deamon_url << endl;
|
<< daemon_url << endl;
|
||||||
return false;
|
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);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,15 +411,15 @@ rpccalls::get_block(string const& blk_hash, block& blk, string& error_msg)
|
|||||||
|
|
||||||
if (!err.empty())
|
if (!err.empty())
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon due to "
|
cerr << "Error connecting to Monero daemon due to "
|
||||||
<< err << endl;
|
<< err << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "get_block: error connecting to Monero deamon at "
|
cerr << "get_block: error connecting to Monero daemon at "
|
||||||
<< deamon_url << endl;
|
<< daemon_url << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-8
@@ -69,7 +69,7 @@ using namespace std;
|
|||||||
|
|
||||||
class rpccalls
|
class rpccalls
|
||||||
{
|
{
|
||||||
string deamon_url ;
|
string daemon_url ;
|
||||||
uint64_t timeout_time;
|
uint64_t timeout_time;
|
||||||
|
|
||||||
std::chrono::milliseconds timeout_time_ms;
|
std::chrono::milliseconds timeout_time_ms;
|
||||||
@@ -77,6 +77,7 @@ class rpccalls
|
|||||||
epee::net_utils::http::url_content url;
|
epee::net_utils::http::url_content url;
|
||||||
|
|
||||||
epee::net_utils::http::http_simple_client m_http_client;
|
epee::net_utils::http::http_simple_client m_http_client;
|
||||||
|
|
||||||
std::mutex m_daemon_rpc_mutex;
|
std::mutex m_daemon_rpc_mutex;
|
||||||
|
|
||||||
string port;
|
string port;
|
||||||
@@ -85,12 +86,12 @@ public:
|
|||||||
|
|
||||||
using login_opt = boost::optional<epee::net_utils::http::login>;
|
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 {},
|
login_opt _login = login_opt {},
|
||||||
uint64_t _timeout = 200000);
|
uint64_t _timeout = 200000);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
connect_to_monero_deamon();
|
connect_to_monero_daemon();
|
||||||
|
|
||||||
uint64_t
|
uint64_t
|
||||||
get_current_height();
|
get_current_height();
|
||||||
@@ -104,6 +105,9 @@ public:
|
|||||||
bool
|
bool
|
||||||
get_network_info(COMMAND_RPC_GET_INFO::response& info);
|
get_network_info(COMMAND_RPC_GET_INFO::response& info);
|
||||||
|
|
||||||
|
bool
|
||||||
|
get_base_fee_estimate(uint64_t grace_blocks, uint64_t& fee_estimate);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
get_hardfork_info( COMMAND_RPC_HARD_FORK_INFO::response& res);
|
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);
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,15 +165,15 @@ public:
|
|||||||
|
|
||||||
if (!err.empty())
|
if (!err.empty())
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon due to "
|
cerr << "Error connecting to Monero daemon due to "
|
||||||
<< err << endl;
|
<< err << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
cerr << "Error connecting to Monero deamon at "
|
cerr << "Error connecting to Monero daemon at "
|
||||||
<< deamon_url << endl;
|
<< daemon_url << endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
<table class="center">
|
<table class="center">
|
||||||
<tr>
|
<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>Age {{age_format}}:</td><td>{{blk_age}}</td>
|
||||||
<td>Δ [h:m:s]:</td><td>{{delta_time}}</td>
|
<td>Δ [h:m:s]:</td><td>{{delta_time}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ tr, li, #pages, .info {
|
|||||||
|
|
||||||
td {
|
td {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:link {
|
a:link {
|
||||||
@@ -70,7 +71,7 @@ form {
|
|||||||
|
|
||||||
.tabs {
|
.tabs {
|
||||||
position: relative;
|
position: relative;
|
||||||
min-height: 220px; /* This part sucks */
|
min-height: 240px;
|
||||||
clear: both;
|
clear: both;
|
||||||
margin: 25px 0;
|
margin: 25px 0;
|
||||||
}
|
}
|
||||||
@@ -101,6 +102,7 @@ form {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border: 1px solid #ccc;
|
border: 1px solid #ccc;
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
[type=radio]:checked ~ label {
|
[type=radio]:checked ~ label {
|
||||||
@@ -113,6 +115,11 @@ form {
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#tab-1:checked ~ .content.tab-1,
|
||||||
|
#tab-2:checked ~ .content.tab-2 {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
input#toggle-1[type=checkbox] {
|
input#toggle-1[type=checkbox] {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
/*top: -9999px;*/
|
/*top: -9999px;*/
|
||||||
@@ -138,4 +145,4 @@ div#decoded-inputs{
|
|||||||
/* Toggled State */
|
/* Toggled State */
|
||||||
input#toggle-1[type=checkbox]:checked ~ div#decoded-inputs {
|
input#toggle-1[type=checkbox]:checked ~ div#decoded-inputs {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
{{#refresh}}
|
{{#refresh}}
|
||||||
<meta http-equiv="refresh" content="10">
|
<meta http-equiv="refresh" content="10">
|
||||||
{{/refresh}}
|
{{/refresh}}
|
||||||
<title>Wownero Blockchain Explorer</title>
|
<title>Onion Wownero Blockchain Explorer</title>
|
||||||
<!--<link rel="stylesheet" type="text/css" href="/css/style.css">-->
|
<!--<link rel="stylesheet" type="text/css" href="/css/style.css">-->
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
{{#css_styles}}{{/css_styles}}
|
{{#css_styles}}{{/css_styles}}
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
|
|
||||||
{{#emission}}
|
{{#emission}}
|
||||||
<h3 style="font-size: 12px; margin-top: 2px">
|
<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>
|
</h3>
|
||||||
{{/emission}}
|
{{/emission}}
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
<table class="center" style="width: 80%; margin-top:10px">
|
<table class="center" style="width: 80%; margin-top:10px">
|
||||||
<tr>
|
<tr>
|
||||||
<td>Block: {{blk_height}}</td>
|
<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>Age [y:d:h:m:s]: {{delta_time}}</td>
|
||||||
<td>Fee: {{tx_fee}}</td>
|
<td>Fee: {{tx_fee}}</td>
|
||||||
<td>Tx size: {{tx_size}} kB</td>
|
<td>Tx size: {{tx_size}} kB</td>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
{{^have_raw_tx}}
|
{{^have_raw_tx}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>Timestamp: {{blk_timestamp_uint}}</td>
|
<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>
|
<td>Age [y:d:h:m:s]: {{delta_time}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/have_raw_tx}}
|
{{/have_raw_tx}}
|
||||||
@@ -62,12 +62,14 @@
|
|||||||
<td>stealth address</td>
|
<td>stealth address</td>
|
||||||
<td>amount</td>
|
<td>amount</td>
|
||||||
<td>amount idx</td>
|
<td>amount idx</td>
|
||||||
|
<td>tag</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{#outputs}}
|
{{#outputs}}
|
||||||
<tr>
|
<tr>
|
||||||
<td>{{output_idx}}: {{out_pub_key}}</td>
|
<td>{{output_idx}}: {{out_pub_key}}</td>
|
||||||
<td>{{amount}}</td>
|
<td>{{amount}}</td>
|
||||||
<td>{{amount_idx}} of {{num_outputs}}</td>
|
<td>{{amount_idx}} of {{num_outputs}}</td>
|
||||||
|
<td>{{output_tag}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/outputs}}
|
{{/outputs}}
|
||||||
</table>
|
</table>
|
||||||
@@ -80,7 +82,7 @@
|
|||||||
<div class="tab">
|
<div class="tab">
|
||||||
<input type="radio" id="tab-1" name="tab-group-1" checked>
|
<input type="radio" id="tab-1" name="tab-group-1" checked>
|
||||||
<label for="tab-1">Decode outputs</label>
|
<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>
|
<h4 style="margin: 0px">Check which outputs belong to given Wownero address/subaddress and viewkey</h4>
|
||||||
<h5 style="margin: 0px">
|
<h5 style="margin: 0px">
|
||||||
For RingCT transactions, outputs' amounts are also decoded
|
For RingCT transactions, outputs' amounts are also decoded
|
||||||
@@ -89,7 +91,7 @@
|
|||||||
</h5>
|
</h5>
|
||||||
<form action="/myoutputs" method="post" style="width:100%; margin-top:2px" class="style-1">
|
<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="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="text" name="viewkey" size="110" placeholder="Private viewkey" style="margin-top:5px"><br/>
|
||||||
<input type="hidden" name="raw_tx_data" value="{{raw_tx_data}}">
|
<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-->
|
<!--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">
|
<input type="radio" id="tab-2" name="tab-group-1">
|
||||||
<label for="tab-2">Prove sending</label>
|
<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>
|
<h4 style="margin: 0px">Prove to someone that you have sent them Wownero in this transaction</h4>
|
||||||
<h5 style="margin: 0px">
|
<h5 style="margin: 0px">
|
||||||
Tx private key can be obtained using <i>get_tx_key</i>
|
Tx private key can be obtained using <i>get_tx_key</i>
|
||||||
|
|||||||
+53
-36
@@ -345,7 +345,7 @@ sum_money_in_outputs(const json& _json)
|
|||||||
array<uint64_t, 4>
|
array<uint64_t, 4>
|
||||||
summary_of_in_out_rct(
|
summary_of_in_out_rct(
|
||||||
const transaction& tx,
|
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)
|
vector<txin_to_key>& input_key_imgs)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -357,18 +357,28 @@ summary_of_in_out_rct(
|
|||||||
|
|
||||||
for (const tx_out& txout: tx.vout)
|
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.
|
// 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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get tx input key
|
boost::optional<view_tag> output_tag;
|
||||||
const txout_to_key& txout_key
|
|
||||||
= boost::get<cryptonote::txout_to_key>(txout.target);
|
|
||||||
|
|
||||||
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;
|
xmr_outputs += txout.amount;
|
||||||
}
|
}
|
||||||
@@ -617,51 +627,56 @@ sum_fees_in_txs(const vector<transaction>& txs)
|
|||||||
return fees_sum;
|
return fees_sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<output_tuple_with_tag>
|
||||||
|
|
||||||
vector<pair<txout_to_key, uint64_t>>
|
|
||||||
get_ouputs(const transaction& tx)
|
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)
|
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.
|
// push empty tuple.
|
||||||
outputs.push_back(pair<txout_to_key, uint64_t>{});
|
outputs.push_back(output_tuple_with_tag {
|
||||||
|
public_key{},
|
||||||
|
uint64_t{},
|
||||||
|
boost::none
|
||||||
|
});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get tx input key
|
boost::optional<view_tag> output_tag;
|
||||||
const txout_to_key& txout_key
|
|
||||||
= boost::get<cryptonote::txout_to_key>(txout.target);
|
|
||||||
|
|
||||||
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;
|
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)
|
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)
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get tx input key
|
outputs.push_back(make_tuple(output_pub_key, tx.vout[n].amount, n));
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return outputs;
|
return outputs;
|
||||||
@@ -937,7 +952,8 @@ decode_ringct(rct::rctSig const& rv,
|
|||||||
case rct::RCTTypeSimple:
|
case rct::RCTTypeSimple:
|
||||||
case rct::RCTTypeBulletproof:
|
case rct::RCTTypeBulletproof:
|
||||||
case rct::RCTTypeBulletproof2:
|
case rct::RCTTypeBulletproof2:
|
||||||
case rct::RCTTypeCLSAG:
|
case rct::RCTTypeCLSAG:
|
||||||
|
case rct::RCTTypeBulletproofPlus:
|
||||||
amount = rct::decodeRctSimple(rv,
|
amount = rct::decodeRctSimple(rv,
|
||||||
rct::sk2rct(scalar1),
|
rct::sk2rct(scalar1),
|
||||||
i,
|
i,
|
||||||
@@ -946,11 +962,11 @@ decode_ringct(rct::rctSig const& rv,
|
|||||||
break;
|
break;
|
||||||
case rct::RCTTypeFull:
|
case rct::RCTTypeFull:
|
||||||
amount = rct::decodeRct(rv,
|
amount = rct::decodeRct(rv,
|
||||||
rct::sk2rct(scalar1),
|
rct::sk2rct(scalar1),
|
||||||
i,
|
i,
|
||||||
mask,
|
mask,
|
||||||
hw::get_device("default"));
|
hw::get_device("default"));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
cerr << "Unsupported rct type: " << rv.type << '\n';
|
cerr << "Unsupported rct type: " << rv.type << '\n';
|
||||||
return false;
|
return false;
|
||||||
@@ -1147,7 +1163,8 @@ is_output_ours(const size_t& output_index,
|
|||||||
{
|
{
|
||||||
cerr << "Cant get dervied key for: " << "\n"
|
cerr << "Cant get dervied key for: " << "\n"
|
||||||
<< "pub_tx_key: " << pub_tx_key << " and "
|
<< "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;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -1166,11 +1183,11 @@ is_output_ours(const size_t& output_index,
|
|||||||
//cout << "\n" << tx.vout.size() << " " << output_index << endl;
|
//cout << "\n" << tx.vout.size() << " " << output_index << endl;
|
||||||
|
|
||||||
// get tx output public key
|
// get tx output public key
|
||||||
const txout_to_key tx_out_to_key
|
public_key output_pub_key;
|
||||||
= boost::get<txout_to_key>(tx.vout[output_index].target);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-3
@@ -49,6 +49,10 @@ namespace bf = boost::filesystem;
|
|||||||
|
|
||||||
using json = nlohmann::json;
|
using json = nlohmann::json;
|
||||||
|
|
||||||
|
using output_tuple_with_tag = tuple<public_key,
|
||||||
|
uint64_t,
|
||||||
|
boost::optional<view_tag>>;
|
||||||
|
|
||||||
struct outputs_visitor
|
struct outputs_visitor
|
||||||
{
|
{
|
||||||
std::vector<crypto::public_key >& m_output_keys;
|
std::vector<crypto::public_key >& m_output_keys;
|
||||||
@@ -154,7 +158,7 @@ sum_money_in_outputs(const json& _json);
|
|||||||
array<uint64_t, 4>
|
array<uint64_t, 4>
|
||||||
summary_of_in_out_rct(
|
summary_of_in_out_rct(
|
||||||
const transaction& tx,
|
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);
|
vector<txin_to_key>& input_key_imgs);
|
||||||
|
|
||||||
// this version for mempool txs from json
|
// this version for mempool txs from json
|
||||||
@@ -200,10 +204,10 @@ get_mixin_no(const json& _json);
|
|||||||
vector<uint64_t>
|
vector<uint64_t>
|
||||||
get_mixin_no_in_txs(const vector<transaction>& txs);
|
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);
|
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);
|
get_ouputs_tuple(const transaction& tx);
|
||||||
|
|
||||||
vector<txin_to_key>
|
vector<txin_to_key>
|
||||||
|
|||||||
Reference in New Issue
Block a user