forked from such-gitea/wownero
Compare commits
237 Commits
v0.9.0.1
...
release-0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d1ce0993d | ||
|
|
437134b47d | ||
|
|
74a9ab0b03 | ||
|
|
f33c12396f | ||
|
|
51bf95597d | ||
|
|
45142e0ecb | ||
|
|
9e9e4b8485 | ||
|
|
c590033558 | ||
|
|
11b13ee36f | ||
|
|
04d6c39149 | ||
|
|
e805d42c1a | ||
|
|
8757282908 | ||
|
|
465b5d85e4 | ||
|
|
5b46a0df6d | ||
|
|
1eb01bb388 | ||
|
|
db89c585da | ||
|
|
97dfd5ae74 | ||
|
|
7d1693b160 | ||
|
|
a649ba1fc9 | ||
|
|
b8a5a1f3db | ||
|
|
d4efbf1f8d | ||
|
|
bda76b6be9 | ||
|
|
83a26b1291 | ||
|
|
3d0153dd8e | ||
|
|
70fa6c98eb | ||
|
|
f830130ad4 | ||
|
|
31c9e27ec0 | ||
|
|
917433511c | ||
|
|
9cc1a1ad48 | ||
|
|
5b37124d34 | ||
|
|
b3453b4b65 | ||
|
|
35429bbb5d | ||
|
|
c1e94b21dd | ||
|
|
b532cd8109 | ||
|
|
5b83ccbb2d | ||
|
|
fd66a5f7e1 | ||
|
|
6a829c77e1 | ||
|
|
ac3c9e9dc7 | ||
|
|
365a9ecacd | ||
|
|
e537161b65 | ||
|
|
705a21aee1 | ||
|
|
57e60e87bd | ||
|
|
121cdd5012 | ||
|
|
bcd71a5af9 | ||
|
|
1b9226ecfb | ||
|
|
1b7b438337 | ||
|
|
366463f2d0 | ||
|
|
b1a2668fa9 | ||
|
|
c255220284 | ||
|
|
cc395f82e6 | ||
|
|
4b1748de17 | ||
|
|
ac69df97a7 | ||
|
|
052bce16d3 | ||
|
|
0e0de44a3a | ||
|
|
1f5a4b3ea7 | ||
|
|
6c0afb8b9d | ||
|
|
29e7770602 | ||
|
|
7e01ba8463 | ||
|
|
ef88ad4b6e | ||
|
|
c8a59f82e2 | ||
|
|
70bcf1df3b | ||
|
|
9f099388a9 | ||
|
|
7a6d90c55a | ||
|
|
c70878b54e | ||
|
|
c8ed320949 | ||
|
|
f7ba826cd2 | ||
|
|
e91b041c75 | ||
|
|
aefce0c5fe | ||
|
|
2f8ccfe0ca | ||
|
|
a85e6fc276 | ||
|
|
0ce2ef719f | ||
|
|
9f5fa3f7f9 | ||
|
|
c5e224944e | ||
|
|
b5b1463487 | ||
|
|
ae60c289f9 | ||
|
|
6da460a8df | ||
|
|
72655f78fc | ||
|
|
4be84b7753 | ||
|
|
b3847bc194 | ||
|
|
c573ee65f6 | ||
|
|
eb49cb728e | ||
|
|
fd83d71bc7 | ||
|
|
da1720ec30 | ||
|
|
6c652ef1ad | ||
|
|
e592a515db | ||
|
|
5df0ffb57c | ||
|
|
d9939ce2fa | ||
|
|
29ebcc4e7e | ||
|
|
d759d13815 | ||
|
|
31ef8e30c4 | ||
|
|
34779a4047 | ||
|
|
1b5a28351d | ||
|
|
c5d7dd9f18 | ||
|
|
a4e2fac1ff | ||
|
|
b993d1b833 | ||
|
|
d8b68a6369 | ||
|
|
7c2b754321 | ||
|
|
da7e511967 | ||
|
|
95afa9c538 | ||
|
|
c3e70dffc5 | ||
|
|
72effc5c07 | ||
|
|
804c985ecc | ||
|
|
1861889b31 | ||
|
|
81f79d900b | ||
|
|
e0a9633557 | ||
|
|
19f284ddf9 | ||
|
|
9c10229268 | ||
|
|
18cb1753b7 | ||
|
|
4eb2f5c2c8 | ||
|
|
e062e1efe3 | ||
|
|
24660441a9 | ||
|
|
1125b332d2 | ||
|
|
009abd48e5 | ||
|
|
60cf237210 | ||
|
|
4ef1ab3e38 | ||
|
|
a37da20bc7 | ||
|
|
7f868fafcc | ||
|
|
1271a7e3a9 | ||
|
|
7a545ddc2d | ||
|
|
16a1f497e3 | ||
|
|
70804bd639 | ||
|
|
3b1c27db69 | ||
|
|
ac29d15fc3 | ||
|
|
4b5eda696f | ||
|
|
533f58dae6 | ||
|
|
eeffe5c719 | ||
|
|
87dcc37776 | ||
|
|
6e43f020ae | ||
|
|
57a5022f7d | ||
|
|
4c757a7a2a | ||
|
|
febb8df4bb | ||
|
|
e74aff06c2 | ||
|
|
7e3dbdde05 | ||
|
|
116d29906c | ||
|
|
9d31efa09e | ||
|
|
12a2a4084b | ||
|
|
d1859d6224 | ||
|
|
193c15ecce | ||
|
|
eeadc8b723 | ||
|
|
3a8f49f79c | ||
|
|
1e981f5be6 | ||
|
|
b59ef9a359 | ||
|
|
e1bba18cc5 | ||
|
|
a018e01370 | ||
|
|
014bc83b5e | ||
|
|
a0048e2a49 | ||
|
|
30ed4a23bf | ||
|
|
0e59f26064 | ||
|
|
a3fc63fa78 | ||
|
|
0c201ab438 | ||
|
|
4cb99f9365 | ||
|
|
c26c40472d | ||
|
|
9ac662cb14 | ||
|
|
0b8e49a0aa | ||
|
|
f879d48df7 | ||
|
|
603ca020ed | ||
|
|
ecc2c3b707 | ||
|
|
8347fb8d58 | ||
|
|
2b8bab2132 | ||
|
|
9b70fad289 | ||
|
|
4aad596a95 | ||
|
|
ebe75aaa5f | ||
|
|
f5765455c5 | ||
|
|
9fde7e7253 | ||
|
|
43cadb23b6 | ||
|
|
b5920da958 | ||
|
|
9fb542e89c | ||
|
|
39e2802b9a | ||
|
|
2f8fff39bf | ||
|
|
839a9e3707 | ||
|
|
2dcfca2799 | ||
|
|
47b8e6437a | ||
|
|
a0b1b89534 | ||
|
|
b38aac4a81 | ||
|
|
0df692a814 | ||
|
|
b7be110ec3 | ||
|
|
3278e86ed8 | ||
|
|
5fcc5da9f7 | ||
|
|
8f17e8c0af | ||
|
|
03743db2ed | ||
|
|
56c01e22bc | ||
|
|
6a5f0688b8 | ||
|
|
459f8da6af | ||
|
|
acab673a6e | ||
|
|
ed16ffcb4e | ||
|
|
d3184d030d | ||
|
|
a17e36f1f5 | ||
|
|
7747151e98 | ||
|
|
24974ccd36 | ||
|
|
9312008532 | ||
|
|
7a73554c04 | ||
|
|
b39feaad30 | ||
|
|
67eaf231ad | ||
|
|
c74ff98e78 | ||
|
|
94f4af6cc4 | ||
|
|
d4c7ae4554 | ||
|
|
8d6e97ba0d | ||
|
|
a33c86d875 | ||
|
|
b33dfc2ee4 | ||
|
|
1bbb2cbd63 | ||
|
|
ca0abf8615 | ||
|
|
146f5ea3f4 | ||
|
|
dc517f5da6 | ||
|
|
f516f8ce23 | ||
|
|
b0e3091152 | ||
|
|
f30b320d41 | ||
|
|
ca5db2fb30 | ||
|
|
3c0737a8c0 | ||
|
|
40d7bec2a7 | ||
|
|
4fae945114 | ||
|
|
c9a8f4f01c | ||
|
|
69663861e0 | ||
|
|
aafa830f85 | ||
|
|
6a9515697e | ||
|
|
65f6d4cc47 | ||
|
|
5ebb10cb5b | ||
|
|
0705cff367 | ||
|
|
2185265e44 | ||
|
|
3434473395 | ||
|
|
9d1e2828d4 | ||
|
|
cd36916956 | ||
|
|
2bcaa4ec02 | ||
|
|
17d4fb378e | ||
|
|
b78a40f7a4 | ||
|
|
cf607654b6 | ||
|
|
a2ab66e258 | ||
|
|
f764cf0626 | ||
|
|
338771fe21 | ||
|
|
87f6f29c4b | ||
|
|
22d3dc9a45 | ||
|
|
140daa4783 | ||
|
|
e5e2ca539f | ||
|
|
1730faf01a | ||
|
|
aff20484c3 | ||
|
|
6b1d4e67bc | ||
|
|
e89be7b80c | ||
|
|
652bd57080 |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -1 +1 @@
|
||||
custom: https://dev-funding.webui.wowkira.com
|
||||
custom: https://dev-funding.webui.wowkira.co
|
||||
|
||||
38
.github/workflows/build.yml
vendored
38
.github/workflows/build.yml
vendored
@@ -38,15 +38,10 @@ jobs:
|
||||
submodules: recursive
|
||||
- name: remove bundled boost
|
||||
run: sudo rm -rf /usr/local/share/boost
|
||||
- name: set apt conf
|
||||
run: |
|
||||
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
- name: update apt
|
||||
run: sudo apt update
|
||||
- name: install monero dependencies
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev
|
||||
- name: build
|
||||
run: make -j3
|
||||
|
||||
@@ -58,39 +53,10 @@ jobs:
|
||||
submodules: recursive
|
||||
- name: remove bundled boost
|
||||
run: sudo rm -rf /usr/local/share/boost
|
||||
- name: set apt conf
|
||||
run: |
|
||||
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
- name: update apt
|
||||
run: sudo apt update
|
||||
- name: install monero dependencies
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev
|
||||
- name: build
|
||||
run: cmake -DBUILD_GUI_DEPS=ON && make -j3
|
||||
|
||||
test-ubuntu:
|
||||
needs: build-ubuntu
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: remove bundled boost
|
||||
run: sudo rm -rf /usr/local/share/boost
|
||||
- name: set apt conf
|
||||
run: |
|
||||
echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
|
||||
- name: update apt
|
||||
run: sudo apt update
|
||||
- name: install monero dependencies
|
||||
run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler
|
||||
- name: install requests
|
||||
run: pip install requests
|
||||
- name: tests
|
||||
env:
|
||||
CTEST_OUTPUT_ON_FAILURE: ON
|
||||
run: make release-test -j3
|
||||
|
||||
4
.gitmodules
vendored
4
.gitmodules
vendored
@@ -13,7 +13,3 @@
|
||||
path = external/RandomWOW
|
||||
url = https://git.wownero.com/wownero/RandomWOW
|
||||
branch = 1.1.8-wow
|
||||
[submodule "external/supercop"]
|
||||
path = external/supercop
|
||||
url = https://git.wownero.com/wownero/supercop
|
||||
branch = monero
|
||||
|
||||
@@ -25,7 +25,7 @@ env:
|
||||
# ARM v8
|
||||
- HOST=aarch64-linux-gnu PACKAGES="python3 gperf g++-aarch64-linux-gnu"
|
||||
# i686 Win
|
||||
- HOST=i686-w64-mingw32 DEP_OPTS="NO_QT=1" PACKAGES="python3 g++-mingw-w64-i686 qttools5-dev-tools" MAKEJOBS=-j2
|
||||
- HOST=i686-w64-mingw32 DEP_OPTS="NO_QT=1" PACKAGES="python3 g++-mingw-w64-i686 qttools5-dev-tools"
|
||||
# i686 Linux
|
||||
- HOST=i686-pc-linux-gnu PACKAGES="gperf cmake g++-multilib python3-zmq"
|
||||
# Win64
|
||||
|
||||
@@ -233,7 +233,6 @@ if(NOT MANUAL_SUBMODULES)
|
||||
check_submodule(external/unbound)
|
||||
check_submodule(external/rapidjson)
|
||||
check_submodule(external/RandomWOW)
|
||||
check_submodule(external/supercop)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -291,12 +290,6 @@ else()
|
||||
endif()
|
||||
option(BUILD_DEBUG_UTILITIES "Build debug utilities." DEFAULT_BUILD_DEBUG_UTILITIES)
|
||||
|
||||
if(OSSFUZZ)
|
||||
message(STATUS "Using OSS-Fuzz fuzzing system")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DOSSFUZZ")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DOSSFUZZ")
|
||||
endif()
|
||||
|
||||
# Check whether we're on a 32-bit or 64-bit system
|
||||
if(CMAKE_SIZEOF_VOID_P EQUAL "8")
|
||||
set(DEFAULT_BUILD_64 ON)
|
||||
@@ -335,7 +328,7 @@ endif()
|
||||
# elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*")
|
||||
# set(BSDI TRUE)
|
||||
|
||||
include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external external/supercop/include)
|
||||
include_directories(external/rapidjson/include external/easylogging++ src contrib/epee/include external)
|
||||
|
||||
if(APPLE)
|
||||
include_directories(SYSTEM /usr/include/malloc)
|
||||
@@ -455,7 +448,7 @@ endif ()
|
||||
|
||||
if (APPLE AND NOT IOS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=x86-64 -fvisibility=default -std=c++11")
|
||||
if (NOT OPENSSL_ROOT_DIR)
|
||||
if (NOT OpenSSL_DIR)
|
||||
EXECUTE_PROCESS(COMMAND brew --prefix openssl
|
||||
OUTPUT_VARIABLE OPENSSL_ROOT_DIR
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
@@ -480,9 +473,6 @@ add_definition_if_function_found(strptime HAVE_STRPTIME)
|
||||
|
||||
add_definitions(-DAUTO_INITIALIZE_EASYLOGGINGPP)
|
||||
|
||||
set(MONERO_GENERATED_HEADERS_DIR "${CMAKE_CURRENT_BINARY_DIR}/generated_include")
|
||||
include_directories(${MONERO_GENERATED_HEADERS_DIR})
|
||||
|
||||
# Generate header for embedded translations
|
||||
# Generate header for embedded translations, use target toolchain if depends, otherwise use the
|
||||
# lrelease and lupdate binaries from the host
|
||||
@@ -496,6 +486,14 @@ ExternalProject_Add(generate_translations_header
|
||||
include_directories("${CMAKE_CURRENT_BINARY_DIR}/translations")
|
||||
add_subdirectory(external)
|
||||
|
||||
# Final setup for miniupnpc
|
||||
if(UPNP_STATIC OR IOS)
|
||||
add_definitions("-DUPNP_STATIC")
|
||||
else()
|
||||
add_definitions("-DUPNP_DYNAMIC")
|
||||
include_directories(${UPNP_INCLUDE})
|
||||
endif()
|
||||
|
||||
# Final setup for libunbound
|
||||
include_directories(${UNBOUND_INCLUDE})
|
||||
link_directories(${UNBOUND_LIBRARY_DIRS})
|
||||
@@ -684,8 +682,7 @@ else()
|
||||
endif()
|
||||
|
||||
# linker
|
||||
if (NOT SANITIZE AND NOT OSSFUZZ AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
|
||||
# PIE executables randomly crash at startup with ASAN
|
||||
if (NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
|
||||
# Windows binaries die on startup with PIE when compiled with GCC <9.x
|
||||
add_linker_flag_if_supported(-pie LD_SECURITY_FLAGS)
|
||||
endif()
|
||||
@@ -807,8 +804,7 @@ else()
|
||||
|
||||
endif(ARM)
|
||||
|
||||
# random crash on startup when asan is on if pie is enabled
|
||||
if(NOT SANITIZE AND ANDROID AND NOT BUILD_GUI_DEPS STREQUAL "ON" OR IOS)
|
||||
if(ANDROID AND NOT BUILD_GUI_DEPS STREQUAL "ON" OR IOS)
|
||||
#From Android 5: "only position independent executables (PIE) are supported"
|
||||
message(STATUS "Enabling PIE executable")
|
||||
set(PIC_FLAG "")
|
||||
@@ -992,10 +988,12 @@ find_path(ZMQ_INCLUDE_PATH zmq.h)
|
||||
find_library(ZMQ_LIB zmq)
|
||||
find_library(PGM_LIBRARY pgm)
|
||||
find_library(NORM_LIBRARY norm)
|
||||
find_library(GSSAPI_LIBRARY gssapi_krb5)
|
||||
find_library(PROTOLIB_LIBRARY protolib)
|
||||
find_library(SODIUM_LIBRARY sodium)
|
||||
|
||||
set(ZMQ_INCLUDE_PATH zmq_dummy_include_path)
|
||||
set(ZMQ_LIB zmq_dummy_lib_2)
|
||||
|
||||
if(NOT ZMQ_INCLUDE_PATH)
|
||||
message(FATAL_ERROR "Could not find required header zmq.h")
|
||||
endif()
|
||||
@@ -1008,9 +1006,6 @@ endif()
|
||||
if(NORM_LIBRARY)
|
||||
set(ZMQ_LIB "${ZMQ_LIB};${NORM_LIBRARY}")
|
||||
endif()
|
||||
if(GSSAPI_LIBRARY)
|
||||
set(ZMQ_LIB "${ZMQ_LIB};${GSSAPI_LIBRARY}")
|
||||
endif()
|
||||
if(PROTOLIB_LIBRARY)
|
||||
set(ZMQ_LIB "${ZMQ_LIB};${PROTOLIB_LIBRARY}")
|
||||
endif()
|
||||
@@ -1018,7 +1013,6 @@ if(SODIUM_LIBRARY)
|
||||
set(ZMQ_LIB "${ZMQ_LIB};${SODIUM_LIBRARY}")
|
||||
endif()
|
||||
|
||||
include(external/supercop/functions.cmake) # place after setting flags and before src directory inclusion
|
||||
add_subdirectory(contrib)
|
||||
add_subdirectory(src)
|
||||
|
||||
|
||||
@@ -102,7 +102,7 @@ Dates are provided in the format YYYY-MM-DD.
|
||||
| 114,969 | 2019-06-14 | F For Fappening | v0.6.1.0 | v0.6.1.2 | RandomWOW, new block weight algorithm, slightly more efficient RingCT format
|
||||
| 160,777 | 2019-11-20 | Gaping Goatse | v0.7.0.0 | v0.7.1.0 | Only allow >= 2 outputs, change to the block median used to calculate penalty, rct sigs in coinbase forbidden, 4 unlock time as protocol rule
|
||||
| - | 2020-06-28 | Hallucinogenic Hypnotoad | v0.8.0.0 | v0.8.0.2 | Dandelion++ support
|
||||
| 253,999 | 2020-10-09 | Illiterate Illuminati | v0.9.0.0 | v0.9.0.0 | Dynamic coinbase unlock (up to 1 mo.), Deterministic unlock times, Enforce maximum coinbase amount, show_qr_code wallet command, CLSAG
|
||||
| XXXX | 2020-09-XX | XXXXX | v0.9.0.0 | v0.9.0.0 | RandomWOW v2 (WOWv2), increase coinbase unlock to 8,640 (1 mo.), CLSAG
|
||||
|
||||
X's indicate that these details have not been determined as of commit date.
|
||||
|
||||
@@ -154,6 +154,7 @@ Packaging for your favorite distribution would be a welcome contribution!
|
||||
git clone https://git.wownero.com/wownero/wownero && cd wownero
|
||||
make -j2
|
||||
|
||||
|
||||
* Debian/Ubuntu
|
||||
|
||||
sudo apt update && sudo apt install build-essential cmake pkg-config libboost-all-dev libssl-dev libzmq3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline6-dev libldns-dev libexpat1-dev libpgm-dev libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler libudev-dev git -y
|
||||
@@ -164,7 +165,7 @@ Packaging for your favorite distribution would be a welcome contribution!
|
||||
## Running Binaries
|
||||
|
||||
The build places the binary in `bin/` sub-directory within the build directory
|
||||
from which cmake was invoked (repository root by default). To run in the
|
||||
from which cmake was invoked (repository root by default). To run in
|
||||
foreground:
|
||||
|
||||
./bin/wownerod
|
||||
@@ -173,7 +174,7 @@ To list all available options, run `./bin/wownerod --help`. Options can be
|
||||
specified either on the command line or in a configuration file passed by the
|
||||
`--config-file` argument. To specify an option in the configuration file, add
|
||||
a line with the syntax `argumentname=value`, where `argumentname` is the name
|
||||
of the argument without the leading dashes, for example, `log-level=1`.
|
||||
of the argument without the leading dashes, for example `log-level=1`.
|
||||
|
||||
To run in background:
|
||||
|
||||
|
||||
61
ZMQ.md
61
ZMQ.md
@@ -1,61 +0,0 @@
|
||||
# The Current/Future Status of ZMQ in Monero
|
||||
|
||||
## ZMQ Pub/Sub
|
||||
Client `ZMQ_SUB` sockets must "subscribe" to topics before it receives any data.
|
||||
This allows filtering on the server side, so network traffic is reduced. Monero
|
||||
allows for filtering on: (1) format, (2) context, and (3) event.
|
||||
|
||||
* **format** refers to the _wire_ format (i.e. JSON) used to send event
|
||||
information.
|
||||
* **context** allows for a reduction in fields for the event, so the
|
||||
daemon doesn't waste cycles serializing fields that get ignored.
|
||||
* **event** refers to status changes occurring within the daemon (i.e. new
|
||||
block to main chain).
|
||||
|
||||
* Formats:
|
||||
* `json`
|
||||
* Contexts:
|
||||
* `full` - the entire block or transaction is transmitted (the hash can be
|
||||
computed remotely).
|
||||
* `minimal` - the bare minimum for a remote client to react to an event is
|
||||
sent.
|
||||
* Events:
|
||||
* `chain_main` - changes to the primary/main blockchain.
|
||||
* `txpool_add` - new _publicly visible_ transactions in the mempool.
|
||||
Includes previously unseen transactions in a block but _not_ the
|
||||
`miner_tx`. Does not "re-publish" after a reorg. Includes `do_not_relay`
|
||||
transactions.
|
||||
|
||||
The subscription topics are formatted as `format-context-event`, with prefix
|
||||
matching supported by both Monero and ZMQ. The `format`, `context` and `event`
|
||||
will _never_ have hyphens or colons in their name. For example, subscribing to
|
||||
`json-minimal-chain_main` will send minimal information in JSON when changes
|
||||
to the main/primary blockchain occur. Whereas, subscribing to `json-minimal`
|
||||
will send minimal information in JSON on all available events supported by the
|
||||
daemon.
|
||||
|
||||
The Monero daemon will ensure that events prefixed by `chain` will be sent in
|
||||
"chain-order" - the `prev_id` (hash) field will _always_ refer to a previous
|
||||
block. On rollbacks/reorgs, the event will reference an earlier block in the
|
||||
chain instead of the last block. The Monero daemon also ensures that
|
||||
`txpool_add` events are sent before `chain_*` events - the `chain_*` messages
|
||||
will only serialize miner transactions since the other transactions were
|
||||
previously published via `txpool_add`. This prevents transactions from being
|
||||
serialized twice, even when the transaction was first observed in a block.
|
||||
|
||||
ZMQ Pub/Sub will drop messages if the network is congested, so the above rules
|
||||
for send order are used for detecting lost messages. A missing gap in `height`
|
||||
or `prev_id` for `chain_*` events indicates a lost pub message. Missing
|
||||
`txpool_add` messages can only be detected at the next `chain_` message.
|
||||
|
||||
Since blockchain events can be dropped, clients will likely want to have a
|
||||
timeout against `chain_main` events. The `GetLastBlockHeader` RPC is useful
|
||||
for checking the current chain state. Dropped messages should be rare in most
|
||||
conditions.
|
||||
|
||||
The Monero daemon will send a `txpool_add` pub exactly once for each
|
||||
transaction, even after a reorg or restarts. Clients should use the
|
||||
`GetTransactionPool` after a reorg to get all transactions that have been put
|
||||
back into the tx pool or been invalidated due to a double-spend.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package=expat
|
||||
$(package)_version=2.2.4
|
||||
$(package)_download_path=https://github.com/libexpat/libexpat/releases/download/R_2_2_4
|
||||
$(package)_download_path=https://downloads.sourceforge.net/project/expat/expat/$($(package)_version)
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=03ad85db965f8ab2d27328abcf0bc5571af6ec0a414874b2066ee3fdd372019e
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
# Set the system name to one of Android, Darwin, FreeBSD, Linux, or Windows
|
||||
SET(CMAKE_SYSTEM_NAME @depends@)
|
||||
SET(CMAKE_SYSTEM_PROCESSOR @arch@)
|
||||
SET(CMAKE_BUILD_TYPE @release_type@)
|
||||
|
||||
OPTION(STATIC "Link libraries statically" ON)
|
||||
@@ -56,7 +55,7 @@ SET(Boost_NO_SYSTEM_PATHS ON)
|
||||
SET(Boost_USE_STATIC_LIBS ON)
|
||||
SET(Boost_USE_STATIC_RUNTIME ON)
|
||||
|
||||
SET(OPENSSL_ROOT_DIR @prefix@)
|
||||
SET(OpenSSL_DIR @prefix@/lib)
|
||||
SET(ARCHITECTURE @arch@)
|
||||
|
||||
# for libraries and headers in the target directories
|
||||
@@ -64,14 +63,14 @@ set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) # Find programs on host
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) # Find libs in target
|
||||
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) # Find includes in target
|
||||
|
||||
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_HOST_SYSTEM_PROCESSOR} CACHE STRING "" FORCE)
|
||||
|
||||
# specify the cross compiler to be used. Darwin uses clang provided by the SDK.
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
SET(CMAKE_C_COMPILER @prefix@/native/bin/clang)
|
||||
SET(CMAKE_C_COMPILER_TARGET x86_64-apple-darwin11)
|
||||
SET(CMAKE_CXX_COMPILER @prefix@/native/bin/clang++ -stdlib=libc++)
|
||||
SET(CMAKE_CXX_COMPILER_TARGET x86_64-apple-darwin11)
|
||||
SET(CMAKE_ASM_COMPILER_TARGET x86_64-apple-darwin11)
|
||||
SET(CMAKE_ASM-ATT_COMPILER_TARGET x86_64-apple-darwin11)
|
||||
SET(_CMAKE_TOOLCHAIN_PREFIX x86_64-apple-darwin11-)
|
||||
SET(APPLE True)
|
||||
SET(BUILD_TAG "mac-x64")
|
||||
|
||||
@@ -117,9 +117,6 @@ namespace epee
|
||||
check(more);
|
||||
}
|
||||
|
||||
//! Reset write position, but do not release internal memory. \post `size() == 0`.
|
||||
void clear() noexcept { next_write_ = buffer_.get(); }
|
||||
|
||||
/*! Copy `length` bytes starting at `ptr` to end of stream.
|
||||
\throw std::range_error If exceeding max size_t value.
|
||||
\throw std::bad_alloc If allocation fails. */
|
||||
|
||||
@@ -543,31 +543,6 @@ eof:
|
||||
return it->second.second;
|
||||
}
|
||||
|
||||
std::vector<std::string> get_command_list(const std::vector<std::string>& keywords = std::vector<std::string>())
|
||||
{
|
||||
std::vector<std::string> list;
|
||||
list.reserve(m_command_handlers.size());
|
||||
for(auto const& x:m_command_handlers)
|
||||
{
|
||||
bool take = true;
|
||||
for(auto const& y:keywords)
|
||||
{
|
||||
bool in_usage = x.second.second.first.find(y) != std::string::npos;
|
||||
bool in_description = x.second.second.second.find(y) != std::string::npos;
|
||||
if (!(in_usage || in_description))
|
||||
{
|
||||
take = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (take)
|
||||
{
|
||||
list.push_back(x.first);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void set_handler(const std::string& cmd, const callback& hndlr, const std::string& usage = "", const std::string& description = "")
|
||||
{
|
||||
lookup::mapped_type & vt = m_command_handlers[cmd];
|
||||
|
||||
@@ -106,14 +106,6 @@ namespace misc_utils
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T get_mid(const T &a, const T &b)
|
||||
{
|
||||
//returns the average of two numbers; overflow safe and works with at least all integral and floating point types
|
||||
//(a+b)/2 = (a/2) + (b/2) + ((a - 2*(a/2)) + (b - 2*(b/2)))/2
|
||||
return (a/2) + (b/2) + ((a - 2*(a/2)) + (b - 2*(b/2)))/2;
|
||||
}
|
||||
|
||||
template<class type_vec_type>
|
||||
type_vec_type median(std::vector<type_vec_type> &v)
|
||||
{
|
||||
@@ -130,7 +122,7 @@ namespace misc_utils
|
||||
return v[n];
|
||||
}else
|
||||
{//2, 4, 6...
|
||||
return get_mid<type_vec_type>(v[n-1],v[n]);
|
||||
return (v[n-1] + v[n])/2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -64,7 +64,6 @@ namespace http
|
||||
abstract_http_client() {}
|
||||
virtual ~abstract_http_client() {}
|
||||
bool set_server(const std::string& address, boost::optional<login> user, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect);
|
||||
virtual bool set_proxy(const std::string& address);
|
||||
virtual void set_server(std::string host, std::string port, boost::optional<login> user, ssl_options_t ssl_options = ssl_support_t::e_ssl_support_autodetect) = 0;
|
||||
virtual void set_auto_connect(bool auto_connect) = 0;
|
||||
virtual bool connect(std::chrono::milliseconds timeout) = 0;
|
||||
|
||||
@@ -885,6 +885,14 @@ namespace net_utils
|
||||
}
|
||||
};
|
||||
typedef http_simple_client_template<blocked_mode_client> http_simple_client;
|
||||
|
||||
class http_simple_client_factory : public http_client_factory
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<abstract_http_client> create() override {
|
||||
return std::unique_ptr<epee::net_utils::http::abstract_http_client>(new epee::net_utils::http::http_simple_client());
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,17 +42,8 @@
|
||||
MINFO("HTTP [" << m_conn_context.m_remote_address.host_str() << "] " << query_info.m_http_method_str << " " << query_info.m_URI); \
|
||||
response.m_response_code = 200; \
|
||||
response.m_response_comment = "Ok"; \
|
||||
try \
|
||||
{ \
|
||||
if(!handle_http_request_map(query_info, response, m_conn_context)) \
|
||||
{response.m_response_code = 404;response.m_response_comment = "Not found";} \
|
||||
} \
|
||||
catch (const std::exception &e) \
|
||||
{ \
|
||||
MERROR(m_conn_context << "Exception in handle_http_request_map: " << e.what()); \
|
||||
response.m_response_code = 500; \
|
||||
response.m_response_comment = "Internal Server Error"; \
|
||||
} \
|
||||
if(!handle_http_request_map(query_info, response, m_conn_context)) \
|
||||
{response.m_response_code = 404;response.m_response_comment = "Not found";} \
|
||||
return true; \
|
||||
}
|
||||
|
||||
@@ -78,11 +69,9 @@
|
||||
uint64_t ticks1 = epee::misc_utils::get_tick_count(); \
|
||||
boost::value_initialized<command_type::response> resp;\
|
||||
MINFO(m_conn_context << "calling " << s_pattern); \
|
||||
bool res = false; \
|
||||
try { res = callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context); } \
|
||||
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "(): " << e.what()); } \
|
||||
if (!res) \
|
||||
if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context)) \
|
||||
{ \
|
||||
MERROR(m_conn_context << "Failed to " << #callback_f << "()"); \
|
||||
response_info.m_response_code = 500; \
|
||||
response_info.m_response_comment = "Internal Server Error"; \
|
||||
return true; \
|
||||
@@ -108,11 +97,9 @@
|
||||
uint64_t ticks1 = misc_utils::get_tick_count(); \
|
||||
boost::value_initialized<command_type::response> resp;\
|
||||
MINFO(m_conn_context << "calling " << s_pattern); \
|
||||
bool res = false; \
|
||||
try { res = callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context); } \
|
||||
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "()"); } \
|
||||
if (!res) \
|
||||
if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context)) \
|
||||
{ \
|
||||
MERROR(m_conn_context << "Failed to " << #callback_f << "()"); \
|
||||
response_info.m_response_code = 500; \
|
||||
response_info.m_response_comment = "Internal Server Error"; \
|
||||
return true; \
|
||||
@@ -197,10 +184,7 @@
|
||||
fail_resp.jsonrpc = "2.0"; \
|
||||
fail_resp.id = req.id; \
|
||||
MINFO(m_conn_context << "Calling RPC method " << method_name); \
|
||||
bool res = false; \
|
||||
try { res = callback_f(req.params, resp.result, fail_resp.error, &m_conn_context); } \
|
||||
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "(): " << e.what()); } \
|
||||
if (!res) \
|
||||
if(!callback_f(req.params, resp.result, fail_resp.error, &m_conn_context)) \
|
||||
{ \
|
||||
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \
|
||||
return true; \
|
||||
@@ -219,10 +203,7 @@
|
||||
fail_resp.jsonrpc = "2.0"; \
|
||||
fail_resp.id = req.id; \
|
||||
MINFO(m_conn_context << "calling RPC method " << method_name); \
|
||||
bool res = false; \
|
||||
try { res = callback_f(req.params, resp.result, fail_resp.error, response_info, &m_conn_context); } \
|
||||
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "(): " << e.what()); } \
|
||||
if (!res) \
|
||||
if(!callback_f(req.params, resp.result, fail_resp.error, response_info, &m_conn_context)) \
|
||||
{ \
|
||||
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \
|
||||
return true; \
|
||||
@@ -236,10 +217,7 @@
|
||||
{ \
|
||||
PREPARE_OBJECTS_FROM_JSON(command_type) \
|
||||
MINFO(m_conn_context << "calling RPC method " << method_name); \
|
||||
bool res = false; \
|
||||
try { res = callback_f(req.params, resp.result, &m_conn_context); } \
|
||||
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "(): " << e.what()); } \
|
||||
if (!res) \
|
||||
if(!callback_f(req.params, resp.result, &m_conn_context)) \
|
||||
{ \
|
||||
epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \
|
||||
fail_resp.jsonrpc = "2.0"; \
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <boost/asio/ip/address_v6.hpp>
|
||||
#include "int-util.h"
|
||||
|
||||
// IP addresses are kept in network byte order
|
||||
@@ -38,6 +40,30 @@ namespace epee
|
||||
{
|
||||
namespace net_utils
|
||||
{
|
||||
|
||||
inline
|
||||
bool is_ipv6_local(const std::string& ip)
|
||||
{
|
||||
auto addr = boost::asio::ip::address_v6::from_string(ip);
|
||||
|
||||
// ipv6 link-local unicast addresses are fe80::/10
|
||||
bool is_link_local = addr.is_link_local();
|
||||
|
||||
auto addr_bytes = addr.to_bytes();
|
||||
|
||||
// ipv6 unique local unicast addresses start with fc00::/7 -- (fcXX or fdXX)
|
||||
bool is_unique_local_unicast = (addr_bytes[0] == 0xfc || addr_bytes[0] == 0xfd);
|
||||
|
||||
return is_link_local || is_unique_local_unicast;
|
||||
}
|
||||
|
||||
inline
|
||||
bool is_ipv6_loopback(const std::string& ip)
|
||||
{
|
||||
// ipv6 loopback is ::1
|
||||
return boost::asio::ip::address_v6::from_string(ip).is_loopback();
|
||||
}
|
||||
|
||||
inline
|
||||
bool is_ip_local(uint32_t ip)
|
||||
{
|
||||
|
||||
@@ -34,8 +34,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "misc_language.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
@@ -228,7 +226,7 @@ public:
|
||||
Item v = data[heap[0]];
|
||||
if (minCt < maxCt)
|
||||
{
|
||||
v = get_mid<Item>(v, data[heap[-1]]);
|
||||
v = (v + data[heap[-1]]) / 2;
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -291,7 +291,6 @@ namespace epee
|
||||
#define BEGIN_INVOKE_MAP2(owner_type) \
|
||||
template <class t_context> int handle_invoke_map(bool is_notify, int command, const epee::span<const uint8_t> in_buff, std::string& buff_out, t_context& context, bool& handled) \
|
||||
{ \
|
||||
try { \
|
||||
typedef owner_type internal_owner_type_name;
|
||||
|
||||
#define HANDLE_INVOKE2(command_id, func, type_name_in, typename_out) \
|
||||
@@ -337,13 +336,7 @@ namespace epee
|
||||
LOG_ERROR("Unknown command:" << command); \
|
||||
on_levin_traffic(context, false, false, true, in_buff.size(), "invalid-command"); \
|
||||
return LEVIN_ERROR_CONNECTION_HANDLER_NOT_DEFINED; \
|
||||
} \
|
||||
catch (const std::exception &e) { \
|
||||
MERROR("Error in handle_invoke_map: " << e.what()); \
|
||||
return LEVIN_ERROR_CONNECTION_TIMEDOUT; /* seems kinda appropriate */ \
|
||||
} \
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -137,11 +137,6 @@ namespace http
|
||||
set_server(std::move(parsed.host), std::to_string(parsed.port), std::move(user), std::move(ssl_options));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool epee::net_utils::http::abstract_http_client::set_proxy(const std::string& address)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ Setup for LXC:
|
||||
|
||||
```bash
|
||||
GH_USER=fluffypony
|
||||
VERSION=v0.17.0.0
|
||||
VERSION=v0.15.0.0
|
||||
|
||||
./gitian-build.py --setup $GH_USER $VERSION
|
||||
```
|
||||
@@ -182,7 +182,7 @@ If you chose to do detached signing using `--detach-sign` above (recommended), y
|
||||
|
||||
```bash
|
||||
GH_USER=fluffypony
|
||||
VERSION=v0.17.0.0
|
||||
VERSION=v0.15.0.0
|
||||
|
||||
gpg --detach-sign ${VERSION}-linux/${GH_USER}/monero-linux-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-win/${GH_USER}/monero-win-*-build.assert
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-android-0.9"
|
||||
name: "wownero-android-0.8"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
@@ -32,7 +32,7 @@ packages:
|
||||
- "python3-zmq"
|
||||
- "unzip"
|
||||
remotes:
|
||||
- "url": "https://git.wownero.com/wownero/wownero.git"
|
||||
- "url": "https://git.wownero.com/qvqc/wownero.git"
|
||||
"dir": "wownero"
|
||||
files: []
|
||||
script: |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-freebsd-0.9"
|
||||
name: "wownero-freebsd-0.8"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-linux-0.9"
|
||||
name: "wownero-linux-0.8"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-osx-0.9"
|
||||
name: "wownero-osx-0.8"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
name: "wownero-win-0.9"
|
||||
name: "wownero-win-0.8"
|
||||
enable_cache: true
|
||||
suites:
|
||||
- "bionic"
|
||||
|
||||
48
external/CMakeLists.txt
vendored
48
external/CMakeLists.txt
vendored
@@ -34,22 +34,42 @@
|
||||
# We always compile if we are building statically to reduce static dependency issues...
|
||||
# ...except for FreeBSD, because FreeBSD is a special case that doesn't play well with
|
||||
# others.
|
||||
|
||||
find_package(Miniupnpc REQUIRED)
|
||||
|
||||
message(STATUS "Using in-tree miniupnpc")
|
||||
add_subdirectory(miniupnp/miniupnpc)
|
||||
set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external")
|
||||
if(MSVC)
|
||||
set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
|
||||
elseif(NOT MSVC)
|
||||
set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value")
|
||||
endif()
|
||||
if(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
|
||||
set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -D_NETBSD_SOURCE")
|
||||
if(NOT IOS)
|
||||
find_package(Miniupnpc QUIET)
|
||||
endif()
|
||||
|
||||
set(UPNP_LIBRARIES "libminiupnpc-static" PARENT_SCOPE)
|
||||
# If we have the correct shared version and we're not building static, use it
|
||||
if(STATIC OR IOS)
|
||||
set(USE_SHARED_MINIUPNPC false)
|
||||
elseif(MINIUPNP_FOUND AND MINIUPNPC_VERSION_1_7_OR_HIGHER)
|
||||
set(USE_SHARED_MINIUPNPC true)
|
||||
endif()
|
||||
|
||||
if(USE_SHARED_MINIUPNPC)
|
||||
message(STATUS "Using shared miniupnpc found at ${MINIUPNP_INCLUDE_DIR}")
|
||||
|
||||
set(UPNP_STATIC false PARENT_SCOPE)
|
||||
set(UPNP_INCLUDE ${MINIUPNP_INCLUDE_DIR} PARENT_SCOPE)
|
||||
set(UPNP_LIBRARIES ${MINIUPNP_LIBRARY} PARENT_SCOPE)
|
||||
else()
|
||||
if(STATIC)
|
||||
message(STATUS "Using miniupnpc from local source tree for static build")
|
||||
else()
|
||||
message(STATUS "Using miniupnpc from local source tree (/external/miniupnp/miniupnpc)")
|
||||
endif()
|
||||
|
||||
add_subdirectory(miniupnp/miniupnpc)
|
||||
|
||||
set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external")
|
||||
if(MSVC)
|
||||
set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
|
||||
elseif(NOT MSVC)
|
||||
set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -Wno-undef -Wno-unused-result -Wno-unused-value")
|
||||
endif()
|
||||
|
||||
set(UPNP_STATIC true PARENT_SCOPE)
|
||||
set(UPNP_LIBRARIES "libminiupnpc-static" PARENT_SCOPE)
|
||||
endif()
|
||||
|
||||
find_package(Unbound)
|
||||
|
||||
|
||||
2
external/easylogging++/ea_config.h
vendored
2
external/easylogging++/ea_config.h
vendored
@@ -11,7 +11,7 @@
|
||||
#define ELPP_UTC_DATETIME
|
||||
|
||||
#ifdef EASYLOGGING_CC
|
||||
#if !(!defined __GLIBC__ || !defined __GNUC__ || defined __MINGW32__ || defined __MINGW64__ || defined __ANDROID__ || defined __NetBSD__)
|
||||
#if !(!defined __GLIBC__ || !defined __GNUC__ || defined __MINGW32__ || defined __MINGW64__ || defined __ANDROID__)
|
||||
#define ELPP_FEATURE_CRASH_LOG
|
||||
#endif
|
||||
#endif
|
||||
|
||||
11
external/easylogging++/easylogging++.cc
vendored
11
external/easylogging++/easylogging++.cc
vendored
@@ -2968,16 +2968,6 @@ void Writer::initializeLogger(Logger *logger, bool needLock) {
|
||||
}
|
||||
|
||||
void Writer::processDispatch() {
|
||||
static std::atomic_flag in_dispatch;
|
||||
if (in_dispatch.test_and_set())
|
||||
{
|
||||
if (m_proceed && m_logger != NULL)
|
||||
{
|
||||
m_logger->stream().str(ELPP_LITERAL(""));
|
||||
m_logger->releaseLock();
|
||||
}
|
||||
return;
|
||||
}
|
||||
#if ELPP_LOGGING_ENABLED
|
||||
if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) {
|
||||
bool firstDispatched = false;
|
||||
@@ -3016,7 +3006,6 @@ void Writer::processDispatch() {
|
||||
m_logger->releaseLock();
|
||||
}
|
||||
#endif // ELPP_LOGGING_ENABLED
|
||||
in_dispatch.clear();
|
||||
}
|
||||
|
||||
void Writer::triggerDispatch(void) {
|
||||
|
||||
3
external/qrcodegen/CMakeLists.txt
vendored
3
external/qrcodegen/CMakeLists.txt
vendored
@@ -1,8 +1,7 @@
|
||||
project(libqrcodegen)
|
||||
|
||||
add_library(qrcodegen STATIC QrCode.cpp)
|
||||
set_target_properties(qrcodegen PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||
set_target_properties(qrcodegen PROPERTIES CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
|
||||
|
||||
target_include_directories(qrcodegen PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
1
external/supercop
vendored
1
external/supercop
vendored
Submodule external/supercop deleted from 633500ad8c
@@ -63,7 +63,6 @@ bool matches_category(relay_method method, relay_category category) noexcept
|
||||
{
|
||||
default:
|
||||
case relay_method::local:
|
||||
case relay_method::forward:
|
||||
case relay_method::stem:
|
||||
return false;
|
||||
case relay_method::block:
|
||||
@@ -80,7 +79,6 @@ void txpool_tx_meta_t::set_relay_method(relay_method method) noexcept
|
||||
kept_by_block = 0;
|
||||
do_not_relay = 0;
|
||||
is_local = 0;
|
||||
is_forwarding = 0;
|
||||
dandelionpp_stem = 0;
|
||||
|
||||
switch (method)
|
||||
@@ -91,8 +89,8 @@ void txpool_tx_meta_t::set_relay_method(relay_method method) noexcept
|
||||
case relay_method::local:
|
||||
is_local = 1;
|
||||
break;
|
||||
case relay_method::forward:
|
||||
is_forwarding = 1;
|
||||
default:
|
||||
case relay_method::fluff:
|
||||
break;
|
||||
case relay_method::stem:
|
||||
dandelionpp_stem = 1;
|
||||
@@ -100,45 +98,26 @@ void txpool_tx_meta_t::set_relay_method(relay_method method) noexcept
|
||||
case relay_method::block:
|
||||
kept_by_block = 1;
|
||||
break;
|
||||
default:
|
||||
case relay_method::fluff:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
relay_method txpool_tx_meta_t::get_relay_method() const noexcept
|
||||
{
|
||||
const uint8_t state =
|
||||
uint8_t(kept_by_block) +
|
||||
(uint8_t(do_not_relay) << 1) +
|
||||
(uint8_t(is_local) << 2) +
|
||||
(uint8_t(is_forwarding) << 3) +
|
||||
(uint8_t(dandelionpp_stem) << 4);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
default: // error case
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
return relay_method::block;
|
||||
case 2:
|
||||
return relay_method::none;
|
||||
case 4:
|
||||
return relay_method::local;
|
||||
case 8:
|
||||
return relay_method::forward;
|
||||
case 16:
|
||||
return relay_method::stem;
|
||||
};
|
||||
if (kept_by_block)
|
||||
return relay_method::block;
|
||||
if (do_not_relay)
|
||||
return relay_method::none;
|
||||
if (is_local)
|
||||
return relay_method::local;
|
||||
if (dandelionpp_stem)
|
||||
return relay_method::stem;
|
||||
return relay_method::fluff;
|
||||
}
|
||||
|
||||
bool txpool_tx_meta_t::upgrade_relay_method(relay_method method) noexcept
|
||||
{
|
||||
static_assert(relay_method::none < relay_method::local, "bad relay_method value");
|
||||
static_assert(relay_method::local < relay_method::forward, "bad relay_method value");
|
||||
static_assert(relay_method::forward < relay_method::stem, "bad relay_method value");
|
||||
static_assert(relay_method::local < relay_method::stem, "bad relay_method value");
|
||||
static_assert(relay_method::stem < relay_method::fluff, "bad relay_method value");
|
||||
static_assert(relay_method::fluff < relay_method::block, "bad relay_method value");
|
||||
|
||||
@@ -179,7 +158,7 @@ void BlockchainDB::pop_block()
|
||||
pop_block(blk, txs);
|
||||
}
|
||||
|
||||
void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata_ref>& txp, const crypto::hash* tx_hash_ptr, const crypto::hash* tx_prunable_hash_ptr)
|
||||
void BlockchainDB::add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata>& txp, const crypto::hash* tx_hash_ptr, const crypto::hash* tx_prunable_hash_ptr)
|
||||
{
|
||||
const transaction &tx = txp.first;
|
||||
|
||||
@@ -281,13 +260,12 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck
|
||||
time1 = epee::misc_utils::get_tick_count();
|
||||
|
||||
uint64_t num_rct_outs = 0;
|
||||
blobdata miner_bd = tx_to_blob(blk.miner_tx);
|
||||
add_transaction(blk_hash, std::make_pair(blk.miner_tx, blobdata_ref(miner_bd)));
|
||||
add_transaction(blk_hash, std::make_pair(blk.miner_tx, tx_to_blob(blk.miner_tx)));
|
||||
if (blk.miner_tx.version == 2)
|
||||
num_rct_outs += blk.miner_tx.vout.size();
|
||||
int tx_i = 0;
|
||||
crypto::hash tx_hash = crypto::null_hash;
|
||||
for (const std::pair<transaction, blobdata_ref>& tx : txs)
|
||||
for (const std::pair<transaction, blobdata>& tx : txs)
|
||||
{
|
||||
tx_hash = blk.tx_hashes[tx_i];
|
||||
add_transaction(blk_hash, tx, &tx_hash);
|
||||
|
||||
@@ -160,7 +160,7 @@ struct txpool_tx_meta_t
|
||||
uint64_t max_used_block_height;
|
||||
uint64_t last_failed_height;
|
||||
uint64_t receive_time;
|
||||
uint64_t last_relayed_time; //!< If received over i2p/tor, randomized forward time. If Dandelion++stem, randomized embargo time. Otherwise, last relayed timestamp
|
||||
uint64_t last_relayed_time; //!< If Dandelion++ stem, randomized embargo timestamp. Otherwise, last relayed timestmap.
|
||||
// 112 bytes
|
||||
uint8_t kept_by_block;
|
||||
uint8_t relayed;
|
||||
@@ -169,8 +169,7 @@ struct txpool_tx_meta_t
|
||||
uint8_t pruned: 1;
|
||||
uint8_t is_local: 1;
|
||||
uint8_t dandelionpp_stem : 1;
|
||||
uint8_t is_forwarding: 1;
|
||||
uint8_t bf_padding: 3;
|
||||
uint8_t bf_padding: 4;
|
||||
|
||||
uint8_t padding[76]; // till 192 bytes
|
||||
|
||||
@@ -440,7 +439,7 @@ private:
|
||||
* @param tx_prunable_hash the hash of the prunable part of the transaction
|
||||
* @return the transaction ID
|
||||
*/
|
||||
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const std::pair<transaction, blobdata_ref>& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash) = 0;
|
||||
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const std::pair<transaction, blobdata>& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash) = 0;
|
||||
|
||||
/**
|
||||
* @brief remove data about a transaction
|
||||
@@ -568,7 +567,7 @@ protected:
|
||||
* @param tx_hash_ptr the hash of the transaction, if already calculated
|
||||
* @param tx_prunable_hash_ptr the hash of the prunable part of the transaction, if already calculated
|
||||
*/
|
||||
void add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata_ref>& tx, const crypto::hash* tx_hash_ptr = NULL, const crypto::hash* tx_prunable_hash_ptr = NULL);
|
||||
void add_transaction(const crypto::hash& blk_hash, const std::pair<transaction, blobdata>& tx, const crypto::hash* tx_hash_ptr = NULL, const crypto::hash* tx_prunable_hash_ptr = NULL);
|
||||
|
||||
mutable uint64_t time_tx_exists = 0; //!< a performance metric
|
||||
uint64_t time_commit1 = 0; //!< a performance metric
|
||||
@@ -1524,7 +1523,7 @@ public:
|
||||
*
|
||||
* @param details the details of the transaction to add
|
||||
*/
|
||||
virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata_ref &blob, const txpool_tx_meta_t& details) = 0;
|
||||
virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t& details) = 0;
|
||||
|
||||
/**
|
||||
* @brief update a txpool transaction's metadata
|
||||
@@ -1644,7 +1643,7 @@ public:
|
||||
* @param: data: the metadata for the block
|
||||
* @param: blob: the block's blob
|
||||
*/
|
||||
virtual void add_alt_block(const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata_ref &blob) = 0;
|
||||
virtual void add_alt_block(const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata &blob) = 0;
|
||||
|
||||
/**
|
||||
* @brief get an alternative block by hash
|
||||
@@ -1687,7 +1686,7 @@ public:
|
||||
*
|
||||
* @return false if the function returns false for any transaction, otherwise true
|
||||
*/
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata_ref*)>, bool include_blob = false, relay_category category = relay_category::broadcasted) const = 0;
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, relay_category category = relay_category::broadcasted) const = 0;
|
||||
|
||||
/**
|
||||
* @brief runs a function over all key images stored
|
||||
@@ -1779,7 +1778,7 @@ public:
|
||||
*
|
||||
* @return false if the function returns false for any output, otherwise true
|
||||
*/
|
||||
virtual bool for_all_alt_blocks(std::function<bool(const crypto::hash &blkid, const alt_block_data_t &data, const cryptonote::blobdata_ref *blob)> f, bool include_blob = false) const = 0;
|
||||
virtual bool for_all_alt_blocks(std::function<bool(const crypto::hash &blkid, const alt_block_data_t &data, const cryptonote::blobdata *blob)> f, bool include_blob = false) const = 0;
|
||||
|
||||
|
||||
//
|
||||
|
||||
@@ -856,7 +856,7 @@ void BlockchainLMDB::remove_block()
|
||||
throw1(DB_ERROR(lmdb_error("Failed to add removal of block info to db transaction: ", result).c_str()));
|
||||
}
|
||||
|
||||
uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, const std::pair<transaction, blobdata_ref>& txp, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash)
|
||||
uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, const std::pair<transaction, blobdata>& txp, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash)
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -896,7 +896,7 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to add tx data to db transaction: ", result).c_str()));
|
||||
|
||||
const cryptonote::blobdata_ref &blob = txp.second;
|
||||
const cryptonote::blobdata &blob = txp.second;
|
||||
MDB_val_sized(blobval, blob);
|
||||
|
||||
unsigned int unprunable_size = tx.unprunable_size;
|
||||
@@ -1756,7 +1756,7 @@ void BlockchainLMDB::unlock()
|
||||
auto_txn.commit(); \
|
||||
} while(0)
|
||||
|
||||
void BlockchainLMDB::add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata_ref &blob, const txpool_tx_meta_t &meta)
|
||||
void BlockchainLMDB::add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t &meta)
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -2308,7 +2308,7 @@ bool BlockchainLMDB::check_pruning()
|
||||
return prune_worker(prune_mode_check, 0);
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata_ref*)> f, bool include_blob, relay_category category) const
|
||||
bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob, relay_category category) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -2334,7 +2334,8 @@ bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&,
|
||||
const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data;
|
||||
if (!meta.matches(category))
|
||||
continue;
|
||||
cryptonote::blobdata_ref bd;
|
||||
const cryptonote::blobdata *passed_bd = NULL;
|
||||
cryptonote::blobdata bd;
|
||||
if (include_blob)
|
||||
{
|
||||
MDB_val b;
|
||||
@@ -2343,10 +2344,11 @@ bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&,
|
||||
throw0(DB_ERROR("Failed to find txpool tx blob to match metadata"));
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx blob: ", result).c_str()));
|
||||
bd = {reinterpret_cast<const char*>(b.mv_data), b.mv_size};
|
||||
bd.assign(reinterpret_cast<const char*>(b.mv_data), b.mv_size);
|
||||
passed_bd = &bd;
|
||||
}
|
||||
|
||||
if (!f(txid, meta, &bd)) {
|
||||
if (!f(txid, meta, passed_bd)) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
@@ -2357,7 +2359,7 @@ bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&,
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool BlockchainLMDB::for_all_alt_blocks(std::function<bool(const crypto::hash&, const alt_block_data_t&, const cryptonote::blobdata_ref*)> f, bool include_blob) const
|
||||
bool BlockchainLMDB::for_all_alt_blocks(std::function<bool(const crypto::hash&, const alt_block_data_t&, const cryptonote::blobdata*)> f, bool include_blob) const
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -2382,13 +2384,15 @@ bool BlockchainLMDB::for_all_alt_blocks(std::function<bool(const crypto::hash&,
|
||||
if (v.mv_size < sizeof(alt_block_data_t))
|
||||
throw0(DB_ERROR("alt_blocks record is too small"));
|
||||
const alt_block_data_t *data = (const alt_block_data_t*)v.mv_data;
|
||||
cryptonote::blobdata_ref bd;
|
||||
const cryptonote::blobdata *passed_bd = NULL;
|
||||
cryptonote::blobdata bd;
|
||||
if (include_blob)
|
||||
{
|
||||
bd = {reinterpret_cast<const char*>(v.mv_data) + sizeof(alt_block_data_t), v.mv_size - sizeof(alt_block_data_t)};
|
||||
bd.assign(reinterpret_cast<const char*>(v.mv_data) + sizeof(alt_block_data_t), v.mv_size - sizeof(alt_block_data_t));
|
||||
passed_bd = &bd;
|
||||
}
|
||||
|
||||
if (!f(blkid, *data, &bd)) {
|
||||
if (!f(blkid, *data, passed_bd)) {
|
||||
ret = false;
|
||||
break;
|
||||
}
|
||||
@@ -3600,7 +3604,8 @@ bool BlockchainLMDB::for_blocks_range(const uint64_t& h1, const uint64_t& h2, st
|
||||
if (ret)
|
||||
throw0(DB_ERROR("Failed to enumerate blocks"));
|
||||
uint64_t height = *(const uint64_t*)k.mv_data;
|
||||
blobdata_ref bd{reinterpret_cast<char*>(v.mv_data), v.mv_size};
|
||||
blobdata bd;
|
||||
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
|
||||
block b;
|
||||
if (!parse_and_validate_block_from_blob(bd, b))
|
||||
throw0(DB_ERROR("Failed to parse block from blob retrieved from the db"));
|
||||
@@ -3655,16 +3660,15 @@ bool BlockchainLMDB::for_all_transactions(std::function<bool(const crypto::hash&
|
||||
if (ret)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to enumerate transactions: ", ret).c_str()));
|
||||
transaction tx;
|
||||
blobdata bd;
|
||||
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
|
||||
if (pruned)
|
||||
{
|
||||
blobdata_ref bd{reinterpret_cast<char*>(v.mv_data), v.mv_size};
|
||||
if (!parse_and_validate_tx_base_from_blob(bd, tx))
|
||||
throw0(DB_ERROR("Failed to parse tx from blob retrieved from the db"));
|
||||
}
|
||||
else
|
||||
{
|
||||
blobdata bd;
|
||||
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
|
||||
ret = mdb_cursor_get(m_cur_txs_prunable, &k, &v, MDB_SET);
|
||||
if (ret)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to get prunable tx data the db: ", ret).c_str()));
|
||||
@@ -4398,7 +4402,7 @@ uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const
|
||||
return ret;
|
||||
}
|
||||
|
||||
void BlockchainLMDB::add_alt_block(const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata_ref &blob)
|
||||
void BlockchainLMDB::add_alt_block(const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata &blob)
|
||||
{
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
@@ -4965,7 +4969,7 @@ void BlockchainLMDB::migrate_0_1()
|
||||
}
|
||||
|
||||
MDB_dbi o_txs;
|
||||
blobdata_ref bd;
|
||||
blobdata bd;
|
||||
block b;
|
||||
MDB_val hk;
|
||||
|
||||
@@ -5047,7 +5051,7 @@ void BlockchainLMDB::migrate_0_1()
|
||||
} else if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to get a record from blocks: ", result).c_str()));
|
||||
|
||||
bd = {reinterpret_cast<char*>(v.mv_data), v.mv_size};
|
||||
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
|
||||
if (!parse_and_validate_block_from_blob(bd, b))
|
||||
throw0(DB_ERROR("Failed to parse block from blob retrieved from the db"));
|
||||
|
||||
@@ -5058,7 +5062,7 @@ void BlockchainLMDB::migrate_0_1()
|
||||
result = mdb_cursor_get(c_txs, &hk, &v, MDB_SET);
|
||||
if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to get record from txs: ", result).c_str()));
|
||||
bd = {reinterpret_cast<char*>(v.mv_data), v.mv_size};
|
||||
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
|
||||
if (!parse_and_validate_tx_from_blob(bd, tx))
|
||||
throw0(DB_ERROR("Failed to parse tx from blob retrieved from the db"));
|
||||
add_transaction(null_hash, std::make_pair(std::move(tx), bd), &b.tx_hashes[j]);
|
||||
@@ -5180,7 +5184,8 @@ void BlockchainLMDB::migrate_1_2()
|
||||
else if (result)
|
||||
throw0(DB_ERROR(lmdb_error("Failed to get a record from txs: ", result).c_str()));
|
||||
|
||||
cryptonote::blobdata bd{reinterpret_cast<char*>(v.mv_data), v.mv_size};
|
||||
cryptonote::blobdata bd;
|
||||
bd.assign(reinterpret_cast<char*>(v.mv_data), v.mv_size);
|
||||
transaction tx;
|
||||
if (!parse_and_validate_tx_from_blob(bd, tx))
|
||||
throw0(DB_ERROR("Failed to parse tx from blob retrieved from the db"));
|
||||
|
||||
@@ -283,7 +283,7 @@ public:
|
||||
|
||||
virtual bool has_key_image(const crypto::key_image& img) const;
|
||||
|
||||
virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata_ref &blob, const txpool_tx_meta_t& meta);
|
||||
virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const txpool_tx_meta_t& meta);
|
||||
virtual void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t& meta);
|
||||
virtual uint64_t get_txpool_tx_count(relay_category category = relay_category::broadcasted) const;
|
||||
virtual bool txpool_has_tx(const crypto::hash &txid, relay_category tx_category) const;
|
||||
@@ -296,20 +296,20 @@ public:
|
||||
virtual bool update_pruning();
|
||||
virtual bool check_pruning();
|
||||
|
||||
virtual void add_alt_block(const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata_ref &blob);
|
||||
virtual void add_alt_block(const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata &blob);
|
||||
virtual bool get_alt_block(const crypto::hash &blkid, alt_block_data_t *data, cryptonote::blobdata *blob);
|
||||
virtual void remove_alt_block(const crypto::hash &blkid);
|
||||
virtual uint64_t get_alt_block_count();
|
||||
virtual void drop_alt_blocks();
|
||||
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata_ref*)> f, bool include_blob = false, relay_category category = relay_category::broadcasted) const;
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob = false, relay_category category = relay_category::broadcasted) const;
|
||||
|
||||
virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const;
|
||||
virtual bool for_blocks_range(const uint64_t& h1, const uint64_t& h2, std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const;
|
||||
virtual bool for_all_transactions(std::function<bool(const crypto::hash&, const cryptonote::transaction&)>, bool pruned) const;
|
||||
virtual bool for_all_outputs(std::function<bool(uint64_t amount, const crypto::hash &tx_hash, uint64_t height, size_t tx_idx)> f) const;
|
||||
virtual bool for_all_outputs(uint64_t amount, const std::function<bool(uint64_t height)> &f) const;
|
||||
virtual bool for_all_alt_blocks(std::function<bool(const crypto::hash &blkid, const alt_block_data_t &data, const cryptonote::blobdata_ref *blob)> f, bool include_blob = false) const;
|
||||
virtual bool for_all_alt_blocks(std::function<bool(const crypto::hash &blkid, const alt_block_data_t &data, const cryptonote::blobdata *blob)> f, bool include_blob = false) const;
|
||||
|
||||
virtual uint64_t add_block( const std::pair<block, blobdata>& blk
|
||||
, size_t block_weight
|
||||
@@ -376,7 +376,7 @@ private:
|
||||
|
||||
virtual void remove_block();
|
||||
|
||||
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const std::pair<transaction, blobdata_ref>& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash);
|
||||
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const std::pair<transaction, blobdata>& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash);
|
||||
|
||||
virtual void remove_transaction_data(const crypto::hash& tx_hash, const transaction& tx);
|
||||
|
||||
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
virtual std::vector<std::vector<uint64_t>> get_tx_amount_output_indices(const uint64_t tx_index, size_t n_txes) const override { return std::vector<std::vector<uint64_t>>(); }
|
||||
virtual bool has_key_image(const crypto::key_image& img) const override { return false; }
|
||||
virtual void remove_block() override { }
|
||||
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const std::pair<cryptonote::transaction, cryptonote::blobdata_ref>& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash) override {return 0;}
|
||||
virtual uint64_t add_transaction_data(const crypto::hash& blk_hash, const std::pair<cryptonote::transaction, cryptonote::blobdata>& tx, const crypto::hash& tx_hash, const crypto::hash& tx_prunable_hash) override {return 0;}
|
||||
virtual void remove_transaction_data(const crypto::hash& tx_hash, const cryptonote::transaction& tx) override {}
|
||||
virtual uint64_t add_output(const crypto::hash& tx_hash, const cryptonote::tx_out& tx_output, const uint64_t& local_index, const uint64_t unlock_time, const rct::key *commitment) override {return 0;}
|
||||
virtual void add_tx_amount_output_indices(const uint64_t tx_index, const std::vector<uint64_t>& amount_output_indices) override {}
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
virtual std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>> get_output_histogram(const std::vector<uint64_t> &amounts, bool unlocked, uint64_t recent_cutoff, uint64_t min_count) const override { return std::map<uint64_t, std::tuple<uint64_t, uint64_t, uint64_t>>(); }
|
||||
virtual bool get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, std::vector<uint64_t> &distribution, uint64_t &base) const override { return false; }
|
||||
|
||||
virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata_ref &blob, const cryptonote::txpool_tx_meta_t& details) override {}
|
||||
virtual void add_txpool_tx(const crypto::hash &txid, const cryptonote::blobdata &blob, const cryptonote::txpool_tx_meta_t& details) override {}
|
||||
virtual void update_txpool_tx(const crypto::hash &txid, const cryptonote::txpool_tx_meta_t& details) override {}
|
||||
virtual uint64_t get_txpool_tx_count(relay_category tx_relay = relay_category::broadcasted) const override { return 0; }
|
||||
virtual bool txpool_has_tx(const crypto::hash &txid, relay_category tx_category) const override { return false; }
|
||||
@@ -136,7 +136,7 @@ public:
|
||||
virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd, relay_category tx_category) const override { return false; }
|
||||
virtual uint64_t get_database_size() const override { return 0; }
|
||||
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid, relay_category tx_category) const override { return ""; }
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const cryptonote::txpool_tx_meta_t&, const cryptonote::blobdata_ref*)>, bool include_blob = false, relay_category category = relay_category::broadcasted) const override { return false; }
|
||||
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const cryptonote::txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, relay_category category = relay_category::broadcasted) const override { return false; }
|
||||
|
||||
virtual void add_block( const cryptonote::block& blk
|
||||
, size_t block_weight
|
||||
@@ -160,12 +160,12 @@ public:
|
||||
virtual uint64_t get_max_block_size() override { return 100000000; }
|
||||
virtual void add_max_block_size(uint64_t sz) override { }
|
||||
|
||||
virtual void add_alt_block(const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata_ref &blob) override {}
|
||||
virtual void add_alt_block(const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata &blob) override {}
|
||||
virtual bool get_alt_block(const crypto::hash &blkid, alt_block_data_t *data, cryptonote::blobdata *blob) override { return false; }
|
||||
virtual void remove_alt_block(const crypto::hash &blkid) override {}
|
||||
virtual uint64_t get_alt_block_count() override { return 0; }
|
||||
virtual void drop_alt_blocks() override {}
|
||||
virtual bool for_all_alt_blocks(std::function<bool(const crypto::hash &blkid, const alt_block_data_t &data, const cryptonote::blobdata_ref *blob)> f, bool include_blob = false) const override { return true; }
|
||||
virtual bool for_all_alt_blocks(std::function<bool(const crypto::hash &blkid, const alt_block_data_t &data, const cryptonote::blobdata *blob)> f, bool include_blob = false) const override { return true; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include <boost/range/adaptor/transformed.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include "common/unordered_containers_boost_serialization.h"
|
||||
#include "common/command_line.h"
|
||||
#include "common/varint.h"
|
||||
|
||||
@@ -68,9 +68,6 @@ int main(int argc, char* argv[])
|
||||
const command_line::arg_descriptor<bool> arg_outputs = {"with-outputs", "with output stats", false};
|
||||
const command_line::arg_descriptor<bool> arg_ringsize = {"with-ringsize", "with ringsize stats", false};
|
||||
const command_line::arg_descriptor<bool> arg_hours = {"with-hours", "with txns per hour", false};
|
||||
const command_line::arg_descriptor<bool> arg_emission = {"with-emission", "with coin emission", false};
|
||||
const command_line::arg_descriptor<bool> arg_fees = {"with-fees", "with txn fees", false};
|
||||
const command_line::arg_descriptor<bool> arg_diff = {"with-diff", "with difficulty", false};
|
||||
|
||||
command_line::add_arg(desc_cmd_sett, cryptonote::arg_data_dir);
|
||||
command_line::add_arg(desc_cmd_sett, cryptonote::arg_testnet_on);
|
||||
@@ -82,9 +79,6 @@ int main(int argc, char* argv[])
|
||||
command_line::add_arg(desc_cmd_sett, arg_outputs);
|
||||
command_line::add_arg(desc_cmd_sett, arg_ringsize);
|
||||
command_line::add_arg(desc_cmd_sett, arg_hours);
|
||||
command_line::add_arg(desc_cmd_sett, arg_emission);
|
||||
command_line::add_arg(desc_cmd_sett, arg_fees);
|
||||
command_line::add_arg(desc_cmd_sett, arg_diff);
|
||||
command_line::add_arg(desc_cmd_only, command_line::arg_help);
|
||||
|
||||
po::options_description desc_options("Allowed options");
|
||||
@@ -126,9 +120,6 @@ int main(int argc, char* argv[])
|
||||
bool do_outputs = command_line::get_arg(vm, arg_outputs);
|
||||
bool do_ringsize = command_line::get_arg(vm, arg_ringsize);
|
||||
bool do_hours = command_line::get_arg(vm, arg_hours);
|
||||
bool do_emission = command_line::get_arg(vm, arg_emission);
|
||||
bool do_fees = command_line::get_arg(vm, arg_fees);
|
||||
bool do_diff = command_line::get_arg(vm, arg_diff);
|
||||
|
||||
LOG_PRINT_L0("Initializing source blockchain (BlockchainDB)");
|
||||
std::unique_ptr<Blockchain> core_storage;
|
||||
@@ -186,20 +177,12 @@ plot 'stats.csv' index "DATA" using (timecolumn(1,"%Y-%m-%d")):4 with lines, ''
|
||||
// spit out a comment that GnuPlot can use as an index
|
||||
std::cout << ENDL << "# DATA" << ENDL;
|
||||
std::cout << "Date\tBlocks/day\tBlocks\tTxs/Day\tTxs\tBytes/Day\tBytes";
|
||||
if (do_emission)
|
||||
std::cout << "\tEmission/day\tEmission";
|
||||
if (do_fees)
|
||||
std::cout << "\tFees/day\tFees";
|
||||
if (do_diff)
|
||||
std::cout << "\tDiffMin\tDiffMax\tDiffAvg";
|
||||
if (do_inputs)
|
||||
std::cout << "\tInMin\tInMax\tInAvg";
|
||||
if (do_outputs)
|
||||
std::cout << "\tOutMin\tOutMax\tOutAvg";
|
||||
if (do_ringsize)
|
||||
std::cout << "\tRingMin\tRingMax\tRingAvg";
|
||||
if (do_inputs || do_outputs || do_ringsize)
|
||||
std::cout << std::setprecision(2) << std::fixed;
|
||||
if (do_hours) {
|
||||
char buf[8];
|
||||
unsigned int i;
|
||||
@@ -210,20 +193,14 @@ plot 'stats.csv' index "DATA" using (timecolumn(1,"%Y-%m-%d")):4 with lines, ''
|
||||
}
|
||||
std::cout << ENDL;
|
||||
|
||||
#define MAX_INOUT 0xffffffff
|
||||
#define MAX_RINGS 0xffffffff
|
||||
|
||||
struct tm prevtm = {0}, currtm;
|
||||
uint64_t prevsz = 0, currsz = 0;
|
||||
uint64_t prevtxs = 0, currtxs = 0;
|
||||
uint64_t currblks = 0;
|
||||
uint64_t totins = 0, totouts = 0, totrings = 0;
|
||||
boost::multiprecision::uint128_t prevemission = 0, prevfees = 0;
|
||||
boost::multiprecision::uint128_t emission = 0, fees = 0;
|
||||
boost::multiprecision::uint128_t totdiff = 0, mindiff = 0, maxdiff = 0;
|
||||
uint32_t minins = MAX_INOUT, maxins = 0;
|
||||
uint32_t minouts = MAX_INOUT, maxouts = 0;
|
||||
uint32_t minrings = MAX_RINGS, maxrings = 0;
|
||||
uint32_t minins = 10, maxins = 0;
|
||||
uint32_t minouts = 10, maxouts = 0;
|
||||
uint32_t minrings = 50, maxrings = 0;
|
||||
uint32_t io, tottxs = 0;
|
||||
uint32_t txhr[24] = {0};
|
||||
unsigned int i;
|
||||
@@ -253,50 +230,34 @@ plot 'stats.csv' index "DATA" using (timecolumn(1,"%Y-%m-%d")):4 with lines, ''
|
||||
std::cout << timebuf << "\t" << currblks << "\t" << h << "\t" << currtxs << "\t" << prevtxs + currtxs << "\t" << currsz << "\t" << prevsz + currsz;
|
||||
prevsz += currsz;
|
||||
currsz = 0;
|
||||
currblks = 0;
|
||||
prevtxs += currtxs;
|
||||
currtxs = 0;
|
||||
if (!tottxs)
|
||||
tottxs = 1;
|
||||
if (do_emission) {
|
||||
std::cout << "\t" << print_money(emission) << "\t" << print_money(prevemission + emission);
|
||||
prevemission += emission;
|
||||
emission = 0;
|
||||
}
|
||||
if (do_fees) {
|
||||
std::cout << "\t" << print_money(fees) << "\t" << print_money(prevfees + fees);
|
||||
prevfees += fees;
|
||||
fees = 0;
|
||||
}
|
||||
if (do_diff) {
|
||||
std::cout << "\t" << (maxdiff ? mindiff : 0) << "\t" << maxdiff << "\t" << totdiff / currblks;
|
||||
mindiff = 0; maxdiff = 0; totdiff = 0;
|
||||
}
|
||||
if (do_inputs) {
|
||||
std::cout << "\t" << (maxins ? minins : 0) << "\t" << maxins << "\t" << totins * 1.0 / tottxs;
|
||||
minins = MAX_INOUT; maxins = 0; totins = 0;
|
||||
std::cout << "\t" << (maxins ? minins : 0) << "\t" << maxins << "\t" << totins / tottxs;
|
||||
minins = 10; maxins = 0; totins = 0;
|
||||
}
|
||||
if (do_outputs) {
|
||||
std::cout << "\t" << (maxouts ? minouts : 0) << "\t" << maxouts << "\t" << totouts * 1.0 / tottxs;
|
||||
minouts = MAX_INOUT; maxouts = 0; totouts = 0;
|
||||
std::cout << "\t" << (maxouts ? minouts : 0) << "\t" << maxouts << "\t" << totouts / tottxs;
|
||||
minouts = 10; maxouts = 0; totouts = 0;
|
||||
}
|
||||
if (do_ringsize) {
|
||||
std::cout << "\t" << (maxrings ? minrings : 0) << "\t" << maxrings << "\t" << totrings * 1.0 / tottxs;
|
||||
minrings = MAX_RINGS; maxrings = 0; totrings = 0;
|
||||
std::cout << "\t" << (maxrings ? minrings : 0) << "\t" << maxrings << "\t" << totrings / tottxs;
|
||||
minrings = 50; maxrings = 0; totrings = 0;
|
||||
}
|
||||
tottxs = 0;
|
||||
if (do_hours) {
|
||||
for (i=0; i<24; i++) {
|
||||
std::cout << "\t" << txhr[i];
|
||||
txhr[i] = 0;
|
||||
}
|
||||
}
|
||||
currblks = 0;
|
||||
tottxs = 0;
|
||||
std::cout << ENDL;
|
||||
}
|
||||
skip:
|
||||
currsz += bd.size();
|
||||
uint64_t coinbase_amount;
|
||||
uint64_t tx_fee_amount = 0;
|
||||
for (const auto& tx_id : blk.tx_hashes)
|
||||
{
|
||||
if (tx_id == crypto::null_hash)
|
||||
@@ -314,12 +275,7 @@ skip:
|
||||
return 1;
|
||||
}
|
||||
currsz += bd.size();
|
||||
if (db->get_prunable_tx_blob(tx_id, bd))
|
||||
currsz += bd.size();
|
||||
currtxs++;
|
||||
if (do_fees || do_emission) {
|
||||
tx_fee_amount += get_tx_fee(tx);
|
||||
}
|
||||
if (do_hours)
|
||||
txhr[currtm.tm_hour]++;
|
||||
if (do_inputs) {
|
||||
@@ -350,21 +306,6 @@ skip:
|
||||
}
|
||||
tottxs++;
|
||||
}
|
||||
if (do_diff) {
|
||||
difficulty_type diff = db->get_block_difficulty(h);
|
||||
if (!mindiff || diff < mindiff)
|
||||
mindiff = diff;
|
||||
if (diff > maxdiff)
|
||||
maxdiff = diff;
|
||||
totdiff += diff;
|
||||
}
|
||||
if (do_emission) {
|
||||
coinbase_amount = get_outs_money_amount(blk.miner_tx);
|
||||
emission += coinbase_amount - tx_fee_amount;
|
||||
}
|
||||
if (do_fees) {
|
||||
fees += tx_fee_amount;
|
||||
}
|
||||
currblks++;
|
||||
|
||||
if (stop_requested)
|
||||
|
||||
Binary file not shown.
@@ -182,26 +182,12 @@ namespace cryptonote
|
||||
{
|
||||
if (nettype == TESTNET)
|
||||
{
|
||||
ADD_CHECKPOINT2(1, "c47b8effcc84e22ddd1b876d059c8fbd3e26e4bdffb6bed8b8f4fe283104a7af", "0x2");
|
||||
ADD_CHECKPOINT2(5, "292add330f6cf5f3845dc4cd2f28ce8d211dd487ddcfe1b5d1d545d7b90ff7d1", "0x5df"); //Hard fork to v8
|
||||
ADD_CHECKPOINT2(10, "fbdf7d812aa6dd4c5915aadcbf023e722eab1d8ad47c24a230634e688d314798", "0xfa3"); //Hard fork to v9
|
||||
ADD_CHECKPOINT2(15, "9b86e40b959d7cfe75366686dfd2657699e85b8c658aa8c20b23f7bc01b38af0", "0x1967"); //Hard fork to v10
|
||||
ADD_CHECKPOINT2(20, "8f65c309ba3ed2bf25df2b7d91e1db40c864230aa3caaf823db81bc19e0bd6a3", "0x232b"); //Hard fork to v11
|
||||
ADD_CHECKPOINT2(25, "35f2957fdba45d5421561ba2f126a61ec0101b5c2eb79b9e296310acbbdbbe58", "0x2cef"); //Hard fork to v12
|
||||
ADD_CHECKPOINT2(30, "32cc5aacce8bea10ae869313e194ba51a30720810f3665433ffeea2818938429", "0x36b3"); //Hard fork to v13
|
||||
ADD_CHECKPOINT2(35, "7f1cdd2c4a6002772343ad9de6c5dba743a0be1d326a6f63924511f08b15863a", "0x4077"); //Hard fork to v14
|
||||
ADD_CHECKPOINT2(40, "63cf4f703489a881baf63bacd6a3af2b5bde79b558ce123e97313890be6f747f", "0x4a3b"); //Hard fork to v15
|
||||
ADD_CHECKPOINT2(45, "65da4c966ae02983c6c8b7ab9b959df612863c379c5e48669061cbbb1e02a3ab", "0x53ff"); //Hard fork to v16
|
||||
ADD_CHECKPOINT2(50, "8c68a444b6743a14152f130357be9751e42e82a84f69f25320eda532a830c7b0", "0x5dc3"); //Hard fork to v17
|
||||
return true;
|
||||
}
|
||||
if (nettype == STAGENET)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// make RPC call to daemon
|
||||
// curl http://127.0.0.1:34568/json_rpc -d '{"jsonrpc":"2.0","id":"0","method":"get_block","params":{"height":247600}}' -H 'Content-Type: application/json'
|
||||
// "wide_cumulative_difficulty": "0x14eb4d0131fe8",
|
||||
ADD_CHECKPOINT2(1, "97f4ce4d7879b3bea54dcec738cd2ebb7952b4e9bb9743262310cd5fec749340", "0x2");
|
||||
ADD_CHECKPOINT2(6969, "aa7b66e8c461065139b55c29538a39c33ceda93e587f84d490ed573d80511c87", "0x118eef693fd"); //Hard fork to v8
|
||||
ADD_CHECKPOINT2(53666, "3f43f56f66ef0c43cf2fd14d0d28fa2aae0ef8f40716773511345750770f1255", "0xb677d6405ae"); //Hard fork to v9
|
||||
@@ -211,8 +197,7 @@ namespace cryptonote
|
||||
ADD_CHECKPOINT2(114969, "b48245956b87f243048fd61021f4b3e5443e57eee7ff8ba4762d18926e80b80c", "0x1ca552b3ec68"); //Hard fork to v13
|
||||
ADD_CHECKPOINT2(115257, "338e056551087fe23d6c4b4280244bc5362b004716d85ec799a775f190f9fea9", "0x1cb25f5d4628"); //Hard fork to v14
|
||||
ADD_CHECKPOINT2(160777, "9496690579af21f38f00e67e11c2e85a15912fe4f412aad33d1162be1579e755", "0x5376eaa196a8"); //Hard fork to v15
|
||||
ADD_CHECKPOINT2(247600, "f5ecf7b9d2376d7b1d4ca7843c7d39c5854b8f94c968bf9bc2072fa2e0c92ef7", "0x14eb4d0131fe8");
|
||||
|
||||
ADD_CHECKPOINT2(230200, "0ebb018c452fa84997f573937db67ef3946a857ee57cd40fa51ffe368896c666", "0xbcc1409c7268");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -519,14 +519,14 @@ bool load_txt_records_from_dns(std::vector<std::string> &good_records, const std
|
||||
// send all requests in parallel
|
||||
std::deque<bool> avail(dns_urls.size(), false), valid(dns_urls.size(), false);
|
||||
tools::threadpool& tpool = tools::threadpool::getInstance();
|
||||
tools::threadpool::waiter waiter(tpool);
|
||||
tools::threadpool::waiter waiter;
|
||||
for (size_t n = 0; n < dns_urls.size(); ++n)
|
||||
{
|
||||
tpool.submit(&waiter,[n, dns_urls, &records, &avail, &valid](){
|
||||
records[n] = tools::DNSResolver::instance().get_txt_record(dns_urls[n], avail[n], valid[n]);
|
||||
});
|
||||
}
|
||||
waiter.wait();
|
||||
waiter.wait(&tpool);
|
||||
|
||||
size_t cur_index = first_index;
|
||||
do
|
||||
|
||||
@@ -62,7 +62,7 @@ static void replace(std::vector<std::string> &v, const char *tag, const char *s)
|
||||
boost::replace_all(str, tag, s);
|
||||
}
|
||||
|
||||
int Notify::notify(const char *tag, const char *s, ...) const
|
||||
int Notify::notify(const char *tag, const char *s, ...)
|
||||
{
|
||||
std::vector<std::string> margs = args;
|
||||
|
||||
|
||||
@@ -38,12 +38,8 @@ class Notify
|
||||
{
|
||||
public:
|
||||
Notify(const char *spec);
|
||||
Notify(const Notify&) = default;
|
||||
Notify(Notify&&) = default;
|
||||
Notify& operator=(const Notify&) = default;
|
||||
Notify& operator=(Notify&&) = default;
|
||||
|
||||
int notify(const char *tag, const char *s, ...) const;
|
||||
int notify(const char *tag, const char *s, ...);
|
||||
|
||||
private:
|
||||
std::string filename;
|
||||
@@ -51,4 +47,3 @@ private:
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ threadpool::waiter::~waiter()
|
||||
catch (...) { /* ignore */ }
|
||||
try
|
||||
{
|
||||
wait();
|
||||
wait(NULL);
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
@@ -128,12 +128,12 @@ threadpool::waiter::~waiter()
|
||||
}
|
||||
}
|
||||
|
||||
bool threadpool::waiter::wait() {
|
||||
pool.run(true);
|
||||
void threadpool::waiter::wait(threadpool *tpool) {
|
||||
if (tpool)
|
||||
tpool->run(true);
|
||||
boost::unique_lock<boost::mutex> lock(mt);
|
||||
while(num)
|
||||
cv.wait(lock);
|
||||
return !error();
|
||||
}
|
||||
|
||||
void threadpool::waiter::inc() {
|
||||
@@ -166,8 +166,7 @@ void threadpool::run(bool flush) {
|
||||
lock.unlock();
|
||||
++depth;
|
||||
is_leaf = e.leaf;
|
||||
try { e.f(); }
|
||||
catch (const std::exception &ex) { e.wo->set_error(); try { MERROR("Exception in threadpool job: " << ex.what()); } catch (...) {} }
|
||||
e.f();
|
||||
--depth;
|
||||
is_leaf = false;
|
||||
|
||||
|
||||
@@ -55,16 +55,12 @@ public:
|
||||
class waiter {
|
||||
boost::mutex mt;
|
||||
boost::condition_variable cv;
|
||||
threadpool &pool;
|
||||
int num;
|
||||
bool error_flag;
|
||||
public:
|
||||
void inc();
|
||||
void dec();
|
||||
bool wait(); //! Wait for a set of tasks to finish, returns false iff any error
|
||||
void set_error() noexcept { error_flag = true; }
|
||||
bool error() const noexcept { return error_flag; }
|
||||
waiter(threadpool &pool) : pool(pool), num(0), error_flag(false) {}
|
||||
void wait(threadpool *tpool); //! Wait for a set of tasks to finish.
|
||||
waiter() : num(0){}
|
||||
~waiter();
|
||||
};
|
||||
|
||||
|
||||
@@ -98,8 +98,6 @@ namespace tools
|
||||
const char *base = user ? "" : "";
|
||||
#ifdef _WIN32
|
||||
static const char *extension = strncmp(buildtag.c_str(), "source", 6) ? (strncmp(buildtag.c_str(), "install-", 8) ? ".zip" : ".exe") : ".tar.bz2";
|
||||
#elif defined(__APPLE__)
|
||||
static const char *extension = strncmp(software.c_str(), "monero-gui", 10) ? ".tar.bz2" : ".dmg";
|
||||
#else
|
||||
static const char extension[] = ".tar.bz2";
|
||||
#endif
|
||||
|
||||
@@ -1116,7 +1116,7 @@ std::string get_nix_version_display_string()
|
||||
static constexpr const byte_map sizes[] =
|
||||
{
|
||||
{"%.0f B", 1024},
|
||||
{"%.2f kB", 1024 * 1024},
|
||||
{"%.2f KB", 1024 * 1024},
|
||||
{"%.2f MB", std::uint64_t(1024) * 1024 * 1024},
|
||||
{"%.2f GB", std::uint64_t(1024) * 1024 * 1024 * 1024},
|
||||
{"%.2f TB", std::uint64_t(1024) * 1024 * 1024 * 1024 * 1024}
|
||||
|
||||
@@ -116,6 +116,3 @@ endif()
|
||||
|
||||
# cheat because cmake and ccache hate each other
|
||||
set_property(SOURCE CryptonightR_template.S PROPERTY LANGUAGE C)
|
||||
|
||||
# Must be done last, because it references libraries in this directory
|
||||
add_subdirectory(wallet)
|
||||
|
||||
@@ -1234,56 +1234,6 @@ void ge_double_scalarmult_base_vartime(ge_p2 *r, const unsigned char *a, const g
|
||||
}
|
||||
}
|
||||
|
||||
// Computes aG + bB + cC (G is the fixed basepoint)
|
||||
void ge_triple_scalarmult_base_vartime(ge_p2 *r, const unsigned char *a, const unsigned char *b, const ge_dsmp Bi, const unsigned char *c, const ge_dsmp Ci) {
|
||||
signed char aslide[256];
|
||||
signed char bslide[256];
|
||||
signed char cslide[256];
|
||||
ge_p1p1 t;
|
||||
ge_p3 u;
|
||||
int i;
|
||||
|
||||
slide(aslide, a);
|
||||
slide(bslide, b);
|
||||
slide(cslide, c);
|
||||
|
||||
ge_p2_0(r);
|
||||
|
||||
for (i = 255; i >= 0; --i) {
|
||||
if (aslide[i] || bslide[i] || cslide[i]) break;
|
||||
}
|
||||
|
||||
for (; i >= 0; --i) {
|
||||
ge_p2_dbl(&t, r);
|
||||
|
||||
if (aslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_madd(&t, &u, &ge_Bi[aslide[i]/2]);
|
||||
} else if (aslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_msub(&t, &u, &ge_Bi[(-aslide[i])/2]);
|
||||
}
|
||||
|
||||
if (bslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_add(&t, &u, &Bi[bslide[i]/2]);
|
||||
} else if (bslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_sub(&t, &u, &Bi[(-bslide[i])/2]);
|
||||
}
|
||||
|
||||
if (cslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_add(&t, &u, &Ci[cslide[i]/2]);
|
||||
} else if (cslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_sub(&t, &u, &Ci[(-cslide[i])/2]);
|
||||
}
|
||||
|
||||
ge_p1p1_to_p2(r, &t);
|
||||
}
|
||||
}
|
||||
|
||||
void ge_double_scalarmult_base_vartime_p3(ge_p3 *r3, const unsigned char *a, const ge_p3 *A, const unsigned char *b) {
|
||||
signed char aslide[256];
|
||||
signed char bslide[256];
|
||||
@@ -2198,56 +2148,6 @@ void ge_double_scalarmult_precomp_vartime2(ge_p2 *r, const unsigned char *a, con
|
||||
}
|
||||
}
|
||||
|
||||
// Computes aA + bB + cC (all points require precomputation)
|
||||
void ge_triple_scalarmult_precomp_vartime(ge_p2 *r, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi, const unsigned char *c, const ge_dsmp Ci) {
|
||||
signed char aslide[256];
|
||||
signed char bslide[256];
|
||||
signed char cslide[256];
|
||||
ge_p1p1 t;
|
||||
ge_p3 u;
|
||||
int i;
|
||||
|
||||
slide(aslide, a);
|
||||
slide(bslide, b);
|
||||
slide(cslide, c);
|
||||
|
||||
ge_p2_0(r);
|
||||
|
||||
for (i = 255; i >= 0; --i) {
|
||||
if (aslide[i] || bslide[i] || cslide[i]) break;
|
||||
}
|
||||
|
||||
for (; i >= 0; --i) {
|
||||
ge_p2_dbl(&t, r);
|
||||
|
||||
if (aslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_add(&t, &u, &Ai[aslide[i]/2]);
|
||||
} else if (aslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_sub(&t, &u, &Ai[(-aslide[i])/2]);
|
||||
}
|
||||
|
||||
if (bslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_add(&t, &u, &Bi[bslide[i]/2]);
|
||||
} else if (bslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_sub(&t, &u, &Bi[(-bslide[i])/2]);
|
||||
}
|
||||
|
||||
if (cslide[i] > 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_add(&t, &u, &Ci[cslide[i]/2]);
|
||||
} else if (cslide[i] < 0) {
|
||||
ge_p1p1_to_p3(&u, &t);
|
||||
ge_sub(&t, &u, &Ci[(-cslide[i])/2]);
|
||||
}
|
||||
|
||||
ge_p1p1_to_p2(r, &t);
|
||||
}
|
||||
}
|
||||
|
||||
void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *r3, const unsigned char *a, const ge_dsmp Ai, const unsigned char *b, const ge_dsmp Bi) {
|
||||
signed char aslide[256];
|
||||
signed char bslide[256];
|
||||
|
||||
@@ -79,7 +79,6 @@ typedef ge_cached ge_dsmp[8];
|
||||
extern const ge_precomp ge_Bi[8];
|
||||
void ge_dsm_precomp(ge_dsmp r, const ge_p3 *s);
|
||||
void ge_double_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *);
|
||||
void ge_triple_scalarmult_base_vartime(ge_p2 *, const unsigned char *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp);
|
||||
void ge_double_scalarmult_base_vartime_p3(ge_p3 *, const unsigned char *, const ge_p3 *, const unsigned char *);
|
||||
|
||||
/* From ge_frombytes.c, modified */
|
||||
@@ -131,7 +130,6 @@ void sc_reduce(unsigned char *);
|
||||
void ge_scalarmult(ge_p2 *, const unsigned char *, const ge_p3 *);
|
||||
void ge_scalarmult_p3(ge_p3 *, const unsigned char *, const ge_p3 *);
|
||||
void ge_double_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_p3 *, const unsigned char *, const ge_dsmp);
|
||||
void ge_triple_scalarmult_precomp_vartime(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp);
|
||||
void ge_double_scalarmult_precomp_vartime2(ge_p2 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp);
|
||||
void ge_double_scalarmult_precomp_vartime2_p3(ge_p3 *, const unsigned char *, const ge_dsmp, const unsigned char *, const ge_dsmp);
|
||||
void ge_mul8(ge_p1p1 *, const ge_p2 *);
|
||||
|
||||
@@ -43,8 +43,6 @@
|
||||
#include "crypto.h"
|
||||
#include "hash.h"
|
||||
|
||||
#include "cryptonote_config.h"
|
||||
|
||||
namespace {
|
||||
static void local_abort(const char *msg)
|
||||
{
|
||||
@@ -263,24 +261,11 @@ namespace crypto {
|
||||
ec_point comm;
|
||||
};
|
||||
|
||||
// Used in v1 tx proofs
|
||||
struct s_comm_2_v1 {
|
||||
hash msg;
|
||||
ec_point D;
|
||||
ec_point X;
|
||||
ec_point Y;
|
||||
};
|
||||
|
||||
// Used in v1/v2 tx proofs
|
||||
struct s_comm_2 {
|
||||
hash msg;
|
||||
ec_point D;
|
||||
ec_point X;
|
||||
ec_point Y;
|
||||
hash sep; // domain separation
|
||||
ec_point R;
|
||||
ec_point A;
|
||||
ec_point B;
|
||||
};
|
||||
|
||||
void crypto_ops::generate_signature(const hash &prefix_hash, const public_key &pub, const secret_key &sec, signature &sig) {
|
||||
@@ -336,86 +321,6 @@ namespace crypto {
|
||||
return sc_isnonzero(&c) == 0;
|
||||
}
|
||||
|
||||
// Generate a proof of knowledge of `r` such that (`R = rG` and `D = rA`) or (`R = rB` and `D = rA`) via a Schnorr proof
|
||||
// This handles use cases for both standard addresses and subaddresses
|
||||
//
|
||||
// NOTE: This generates old v1 proofs, and is for TESTING ONLY
|
||||
void crypto_ops::generate_tx_proof_v1(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const secret_key &r, signature &sig) {
|
||||
// sanity check
|
||||
ge_p3 R_p3;
|
||||
ge_p3 A_p3;
|
||||
ge_p3 B_p3;
|
||||
ge_p3 D_p3;
|
||||
if (ge_frombytes_vartime(&R_p3, &R) != 0) throw std::runtime_error("tx pubkey is invalid");
|
||||
if (ge_frombytes_vartime(&A_p3, &A) != 0) throw std::runtime_error("recipient view pubkey is invalid");
|
||||
if (B && ge_frombytes_vartime(&B_p3, &*B) != 0) throw std::runtime_error("recipient spend pubkey is invalid");
|
||||
if (ge_frombytes_vartime(&D_p3, &D) != 0) throw std::runtime_error("key derivation is invalid");
|
||||
#if !defined(NDEBUG)
|
||||
{
|
||||
assert(sc_check(&r) == 0);
|
||||
// check R == r*G or R == r*B
|
||||
public_key dbg_R;
|
||||
if (B)
|
||||
{
|
||||
ge_p2 dbg_R_p2;
|
||||
ge_scalarmult(&dbg_R_p2, &r, &B_p3);
|
||||
ge_tobytes(&dbg_R, &dbg_R_p2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ge_p3 dbg_R_p3;
|
||||
ge_scalarmult_base(&dbg_R_p3, &r);
|
||||
ge_p3_tobytes(&dbg_R, &dbg_R_p3);
|
||||
}
|
||||
assert(R == dbg_R);
|
||||
// check D == r*A
|
||||
ge_p2 dbg_D_p2;
|
||||
ge_scalarmult(&dbg_D_p2, &r, &A_p3);
|
||||
public_key dbg_D;
|
||||
ge_tobytes(&dbg_D, &dbg_D_p2);
|
||||
assert(D == dbg_D);
|
||||
}
|
||||
#endif
|
||||
|
||||
// pick random k
|
||||
ec_scalar k;
|
||||
random_scalar(k);
|
||||
|
||||
s_comm_2_v1 buf;
|
||||
buf.msg = prefix_hash;
|
||||
buf.D = D;
|
||||
|
||||
if (B)
|
||||
{
|
||||
// compute X = k*B
|
||||
ge_p2 X_p2;
|
||||
ge_scalarmult(&X_p2, &k, &B_p3);
|
||||
ge_tobytes(&buf.X, &X_p2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// compute X = k*G
|
||||
ge_p3 X_p3;
|
||||
ge_scalarmult_base(&X_p3, &k);
|
||||
ge_p3_tobytes(&buf.X, &X_p3);
|
||||
}
|
||||
|
||||
// compute Y = k*A
|
||||
ge_p2 Y_p2;
|
||||
ge_scalarmult(&Y_p2, &k, &A_p3);
|
||||
ge_tobytes(&buf.Y, &Y_p2);
|
||||
|
||||
// sig.c = Hs(Msg || D || X || Y)
|
||||
hash_to_scalar(&buf, sizeof(buf), sig.c);
|
||||
|
||||
// sig.r = k - sig.c*r
|
||||
sc_mulsub(&sig.r, &sig.c, &unwrap(r), &k);
|
||||
}
|
||||
|
||||
// Generate a proof of knowledge of `r` such that (`R = rG` and `D = rA`) or (`R = rB` and `D = rA`) via a Schnorr proof
|
||||
// This handles use cases for both standard addresses and subaddresses
|
||||
//
|
||||
// Generates only proofs for InProofV2 and OutProofV2
|
||||
void crypto_ops::generate_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const secret_key &r, signature &sig) {
|
||||
// sanity check
|
||||
ge_p3 R_p3;
|
||||
@@ -457,20 +362,10 @@ namespace crypto {
|
||||
ec_scalar k;
|
||||
random_scalar(k);
|
||||
|
||||
// if B is not present
|
||||
static const ec_point zero = {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }};
|
||||
|
||||
s_comm_2 buf;
|
||||
buf.msg = prefix_hash;
|
||||
buf.D = D;
|
||||
buf.R = R;
|
||||
buf.A = A;
|
||||
if (B)
|
||||
buf.B = *B;
|
||||
else
|
||||
buf.B = zero;
|
||||
cn_fast_hash(config::HASH_KEY_TXPROOF_V2, sizeof(config::HASH_KEY_TXPROOF_V2)-1, buf.sep);
|
||||
|
||||
|
||||
if (B)
|
||||
{
|
||||
// compute X = k*B
|
||||
@@ -491,7 +386,7 @@ namespace crypto {
|
||||
ge_scalarmult(&Y_p2, &k, &A_p3);
|
||||
ge_tobytes(&buf.Y, &Y_p2);
|
||||
|
||||
// sig.c = Hs(Msg || D || X || Y || sep || R || A || B)
|
||||
// sig.c = Hs(Msg || D || X || Y)
|
||||
hash_to_scalar(&buf, sizeof(buf), sig.c);
|
||||
|
||||
// sig.r = k - sig.c*r
|
||||
@@ -500,8 +395,7 @@ namespace crypto {
|
||||
memwipe(&k, sizeof(k));
|
||||
}
|
||||
|
||||
// Verify a proof: either v1 (version == 1) or v2 (version == 2)
|
||||
bool crypto_ops::check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const signature &sig, const int version) {
|
||||
bool crypto_ops::check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const signature &sig) {
|
||||
// sanity check
|
||||
ge_p3 R_p3;
|
||||
ge_p3 A_p3;
|
||||
@@ -573,31 +467,14 @@ namespace crypto {
|
||||
ge_p2 Y_p2;
|
||||
ge_p1p1_to_p2(&Y_p2, &Y_p1p1);
|
||||
|
||||
// Compute hash challenge
|
||||
// for v1, c2 = Hs(Msg || D || X || Y)
|
||||
// for v2, c2 = Hs(Msg || D || X || Y || sep || R || A || B)
|
||||
|
||||
// if B is not present
|
||||
static const ec_point zero = {{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }};
|
||||
|
||||
// compute c2 = Hs(Msg || D || X || Y)
|
||||
s_comm_2 buf;
|
||||
buf.msg = prefix_hash;
|
||||
buf.D = D;
|
||||
buf.R = R;
|
||||
buf.A = A;
|
||||
if (B)
|
||||
buf.B = *B;
|
||||
else
|
||||
buf.B = zero;
|
||||
cn_fast_hash(config::HASH_KEY_TXPROOF_V2, sizeof(config::HASH_KEY_TXPROOF_V2)-1, buf.sep);
|
||||
ge_tobytes(&buf.X, &X_p2);
|
||||
ge_tobytes(&buf.Y, &Y_p2);
|
||||
ec_scalar c2;
|
||||
|
||||
// Hash depends on version
|
||||
if (version == 1) hash_to_scalar(&buf, sizeof(s_comm_2) - 3*sizeof(ec_point) - sizeof(hash), c2);
|
||||
else if (version == 2) hash_to_scalar(&buf, sizeof(s_comm_2), c2);
|
||||
else return false;
|
||||
hash_to_scalar(&buf, sizeof(s_comm_2), c2);
|
||||
|
||||
// test if c2 == sig.c
|
||||
sc_sub(&c2, &c2, &sig.c);
|
||||
|
||||
@@ -132,10 +132,8 @@ namespace crypto {
|
||||
friend bool check_signature(const hash &, const public_key &, const signature &);
|
||||
static void generate_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const secret_key &, signature &);
|
||||
friend void generate_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const secret_key &, signature &);
|
||||
static void generate_tx_proof_v1(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const secret_key &, signature &);
|
||||
friend void generate_tx_proof_v1(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const secret_key &, signature &);
|
||||
static bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &, const int);
|
||||
friend bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &, const int);
|
||||
static bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &);
|
||||
friend bool check_tx_proof(const hash &, const public_key &, const public_key &, const boost::optional<public_key> &, const public_key &, const signature &);
|
||||
static void generate_key_image(const public_key &, const secret_key &, key_image &);
|
||||
friend void generate_key_image(const public_key &, const secret_key &, key_image &);
|
||||
static void generate_ring_signature(const hash &, const key_image &,
|
||||
@@ -250,11 +248,8 @@ namespace crypto {
|
||||
inline void generate_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const secret_key &r, signature &sig) {
|
||||
crypto_ops::generate_tx_proof(prefix_hash, R, A, B, D, r, sig);
|
||||
}
|
||||
inline void generate_tx_proof_v1(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const secret_key &r, signature &sig) {
|
||||
crypto_ops::generate_tx_proof_v1(prefix_hash, R, A, B, D, r, sig);
|
||||
}
|
||||
inline bool check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const signature &sig, const int version) {
|
||||
return crypto_ops::check_tx_proof(prefix_hash, R, A, B, D, sig, version);
|
||||
inline bool check_tx_proof(const hash &prefix_hash, const public_key &R, const public_key &A, const boost::optional<public_key> &B, const public_key &D, const signature &sig) {
|
||||
return crypto_ops::check_tx_proof(prefix_hash, R, A, B, D, sig);
|
||||
}
|
||||
|
||||
/* To send money to a key:
|
||||
|
||||
@@ -73,7 +73,7 @@ namespace crypto {
|
||||
inline void cn_slow_hash(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
|
||||
cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 0/*prehashed*/, height);
|
||||
}
|
||||
|
||||
|
||||
inline void cn_slow_hash_prehashed(const void *data, std::size_t length, hash &hash, int variant = 0, uint64_t height = 0) {
|
||||
cn_slow_hash(data, length, reinterpret_cast<char *>(&hash), variant, 1/*prehashed*/, height);
|
||||
}
|
||||
|
||||
@@ -116,46 +116,6 @@ static inline int enabled_flags(void) {
|
||||
#define SEEDHASH_EPOCH_BLOCKS 2048 /* Must be same as BLOCKS_SYNCHRONIZING_MAX_COUNT in cryptonote_config.h */
|
||||
#define SEEDHASH_EPOCH_LAG 64
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
void rx_reorg(const uint64_t split_height) {
|
||||
int i;
|
||||
CTHR_MUTEX_LOCK(rx_mutex);
|
||||
@@ -170,16 +130,14 @@ void rx_reorg(const uint64_t split_height) {
|
||||
}
|
||||
|
||||
uint64_t rx_seedheight(const uint64_t height) {
|
||||
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);
|
||||
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 rx_seedheights(const uint64_t height, uint64_t *seedheight, uint64_t *nextheight) {
|
||||
*seedheight = rx_seedheight(height);
|
||||
*nextheight = rx_seedheight(height + get_seedhash_epoch_lag());
|
||||
*nextheight = rx_seedheight(height + SEEDHASH_EPOCH_LAG);
|
||||
}
|
||||
|
||||
typedef struct seedinfo {
|
||||
@@ -203,11 +161,11 @@ static void rx_initdata(randomx_cache *rs_cache, const int miners, const uint64_
|
||||
CTHR_THREAD_TYPE *st;
|
||||
si = malloc(miners * sizeof(seedinfo));
|
||||
if (si == NULL)
|
||||
local_abort("Couldn't allocate RandomX mining threadinfo");
|
||||
local_abort("Couldn't allocate RandomWOW mining threadinfo");
|
||||
st = malloc(miners * sizeof(CTHR_THREAD_TYPE));
|
||||
if (st == NULL) {
|
||||
free(si);
|
||||
local_abort("Couldn't allocate RandomX mining threadlist");
|
||||
local_abort("Couldn't allocate RandomWOW mining threadlist");
|
||||
}
|
||||
for (i=0; i<miners-1; i++) {
|
||||
si[i].si_cache = rs_cache;
|
||||
@@ -236,7 +194,7 @@ static void rx_initdata(randomx_cache *rs_cache, const int miners, const uint64_
|
||||
void 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 = rx_seedheight(mainheight);
|
||||
int toggle = (s_height & get_seedhash_epoch_blocks()) != 0;
|
||||
int toggle = (s_height & SEEDHASH_EPOCH_BLOCKS) != 0;
|
||||
randomx_flags flags = enabled_flags() & ~disabled_flags();
|
||||
rx_state *rx_sp;
|
||||
randomx_cache *cache;
|
||||
@@ -267,11 +225,11 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
|
||||
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");
|
||||
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomWOW cache");
|
||||
cache = randomx_alloc_cache(flags);
|
||||
}
|
||||
if (cache == NULL)
|
||||
local_abort("Couldn't allocate RandomX cache");
|
||||
local_abort("Couldn't allocate RandomWOW cache");
|
||||
}
|
||||
}
|
||||
if (rx_sp->rs_height != seedheight || rx_sp->rs_cache == NULL || memcmp(seedhash, rx_sp->rs_hash, HASH_SIZE)) {
|
||||
@@ -293,7 +251,7 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
|
||||
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");
|
||||
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomWOW dataset");
|
||||
rx_dataset = randomx_alloc_dataset(RANDOMX_FLAG_DEFAULT);
|
||||
}
|
||||
if (rx_dataset != NULL)
|
||||
@@ -306,14 +264,14 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
|
||||
miners = 0;
|
||||
if (!rx_dataset_nomem) {
|
||||
rx_dataset_nomem = 1;
|
||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomX dataset for miner");
|
||||
mwarning(RX_LOGCAT, "Couldn't allocate RandomWOW 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");
|
||||
mdebug(RX_LOGCAT, "Couldn't use largePages for RandomWOW VM");
|
||||
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, rx_dataset);
|
||||
}
|
||||
if(rx_vm == NULL) {//fallback if everything fails
|
||||
@@ -321,7 +279,7 @@ void rx_slow_hash(const uint64_t mainheight, const uint64_t seedheight, const ch
|
||||
rx_vm = randomx_create_vm(flags, rx_sp->rs_cache, rx_dataset);
|
||||
}
|
||||
if (rx_vm == NULL)
|
||||
local_abort("Couldn't allocate RandomX VM");
|
||||
local_abort("Couldn't allocate RandomWOW VM");
|
||||
} else if (miners) {
|
||||
CTHR_MUTEX_LOCK(rx_dataset_mutex);
|
||||
if (rx_dataset != NULL && rx_dataset_height != seedheight)
|
||||
|
||||
@@ -1,62 +0,0 @@
|
||||
# Copyright (c) 2020, The Monero Project
|
||||
#
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification, are
|
||||
# permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other
|
||||
# materials provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software without specific
|
||||
# prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
# THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#
|
||||
# Possibly user defined values.
|
||||
#
|
||||
set(MONERO_WALLET_CRYPTO_LIBRARY "auto" CACHE STRING "Select a wallet crypto library")
|
||||
|
||||
#
|
||||
# If the user specified "auto", detect best library defaulting to internal.
|
||||
#
|
||||
if (${MONERO_WALLET_CRYPTO_LIBRARY} STREQUAL "auto")
|
||||
monero_crypto_autodetect(AVAILABLE BEST)
|
||||
if (DEFINED BEST)
|
||||
message("Wallet crypto is using ${BEST} backend")
|
||||
set(MONERO_WALLET_CRYPTO_LIBRARY ${BEST})
|
||||
else ()
|
||||
message("Defaulting to internal crypto library for wallet")
|
||||
set(MONERO_WALLET_CRYPTO_LIBRARY "cn")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
#
|
||||
# Configure library target "wallet-crypto" - clients will use this as a
|
||||
# library dependency which in turn will depend on the crypto library selected.
|
||||
#
|
||||
if (${MONERO_WALLET_CRYPTO_LIBRARY} STREQUAL "cn")
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/empty.h.in ${MONERO_GENERATED_HEADERS_DIR}/crypto/wallet/ops.h)
|
||||
add_library(wallet-crypto ALIAS cncrypto)
|
||||
else ()
|
||||
monero_crypto_generate_header(${MONERO_WALLET_CRYPTO_LIBRARY} "${MONERO_GENERATED_HEADERS_DIR}/crypto/wallet/ops.h")
|
||||
monero_crypto_get_target(${MONERO_WALLET_CRYPTO_LIBRARY} CRYPTO_TARGET)
|
||||
add_library(wallet-crypto $<TARGET_OBJECTS:${CRYPTO_TARGET}>)
|
||||
target_link_libraries(wallet-crypto cncrypto)
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright (c) 2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstddef>
|
||||
#include "crypto/wallet/ops.h"
|
||||
|
||||
namespace crypto {
|
||||
namespace wallet {
|
||||
// if C functions defined from external/supercop - cmake generates crypto/wallet/ops.h
|
||||
#if defined(monero_crypto_generate_key_derivation)
|
||||
inline
|
||||
bool generate_key_derivation(const public_key &tx_pub, const secret_key &view_sec, key_derivation &out)
|
||||
{
|
||||
return monero_crypto_generate_key_derivation(out.data, tx_pub.data, view_sec.data) == 0;
|
||||
}
|
||||
|
||||
inline
|
||||
bool derive_subaddress_public_key(const public_key &output_pub, const key_derivation &d, std::size_t index, public_key &out)
|
||||
{
|
||||
ec_scalar scalar;
|
||||
derivation_to_scalar(d, index, scalar);
|
||||
return monero_crypto_generate_subaddress_public_key(out.data, output_pub.data, scalar.data) == 0;
|
||||
}
|
||||
#else
|
||||
using ::crypto::generate_key_derivation;
|
||||
using ::crypto::derive_subaddress_public_key;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
// Copyright (c) 2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
// Left empty so internal cryptonote crypto library is used.
|
||||
@@ -31,11 +31,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/utility/string_ref_fwd.hpp>
|
||||
#include "span.h"
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
typedef std::string blobdata;
|
||||
typedef boost::string_ref blobdata_ref;
|
||||
typedef epee::span<const char> blobdata_ref;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
#include <sstream>
|
||||
#include <atomic>
|
||||
#include "serialization/variant.h"
|
||||
#include "serialization/containers.h"
|
||||
#include "serialization/vector.h"
|
||||
#include "serialization/binary_archive.h"
|
||||
#include "serialization/json_archive.h"
|
||||
#include "serialization/debug_archive.h"
|
||||
|
||||
@@ -34,6 +34,7 @@ using namespace epee;
|
||||
#include "cryptonote_basic_impl.h"
|
||||
#include "string_tools.h"
|
||||
#include "serialization/binary_utils.h"
|
||||
#include "serialization/container.h"
|
||||
#include "cryptonote_format_utils.h"
|
||||
#include "cryptonote_config.h"
|
||||
#include "misc_language.h"
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include <boost/serialization/set.hpp>
|
||||
#include <boost/serialization/map.hpp>
|
||||
#include <boost/serialization/is_bitwise_serializable.hpp>
|
||||
#include <boost/archive/binary_iarchive.hpp>
|
||||
#include <boost/archive/portable_binary_iarchive.hpp>
|
||||
#include <boost/archive/portable_binary_oarchive.hpp>
|
||||
#include "cryptonote_basic.h"
|
||||
@@ -45,6 +46,7 @@
|
||||
#include "ringct/rctTypes.h"
|
||||
#include "ringct/rctOps.h"
|
||||
|
||||
//namespace cryptonote {
|
||||
namespace boost
|
||||
{
|
||||
namespace serialization
|
||||
@@ -243,15 +245,6 @@ namespace boost
|
||||
// a & x.II; // not serialized, we can recover it from the tx vin
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, rct::clsag &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & x.s;
|
||||
a & x.c1;
|
||||
// a & x.I; // not serialized, we can recover it from the tx vin
|
||||
a & x.D;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
inline void serialize(Archive &a, rct::ecdhTuple &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
@@ -272,9 +265,6 @@ namespace boost
|
||||
inline void serialize(Archive &a, rct::multisig_out &x, const boost::serialization::version_type ver)
|
||||
{
|
||||
a & x.c;
|
||||
if (ver < 1)
|
||||
return;
|
||||
a & x.mu_p;
|
||||
}
|
||||
|
||||
template <class Archive>
|
||||
@@ -305,7 +295,7 @@ namespace boost
|
||||
a & x.type;
|
||||
if (x.type == rct::RCTTypeNull)
|
||||
return;
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof && x.type != rct::RCTTypeCLSAG)
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof)
|
||||
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
||||
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
||||
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
||||
@@ -323,8 +313,6 @@ namespace boost
|
||||
if (x.rangeSigs.empty())
|
||||
a & x.bulletproofs;
|
||||
a & x.MGs;
|
||||
if (ver >= 1u)
|
||||
a & x.CLSAGs;
|
||||
if (x.rangeSigs.empty())
|
||||
a & x.pseudoOuts;
|
||||
}
|
||||
@@ -335,7 +323,7 @@ namespace boost
|
||||
a & x.type;
|
||||
if (x.type == rct::RCTTypeNull)
|
||||
return;
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof && x.type != rct::RCTTypeCLSAG)
|
||||
if (x.type != rct::RCTTypeFull && x.type != rct::RCTTypeSimple && x.type != rct::RCTTypeBulletproof && x.type != rct::RCTTypeBulletproof2 && x.type != rct::RCTTypeFullBulletproof && x.type != rct::RCTTypeSimpleBulletproof)
|
||||
throw boost::archive::archive_exception(boost::archive::archive_exception::other_exception, "Unsupported rct type");
|
||||
// a & x.message; message is not serialized, as it can be reconstructed from the tx data
|
||||
// a & x.mixRing; mixRing is not serialized, as it can be reconstructed from the offsets
|
||||
@@ -349,9 +337,7 @@ namespace boost
|
||||
if (x.p.rangeSigs.empty())
|
||||
a & x.p.bulletproofs;
|
||||
a & x.p.MGs;
|
||||
if (ver >= 1u)
|
||||
a & x.p.CLSAGs;
|
||||
if (x.type == rct::RCTTypeBulletproof || x.type == rct::RCTTypeBulletproof2 || x.type == rct::RCTTypeSimpleBulletproof || x.type == rct::RCTTypeCLSAG)
|
||||
if (x.type == rct::RCTTypeBulletproof || x.type == rct::RCTTypeBulletproof2 || x.type == rct::RCTTypeSimpleBulletproof)
|
||||
a & x.p.pseudoOuts;
|
||||
}
|
||||
|
||||
@@ -392,6 +378,4 @@ namespace boost
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_CLASS_VERSION(rct::rctSigPrunable, 1)
|
||||
BOOST_CLASS_VERSION(rct::rctSig, 1)
|
||||
BOOST_CLASS_VERSION(rct::multisig_out, 1)
|
||||
//}
|
||||
|
||||
@@ -229,7 +229,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_from_blob(const blobdata_ref& tx_blob, transaction& tx)
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << tx_blob;
|
||||
@@ -242,7 +242,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_base_from_blob(const blobdata_ref& tx_blob, transaction& tx)
|
||||
bool parse_and_validate_tx_base_from_blob(const blobdata& tx_blob, transaction& tx)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << tx_blob;
|
||||
@@ -254,7 +254,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_prefix_from_blob(const blobdata_ref& tx_blob, transaction_prefix& tx)
|
||||
bool parse_and_validate_tx_prefix_from_blob(const blobdata& tx_blob, transaction_prefix& tx)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << tx_blob;
|
||||
@@ -264,7 +264,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_from_blob(const blobdata_ref& tx_blob, transaction& tx, crypto::hash& tx_hash)
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << tx_blob;
|
||||
@@ -278,7 +278,7 @@ namespace cryptonote
|
||||
return get_transaction_hash(tx, tx_hash);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_tx_from_blob(const blobdata_ref& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash)
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash)
|
||||
{
|
||||
if (!parse_and_validate_tx_from_blob(tx_blob, tx, tx_hash))
|
||||
return false;
|
||||
@@ -462,7 +462,7 @@ namespace cryptonote
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(tx.pruned, std::numeric_limits<uint64_t>::max(), "get_pruned_transaction_weight does not support non pruned txes");
|
||||
CHECK_AND_ASSERT_MES(tx.version >= 2, std::numeric_limits<uint64_t>::max(), "get_pruned_transaction_weight does not support v1 txes");
|
||||
CHECK_AND_ASSERT_MES(tx.rct_signatures.type >= rct::RCTTypeBulletproof2 || tx.rct_signatures.type == rct::RCTTypeCLSAG,
|
||||
CHECK_AND_ASSERT_MES(tx.rct_signatures.type >= rct::RCTTypeBulletproof2,
|
||||
std::numeric_limits<uint64_t>::max(), "get_pruned_transaction_weight does not support older range proof types");
|
||||
CHECK_AND_ASSERT_MES(!tx.vin.empty(), std::numeric_limits<uint64_t>::max(), "empty vin");
|
||||
CHECK_AND_ASSERT_MES(tx.vin[0].type() == typeid(cryptonote::txin_to_key), std::numeric_limits<uint64_t>::max(), "empty vin");
|
||||
@@ -484,12 +484,9 @@ namespace cryptonote
|
||||
extra = 32 * (9 + 2 * nrl) + 2;
|
||||
weight += extra;
|
||||
|
||||
// calculate deterministic CLSAG/MLSAG data size
|
||||
// calculate deterministic MLSAG data size
|
||||
const size_t ring_size = boost::get<cryptonote::txin_to_key>(tx.vin[0]).key_offsets.size();
|
||||
if (tx.rct_signatures.type == rct::RCTTypeCLSAG)
|
||||
extra = tx.vin.size() * (ring_size + 2) * 32;
|
||||
else
|
||||
extra = tx.vin.size() * (ring_size * (1 + 1) * 32 + 32 /* cc */);
|
||||
extra = tx.vin.size() * (ring_size * (1 + 1) * 32 + 32 /* cc */);
|
||||
weight += extra;
|
||||
|
||||
// calculate deterministic pseudoOuts size
|
||||
@@ -987,7 +984,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
void get_blob_hash(const blobdata_ref& blob, crypto::hash& res)
|
||||
void get_blob_hash(const epee::span<const char>& blob, crypto::hash& res)
|
||||
{
|
||||
cn_fast_hash(blob.data(), blob.size(), res);
|
||||
}
|
||||
@@ -1074,7 +1071,7 @@ namespace cryptonote
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_blob_hash(const blobdata_ref& blob)
|
||||
crypto::hash get_blob_hash(const epee::span<const char>& blob)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_blob_hash(blob, h);
|
||||
@@ -1094,7 +1091,7 @@ namespace cryptonote
|
||||
return get_transaction_hash(t, res, NULL);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool calculate_transaction_prunable_hash(const transaction& t, const cryptonote::blobdata_ref *blob, crypto::hash& res)
|
||||
bool calculate_transaction_prunable_hash(const transaction& t, const cryptonote::blobdata *blob, crypto::hash& res)
|
||||
{
|
||||
if (t.version == 1)
|
||||
return false;
|
||||
@@ -1102,7 +1099,7 @@ namespace cryptonote
|
||||
if (blob && unprunable_size)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(unprunable_size <= blob->size(), false, "Inconsistent transaction unprunable and blob sizes");
|
||||
cryptonote::get_blob_hash(blobdata_ref(blob->data() + unprunable_size, blob->size() - unprunable_size), res);
|
||||
cryptonote::get_blob_hash(epee::span<const char>(blob->data() + unprunable_size, blob->size() - unprunable_size), res);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1119,7 +1116,7 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_transaction_prunable_hash(const transaction& t, const cryptonote::blobdata_ref *blobdata)
|
||||
crypto::hash get_transaction_prunable_hash(const transaction& t, const cryptonote::blobdata *blobdata)
|
||||
{
|
||||
crypto::hash res;
|
||||
if (t.is_prunable_hash_valid())
|
||||
@@ -1197,7 +1194,7 @@ namespace cryptonote
|
||||
|
||||
// base rct
|
||||
CHECK_AND_ASSERT_MES(prefix_size <= unprunable_size && unprunable_size <= blob.size(), false, "Inconsistent transaction prefix, unprunable and blob sizes");
|
||||
cryptonote::get_blob_hash(blobdata_ref(blob.data() + prefix_size, unprunable_size - prefix_size), hashes[1]);
|
||||
cryptonote::get_blob_hash(epee::span<const char>(blob.data() + prefix_size, unprunable_size - prefix_size), hashes[1]);
|
||||
|
||||
// prunable rct
|
||||
if (t.rct_signatures.type == rct::RCTTypeNull)
|
||||
@@ -1206,8 +1203,7 @@ namespace cryptonote
|
||||
}
|
||||
else
|
||||
{
|
||||
cryptonote::blobdata_ref blobref(blob);
|
||||
CHECK_AND_ASSERT_MES(calculate_transaction_prunable_hash(t, &blobref, hashes[2]), false, "Failed to get tx prunable hash");
|
||||
CHECK_AND_ASSERT_MES(calculate_transaction_prunable_hash(t, &blob, hashes[2]), false, "Failed to get tx prunable hash");
|
||||
}
|
||||
|
||||
// the tx hash is the hash of the 3 hashes
|
||||
@@ -1271,7 +1267,7 @@ namespace cryptonote
|
||||
return blob;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata_ref *blob)
|
||||
bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata *blob)
|
||||
{
|
||||
return get_object_hash(get_block_hashing_blob(b), res);
|
||||
}
|
||||
@@ -1322,7 +1318,7 @@ namespace cryptonote
|
||||
return res;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash *block_hash)
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b, crypto::hash *block_hash)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << b_blob;
|
||||
@@ -1340,12 +1336,12 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b)
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b)
|
||||
{
|
||||
return parse_and_validate_block_from_blob(b_blob, b, NULL);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash &block_hash)
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b, crypto::hash &block_hash)
|
||||
{
|
||||
return parse_and_validate_block_from_blob(b_blob, b, &block_hash);
|
||||
}
|
||||
|
||||
@@ -52,11 +52,11 @@ namespace cryptonote
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx, hw::device &hwdev);
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h);
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx);
|
||||
bool parse_and_validate_tx_prefix_from_blob(const blobdata_ref& tx_blob, transaction_prefix& tx);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata_ref& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata_ref& tx_blob, transaction& tx, crypto::hash& tx_hash);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata_ref& tx_blob, transaction& tx);
|
||||
bool parse_and_validate_tx_base_from_blob(const blobdata_ref& tx_blob, transaction& tx);
|
||||
bool parse_and_validate_tx_prefix_from_blob(const blobdata& tx_blob, transaction_prefix& tx);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash, crypto::hash& tx_prefix_hash);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx, crypto::hash& tx_hash);
|
||||
bool parse_and_validate_tx_from_blob(const blobdata& tx_blob, transaction& tx);
|
||||
bool parse_and_validate_tx_base_from_blob(const blobdata& tx_blob, transaction& tx);
|
||||
bool is_v1_tx(const blobdata_ref& tx_blob);
|
||||
bool is_v1_tx(const blobdata& tx_blob);
|
||||
|
||||
@@ -102,27 +102,27 @@ namespace cryptonote
|
||||
bool generate_key_image_helper(const account_keys& ack, const std::unordered_map<crypto::public_key, subaddress_index>& subaddresses, const crypto::public_key& out_key, const crypto::public_key& tx_public_key, const std::vector<crypto::public_key>& additional_tx_public_keys, size_t real_output_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev);
|
||||
bool generate_key_image_helper_precomp(const account_keys& ack, const crypto::public_key& out_key, const crypto::key_derivation& recv_derivation, size_t real_output_index, const subaddress_index& received_index, keypair& in_ephemeral, crypto::key_image& ki, hw::device &hwdev);
|
||||
void get_blob_hash(const blobdata& blob, crypto::hash& res);
|
||||
void get_blob_hash(const blobdata_ref& blob, crypto::hash& res);
|
||||
void get_blob_hash(const epee::span<const char>& blob, crypto::hash& res);
|
||||
crypto::hash get_blob_hash(const blobdata& blob);
|
||||
crypto::hash get_blob_hash(const blobdata_ref& blob);
|
||||
crypto::hash get_blob_hash(const epee::span<const char>& blob);
|
||||
std::string short_hash_str(const crypto::hash& h);
|
||||
|
||||
crypto::hash get_transaction_hash(const transaction& t);
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res);
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t& blob_size);
|
||||
bool get_transaction_hash(const transaction& t, crypto::hash& res, size_t* blob_size);
|
||||
bool calculate_transaction_prunable_hash(const transaction& t, const cryptonote::blobdata_ref *blob, crypto::hash& res);
|
||||
crypto::hash get_transaction_prunable_hash(const transaction& t, const cryptonote::blobdata_ref *blob = NULL);
|
||||
bool calculate_transaction_prunable_hash(const transaction& t, const cryptonote::blobdata *blob, crypto::hash& res);
|
||||
crypto::hash get_transaction_prunable_hash(const transaction& t, const cryptonote::blobdata *blob = NULL);
|
||||
bool calculate_transaction_hash(const transaction& t, crypto::hash& res, size_t* blob_size);
|
||||
crypto::hash get_pruned_transaction_hash(const transaction& t, const crypto::hash &pruned_data_hash);
|
||||
|
||||
blobdata get_block_hashing_blob(const block& b);
|
||||
bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata_ref *blob = NULL);
|
||||
bool calculate_block_hash(const block& b, crypto::hash& res, const blobdata *blob = NULL);
|
||||
bool get_block_hash(const block& b, crypto::hash& res);
|
||||
crypto::hash get_block_hash(const block& b);
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash *block_hash);
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b);
|
||||
bool parse_and_validate_block_from_blob(const blobdata_ref& b_blob, block& b, crypto::hash &block_hash);
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b, crypto::hash *block_hash);
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b);
|
||||
bool parse_and_validate_block_from_blob(const blobdata& b_blob, block& b, crypto::hash &block_hash);
|
||||
bool get_inputs_money_amount(const transaction& tx, uint64_t& money);
|
||||
uint64_t get_outs_money_amount(const transaction& tx);
|
||||
bool check_inputs_types_supported(const transaction& tx);
|
||||
|
||||
@@ -201,19 +201,20 @@ namespace cryptonote {
|
||||
return check_hash_128(hash, difficulty);
|
||||
}
|
||||
|
||||
difficulty_type next_difficulty(std::vector<uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT) {
|
||||
difficulty_type next_difficulty(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds) {
|
||||
//cutoff DIFFICULTY_LAG
|
||||
if(timestamps.size() > DIFFICULTY_WINDOW)
|
||||
{
|
||||
timestamps.resize(DIFFICULTY_WINDOW);
|
||||
cumulative_difficulties.resize(DIFFICULTY_WINDOW);
|
||||
}
|
||||
|
||||
|
||||
size_t length = timestamps.size();
|
||||
assert(length == cumulative_difficulties.size());
|
||||
if (length <= 1) {
|
||||
return 1;
|
||||
}
|
||||
if (HEIGHT < 200 && HEIGHT > 2 && m_nettype == TESTNET) { return 500; }
|
||||
static_assert(DIFFICULTY_WINDOW >= 2, "Window is too small");
|
||||
assert(length <= DIFFICULTY_WINDOW);
|
||||
sort(timestamps.begin(), timestamps.end());
|
||||
@@ -257,21 +258,18 @@ namespace cryptonote {
|
||||
// LWMA difficulty algorithm
|
||||
// Background: https://github.com/zawy12/difficulty-algorithms/issues/3
|
||||
// Copyright (c) 2017-2018 Zawy
|
||||
difficulty_type next_difficulty_v2(std::vector<std::uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT) {
|
||||
difficulty_type next_difficulty_v2(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds) {
|
||||
|
||||
const int64_t T = static_cast<int64_t>(target_seconds);
|
||||
size_t N = DIFFICULTY_WINDOW_V2;
|
||||
if (m_nettype == MAINNET) {
|
||||
if (timestamps.size() < 4) {
|
||||
return 1;
|
||||
} else if ( timestamps.size() < N+1 ) {
|
||||
N = timestamps.size() - 1;
|
||||
} else {
|
||||
timestamps.resize(N+1);
|
||||
cumulative_difficulties.resize(N+1);
|
||||
}
|
||||
if (timestamps.size() < 4) {
|
||||
return 1;
|
||||
} else if ( timestamps.size() < N+1 ) {
|
||||
N = timestamps.size() - 1;
|
||||
} else {
|
||||
timestamps.resize(N+1);
|
||||
cumulative_difficulties.resize(N+1);
|
||||
}
|
||||
if (HEIGHT < 200 && m_nettype == TESTNET) { return 500; }
|
||||
const double adjust = 0.998;
|
||||
const double k = N * (N + 1) / 2;
|
||||
double LWMA(0), sum_inverse_D(0), harmonic_mean_D(0), nextDifficulty(0);
|
||||
@@ -294,13 +292,12 @@ namespace cryptonote {
|
||||
}
|
||||
|
||||
// LWMA-2
|
||||
difficulty_type next_difficulty_v3(std::vector<uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT) {
|
||||
difficulty_type next_difficulty_v3(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties) {
|
||||
|
||||
int64_t T = DIFFICULTY_TARGET_V2;
|
||||
int64_t N = DIFFICULTY_WINDOW_V2;
|
||||
int64_t L(0), ST, sum_3_ST(0), next_D, prev_D;
|
||||
assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= static_cast<uint64_t>(N+1) );
|
||||
if (HEIGHT < 200 && m_nettype == TESTNET) { return 500; }
|
||||
for ( int64_t i = 1; i <= N; i++ ) {
|
||||
ST = static_cast<int64_t>(timestamps[i]) - static_cast<int64_t>(timestamps[i-1]);
|
||||
ST = std::max(-4*T, std::min(ST, 6*T));
|
||||
@@ -319,14 +316,13 @@ namespace cryptonote {
|
||||
}
|
||||
|
||||
// LWMA-4
|
||||
difficulty_type next_difficulty_v4(std::vector<uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT) {
|
||||
difficulty_type next_difficulty_v4(std::vector<uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t height) {
|
||||
|
||||
uint64_t T = DIFFICULTY_TARGET_V2;
|
||||
uint64_t N = DIFFICULTY_WINDOW_V2;
|
||||
uint64_t L(0), ST(0), next_D, prev_D, avg_D, i;
|
||||
assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 );
|
||||
if (HEIGHT <= 63469 + 1 && m_nettype == MAINNET) { return 100000069; }
|
||||
if (HEIGHT < 200 && m_nettype == TESTNET) { return 500; }
|
||||
if ( height <= 63469 + 1 ) { return 100000069; }
|
||||
std::vector<uint64_t>TS(N+1);
|
||||
TS[0] = timestamps[0];
|
||||
for ( i = 1; i <= N; i++) {
|
||||
@@ -368,11 +364,44 @@ namespace cryptonote {
|
||||
// LWMA-1 difficulty algorithm
|
||||
// Copyright (c) 2017-2019 Zawy, MIT License
|
||||
// https://github.com/zawy12/difficulty-algorithms/issues/3
|
||||
difficulty_type next_difficulty_v5(std::vector<std::uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT) {
|
||||
difficulty_type next_difficulty_v5(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT) {
|
||||
assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 );
|
||||
|
||||
if (HEIGHT >= 81769 && HEIGHT < 81769 + N && m_nettype == MAINNET) { return 10000000; }
|
||||
if (HEIGHT < 200 && m_nettype == TESTNET) { return 500; }
|
||||
if (HEIGHT >= 81769 && HEIGHT < 81769 + N) { return 10000000; }
|
||||
assert(timestamps.size() == N+1);
|
||||
|
||||
uint64_t L(0), next_D, i, this_timestamp(0), previous_timestamp(0), avg_D;
|
||||
|
||||
previous_timestamp = timestamps[0]-T;
|
||||
for ( i = 1; i <= N; i++) {
|
||||
// Safely prevent out-of-sequence timestamps
|
||||
if ( timestamps[i] > previous_timestamp ) { this_timestamp = timestamps[i]; }
|
||||
else { this_timestamp = previous_timestamp+1; }
|
||||
L += i*std::min(6*T ,this_timestamp - previous_timestamp);
|
||||
previous_timestamp = this_timestamp;
|
||||
}
|
||||
if (L < N*N*T/20 ) { L = N*N*T/20; }
|
||||
avg_D = static_cast<uint64_t>(( cumulative_difficulties[N] - cumulative_difficulties[0] )/ N);
|
||||
|
||||
// Prevent round off error for small D and overflow for large D.
|
||||
if (avg_D > 2000000*N*N*T) {
|
||||
next_D = (avg_D/(200*L))*(N*(N+1)*T*99);
|
||||
}
|
||||
else { next_D = (avg_D*N*(N+1)*T*99)/(200*L); }
|
||||
|
||||
// Make all insignificant digits zero for easy reading.
|
||||
i = 1000000000;
|
||||
while (i > 1) {
|
||||
if ( next_D > i*100 ) { next_D = ((next_D+i/2)/i)*i; break; }
|
||||
else { i /= 10; }
|
||||
}
|
||||
return next_D;
|
||||
}
|
||||
|
||||
difficulty_type next_difficulty_test(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT) {
|
||||
assert(timestamps.size() == cumulative_difficulties.size() && timestamps.size() <= N+1 );
|
||||
|
||||
if (HEIGHT < N) { return 1337; }
|
||||
assert(timestamps.size() == N+1);
|
||||
|
||||
uint64_t L(0), next_D, i, this_timestamp(0), previous_timestamp(0), avg_D;
|
||||
|
||||
@@ -57,11 +57,12 @@ namespace cryptonote
|
||||
|
||||
bool check_hash_128(const crypto::hash &hash, difficulty_type difficulty);
|
||||
bool check_hash(const crypto::hash &hash, difficulty_type difficulty);
|
||||
difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_v2(std::vector<std::uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_v3(std::vector<std::uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_v4(std::vector<std::uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_v5(std::vector<std::uint64_t> timestamps, network_type m_nettype, std::vector<difficulty_type> cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
|
||||
difficulty_type next_difficulty_v2(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t target_seconds);
|
||||
difficulty_type next_difficulty_v3(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties);
|
||||
difficulty_type next_difficulty_v4(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, size_t height);
|
||||
difficulty_type next_difficulty_v5(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT);
|
||||
difficulty_type next_difficulty_test(std::vector<std::uint64_t> timestamps, std::vector<difficulty_type> cumulative_difficulties, uint64_t T, uint64_t N, uint64_t HEIGHT);
|
||||
|
||||
std::string hex(difficulty_type v);
|
||||
}
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
// Copyright (c) 2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
struct block;
|
||||
class transaction;
|
||||
struct txpool_event;
|
||||
}
|
||||
@@ -169,9 +169,7 @@ namespace cryptonote
|
||||
extra_nonce = m_extra_messages[m_config.current_extra_message_index];
|
||||
}
|
||||
|
||||
uint64_t seed_height;
|
||||
crypto::hash seed_hash;
|
||||
if(!m_phandler->get_block_template(bl, m_mine_address, di, height, expected_reward, extra_nonce, seed_height, seed_hash))
|
||||
if(!m_phandler->get_block_template(bl, m_mine_address, di, height, expected_reward, extra_nonce))
|
||||
{
|
||||
LOG_ERROR("Failed to get_block_template(), stopping mining");
|
||||
return false;
|
||||
@@ -473,12 +471,12 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------------
|
||||
bool miner::find_nonce_for_given_block(const get_block_hash_t &gbh, block& bl, const difficulty_type& diffic, uint64_t height, const crypto::hash *seed_hash)
|
||||
bool miner::find_nonce_for_given_block(const get_block_hash_t &gbh, block& bl, const difficulty_type& diffic, uint64_t height)
|
||||
{
|
||||
for(; bl.nonce != std::numeric_limits<uint32_t>::max(); bl.nonce++)
|
||||
{
|
||||
crypto::hash h;
|
||||
gbh(bl, height, seed_hash, diffic <= 100 ? 0 : tools::get_max_concurrency(), h);
|
||||
gbh(bl, height, diffic <= 100 ? 0 : tools::get_max_concurrency(), h);
|
||||
|
||||
if(check_hash(h, diffic))
|
||||
{
|
||||
@@ -574,7 +572,7 @@ namespace cryptonote
|
||||
|
||||
b.nonce = nonce;
|
||||
crypto::hash h;
|
||||
m_gbh(b, height, NULL, tools::get_max_concurrency(), h);
|
||||
m_gbh(b, height, tools::get_max_concurrency(), h);
|
||||
|
||||
if(check_hash(h, local_diff))
|
||||
{
|
||||
|
||||
@@ -47,12 +47,12 @@ namespace cryptonote
|
||||
struct i_miner_handler
|
||||
{
|
||||
virtual bool handle_block_found(block& b, block_verification_context &bvc) = 0;
|
||||
virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash) = 0;
|
||||
virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce) = 0;
|
||||
protected:
|
||||
~i_miner_handler(){};
|
||||
};
|
||||
|
||||
typedef std::function<bool(const cryptonote::block&, uint64_t, const crypto::hash*, unsigned int, crypto::hash&)> get_block_hash_t;
|
||||
typedef std::function<bool(const cryptonote::block&, uint64_t, unsigned int, crypto::hash&)> get_block_hash_t;
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
@@ -76,7 +76,7 @@ namespace cryptonote
|
||||
bool on_idle();
|
||||
void on_synchronized();
|
||||
//synchronous analog (for fast calls)
|
||||
static bool find_nonce_for_given_block(const get_block_hash_t &gbh, block& bl, const difficulty_type& diffic, uint64_t height, const crypto::hash *seed_hash = NULL);
|
||||
static bool find_nonce_for_given_block(const get_block_hash_t &gbh, block& bl, const difficulty_type& diffic, uint64_t height);
|
||||
void pause();
|
||||
void resume();
|
||||
void do_print_hashrate(bool do_hr);
|
||||
@@ -91,16 +91,17 @@ namespace cryptonote
|
||||
uint64_t get_block_reward() const { return m_block_reward; }
|
||||
|
||||
static constexpr uint8_t BACKGROUND_MINING_DEFAULT_IDLE_THRESHOLD_PERCENTAGE = 90;
|
||||
static constexpr uint8_t BACKGROUND_MINING_MIN_IDLE_THRESHOLD_PERCENTAGE = 0;
|
||||
static constexpr uint8_t BACKGROUND_MINING_MIN_IDLE_THRESHOLD_PERCENTAGE = 50;
|
||||
static constexpr uint8_t BACKGROUND_MINING_MAX_IDLE_THRESHOLD_PERCENTAGE = 99;
|
||||
static constexpr uint16_t BACKGROUND_MINING_DEFAULT_MIN_IDLE_INTERVAL_IN_SECONDS = 10;
|
||||
static constexpr uint16_t BACKGROUND_MINING_MIN_MIN_IDLE_INTERVAL_IN_SECONDS = 10;
|
||||
static constexpr uint16_t BACKGROUND_MINING_MAX_MIN_IDLE_INTERVAL_IN_SECONDS = 3600;
|
||||
static constexpr uint8_t BACKGROUND_MINING_DEFAULT_MINING_TARGET_PERCENTAGE = 40;
|
||||
static constexpr uint8_t BACKGROUND_MINING_MIN_MINING_TARGET_PERCENTAGE = 1;
|
||||
static constexpr uint8_t BACKGROUND_MINING_MAX_MINING_TARGET_PERCENTAGE = 100;
|
||||
static constexpr uint8_t BACKGROUND_MINING_MIN_MINING_TARGET_PERCENTAGE = 5;
|
||||
static constexpr uint8_t BACKGROUND_MINING_MAX_MINING_TARGET_PERCENTAGE = 50;
|
||||
static constexpr uint8_t BACKGROUND_MINING_MINER_MONITOR_INVERVAL_IN_SECONDS = 10;
|
||||
static constexpr uint64_t BACKGROUND_MINING_DEFAULT_MINER_EXTRA_SLEEP_MILLIS = 400; // ramp up
|
||||
static constexpr uint64_t BACKGROUND_MINING_MIN_MINER_EXTRA_SLEEP_MILLIS = 5;
|
||||
|
||||
private:
|
||||
bool worker_thread();
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#define CRYPTONOTE_DNS_TIMEOUT_MS 20000
|
||||
|
||||
#define CRYPTONOTE_MAX_BLOCK_NUMBER 500000000
|
||||
#define CRYPTONOTE_GETBLOCKTEMPLATE_MAX_BLOCK_SIZE 196608 //size of block (bytes) that is the maximum that miners will produce
|
||||
#define CRYPTONOTE_MAX_TX_SIZE 1000000
|
||||
#define CRYPTONOTE_MAX_TX_PER_BLOCK 0x10000000
|
||||
#define CRYPTONOTE_PUBLIC_ADDRESS_TEXTBLOB_VER 0
|
||||
@@ -120,11 +121,6 @@
|
||||
#define CRYPTONOTE_NOISE_BYTES 3*1024 // 3 KiB
|
||||
#define CRYPTONOTE_NOISE_CHANNELS 2 // Max outgoing connections per zone used for noise/covert sending
|
||||
|
||||
// Both below are in seconds. The idea is to delay forwarding from i2p/tor
|
||||
// to ipv4/6, such that 2+ incoming connections _could_ have sent the tx
|
||||
#define CRYPTONOTE_FORWARD_DELAY_BASE (CRYPTONOTE_NOISE_MIN_DELAY + CRYPTONOTE_NOISE_DELAY_RANGE)
|
||||
#define CRYPTONOTE_FORWARD_DELAY_AVERAGE (CRYPTONOTE_FORWARD_DELAY_BASE + (CRYPTONOTE_FORWARD_DELAY_BASE / 2))
|
||||
|
||||
#define CRYPTONOTE_MAX_FRAGMENTS 20 // ~20 * NOISE_BYTES max payload size for covert/noise send
|
||||
|
||||
#define COMMAND_RPC_GET_BLOCKS_FAST_MAX_COUNT 1000
|
||||
@@ -181,9 +177,6 @@
|
||||
#define HF_VERSION_REJECT_SIGS_IN_COINBASE 15
|
||||
#define HF_VERSION_ENFORCE_MIN_AGE 15
|
||||
#define HF_VERSION_EFFECTIVE_SHORT_TERM_MEDIAN_IN_PENALTY 15
|
||||
#define HF_VERSION_EXACT_COINBASE 16
|
||||
#define HF_VERSION_CLSAG 16
|
||||
#define HF_VERSION_DETERMINISTIC_UNLOCK_TIME 16
|
||||
#define HF_VERSION_DYNAMIC_UNLOCK 16
|
||||
|
||||
#define PER_KB_FEE_QUANTIZATION_DECIMALS 8
|
||||
@@ -231,11 +224,6 @@ namespace config
|
||||
const unsigned char HASH_KEY_RPC_PAYMENT_NONCE = 0x58;
|
||||
const unsigned char HASH_KEY_MEMORY = 'k';
|
||||
const unsigned char HASH_KEY_MULTISIG[] = {'M', 'u', 'l', 't' , 'i', 's', 'i', 'g', 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
const unsigned char HASH_KEY_TXPROOF_V2[] = "TXPROOF_V2";
|
||||
const unsigned char HASH_KEY_CLSAG_ROUND[] = "CLSAG_round";
|
||||
const unsigned char HASH_KEY_CLSAG_AGG_0[] = "CLSAG_agg_0";
|
||||
const unsigned char HASH_KEY_CLSAG_AGG_1[] = "CLSAG_agg_1";
|
||||
const char HASH_KEY_MESSAGE_SIGNING[] = "MoneroMessageSignature";
|
||||
|
||||
namespace testnet
|
||||
{
|
||||
|
||||
@@ -861,11 +861,11 @@ start:
|
||||
uint64_t height;
|
||||
auto new_top_hash = get_tail_id(height); // get it again now that we have the lock
|
||||
++height;
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t difficulty_blocks_count = version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
if (!(new_top_hash == top_hash)) D=0;
|
||||
ss << "Re-locked, height " << height << ", tail id " << new_top_hash << (new_top_hash == top_hash ? "" : " (different)") << std::endl;
|
||||
top_hash = new_top_hash;
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t difficulty_blocks_count = version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
|
||||
// ND: Speedup
|
||||
// 1. Keep a list of the last 735 (or less) blocks that is used to compute difficulty,
|
||||
@@ -946,31 +946,37 @@ start:
|
||||
uint64_t N = DIFFICULTY_WINDOW_V3;
|
||||
uint64_t HEIGHT = m_db->height();
|
||||
|
||||
difficulty_type diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT);
|
||||
difficulty_type diff = next_difficulty(timestamps, difficulties, target);
|
||||
|
||||
if (version >= 11) {
|
||||
diff = next_difficulty_v5(timestamps, m_nettype, difficulties, T, N, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
diff = next_difficulty_v4(timestamps, m_nettype, difficulties, HEIGHT);
|
||||
} else if (version == 9) {
|
||||
diff = next_difficulty_v3(timestamps, m_nettype, difficulties, HEIGHT);
|
||||
} else if (version == 8) {
|
||||
diff = next_difficulty_v2(timestamps, m_nettype, difficulties, target, HEIGHT);
|
||||
} else {
|
||||
diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT);
|
||||
if (m_nettype == MAINNET) {
|
||||
if (version >= 11) {
|
||||
diff = next_difficulty_v5(timestamps, difficulties, T, N, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
diff = next_difficulty_v4(timestamps, difficulties, height);
|
||||
} else if (version == 9) {
|
||||
diff = next_difficulty_v3(timestamps, difficulties);
|
||||
} else if (version == 8) {
|
||||
diff = next_difficulty_v2(timestamps, difficulties, target);
|
||||
} else {
|
||||
diff = next_difficulty(timestamps, difficulties, target);
|
||||
}
|
||||
}
|
||||
|
||||
if (m_nettype == TESTNET) {
|
||||
diff = next_difficulty_test(timestamps, difficulties, T, N, HEIGHT);
|
||||
}
|
||||
|
||||
CRITICAL_REGION_LOCAL1(m_difficulty_lock);
|
||||
m_difficulty_for_next_block_top_hash = top_hash;
|
||||
m_difficulty_for_next_block = diff;
|
||||
if (D && D != diff && m_nettype == MAINNET)
|
||||
if (D && D != diff)
|
||||
{
|
||||
ss << "XXX Mismatch at " << height << "/" << top_hash << "/" << get_tail_id() << ": cached " << D << ", real " << diff << std::endl;
|
||||
print = true;
|
||||
}
|
||||
|
||||
++done;
|
||||
if (done == 1 && D && D != diff && m_nettype == MAINNET)
|
||||
if (done == 1 && D && D != diff)
|
||||
{
|
||||
print = true;
|
||||
ss << "Might be a race. Let's see what happens if we try again..." << std::endl;
|
||||
@@ -978,12 +984,12 @@ start:
|
||||
goto start;
|
||||
}
|
||||
ss << "Diff for " << top_hash << ": " << diff << std::endl;
|
||||
if (print && m_nettype == MAINNET)
|
||||
if (print)
|
||||
{
|
||||
MGINFO("START DUMP");
|
||||
MGINFO(ss.str());
|
||||
MGINFO("END DUMP");
|
||||
MGINFO("Please send wowario on Freenode #wownero-dev the contents of this log, from a couple dozen lines before START DUMP to END DUMP");
|
||||
MGINFO("Please send moneromooo on Freenode the contents of this log, from a couple dozen lines before START DUMP to END DUMP");
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
@@ -1014,15 +1020,14 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
||||
const uint64_t start_height = start_height_opt ? *start_height_opt : check_difficulty_checkpoints().second;
|
||||
const uint64_t top_height = m_db->height() - 1;
|
||||
MGINFO("Recalculating difficulties from height " << start_height << " to height " << top_height);
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t difficulty_blocks_count = version >= 11 ? DIFFICULTY_BLOCKS_COUNT_V3 : version <= 10 && version >= 8 ? DIFFICULTY_BLOCKS_COUNT_V2 : DIFFICULTY_BLOCKS_COUNT;
|
||||
|
||||
std::vector<uint64_t> timestamps;
|
||||
std::vector<difficulty_type> difficulties;
|
||||
timestamps.reserve(difficulty_blocks_count + 1);
|
||||
difficulties.reserve(difficulty_blocks_count + 1);
|
||||
timestamps.reserve(DIFFICULTY_BLOCKS_COUNT + 1);
|
||||
difficulties.reserve(DIFFICULTY_BLOCKS_COUNT + 1);
|
||||
if (start_height > 1)
|
||||
{
|
||||
for (uint64_t i = 0; i < difficulty_blocks_count; ++i)
|
||||
for (uint64_t i = 0; i < DIFFICULTY_BLOCKS_COUNT; ++i)
|
||||
{
|
||||
uint64_t height = start_height - 1 - i;
|
||||
if (height == 0)
|
||||
@@ -1036,24 +1041,8 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
||||
std::vector<difficulty_type> new_cumulative_difficulties;
|
||||
for (uint64_t height = start_height; height <= top_height; ++height)
|
||||
{
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t T = DIFFICULTY_TARGET_V2;
|
||||
uint64_t N = DIFFICULTY_WINDOW_V3;
|
||||
uint64_t HEIGHT = m_db->height();
|
||||
size_t target = get_ideal_hard_fork_version(height) < 2 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2;
|
||||
difficulty_type recalculated_diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT);
|
||||
|
||||
if (version >= 11) {
|
||||
recalculated_diff = next_difficulty_v5(timestamps, m_nettype, difficulties, T, N, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
recalculated_diff = next_difficulty_v4(timestamps, m_nettype, difficulties, HEIGHT);
|
||||
} else if (version == 9) {
|
||||
recalculated_diff = next_difficulty_v3(timestamps, m_nettype, difficulties, HEIGHT);
|
||||
} else if (version == 8) {
|
||||
recalculated_diff = next_difficulty_v2(timestamps, m_nettype, difficulties, target, HEIGHT);
|
||||
} else {
|
||||
recalculated_diff = next_difficulty(timestamps, m_nettype, difficulties, target, HEIGHT);
|
||||
}
|
||||
difficulty_type recalculated_diff = next_difficulty(timestamps, difficulties, target);
|
||||
|
||||
boost::multiprecision::uint256_t recalculated_cum_diff_256 = boost::multiprecision::uint256_t(recalculated_diff) + last_cum_diff;
|
||||
CHECK_AND_ASSERT_THROW_MES(recalculated_cum_diff_256 <= std::numeric_limits<difficulty_type>::max(), "Difficulty overflow!");
|
||||
@@ -1081,9 +1070,9 @@ size_t Blockchain::recalculate_difficulties(boost::optional<uint64_t> start_heig
|
||||
timestamps.push_back(m_db->get_block_timestamp(height));
|
||||
difficulties.push_back(recalculated_cum_diff);
|
||||
}
|
||||
if (timestamps.size() > difficulty_blocks_count)
|
||||
if (timestamps.size() > DIFFICULTY_BLOCKS_COUNT)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(timestamps.size() == difficulty_blocks_count + 1, "Wrong timestamps size: " << timestamps.size());
|
||||
CHECK_AND_ASSERT_THROW_MES(timestamps.size() == DIFFICULTY_BLOCKS_COUNT + 1, "Wrong timestamps size: " << timestamps.size());
|
||||
timestamps.erase(timestamps.begin());
|
||||
difficulties.erase(difficulties.begin());
|
||||
}
|
||||
@@ -1269,15 +1258,10 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info>
|
||||
reorg_notify->notify("%s", std::to_string(split_height).c_str(), "%h", std::to_string(m_db->height()).c_str(),
|
||||
"%n", std::to_string(m_db->height() - split_height).c_str(), "%d", std::to_string(discarded_blocks).c_str(), NULL);
|
||||
|
||||
for (const auto& notifier : m_block_notifiers)
|
||||
{
|
||||
std::size_t notify_height = split_height;
|
||||
for (const auto& bei: alt_chain)
|
||||
{
|
||||
notifier(notify_height, {std::addressof(bei.bl), 1});
|
||||
++notify_height;
|
||||
}
|
||||
}
|
||||
std::shared_ptr<tools::Notify> block_notify = m_block_notify;
|
||||
if (block_notify)
|
||||
for (const auto &bei: alt_chain)
|
||||
block_notify->notify("%s", epee::string_tools::pod_to_hex(get_block_hash(bei.bl)).c_str(), NULL);
|
||||
|
||||
MGINFO_GREEN("REORGANIZE SUCCESS! on height: " << split_height << ", new blockchain size: " << m_db->height());
|
||||
return true;
|
||||
@@ -1340,7 +1324,7 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
||||
size_t count = 0;
|
||||
size_t max_i = timestamps.size()-1;
|
||||
// get difficulties and timestamps from most recent blocks in alt chain
|
||||
for (const auto &bei: boost::adaptors::reverse(alt_chain))
|
||||
for (const auto bei: boost::adaptors::reverse(alt_chain))
|
||||
{
|
||||
timestamps[max_i - count] = bei.bl.timestamp;
|
||||
cumulative_difficulties[max_i - count] = bei.cumulative_difficulty;
|
||||
@@ -1357,18 +1341,24 @@ difficulty_type Blockchain::get_next_difficulty_for_alternative_chain(const std:
|
||||
uint64_t HEIGHT = m_db->height();
|
||||
|
||||
// calculate the difficulty target for the block and return it
|
||||
if (version >= 11) {
|
||||
return next_difficulty_v5(timestamps, m_nettype, cumulative_difficulties, T, N, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
return next_difficulty_v4(timestamps, m_nettype, cumulative_difficulties, HEIGHT);
|
||||
} else if (version == 9) {
|
||||
return next_difficulty_v3(timestamps, m_nettype, cumulative_difficulties, HEIGHT);
|
||||
} else if (version == 8) {
|
||||
return next_difficulty_v2(timestamps, m_nettype, cumulative_difficulties, target, HEIGHT);
|
||||
} else {
|
||||
return next_difficulty(timestamps, m_nettype, cumulative_difficulties, target, HEIGHT);
|
||||
if (m_nettype == MAINNET) {
|
||||
if (version >= 11) {
|
||||
return next_difficulty_v5(timestamps, cumulative_difficulties, T, N, HEIGHT);
|
||||
} else if (version == 10) {
|
||||
return next_difficulty_v4(timestamps, cumulative_difficulties, height);
|
||||
} else if (version == 9) {
|
||||
return next_difficulty_v3(timestamps, cumulative_difficulties);
|
||||
} else if (version == 8) {
|
||||
return next_difficulty_v2(timestamps, cumulative_difficulties, target);
|
||||
} else {
|
||||
return next_difficulty(timestamps, cumulative_difficulties, target);
|
||||
}
|
||||
}
|
||||
return next_difficulty(timestamps, m_nettype, cumulative_difficulties, target, HEIGHT);
|
||||
|
||||
if (m_nettype == TESTNET) {
|
||||
return next_difficulty_test(timestamps, cumulative_difficulties, T, N, HEIGHT);
|
||||
}
|
||||
return next_difficulty(timestamps, cumulative_difficulties, target);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
// This function does a sanity check on basic things that all miner
|
||||
@@ -1403,8 +1393,7 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height,
|
||||
// unlock time = unlock_window + height
|
||||
if (hf_version >= HF_VERSION_DYNAMIC_UNLOCK)
|
||||
{
|
||||
uint64_t N = m_nettype == MAINNET ? 1337 : 5;
|
||||
crypto::hash blk_id = get_block_id_by_height(height-N);
|
||||
crypto::hash blk_id = get_block_id_by_height(height-1337);
|
||||
std::string hex_str = epee::string_tools::pod_to_hex(blk_id).substr(0, 3);
|
||||
uint64_t blk_num = std::stol(hex_str,nullptr,16)*2;
|
||||
uint64_t unlock_window = blk_num + 288;
|
||||
@@ -1415,7 +1404,7 @@ bool Blockchain::prevalidate_miner_transaction(const block& b, uint64_t height,
|
||||
}
|
||||
LOG_PRINT_L1("+++++ MINER TX UNLOCK TIME INFO" <<
|
||||
"\nHeight: " << height << ", Unlock window: " << unlock_window << ", Unlock time: " << b.miner_tx.unlock_time <<
|
||||
"\nblk_height: " << height-N << ", blk_id: " << blk_id <<
|
||||
"\nblk_height: " << height-1337 << ", blk_id: " << blk_id <<
|
||||
"\nhex_str: " << hex_str << ", blk_num: " << blk_num);
|
||||
} else {
|
||||
CHECK_AND_ASSERT_MES(b.miner_tx.unlock_time == height + 60, false, "coinbase transaction transaction has the wrong unlock time="
|
||||
@@ -1475,8 +1464,8 @@ bool Blockchain::validate_miner_transaction(const block& b, size_t cumulative_bl
|
||||
MERROR_VER("coinbase transaction spend too much money (" << print_money(money_in_use) << "). Block reward is " << print_money(base_reward + fee) << "(" << print_money(base_reward) << "+" << print_money(fee) << "), cumulative_block_weight " << cumulative_block_weight);
|
||||
return false;
|
||||
}
|
||||
// From hard fork 2 till 12, we allow a miner to claim less block reward than is allowed, in case a miner wants less dust
|
||||
if (version < 2 || version >= HF_VERSION_EXACT_COINBASE)
|
||||
// From hard fork 2, we allow a miner to claim less block reward than is allowed, in case a miner wants less dust
|
||||
if (version < 2)
|
||||
{
|
||||
if(base_reward + fee != money_in_use)
|
||||
{
|
||||
@@ -1584,15 +1573,13 @@ uint64_t Blockchain::get_current_cumulative_block_weight_median() const
|
||||
// in a lot of places. That flag is not referenced in any of the code
|
||||
// nor any of the makefiles, howeve. Need to look into whether or not it's
|
||||
// necessary at all.
|
||||
bool Blockchain::create_block_template(block& b, const crypto::hash *from_block, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash)
|
||||
bool Blockchain::create_block_template(block& b, const crypto::hash *from_block, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce)
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
size_t median_weight;
|
||||
uint64_t already_generated_coins;
|
||||
uint64_t pool_cookie;
|
||||
|
||||
seed_hash = crypto::null_hash;
|
||||
|
||||
m_tx_pool.lock();
|
||||
const auto unlock_guard = epee::misc_utils::create_scope_leave_handler([&]() { m_tx_pool.unlock(); });
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
@@ -1611,8 +1598,6 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
diffic = m_btc_difficulty;
|
||||
height = m_btc_height;
|
||||
expected_reward = m_btc_expected_reward;
|
||||
seed_height = m_btc_seed_height;
|
||||
seed_hash = m_btc_seed_hash;
|
||||
return true;
|
||||
}
|
||||
MDEBUG("Not using cached template: address " << (!memcmp(&miner_address, &m_btc_address, sizeof(cryptonote::account_public_address))) << ", nonce " << (m_btc_nonce == ex_nonce) << ", cookie " << (m_btc_pool_cookie == m_tx_pool.cookie()) << ", from_block " << (!!from_block));
|
||||
@@ -1646,34 +1631,10 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
CHECK_AND_ASSERT_MES(get_block_by_hash(*from_block, prev_block), false, "From block not found"); // TODO
|
||||
uint64_t from_block_height = cryptonote::get_block_height(prev_block);
|
||||
height = from_block_height + 1;
|
||||
if (m_hardfork->get_current_version() >= RX_BLOCK_VERSION)
|
||||
{
|
||||
uint64_t next_height;
|
||||
crypto::rx_seedheights(height, &seed_height, &next_height);
|
||||
seed_hash = get_block_id_by_height(seed_height);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
height = alt_chain.back().height + 1;
|
||||
uint64_t next_height;
|
||||
crypto::rx_seedheights(height, &seed_height, &next_height);
|
||||
|
||||
if (alt_chain.size() && alt_chain.front().height <= seed_height)
|
||||
{
|
||||
for (auto it=alt_chain.begin(); it != alt_chain.end(); it++)
|
||||
{
|
||||
if (it->height == seed_height+1)
|
||||
{
|
||||
seed_hash = it->bl.prev_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
seed_hash = get_block_id_by_height(seed_height);
|
||||
}
|
||||
}
|
||||
b.major_version = m_hardfork->get_ideal_version(height);
|
||||
b.minor_version = m_hardfork->get_ideal_version();
|
||||
@@ -1708,12 +1669,6 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
median_weight = m_current_block_cumul_weight_limit / 2;
|
||||
diffic = get_difficulty_for_next_block();
|
||||
already_generated_coins = m_db->get_block_already_generated_coins(height - 1);
|
||||
if (m_hardfork->get_current_version() >= RX_BLOCK_VERSION)
|
||||
{
|
||||
uint64_t next_height;
|
||||
crypto::rx_seedheights(height, &seed_height, &next_height);
|
||||
seed_hash = get_block_id_by_height(seed_height);
|
||||
}
|
||||
}
|
||||
b.timestamp = time(NULL);
|
||||
|
||||
@@ -1792,7 +1747,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
//make blocks coin-base tx looks close to real coinbase tx to get truthful blob weight
|
||||
uint8_t hf_version = b.major_version;
|
||||
size_t max_outs = hf_version >= 4 ? 1 : 11;
|
||||
bool r = construct_miner_tx(this, m_nettype, height, median_weight, already_generated_coins, txs_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
bool r = construct_miner_tx(this, height, median_weight, already_generated_coins, txs_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to construct miner tx, first chance");
|
||||
size_t cumulative_weight = txs_weight + get_transaction_weight(b.miner_tx);
|
||||
#if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
|
||||
@@ -1801,7 +1756,7 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
#endif
|
||||
for (size_t try_count = 0; try_count != 10; ++try_count)
|
||||
{
|
||||
r = construct_miner_tx(this, m_nettype, height, median_weight, already_generated_coins, cumulative_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
r = construct_miner_tx(this, height, median_weight, already_generated_coins, cumulative_weight, fee, miner_address, b.miner_tx, ex_nonce, max_outs, hf_version);
|
||||
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to construct miner tx, second chance");
|
||||
size_t coinbase_weight = get_transaction_weight(b.miner_tx);
|
||||
@@ -1846,16 +1801,16 @@ bool Blockchain::create_block_template(block& b, const crypto::hash *from_block,
|
||||
#endif
|
||||
|
||||
if (!from_block)
|
||||
cache_block_template(b, miner_address, ex_nonce, diffic, height, expected_reward, seed_height, seed_hash, pool_cookie);
|
||||
cache_block_template(b, miner_address, ex_nonce, diffic, height, expected_reward, pool_cookie);
|
||||
return true;
|
||||
}
|
||||
LOG_ERROR("Failed to create_block_template with " << 10 << " tries");
|
||||
return false;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::create_block_template(block& b, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash)
|
||||
bool Blockchain::create_block_template(block& b, const account_public_address& miner_address, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce)
|
||||
{
|
||||
return create_block_template(b, NULL, miner_address, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash);
|
||||
return create_block_template(b, NULL, miner_address, diffic, height, expected_reward, ex_nonce);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
// for an alternate chain, get the timestamps from the main chain to complete
|
||||
@@ -2271,7 +2226,7 @@ bool Blockchain::get_alternative_blocks(std::vector<block>& blocks) const
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
|
||||
blocks.reserve(m_db->get_alt_block_count());
|
||||
m_db->for_all_alt_blocks([&blocks](const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata_ref *blob) {
|
||||
m_db->for_all_alt_blocks([&blocks](const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata *blob) {
|
||||
if (!blob)
|
||||
{
|
||||
MERROR("No blob, but blobs were requested");
|
||||
@@ -2346,9 +2301,8 @@ bool Blockchain::get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMA
|
||||
MERROR("Unexpected output data size: expected " << req.outputs.size() << ", got " << data.size());
|
||||
return false;
|
||||
}
|
||||
const uint8_t hf_version = m_hardfork->get_current_version();
|
||||
for (const auto &t: data)
|
||||
res.outs.push_back({t.pubkey, t.commitment, is_tx_spendtime_unlocked(t.unlock_time, hf_version), t.height, crypto::null_hash});
|
||||
res.outs.push_back({t.pubkey, t.commitment, is_tx_spendtime_unlocked(t.unlock_time), t.height, crypto::null_hash});
|
||||
|
||||
if (req.get_txid)
|
||||
{
|
||||
@@ -2372,8 +2326,7 @@ void Blockchain::get_output_key_mask_unlocked(const uint64_t& amount, const uint
|
||||
key = o_data.pubkey;
|
||||
mask = o_data.commitment;
|
||||
tx_out_index toi = m_db->get_output_tx_and_index(amount, index);
|
||||
const uint8_t hf_version = m_hardfork->get_current_version();
|
||||
unlocked = is_tx_spendtime_unlocked(m_db->get_tx_unlock_time(toi.first), hf_version);
|
||||
unlocked = is_tx_spendtime_unlocked(m_db->get_tx_unlock_time(toi.first));
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::get_output_distribution(uint64_t amount, uint64_t from_height, uint64_t to_height, uint64_t &start_height, std::vector<uint64_t> &distribution, uint64_t &base) const
|
||||
@@ -3086,7 +3039,7 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
||||
const bool bulletproof = rct::is_rct_bulletproof(tx.rct_signatures.type);
|
||||
if (bulletproof || !tx.rct_signatures.p.bulletproofs.empty())
|
||||
{
|
||||
MERROR_VER("Bulletproofs are not allowed before v8");
|
||||
MERROR_VER("New Bulletproofs are not allowed before v8");
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
@@ -3130,30 +3083,6 @@ bool Blockchain::check_tx_outputs(const transaction& tx, tx_verification_context
|
||||
}
|
||||
}
|
||||
|
||||
// from v16, allow CLSAGs
|
||||
if (hf_version < HF_VERSION_CLSAG) {
|
||||
if (tx.version >= 2) {
|
||||
if (tx.rct_signatures.type == rct::RCTTypeCLSAG)
|
||||
{
|
||||
MERROR_VER("Ringct type " << (unsigned)rct::RCTTypeCLSAG << " is not allowed before v" << HF_VERSION_CLSAG);
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// from v17, allow only CLSAGs
|
||||
if (hf_version > HF_VERSION_CLSAG) {
|
||||
if (tx.version >= 2) {
|
||||
if (tx.rct_signatures.type <= rct::RCTTypeBulletproof2)
|
||||
{
|
||||
MERROR_VER("Ringct type " << (unsigned)tx.rct_signatures.type << " is not allowed from v" << (HF_VERSION_CLSAG + 1));
|
||||
tvc.m_invalid_output = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// from v12, forbid old bulletproofs
|
||||
if (hf_version > 11) {
|
||||
if (tx.version >= 2) {
|
||||
@@ -3207,7 +3136,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeSimpleBulletproof || rv.type == rct::RCTTypeCLSAG)
|
||||
else if (rv.type == rct::RCTTypeSimple || rv.type == rct::RCTTypeBulletproof || rv.type == rct::RCTTypeBulletproof2 || rv.type == rct::RCTTypeSimpleBulletproof)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(!pubkeys.empty() && !pubkeys[0].empty(), false, "empty pubkeys");
|
||||
rv.mixRing.resize(pubkeys.size());
|
||||
@@ -3220,14 +3149,6 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rv.type == rct::RCTTypeCLSAG)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(rv.p.CLSAGs.size() == tx.vin.size(), false, "Bad CLSAGs size");
|
||||
for (size_t n = 0; n < tx.vin.size(); ++n)
|
||||
{
|
||||
rv.p.CLSAGs[n].I = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + boost::lexical_cast<std::string>(rv.type));
|
||||
@@ -3256,17 +3177,6 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rv.type == rct::RCTTypeCLSAG)
|
||||
{
|
||||
if (!tx.pruned)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(rv.p.CLSAGs.size() == tx.vin.size(), false, "Bad CLSAGs size");
|
||||
for (size_t n = 0; n < tx.vin.size(); ++n)
|
||||
{
|
||||
rv.p.CLSAGs[n].I = rct::ki2rct(boost::get<txin_to_key>(tx.vin[n]).k_image);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + boost::lexical_cast<std::string>(rv.type));
|
||||
@@ -3426,7 +3336,8 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
results.resize(tx.vin.size(), 0);
|
||||
|
||||
tools::threadpool& tpool = tools::threadpool::getInstance();
|
||||
tools::threadpool::waiter waiter(tpool);
|
||||
tools::threadpool::waiter waiter;
|
||||
const auto waiter_guard = epee::misc_utils::create_scope_leave_handler([&]() { waiter.wait(&tpool); });
|
||||
int threads = tpool.get_max_concurrency();
|
||||
|
||||
uint64_t max_used_block_height = 0;
|
||||
@@ -3457,7 +3368,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
|
||||
// make sure that output being spent matches up correctly with the
|
||||
// signature spending it.
|
||||
if (!check_tx_input(tx.version, in_to_key, tx_prefix_hash, tx.version == 1 ? tx.signatures[sig_index] : std::vector<crypto::signature>(), tx.rct_signatures, pubkeys[sig_index], pmax_used_block_height, hf_version))
|
||||
if (!check_tx_input(tx.version, in_to_key, tx_prefix_hash, tx.version == 1 ? tx.signatures[sig_index] : std::vector<crypto::signature>(), tx.rct_signatures, pubkeys[sig_index], pmax_used_block_height))
|
||||
{
|
||||
MERROR_VER("Failed to check ring signature for tx " << get_transaction_hash(tx) << " vin key with k_image: " << in_to_key.k_image << " sig_index: " << sig_index);
|
||||
if (pmax_used_block_height) // a default value of NULL is used when called from Blockchain::handle_block_to_main_chain()
|
||||
@@ -3496,8 +3407,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
sig_index++;
|
||||
}
|
||||
if (tx.version == 1 && threads > 1)
|
||||
if (!waiter.wait())
|
||||
return false;
|
||||
waiter.wait(&tpool);
|
||||
|
||||
// enforce min output age
|
||||
if (hf_version >= HF_VERSION_ENFORCE_MIN_AGE)
|
||||
@@ -3549,7 +3459,6 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
case rct::RCTTypeSimpleBulletproof:
|
||||
case rct::RCTTypeBulletproof:
|
||||
case rct::RCTTypeBulletproof2:
|
||||
case rct::RCTTypeCLSAG:
|
||||
{
|
||||
// check all this, either reconstructed (so should really pass), or not
|
||||
{
|
||||
@@ -3585,20 +3494,14 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc,
|
||||
}
|
||||
}
|
||||
|
||||
const size_t n_sigs = rv.type == rct::RCTTypeCLSAG ? rv.p.CLSAGs.size() : rv.p.MGs.size();
|
||||
if (n_sigs != tx.vin.size())
|
||||
if (rv.p.MGs.size() != tx.vin.size())
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures: mismatched MGs/vin sizes");
|
||||
return false;
|
||||
}
|
||||
for (size_t n = 0; n < tx.vin.size(); ++n)
|
||||
{
|
||||
bool error;
|
||||
if (rv.type == rct::RCTTypeCLSAG)
|
||||
error = memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.CLSAGs[n].I, 32);
|
||||
else
|
||||
error = rv.p.MGs[n].II.empty() || memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.MGs[n].II[0], 32);
|
||||
if (error)
|
||||
if (rv.p.MGs[n].II.empty() || memcmp(&boost::get<txin_to_key>(tx.vin[n]).k_image, &rv.p.MGs[n].II[0], 32))
|
||||
{
|
||||
MERROR_VER("Failed to check ringct signatures: mismatched key image");
|
||||
return false;
|
||||
@@ -3852,7 +3755,7 @@ uint64_t Blockchain::get_dynamic_base_fee_estimate(uint64_t grace_blocks) const
|
||||
//------------------------------------------------------------------
|
||||
// This function checks to see if a tx is unlocked. unlock_time is either
|
||||
// a block index or a unix time.
|
||||
bool Blockchain::is_tx_spendtime_unlocked(uint64_t unlock_time, uint8_t hf_version) const
|
||||
bool Blockchain::is_tx_spendtime_unlocked(uint64_t unlock_time) const
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
if(unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER)
|
||||
@@ -3867,7 +3770,7 @@ bool Blockchain::is_tx_spendtime_unlocked(uint64_t unlock_time, uint8_t hf_versi
|
||||
else
|
||||
{
|
||||
//interpret as time
|
||||
const uint64_t current_time = hf_version >= HF_VERSION_DETERMINISTIC_UNLOCK_TIME ? get_adjusted_time(m_db->height()) : static_cast<uint64_t>(time(NULL));
|
||||
uint64_t current_time = static_cast<uint64_t>(time(NULL));
|
||||
if(current_time + (get_current_hard_fork_version() < 2 ? CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V1 : CRYPTONOTE_LOCKED_TX_ALLOWED_DELTA_SECONDS_V2) >= unlock_time)
|
||||
return true;
|
||||
else
|
||||
@@ -3879,7 +3782,7 @@ bool Blockchain::is_tx_spendtime_unlocked(uint64_t unlock_time, uint8_t hf_versi
|
||||
// This function locates all outputs associated with a given input (mixins)
|
||||
// and validates that they exist and are usable. It also checks the ring
|
||||
// signature for each input.
|
||||
bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const rct::rctSig &rct_signatures, std::vector<rct::ctkey> &output_keys, uint64_t* pmax_related_block_height, uint8_t hf_version) const
|
||||
bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const rct::rctSig &rct_signatures, std::vector<rct::ctkey> &output_keys, uint64_t* pmax_related_block_height) const
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
|
||||
@@ -3891,15 +3794,14 @@ bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, cons
|
||||
{
|
||||
std::vector<rct::ctkey >& m_output_keys;
|
||||
const Blockchain& m_bch;
|
||||
const uint8_t hf_version;
|
||||
outputs_visitor(std::vector<rct::ctkey>& output_keys, const Blockchain& bch, uint8_t hf_version) :
|
||||
m_output_keys(output_keys), m_bch(bch), hf_version(hf_version)
|
||||
outputs_visitor(std::vector<rct::ctkey>& output_keys, const Blockchain& bch) :
|
||||
m_output_keys(output_keys), m_bch(bch)
|
||||
{
|
||||
}
|
||||
bool handle_output(uint64_t unlock_time, const crypto::public_key &pubkey, const rct::key &commitment)
|
||||
{
|
||||
//check tx unlock time
|
||||
if (!m_bch.is_tx_spendtime_unlocked(unlock_time, hf_version))
|
||||
if (!m_bch.is_tx_spendtime_unlocked(unlock_time))
|
||||
{
|
||||
MERROR_VER("One of outputs for one of inputs has wrong tx.unlock_time = " << unlock_time);
|
||||
return false;
|
||||
@@ -3918,7 +3820,7 @@ bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, cons
|
||||
output_keys.clear();
|
||||
|
||||
// collect output keys
|
||||
outputs_visitor vi(output_keys, *this, hf_version);
|
||||
outputs_visitor vi(output_keys, *this);
|
||||
if (!scan_outputkeys_for_indexes(tx_version, txin, vi, tx_prefix_hash, pmax_related_block_height))
|
||||
{
|
||||
MERROR_VER("Failed to get output keys for tx with amount = " << print_money(txin.amount) << " and count indexes " << txin.key_offsets.size());
|
||||
@@ -3937,41 +3839,12 @@ bool Blockchain::check_tx_input(size_t tx_version, const txin_to_key& txin, cons
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
// only works on the main chain
|
||||
uint64_t Blockchain::get_adjusted_time(uint64_t height) const
|
||||
//TODO: Is this intended to do something else? Need to look into the todo there.
|
||||
uint64_t Blockchain::get_adjusted_time() const
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
size_t blockchain_timestamp_check_window = version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
|
||||
// if not enough blocks, no proper median yet, return current time
|
||||
if(height < blockchain_timestamp_check_window)
|
||||
{
|
||||
return static_cast<uint64_t>(time(NULL));
|
||||
}
|
||||
std::vector<uint64_t> timestamps;
|
||||
|
||||
// need most recent 60 blocks, get index of first of those
|
||||
size_t offset = height - blockchain_timestamp_check_window;
|
||||
timestamps.reserve(height - offset);
|
||||
for(;offset < height; ++offset)
|
||||
{
|
||||
timestamps.push_back(m_db->get_block_timestamp(offset));
|
||||
}
|
||||
uint64_t median_ts = epee::misc_utils::median(timestamps);
|
||||
|
||||
// project the median to match approximately when the block being validated will appear
|
||||
// the median is calculated from a chunk of past blocks, so we use +1 to offset onto the current block
|
||||
median_ts += (blockchain_timestamp_check_window + 1) * DIFFICULTY_TARGET_V2 / 2;
|
||||
|
||||
// project the current block's time based on the previous block's time
|
||||
// we don't use the current block's time directly to mitigate timestamp manipulation
|
||||
uint64_t adjusted_current_block_ts = timestamps.back() + DIFFICULTY_TARGET_V2;
|
||||
|
||||
// return minimum of ~current block time and adjusted median time
|
||||
// we do this since it's better to report a time in the past than a time in the future
|
||||
return (adjusted_current_block_ts < median_ts ? adjusted_current_block_ts : median_ts);
|
||||
//TODO: add collecting median time
|
||||
return time(NULL);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
//TODO: revisit, has changed a bit on upstream
|
||||
@@ -4000,14 +3873,13 @@ bool Blockchain::check_block_timestamp(std::vector<uint64_t>& timestamps, const
|
||||
bool Blockchain::check_block_timestamp(const block& b, uint64_t& median_ts) const
|
||||
{
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
|
||||
uint8_t version = get_current_hard_fork_version();
|
||||
uint64_t cryptonote_block_future_time_limit = version >= 8 ? CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT_V2 : CRYPTONOTE_BLOCK_FUTURE_TIME_LIMIT;
|
||||
size_t blockchain_timestamp_check_window = version >= 10 ? BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW_V2 : BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW;
|
||||
|
||||
if(b.timestamp > (uint64_t)time(NULL) + cryptonote_block_future_time_limit)
|
||||
|
||||
if(b.timestamp > get_adjusted_time() + cryptonote_block_future_time_limit)
|
||||
{
|
||||
MERROR_VER("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than local time + 10 minutes");
|
||||
MERROR_VER("Timestamp of block with id: " << get_block_hash(b) << ", " << b.timestamp << ", bigger than adjusted time + 10 minutes");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -4181,8 +4053,8 @@ leave:
|
||||
MCINFO("verify", "No pre-validated hash at height " << blockchain_height << ", verifying fully");
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!fast_check)
|
||||
{
|
||||
auto it = m_blocks_longhash_table.find(id);
|
||||
if (it != m_blocks_longhash_table.end())
|
||||
@@ -4457,9 +4329,12 @@ leave:
|
||||
get_difficulty_for_next_block(); // just to cache it
|
||||
invalidate_block_template_cache();
|
||||
|
||||
|
||||
for (const auto& notifier: m_block_notifiers)
|
||||
notifier(new_height - 1, {std::addressof(bl), 1});
|
||||
if (notify)
|
||||
{
|
||||
std::shared_ptr<tools::Notify> block_notify = m_block_notify;
|
||||
if (block_notify)
|
||||
block_notify->notify("%s", epee::string_tools::pod_to_hex(id).c_str(), NULL);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -4587,9 +4462,6 @@ bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effecti
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::add_new_block(const block& bl, block_verification_context& bvc)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
LOG_PRINT_L3("Blockchain::" << __func__);
|
||||
crypto::hash id = get_block_hash(bl);
|
||||
CRITICAL_REGION_LOCAL(m_tx_pool);//to avoid deadlock lets lock tx_pool for whole add/reorganize process
|
||||
@@ -4617,14 +4489,6 @@ bool Blockchain::add_new_block(const block& bl, block_verification_context& bvc)
|
||||
|
||||
rtxn_guard.stop();
|
||||
return handle_block_to_main_chain(bl, id, bvc);
|
||||
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG_ERROR("Exception at [add_new_block], what=" << e.what());
|
||||
bvc.m_verifivation_failed = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
//TODO: Refactor, consider returning a failure height and letting
|
||||
@@ -5074,7 +4938,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
|
||||
{
|
||||
m_blocks_longhash_table.clear();
|
||||
uint64_t thread_height = height;
|
||||
tools::threadpool::waiter waiter(tpool);
|
||||
tools::threadpool::waiter waiter;
|
||||
m_prepare_height = height;
|
||||
m_prepare_nblocks = blocks_entry.size();
|
||||
m_prepare_blocks = &blocks;
|
||||
@@ -5087,8 +4951,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
|
||||
thread_height += nblocks;
|
||||
}
|
||||
|
||||
if (!waiter.wait())
|
||||
return false;
|
||||
waiter.wait(&tpool);
|
||||
m_prepare_height = 0;
|
||||
|
||||
if (m_cancel)
|
||||
@@ -5222,15 +5085,14 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
|
||||
|
||||
if (threads > 1 && amounts.size() > 1)
|
||||
{
|
||||
tools::threadpool::waiter waiter(tpool);
|
||||
tools::threadpool::waiter waiter;
|
||||
|
||||
for (size_t i = 0; i < amounts.size(); i++)
|
||||
{
|
||||
uint64_t amount = amounts[i];
|
||||
tpool.submit(&waiter, boost::bind(&Blockchain::output_scan_worker, this, amount, std::cref(offset_map[amount]), std::ref(tx_map[amount])), true);
|
||||
}
|
||||
if (!waiter.wait())
|
||||
return false;
|
||||
waiter.wait(&tpool);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5339,7 +5201,7 @@ cryptonote::blobdata Blockchain::get_txpool_tx_blob(const crypto::hash& txid, re
|
||||
return m_db->get_txpool_tx_blob(txid, tx_category);
|
||||
}
|
||||
|
||||
bool Blockchain::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata_ref*)> f, bool include_blob, relay_category tx_category) const
|
||||
bool Blockchain::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob, relay_category tx_category) const
|
||||
{
|
||||
return m_db->for_all_txpool_txes(f, include_blob, tx_category);
|
||||
}
|
||||
@@ -5363,15 +5225,6 @@ void Blockchain::set_user_options(uint64_t maxthreads, bool sync_on_blocks, uint
|
||||
m_max_prepare_blocks_threads = maxthreads;
|
||||
}
|
||||
|
||||
void Blockchain::add_block_notify(boost::function<void(std::uint64_t, epee::span<const block>)>&& notify)
|
||||
{
|
||||
if (notify)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
m_block_notifiers.push_back(std::move(notify));
|
||||
}
|
||||
}
|
||||
|
||||
void Blockchain::safesyncmode(const bool onoff)
|
||||
{
|
||||
/* all of this is no-op'd if the user set a specific
|
||||
@@ -5410,7 +5263,7 @@ std::vector<std::pair<Blockchain::block_extended_info,std::vector<crypto::hash>>
|
||||
|
||||
blocks_ext_by_hash alt_blocks;
|
||||
alt_blocks.reserve(m_db->get_alt_block_count());
|
||||
m_db->for_all_alt_blocks([&alt_blocks](const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata_ref *blob) {
|
||||
m_db->for_all_alt_blocks([&alt_blocks](const crypto::hash &blkid, const cryptonote::alt_block_data_t &data, const cryptonote::blobdata *blob) {
|
||||
if (!blob)
|
||||
{
|
||||
MERROR("No blob, but blobs were requested");
|
||||
@@ -5467,7 +5320,7 @@ void Blockchain::cancel()
|
||||
}
|
||||
|
||||
#if defined(PER_BLOCK_CHECKPOINT)
|
||||
static const char expected_block_hashes_hash[] = "5489781213b29d0227fd79b3ac854c42793bc5d11b554b89f822035e117df586";
|
||||
static const char expected_block_hashes_hash[] = "c8d6e428606b22f77d2df05d880cac01dc59d485b356bc469e78b7c79ad1ed1f";
|
||||
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
|
||||
{
|
||||
if (get_checkpoints == nullptr || !m_fast_sync)
|
||||
@@ -5609,7 +5462,7 @@ void Blockchain::invalidate_block_template_cache()
|
||||
m_btc_valid = false;
|
||||
}
|
||||
|
||||
void Blockchain::cache_block_template(const block &b, const cryptonote::account_public_address &address, const blobdata &nonce, const difficulty_type &diff, uint64_t height, uint64_t expected_reward, uint64_t seed_height, const crypto::hash &seed_hash, uint64_t pool_cookie)
|
||||
void Blockchain::cache_block_template(const block &b, const cryptonote::account_public_address &address, const blobdata &nonce, const difficulty_type &diff, uint64_t height, uint64_t expected_reward, uint64_t pool_cookie)
|
||||
{
|
||||
MDEBUG("Setting block template cache");
|
||||
m_btc = b;
|
||||
@@ -5618,8 +5471,6 @@ void Blockchain::cache_block_template(const block &b, const cryptonote::account_
|
||||
m_btc_difficulty = diff;
|
||||
m_btc_height = height;
|
||||
m_btc_expected_reward = expected_reward;
|
||||
m_btc_seed_hash = seed_hash;
|
||||
m_btc_seed_height = seed_height;
|
||||
m_btc_pool_cookie = pool_cookie;
|
||||
m_btc_valid = true;
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@
|
||||
|
||||
#pragma once
|
||||
#include <boost/asio/io_service.hpp>
|
||||
#include <boost/function/function_fwd.hpp>
|
||||
#if BOOST_VERSION >= 107400
|
||||
#include <boost/serialization/library_version_type.hpp>
|
||||
#endif
|
||||
@@ -366,8 +365,8 @@ namespace cryptonote
|
||||
*
|
||||
* @return true if block template filled in successfully, else false
|
||||
*/
|
||||
bool create_block_template(block& b, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash);
|
||||
bool create_block_template(block& b, const crypto::hash *from_block, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash);
|
||||
bool create_block_template(block& b, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce);
|
||||
bool create_block_template(block& b, const crypto::hash *from_block, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce);
|
||||
|
||||
/**
|
||||
* @brief checks if a block is known about with a given hash
|
||||
@@ -768,7 +767,7 @@ namespace cryptonote
|
||||
*
|
||||
* @param notify the notify object to call at every new block
|
||||
*/
|
||||
void add_block_notify(boost::function<void(std::uint64_t, epee::span<const block>)> &¬ify);
|
||||
void set_block_notify(const std::shared_ptr<tools::Notify> ¬ify) { m_block_notify = notify; }
|
||||
|
||||
/**
|
||||
* @brief sets a reorg notify object to call for every reorg
|
||||
@@ -988,7 +987,7 @@ namespace cryptonote
|
||||
bool get_txpool_tx_meta(const crypto::hash& txid, txpool_tx_meta_t &meta) const;
|
||||
bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd, relay_category tx_category) const;
|
||||
cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid, relay_category tx_category) const;
|
||||
bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata_ref*)>, bool include_blob = false, relay_category tx_category = relay_category::broadcasted) const;
|
||||
bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, relay_category tx_category = relay_category::broadcasted) const;
|
||||
bool txpool_tx_matches_category(const crypto::hash& tx_hash, relay_category category);
|
||||
|
||||
bool is_within_compiled_block_hash_area() const { return is_within_compiled_block_hash_area(m_db->height()); }
|
||||
@@ -1042,21 +1041,6 @@ namespace cryptonote
|
||||
*/
|
||||
void flush_invalid_blocks();
|
||||
|
||||
/**
|
||||
* @brief get the "adjusted time"
|
||||
*
|
||||
* Computes the median timestamp of the previous 60 blocks, projects it
|
||||
* onto the current block to get an 'adjusted median time' which approximates
|
||||
* what the current block's timestamp should be. Also projects the previous
|
||||
* block's timestamp to estimate the current block's timestamp.
|
||||
*
|
||||
* Returns the minimum of the two projections, or the current local time on
|
||||
* the machine if less than 60 blocks are available.
|
||||
*
|
||||
* @return current time approximated from chain data
|
||||
*/
|
||||
uint64_t get_adjusted_time(uint64_t height) const;
|
||||
|
||||
#ifndef IN_UNIT_TESTS
|
||||
private:
|
||||
#endif
|
||||
@@ -1139,18 +1123,12 @@ namespace cryptonote
|
||||
uint64_t m_btc_height;
|
||||
uint64_t m_btc_pool_cookie;
|
||||
uint64_t m_btc_expected_reward;
|
||||
crypto::hash m_btc_seed_hash;
|
||||
uint64_t m_btc_seed_height;
|
||||
bool m_btc_valid;
|
||||
|
||||
|
||||
bool m_batch_success;
|
||||
|
||||
/* `boost::function` is used because the implementation never allocates if
|
||||
the callable object has a single `std::shared_ptr` or `std::weap_ptr`
|
||||
internally. Whereas, the libstdc++ `std::function` will allocate. */
|
||||
|
||||
std::vector<boost::function<void(std::uint64_t, epee::span<const block>)>> m_block_notifiers;
|
||||
std::shared_ptr<tools::Notify> m_block_notify;
|
||||
std::shared_ptr<tools::Notify> m_reorg_notify;
|
||||
|
||||
// for prepare_handle_incoming_blocks
|
||||
@@ -1197,11 +1175,10 @@ namespace cryptonote
|
||||
* @param output_keys return-by-reference the public keys of the outputs in the input set
|
||||
* @param rct_signatures the ringCT signatures, which are only valid if tx version > 1
|
||||
* @param pmax_related_block_height return-by-pointer the height of the most recent block in the input set
|
||||
* @param hf_version the consensus rules version to use
|
||||
*
|
||||
* @return false if any output is not yet unlocked, or is missing, otherwise true
|
||||
*/
|
||||
bool check_tx_input(size_t tx_version,const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const rct::rctSig &rct_signatures, std::vector<rct::ctkey> &output_keys, uint64_t* pmax_related_block_height, uint8_t hf_version) const;
|
||||
bool check_tx_input(size_t tx_version,const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, const rct::rctSig &rct_signatures, std::vector<rct::ctkey> &output_keys, uint64_t* pmax_related_block_height) const;
|
||||
|
||||
/**
|
||||
* @brief validate a transaction's inputs and their keys
|
||||
@@ -1389,11 +1366,10 @@ namespace cryptonote
|
||||
* unlock_time is either a block index or a unix time.
|
||||
*
|
||||
* @param unlock_time the unlock parameter (height or time)
|
||||
* @param hf_version the consensus rules version to use
|
||||
*
|
||||
* @return true if spendable, otherwise false
|
||||
*/
|
||||
bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint8_t hf_version) const;
|
||||
bool is_tx_spendtime_unlocked(uint64_t unlock_time) const;
|
||||
|
||||
/**
|
||||
* @brief stores an invalid block in a separate container
|
||||
@@ -1454,6 +1430,16 @@ namespace cryptonote
|
||||
bool check_block_timestamp(std::vector<uint64_t>& timestamps, const block& b, uint64_t& median_ts) const;
|
||||
bool check_block_timestamp(std::vector<uint64_t>& timestamps, const block& b) const { uint64_t median_ts; return check_block_timestamp(timestamps, b, median_ts); }
|
||||
|
||||
/**
|
||||
* @brief get the "adjusted time"
|
||||
*
|
||||
* Currently this simply returns the current time according to the
|
||||
* user's machine.
|
||||
*
|
||||
* @return the current time
|
||||
*/
|
||||
uint64_t get_adjusted_time() const;
|
||||
|
||||
/**
|
||||
* @brief finish an alternate chain's timestamp window from the main chain
|
||||
*
|
||||
@@ -1529,6 +1515,6 @@ namespace cryptonote
|
||||
*
|
||||
* At some point, may be used to push an update to miners
|
||||
*/
|
||||
void cache_block_template(const block &b, const cryptonote::account_public_address &address, const blobdata &nonce, const difficulty_type &diff, uint64_t height, uint64_t expected_reward, uint64_t seed_height, const crypto::hash &seed_hash, uint64_t pool_cookie);
|
||||
void cache_block_template(const block &b, const cryptonote::account_public_address &address, const blobdata &nonce, const difficulty_type &diff, uint64_t height, uint64_t expected_reward, uint64_t pool_cookie);
|
||||
};
|
||||
} // namespace cryptonote
|
||||
|
||||
@@ -41,7 +41,6 @@ using namespace epee;
|
||||
#include "common/download.h"
|
||||
#include "common/threadpool.h"
|
||||
#include "common/command_line.h"
|
||||
#include "cryptonote_basic/events.h"
|
||||
#include "warnings.h"
|
||||
#include "crypto/crypto.h"
|
||||
#include "cryptonote_config.h"
|
||||
@@ -52,7 +51,6 @@ using namespace epee;
|
||||
#include "ringct/rctTypes.h"
|
||||
#include "blockchain_db/blockchain_db.h"
|
||||
#include "ringct/rctSigs.h"
|
||||
#include "rpc/zmq_pub.h"
|
||||
#include "common/notify.h"
|
||||
#include "hardforks/hardforks.h"
|
||||
#include "version.h"
|
||||
@@ -226,8 +224,8 @@ namespace cryptonote
|
||||
core::core(i_cryptonote_protocol* pprotocol):
|
||||
m_mempool(m_blockchain_storage),
|
||||
m_blockchain_storage(m_mempool),
|
||||
m_miner(this, [this](const cryptonote::block &b, uint64_t height, const crypto::hash *seed_hash, unsigned int threads, crypto::hash &hash) {
|
||||
return cryptonote::get_block_longhash(&m_blockchain_storage, b, hash, height, seed_hash, threads);
|
||||
m_miner(this, [this](const cryptonote::block &b, uint64_t height, unsigned int threads, crypto::hash &hash) {
|
||||
return cryptonote::get_block_longhash(&m_blockchain_storage, b, hash, height, threads);
|
||||
}),
|
||||
m_starter_message_showed(false),
|
||||
m_target_blockchain_height(0),
|
||||
@@ -264,13 +262,6 @@ namespace cryptonote
|
||||
{
|
||||
m_blockchain_storage.set_enforce_dns_checkpoints(enforce_dns);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
void core::set_txpool_listener(boost::function<void(std::vector<txpool_event>)> zmq_pub)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_incoming_tx_lock);
|
||||
m_zmq_pub = std::move(zmq_pub);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::update_checkpoints(const bool skip_dns /* = false */)
|
||||
{
|
||||
@@ -623,20 +614,7 @@ namespace cryptonote
|
||||
try
|
||||
{
|
||||
if (!command_line::is_arg_defaulted(vm, arg_block_notify))
|
||||
{
|
||||
struct hash_notify
|
||||
{
|
||||
tools::Notify cmdline;
|
||||
|
||||
void operator()(std::uint64_t, epee::span<const block> blocks) const
|
||||
{
|
||||
for (const block bl : blocks)
|
||||
cmdline.notify("%s", epee::string_tools::pod_to_hex(get_block_hash(bl)).c_str(), NULL);
|
||||
}
|
||||
};
|
||||
|
||||
m_blockchain_storage.add_block_notify(hash_notify{{command_line::get_arg(vm, arg_block_notify).c_str()}});
|
||||
}
|
||||
m_blockchain_storage.set_block_notify(std::shared_ptr<tools::Notify>(new tools::Notify(command_line::get_arg(vm, arg_block_notify).c_str())));
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
@@ -968,7 +946,6 @@ namespace cryptonote
|
||||
break;
|
||||
case rct::RCTTypeBulletproof:
|
||||
case rct::RCTTypeBulletproof2:
|
||||
case rct::RCTTypeCLSAG:
|
||||
if (!is_canonical_bulletproof_layout(rv.p.bulletproofs))
|
||||
{
|
||||
MERROR_VER("Bulletproof does not have canonical form");
|
||||
@@ -996,7 +973,7 @@ namespace cryptonote
|
||||
{
|
||||
if (!tx_info[n].result)
|
||||
continue;
|
||||
if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof2 && tx_info[n].tx->rct_signatures.type != rct::RCTTypeCLSAG)
|
||||
if (tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof && tx_info[n].tx->rct_signatures.type != rct::RCTTypeBulletproof2)
|
||||
continue;
|
||||
if (assumed_bad || !rct::verRctSemanticsSimple(tx_info[n].tx->rct_signatures))
|
||||
{
|
||||
@@ -1020,12 +997,13 @@ namespace cryptonote
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<txpool_event> results(tx_blobs.size());
|
||||
struct result { bool res; cryptonote::transaction tx; crypto::hash hash; };
|
||||
std::vector<result> results(tx_blobs.size());
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_incoming_tx_lock);
|
||||
|
||||
tools::threadpool& tpool = tools::threadpool::getInstance();
|
||||
tools::threadpool::waiter waiter(tpool);
|
||||
tools::threadpool::waiter waiter;
|
||||
epee::span<tx_blob_entry>::const_iterator it = tx_blobs.begin();
|
||||
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
|
||||
tpool.submit(&waiter, [&, i, it] {
|
||||
@@ -1041,8 +1019,7 @@ namespace cryptonote
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!waiter.wait())
|
||||
return false;
|
||||
waiter.wait(&tpool);
|
||||
it = tx_blobs.begin();
|
||||
std::vector<bool> already_have(tx_blobs.size(), false);
|
||||
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
|
||||
@@ -1074,8 +1051,7 @@ namespace cryptonote
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!waiter.wait())
|
||||
return false;
|
||||
waiter.wait(&tpool);
|
||||
|
||||
std::vector<tx_verification_batch_info> tx_info;
|
||||
tx_info.reserve(tx_blobs.size());
|
||||
@@ -1087,7 +1063,6 @@ namespace cryptonote
|
||||
if (!tx_info.empty())
|
||||
handle_incoming_tx_accumulated_batch(tx_info, tx_relay == relay_method::block);
|
||||
|
||||
bool valid_events = false;
|
||||
bool ok = true;
|
||||
it = tx_blobs.begin();
|
||||
for (size_t i = 0; i < tx_blobs.size(); i++, ++it) {
|
||||
@@ -1110,18 +1085,10 @@ namespace cryptonote
|
||||
{MERROR_VER("Transaction verification impossible: " << results[i].hash);}
|
||||
|
||||
if(tvc[i].m_added_to_pool)
|
||||
{
|
||||
MDEBUG("tx added: " << results[i].hash);
|
||||
valid_events = true;
|
||||
}
|
||||
else
|
||||
results[i].res = false;
|
||||
}
|
||||
|
||||
if (valid_events && m_zmq_pub && matches_category(tx_relay, relay_category::legacy))
|
||||
m_zmq_pub(std::move(results));
|
||||
|
||||
return ok;
|
||||
|
||||
CATCH_ENTRY_L0("core::handle_incoming_txs()", false);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
@@ -1224,42 +1191,11 @@ namespace cryptonote
|
||||
size_t core::get_block_sync_size(uint64_t height) const
|
||||
{
|
||||
static const uint64_t quick_height = m_nettype == TESTNET ? 801219 : m_nettype == MAINNET ? 53666 : 0;
|
||||
size_t res = 0;
|
||||
if (block_sync_size > 0)
|
||||
res = block_sync_size;
|
||||
else if (height >= quick_height)
|
||||
res = BLOCKS_SYNCHRONIZING_DEFAULT_COUNT;
|
||||
else
|
||||
res = BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4;
|
||||
|
||||
static size_t max_block_size = 0;
|
||||
if (max_block_size == 0)
|
||||
{
|
||||
const char *env = getenv("SEEDHASH_EPOCH_BLOCKS");
|
||||
if (env)
|
||||
{
|
||||
int n = atoi(env);
|
||||
if (n <= 0)
|
||||
n = BLOCKS_SYNCHRONIZING_MAX_COUNT;
|
||||
size_t p = 1;
|
||||
while (p < (size_t)n)
|
||||
p <<= 1;
|
||||
max_block_size = p;
|
||||
}
|
||||
else
|
||||
max_block_size = BLOCKS_SYNCHRONIZING_MAX_COUNT;
|
||||
}
|
||||
if (res > max_block_size)
|
||||
{
|
||||
static bool warned = false;
|
||||
if (!warned)
|
||||
{
|
||||
MWARNING("Clamping block sync size to " << max_block_size);
|
||||
warned = true;
|
||||
}
|
||||
res = max_block_size;
|
||||
}
|
||||
return res;
|
||||
return block_sync_size;
|
||||
if (height >= quick_height)
|
||||
return BLOCKS_SYNCHRONIZING_DEFAULT_COUNT;
|
||||
return BLOCKS_SYNCHRONIZING_DEFAULT_COUNT_PRE_V4;
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::are_key_images_spent_in_pool(const std::vector<crypto::key_image>& key_im, std::vector<bool> &spent) const
|
||||
@@ -1377,7 +1313,6 @@ namespace cryptonote
|
||||
{
|
||||
NOTIFY_NEW_TRANSACTIONS::request public_req{};
|
||||
NOTIFY_NEW_TRANSACTIONS::request private_req{};
|
||||
NOTIFY_NEW_TRANSACTIONS::request stem_req{};
|
||||
for (auto& tx : txs)
|
||||
{
|
||||
switch (std::get<2>(tx))
|
||||
@@ -1388,9 +1323,6 @@ namespace cryptonote
|
||||
case relay_method::local:
|
||||
private_req.txs.push_back(std::move(std::get<1>(tx)));
|
||||
break;
|
||||
case relay_method::forward:
|
||||
stem_req.txs.push_back(std::move(std::get<1>(tx)));
|
||||
break;
|
||||
case relay_method::block:
|
||||
case relay_method::fluff:
|
||||
case relay_method::stem:
|
||||
@@ -1408,8 +1340,6 @@ namespace cryptonote
|
||||
get_protocol()->relay_transactions(public_req, source, epee::net_utils::zone::public_, relay_method::fluff);
|
||||
if (!private_req.txs.empty())
|
||||
get_protocol()->relay_transactions(private_req, source, epee::net_utils::zone::invalid, relay_method::local);
|
||||
if (!stem_req.txs.empty())
|
||||
get_protocol()->relay_transactions(stem_req, source, epee::net_utils::zone::public_, relay_method::stem);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -1431,14 +1361,14 @@ namespace cryptonote
|
||||
m_mempool.set_relayed(epee::to_span(tx_hashes), tx_relay);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash)
|
||||
bool core::get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce)
|
||||
{
|
||||
return m_blockchain_storage.create_block_template(b, adr, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash);
|
||||
return m_blockchain_storage.create_block_template(b, adr, diffic, height, expected_reward, ex_nonce);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash)
|
||||
bool core::get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce)
|
||||
{
|
||||
return m_blockchain_storage.create_block_template(b, prev_block, adr, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash);
|
||||
return m_blockchain_storage.create_block_template(b, prev_block, adr, diffic, height, expected_reward, ex_nonce);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, bool clip_pruned, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const
|
||||
@@ -1753,36 +1683,27 @@ namespace cryptonote
|
||||
main_message = "The daemon is running offline and will not attempt to sync to the Monero network.";
|
||||
else
|
||||
main_message = "The daemon will start synchronizing with the network. This may take a long time to complete.";
|
||||
MGINFO_MAGENTA(ENDL <<
|
||||
MGINFO_GREEN(ENDL <<
|
||||
"\n \n"
|
||||
" ... . -..- \n"
|
||||
" `-. .-'. \n"
|
||||
" `-. -./\\.- .-' \n"
|
||||
" -. /__\\ .- \n"
|
||||
" `-. `/__|_\\' .-'. \n"
|
||||
" `-. -./ .-- \\.- ' \n"
|
||||
" `-. / <(O)> \\ .-' \n"
|
||||
" - .`/__ .-- ___\\ .- Magnus \n"
|
||||
" ,...`-./___|__|__|__\\.-'.,. Frater \n"
|
||||
" -.. .-. ..- --. ... Spectat Te \n"
|
||||
" .-. --- -.-. -.- -. .-. --- .-.. .-.. \n"
|
||||
" ,-' ________________ `-, \n"
|
||||
" /'/____|_____|_____\\ \n"
|
||||
" / /__|___|___|___|___\\ \n"
|
||||
" / /|_____|_____|____|__\\ \n"
|
||||
" ' /_____|____|_____|_____\\ \n"
|
||||
" ' /__|_____|______|_____|__\\ \n"
|
||||
" /' /_|_____|_____|_____|____|_\\ \n"
|
||||
" .. - . .-. .- - .. ...- ./ /____|_____|_____|_____|_____\\-.. .. ... -.-. --- ..- .-. ... .\n"
|
||||
" / /__|_____|_____|_____|_____|___\\ \n"
|
||||
" / /|_____|_____|_____|_____|_____|_\\ \n"
|
||||
" / /____|_____|_____|_____|_____|_____\\ \n"
|
||||
" / /__|_____|_____|_____|_____|_____|___\\ \n"
|
||||
" / /|_____|_____|_____|_____|_____|_____|_\\ \n"
|
||||
" / /____|_____|_____|_____|_____|_____|_____\\ \n"
|
||||
" \\ /___________.-- --- .-- -. . .-. ---_______\\ \n"
|
||||
" IV.I.MMXVIII \n"
|
||||
" .- / -... .-.. .- -.-. -.- .... .- - / -.-. ..- .-.. - ..- .-. . \n"
|
||||
" ,'``.._ ,'``. \n"
|
||||
" :,--._:)|,:,._,.: All Glory to \n"
|
||||
" :`--,'' :`...';| the HYPNO TOAD! \n"
|
||||
" `,' `---' `. \n"
|
||||
" / : \n"
|
||||
" / | \n"
|
||||
" ,' :|.___,-. \n"
|
||||
" `...,---'``````-..._ |: | \n"
|
||||
" ( ) ;: ) | _,-. \n"
|
||||
" `. ( // `' | \n"
|
||||
" : `.// ) ) , ; \n"
|
||||
" ,-|`. _,'/ ) ) ,' ,' \n"
|
||||
" ( :`.`-..____..=:.-': . _,' ,' \n"
|
||||
" `,'| ``--....-)=' `._, | ,') _ '``._ \n"
|
||||
" _.-/ _ `. (WOW) / )' ; / | |`-.' \n"
|
||||
"`--( `-:`. `' ___..' _,-' |/ `.) \n"
|
||||
" `-. `.`.``-----``--, .' \n"
|
||||
" |/`.|`' ,','); \n"
|
||||
" ` (/ (/ \n"
|
||||
"\n \n" << ENDL);
|
||||
MGINFO_YELLOW(ENDL << "**********************************************************************" << ENDL
|
||||
<< main_message << ENDL
|
||||
@@ -1793,8 +1714,9 @@ namespace cryptonote
|
||||
<< "You can set the level of process detailization through \"set_log <level|categories>\" command," << ENDL
|
||||
<< "where <level> is between 0 (no details) and 4 (very verbose), or custom category based levels (eg, *:WARNING)." << ENDL
|
||||
<< ENDL
|
||||
<< "Use the \"help\" command to see the list of available commands." << ENDL
|
||||
<< "Use \"help <command>\" to see a command's documentation." << ENDL
|
||||
<< "Use the \"help\" command to see a simplified list of available commands." << ENDL
|
||||
<< "Use the \"help_advanced\" command to see an advanced list of available commands." << ENDL
|
||||
<< "Use \"help_advanced <command>\" to see a command's documentation." << ENDL
|
||||
<< "**********************************************************************" << ENDL);
|
||||
m_starter_message_showed = true;
|
||||
}
|
||||
|
||||
@@ -32,11 +32,9 @@
|
||||
|
||||
#include <ctime>
|
||||
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/program_options/options_description.hpp>
|
||||
#include <boost/program_options/variables_map.hpp>
|
||||
|
||||
#include "cryptonote_basic/fwd.h"
|
||||
#include "cryptonote_core/i_core_events.h"
|
||||
#include "cryptonote_protocol/cryptonote_protocol_handler_common.h"
|
||||
#include "cryptonote_protocol/enums.h"
|
||||
@@ -50,7 +48,6 @@
|
||||
#include "warnings.h"
|
||||
#include "crypto/hash.h"
|
||||
#include "span.h"
|
||||
#include "rpc/fwd.h"
|
||||
|
||||
PUSH_WARNINGS
|
||||
DISABLE_VS_WARNINGS(4355)
|
||||
@@ -231,8 +228,8 @@ namespace cryptonote
|
||||
*
|
||||
* @note see Blockchain::create_block_template
|
||||
*/
|
||||
virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash);
|
||||
virtual bool get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce, uint64_t &seed_height, crypto::hash &seed_hash);
|
||||
virtual bool get_block_template(block& b, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce);
|
||||
virtual bool get_block_template(block& b, const crypto::hash *prev_block, const account_public_address& adr, difficulty_type& diffic, uint64_t& height, uint64_t& expected_reward, const blobdata& ex_nonce);
|
||||
|
||||
/**
|
||||
* @brief called when a transaction is relayed.
|
||||
@@ -448,13 +445,6 @@ namespace cryptonote
|
||||
*/
|
||||
void set_enforce_dns_checkpoints(bool enforce_dns);
|
||||
|
||||
/**
|
||||
* @brief set a listener for txes being added to the txpool
|
||||
*
|
||||
* @param callable to notify, or empty function to disable.
|
||||
*/
|
||||
void set_txpool_listener(boost::function<void(std::vector<txpool_event>)> zmq_pub);
|
||||
|
||||
/**
|
||||
* @brief set whether or not to enable or disable DNS checkpoints
|
||||
*
|
||||
@@ -1108,12 +1098,7 @@ namespace cryptonote
|
||||
bool m_fluffy_blocks_enabled;
|
||||
bool m_offline;
|
||||
|
||||
/* `boost::function` is used because the implementation never allocates if
|
||||
the callable object has a single `std::shared_ptr` or `std::weap_ptr`
|
||||
internally. Whereas, the libstdc++ `std::function` will allocate. */
|
||||
|
||||
std::shared_ptr<tools::Notify> m_block_rate_notify;
|
||||
boost::function<void(std::vector<txpool_event>)> m_zmq_pub;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ namespace cryptonote
|
||||
LOG_PRINT_L2("destinations include " << num_stdaddresses << " standard addresses and " << num_subaddresses << " subaddresses");
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool construct_miner_tx(const Blockchain *pb, network_type m_nettype, size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) {
|
||||
bool construct_miner_tx(const Blockchain *pb, size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce, size_t max_outs, uint8_t hard_fork_version) {
|
||||
tx.vin.clear();
|
||||
tx.vout.clear();
|
||||
tx.extra.clear();
|
||||
@@ -169,8 +169,7 @@ namespace cryptonote
|
||||
//lock
|
||||
if (hard_fork_version >= HF_VERSION_DYNAMIC_UNLOCK)
|
||||
{
|
||||
uint64_t N = m_nettype == MAINNET ? 1337 : 5;
|
||||
crypto::hash blk_id = pb->get_block_id_by_height(height-N);
|
||||
crypto::hash blk_id = pb->get_block_id_by_height(height-1337);
|
||||
std::string hex_str = epee::string_tools::pod_to_hex(blk_id).substr(0, 3);
|
||||
uint64_t blk_num = std::stol(hex_str,nullptr,16)*2;
|
||||
uint64_t unlock_window = blk_num + 288;
|
||||
@@ -675,9 +674,9 @@ namespace cryptonote
|
||||
bl.minor_version = CURRENT_BLOCK_MINOR_VERSION;
|
||||
bl.timestamp = 0;
|
||||
bl.nonce = nonce;
|
||||
miner::find_nonce_for_given_block([](const cryptonote::block &b, uint64_t height, const crypto::hash *seed_hash, unsigned int threads, crypto::hash &hash){
|
||||
return cryptonote::get_block_longhash(NULL, b, hash, height, seed_hash, threads);
|
||||
}, bl, 1, 0, NULL);
|
||||
miner::find_nonce_for_given_block([](const cryptonote::block &b, uint64_t height, unsigned int threads, crypto::hash &hash){
|
||||
return cryptonote::get_block_longhash(NULL, b, hash, height, threads);
|
||||
}, bl, 1, 0);
|
||||
bl.invalidate_hashes();
|
||||
return true;
|
||||
}
|
||||
@@ -688,15 +687,8 @@ namespace cryptonote
|
||||
rx_slow_hash(main_height, seed_height, seed_hash.data, bd.data(), bd.size(), res.data, 0, 1);
|
||||
}
|
||||
|
||||
bool get_block_longhash(const Blockchain *pbc, const block& b, crypto::hash& res, const uint64_t height, const crypto::hash *seed_hash, const int miners)
|
||||
bool get_block_longhash(const Blockchain *pbc, const block& b, crypto::hash& res, const uint64_t height, const int miners)
|
||||
{
|
||||
// block 202612 bug workaround
|
||||
if (height == 202612)
|
||||
{
|
||||
static const std::string longhash_202612 = "84f64766475d51837ac9efbef1926486e58563c95a19fef4aec3254f03000000";
|
||||
epee::string_tools::hex_to_pod(longhash_202612, res);
|
||||
return true;
|
||||
}
|
||||
blobdata bd = get_block_hashing_blob(b);
|
||||
if (b.major_version >= RX_BLOCK_VERSION)
|
||||
{
|
||||
@@ -705,7 +697,7 @@ namespace cryptonote
|
||||
if (pbc != NULL)
|
||||
{
|
||||
seed_height = rx_seedheight(height);
|
||||
hash = seed_hash ? *seed_hash : pbc->get_pending_block_id_by_height(seed_height);
|
||||
hash = pbc->get_pending_block_id_by_height(seed_height);
|
||||
main_height = pbc->get_current_blockchain_height();
|
||||
} else
|
||||
{
|
||||
@@ -713,7 +705,7 @@ namespace cryptonote
|
||||
seed_height = 0;
|
||||
main_height = 0;
|
||||
}
|
||||
rx_slow_hash(main_height, seed_height, hash.data, bd.data(), bd.size(), res.data, seed_hash ? 0 : miners, !!seed_hash);
|
||||
rx_slow_hash(main_height, seed_height, hash.data, bd.data(), bd.size(), res.data, miners, 0);
|
||||
} else {
|
||||
const int pow_variant = b.major_version >= 11 ? 4 : b.major_version >= 9 ? 2 : 1;
|
||||
crypto::cn_slow_hash(bd.data(), bd.size(), res, pow_variant, height);
|
||||
@@ -721,11 +713,6 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get_block_longhash(const Blockchain *pbc, const block& b, crypto::hash& res, const uint64_t height, const int miners)
|
||||
{
|
||||
return get_block_longhash(pbc, b, res, height, NULL, miners);
|
||||
}
|
||||
|
||||
crypto::hash get_block_longhash(const Blockchain *pbc, const block& b, const uint64_t height, const int miners)
|
||||
{
|
||||
crypto::hash p = crypto::null_hash;
|
||||
|
||||
@@ -38,7 +38,7 @@ namespace cryptonote
|
||||
{
|
||||
//---------------------------------------------------------------
|
||||
class Blockchain;
|
||||
bool construct_miner_tx(const Blockchain *pb, network_type m_nettype, size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1);
|
||||
bool construct_miner_tx(const Blockchain *pb, size_t height, size_t median_weight, uint64_t already_generated_coins, size_t current_block_weight, uint64_t fee, const account_public_address &miner_address, transaction& tx, const blobdata& extra_nonce = blobdata(), size_t max_outs = 999, uint8_t hard_fork_version = 1);
|
||||
|
||||
struct tx_source_entry
|
||||
{
|
||||
@@ -135,7 +135,6 @@ namespace cryptonote
|
||||
|
||||
class Blockchain;
|
||||
bool get_block_longhash(const Blockchain *pb, const block& b, crypto::hash& res, const uint64_t height, const int miners);
|
||||
bool get_block_longhash(const Blockchain *pb, const block& b, crypto::hash& res, const uint64_t height, const crypto::hash *seed_hash, const int miners);
|
||||
void get_altblock_longhash(const block& b, crypto::hash& res, const uint64_t main_height, const uint64_t height,
|
||||
const uint64_t seed_height, const crypto::hash& seed_hash);
|
||||
crypto::hash get_block_longhash(const Blockchain *pb, const block& b, const uint64_t height, const int miners);
|
||||
|
||||
@@ -91,8 +91,6 @@ namespace cryptonote
|
||||
time_t const MAX_RELAY_TIME = (60 * 60 * 4); // at most that many seconds between resends
|
||||
float const ACCEPT_THRESHOLD = 1.0f;
|
||||
|
||||
constexpr const std::chrono::seconds forward_delay_average{CRYPTONOTE_FORWARD_DELAY_AVERAGE};
|
||||
|
||||
// a kind of increasing backoff within min/max bounds
|
||||
uint64_t get_relay_delay(time_t now, time_t received)
|
||||
{
|
||||
@@ -311,14 +309,8 @@ namespace cryptonote
|
||||
|
||||
if (meta.upgrade_relay_method(tx_relay) || !existing_tx) // synchronize with embargo timer or stem/fluff out-of-order messages
|
||||
{
|
||||
using clock = std::chrono::system_clock;
|
||||
auto last_relayed_time = std::numeric_limits<decltype(meta.last_relayed_time)>::max();
|
||||
if (tx_relay == relay_method::forward)
|
||||
last_relayed_time = clock::to_time_t(clock::now() + crypto::random_poisson_seconds{forward_delay_average}());
|
||||
// else the `set_relayed` function will adjust the time accordingly later
|
||||
|
||||
//update transactions container
|
||||
meta.last_relayed_time = last_relayed_time;
|
||||
meta.last_relayed_time = std::numeric_limits<decltype(meta.last_relayed_time)>::max();
|
||||
meta.receive_time = receive_time;
|
||||
meta.weight = tx_weight;
|
||||
meta.fee = fee;
|
||||
@@ -349,7 +341,7 @@ namespace cryptonote
|
||||
tvc.m_added_to_pool = true;
|
||||
|
||||
static_assert(unsigned(relay_method::none) == 0, "expected relay_method::none value to be zero");
|
||||
if(meta.fee > 0 && tx_relay != relay_method::forward)
|
||||
if(meta.fee > 0)
|
||||
tvc.m_relay = tx_relay;
|
||||
}
|
||||
|
||||
@@ -622,7 +614,7 @@ namespace cryptonote
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
|
||||
m_blockchain.for_all_txpool_txes([this, &hashes, &txes](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref*) {
|
||||
m_blockchain.for_all_txpool_txes([this, &hashes, &txes](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata*) {
|
||||
const auto tx_relay_method = meta.get_relay_method();
|
||||
if (tx_relay_method != relay_method::block && tx_relay_method != relay_method::fluff)
|
||||
return true;
|
||||
@@ -670,7 +662,7 @@ namespace cryptonote
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
std::list<std::pair<crypto::hash, uint64_t>> remove;
|
||||
m_blockchain.for_all_txpool_txes([this, &remove](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref*) {
|
||||
m_blockchain.for_all_txpool_txes([this, &remove](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata*) {
|
||||
uint64_t tx_age = time(nullptr) - meta.receive_time;
|
||||
|
||||
if((tx_age > CRYPTONOTE_MEMPOOL_TX_LIVETIME && !meta.kept_by_block) ||
|
||||
@@ -730,46 +722,28 @@ namespace cryptonote
|
||||
//TODO: investigate whether boolean return is appropriate
|
||||
bool tx_memory_pool::get_relayable_transactions(std::vector<std::tuple<crypto::hash, cryptonote::blobdata, relay_method>> &txs) const
|
||||
{
|
||||
std::vector<std::pair<crypto::hash, txpool_tx_meta_t>> change_timestamps;
|
||||
const uint64_t now = time(NULL);
|
||||
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
LockedTXN lock(m_blockchain.get_db());
|
||||
const uint64_t now = time(NULL);
|
||||
txs.reserve(m_blockchain.get_txpool_tx_count());
|
||||
m_blockchain.for_all_txpool_txes([this, now, &txs, &change_timestamps](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *){
|
||||
m_blockchain.for_all_txpool_txes([this, now, &txs](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *){
|
||||
// 0 fee transactions are never relayed
|
||||
if(!meta.pruned && meta.fee > 0 && !meta.do_not_relay)
|
||||
{
|
||||
const relay_method tx_relay = meta.get_relay_method();
|
||||
switch (tx_relay)
|
||||
{
|
||||
case relay_method::stem:
|
||||
case relay_method::forward:
|
||||
if (meta.last_relayed_time > now)
|
||||
return true; // continue to next tx
|
||||
change_timestamps.emplace_back(txid, meta);
|
||||
break;
|
||||
default:
|
||||
case relay_method::none:
|
||||
return true;
|
||||
case relay_method::local:
|
||||
case relay_method::fluff:
|
||||
case relay_method::block:
|
||||
if (now - meta.last_relayed_time <= get_relay_delay(now, meta.receive_time))
|
||||
return true; // continue to next tx
|
||||
break;
|
||||
}
|
||||
if (!meta.dandelionpp_stem && now - meta.last_relayed_time <= get_relay_delay(now, meta.receive_time))
|
||||
return true;
|
||||
if (meta.dandelionpp_stem && meta.last_relayed_time < now) // for dandelion++ stem, this value is the embargo timeout
|
||||
return true;
|
||||
|
||||
// if the tx is older than half the max lifetime, we don't re-relay it, to avoid a problem
|
||||
// mentioned by smooth where nodes would flush txes at slightly different times, causing
|
||||
// flushed txes to be re-added when received from a node which was just about to flush it
|
||||
uint64_t max_age = (tx_relay == relay_method::block) ? CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME : CRYPTONOTE_MEMPOOL_TX_LIVETIME;
|
||||
uint64_t max_age = meta.kept_by_block ? CRYPTONOTE_MEMPOOL_TX_FROM_ALT_BLOCK_LIVETIME : CRYPTONOTE_MEMPOOL_TX_LIVETIME;
|
||||
if (now - meta.receive_time <= max_age / 2)
|
||||
{
|
||||
try
|
||||
{
|
||||
txs.emplace_back(txid, m_blockchain.get_txpool_tx_blob(txid, relay_category::all), tx_relay);
|
||||
txs.emplace_back(txid, m_blockchain.get_txpool_tx_blob(txid, relay_category::all), meta.get_relay_method());
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
@@ -780,18 +754,6 @@ namespace cryptonote
|
||||
}
|
||||
return true;
|
||||
}, false, relay_category::relayable);
|
||||
|
||||
for (auto& elem : change_timestamps)
|
||||
{
|
||||
/* These transactions are still in forward or stem state, so the field
|
||||
represents the next time a relay should be attempted. Will be
|
||||
overwritten when the state is upgraded to stem, fluff or block. This
|
||||
function is only called every ~2 minutes, so this resetting should be
|
||||
unnecessary, but is primarily a precaution against potential changes
|
||||
to the callback routines. */
|
||||
elem.second.last_relayed_time = now + get_relay_delay(now, elem.second.receive_time);
|
||||
m_blockchain.update_txpool_tx(elem.first, elem.second);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
@@ -844,7 +806,7 @@ namespace cryptonote
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
const relay_category category = include_sensitive ? relay_category::all : relay_category::broadcasted;
|
||||
txs.reserve(m_blockchain.get_txpool_tx_count(include_sensitive));
|
||||
m_blockchain.for_all_txpool_txes([&txs](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){
|
||||
m_blockchain.for_all_txpool_txes([&txs](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){
|
||||
transaction tx;
|
||||
if (!(meta.pruned ? parse_and_validate_tx_base_from_blob(*bd, tx) : parse_and_validate_tx_from_blob(*bd, tx)))
|
||||
{
|
||||
@@ -864,7 +826,7 @@ namespace cryptonote
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
const relay_category category = include_sensitive ? relay_category::all : relay_category::broadcasted;
|
||||
txs.reserve(m_blockchain.get_txpool_tx_count(include_sensitive));
|
||||
m_blockchain.for_all_txpool_txes([&txs](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){
|
||||
m_blockchain.for_all_txpool_txes([&txs](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){
|
||||
txs.push_back(txid);
|
||||
return true;
|
||||
}, false, category);
|
||||
@@ -877,7 +839,7 @@ namespace cryptonote
|
||||
const uint64_t now = time(NULL);
|
||||
const relay_category category = include_sensitive ? relay_category::all : relay_category::broadcasted;
|
||||
backlog.reserve(m_blockchain.get_txpool_tx_count(include_sensitive));
|
||||
m_blockchain.for_all_txpool_txes([&backlog, now](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){
|
||||
m_blockchain.for_all_txpool_txes([&backlog, now](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){
|
||||
backlog.push_back({meta.weight, meta.fee, meta.receive_time - now});
|
||||
return true;
|
||||
}, false, category);
|
||||
@@ -893,7 +855,7 @@ namespace cryptonote
|
||||
stats.txs_total = m_blockchain.get_txpool_tx_count(include_sensitive);
|
||||
std::vector<uint32_t> weights;
|
||||
weights.reserve(stats.txs_total);
|
||||
m_blockchain.for_all_txpool_txes([&stats, &weights, now, &agebytes](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){
|
||||
m_blockchain.for_all_txpool_txes([&stats, &weights, now, &agebytes](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){
|
||||
weights.push_back(meta.weight);
|
||||
stats.bytes_total += meta.weight;
|
||||
if (!stats.bytes_min || meta.weight < stats.bytes_min)
|
||||
@@ -978,10 +940,10 @@ namespace cryptonote
|
||||
const size_t count = m_blockchain.get_txpool_tx_count(include_sensitive_data);
|
||||
tx_infos.reserve(count);
|
||||
key_image_infos.reserve(count);
|
||||
m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos, include_sensitive_data](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){
|
||||
m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos, include_sensitive_data](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){
|
||||
tx_info txi;
|
||||
txi.id_hash = epee::string_tools::pod_to_hex(txid);
|
||||
txi.tx_blob = blobdata(bd->data(), bd->size());
|
||||
txi.tx_blob = *bd;
|
||||
transaction tx;
|
||||
if (!(meta.pruned ? parse_and_validate_tx_base_from_blob(*bd, tx) : parse_and_validate_tx_from_blob(*bd, tx)))
|
||||
{
|
||||
@@ -1035,7 +997,7 @@ namespace cryptonote
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
tx_infos.reserve(m_blockchain.get_txpool_tx_count());
|
||||
key_image_infos.reserve(m_blockchain.get_txpool_tx_count());
|
||||
m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){
|
||||
m_blockchain.for_all_txpool_txes([&tx_infos, key_image_infos](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd){
|
||||
cryptonote::rpc::tx_in_pool txi;
|
||||
txi.tx_hash = txid;
|
||||
if (!(meta.pruned ? parse_and_validate_tx_base_from_blob(*bd, txi.tx) : parse_and_validate_tx_from_blob(*bd, txi.tx)))
|
||||
@@ -1299,7 +1261,7 @@ namespace cryptonote
|
||||
txpool_tx_meta_t meta;
|
||||
if (!m_blockchain.get_txpool_tx_meta(txid, meta))
|
||||
{
|
||||
MDEBUG("Failed to find tx meta in txpool");
|
||||
MERROR("Failed to find tx meta in txpool");
|
||||
// continue, not fatal
|
||||
continue;
|
||||
}
|
||||
@@ -1331,7 +1293,7 @@ namespace cryptonote
|
||||
std::stringstream ss;
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
m_blockchain.for_all_txpool_txes([&ss, short_format](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *txblob) {
|
||||
m_blockchain.for_all_txpool_txes([&ss, short_format](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *txblob) {
|
||||
ss << "id: " << txid << std::endl;
|
||||
if (!short_format) {
|
||||
cryptonote::transaction tx;
|
||||
@@ -1391,7 +1353,7 @@ namespace cryptonote
|
||||
txpool_tx_meta_t meta;
|
||||
if (!m_blockchain.get_txpool_tx_meta(sorted_it->second, meta))
|
||||
{
|
||||
MDEBUG(" failed to find tx meta");
|
||||
MERROR(" failed to find tx meta");
|
||||
continue;
|
||||
}
|
||||
LOG_PRINT_L2("Considering " << sorted_it->second << ", weight " << meta.weight << ", current block weight " << total_weight << "/" << max_total_weight << ", current coinbase " << print_money(best_coinbase) << ", relay method " << (unsigned)meta.get_relay_method());
|
||||
@@ -1509,7 +1471,7 @@ namespace cryptonote
|
||||
std::unordered_set<crypto::hash> remove;
|
||||
|
||||
m_txpool_weight = 0;
|
||||
m_blockchain.for_all_txpool_txes([this, &remove, tx_weight_limit](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref*) {
|
||||
m_blockchain.for_all_txpool_txes([this, &remove, tx_weight_limit](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata*) {
|
||||
m_txpool_weight += meta.weight;
|
||||
if (meta.weight > tx_weight_limit) {
|
||||
LOG_PRINT_L1("Transaction " << txid << " is too big (" << meta.weight << " bytes), removing it from pool");
|
||||
@@ -1581,7 +1543,7 @@ namespace cryptonote
|
||||
for (int pass = 0; pass < 2; ++pass)
|
||||
{
|
||||
const bool kept = pass == 1;
|
||||
bool r = m_blockchain.for_all_txpool_txes([this, &remove, kept](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd) {
|
||||
bool r = m_blockchain.for_all_txpool_txes([this, &remove, kept](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata *bd) {
|
||||
if (!!kept != !!meta.kept_by_block)
|
||||
return true;
|
||||
cryptonote::transaction_prefix tx;
|
||||
|
||||
@@ -935,19 +935,7 @@ namespace cryptonote
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If the txes were received over i2p/tor, the default is to "forward"
|
||||
with a randomized delay to further enhance the "white noise" behavior,
|
||||
potentially making it harder for ISP-level spies to determine which
|
||||
inbound link sent the tx. If the sender disabled "white noise" over
|
||||
i2p/tor, then the sender is "fluffing" (to only outbound) i2p/tor
|
||||
connections with the `dandelionpp_fluff` flag set. The receiver (hidden
|
||||
service) will immediately fluff in that scenario (i.e. this assumes that a
|
||||
sybil spy will be unable to link an IP to an i2p/tor connection). */
|
||||
|
||||
const epee::net_utils::zone zone = context.m_remote_address.get_zone();
|
||||
relay_method tx_relay = zone == epee::net_utils::zone::public_ ?
|
||||
relay_method::stem : relay_method::forward;
|
||||
|
||||
relay_method tx_relay;
|
||||
std::vector<blobdata> stem_txs{};
|
||||
std::vector<blobdata> fluff_txs{};
|
||||
if (arg.dandelionpp_fluff)
|
||||
@@ -956,7 +944,10 @@ namespace cryptonote
|
||||
fluff_txs.reserve(arg.txs.size());
|
||||
}
|
||||
else
|
||||
{
|
||||
tx_relay = relay_method::stem;
|
||||
stem_txs.reserve(arg.txs.size());
|
||||
}
|
||||
|
||||
for (auto& tx : arg.txs)
|
||||
{
|
||||
@@ -979,7 +970,6 @@ namespace cryptonote
|
||||
fluff_txs.push_back(std::move(tx));
|
||||
break;
|
||||
default:
|
||||
case relay_method::forward: // not supposed to happen here
|
||||
case relay_method::none:
|
||||
break;
|
||||
}
|
||||
@@ -1937,8 +1927,8 @@ skip:
|
||||
if (local_stripe == 0)
|
||||
return false;
|
||||
// don't request pre-bulletprooof pruned blocks, we can't reconstruct their weight (yet)
|
||||
static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(HF_VERSION_SMALLER_BP);
|
||||
if (first_block_height < bp_fork_height)
|
||||
static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(8);
|
||||
if (first_block_height + nblocks - 1 < bp_fork_height)
|
||||
return false;
|
||||
// assumes the span size is less or equal to the stripe size
|
||||
bool full_data_needed = tools::get_pruning_stripe(first_block_height, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES) == local_stripe
|
||||
@@ -2116,7 +2106,7 @@ skip:
|
||||
skip_unneeded_hashes(context, false);
|
||||
|
||||
const uint64_t first_block_height = context.m_last_response_height - context.m_needed_objects.size() + 1;
|
||||
static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(HF_VERSION_SMALLER_BP);
|
||||
static const uint64_t bp_fork_height = m_core.get_earliest_ideal_height_for_version(8);
|
||||
bool sync_pruned_blocks = m_sync_pruned_blocks && first_block_height >= bp_fork_height && m_core.get_blockchain_pruning_seed();
|
||||
span = m_block_queue.reserve_span(first_block_height, context.m_last_response_height, count_limit, context.m_connection_id, sync_pruned_blocks, m_core.get_blockchain_pruning_seed(), context.m_pruning_seed, context.m_remote_blockchain_height, context.m_needed_objects);
|
||||
MDEBUG(context << " span from " << first_block_height << ": " << span.first << "/" << span.second);
|
||||
@@ -2347,7 +2337,8 @@ skip:
|
||||
MGINFO_YELLOW(ENDL << "**********************************************************************" << ENDL
|
||||
<< "You are now synchronized with the network. You may now start wownero-wallet-cli." << ENDL
|
||||
<< ENDL
|
||||
<< "Use the \"help\" command to see the list of available commands." << ENDL
|
||||
<< "Use the \"help\" command to see a simplified list of available commands." << ENDL
|
||||
<< "Use the \"help_advanced\" command to see an advanced list of available commands." << ENDL
|
||||
<< "**********************************************************************");
|
||||
m_sync_timer.pause();
|
||||
if (ELPP->vRegistry()->allowed(el::Level::Info, "sync-info"))
|
||||
|
||||
@@ -37,7 +37,6 @@ namespace cryptonote
|
||||
{
|
||||
none = 0, //!< Received via RPC with `do_not_relay` set
|
||||
local, //!< Received via RPC; trying to send over i2p/tor, etc.
|
||||
forward, //!< Received over i2p/tor; timer delayed before ipv4/6 public broadcast
|
||||
stem, //!< Received/send over network using Dandelion++ stem
|
||||
fluff, //!< Received/sent over network using Dandelion++ fluff
|
||||
block //!< Received in block, takes precedence over others
|
||||
|
||||
@@ -357,15 +357,11 @@ namespace levin
|
||||
return true;
|
||||
});
|
||||
|
||||
/* Always send with `fluff` flag, even over i2p/tor. The hidden service
|
||||
will disable the forwarding delay and immediately fluff. The i2p/tor
|
||||
network is therefore replacing the sybil protection of Dandelion++.
|
||||
Dandelion++ stem phase over i2p/tor is also worth investigating
|
||||
(with/without "noise"?). */
|
||||
// Always send txs in stem mode over i2p/tor, see comments in `send_txs` below.
|
||||
for (auto& connection : connections)
|
||||
{
|
||||
std::sort(connection.first.begin(), connection.first.end()); // don't leak receive order
|
||||
make_payload_send_txs(*zone_->p2p, std::move(connection.first), connection.second, zone_->pad_txs, true);
|
||||
make_payload_send_txs(*zone_->p2p, std::move(connection.first), connection.second, zone_->pad_txs, zone_->is_public);
|
||||
}
|
||||
|
||||
if (next_flush != std::chrono::steady_clock::time_point::max())
|
||||
@@ -815,11 +811,12 @@ namespace levin
|
||||
case relay_method::block:
|
||||
return false;
|
||||
case relay_method::stem:
|
||||
case relay_method::forward:
|
||||
tx_relay = relay_method::fluff; // don't set stempool embargo when skipping to fluff
|
||||
/* fallthrough */
|
||||
case relay_method::local:
|
||||
if (zone_->is_public)
|
||||
{
|
||||
// this will change a local/forward tx to stem or fluff ...
|
||||
// this will change a local tx to stem or fluff ...
|
||||
zone_->strand.dispatch(
|
||||
dandelionpp_notify{zone_, std::addressof(core), std::move(txs), source}
|
||||
);
|
||||
@@ -827,11 +824,6 @@ namespace levin
|
||||
}
|
||||
/* fallthrough */
|
||||
case relay_method::fluff:
|
||||
/* If sending stem/forward/local txes over non public networks,
|
||||
continue to claim that relay mode even though it used the "fluff"
|
||||
routine. A "fluff" over i2p/tor is not the same as a "fluff" over
|
||||
ipv4/6. Marking it as "fluff" here will make the tx immediately
|
||||
visible externally from this node, which is not desired. */
|
||||
core.on_transactions_relayed(epee::to_span(txs), tx_relay);
|
||||
zone_->strand.dispatch(fluff_notify{zone_, std::move(txs), source});
|
||||
break;
|
||||
|
||||
@@ -88,7 +88,6 @@ target_link_libraries(daemon
|
||||
${Boost_REGEX_LIBRARY}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${ZMQ_LIB}
|
||||
${GNU_READLINE_LIBRARY}
|
||||
${EXTRA_LIBRARIES}
|
||||
${Blocks})
|
||||
|
||||
@@ -121,10 +121,6 @@ namespace daemon_args
|
||||
return val;
|
||||
}
|
||||
};
|
||||
const command_line::arg_descriptor<std::vector<std::string>> arg_zmq_pub = {
|
||||
"zmq-pub"
|
||||
, "Address for ZMQ pub - tcp://ip:port or ipc://path"
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<bool> arg_zmq_rpc_disabled = {
|
||||
"no-zmq"
|
||||
|
||||
@@ -57,12 +57,6 @@ t_command_server::t_command_server(
|
||||
, "help [<command>]"
|
||||
, "Show the help section or the documentation about a <command>."
|
||||
);
|
||||
m_command_lookup.set_handler(
|
||||
"apropos"
|
||||
, std::bind(&t_command_server::apropos, this, p::_1)
|
||||
, "apropos <keyword> [<keyword> ...]"
|
||||
, "Search all command descriptions for keyword(s)."
|
||||
);
|
||||
m_command_lookup.set_handler(
|
||||
"print_height"
|
||||
, std::bind(&t_command_parser_executor::print_height, &m_parser, p::_1)
|
||||
@@ -355,7 +349,7 @@ bool t_command_server::start_handling(std::function<void(void)> exit_handler)
|
||||
{
|
||||
if (m_is_rpc) return false;
|
||||
|
||||
m_command_lookup.start_handling("", "Use \"help\" to list all commands and their usage\n", exit_handler);
|
||||
m_command_lookup.start_handling("", get_commands_str(), exit_handler);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -380,33 +374,6 @@ bool t_command_server::help(const std::vector<std::string>& args)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool t_command_server::apropos(const std::vector<std::string>& args)
|
||||
{
|
||||
if (args.empty())
|
||||
{
|
||||
std::cout << "Missing keyword" << std::endl;
|
||||
return true;
|
||||
}
|
||||
const std::vector<std::string>& command_list = m_command_lookup.get_command_list(args);
|
||||
if (command_list.empty())
|
||||
{
|
||||
std::cout << "Nothing found" << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
for(auto const& command:command_list)
|
||||
{
|
||||
std::vector<std::string> cmd;
|
||||
cmd.push_back(command);
|
||||
std::pair<std::string, std::string> documentation = m_command_lookup.get_documentation(cmd);
|
||||
std::cout << " " << documentation.first << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string t_command_server::get_commands_str()
|
||||
{
|
||||
std::stringstream ss;
|
||||
@@ -415,7 +382,7 @@ std::string t_command_server::get_commands_str()
|
||||
std::string usage = m_command_lookup.get_usage();
|
||||
boost::replace_all(usage, "\n", "\n ");
|
||||
usage.insert(0, " ");
|
||||
ss << usage;
|
||||
ss << usage << std::endl;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,6 @@ public:
|
||||
|
||||
private:
|
||||
bool help(const std::vector<std::string>& args);
|
||||
bool apropos(const std::vector<std::string>& args);
|
||||
|
||||
std::string get_commands_str();
|
||||
std::string get_command_usage(const std::vector<std::string> &args);
|
||||
|
||||
@@ -34,12 +34,9 @@
|
||||
#include "misc_log_ex.h"
|
||||
#include "daemon/daemon.h"
|
||||
#include "rpc/daemon_handler.h"
|
||||
#include "rpc/zmq_pub.h"
|
||||
#include "rpc/zmq_server.h"
|
||||
|
||||
#include "common/password.h"
|
||||
#include "common/util.h"
|
||||
#include "cryptonote_basic/events.h"
|
||||
#include "daemon/core.h"
|
||||
#include "daemon/p2p.h"
|
||||
#include "daemon/protocol.h"
|
||||
@@ -58,17 +55,6 @@ using namespace epee;
|
||||
|
||||
namespace daemonize {
|
||||
|
||||
struct zmq_internals
|
||||
{
|
||||
explicit zmq_internals(t_core& core, t_p2p& p2p)
|
||||
: rpc_handler{core.get(), p2p.get()}
|
||||
, server{rpc_handler}
|
||||
{}
|
||||
|
||||
cryptonote::rpc::DaemonHandler rpc_handler;
|
||||
cryptonote::rpc::ZmqServer server;
|
||||
};
|
||||
|
||||
struct t_internals {
|
||||
private:
|
||||
t_protocol protocol;
|
||||
@@ -76,7 +62,6 @@ public:
|
||||
t_core core;
|
||||
t_p2p p2p;
|
||||
std::vector<std::unique_ptr<t_rpc>> rpcs;
|
||||
std::unique_ptr<zmq_internals> zmq;
|
||||
|
||||
t_internals(
|
||||
boost::program_options::variables_map const & vm
|
||||
@@ -84,7 +69,6 @@ public:
|
||||
: core{vm}
|
||||
, protocol{vm, core, command_line::get_arg(vm, cryptonote::arg_offline)}
|
||||
, p2p{vm, protocol}
|
||||
, zmq{nullptr}
|
||||
{
|
||||
// Handle circular dependencies
|
||||
protocol.set_p2p_endpoint(p2p.get());
|
||||
@@ -101,28 +85,6 @@ public:
|
||||
auto restricted_rpc_port = command_line::get_arg(vm, restricted_rpc_port_arg);
|
||||
rpcs.emplace_back(new t_rpc{vm, core, p2p, true, restricted_rpc_port, "restricted", true});
|
||||
}
|
||||
|
||||
if (!command_line::get_arg(vm, daemon_args::arg_zmq_rpc_disabled))
|
||||
{
|
||||
zmq.reset(new zmq_internals{core, p2p});
|
||||
|
||||
const std::string zmq_port = command_line::get_arg(vm, daemon_args::arg_zmq_rpc_bind_port);
|
||||
const std::string zmq_address = command_line::get_arg(vm, daemon_args::arg_zmq_rpc_bind_ip);
|
||||
|
||||
if (!zmq->server.init_rpc(zmq_address, zmq_port))
|
||||
throw std::runtime_error{"Failed to add TCP socket(" + zmq_address + ":" + zmq_port + ") to ZMQ RPC Server"};
|
||||
|
||||
std::shared_ptr<cryptonote::listener::zmq_pub> shared;
|
||||
const std::vector<std::string> zmq_pub = command_line::get_arg(vm, daemon_args::arg_zmq_pub);
|
||||
if (!zmq_pub.empty() && !(shared = zmq->server.init_pub(epee::to_span(zmq_pub))))
|
||||
throw std::runtime_error{"Failed to initialize zmq_pub"};
|
||||
|
||||
if (shared)
|
||||
{
|
||||
core.get().get_blockchain_storage().add_block_notify(cryptonote::listener::zmq_pub::chain_main{shared});
|
||||
core.get().set_txpool_listener(cryptonote::listener::zmq_pub::txpool_add{shared});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -140,6 +102,9 @@ t_daemon::t_daemon(
|
||||
: mp_internals{new t_internals{vm}},
|
||||
public_rpc_port(public_rpc_port)
|
||||
{
|
||||
zmq_rpc_bind_port = command_line::get_arg(vm, daemon_args::arg_zmq_rpc_bind_port);
|
||||
zmq_rpc_bind_address = command_line::get_arg(vm, daemon_args::arg_zmq_rpc_bind_ip);
|
||||
zmq_rpc_disabled = command_line::get_arg(vm, daemon_args::arg_zmq_rpc_disabled);
|
||||
}
|
||||
|
||||
t_daemon::~t_daemon() = default;
|
||||
@@ -203,8 +168,29 @@ bool t_daemon::run(bool interactive)
|
||||
rpc_commands->start_handling(std::bind(&daemonize::t_daemon::stop_p2p, this));
|
||||
}
|
||||
|
||||
if (mp_internals->zmq)
|
||||
mp_internals->zmq->server.run();
|
||||
cryptonote::rpc::DaemonHandler rpc_daemon_handler(mp_internals->core.get(), mp_internals->p2p.get());
|
||||
|
||||
if (false)
|
||||
{
|
||||
if (false)
|
||||
{
|
||||
LOG_ERROR(std::string("Failed to add TCP Socket (") + zmq_rpc_bind_address
|
||||
+ ":" + zmq_rpc_bind_port + ") to ZMQ RPC Server");
|
||||
|
||||
if (rpc_commands)
|
||||
rpc_commands->stop_handling();
|
||||
|
||||
for(auto& rpc : mp_internals->rpcs)
|
||||
rpc->stop();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
MINFO("Starting ZMQ server...");
|
||||
|
||||
MINFO(std::string("ZMQ server started at ") + zmq_rpc_bind_address
|
||||
+ ":" + zmq_rpc_bind_port + ".");
|
||||
}
|
||||
else
|
||||
MINFO("ZMQ server disabled");
|
||||
|
||||
@@ -219,9 +205,6 @@ bool t_daemon::run(bool interactive)
|
||||
if (rpc_commands)
|
||||
rpc_commands->stop_handling();
|
||||
|
||||
if (mp_internals->zmq)
|
||||
mp_internals->zmq->server.stop();
|
||||
|
||||
for(auto& rpc : mp_internals->rpcs)
|
||||
rpc->stop();
|
||||
MGINFO("Node stopped.");
|
||||
|
||||
@@ -44,6 +44,9 @@ private:
|
||||
private:
|
||||
std::unique_ptr<t_internals> mp_internals;
|
||||
uint16_t public_rpc_port;
|
||||
std::string zmq_rpc_bind_address;
|
||||
std::string zmq_rpc_bind_port;
|
||||
bool zmq_rpc_disabled;
|
||||
public:
|
||||
t_daemon(
|
||||
boost::program_options::variables_map const & vm,
|
||||
|
||||
@@ -154,7 +154,6 @@ int main(int argc, char const * argv[])
|
||||
command_line::add_arg(core_settings, daemon_args::arg_public_node);
|
||||
command_line::add_arg(core_settings, daemon_args::arg_zmq_rpc_bind_ip);
|
||||
command_line::add_arg(core_settings, daemon_args::arg_zmq_rpc_bind_port);
|
||||
command_line::add_arg(core_settings, daemon_args::arg_zmq_pub);
|
||||
command_line::add_arg(core_settings, daemon_args::arg_zmq_rpc_disabled);
|
||||
|
||||
daemonizer::init_options(hidden_options, visible_options);
|
||||
@@ -249,7 +248,7 @@ int main(int argc, char const * argv[])
|
||||
command_line::get_arg(vm, cryptonote::arg_data_dir));
|
||||
|
||||
#ifdef WIN32
|
||||
if (isFat32(data_dir.root_path().c_str()))
|
||||
if (isFat32(data_dir.root_name().c_str()))
|
||||
{
|
||||
MERROR("Data directory resides on FAT32 volume that has 4GiB file size limit, blockchain might get corrupted.");
|
||||
}
|
||||
|
||||
@@ -721,11 +721,10 @@ bool t_rpc_command_executor::print_net_stats()
|
||||
uint64_t average = seconds > 0 ? net_stats_res.total_bytes_in / seconds : 0;
|
||||
uint64_t limit = limit_res.limit_down * 1024; // convert to bytes, as limits are always kB/s
|
||||
double percent = (double)average / (double)limit * 100.0;
|
||||
tools::success_msg_writer() << boost::format("Received %u bytes (%s) in %u packets in %s, average %s/s = %.2f%% of the limit of %s/s")
|
||||
tools::success_msg_writer() << boost::format("Received %u bytes (%s) in %u packets, average %s/s = %.2f%% of the limit of %s/s")
|
||||
% net_stats_res.total_bytes_in
|
||||
% tools::get_human_readable_bytes(net_stats_res.total_bytes_in)
|
||||
% net_stats_res.total_packets_in
|
||||
% tools::get_human_readable_timespan(seconds)
|
||||
% tools::get_human_readable_bytes(average)
|
||||
% percent
|
||||
% tools::get_human_readable_bytes(limit);
|
||||
@@ -733,11 +732,10 @@ bool t_rpc_command_executor::print_net_stats()
|
||||
average = seconds > 0 ? net_stats_res.total_bytes_out / seconds : 0;
|
||||
limit = limit_res.limit_up * 1024;
|
||||
percent = (double)average / (double)limit * 100.0;
|
||||
tools::success_msg_writer() << boost::format("Sent %u bytes (%s) in %u packets in %s, average %s/s = %.2f%% of the limit of %s/s")
|
||||
tools::success_msg_writer() << boost::format("Sent %u bytes (%s) in %u packets, average %s/s = %.2f%% of the limit of %s/s")
|
||||
% net_stats_res.total_bytes_out
|
||||
% tools::get_human_readable_bytes(net_stats_res.total_bytes_out)
|
||||
% net_stats_res.total_packets_out
|
||||
% tools::get_human_readable_timespan(seconds)
|
||||
% tools::get_human_readable_bytes(average)
|
||||
% percent
|
||||
% tools::get_human_readable_bytes(limit);
|
||||
@@ -1003,9 +1001,7 @@ bool t_rpc_command_executor::print_transaction(crypto::hash transaction_hash,
|
||||
if (1 == res.txs.size())
|
||||
{
|
||||
// only available for new style answers
|
||||
static const std::string empty_hash = epee::string_tools::pod_to_hex(crypto::cn_fast_hash("", 0));
|
||||
// prunable_hash will equal empty_hash when nothing is prunable (mostly when the transaction is coinbase)
|
||||
bool pruned = res.txs.front().prunable_as_hex.empty() && res.txs.front().prunable_hash != epee::string_tools::pod_to_hex(crypto::null_hash) && res.txs.front().prunable_hash != empty_hash;
|
||||
bool pruned = res.txs.front().prunable_as_hex.empty() && res.txs.front().prunable_hash != epee::string_tools::pod_to_hex(crypto::null_hash);
|
||||
if (res.txs.front().in_pool)
|
||||
tools::success_msg_writer() << "Found in pool";
|
||||
else
|
||||
|
||||
@@ -72,7 +72,6 @@ target_link_libraries(device
|
||||
${HIDAPI_LIBRARIES}
|
||||
cncrypto
|
||||
ringct_basic
|
||||
wallet-crypto
|
||||
${OPENSSL_CRYPTO_LIBRARIES}
|
||||
${Boost_SERIALIZATION_LIBRARY}
|
||||
PRIVATE
|
||||
|
||||
@@ -231,10 +231,6 @@ namespace hw {
|
||||
virtual bool mlsag_hash(const rct::keyV &long_message, rct::key &c) = 0;
|
||||
virtual bool mlsag_sign(const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss) = 0;
|
||||
|
||||
virtual bool clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) = 0;
|
||||
virtual bool clsag_hash(const rct::keyV &data, rct::key &hash) = 0;
|
||||
virtual bool clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) = 0;
|
||||
|
||||
virtual bool close_tx(void) = 0;
|
||||
|
||||
virtual bool has_ki_cold_sync(void) const { return false; }
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
|
||||
#include "device_default.hpp"
|
||||
#include "int-util.h"
|
||||
#include "crypto/wallet/crypto.h"
|
||||
#include "cryptonote_basic/account.h"
|
||||
#include "cryptonote_basic/subaddress_index.h"
|
||||
#include "cryptonote_core/cryptonote_tx_utils.h"
|
||||
@@ -121,7 +120,7 @@ namespace hw {
|
||||
/* ======================================================================= */
|
||||
|
||||
bool device_default::derive_subaddress_public_key(const crypto::public_key &out_key, const crypto::key_derivation &derivation, const std::size_t output_index, crypto::public_key &derived_key) {
|
||||
return crypto::wallet::derive_subaddress_public_key(out_key, derivation, output_index,derived_key);
|
||||
return crypto::derive_subaddress_public_key(out_key, derivation, output_index,derived_key);
|
||||
}
|
||||
|
||||
crypto::public_key device_default::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) {
|
||||
@@ -237,7 +236,7 @@ namespace hw {
|
||||
}
|
||||
|
||||
bool device_default::generate_key_derivation(const crypto::public_key &key1, const crypto::secret_key &key2, crypto::key_derivation &derivation) {
|
||||
return crypto::wallet::generate_key_derivation(key1, key2, derivation);
|
||||
return crypto::generate_key_derivation(key1, key2, derivation);
|
||||
}
|
||||
|
||||
bool device_default::derivation_to_scalar(const crypto::key_derivation &derivation, const size_t output_index, crypto::ec_scalar &res){
|
||||
@@ -402,29 +401,6 @@ namespace hw {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_default::clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) {
|
||||
rct::skpkGen(a,aG); // aG = a*G
|
||||
rct::scalarmultKey(aH,H,a); // aH = a*H
|
||||
rct::scalarmultKey(I,H,p); // I = p*H
|
||||
rct::scalarmultKey(D,H,z); // D = z*H
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_default::clsag_hash(const rct::keyV &data, rct::key &hash) {
|
||||
hash = rct::hash_to_scalar(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_default::clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) {
|
||||
rct::key s0_p_mu_P;
|
||||
sc_mul(s0_p_mu_P.bytes,mu_P.bytes,p.bytes);
|
||||
rct::key s0_add_z_mu_C;
|
||||
sc_muladd(s0_add_z_mu_C.bytes,mu_C.bytes,z.bytes,s0_p_mu_P.bytes);
|
||||
sc_mulsub(s.bytes,c.bytes,s0_add_z_mu_C.bytes,a.bytes);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_default::close_tx() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -134,10 +134,6 @@ namespace hw {
|
||||
bool mlsag_hash(const rct::keyV &long_message, rct::key &c) override;
|
||||
bool mlsag_sign(const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss) override;
|
||||
|
||||
bool clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) override;
|
||||
bool clsag_hash(const rct::keyV &data, rct::key &hash) override;
|
||||
bool clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) override;
|
||||
|
||||
bool close_tx(void) override;
|
||||
};
|
||||
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace hw {
|
||||
|
||||
static int device_id = 0;
|
||||
|
||||
#define PROTOCOL_VERSION 4
|
||||
#define PROTOCOL_VERSION 3
|
||||
|
||||
#define INS_NONE 0x00
|
||||
#define INS_RESET 0x02
|
||||
@@ -299,7 +299,6 @@ namespace hw {
|
||||
#define INS_PREFIX_HASH 0x7D
|
||||
#define INS_VALIDATE 0x7C
|
||||
#define INS_MLSAG 0x7E
|
||||
#define INS_CLSAG 0x7F
|
||||
#define INS_CLOSE_TX 0x80
|
||||
|
||||
#define INS_GET_TX_PROOF 0xA0
|
||||
@@ -1549,7 +1548,7 @@ namespace hw {
|
||||
const bool need_additional_txkeys_x = need_additional_txkeys;
|
||||
|
||||
std::vector<crypto::secret_key> additional_tx_keys_x;
|
||||
for (const auto &k: additional_tx_keys) {
|
||||
for (const auto k: additional_tx_keys) {
|
||||
additional_tx_keys_x.push_back(hw::ledger::decrypt(k));
|
||||
}
|
||||
|
||||
@@ -1858,7 +1857,7 @@ namespace hw {
|
||||
|
||||
// ====== Aout, Bout, AKout, C, v, k ======
|
||||
kv_offset = data_offset;
|
||||
if (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG) {
|
||||
if (type==rct::RCTTypeBulletproof2) {
|
||||
C_offset = kv_offset+ (8)*outputs_size;
|
||||
} else {
|
||||
C_offset = kv_offset+ (32+32)*outputs_size;
|
||||
@@ -1875,7 +1874,7 @@ namespace hw {
|
||||
offset = set_command_header(INS_VALIDATE, 0x02, i+1);
|
||||
//options
|
||||
this->buffer_send[offset] = (i==outputs_size-1)? 0x00:0x80 ;
|
||||
this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG)?0x02:0x00;
|
||||
this->buffer_send[offset] |= (type==rct::RCTTypeBulletproof2)?0x02:0x00;
|
||||
offset += 1;
|
||||
//is_subaddress
|
||||
this->buffer_send[offset] = outKeys.is_subaddress;
|
||||
@@ -1896,7 +1895,7 @@ namespace hw {
|
||||
memmove(this->buffer_send+offset, data+C_offset,32);
|
||||
offset += 32;
|
||||
C_offset += 32;
|
||||
if (type==rct::RCTTypeBulletproof2 || type==rct::RCTTypeCLSAG) {
|
||||
if (type==rct::RCTTypeBulletproof2) {
|
||||
//k
|
||||
memset(this->buffer_send+offset, 0, 32);
|
||||
offset += 32;
|
||||
@@ -2122,159 +2121,6 @@ namespace hw {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) {
|
||||
AUTO_LOCK_CMD();
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const rct::key p_x = hw::ledger::decrypt(p);
|
||||
const rct::key z_x = z;
|
||||
rct::key I_x;
|
||||
rct::key D_x;
|
||||
const rct::key H_x = H;
|
||||
rct::key a_x;
|
||||
rct::key aG_x;
|
||||
rct::key aH_x;
|
||||
this->controle_device->clsag_prepare(p_x, z_x, I_x, D_x, H_x, a_x, aG_x, aH_x);
|
||||
#endif
|
||||
|
||||
/*
|
||||
rct::skpkGen(a,aG); // aG = a*G
|
||||
rct::scalarmultKey(aH,H,a); // aH = a*H
|
||||
rct::scalarmultKey(I,H,p); // I = p*H
|
||||
rct::scalarmultKey(D,H,z); // D = z*H
|
||||
*/
|
||||
int offset = set_command_header_noopt(INS_CLSAG, 0x01);
|
||||
//p
|
||||
this->send_secret(p.bytes, offset);
|
||||
//z
|
||||
memmove(this->buffer_send+offset, z.bytes, 32);
|
||||
offset += 32;
|
||||
//H
|
||||
memmove(this->buffer_send+offset, H.bytes, 32);
|
||||
offset += 32;
|
||||
|
||||
this->buffer_send[4] = offset-5;
|
||||
this->length_send = offset;
|
||||
this->exchange();
|
||||
|
||||
offset = 0;
|
||||
//a
|
||||
this->receive_secret(a.bytes, offset);
|
||||
//aG
|
||||
memmove(aG.bytes, this->buffer_recv+offset, 32);
|
||||
offset +=32;
|
||||
//aH
|
||||
memmove(aH.bytes, this->buffer_recv+offset, 32);
|
||||
offset +=32;
|
||||
//I = pH
|
||||
memmove(I.bytes, this->buffer_recv+offset, 32);
|
||||
offset +=32;
|
||||
//D = zH
|
||||
memmove(D.bytes, this->buffer_recv+offset, 32);
|
||||
offset +=32;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
hw::ledger::check32("clsag_prepare", "I", (char*)I_x.bytes, (char*)I.bytes);
|
||||
hw::ledger::check32("clsag_prepare", "D", (char*)D_x.bytes, (char*)D.bytes);
|
||||
hw::ledger::check32("clsag_prepare", "a", (char*)a_x.bytes, (char*)a.bytes);
|
||||
hw::ledger::check32("clsag_prepare", "aG", (char*)aG_x.bytes, (char*)aG.bytes);
|
||||
hw::ledger::check32("clsag_prepare", "aH", (char*)aH_x.bytes, (char*)aH.bytes);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::clsag_hash(const rct::keyV &data, rct::key &hash) {
|
||||
AUTO_LOCK_CMD();
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const rct::keyV data_x = data;
|
||||
rct::key hash_x;
|
||||
this->controle_device->mlsag_hash(data_x, hash_x);
|
||||
#endif
|
||||
|
||||
size_t cnt;
|
||||
int offset;
|
||||
|
||||
cnt = data.size();
|
||||
for (size_t i = 0; i<cnt; i++) {
|
||||
offset = set_command_header(INS_CLSAG, 0x02, i+1);
|
||||
//options
|
||||
this->buffer_send[offset] = (i==(cnt-1))?0x00:0x80; //last
|
||||
offset += 1;
|
||||
//msg part
|
||||
memmove(this->buffer_send+offset, data[i].bytes, 32);
|
||||
offset += 32;
|
||||
|
||||
this->buffer_send[4] = offset-5;
|
||||
this->length_send = offset;
|
||||
this->exchange();
|
||||
}
|
||||
|
||||
//c/hash
|
||||
memmove(hash.bytes, &this->buffer_recv[0], 32);
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
hw::ledger::check32("mlsag_hash", "hash", (char*)hash_x.bytes, (char*)hash.bytes);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool device_ledger::clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) {
|
||||
AUTO_LOCK_CMD();
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const rct::key c_x = c;
|
||||
const rct::key a_x = hw::ledger::decrypt(a);
|
||||
const rct::key p_x = hw::ledger::decrypt(p);
|
||||
const rct::key z_x = z;
|
||||
const rct::key mu_P_x = mu_P;
|
||||
const rct::key mu_C_x = mu_C;
|
||||
rct::key s_x;
|
||||
this->controle_device->clsag_sign(c_x, a_x, p_x, z_x, mu_P_x, mu_C_x, s_x);
|
||||
#endif
|
||||
|
||||
/*
|
||||
rct::key s0_p_mu_P;
|
||||
sc_mul(s0_p_mu_P.bytes,mu_P.bytes,p.bytes);
|
||||
rct::key s0_add_z_mu_C;
|
||||
sc_muladd(s0_add_z_mu_C.bytes,mu_C.bytes,z.bytes,s0_p_mu_P.bytes);
|
||||
sc_mulsub(s.bytes,c.bytes,s0_add_z_mu_C.bytes,a.bytes);
|
||||
*/
|
||||
|
||||
int offset = set_command_header_noopt(INS_CLSAG, 0x03);
|
||||
|
||||
//c
|
||||
//discard, unse internal one
|
||||
//a
|
||||
this->send_secret(a.bytes, offset);
|
||||
//p
|
||||
this->send_secret(p.bytes, offset);
|
||||
//z
|
||||
memmove(this->buffer_send+offset, z.bytes, 32);
|
||||
offset += 32;
|
||||
//mu_P
|
||||
memmove(this->buffer_send+offset, mu_P.bytes, 32);
|
||||
offset += 32;
|
||||
//mu_C
|
||||
memmove(this->buffer_send+offset, mu_C.bytes, 32);
|
||||
offset += 32;
|
||||
|
||||
this->buffer_send[4] = offset-5;
|
||||
this->length_send = offset;
|
||||
this->exchange();
|
||||
|
||||
offset = 0;
|
||||
//s
|
||||
memmove(s.bytes, this->buffer_recv+offset, 32);
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
hw::ledger::check32("clsag_sign", "s", (char*)s_x.bytes, (char*)s.bytes);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool device_ledger::close_tx() {
|
||||
AUTO_LOCK_CMD();
|
||||
send_simple(INS_CLOSE_TX);
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace hw {
|
||||
|
||||
/* Minimal supported version */
|
||||
#define MINIMAL_APP_VERSION_MAJOR 1
|
||||
#define MINIMAL_APP_VERSION_MINOR 6
|
||||
#define MINIMAL_APP_VERSION_MICRO 0
|
||||
#define MINIMAL_APP_VERSION_MINOR 3
|
||||
#define MINIMAL_APP_VERSION_MICRO 1
|
||||
|
||||
#define VERSION(M,m,u) ((M)<<16|(m)<<8|(u))
|
||||
#define VERSION_MAJOR(v) (((v)>>16)&0xFF)
|
||||
@@ -297,11 +297,6 @@ namespace hw {
|
||||
bool mlsag_hash(const rct::keyV &long_message, rct::key &c) override;
|
||||
bool mlsag_sign( const rct::key &c, const rct::keyV &xx, const rct::keyV &alpha, const size_t rows, const size_t dsRows, rct::keyV &ss) override;
|
||||
|
||||
bool clsag_prepare(const rct::key &p, const rct::key &z, rct::key &I, rct::key &D, const rct::key &H, rct::key &a, rct::key &aG, rct::key &aH) override;
|
||||
bool clsag_hash(const rct::keyV &data, rct::key &hash) override;
|
||||
bool clsag_sign(const rct::key &c, const rct::key &a, const rct::key &p, const rct::key &z, const rct::key &mu_P, const rct::key &mu_C, rct::key &s) override;
|
||||
|
||||
|
||||
bool close_tx(void) override;
|
||||
|
||||
};
|
||||
|
||||
@@ -678,10 +678,8 @@ namespace trezor {
|
||||
throw exc::TrezorException("Trezor firmware 2.0.10 and lower are not supported. Please update.");
|
||||
}
|
||||
|
||||
// default client version, higher versions check will be added
|
||||
unsigned client_version = 1;
|
||||
if (trezor_version >= pack_version(2, 3, 1)){
|
||||
client_version = 3;
|
||||
}
|
||||
|
||||
#ifdef WITH_TREZOR_DEBUGGING
|
||||
// Override client version for tests
|
||||
|
||||
@@ -561,6 +561,11 @@ namespace tx {
|
||||
assign_to_repeatable(tsx_data.mutable_minor_indices(), tx.subaddr_indices.begin(), tx.subaddr_indices.end());
|
||||
}
|
||||
|
||||
// TODO: use HF_VERSION_CLSAG after CLSAG is merged
|
||||
if (tsx_data.hard_fork() >= 13){
|
||||
throw exc::ProtocolException("CLSAG is not yet implemented");
|
||||
}
|
||||
|
||||
// Rsig decision
|
||||
auto rsig_data = tsx_data.mutable_rsig_data();
|
||||
m_ct.rsig_type = get_rsig_type(tx.rct_config, tx.splitted_dsts.size());
|
||||
@@ -1012,24 +1017,14 @@ namespace tx {
|
||||
}
|
||||
}
|
||||
|
||||
if (m_ct.rv->type == rct::RCTTypeCLSAG){
|
||||
m_ct.rv->p.CLSAGs.reserve(m_ct.signatures.size());
|
||||
for (size_t i = 0; i < m_ct.signatures.size(); ++i) {
|
||||
rct::clsag clsag;
|
||||
if (!cn_deserialize(m_ct.signatures[i], clsag)) {
|
||||
throw exc::ProtocolException("Cannot deserialize clsag[i]");
|
||||
}
|
||||
m_ct.rv->p.CLSAGs.push_back(clsag);
|
||||
}
|
||||
} else {
|
||||
m_ct.rv->p.MGs.reserve(m_ct.signatures.size());
|
||||
for (size_t i = 0; i < m_ct.signatures.size(); ++i) {
|
||||
rct::mgSig mg;
|
||||
if (!cn_deserialize(m_ct.signatures[i], mg)) {
|
||||
throw exc::ProtocolException("Cannot deserialize mg[i]");
|
||||
}
|
||||
m_ct.rv->p.MGs.push_back(mg);
|
||||
// CLSAG support comes here once it is merged to the Monero
|
||||
m_ct.rv->p.MGs.reserve(m_ct.signatures.size());
|
||||
for(size_t i = 0; i < m_ct.signatures.size(); ++i) {
|
||||
rct::mgSig mg;
|
||||
if (!cn_deserialize(m_ct.signatures[i], mg)) {
|
||||
throw exc::ProtocolException("Cannot deserialize mg[i]");
|
||||
}
|
||||
m_ct.rv->p.MGs.push_back(mg);
|
||||
}
|
||||
|
||||
m_ct.tx.rct_signatures = *(m_ct.rv);
|
||||
|
||||
@@ -309,7 +309,7 @@ namespace tx {
|
||||
throw std::invalid_argument("RV not initialized");
|
||||
}
|
||||
auto tp = m_ct.rv->type;
|
||||
return tp == rct::RCTTypeBulletproof || tp == rct::RCTTypeBulletproof2 || tp == rct::RCTTypeCLSAG;
|
||||
return tp == rct::RCTTypeBulletproof || tp == rct::RCTTypeBulletproof2;
|
||||
}
|
||||
|
||||
bool is_offloading() const {
|
||||
|
||||
@@ -41,8 +41,6 @@ const hardfork_t mainnet_hard_forks[] = {
|
||||
{ 13, 114969, 0, 1559292691 },
|
||||
{ 14, 115257, 0, 1559292774 },
|
||||
{ 15, 160777, 0, 1573280497 },
|
||||
{ 16, 253999, 0, 1600576508 },
|
||||
{ 17, 254287, 0, 1600576524 },
|
||||
};
|
||||
const size_t num_mainnet_hard_forks = sizeof(mainnet_hard_forks) / sizeof(mainnet_hard_forks[0]);
|
||||
|
||||
@@ -56,8 +54,7 @@ const hardfork_t testnet_hard_forks[] = {
|
||||
{ 13, 30, 0, 1559292691 },
|
||||
{ 14, 35, 0, 1559292774 },
|
||||
{ 15, 40, 0, 1573280497 },
|
||||
{ 16, 45, 0, 1600576508 },
|
||||
{ 17, 50, 0, 1600576524 },
|
||||
{ 16, 45, 0, 1589210508 },
|
||||
};
|
||||
const size_t num_testnet_hard_forks = sizeof(testnet_hard_forks) / sizeof(testnet_hard_forks[0]);
|
||||
|
||||
@@ -77,7 +74,5 @@ const hardfork_t stagenet_hard_forks[] = {
|
||||
{ 10, 269000, 0, 1550153694 },
|
||||
{ 11, 269720, 0, 1550225678 },
|
||||
{ 12, 454721, 0, 1571419280 },
|
||||
{ 13, 675405, 0, 1598180817 },
|
||||
{ 14, 676125, 0, 1598180818 },
|
||||
};
|
||||
const size_t num_stagenet_hard_forks = sizeof(stagenet_hard_forks) / sizeof(stagenet_hard_forks[0]);
|
||||
|
||||
@@ -26,11 +26,11 @@
|
||||
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
set(net_sources dandelionpp.cpp error.cpp http.cpp i2p_address.cpp parse.cpp socks.cpp
|
||||
socks_connect.cpp tor_address.cpp zmq.cpp)
|
||||
set(net_headers dandelionpp.h error.h http.cpp i2p_address.h parse.h socks.h socks_connect.h
|
||||
tor_address.h zmq.h)
|
||||
set(net_sources dandelionpp.cpp error.cpp i2p_address.cpp parse.cpp socks.cpp
|
||||
socks_connect.cpp tor_address.cpp)
|
||||
set(net_headers dandelionpp.h error.h i2p_address.h parse.h socks.h socks_connect.h
|
||||
tor_address.h)
|
||||
|
||||
monero_add_library(net ${net_sources} ${net_headers})
|
||||
target_link_libraries(net common epee ${ZMQ_LIB} ${Boost_ASIO_LIBRARY})
|
||||
target_link_libraries(net common epee ${Boost_ASIO_LIBRARY})
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
// Copyright (c) 2020, The Monero Project
|
||||
//
|
||||
// All rights reserved.
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without modification, are
|
||||
// permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
// conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
// of conditions and the following disclaimer in the documentation and/or other
|
||||
// materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its contributors may be
|
||||
// used to endorse or promote products derived from this software without specific
|
||||
// prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "net/http_client.h"
|
||||
|
||||
namespace net
|
||||
{
|
||||
namespace http
|
||||
{
|
||||
|
||||
class client : public epee::net_utils::http::http_simple_client
|
||||
{
|
||||
public:
|
||||
bool set_proxy(const std::string &address) override;
|
||||
};
|
||||
|
||||
class client_factory : public epee::net_utils::http::http_client_factory
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<epee::net_utils::http::abstract_http_client> create() override;
|
||||
};
|
||||
|
||||
} // namespace http
|
||||
} // namespace net
|
||||
@@ -122,39 +122,4 @@ namespace net
|
||||
|
||||
return {epee::net_utils::ipv4_network_subnet{ip, (uint8_t)mask}};
|
||||
}
|
||||
|
||||
expect<boost::asio::ip::tcp::endpoint> get_tcp_endpoint(const boost::string_ref address)
|
||||
{
|
||||
uint16_t port = 0;
|
||||
expect<epee::net_utils::network_address> parsed = get_network_address(address, port);
|
||||
if (!parsed)
|
||||
{
|
||||
return parsed.error();
|
||||
}
|
||||
|
||||
boost::asio::ip::tcp::endpoint result;
|
||||
switch (parsed->get_type_id())
|
||||
{
|
||||
case epee::net_utils::ipv4_network_address::get_type_id():
|
||||
{
|
||||
const auto &ipv4 = parsed->as<epee::net_utils::ipv4_network_address>();
|
||||
result = boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4(SWAP32BE(ipv4.ip())), ipv4.port());
|
||||
break;
|
||||
}
|
||||
case epee::net_utils::ipv6_network_address::get_type_id():
|
||||
{
|
||||
const auto &ipv6 = parsed->as<epee::net_utils::ipv6_network_address>();
|
||||
result = boost::asio::ip::tcp::endpoint(ipv6.ip(), ipv6.port());
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return make_error_code(net::error::unsupported_address);
|
||||
}
|
||||
if (result.port() == 0)
|
||||
{
|
||||
return make_error_code(net::error::invalid_port);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
#include <cstdint>
|
||||
|
||||
@@ -66,7 +65,5 @@ namespace net
|
||||
*/
|
||||
expect<epee::net_utils::ipv4_network_subnet>
|
||||
get_ipv4_subnet_address(boost::string_ref address, bool allow_implicit_32 = false);
|
||||
|
||||
expect<boost::asio::ip::tcp::endpoint> get_tcp_endpoint(const boost::string_ref address);
|
||||
}
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user