Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab18fea350 | |||
| 36e94231e8 | |||
| 7430b9e7dc | |||
| 6b881af1ac | |||
| 0ea5cc9bd2 | |||
| 6a3902b9a5 | |||
| dfb818a01b | |||
| a96fd84502 | |||
| bf54ddd048 | |||
| 0de147644a | |||
| 39bb22a114 | |||
| 6f80a46afa | |||
| c09054bbf9 | |||
| 7a2148744c | |||
| 72e778a04c | |||
| 331c3e4ba3 | |||
| 369853979a | |||
| c803f6727a | |||
| 85653bcd83 | |||
| e4376eed9e | |||
| 9d6ba37ad4 | |||
| 782e8a3c08 | |||
| c942c2c97b | |||
| 99b97dc389 | |||
| df79eb15e2 | |||
| 97b7a41bfa | |||
| f68e72b2a2 | |||
| c9f73f1c7a | |||
| 3cb7fda428 | |||
| 89a0b31380 | |||
| fce167d7cc | |||
| b2185fe512 | |||
| 2ac8f5b58e | |||
| a4954a9eeb | |||
| 6c084e1fa3 | |||
| 423b6553a1 | |||
| 29c03e2d90 | |||
| 1c26d34a2a | |||
| 1d451a6855 | |||
| 5180610c4b | |||
| 5aae00ac79 | |||
| 103c9733b3 | |||
| cf31136617 | |||
| 61e16307cd | |||
| 7ab32cf13a | |||
| 0ad56647d3 | |||
| 1aad001d96 | |||
| 33fe0e8003 | |||
| b8ed1cbbc9 | |||
| 8bc414bb55 | |||
| 840cd25d27 | |||
| 945665ff70 | |||
| 908ecb3cee | |||
| a492c4e3ab | |||
| 3a3fbc3347 | |||
| 88b80583b8 | |||
| 532d382d56 | |||
| e6f07c0379 | |||
| 6f2ebee8ff | |||
| 1e663e8488 | |||
| 4760f8b49b | |||
| 123c46d331 | |||
| 76b61204d1 | |||
| 306798746e | |||
| 1219c74e80 | |||
| 689dd52a9d | |||
| 95936a3fc3 | |||
| e2c802f6b2 | |||
| 14df8ad7a6 | |||
| 5fa7208ef0 | |||
| fe6ab93fb0 | |||
| 52dcc03068 | |||
| a6df656b4e | |||
| c599b56f2c | |||
| 24813330ec | |||
| fc4e5741ae | |||
| f5086126ca | |||
| b8685bcf24 | |||
| 4d224de6e5 | |||
| 2243318000 | |||
| 240cd780fe | |||
| 0e6b12de78 | |||
| 728409ec6d | |||
| f4a745d3b1 | |||
| d51e3f21f7 | |||
| 209c031b93 | |||
| d4c754923e | |||
| 2909bd199d | |||
| 8a7f692aab | |||
| 3d9f34875c | |||
| 24f3e4c72e | |||
| 665bd8933a | |||
| cf65e5b41b | |||
| 56589ddab8 | |||
| 36527c05bd | |||
| 58892be4ad |
@@ -10,7 +10,7 @@ jobs:
|
||||
with:
|
||||
submodules: recursive
|
||||
- name: update brew and install dependencies
|
||||
run: brew update && brew install boost hidapi zmq libpgm miniupnpc ldns expat libunwind-headers protobuf
|
||||
run: brew update && brew install boost hidapi openssl zmq libpgm miniupnpc ldns expat libunwind-headers protobuf
|
||||
- name: build
|
||||
run: make -j3
|
||||
|
||||
|
||||
+1
-2
@@ -4,8 +4,7 @@
|
||||
branch = monero
|
||||
[submodule "external/miniupnp"]
|
||||
path = external/miniupnp
|
||||
url = https://github.com/monero-project/miniupnp
|
||||
branch = monero
|
||||
url = https://github.com/miniupnp/miniupnp
|
||||
[submodule "external/rapidjson"]
|
||||
path = external/rapidjson
|
||||
url = https://github.com/Tencent/rapidjson
|
||||
|
||||
+17
-11
@@ -43,7 +43,7 @@ if (IOS)
|
||||
INCLUDE(CmakeLists_IOS.txt)
|
||||
endif()
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
message(STATUS "CMake version ${CMAKE_VERSION}")
|
||||
|
||||
project(monero)
|
||||
@@ -57,6 +57,14 @@ endif()
|
||||
|
||||
enable_language(C ASM)
|
||||
|
||||
# Require C11/C++11 and disable extensions for all targets
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 14)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
function (die msg)
|
||||
if (NOT WIN32)
|
||||
string(ASCII 27 Esc)
|
||||
@@ -493,7 +501,7 @@ if (CMAKE_SYSTEM_NAME MATCHES "(SunOS|Solaris)")
|
||||
endif ()
|
||||
|
||||
if (APPLE AND NOT IOS)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=x86-64 -fvisibility=default -std=c++11")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=default")
|
||||
if (NOT OPENSSL_ROOT_DIR)
|
||||
EXECUTE_PROCESS(COMMAND brew --prefix openssl
|
||||
OUTPUT_VARIABLE OPENSSL_ROOT_DIR
|
||||
@@ -654,7 +662,7 @@ else()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${ARCH_FLAG}")
|
||||
|
||||
set(WARNINGS "-Wall -Wextra -Wpointer-arith -Wundef -Wvla -Wwrite-strings -Wno-error=extra -Wno-error=deprecated-declarations -Wno-unused-parameter -Wno-unused-variable -Wno-error=unused-variable -Wno-error=undef -Wno-error=uninitialized")
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
if(ARM)
|
||||
set(WARNINGS "${WARNINGS} -Wno-error=inline-asm")
|
||||
endif()
|
||||
@@ -675,14 +683,14 @@ else()
|
||||
endif()
|
||||
set(C_WARNINGS "-Waggregate-return -Wnested-externs -Wold-style-definition -Wstrict-prototypes")
|
||||
set(CXX_WARNINGS "-Wno-reorder -Wno-missing-field-initializers")
|
||||
try_compile(STATIC_ASSERT_RES "${CMAKE_CURRENT_BINARY_DIR}/static-assert" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-static-assert.c" COMPILE_DEFINITIONS "-std=c11")
|
||||
try_compile(STATIC_ASSERT_RES "${CMAKE_CURRENT_BINARY_DIR}/static-assert" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-static-assert.c" CMAKE_FLAGS -DCMAKE_C_STANDARD=11)
|
||||
if(STATIC_ASSERT_RES)
|
||||
set(STATIC_ASSERT_FLAG "")
|
||||
else()
|
||||
set(STATIC_ASSERT_FLAG "-Dstatic_assert=_Static_assert")
|
||||
endif()
|
||||
|
||||
try_compile(STATIC_ASSERT_CPP_RES "${CMAKE_CURRENT_BINARY_DIR}/static-assert" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-static-assert.cpp" COMPILE_DEFINITIONS "-std=c++11")
|
||||
try_compile(STATIC_ASSERT_CPP_RES "${CMAKE_CURRENT_BINARY_DIR}/static-assert" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/test-static-assert.cpp" CMAKE_FLAGS -DCMAKE_CXX_STANDARD=11)
|
||||
if(STATIC_ASSERT_CPP_RES)
|
||||
set(STATIC_ASSERT_CPP_FLAG "")
|
||||
else()
|
||||
@@ -771,8 +779,8 @@ else()
|
||||
message(STATUS "Using C++ security hardening flags: ${CXX_SECURITY_FLAGS}")
|
||||
message(STATUS "Using linker security hardening flags: ${LD_SECURITY_FLAGS}")
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${C_SECURITY_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${CXX_SECURITY_FLAGS}")
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_FLAG} ${WARNINGS} ${C_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${C_SECURITY_FLAGS}")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_GNU_SOURCE ${MINGW_FLAG} ${STATIC_ASSERT_CPP_FLAG} ${WARNINGS} ${CXX_WARNINGS} ${COVERAGE_FLAGS} ${PIC_FLAG} ${CXX_SECURITY_FLAGS}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${LD_SECURITY_FLAGS} ${LD_BACKCOMPAT_FLAGS}")
|
||||
|
||||
# With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that
|
||||
@@ -890,7 +898,7 @@ else()
|
||||
endif()
|
||||
set(USE_LTO ${USE_LTO_DEFAULT} CACHE BOOL "Use Link-Time Optimization (Release mode only)")
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
||||
# There is a clang bug that does not allow to compile code that uses AES-NI intrinsics if -flto is enabled, so explicitly disable
|
||||
set(USE_LTO false)
|
||||
endif()
|
||||
@@ -1037,7 +1045,7 @@ if(ANDROID)
|
||||
set(ATOMIC libatomic.a)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=user-defined-warnings")
|
||||
endif()
|
||||
if(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND ARCH_WIDTH EQUAL "32" AND NOT IOS AND NOT FREEBSD)
|
||||
if(CMAKE_C_COMPILER_ID MATCHES "Clang" AND ARCH_WIDTH EQUAL "32" AND NOT IOS AND NOT FREEBSD)
|
||||
find_library(ATOMIC atomic)
|
||||
if (ATOMIC_FOUND)
|
||||
list(APPEND EXTRA_LIBRARIES ${ATOMIC})
|
||||
@@ -1122,8 +1130,6 @@ option(BUILD_GUI_DEPS "Build GUI dependencies." OFF)
|
||||
option(INSTALL_VENDORED_LIBUNBOUND "Install libunbound binary built from source vendored with this repo." OFF)
|
||||
|
||||
|
||||
CHECK_C_COMPILER_FLAG(-std=c11 HAVE_C11)
|
||||
|
||||
find_package(PythonInterp)
|
||||
find_program(iwyu_tool_path NAMES iwyu_tool.py iwyu_tool)
|
||||
if (iwyu_tool_path AND PYTHONINTERP_FOUND)
|
||||
|
||||
@@ -133,9 +133,9 @@ Dates are provided in the format YYYY-MM-DD.
|
||||
| 1686275 | 2018-10-19 | v9 | v0.13.0.0 | v0.13.0.4 | bulletproofs required
|
||||
| 1788000 | 2019-03-09 | v10 | v0.14.0.0 | v0.14.1.2 | New PoW based on Cryptonight-R, new block weight algorithm, slightly more efficient RingCT format
|
||||
| 1788720 | 2019-03-10 | v11 | v0.14.0.0 | v0.14.1.2 | forbid old RingCT transaction format
|
||||
| 1978433 | 2019-11-30* | v12 | v0.15.0.0 | v0.16.0.0 | New PoW based on RandomX, only allow >= 2 outputs, change to the block median used to calculate penalty, v1 coinbases are forbidden, rct sigs in coinbase forbidden, 10 block lock time for incoming outputs
|
||||
| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.2.3 | New CLSAG transaction format
|
||||
| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.2.3 | forbid old MLSAG transaction format
|
||||
| 1978433 | 2019-11-30 | v12 | v0.15.0.0 | v0.16.0.0 | New PoW based on RandomX, only allow >= 2 outputs, change to the block median used to calculate penalty, v1 coinbases are forbidden, rct sigs in coinbase forbidden, 10 block lock time for incoming outputs
|
||||
| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.3.0 | New CLSAG transaction format
|
||||
| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.3.0 | forbid old MLSAG transaction format
|
||||
| XXXXXXX | XXX-XX-XX | XXX | vX.XX.X.X | vX.XX.X.X | XXX |
|
||||
|
||||
X's indicate that these details have not been determined as of commit date.
|
||||
@@ -161,7 +161,7 @@ library archives (`.a`).
|
||||
|
||||
| Dep | Min. version | Vendored | Debian/Ubuntu pkg | Arch pkg | Void pkg | Fedora pkg | Optional | Purpose |
|
||||
| ------------ | ------------- | -------- | -------------------- | ------------ | ------------------ | ------------------- | -------- | --------------- |
|
||||
| GCC | 4.7.3 | NO | `build-essential` | `base-devel` | `base-devel` | `gcc` | NO | |
|
||||
| GCC | 5 | NO | `build-essential` | `base-devel` | `base-devel` | `gcc` | NO | |
|
||||
| CMake | 3.5 | NO | `cmake` | `cmake` | `cmake` | `cmake` | NO | |
|
||||
| pkg-config | any | NO | `pkg-config` | `base-devel` | `base-devel` | `pkgconf` | NO | |
|
||||
| Boost | 1.58 | NO | `libboost-all-dev` | `boost` | `boost-devel` | `boost-devel` | NO | C++ libraries |
|
||||
@@ -295,7 +295,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch (
|
||||
```bash
|
||||
git clone https://github.com/monero-project/monero.git
|
||||
cd monero
|
||||
git checkout tags/v0.17.2.3
|
||||
git checkout tags/v0.17.3.0
|
||||
```
|
||||
|
||||
* Build:
|
||||
@@ -412,10 +412,10 @@ application.
|
||||
cd monero
|
||||
```
|
||||
|
||||
* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.17.2.3'. If you don't care about the version and just want binaries from master, skip this step:
|
||||
* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.17.3.0'. If you don't care about the version and just want binaries from master, skip this step:
|
||||
|
||||
```bash
|
||||
git checkout v0.17.2.3
|
||||
git checkout v0.17.3.0
|
||||
```
|
||||
|
||||
* If you are on a 64-bit system, run:
|
||||
|
||||
@@ -25,6 +25,8 @@ allows for filtering on: (1) format, (2) context, and (3) event.
|
||||
Includes previously unseen transactions in a block but _not_ the
|
||||
`miner_tx`. Does not "re-publish" after a reorg. Includes `do_not_relay`
|
||||
transactions.
|
||||
* `miner_data` - provides the necessary data to create a custom block template
|
||||
Available only in the `full` context.
|
||||
|
||||
The subscription topics are formatted as `format-context-event`, with prefix
|
||||
matching supported by both Monero and ZMQ. The `format`, `context` and `event`
|
||||
|
||||
@@ -44,7 +44,7 @@ if (CCACHE_FOUND)
|
||||
# Try to compile a test program with ccache, in order to verify if it really works. (needed on exotic setups)
|
||||
set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp")
|
||||
file(WRITE "${TEST_PROJECT}/CMakeLists.txt" [=[
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
project(test)
|
||||
option (CCACHE "")
|
||||
file(WRITE "${CMAKE_SOURCE_DIR}/test.cpp" "int main() { return 0; }")
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
|
||||
function (get_version_tag_from_git GIT)
|
||||
execute_process(COMMAND "${GIT}" rev-parse --short=9 HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
RESULT_VARIABLE RET
|
||||
OUTPUT_VARIABLE COMMIT
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
@@ -49,7 +49,7 @@ function (get_version_tag_from_git GIT)
|
||||
|
||||
# Get all the tags
|
||||
execute_process(COMMAND "${GIT}" tag -l --points-at HEAD
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}
|
||||
RESULT_VARIABLE RET
|
||||
OUTPUT_VARIABLE TAG
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
|
||||
@@ -133,6 +133,11 @@ $(1)_config_env+=$($(1)_config_env_$(host_arch)) $($(1)_config_env_$(host_arch)_
|
||||
$(1)_config_env+=$($(1)_config_env_$(host_os)) $($(1)_config_env_$(host_os)_$(release_type))
|
||||
$(1)_config_env+=$($(1)_config_env_$(host_arch)_$(host_os)) $($(1)_config_env_$(host_arch)_$(host_os)_$(release_type))
|
||||
|
||||
$(1)_build_env+=$$($(1)_build_env_$(release_type))
|
||||
$(1)_build_env+=$($(1)_build_env_$(host_arch)) $($(1)_build_env_$(host_arch)_$(release_type))
|
||||
$(1)_build_env+=$($(1)_build_env_$(host_os)) $($(1)_build_env_$(host_os)_$(release_type))
|
||||
$(1)_build_env+=$($(1)_build_env_$(host_arch)_$(host_os)) $($(1)_build_env_$(host_arch)_$(host_os)_$(release_type))
|
||||
|
||||
$(1)_config_env+=PKG_CONFIG_LIBDIR=$($($(1)_type)_prefix)/lib/pkgconfig
|
||||
$(1)_config_env+=PKG_CONFIG_PATH=$($($(1)_type)_prefix)/share/pkgconfig
|
||||
$(1)_config_env+=PATH="$(build_prefix)/bin:$(PATH)"
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package=hidapi
|
||||
$(package)_version=0.9.0
|
||||
$(package)_version=0.11.0
|
||||
$(package)_download_path=https://github.com/libusb/hidapi/archive
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=630ee1834bdd5c5761ab079fd04f463a89585df8fcae51a7bfe4229b1e02a652
|
||||
$(package)_sha256_hash=391d8e52f2d6a5cf76e2b0c079cfefe25497ba1d4659131297081fc0cd744632
|
||||
$(package)_linux_dependencies=libusb eudev
|
||||
$(package)_patches=missing_win_include.patch
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=--enable-static --disable-shared
|
||||
@@ -16,6 +17,10 @@ $(package)_config_opts_linux+=libusb_CFLAGS=-I$(host_prefix)/include/libusb-1.0
|
||||
$(package)_config_opts_linux+=--with-pic
|
||||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
patch -p1 < $($(package)_patch_dir)/missing_win_include.patch
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
./bootstrap &&\
|
||||
$($(package)_autoconf) $($(package)_config_opts) AR_FLAGS=$($(package)_arflags)
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package=openssl
|
||||
$(package)_version=1.1.1k
|
||||
$(package)_version=1.1.1l
|
||||
$(package)_download_path=https://www.openssl.org/source
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=892a0875b9872acd04a9fde79b1f943075d5ea162415de3047c327df33fbaee5
|
||||
$(package)_sha256_hash=0b7a3e5e59c34827fe0c3a74b7ec8baef302b98fa80088d7f9153aa16fa76bd1
|
||||
$(package)_patches=fix_darwin.patch
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_env=AR="$($(package)_ar)" ARFLAGS=$($(package)_arflags) RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
|
||||
$(package)_config_env_arm_android=ANDROID_NDK_HOME="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
|
||||
$(package)_config_env_aarch64_android=ANDROID_NDK_HOME="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
|
||||
$(package)_build_env_arm_android=ANDROID_NDK_HOME="$(host_prefix)/native"
|
||||
$(package)_build_env_aarch64_android=ANDROID_NDK_HOME="$(host_prefix)/native"
|
||||
$(package)_config_env_android=ANDROID_NDK_HOME="$(host_prefix)/native" PATH="$(host_prefix)/native/bin" CC=clang AR=ar RANLIB=ranlib
|
||||
$(package)_build_env_android=ANDROID_NDK_HOME="$(host_prefix)/native"
|
||||
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl
|
||||
$(package)_config_opts+=no-capieng
|
||||
$(package)_config_opts+=no-dso
|
||||
@@ -51,7 +50,7 @@ endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
sed -i.old 's|"engines", "apps", "test", "util", "tools", "fuzz"|"engines", "tools"|' Configure && \
|
||||
sed -i -e 's|cflags --sysroot.*",|cflags",|' Configurations/15-android.conf
|
||||
patch -p1 < $($(package)_patch_dir)/fix_darwin.patch
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
@@ -59,11 +58,11 @@ define $(package)_config_cmds
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
$(MAKE) -j1 build_libs libcrypto.pc libssl.pc openssl.pc
|
||||
$(MAKE) build_libs
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) -j1 install_sw
|
||||
$(MAKE) DESTDIR=$($(package)_staging_dir) install_sw
|
||||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
packages:=boost openssl zeromq libiconv
|
||||
|
||||
# ccache is useless in gitian builds
|
||||
ifneq ($(GITIAN),1)
|
||||
native_packages := native_ccache
|
||||
endif
|
||||
|
||||
hardware_packages := hidapi protobuf libusb
|
||||
hardware_native_packages := native_protobuf
|
||||
@@ -8,8 +11,8 @@ hardware_native_packages := native_protobuf
|
||||
android_native_packages = android_ndk
|
||||
android_packages = ncurses readline sodium
|
||||
|
||||
darwin_native_packages = native_biplist native_ds_store native_mac_alias $(hardware_native_packages)
|
||||
darwin_packages = sodium ncurses readline $(hardware_packages)
|
||||
darwin_native_packages = $(hardware_native_packages)
|
||||
darwin_packages = ncurses readline sodium $(hardware_packages)
|
||||
|
||||
# not really native...
|
||||
freebsd_native_packages = freebsd_base
|
||||
@@ -31,6 +34,6 @@ mingw32_packages = icu4c sodium $(hardware_packages)
|
||||
mingw32_native_packages = $(hardware_native_packages)
|
||||
|
||||
ifneq ($(build_os),darwin)
|
||||
darwin_native_packages += native_cctools native_cdrkit native_libdmg-hfsplus
|
||||
darwin_native_packages += native_cctools
|
||||
endif
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package=unwind
|
||||
$(package)_version=1.2
|
||||
$(package)_version=1.5.0
|
||||
$(package)_download_path=https://download.savannah.nongnu.org/releases/libunwind
|
||||
$(package)_file_name=lib$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=1de38ffbdc88bd694d10081865871cd2bfbb02ad8ef9e1606aee18d65532b992
|
||||
$(package)_sha256_hash=90337653d92d4a13de590781371c604f9031cdb50520366aa1e3a91e1efb1017
|
||||
$(package)_patches=fix_obj_order.patch
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
@@ -12,7 +12,7 @@ endef
|
||||
define $(package)_config_cmds
|
||||
cp -f $(BASEDIR)/config.guess config/config.guess &&\
|
||||
cp -f $(BASEDIR)/config.sub config/config.sub &&\
|
||||
$($(package)_autoconf) --disable-shared --enable-static AR_FLAGS=$($(package)_arflags)
|
||||
$($(package)_autoconf) --disable-shared --enable-static --disable-tests --disable-documentation AR_FLAGS=$($(package)_arflags)
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package=zeromq
|
||||
$(package)_version=4.1.7
|
||||
$(package)_download_path=https://github.com/zeromq/zeromq4-1/releases/download/v$($(package)_version)/
|
||||
$(package)_version=4.3.4
|
||||
$(package)_download_path=https://github.com/zeromq/libzmq/releases/download/v$($(package)_version)/
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=31c383cfcd3be1dc8a66e448c403029e793687e70473b89c4cc0bd626e7da299
|
||||
$(package)_patches=9114d3957725acd34aa8b8d011585812f3369411.patch 9e6745c12e0b100cd38acecc16ce7db02905e27c.patch ffe62d3398d5e0191f554f61049aa7ec9fc892ae.patch
|
||||
$(package)_sha256_hash=c593001a89f5a85dd2ddf564805deb860e02471171b3f204944857336295c3e5
|
||||
$(package)_patches=06aba27b04c5822cb88a69677382a0f053367143.patch
|
||||
|
||||
define $(package)_set_vars
|
||||
$(package)_config_opts=--without-documentation --disable-shared --without-libsodium --disable-curve
|
||||
@@ -13,10 +13,7 @@ define $(package)_set_vars
|
||||
endef
|
||||
|
||||
define $(package)_preprocess_cmds
|
||||
patch -p1 < $($(package)_patch_dir)/9114d3957725acd34aa8b8d011585812f3369411.patch && \
|
||||
patch -p1 < $($(package)_patch_dir)/9e6745c12e0b100cd38acecc16ce7db02905e27c.patch && \
|
||||
patch -p1 < $($(package)_patch_dir)/ffe62d3398d5e0191f554f61049aa7ec9fc892ae.patch && \
|
||||
./autogen.sh
|
||||
patch -p1 < $($(package)_patch_dir)/06aba27b04c5822cb88a69677382a0f053367143.patch
|
||||
endef
|
||||
|
||||
define $(package)_config_cmds
|
||||
@@ -24,7 +21,7 @@ define $(package)_config_cmds
|
||||
endef
|
||||
|
||||
define $(package)_build_cmds
|
||||
$(MAKE) libzmq.la
|
||||
$(MAKE) src/libzmq.la
|
||||
endef
|
||||
|
||||
define $(package)_stage_cmds
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
From a77b066311da42ed7654e39c0356a3b951b2e296 Mon Sep 17 00:00:00 2001
|
||||
From: selsta <selsta@sent.at>
|
||||
Date: Wed, 10 Nov 2021 02:28:54 +0100
|
||||
Subject: [PATCH] windows: add missing include for mingw32
|
||||
|
||||
---
|
||||
windows/hid.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/windows/hid.c b/windows/hid.c
|
||||
index 24756a4..6d8394c 100644
|
||||
--- a/windows/hid.c
|
||||
+++ b/windows/hid.c
|
||||
@@ -33,6 +33,7 @@ typedef LONG NTSTATUS;
|
||||
#endif
|
||||
|
||||
#ifdef __MINGW32__
|
||||
+#include <devpropdef.h>
|
||||
#include <ntdef.h>
|
||||
#include <winbase.h>
|
||||
#endif
|
||||
@@ -0,0 +1,60 @@
|
||||
From 96ac8f13f4d0ee96baf5724d9f96c44c34b8606c Mon Sep 17 00:00:00 2001
|
||||
From: David Carlier <devnexen@gmail.com>
|
||||
Date: Tue, 24 Aug 2021 22:40:14 +0100
|
||||
Subject: [PATCH] Darwin platform allows to build on releases before
|
||||
Yosemite/ios 8.
|
||||
|
||||
issue #16407 #16408
|
||||
|
||||
Reviewed-by: Paul Dale <pauli@openssl.org>
|
||||
Reviewed-by: Tomas Mraz <tomas@openssl.org>
|
||||
(Merged from https://github.com/openssl/openssl/pull/16409)
|
||||
---
|
||||
crypto/rand/rand_unix.c | 5 +----
|
||||
include/crypto/rand.h | 10 ++++++++++
|
||||
2 files changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/crypto/rand/rand_unix.c b/crypto/rand/rand_unix.c
|
||||
index 43f1069d151d..0f4525106af7 100644
|
||||
--- a/crypto/rand/rand_unix.c
|
||||
+++ b/crypto/rand/rand_unix.c
|
||||
@@ -34,9 +34,6 @@
|
||||
#if defined(__OpenBSD__)
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
-#if defined(__APPLE__)
|
||||
-# include <CommonCrypto/CommonRandom.h>
|
||||
-#endif
|
||||
|
||||
#if defined(OPENSSL_SYS_UNIX) || defined(__DJGPP__)
|
||||
# include <sys/types.h>
|
||||
@@ -381,7 +378,7 @@ static ssize_t syscall_random(void *buf, size_t buflen)
|
||||
if (errno != ENOSYS)
|
||||
return -1;
|
||||
}
|
||||
-# elif defined(__APPLE__)
|
||||
+# elif defined(OPENSSL_APPLE_CRYPTO_RANDOM)
|
||||
if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess)
|
||||
return (ssize_t)buflen;
|
||||
|
||||
diff --git a/include/crypto/rand.h b/include/crypto/rand.h
|
||||
index 5350d3a93119..674f840fd13c 100644
|
||||
--- a/include/crypto/rand.h
|
||||
+++ b/include/crypto/rand.h
|
||||
@@ -20,6 +20,16 @@
|
||||
|
||||
# include <openssl/rand.h>
|
||||
|
||||
+# if defined(__APPLE__) && !defined(OPENSSL_NO_APPLE_CRYPTO_RANDOM)
|
||||
+# include <Availability.h>
|
||||
+# if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000) || \
|
||||
+ (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000)
|
||||
+# define OPENSSL_APPLE_CRYPTO_RANDOM 1
|
||||
+# include <CommonCrypto/CommonCryptoError.h>
|
||||
+# include <CommonCrypto/CommonRandom.h>
|
||||
+# endif
|
||||
+# endif
|
||||
+
|
||||
/* forward declaration */
|
||||
typedef struct rand_pool_st RAND_POOL;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
--- config/ltmain.sh.O 2017-01-13 16:00:54.000000000 +0000
|
||||
+++ config/ltmain.sh 2019-11-17 06:46:51.994402494 +0000
|
||||
@@ -7957,6 +7957,8 @@
|
||||
esac
|
||||
done
|
||||
--- config/ltmain.sh.0 2020-11-10 17:25:26.000000000 +0100
|
||||
+++ config/ltmain.sh 2021-09-11 19:39:36.000000000 +0200
|
||||
@@ -10768,6 +10768,8 @@
|
||||
fi
|
||||
func_to_tool_file "$oldlib" func_convert_file_msys_to_w32
|
||||
tool_oldlib=$func_to_tool_file_result
|
||||
+ oldobjs=`for obj in $oldobjs; do echo $obj; done | sort`
|
||||
+ oldobjs=" `echo $oldobjs`"
|
||||
eval cmds=\"$old_archive_cmds\"
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
From 06aba27b04c5822cb88a69677382a0f053367143 Mon Sep 17 00:00:00 2001
|
||||
From: sabotagebeats <27985126+sabotagebeats@users.noreply.github.com>
|
||||
Date: Thu, 22 Jul 2021 21:53:19 -0700
|
||||
Subject: [PATCH] fix: building libzmq fails with error src/clock.cpp:131:16:
|
||||
error: unused variable 'nsecs_per_usec'
|
||||
|
||||
---
|
||||
src/clock.cpp | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/clock.cpp b/src/clock.cpp
|
||||
index 93da90a8e..63c0100a5 100644
|
||||
--- a/src/clock.cpp
|
||||
+++ b/src/clock.cpp
|
||||
@@ -195,6 +195,7 @@ uint64_t zmq::clock_t::now_us ()
|
||||
|
||||
#else
|
||||
|
||||
+ LIBZMQ_UNUSED (nsecs_per_usec);
|
||||
// Use POSIX gettimeofday function to get precise time.
|
||||
struct timeval tv;
|
||||
int rc = gettimeofday (&tv, NULL);
|
||||
@@ -1,22 +0,0 @@
|
||||
From 9114d3957725acd34aa8b8d011585812f3369411 Mon Sep 17 00:00:00 2001
|
||||
From: Jeroen Ooms <jeroenooms@gmail.com>
|
||||
Date: Tue, 20 Oct 2015 13:10:38 +0200
|
||||
Subject: [PATCH] enable static libraries on mingw
|
||||
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 393505b..e92131a 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -265,7 +265,7 @@ case "${host_os}" in
|
||||
libzmq_dso_visibility="no"
|
||||
|
||||
if test "x$enable_static" = "xyes"; then
|
||||
- AC_MSG_ERROR([Building static libraries is not supported under MinGW32])
|
||||
+ CPPFLAGS="-DZMQ_STATIC"
|
||||
fi
|
||||
|
||||
# Set FD_SETSIZE to 1024
|
||||
@@ -1,22 +0,0 @@
|
||||
From 9e6745c12e0b100cd38acecc16ce7db02905e27c Mon Sep 17 00:00:00 2001
|
||||
From: David Millard <dmillard10@gmail.com>
|
||||
Date: Tue, 10 May 2016 13:53:53 -0700
|
||||
Subject: [PATCH] Fix autotools for static MinGW builds
|
||||
|
||||
---
|
||||
configure.ac | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index 5a0fa14..def6ea7 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -259,7 +259,7 @@ case "${host_os}" in
|
||||
libzmq_dso_visibility="no"
|
||||
|
||||
if test "x$enable_static" = "xyes"; then
|
||||
- CPPFLAGS="-DZMQ_STATIC"
|
||||
+ CPPFLAGS="-DZMQ_STATIC $CPPFLAGS"
|
||||
fi
|
||||
|
||||
# Set FD_SETSIZE to 1024
|
||||
@@ -1,38 +0,0 @@
|
||||
From ffe62d3398d5e0191f554f61049aa7ec9fc892ae Mon Sep 17 00:00:00 2001
|
||||
From: Gregory Lemercier <greglemercier@free.fr>
|
||||
Date: Sun, 7 Oct 2018 18:06:54 +0200
|
||||
Subject: [PATCH] Fix build on arm64 architectures with some strict compilers
|
||||
|
||||
This patch fixes an issue that occurs on 64-bit architetures under
|
||||
strict compiler rules. The code initially checked that the received
|
||||
size stored in 'uint64_t' was not bigger than the max value of a
|
||||
'size_t' variable, which is legitimate on 32-bit architectures where
|
||||
'size_t' variables are stored on 32 bits. On 64-bit architectures,
|
||||
this test no longer makes sense since 'uint64_t' and 'size_t' types
|
||||
have the same size. The issue is fixed by ignoring this portion
|
||||
of code when built for arm64.
|
||||
---
|
||||
src/v1_decoder.cpp | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/v1_decoder.cpp b/src/v1_decoder.cpp
|
||||
index b002dc9d..2c8c97a7 100644
|
||||
--- a/src/v1_decoder.cpp
|
||||
+++ b/src/v1_decoder.cpp
|
||||
@@ -114,11 +114,13 @@ int zmq::v1_decoder_t::eight_byte_size_ready ()
|
||||
return -1;
|
||||
}
|
||||
|
||||
+#ifndef __aarch64__
|
||||
// Message size must fit within range of size_t data type.
|
||||
if (payload_length - 1 > std::numeric_limits <size_t>::max ()) {
|
||||
errno = EMSGSIZE;
|
||||
return -1;
|
||||
}
|
||||
+#endif
|
||||
|
||||
const size_t msg_size = static_cast <size_t> (payload_length - 1);
|
||||
|
||||
--
|
||||
2.20.1
|
||||
|
||||
@@ -80,7 +80,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
|
||||
SET(PORT OFF)
|
||||
SET(CMAKE_OSX_SYSROOT "@sdk@/MacOSX10.11.sdk/")
|
||||
SET(CMAKE_OSX_DEPLOYMENT_TARGET "10.08")
|
||||
SET(CMAKE_CXX_STANDARD 11)
|
||||
SET(CMAKE_CXX_STANDARD 14)
|
||||
SET(CMAKE_OSX_ARCHITECTURES "x86_64")
|
||||
SET(LLVM_ENABLE_PIC OFF)
|
||||
SET(LLVM_ENABLE_PIE OFF)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
#set(Boost_DEBUG 1)
|
||||
find_package(Boost COMPONENTS system filesystem thread date_time chrono regex )
|
||||
|
||||
@@ -560,7 +560,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
{ // LOCK: chunking
|
||||
epee::critical_region_t<decltype(m_chunking_lock)> send_guard(m_chunking_lock); // *** critical ***
|
||||
|
||||
MDEBUG("do_send() will SPLIT into small chunks, from packet="<<message_size<<" B for ptr="<<message_data);
|
||||
MDEBUG("do_send() will SPLIT into small chunks, from packet="<<message_size<<" B for ptr="<<(const void*)message_data);
|
||||
// 01234567890
|
||||
// ^^^^ (pos=0, len=4) ; pos:=pos+len, pos=4
|
||||
// ^^^^ (pos=4, len=4) ; pos:=pos+len, pos=8
|
||||
@@ -573,14 +573,14 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
while (!message.empty()) {
|
||||
byte_slice chunk = message.take_slice(chunksize_good);
|
||||
|
||||
MDEBUG("chunk_start="<<(void*)chunk.data()<<" ptr="<<message_data<<" pos="<<(chunk.data() - message_data));
|
||||
MDEBUG("chunk_start="<<(void*)chunk.data()<<" ptr="<<(const void*)message_data<<" pos="<<(chunk.data() - message_data));
|
||||
MDEBUG("part of " << message.size() << ": pos="<<(chunk.data() - message_data) << " len="<<chunk.size());
|
||||
|
||||
bool ok = do_send_chunk(std::move(chunk)); // <====== ***
|
||||
|
||||
all_ok = all_ok && ok;
|
||||
if (!all_ok) {
|
||||
MDEBUG("do_send() DONE ***FAILED*** from packet="<<message_size<<" B for ptr="<<message_data);
|
||||
MDEBUG("do_send() DONE ***FAILED*** from packet="<<message_size<<" B for ptr="<<(const void*)message_data);
|
||||
MDEBUG("do_send() SEND was aborted in middle of big package - this is mostly harmless "
|
||||
<< " (e.g. peer closed connection) but if it causes trouble tell us at #monero-dev. " << message_size);
|
||||
return false; // partial failure in sending
|
||||
@@ -588,7 +588,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
|
||||
// (in catch block, or uniq pointer) delete buf;
|
||||
} // each chunk
|
||||
|
||||
MDEBUG("do_send() DONE SPLIT from packet="<<message_size<<" B for ptr="<<message_data);
|
||||
MDEBUG("do_send() DONE SPLIT from packet="<<message_size<<" B for ptr="<<(const void*)message_data);
|
||||
|
||||
MDEBUG("do_send() m_connection_type = " << m_connection_type);
|
||||
|
||||
|
||||
@@ -668,7 +668,7 @@ namespace net_utils
|
||||
// Cross-origin resource sharing
|
||||
if(m_query_info.m_header_info.m_origin.size())
|
||||
{
|
||||
if (std::binary_search(m_config.m_access_control_origins.begin(), m_config.m_access_control_origins.end(), m_query_info.m_header_info.m_origin))
|
||||
if (std::binary_search(m_config.m_access_control_origins.begin(), m_config.m_access_control_origins.end(), "*") || std::binary_search(m_config.m_access_control_origins.begin(), m_config.m_access_control_origins.end(), m_query_info.m_header_info.m_origin))
|
||||
{
|
||||
buf += "Access-Control-Allow-Origin: ";
|
||||
buf += m_query_info.m_header_info.m_origin;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <math.h>
|
||||
#include <limits>
|
||||
#include <algorithm>
|
||||
#include "misc_language.h"
|
||||
#include "stats.h"
|
||||
|
||||
enum
|
||||
@@ -86,7 +87,7 @@ Tpod Stats<T, Tpod>::get_median() const
|
||||
}
|
||||
else
|
||||
{
|
||||
median = (sorted[(sorted.size() - 1) / 2] + sorted[sorted.size() / 2]) / 2;
|
||||
median = epee::misc_utils::get_mid(sorted[(sorted.size() - 1) / 2], sorted[sorted.size() / 2]);
|
||||
}
|
||||
set_cached(bit_median);
|
||||
}
|
||||
|
||||
@@ -35,9 +35,7 @@ if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
|
||||
add_library(epee_readline STATIC readline_buffer.cpp)
|
||||
endif()
|
||||
|
||||
if(HAVE_C11)
|
||||
SET_PROPERTY(SOURCE memwipe.c PROPERTY COMPILE_FLAGS -std=c11)
|
||||
endif()
|
||||
set_property(SOURCE memwipe.c PROPERTY C_STANDARD 11)
|
||||
|
||||
# Build and install libepee if we're building for GUI
|
||||
if (BUILD_GUI_DEPS)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
// 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.
|
||||
|
||||
#include <limits>
|
||||
#include <string.h>
|
||||
#include "net/buffer.h"
|
||||
|
||||
|
||||
@@ -209,12 +209,7 @@ namespace
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
using quoted_result = boost::joined_range<
|
||||
const boost::joined_range<const boost::string_ref, const T>, const boost::string_ref
|
||||
>;
|
||||
|
||||
template<typename T>
|
||||
quoted_result<T> quoted(const T& arg)
|
||||
auto quoted_(const T& arg) // avoid ADL selecting C++14 std::quoted
|
||||
{
|
||||
return boost::range::join(boost::range::join(ceref(u8"\""), arg), ceref(u8"\""));
|
||||
}
|
||||
@@ -242,13 +237,13 @@ namespace
|
||||
{
|
||||
str.append(u8"Digest ");
|
||||
add_first_field(str, u8"algorithm", algorithm);
|
||||
add_field(str, u8"nonce", quoted(user.server.nonce));
|
||||
add_field(str, u8"realm", quoted(user.server.realm));
|
||||
add_field(str, u8"response", quoted(response));
|
||||
add_field(str, u8"uri", quoted(uri));
|
||||
add_field(str, u8"username", quoted(user.credentials.username));
|
||||
add_field(str, u8"nonce", quoted_(user.server.nonce));
|
||||
add_field(str, u8"realm", quoted_(user.server.realm));
|
||||
add_field(str, u8"response", quoted_(response));
|
||||
add_field(str, u8"uri", quoted_(uri));
|
||||
add_field(str, u8"username", quoted_(user.credentials.username));
|
||||
if (!user.server.opaque.empty())
|
||||
add_field(str, u8"opaque", quoted(user.server.opaque));
|
||||
add_field(str, u8"opaque", quoted_(user.server.opaque));
|
||||
}
|
||||
|
||||
//! Implements superseded algorithm specified in RFC 2069
|
||||
@@ -674,8 +669,8 @@ namespace
|
||||
Digest::name, (i == 0 ? boost::string_ref{} : sess_algo)
|
||||
);
|
||||
add_field(out, u8"algorithm", algorithm);
|
||||
add_field(out, u8"realm", quoted(auth_realm));
|
||||
add_field(out, u8"nonce", quoted(nonce));
|
||||
add_field(out, u8"realm", quoted_(auth_realm));
|
||||
add_field(out, u8"nonce", quoted_(nonce));
|
||||
add_field(out, u8"stale", is_stale ? ceref("true") : ceref("false"));
|
||||
|
||||
fields.push_back(std::make_pair(std::string(server_auth_field), std::move(out)));
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <boost/optional/optional.hpp>
|
||||
#include <limits>
|
||||
#include <string.h>
|
||||
#include "memwipe.h"
|
||||
#include "misc_log_ex.h"
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
set(Boost_USE_MULTITHREADED ON)
|
||||
|
||||
@@ -14,8 +21,8 @@ IF (MSVC)
|
||||
include_directories(SYSTEM platform/msvc)
|
||||
ELSE()
|
||||
# set stuff for other systems
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11 -Wall")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wno-reorder")
|
||||
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-reorder")
|
||||
ENDIF()
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
Quick Gitian building with docker
|
||||
=================================
|
||||
|
||||
*Setup instructions for a Gitian build of Monero using Docker.*
|
||||
|
||||
Gitian supports other container mechanisms too but if you have a Debian or
|
||||
Ubuntu-based host the steps can be greatly simplified.
|
||||
|
||||
Preparing the Gitian builder host
|
||||
---------------------------------
|
||||
|
||||
The procedure here will create a docker container for build preparation, as well as
|
||||
for actually running the builds. The only items you must install on your own host
|
||||
are docker and apt-cacher-ng. With docker installed, you should also give yourself
|
||||
permission to use docker by adding yourself to the docker group.
|
||||
|
||||
```bash
|
||||
sudo apt-get install docker.io apt-cacher-ng
|
||||
sudo usermod -aG docker $USER
|
||||
su $USER
|
||||
```
|
||||
|
||||
The final `su` command is needed to start a new shell with your new group membership,
|
||||
since the `usermod` command doesn't affect any existing sessions.
|
||||
|
||||
If you want Mac binaries included in your build, you need to obtain the MacOS SDK:
|
||||
|
||||
```bash
|
||||
curl -O https://bitcoincore.org/depends-sources/sdks/MacOSX10.11.sdk.tar.gz
|
||||
```
|
||||
|
||||
Other User Preparation
|
||||
----------------------
|
||||
|
||||
The final step will be to `gpg` sign the results of your build and upload them to GitHub.
|
||||
Before you can do that, you'll need
|
||||
* a GitHub account.
|
||||
If your GitHub account name is different from your local account name, you must
|
||||
set your GitHub account name for the script to use:
|
||||
|
||||
```bash
|
||||
export GH_USER=<github account name>
|
||||
```
|
||||
|
||||
* PGP keys - if you don't have one already, you can use `gpg --quick-gen-key` to generate it.
|
||||
* a fork of the [gitian.sigs](https://github.com/monero-project/gitian.sigs/) repo on your GitHub account.
|
||||
Please follow the directions there for uploading your key first.
|
||||
|
||||
**Note:** Please ensure your gpg public key is available to check signatures by adding it to the [gitian.sigs/gitian-pubkeys/](https://github.com/monero-project/gitian.sigs/tree/master/gitian-pubkeys) directory in a pull request.
|
||||
|
||||
|
||||
Building the Binaries
|
||||
---------------------
|
||||
|
||||
The dockrun.sh script will do everything to build the binaries. Just specify the
|
||||
version to build as its only argument, e.g.
|
||||
|
||||
```bash
|
||||
./dockrun.sh v0.17.2.3
|
||||
```
|
||||
|
||||
The build should run to completion with no errors, and will display the SHA256 checksums
|
||||
of the resulting binaries. You'll be prompted to check if the sums look good, and if so
|
||||
then the results will be signed, and the signatures will be pushed to GitHub.
|
||||
|
||||
You can also look in the [gitian.sigs](https://github.com/monero-project/gitian.sigs/) repo and / or [getmonero.org release checksums](https://web.getmonero.org/downloads/hashes.txt) to see if others got the same checksum for the same version tag. If there is ever a mismatch -- **STOP! Something is wrong**. Contact others on IRC / GitHub to figure out what is going on.
|
||||
|
||||
|
||||
Other Options
|
||||
-------------
|
||||
|
||||
This script just runs the [gitian-build.py](gitian-build.py) inside a container named `gitrun`.
|
||||
You can set other options for that script by setting the OPT variable when running `dockrun.sh`
|
||||
e.g.
|
||||
|
||||
```bash
|
||||
OPT="-j 8" ./dockrun.sh v0.17.2.3
|
||||
```
|
||||
|
||||
You can also examine the build and install logs by running a shell in the container, e.g.
|
||||
|
||||
```bash
|
||||
docker exec -it gitrun /bin/bash
|
||||
more builder/var/install-linux.log
|
||||
```
|
||||
@@ -31,6 +31,8 @@ This guide explains how to set up the environment, and how to start the builds.
|
||||
|
||||
* Gitian gives you the option of using any of 3 different virtualization tools: `kvm`, `docker` or `lxc`. This documentation will only show how to build with `lxc` and `docker` (documentation for `kvm` is welcome). Building with `lxc` is the default, but is more complicated, so we recommend docker your first time.
|
||||
|
||||
* For a shortcut using `docker` follow the instructions in [DOCKRUN.md](DOCKRUN.md) instead
|
||||
of following the rest of this document..
|
||||
|
||||
## Create the gitianuser account
|
||||
|
||||
@@ -126,7 +128,7 @@ Setup for LXC:
|
||||
|
||||
```bash
|
||||
GH_USER=fluffypony
|
||||
VERSION=v0.17.2.0
|
||||
VERSION=v0.17.3.0
|
||||
|
||||
./gitian-build.py --setup $GH_USER $VERSION
|
||||
```
|
||||
@@ -182,7 +184,7 @@ If you chose to do detached signing using `--detach-sign` above (recommended), y
|
||||
|
||||
```bash
|
||||
GH_USER=fluffypony
|
||||
VERSION=v0.17.2.0
|
||||
VERSION=v0.17.3.0
|
||||
|
||||
gpg --detach-sign ${VERSION}-linux/${GH_USER}/monero-linux-*-build.assert
|
||||
gpg --detach-sign ${VERSION}-win/${GH_USER}/monero-win-*-build.assert
|
||||
|
||||
Executable
+133
@@ -0,0 +1,133 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ $# -ne 1 ]; then
|
||||
echo "usage: $0 <version>"
|
||||
exit 1
|
||||
fi
|
||||
VERSION=$1
|
||||
|
||||
DOCKER=`command -v docker`
|
||||
CACHER=`command -v apt-cacher-ng`
|
||||
|
||||
if [ -z "$DOCKER" -o -z "$CACHER" ]; then
|
||||
echo "$0: you must first install docker.io and apt-cacher-ng"
|
||||
echo " e.g. sudo apt-get install docker.io apt-cacher-ng"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
GH_USER=${GH_USER-$USER}
|
||||
|
||||
TAG=gitrun-bionic
|
||||
TAG2=base-bionic-amd64
|
||||
IMAGE=`docker images | grep $TAG`
|
||||
|
||||
WORKDIR=/home/ubuntu
|
||||
|
||||
if [ -z "$IMAGE" ]; then
|
||||
GID=`getent group docker`
|
||||
mkdir -p docker
|
||||
cd docker
|
||||
|
||||
# container for running gitian-build.py
|
||||
cat <<EOF > ${TAG}.Dockerfile
|
||||
FROM ubuntu:bionic
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN echo 'Acquire::http { Proxy "http://172.17.0.1:3142"; };' > /etc/apt/apt.conf.d/50cacher
|
||||
RUN echo "$GID" >> /etc/group
|
||||
RUN apt-get update && apt-get --no-install-recommends -y install lsb-release ruby git make wget docker.io python3 curl
|
||||
|
||||
RUN useradd -ms /bin/bash -U ubuntu -G docker
|
||||
USER ubuntu:docker
|
||||
WORKDIR $WORKDIR
|
||||
|
||||
RUN git clone https://github.com/monero-project/gitian.sigs.git sigs; \
|
||||
git clone https://github.com/devrandom/gitian-builder.git builder; \
|
||||
cd builder; git checkout c0f77ca018cb5332bfd595e0aff0468f77542c23; mkdir -p inputs var; cd inputs; \
|
||||
git clone https://github.com/monero-project/monero
|
||||
|
||||
CMD ["sleep", "infinity"]
|
||||
EOF
|
||||
|
||||
docker build --pull -f ${TAG}.Dockerfile -t $TAG .
|
||||
|
||||
cd ..
|
||||
docker run -v /var/run/docker.sock:/var/run/docker.sock -d --name gitrun $TAG
|
||||
if [ -f MacOSX10.11.sdk.tar.gz ]; then
|
||||
docker cp MacOSX10.11.sdk.tar.gz gitrun:$WORKDIR/builder/inputs/
|
||||
else
|
||||
echo "No MacOS SDK found, Mac builds will be omitted"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
IMAGE=`docker images | grep $TAG2`
|
||||
if [ -z "$IMAGE" ]; then
|
||||
mkdir -p docker
|
||||
cd docker
|
||||
|
||||
# container for actually running each build
|
||||
cat <<EOF > ${TAG2}.Dockerfile
|
||||
FROM ubuntu:bionic
|
||||
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
RUN echo 'Acquire::http { Proxy "http://172.17.0.1:3142"; };' > /etc/apt/apt.conf.d/50cacher
|
||||
RUN apt-get update && apt-get --no-install-recommends -y install build-essential git language-pack-en \
|
||||
wget lsb-release curl gcc-7 g++-7 gcc g++ binutils-gold pkg-config autoconf libtool automake faketime \
|
||||
bsdmainutils ca-certificates python cmake gperf
|
||||
|
||||
RUN useradd -ms /bin/bash -U ubuntu
|
||||
USER ubuntu:ubuntu
|
||||
WORKDIR $WORKDIR
|
||||
|
||||
CMD ["sleep", "infinity"]
|
||||
EOF
|
||||
|
||||
docker build --pull -f ${TAG2}.Dockerfile -t $TAG2 .
|
||||
|
||||
cd ..
|
||||
|
||||
fi
|
||||
|
||||
RUNNING=`docker ps | grep gitrun`
|
||||
if [ -z "$RUNNING" ]; then
|
||||
BUILT=`docker ps -a | grep gitrun`
|
||||
if [ -z "$BUILT" ]; then
|
||||
docker run -v /var/run/docker.sock:/var/run/docker.sock -d --name gitrun $TAG
|
||||
else
|
||||
docker start gitrun
|
||||
fi
|
||||
fi
|
||||
docker cp gitian-build.py gitrun:$WORKDIR/
|
||||
docker exec -t gitrun ./gitian-build.py -d -b -D -n $OPT $GH_USER $VERSION
|
||||
RC=$?
|
||||
if [ $RC != 0 ]; then
|
||||
exit $RC
|
||||
fi
|
||||
echo "\nBuild Results:\n"
|
||||
docker exec gitrun sh -c "sha256sum out/$VERSION/*"
|
||||
echo "\nIf these results look correct, type \"sign\" to sign them, otherwise ^C to stop now."
|
||||
read check
|
||||
if [ "$check" != "sign" ]; then
|
||||
echo "Not signing, bye."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -d sigs ]; then
|
||||
git clone https://github.com/monero-project/gitian.sigs.git sigs
|
||||
cd sigs
|
||||
git remote add $GH_USER git@github.com:$GH_USER/gitian.sigs.git
|
||||
cd ..
|
||||
fi
|
||||
|
||||
DIRS=`docker exec gitrun sh -c "echo sigs/$VERSION-*"`
|
||||
for i in $DIRS; do
|
||||
docker cp gitrun:$WORKDIR/$i sigs
|
||||
gpg --detach-sign $i/$GH_USER/*.assert
|
||||
done
|
||||
|
||||
cd sigs
|
||||
git checkout -b $VERSION
|
||||
git add $VERSION-*
|
||||
git commit -S -m "Add $GH_USER $VERSION"
|
||||
git push --set-upstream $GH_USER $VERSION
|
||||
@@ -24,12 +24,6 @@ packages:
|
||||
- "ca-certificates"
|
||||
- "python"
|
||||
- "cmake"
|
||||
- "ccache"
|
||||
- "protobuf-compiler"
|
||||
- "libdbus-1-dev"
|
||||
- "libharfbuzz-dev"
|
||||
- "libprotobuf-dev"
|
||||
- "python3-zmq"
|
||||
- "unzip"
|
||||
remotes:
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
@@ -52,6 +46,7 @@ script: |
|
||||
if test -n "$GBUILD_CACHE_ENABLED"; then
|
||||
export SOURCES_PATH=${GBUILD_COMMON_CACHE}
|
||||
export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
|
||||
export GITIAN=1
|
||||
mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
|
||||
fi
|
||||
|
||||
@@ -125,8 +120,8 @@ script: |
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DCMAKE_BUILD_TYPE=Release
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
chmod 644 bin/LICENSE
|
||||
cp ../LICENSE ../README.md ../ANONYMITY_NETWORKS.md bin
|
||||
chmod 644 bin/LICENSE bin/*.md
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
|
||||
@@ -25,12 +25,6 @@ packages:
|
||||
- "ca-certificates"
|
||||
- "python"
|
||||
- "cmake"
|
||||
- "ccache"
|
||||
- "protobuf-compiler"
|
||||
- "libdbus-1-dev"
|
||||
- "libharfbuzz-dev"
|
||||
- "libprotobuf-dev"
|
||||
- "python3-zmq"
|
||||
remotes:
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
@@ -52,6 +46,7 @@ script: |
|
||||
if test -n "$GBUILD_CACHE_ENABLED"; then
|
||||
export SOURCES_PATH=${GBUILD_COMMON_CACHE}
|
||||
export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
|
||||
export GITIAN=1
|
||||
mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
|
||||
fi
|
||||
|
||||
@@ -122,8 +117,8 @@ script: |
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_SKIP_RPATH=ON
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
chmod 644 bin/LICENSE
|
||||
cp ../LICENSE ../README.md ../ANONYMITY_NETWORKS.md bin
|
||||
chmod 644 bin/LICENSE bin/*.md
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
|
||||
@@ -36,12 +36,6 @@ packages:
|
||||
- "ca-certificates"
|
||||
- "python"
|
||||
- "cmake"
|
||||
- "ccache"
|
||||
- "protobuf-compiler"
|
||||
- "libdbus-1-dev"
|
||||
- "libharfbuzz-dev"
|
||||
- "libprotobuf-dev"
|
||||
- "python3-zmq"
|
||||
remotes:
|
||||
- "url": "https://github.com/monero-project/monero.git"
|
||||
"dir": "monero"
|
||||
@@ -63,6 +57,7 @@ script: |
|
||||
if test -n "$GBUILD_CACHE_ENABLED"; then
|
||||
export SOURCES_PATH=${GBUILD_COMMON_CACHE}
|
||||
export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
|
||||
export GITIAN=1
|
||||
mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
|
||||
fi
|
||||
|
||||
@@ -167,8 +162,8 @@ script: |
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake -DBACKCOMPAT=ON -DCMAKE_SKIP_RPATH=ON
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
chmod 644 bin/LICENSE
|
||||
cp ../LICENSE ../README.md ../ANONYMITY_NETWORKS.md bin
|
||||
chmod 644 bin/LICENSE bin/*.md
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
|
||||
@@ -41,6 +41,7 @@ script: |
|
||||
if test -n "$GBUILD_CACHE_ENABLED"; then
|
||||
export SOURCES_PATH=${GBUILD_COMMON_CACHE}
|
||||
export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
|
||||
export GITIAN=1
|
||||
mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
|
||||
fi
|
||||
|
||||
@@ -111,8 +112,8 @@ script: |
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake
|
||||
make ${MAKEOPTS}
|
||||
chmod 755 bin/*
|
||||
cp ../LICENSE bin
|
||||
chmod 644 bin/LICENSE
|
||||
cp ../LICENSE ../README.md ../ANONYMITY_NETWORKS.md bin
|
||||
chmod 644 bin/LICENSE bin/*.md
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | tar --no-recursion --owner=0 --group=0 -c -T - | bzip2 -9 > ${OUTDIR}/${DISTNAME}.tar.bz2
|
||||
|
||||
@@ -20,7 +20,6 @@ packages:
|
||||
- "zip"
|
||||
- "ca-certificates"
|
||||
- "python"
|
||||
- "rename"
|
||||
- "cmake"
|
||||
alternatives:
|
||||
-
|
||||
@@ -54,6 +53,7 @@ script: |
|
||||
if test -n "$GBUILD_CACHE_ENABLED"; then
|
||||
export SOURCES_PATH=${GBUILD_COMMON_CACHE}
|
||||
export BASE_CACHE=${GBUILD_PACKAGE_CACHE}
|
||||
export GITIAN=1
|
||||
mkdir -p ${BASE_CACHE} ${SOURCES_PATH}
|
||||
fi
|
||||
|
||||
@@ -127,7 +127,7 @@ script: |
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=${BASEPREFIX}/${i}/share/toolchain.cmake
|
||||
make ${MAKEOPTS}
|
||||
cp ../LICENSE bin
|
||||
cp ../LICENSE ../README.md ../ANONYMITY_NETWORKS.md bin
|
||||
DISTNAME=monero-${i}-${version}
|
||||
mv bin ${DISTNAME}
|
||||
find ${DISTNAME}/ | sort | zip -X@ ${OUTDIR}/${DISTNAME}.zip
|
||||
|
||||
Vendored
+2
@@ -38,8 +38,10 @@
|
||||
find_package(Miniupnpc REQUIRED)
|
||||
|
||||
message(STATUS "Using in-tree miniupnpc")
|
||||
set(UPNPC_NO_INSTALL TRUE CACHE BOOL "Disable miniupnp installation" FORCE)
|
||||
add_subdirectory(miniupnp/miniupnpc)
|
||||
set_property(TARGET libminiupnpc-static PROPERTY FOLDER "external")
|
||||
set_property(TARGET libminiupnpc-static PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||
if(MSVC)
|
||||
set_property(TARGET libminiupnpc-static APPEND_STRING PROPERTY COMPILE_FLAGS " -wd4244 -wd4267")
|
||||
elseif(NOT MSVC)
|
||||
|
||||
+4
-2
@@ -26,11 +26,13 @@
|
||||
# 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.
|
||||
|
||||
cmake_minimum_required(VERSION 2.8.7)
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
project(easylogging CXX)
|
||||
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
find_package(Threads)
|
||||
find_package(Backtrace)
|
||||
|
||||
+4
-3
@@ -2968,8 +2968,8 @@ void Writer::initializeLogger(Logger *logger, bool needLock) {
|
||||
}
|
||||
|
||||
void Writer::processDispatch() {
|
||||
static std::atomic_flag in_dispatch;
|
||||
if (in_dispatch.test_and_set())
|
||||
static __thread bool in_dispatch = false;
|
||||
if (in_dispatch)
|
||||
{
|
||||
if (m_proceed && m_logger != NULL)
|
||||
{
|
||||
@@ -2978,6 +2978,7 @@ void Writer::processDispatch() {
|
||||
}
|
||||
return;
|
||||
}
|
||||
in_dispatch = true;
|
||||
#if ELPP_LOGGING_ENABLED
|
||||
if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) {
|
||||
bool firstDispatched = false;
|
||||
@@ -3016,7 +3017,7 @@ void Writer::processDispatch() {
|
||||
m_logger->releaseLock();
|
||||
}
|
||||
#endif // ELPP_LOGGING_ENABLED
|
||||
in_dispatch.clear();
|
||||
in_dispatch = false;
|
||||
}
|
||||
|
||||
void Writer::triggerDispatch(void) {
|
||||
|
||||
Vendored
+1
-1
Submodule external/miniupnp updated: 4c700e0952...544e6fcc73
Vendored
+1
-1
Submodule external/randomx updated: fe4324e8c0...9efc398c19
@@ -467,7 +467,12 @@ void mdb_txn_safe::allow_new_txns()
|
||||
creation_gate.clear();
|
||||
}
|
||||
|
||||
void lmdb_resized(MDB_env *env)
|
||||
void mdb_txn_safe::increment_txns(int i)
|
||||
{
|
||||
num_active_txns += i;
|
||||
}
|
||||
|
||||
void lmdb_resized(MDB_env *env, int isactive)
|
||||
{
|
||||
mdb_txn_safe::prevent_new_txns();
|
||||
|
||||
@@ -478,7 +483,11 @@ void lmdb_resized(MDB_env *env)
|
||||
mdb_env_info(env, &mei);
|
||||
uint64_t old = mei.me_mapsize;
|
||||
|
||||
if (isactive)
|
||||
mdb_txn_safe::increment_txns(-1);
|
||||
mdb_txn_safe::wait_no_active_txns();
|
||||
if (isactive)
|
||||
mdb_txn_safe::increment_txns(1);
|
||||
|
||||
int result = mdb_env_set_mapsize(env, 0);
|
||||
if (result)
|
||||
@@ -496,7 +505,7 @@ inline int lmdb_txn_begin(MDB_env *env, MDB_txn *parent, unsigned int flags, MDB
|
||||
{
|
||||
int res = mdb_txn_begin(env, parent, flags, txn);
|
||||
if (res == MDB_MAP_RESIZED) {
|
||||
lmdb_resized(env);
|
||||
lmdb_resized(env, 1);
|
||||
res = mdb_txn_begin(env, parent, flags, txn);
|
||||
}
|
||||
return res;
|
||||
@@ -506,7 +515,7 @@ inline int lmdb_txn_renew(MDB_txn *txn)
|
||||
{
|
||||
int res = mdb_txn_renew(txn);
|
||||
if (res == MDB_MAP_RESIZED) {
|
||||
lmdb_resized(mdb_txn_env(txn));
|
||||
lmdb_resized(mdb_txn_env(txn), 0);
|
||||
res = mdb_txn_renew(txn);
|
||||
}
|
||||
return res;
|
||||
@@ -1268,11 +1277,11 @@ BlockchainLMDB::~BlockchainLMDB()
|
||||
// batch transaction shouldn't be active at this point. If it is, consider it aborted.
|
||||
if (m_batch_active)
|
||||
{
|
||||
try { batch_abort(); }
|
||||
try { BlockchainLMDB::batch_abort(); }
|
||||
catch (...) { /* ignore */ }
|
||||
}
|
||||
if (m_open)
|
||||
close();
|
||||
BlockchainLMDB::close();
|
||||
}
|
||||
|
||||
BlockchainLMDB::BlockchainLMDB(bool batch_transactions): BlockchainDB()
|
||||
@@ -1569,9 +1578,9 @@ void BlockchainLMDB::close()
|
||||
if (m_batch_active)
|
||||
{
|
||||
LOG_PRINT_L3("close() first calling batch_abort() due to active batch transaction");
|
||||
batch_abort();
|
||||
BlockchainLMDB::batch_abort();
|
||||
}
|
||||
this->sync();
|
||||
BlockchainLMDB::sync();
|
||||
m_tinfo.reset();
|
||||
|
||||
// FIXME: not yet thread safe!!! Use with care.
|
||||
@@ -1584,7 +1593,7 @@ void BlockchainLMDB::sync()
|
||||
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
|
||||
check_open();
|
||||
|
||||
if (is_read_only())
|
||||
if (BlockchainLMDB::is_read_only())
|
||||
return;
|
||||
|
||||
// Does nothing unless LMDB environment was opened with MDB_NOSYNC or in part
|
||||
|
||||
@@ -154,6 +154,7 @@ struct mdb_txn_safe
|
||||
static void prevent_new_txns();
|
||||
static void wait_no_active_txns();
|
||||
static void allow_new_txns();
|
||||
static void increment_txns(int);
|
||||
|
||||
mdb_threadinfo* m_tinfo;
|
||||
MDB_txn* m_txn;
|
||||
|
||||
Binary file not shown.
@@ -248,6 +248,7 @@ namespace cryptonote
|
||||
ADD_CHECKPOINT2(2265000, "727a6228a71f5b35c899553ee19d60bfc10c126a009ffd633afb30666e8edbe6", "0x121a33e656ecad4");
|
||||
ADD_CHECKPOINT2(2325000, "f61261994b368700f0cbbfb4477433fa36a3c7537908ab2d1a06ac2987cc8b01", "0x154bceeffaff847");
|
||||
ADD_CHECKPOINT2(2430000, "5f7f4273eb6be024df3c4311a8d28482220a253190efa1719f35b7782587740c", "0x1c3f14ba9b0bebc");
|
||||
ADD_CHECKPOINT2(2478000, "692fc889f5328c9cfe47e9846ca2bb3d61d82dbeb37077e90e0f8c36b8fc0c84", "0x1fbb38d0aae41a6");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
+159
-51
@@ -51,6 +51,12 @@
|
||||
#define INIT_SIZE_BLK 8
|
||||
#define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define THREADV __declspec(thread)
|
||||
#else
|
||||
#define THREADV __thread
|
||||
#endif
|
||||
|
||||
extern void aesb_single_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey);
|
||||
extern void aesb_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey);
|
||||
|
||||
@@ -89,6 +95,28 @@ static inline int use_v4_jit(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(__x86_64__) || defined(__aarch64__)
|
||||
static inline int force_software_aes(void)
|
||||
{
|
||||
static int use = -1;
|
||||
|
||||
if (use != -1)
|
||||
return use;
|
||||
|
||||
const char *env = getenv("MONERO_USE_SOFTWARE_AES");
|
||||
if (!env) {
|
||||
use = 0;
|
||||
}
|
||||
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
|
||||
use = 0;
|
||||
}
|
||||
else {
|
||||
use = 1;
|
||||
}
|
||||
return use;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define VARIANT1_1(p) \
|
||||
do if (variant == 1) \
|
||||
{ \
|
||||
@@ -437,12 +465,6 @@ static inline int use_v4_jit(void)
|
||||
_b1 = _b; \
|
||||
_b = _c; \
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define THREADV __declspec(thread)
|
||||
#else
|
||||
#define THREADV __thread
|
||||
#endif
|
||||
|
||||
#pragma pack(push, 1)
|
||||
union cn_slow_hash_state
|
||||
{
|
||||
@@ -498,25 +520,6 @@ STATIC INLINE void xor64(uint64_t *a, const uint64_t b)
|
||||
* @return true if the CPU supports AES, false otherwise
|
||||
*/
|
||||
|
||||
STATIC INLINE int force_software_aes(void)
|
||||
{
|
||||
static int use = -1;
|
||||
|
||||
if (use != -1)
|
||||
return use;
|
||||
|
||||
const char *env = getenv("MONERO_USE_SOFTWARE_AES");
|
||||
if (!env) {
|
||||
use = 0;
|
||||
}
|
||||
else if (!strcmp(env, "0") || !strcmp(env, "no")) {
|
||||
use = 0;
|
||||
}
|
||||
else {
|
||||
use = 1;
|
||||
}
|
||||
return use;
|
||||
}
|
||||
|
||||
STATIC INLINE int check_aes_hw(void)
|
||||
{
|
||||
@@ -1009,6 +1012,44 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
||||
}
|
||||
|
||||
#elif !defined NO_AES && (defined(__arm__) || defined(__aarch64__))
|
||||
#ifdef __aarch64__
|
||||
#include <sys/mman.h>
|
||||
THREADV uint8_t *hp_state = NULL;
|
||||
THREADV int hp_malloced = 0;
|
||||
|
||||
void cn_slow_hash_allocate_state(void)
|
||||
{
|
||||
if(hp_state != NULL)
|
||||
return;
|
||||
|
||||
#ifndef MAP_HUGETLB
|
||||
#define MAP_HUGETLB 0
|
||||
#endif
|
||||
hp_state = mmap(0, MEMORY, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON | MAP_HUGETLB, -1, 0);
|
||||
|
||||
if(hp_state == MAP_FAILED)
|
||||
hp_state = NULL;
|
||||
if(hp_state == NULL)
|
||||
{
|
||||
hp_malloced = 1;
|
||||
hp_state = (uint8_t *) malloc(MEMORY);
|
||||
}
|
||||
}
|
||||
|
||||
void cn_slow_hash_free_state(void)
|
||||
{
|
||||
if(hp_state == NULL)
|
||||
return;
|
||||
|
||||
if (hp_malloced)
|
||||
free(hp_state);
|
||||
else
|
||||
munmap(hp_state, MEMORY);
|
||||
hp_state = NULL;
|
||||
hp_malloced = 0;
|
||||
}
|
||||
#else
|
||||
void cn_slow_hash_allocate_state(void)
|
||||
{
|
||||
// Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c
|
||||
@@ -1020,6 +1061,7 @@ void cn_slow_hash_free_state(void)
|
||||
// As above
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define RDATA_ALIGN16 __attribute__ ((aligned(16)))
|
||||
@@ -1060,6 +1102,23 @@ union cn_slow_hash_state
|
||||
* and moving between vector and regular registers stalls the pipeline.
|
||||
*/
|
||||
#include <arm_neon.h>
|
||||
#ifndef __APPLE__
|
||||
#include <sys/auxv.h>
|
||||
#include <asm/hwcap.h>
|
||||
#endif
|
||||
|
||||
STATIC INLINE int check_aes_hw(void)
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
return 1;
|
||||
#else
|
||||
static int supported = -1;
|
||||
|
||||
if(supported < 0)
|
||||
supported = (getauxval(AT_HWCAP) & HWCAP_AES) != 0;
|
||||
return supported;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define TOTALBLOCKS (MEMORY / AES_BLOCK_SIZE)
|
||||
|
||||
@@ -1156,7 +1215,6 @@ __asm__(
|
||||
STATIC INLINE void aes_pseudo_round(const uint8_t *in, uint8_t *out, const uint8_t *expandedKey, int nblocks)
|
||||
{
|
||||
const uint8x16_t *k = (const uint8x16_t *)expandedKey, zero = {0};
|
||||
uint8x16_t tmp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<nblocks; i++)
|
||||
@@ -1191,7 +1249,6 @@ STATIC INLINE void aes_pseudo_round_xor(const uint8_t *in, uint8_t *out, const u
|
||||
{
|
||||
const uint8x16_t *k = (const uint8x16_t *)expandedKey;
|
||||
const uint8x16_t *x = (const uint8x16_t *)xor;
|
||||
uint8x16_t tmp;
|
||||
int i;
|
||||
|
||||
for (i=0; i<nblocks; i++)
|
||||
@@ -1244,16 +1301,17 @@ STATIC INLINE void aligned_free(void *ptr)
|
||||
}
|
||||
#endif /* FORCE_USE_HEAP */
|
||||
|
||||
STATIC INLINE void xor_blocks(uint8_t* a, const uint8_t* b)
|
||||
{
|
||||
U64(a)[0] ^= U64(b)[0];
|
||||
U64(a)[1] ^= U64(b)[1];
|
||||
}
|
||||
|
||||
void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int prehashed, uint64_t height)
|
||||
{
|
||||
RDATA_ALIGN16 uint8_t expandedKey[240];
|
||||
|
||||
#ifndef FORCE_USE_HEAP
|
||||
RDATA_ALIGN16 uint8_t local_hp_state[MEMORY];
|
||||
#else
|
||||
uint8_t *local_hp_state = (uint8_t *)aligned_malloc(MEMORY,16);
|
||||
#endif
|
||||
|
||||
uint8_t *local_hp_state;
|
||||
uint8_t text[INIT_SIZE_BYTE];
|
||||
RDATA_ALIGN16 uint64_t a[2];
|
||||
RDATA_ALIGN16 uint64_t b[4];
|
||||
@@ -1264,12 +1322,22 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
||||
|
||||
size_t i, j;
|
||||
uint64_t *p = NULL;
|
||||
oaes_ctx *aes_ctx = NULL;
|
||||
int useAes = !force_software_aes() && check_aes_hw();
|
||||
|
||||
static void (*const extra_hashes[4])(const void *, size_t, char *) =
|
||||
{
|
||||
hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein
|
||||
};
|
||||
|
||||
// this isn't supposed to happen, but guard against it for now.
|
||||
if(hp_state == NULL)
|
||||
cn_slow_hash_allocate_state();
|
||||
|
||||
// locals to avoid constant TLS dereferencing
|
||||
local_hp_state = hp_state;
|
||||
|
||||
// locals to avoid constant TLS dereferencing
|
||||
/* CryptoNight Step 1: Use Keccak1600 to initialize the 'state' (and 'text') buffers from the data. */
|
||||
|
||||
if (prehashed) {
|
||||
@@ -1287,11 +1355,26 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
||||
* the 2MB large random access buffer.
|
||||
*/
|
||||
|
||||
aes_expand_key(state.hs.b, expandedKey);
|
||||
for(i = 0; i < MEMORY / INIT_SIZE_BYTE; i++)
|
||||
if(useAes)
|
||||
{
|
||||
aes_pseudo_round(text, text, expandedKey, INIT_SIZE_BLK);
|
||||
memcpy(&local_hp_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE);
|
||||
aes_expand_key(state.hs.b, expandedKey);
|
||||
for(i = 0; i < MEMORY / INIT_SIZE_BYTE; i++)
|
||||
{
|
||||
aes_pseudo_round(text, text, expandedKey, INIT_SIZE_BLK);
|
||||
memcpy(&local_hp_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
aes_ctx = (oaes_ctx *) oaes_alloc();
|
||||
oaes_key_import_data(aes_ctx, state.hs.b, AES_KEY_SIZE);
|
||||
for(i = 0; i < MEMORY / INIT_SIZE_BYTE; i++)
|
||||
{
|
||||
for(j = 0; j < INIT_SIZE_BLK; j++)
|
||||
aesb_pseudo_round(&text[AES_BLOCK_SIZE * j], &text[AES_BLOCK_SIZE * j], aes_ctx->key->exp_data);
|
||||
|
||||
memcpy(&local_hp_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE);
|
||||
}
|
||||
}
|
||||
|
||||
U64(a)[0] = U64(&state.k[0])[0] ^ U64(&state.k[32])[0];
|
||||
@@ -1307,13 +1390,26 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
||||
_b = vld1q_u8((const uint8_t *)b);
|
||||
_b1 = vld1q_u8(((const uint8_t *)b) + AES_BLOCK_SIZE);
|
||||
|
||||
for(i = 0; i < ITER / 2; i++)
|
||||
if(useAes)
|
||||
{
|
||||
pre_aes();
|
||||
_c = vaeseq_u8(_c, zero);
|
||||
_c = vaesmcq_u8(_c);
|
||||
_c = veorq_u8(_c, _a);
|
||||
post_aes();
|
||||
for(i = 0; i < ITER / 2; i++)
|
||||
{
|
||||
pre_aes();
|
||||
_c = vaeseq_u8(_c, zero);
|
||||
_c = vaesmcq_u8(_c);
|
||||
_c = veorq_u8(_c, _a);
|
||||
post_aes();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(i = 0; i < ITER / 2; i++)
|
||||
{
|
||||
pre_aes();
|
||||
aesb_single_round((uint8_t *) &_c, (uint8_t *) &_c, (uint8_t *) &_a);
|
||||
post_aes();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* CryptoNight Step 4: Sequentially pass through the mixing buffer and use 10 rounds
|
||||
@@ -1322,11 +1418,27 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
||||
|
||||
memcpy(text, state.init, INIT_SIZE_BYTE);
|
||||
|
||||
aes_expand_key(&state.hs.b[32], expandedKey);
|
||||
for(i = 0; i < MEMORY / INIT_SIZE_BYTE; i++)
|
||||
if(useAes)
|
||||
{
|
||||
// add the xor to the pseudo round
|
||||
aes_pseudo_round_xor(text, text, expandedKey, &local_hp_state[i * INIT_SIZE_BYTE], INIT_SIZE_BLK);
|
||||
aes_expand_key(&state.hs.b[32], expandedKey);
|
||||
for(i = 0; i < MEMORY / INIT_SIZE_BYTE; i++)
|
||||
{
|
||||
// add the xor to the pseudo round
|
||||
aes_pseudo_round_xor(text, text, expandedKey, &local_hp_state[i * INIT_SIZE_BYTE], INIT_SIZE_BLK);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oaes_key_import_data(aes_ctx, &state.hs.b[32], AES_KEY_SIZE);
|
||||
for(i = 0; i < MEMORY / INIT_SIZE_BYTE; i++)
|
||||
{
|
||||
for(j = 0; j < INIT_SIZE_BLK; j++)
|
||||
{
|
||||
xor_blocks(&text[j * AES_BLOCK_SIZE], &local_hp_state[i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE]);
|
||||
aesb_pseudo_round(&text[AES_BLOCK_SIZE * j], &text[AES_BLOCK_SIZE * j], aes_ctx->key->exp_data);
|
||||
}
|
||||
}
|
||||
oaes_free((OAES_CTX **) &aes_ctx);
|
||||
}
|
||||
|
||||
/* CryptoNight Step 5: Apply Keccak to the state again, and then
|
||||
@@ -1339,10 +1451,6 @@ void cn_slow_hash(const void *data, size_t length, char *hash, int variant, int
|
||||
memcpy(state.init, text, INIT_SIZE_BYTE);
|
||||
hash_permutation(&state.hs);
|
||||
extra_hashes[state.hs.b[0] & 3](&state, 200, hash);
|
||||
|
||||
#ifdef FORCE_USE_HEAP
|
||||
aligned_free(local_hp_state);
|
||||
#endif
|
||||
}
|
||||
#else /* aarch64 && crypto */
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "misc_language.h"
|
||||
#include "ringct/rctTypes.h"
|
||||
#include "device/device.hpp"
|
||||
#include "cryptonote_basic/fwd.h"
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
|
||||
@@ -41,6 +41,8 @@ namespace cryptonote
|
||||
{
|
||||
cryptonote::transaction tx;
|
||||
crypto::hash hash;
|
||||
uint64_t blob_size;
|
||||
uint64_t weight;
|
||||
bool res; //!< Listeners must ignore `tx` when this is false.
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,4 +33,5 @@ namespace cryptonote
|
||||
struct block;
|
||||
class transaction;
|
||||
struct txpool_event;
|
||||
struct tx_block_template_backlog_entry;
|
||||
}
|
||||
|
||||
@@ -1234,6 +1234,12 @@ 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);
|
||||
|
||||
crypto::hash prev_id;
|
||||
if (!get_block_hash(alt_chain.back().bl, prev_id))
|
||||
MERROR("Failed to get block hash of an alternative chain's tip");
|
||||
else
|
||||
send_miner_notifications(prev_id, alt_chain.back().already_generated_coins);
|
||||
|
||||
for (const auto& notifier : m_block_notifiers)
|
||||
{
|
||||
std::size_t notify_height = split_height;
|
||||
@@ -1780,6 +1786,30 @@ bool Blockchain::create_block_template(block& b, const account_public_address& m
|
||||
return create_block_template(b, NULL, miner_address, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
bool Blockchain::get_miner_data(uint8_t& major_version, uint64_t& height, crypto::hash& prev_id, crypto::hash& seed_hash, difficulty_type& difficulty, uint64_t& median_weight, uint64_t& already_generated_coins, std::vector<tx_block_template_backlog_entry>& tx_backlog)
|
||||
{
|
||||
prev_id = m_db->top_block_hash(&height);
|
||||
++height;
|
||||
|
||||
major_version = m_hardfork->get_ideal_version(height);
|
||||
|
||||
seed_hash = crypto::null_hash;
|
||||
if (m_hardfork->get_current_version() >= RX_BLOCK_VERSION)
|
||||
{
|
||||
uint64_t seed_height, next_height;
|
||||
crypto::rx_seedheights(height, &seed_height, &next_height);
|
||||
seed_hash = get_block_id_by_height(seed_height);
|
||||
}
|
||||
|
||||
difficulty = get_difficulty_for_next_block();
|
||||
median_weight = m_current_block_cumul_weight_median;
|
||||
already_generated_coins = m_db->get_block_already_generated_coins(height - 1);
|
||||
|
||||
m_tx_pool.get_block_template_backlog(tx_backlog);
|
||||
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
// for an alternate chain, get the timestamps from the main chain to complete
|
||||
// the needed number of timestamps for the BLOCKCHAIN_TIMESTAMP_CHECK_WINDOW.
|
||||
bool Blockchain::complete_timestamps_vector(uint64_t start_top_height, std::vector<uint64_t>& timestamps) const
|
||||
@@ -4378,6 +4408,7 @@ leave:
|
||||
get_difficulty_for_next_block(); // just to cache it
|
||||
invalidate_block_template_cache();
|
||||
|
||||
send_miner_notifications(id, already_generated_coins);
|
||||
|
||||
for (const auto& notifier: m_block_notifiers)
|
||||
notifier(new_height - 1, {std::addressof(bl), 1});
|
||||
@@ -5006,6 +5037,8 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
|
||||
unsigned nblocks = batches;
|
||||
if (i < extra)
|
||||
++nblocks;
|
||||
if (nblocks == 0)
|
||||
break;
|
||||
tpool.submit(&waiter, boost::bind(&Blockchain::block_longhash_worker, this, thread_height, epee::span<const block>(&blocks[thread_height - height], nblocks), std::ref(maps[i])), true);
|
||||
thread_height += nblocks;
|
||||
}
|
||||
@@ -5286,7 +5319,7 @@ 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)
|
||||
void Blockchain::add_block_notify(BlockNotifyCallback&& notify)
|
||||
{
|
||||
if (notify)
|
||||
{
|
||||
@@ -5295,6 +5328,15 @@ void Blockchain::add_block_notify(boost::function<void(std::uint64_t, epee::span
|
||||
}
|
||||
}
|
||||
|
||||
void Blockchain::add_miner_notify(MinerNotifyCallback&& notify)
|
||||
{
|
||||
if (notify)
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_blockchain_lock);
|
||||
m_miner_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
|
||||
@@ -5390,7 +5432,7 @@ void Blockchain::cancel()
|
||||
}
|
||||
|
||||
#if defined(PER_BLOCK_CHECKPOINT)
|
||||
static const char expected_block_hashes_hash[] = "ff99bc76e59e0d6268e2d8ed54a2206d828de643fcb13be8d296611fc051a540";
|
||||
static const char expected_block_hashes_hash[] = "dbc25cc509fe8a44426f7168c608d0b4cf6ea5d43682ba4087d6a47aa0384656";
|
||||
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
|
||||
{
|
||||
if (get_checkpoints == nullptr || !m_fast_sync)
|
||||
@@ -5547,6 +5589,33 @@ void Blockchain::cache_block_template(const block &b, const cryptonote::account_
|
||||
m_btc_valid = true;
|
||||
}
|
||||
|
||||
void Blockchain::send_miner_notifications(const crypto::hash &prev_id, uint64_t already_generated_coins)
|
||||
{
|
||||
if (m_miner_notifiers.empty())
|
||||
return;
|
||||
|
||||
const uint64_t height = m_db->height();
|
||||
const uint8_t major_version = m_hardfork->get_ideal_version(height);
|
||||
const difficulty_type diff = get_difficulty_for_next_block();
|
||||
const uint64_t median_weight = m_current_block_cumul_weight_median;
|
||||
|
||||
crypto::hash seed_hash = crypto::null_hash;
|
||||
if (m_hardfork->get_current_version() >= RX_BLOCK_VERSION)
|
||||
{
|
||||
uint64_t seed_height, next_height;
|
||||
crypto::rx_seedheights(height, &seed_height, &next_height);
|
||||
seed_hash = get_block_id_by_height(seed_height);
|
||||
}
|
||||
|
||||
std::vector<tx_block_template_backlog_entry> tx_backlog;
|
||||
m_tx_pool.get_block_template_backlog(tx_backlog);
|
||||
|
||||
for (const auto& notifier : m_miner_notifiers)
|
||||
{
|
||||
notifier(major_version, height, prev_id, seed_hash, diff, median_weight, already_generated_coins, tx_backlog);
|
||||
}
|
||||
}
|
||||
|
||||
namespace cryptonote {
|
||||
template bool Blockchain::get_transactions(const std::vector<crypto::hash>&, std::vector<transaction>&, std::vector<crypto::hash>&) const;
|
||||
template bool Blockchain::get_split_transactions_blobs(const std::vector<crypto::hash>&, std::vector<std::tuple<crypto::hash, cryptonote::blobdata, crypto::hash, cryptonote::blobdata>>&, std::vector<crypto::hash>&) const;
|
||||
|
||||
@@ -89,6 +89,9 @@ namespace cryptonote
|
||||
*/
|
||||
typedef std::function<const epee::span<const unsigned char>(cryptonote::network_type network)> GetCheckpointsCallback;
|
||||
|
||||
typedef boost::function<void(uint64_t /* height */, epee::span<const block> /* blocks */)> BlockNotifyCallback;
|
||||
typedef boost::function<void(uint8_t /* major_version */, uint64_t /* height */, const crypto::hash& /* prev_id */, const crypto::hash& /* seed_hash */, difficulty_type /* diff */, uint64_t /* median_weight */, uint64_t /* already_generated_coins */, const std::vector<tx_block_template_backlog_entry>& /* tx_backlog */)> MinerNotifyCallback;
|
||||
|
||||
/************************************************************************/
|
||||
/* */
|
||||
/************************************************************************/
|
||||
@@ -369,6 +372,22 @@ namespace cryptonote
|
||||
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);
|
||||
|
||||
/**
|
||||
* @brief gets data required to create a block template and start mining on it
|
||||
*
|
||||
* @param major_version current hardfork version
|
||||
* @param height current blockchain height
|
||||
* @param prev_id hash of the top block
|
||||
* @param seed_hash seed hash used for RandomX initialization
|
||||
* @param difficulty current mining difficulty
|
||||
* @param median_weight current median block weight
|
||||
* @param already_generated_coins current emission
|
||||
* @param tx_backlog transactions in mempool ready to be mined
|
||||
*
|
||||
* @return true if block template filled in successfully, else false
|
||||
*/
|
||||
bool get_miner_data(uint8_t& major_version, uint64_t& height, crypto::hash& prev_id, crypto::hash& seed_hash, difficulty_type& difficulty, uint64_t& median_weight, uint64_t& already_generated_coins, std::vector<tx_block_template_backlog_entry>& tx_backlog);
|
||||
|
||||
/**
|
||||
* @brief checks if a block is known about with a given hash
|
||||
*
|
||||
@@ -771,7 +790,14 @@ 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 add_block_notify(BlockNotifyCallback&& notify);
|
||||
|
||||
/**
|
||||
* @brief sets a miner notify object to call for every new block
|
||||
*
|
||||
* @param notify the notify object to call at every new block
|
||||
*/
|
||||
void add_miner_notify(MinerNotifyCallback&& notify);
|
||||
|
||||
/**
|
||||
* @brief sets a reorg notify object to call for every reorg
|
||||
@@ -1153,7 +1179,8 @@ namespace cryptonote
|
||||
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::vector<BlockNotifyCallback> m_block_notifiers;
|
||||
std::vector<MinerNotifyCallback> m_miner_notifiers;
|
||||
std::shared_ptr<tools::Notify> m_reorg_notify;
|
||||
|
||||
// for prepare_handle_incoming_blocks
|
||||
@@ -1533,5 +1560,13 @@ 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);
|
||||
|
||||
/**
|
||||
* @brief sends new block notifications to ZMQ `miner_data` subscribers
|
||||
*
|
||||
* @param prev_id hash of new blockchain tip
|
||||
* @param already_generated_coins total coins mined by the network so far
|
||||
*/
|
||||
void send_miner_notifications(const crypto::hash &prev_id, uint64_t already_generated_coins);
|
||||
};
|
||||
} // namespace cryptonote
|
||||
|
||||
@@ -386,6 +386,7 @@ namespace cryptonote
|
||||
m_fluffy_blocks_enabled = !get_arg(vm, arg_no_fluffy_blocks);
|
||||
m_offline = get_arg(vm, arg_offline);
|
||||
m_disable_dns_checkpoints = get_arg(vm, arg_disable_dns_checkpoints);
|
||||
|
||||
if (!command_line::is_arg_defaulted(vm, arg_fluffy_blocks))
|
||||
MWARNING(arg_fluffy_blocks.name << " is obsolete, it is now default");
|
||||
|
||||
@@ -458,7 +459,7 @@ namespace cryptonote
|
||||
return m_blockchain_storage.get_alternative_blocks_count();
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::init(const boost::program_options::variables_map& vm, const cryptonote::test_options *test_options, const GetCheckpointsCallback& get_checkpoints/* = nullptr */)
|
||||
bool core::init(const boost::program_options::variables_map& vm, const cryptonote::test_options *test_options, const GetCheckpointsCallback& get_checkpoints/* = nullptr */, bool allow_dns)
|
||||
{
|
||||
start_time = std::time(nullptr);
|
||||
|
||||
@@ -469,6 +470,7 @@ namespace cryptonote
|
||||
}
|
||||
bool r = handle_command_line(vm);
|
||||
CHECK_AND_ASSERT_MES(r, false, "Failed to handle command line");
|
||||
m_disable_dns_checkpoints |= not allow_dns;
|
||||
|
||||
std::string db_sync_mode = command_line::get_arg(vm, cryptonote::arg_db_sync_mode);
|
||||
bool db_salvage = command_line::get_arg(vm, cryptonote::arg_db_salvage) != 0;
|
||||
@@ -695,7 +697,7 @@ namespace cryptonote
|
||||
CHECK_AND_ASSERT_MES(update_checkpoints(skip_dns_checkpoints), false, "One or more checkpoints loaded from json or dns conflicted with existing checkpoints.");
|
||||
|
||||
// DNS versions checking
|
||||
if (check_updates_string == "disabled")
|
||||
if (check_updates_string == "disabled" || not allow_dns)
|
||||
check_updates_level = UPDATES_DISABLED;
|
||||
else if (check_updates_string == "notify")
|
||||
check_updates_level = UPDATES_NOTIFY;
|
||||
@@ -1061,8 +1063,9 @@ namespace cryptonote
|
||||
if (already_have[i])
|
||||
continue;
|
||||
|
||||
const uint64_t weight = results[i].tx.pruned ? get_pruned_transaction_weight(results[i].tx) : get_transaction_weight(results[i].tx, it->blob.size());
|
||||
ok &= add_new_tx(results[i].tx, results[i].hash, tx_blobs[i].blob, weight, tvc[i], tx_relay, relayed);
|
||||
results[i].blob_size = it->blob.size();
|
||||
results[i].weight = results[i].tx.pruned ? get_pruned_transaction_weight(results[i].tx) : get_transaction_weight(results[i].tx, it->blob.size());
|
||||
ok &= add_new_tx(results[i].tx, results[i].hash, tx_blobs[i].blob, results[i].weight, tvc[i], tx_relay, relayed);
|
||||
|
||||
if(tvc[i].m_verifivation_failed)
|
||||
{MERROR_VER("Transaction verification failed: " << results[i].hash);}
|
||||
@@ -1401,6 +1404,11 @@ namespace cryptonote
|
||||
return m_blockchain_storage.create_block_template(b, prev_block, adr, diffic, height, expected_reward, ex_nonce, seed_height, seed_hash);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::get_miner_data(uint8_t& major_version, uint64_t& height, crypto::hash& prev_id, crypto::hash& seed_hash, difficulty_type& difficulty, uint64_t& median_weight, uint64_t& already_generated_coins, std::vector<tx_block_template_backlog_entry>& tx_backlog)
|
||||
{
|
||||
return m_blockchain_storage.get_miner_data(major_version, height, prev_id, seed_hash, difficulty, median_weight, already_generated_coins, tx_backlog);
|
||||
}
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
bool core::find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, bool clip_pruned, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const
|
||||
{
|
||||
return m_blockchain_storage.find_blockchain_supplement(qblock_ids, clip_pruned, resp);
|
||||
|
||||
@@ -236,6 +236,13 @@ namespace cryptonote
|
||||
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);
|
||||
|
||||
/**
|
||||
* @copydoc Blockchain::get_miner_data
|
||||
*
|
||||
* @note see Blockchain::get_miner_data
|
||||
*/
|
||||
bool get_miner_data(uint8_t& major_version, uint64_t& height, crypto::hash& prev_id, crypto::hash& seed_hash, difficulty_type& difficulty, uint64_t& median_weight, uint64_t& already_generated_coins, std::vector<tx_block_template_backlog_entry>& tx_backlog);
|
||||
|
||||
/**
|
||||
* @brief called when a transaction is relayed.
|
||||
* @note Should only be invoked from `levin_notify`.
|
||||
@@ -276,10 +283,11 @@ namespace cryptonote
|
||||
* @param vm command line parameters
|
||||
* @param test_options configuration options for testing
|
||||
* @param get_checkpoints if set, will be called to get checkpoints data, must return checkpoints data pointer and size or nullptr if there ain't any checkpoints for specific network type
|
||||
* @param allow_dns whether or not to allow DNS requests
|
||||
*
|
||||
* @return false if one of the init steps fails, otherwise true
|
||||
*/
|
||||
bool init(const boost::program_options::variables_map& vm, const test_options *test_options = NULL, const GetCheckpointsCallback& get_checkpoints = nullptr);
|
||||
bool init(const boost::program_options::variables_map& vm, const test_options *test_options = NULL, const GetCheckpointsCallback& get_checkpoints = nullptr, bool allow_dns = true);
|
||||
|
||||
/**
|
||||
* @copydoc Blockchain::reset_and_set_genesis_block
|
||||
|
||||
@@ -676,7 +676,7 @@ 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 blobdata& bd, crypto::hash& res, const uint64_t height, const int major_version, const crypto::hash *seed_hash, const int miners)
|
||||
{
|
||||
// block 202612 bug workaround
|
||||
if (height == 202612)
|
||||
@@ -685,8 +685,7 @@ namespace cryptonote
|
||||
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)
|
||||
if (major_version >= RX_BLOCK_VERSION)
|
||||
{
|
||||
uint64_t seed_height, main_height;
|
||||
crypto::hash hash;
|
||||
@@ -703,12 +702,18 @@ namespace cryptonote
|
||||
}
|
||||
rx_slow_hash(main_height, seed_height, hash.data, bd.data(), bd.size(), res.data, seed_hash ? 0 : miners, !!seed_hash);
|
||||
} else {
|
||||
const int pow_variant = b.major_version >= 7 ? b.major_version - 6 : 0;
|
||||
const int pow_variant = major_version >= 7 ? major_version - 6 : 0;
|
||||
crypto::cn_slow_hash(bd.data(), bd.size(), res, pow_variant, height);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
blobdata bd = get_block_hashing_blob(b);
|
||||
return get_block_longhash(pbc, bd, res, height, b.major_version, seed_hash, miners);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -107,6 +107,15 @@ namespace cryptonote
|
||||
END_SERIALIZE()
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
struct tx_block_template_backlog_entry
|
||||
{
|
||||
crypto::hash id;
|
||||
uint64_t weight;
|
||||
uint64_t fee;
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------
|
||||
crypto::public_key get_destination_view_key_pub(const std::vector<tx_destination_entry> &destinations, const boost::optional<cryptonote::account_public_address>& change_addr);
|
||||
bool construct_tx(const account_keys& sender_account_keys, std::vector<tx_source_entry> &sources, const std::vector<tx_destination_entry>& destinations, const boost::optional<cryptonote::account_public_address>& change_addr, const std::vector<uint8_t> &extra, transaction& tx, uint64_t unlock_time);
|
||||
@@ -133,6 +142,8 @@ namespace cryptonote
|
||||
);
|
||||
|
||||
class Blockchain;
|
||||
bool get_block_longhash(const Blockchain *pb, const blobdata& bd, crypto::hash& res, const uint64_t height,
|
||||
const int major_version, const crypto::hash *seed_hash, const int miners);
|
||||
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,
|
||||
|
||||
@@ -914,6 +914,32 @@ namespace cryptonote
|
||||
}, false, category);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
void tx_memory_pool::get_block_template_backlog(std::vector<tx_block_template_backlog_entry>& backlog, bool include_sensitive) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
CRITICAL_REGION_LOCAL1(m_blockchain);
|
||||
const relay_category category = include_sensitive ? relay_category::all : relay_category::broadcasted;
|
||||
backlog.reserve(m_blockchain.get_txpool_tx_count(include_sensitive));
|
||||
txpool_tx_meta_t tmp_meta;
|
||||
m_blockchain.for_all_txpool_txes([this, &backlog, &tmp_meta](const crypto::hash &txid, const txpool_tx_meta_t &meta, const cryptonote::blobdata_ref *bd){
|
||||
transaction tx;
|
||||
if (!(meta.pruned ? parse_and_validate_tx_base_from_blob(*bd, tx) : parse_and_validate_tx_from_blob(*bd, tx)))
|
||||
{
|
||||
MERROR("Failed to parse tx from txpool");
|
||||
// continue
|
||||
return true;
|
||||
}
|
||||
tx.set_hash(txid);
|
||||
|
||||
tmp_meta = meta;
|
||||
|
||||
if (is_transaction_ready_to_go(tmp_meta, txid, *bd, tx))
|
||||
backlog.push_back({txid, meta.weight, meta.fee});
|
||||
|
||||
return true;
|
||||
}, true, category);
|
||||
}
|
||||
//------------------------------------------------------------------
|
||||
void tx_memory_pool::get_transaction_stats(struct txpool_stats& stats, bool include_sensitive) const
|
||||
{
|
||||
CRITICAL_REGION_LOCAL(m_transactions_lock);
|
||||
@@ -1224,11 +1250,11 @@ namespace cryptonote
|
||||
return ret;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction &tx) const
|
||||
bool tx_memory_pool::is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata_ref& txblob, transaction &tx) const
|
||||
{
|
||||
struct transction_parser
|
||||
struct transaction_parser
|
||||
{
|
||||
transction_parser(const cryptonote::blobdata &txblob, const crypto::hash &txid, transaction &tx): txblob(txblob), txid(txid), tx(tx), parsed(false) {}
|
||||
transaction_parser(const cryptonote::blobdata_ref &txblob, const crypto::hash &txid, transaction &tx): txblob(txblob), txid(txid), tx(tx), parsed(false) {}
|
||||
cryptonote::transaction &operator()()
|
||||
{
|
||||
if (!parsed)
|
||||
@@ -1240,7 +1266,7 @@ namespace cryptonote
|
||||
}
|
||||
return tx;
|
||||
}
|
||||
const cryptonote::blobdata &txblob;
|
||||
const cryptonote::blobdata_ref &txblob;
|
||||
const crypto::hash &txid;
|
||||
transaction &tx;
|
||||
bool parsed;
|
||||
@@ -1291,6 +1317,11 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata& txblob, transaction &tx) const
|
||||
{
|
||||
return is_transaction_ready_to_go(txd, txid, cryptonote::blobdata_ref{txblob.data(), txblob.size()}, tx);
|
||||
}
|
||||
//---------------------------------------------------------------------------------
|
||||
bool tx_memory_pool::have_key_images(const std::unordered_set<crypto::key_image>& k_images, const transaction_prefix& tx)
|
||||
{
|
||||
for(size_t i = 0; i!= tx.vin.size(); i++)
|
||||
|
||||
@@ -265,6 +265,15 @@ namespace cryptonote
|
||||
*/
|
||||
void get_transaction_backlog(std::vector<tx_backlog_entry>& backlog, bool include_sensitive = false) const;
|
||||
|
||||
/**
|
||||
* @brief get (hash, weight, fee) for all transactions in the pool - the minimum required information to create a block template
|
||||
*
|
||||
* @param backlog return-by-reference that data
|
||||
* @param include_sensitive return stempool, anonymity-pool, and unrelayed txes
|
||||
*
|
||||
*/
|
||||
void get_block_template_backlog(std::vector<tx_block_template_backlog_entry>& backlog, bool include_sensitive = false) const;
|
||||
|
||||
/**
|
||||
* @brief get a summary statistics of all transaction hashes in the pool
|
||||
*
|
||||
@@ -540,6 +549,7 @@ namespace cryptonote
|
||||
*
|
||||
* @return true if the transaction is good to go, otherwise false
|
||||
*/
|
||||
bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata_ref &txblob, transaction&tx) const;
|
||||
bool is_transaction_ready_to_go(txpool_tx_meta_t& txd, const crypto::hash &txid, const cryptonote::blobdata &txblob, transaction&tx) const;
|
||||
|
||||
/**
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
# 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.
|
||||
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
cmake_minimum_required (VERSION 3.5)
|
||||
project (monero CXX)
|
||||
|
||||
file(GLOB CRYPTONOTE_PROTOCOL *)
|
||||
|
||||
@@ -153,6 +153,7 @@ namespace cryptonote
|
||||
context.m_last_request_time = boost::date_time::not_a_date_time;
|
||||
context.m_expect_response = 0;
|
||||
context.m_expect_height = 0;
|
||||
context.m_requested_objects.clear();
|
||||
context.m_state = cryptonote_connection_context::state_standby; // we'll go back to adding, then (if we can't), download
|
||||
}
|
||||
else
|
||||
|
||||
@@ -298,6 +298,12 @@ namespace levin
|
||||
boost::asio::steady_timer next_epoch;
|
||||
boost::asio::steady_timer flush_txs;
|
||||
boost::asio::io_service::strand strand;
|
||||
struct context_t {
|
||||
std::vector<cryptonote::blobdata> fluff_txs;
|
||||
std::chrono::steady_clock::time_point flush_time;
|
||||
bool m_is_income;
|
||||
};
|
||||
boost::unordered_map<boost::uuids::uuid, context_t> contexts;
|
||||
net::dandelionpp::connection_map map;//!< Tracks outgoing uuid's for noise channels or Dandelion++ stems
|
||||
std::deque<noise_channel> channels; //!< Never touch after init; only update elements on `noise_channel.strand`
|
||||
std::atomic<std::size_t> connection_count; //!< Only update in strand, can be read at any time
|
||||
@@ -374,14 +380,16 @@ namespace levin
|
||||
const auto now = std::chrono::steady_clock::now();
|
||||
auto next_flush = std::chrono::steady_clock::time_point::max();
|
||||
std::vector<std::pair<std::vector<blobdata>, boost::uuids::uuid>> connections{};
|
||||
zone_->p2p->foreach_connection([timer_error, now, &next_flush, &connections] (detail::p2p_context& context)
|
||||
for (auto &e: zone_->contexts)
|
||||
{
|
||||
auto &id = e.first;
|
||||
auto &context = e.second;
|
||||
if (!context.fluff_txs.empty())
|
||||
{
|
||||
if (context.flush_time <= now || timer_error) // flush on canceled timer
|
||||
{
|
||||
context.flush_time = std::chrono::steady_clock::time_point::max();
|
||||
connections.emplace_back(std::move(context.fluff_txs), context.m_connection_id);
|
||||
connections.emplace_back(std::move(context.fluff_txs), id);
|
||||
context.fluff_txs.clear();
|
||||
}
|
||||
else // not flushing yet
|
||||
@@ -389,8 +397,7 @@ namespace levin
|
||||
}
|
||||
else // nothing to flush
|
||||
context.flush_time = std::chrono::steady_clock::time_point::max();
|
||||
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
|
||||
@@ -438,22 +445,21 @@ namespace levin
|
||||
|
||||
|
||||
MDEBUG("Queueing " << txs.size() << " transaction(s) for Dandelion++ fluffing");
|
||||
|
||||
zone->p2p->foreach_connection([txs, now, &zone, &source, &in_duration, &out_duration, &next_flush] (detail::p2p_context& context)
|
||||
for (auto &e: zone->contexts)
|
||||
{
|
||||
auto &id = e.first;
|
||||
auto &context = e.second;
|
||||
// When i2p/tor, only fluff to outbound connections
|
||||
if (context.handshake_complete() && source != context.m_connection_id && (zone->nzone == epee::net_utils::zone::public_ || !context.m_is_income))
|
||||
if (source != id && (zone->nzone == epee::net_utils::zone::public_ || !context.m_is_income))
|
||||
{
|
||||
if (context.fluff_txs.empty())
|
||||
context.flush_time = now + (context.m_is_income ? in_duration() : out_duration());
|
||||
|
||||
next_flush = std::min(next_flush, context.flush_time);
|
||||
context.fluff_txs.reserve(context.fluff_txs.size() + txs.size());
|
||||
for (const blobdata& tx : txs)
|
||||
context.fluff_txs.push_back(tx); // must copy instead of move (multiple conns)
|
||||
context.fluff_txs.insert(context.fluff_txs.end(), txs.begin(), txs.end());
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
if (next_flush == std::chrono::steady_clock::time_point::max())
|
||||
MWARNING("Unable to send transaction(s), no available connections");
|
||||
@@ -764,6 +770,32 @@ namespace levin
|
||||
);
|
||||
}
|
||||
|
||||
void notify::on_handshake_complete(const boost::uuids::uuid &id, bool is_income)
|
||||
{
|
||||
if (!zone_)
|
||||
return;
|
||||
|
||||
auto& zone = zone_;
|
||||
zone_->strand.dispatch([zone, id, is_income]{
|
||||
zone->contexts[id] = {
|
||||
.fluff_txs = {},
|
||||
.flush_time = std::chrono::steady_clock::time_point::max(),
|
||||
.m_is_income = is_income,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
void notify::on_connection_close(const boost::uuids::uuid &id)
|
||||
{
|
||||
if (!zone_)
|
||||
return;
|
||||
|
||||
auto& zone = zone_;
|
||||
zone_->strand.dispatch([zone, id]{
|
||||
zone->contexts.erase(id);
|
||||
});
|
||||
}
|
||||
|
||||
void notify::run_epoch()
|
||||
{
|
||||
if (!zone_)
|
||||
|
||||
@@ -101,6 +101,9 @@ namespace levin
|
||||
//! Probe for new outbound connection - skips if not needed.
|
||||
void new_out_connection();
|
||||
|
||||
void on_handshake_complete(const boost::uuids::uuid &id, bool is_income);
|
||||
void on_connection_close(const boost::uuids::uuid &id);
|
||||
|
||||
//! Run the logic for the next epoch immediately. Only use in testing.
|
||||
void run_epoch();
|
||||
|
||||
|
||||
@@ -96,6 +96,16 @@ namespace daemon_args
|
||||
, 0
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> arg_proxy = {
|
||||
"proxy",
|
||||
"Network communication through proxy: <socks-ip:port> i.e. \"127.0.0.1:9050\"",
|
||||
"",
|
||||
};
|
||||
const command_line::arg_descriptor<bool> arg_proxy_allow_dns_leaks = {
|
||||
"proxy-allow-dns-leaks",
|
||||
"Allow DNS leaks outside of proxy",
|
||||
false,
|
||||
};
|
||||
const command_line::arg_descriptor<bool> arg_public_node = {
|
||||
"public-node"
|
||||
, "Allow other users to use the node as a remote (restricted RPC mode, view-only commands) and advertise it over P2P"
|
||||
|
||||
@@ -887,16 +887,66 @@ bool t_command_parser_executor::check_blockchain_pruning(const std::vector<std::
|
||||
|
||||
bool t_command_parser_executor::set_bootstrap_daemon(const std::vector<std::string>& args)
|
||||
{
|
||||
const size_t args_count = args.size();
|
||||
if (args_count < 1 || args_count > 3)
|
||||
struct parsed_t
|
||||
{
|
||||
std::string address;
|
||||
std::string user;
|
||||
std::string password;
|
||||
std::string proxy;
|
||||
};
|
||||
|
||||
boost::optional<parsed_t> parsed = [&args]() -> boost::optional<parsed_t> {
|
||||
const size_t args_count = args.size();
|
||||
if (args_count == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
if (args[0] == "auto")
|
||||
{
|
||||
if (args_count == 1)
|
||||
{
|
||||
return {{args[0], "", "", ""}};
|
||||
}
|
||||
if (args_count == 2)
|
||||
{
|
||||
return {{args[0], "", "", args[1]}};
|
||||
}
|
||||
}
|
||||
else if (args[0] == "none")
|
||||
{
|
||||
if (args_count == 1)
|
||||
{
|
||||
return {{"", "", "", ""}};
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (args_count == 1)
|
||||
{
|
||||
return {{args[0], "", "", ""}};
|
||||
}
|
||||
if (args_count == 2)
|
||||
{
|
||||
return {{args[0], "", "", args[1]}};
|
||||
}
|
||||
if (args_count == 3)
|
||||
{
|
||||
return {{args[0], args[1], args[2], ""}};
|
||||
}
|
||||
if (args_count == 4)
|
||||
{
|
||||
return {{args[0], args[1], args[2], args[3]}};
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}();
|
||||
|
||||
if (!parsed)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return m_executor.set_bootstrap_daemon(
|
||||
args[0] != "none" ? args[0] : std::string(),
|
||||
args_count > 1 ? args[1] : std::string(),
|
||||
args_count > 2 ? args[2] : std::string());
|
||||
return m_executor.set_bootstrap_daemon(parsed->address, parsed->user, parsed->password, parsed->proxy);
|
||||
}
|
||||
|
||||
bool t_command_parser_executor::flush_cache(const std::vector<std::string>& args)
|
||||
|
||||
@@ -324,7 +324,7 @@ t_command_server::t_command_server(
|
||||
m_command_lookup.set_handler(
|
||||
"set_bootstrap_daemon"
|
||||
, std::bind(&t_command_parser_executor::set_bootstrap_daemon, &m_parser, p::_1)
|
||||
, "set_bootstrap_daemon (auto | none | host[:port] [username] [password])"
|
||||
, "set_bootstrap_daemon (auto | none | host[:port] [username] [password]) [proxy_ip:proxy_port]"
|
||||
, "URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced.\n"
|
||||
"Use 'auto' to enable automatic public nodes discovering and bootstrap daemon switching"
|
||||
);
|
||||
|
||||
+9
-1
@@ -32,6 +32,7 @@
|
||||
#include "cryptonote_core/cryptonote_core.h"
|
||||
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
|
||||
#include "misc_log_ex.h"
|
||||
#include "daemon/command_line_args.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "daemon"
|
||||
@@ -66,7 +67,14 @@ public:
|
||||
#else
|
||||
const cryptonote::GetCheckpointsCallback& get_checkpoints = nullptr;
|
||||
#endif
|
||||
if (!m_core.init(m_vm_HACK, nullptr, get_checkpoints))
|
||||
|
||||
if (command_line::is_arg_defaulted(vm, daemon_args::arg_proxy) && command_line::get_arg(vm, daemon_args::arg_proxy_allow_dns_leaks)) {
|
||||
MLOG_RED(el::Level::Warning, "--" << daemon_args::arg_proxy_allow_dns_leaks.name << " is enabled, but --"
|
||||
<< daemon_args::arg_proxy.name << " is not specified.");
|
||||
}
|
||||
|
||||
const bool allow_dns = command_line::is_arg_defaulted(vm, daemon_args::arg_proxy) || command_line::get_arg(vm, daemon_args::arg_proxy_allow_dns_leaks);
|
||||
if (!m_core.init(m_vm_HACK, nullptr, get_checkpoints, allow_dns))
|
||||
{
|
||||
throw std::runtime_error("Failed to initialize core");
|
||||
}
|
||||
|
||||
@@ -120,6 +120,7 @@ public:
|
||||
if (shared)
|
||||
{
|
||||
core.get().get_blockchain_storage().add_block_notify(cryptonote::listener::zmq_pub::chain_main{shared});
|
||||
core.get().get_blockchain_storage().add_miner_notify(cryptonote::listener::zmq_pub::miner_data{shared});
|
||||
core.get().set_txpool_listener(cryptonote::listener::zmq_pub::txpool_add{shared});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -152,6 +152,8 @@ int main(int argc, char const * argv[])
|
||||
command_line::add_arg(core_settings, daemon_args::arg_max_log_file_size);
|
||||
command_line::add_arg(core_settings, daemon_args::arg_max_log_files);
|
||||
command_line::add_arg(core_settings, daemon_args::arg_max_concurrency);
|
||||
command_line::add_arg(core_settings, daemon_args::arg_proxy);
|
||||
command_line::add_arg(core_settings, daemon_args::arg_proxy_allow_dns_leaks);
|
||||
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);
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@
|
||||
#include "cryptonote_protocol/cryptonote_protocol_handler.h"
|
||||
#include "p2p/net_node.h"
|
||||
#include "daemon/protocol.h"
|
||||
#include "daemon/command_line_args.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "daemon"
|
||||
@@ -61,7 +62,7 @@ public:
|
||||
{
|
||||
//initialize objects
|
||||
MGINFO("Initializing p2p server...");
|
||||
if (!m_server.init(vm))
|
||||
if (!m_server.init(vm, command_line::get_arg(vm, daemon_args::arg_proxy), command_line::get_arg(vm, daemon_args::arg_proxy_allow_dns_leaks)))
|
||||
{
|
||||
throw std::runtime_error("Failed to initialize p2p server.");
|
||||
}
|
||||
|
||||
+1
-1
@@ -62,7 +62,7 @@ public:
|
||||
{
|
||||
MGINFO("Initializing " << m_description << " RPC server...");
|
||||
|
||||
if (!m_server.init(vm, restricted, port, allow_rpc_payment))
|
||||
if (!m_server.init(vm, restricted, port, allow_rpc_payment, command_line::get_arg(vm, daemon_args::arg_proxy)))
|
||||
{
|
||||
throw std::runtime_error("Failed to initialize " + m_description + " RPC server.");
|
||||
}
|
||||
|
||||
@@ -2405,7 +2405,8 @@ bool t_rpc_command_executor::check_blockchain_pruning()
|
||||
bool t_rpc_command_executor::set_bootstrap_daemon(
|
||||
const std::string &address,
|
||||
const std::string &username,
|
||||
const std::string &password)
|
||||
const std::string &password,
|
||||
const std::string &proxy)
|
||||
{
|
||||
cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::request req;
|
||||
cryptonote::COMMAND_RPC_SET_BOOTSTRAP_DAEMON::response res;
|
||||
@@ -2414,6 +2415,7 @@ bool t_rpc_command_executor::set_bootstrap_daemon(
|
||||
req.address = address;
|
||||
req.username = username;
|
||||
req.password = password;
|
||||
req.proxy = proxy;
|
||||
|
||||
if (m_is_rpc)
|
||||
{
|
||||
|
||||
@@ -168,7 +168,8 @@ public:
|
||||
bool set_bootstrap_daemon(
|
||||
const std::string &address,
|
||||
const std::string &username,
|
||||
const std::string &password);
|
||||
const std::string &password,
|
||||
const std::string &proxy);
|
||||
|
||||
bool rpc_payments();
|
||||
|
||||
|
||||
@@ -83,44 +83,33 @@ namespace hw {
|
||||
// Must be sorted in ascending order by the code
|
||||
#define LEDGER_STATUS(status) {status, #status}
|
||||
constexpr Status status_codes[] = {
|
||||
LEDGER_STATUS(SW_BYTES_REMAINING_00),
|
||||
LEDGER_STATUS(SW_WARNING_STATE_UNCHANGED),
|
||||
LEDGER_STATUS(SW_STATE_TERMINATED),
|
||||
LEDGER_STATUS(SW_MORE_DATA_AVAILABLE),
|
||||
LEDGER_STATUS(SW_OK),
|
||||
LEDGER_STATUS(SW_WRONG_LENGTH),
|
||||
LEDGER_STATUS(SW_LOGICAL_CHANNEL_NOT_SUPPORTED),
|
||||
LEDGER_STATUS(SW_SECURE_MESSAGING_NOT_SUPPORTED),
|
||||
LEDGER_STATUS(SW_LAST_COMMAND_EXPECTED),
|
||||
LEDGER_STATUS(SW_COMMAND_CHAINING_NOT_SUPPORTED),
|
||||
LEDGER_STATUS(SW_SECURITY_PIN_LOCKED),
|
||||
LEDGER_STATUS(SW_SECURITY_LOAD_KEY),
|
||||
LEDGER_STATUS(SW_SECURITY_COMMITMENT_CONTROL),
|
||||
LEDGER_STATUS(SW_SECURITY_AMOUNT_CHAIN_CONTROL),
|
||||
LEDGER_STATUS(SW_SECURITY_COMMITMENT_CHAIN_CONTROL),
|
||||
LEDGER_STATUS(SW_SECURITY_OUTKEYS_CHAIN_CONTROL),
|
||||
LEDGER_STATUS(SW_SECURITY_MAXOUTPUT_REACHED),
|
||||
LEDGER_STATUS(SW_SECURITY_TRUSTED_INPUT),
|
||||
LEDGER_STATUS(SW_CLIENT_NOT_SUPPORTED),
|
||||
LEDGER_STATUS(SW_SECURITY_STATUS_NOT_SATISFIED),
|
||||
LEDGER_STATUS(SW_FILE_INVALID),
|
||||
LEDGER_STATUS(SW_PIN_BLOCKED),
|
||||
LEDGER_STATUS(SW_DATA_INVALID),
|
||||
LEDGER_STATUS(SW_CONDITIONS_NOT_SATISFIED),
|
||||
LEDGER_STATUS(SW_SECURITY_HMAC),
|
||||
LEDGER_STATUS(SW_SECURITY_RANGE_VALUE),
|
||||
LEDGER_STATUS(SW_SECURITY_INTERNAL),
|
||||
LEDGER_STATUS(SW_SECURITY_MAX_SIGNATURE_REACHED),
|
||||
LEDGER_STATUS(SW_SECURITY_PREFIX_HASH),
|
||||
LEDGER_STATUS(SW_SECURITY_LOCKED),
|
||||
LEDGER_STATUS(SW_COMMAND_NOT_ALLOWED),
|
||||
LEDGER_STATUS(SW_APPLET_SELECT_FAILED),
|
||||
LEDGER_STATUS(SW_SUBCOMMAND_NOT_ALLOWED),
|
||||
LEDGER_STATUS(SW_DENY),
|
||||
LEDGER_STATUS(SW_KEY_NOT_SET),
|
||||
LEDGER_STATUS(SW_WRONG_DATA),
|
||||
LEDGER_STATUS(SW_FUNC_NOT_SUPPORTED),
|
||||
LEDGER_STATUS(SW_FILE_NOT_FOUND),
|
||||
LEDGER_STATUS(SW_RECORD_NOT_FOUND),
|
||||
LEDGER_STATUS(SW_FILE_FULL),
|
||||
LEDGER_STATUS(SW_INCORRECT_P1P2),
|
||||
LEDGER_STATUS(SW_REFERENCED_DATA_NOT_FOUND),
|
||||
LEDGER_STATUS(SW_WRONG_DATA_RANGE),
|
||||
LEDGER_STATUS(SW_IO_FULL),
|
||||
LEDGER_STATUS(SW_CLIENT_NOT_SUPPORTED),
|
||||
LEDGER_STATUS(SW_WRONG_P1P2),
|
||||
LEDGER_STATUS(SW_CORRECT_LENGTH_00),
|
||||
LEDGER_STATUS(SW_INS_NOT_SUPPORTED),
|
||||
LEDGER_STATUS(SW_CLA_NOT_SUPPORTED),
|
||||
LEDGER_STATUS(SW_UNKNOWN),
|
||||
LEDGER_STATUS(SW_OK),
|
||||
LEDGER_STATUS(SW_ALGORITHM_UNSUPPORTED)
|
||||
LEDGER_STATUS(SW_PROTOCOL_NOT_SUPPORTED),
|
||||
LEDGER_STATUS(SW_UNKNOWN)
|
||||
};
|
||||
|
||||
const char *Status::to_string(unsigned int code)
|
||||
@@ -462,13 +451,6 @@ namespace hw {
|
||||
|
||||
ASSERT_X(this->length_recv>=3, "Communication error, less than three bytes received. Check your application version.");
|
||||
|
||||
unsigned int device_version = 0;
|
||||
device_version = VERSION(this->buffer_recv[0], this->buffer_recv[1], this->buffer_recv[2]);
|
||||
|
||||
ASSERT_X (device_version >= MINIMAL_APP_VERSION,
|
||||
"Unsupported device application version: " << VERSION_MAJOR(device_version)<<"."<<VERSION_MINOR(device_version)<<"."<<VERSION_MICRO(device_version) <<
|
||||
" At least " << MINIMAL_APP_VERSION_MAJOR<<"."<<MINIMAL_APP_VERSION_MINOR<<"."<<MINIMAL_APP_VERSION_MICRO<<" is required.");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -481,6 +463,9 @@ namespace hw {
|
||||
this->length_recv -= 2;
|
||||
this->sw = (this->buffer_recv[length_recv]<<8) | this->buffer_recv[length_recv+1];
|
||||
logRESP();
|
||||
MDEBUG("Device "<< this->id << " exchange: sw: " << this->sw << " expected: " << ok);
|
||||
ASSERT_X(sw != SW_CLIENT_NOT_SUPPORTED, "Monero Ledger App doesn't support current monero version. Try to update the Monero Ledger App, at least " << MINIMAL_APP_VERSION_MAJOR<< "." << MINIMAL_APP_VERSION_MINOR << "." << MINIMAL_APP_VERSION_MICRO << " is required.");
|
||||
ASSERT_X(sw != SW_PROTOCOL_NOT_SUPPORTED, "Make sure no other program is communicating with the Ledger.");
|
||||
ASSERT_SW(this->sw,ok,msk);
|
||||
|
||||
return this->sw;
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace hw {
|
||||
/* Minimal supported version */
|
||||
#define MINIMAL_APP_VERSION_MAJOR 1
|
||||
#define MINIMAL_APP_VERSION_MINOR 7
|
||||
#define MINIMAL_APP_VERSION_MICRO 6
|
||||
#define MINIMAL_APP_VERSION_MICRO 8
|
||||
|
||||
#define VERSION(M,m,u) ((M)<<16|(m)<<8|(u))
|
||||
#define VERSION_MAJOR(v) (((v)>>16)&0xFF)
|
||||
@@ -59,44 +59,33 @@ namespace hw {
|
||||
#ifdef WITH_DEVICE_LEDGER
|
||||
|
||||
// Origin: https://github.com/LedgerHQ/ledger-app-monero/blob/master/src/monero_types.h
|
||||
#define SW_BYTES_REMAINING_00 0x6100
|
||||
#define SW_WARNING_STATE_UNCHANGED 0x6200
|
||||
#define SW_STATE_TERMINATED 0x6285
|
||||
#define SW_MORE_DATA_AVAILABLE 0x6310
|
||||
#define SW_WRONG_LENGTH 0x6700
|
||||
#define SW_LOGICAL_CHANNEL_NOT_SUPPORTED 0x6881
|
||||
#define SW_SECURE_MESSAGING_NOT_SUPPORTED 0x6882
|
||||
#define SW_LAST_COMMAND_EXPECTED 0x6883
|
||||
#define SW_COMMAND_CHAINING_NOT_SUPPORTED 0x6884
|
||||
#define SW_SECURITY_LOAD_KEY 0x6900
|
||||
#define SW_SECURITY_COMMITMENT_CONTROL 0x6911
|
||||
#define SW_SECURITY_AMOUNT_CHAIN_CONTROL 0x6912
|
||||
#define SW_SECURITY_COMMITMENT_CHAIN_CONTROL 0x6913
|
||||
#define SW_SECURITY_OUTKEYS_CHAIN_CONTROL 0x6914
|
||||
#define SW_SECURITY_MAXOUTPUT_REACHED 0x6915
|
||||
#define SW_SECURITY_TRUSTED_INPUT 0x6916
|
||||
#define SW_CLIENT_NOT_SUPPORTED 0x6930
|
||||
#define SW_SECURITY_STATUS_NOT_SATISFIED 0x6982
|
||||
#define SW_FILE_INVALID 0x6983
|
||||
#define SW_PIN_BLOCKED 0x6983
|
||||
#define SW_DATA_INVALID 0x6984
|
||||
#define SW_CONDITIONS_NOT_SATISFIED 0x6985
|
||||
#define SW_COMMAND_NOT_ALLOWED 0x6986
|
||||
#define SW_APPLET_SELECT_FAILED 0x6999
|
||||
#define SW_WRONG_DATA 0x6a80
|
||||
#define SW_FUNC_NOT_SUPPORTED 0x6a81
|
||||
#define SW_FILE_NOT_FOUND 0x6a82
|
||||
#define SW_RECORD_NOT_FOUND 0x6a83
|
||||
#define SW_FILE_FULL 0x6a84
|
||||
#define SW_INCORRECT_P1P2 0x6a86
|
||||
#define SW_REFERENCED_DATA_NOT_FOUND 0x6a88
|
||||
#define SW_WRONG_P1P2 0x6b00
|
||||
#define SW_CORRECT_LENGTH_00 0x6c00
|
||||
#define SW_INS_NOT_SUPPORTED 0x6d00
|
||||
#define SW_CLA_NOT_SUPPORTED 0x6e00
|
||||
#define SW_UNKNOWN 0x6f00
|
||||
#define SW_OK 0x9000
|
||||
#define SW_ALGORITHM_UNSUPPORTED 0x9484
|
||||
#define SW_OK 0x9000
|
||||
#define SW_WRONG_LENGTH 0x6700
|
||||
#define SW_SECURITY_PIN_LOCKED 0x6910
|
||||
#define SW_SECURITY_LOAD_KEY 0x6911
|
||||
#define SW_SECURITY_COMMITMENT_CONTROL 0x6912
|
||||
#define SW_SECURITY_AMOUNT_CHAIN_CONTROL 0x6913
|
||||
#define SW_SECURITY_COMMITMENT_CHAIN_CONTROL 0x6914
|
||||
#define SW_SECURITY_OUTKEYS_CHAIN_CONTROL 0x6915
|
||||
#define SW_SECURITY_MAXOUTPUT_REACHED 0x6916
|
||||
#define SW_SECURITY_HMAC 0x6917
|
||||
#define SW_SECURITY_RANGE_VALUE 0x6918
|
||||
#define SW_SECURITY_INTERNAL 0x6919
|
||||
#define SW_SECURITY_MAX_SIGNATURE_REACHED 0x691A
|
||||
#define SW_SECURITY_PREFIX_HASH 0x691B
|
||||
#define SW_SECURITY_LOCKED 0x69EE
|
||||
#define SW_COMMAND_NOT_ALLOWED 0x6980
|
||||
#define SW_SUBCOMMAND_NOT_ALLOWED 0x6981
|
||||
#define SW_DENY 0x6982
|
||||
#define SW_KEY_NOT_SET 0x6983
|
||||
#define SW_WRONG_DATA 0x6984
|
||||
#define SW_WRONG_DATA_RANGE 0x6985
|
||||
#define SW_IO_FULL 0x6986
|
||||
#define SW_CLIENT_NOT_SUPPORTED 0x6A30
|
||||
#define SW_WRONG_P1P2 0x6b00
|
||||
#define SW_INS_NOT_SUPPORTED 0x6d00
|
||||
#define SW_PROTOCOL_NOT_SUPPORTED 0x6e00
|
||||
#define SW_UNKNOWN 0x6f00
|
||||
|
||||
namespace {
|
||||
bool apdu_verbose =true;
|
||||
|
||||
@@ -64,8 +64,8 @@ namespace trezor {
|
||||
|
||||
device_trezor::~device_trezor() {
|
||||
try {
|
||||
disconnect();
|
||||
release();
|
||||
device_trezor::disconnect();
|
||||
device_trezor::release();
|
||||
} catch(std::exception const& e){
|
||||
MWARNING("Could not disconnect and release: " << e.what());
|
||||
}
|
||||
|
||||
@@ -129,7 +129,7 @@ namespace Language
|
||||
if ((*it).size() < unique_prefix_length)
|
||||
{
|
||||
if (flags & ALLOW_SHORT_WORDS)
|
||||
MWARNING(language_name << " word '" << *it << "' is shorter than its prefix length, " << unique_prefix_length);
|
||||
MINFO(language_name << " word '" << *it << "' is shorter than its prefix length, " << unique_prefix_length);
|
||||
else
|
||||
throw std::runtime_error("Too short word in " + language_name + " word list: " + *it);
|
||||
}
|
||||
|
||||
+3
-2
@@ -322,8 +322,9 @@ namespace socks
|
||||
{
|
||||
if (self && self->proxy_.is_open())
|
||||
{
|
||||
self->proxy_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
|
||||
self->proxy_.close();
|
||||
boost::system::error_code ec;
|
||||
self->proxy_.shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
|
||||
self->proxy_.close(ec);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -201,6 +201,13 @@ namespace socks
|
||||
std::shared_ptr<client> self_;
|
||||
void operator()(boost::system::error_code error = boost::system::error_code{});
|
||||
};
|
||||
|
||||
//! Calls `async_close` on `self` at destruction. NOP if `nullptr`.
|
||||
struct close_on_exit
|
||||
{
|
||||
std::shared_ptr<client> self;
|
||||
~close_on_exit() { async_close{std::move(self)}(); }
|
||||
};
|
||||
};
|
||||
|
||||
template<typename Handler>
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
# 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.
|
||||
|
||||
cmake_minimum_required (VERSION 2.6)
|
||||
cmake_minimum_required (VERSION 3.5)
|
||||
project (monero CXX)
|
||||
|
||||
file(GLOB P2P *)
|
||||
|
||||
@@ -94,6 +94,9 @@ namespace
|
||||
case net::i2p_address::get_type_id():
|
||||
set = client->set_connect_command(remote.as<net::i2p_address>());
|
||||
break;
|
||||
case epee::net_utils::ipv4_network_address::get_type_id():
|
||||
set = client->set_connect_command(remote.as<epee::net_utils::ipv4_network_address>());
|
||||
break;
|
||||
default:
|
||||
MERROR("Unsupported network address in socks_connect");
|
||||
return false;
|
||||
@@ -338,6 +341,7 @@ namespace nodetool
|
||||
}
|
||||
};
|
||||
|
||||
net::socks::client::close_on_exit close_client{};
|
||||
boost::unique_future<client_result> socks_result{};
|
||||
{
|
||||
boost::promise<client_result> socks_promise{};
|
||||
@@ -346,6 +350,7 @@ namespace nodetool
|
||||
auto client = net::socks::make_connect_client(
|
||||
boost::asio::ip::tcp::socket{service}, net::socks::version::v4a, notify{std::move(socks_promise)}
|
||||
);
|
||||
close_client.self = client;
|
||||
if (!start_socks(std::move(client), proxy, remote))
|
||||
return boost::none;
|
||||
}
|
||||
@@ -367,7 +372,10 @@ namespace nodetool
|
||||
{
|
||||
auto result = socks_result.get();
|
||||
if (!result.first)
|
||||
{
|
||||
close_client.self.reset();
|
||||
return {std::move(result.second)};
|
||||
}
|
||||
|
||||
MERROR("Failed to make socks connection to " << remote.str() << " (via " << proxy << "): " << result.first.message());
|
||||
}
|
||||
|
||||
+5
-7
@@ -111,15 +111,11 @@ namespace nodetool
|
||||
struct p2p_connection_context_t: base_type //t_payload_net_handler::connection_context //public net_utils::connection_context_base
|
||||
{
|
||||
p2p_connection_context_t()
|
||||
: fluff_txs(),
|
||||
flush_time(std::chrono::steady_clock::time_point::max()),
|
||||
peer_id(0),
|
||||
: peer_id(0),
|
||||
support_flags(0),
|
||||
m_in_timedsync(false)
|
||||
{}
|
||||
|
||||
std::vector<cryptonote::blobdata> fluff_txs;
|
||||
std::chrono::steady_clock::time_point flush_time;
|
||||
peerid_type peer_id;
|
||||
uint32_t support_flags;
|
||||
bool m_in_timedsync;
|
||||
@@ -258,7 +254,8 @@ namespace nodetool
|
||||
m_igd(no_igd),
|
||||
m_offline(false),
|
||||
is_closing(false),
|
||||
m_network_id()
|
||||
m_network_id(),
|
||||
m_enable_dns_seed_nodes(true)
|
||||
{}
|
||||
virtual ~node_server();
|
||||
|
||||
@@ -266,7 +263,7 @@ namespace nodetool
|
||||
|
||||
bool run();
|
||||
network_zone& add_zone(epee::net_utils::zone zone);
|
||||
bool init(const boost::program_options::variables_map& vm);
|
||||
bool init(const boost::program_options::variables_map& vm, const std::string& proxy = {}, bool proxy_dns_leaks_allowed = {});
|
||||
bool deinit();
|
||||
bool send_stop_signal();
|
||||
uint32_t get_this_peer_port(){return m_listening_port;}
|
||||
@@ -516,6 +513,7 @@ namespace nodetool
|
||||
|
||||
epee::net_utils::ssl_support_t m_ssl_support;
|
||||
|
||||
bool m_enable_dns_seed_nodes;
|
||||
bool m_enable_dns_blocklist;
|
||||
};
|
||||
|
||||
|
||||
+32
-2
@@ -694,11 +694,15 @@ namespace nodetool
|
||||
full_addrs.insert("212.83.175.67:28080");
|
||||
full_addrs.insert("212.83.172.165:28080");
|
||||
full_addrs.insert("192.110.160.146:28080");
|
||||
full_addrs.insert("88.99.173.38:28080");
|
||||
full_addrs.insert("51.79.173.165:28080");
|
||||
}
|
||||
else if (m_nettype == cryptonote::STAGENET)
|
||||
{
|
||||
full_addrs.insert("162.210.173.150:38080");
|
||||
full_addrs.insert("192.110.160.146:38080");
|
||||
full_addrs.insert("88.99.173.38:38080");
|
||||
full_addrs.insert("51.79.173.165:38080");
|
||||
}
|
||||
else if (m_nettype == cryptonote::FAKECHAIN)
|
||||
{
|
||||
@@ -713,6 +717,8 @@ namespace nodetool
|
||||
full_addrs.insert("209.250.243.248:18080");
|
||||
full_addrs.insert("104.238.221.81:18080");
|
||||
full_addrs.insert("66.85.74.134:18080");
|
||||
full_addrs.insert("88.99.173.38:18080");
|
||||
full_addrs.insert("51.79.173.165:18080");
|
||||
}
|
||||
return full_addrs;
|
||||
}
|
||||
@@ -732,6 +738,12 @@ namespace nodetool
|
||||
{
|
||||
return get_ip_seed_nodes();
|
||||
}
|
||||
if (!m_enable_dns_seed_nodes)
|
||||
{
|
||||
// TODO: a domain can be set through socks, so that the remote side does the lookup for the DNS seed nodes.
|
||||
m_fallback_seed_nodes_added.test_and_set();
|
||||
return get_ip_seed_nodes();
|
||||
}
|
||||
|
||||
std::set<std::string> full_addrs;
|
||||
|
||||
@@ -839,7 +851,8 @@ namespace nodetool
|
||||
return {
|
||||
"xwvz3ekocr3dkyxfkmgm2hvbpzx2ysqmaxgter7znnqrhoicygkfswid.onion:18083",
|
||||
"4pixvbejrvihnkxmduo2agsnmc3rrulrqc7s3cbwwrep6h6hrzsibeqd.onion:18083",
|
||||
"zbjkbsxc5munw3qusl7j2hpcmikhqocdf4pqhnhtpzw5nt5jrmofptid.onion:18083"
|
||||
"zbjkbsxc5munw3qusl7j2hpcmikhqocdf4pqhnhtpzw5nt5jrmofptid.onion:18083",
|
||||
"qz43zul2x56jexzoqgkx2trzwcfnr6l3hbtfcfx54g4r3eahy3bssjyd.onion:18083",
|
||||
};
|
||||
}
|
||||
return {};
|
||||
@@ -870,10 +883,21 @@ namespace nodetool
|
||||
}
|
||||
//-----------------------------------------------------------------------------------
|
||||
template<class t_payload_net_handler>
|
||||
bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm)
|
||||
bool node_server<t_payload_net_handler>::init(const boost::program_options::variables_map& vm, const std::string& proxy, bool proxy_dns_leaks_allowed)
|
||||
{
|
||||
bool res = handle_command_line(vm);
|
||||
CHECK_AND_ASSERT_MES(res, false, "Failed to handle command line");
|
||||
if (proxy.size())
|
||||
{
|
||||
const auto endpoint = net::get_tcp_endpoint(proxy);
|
||||
CHECK_AND_ASSERT_MES(endpoint, false, "Failed to parse proxy: " << proxy << " - " << endpoint.error());
|
||||
network_zone& public_zone = m_network_zones[epee::net_utils::zone::public_];
|
||||
public_zone.m_connect = &socks_connect;
|
||||
public_zone.m_proxy_address = *endpoint;
|
||||
public_zone.m_can_pingback = false;
|
||||
m_enable_dns_seed_nodes &= proxy_dns_leaks_allowed;
|
||||
m_enable_dns_blocklist &= proxy_dns_leaks_allowed;
|
||||
}
|
||||
|
||||
if (m_nettype == cryptonote::TESTNET)
|
||||
{
|
||||
@@ -1432,6 +1456,7 @@ namespace nodetool
|
||||
ape.first_seen = first_seen_stamp ? first_seen_stamp : time(nullptr);
|
||||
|
||||
zone.m_peerlist.append_with_peer_anchor(ape);
|
||||
zone.m_notifier.on_handshake_complete(con->m_connection_id, con->m_is_income);
|
||||
zone.m_notifier.new_out_connection();
|
||||
|
||||
LOG_DEBUG_CC(*con, "CONNECTION HANDSHAKED OK.");
|
||||
@@ -2559,6 +2584,8 @@ namespace nodetool
|
||||
return 1;
|
||||
}
|
||||
|
||||
zone.m_notifier.on_handshake_complete(context.m_connection_id, context.m_is_income);
|
||||
|
||||
if(has_too_many_connections(context.m_remote_address))
|
||||
{
|
||||
LOG_PRINT_CCONTEXT_L1("CONNECTION FROM " << context.m_remote_address.host_str() << " REFUSED, too many connections from the same address");
|
||||
@@ -2683,6 +2710,9 @@ namespace nodetool
|
||||
zone.m_peerlist.remove_from_peer_anchor(na);
|
||||
}
|
||||
|
||||
if (!zone.m_net_server.is_stop_signal_sent()) {
|
||||
zone.m_notifier.on_connection_close(context.m_connection_id);
|
||||
}
|
||||
m_payload_handler.on_connection_close(context);
|
||||
|
||||
MINFO("["<< epee::net_utils::print_connection_context(context) << "] CLOSE CONNECTION");
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include "crypto/crypto.h"
|
||||
#include "cryptonote_core/cryptonote_core.h"
|
||||
#include "misc_log_ex.h"
|
||||
#include "net/parse.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "daemon.rpc.bootstrap_daemon"
|
||||
@@ -16,19 +17,23 @@ namespace cryptonote
|
||||
|
||||
bootstrap_daemon::bootstrap_daemon(
|
||||
std::function<std::map<std::string, bool>()> get_public_nodes,
|
||||
bool rpc_payment_enabled)
|
||||
bool rpc_payment_enabled,
|
||||
const std::string &proxy)
|
||||
: m_selector(new bootstrap_node::selector_auto(std::move(get_public_nodes)))
|
||||
, m_rpc_payment_enabled(rpc_payment_enabled)
|
||||
{
|
||||
set_proxy(proxy);
|
||||
}
|
||||
|
||||
bootstrap_daemon::bootstrap_daemon(
|
||||
const std::string &address,
|
||||
boost::optional<epee::net_utils::http::login> credentials,
|
||||
bool rpc_payment_enabled)
|
||||
bool rpc_payment_enabled,
|
||||
const std::string &proxy)
|
||||
: m_selector(nullptr)
|
||||
, m_rpc_payment_enabled(rpc_payment_enabled)
|
||||
{
|
||||
set_proxy(proxy);
|
||||
if (!set_server(address, std::move(credentials)))
|
||||
{
|
||||
throw std::runtime_error("invalid bootstrap daemon address or credentials");
|
||||
@@ -78,6 +83,18 @@ namespace cryptonote
|
||||
return success;
|
||||
}
|
||||
|
||||
void bootstrap_daemon::set_proxy(const std::string &address)
|
||||
{
|
||||
if (!address.empty() && !net::get_tcp_endpoint(address))
|
||||
{
|
||||
throw std::runtime_error("invalid proxy address format");
|
||||
}
|
||||
if (!m_http_client.set_proxy(address))
|
||||
{
|
||||
throw std::runtime_error("failed to set proxy address");
|
||||
}
|
||||
}
|
||||
|
||||
bool bootstrap_daemon::set_server(const std::string &address, const boost::optional<epee::net_utils::http::login> &credentials /* = boost::none */)
|
||||
{
|
||||
if (!m_http_client.set_server(address, credentials))
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <boost/thread/mutex.hpp>
|
||||
#include <boost/utility/string_ref.hpp>
|
||||
|
||||
#include "net/http_client.h"
|
||||
#include "net/http.h"
|
||||
#include "storages/http_abstract_invoke.h"
|
||||
|
||||
#include "bootstrap_node_selector.h"
|
||||
@@ -21,11 +21,13 @@ namespace cryptonote
|
||||
public:
|
||||
bootstrap_daemon(
|
||||
std::function<std::map<std::string, bool>()> get_public_nodes,
|
||||
bool rpc_payment_enabled);
|
||||
bool rpc_payment_enabled,
|
||||
const std::string &proxy);
|
||||
bootstrap_daemon(
|
||||
const std::string &address,
|
||||
boost::optional<epee::net_utils::http::login> credentials,
|
||||
bool rpc_payment_enabled);
|
||||
bool rpc_payment_enabled,
|
||||
const std::string &proxy);
|
||||
|
||||
std::string address() const noexcept;
|
||||
boost::optional<std::pair<uint64_t, uint64_t>> get_height();
|
||||
@@ -72,12 +74,14 @@ namespace cryptonote
|
||||
return handle_result(result, result_struct.status);
|
||||
}
|
||||
|
||||
void set_proxy(const std::string &address);
|
||||
|
||||
private:
|
||||
bool set_server(const std::string &address, const boost::optional<epee::net_utils::http::login> &credentials = boost::none);
|
||||
bool switch_server_if_needed();
|
||||
|
||||
private:
|
||||
epee::net_utils::http::http_simple_client m_http_client;
|
||||
net::http::client m_http_client;
|
||||
const bool m_rpc_payment_enabled;
|
||||
const std::unique_ptr<bootstrap_node::selector> m_selector;
|
||||
boost::mutex m_selector_mutex;
|
||||
|
||||
+130
-12
@@ -154,6 +154,7 @@ namespace cryptonote
|
||||
command_line::add_arg(desc, arg_restricted_rpc);
|
||||
command_line::add_arg(desc, arg_bootstrap_daemon_address);
|
||||
command_line::add_arg(desc, arg_bootstrap_daemon_login);
|
||||
command_line::add_arg(desc, arg_bootstrap_daemon_proxy);
|
||||
cryptonote::rpc_args::init_options(desc, true);
|
||||
command_line::add_arg(desc, arg_rpc_payment_address);
|
||||
command_line::add_arg(desc, arg_rpc_payment_difficulty);
|
||||
@@ -172,7 +173,10 @@ namespace cryptonote
|
||||
, m_rpc_payment_allow_free_loopback(false)
|
||||
{}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::set_bootstrap_daemon(const std::string &address, const std::string &username_password)
|
||||
bool core_rpc_server::set_bootstrap_daemon(
|
||||
const std::string &address,
|
||||
const std::string &username_password,
|
||||
const std::string &proxy)
|
||||
{
|
||||
boost::optional<epee::net_utils::http::login> credentials;
|
||||
const auto loc = username_password.find(':');
|
||||
@@ -180,7 +184,7 @@ namespace cryptonote
|
||||
{
|
||||
credentials = epee::net_utils::http::login(username_password.substr(0, loc), username_password.substr(loc + 1));
|
||||
}
|
||||
return set_bootstrap_daemon(address, credentials);
|
||||
return set_bootstrap_daemon(address, credentials, proxy);
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
std::map<std::string, bool> core_rpc_server::get_public_nodes(uint32_t credits_per_hash_threshold/* = 0*/)
|
||||
@@ -217,7 +221,10 @@ namespace cryptonote
|
||||
return result;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::set_bootstrap_daemon(const std::string &address, const boost::optional<epee::net_utils::http::login> &credentials)
|
||||
bool core_rpc_server::set_bootstrap_daemon(
|
||||
const std::string &address,
|
||||
const boost::optional<epee::net_utils::http::login> &credentials,
|
||||
const std::string &proxy)
|
||||
{
|
||||
boost::unique_lock<boost::shared_mutex> lock(m_bootstrap_daemon_mutex);
|
||||
|
||||
@@ -233,11 +240,11 @@ namespace cryptonote
|
||||
auto get_nodes = [this]() {
|
||||
return get_public_nodes(credits_per_hash_threshold);
|
||||
};
|
||||
m_bootstrap_daemon.reset(new bootstrap_daemon(std::move(get_nodes), rpc_payment_enabled));
|
||||
m_bootstrap_daemon.reset(new bootstrap_daemon(std::move(get_nodes), rpc_payment_enabled, m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy));
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bootstrap_daemon.reset(new bootstrap_daemon(address, credentials, rpc_payment_enabled));
|
||||
m_bootstrap_daemon.reset(new bootstrap_daemon(address, credentials, rpc_payment_enabled, m_bootstrap_daemon_proxy.empty() ? proxy : m_bootstrap_daemon_proxy));
|
||||
}
|
||||
|
||||
m_should_use_bootstrap_daemon = m_bootstrap_daemon.get() != nullptr;
|
||||
@@ -255,8 +262,10 @@ namespace cryptonote
|
||||
, const bool restricted
|
||||
, const std::string& port
|
||||
, bool allow_rpc_payment
|
||||
, const std::string& proxy
|
||||
)
|
||||
{
|
||||
m_bootstrap_daemon_proxy = proxy;
|
||||
m_restricted = restricted;
|
||||
m_net_server.set_threads_prefix("RPC");
|
||||
m_net_server.set_connection_filter(&m_p2p);
|
||||
@@ -318,8 +327,10 @@ namespace cryptonote
|
||||
MWARNING("The RPC server is accessible from the outside, but no RPC payment was setup. RPC access will be free for all.");
|
||||
}
|
||||
|
||||
if (!set_bootstrap_daemon(command_line::get_arg(vm, arg_bootstrap_daemon_address),
|
||||
command_line::get_arg(vm, arg_bootstrap_daemon_login)))
|
||||
if (!set_bootstrap_daemon(
|
||||
command_line::get_arg(vm, arg_bootstrap_daemon_address),
|
||||
command_line::get_arg(vm, arg_bootstrap_daemon_login),
|
||||
command_line::get_arg(vm, arg_bootstrap_daemon_proxy)))
|
||||
{
|
||||
MFATAL("Failed to parse bootstrap daemon address");
|
||||
return false;
|
||||
@@ -939,14 +950,26 @@ namespace cryptonote
|
||||
LOG_PRINT_L2("Found " << found_in_pool << "/" << vh.size() << " transactions in the pool");
|
||||
}
|
||||
|
||||
std::vector<std::string>::const_iterator txhi = req.txs_hashes.begin();
|
||||
std::vector<crypto::hash>::const_iterator vhi = vh.begin();
|
||||
CHECK_AND_ASSERT_MES(txs.size() + missed_txs.size() == vh.size(), false, "mismatched number of txs");
|
||||
|
||||
auto txhi = req.txs_hashes.cbegin();
|
||||
auto vhi = vh.cbegin();
|
||||
auto missedi = missed_txs.cbegin();
|
||||
|
||||
for(auto& tx: txs)
|
||||
{
|
||||
res.txs.push_back(COMMAND_RPC_GET_TRANSACTIONS::entry());
|
||||
COMMAND_RPC_GET_TRANSACTIONS::entry &e = res.txs.back();
|
||||
|
||||
while (missedi != missed_txs.end() && *missedi == *vhi)
|
||||
{
|
||||
++vhi;
|
||||
++txhi;
|
||||
++missedi;
|
||||
}
|
||||
|
||||
crypto::hash tx_hash = *vhi++;
|
||||
CHECK_AND_ASSERT_MES(tx_hash == std::get<0>(tx), false, "mismatched tx hash");
|
||||
e.tx_hash = *txhi++;
|
||||
e.prunable_hash = epee::string_tools::pod_to_hex(std::get<2>(tx));
|
||||
if (req.split || req.prune || std::get<3>(tx).empty())
|
||||
@@ -1596,15 +1619,15 @@ namespace cryptonote
|
||||
{
|
||||
credentials = epee::net_utils::http::login(req.username, req.password);
|
||||
}
|
||||
|
||||
if (set_bootstrap_daemon(req.address, credentials))
|
||||
|
||||
if (set_bootstrap_daemon(req.address, credentials, req.proxy))
|
||||
{
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
res.status = "Failed to set bootstrap daemon";
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -1828,6 +1851,80 @@ namespace cryptonote
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_getminerdata(const COMMAND_RPC_GETMINERDATA::request& req, COMMAND_RPC_GETMINERDATA::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||
{
|
||||
if(!check_core_ready())
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_CORE_BUSY;
|
||||
error_resp.message = "Core is busy";
|
||||
return false;
|
||||
}
|
||||
|
||||
crypto::hash prev_id, seed_hash;
|
||||
difficulty_type difficulty;
|
||||
|
||||
std::vector<tx_block_template_backlog_entry> tx_backlog;
|
||||
if (!m_core.get_miner_data(res.major_version, res.height, prev_id, seed_hash, difficulty, res.median_weight, res.already_generated_coins, tx_backlog))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_INTERNAL_ERROR;
|
||||
error_resp.message = "Internal error: failed to get miner data";
|
||||
LOG_ERROR("Failed to get miner data");
|
||||
return false;
|
||||
}
|
||||
|
||||
res.tx_backlog.clear();
|
||||
res.tx_backlog.reserve(tx_backlog.size());
|
||||
|
||||
for (const auto& entry : tx_backlog)
|
||||
{
|
||||
res.tx_backlog.emplace_back(COMMAND_RPC_GETMINERDATA::response::tx_backlog_entry{string_tools::pod_to_hex(entry.id), entry.weight, entry.fee});
|
||||
}
|
||||
|
||||
res.prev_id = string_tools::pod_to_hex(prev_id);
|
||||
res.seed_hash = string_tools::pod_to_hex(seed_hash);
|
||||
res.difficulty = cryptonote::hex(difficulty);
|
||||
|
||||
res.status = CORE_RPC_STATUS_OK;
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_calcpow(const COMMAND_RPC_CALCPOW::request& req, COMMAND_RPC_CALCPOW::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||
{
|
||||
RPC_TRACKER(calcpow);
|
||||
|
||||
blobdata blockblob;
|
||||
if(!string_tools::parse_hexstr_to_binbuff(req.block_blob, blockblob))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB;
|
||||
error_resp.message = "Wrong block blob";
|
||||
return false;
|
||||
}
|
||||
if(!m_core.check_incoming_block_size(blockblob))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_BLOCKBLOB_SIZE;
|
||||
error_resp.message = "Block blob size is too big, rejecting block";
|
||||
return false;
|
||||
}
|
||||
crypto::hash seed_hash, pow_hash;
|
||||
std::string buf;
|
||||
if(req.seed_hash.size())
|
||||
{
|
||||
if (!string_tools::parse_hexstr_to_binbuff(req.seed_hash, buf) ||
|
||||
buf.size() != sizeof(crypto::hash))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_WRONG_PARAM;
|
||||
error_resp.message = "Wrong seed hash";
|
||||
return false;
|
||||
}
|
||||
buf.copy(reinterpret_cast<char *>(&seed_hash), sizeof(crypto::hash));
|
||||
}
|
||||
|
||||
cryptonote::get_block_longhash(&(m_core.get_blockchain_storage()), blockblob, pow_hash, req.height,
|
||||
req.major_version, req.seed_hash.size() ? &seed_hash : NULL, 0);
|
||||
res = string_tools::pod_to_hex(pow_hash);
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool core_rpc_server::on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx)
|
||||
{
|
||||
RPC_TRACKER(submitblock);
|
||||
@@ -2958,6 +3055,14 @@ namespace cryptonote
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(invoke_http_mode::JON_RPC, "get_output_distribution", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
if (restricted && req.amounts != std::vector<uint64_t>(1, 0))
|
||||
{
|
||||
error_resp.code = CORE_RPC_ERROR_CODE_RESTRICTED;
|
||||
error_resp.message = "Restricted RPC can only get output distribution for rct outputs. Use your own node.";
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t n_0 = 0, n_non0 = 0;
|
||||
for (uint64_t amount: req.amounts)
|
||||
if (amount) ++n_non0; else ++n_0;
|
||||
@@ -2999,6 +3104,13 @@ namespace cryptonote
|
||||
if (use_bootstrap_daemon_if_necessary<COMMAND_RPC_GET_OUTPUT_DISTRIBUTION>(invoke_http_mode::BIN, "/get_output_distribution.bin", req, res, r))
|
||||
return r;
|
||||
|
||||
const bool restricted = m_restricted && ctx;
|
||||
if (restricted && req.amounts != std::vector<uint64_t>(1, 0))
|
||||
{
|
||||
res.status = "Restricted RPC can only get output distribution for rct outputs. Use your own node.";
|
||||
return false;
|
||||
}
|
||||
|
||||
size_t n_0 = 0, n_non0 = 0;
|
||||
for (uint64_t amount: req.amounts)
|
||||
if (amount) ++n_non0; else ++n_0;
|
||||
@@ -3349,6 +3461,12 @@ namespace cryptonote
|
||||
, ""
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> core_rpc_server::arg_bootstrap_daemon_proxy = {
|
||||
"bootstrap-daemon-proxy"
|
||||
, "<ip>:<port> socks proxy to use for bootstrap daemon connections"
|
||||
, ""
|
||||
};
|
||||
|
||||
const command_line::arg_descriptor<std::string> core_rpc_server::arg_rpc_payment_address = {
|
||||
"rpc-payment-address"
|
||||
, "Restrict RPC to clients sending micropayment to this address"
|
||||
|
||||
@@ -72,6 +72,7 @@ namespace cryptonote
|
||||
static const command_line::arg_descriptor<bool> arg_rpc_ssl_allow_any_cert;
|
||||
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_address;
|
||||
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_login;
|
||||
static const command_line::arg_descriptor<std::string> arg_bootstrap_daemon_proxy;
|
||||
static const command_line::arg_descriptor<std::string> arg_rpc_payment_address;
|
||||
static const command_line::arg_descriptor<uint64_t> arg_rpc_payment_difficulty;
|
||||
static const command_line::arg_descriptor<uint64_t> arg_rpc_payment_credits;
|
||||
@@ -90,7 +91,8 @@ namespace cryptonote
|
||||
const boost::program_options::variables_map& vm,
|
||||
const bool restricted,
|
||||
const std::string& port,
|
||||
bool allow_rpc_payment
|
||||
bool allow_rpc_payment,
|
||||
const std::string& proxy = {}
|
||||
);
|
||||
network_type nettype() const { return m_core.get_nettype(); }
|
||||
|
||||
@@ -146,6 +148,8 @@ namespace cryptonote
|
||||
MAP_JON_RPC_WE("on_getblockhash", on_getblockhash, COMMAND_RPC_GETBLOCKHASH)
|
||||
MAP_JON_RPC_WE("get_block_template", on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE)
|
||||
MAP_JON_RPC_WE("getblocktemplate", on_getblocktemplate, COMMAND_RPC_GETBLOCKTEMPLATE)
|
||||
MAP_JON_RPC_WE("get_miner_data", on_getminerdata, COMMAND_RPC_GETMINERDATA)
|
||||
MAP_JON_RPC_WE_IF("calc_pow", on_calcpow, COMMAND_RPC_CALCPOW, !m_restricted)
|
||||
MAP_JON_RPC_WE("submit_block", on_submitblock, COMMAND_RPC_SUBMITBLOCK)
|
||||
MAP_JON_RPC_WE("submitblock", on_submitblock, COMMAND_RPC_SUBMITBLOCK)
|
||||
MAP_JON_RPC_WE_IF("generateblocks", on_generateblocks, COMMAND_RPC_GENERATEBLOCKS, !m_restricted)
|
||||
@@ -226,6 +230,8 @@ namespace cryptonote
|
||||
bool on_getblockcount(const COMMAND_RPC_GETBLOCKCOUNT::request& req, COMMAND_RPC_GETBLOCKCOUNT::response& res, const connection_context *ctx = NULL);
|
||||
bool on_getblockhash(const COMMAND_RPC_GETBLOCKHASH::request& req, COMMAND_RPC_GETBLOCKHASH::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_getblocktemplate(const COMMAND_RPC_GETBLOCKTEMPLATE::request& req, COMMAND_RPC_GETBLOCKTEMPLATE::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_getminerdata(const COMMAND_RPC_GETMINERDATA::request& req, COMMAND_RPC_GETMINERDATA::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_calcpow(const COMMAND_RPC_CALCPOW::request& req, COMMAND_RPC_CALCPOW::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_submitblock(const COMMAND_RPC_SUBMITBLOCK::request& req, COMMAND_RPC_SUBMITBLOCK::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_generateblocks(const COMMAND_RPC_GENERATEBLOCKS::request& req, COMMAND_RPC_GENERATEBLOCKS::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
bool on_get_last_block_header(const COMMAND_RPC_GET_LAST_BLOCK_HEADER::request& req, COMMAND_RPC_GET_LAST_BLOCK_HEADER::response& res, epee::json_rpc::error& error_resp, const connection_context *ctx = NULL);
|
||||
@@ -268,8 +274,14 @@ private:
|
||||
uint64_t get_block_reward(const block& blk);
|
||||
bool fill_block_header_response(const block& blk, bool orphan_status, uint64_t height, const crypto::hash& hash, block_header_response& response, bool fill_pow_hash);
|
||||
std::map<std::string, bool> get_public_nodes(uint32_t credits_per_hash_threshold = 0);
|
||||
bool set_bootstrap_daemon(const std::string &address, const std::string &username_password);
|
||||
bool set_bootstrap_daemon(const std::string &address, const boost::optional<epee::net_utils::http::login> &credentials);
|
||||
bool set_bootstrap_daemon(
|
||||
const std::string &address,
|
||||
const std::string &username_password,
|
||||
const std::string &proxy);
|
||||
bool set_bootstrap_daemon(
|
||||
const std::string &address,
|
||||
const boost::optional<epee::net_utils::http::login> &credentials,
|
||||
const std::string &proxy);
|
||||
enum invoke_http_mode { JON, BIN, JON_RPC };
|
||||
template <typename COMMAND_TYPE>
|
||||
bool use_bootstrap_daemon_if_necessary(const invoke_http_mode &mode, const std::string &command_name, const typename COMMAND_TYPE::request& req, typename COMMAND_TYPE::response& res, bool &r);
|
||||
@@ -280,6 +292,7 @@ private:
|
||||
nodetool::node_server<cryptonote::t_cryptonote_protocol_handler<cryptonote::core> >& m_p2p;
|
||||
boost::shared_mutex m_bootstrap_daemon_mutex;
|
||||
std::unique_ptr<bootstrap_daemon> m_bootstrap_daemon;
|
||||
std::string m_bootstrap_daemon_proxy;
|
||||
bool m_should_use_bootstrap_daemon;
|
||||
std::chrono::system_clock::time_point m_bootstrap_height_check_time;
|
||||
bool m_was_bootstrap_ever_used;
|
||||
|
||||
@@ -88,7 +88,7 @@ namespace cryptonote
|
||||
// advance which version they will stop working with
|
||||
// Don't go over 32767 for any of these
|
||||
#define CORE_RPC_VERSION_MAJOR 3
|
||||
#define CORE_RPC_VERSION_MINOR 5
|
||||
#define CORE_RPC_VERSION_MINOR 9
|
||||
#define MAKE_CORE_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
||||
#define CORE_RPC_VERSION MAKE_CORE_RPC_VERSION(CORE_RPC_VERSION_MAJOR, CORE_RPC_VERSION_MINOR)
|
||||
|
||||
@@ -938,6 +938,78 @@ namespace cryptonote
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_GETMINERDATA
|
||||
{
|
||||
struct request_t: public rpc_request_base
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_PARENT(rpc_request_base)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t: public rpc_response_base
|
||||
{
|
||||
uint8_t major_version;
|
||||
uint64_t height;
|
||||
std::string prev_id;
|
||||
std::string seed_hash;
|
||||
std::string difficulty;
|
||||
uint64_t median_weight;
|
||||
uint64_t already_generated_coins;
|
||||
|
||||
struct tx_backlog_entry
|
||||
{
|
||||
std::string id;
|
||||
uint64_t weight;
|
||||
uint64_t fee;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(id)
|
||||
KV_SERIALIZE(weight)
|
||||
KV_SERIALIZE(fee)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
std::vector<tx_backlog_entry> tx_backlog;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_PARENT(rpc_response_base)
|
||||
KV_SERIALIZE(major_version)
|
||||
KV_SERIALIZE(height)
|
||||
KV_SERIALIZE(prev_id)
|
||||
KV_SERIALIZE(seed_hash)
|
||||
KV_SERIALIZE(difficulty)
|
||||
KV_SERIALIZE(median_weight)
|
||||
KV_SERIALIZE(already_generated_coins)
|
||||
KV_SERIALIZE(tx_backlog)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_CALCPOW
|
||||
{
|
||||
struct request_t: public rpc_request_base
|
||||
{
|
||||
uint8_t major_version;
|
||||
uint64_t height;
|
||||
blobdata block_blob;
|
||||
std::string seed_hash;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE_PARENT(rpc_request_base)
|
||||
KV_SERIALIZE(major_version)
|
||||
KV_SERIALIZE(height)
|
||||
KV_SERIALIZE(block_blob)
|
||||
KV_SERIALIZE(seed_hash)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
typedef std::string response;
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_SUBMITBLOCK
|
||||
{
|
||||
typedef std::vector<std::string> request;
|
||||
@@ -1613,11 +1685,13 @@ namespace cryptonote
|
||||
std::string address;
|
||||
std::string username;
|
||||
std::string password;
|
||||
std::string proxy;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(address)
|
||||
KV_SERIALIZE(username)
|
||||
KV_SERIALIZE(password)
|
||||
KV_SERIALIZE(proxy)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
+86
-15
@@ -48,6 +48,8 @@
|
||||
#include "cryptonote_basic/events.h"
|
||||
#include "misc_log_ex.h"
|
||||
#include "serialization/json_object.h"
|
||||
#include "ringct/rctTypes.h"
|
||||
#include "cryptonote_core/cryptonote_tx_utils.h"
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "net.zmq"
|
||||
@@ -57,6 +59,7 @@ namespace
|
||||
constexpr const char txpool_signal[] = "tx_signal";
|
||||
|
||||
using chain_writer = void(epee::byte_stream&, std::uint64_t, epee::span<const cryptonote::block>);
|
||||
using miner_writer = void(epee::byte_stream&, uint8_t, uint64_t, const crypto::hash&, const crypto::hash&, cryptonote::difficulty_type, uint64_t, uint64_t, const std::vector<cryptonote::tx_block_template_backlog_entry>&);
|
||||
using txpool_writer = void(epee::byte_stream&, epee::span<const cryptonote::txpool_event>);
|
||||
|
||||
template<typename F>
|
||||
@@ -116,13 +119,30 @@ namespace
|
||||
const epee::span<const cryptonote::block> blocks;
|
||||
};
|
||||
|
||||
//! Object for miner data serialization
|
||||
struct miner_data
|
||||
{
|
||||
uint8_t major_version;
|
||||
uint64_t height;
|
||||
const crypto::hash& prev_id;
|
||||
const crypto::hash& seed_hash;
|
||||
cryptonote::difficulty_type diff;
|
||||
uint64_t median_weight;
|
||||
uint64_t already_generated_coins;
|
||||
const std::vector<cryptonote::tx_block_template_backlog_entry>& tx_backlog;
|
||||
};
|
||||
|
||||
//! Object for "minimal" tx serialization
|
||||
struct minimal_txpool
|
||||
{
|
||||
const cryptonote::transaction& tx;
|
||||
crypto::hash hash;
|
||||
uint64_t blob_size;
|
||||
uint64_t weight;
|
||||
uint64_t fee;
|
||||
};
|
||||
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const minimal_chain self)
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const minimal_chain& self)
|
||||
{
|
||||
namespace adapt = boost::adaptors;
|
||||
|
||||
@@ -143,19 +163,27 @@ namespace
|
||||
dest.EndObject();
|
||||
}
|
||||
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const minimal_txpool self)
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const miner_data& self)
|
||||
{
|
||||
crypto::hash id{};
|
||||
std::size_t blob_size = 0;
|
||||
if (!get_transaction_hash(self.tx, id, blob_size))
|
||||
{
|
||||
MERROR("ZMQ/Pub failure: get_transaction_hash");
|
||||
return;
|
||||
}
|
||||
|
||||
dest.StartObject();
|
||||
INSERT_INTO_JSON_OBJECT(dest, id, id);
|
||||
INSERT_INTO_JSON_OBJECT(dest, blob_size, blob_size);
|
||||
INSERT_INTO_JSON_OBJECT(dest, major_version, self.major_version);
|
||||
INSERT_INTO_JSON_OBJECT(dest, height, self.height);
|
||||
INSERT_INTO_JSON_OBJECT(dest, prev_id, self.prev_id);
|
||||
INSERT_INTO_JSON_OBJECT(dest, seed_hash, self.seed_hash);
|
||||
INSERT_INTO_JSON_OBJECT(dest, difficulty, cryptonote::hex(self.diff));
|
||||
INSERT_INTO_JSON_OBJECT(dest, median_weight, self.median_weight);
|
||||
INSERT_INTO_JSON_OBJECT(dest, already_generated_coins, self.already_generated_coins);
|
||||
INSERT_INTO_JSON_OBJECT(dest, tx_backlog, self.tx_backlog);
|
||||
dest.EndObject();
|
||||
}
|
||||
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const minimal_txpool& self)
|
||||
{
|
||||
dest.StartObject();
|
||||
INSERT_INTO_JSON_OBJECT(dest, id, self.hash);
|
||||
INSERT_INTO_JSON_OBJECT(dest, blob_size, self.blob_size);
|
||||
INSERT_INTO_JSON_OBJECT(dest, weight, self.weight);
|
||||
INSERT_INTO_JSON_OBJECT(dest, fee, self.fee);
|
||||
dest.EndObject();
|
||||
}
|
||||
|
||||
@@ -169,6 +197,11 @@ namespace
|
||||
json_pub(buf, minimal_chain{height, blocks});
|
||||
}
|
||||
|
||||
void json_miner_data(epee::byte_stream& buf, uint8_t major_version, uint64_t height, const crypto::hash& prev_id, const crypto::hash& seed_hash, cryptonote::difficulty_type diff, uint64_t median_weight, uint64_t already_generated_coins, const std::vector<cryptonote::tx_block_template_backlog_entry>& tx_backlog)
|
||||
{
|
||||
json_pub(buf, miner_data{major_version, height, prev_id, seed_hash, diff, median_weight, already_generated_coins, tx_backlog});
|
||||
}
|
||||
|
||||
// boost::adaptors are in place "views" - no copy/move takes place
|
||||
// moving transactions (via sort, etc.), is expensive!
|
||||
|
||||
@@ -187,7 +220,7 @@ namespace
|
||||
namespace adapt = boost::adaptors;
|
||||
const auto to_minimal_tx = [](const cryptonote::txpool_event& event)
|
||||
{
|
||||
return minimal_txpool{event.tx};
|
||||
return minimal_txpool{event.tx, event.hash, event.blob_size, event.weight, cryptonote::get_tx_fee(event.tx)};
|
||||
};
|
||||
json_pub(buf, (txes | adapt::filtered(is_valid{}) | adapt::transformed(to_minimal_tx)));
|
||||
}
|
||||
@@ -198,6 +231,11 @@ namespace
|
||||
{u8"json-minimal-chain_main", json_minimal_chain}
|
||||
}};
|
||||
|
||||
constexpr const std::array<context<miner_writer>, 1> miner_contexts =
|
||||
{{
|
||||
{u8"json-full-miner_data", json_miner_data},
|
||||
}};
|
||||
|
||||
constexpr const std::array<context<txpool_writer>, 2> txpool_contexts =
|
||||
{{
|
||||
{u8"json-full-txpool_add", json_full_txpool},
|
||||
@@ -321,6 +359,7 @@ namespace cryptonote { namespace listener
|
||||
zmq_pub::zmq_pub(void* context)
|
||||
: relay_(),
|
||||
chain_subs_{{0}},
|
||||
miner_subs_{{0}},
|
||||
txpool_subs_{{0}},
|
||||
sync_()
|
||||
{
|
||||
@@ -328,6 +367,7 @@ zmq_pub::zmq_pub(void* context)
|
||||
throw std::logic_error{"ZMQ context cannot be NULL"};
|
||||
|
||||
verify_sorted(chain_contexts, "chain_contexts");
|
||||
verify_sorted(miner_contexts, "miner_contexts");
|
||||
verify_sorted(txpool_contexts, "txpool_contexts");
|
||||
|
||||
relay_.reset(zmq_socket(context, ZMQ_PAIR));
|
||||
@@ -348,22 +388,25 @@ bool zmq_pub::sub_request(boost::string_ref message)
|
||||
message.remove_prefix(1);
|
||||
|
||||
const auto chain_range = get_range(chain_contexts, message);
|
||||
const auto miner_range = get_range(miner_contexts, message);
|
||||
const auto txpool_range = get_range(txpool_contexts, message);
|
||||
|
||||
if (!chain_range.empty() || !txpool_range.empty())
|
||||
if (!chain_range.empty() || !miner_range.empty() || !txpool_range.empty())
|
||||
{
|
||||
MDEBUG("Client " << (tag ? "subscribed" : "unsubscribed") << " to " <<
|
||||
chain_range.size() << " chain topic(s) and " << txpool_range.size() << " txpool topic(s)");
|
||||
chain_range.size() << " chain topic(s), " << miner_range.size() << " miner topic(s) and " << txpool_range.size() << " txpool topic(s)");
|
||||
|
||||
const boost::lock_guard<boost::mutex> lock{sync_};
|
||||
switch (tag)
|
||||
{
|
||||
case 0:
|
||||
remove_subscriptions(chain_subs_, chain_range, chain_contexts.begin());
|
||||
remove_subscriptions(miner_subs_, miner_range, miner_contexts.begin());
|
||||
remove_subscriptions(txpool_subs_, txpool_range, txpool_contexts.begin());
|
||||
return true;
|
||||
case 1:
|
||||
add_subscriptions(chain_subs_, chain_range, chain_contexts.begin());
|
||||
add_subscriptions(miner_subs_, miner_range, miner_contexts.begin());
|
||||
add_subscriptions(txpool_subs_, txpool_range, txpool_contexts.begin());
|
||||
return true;
|
||||
default:
|
||||
@@ -436,6 +479,25 @@ std::size_t zmq_pub::send_chain_main(const std::uint64_t height, const epee::spa
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t zmq_pub::send_miner_data(uint8_t major_version, uint64_t height, const crypto::hash& prev_id, const crypto::hash& seed_hash, difficulty_type diff, uint64_t median_weight, uint64_t already_generated_coins, const std::vector<tx_block_template_backlog_entry>& tx_backlog)
|
||||
{
|
||||
boost::unique_lock<boost::mutex> guard{sync_};
|
||||
|
||||
const auto subs_copy = miner_subs_;
|
||||
guard.unlock();
|
||||
|
||||
for (const std::size_t sub : subs_copy)
|
||||
{
|
||||
if (sub)
|
||||
{
|
||||
auto messages = make_pubs(subs_copy, miner_contexts, major_version, height, prev_id, seed_hash, diff, median_weight, already_generated_coins, tx_backlog);
|
||||
guard.lock();
|
||||
return send_messages(relay_.get(), messages);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::size_t zmq_pub::send_txpool_add(std::vector<txpool_event> txes)
|
||||
{
|
||||
if (txes.empty())
|
||||
@@ -466,6 +528,15 @@ void zmq_pub::chain_main::operator()(const std::uint64_t height, epee::span<cons
|
||||
MERROR("Unable to send ZMQ/Pub - ZMQ server destroyed");
|
||||
}
|
||||
|
||||
void zmq_pub::miner_data::operator()(uint8_t major_version, uint64_t height, const crypto::hash& prev_id, const crypto::hash& seed_hash, difficulty_type diff, uint64_t median_weight, uint64_t already_generated_coins, const std::vector<tx_block_template_backlog_entry>& tx_backlog) const
|
||||
{
|
||||
const std::shared_ptr<zmq_pub> self = self_.lock();
|
||||
if (self)
|
||||
self->send_miner_data(major_version, height, prev_id, seed_hash, diff, median_weight, already_generated_coins, tx_backlog);
|
||||
else
|
||||
MERROR("Unable to send ZMQ/Pub - ZMQ server destroyed");
|
||||
}
|
||||
|
||||
void zmq_pub::txpool_add::operator()(std::vector<cryptonote::txpool_event> txes) const
|
||||
{
|
||||
const std::shared_ptr<zmq_pub> self = self_.lock();
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include "cryptonote_basic/fwd.h"
|
||||
#include "net/zmq.h"
|
||||
#include "span.h"
|
||||
#include "cryptonote_basic/difficulty.h"
|
||||
|
||||
namespace cryptonote { namespace listener
|
||||
{
|
||||
@@ -59,6 +60,7 @@ class zmq_pub
|
||||
net::zmq::socket relay_;
|
||||
std::deque<std::vector<txpool_event>> txes_;
|
||||
std::array<std::size_t, 2> chain_subs_;
|
||||
std::array<std::size_t, 1> miner_subs_;
|
||||
std::array<std::size_t, 2> txpool_subs_;
|
||||
boost::mutex sync_; //!< Synchronizes counts in `*_subs_` arrays.
|
||||
|
||||
@@ -88,6 +90,11 @@ class zmq_pub
|
||||
\return Number of ZMQ messages sent to relay. */
|
||||
std::size_t send_chain_main(std::uint64_t height, epee::span<const cryptonote::block> blocks);
|
||||
|
||||
/*! Send a `ZMQ_PUB` notification for a new miner data.
|
||||
Thread-safe.
|
||||
\return Number of ZMQ messages sent to relay. */
|
||||
std::size_t send_miner_data(uint8_t major_version, uint64_t height, const crypto::hash& prev_id, const crypto::hash& seed_hash, difficulty_type diff, uint64_t median_weight, uint64_t already_generated_coins, const std::vector<tx_block_template_backlog_entry>& tx_backlog);
|
||||
|
||||
/*! Send a `ZMQ_PUB` notification for new tx(es) being added to the local
|
||||
pool. Thread-safe.
|
||||
\return Number of ZMQ messages sent to relay. */
|
||||
@@ -100,6 +107,13 @@ class zmq_pub
|
||||
void operator()(std::uint64_t height, epee::span<const cryptonote::block> blocks) const;
|
||||
};
|
||||
|
||||
//! Callable for `send_miner_data` with weak ownership to `zmq_pub` object.
|
||||
struct miner_data
|
||||
{
|
||||
std::weak_ptr<zmq_pub> self_;
|
||||
void operator()(uint8_t major_version, uint64_t height, const crypto::hash& prev_id, const crypto::hash& seed_hash, difficulty_type diff, uint64_t median_weight, uint64_t already_generated_coins, const std::vector<tx_block_template_backlog_entry>& tx_backlog) const;
|
||||
};
|
||||
|
||||
//! Callable for `send_txpool_add` with weak ownership to `zmq_pub` object.
|
||||
struct txpool_add
|
||||
{
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include <type_traits>
|
||||
|
||||
#include "cryptonote_basic/cryptonote_basic_impl.h"
|
||||
#include "cryptonote_core/cryptonote_tx_utils.h"
|
||||
|
||||
// drop macro from windows.h
|
||||
#ifdef GetObject
|
||||
@@ -1411,6 +1412,27 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_distribu
|
||||
GET_FROM_JSON_OBJECT(val, dist.data.base, base);
|
||||
}
|
||||
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::tx_block_template_backlog_entry& entry)
|
||||
{
|
||||
dest.StartObject();
|
||||
INSERT_INTO_JSON_OBJECT(dest, id, entry.id);
|
||||
INSERT_INTO_JSON_OBJECT(dest, weight, entry.weight);
|
||||
INSERT_INTO_JSON_OBJECT(dest, fee, entry.fee);
|
||||
dest.EndObject();
|
||||
}
|
||||
|
||||
void fromJsonValue(const rapidjson::Value& val, cryptonote::tx_block_template_backlog_entry& entry)
|
||||
{
|
||||
if (!val.IsObject())
|
||||
{
|
||||
throw WRONG_TYPE("json object");
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, entry.id, id);
|
||||
GET_FROM_JSON_OBJECT(val, entry.weight, weight);
|
||||
GET_FROM_JSON_OBJECT(val, entry.fee, fee);
|
||||
}
|
||||
|
||||
} // namespace json
|
||||
|
||||
} // namespace cryptonote
|
||||
|
||||
@@ -304,6 +304,9 @@ void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::DaemonInfo& inf
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::rpc::output_distribution& dist);
|
||||
void fromJsonValue(const rapidjson::Value& val, cryptonote::rpc::output_distribution& dist);
|
||||
|
||||
void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const cryptonote::tx_block_template_backlog_entry& entry);
|
||||
void fromJsonValue(const rapidjson::Value& val, cryptonote::tx_block_template_backlog_entry& entry);
|
||||
|
||||
template <typename Map>
|
||||
typename std::enable_if<sfinae::is_map_like<Map>::value, void>::type toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const Map& map);
|
||||
|
||||
|
||||
@@ -8817,12 +8817,12 @@ bool simple_wallet::export_transfers(const std::vector<std::string>& args_)
|
||||
|
||||
// header
|
||||
file <<
|
||||
boost::format("%8.8s,%9.9s,%8.8s,%25.25s,%20.20s,%20.20s,%64.64s,%16.16s,%14.14s,%100.100s,%20.20s,%s,%s") %
|
||||
boost::format("%8.8s,%9.9s,%8.8s,%25.25s,%20.20s,%20.20s,%64.64s,%16.16s,%14.14s,%106.106s,%20.20s,%s,%s") %
|
||||
tr("block") % tr("direction") % tr("unlocked") % tr("timestamp") % tr("amount") % tr("running balance") % tr("hash") % tr("payment ID") % tr("fee") % tr("destination") % tr("amount") % tr("index") % tr("note")
|
||||
<< std::endl;
|
||||
|
||||
uint64_t running_balance = 0;
|
||||
auto formatter = boost::format("%8.8llu,%9.9s,%8.8s,%25.25s,%20.20s,%20.20s,%64.64s,%16.16s,%14.14s,%100.100s,%20.20s,\"%s\",%s");
|
||||
auto formatter = boost::format("%8.8llu,%9.9s,%8.8s,%25.25s,%20.20s,%20.20s,%64.64s,%16.16s,%14.14s,%106.106s,%20.20s,\"%s\",%s");
|
||||
|
||||
for (const auto& transfer : all_transfers)
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
|
||||
#define DEF_MONERO_VERSION "0.17.2.3"
|
||||
#define DEF_MONERO_VERSION "0.17.3.0"
|
||||
#define DEF_MONERO_RELEASE_NAME "Oxygen Orion"
|
||||
#define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG
|
||||
#define DEF_MONERO_VERSION_IS_RELEASE @VERSION_IS_RELEASE@
|
||||
|
||||
@@ -453,7 +453,7 @@ WalletImpl::~WalletImpl()
|
||||
LOG_PRINT_L1(__FUNCTION__);
|
||||
m_wallet->callback(NULL);
|
||||
// Pause refresh thread - prevents refresh from starting again
|
||||
pauseRefresh();
|
||||
WalletImpl::pauseRefresh(); // Call the method directly (not polymorphically) to protect against UB in destructor.
|
||||
// Close wallet - stores cache and stops ongoing refresh operation
|
||||
close(false); // do not store wallet as part of the closing activities
|
||||
// Stop refresh thread
|
||||
|
||||
@@ -49,6 +49,11 @@ namespace epee {
|
||||
|
||||
namespace Monero {
|
||||
|
||||
WalletManagerImpl::WalletManagerImpl()
|
||||
{
|
||||
tools::set_strict_default_file_permissions(true);
|
||||
}
|
||||
|
||||
Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::string &password,
|
||||
const std::string &language, NetworkType nettype, uint64_t kdf_rounds)
|
||||
{
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
bool setProxy(const std::string &address) override;
|
||||
|
||||
private:
|
||||
WalletManagerImpl() {}
|
||||
WalletManagerImpl();
|
||||
friend struct WalletManagerFactory;
|
||||
net::http::client m_http_client;
|
||||
std::string m_errorString;
|
||||
|
||||
+26
-37
@@ -143,7 +143,7 @@ using namespace cryptonote;
|
||||
#define IGNORE_LONG_PAYMENT_ID_FROM_BLOCK_VERSION 12
|
||||
|
||||
#define DEFAULT_UNLOCK_TIME (CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE * DIFFICULTY_TARGET_V2)
|
||||
#define RECENT_SPEND_WINDOW (50 * DIFFICULTY_TARGET_V2)
|
||||
#define RECENT_SPEND_WINDOW (15 * DIFFICULTY_TARGET_V2)
|
||||
|
||||
static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1";
|
||||
static const std::string MULTISIG_EXTRA_INFO_MAGIC = "MultisigxV1";
|
||||
@@ -1025,13 +1025,7 @@ gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets, double shap
|
||||
end = rct_offsets.data() + rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
|
||||
num_rct_outputs = *(end - 1);
|
||||
THROW_WALLET_EXCEPTION_IF(num_rct_outputs == 0, error::wallet_internal_error, "No rct outputs");
|
||||
THROW_WALLET_EXCEPTION_IF(outputs_to_consider == 0, error::wallet_internal_error, "No rct outputs to consider");
|
||||
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / outputs_to_consider; // this assumes constant target over the whole rct range
|
||||
if (average_output_time == 0) {
|
||||
// TODO: apply this to all cases; do so alongside a hard fork, where all clients will update at the same time, preventing anonymity puddle formation
|
||||
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider);
|
||||
}
|
||||
THROW_WALLET_EXCEPTION_IF(average_output_time == 0, error::wallet_internal_error, "Average seconds per output cannot be 0.");
|
||||
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider); // this assumes constant target over the whole rct range
|
||||
};
|
||||
|
||||
gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets): gamma_picker(rct_offsets, GAMMA_SHAPE, GAMMA_SCALE) {}
|
||||
@@ -1235,8 +1229,6 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
|
||||
m_ring_history_saved(false),
|
||||
m_ringdb(),
|
||||
m_last_block_reward(0),
|
||||
m_encrypt_keys_after_refresh(boost::none),
|
||||
m_decrypt_keys_lockers(0),
|
||||
m_unattended(unattended),
|
||||
m_devices_registered(false),
|
||||
m_device_last_key_image_sync(0),
|
||||
@@ -1844,8 +1836,7 @@ void wallet2::scan_output(const cryptonote::transaction &tx, bool miner_tx, cons
|
||||
boost::optional<epee::wipeable_string> pwd = m_callback->on_get_password(pool ? "output found in pool" : "output received");
|
||||
THROW_WALLET_EXCEPTION_IF(!pwd, error::password_needed, tr("Password is needed to compute key image for incoming monero"));
|
||||
THROW_WALLET_EXCEPTION_IF(!verify_password(*pwd), error::password_needed, tr("Invalid password: password is needed to compute key image for incoming monero"));
|
||||
decrypt_keys(*pwd);
|
||||
m_encrypt_keys_after_refresh = *pwd;
|
||||
m_encrypt_keys_after_refresh.reset(new wallet_keys_unlocker(*this, m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only, *pwd));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2977,11 +2968,7 @@ void wallet2::update_pool_state(std::vector<std::tuple<cryptonote::transaction,
|
||||
MTRACE("update_pool_state start");
|
||||
|
||||
auto keys_reencryptor = epee::misc_utils::create_scope_leave_handler([&, this]() {
|
||||
if (m_encrypt_keys_after_refresh)
|
||||
{
|
||||
encrypt_keys(*m_encrypt_keys_after_refresh);
|
||||
m_encrypt_keys_after_refresh = boost::none;
|
||||
}
|
||||
m_encrypt_keys_after_refresh.reset();
|
||||
});
|
||||
|
||||
// get the pool state
|
||||
@@ -3412,11 +3399,7 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo
|
||||
start_height = 0;
|
||||
|
||||
auto keys_reencryptor = epee::misc_utils::create_scope_leave_handler([&, this]() {
|
||||
if (m_encrypt_keys_after_refresh)
|
||||
{
|
||||
encrypt_keys(*m_encrypt_keys_after_refresh);
|
||||
m_encrypt_keys_after_refresh = boost::none;
|
||||
}
|
||||
m_encrypt_keys_after_refresh.reset();
|
||||
});
|
||||
|
||||
auto scope_exit_handler_hwdev = epee::misc_utils::create_scope_leave_handler([&](){hwdev.computing_key_images(false);});
|
||||
@@ -4517,18 +4500,12 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip
|
||||
|
||||
void wallet2::encrypt_keys(const crypto::chacha_key &key)
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(m_decrypt_keys_lock);
|
||||
if (--m_decrypt_keys_lockers) // another lock left ?
|
||||
return;
|
||||
m_account.encrypt_keys(key);
|
||||
m_account.decrypt_viewkey(key);
|
||||
}
|
||||
|
||||
void wallet2::decrypt_keys(const crypto::chacha_key &key)
|
||||
{
|
||||
boost::lock_guard<boost::mutex> lock(m_decrypt_keys_lock);
|
||||
if (m_decrypt_keys_lockers++) // already unlocked ?
|
||||
return;
|
||||
m_account.encrypt_viewkey(key);
|
||||
m_account.decrypt_keys(key);
|
||||
}
|
||||
@@ -8569,18 +8546,30 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
|
||||
}
|
||||
|
||||
// get the keys for those
|
||||
req.get_txid = false;
|
||||
|
||||
// the response can get large and end up rejected by the anti DoS limits, so chunk it if needed
|
||||
size_t offset = 0;
|
||||
while (offset < req.outputs.size())
|
||||
{
|
||||
static const size_t chunk_size = 1000;
|
||||
COMMAND_RPC_GET_OUTPUTS_BIN::request chunk_req = AUTO_VAL_INIT(chunk_req);
|
||||
COMMAND_RPC_GET_OUTPUTS_BIN::response chunk_daemon_resp = AUTO_VAL_INIT(chunk_daemon_resp);
|
||||
chunk_req.get_txid = false;
|
||||
for (size_t i = 0; i < std::min<size_t>(req.outputs.size() - offset, chunk_size); ++i)
|
||||
chunk_req.outputs.push_back(req.outputs[offset + i]);
|
||||
|
||||
const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex};
|
||||
uint64_t pre_call_credits = m_rpc_payment_state.credits;
|
||||
req.client = get_client_signature();
|
||||
bool r = epee::net_utils::invoke_http_bin("/get_outs.bin", req, daemon_resp, *m_http_client, rpc_timeout);
|
||||
THROW_ON_RPC_RESPONSE_ERROR(r, {}, daemon_resp, "get_outs.bin", error::get_outs_error, get_rpc_status(daemon_resp.status));
|
||||
THROW_WALLET_EXCEPTION_IF(daemon_resp.outs.size() != req.outputs.size(), error::wallet_internal_error,
|
||||
chunk_req.client = get_client_signature();
|
||||
bool r = epee::net_utils::invoke_http_bin("/get_outs.bin", chunk_req, chunk_daemon_resp, *m_http_client, rpc_timeout);
|
||||
THROW_ON_RPC_RESPONSE_ERROR(r, {}, chunk_daemon_resp, "get_outs.bin", error::get_outs_error, get_rpc_status(chunk_daemon_resp.status));
|
||||
THROW_WALLET_EXCEPTION_IF(chunk_daemon_resp.outs.size() != chunk_req.outputs.size(), error::wallet_internal_error,
|
||||
"daemon returned wrong response for get_outs.bin, wrong amounts count = " +
|
||||
std::to_string(daemon_resp.outs.size()) + ", expected " + std::to_string(req.outputs.size()));
|
||||
check_rpc_cost("/get_outs.bin", daemon_resp.credits, pre_call_credits, daemon_resp.outs.size() * COST_PER_OUT);
|
||||
std::to_string(chunk_daemon_resp.outs.size()) + ", expected " + std::to_string(chunk_req.outputs.size()));
|
||||
check_rpc_cost("/get_outs.bin", chunk_daemon_resp.credits, pre_call_credits, chunk_daemon_resp.outs.size() * COST_PER_OUT);
|
||||
|
||||
offset += chunk_size;
|
||||
for (size_t i = 0; i < chunk_daemon_resp.outs.size(); ++i)
|
||||
daemon_resp.outs.push_back(std::move(chunk_daemon_resp.outs[i]));
|
||||
}
|
||||
|
||||
std::unordered_map<uint64_t, uint64_t> scanty_outs;
|
||||
@@ -12207,7 +12196,7 @@ uint64_t wallet2::get_approximate_blockchain_height() const
|
||||
// Calculated blockchain height
|
||||
uint64_t approx_blockchain_height = fork_block + (time(NULL) - fork_time)/seconds_per_block;
|
||||
// testnet got some huge rollbacks, so the estimation is way off
|
||||
static const uint64_t approximate_testnet_rolled_back_blocks = 303967;
|
||||
static const uint64_t approximate_testnet_rolled_back_blocks = 342100;
|
||||
if (m_nettype == TESTNET && approx_blockchain_height > approximate_testnet_rolled_back_blocks)
|
||||
approx_blockchain_height -= approximate_testnet_rolled_back_blocks;
|
||||
LOG_PRINT_L2("Calculated blockchain height: " << approx_blockchain_height);
|
||||
|
||||
@@ -1791,9 +1791,7 @@ private:
|
||||
crypto::secret_key m_original_view_secret_key;
|
||||
|
||||
crypto::chacha_key m_cache_key;
|
||||
boost::optional<epee::wipeable_string> m_encrypt_keys_after_refresh;
|
||||
boost::mutex m_decrypt_keys_lock;
|
||||
unsigned int m_decrypt_keys_lockers;
|
||||
std::shared_ptr<wallet_keys_unlocker> m_encrypt_keys_after_refresh;
|
||||
|
||||
bool m_unattended;
|
||||
bool m_devices_registered;
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
namespace
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user