aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml53
-rw-r--r--CMakeLists.txt59
-rw-r--r--Dockerfile2
-rw-r--r--cmake/CheckLinkerFlag.cmake1
-rw-r--r--cmake/FindCcache.cmake2
-rw-r--r--cmake/FindLibUSB.cmake2
-rw-r--r--contrib/depends/Makefile4
-rw-r--r--contrib/depends/packages/boost.mk2
-rw-r--r--contrib/epee/demo/CMakeLists.txt2
-rw-r--r--contrib/epee/include/storages/portable_storage.h2
-rw-r--r--contrib/epee/src/CMakeLists.txt19
-rw-r--r--contrib/epee/src/byte_slice.cpp4
-rw-r--r--contrib/epee/tests/src/CMakeLists.txt2
-rw-r--r--docs/COMPILING_DEBUGGING_TESTING.md86
-rw-r--r--external/easylogging++/CMakeLists.txt8
-rw-r--r--src/CMakeLists.txt24
-rw-r--r--src/crypto/CMakeLists.txt1
-rw-r--r--src/cryptonote_core/blockchain.cpp7
-rw-r--r--src/cryptonote_core/cryptonote_tx_utils.cpp4
-rw-r--r--src/cryptonote_protocol/CMakeLists.txt2
-rw-r--r--src/cryptonote_protocol/cryptonote_protocol_handler.inl2
-rw-r--r--src/device_trezor/trezor/transport.cpp2
-rw-r--r--src/p2p/CMakeLists.txt2
-rw-r--r--src/p2p/net_node.inl3
-rw-r--r--src/rpc/core_rpc_server.cpp2
-rw-r--r--src/rpc/core_rpc_server_commands_defs.h4
-rw-r--r--src/serialization/json_object.h2
-rw-r--r--src/simplewallet/simplewallet.cpp2
-rw-r--r--src/wallet/CMakeLists.txt54
-rw-r--r--src/wallet/api/wallet.cpp62
-rw-r--r--src/wallet/api/wallet.h2
-rw-r--r--src/wallet/api/wallet2_api.h13
-rw-r--r--src/wallet/wallet2.cpp67
-rw-r--r--src/wallet/wallet2.h2
-rw-r--r--src/wallet/wallet_rpc_server.cpp84
-rw-r--r--src/wallet/wallet_rpc_server.h6
-rw-r--r--src/wallet/wallet_rpc_server_commands_defs.h65
-rw-r--r--tests/README.md21
-rw-r--r--tests/core_tests/chaingen.h2
-rwxr-xr-xtests/functional_tests/functional_tests_rpc.py9
-rwxr-xr-xtests/functional_tests/mining.py94
-rwxr-xr-xtests/functional_tests/util_resources.py4
-rw-r--r--tests/gtest/CMakeLists.txt2
-rw-r--r--tests/gtest/cmake/internal_utils.cmake2
-rw-r--r--tests/unit_tests/epee_boosted_tcp_server.cpp3
-rw-r--r--tests/unit_tests/json_serialization.cpp2
-rw-r--r--translations/CMakeLists.txt4
-rw-r--r--utils/build_scripts/android32.Dockerfile2
-rw-r--r--utils/build_scripts/android64.Dockerfile2
-rw-r--r--utils/gpg_keys/mj-xmr.asc52
50 files changed, 649 insertions, 210 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index aa6afbfbc..36eab5027 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -2,6 +2,15 @@ name: ci/gh-actions/cli
on: [push, pull_request]
+# The below variables reduce repetitions across similar targets
+env:
+ REMOVE_BUNDLED_BOOST : rm -rf /usr/local/share/boost
+ APT_INSTALL_LINUX: 'sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache'
+ APT_SET_CONF: |
+ echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
+ echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
+ echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
+
jobs:
build-macos:
runs-on: macOS-latest
@@ -66,16 +75,13 @@ jobs:
key: ccache-ubuntu-build-${{ github.sha }}
restore-keys: ccache-ubuntu-build-
- name: remove bundled boost
- run: sudo rm -rf /usr/local/share/boost
+ run: ${{env.REMOVE_BUNDLED_BOOST}}
- name: set apt conf
- run: |
- echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
+ run: ${{env.APT_SET_CONF}}
- name: update apt
run: sudo apt update
- name: install monero dependencies
- run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache
+ run: ${{env.APT_INSTALL_LINUX}}
- name: build
run: |
ccache --max-size=150M
@@ -96,16 +102,13 @@ jobs:
key: ccache-ubuntu-libwallet-${{ github.sha }}
restore-keys: ccache-ubuntu-libwallet-
- name: remove bundled boost
- run: sudo rm -rf /usr/local/share/boost
+ run: ${{env.REMOVE_BUNDLED_BOOST}}
- name: set apt conf
- run: |
- echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
+ run: ${{env.APT_SET_CONF}}
- name: update apt
run: sudo apt update
- name: install monero dependencies
- run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache
+ run: ${{env.APT_INSTALL_LINUX}}
- name: build
run: |
ccache --max-size=150M
@@ -129,16 +132,13 @@ jobs:
key: test-ubuntu-ccache-${{ github.sha }}
restore-keys: test-ubuntu-ccache-
- name: remove bundled boost
- run: sudo rm -rf /usr/local/share/boost
+ run: ${{env.REMOVE_BUNDLED_BOOST}}
- name: set apt conf
- run: |
- echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- echo "Acquire::http::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
- echo "Acquire::ftp::Timeout \"120\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom
+ run: ${{env.APT_SET_CONF}}
- name: update apt
run: sudo apt update
- name: install monero dependencies
- run: sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache
+ run: ${{env.APT_INSTALL_LINUX}}
- name: install Python dependencies
run: pip install requests psutil monotonic
- name: tests
@@ -154,3 +154,20 @@ jobs:
# ARCH="default" (not "native") ensures, that a different execution host can execute binaries compiled elsewhere.
# BUILD_SHARED_LIBS=ON speeds up the linkage part a bit, reduces size, and is the only place where the dynamic linkage is tested.
+ source-archive:
+ runs-on: ubuntu-20.04
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ submodules: recursive
+ - name: archive
+ run: |
+ pip install git-archive-all
+ export VERSION="monero-$(git describe)"
+ export OUTPUT="$VERSION.tar"
+ echo "OUTPUT=$OUTPUT" >> $GITHUB_ENV
+ /home/runner/.local/bin/git-archive-all --prefix "$VERSION/" --force-submodules "$OUTPUT"
+ - uses: actions/upload-artifact@v2
+ with:
+ name: ${{ env.OUTPUT }}
+ path: /home/runner/work/monero/monero/${{ env.OUTPUT }}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index e858b3aaf..b35eb2b7a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -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)
@@ -164,6 +164,20 @@ function (monero_add_minimal_executable name)
monero_set_target_no_relink( ${name} )
endfunction()
+# Finds all headers in a directory and its subdirs, to be able to search for them and autosave in IDEs.
+#
+# Parameters:
+# - headers_found: Output variable, which will hold the found headers
+# - module_root_dir: The search path for the headers. Typically it will be the module's root dir, so "${CMAKE_CURRENT_SOURCE_DIR}" or a derivative of it.
+macro (monero_find_all_headers headers_found module_root_dir)
+ file(GLOB ${headers_found}
+ "${module_root_dir}/*.h*" # h* will include hpps as well.
+ "${module_root_dir}/**/*.h*" # Any number of subdirs will be included.
+ "${module_root_dir}/*.inl" # .inl is typically template code and is being treated as headers (it's being included).
+ "${module_root_dir}/**/*.inl"
+)
+endmacro()
+
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}")
@@ -526,6 +540,29 @@ macro (monero_enable_coverage)
endif()
endmacro()
+function (monero_add_library name)
+ monero_add_library_with_deps(NAME "${name}" SOURCES ${ARGN})
+endfunction()
+
+function (monero_add_library_with_deps)
+ cmake_parse_arguments(MONERO_ADD_LIBRARY "" "NAME" "DEPENDS;SOURCES" ${ARGN})
+ source_group("${MONERO_ADD_LIBRARY_NAME}" FILES ${MONERO_ADD_LIBRARY_SOURCES})
+
+ # Define a ("virtual") object library and an actual library that links those
+ # objects together. The virtual libraries can be arbitrarily combined to link
+ # any subset of objects into one library archive. This is used for releasing
+ # libwallet, which combines multiple components.
+ set(objlib obj_${MONERO_ADD_LIBRARY_NAME})
+ add_library(${objlib} OBJECT ${MONERO_ADD_LIBRARY_SOURCES})
+ add_library("${MONERO_ADD_LIBRARY_NAME}" $<TARGET_OBJECTS:${objlib}>)
+ monero_set_target_no_relink("${MONERO_ADD_LIBRARY_NAME}")
+ if (MONERO_ADD_LIBRARY_DEPENDS)
+ add_dependencies(${objlib} ${MONERO_ADD_LIBRARY_DEPENDS})
+ endif()
+ set_property(TARGET "${MONERO_ADD_LIBRARY_NAME}" PROPERTY FOLDER "libs")
+ target_compile_definitions(${objlib}
+ PRIVATE $<TARGET_PROPERTY:${MONERO_ADD_LIBRARY_NAME},INTERFACE_COMPILE_DEFINITIONS>)
+endfunction ()
# Generate header for embedded translations
# Generate header for embedded translations, use target toolchain if depends, otherwise use the
@@ -655,7 +692,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-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()
@@ -737,7 +774,12 @@ else()
# PIE executables randomly crash at startup with ASAN
# Windows binaries die on startup with PIE when compiled with GCC <9.x
# Windows dynamically-linked binaries die on startup with PIE regardless of GCC version
- add_linker_flag_if_supported(-pie LD_SECURITY_FLAGS)
+ if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ # Clang does not support -pie flag
+ add_linker_flag_if_supported("-Wl,-pie" LD_SECURITY_FLAGS)
+ else()
+ add_linker_flag_if_supported("-pie" LD_SECURITY_FLAGS)
+ endif()
endif()
add_linker_flag_if_supported(-Wl,-z,relro LD_SECURITY_FLAGS)
add_linker_flag_if_supported(-Wl,-z,now LD_SECURITY_FLAGS)
@@ -763,6 +805,13 @@ else()
add_linker_flag_if_supported(-Wl,--high-entropy-va LD_SECURITY_FLAGS)
endif()
+ # Warnings, that when ignored are so severe, that they can segfault or even UB any application.
+ # Treat them as errors.
+ add_c_flag_if_supported( -Werror=switch C_SECURITY_FLAGS)
+ add_cxx_flag_if_supported(-Werror=switch CXX_SECURITY_FLAGS)
+ add_c_flag_if_supported( -Werror=return-type C_SECURITY_FLAGS)
+ add_cxx_flag_if_supported(-Werror=return-type CXX_SECURITY_FLAGS)
+
message(STATUS "Using C security hardening flags: ${C_SECURITY_FLAGS}")
message(STATUS "Using C++ security hardening flags: ${CXX_SECURITY_FLAGS}")
message(STATUS "Using linker security hardening flags: ${LD_SECURITY_FLAGS}")
@@ -886,7 +935,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()
@@ -1033,7 +1082,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})
diff --git a/Dockerfile b/Dockerfile
index 51fd51e1c..f21f74ac3 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -46,7 +46,7 @@ ARG BOOST_VERSION=1_70_0
ARG BOOST_VERSION_DOT=1.70.0
ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778
RUN set -ex \
- && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
+ && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
&& cd boost_${BOOST_VERSION} \
diff --git a/cmake/CheckLinkerFlag.cmake b/cmake/CheckLinkerFlag.cmake
index 2b507ab71..7ecf5f610 100644
--- a/cmake/CheckLinkerFlag.cmake
+++ b/cmake/CheckLinkerFlag.cmake
@@ -15,6 +15,7 @@ macro(CHECK_LINKER_FLAG flag VARIABLE)
${_cle_source}
COMPILE_DEFINITIONS ${CMAKE_REQUIRED_DEFINITIONS} ${flag}
CMAKE_FLAGS
+ "-DCMAKE_EXE_LINKER_FLAGS=${flag}"
OUTPUT_VARIABLE OUTPUT)
unset(_cle_source)
set(CMAKE_C_FLAGS ${saved_CMAKE_C_FLAGS})
diff --git a/cmake/FindCcache.cmake b/cmake/FindCcache.cmake
index f7b1b8425..2eb2fa2fd 100644
--- a/cmake/FindCcache.cmake
+++ b/cmake/FindCcache.cmake
@@ -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; }")
diff --git a/cmake/FindLibUSB.cmake b/cmake/FindLibUSB.cmake
index 79d8fba75..6944c6c45 100644
--- a/cmake/FindLibUSB.cmake
+++ b/cmake/FindLibUSB.cmake
@@ -134,7 +134,7 @@ if ( LibUSB_FOUND )
try_compile(LibUSB_COMPILE_TEST_PASSED
${CMAKE_BINARY_DIR}
- "${CMAKE_SOURCE_DIR}/cmake/test-libusb-version.c"
+ "${CMAKE_CURRENT_LIST_DIR}/test-libusb-version.c"
CMAKE_FLAGS
"-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}"
"-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}"
diff --git a/contrib/depends/Makefile b/contrib/depends/Makefile
index 28ec972e4..0d71ddb13 100644
--- a/contrib/depends/Makefile
+++ b/contrib/depends/Makefile
@@ -10,8 +10,8 @@ HOST ?= $(BUILD)
PATCHES_PATH = $(BASEDIR)/patches
BASEDIR = $(CURDIR)
HASH_LENGTH:=11
-DOWNLOAD_CONNECT_TIMEOUT:=10
-DOWNLOAD_RETRIES:=3
+DOWNLOAD_CONNECT_TIMEOUT:=30
+DOWNLOAD_RETRIES:=5
HOST_ID_SALT ?= salt
BUILD_ID_SALT ?= salt
diff --git a/contrib/depends/packages/boost.mk b/contrib/depends/packages/boost.mk
index 0d241928e..4571d4232 100644
--- a/contrib/depends/packages/boost.mk
+++ b/contrib/depends/packages/boost.mk
@@ -1,6 +1,6 @@
package=boost
$(package)_version=1_64_0
-$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/
+$(package)_download_path=https://downloads.sourceforge.net/project/boost/boost/1.64.0/
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
$(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332
$(package)_dependencies=libiconv
diff --git a/contrib/epee/demo/CMakeLists.txt b/contrib/epee/demo/CMakeLists.txt
index b4ac2cc8b..d2ae0ed55 100644
--- a/contrib/epee/demo/CMakeLists.txt
+++ b/contrib/epee/demo/CMakeLists.txt
@@ -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 )
diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/storages/portable_storage.h
index 655a2eb12..60f3e672f 100644
--- a/contrib/epee/include/storages/portable_storage.h
+++ b/contrib/epee/include/storages/portable_storage.h
@@ -31,6 +31,8 @@
#include "misc_log_ex.h"
#include "span.h"
+#include <boost/mpl/contains.hpp>
+
namespace epee
{
class byte_slice;
diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt
index 368f49c95..7bc75caf3 100644
--- a/contrib/epee/src/CMakeLists.txt
+++ b/contrib/epee/src/CMakeLists.txt
@@ -28,13 +28,10 @@
set(EPEE_INCLUDE_DIR_BASE "${CMAKE_CURRENT_SOURCE_DIR}/../include")
-# Adding headers to the file list, to be able to search for them in IDEs.
-file(GLOB EPEE_HEADERS_PUBLIC
- "${EPEE_INCLUDE_DIR_BASE}/*.h*" # h* will include hpps as well.
- "${EPEE_INCLUDE_DIR_BASE}/**/*.h*" # Any number of subdirs will be included.
-)
+# Add headers to the file list, to be able to search for them and autosave in IDEs.
+monero_find_all_headers(EPEE_HEADERS_PUBLIC "${EPEE_INCLUDE_DIR_BASE}")
-add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
+monero_add_library(epee byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
int-util.cpp portable_storage.cpp
misc_language.cpp
@@ -47,7 +44,7 @@ add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_cli
)
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
- add_library(epee_readline STATIC readline_buffer.cpp)
+ monero_add_library(epee_readline readline_buffer.cpp)
endif()
if(HAVE_C11)
@@ -75,8 +72,9 @@ target_link_libraries(epee
${Boost_CHRONO_LIBRARY}
${Boost_FILESYSTEM_LIBRARY}
${Boost_THREAD_LIBRARY}
- PRIVATE
+ ${Boost_REGEX_LIBRARY}
${OPENSSL_LIBRARIES}
+ PRIVATE
${EXTRA_LIBRARIES})
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
@@ -87,5 +85,8 @@ if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
${GNU_READLINE_LIBRARY})
endif()
-target_include_directories(epee PUBLIC "${EPEE_INCLUDE_DIR_BASE}")
+target_include_directories(epee
+ PUBLIC
+ "${EPEE_INCLUDE_DIR_BASE}"
+ "${OPENSSL_INCLUDE_DIR}")
diff --git a/contrib/epee/src/byte_slice.cpp b/contrib/epee/src/byte_slice.cpp
index 453b63a4c..430853c64 100644
--- a/contrib/epee/src/byte_slice.cpp
+++ b/contrib/epee/src/byte_slice.cpp
@@ -151,7 +151,7 @@ namespace epee
: byte_slice()
{
std::size_t space_needed = 0;
- for (const auto source : sources)
+ for (const auto& source : sources)
space_needed += source.size();
if (space_needed)
@@ -160,7 +160,7 @@ namespace epee
span<std::uint8_t> out{reinterpret_cast<std::uint8_t*>(storage.get() + 1), space_needed};
portion_ = {out.data(), out.size()};
- for (const auto source : sources)
+ for (const auto& source : sources)
{
std::memcpy(out.data(), source.data(), source.size());
if (out.remove_prefix(source.size()) < source.size())
diff --git a/contrib/epee/tests/src/CMakeLists.txt b/contrib/epee/tests/src/CMakeLists.txt
index 4807fa7ea..0c42f87ca 100644
--- a/contrib/epee/tests/src/CMakeLists.txt
+++ b/contrib/epee/tests/src/CMakeLists.txt
@@ -1,5 +1,5 @@
-cmake_minimum_required(VERSION 2.8)
+cmake_minimum_required(VERSION 3.5)
set(Boost_USE_MULTITHREADED ON)
diff --git a/docs/COMPILING_DEBUGGING_TESTING.md b/docs/COMPILING_DEBUGGING_TESTING.md
new file mode 100644
index 000000000..f5c202303
--- /dev/null
+++ b/docs/COMPILING_DEBUGGING_TESTING.md
@@ -0,0 +1,86 @@
+# Compiling, debugging and testing efficiently
+
+This document describes ways of compiling, debugging and testing efficiently for various use cases.
+The intented audience are developers, who want to leverage newly added tricks to Monero via `CMake`. The document will lower the entry point for these developers.
+Before reading this document, please consult section "Build instructions" in the main README.md.
+Some information from README.md will be repeated here, but the aim is to go beyond it.
+
+## Basic compilation
+
+Monero can be compiled via the main `Makefile`, using one of several targets listed there.
+The targets are actually presets for `CMake` calls with various options, plus `make` commands for building or in some cases `make test` for testing.
+It is possible to extract these `CMake` calls and modify them for your specific needs. For example, a minimal external cmake command to compile Monero, executed from within a newly created build directory could look like:
+
+`cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release && make`
+
+where the variable `DIR_SRC` is expected to store the path to the Monero source code.
+
+## Use cases
+
+### Test Driven Development (TDD) - shared libraries for release builds
+
+Building shared libraries spares a lot of disk space and linkage time. By default only the debug builds produce shared libraries. If you'd like to produce dynamic libraries for the release build for the same reasons as it's being done for the debug version, then you need to add the `BUILD_SHARED_LIBS=ON` flag to the `CMake` call, like the following:
+
+`cmake -S "$DIR_SRC" -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=ON && make`
+
+A perfect use case for the above call is following the Test Driven Development (TDD) principles. In a nutshell, you'd first write a couple of tests, which describe the (new) requirements of the class/method that you're about to write or modify. The tests will typically compile for quite a long time, so ideally write them once. After you're done with the tests, the only thing left to do is to keep modifying the implementation for as long as the tests are failing. If the implementation is contained properly within a .cpp file, then the only time cost to be paid will be compiling the single source file and generating the implementation's shared library. The test itself will not have to be touched and will pick up the new version of the implementation (via the shared library) upon the next execution of the test.
+
+### Project generation for IDEs
+
+CMake allows to generate project files for many IDEs. The list of supported project files can be obtained by writing in the console:
+
+`cmake -G`
+
+For instance, in order to generate Makefiles and project files for the Code::Blocks IDE, this part of the call would look like the following:
+
+`cmake -G "CodeBlocks - Unix Makefiles" (...)`
+
+The additional artifact of the above call is the `monero.cbp` Code::Blocks project file in the build directory.
+
+### Debugging in Code::Blocks (CB)
+
+First prepare the build directory for debugging using the following example command, assuming, that the path to the source dir is being held in the DIR_SRC variable, and using 2 cores:
+
+`cmake -S "$DIR_SRC" -G "CodeBlocks - Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=ON && make -j 2`
+
+After a successful build, open the `monero.cbp` with CB. From the CB's menu bar select the target, that you want debug. Assuming these are unit tests:
+
+`Build -> Select target -> Select target -> unit_tests`
+
+In order to lower the turnaround times, we will run a specific portion of code of interest, without having to go through all the time costly initialization and execution of unrelated parts. For this we'll use GTest's capabilities of test filtering. From the build directory run the following command to learn all the registered tests:
+
+`tests/unit_tests/unit_tests --gtest_list_tests`
+
+For example, if you're only interested in logging, you'd find in the list the label `logging.` and its subtests. To execute all the logging tests, you'd write in the console:
+
+`tests/unit_tests/unit_tests --gtest_filter="logging.*"`
+
+This parameter is what we need to transfer to CB, in order to reflect the same behaviour in the CB's debugger. From the main menu select:
+
+`Project -> Set program's arguments...`
+
+Then in the `Program's arguments` textbox you'd write in this case:
+
+`--gtest_filter="logging.*"`
+
+Verify if the expected UTs are being properly executed with `F9` or select:
+
+`Build -> Build and run`
+
+If everything looks fine, then after setting some breakpoints of your choice, the target is ready for debugging in CB via:
+
+`Debug -> Start/Continue`
+
+## To be done (and merged):
+### Multihost parallel compilation
+https://github.com/monero-project/monero/pull/7160
+
+### Faster core_tests with caching
+https://github.com/monero-project/monero/pull/5821
+
+### Precompiled headers
+https://github.com/monero-project/monero/pull/7216
+
+### Unity builds
+https://github.com/monero-project/monero/pull/7217
+
diff --git a/external/easylogging++/CMakeLists.txt b/external/easylogging++/CMakeLists.txt
index fcda54547..9aa4c08bc 100644
--- a/external/easylogging++/CMakeLists.txt
+++ b/external/easylogging++/CMakeLists.txt
@@ -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.8.7)
+cmake_minimum_required(VERSION 3.5)
project(easylogging CXX)
@@ -36,8 +36,12 @@ monero_enable_coverage()
find_package(Threads)
find_package(Backtrace)
+monero_find_all_headers(EASYLOGGING_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}")
+
add_library(easylogging
- easylogging++.cc)
+ easylogging++.cc
+ ${EASYLOGGING_HEADERS}
+ )
include_directories("${CMAKE_CURRENT_SOURCE_DIR}")
include_directories("${CMAKE_CURRENT_BINARY_DIR}")
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 9904c5de7..1f89faf98 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -79,30 +79,6 @@ function (monero_add_executable name)
monero_set_target_no_relink("${name}")
endfunction ()
-function (monero_add_library name)
- monero_add_library_with_deps(NAME "${name}" SOURCES ${ARGN})
-endfunction()
-
-function (monero_add_library_with_deps)
- cmake_parse_arguments(MONERO_ADD_LIBRARY "" "NAME" "DEPENDS;SOURCES" ${ARGN})
- source_group("${MONERO_ADD_LIBRARY_NAME}" FILES ${MONERO_ADD_LIBRARY_SOURCES})
-
- # Define a ("virtual") object library and an actual library that links those
- # objects together. The virtual libraries can be arbitrarily combined to link
- # any subset of objects into one library archive. This is used for releasing
- # libwallet, which combines multiple components.
- set(objlib obj_${MONERO_ADD_LIBRARY_NAME})
- add_library(${objlib} OBJECT ${MONERO_ADD_LIBRARY_SOURCES})
- add_library("${MONERO_ADD_LIBRARY_NAME}" $<TARGET_OBJECTS:${objlib}>)
- monero_set_target_no_relink("${MONERO_ADD_LIBRARY_NAME}")
- if (MONERO_ADD_LIBRARY_DEPENDS)
- add_dependencies(${objlib} ${MONERO_ADD_LIBRARY_DEPENDS})
- endif()
- set_property(TARGET "${MONERO_ADD_LIBRARY_NAME}" PROPERTY FOLDER "libs")
- target_compile_definitions(${objlib}
- PRIVATE $<TARGET_PROPERTY:${MONERO_ADD_LIBRARY_NAME},INTERFACE_COMPILE_DEFINITIONS>)
-endfunction ()
-
include(Version)
monero_add_library(version SOURCES ${CMAKE_BINARY_DIR}/version.cpp DEPENDS genversion)
diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt
index 3b33fe90a..3f0f7d34b 100644
--- a/src/crypto/CMakeLists.txt
+++ b/src/crypto/CMakeLists.txt
@@ -116,6 +116,7 @@ endif()
# cheat because cmake and ccache hate each other
set_property(SOURCE CryptonightR_template.S PROPERTY LANGUAGE C)
+set_property(SOURCE CryptonightR_template.S PROPERTY XCODE_EXPLICIT_FILE_TYPE sourcecode.asm)
# Must be done last, because it references libraries in this directory
add_subdirectory(wallet)
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index a3d695b85..db707bb65 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -566,6 +566,8 @@ void Blockchain::pop_blocks(uint64_t nblocks)
return;
}
+ CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
+
if (stop_batch)
m_db->batch_stop();
}
@@ -643,7 +645,6 @@ block Blockchain::pop_block_from_blockchain()
m_scan_table.clear();
m_blocks_txs_check.clear();
- CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
uint64_t top_block_height;
crypto::hash top_block_hash = get_tail_id(top_block_height);
m_tx_pool.on_blockchain_dec(top_block_height, top_block_hash);
@@ -1110,6 +1111,7 @@ bool Blockchain::rollback_blockchain_switching(std::list<block>& original_chain,
{
pop_block_from_blockchain();
}
+ CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
// make sure the hard fork object updates its current version
m_hardfork->reorganize_from_chain_height(rollback_height);
@@ -1160,6 +1162,7 @@ bool Blockchain::switch_to_alternative_blockchain(std::list<block_extended_info>
block b = pop_block_from_blockchain();
disconnected_chain.push_front(b);
}
+ CHECK_AND_ASSERT_THROW_MES(update_next_cumulative_weight_limit(), "Error updating next cumulative weight limit");
auto split_height = m_db->height();
@@ -5150,7 +5153,7 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector<block_complete
if (m_cancel)
return false;
- for (const auto &tx_blob : entry.txs)
+ for (size_t i = 0; i < entry.txs.size(); ++i)
{
if (tx_index >= txes.size())
SCAN_TABLE_QUIT("tx_index is out of sync");
diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp
index 7400c4328..f41c63a4b 100644
--- a/src/cryptonote_core/cryptonote_tx_utils.cpp
+++ b/src/cryptonote_core/cryptonote_tx_utils.cpp
@@ -622,8 +622,10 @@ namespace cryptonote
if (need_additional_txkeys)
{
additional_tx_keys.clear();
- for (const auto &d: destinations)
+ for (size_t i = 0; i < destinations.size(); ++i)
+ {
additional_tx_keys.push_back(keypair::generate(sender_account_keys.get_device()).sec);
+ }
}
bool r = construct_tx_with_tx_key(sender_account_keys, subaddresses, sources, destinations, change_addr, extra, tx, unlock_time, tx_key, additional_tx_keys, rct, rct_config, msout);
diff --git a/src/cryptonote_protocol/CMakeLists.txt b/src/cryptonote_protocol/CMakeLists.txt
index d28b44bb7..85c25546f 100644
--- a/src/cryptonote_protocol/CMakeLists.txt
+++ b/src/cryptonote_protocol/CMakeLists.txt
@@ -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 *)
diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
index afc81f552..685968c08 100644
--- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl
+++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl
@@ -2310,7 +2310,7 @@ skip:
const uint32_t peer_stripe = tools::get_pruning_stripe(context.m_pruning_seed);
const uint32_t first_stripe = tools::get_pruning_stripe(span.first, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES);
const uint32_t last_stripe = tools::get_pruning_stripe(span.first + span.second - 1, context.m_remote_blockchain_height, CRYPTONOTE_PRUNING_LOG_STRIPES);
- if ((((first_stripe && peer_stripe != first_stripe) || (last_stripe && peer_stripe != last_stripe)) && !m_sync_pruned_blocks) || (m_sync_pruned_blocks && req.prune))
+ if (((first_stripe && peer_stripe != first_stripe) || (last_stripe && peer_stripe != last_stripe)) && !m_sync_pruned_blocks)
{
MDEBUG(context << "We need full data, but the peer does not have it, dropping peer");
return false;
diff --git a/src/device_trezor/trezor/transport.cpp b/src/device_trezor/trezor/transport.cpp
index be95868d0..194176413 100644
--- a/src/device_trezor/trezor/transport.cpp
+++ b/src/device_trezor/trezor/transport.cpp
@@ -157,7 +157,7 @@ namespace trezor{
#define PROTO_HEADER_SIZE 6
static size_t message_size(const google::protobuf::Message &req){
- return static_cast<size_t>(req.ByteSize());
+ return req.ByteSizeLong();
}
static size_t serialize_message_buffer_size(size_t msg_size) {
diff --git a/src/p2p/CMakeLists.txt b/src/p2p/CMakeLists.txt
index cfd8273b4..0cd38f253 100644
--- a/src/p2p/CMakeLists.txt
+++ b/src/p2p/CMakeLists.txt
@@ -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 *)
diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl
index e1d6d1e10..a0b8438b2 100644
--- a/src/p2p/net_node.inl
+++ b/src/p2p/net_node.inl
@@ -682,11 +682,13 @@ 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");
}
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");
}
else if (m_nettype == cryptonote::FAKECHAIN)
{
@@ -701,6 +703,7 @@ 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");
}
return full_addrs;
}
diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp
index ded545efa..8d8a68efb 100644
--- a/src/rpc/core_rpc_server.cpp
+++ b/src/rpc/core_rpc_server.cpp
@@ -1044,6 +1044,7 @@ namespace cryptonote
if (e.in_pool)
{
e.block_height = e.block_timestamp = std::numeric_limits<uint64_t>::max();
+ e.confirmations = 0;
auto it = per_tx_pool_tx_info.find(tx_hash);
if (it != per_tx_pool_tx_info.end())
{
@@ -1062,6 +1063,7 @@ namespace cryptonote
else
{
e.block_height = m_core.get_blockchain_storage().get_db().get_tx_block_height(tx_hash);
+ e.confirmations = m_core.get_current_blockchain_height() - e.block_height;
e.block_timestamp = m_core.get_blockchain_storage().get_db().get_block_timestamp(e.block_height);
e.received_timestamp = 0;
e.double_spend_seen = false;
diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h
index 5ebe4f654..ff8c98b98 100644
--- a/src/rpc/core_rpc_server_commands_defs.h
+++ b/src/rpc/core_rpc_server_commands_defs.h
@@ -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 6
+#define CORE_RPC_VERSION_MINOR 7
#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)
@@ -350,6 +350,7 @@ namespace cryptonote
bool in_pool;
bool double_spend_seen;
uint64_t block_height;
+ uint64_t confirmations;
uint64_t block_timestamp;
uint64_t received_timestamp;
std::vector<uint64_t> output_indices;
@@ -367,6 +368,7 @@ namespace cryptonote
if (!this_ref.in_pool)
{
KV_SERIALIZE(block_height)
+ KV_SERIALIZE(confirmations)
KV_SERIALIZE(block_timestamp)
KV_SERIALIZE(output_indices)
}
diff --git a/src/serialization/json_object.h b/src/serialization/json_object.h
index de14c8911..35ea990b3 100644
--- a/src/serialization/json_object.h
+++ b/src/serialization/json_object.h
@@ -365,7 +365,7 @@ inline typename std::enable_if<sfinae::is_vector_like<Vec>::value, void>::type t
static_assert(!std::is_same<value_type, unsigned char>::value, "encoding an array of unsigned char is faster as hex");
dest.StartArray();
- for (const auto& t : vec)
+ for (auto t : vec)
toJsonValue(dest, t);
dest.EndArray();
}
diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp
index a7856d60f..e859a4693 100644
--- a/src/simplewallet/simplewallet.cpp
+++ b/src/simplewallet/simplewallet.cpp
@@ -5895,7 +5895,7 @@ bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bo
if (reset != ResetNone)
{
if (reset == ResetSoftKeepKI)
- height_pre = m_wallet->hash_m_transfers(-1, transfer_hash_pre);
+ height_pre = m_wallet->hash_m_transfers(boost::none, transfer_hash_pre);
m_wallet->rescan_blockchain(reset == ResetHard, false, reset == ResetSoftKeepKI);
}
diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt
index bf238ae37..2dd64a38f 100644
--- a/src/wallet/CMakeLists.txt
+++ b/src/wallet/CMakeLists.txt
@@ -40,18 +40,7 @@ set(wallet_sources
wallet_rpc_payments.cpp
)
-set(wallet_private_headers
- wallet2.h
- wallet_args.h
- wallet_errors.h
- wallet_rpc_server.h
- wallet_rpc_server_commands_defs.h
- wallet_rpc_server_error_codes.h
- ringdb.h
- node_rpc_proxy.h
- message_store.h
- message_transporter.h
- wallet_rpc_helpers.h)
+monero_find_all_headers(wallet_private_headers "${CMAKE_CURRENT_SOURCE_DIR}")
monero_private_headers(wallet
${wallet_private_headers})
@@ -115,45 +104,4 @@ if(NOT IOS)
install(TARGETS wallet_rpc_server DESTINATION bin)
endif()
-# build and install libwallet_merged only if we building for GUI
-if (BUILD_GUI_DEPS)
- set(libs_to_merge
- wallet_api
- wallet
- rpc_base
- multisig
- blockchain_db
- cryptonote_core
- cryptonote_basic
- mnemonics
- common
- cncrypto
- device
- hardforks
- ringct
- ringct_basic
- checkpoints
- version
- net
- device_trezor)
-
- foreach(lib ${libs_to_merge})
- list(APPEND objlibs $<TARGET_OBJECTS:obj_${lib}>) # matches naming convention in src/CMakeLists.txt
- endforeach()
- add_library(wallet_merged STATIC ${objlibs})
- if(IOS)
- set(lib_folder lib-${ARCH})
- else()
- set(lib_folder lib)
- endif()
- install(TARGETS wallet_merged
- ARCHIVE DESTINATION ${lib_folder})
-
- install(FILES ${TREZOR_DEP_LIBS}
- DESTINATION ${lib_folder})
- file(WRITE "trezor_link_flags.txt" ${TREZOR_DEP_LINKER})
- install(FILES "trezor_link_flags.txt"
- DESTINATION ${lib_folder})
-endif()
-
add_subdirectory(api)
diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp
index adff042ad..db3049f9e 100644
--- a/src/wallet/api/wallet.cpp
+++ b/src/wallet/api/wallet.cpp
@@ -1214,6 +1214,68 @@ bool WalletImpl::importKeyImages(const string &filename)
return true;
}
+bool WalletImpl::exportOutputs(const string &filename, bool all)
+{
+ if (m_wallet->key_on_device())
+ {
+ setStatusError(string(tr("Not supported on HW wallets.")) + filename);
+ return false;
+ }
+
+ try
+ {
+ std::string data = m_wallet->export_outputs_to_str(all);
+ bool r = m_wallet->save_to_file(filename, data);
+ if (!r)
+ {
+ LOG_ERROR("Failed to save file " << filename);
+ setStatusError(string(tr("Failed to save file: ")) + filename);
+ return false;
+ }
+ }
+ catch (const std::exception &e)
+ {
+ LOG_ERROR("Error exporting outputs: " << e.what());
+ setStatusError(string(tr("Error exporting outputs: ")) + e.what());
+ return false;
+ }
+
+ LOG_PRINT_L2("Outputs exported to " << filename);
+ return true;
+}
+
+bool WalletImpl::importOutputs(const string &filename)
+{
+ if (m_wallet->key_on_device())
+ {
+ setStatusError(string(tr("Not supported on HW wallets.")) + filename);
+ return false;
+ }
+
+ std::string data;
+ bool r = m_wallet->load_from_file(filename, data);
+ if (!r)
+ {
+ LOG_ERROR("Failed to read file: " << filename);
+ setStatusError(string(tr("Failed to read file: ")) + filename);
+ return false;
+ }
+
+ try
+ {
+ size_t n_outputs = m_wallet->import_outputs_from_str(data);
+ LOG_PRINT_L2(std::to_string(n_outputs) << " outputs imported");
+ }
+ catch (const std::exception &e)
+ {
+ LOG_ERROR("Failed to import outputs: " << e.what());
+ setStatusError(string(tr("Failed to import outputs: ")) + e.what());
+ return false;
+ }
+
+ return true;
+}
+
void WalletImpl::addSubaddressAccount(const std::string& label)
{
m_wallet->add_subaddress_account(label);
diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h
index 13b33d1cd..ce2d7d7e4 100644
--- a/src/wallet/api/wallet.h
+++ b/src/wallet/api/wallet.h
@@ -167,6 +167,8 @@ public:
virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override;
bool exportKeyImages(const std::string &filename, bool all = false) override;
bool importKeyImages(const std::string &filename) override;
+ bool exportOutputs(const std::string &filename, bool all = false) override;
+ bool importOutputs(const std::string &filename) override;
virtual void disposeTransaction(PendingTransaction * t) override;
virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations,
diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h
index 320b458bd..e34332734 100644
--- a/src/wallet/api/wallet2_api.h
+++ b/src/wallet/api/wallet2_api.h
@@ -919,6 +919,19 @@ struct Wallet
*/
virtual bool importKeyImages(const std::string &filename) = 0;
+ /*!
+ * \brief importOutputs - exports outputs to file
+ * \param filename
+ * \return - true on success
+ */
+ virtual bool exportOutputs(const std::string &filename, bool all = false) = 0;
+
+ /*!
+ * \brief importOutputs - imports outputs from file
+ * \param filename
+ * \return - true on success
+ */
+ virtual bool importOutputs(const std::string &filename) = 0;
virtual TransactionHistory * history() = 0;
virtual AddressBook * addressBook() = 0;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index f18e3abc7..05fe0a1ad 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -11509,6 +11509,9 @@ void wallet2::check_tx_key_helper(const cryptonote::transaction &tx, const crypt
void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_derivation &derivation, const std::vector<crypto::key_derivation> &additional_derivations, const cryptonote::account_public_address &address, uint64_t &received, bool &in_pool, uint64_t &confirmations)
{
+ uint32_t rpc_version;
+ THROW_WALLET_EXCEPTION_IF(!check_connection(&rpc_version), error::wallet_internal_error, "Failed to connect to daemon: " + get_daemon_address());
+
COMMAND_RPC_GET_TRANSACTIONS::request req;
COMMAND_RPC_GET_TRANSACTIONS::response res;
req.txs_hashes.push_back(epee::string_tools::pod_to_hex(txid));
@@ -11554,10 +11557,17 @@ void wallet2::check_tx_key_helper(const crypto::hash &txid, const crypto::key_de
confirmations = 0;
if (!in_pool)
{
- std::string err;
- uint64_t bc_height = get_daemon_blockchain_height(err);
- if (err.empty())
- confirmations = bc_height - res.txs.front().block_height;
+ if (rpc_version < MAKE_CORE_RPC_VERSION(3, 7))
+ {
+ std::string err;
+ uint64_t bc_height = get_daemon_blockchain_height(err);
+ if (err.empty() && bc_height > res.txs.front().block_height)
+ confirmations = bc_height - res.txs.front().block_height;
+ }
+ else
+ {
+ confirmations = res.txs.front().confirmations;
+ }
}
}
@@ -12220,7 +12230,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);
@@ -14178,15 +14188,15 @@ void wallet2::hash_m_transfer(const transfer_details & transfer, crypto::hash &h
KECCAK_CTX state;
keccak_init(&state);
keccak_update(&state, (const uint8_t *) transfer.m_txid.data, sizeof(transfer.m_txid.data));
- keccak_update(&state, (const uint8_t *) transfer.m_internal_output_index, sizeof(transfer.m_internal_output_index));
- keccak_update(&state, (const uint8_t *) transfer.m_global_output_index, sizeof(transfer.m_global_output_index));
- keccak_update(&state, (const uint8_t *) transfer.m_amount, sizeof(transfer.m_amount));
+ keccak_update(&state, (const uint8_t *) &transfer.m_internal_output_index, sizeof(transfer.m_internal_output_index));
+ keccak_update(&state, (const uint8_t *) &transfer.m_global_output_index, sizeof(transfer.m_global_output_index));
+ keccak_update(&state, (const uint8_t *) &transfer.m_amount, sizeof(transfer.m_amount));
keccak_finish(&state, (uint8_t *) hash.data);
}
//----------------------------------------------------------------------------------------------------
-uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const
+uint64_t wallet2::hash_m_transfers(boost::optional<uint64_t> transfer_height, crypto::hash &hash) const
{
- CHECK_AND_ASSERT_THROW_MES(transfer_height > (int64_t)m_transfers.size(), "Hash height is greater than number of transfers");
+ CHECK_AND_ASSERT_THROW_MES(!transfer_height || *transfer_height <= m_transfers.size(), "Hash height is greater than number of transfers");
KECCAK_CTX state;
crypto::hash tmp_hash{};
@@ -14194,12 +14204,12 @@ uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash)
keccak_init(&state);
for(const transfer_details & transfer : m_transfers){
- if (transfer_height >= 0 && current_height >= (uint64_t)transfer_height){
+ if (transfer_height && current_height >= *transfer_height){
break;
}
hash_m_transfer(transfer, tmp_hash);
- keccak_update(&state, (const uint8_t *) transfer.m_block_height, sizeof(transfer.m_block_height));
+ keccak_update(&state, (const uint8_t *) &transfer.m_block_height, sizeof(transfer.m_block_height));
keccak_update(&state, (const uint8_t *) tmp_hash.data, sizeof(tmp_hash.data));
current_height += 1;
}
@@ -14211,23 +14221,28 @@ uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash)
void wallet2::finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash)
{
// Compute hash of m_transfers, if differs there had to be BC reorg.
- crypto::hash new_transfers_hash{};
- hash_m_transfers((int64_t) transfer_height, new_transfers_hash);
+ if (transfer_height <= m_transfers.size()) {
+ crypto::hash new_transfers_hash{};
+ hash_m_transfers(transfer_height, new_transfers_hash);
- if (new_transfers_hash != hash)
- {
- // Soft-Reset to avoid inconsistency in case of BC reorg.
- clear_soft(false); // keep_key_images works only with soft reset.
- THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Transfers changed during rescan, soft or hard rescan is needed");
- }
+ if (new_transfers_hash == hash) {
+ // Restore key images in m_transfers from m_key_images
+ for(auto it = m_key_images.begin(); it != m_key_images.end(); it++)
+ {
+ THROW_WALLET_EXCEPTION_IF(it->second >= m_transfers.size(),
+ error::wallet_internal_error,
+ "Key images cache contains illegal transfer offset");
+ m_transfers[it->second].m_key_image = it->first;
+ m_transfers[it->second].m_key_image_known = true;
+ }
- // Restore key images in m_transfers from m_key_images
- for(auto it = m_key_images.begin(); it != m_key_images.end(); it++)
- {
- THROW_WALLET_EXCEPTION_IF(it->second >= m_transfers.size(), error::wallet_internal_error, "Key images cache contains illegal transfer offset");
- m_transfers[it->second].m_key_image = it->first;
- m_transfers[it->second].m_key_image_known = true;
+ return;
+ }
}
+
+ // Soft-Reset to avoid inconsistency in case of BC reorg.
+ clear_soft(false); // keep_key_images works only with soft reset.
+ THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Transfers changed during rescan, soft or hard rescan is needed");
}
//----------------------------------------------------------------------------------------------------
uint64_t wallet2::get_bytes_sent() const
diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h
index e96a6b51c..facf9878d 100644
--- a/src/wallet/wallet2.h
+++ b/src/wallet/wallet2.h
@@ -1547,7 +1547,7 @@ private:
bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height);
void hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const;
- uint64_t hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const;
+ uint64_t hash_m_transfers(boost::optional<uint64_t> transfer_height, crypto::hash &hash) const;
void finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash);
void enable_dns(bool enable) { m_use_dns = enable; }
void set_offline(bool offline = true);
diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp
index 4fbda72da..e6b48b92f 100644
--- a/src/wallet/wallet_rpc_server.cpp
+++ b/src/wallet/wallet_rpc_server.cpp
@@ -762,6 +762,90 @@ namespace tools
return true;
}
//------------------------------------------------------------------------------------------------------------------------------
+ bool wallet_rpc_server::on_freeze(const wallet_rpc::COMMAND_RPC_FREEZE::request& req, wallet_rpc::COMMAND_RPC_FREEZE::response& res, epee::json_rpc::error& er, const connection_context *ctx)
+ {
+ if (!m_wallet) return not_open(er);
+ try
+ {
+ if (req.key_image.empty())
+ {
+ er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
+ er.message = std::string("Must specify key image to freeze");
+ return false;
+ }
+ crypto::key_image ki;
+ if (!epee::string_tools::hex_to_pod(req.key_image, ki))
+ {
+ er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
+ er.message = "failed to parse key image";
+ return false;
+ }
+ m_wallet->freeze(ki);
+ }
+ catch (const std::exception& e)
+ {
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
+ return false;
+ }
+ return true;
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
+ bool wallet_rpc_server::on_thaw(const wallet_rpc::COMMAND_RPC_THAW::request& req, wallet_rpc::COMMAND_RPC_THAW::response& res, epee::json_rpc::error& er, const connection_context *ctx)
+ {
+ if (!m_wallet) return not_open(er);
+ try
+ {
+ if (req.key_image.empty())
+ {
+ er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
+ er.message = std::string("Must specify key image to thaw");
+ return false;
+ }
+ crypto::key_image ki;
+ if (!epee::string_tools::hex_to_pod(req.key_image, ki))
+ {
+ er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
+ er.message = "failed to parse key image";
+ return false;
+ }
+ m_wallet->thaw(ki);
+ }
+ catch (const std::exception& e)
+ {
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
+ return false;
+ }
+ return true;
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
+ bool wallet_rpc_server::on_frozen(const wallet_rpc::COMMAND_RPC_FROZEN::request& req, wallet_rpc::COMMAND_RPC_FROZEN::response& res, epee::json_rpc::error& er, const connection_context *ctx)
+ {
+ if (!m_wallet) return not_open(er);
+ try
+ {
+ if (req.key_image.empty())
+ {
+ er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
+ er.message = std::string("Must specify key image to check if frozen");
+ return false;
+ }
+ crypto::key_image ki;
+ if (!epee::string_tools::hex_to_pod(req.key_image, ki))
+ {
+ er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
+ er.message = "failed to parse key image";
+ return false;
+ }
+ res.frozen = m_wallet->frozen(ki);
+ }
+ catch (const std::exception& e)
+ {
+ handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
+ return false;
+ }
+ return true;
+ }
+ //------------------------------------------------------------------------------------------------------------------------------
bool wallet_rpc_server::validate_transfer(const std::list<wallet_rpc::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er)
{
crypto::hash8 integrated_payment_id = crypto::null_hash8;
diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h
index 9f9e3c134..e1f27ea40 100644
--- a/src/wallet/wallet_rpc_server.h
+++ b/src/wallet/wallet_rpc_server.h
@@ -84,6 +84,9 @@ namespace tools
MAP_JON_RPC_WE("set_account_tag_description", on_set_account_tag_description, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION)
MAP_JON_RPC_WE("get_height", on_getheight, wallet_rpc::COMMAND_RPC_GET_HEIGHT)
MAP_JON_RPC_WE("getheight", on_getheight, wallet_rpc::COMMAND_RPC_GET_HEIGHT)
+ MAP_JON_RPC_WE("freeze", on_freeze, wallet_rpc::COMMAND_RPC_FREEZE)
+ MAP_JON_RPC_WE("thaw", on_thaw, wallet_rpc::COMMAND_RPC_THAW)
+ MAP_JON_RPC_WE("frozen", on_frozen, wallet_rpc::COMMAND_RPC_FROZEN)
MAP_JON_RPC_WE("transfer", on_transfer, wallet_rpc::COMMAND_RPC_TRANSFER)
MAP_JON_RPC_WE("transfer_split", on_transfer_split, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT)
MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER)
@@ -174,6 +177,9 @@ namespace tools
bool on_untag_accounts(const wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_set_account_tag_description(const wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::request& req, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_getheight(const wallet_rpc::COMMAND_RPC_GET_HEIGHT::request& req, wallet_rpc::COMMAND_RPC_GET_HEIGHT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
+ bool on_freeze(const wallet_rpc::COMMAND_RPC_FREEZE::request& req, wallet_rpc::COMMAND_RPC_FREEZE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
+ bool on_thaw(const wallet_rpc::COMMAND_RPC_THAW::request& req, wallet_rpc::COMMAND_RPC_THAW::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
+ bool on_frozen(const wallet_rpc::COMMAND_RPC_FROZEN::request& req, wallet_rpc::COMMAND_RPC_FROZEN::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
bool on_sign_transfer(const wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h
index 0002508a2..07cda2ba7 100644
--- a/src/wallet/wallet_rpc_server_commands_defs.h
+++ b/src/wallet/wallet_rpc_server_commands_defs.h
@@ -47,7 +47,7 @@
// advance which version they will stop working with
// Don't go over 32767 for any of these
#define WALLET_RPC_VERSION_MAJOR 1
-#define WALLET_RPC_VERSION_MINOR 21
+#define WALLET_RPC_VERSION_MINOR 22
#define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor))
#define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR)
namespace tools
@@ -456,6 +456,69 @@ namespace wallet_rpc
END_KV_SERIALIZE_MAP()
};
+ struct COMMAND_RPC_FREEZE
+ {
+ struct request_t
+ {
+ std::string key_image;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(key_image)
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<request_t> request;
+
+ struct response_t
+ {
+ BEGIN_KV_SERIALIZE_MAP()
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<response_t> response;
+ };
+
+ struct COMMAND_RPC_THAW
+ {
+ struct request_t
+ {
+ std::string key_image;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(key_image)
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<request_t> request;
+
+ struct response_t
+ {
+ BEGIN_KV_SERIALIZE_MAP()
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<response_t> response;
+ };
+
+ struct COMMAND_RPC_FROZEN
+ {
+ struct request_t
+ {
+ std::string key_image;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(key_image)
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<request_t> request;
+
+ struct response_t
+ {
+ bool frozen;
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(frozen)
+ END_KV_SERIALIZE_MAP()
+ };
+ typedef epee::misc_utils::struct_init<response_t> response;
+ };
+
struct COMMAND_RPC_TRANSFER
{
struct request_t
diff --git a/tests/README.md b/tests/README.md
index c4ad1ce37..908482c99 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -50,7 +50,7 @@ To run the same tests on a release build, replace `debug` with `release`.
# Functional tests
[TODO]
-Functional tests are located under the `tests/functional` directory.
+Functional tests are located under the `tests/functional_tests` directory.
Building all the tests requires installing the following dependencies:
```bash
@@ -70,6 +70,25 @@ velvet lymph giddy number token physics poetry unquoted nibs useful sabotage lim
Open the wallet file with `monero-wallet-rpc` with RPC port 18083. Finally, start tests by invoking ./blockchain.py or ./speed.py
+## Parameters
+
+Configuration of individual tests.
+
+### Mining test
+
+The following environment variables may be set to control the mining test:
+
+- `MINING_NO_MEASUREMENT` - set to anything to use large enough and fixed mining timeouts (use case: very slow PCs and no intention to change the mining code)
+- `MINING_SILENT` - set to anything to disable mining logging
+
+For example, to customize the run of the functional tests, you may run the following commands from the build directory:
+
+```bash
+export MINING_NO_MEASUREMENT=1
+ctest -V -R functional_tests_rpc
+unset MINING_NO_MEASUREMENT
+```
+
# Fuzz tests
Fuzz tests are written using American Fuzzy Lop (AFL), and located under the `tests/fuzz` directory.
diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h
index af12b6006..3f9f01a11 100644
--- a/tests/core_tests/chaingen.h
+++ b/tests/core_tests/chaingen.h
@@ -1080,7 +1080,7 @@ inline bool do_replay_file(const std::string& filename)
}
#define QUOTEME(x) #x
-#define DEFINE_TESTS_ERROR_CONTEXT(text) const char* perr_context = text;
+#define DEFINE_TESTS_ERROR_CONTEXT(text) const char* perr_context = text; (void) perr_context;
#define CHECK_TEST_CONDITION(cond) CHECK_AND_ASSERT_MES(cond, false, "[" << perr_context << "] failed: \"" << QUOTEME(cond) << "\"")
#define CHECK_EQ(v1, v2) CHECK_AND_ASSERT_MES(v1 == v2, false, "[" << perr_context << "] failed: \"" << QUOTEME(v1) << " == " << QUOTEME(v2) << "\", " << v1 << " != " << v2)
#define CHECK_NOT_EQ(v1, v2) CHECK_AND_ASSERT_MES(!(v1 == v2), false, "[" << perr_context << "] failed: \"" << QUOTEME(v1) << " != " << QUOTEME(v2) << "\", " << v1 << " == " << v2)
diff --git a/tests/functional_tests/functional_tests_rpc.py b/tests/functional_tests/functional_tests_rpc.py
index 79e04b8a6..450552cf8 100755
--- a/tests/functional_tests/functional_tests_rpc.py
+++ b/tests/functional_tests/functional_tests_rpc.py
@@ -44,6 +44,7 @@ N_MONERODS = 4
N_WALLETS = 5
WALLET_DIRECTORY = builddir + "/functional-tests-directory"
+FUNCTIONAL_TESTS_DIRECTORY = builddir + "/tests/functional_tests"
DIFFICULTY = 10
monerod_base = [builddir + "/bin/monerod", "--regtest", "--fixed-difficulty", str(DIFFICULTY), "--no-igd", "--p2p-bind-port", "monerod_p2p_port", "--rpc-bind-port", "monerod_rpc_port", "--zmq-rpc-bind-port", "monerod_zmq_port", "--non-interactive", "--disable-dns-checkpoints", "--check-updates", "disabled", "--rpc-ssl", "disabled", "--data-dir", "monerod_data_dir", "--log-level", "1"]
@@ -71,14 +72,14 @@ for i in range(N_MONERODS):
command_lines.append([str(18180+i) if x == "monerod_rpc_port" else str(18280+i) if x == "monerod_p2p_port" else str(18380+i) if x == "monerod_zmq_port" else builddir + "/functional-tests-directory/monerod" + str(i) if x == "monerod_data_dir" else x for x in monerod_base])
if i < len(monerod_extra):
command_lines[-1] += monerod_extra[i]
- outputs.append(open(builddir + '/tests/functional_tests/monerod' + str(i) + '.log', 'a+'))
+ outputs.append(open(FUNCTIONAL_TESTS_DIRECTORY + '/monerod' + str(i) + '.log', 'a+'))
ports.append(18180+i)
for i in range(N_WALLETS):
command_lines.append([str(18090+i) if x == "wallet_port" else x for x in wallet_base])
if i < len(wallet_extra):
command_lines[-1] += wallet_extra[i]
- outputs.append(open(builddir + '/tests/functional_tests/wallet' + str(i) + '.log', 'a+'))
+ outputs.append(open(FUNCTIONAL_TESTS_DIRECTORY + '/wallet' + str(i) + '.log', 'a+'))
ports.append(18090+i)
print('Starting servers...')
@@ -89,9 +90,11 @@ try:
PYTHONPATH += srcdir + '/../../utils/python-rpc'
os.environ['PYTHONPATH'] = PYTHONPATH
os.environ['WALLET_DIRECTORY'] = WALLET_DIRECTORY
+ os.environ['FUNCTIONAL_TESTS_DIRECTORY'] = FUNCTIONAL_TESTS_DIRECTORY
+ os.environ['SOURCE_DIRECTORY'] = srcdir
os.environ['PYTHONIOENCODING'] = 'utf-8'
os.environ['DIFFICULTY'] = str(DIFFICULTY)
- os.environ['MAKE_TEST_SIGNATURE'] = builddir + '/tests/functional_tests/make_test_signature'
+ os.environ['MAKE_TEST_SIGNATURE'] = FUNCTIONAL_TESTS_DIRECTORY + '/make_test_signature'
os.environ['SEEDHASH_EPOCH_BLOCKS'] = "8"
os.environ['SEEDHASH_EPOCH_LAG'] = "4"
diff --git a/tests/functional_tests/mining.py b/tests/functional_tests/mining.py
index cb2fd66e1..7ecbdeed5 100755
--- a/tests/functional_tests/mining.py
+++ b/tests/functional_tests/mining.py
@@ -42,6 +42,10 @@ Test the following RPCs:
- start_mining
- stop_mining
- mining_status
+
+Control the behavior with these environment variables:
+ MINING_NO_MEASUREMENT - set to anything to use large enough and fixed mining timeouts
+ MINING_SILENT - set to anything to disable mining logging
"""
from framework.daemon import Daemon
@@ -77,8 +81,11 @@ class MiningTest():
cores_init = multiprocessing.cpu_count() # RX init uses all cores
cores_mine = 1 # Mining uses a parametric number of cores
- time_pi_single_cpu = self.measure_cpu_power_get_time(cores_mine)
- time_pi_all_cores = self.measure_cpu_power_get_time(cores_init)
+ is_mining_measurent = 'MINING_NO_MEASUREMENT' not in os.environ
+
+ if is_mining_measurent: # A dynamic calculation of the CPU power requested
+ time_pi_single_cpu = self.measure_cpu_power_get_time(cores_mine)
+ time_pi_all_cores = self.measure_cpu_power_get_time(cores_init)
# This is the last measurement, since it takes very little time and can be placed timewise-closer to the mining itself.
available_ram = self.get_available_ram() # So far no ideas how to use this var, other than printing it
@@ -110,38 +117,42 @@ class MiningTest():
target_height = initial_height + 5
height = initial_height
- """
- Randomx init has high variance on CI machines due to noisy neighbors,
- taking up resources in parallel (including by our own jobs).
-
- Mining is organized in the following scheme:
- 1) first loop's pass: RandomX init and mining
- 2) every next pass: only mining
- Pass 1) takes much more time than pass 2)
- Pass 1) uses all cores, pass 2) just one (currently)
- For the above reasons both passes need separate timeouts and adjustments.
- After the first pass, the timeout is being reset to a lower value.
- """
-
- def calc_timeout(seconds_constant, time_pi, cores):
+ if not is_mining_measurent:
+ timeout_init = 600
+ timeout_mine = 300
+ else:
"""
- The time it took to calculate pi under certain conditions
- is proportional to the time it will take to calculate the real job.
+ Randomx init has high variance on CI machines due to noisy neighbors,
+ taking up resources in parallel (including by our own jobs).
- The number of cores used decreases the time almost linearly.
+ Mining is organized in the following scheme:
+ 1) first loop's pass: RandomX init and mining
+ 2) every next pass: only mining
+ Pass 1) takes much more time than pass 2)
+ Pass 1) uses all cores, pass 2) just one (currently)
+ For the above reasons both passes need separate timeouts and adjustments.
+ After the first pass, the timeout is being reset to a lower value.
"""
- timeout = float(seconds_constant) * time_pi / float(cores)
- return timeout
- timeout_base_init = 60 # RX init needs more time
- timeout_base_mine = 20
- timeout_init = calc_timeout(timeout_base_init, time_pi_all_cores, cores_init)
- timeout_mine = calc_timeout(timeout_base_mine, time_pi_single_cpu, cores_mine)
-
- msg = "Timeout for {} adjusted for the currently available CPU power, is {:.1f} s"
- print(msg.format("init, ", timeout_init))
- print(msg.format("mining,", timeout_mine))
+ def calc_timeout(seconds_constant, time_pi, cores):
+ """
+ The time it took to calculate pi under certain conditions
+ is proportional to the time it will take to calculate the real job.
+
+ The number of cores used decreases the time almost linearly.
+ """
+ timeout = float(seconds_constant) * time_pi / float(cores)
+ return timeout
+
+ timeout_base_init = 60 # RX init needs more time
+ timeout_base_mine = 20
+ timeout_init = calc_timeout(timeout_base_init, time_pi_all_cores, cores_init)
+ timeout_mine = calc_timeout(timeout_base_mine, time_pi_single_cpu, cores_mine)
+ msg_timeout_src = "adjusted for the currently available CPU power" if is_mining_measurent else "selected to have the default value"
+ msg = "Timeout for {} {}, is {:.1f} s"
+ self.print_mining_info(msg.format("init, ", msg_timeout_src, timeout_init))
+ self.print_mining_info(msg.format("mining,", msg_timeout_src, timeout_mine))
timeout = timeout_init
rx_inited = False # Gets initialized in the first pass of the below loop
while height < target_height:
@@ -197,17 +208,18 @@ class MiningTest():
res = wallet.stop_mining()
res_status = daemon.mining_status()
assert res_status.active == False
-
+
def measure_cpu_power_get_time(self, cores):
- print("Measuring the currently available CPU power...")
- time_pi = util_resources.get_time_pi_seconds(cores)
- print("Time taken to calculate Pi on {} core(s) was {:.2f} s.".format(cores, time_pi))
+ self.print_mining_info("Measuring the currently available CPU power...")
+ build_dir_funcional_tests = os.environ['FUNCTIONAL_TESTS_DIRECTORY']
+ time_pi = util_resources.get_time_pi_seconds(cores, build_dir_funcional_tests)
+ self.print_mining_info("Time taken to calculate Pi on {} core(s) was {:.2f} s.".format(cores, time_pi))
return time_pi
-
+
def get_available_ram(self):
available_ram = util_resources.available_ram_gb()
threshold_ram = 3
- print("Available RAM =", round(available_ram, 1), "GB")
+ self.print_mining_info("Available RAM = " + str(round(available_ram, 1)) + " GB")
if available_ram < threshold_ram:
print("Warning! Available RAM =", round(available_ram, 1),
"GB is less than the reasonable threshold =", threshold_ram,
@@ -240,8 +252,18 @@ class MiningTest():
res = daemon.get_height()
assert res.height == height + i + 1
assert res.hash == block_hash
-
+
+ def is_mining_silent(self):
+ return 'MINING_SILENT' in os.environ
+
+ def print_mining_info(self, msg):
+ if self.is_mining_silent():
+ return
+ print(msg)
+
def print_time_taken(self, start, msg_context):
+ if self.is_mining_silent():
+ return
seconds_passed = monotonic.monotonic() - start
print("Time taken for", msg_context, "=", round(seconds_passed, 1), "s.")
diff --git a/tests/functional_tests/util_resources.py b/tests/functional_tests/util_resources.py
index e45122e66..0ea96c129 100755
--- a/tests/functional_tests/util_resources.py
+++ b/tests/functional_tests/util_resources.py
@@ -43,8 +43,8 @@ def available_ram_gb():
ram_gb = ram_bytes / kilo**3
return ram_gb
-def get_time_pi_seconds(cores):
- app_path = './cpu_power_test'
+def get_time_pi_seconds(cores, app_dir='.'):
+ app_path = '{}/cpu_power_test'.format(app_dir)
time_calc = subprocess.check_output([app_path, str(cores)])
decoded = time_calc.decode('utf-8')
miliseconds = int(decoded)
diff --git a/tests/gtest/CMakeLists.txt b/tests/gtest/CMakeLists.txt
index 621d0f042..50941b8d8 100644
--- a/tests/gtest/CMakeLists.txt
+++ b/tests/gtest/CMakeLists.txt
@@ -45,7 +45,7 @@ endif()
# ${gtest_BINARY_DIR}.
# Language "C" is required for find_package(Threads).
project(gtest CXX C)
-cmake_minimum_required(VERSION 2.6.2)
+cmake_minimum_required(VERSION 3.5)
if (COMMAND set_up_hermetic_build)
set_up_hermetic_build()
diff --git a/tests/gtest/cmake/internal_utils.cmake b/tests/gtest/cmake/internal_utils.cmake
index ae45d7d7a..b33197989 100644
--- a/tests/gtest/cmake/internal_utils.cmake
+++ b/tests/gtest/cmake/internal_utils.cmake
@@ -96,7 +96,7 @@ macro(config_compiler_and_linker)
set(cxx_no_rtti_flags "-fno-rtti -DGTEST_HAS_RTTI=0")
set(cxx_strict_flags
"-Wextra -Wno-unused-parameter -Wno-missing-field-initializers")
- elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(cxx_base_flags "-Wall -Wshadow -fPIC")
set(cxx_exception_flags "-fexceptions")
set(cxx_no_exception_flags "-fno-exceptions")
diff --git a/tests/unit_tests/epee_boosted_tcp_server.cpp b/tests/unit_tests/epee_boosted_tcp_server.cpp
index 84fc0a29b..d10b2bb33 100644
--- a/tests/unit_tests/epee_boosted_tcp_server.cpp
+++ b/tests/unit_tests/epee_boosted_tcp_server.cpp
@@ -320,7 +320,8 @@ TEST(test_epee_connection, test_lifetime)
connection_ptr conn;
{
lock_guard_t guard(shared_conn->lock);
- conn = std::move(shared_conn->conn.lock());
+ conn = shared_conn->conn.lock();
+ shared_conn->conn.reset();
}
if (conn)
conn->cancel();
diff --git a/tests/unit_tests/json_serialization.cpp b/tests/unit_tests/json_serialization.cpp
index f76199e57..9fa589139 100644
--- a/tests/unit_tests/json_serialization.cpp
+++ b/tests/unit_tests/json_serialization.cpp
@@ -51,7 +51,7 @@ namespace test
if (!cryptonote::find_tx_extra_field_by_type(extra_fields, key_field))
throw std::runtime_error{"invalid transaction"};
- for (auto const& input : boost::adaptors::index(source.vout))
+ for (auto const input : boost::adaptors::index(source.vout))
{
source_amount += input.value().amount;
auto const& key = boost::get<cryptonote::txout_to_key>(input.value().target);
diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt
index 0081746f2..927d1733a 100644
--- a/translations/CMakeLists.txt
+++ b/translations/CMakeLists.txt
@@ -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.8.7)
+cmake_minimum_required(VERSION 3.5)
project(translations)
@@ -73,7 +73,7 @@ string(REPLACE ".ts" ".qm" qm_files "${ts_files}")
add_custom_command(TARGET generate_translations_header
POST_BUILD
- COMMAND ./generate_translations_header ${qm_files}
+ COMMAND $<TARGET_FILE:generate_translations_header> ${qm_files}
WORKING_DIRECTORY "${CMAKE_CURRENT_BIN_DIR}"
COMMENT "Generating embedded translations header")
diff --git a/utils/build_scripts/android32.Dockerfile b/utils/build_scripts/android32.Dockerfile
index a2d0edbb3..c0931ce05 100644
--- a/utils/build_scripts/android32.Dockerfile
+++ b/utils/build_scripts/android32.Dockerfile
@@ -44,7 +44,7 @@ ARG BOOST_VERSION=1_68_0
ARG BOOST_VERSION_DOT=1.68.0
ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7
RUN set -ex \
- && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
+ && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
&& rm -f boost_${BOOST_VERSION}.tar.bz2 \
diff --git a/utils/build_scripts/android64.Dockerfile b/utils/build_scripts/android64.Dockerfile
index eca2d4da1..3a62da464 100644
--- a/utils/build_scripts/android64.Dockerfile
+++ b/utils/build_scripts/android64.Dockerfile
@@ -44,7 +44,7 @@ ARG BOOST_VERSION=1_68_0
ARG BOOST_VERSION_DOT=1.68.0
ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7
RUN set -ex \
- && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
+ && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
&& rm -f boost_${BOOST_VERSION}.tar.bz2 \
diff --git a/utils/gpg_keys/mj-xmr.asc b/utils/gpg_keys/mj-xmr.asc
new file mode 100644
index 000000000..e02d3e511
--- /dev/null
+++ b/utils/gpg_keys/mj-xmr.asc
@@ -0,0 +1,52 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+
+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
+=egkb
+-----END PGP PUBLIC KEY BLOCK-----