Rewowify using d7853cc48c on current xmrblocks codebase

This commit is contained in:
jwinterm
2025-04-24 14:23:54 -04:00
parent 8129bc88c1
commit e8540e0c35
26 changed files with 13232 additions and 897 deletions
+1
View File
@@ -1,4 +1,5 @@
.DS_Store
.vscode
.sass-cache
*.*~
*.user
+6 -7
View File
@@ -6,7 +6,7 @@ set(PROJECT_NAME
project(${PROJECT_NAME})
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD 17)
if (WIN32)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -O3")
@@ -14,7 +14,7 @@ endif()
if (NOT MONERO_DIR)
set(MONERO_DIR ~/wownero)
set(MONERO_DIR ~/src/wownero)
endif()
message(STATUS MONERO_DIR ": ${MONERO_DIR}")
@@ -49,7 +49,6 @@ list(APPEND CMAKE_MODULE_PATH "${MY_CMAKE_DIR}")
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "${MONERO_BUILD_DIR}"
CACHE PATH "Add Monero directory for library searching")
include(MyUtils)
find_package(Monero)
@@ -139,12 +138,13 @@ set(LIBRARIES
myext
mstch
wallet
cryptonote_core
cryptonote_basic
cryptonote_protocol
cryptonote_format_utils_basic
blockchain_db
device
${WALLET_CRYPTO}
cryptonote_core
cryptonote_protocol
cryptonote_basic
multisig
daemonizer
blocks
@@ -165,7 +165,6 @@ set(LIBRARIES
${Boost_LIBRARIES}
pthread
unbound
curl
crypto
ssl)
+97
View File
@@ -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"]
+9 -2
View File
@@ -45,7 +45,7 @@ foreach (l ${LIBS})
find_library(Xmr_${L}_LIBRARY
NAMES ${l}
PATHS ${CMAKE_LIBRARY_PATH}
PATH_SUFFIXES "/src/${l}" "/src/" "/external/db_drivers/lib${l}" "/lib" "/src/crypto" "/src/crypto/wallet" "/contrib/epee/src" "/external/easylogging++/" "/external/${l}" "external/miniupnp/miniupnpc" "/external/RandomWOW"
PATH_SUFFIXES "/src/${l}" "/src/" "/external/db_drivers/lib${l}" "/lib" "/src/crypto" "/src/crypto/wallet" "/contrib/epee/src" "/external/easylogging++/" "/external/${l}" "external/miniupnp/miniupnpc" "/external/randomwow"
NO_DEFAULT_PATH
)
@@ -67,6 +67,13 @@ if (EXISTS ${MONERO_BUILD_DIR}/src/ringct/libringct_basic.a)
PROPERTY IMPORTED_LOCATION ${MONERO_BUILD_DIR}/src/ringct/libringct_basic.a)
endif()
if (EXISTS ${MONERO_BUILD_DIR}/src/cryptonote_basic/libcryptonote_format_utils_basic.a)
message(STATUS FindMonero " found libcryptonote_format_utils_basic.a")
add_library(cryptonote_format_utils_basic STATIC IMPORTED)
set_property(TARGET cryptonote_format_utils_basic
PROPERTY IMPORTED_LOCATION ${MONERO_BUILD_DIR}/src/cryptonote_basic/libcryptonote_format_utils_basic.a)
endif()
message(STATUS ${MONERO_SOURCE_DIR}/build)
@@ -76,7 +83,7 @@ include_directories(
${MONERO_SOURCE_DIR}/src/crypto
${MONERO_SOURCE_DIR}/src/crypto/wallet
${MONERO_SOURCE_DIR}/external
${MONERO_SOURCE_DIR}/external/RandomWOW/src
${MONERO_SOURCE_DIR}/external/randomwow/src
${MONERO_SOURCE_DIR}/build
${MONERO_SOURCE_DIR}/external/easylogging++
${MONERO_SOURCE_DIR}/contrib/epee/include
+450
View File
@@ -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
View File
File diff suppressed because it is too large Load Diff
+21 -13
View File
@@ -1,9 +1,9 @@
#define CROW_ENABLE_SSL
#define CROW_MAIN
#include "src/page.h"
#include "ext/crow/crow.h"
#include "ext/crow_all.h"
#include "src/CmdLineOptions.h"
#include "src/MicroCore.h"
@@ -56,7 +56,7 @@ main(int ac, const char* av[])
auto port_opt = opts.get_option<string>("port");
auto bindaddr_opt = opts.get_option<string>("bindaddr");
auto bc_path_opt = opts.get_option<string>("bc-path");
auto deamon_url_opt = opts.get_option<string>("deamon-url");
auto daemon_url_opt = opts.get_option<string>("daemon-url");
auto ssl_crt_file_opt = opts.get_option<string>("ssl-crt-file");
auto ssl_key_file_opt = opts.get_option<string>("ssl-key-file");
auto no_blocks_on_index_opt = opts.get_option<string>("no-blocks-on-index");
@@ -76,6 +76,7 @@ main(int ac, const char* av[])
auto enable_mixin_details_opt = opts.get_option<bool>("enable-mixin-details");
auto enable_json_api_opt = opts.get_option<bool>("enable-json-api");
auto enable_as_hex_opt = opts.get_option<bool>("enable-as-hex");
auto enable_mixin_guess_opt = opts.get_option<bool>("enable-mixin-guess");
auto concurrency_opt = opts.get_option<size_t>("concurrency");
auto enable_emission_monitor_opt = opts.get_option<bool>("enable-emission-monitor");
@@ -99,10 +100,16 @@ main(int ac, const char* av[])
bool enable_autorefresh_option {*enable_autorefresh_option_opt};
bool enable_output_key_checker {*enable_output_key_checker_opt};
bool enable_mixin_details {*enable_mixin_details_opt};
bool enable_mixin_guess {*enable_mixin_guess_opt};
bool enable_json_api {*enable_json_api_opt};
bool enable_as_hex {*enable_as_hex_opt};
bool enable_emission_monitor {*enable_emission_monitor_opt};
//temprorary disable randomx
if (enable_randomx == true) {
cout << "Support for randomx code is disabled due to issues with it"<< endl;
enable_randomx = false;
}
// set monero log output level
uint32_t log_level = 0;
@@ -205,12 +212,12 @@ main(int ac, const char* av[])
return EXIT_FAILURE;
}
string deamon_url {*deamon_url_opt};
string daemon_url {*daemon_url_opt};
if (testnet && deamon_url == "http:://127.0.0.1:34568")
deamon_url = "http:://127.0.0.1:11181";
if (stagenet && deamon_url == "http:://127.0.0.1:34568")
deamon_url = "http:://127.0.0.1:38081";
if (testnet && daemon_url == "127.0.0.1:34568")
daemon_url = "127.0.0.1:11181";
if (stagenet && daemon_url == "127.0.0.1:34568")
daemon_url = "127.0.0.1:38081";
uint64_t mempool_info_timeout {5000};
@@ -247,8 +254,8 @@ main(int ac, const char* av[])
= blockchain_path;
xmreg::CurrentBlockchainStatus::nettype
= nettype;
xmreg::CurrentBlockchainStatus::deamon_url
= deamon_url;
xmreg::CurrentBlockchainStatus::daemon_url
= daemon_url;
xmreg::CurrentBlockchainStatus::set_blockchain_variables(
&mcore, core_storage);
@@ -264,8 +271,8 @@ main(int ac, const char* av[])
= blockchain_path;
xmreg::MempoolStatus::nettype
= nettype;
xmreg::MempoolStatus::deamon_url
= deamon_url;
xmreg::MempoolStatus::daemon_url
= daemon_url;
xmreg::MempoolStatus::login
= daemon_rpc_login;
xmreg::MempoolStatus::set_blockchain_variables(
@@ -299,7 +306,7 @@ main(int ac, const char* av[])
// contains logic for the website
xmreg::page xmrblocks(&mcore,
core_storage,
deamon_url,
daemon_url,
nettype,
enable_pusher,
enable_randomx,
@@ -308,6 +315,7 @@ main(int ac, const char* av[])
enable_output_key_checker,
enable_autorefresh_option,
enable_mixin_details,
enable_mixin_guess,
no_blocks_on_index,
mempool_info_timeout,
*testnet_url,
+5 -3
View File
@@ -18,7 +18,7 @@ namespace xmreg
p.add("txhash", -1);
options_description desc(
"xmrblocks, Wownero Blockchain Explorer");
"xmrblocks, Onion Wownero Blockchain Explorer");
desc.add_options()
("help,h", value<bool>()->default_value(false)->implicit_value(true),
@@ -71,8 +71,10 @@ namespace xmreg
"path to key file for ssl (https) functionality")
("daemon-login", value<string>(),
"Specify username[:password] for daemon RPC client")
("deamon-url,d", value<string>()->default_value("http:://127.0.0.1:18081"),
"Monero daemon url");
("daemon-url,d", value<string>()->default_value("127.0.0.1:18081"),
"Monero daemon url")
("enable-mixin-guess", value<bool>()->default_value(false)->implicit_value(true),
"enable guessing real outputs in key images based on viewkey");
store(command_line_parser(acc, avv)
+1 -1
View File
@@ -303,7 +303,7 @@ cryptonote::network_type CurrentBlockchainStatus::nettype {cryptonote::network_t
string CurrentBlockchainStatus::output_file {"emission_amount.txt"};
string CurrentBlockchainStatus::deamon_url {"http:://127.0.0.1:34568"};
string CurrentBlockchainStatus::daemon_url {"http:://127.0.0.1:34568"};
uint64_t CurrentBlockchainStatus::blockchain_chunk_size {10000};
+1 -1
View File
@@ -51,7 +51,7 @@ struct CurrentBlockchainStatus
static string output_file;
static string deamon_url;
static string daemon_url;
// how many blocks to read before thread goes to sleep
static uint64_t blockchain_chunk_size;
+7 -4
View File
@@ -96,7 +96,7 @@ MempoolStatus::start_mempool_status_thread()
bool
MempoolStatus::read_mempool()
{
rpccalls rpc {deamon_url, login};
rpccalls rpc {daemon_url, login};
string error_msg;
@@ -170,7 +170,7 @@ MempoolStatus::read_mempool()
vector<txin_to_key> input_key_imgs;
// public keys and xmr amount of outputs
vector<pair<txout_to_key, uint64_t>> output_pub_keys;
vector<output_tuple_with_tag> output_pub_keys;
// sum xmr in inputs and ouputs in the given tx
const array<uint64_t, 4>& sum_data = summary_of_in_out_rct(
@@ -222,12 +222,15 @@ MempoolStatus::read_mempool()
bool
MempoolStatus::read_network_info()
{
rpccalls rpc {deamon_url, login};
rpccalls rpc {daemon_url, login};
COMMAND_RPC_GET_INFO::response rpc_network_info;
if (!rpc.get_network_info(rpc_network_info))
{
cerr << "rpc.get_network_info(rpc_network_info) failed";
return false;
}
uint64_t fee_estimated;
@@ -326,7 +329,7 @@ MempoolStatus::is_thread_running()
}
bf::path MempoolStatus::blockchain_path {"/home/mwo/.wownero/lmdb"};
string MempoolStatus::deamon_url {"http:://127.0.0.1:34568"};
string MempoolStatus::daemon_url {"http:://127.0.0.1:34568"};
cryptonote::network_type MempoolStatus::nettype {cryptonote::network_type::MAINNET};
atomic<bool> MempoolStatus::is_running {false};
boost::thread MempoolStatus::m_thread;
+1 -1
View File
@@ -125,7 +125,7 @@ struct MempoolStatus
static atomic<uint64_t> mempool_size; // size in bytes.
static bf::path blockchain_path;
static string deamon_url;
static string daemon_url;
static cryptonote::network_type nettype;
static rpccalls::login_opt login;
+4 -18
View File
@@ -211,12 +211,13 @@ MicroCore::find_output_in_tx(const transaction& tx,
auto it = std::find_if(tx.vout.begin(), tx.vout.end(),
[&](const tx_out& o)
{
const txout_to_key& tx_in_to_key
= boost::get<txout_to_key>(o.target);
public_key found_output_pubkey;
cryptonote::get_output_public_key(
o, found_output_pubkey);
++idx;
return tx_in_to_key.key == output_pubkey;
return found_output_pubkey == output_pubkey;
});
if (it != tx.vout.end())
@@ -248,21 +249,6 @@ MicroCore::get_blk_timestamp(uint64_t blk_height)
return blk.timestamp;
}
/**
* De-initialized Blockchain.
*
* since blockchain is opened as MDB_RDONLY
* need to manually free memory taken on heap
* by BlockchainLMDB
*/
MicroCore::~MicroCore()
{
//m_blockchain_storage.get_db().close();
delete &m_blockchain_storage.get_db();
}
bool
init_blockchain(const string& path,
MicroCore& mcore,
-2
View File
@@ -73,8 +73,6 @@ namespace xmreg
hw::device* const
get_device() const;
virtual ~MicroCore();
};
+403 -240
View File
@@ -1,4 +1,4 @@
// Copyright (c) 2019, The Monero Project
// Copyright (c) 2019-2022, The Monero Project
//
// All rights reserved.
//
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include "randomx.h"
#include "c_threads.h"
@@ -42,31 +43,38 @@
#define RX_LOGCAT "randomx"
static CTHR_RWLOCK_TYPE main_dataset_lock = CTHR_RWLOCK_INIT;
static CTHR_RWLOCK_TYPE main_cache_lock = CTHR_RWLOCK_INIT;
static randomx_dataset *main_dataset = NULL;
static randomx_cache *main_cache = NULL;
static char main_seedhash[HASH_SIZE];
static int main_seedhash_set = 0;
static CTHR_RWLOCK_TYPE secondary_cache_lock = CTHR_RWLOCK_INIT;
static randomx_cache *secondary_cache = NULL;
static char secondary_seedhash[HASH_SIZE];
static int secondary_seedhash_set = 0;
#if defined(_MSC_VER)
#define THREADV __declspec(thread)
#else
#define THREADV __thread
#endif
typedef struct rx_state {
CTHR_MUTEX_TYPE rs_mutex;
char rs_hash[32];
uint64_t rs_height;
randomx_cache *rs_cache;
} rx_state;
THREADV randomx_vm *main_vm_full = NULL;
static THREADV randomx_vm *main_vm_light = NULL;
static THREADV randomx_vm *secondary_vm_light = NULL;
static CTHR_MUTEX_TYPE rx_mutex = CTHR_MUTEX_INIT;
static CTHR_MUTEX_TYPE rx_dataset_mutex = CTHR_MUTEX_INIT;
static THREADV uint32_t miner_thread = 0;
static rx_state rx_s[2] = {{CTHR_MUTEX_INIT,{0},0,0},{CTHR_MUTEX_INIT,{0},0,0}};
static randomx_dataset *rx_dataset;
static uint64_t rx_dataset_height;
THREADV randomx_vm *rx_vm = NULL;
static THREADV int rx_toggle;
static bool is_main(const char* seedhash) { return main_seedhash_set && (memcmp(seedhash, main_seedhash, HASH_SIZE) == 0); }
static bool is_secondary(const char* seedhash) { return secondary_seedhash_set && (memcmp(seedhash, secondary_seedhash, HASH_SIZE) == 0); }
static void local_abort(const char *msg)
{
merror(RX_LOGCAT, "%s", msg);
fprintf(stderr, "%s\n", msg);
#ifdef NDEBUG
_exit(1);
@@ -75,108 +83,196 @@ static void local_abort(const char *msg)
#endif
}
/**
* @brief uses cpuid to determine if the CPU supports the AES instructions
* @return true if the CPU supports AES, false otherwise
*/
static inline int force_software_aes(void)
{
static int use = -1;
if (use != -1)
return use;
const char *env = getenv("MONERO_USE_SOFTWARE_AES");
if (!env) {
use = 0;
static void hash2hex(const char* hash, char* hex) {
const char* d = "0123456789abcdef";
for (int i = 0; i < HASH_SIZE; ++i) {
const uint8_t b = hash[i];
hex[i * 2 + 0] = d[b >> 4];
hex[i * 2 + 1] = d[b & 15];
}
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
use = 0;
hex[HASH_SIZE * 2] = '\0';
}
static inline int disabled_flags(void) {
static int flags = -1;
if (flags != -1) {
return flags;
}
const char *env = getenv("MONERO_RANDOMX_UMASK");
if (!env) {
flags = 0;
}
else {
use = 1;
}
return use;
}
static void cpuid(int CPUInfo[4], int InfoType)
{
#if defined(__x86_64__)
__asm __volatile__
(
"cpuid":
"=a" (CPUInfo[0]),
"=b" (CPUInfo[1]),
"=c" (CPUInfo[2]),
"=d" (CPUInfo[3]) :
"a" (InfoType), "c" (0)
);
#endif
}
static inline int check_aes_hw(void)
{
#if defined(__x86_64__)
int cpuid_results[4];
static int supported = -1;
if(supported >= 0)
return supported;
cpuid(cpuid_results,1);
return supported = cpuid_results[2] & (1 << 25);
#else
return 0;
#endif
}
static volatile int use_rx_jit_flag = -1;
static inline int use_rx_jit(void)
{
#if defined(__x86_64__)
if (use_rx_jit_flag != -1)
return use_rx_jit_flag;
const char *env = getenv("MONERO_USE_RX_JIT");
if (!env) {
use_rx_jit_flag = 1;
}
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
use_rx_jit_flag = 0;
char* endptr;
long int value = strtol(env, &endptr, 0);
if (endptr != env && value >= 0 && value < INT_MAX) {
flags = value;
}
else {
use_rx_jit_flag = 1;
flags = 0;
}
return use_rx_jit_flag;
#else
return 0;
#endif
}
return flags;
}
static inline int enabled_flags(void) {
static int flags = -1;
if (flags != -1) {
return flags;
}
flags = randomx_get_flags();
return flags;
}
#define SEEDHASH_EPOCH_BLOCKS 2048 /* Must be same as BLOCKS_SYNCHRONIZING_MAX_COUNT in cryptonote_config.h */
#define SEEDHASH_EPOCH_LAG 64
void me_rx_reorg(const uint64_t split_height) {
int i;
CTHR_MUTEX_LOCK(rx_mutex);
for (i=0; i<2; i++) {
if (split_height < rx_s[i].rs_height)
rx_s[i].rs_height = 1; /* set to an invalid seed height */
static inline int is_power_of_2(uint64_t n) { return n && (n & (n-1)) == 0; }
static int get_seedhash_epoch_lag(void)
{
static unsigned int lag = (unsigned int)-1;
if (lag != (unsigned int)-1)
return lag;
const char *e = getenv("SEEDHASH_EPOCH_LAG");
if (e)
{
lag = atoi(e);
if (lag > SEEDHASH_EPOCH_LAG || !is_power_of_2(lag))
lag = SEEDHASH_EPOCH_LAG;
}
CTHR_MUTEX_UNLOCK(rx_mutex);
else
{
lag = SEEDHASH_EPOCH_LAG;
}
return lag;
}
static unsigned int get_seedhash_epoch_blocks(void)
{
static unsigned int blocks = (unsigned int)-1;
if (blocks != (unsigned int)-1)
return blocks;
const char *e = getenv("SEEDHASH_EPOCH_BLOCKS");
if (e)
{
blocks = atoi(e);
if (blocks < 2 || blocks > SEEDHASH_EPOCH_BLOCKS || !is_power_of_2(blocks))
blocks = SEEDHASH_EPOCH_BLOCKS;
}
else
{
blocks = SEEDHASH_EPOCH_BLOCKS;
}
return blocks;
}
uint64_t me_rx_seedheight(const uint64_t height) {
uint64_t s_height = (height <= SEEDHASH_EPOCH_BLOCKS+SEEDHASH_EPOCH_LAG) ? 0 :
(height - SEEDHASH_EPOCH_LAG - 1) & ~(SEEDHASH_EPOCH_BLOCKS-1);
const uint64_t seedhash_epoch_lag = get_seedhash_epoch_lag();
const uint64_t seedhash_epoch_blocks = get_seedhash_epoch_blocks();
uint64_t s_height = (height <= seedhash_epoch_blocks+seedhash_epoch_lag) ? 0 :
(height - seedhash_epoch_lag - 1) & ~(seedhash_epoch_blocks-1);
return s_height;
}
void me_rx_seedheights(const uint64_t height, uint64_t *seedheight, uint64_t *nextheight) {
*seedheight = me_rx_seedheight(height);
*nextheight = me_rx_seedheight(height + SEEDHASH_EPOCH_LAG);
*nextheight = me_rx_seedheight(height + get_seedhash_epoch_lag());
}
static void rx_alloc_dataset(randomx_flags flags, randomx_dataset** dataset, int ignore_env)
{
if (*dataset) {
return;
}
if (disabled_flags() & RANDOMX_FLAG_FULL_MEM) {
static int shown = 0;
if (!shown) {
shown = 1;
minfo(RX_LOGCAT, "RandomX dataset is disabled by MONERO_RANDOMX_UMASK environment variable.");
}
return;
}
if (!ignore_env && !getenv("MONERO_RANDOMX_FULL_MEM")) {
static int shown = 0;
if (!shown) {
shown = 1;
minfo(RX_LOGCAT, "RandomX dataset is not enabled by default. Use MONERO_RANDOMX_FULL_MEM environment variable to enable it.");
}
return;
}
*dataset = randomx_alloc_dataset((flags | RANDOMX_FLAG_LARGE_PAGES) & ~disabled_flags());
if (!*dataset) {
mwarning(RX_LOGCAT, "Couldn't allocate RandomX dataset using large pages");
*dataset = randomx_alloc_dataset(flags & ~disabled_flags());
if (!*dataset) {
merror(RX_LOGCAT, "Couldn't allocate RandomX dataset");
}
}
}
static void rx_alloc_cache(randomx_flags flags, randomx_cache** cache)
{
if (*cache) {
return;
}
*cache = randomx_alloc_cache((flags | RANDOMX_FLAG_LARGE_PAGES) & ~disabled_flags());
if (!*cache) {
mwarning(RX_LOGCAT, "Couldn't allocate RandomX cache using large pages");
*cache = randomx_alloc_cache(flags & ~disabled_flags());
if (!*cache) local_abort("Couldn't allocate RandomX cache");
}
}
static void rx_init_full_vm(randomx_flags flags, randomx_vm** vm)
{
if (*vm || !main_dataset || (disabled_flags() & RANDOMX_FLAG_FULL_MEM)) {
return;
}
if ((flags & RANDOMX_FLAG_JIT) && !miner_thread) {
flags |= RANDOMX_FLAG_SECURE;
}
*vm = randomx_create_vm((flags | RANDOMX_FLAG_LARGE_PAGES | RANDOMX_FLAG_FULL_MEM) & ~disabled_flags(), NULL, main_dataset);
if (!*vm) {
mwarning(RX_LOGCAT, "Couldn't allocate RandomX full VM using large pages");
*vm = randomx_create_vm((flags | RANDOMX_FLAG_FULL_MEM) & ~disabled_flags(), NULL, main_dataset);
if (!*vm) {
merror(RX_LOGCAT, "Couldn't allocate RandomX full VM");
}
}
}
static void rx_init_light_vm(randomx_flags flags, randomx_vm** vm, randomx_cache* cache)
{
if (*vm) {
randomx_vm_set_cache(*vm, cache);
return;
}
if ((flags & RANDOMX_FLAG_JIT) && !miner_thread) {
flags |= RANDOMX_FLAG_SECURE;
}
flags &= ~RANDOMX_FLAG_FULL_MEM;
*vm = randomx_create_vm((flags | RANDOMX_FLAG_LARGE_PAGES) & ~disabled_flags(), cache, NULL);
if (!*vm) {
mwarning(RX_LOGCAT, "Couldn't allocate RandomX light VM using large pages");
*vm = randomx_create_vm(flags & ~disabled_flags(), cache, NULL);
if (!*vm) local_abort("Couldn't allocate RandomX light VM");
}
}
typedef struct seedinfo {
@@ -185,165 +281,232 @@ typedef struct seedinfo {
unsigned long si_count;
} seedinfo;
static CTHR_THREAD_RTYPE rx_seedthread(void *arg) {
static CTHR_THREAD_RTYPE me_rx_seedthread(void *arg) {
seedinfo *si = arg;
randomx_init_dataset(rx_dataset, si->si_cache, si->si_start, si->si_count);
randomx_init_dataset(main_dataset, si->si_cache, si->si_start, si->si_count);
CTHR_THREAD_RETURN;
}
static void rx_initdata(randomx_cache *rs_cache, const int miners, const uint64_t seedheight) {
if (miners > 1) {
unsigned long delta = randomx_dataset_item_count() / miners;
unsigned long start = 0;
int i;
seedinfo *si;
CTHR_THREAD_TYPE *st;
si = malloc(miners * sizeof(seedinfo));
if (si == NULL)
local_abort("Couldn't allocate RandomX mining threadinfo");
st = malloc(miners * sizeof(CTHR_THREAD_TYPE));
if (st == NULL) {
free(si);
local_abort("Couldn't allocate RandomX mining threadlist");
static void me_rx_init_dataset(size_t max_threads) {
if (!main_dataset) {
return;
}
for (i=0; i<miners-1; i++) {
si[i].si_cache = rs_cache;
// leave 2 CPU cores for other tasks
const size_t num_threads = (max_threads < 4) ? 1 : (max_threads - 2);
seedinfo* si = malloc(num_threads * sizeof(seedinfo));
if (!si) local_abort("Couldn't allocate RandomX mining threadinfo");
const uint32_t delta = randomx_dataset_item_count() / num_threads;
uint32_t start = 0;
const size_t n1 = num_threads - 1;
for (size_t i = 0; i < n1; ++i) {
si[i].si_cache = main_cache;
si[i].si_start = start;
si[i].si_count = delta;
start += delta;
}
si[i].si_cache = rs_cache;
si[i].si_start = start;
si[i].si_count = randomx_dataset_item_count() - start;
for (i=1; i<miners; i++) {
CTHR_THREAD_CREATE(st[i], rx_seedthread, &si[i]);
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");
}
randomx_init_dataset(rx_dataset, rs_cache, 0, si[0].si_count);
for (i=1; i<miners; i++) {
CTHR_THREAD_JOIN(st[i]);
}
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");
}
typedef struct thread_info {
char seedhash[HASH_SIZE];
size_t max_threads;
} thread_info;
static CTHR_THREAD_RTYPE me_rx_set_main_seedhash_thread(void *arg) {
thread_info* info = arg;
CTHR_RWLOCK_LOCK_WRITE(main_dataset_lock);
CTHR_RWLOCK_LOCK_WRITE(main_cache_lock);
// Double check that seedhash wasn't already updated
if (is_main(info->seedhash)) {
CTHR_RWLOCK_UNLOCK_WRITE(main_cache_lock);
CTHR_RWLOCK_UNLOCK_WRITE(main_dataset_lock);
free(info);
CTHR_THREAD_RETURN;
}
memcpy(main_seedhash, info->seedhash, HASH_SIZE);
main_seedhash_set = 1;
char buf[HASH_SIZE * 2 + 1];
hash2hex(main_seedhash, buf);
minfo(RX_LOGCAT, "RandomX new main seed hash is %s", buf);
const randomx_flags flags = enabled_flags() & ~disabled_flags();
rx_alloc_dataset(flags, &main_dataset, 0);
rx_alloc_cache(flags, &main_cache);
randomx_init_cache(main_cache, info->seedhash, HASH_SIZE);
minfo(RX_LOGCAT, "RandomX main cache initialized");
CTHR_RWLOCK_UNLOCK_WRITE(main_cache_lock);
// From this point, rx_slow_hash can calculate hashes in light mode, but dataset is not initialized yet
me_rx_init_dataset(info->max_threads);
CTHR_RWLOCK_UNLOCK_WRITE(main_dataset_lock);
free(info);
CTHR_THREAD_RETURN;
}
void me_rx_set_main_seedhash(const char *seedhash, size_t max_dataset_init_threads) {
// Early out if seedhash didn't change
if (is_main(seedhash)) {
return;
}
// Update main cache and dataset in the background
thread_info* info = malloc(sizeof(thread_info));
if (!info) local_abort("Couldn't allocate RandomX mining threadinfo");
memcpy(info->seedhash, seedhash, HASH_SIZE);
info->max_threads = max_dataset_init_threads;
CTHR_THREAD_TYPE t;
if (!CTHR_THREAD_CREATE(t, me_rx_set_main_seedhash_thread, info)) {
local_abort("Couldn't start RandomX seed thread");
}
}
void me_rx_slow_hash(const char *seedhash, const void *data, size_t length, char *result_hash) {
const randomx_flags flags = enabled_flags() & ~disabled_flags();
int success = 0;
// Fast path (seedhash == main_seedhash)
// Multiple threads can run in parallel in fast or light mode, 1-2 ms or 10-15 ms per hash per thread
if (is_main(seedhash)) {
// If CTHR_RWLOCK_TRYLOCK_READ fails it means dataset is being initialized now, so use the light mode
if (main_dataset && CTHR_RWLOCK_TRYLOCK_READ(main_dataset_lock)) {
// Double check that main_seedhash didn't change
if (is_main(seedhash)) {
rx_init_full_vm(flags, &main_vm_full);
if (main_vm_full) {
randomx_calculate_hash(main_vm_full, data, length, result_hash);
success = 1;
}
}
CTHR_RWLOCK_UNLOCK_READ(main_dataset_lock);
} else {
randomx_init_dataset(rx_dataset, rs_cache, 0, randomx_dataset_item_count());
CTHR_RWLOCK_LOCK_READ(main_cache_lock);
// Double check that main_seedhash didn't change
if (is_main(seedhash)) {
rx_init_light_vm(flags, &main_vm_light, main_cache);
randomx_calculate_hash(main_vm_light, data, length, result_hash);
success = 1;
}
rx_dataset_height = seedheight;
}
void me_rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const char *seedhash, const void *data, size_t length,
char *hash, int miners, int is_alt) {
uint64_t s_height = me_rx_seedheight(mainheight);
int changed = 0;
int toggle = is_alt ? s_height : seedheight;
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
rx_state *rx_sp;
randomx_cache *cache;
toggle = (toggle & SEEDHASH_EPOCH_BLOCKS) != 0;
CTHR_MUTEX_LOCK(rx_mutex);
/* if alt block but with same seed as mainchain, no need for alt cache */
if (is_alt && s_height == seedheight && !memcmp(rx_s[toggle].rs_hash, seedhash, sizeof(rx_s[toggle].rs_hash)))
is_alt = 0;
/* RPC could request an earlier block on mainchain */
if (!is_alt && s_height > seedheight)
is_alt = 1;
toggle ^= (is_alt != 0);
if (toggle != rx_toggle)
changed = 1;
rx_toggle = toggle;
rx_sp = &rx_s[toggle];
CTHR_MUTEX_LOCK(rx_sp->rs_mutex);
CTHR_MUTEX_UNLOCK(rx_mutex);
cache = rx_sp->rs_cache;
if (cache == NULL) {
if (use_rx_jit())
flags |= RANDOMX_FLAG_JIT;
if (cache == NULL) {
cache = randomx_alloc_cache(flags | RANDOMX_FLAG_LARGE_PAGES);
if (cache == NULL) {
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomX cache");
cache = randomx_alloc_cache(flags);
}
if (cache == NULL)
local_abort("Couldn't allocate RandomX cache");
}
}
if (rx_sp->rs_height != seedheight || rx_sp->rs_cache == NULL || memcmp(seedhash, rx_sp->rs_hash, sizeof(rx_sp->rs_hash))) {
randomx_init_cache(cache, seedhash, 32);
rx_sp->rs_cache = cache;
rx_sp->rs_height = seedheight;
memcpy(rx_sp->rs_hash, seedhash, sizeof(rx_sp->rs_hash));
changed = 1;
}
if (rx_vm == NULL) {
randomx_flags flags = RANDOMX_FLAG_DEFAULT;
if (use_rx_jit()) {
flags |= RANDOMX_FLAG_JIT;
if (!miners)
flags |= RANDOMX_FLAG_SECURE;
}
if(!force_software_aes() && check_aes_hw())
flags |= RANDOMX_FLAG_HARD_AES;
if (miners) {
CTHR_MUTEX_LOCK(rx_dataset_mutex);
if (rx_dataset == NULL) {
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_LARGE_PAGES);
if (rx_dataset == NULL) {
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomX dataset");
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_DEFAULT);
}
if (rx_dataset != NULL)
rx_initdata(rx_sp->rs_cache, miners, seedheight);
}
if (rx_dataset != NULL)
flags |= RANDOMX_FLAG_FULL_MEM;
else {
miners = 0;
mwarning(RX_LOGCAT, "Couldn't allocate RandomX dataset for miner");
}
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
}
rx_vm = randomx_create_vm(flags | RANDOMX_FLAG_LARGE_PAGES, rx_sp->rs_cache, rx_dataset);
if(rx_vm == NULL) { //large pages failed
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomX VM");
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, rx_dataset);
}
if(rx_vm == NULL) {//fallback if everything fails
flags = RANDOMX_FLAG_DEFAULT | (miners ? RANDOMX_FLAG_FULL_MEM : 0);
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, rx_dataset);
}
if (rx_vm == NULL)
local_abort("Couldn't allocate RandomX VM");
} else if (miners) {
CTHR_MUTEX_LOCK(rx_dataset_mutex);
if (rx_dataset != NULL && rx_dataset_height != seedheight)
rx_initdata(cache, miners, seedheight);
CTHR_MUTEX_UNLOCK(rx_dataset_mutex);
} else if (changed) {
randomx_vm_set_cache(rx_vm, rx_sp->rs_cache);
}
/* mainchain users can run in parallel */
if (!is_alt)
CTHR_MUTEX_UNLOCK(rx_sp->rs_mutex);
randomx_calculate_hash(rx_vm, data, length, hash);
/* altchain slot users always get fully serialized */
if (is_alt)
CTHR_MUTEX_UNLOCK(rx_sp->rs_mutex);
}
void me_rx_slow_hash_allocate_state(void) {
}
void me_rx_slow_hash_free_state(void) {
if (rx_vm != NULL) {
randomx_destroy_vm(rx_vm);
rx_vm = NULL;
CTHR_RWLOCK_UNLOCK_READ(main_cache_lock);
}
}
if (success) {
return;
}
char buf[HASH_SIZE * 2 + 1];
// Slow path (seedhash != main_seedhash, but seedhash == secondary_seedhash)
// Multiple threads can run in parallel in light mode, 10-15 ms per hash per thread
if (!secondary_cache) {
CTHR_RWLOCK_LOCK_WRITE(secondary_cache_lock);
if (!secondary_cache) {
hash2hex(seedhash, buf);
minfo(RX_LOGCAT, "RandomX new secondary seed hash is %s", buf);
rx_alloc_cache(flags, &secondary_cache);
randomx_init_cache(secondary_cache, seedhash, HASH_SIZE);
minfo(RX_LOGCAT, "RandomX secondary cache updated");
memcpy(secondary_seedhash, seedhash, HASH_SIZE);
secondary_seedhash_set = 1;
}
CTHR_RWLOCK_UNLOCK_WRITE(secondary_cache_lock);
}
CTHR_RWLOCK_LOCK_READ(secondary_cache_lock);
if (is_secondary(seedhash)) {
rx_init_light_vm(flags, &secondary_vm_light, secondary_cache);
randomx_calculate_hash(secondary_vm_light, data, length, result_hash);
success = 1;
}
CTHR_RWLOCK_UNLOCK_READ(secondary_cache_lock);
if (success) {
return;
}
// Slowest path (seedhash != main_seedhash, seedhash != secondary_seedhash)
// Only one thread runs at a time and updates secondary_seedhash if needed, up to 200-500 ms per hash
CTHR_RWLOCK_LOCK_WRITE(secondary_cache_lock);
if (!is_secondary(seedhash)) {
hash2hex(seedhash, buf);
minfo(RX_LOGCAT, "RandomX new secondary seed hash is %s", buf);
randomx_init_cache(secondary_cache, seedhash, HASH_SIZE);
minfo(RX_LOGCAT, "RandomX secondary cache updated");
memcpy(secondary_seedhash, seedhash, HASH_SIZE);
secondary_seedhash_set = 1;
}
rx_init_light_vm(flags, &secondary_vm_light, secondary_cache);
randomx_calculate_hash(secondary_vm_light, data, length, result_hash);
CTHR_RWLOCK_UNLOCK_WRITE(secondary_cache_lock);
}
void me_rx_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);
}
uint32_t me_rx_get_miner_thread() {
return miner_thread;
}
void me_rx_slow_hash_allocate_state() {}
static void me_rx_destroy_vm(randomx_vm** vm) {
if (*vm) {
randomx_destroy_vm(*vm);
*vm = NULL;
}
}
void me_rx_slow_hash_free_state() {
me_rx_destroy_vm(&main_vm_full);
me_rx_destroy_vm(&main_vm_light);
me_rx_destroy_vm(&secondary_vm_light);
}
+190 -125
View File
@@ -27,7 +27,7 @@
#include "CurrentBlockchainStatus.h"
#include "MempoolStatus.h"
#include "../ext/crow/crow.h"
#include "../ext/crow_all.h"
#include "../ext/json.hpp"
@@ -42,7 +42,7 @@ extern "C" void me_rx_slow_hash(const uint64_t mainheight, const uint64_t seedhe
char *hash, int miners, int is_alt);
//extern "C" void me_rx_reorg(const uint64_t split_height);
extern __thread randomx_vm *rx_vm;
extern __thread randomx_vm *main_vm_full;
#include <algorithm>
#include <limits>
@@ -336,7 +336,7 @@ struct tx_details
vector<txin_to_key> input_key_imgs;
// public keys and xmr amount of outputs
vector<pair<txout_to_key, uint64_t>> output_pub_keys;
vector<output_tuple_with_tag> output_pub_keys;
mstch::map
get_mstch_map() const
@@ -473,6 +473,7 @@ bool enable_key_image_checker;
bool enable_output_key_checker;
bool enable_mixins_details;
bool enable_as_hex;
bool enable_mixin_guess;
bool enable_autorefresh_option;
@@ -498,7 +499,7 @@ public:
page(MicroCore* _mcore,
Blockchain* _core_storage,
string _deamon_url,
string _daemon_url,
cryptonote::network_type _nettype,
bool _enable_pusher,
bool _enable_randomx,
@@ -507,6 +508,7 @@ page(MicroCore* _mcore,
bool _enable_output_key_checker,
bool _enable_autorefresh_option,
bool _enable_mixins_details,
bool _enable_mixin_guess,
uint64_t _no_blocks_on_index,
uint64_t _mempool_info_timeout,
string _testnet_url,
@@ -515,7 +517,7 @@ page(MicroCore* _mcore,
rpccalls::login_opt _daemon_rpc_login)
: mcore {_mcore},
core_storage {_core_storage},
rpc {_deamon_url, _daemon_rpc_login},
rpc {_daemon_url, _daemon_rpc_login},
server_timestamp {std::time(nullptr)},
nettype {_nettype},
enable_pusher {_enable_pusher},
@@ -525,6 +527,7 @@ page(MicroCore* _mcore,
enable_output_key_checker {_enable_output_key_checker},
enable_autorefresh_option {_enable_autorefresh_option},
enable_mixins_details {_enable_mixins_details},
enable_mixin_guess {_enable_mixin_guess},
no_blocks_on_index {_no_blocks_on_index},
mempool_info_timeout {_mempool_info_timeout},
testnet_url {_testnet_url},
@@ -575,21 +578,6 @@ page(MicroCore* _mcore,
string
index2(uint64_t page_no = 0, bool refresh_page = false)
{
// we get network info, such as current hash rate
// but since this makes a rpc call to deamon, we make it as an async
// call. this way we dont have to wait with execution of the rest of the
// index2 method, until deamon gives as the required result.
std::future<json> network_info_ftr = std::async(std::launch::async, [&]
{
json j_info;
get_monero_network_info(j_info);
return j_info;
});
// get mempool for the front page also using async future
std::future<string> mempool_ftr = std::async(std::launch::async, [&]
{
@@ -1446,17 +1434,23 @@ show_block_hex(size_t block_height, bool complete_blk)
return string {"Failed to obtain complete block data "};
}
std::string complete_block_data_str;
epee::byte_slice complete_block_data_slice;
/*if(!epee::serialization::store_t_to_binary(
complete_block_data, complete_block_data_str))
if(!epee::serialization::store_t_to_binary(
complete_block_data, complete_block_data_slice))
{
cerr << "Failed to serialize complete_block_data\n";
return string {"Failed to obtain complete block data"};
}*/
}
std::string block_data_str(
complete_block_data_slice.begin(),
complete_block_data_slice.end());
return epee::string_tools
::buff_to_hex_nodelimer(complete_block_data_str);
::buff_to_hex_nodelimer(block_data_str);
}
}
catch (std::exception const& e)
@@ -1743,14 +1737,14 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str)
return json {"error", "Failed to obtain complete block data "};
}
std::string complete_block_data_str;
epee::byte_slice complete_block_data_slice;
/*if(!epee::serialization::store_t_to_binary(
complete_block_data, complete_block_data_str))
if(!epee::serialization::store_t_to_binary(
complete_block_data, complete_block_data_slice))
{
cerr << "Failed to serialize complete_block_data\n";
return json {"error", "Failed to obtain complete block data"};
}*/
}
tx_details txd = get_tx_details(tx);
@@ -1758,6 +1752,10 @@ show_ringmemberstx_jsonhex(string const& tx_hash_str)
tx_json["payment_id8"] = pod_to_hex(txd.payment_id8);
tx_json["payment_id8e"] = pod_to_hex(txd.payment_id8);
std::string complete_block_data_str(
complete_block_data_slice.begin(),
complete_block_data_slice.end());
tx_json["block"] = epee::string_tools
::buff_to_hex_nodelimer(complete_block_data_str);
@@ -1893,6 +1891,8 @@ show_my_outputs(string tx_hash_str,
boost::trim(viewkey_str);
boost::trim(raw_tx_data);
(void) domain; // not used
if (tx_hash_str.empty())
{
return string("tx hash not provided!");
@@ -2113,7 +2113,6 @@ show_my_outputs(string tx_hash_str,
{"payment_id8" , pid8_str},
{"decrypted_payment_id8", string{}},
{"tx_prove" , tx_prove},
{"domain_url" , domain},
{"shortcut_url" , shortcut_url}
};
@@ -2143,7 +2142,7 @@ show_my_outputs(string tx_hash_str,
{
cerr << "Cant get derived key for: " << "\n"
<< "pub_tx_key: " << pub_key << " and "
<< "prv_view_key" << prv_view_key << endl;
<< "prv_view_key" << pod_to_hex(unwrap(unwrap(prv_view_key))) << endl;
return string("Cant get key_derivation");
}
@@ -2156,7 +2155,7 @@ show_my_outputs(string tx_hash_str,
{
cerr << "Cant get derived key for: " << "\n"
<< "pub_tx_key: " << txd.additional_pks[i] << " and "
<< "prv_view_key" << prv_view_key << endl;
<< "prv_view_key" << pod_to_hex(unwrap(unwrap(prv_view_key))) << endl;
return string("Cant get key_derivation");
}
@@ -2184,7 +2183,7 @@ show_my_outputs(string tx_hash_str,
uint64_t output_idx {0};
for (pair<txout_to_key, uint64_t>& outp: txd.output_pub_keys)
for (output_tuple_with_tag& outp: txd.output_pub_keys)
{
// get the tx output public key
@@ -2199,12 +2198,14 @@ show_my_outputs(string tx_hash_str,
// cout << pod_to_hex(derivation) << ", " << output_idx << ", "
// << pod_to_hex(address_info.address.m_spend_public_key) << ", "
// << pod_to_hex(outp.first.key) << " == "
// << pod_to_hex(outp.first) << " == "
// << pod_to_hex(tx_pubkey) << '\n' << '\n';
// check if generated public key matches the current output's key
bool mine_output = (outp.first.key == tx_pubkey);
bool mine_output = (std::get<0>(outp) == tx_pubkey);
bool with_additional = false;
@@ -2217,11 +2218,13 @@ show_my_outputs(string tx_hash_str,
tx_pubkey);
mine_output = (outp.first.key == tx_pubkey);
mine_output = (std::get<0>(outp) == tx_pubkey);
with_additional = true;
}
uint64_t xmr_amount = std::get<1>(outp);
// if mine output has RingCT, i.e., tx version is 2
if (mine_output && tx.version == 2)
{
@@ -2235,10 +2238,12 @@ show_my_outputs(string tx_hash_str,
bool r;
auto derivation_to_use = with_additional
? additional_derivations[output_idx] : derivation;
r = decode_ringct(
tx.rct_signatures,
with_additional
? additional_derivations[output_idx] : derivation,
derivation_to_use,
output_idx,
tx.rct_signatures.ecdhInfo[output_idx].mask,
rct_amount);
@@ -2248,7 +2253,14 @@ show_my_outputs(string tx_hash_str,
cerr << "\nshow_my_outputs: Cant decode RingCT!\n";
}
outp.second = rct_amount;
// decode view key
// crypto::view_tag derived_view_tag;
// crypto::derive_view_tag(derivation_to_use,
// output_idx, derived_view_tag);
// cout << derived_view_tag << endl;
xmr_amount = rct_amount;
money_transfered[output_idx] = rct_amount;
}
@@ -2256,12 +2268,12 @@ show_my_outputs(string tx_hash_str,
if (mine_output)
{
sum_xmr += outp.second;
sum_xmr += xmr_amount;
}
outputs.push_back(mstch::map {
{"out_pub_key" , pod_to_hex(outp.first.key)},
{"amount" , xmreg::xmr_amount_to_str(outp.second)},
{"out_pub_key" , pod_to_hex(std::get<0>(outp))},
{"amount" , xmreg::xmr_amount_to_str(xmr_amount)},
{"mine_output" , mine_output},
{"output_idx" , fmt::format("{:02d}", output_idx)}
});
@@ -2269,13 +2281,21 @@ show_my_outputs(string tx_hash_str,
++output_idx;
}
context.emplace("outputs", outputs);
context["found_our_outputs"] = (sum_xmr > 0);
context["sum_xmr"] = xmreg::xmr_amount_to_str(sum_xmr);
// we can also test ouputs used in mixins for key images
// this can show possible spending. Only possible, because
// without a spend key, we cant know for sure. It might be
// that our output was used by someone else for their mixins.
bool show_key_images {false};
if (enable_mixin_guess) {
bool show_key_images {false};
mstch::array inputs;
@@ -2438,7 +2458,7 @@ show_my_outputs(string tx_hash_str,
{
cerr << "Cant get derived key for: " << "\n"
<< "pub_tx_key: " << mixin_tx_pub_key << " and "
<< "prv_view_key" << prv_view_key << endl;
<< "prv_view_key" << pod_to_hex(unwrap(unwrap(prv_view_key))) << endl;
continue;
}
@@ -2450,14 +2470,14 @@ show_my_outputs(string tx_hash_str,
{
cerr << "Cant get derived key for: " << "\n"
<< "pub_tx_key: " << mixin_additional_tx_pub_keys[i]
<< " and prv_view_key" << prv_view_key << endl;
<< " and prv_view_key" << pod_to_hex(unwrap(unwrap(prv_view_key))) << endl;
continue;
}
}
// <public_key , amount , out idx>
vector<tuple<txout_to_key, uint64_t, uint64_t>> output_pub_keys;
vector<tuple<public_key, uint64_t, uint64_t>> output_pub_keys;
output_pub_keys = xmreg::get_ouputs_tuple(mixin_tx);
@@ -2485,15 +2505,15 @@ show_my_outputs(string tx_hash_str,
for (const auto& mix_out: output_pub_keys)
{
txout_to_key const& txout_k = std::get<0>(mix_out);
public_key const& output_pub_key = std::get<0>(mix_out);
uint64_t amount = std::get<1>(mix_out);
uint64_t output_idx_in_tx = std::get<2>(mix_out);
//cout << " - " << pod_to_hex(txout_k.key) << endl;
//cout << " - " << pod_to_hex(output_pub_key) << endl;
// // analyze only those output keys
// // that were used in mixins
// if (txout_k.key != output_data.pubkey)
// if (output_pub_key != output_data.pubkey)
// {
// continue;
// }
@@ -2509,7 +2529,7 @@ show_my_outputs(string tx_hash_str,
tx_pubkey_generated);
// check if generated public key matches the current output's key
bool mine_output = (txout_k.key == tx_pubkey_generated);
bool mine_output = (output_pub_key == tx_pubkey_generated);
bool with_additional = false;
@@ -2521,7 +2541,7 @@ show_my_outputs(string tx_hash_str,
address_info.address.m_spend_public_key,
tx_pubkey_generated);
mine_output = (txout_k.key == tx_pubkey_generated);
mine_output = (output_pub_key == tx_pubkey_generated);
with_additional = true;
}
@@ -2538,10 +2558,12 @@ show_my_outputs(string tx_hash_str,
bool r;
auto derivation_to_use = with_additional
? additional_derivations[output_idx] : derivation;
r = decode_ringct(
mixin_tx.rct_signatures,
with_additional
? additional_derivations[output_idx_in_tx] : derivation,
derivation_to_use,
output_idx_in_tx,
mixin_tx.rct_signatures.ecdhInfo[output_idx_in_tx].mask,
rct_amount);
@@ -2556,7 +2578,7 @@ show_my_outputs(string tx_hash_str,
}
// makre only
bool output_match = (txout_k.key == output_data.pubkey);
bool output_match = (output_pub_key == output_data.pubkey);
// mark only first output_match as the "real" one
// due to luck of better method of gussing which output
@@ -2565,7 +2587,7 @@ show_my_outputs(string tx_hash_str,
// save our mixnin's public keys
found_outputs.push_back(mstch::map {
{"my_public_key" , pod_to_hex(txout_k.key)},
{"my_public_key" , pod_to_hex(output_pub_key)},
{"tx_hash" , tx_hash_str},
{"mine_output" , mine_output},
{"out_idx" , output_idx_in_tx},
@@ -2574,7 +2596,7 @@ show_my_outputs(string tx_hash_str,
{"amount" , xmreg::xmr_amount_to_str(amount)}
});
//cout << "txout_k.key == output_data.pubkey" << endl;
//cout << "output_pub_key == output_data.pubkey" << endl;
if (mine_output)
{
@@ -2584,7 +2606,7 @@ show_my_outputs(string tx_hash_str,
// increase sum_mixin_xmr only when
// public key of an outputs used in ring signature,
// matches a public key in a mixin_tx
if (txout_k.key != output_data.pubkey)
if (output_pub_key != output_data.pubkey)
continue;
// sum up only first output matched found in each input
@@ -2633,7 +2655,7 @@ show_my_outputs(string tx_hash_str,
} // if (mine_output)
} // for (const pair<txout_to_key, uint64_t>& mix_out: txd.output_pub_keys)
} // for (const pair<public_key, uint64_t>& mix_out: txd.output_pub_keys)
has_found_outputs = !found_outputs.empty();
@@ -2653,10 +2675,9 @@ show_my_outputs(string tx_hash_str,
} // for (const txin_to_key& in_key: input_key_imgs)
context.emplace("outputs", outputs);
context["found_our_outputs"] = (sum_xmr > 0);
context["sum_xmr"] = xmreg::xmr_amount_to_str(sum_xmr);
context.emplace("inputs", inputs);
@@ -2698,6 +2719,8 @@ show_my_outputs(string tx_hash_str,
context["possible_spending"] = xmreg::xmr_amount_to_str(
possible_spending, "{:0.11f}", false);
} // if (enable_mixin_guess)
add_css_style(context);
// render the page
@@ -2903,7 +2926,7 @@ show_checkrawtx(string raw_tx_data, string action)
real_output_indices.push_back(tx_source.real_output);
public_key real_out_pub_key = real_txd.output_pub_keys[tx_source.real_output_in_tx_index].first.key;
public_key real_out_pub_key = std::get<0>(real_txd.output_pub_keys[tx_source.real_output_in_tx_index]);
//cout << "real_txd.hash: " << pod_to_hex(real_txd.hash) << endl;
//cout << "real_txd.pk: " << pod_to_hex(real_txd.pk) << endl;
@@ -2952,7 +2975,7 @@ show_checkrawtx(string raw_tx_data, string action)
tx_details txd = get_tx_details(tx);
public_key out_pub_key = txd.output_pub_keys[toi.second].first.key;
public_key out_pub_key = std::get<0>(txd.output_pub_keys[toi.second]);
// get block cointaining this tx
@@ -3163,7 +3186,7 @@ show_checkrawtx(string raw_tx_data, string action)
return boost::get<string>(tx_context["error_msg"]);
}
tx_context["tx_prv_key"] = fmt::format("{:s}", ptx.tx_key);
tx_context["tx_prv_key"] = fmt::format("{:s}", pod_to_hex(unwrap(unwrap(ptx.tx_key))));
mstch::array destination_addresses;
vector<uint64_t> real_ammounts;
@@ -3246,7 +3269,7 @@ show_checkrawtx(string raw_tx_data, string action)
{
transaction real_source_tx;
uint64_t index_of_real_output = tx_source.outputs[tx_source.real_output].first;
uint64_t index_of_real_output = std::get<0>(tx_source.outputs[tx_source.real_output]);
uint64_t tx_source_amount = (tx_source.rct ? 0 : tx_source.amount);
@@ -3280,7 +3303,7 @@ show_checkrawtx(string raw_tx_data, string action)
tx_details real_txd = get_tx_details(real_source_tx);
public_key real_out_pub_key
= real_txd.output_pub_keys[tx_source.real_output_in_tx_index].first.key;
= std::get<0>(real_txd.output_pub_keys[tx_source.real_output_in_tx_index]);
real_output_pub_keys.push_back(
REMOVE_HASH_BRAKETS(fmt::format("{:s}",real_out_pub_key))
@@ -3714,7 +3737,7 @@ show_checkrawkeyimgs(string raw_data, string viewkey_str)
context.insert({"address" , REMOVE_HASH_BRAKETS(
xmreg::print_address(address_info, nettype))});
context.insert({"viewkey" , REMOVE_HASH_BRAKETS(
fmt::format("{:s}", prv_view_key))});
fmt::format("{:s}", pod_to_hex(unwrap(unwrap(prv_view_key)))))});
context.insert({"has_total_xmr" , false});
context.insert({"total_xmr" , string{}});
context.insert({"key_imgs" , mstch::array{}});
@@ -3847,7 +3870,7 @@ show_checkcheckrawoutput(string raw_data, string viewkey_str)
context.insert({"address" , REMOVE_HASH_BRAKETS(
xmreg::print_address(address_info, nettype))});
context.insert({"viewkey" , pod_to_hex(prv_view_key)});
context.insert({"viewkey" , pod_to_hex(unwrap(unwrap(prv_view_key)))});
context.insert({"has_total_xmr" , false});
context.insert({"total_xmr" , string{}});
context.insert({"output_keys" , mstch::array{}});
@@ -3889,8 +3912,7 @@ show_checkcheckrawoutput(string raw_data, string viewkey_str)
const transaction_prefix& txp = td.m_tx;
txout_to_key txout_key = boost::get<txout_to_key>(
txp.vout[td.m_internal_output_index].target);
public_key output_pub_key = td.get_public_key();
uint64_t xmr_amount = td.amount();
@@ -3936,7 +3958,7 @@ show_checkcheckrawoutput(string raw_data, string viewkey_str)
{
string error_msg = fmt::format(
"Cant decode RingCT for output: {:s}",
txout_key.key);
output_pub_key);
context["has_error"] = true;
context["error_msg"] = error_msg;
@@ -3968,7 +3990,7 @@ show_checkcheckrawoutput(string raw_data, string viewkey_str)
mstch::map output_info {
{"output_no" , fmt::format("{:03d}", output_no)},
{"output_pub_key" , REMOVE_HASH_BRAKETS(fmt::format("{:s}", txout_key.key))},
{"output_pub_key" , REMOVE_HASH_BRAKETS(fmt::format("{:s}", output_pub_key))},
{"amount" , xmreg::xmr_amount_to_str(xmr_amount)},
{"tx_hash" , REMOVE_HASH_BRAKETS(fmt::format("{:s}", td.m_txid))},
{"timestamp" , xmreg::timestamp_to_str_gm(blk_timestamp)},
@@ -4218,11 +4240,11 @@ search_txs(vector<transaction> txs, const string& search_text)
// check if output_public_keys matche the search_text
vector<pair<txout_to_key, uint64_t>>::iterator it2 =
vector<output_tuple_with_tag>::iterator it2 =
find_if(begin(txd.output_pub_keys), end(txd.output_pub_keys),
[&](const pair<txout_to_key, uint64_t>& tx_out_pk)
[&](const output_tuple_with_tag& tx_out_pk)
{
return pod_to_hex(tx_out_pk.first.key) == search_text;
return pod_to_hex(std::get<0>(tx_out_pk)) == search_text;
});
if (it2 != txd.output_pub_keys.end())
@@ -4452,8 +4474,8 @@ json_transaction(string tx_hash_str)
for (const auto& output: txd.output_pub_keys)
{
outputs.push_back(json {
{"public_key", pod_to_hex(output.first.key)},
{"amount" , output.second}
{"public_key", pod_to_hex(std::get<0>(output))},
{"amount" , std::get<1>(output)}
});
}
@@ -5369,7 +5391,7 @@ json_outputs(string tx_hash_str,
j_data["outputs"] = json::array();
json& j_outptus = j_data["outputs"];
for (pair<txout_to_key, uint64_t>& outp: txd.output_pub_keys)
for (output_tuple_with_tag& outp: txd.output_pub_keys)
{
// get the tx output public key
@@ -5383,7 +5405,7 @@ json_outputs(string tx_hash_str,
tx_pubkey);
// check if generated public key matches the current output's key
bool mine_output = (outp.first.key == tx_pubkey);
bool mine_output = (std::get<0>(outp) == tx_pubkey);
bool with_additional = false;
if (!mine_output && txd.additional_pks.size() == txd.output_pub_keys.size())
{
@@ -5391,10 +5413,12 @@ json_outputs(string tx_hash_str,
output_idx,
address_info.address.m_spend_public_key,
tx_pubkey);
mine_output = (outp.first.key == tx_pubkey);
mine_output = (std::get<0>(outp) == tx_pubkey);
with_additional = true;
}
uint64_t xmr_amount = std::get<1>(outp);
// if mine output has RingCT, i.e., tx version is 2
if (mine_output && tx.version == 2)
{
@@ -5408,8 +5432,11 @@ json_outputs(string tx_hash_str,
bool r;
auto derivation_to_use = with_additional
? additional_derivations[output_idx] : derivation;
r = decode_ringct(tx.rct_signatures,
with_additional ? additional_derivations[output_idx] : derivation,
derivation_to_use,
output_idx,
tx.rct_signatures.ecdhInfo[output_idx].mask,
rct_amount);
@@ -5419,7 +5446,7 @@ json_outputs(string tx_hash_str,
cerr << "\nshow_my_outputs: Cant decode ringCT! " << endl;
}
outp.second = rct_amount;
xmr_amount = rct_amount;
money_transfered[output_idx] = rct_amount;
} // if (!is_coinbase(tx))
@@ -5427,15 +5454,15 @@ json_outputs(string tx_hash_str,
} // if (mine_output && tx.version == 2)
j_outptus.push_back(json {
{"output_pubkey", pod_to_hex(outp.first.key)},
{"amount" , outp.second},
{"output_pubkey", pod_to_hex(std::get<0>(outp))},
{"amount" , xmr_amount},
{"match" , mine_output},
{"output_idx" , output_idx},
});
++output_idx;
} // for (pair<txout_to_key, uint64_t>& outp: txd.output_pub_keys)
} // for (pair<public_key, uint64_t>& outp: txd.output_pub_keys)
// if we don't already have the tx_timestamp from the mempool
// then read it from the block that the transaction is in
@@ -5450,7 +5477,7 @@ json_outputs(string tx_hash_str,
// matches to what was used to produce response.
j_data["tx_hash"] = pod_to_hex(txd.hash);
j_data["address"] = pod_to_hex(address_info.address);
j_data["viewkey"] = pod_to_hex(prv_view_key);
j_data["viewkey"] = pod_to_hex(unwrap(unwrap(prv_view_key)));
j_data["tx_prove"] = tx_prove;
j_data["tx_confirmations"] = txd.no_confirmations;
j_data["tx_timestamp"] = tx_timestamp;
@@ -5634,7 +5661,7 @@ json_outputsblocks(string _limit,
// check if submited data in the request
// matches to what was used to produce response.
j_data["address"] = pod_to_hex(address_info.address);
j_data["viewkey"] = pod_to_hex(prv_view_key);
j_data["viewkey"] = pod_to_hex(unwrap(unwrap(prv_view_key)));
j_data["limit"] = _limit;
j_data["height"] = height;
j_data["mempool"] = in_mempool_aswell;
@@ -5665,20 +5692,23 @@ json_networkinfo()
{
j_response["status"] = "error";
j_response["message"] = "Cant get monero network info";
return j_response;
// return j_response;
}
uint64_t per_kb_fee_estimated {0};
// get dynamic fee estimate from last 10 blocks
if (!get_dynamic_per_kb_fee_estimate(per_kb_fee_estimated))
{
j_response["status"] = "error";
j_response["message"] = "Cant get per kb dynamic fee esimate";
// return j_response;
}
uint64_t fee_estimated {0};
// get dynamic fee estimate from last 10 blocks
if (!get_dynamic_per_kb_fee_estimate(fee_estimated))
{
j_response["status"] = "error";
j_response["message"] = "Cant get dynamic fee esimate";
return j_response;
}
j_info["fee_per_kb"] = fee_estimated;
j_info["fee_per_kb"] = per_kb_fee_estimated;
j_info["fee_estimate"] = fee_estimated;
j_info["tx_pool_size"] = MempoolStatus::mempool_no.load();
j_info["tx_pool_size_kbytes"] = MempoolStatus::mempool_size.load();
@@ -5840,7 +5870,7 @@ find_our_outputs(
//j_data["outputs"] = json::array();
//json& j_outptus = j_data["outputs"];
for (pair<txout_to_key, uint64_t> &outp: txd.output_pub_keys)
for (output_tuple_with_tag &outp: txd.output_pub_keys)
{
// get the tx output public key
@@ -5854,7 +5884,7 @@ find_our_outputs(
tx_pubkey);
// check if generated public key matches the current output's key
bool mine_output = (outp.first.key == tx_pubkey);
bool mine_output = (std::get<0>(outp) == tx_pubkey);
bool with_additional = false;
if (!mine_output && txd.additional_pks.size() == txd.output_pub_keys.size())
{
@@ -5862,10 +5892,12 @@ find_our_outputs(
output_idx,
address.m_spend_public_key,
tx_pubkey);
mine_output = (outp.first.key == tx_pubkey);
mine_output = (std::get<0>(outp) == tx_pubkey);
with_additional = true;
}
uint64_t xmr_amount = std::get<1>(outp);
// if mine output has RingCT, i.e., tx version is 2
if (mine_output && tx.version == 2)
{
@@ -5881,8 +5913,11 @@ find_our_outputs(
rct::key mask = tx.rct_signatures.ecdhInfo[output_idx].mask;
auto derivation_to_use = with_additional
? additional_derivations[output_idx] : derivation;
r = decode_ringct(tx.rct_signatures,
with_additional ? additional_derivations[output_idx] : derivation,
derivation_to_use,
output_idx,
mask,
rct_amount);
@@ -5894,7 +5929,7 @@ find_our_outputs(
return false;
}
outp.second = rct_amount;
xmr_amount = rct_amount;
money_transfered[output_idx] = rct_amount;
} // if (!is_coinbase(tx))
@@ -5906,8 +5941,8 @@ find_our_outputs(
string payment_id_str = get_payment_id_as_string(txd, prv_view_key);
j_outptus.push_back(json {
{"output_pubkey" , pod_to_hex(outp.first.key)},
{"amount" , outp.second},
{"output_pubkey" , pod_to_hex(std::get<0>(outp))},
{"amount" , xmr_amount},
{"block_no" , block_no},
{"in_mempool" , is_mempool},
{"output_idx" , output_idx},
@@ -5918,7 +5953,7 @@ find_our_outputs(
++output_idx;
} // for (pair<txout_to_key, uint64_t>& outp: txd.output_pub_keys)
} // for (pair<public_key, uint64_t>& outp: txd.output_pub_keys)
} // for (auto it = blk_txs.begin(); it != blk_txs.end(); ++it)
@@ -6428,12 +6463,12 @@ construct_tx_context(transaction tx, uint16_t with_ring_signatures = 0)
uint64_t outputs_xmr_sum {0};
for (pair<txout_to_key, uint64_t>& outp: txd.output_pub_keys)
for (output_tuple_with_tag& outp: txd.output_pub_keys)
{
// total number of ouputs in the blockchain for this amount
uint64_t num_outputs_amount = core_storage->get_db()
.get_num_outputs(outp.second);
.get_num_outputs(std::get<1>(outp));
string out_amount_index_str {"N/A"};
@@ -6445,18 +6480,29 @@ construct_tx_context(transaction tx, uint16_t with_ring_signatures = 0)
= std::to_string(out_amount_indices.at(output_idx));
}
outputs_xmr_sum += outp.second;
outputs_xmr_sum += std::get<1>(outp);
std::stringstream ss;
if (std::get<2>(outp)) {
ss << *(std::get<2>(outp));
}
else {
ss << "-";
}
string view_tag_str = ss.str();
outputs.push_back(mstch::map {
{"out_pub_key" , pod_to_hex(outp.first.key)},
{"amount" , xmreg::xmr_amount_to_str(outp.second)},
{"out_pub_key" , pod_to_hex(std::get<0>(outp))},
{"amount" , xmreg::xmr_amount_to_str(std::get<1>(outp))},
{"amount_idx" , out_amount_index_str},
{"num_outputs" , num_outputs_amount},
{"output_tag" , view_tag_str},
{"unformated_output_idx" , output_idx},
{"output_idx" , fmt::format("{:02d}", output_idx++)}
});
} // for (pair<txout_to_key, uint64_t>& outp: txd.output_pub_keys)
} // for (pair<public_key, uint64_t>& outp: txd.output_pub_keys)
context["outputs_xmr_sum"] = xmreg::xmr_amount_to_str(outputs_xmr_sum);
@@ -6793,6 +6839,25 @@ get_dynamic_per_kb_fee_estimate(uint64_t& fee_estimated)
return true;
}
bool
get_base_fee_estimate(uint64_t& fee_estimated)
{
string error_msg;
if (!rpc.get_base_fee_estimate(
FEE_ESTIMATE_GRACE_BLOCKS,
fee_estimated))
{
cerr << "rpc.get_base_fee_estimate failed" << endl;
return false;
}
(void) error_msg;
return true;
}
bool
are_absolute_offsets_good(
std::vector<uint64_t> const& absolute_offsets,
@@ -6904,18 +6969,18 @@ get_randomx_code(uint64_t blk_height,
std::lock_guard<std::mutex> lk {mtx};
if (!rx_vm)
if (!main_vm_full)
{
crypto::hash block_hash;
// this will create rx_vm instance if one
// this will create main_vm_full instance if one
// does not exist
me_get_block_longhash(core_storage, blk, block_hash, blk_height, 0);
if (!rx_vm)
if (!main_vm_full)
{
cerr << "rx_vm is still null!";
cerr << "main_vm_full is still null!";
return {};
}
}
@@ -6926,32 +6991,32 @@ get_randomx_code(uint64_t blk_height,
alignas(16) uint64_t tempHash[8];
blake2b(tempHash, sizeof(tempHash), bd.data(), bd.size(), nullptr, 0);
rx_vm->initScratchpad(&tempHash);
rx_vm->resetRoundingMode();
main_vm_full->initScratchpad(&tempHash);
main_vm_full->resetRoundingMode();
for (int chain = 0; chain < RANDOMX_PROGRAM_COUNT - 1; ++chain)
{
rx_vm->run(&tempHash);
main_vm_full->run(&tempHash);
blake2b(tempHash, sizeof(tempHash),
rx_vm->getRegisterFile(),
main_vm_full->getRegisterFile(),
sizeof(randomx::RegisterFile), nullptr, 0);
rx_code.push_back({});
rx_code.back().prog = rx_vm->getProgram();
rx_code.back().reg_file = *(rx_vm->getRegisterFile());
rx_code.back().prog = main_vm_full->getProgram();
rx_code.back().reg_file = *(main_vm_full->getRegisterFile());
}
rx_vm->run(&tempHash);
main_vm_full->run(&tempHash);
rx_code.push_back({});
rx_code.back().prog = rx_vm->getProgram();
rx_code.back().reg_file = *(rx_vm->getRegisterFile());
rx_code.back().prog = main_vm_full->getProgram();
rx_code.back().reg_file = *(main_vm_full->getRegisterFile());
//crypto::hash res2;
//rx_vm->getFinalResult(res2.data, RANDOMX_HASH_SIZE);
//main_vm_full->getFinalResult(res2.data, RANDOMX_HASH_SIZE);
//cout << "pow2: " << pod_to_hex(res2) << endl;
return rx_code;
+63 -36
View File
@@ -9,26 +9,26 @@ namespace xmreg
rpccalls::rpccalls(
string _deamon_url,
string _daemon_url,
login_opt login,
uint64_t _timeout)
: deamon_url {_deamon_url},
: daemon_url {_daemon_url},
timeout_time {_timeout}
{
epee::net_utils::parse_url(deamon_url, url);
epee::net_utils::parse_url(daemon_url, url);
port = std::to_string(url.port);
timeout_time_ms = std::chrono::milliseconds {timeout_time};
m_http_client.set_server(
deamon_url,
daemon_url,
login,
epee::net_utils::ssl_support_t::e_ssl_support_disabled);
}
bool
rpccalls::connect_to_monero_deamon()
rpccalls::connect_to_monero_daemon()
{
//std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
@@ -40,6 +40,33 @@ rpccalls::connect_to_monero_deamon()
return m_http_client.connect(timeout_time_ms);
}
bool
rpccalls::get_base_fee_estimate(uint64_t grace_blocks,
uint64_t& fee_estimate) {
cryptonote::COMMAND_RPC_GET_BASE_FEE_ESTIMATE::request req;
cryptonote::COMMAND_RPC_GET_BASE_FEE_ESTIMATE::response res;
req.grace_blocks = grace_blocks;
if (!connect_to_monero_daemon())
{
cerr << "get_base_fee_estimate: not connected to daemon" << endl;
return false;
}
bool r = epee::net_utils::invoke_http_json(
"/get_fee_estimate",
req, res, m_http_client, timeout_time_ms);
fee_estimate = res.fee;
return r;
}
uint64_t
rpccalls::get_current_height()
{
@@ -48,9 +75,9 @@ rpccalls::get_current_height()
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
if (!connect_to_monero_deamon())
if (!connect_to_monero_daemon())
{
cerr << "get_current_height: not connected to deamon" << endl;
cerr << "get_current_height: not connected to daemon" << endl;
return false;
}
@@ -60,8 +87,8 @@ rpccalls::get_current_height()
if (!r)
{
cerr << "Error connecting to Monero deamon at "
<< deamon_url << endl;
cerr << "Error connecting to Monero daemon at "
<< daemon_url << endl;
return 0;
}
@@ -80,9 +107,9 @@ rpccalls::get_mempool(vector<tx_info>& mempool_txs)
{
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
if (!connect_to_monero_deamon())
if (!connect_to_monero_daemon())
{
cerr << "get_mempool: not connected to deamon" << endl;
cerr << "get_mempool: not connected to daemon" << endl;
return false;
}
@@ -93,8 +120,8 @@ rpccalls::get_mempool(vector<tx_info>& mempool_txs)
if (!r || res.status != CORE_RPC_STATUS_OK)
{
cerr << "Error connecting to Monero deamon at "
<< deamon_url << endl;
cerr << "Error connecting to Monero daemon at "
<< daemon_url << endl;
return false;
}
@@ -127,9 +154,9 @@ rpccalls::commit_tx(tools::wallet2::pending_tx& ptx, string& error_msg)
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
if (!connect_to_monero_deamon())
if (!connect_to_monero_daemon())
{
cerr << "commit_tx: not connected to deamon" << endl;
cerr << "commit_tx: not connected to daemon" << endl;
return false;
}
@@ -166,9 +193,9 @@ rpccalls::get_network_info(COMMAND_RPC_GET_INFO::response& response)
{
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
if (!connect_to_monero_deamon())
if (!connect_to_monero_daemon())
{
cerr << "get_network_info: not connected to deamon" << endl;
cerr << "get_network_info: not connected to daemon" << endl;
return false;
}
@@ -183,7 +210,7 @@ rpccalls::get_network_info(COMMAND_RPC_GET_INFO::response& response)
{
if (resp_t.result.status == CORE_RPC_STATUS_BUSY)
{
err = "daemon is busy. Please try again later.";
err = "Daemon is busy. Please try again later.";
}
else if (resp_t.result.status != CORE_RPC_STATUS_OK)
{
@@ -192,15 +219,15 @@ rpccalls::get_network_info(COMMAND_RPC_GET_INFO::response& response)
if (!err.empty())
{
cerr << "Error connecting to Monero deamon due to "
cerr << "Error connecting to Monero daemon due to "
<< err << endl;
return false;
}
}
else
{
cerr << "Error connecting to Monero deamon at "
<< deamon_url << endl;
cerr << "Error connecting to Monero daemon at "
<< daemon_url << endl;
return false;
}
@@ -226,9 +253,9 @@ rpccalls::get_hardfork_info(COMMAND_RPC_HARD_FORK_INFO::response& response)
{
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
if (!connect_to_monero_deamon())
if (!connect_to_monero_daemon())
{
cerr << "get_hardfork_info: not connected to deamon" << endl;
cerr << "get_hardfork_info: not connected to daemon" << endl;
return false;
}
@@ -253,15 +280,15 @@ rpccalls::get_hardfork_info(COMMAND_RPC_HARD_FORK_INFO::response& response)
if (!err.empty())
{
cerr << "Error connecting to Monero deamon due to "
cerr << "Error connecting to Monero daemon due to "
<< err << endl;
return false;
}
}
else
{
cerr << "Error connecting to Monero deamon at "
<< deamon_url << endl;
cerr << "Error connecting to Monero daemon at "
<< daemon_url << endl;
return false;
}
@@ -294,9 +321,9 @@ rpccalls::get_dynamic_per_kb_fee_estimate(
{
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
if (!connect_to_monero_deamon())
if (!connect_to_monero_daemon())
{
cerr << "get_dynamic_per_kb_fee_estimate: not connected to deamon" << endl;
cerr << "get_dynamic_per_kb_fee_estimate: not connected to daemon" << endl;
return false;
}
@@ -321,15 +348,15 @@ rpccalls::get_dynamic_per_kb_fee_estimate(
if (!err.empty())
{
cerr << "Error connecting to Monero deamon due to "
cerr << "Error connecting to Monero daemon due to "
<< err << endl;
return false;
}
}
else
{
cerr << "Error connecting to Monero deamon at "
<< deamon_url << endl;
cerr << "Error connecting to Monero daemon at "
<< daemon_url << endl;
return false;
}
@@ -357,9 +384,9 @@ rpccalls::get_block(string const& blk_hash, block& blk, string& error_msg)
{
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
if (!connect_to_monero_deamon())
if (!connect_to_monero_daemon())
{
cerr << "get_block: not connected to deamon" << endl;
cerr << "get_block: not connected to daemon" << endl;
return false;
}
@@ -384,15 +411,15 @@ rpccalls::get_block(string const& blk_hash, block& blk, string& error_msg)
if (!err.empty())
{
cerr << "Error connecting to Monero deamon due to "
cerr << "Error connecting to Monero daemon due to "
<< err << endl;
return false;
}
}
else
{
cerr << "get_block: error connecting to Monero deamon at "
<< deamon_url << endl;
cerr << "get_block: error connecting to Monero daemon at "
<< daemon_url << endl;
return false;
}
+12 -8
View File
@@ -69,7 +69,7 @@ using namespace std;
class rpccalls
{
string deamon_url ;
string daemon_url ;
uint64_t timeout_time;
std::chrono::milliseconds timeout_time_ms;
@@ -77,6 +77,7 @@ class rpccalls
epee::net_utils::http::url_content url;
epee::net_utils::http::http_simple_client m_http_client;
std::mutex m_daemon_rpc_mutex;
string port;
@@ -85,12 +86,12 @@ public:
using login_opt = boost::optional<epee::net_utils::http::login>;
rpccalls(string _deamon_url = "http:://127.0.0.1:34568",
rpccalls(string _daemon_url = "http:://127.0.0.1:34568",
login_opt _login = login_opt {},
uint64_t _timeout = 200000);
bool
connect_to_monero_deamon();
connect_to_monero_daemon();
uint64_t
get_current_height();
@@ -104,6 +105,9 @@ public:
bool
get_network_info(COMMAND_RPC_GET_INFO::response& info);
bool
get_base_fee_estimate(uint64_t grace_blocks, uint64_t& fee_estimate);
bool
get_hardfork_info( COMMAND_RPC_HARD_FORK_INFO::response& res);
@@ -135,9 +139,9 @@ public:
{
std::lock_guard<std::mutex> guard(m_daemon_rpc_mutex);
if (!connect_to_monero_deamon())
if (!connect_to_monero_daemon())
{
cerr << "get_alt_blocks: not connected to deamon" << endl;
cerr << "get_alt_blocks: not connected to daemon" << endl;
return false;
}
@@ -161,15 +165,15 @@ public:
if (!err.empty())
{
cerr << "Error connecting to Monero deamon due to "
cerr << "Error connecting to Monero daemon due to "
<< err << endl;
return false;
}
}
else
{
cerr << "Error connecting to Monero deamon at "
<< deamon_url << endl;
cerr << "Error connecting to Monero daemon at "
<< daemon_url << endl;
return false;
}
+1 -1
View File
@@ -16,7 +16,7 @@
<table class="center">
<tr>
<td>Timestamp [UCT] (epoch):</td><td>{{blk_timestamp}} ({{blk_timestamp_epoch}})</td>
<td>Timestamp [UTC] (epoch):</td><td>{{blk_timestamp}} ({{blk_timestamp_epoch}})</td>
<td>Age {{age_format}}:</td><td>{{blk_age}}</td>
<td>Δ [h:m:s]:</td><td>{{delta_time}}</td>
</tr>
+8 -1
View File
@@ -29,6 +29,7 @@ tr, li, #pages, .info {
td {
text-align: center;
word-break: break-all;
}
a:link {
@@ -70,7 +71,7 @@ form {
.tabs {
position: relative;
min-height: 220px; /* This part sucks */
min-height: 240px;
clear: both;
margin: 25px 0;
}
@@ -101,6 +102,7 @@ form {
bottom: 0;
padding: 20px;
border: 1px solid #ccc;
display: none;
}
[type=radio]:checked ~ label {
@@ -113,6 +115,11 @@ form {
z-index: 1;
}
#tab-1:checked ~ .content.tab-1,
#tab-2:checked ~ .content.tab-2 {
display: block;
}
input#toggle-1[type=checkbox] {
position: absolute;
/*top: -9999px;*/
+1 -1
View File
@@ -7,7 +7,7 @@
{{#refresh}}
<meta http-equiv="refresh" content="10">
{{/refresh}}
<title>Wownero Blockchain Explorer</title>
<title>Onion Wownero Blockchain Explorer</title>
<!--<link rel="stylesheet" type="text/css" href="/css/style.css">-->
<style type="text/css">
{{#css_styles}}{{/css_styles}}
+1 -1
View File
@@ -55,7 +55,7 @@
{{#emission}}
<h3 style="font-size: 12px; margin-top: 2px">
Wownero emission is {{amount}} ({{fee_amount}} fees) as of {{blk_no}} block
Wownero emission (fees) is {{amount}} ({{fee_amount}}) as of {{blk_no}} block
</h3>
{{/emission}}
+1 -1
View File
@@ -23,7 +23,7 @@
<table class="center" style="width: 80%; margin-top:10px">
<tr>
<td>Block: {{blk_height}}</td>
<td>Timestamp [UCT]: {{blk_timestamp}}</td>
<td>Timestamp [UTC]: {{blk_timestamp}}</td>
<td>Age [y:d:h:m:s]: {{delta_time}}</td>
<td>Fee: {{tx_fee}}</td>
<td>Tx size: {{tx_size}} kB</td>
+6 -4
View File
@@ -31,7 +31,7 @@
{{^have_raw_tx}}
<tr>
<td>Timestamp: {{blk_timestamp_uint}}</td>
<td>Timestamp [UCT]: {{blk_timestamp}}</td>
<td>Timestamp [UTC]: {{blk_timestamp}}</td>
<td>Age [y:d:h:m:s]: {{delta_time}}</td>
</tr>
{{/have_raw_tx}}
@@ -62,12 +62,14 @@
<td>stealth address</td>
<td>amount</td>
<td>amount idx</td>
<td>tag</td>
</tr>
{{#outputs}}
<tr>
<td>{{output_idx}}: {{out_pub_key}}</td>
<td>{{amount}}</td>
<td>{{amount_idx}} of {{num_outputs}}</td>
<td>{{output_tag}}</td>
</tr>
{{/outputs}}
</table>
@@ -80,7 +82,7 @@
<div class="tab">
<input type="radio" id="tab-1" name="tab-group-1" checked>
<label for="tab-1">Decode outputs</label>
<div class="content">
<div class="content tab-1">
<h4 style="margin: 0px">Check which outputs belong to given Wownero address/subaddress and viewkey</h4>
<h5 style="margin: 0px">
For RingCT transactions, outputs' amounts are also decoded
@@ -89,7 +91,7 @@
</h5>
<form action="/myoutputs" method="post" style="width:100%; margin-top:2px" class="style-1">
<input type="hidden" name="tx_hash" value="{{tx_hash}}"><br/>
<input type="text" name="xmr_address" size="110" placeholder="Wownero address/subaddress"><br/>
<input type="text" name="xmr_address" size="110" placeholder="Monero address/subaddress"><br/>
<input type="text" name="viewkey" size="110" placeholder="Private viewkey" style="margin-top:5px"><br/>
<input type="hidden" name="raw_tx_data" value="{{raw_tx_data}}">
<!--above raw_tx_data field only used when checking raw tx data through tx pusher-->
@@ -102,7 +104,7 @@
<input type="radio" id="tab-2" name="tab-group-1">
<label for="tab-2">Prove sending</label>
<div class="content">
<div class="content tab-2">
<h4 style="margin: 0px">Prove to someone that you have sent them Wownero in this transaction</h4>
<h5 style="margin: 0px">
Tx private key can be obtained using <i>get_tx_key</i>
+47 -30
View File
@@ -345,7 +345,7 @@ sum_money_in_outputs(const json& _json)
array<uint64_t, 4>
summary_of_in_out_rct(
const transaction& tx,
vector<pair<txout_to_key, uint64_t>>& output_pub_keys,
vector<output_tuple_with_tag>& output_pub_keys,
vector<txin_to_key>& input_key_imgs)
{
@@ -357,18 +357,28 @@ summary_of_in_out_rct(
for (const tx_out& txout: tx.vout)
{
if (txout.target.type() != typeid(txout_to_key))
public_key output_pub_key;
if (!cryptonote::get_output_public_key(txout, output_pub_key))
{
// push empty pair.
output_pub_keys.push_back(pair<txout_to_key, uint64_t>{});
output_pub_keys.push_back(output_tuple_with_tag {
public_key{},
uint64_t{},
boost::none
});
continue;
}
// get tx input key
const txout_to_key& txout_key
= boost::get<cryptonote::txout_to_key>(txout.target);
boost::optional<view_tag> output_tag;
output_pub_keys.push_back(make_pair(txout_key, txout.amount));
if (txout.target.type() == typeid(txout_to_tagged_key)) {
output_tag = boost::get< txout_to_tagged_key >(txout.target).view_tag;
}
output_pub_keys.push_back(
make_tuple(output_pub_key,
txout.amount,
output_tag));
xmr_outputs += txout.amount;
}
@@ -617,51 +627,56 @@ sum_fees_in_txs(const vector<transaction>& txs)
return fees_sum;
}
vector<pair<txout_to_key, uint64_t>>
vector<output_tuple_with_tag>
get_ouputs(const transaction& tx)
{
vector<pair<txout_to_key, uint64_t>> outputs;
vector<output_tuple_with_tag> outputs;
for (const tx_out& txout: tx.vout)
{
if (txout.target.type() != typeid(txout_to_key))
public_key output_pub_key;
if (!cryptonote::get_output_public_key(txout, output_pub_key))
{
// push empty pair.
outputs.push_back(pair<txout_to_key, uint64_t>{});
// push empty tuple.
outputs.push_back(output_tuple_with_tag {
public_key{},
uint64_t{},
boost::none
});
continue;
}
// get tx input key
const txout_to_key& txout_key
= boost::get<cryptonote::txout_to_key>(txout.target);
boost::optional<view_tag> output_tag;
outputs.push_back(make_pair(txout_key, txout.amount));
if (txout.target.type() == typeid(txout_to_tagged_key)) {
output_tag = boost::get< txout_to_tagged_key >(txout.target)
.view_tag;
}
outputs.push_back(make_tuple(output_pub_key,
txout.amount,
output_tag));
}
return outputs;
};
vector<tuple<txout_to_key, uint64_t, uint64_t>>
vector<tuple<public_key, uint64_t, uint64_t>>
get_ouputs_tuple(const transaction& tx)
{
vector<tuple<txout_to_key, uint64_t, uint64_t>> outputs;
vector<tuple<public_key, uint64_t, uint64_t>> outputs;
for (uint64_t n = 0; n < tx.vout.size(); ++n)
{
if (tx.vout[n].target.type() != typeid(txout_to_key))
public_key output_pub_key;
if (!cryptonote::get_output_public_key(tx.vout[n], output_pub_key))
{
continue;
}
// get tx input key
const txout_to_key& txout_key
= boost::get<cryptonote::txout_to_key>(tx.vout[n].target);
outputs.push_back(make_tuple(txout_key, tx.vout[n].amount, n));
outputs.push_back(make_tuple(output_pub_key, tx.vout[n].amount, n));
}
return outputs;
@@ -938,6 +953,7 @@ decode_ringct(rct::rctSig const& rv,
case rct::RCTTypeBulletproof:
case rct::RCTTypeBulletproof2:
case rct::RCTTypeCLSAG:
case rct::RCTTypeBulletproofPlus:
amount = rct::decodeRctSimple(rv,
rct::sk2rct(scalar1),
i,
@@ -1147,7 +1163,8 @@ is_output_ours(const size_t& output_index,
{
cerr << "Cant get dervied key for: " << "\n"
<< "pub_tx_key: " << pub_tx_key << " and "
<< "prv_view_key" << private_view_key << endl;
<< "prv_view_key" << epee::string_tools::pod_to_hex(unwrap(unwrap(private_view_key)))
<< endl;
return false;
}
@@ -1166,11 +1183,11 @@ is_output_ours(const size_t& output_index,
//cout << "\n" << tx.vout.size() << " " << output_index << endl;
// get tx output public key
const txout_to_key tx_out_to_key
= boost::get<txout_to_key>(tx.vout[output_index].target);
public_key output_pub_key;
cryptonote::get_output_public_key(tx.vout[output_index], output_pub_key);
if (tx_out_to_key.key == pubkey)
if (output_pub_key == pubkey)
{
return true;
}
+7 -3
View File
@@ -49,6 +49,10 @@ namespace bf = boost::filesystem;
using json = nlohmann::json;
using output_tuple_with_tag = tuple<public_key,
uint64_t,
boost::optional<view_tag>>;
struct outputs_visitor
{
std::vector<crypto::public_key >& m_output_keys;
@@ -154,7 +158,7 @@ sum_money_in_outputs(const json& _json);
array<uint64_t, 4>
summary_of_in_out_rct(
const transaction& tx,
vector<pair<txout_to_key, uint64_t>>& output_pub_keys,
vector<output_tuple_with_tag>& output_pub_keys,
vector<txin_to_key>& input_key_imgs);
// this version for mempool txs from json
@@ -200,10 +204,10 @@ get_mixin_no(const json& _json);
vector<uint64_t>
get_mixin_no_in_txs(const vector<transaction>& txs);
vector<pair<txout_to_key, uint64_t>>
vector<output_tuple_with_tag>
get_ouputs(const transaction& tx);
vector<tuple<txout_to_key, uint64_t, uint64_t>>
vector<tuple<public_key, uint64_t, uint64_t>>
get_ouputs_tuple(const transaction& tx);
vector<txin_to_key>