diff --git a/.drone.jsonnet b/.drone.jsonnet index a9751eca0..85bc1d986 100644 --- a/.drone.jsonnet +++ b/.drone.jsonnet @@ -1,4 +1,4 @@ -local default_deps_base='libsystemd-dev libboost-filesystem-dev libboost-thread-dev libboost-date-time-dev libgtest-dev ' + +local default_deps_base='libsystemd-dev libboost-thread-dev libgtest-dev ' + 'libboost-serialization-dev libboost-program-options-dev libunbound-dev nettle-dev libevent-dev libminiupnpc-dev ' + 'libunwind8-dev libsodium-dev libssl-dev libreadline-dev libhidapi-dev libusb-1.0-0-dev libprotobuf-dev protobuf-compiler python3 ' + 'pkg-config libsqlite3-dev qttools5-dev libcurl4-openssl-dev'; @@ -6,10 +6,11 @@ local default_deps='g++ ' + default_deps_base; // g++ sometimes needs replacemen local gtest_filter='-AddressFromURL.Failure:DNSResolver.DNSSEC*'; +local submodules_commands = ['git fetch --tags', 'git submodule update --init --recursive --depth=1']; local submodules = { name: 'submodules', image: 'drone/git', - commands: ['git fetch --tags', 'git submodule update --init --recursive --depth=1'] + commands: submodules_commands }; local apt_get_quiet = 'apt-get -o=Dpkg::Use-Pty=0 -q'; @@ -45,7 +46,8 @@ local debian_pipeline(name, image, apt_get_quiet + ' update', apt_get_quiet + ' install -y eatmydata', 'eatmydata ' + apt_get_quiet + ' dist-upgrade -y', - 'eatmydata ' + apt_get_quiet + ' install -y --no-install-recommends cmake git ca-certificates ninja-build ccache ' + deps, + 'eatmydata ' + apt_get_quiet + ' install -y --no-install-recommends cmake git ca-certificates ninja-build ccache ' + + deps + (if test_lokid then ' gdb' else ''), 'mkdir build', 'cd build', 'cmake .. -G Ninja -DCMAKE_CXX_FLAGS=-fdiagnostics-color=always -DCMAKE_BUILD_TYPE='+build_type+' ' + @@ -61,7 +63,7 @@ local debian_pipeline(name, image, ['ninja -j' + jobs + ' -v'] ) + ( if test_lokid then [ - '(sleep 3; echo "status\ndiff\nexit") | TERM=xterm ./bin/lokid --offline --data-dir=startuptest' + '(sleep 3; echo "status\ndiff\nexit") | TERM=xterm ../utils/build_scripts/drone-gdb.sh ./bin/lokid --offline --data-dir=startuptest' ] else [] ) + ( if run_tests then [ @@ -71,7 +73,7 @@ local debian_pipeline(name, image, ) + extra_cmds, } ], -}; +}; // Macos build local mac_builder(name, @@ -89,10 +91,7 @@ local mac_builder(name, name: name, platform: { os: 'darwin', arch: 'amd64' }, steps: [ - { - name: 'submodules', - commands: ['git fetch --tags', 'git submodule update --init --recursive'] - }, + { name: 'submodules', commands: submodules_commands }, { name: 'build', environment: { SSH_KEY: { from_secret: "SSH_KEY" }, GTEST_FILTER: gtest_filter }, @@ -128,20 +127,33 @@ local static_check_and_upload = [ local static_build_deps='autoconf automake make qttools5-dev file libtool gperf pkg-config patch openssh-client'; +local android_build_steps(android_abi, android_platform=21, jobs=6, cmake_extra='') = [ + 'mkdir build-' + android_abi, + 'cd build-' + android_abi, + 'cmake .. -DCMAKE_CXX_FLAGS=-fdiagnostics-color=always -DCMAKE_C_FLAGS=-fdiagnostics-color=always ' + + '-DCMAKE_BUILD_TYPE=Release ' + + '-DCMAKE_TOOLCHAIN_FILE=/usr/lib/android-sdk/ndk-bundle/build/cmake/android.toolchain.cmake ' + + '-DANDROID_PLATFORM=' + android_platform + ' -DANDROID_ABI=' + android_abi + ' ' + + '-DBUILD_STATIC_DEPS=ON -DSTATIC=ON -G Ninja ' + cmake_extra, + 'ninja -j' + jobs + ' -v wallet_merged', + 'cd ..', +]; + + [ // Various debian builds - debian_pipeline("Debian (w/ tests) (amd64)", "debian:testing", lto=true, run_tests=true), - debian_pipeline("Debian Debug (amd64)", "debian:testing", build_type='Debug'), - debian_pipeline("Debian clang-10 (amd64)", "debian:testing", deps='clang-10 '+default_deps_base, - cmake_extra='-DCMAKE_C_COMPILER=clang-10 -DCMAKE_CXX_COMPILER=clang++-10 ', lto=true), + debian_pipeline("Debian (w/ tests) (amd64)", "debian:sid", lto=true, run_tests=true), + debian_pipeline("Debian Debug (amd64)", "debian:sid", build_type='Debug'), + debian_pipeline("Debian clang-11 (amd64)", "debian:sid", deps='clang-11 '+default_deps_base, + cmake_extra='-DCMAKE_C_COMPILER=clang-11 -DCMAKE_CXX_COMPILER=clang++-11 ', lto=true), debian_pipeline("Debian gcc-10 (amd64)", "debian:testing", deps='g++-10 '+default_deps_base, cmake_extra='-DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 -DBUILD_DEBUG_UTILS=ON'), debian_pipeline("Debian buster (i386)", "i386/debian:buster", cmake_extra='-DDOWNLOAD_SODIUM=ON -DARCH_ID=i386'), debian_pipeline("Ubuntu focal (amd64)", "ubuntu:focal"), // ARM builds (ARM64 and armhf) - debian_pipeline("Debian (ARM64)", "debian:testing", arch="arm64", build_tests=false), + debian_pipeline("Debian (ARM64)", "debian:sid", arch="arm64", build_tests=false), debian_pipeline("Debian buster (armhf)", "arm32v7/debian:buster", arch="arm64", build_tests=false, cmake_extra='-DDOWNLOAD_SODIUM=ON -DARCH_ID=armhf'), // Static build (on bionic) which gets uploaded to builds.lokinet.dev: @@ -159,4 +171,57 @@ local static_build_deps='autoconf automake make qttools5-dev file libtool gperf build_tests=false, extra_cmds=static_check_and_upload, lto=true), mac_builder('macOS (Release)', run_tests=true), mac_builder('macOS (Debug)', build_type='Debug', cmake_extra='-DBUILD_DEBUG_UTILS=ON'), + + + // Android builds; we do them all in one image because the android NDK is huge + { name: 'Android wallet_api', kind: 'pipeline', type: 'docker', platform: { arch: 'amd64' }, + steps: [submodules, { + name: 'build', + image: 'debian:sid', + environment: { SSH_KEY: { from_secret: "SSH_KEY" } }, + commands: [ + 'echo "man-db man-db/auto-update boolean false" | debconf-set-selections', + 'echo deb http://deb.debian.org/debian sid contrib >/etc/apt/sources.list.d/sid-contrib.list', + apt_get_quiet + ' update', + apt_get_quiet + ' install -y eatmydata', + 'eatmydata ' + apt_get_quiet + ' dist-upgrade -y', + // Keep cached copies of the android NDK around because it is huge: + 'if [ -d /cache ]; then if ! [ -d /cache/google-android-ndk-installer ]; then mkdir /cache/google-android-ndk-installer; fi; ln -s /cache/google-android-ndk-installer /var/cache/; fi', + 'eatmydata ' + apt_get_quiet + ' install -y --no-install-recommends cmake g++ git ninja-build ccache tar xz-utils google-android-ndk-installer ' + static_build_deps, + ] + + android_build_steps('armeabi-v7a', cmake_extra='-DARCH=armv7-a -DARCH_ID=arm32') + + android_build_steps('arm64-v8a', cmake_extra='-DARCH=armv8-a -DARCH_ID=arm64') + + android_build_steps('x86_64', cmake_extra='-DARCH="x86-64 -msse4.2 -mpopcnt" -DARCH_ID=x86-64') + + android_build_steps('x86', cmake_extra='-DARCH="i686 -mssse3 -mfpmath=sse" -DARCH_ID=i386') + + [ + './utils/build_scripts/drone-android-static-upload.sh armeabi-v7a arm64-v8a x86_64 x86' + ] + } + ] + }, + + // iOS build + { name: 'iOS wallet_api', kind: 'pipeline', type: 'exec', platform: { os: 'darwin', arch: 'amd64' }, + steps: [{ + name: 'build', + environment: { SSH_KEY: { from_secret: "SSH_KEY" } }, + commands: submodules_commands + [ + 'mkdir -p build/{arm64,sim64}', + 'cd build/arm64', + 'cmake ../.. -G Ninja ' + + '-DCMAKE_TOOLCHAIN_FILE=../../cmake/ios.toolchain.cmake -DPLATFORM=OS -DDEPLOYMENT_TARGET=11 -DENABLE_VISIBILITY=ON -DENABLE_BITCODE=OFF ' + + '-DSTATIC=ON -DBUILD_STATIC_DEPS=ON -DUSE_LTO=OFF -DCMAKE_BUILD_TYPE=Release ' + + '-DRANDOMX_ENABLE_JIT=OFF -DCMAKE_CXX_FLAGS=-fcolor-diagnostics', + 'ninja -j6 -v wallet_merged', + 'cd ../sim64', + 'cmake ../.. -G Ninja ' + + '-DCMAKE_TOOLCHAIN_FILE=../../cmake/ios.toolchain.cmake -DPLATFORM=SIMULATOR64 -DDEPLOYMENT_TARGET=11 -DENABLE_VISIBILITY=ON -DENABLE_BITCODE=OFF ' + + '-DSTATIC=ON -DBUILD_STATIC_DEPS=ON -DUSE_LTO=OFF -DCMAKE_BUILD_TYPE=Release ' + + '-DRANDOMX_ENABLE_JIT=OFF -DCMAKE_CXX_FLAGS=-fcolor-diagnostics', + 'ninja -j6 -v wallet_merged', + 'cd ../..', + './utils/build_scripts/drone-ios-static-upload.sh' + ] + }] + }, ] diff --git a/.gitmodules b/.gitmodules index 16e609a9a..5a6653a71 100644 --- a/.gitmodules +++ b/.gitmodules @@ -25,3 +25,6 @@ [submodule "external/cpr"] path = external/cpr url = https://github.com/whoshuu/cpr.git +[submodule "external/ghc-filesystem"] + path = external/ghc-filesystem + url = https://github.com/gulrak/filesystem.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 11cc57ee9..abd8c0f8a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -33,15 +33,6 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON) list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_SOURCE_DIR}/cmake") -include(CheckCCompilerFlag) -include(CheckCXXCompilerFlag) -include(CheckLinkerFlag) -include(CheckLibraryExists) -include(CheckFunctionExists) - -if (IOS) - INCLUDE(CmakeLists_IOS.txt) -endif() find_program(CCACHE_PROGRAM ccache) if(CCACHE_PROGRAM) @@ -60,7 +51,7 @@ message(STATUS "CMake version ${CMAKE_VERSION}") set(CMAKE_OSX_DEPLOYMENT_TARGET 10.12 CACHE STRING "macOS deployment target (Apple clang only)") project(loki - VERSION 8.1.2 + VERSION 8.1.3 LANGUAGES CXX C) set(LOKI_RELEASE_CODENAME "Salty Saga") @@ -85,6 +76,12 @@ set(CMAKE_C_EXTENSIONS OFF) set(CMAKE_POSITION_INDEPENDENT_CODE TRUE) +include(CheckCCompilerFlag) +include(CheckCXXCompilerFlag) +include(CheckLinkerFlag) +include(CheckLibraryExists) +include(CheckFunctionExists) + function (add_c_flag_if_supported flag var) string(REPLACE "-" "_" supported ${flag}_c) check_c_compiler_flag(${flag} ${supported}) @@ -147,7 +144,7 @@ endif() cmake_policy(SET CMP0069 NEW) SET(CMAKE_POLICY_DEFAULT_CMP0069 NEW) -if(CMAKE_BUILD_TYPE STREQUAL Release AND NOT MINGW) +if(CMAKE_BUILD_TYPE STREQUAL Release AND NOT MINGW AND NOT ANDROID) set(USE_LTO_DEFAULT ON) else() set(USE_LTO_DEFAULT OFF) @@ -284,6 +281,7 @@ if(NOT MANUAL_SUBMODULES) check_submodule(external/googletest) endif() check_submodule(external/uWebSockets uSockets) + check_submodule(external/ghc-filesystem) endif() endif() @@ -335,6 +333,8 @@ endif() # elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSDI.*") # set(BSDI TRUE) +include(cmake/check_for_std_filesystem.cmake) + include_directories(external/rapidjson/include src external) if(APPLE) @@ -742,7 +742,7 @@ else() endif(ARM) - if(ANDROID AND NOT BUILD_GUI_DEPS STREQUAL "ON" OR IOS) + if(ANDROID OR IOS) #From Android 5: "only position independent executables (PIE) are supported" message(STATUS "Enabling PIE executable") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIE") @@ -792,10 +792,8 @@ set(Boost_USE_MULTITHREADED TRUE) # Needed for macOS, at least, and won't hurt e if(BUILD_STATIC_DEPS) # StaticBuild.cmake sets Boost targets up for us -elseif (WIN32) - find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_time serialization program_options locale) else() - find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system filesystem thread date_time serialization program_options) + find_package(Boost 1.58 QUIET REQUIRED COMPONENTS system thread serialization program_options) endif() set(CMAKE_FIND_LIBRARY_SUFFIXES ${OLD_LIB_SUFFIXES}) @@ -947,9 +945,6 @@ if(BUILD_DOCUMENTATION) endif() endif() -# when ON - will install libwallet_merged into "lib" -option(BUILD_GUI_DEPS "Build GUI dependencies." OFF) - find_package(PythonInterp) find_program(iwyu_tool_path NAMES iwyu_tool.py iwyu_tool) if (iwyu_tool_path AND PYTHONINTERP_FOUND) diff --git a/CMakeLists_IOS.txt b/CMakeLists_IOS.txt deleted file mode 100644 index d25212dd7..000000000 --- a/CMakeLists_IOS.txt +++ /dev/null @@ -1,165 +0,0 @@ -# Portions Copyright (c) 2017-2018, The Monero Project -# This file is based off of the https://code.google.com/archive/p/ios-cmake/ -# It has been altered for Monero iOS development -# -# -# Options: -# -# IOS_PLATFORM = OS (default) or SIMULATOR or SIMULATOR64 -# This decides if SDKS will be selected from the iPhoneOS.platform or iPhoneSimulator.platform folders -# OS - the default, used to build for iPhone and iPad physical devices, which have an arm arch. -# SIMULATOR - used to build for the Simulator platforms, which have an x86 arch. -# -# CMAKE_IOS_DEVELOPER_ROOT = automatic(default) or /path/to/platform/Developer folder -# By default this location is automatcially chosen based on the IOS_PLATFORM value above. -# If set manually, it will override the default location and force the user of a particular Developer Platform -# -# CMAKE_IOS_SDK_ROOT = automatic(default) or /path/to/platform/Developer/SDKs/SDK folder -# By default this location is automatcially chosen based on the CMAKE_IOS_DEVELOPER_ROOT value. -# In this case it will always be the most up-to-date SDK found in the CMAKE_IOS_DEVELOPER_ROOT path. -# If set manually, this will force the use of a specific SDK version - - -# Standard settings -set (CMAKE_SYSTEM_NAME Darwin) -set (CMAKE_SYSTEM_VERSION 1) -set (UNIX True) -set (APPLE True) -set (IOS True) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D IOS") - -# Required as of cmake 2.8.10 -set (CMAKE_OSX_DEPLOYMENT_TARGET "" CACHE STRING "Force unset of the deployment target for iOS" FORCE) - -# Determine the cmake host system version so we know where to find the iOS SDKs -find_program (CMAKE_UNAME uname /bin /usr/bin /usr/local/bin) -if (CMAKE_UNAME) - exec_program(uname ARGS -r OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION) - string (REGEX REPLACE "^([0-9]+)\\.([0-9]+).*$" "\\1" DARWIN_MAJOR_VERSION "${CMAKE_HOST_SYSTEM_VERSION}") -endif (CMAKE_UNAME) - -# Force the compilers to gcc for iOS -include (CMakeForceCompiler) -# set (MAKE_C_COMPILER "/usr/bin/gcc Apple") -# set (CMAKE_CXX_COMPILER "/usr/bin/g++ Apple") -set(CMAKE_AR ar CACHE FILEPATH "" FORCE) - -# Skip the platform compiler checks for cross compiling -set (CMAKE_CXX_COMPILER_WORKS TRUE) -set (CMAKE_C_COMPILER_WORKS TRUE) - -# All iOS/Darwin specific settings - some may be redundant -set (CMAKE_SHARED_LIBRARY_PREFIX "lib") -set (CMAKE_SHARED_LIBRARY_SUFFIX ".dylib") -set (CMAKE_SHARED_MODULE_PREFIX "lib") -set (CMAKE_SHARED_MODULE_SUFFIX ".so") -set (CMAKE_MODULE_EXISTS 1) -set (CMAKE_DL_LIBS "") - -set (CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") -set (CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") -set (CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}") -set (CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}") - -# Hidden visibilty is required for cxx on iOS -set (CMAKE_C_FLAGS_INIT "-fno-stack-check") -set (CMAKE_CXX_FLAGS_INIT "-fvisibility=hidden -fvisibility-inlines-hidden -fno-stack-check") - -set (CMAKE_C_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}") -set (CMAKE_CXX_LINK_FLAGS "-Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}") - -set (CMAKE_PLATFORM_HAS_INSTALLNAME 1) -set (CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -headerpad_max_install_names") -set (CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -headerpad_max_install_names") -set (CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,") -set (CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,") -set (CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a") - -# Setup iOS platform unless specified manually with IOS_PLATFORM -if (NOT DEFINED IOS_PLATFORM) - set (IOS_PLATFORM "OS") -endif (NOT DEFINED IOS_PLATFORM) -set (IOS_PLATFORM ${IOS_PLATFORM} CACHE STRING "Type of iOS Platform") - -# Setup building for arm64 or not -if (NOT DEFINED BUILD_ARM64) - set (BUILD_ARM64 true) -endif (NOT DEFINED BUILD_ARM64) -set (BUILD_ARM64 ${BUILD_ARM64} CACHE STRING "Build arm64 arch or not") - -# Check the platform selection and setup for developer root -if (${IOS_PLATFORM} STREQUAL "OS") - set (IOS_PLATFORM_LOCATION "iPhoneOS.platform") - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphoneos") -elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR") - set (SIMULATOR true) - set (IOS_PLATFORM_LOCATION "iPhoneSimulator.platform") - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphonesimulator") -elseif (${IOS_PLATFORM} STREQUAL "SIMULATOR64") - set (SIMULATOR true) - set (IOS_PLATFORM_LOCATION "iPhoneSimulator.platform") - - # This causes the installers to properly locate the output libraries - set (CMAKE_XCODE_EFFECTIVE_PLATFORMS "-iphonesimulator") -else (${IOS_PLATFORM} STREQUAL "OS") - message (FATAL_ERROR "Unsupported IOS_PLATFORM value selected. Please choose OS or SIMULATOR") -endif (${IOS_PLATFORM} STREQUAL "OS") - -# Setup iOS developer location unless specified manually with CMAKE_IOS_DEVELOPER_ROOT -# Note Xcode 4.3 changed the installation location, choose the most recent one available -exec_program(/usr/bin/xcode-select ARGS -print-path OUTPUT_VARIABLE CMAKE_XCODE_DEVELOPER_DIR) -set (XCODE_POST_43_ROOT "${CMAKE_XCODE_DEVELOPER_DIR}/Platforms/${IOS_PLATFORM_LOCATION}/Developer") -set (XCODE_PRE_43_ROOT "/Developer/Platforms/${IOS_PLATFORM_LOCATION}/Developer") -if (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT) - if (EXISTS ${XCODE_POST_43_ROOT}) - set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_POST_43_ROOT}) - elseif(EXISTS ${XCODE_PRE_43_ROOT}) - set (CMAKE_IOS_DEVELOPER_ROOT ${XCODE_PRE_43_ROOT}) - endif (EXISTS ${XCODE_POST_43_ROOT}) -endif (NOT DEFINED CMAKE_IOS_DEVELOPER_ROOT) -set (CMAKE_IOS_DEVELOPER_ROOT ${CMAKE_IOS_DEVELOPER_ROOT} CACHE PATH "Location of iOS Platform") - -# Find and use the most recent iOS sdk unless specified manually with CMAKE_IOS_SDK_ROOT -if (NOT DEFINED CMAKE_IOS_SDK_ROOT) - file (GLOB _CMAKE_IOS_SDKS "${CMAKE_IOS_DEVELOPER_ROOT}/SDKs/*") - if (_CMAKE_IOS_SDKS) - list (SORT _CMAKE_IOS_SDKS) - list (REVERSE _CMAKE_IOS_SDKS) - list (GET _CMAKE_IOS_SDKS 0 CMAKE_IOS_SDK_ROOT) - else (_CMAKE_IOS_SDKS) - message (FATAL_ERROR "No iOS SDK's found in default search path ${CMAKE_IOS_DEVELOPER_ROOT}. Manually set CMAKE_IOS_SDK_ROOT or install the iOS SDK.") - endif (_CMAKE_IOS_SDKS) - message (STATUS "Toolchain using default iOS SDK: ${CMAKE_IOS_SDK_ROOT}") -endif (NOT DEFINED CMAKE_IOS_SDK_ROOT) -set (CMAKE_IOS_SDK_ROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Location of the selected iOS SDK") - -# Set the sysroot default to the most recent SDK -set (CMAKE_OSX_SYSROOT ${CMAKE_IOS_SDK_ROOT} CACHE PATH "Sysroot used for iOS support") - -# set the architecture for iOS -if (NOT DEFINED ARCH) - set (ARCH armv7) -endif() -set (IOS_ARCH ${ARCH}) - -set (CMAKE_OSX_ARCHITECTURES ${IOS_ARCH} CACHE string "Build architecture for iOS") - message(STATUS "ios arch: ${IOS_ARCH}") - -# Set the find root to the iOS developer roots and to user defined paths -set (CMAKE_FIND_ROOT_PATH ${CMAKE_IOS_DEVELOPER_ROOT} ${CMAKE_IOS_SDK_ROOT} ${CMAKE_PREFIX_PATH} CACHE string "iOS find search path root") - -# default to searching for frameworks first -set (CMAKE_FIND_FRAMEWORK FIRST) - -# set up the default search directories for frameworks -set (CMAKE_SYSTEM_FRAMEWORK_PATH - ${CMAKE_IOS_SDK_ROOT}/System/Library/Frameworks - ${CMAKE_IOS_SDK_ROOT}/System/Library/PrivateFrameworks - ${CMAKE_IOS_SDK_ROOT}/Developer/Library/Frameworks -) - -message(STATUS "IOS CMAKE conf finished") \ No newline at end of file diff --git a/README.md b/README.md index 69e33059b..67f1da7bd 100644 --- a/README.md +++ b/README.md @@ -78,8 +78,7 @@ Install all dependencies at once on Debian/Ubuntu: ``` sudo apt update && \ -sudo apt install g++ cmake pkg-config libboost-filesystem-dev libboost-thread-dev libboost-date-time-dev \ - libboost-serialization-dev libboost-program-options-dev \ +sudo apt install g++ cmake pkg-config libboost-thread-dev libboost-serialization-dev libboost-program-options-dev \ libssl-dev libzmq3-dev libsqlite3-dev libunbound-dev libsodium-dev libunwind8-dev liblzma-dev libreadline-dev \ libldns-dev libexpat1-dev doxygen graphviz libsqlite3-dev libcurl4-openssl-dev ``` diff --git a/cmake/CheckTrezor.cmake b/cmake/CheckTrezor.cmake index 126fe341b..2633326f4 100644 --- a/cmake/CheckTrezor.cmake +++ b/cmake/CheckTrezor.cmake @@ -146,7 +146,7 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON AND Protobuf_COMPILE_T message(STATUS "Trezor compatible LibUSB found") endif() - if (BUILD_GUI_DEPS) + if (ANDROID) if (Protobuf_LIBRARY) list(APPEND TREZOR_DEP_LIBS ${Protobuf_LIBRARY}) diff --git a/cmake/StaticBuild.cmake b/cmake/StaticBuild.cmake index a7c19e524..d4b9018e1 100644 --- a/cmake/StaticBuild.cmake +++ b/cmake/StaticBuild.cmake @@ -5,24 +5,24 @@ set(LOCAL_MIRROR "" CACHE STRING "local mirror path/URL for lib downloads") -set(OPENSSL_VERSION 1.1.1g CACHE STRING "openssl version") +set(OPENSSL_VERSION 1.1.1h CACHE STRING "openssl version") set(OPENSSL_MIRROR ${LOCAL_MIRROR} https://www.openssl.org/source CACHE STRING "openssl download mirror(s)") set(OPENSSL_SOURCE openssl-${OPENSSL_VERSION}.tar.gz) -set(OPENSSL_HASH SHA256=ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46 +set(OPENSSL_HASH SHA256=5c9ca8774bd7b03e5784f26ae9e9e6d749c9da2438545077e6b3d755a06595d9 CACHE STRING "openssl source hash") -set(EXPAT_VERSION 2.2.9 CACHE STRING "expat version") +set(EXPAT_VERSION 2.2.10 CACHE STRING "expat version") string(REPLACE "." "_" EXPAT_TAG "R_${EXPAT_VERSION}") set(EXPAT_MIRROR ${LOCAL_MIRROR} https://github.com/libexpat/libexpat/releases/download/${EXPAT_TAG} CACHE STRING "expat download mirror(s)") set(EXPAT_SOURCE expat-${EXPAT_VERSION}.tar.xz) -set(EXPAT_HASH SHA512=e082874efcc4b00709e2c0192c88fb15dfc4f33fc3a2b09e619b010ea93baaf7e7572683f738463db0ce2350cab3de48a0c38af6b74d1c4f5a9e311f499edab0 +set(EXPAT_HASH SHA512=a8e0c8a9cf7e6fbacdc6e709f3c99c533ab550fba52557d24259bb8b360f9697624c7500c0e9886fa57ee2b529aadd0d1835d66fe8112e15c20df75cd3eb090f CACHE STRING "expat source hash") -set(UNBOUND_VERSION 1.11.0 CACHE STRING "unbound version") +set(UNBOUND_VERSION 1.12.0 CACHE STRING "unbound version") set(UNBOUND_MIRROR ${LOCAL_MIRROR} https://nlnetlabs.nl/downloads/unbound CACHE STRING "unbound download mirror(s)") set(UNBOUND_SOURCE unbound-${UNBOUND_VERSION}.tar.gz) -set(UNBOUND_HASH SHA256=9f2f0798f76eb8f30feaeda7e442ceed479bc54db0e3ac19c052d68685e51ef7 +set(UNBOUND_HASH SHA256=5b9253a97812f24419bf2e6b3ad28c69287261cf8c8fa79e3e9f6d3bf7ef5835 CACHE STRING "unbound source hash") set(BOOST_VERSION 1.74.0 CACHE STRING "boost version") @@ -125,6 +125,29 @@ file(MAKE_DIRECTORY ${DEPS_DESTDIR}/include) set(deps_cc "${CMAKE_C_COMPILER}") set(deps_cxx "${CMAKE_CXX_COMPILER}") +if (ANDROID) + if(NOT ANDROID_TOOLCHAIN_NAME) + message(FATAL_ERROR "ANDROID_TOOLCHAIN_NAME not set; did you run with the proper android toolchain options?") + endif() + if(CMAKE_ANDROID_ARCH_ABI MATCHES x86_64) + set(android_clang x86_64-linux-android${ANDROID_PLATFORM_LEVEL}-clang) + set(openssl_machine x86_64) + elseif(CMAKE_ANDROID_ARCH_ABI MATCHES x86) + set(android_clang i686-linux-android${ANDROID_PLATFORM_LEVEL}-clang) + set(openssl_machine i686) + elseif(CMAKE_ANDROID_ARCH_ABI MATCHES armeabi-v7a) + set(android_clang armv7a-linux-androideabi${ANDROID_PLATFORM_LEVEL}-clang) + set(openssl_machine armv7) + elseif(CMAKE_ANDROID_ARCH_ABI MATCHES arm64-v8a) + set(android_clang aarch64-linux-android${ANDROID_PLATFORM_LEVEL}-clang) + set(openssl_machine aarch64) + else() + message(FATAL_ERROR "Don't know how to build for android arch abi ${CMAKE_ANDROID_ARCH_ABI}") + endif() + set(deps_cc "${ANDROID_TOOLCHAIN_ROOT}/bin/${android_clang}") + set(deps_cxx "${deps_cc}++") +endif() + if(CMAKE_C_COMPILER_LAUNCHER) set(deps_cc "${CMAKE_C_COMPILER_LAUNCHER} ${deps_cc}") endif() @@ -157,20 +180,38 @@ else() endif() set(cross_host "") -set(cross_rc "") -if(CMAKE_CROSSCOMPILING) - set(cross_host "--host=${ARCH_TRIPLET}") - if (ARCH_TRIPLET MATCHES mingw AND CMAKE_RC_COMPILER) - set(cross_rc "WINDRES=${CMAKE_RC_COMPILER}") +set(cross_extra "") +if (ANDROID) + set(cross_host "--host=${CMAKE_LIBRARY_ARCHITECTURE}") + set(cross_extra "LD=${ANDROID_TOOLCHAIN_ROOT}/bin/${CMAKE_LIBRARY_ARCHITECTURE}-ld" "RANLIB=${CMAKE_RANLIB}" "AR=${CMAKE_AR}") +elseif(CMAKE_CROSSCOMPILING) + if(APPLE) + set(cross_host "--host=${APPLE_TARGET_TRIPLE}") + else() + set(cross_host "--host=${ARCH_TRIPLET}") + if (ARCH_TRIPLET MATCHES mingw AND CMAKE_RC_COMPILER) + set(cross_extra "WINDRES=${CMAKE_RC_COMPILER}") + endif() endif() endif() + + set(deps_CFLAGS "-O2 ${flto}") set(deps_CXXFLAGS "-O2 ${flto}") +set(deps_noarch_CFLAGS "${deps_CFLAGS}") +set(deps_noarch_CXXFLAGS "${deps_CXXFLAGS}") if(APPLE) - set(deps_CFLAGS "${deps_CFLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") - set(deps_CXXFLAGS "${deps_CXXFLAGS} -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + foreach(lang C CXX) + string(APPEND deps_${lang}FLAGS " ${CMAKE_${lang}_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT} ${CMAKE_${lang}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}") + + set(deps_noarch_${lang}FLAGS "${deps_${lang}FLAGS}") + + foreach(arch ${CMAKE_OSX_ARCHITECTURES}) + string(APPEND deps_${lang}FLAGS " -arch ${arch}") + endforeach() + endforeach() endif() # Builds a target; takes the target name (e.g. "readline") and builds it in an external project with @@ -180,13 +221,14 @@ endif() set(build_def_DEPENDS "") set(build_def_PATCH_COMMAND "") set(build_def_CONFIGURE_COMMAND ./configure ${cross_host} --disable-shared --prefix=${DEPS_DESTDIR} --with-pic - "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" ${cross_rc}) + "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" ${cross_extra}) set(build_def_BUILD_COMMAND make) set(build_def_INSTALL_COMMAND make install) set(build_def_BUILD_BYPRODUCTS ${DEPS_DESTDIR}/lib/lib___TARGET___.a ${DEPS_DESTDIR}/include/___TARGET___.h) +set(build_dep_TARGET_SUFFIX "") function(build_external target) - set(options DEPENDS PATCH_COMMAND CONFIGURE_COMMAND BUILD_COMMAND INSTALL_COMMAND BUILD_BYPRODUCTS) + set(options TARGET_SUFFIX DEPENDS PATCH_COMMAND CONFIGURE_COMMAND BUILD_COMMAND INSTALL_COMMAND BUILD_BYPRODUCTS) cmake_parse_arguments(PARSE_ARGV 1 arg "" "" "${options}") foreach(o ${options}) if(NOT DEFINED arg_${o}) @@ -197,7 +239,7 @@ function(build_external target) string(TOUPPER "${target}" prefix) expand_urls(urls ${${prefix}_SOURCE} ${${prefix}_MIRROR}) - ExternalProject_Add("${target}_external" + ExternalProject_Add("${target}${arg_TARGET_SUFFIX}_external" DEPENDS ${arg_DEPENDS} BUILD_IN_SOURCE ON PREFIX ${DEPS_SOURCEDIR} @@ -215,7 +257,7 @@ endfunction() build_external(zlib - CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" ./configure --prefix=${DEPS_DESTDIR} --static + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS} -fPIC" ${cross_extra} ./configure --prefix=${DEPS_DESTDIR} --static BUILD_BYPRODUCTS ${DEPS_DESTDIR}/lib/libz.a ${DEPS_DESTDIR}/include/zlib.h @@ -224,17 +266,31 @@ add_static_target(zlib zlib_external libz.a) +set(openssl_configure ./config) set(openssl_system_env "") +set(openssl_cc "${deps_cc}") if(CMAKE_CROSSCOMPILING) if(ARCH_TRIPLET STREQUAL x86_64-w64-mingw32) set(openssl_system_env SYSTEM=MINGW64 RC=${CMAKE_RC_COMPILER}) elseif(ARCH_TRIPLET STREQUAL i686-w64-mingw32) set(openssl_system_env SYSTEM=MINGW64 RC=${CMAKE_RC_COMPILER}) + elseif(ANDROID) + set(openssl_system_env SYSTEM=Linux MACHINE=${openssl_machine} ${cross_extra}) + set(openssl_extra_opts no-asm) + elseif(IOS) + get_filename_component(apple_toolchain "${CMAKE_C_COMPILER}" DIRECTORY) + get_filename_component(apple_sdk "${CMAKE_OSX_SYSROOT}" NAME) + if(NOT ${apple_toolchain} MATCHES Xcode OR NOT ${apple_sdk} MATCHES "iPhone(OS|Simulator)") + message(FATAL_ERROR "didn't find your toolchain and sdk correctly from ${CMAKE_C_COMPILER}/${CMAKE_OSX_SYSROOT}: found toolchain=${apple_toolchain}, sdk=${apple_sdk}") + endif() + set(openssl_system_env CROSS_COMPILE=${apple_toolchain}/ CROSS_TOP=${CMAKE_DEVELOPER_ROOT} CROSS_SDK=${apple_sdk}) + set(openssl_configure ./Configure iphoneos-cross) + set(openssl_cc "clang") endif() endif() build_external(openssl - CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env CC=${deps_cc} ${openssl_system_env} ./config - --prefix=${DEPS_DESTDIR} no-shared no-capieng no-dso no-dtls1 no-ec_nistp_64_gcc_128 no-gost + CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env CC=${openssl_cc} ${openssl_system_env} ${openssl_configure} + --prefix=${DEPS_DESTDIR} ${openssl_extra_opts} no-shared no-capieng no-dso no-dtls1 no-ec_nistp_64_gcc_128 no-gost no-heartbeats no-md2 no-rc5 no-rdrand no-rfc3779 no-sctp no-ssl-trace no-ssl2 no-ssl3 no-static-engine no-tests no-weak-ssl-ciphers no-zlib-dynamic "CFLAGS=${deps_CFLAGS}" INSTALL_COMMAND make install_sw @@ -257,13 +313,19 @@ build_external(expat add_static_target(expat expat_external libexpat.a) +set(unbound_extra) +if(APPLE AND IOS) + # I have no idea why this is necessary: without this it runs `clang -E` which should work, but + # doesn't because... hurray ios is wonderful? + set(unbound_extra CPP=cpp) +endif() build_external(unbound DEPENDS openssl_external expat_external - CONFIGURE_COMMAND ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --disable-shared - --enable-static --with-libunbound-only --with-pic + CONFIGURE_COMMAND ./configure ${cross_host} ${cross_extra} --prefix=${DEPS_DESTDIR} --disable-shared + --enable-static --with-libunbound-only --with-pic --disable-gost --$,enable,disable>-flto --with-ssl=${DEPS_DESTDIR} --with-libexpat=${DEPS_DESTDIR} - "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" + "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" ${unbound_extra} ) add_static_target(libunbound unbound_external libunbound.a) if(WIN32) @@ -289,6 +351,8 @@ if(CMAKE_CROSSCOMPILING) else() list(APPEND boost_extra "address-model=32") endif() + elseif(ANDROID) + set(boost_bootstrap_cxx "CXX=c++") endif() endif() if(CMAKE_CXX_COMPILER_ID STREQUAL GNU) @@ -298,15 +362,33 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "^(Apple)?Clang$") else() message(FATAL_ERROR "don't know how to build boost with ${CMAKE_CXX_COMPILER_ID}") endif() -file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/user-config.bjam "using ${boost_toolset} : : ${deps_cxx} ;") + +if(IOS) + set(boost_arch_flags) + foreach(arch ${CMAKE_OSX_ARCHITECTURES}) + string(APPEND boost_arch_flags " -arch ${arch}") + endforeach() + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/user-config.bjam "using darwin : : ${deps_cxx} : + arm + iphone + \"-fPIC ${boost_arch_flags} ${CMAKE_CXX_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET} -isysroot ${CMAKE_OSX_SYSROOT}\" + multi + ;") +else() + file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/user-config.bjam "using ${boost_toolset} : : ${deps_cxx} ;") +endif() set(boost_patch_commands "") -if(APPLE AND BOOST_VERSION VERSION_LESS 1.74.0) +if(IOS) + set(boost_patch_commands PATCH_COMMAND patch -p1 -i ${PROJECT_SOURCE_DIR}/utils/build_scripts/boost-darwin-libtool-path.patch) +elseif(APPLE AND BOOST_VERSION VERSION_LESS 1.74.0) set(boost_patch_commands PATCH_COMMAND patch -p1 -d tools/build -i ${PROJECT_SOURCE_DIR}/utils/build_scripts/boostorg-build-pr560-macos-build-fix.patch) endif() set(boost_buildflags "cxxflags=-fPIC") -if(APPLE) +if(IOS) + set(boost_buildflags) +elseif(APPLE) set(boost_buildflags "cxxflags=-fPIC -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}" "cflags=-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") endif() @@ -316,7 +398,7 @@ build_external(boost CONFIGURE_COMMAND ${CMAKE_COMMAND} -E env ${boost_bootstrap_cxx} ./bootstrap.sh --without-icu --prefix=${DEPS_DESTDIR} --with-toolset=${boost_toolset} - --with-libraries=filesystem,program_options,system,thread,date_time,serialization,locale,atomic + --with-libraries=program_options,system,thread,serialization BUILD_COMMAND true INSTALL_COMMAND ./b2 -d0 variant=release link=static runtime-link=static optimization=speed ${boost_extra} @@ -324,10 +406,6 @@ build_external(boost --disable-icu --user-config=${CMAKE_CURRENT_BINARY_DIR}/user-config.bjam install BUILD_BYPRODUCTS - ${DEPS_DESTDIR}/lib/libboost_atomic.a - ${DEPS_DESTDIR}/lib/libboost_date_time.a - ${DEPS_DESTDIR}/lib/libboost_filesystem.a - ${DEPS_DESTDIR}/lib/libboost_locale.a ${DEPS_DESTDIR}/lib/libboost_program_options.a ${DEPS_DESTDIR}/lib/libboost_serialization.a ${DEPS_DESTDIR}/lib/libboost_system.a @@ -338,22 +416,23 @@ add_library(boost_core INTERFACE) add_dependencies(boost_core INTERFACE boost_external) target_include_directories(boost_core SYSTEM INTERFACE ${DEPS_DESTDIR}/include) add_library(Boost::boost ALIAS boost_core) -foreach(boostlib atomic date_time filesystem locale program_options serialization system thread) +foreach(boostlib program_options serialization system thread) add_static_target(Boost::${boostlib} boost_external libboost_${boostlib}.a) target_link_libraries(Boost::${boostlib} INTERFACE boost_core) endforeach() -target_link_libraries(Boost::locale INTERFACE Boost::thread) set(Boost_FOUND ON) set(Boost_VERSION ${BOOST_VERSION}) -build_external(sqlite3) +build_external(sqlite3 + BUILD_COMMAND true + INSTALL_COMMAND make install-includeHEADERS install-libLTLIBRARIES) add_static_target(sqlite3 sqlite3_external libsqlite3.a) -if (NOT WIN32) +if (NOT (WIN32 OR ANDROID OR IOS)) build_external(ncurses CONFIGURE_COMMAND ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --without-debug --without-ada --without-cxx-binding --without-cxx --without-ticlib --without-tic --without-progs @@ -394,7 +473,7 @@ endif() -if(APPLE OR WIN32) +if(APPLE OR WIN32 OR ANDROID OR IOS) add_library(libudev INTERFACE) set(maybe_eudev "") else() @@ -411,53 +490,65 @@ endif() -build_external(libusb - CONFIGURE_COMMAND autoreconf -ivf && ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --disable-shared --disable-udev --with-pic - "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" - BUILD_BYPRODUCTS - ${DEPS_DESTDIR}/lib/libusb-1.0.a - ${DEPS_DESTDIR}/include/libusb-1.0 - ${DEPS_DESTDIR}/include/libusb-1.0/libusb.h -) -add_static_target(libusb_vendor libusb_external libusb-1.0.a) -set_target_properties(libusb_vendor PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${DEPS_DESTDIR}/include/libusb-1.0) +if(NOT (ANDROID OR IOS)) + build_external(libusb + CONFIGURE_COMMAND autoreconf -ivf && ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --disable-shared --disable-udev --with-pic + "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" + BUILD_BYPRODUCTS + ${DEPS_DESTDIR}/lib/libusb-1.0.a + ${DEPS_DESTDIR}/include/libusb-1.0 + ${DEPS_DESTDIR}/include/libusb-1.0/libusb.h + ) + add_static_target(libusb_vendor libusb_external libusb-1.0.a) + set_target_properties(libusb_vendor PROPERTIES INTERFACE_SYSTEM_INCLUDE_DIRECTORIES ${DEPS_DESTDIR}/include/libusb-1.0) +endif() -if(CMAKE_SYSTEM_NAME STREQUAL "Linux") - set(hidapi_libusb_lib libhidapi-libusb.a) - set(hidapi_lib_byproducts ${DEPS_DESTDIR}/lib/libhidapi-libusb.a ${DEPS_DESTDIR}/lib/libhidapi-hidraw.a) +if(ANDROID OR IOS) + set(HIDAPI_FOUND FALSE) else() - set(hidapi_libusb_lib libhidapi.a) - set(hidapi_lib_byproducts ${DEPS_DESTDIR}/lib/libhidapi.a) + if(CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(hidapi_libusb_lib libhidapi-libusb.a) + set(hidapi_lib_byproducts ${DEPS_DESTDIR}/lib/libhidapi-libusb.a ${DEPS_DESTDIR}/lib/libhidapi-hidraw.a) + else() + set(hidapi_libusb_lib libhidapi.a) + set(hidapi_lib_byproducts ${DEPS_DESTDIR}/lib/libhidapi.a) + endif() + build_external(hidapi + DEPENDS ${maybe_eudev} libusb_external + CONFIGURE_COMMAND autoreconf -ivf && ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --disable-shared --enable-static --with-pic + "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" + ${cross_extra} + "libudev_CFLAGS=-I${DEPS_DESTDIR}/include" "libudev_LIBS=-L${DEPS_DESTDIR}/lib -ludev" + "libusb_CFLAGS=-I${DEPS_DESTDIR}/include/libusb-1.0" "libusb_LIBS=-L${DEPS_DESTDIR}/lib -lusb-1.0" + BUILD_BYPRODUCTS + ${hidapi_lib_byproducts} + ${DEPS_DESTDIR}/include/hidapi + ${DEPS_DESTDIR}/include/hidapi/hidapi.h + ) + set(HIDAPI_FOUND TRUE) + add_static_target(hidapi_libusb hidapi_external ${hidapi_libusb_lib}) + set(hidapi_links "libusb_vendor;libudev") + if(WIN32) + list(APPEND hidapi_links setupapi) + endif() + set_target_properties(hidapi_libusb PROPERTIES + INTERFACE_LINK_LIBRARIES "${hidapi_links}" + INTERFACE_COMPILE_DEFINITIONS HAVE_HIDAPI) endif() -build_external(hidapi - DEPENDS ${maybe_eudev} libusb_external - CONFIGURE_COMMAND autoreconf -ivf && ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --disable-shared --enable-static --with-pic - "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" - "libudev_CFLAGS=-I${DEPS_DESTDIR}/include" "libudev_LIBS=-L${DEPS_DESTDIR}/lib -ludev" - "libusb_CFLAGS=-I${DEPS_DESTDIR}/include/libusb-1.0" "libusb_LIBS=-L${DEPS_DESTDIR}/lib -lusb-1.0" - BUILD_BYPRODUCTS - ${hidapi_lib_byproducts} - ${DEPS_DESTDIR}/include/hidapi - ${DEPS_DESTDIR}/include/hidapi/hidapi.h -) -set(HIDAPI_FOUND TRUE) -add_static_target(hidapi_libusb hidapi_external ${hidapi_libusb_lib}) -set(hidapi_links "libusb_vendor;libudev") -if(WIN32) - list(APPEND hidapi_links setupapi) + + + +set(protobuf_extra "") +if(ANDROID) + set(protobuf_extra "LDFLAGS=-llog") endif() -set_target_properties(hidapi_libusb PROPERTIES - INTERFACE_LINK_LIBRARIES "${hidapi_links}" - INTERFACE_COMPILE_DEFINITIONS HAVE_HIDAPI) - - - build_external(protobuf CONFIGURE_COMMAND ./configure ${cross_host} --disable-shared --prefix=${DEPS_DESTDIR} --with-pic "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=${deps_CFLAGS}" "CXXFLAGS=${deps_CXXFLAGS}" + ${cross_extra} ${protobuf_extra} "CPP=${deps_cc} -E" "CXXCPP=${deps_cxx} -E" "CC_FOR_BUILD=${deps_cc}" "CXX_FOR_BUILD=${deps_cxx}" # Thanks Google for making people hunt for undocumented magic variables BUILD_BYPRODUCTS @@ -478,13 +569,21 @@ add_static_target(sodium sodium_external libsodium.a) if(ZMQ_VERSION VERSION_LESS 4.3.4 AND CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw) set(zmq_patch PATCH_COMMAND patch -p1 -i ${PROJECT_SOURCE_DIR}/utils/build_scripts/libzmq-mingw-closesocket.patch) endif() + +set(zmq_cross_host "${cross_host}") +if(IOS AND cross_host MATCHES "-ios$") + # zmq doesn't like "-ios" for the host, so replace it with -darwin + string(REGEX REPLACE "-ios$" "-darwin" zmq_cross_host ${cross_host}) +endif() + build_external(zmq DEPENDS sodium_external ${zmq_patch} - CONFIGURE_COMMAND ./configure ${cross_host} --prefix=${DEPS_DESTDIR} --enable-static --disable-shared + CONFIGURE_COMMAND ./configure ${zmq_cross_host} --prefix=${DEPS_DESTDIR} --enable-static --disable-shared --disable-curve-keygen --enable-curve --disable-drafts --disable-libunwind --with-libsodium --without-pgm --without-norm --without-vmci --without-docs --with-pic --disable-Werror "CC=${deps_cc}" "CXX=${deps_cxx}" "CFLAGS=-fstack-protector ${deps_CFLAGS}" "CXXFLAGS=-fstack-protector ${deps_CXXFLAGS}" + ${cross_extra} "sodium_CFLAGS=-I${DEPS_DESTDIR}/include" "sodium_LIBS=-L${DEPS_DESTDIR}/lib -lsodium" ) add_static_target(libzmq zmq_external libzmq.a) @@ -500,33 +599,83 @@ set_target_properties(libzmq PROPERTIES -set(curl_LIBS "") +set(curl_extra) if(WIN32) set(curl_ssl_opts --without-ssl --with-schannel) elseif(APPLE) set(curl_ssl_opts --without-ssl --with-secure-transport) + if(IOS) + # This CPP crap shouldn't be necessary but is because Apple's toolchain is trash + set(curl_extra "LDFLAGS=-L${DEPS_DESTDIR}/lib -isysroot ${CMAKE_OSX_SYSROOT}" CPP=cpp) + endif() else() set(curl_ssl_opts --with-ssl=${DEPS_DESTDIR}) - set(curl_LIBS "LIBS=-pthread") + set(curl_extra "LIBS=-pthread") +endif() + +set(curl_arches default) +set(curl_lib_outputs) +if(IOS) + # On iOS things get a little messy: curl won't build a multi-arch library (with `clang -arch arch1 + # -arch arch2`) so we have to build them separately then glue them together if we're building + # multiple. + set(curl_arches ${CMAKE_OSX_ARCHITECTURES}) + list(GET curl_arches 0 curl_arch0) + list(LENGTH CMAKE_OSX_ARCHITECTURES num_arches) +endif() + +foreach(curl_arch ${curl_arches}) + set(curl_target_suffix "") + set(curl_prefix "${DEPS_DESTDIR}") + if(curl_arch STREQUAL "default") + set(curl_cflags_extra "") + elseif(IOS) + set(cflags_extra " -arch ${curl_arch}") + if(num_arches GREATER 1) + set(curl_target_suffix "-${curl_arch}") + set(curl_prefix "${DEPS_DESTDIR}/tmp/${curl_arch}") + endif() + else() + message(FATAL_ERROR "unexpected curl_arch=${curl_arch}") + endif() + + build_external(curl + TARGET_SUFFIX ${curl_target_suffix} + DEPENDS openssl_external zlib_external + CONFIGURE_COMMAND ./configure ${cross_host} ${cross_extra} --prefix=${curl_prefix} --disable-shared + --enable-static --disable-ares --disable-ftp --disable-ldap --disable-laps --disable-rtsp + --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb + --disable-smtp --disable-gopher --disable-manual --disable-libcurl-option --enable-http + --enable-ipv6 --disable-threaded-resolver --disable-pthreads --disable-verbose --disable-sspi + --enable-crypto-auth --disable-ntlm-wb --disable-tls-srp --disable-unix-sockets --disable-cookies + --enable-http-auth --enable-doh --disable-mime --enable-dateparse --disable-netrc --without-libidn2 + --disable-progress-meter --without-brotli --with-zlib=${DEPS_DESTDIR} ${curl_ssl_opts} + --without-libmetalink --without-librtmp --disable-versioned-symbols --enable-hidden-symbols + --without-zsh-functions-dir --without-fish-functions-dir + "CC=${deps_cc}" "CFLAGS=${deps_noarch_CFLAGS}${cflags_extra}" ${curl_extra} + BUILD_COMMAND true + INSTALL_COMMAND make -C lib install && make -C include install + BUILD_BYPRODUCTS + ${curl_prefix}/lib/libcurl.a + ${curl_prefix}/include/curl/curl.h + ) + list(APPEND curl_lib_targets curl${curl_target_suffix}_external) + list(APPEND curl_lib_outputs ${curl_prefix}/lib/libcurl.a) +endforeach() + +message(STATUS "TARGETS: ${curl_lib_targets}") + +if(IOS AND num_arches GREATER 1) + # We are building multiple architectures for different iOS devices, so we need to glue the + # separate libraries into one. (Normally multiple -arch values passed to clang does this for us, + # but curl refuses to build that way). + add_custom_target(curl_external + COMMAND lipo ${curl_lib_outputs} -create -output ${DEPS_DESTDIR}/libcurl.a + COMMAND ${CMAKE_COMMAND} -E copy_directory ${DEPS_DESTDIR}/tmp/${curl_arch0}/include/curl ${DEPS_DESTDIR}/include/curl + BYPRODUCTS ${DEPS_DESTDIR}/lib/libcurl.a ${DEPS_DESTDIR}/include/curl/curl.h + DEPENDS ${curl_lib_targets}) endif() -build_external(curl - DEPENDS openssl_external zlib_external - CONFIGURE_COMMAND ./configure ${cross_host} ${cross_rc} --prefix=${DEPS_DESTDIR} --disable-shared - --enable-static --disable-ares --disable-ftp --disable-ldap --disable-laps --disable-rtsp - --disable-dict --disable-telnet --disable-tftp --disable-pop3 --disable-imap --disable-smb - --disable-smtp --disable-gopher --disable-manual --disable-libcurl-option --enable-http - --enable-ipv6 --disable-threaded-resolver --disable-pthreads --disable-verbose --disable-sspi - --enable-crypto-auth --disable-ntlm-wb --disable-tls-srp --disable-unix-sockets --disable-cookies - --enable-http-auth --enable-doh --disable-mime --enable-dateparse --disable-netrc --without-libidn2 - --disable-progress-meter --without-brotli --with-zlib=${DEPS_DESTDIR} ${curl_ssl_opts} - --without-libmetalink --without-librtmp --disable-versioned-symbols --enable-hidden-symbols - --without-zsh-functions-dir --without-fish-functions-dir - "CC=${deps_cc}" "CFLAGS=${deps_CFLAGS}" ${curl_LIBS} - BUILD_BYPRODUCTS - ${DEPS_DESTDIR}/lib/libcurl.a - ${DEPS_DESTDIR}/include/curl/curl.h -) add_static_target(CURL::libcurl curl_external libcurl.a) set(libcurl_link_libs zlib) if(CMAKE_CROSSCOMPILING AND ARCH_TRIPLET MATCHES mingw) diff --git a/cmake/check_for_std_filesystem.cmake b/cmake/check_for_std_filesystem.cmake new file mode 100644 index 000000000..b9546906e --- /dev/null +++ b/cmake/check_for_std_filesystem.cmake @@ -0,0 +1,52 @@ +# Figure out if we need -lstdc++fs or -lc++fs and add it to the `filesystem` interface, if needed +# (otherwise just leave it an empty interface library; linking to it will do nothing). The former +# is needed for gcc before v9, and the latter with libc++ before llvm v9. But this gets more +# complicated than just using the compiler, because clang on linux by default uses libstdc++, so +# we'll just give up and see what works. + +add_library(filesystem INTERFACE) + +set(filesystem_code [[ +#include + +int main() { + auto cwd = std::filesystem::current_path(); + return !cwd.string().empty(); +} +]]) + +if(CMAKE_CXX_COMPILER STREQUAL "AppleClang" AND CMAKE_OSX_DEPLOYMENT_TARGET) + # It seems that check_cxx_source_compiles doesn't respect the CMAKE_OSX_DEPLOYMENT_TARGET, so this + # check would pass on Catalina (10.15) and then later compilation would fail because you aren't + # allowed to use when the deployment target is anything before 10.15. + set(CMAKE_REQUIRED_FLAGS -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}) +endif() + +include(CheckCXXSourceCompiles) +check_cxx_source_compiles("${filesystem_code}" filesystem_compiled) +if(filesystem_compiled) + message(STATUS "No extra link flag needed for std::filesystem") + set(filesystem_is_good ON) +else() + foreach(fslib stdc++fs c++fs) + set(CMAKE_REQUIRED_LIBRARIES -l${fslib}) + check_cxx_source_compiles("${filesystem_code}" filesystem_compiled_${fslib}) + if (filesystem_compiled_${fslib}) + message(STATUS "Using -l${fslib} for std::filesystem support") + target_link_libraries(filesystem INTERFACE ${fslib}) + set(filesystem_is_good ON) + break() + endif() + endforeach() +endif() +unset(CMAKE_REQUIRED_LIBRARIES) +option(FORCE_GHC_FILESYSTEM "Force ghc::filesystem even when std::filesystem appears to work" OFF) +if(filesystem_is_good AND NOT FORCE_GHC_FILESYSTEM) + message(STATUS "we have std::filesystem") +else() + # Probably broken AF macos + message(STATUS "std::filesystem is not available, apparently this compiler isn't C++17 compliant; falling back to ghc::filesystem") + add_subdirectory(external/ghc-filesystem) + target_link_libraries(filesystem INTERFACE ghc_filesystem) + target_compile_definitions(filesystem INTERFACE USE_GHC_FILESYSTEM) +endif() diff --git a/cmake/ios.toolchain.cmake b/cmake/ios.toolchain.cmake new file mode 100644 index 000000000..644832062 --- /dev/null +++ b/cmake/ios.toolchain.cmake @@ -0,0 +1,728 @@ +# This file downloaded from https://github.com/leetal/ios-cmake; it +# contained this header regarding the source works' licences: +# +# This file is part of the ios-cmake project. It was retrieved from +# https://github.com/cristeab/ios-cmake.git, which is a fork of +# https://code.google.com/p/ios-cmake/. Which in turn is based off of +# the Platform/Darwin.cmake and Platform/UnixPaths.cmake files which +# are included with CMake 2.8.4 +# +# The ios-cmake project is licensed under the new BSD license. +# +# Copyright (c) 2014, Bogdan Cristea and LTE Engineering Software, +# Kitware, Inc., Insight Software Consortium. All rights reserved. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# This file is based off of the Platform/Darwin.cmake and +# Platform/UnixPaths.cmake files which are included with CMake 2.8.4 +# It has been altered for iOS development. +# +# Updated by Alex Stewart (alexs.mac@gmail.com) +# +# ***************************************************************************** +# Now maintained by Alexander Widerberg (widerbergaren [at] gmail.com) +# under the BSD-3-Clause license +# https://github.com/leetal/ios-cmake +# ***************************************************************************** +# +# INFORMATION / HELP +# +# The following arguments control the behaviour of this toolchain: +# +# PLATFORM: (default "OS") +# OS = Build for iPhoneOS. +# OS64 = Build for arm64 iphoneOS. +# OS64COMBINED = Build for arm64 x86_64 iphoneOS. Combined into FAT STATIC lib (supported on 3.14+ of CMakewith "-G Xcode" argument ONLY) +# SIMULATOR = Build for x86 i386 iphoneOS Simulator. +# SIMULATOR64 = Build for x86_64 iphoneOS Simulator. +# TVOS = Build for arm64 tvOS. +# TVOSCOMBINED = Build for arm64 x86_64 tvOS. Combined into FAT STATIC lib (supported on 3.14+ of CMake with "-G Xcode" argument ONLY) +# SIMULATOR_TVOS = Build for x86_64 tvOS Simulator. +# WATCHOS = Build for armv7k arm64_32 for watchOS. +# WATCHOSCOMBINED = Build for armv7k arm64_32 x86_64 watchOS. Combined into FAT STATIC lib (supported on 3.14+ of CMake with "-G Xcode" argument ONLY) +# SIMULATOR_WATCHOS = Build for x86_64 for watchOS Simulator. +# +# CMAKE_OSX_SYSROOT: Path to the SDK to use. By default this is +# automatically determined from PLATFORM and xcodebuild, but +# can also be manually specified (although this should not be required). +# +# CMAKE_DEVELOPER_ROOT: Path to the Developer directory for the platform +# being compiled for. By default this is automatically determined from +# CMAKE_OSX_SYSROOT, but can also be manually specified (although this should +# not be required). +# +# DEPLOYMENT_TARGET: Minimum SDK version to target. Default 2.0 on watchOS and 9.0 on tvOS+iOS +# +# ENABLE_BITCODE: (1|0) Enables or disables bitcode support. Default 1 (true) +# +# ENABLE_ARC: (1|0) Enables or disables ARC support. Default 1 (true, ARC enabled by default) +# +# ENABLE_VISIBILITY: (1|0) Enables or disables symbol visibility support. Default 0 (false, visibility hidden by default) +# +# ENABLE_STRICT_TRY_COMPILE: (1|0) Enables or disables strict try_compile() on all Check* directives (will run linker +# to actually check if linking is possible). Default 0 (false, will set CMAKE_TRY_COMPILE_TARGET_TYPE to STATIC_LIBRARY) +# +# ARCHS: (armv7 armv7s armv7k arm64 arm64_32 i386 x86_64) If specified, will override the default architectures for the given PLATFORM +# OS = armv7 armv7s arm64 (if applicable) +# OS64 = arm64 (if applicable) +# SIMULATOR = i386 +# SIMULATOR64 = x86_64 +# TVOS = arm64 +# SIMULATOR_TVOS = x86_64 (i386 has since long been deprecated) +# WATCHOS = armv7k arm64_32 (if applicable) +# SIMULATOR_WATCHOS = x86_64 (i386 has since long been deprecated) +# +# This toolchain defines the following variables for use externally: +# +# XCODE_VERSION: Version number (not including Build version) of Xcode detected. +# SDK_VERSION: Version of SDK being used. +# CMAKE_OSX_ARCHITECTURES: Architectures being compiled for (generated from PLATFORM). +# APPLE_TARGET_TRIPLE: Used by autoconf build systems. NOTE: If "ARCHS" are overridden, this will *NOT* be set! +# +# This toolchain defines the following macros for use externally: +# +# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE XCODE_VARIANT) +# A convenience macro for setting xcode specific properties on targets. +# Available variants are: All, Release, RelWithDebInfo, Debug, MinSizeRel +# example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1" "all"). +# +# find_host_package (PROGRAM ARGS) +# A macro used to find executable programs on the host system, not within the +# environment. Thanks to the android-cmake project for providing the +# command. +# +# ******************************** DEPRECATIONS ******************************* +# +# IOS_DEPLOYMENT_TARGET: (Deprecated) Alias to DEPLOYMENT_TARGET +# CMAKE_IOS_DEVELOPER_ROOT: (Deprecated) Alias to CMAKE_DEVELOPER_ROOT +# IOS_PLATFORM: (Deprecated) Alias to PLATFORM +# IOS_ARCH: (Deprecated) Alias to ARCHS +# +# ***************************************************************************** +# + +# Fix for PThread library not in path +set(CMAKE_THREAD_LIBS_INIT "-lpthread") +set(CMAKE_HAVE_THREADS_LIBRARY 1) +set(CMAKE_USE_WIN32_THREADS_INIT 0) +set(CMAKE_USE_PTHREADS_INIT 1) + +# Cache what generator is used +set(USED_CMAKE_GENERATOR "${CMAKE_GENERATOR}" CACHE STRING "Expose CMAKE_GENERATOR" FORCE) + +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14") + set(MODERN_CMAKE YES) +endif() + +# Get the Xcode version being used. +execute_process(COMMAND xcodebuild -version + OUTPUT_VARIABLE XCODE_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION "${XCODE_VERSION}") +string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION "${XCODE_VERSION}") + +######## ALIASES (DEPRECATION WARNINGS) + +if(DEFINED IOS_PLATFORM) + set(PLATFORM ${IOS_PLATFORM}) + message(DEPRECATION "IOS_PLATFORM argument is DEPRECATED. Consider using the new PLATFORM argument instead.") +endif() + +if(DEFINED IOS_DEPLOYMENT_TARGET) + set(DEPLOYMENT_TARGET ${IOS_DEPLOYMENT_TARGET}) + message(DEPRECATION "IOS_DEPLOYMENT_TARGET argument is DEPRECATED. Consider using the new DEPLOYMENT_TARGET argument instead.") +endif() + +if(DEFINED CMAKE_IOS_DEVELOPER_ROOT) + set(CMAKE_DEVELOPER_ROOT ${CMAKE_IOS_DEVELOPER_ROOT}) + message(DEPRECATION "CMAKE_IOS_DEVELOPER_ROOT argument is DEPRECATED. Consider using the new CMAKE_DEVELOPER_ROOT argument instead.") +endif() + +if(DEFINED IOS_ARCH) + set(ARCHS ${IOS_ARCH}) + message(DEPRECATION "IOS_ARCH argument is DEPRECATED. Consider using the new ARCHS argument instead.") +endif() + +######## END ALIASES + +# Unset the FORCE on cache variables if in try_compile() +set(FORCE_CACHE FORCE) +get_property(_CMAKE_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if(_CMAKE_IN_TRY_COMPILE) + unset(FORCE_CACHE) +endif() + +# Default to building for iPhoneOS if not specified otherwise, and we cannot +# determine the platform from the CMAKE_OSX_ARCHITECTURES variable. The use +# of CMAKE_OSX_ARCHITECTURES is such that try_compile() projects can correctly +# determine the value of PLATFORM from the root project, as +# CMAKE_OSX_ARCHITECTURES is propagated to them by CMake. +if(NOT DEFINED PLATFORM) + if (CMAKE_OSX_ARCHITECTURES) + if(CMAKE_OSX_ARCHITECTURES MATCHES ".*arm.*" AND CMAKE_OSX_SYSROOT MATCHES ".*iphoneos.*") + set(PLATFORM "OS") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_SYSROOT MATCHES ".*iphonesimulator.*") + set(PLATFORM "SIMULATOR") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" AND CMAKE_OSX_SYSROOT MATCHES ".*iphonesimulator.*") + set(PLATFORM "SIMULATOR64") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "arm64" AND CMAKE_OSX_SYSROOT MATCHES ".*appletvos.*") + set(PLATFORM "TVOS") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" AND CMAKE_OSX_SYSROOT MATCHES ".*appletvsimulator.*") + set(PLATFORM "SIMULATOR_TVOS") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES ".*armv7k.*" AND CMAKE_OSX_SYSROOT MATCHES ".*watchos.*") + set(PLATFORM "WATCHOS") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_SYSROOT MATCHES ".*watchsimulator.*") + set(PLATFORM "SIMULATOR_WATCHOS") + endif() + endif() + if (NOT PLATFORM) + set(PLATFORM "OS") + endif() +endif() + +set(PLATFORM_INT "${PLATFORM}" CACHE STRING "Type of platform for which the build targets.") + +# Handle the case where we are targeting iOS and a version above 10.3.4 (32-bit support dropped officially) +if(PLATFORM_INT STREQUAL "OS" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4) + set(PLATFORM_INT "OS64") + message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") +elseif(PLATFORM_INT STREQUAL "SIMULATOR" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.3.4) + set(PLATFORM_INT "SIMULATOR64") + message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") +endif() + +# Determine the platform name and architectures for use in xcodebuild commands +# from the specified PLATFORM name. +if(PLATFORM_INT STREQUAL "OS") + set(SDK_NAME iphoneos) + if(NOT ARCHS) + set(ARCHS armv7 armv7s arm64) + set(APPLE_TARGET_TRIPLE_INT arm-apple-ios) + endif() +elseif(PLATFORM_INT STREQUAL "OS64") + set(SDK_NAME iphoneos) + if(NOT ARCHS) + if (XCODE_VERSION VERSION_GREATER 10.0) + set(ARCHS arm64) # Add arm64e when Apple have fixed the integration issues with it, libarclite_iphoneos.a is currently missung bitcode markers for example + else() + set(ARCHS arm64) + endif() + set(APPLE_TARGET_TRIPLE_INT aarch64-apple-ios) + endif() +elseif(PLATFORM_INT STREQUAL "OS64COMBINED") + set(SDK_NAME iphoneos) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION VERSION_GREATER 10.0) + set(ARCHS arm64 x86_64) # Add arm64e when Apple have fixed the integration issues with it, libarclite_iphoneos.a is currently missung bitcode markers for example + else() + set(ARCHS arm64 x86_64) + endif() + set(APPLE_TARGET_TRIPLE_INT aarch64-x86_64-apple-ios) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the OS64COMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS i386) + set(APPLE_TARGET_TRIPLE_INT i386-apple-ios) + endif() + message(DEPRECATION "SIMULATOR IS DEPRECATED. Consider using SIMULATOR64 instead.") +elseif(PLATFORM_INT STREQUAL "SIMULATOR64") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS x86_64) + set(APPLE_TARGET_TRIPLE_INT x86_64-apple-ios) + endif() +elseif(PLATFORM_INT STREQUAL "TVOS") + set(SDK_NAME appletvos) + if(NOT ARCHS) + set(ARCHS arm64) + set(APPLE_TARGET_TRIPLE_INT aarch64-apple-tvos) + endif() +elseif (PLATFORM_INT STREQUAL "TVOSCOMBINED") + set(SDK_NAME appletvos) + if(MODERN_CMAKE) + if(NOT ARCHS) + set(ARCHS arm64 x86_64) + set(APPLE_TARGET_TRIPLE_INT aarch64-x86_64-apple-tvos) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the TVOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") + set(SDK_NAME appletvsimulator) + if(NOT ARCHS) + set(ARCHS x86_64) + set(APPLE_TARGET_TRIPLE_INT x86_64-apple-tvos) + endif() +elseif(PLATFORM_INT STREQUAL "WATCHOS") + set(SDK_NAME watchos) + if(NOT ARCHS) + if (XCODE_VERSION VERSION_GREATER 10.0) + set(ARCHS armv7k arm64_32) + set(APPLE_TARGET_TRIPLE_INT aarch64_32-apple-watchos) + else() + set(ARCHS armv7k) + set(APPLE_TARGET_TRIPLE_INT arm-apple-watchos) + endif() + endif() +elseif(PLATFORM_INT STREQUAL "WATCHOSCOMBINED") + set(SDK_NAME watchos) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION VERSION_GREATER 10.0) + set(ARCHS armv7k arm64_32 i386) + set(APPLE_TARGET_TRIPLE_INT aarch64_32-i386-apple-watchos) + else() + set(ARCHS armv7k i386) + set(APPLE_TARGET_TRIPLE_INT arm-i386-apple-watchos) + endif() + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the WATCHOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + set(SDK_NAME watchsimulator) + if(NOT ARCHS) + set(ARCHS i386) + set(APPLE_TARGET_TRIPLE_INT i386-apple-watchos) + endif() +else() + message(FATAL_ERROR "Invalid PLATFORM: ${PLATFORM_INT}") +endif() + +if(MODERN_CMAKE AND PLATFORM_INT MATCHES ".*COMBINED" AND NOT USED_CMAKE_GENERATOR MATCHES "Xcode") + message(FATAL_ERROR "The COMBINED options only work with Xcode generator, -G Xcode") +endif() + +# If user did not specify the SDK root to use, then query xcodebuild for it. +execute_process(COMMAND xcodebuild -version -sdk ${SDK_NAME} Path + OUTPUT_VARIABLE CMAKE_OSX_SYSROOT_INT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +if (NOT DEFINED CMAKE_OSX_SYSROOT_INT AND NOT DEFINED CMAKE_OSX_SYSROOT) + message(SEND_ERROR "Please make sure that Xcode is installed and that the toolchain" + "is pointing to the correct path. Please run:" + "sudo xcode-select -s /Applications/Xcode.app/Contents/Developer" + "and see if that fixes the problem for you.") + message(FATAL_ERROR "Invalid CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT} " + "does not exist.") +elseif(DEFINED CMAKE_OSX_SYSROOT_INT) + set(CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") +endif() + +# Set Xcode property for SDKROOT as well if Xcode generator is used +if(USED_CMAKE_GENERATOR MATCHES "Xcode") + set(CMAKE_OSX_SYSROOT "${SDK_NAME}" CACHE INTERNAL "") + if(NOT DEFINED CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM) + set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM "123456789A" CACHE INTERNAL "") + endif() +endif() + +# Specify minimum version of deployment target. +if(NOT DEFINED DEPLOYMENT_TARGET) + if (PLATFORM_INT STREQUAL "WATCHOS" OR PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + # Unless specified, SDK version 2.0 is used by default as minimum target version (watchOS). + set(DEPLOYMENT_TARGET "2.0" + CACHE STRING "Minimum SDK version to build for." ) + else() + # Unless specified, SDK version 9.0 is used by default as minimum target version (iOS, tvOS). + set(DEPLOYMENT_TARGET "9.0" + CACHE STRING "Minimum SDK version to build for." ) + endif() + message(STATUS "Using the default min-version since DEPLOYMENT_TARGET not provided!") +endif() + +# Use bitcode or not +if(NOT DEFINED ENABLE_BITCODE AND NOT ARCHS MATCHES "((^|;|, )(i386|x86_64))+") + # Unless specified, enable bitcode support by default + message(STATUS "Enabling bitcode support by default. ENABLE_BITCODE not provided!") + set(ENABLE_BITCODE TRUE) +elseif(NOT DEFINED ENABLE_BITCODE) + message(STATUS "Disabling bitcode support by default on simulators. ENABLE_BITCODE not provided for override!") + set(ENABLE_BITCODE FALSE) +endif() +set(ENABLE_BITCODE_INT ${ENABLE_BITCODE} CACHE BOOL "Whether or not to enable bitcode" ${FORCE_CACHE}) +# Use ARC or not +if(NOT DEFINED ENABLE_ARC) + # Unless specified, enable ARC support by default + set(ENABLE_ARC TRUE) + message(STATUS "Enabling ARC support by default. ENABLE_ARC not provided!") +endif() +set(ENABLE_ARC_INT ${ENABLE_ARC} CACHE BOOL "Whether or not to enable ARC" ${FORCE_CACHE}) +# Use hidden visibility or not +if(NOT DEFINED ENABLE_VISIBILITY) + # Unless specified, disable symbols visibility by default + set(ENABLE_VISIBILITY FALSE) + message(STATUS "Hiding symbols visibility by default. ENABLE_VISIBILITY not provided!") +endif() +set(ENABLE_VISIBILITY_INT ${ENABLE_VISIBILITY} CACHE BOOL "Whether or not to hide symbols (-fvisibility=hidden)" ${FORCE_CACHE}) +# Set strict compiler checks or not +if(NOT DEFINED ENABLE_STRICT_TRY_COMPILE) + # Unless specified, disable strict try_compile() + set(ENABLE_STRICT_TRY_COMPILE FALSE) + message(STATUS "Using NON-strict compiler checks by default. ENABLE_STRICT_TRY_COMPILE not provided!") +endif() +set(ENABLE_STRICT_TRY_COMPILE_INT ${ENABLE_STRICT_TRY_COMPILE} CACHE BOOL "Whether or not to use strict compiler checks" ${FORCE_CACHE}) +# Get the SDK version information. +execute_process(COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version SDKVersion + OUTPUT_VARIABLE SDK_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + +# Find the Developer root for the specific iOS platform being compiled for +# from CMAKE_OSX_SYSROOT. Should be ../../ from SDK specified in +# CMAKE_OSX_SYSROOT. There does not appear to be a direct way to obtain +# this information from xcrun or xcodebuild. +if (NOT DEFINED CMAKE_DEVELOPER_ROOT AND NOT USED_CMAKE_GENERATOR MATCHES "Xcode") + get_filename_component(PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT} PATH) + get_filename_component(CMAKE_DEVELOPER_ROOT ${PLATFORM_SDK_DIR} PATH) + if (NOT DEFINED CMAKE_DEVELOPER_ROOT) + message(FATAL_ERROR "Invalid CMAKE_DEVELOPER_ROOT: " + "${CMAKE_DEVELOPER_ROOT} does not exist.") + endif() +endif() +# Find the C & C++ compilers for the specified SDK. +if(NOT CMAKE_C_COMPILER) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang + OUTPUT_VARIABLE CMAKE_C_COMPILER + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "Using C compiler: ${CMAKE_C_COMPILER}") +endif() +if(NOT CMAKE_CXX_COMPILER) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang++ + OUTPUT_VARIABLE CMAKE_CXX_COMPILER + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}") +endif() +# Find (Apple's) libtool. +execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find libtool + OUTPUT_VARIABLE BUILD_LIBTOOL + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +message(STATUS "Using libtool: ${BUILD_LIBTOOL}") +# Configure libtool to be used instead of ar + ranlib to build static libraries. +# This is required on Xcode 7+, but should also work on previous versions of +# Xcode. +set(CMAKE_C_CREATE_STATIC_LIBRARY + "${BUILD_LIBTOOL} -static -o ") +set(CMAKE_CXX_CREATE_STATIC_LIBRARY + "${BUILD_LIBTOOL} -static -o ") +# Find the toolchain's provided install_name_tool if none is found on the host +if(NOT CMAKE_INSTALL_NAME_TOOL) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find install_name_tool + OUTPUT_VARIABLE CMAKE_INSTALL_NAME_TOOL_INT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + set(CMAKE_INSTALL_NAME_TOOL ${CMAKE_INSTALL_NAME_TOOL_INT} CACHE STRING "" ${FORCE_CACHE}) +endif() +# Get the version of Darwin (OS X) of the host. +execute_process(COMMAND uname -r + OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +if(SDK_NAME MATCHES "iphone") + set(CMAKE_SYSTEM_NAME iOS CACHE INTERNAL "" ${FORCE_CACHE}) +endif() +# CMake 3.14+ support building for iOS, watchOS and tvOS out of the box. +if(MODERN_CMAKE) + if(SDK_NAME MATCHES "appletv") + set(CMAKE_SYSTEM_NAME tvOS CACHE INTERNAL "" ${FORCE_CACHE}) + elseif(SDK_NAME MATCHES "watch") + set(CMAKE_SYSTEM_NAME watchOS CACHE INTERNAL "" ${FORCE_CACHE}) + endif() + # Provide flags for a combined FAT library build on newer CMake versions + if(PLATFORM_INT MATCHES ".*COMBINED") + set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH "NO" CACHE INTERNAL "" ${FORCE_CACHE}) + set(CMAKE_IOS_INSTALL_COMBINED YES CACHE INTERNAL "" ${FORCE_CACHE}) + message(STATUS "Will combine built (static) artifacts into FAT lib...") + endif() +elseif(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.10") + # Legacy code path prior to CMake 3.14 or fallback if no SDK_NAME specified + set(CMAKE_SYSTEM_NAME iOS CACHE INTERNAL "" ${FORCE_CACHE}) +else() + # Legacy code path prior to CMake 3.14 or fallback if no SDK_NAME specified + set(CMAKE_SYSTEM_NAME Darwin CACHE INTERNAL "" ${FORCE_CACHE}) +endif() +# Standard settings. +set(CMAKE_SYSTEM_VERSION ${SDK_VERSION} CACHE INTERNAL "") +set(UNIX TRUE CACHE BOOL "") +set(APPLE TRUE CACHE BOOL "") +set(IOS TRUE CACHE BOOL "") +set(CMAKE_AR ar CACHE FILEPATH "" FORCE) +set(CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE) +set(CMAKE_STRIP strip CACHE FILEPATH "" FORCE) +# Set the architectures for which to build. +set(CMAKE_OSX_ARCHITECTURES ${ARCHS} CACHE STRING "Build architecture for iOS") +# Change the type of target generated for try_compile() so it'll work when cross-compiling, weak compiler checks +if(ENABLE_STRICT_TRY_COMPILE_INT) + message(STATUS "Using strict compiler checks (default in CMake).") +else() + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +endif() +# All iOS/Darwin specific settings - some may be redundant. +set(CMAKE_MACOSX_BUNDLE YES) +set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") +set(CMAKE_SHARED_LIBRARY_PREFIX "lib") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib") +set(CMAKE_SHARED_MODULE_PREFIX "lib") +set(CMAKE_SHARED_MODULE_SUFFIX ".so") +set(CMAKE_C_COMPILER_ABI ELF) +set(CMAKE_CXX_COMPILER_ABI ELF) +set(CMAKE_C_HAS_ISYSROOT 1) +set(CMAKE_CXX_HAS_ISYSROOT 1) +set(CMAKE_MODULE_EXISTS 1) +set(CMAKE_DL_LIBS "") +set(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") +set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") +set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}") +set(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}") + +if(ARCHS MATCHES "((^|;|, )(arm64|arm64e|x86_64))+") + set(CMAKE_C_SIZEOF_DATA_PTR 8) + set(CMAKE_CXX_SIZEOF_DATA_PTR 8) + if(ARCHS MATCHES "((^|;|, )(arm64|arm64e))+") + set(CMAKE_SYSTEM_PROCESSOR "aarch64") + else() + set(CMAKE_SYSTEM_PROCESSOR "x86_64") + endif() +else() + set(CMAKE_C_SIZEOF_DATA_PTR 4) + set(CMAKE_CXX_SIZEOF_DATA_PTR 4) + set(CMAKE_SYSTEM_PROCESSOR "arm") +endif() + +# Note that only Xcode 7+ supports the newer more specific: +# -m${SDK_NAME}-version-min flags, older versions of Xcode use: +# -m(ios/ios-simulator)-version-min instead. +if(${CMAKE_VERSION} VERSION_LESS "3.11") + if(PLATFORM_INT STREQUAL "OS" OR PLATFORM_INT STREQUAL "OS64") + if(XCODE_VERSION VERSION_LESS 7.0) + set(SDK_NAME_VERSION_FLAGS + "-mios-version-min=${DEPLOYMENT_TARGET}") + else() + # Xcode 7.0+ uses flags we can build directly from SDK_NAME. + set(SDK_NAME_VERSION_FLAGS + "-m${SDK_NAME}-version-min=${DEPLOYMENT_TARGET}") + endif() + elseif(PLATFORM_INT STREQUAL "TVOS") + set(SDK_NAME_VERSION_FLAGS + "-mtvos-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") + set(SDK_NAME_VERSION_FLAGS + "-mtvos-simulator-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "WATCHOS") + set(SDK_NAME_VERSION_FLAGS + "-mwatchos-version-min=${DEPLOYMENT_TARGET}") + elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + set(SDK_NAME_VERSION_FLAGS + "-mwatchos-simulator-version-min=${DEPLOYMENT_TARGET}") + else() + # SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min. + set(SDK_NAME_VERSION_FLAGS + "-mios-simulator-version-min=${DEPLOYMENT_TARGET}") + endif() +else() + # Newer versions of CMake sets the version min flags correctly + set(CMAKE_OSX_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET} CACHE STRING + "Set CMake deployment target" ${FORCE_CACHE}) +endif() + +if(DEFINED APPLE_TARGET_TRIPLE_INT) + set(APPLE_TARGET_TRIPLE ${APPLE_TARGET_TRIPLE_INT} CACHE STRING + "Autoconf target triple compatible variable" ${FORCE_CACHE}) +endif() + +if(ENABLE_BITCODE_INT) + set(BITCODE "-fembed-bitcode") + set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE "bitcode" CACHE INTERNAL "") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "YES" CACHE INTERNAL "") +else() + set(BITCODE "") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE "NO" CACHE INTERNAL "") +endif() + +if(ENABLE_ARC_INT) + set(FOBJC_ARC "-fobjc-arc") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "YES" CACHE INTERNAL "") +else() + set(FOBJC_ARC "-fno-objc-arc") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC "NO" CACHE INTERNAL "") +endif() + +if(NOT ENABLE_VISIBILITY_INT) + set(VISIBILITY "-fvisibility=hidden") + set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "YES" CACHE INTERNAL "") +else() + set(VISIBILITY "") + set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN "NO" CACHE INTERNAL "") +endif() + +if(NOT IOS_TOOLCHAIN_HAS_RUN) + #Check if Xcode generator is used, since that will handle these flags automagically + if(USED_CMAKE_GENERATOR MATCHES "Xcode") + message(STATUS "Not setting any manual command-line buildflags, since Xcode is selected as generator.") + else() + set(CMAKE_C_FLAGS + "${SDK_NAME_VERSION_FLAGS} ${BITCODE} -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_C_FLAGS}") + # Hidden visibilty is required for C++ on iOS. + set(CMAKE_CXX_FLAGS + "${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} -fvisibility-inlines-hidden -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g ${CMAKE_CXX_FLAGS_DEBUG}") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG -Os -ffast-math ${CMAKE_CXX_FLAGS_MINSIZEREL}") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG -O2 -g -ffast-math ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG -O3 -ffast-math ${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_C_LINK_FLAGS "${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}") + set(CMAKE_CXX_LINK_FLAGS "${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}") + set(CMAKE_ASM_FLAGS "${CFLAGS} -x assembler-with-cpp") + + # In order to ensure that the updated compiler flags are used in try_compile() + # tests, we have to forcibly set them in the CMake cache, not merely set them + # in the local scope. + set(VARS_TO_FORCE_IN_CACHE + CMAKE_C_FLAGS + CMAKE_CXX_FLAGS + CMAKE_CXX_FLAGS_DEBUG + CMAKE_CXX_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS_MINSIZEREL + CMAKE_CXX_FLAGS_RELEASE + CMAKE_C_LINK_FLAGS + CMAKE_CXX_LINK_FLAGS) + foreach(VAR_TO_FORCE ${VARS_TO_FORCE_IN_CACHE}) + set(${VAR_TO_FORCE} "${${VAR_TO_FORCE}}" CACHE STRING "" ${FORCE_CACHE}) + endforeach() + endif() + + ## Print status messages to inform of the current state + message(STATUS "Configuring ${SDK_NAME} build for platform: ${PLATFORM_INT}, architecture(s): ${ARCHS}") + message(STATUS "Using SDK: ${CMAKE_OSX_SYSROOT_INT}") + if(DEFINED APPLE_TARGET_TRIPLE) + message(STATUS "Autoconf target triple: ${APPLE_TARGET_TRIPLE}") + endif() + message(STATUS "Using minimum deployment version: ${DEPLOYMENT_TARGET}" + " (SDK version: ${SDK_VERSION})") + if(MODERN_CMAKE) + message(STATUS "Merging integrated CMake 3.14+ iOS,tvOS,watchOS,macOS toolchain(s) with this toolchain!") + endif() + if(USED_CMAKE_GENERATOR MATCHES "Xcode") + message(STATUS "Using Xcode version: ${XCODE_VERSION}") + endif() + if(DEFINED SDK_NAME_VERSION_FLAGS) + message(STATUS "Using version flags: ${SDK_NAME_VERSION_FLAGS}") + endif() + message(STATUS "Using a data_ptr size of: ${CMAKE_CXX_SIZEOF_DATA_PTR}") + message(STATUS "Using install_name_tool: ${CMAKE_INSTALL_NAME_TOOL}") + if(ENABLE_BITCODE_INT) + message(STATUS "Enabling bitcode support.") + else() + message(STATUS "Disabling bitcode support.") + endif() + + if(ENABLE_ARC_INT) + message(STATUS "Enabling ARC support.") + else() + message(STATUS "Disabling ARC support.") + endif() + + if(NOT ENABLE_VISIBILITY_INT) + message(STATUS "Hiding symbols (-fvisibility=hidden).") + endif() +endif() + +set(CMAKE_PLATFORM_HAS_INSTALLNAME 1) +set(CMAKE_SHARED_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks") +set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib -Wl,-headerpad_max_install_names") +set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle -Wl,-headerpad_max_install_names") +set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,") +set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".tbd" ".dylib" ".so" ".a") +set(CMAKE_SHARED_LIBRARY_SONAME_C_FLAG "-install_name") + +# Set the find root to the iOS developer roots and to user defined paths. +set(CMAKE_FIND_ROOT_PATH ${CMAKE_OSX_SYSROOT_INT} ${CMAKE_PREFIX_PATH} CACHE STRING "Root path that will be prepended + to all search paths") +# Default to searching for frameworks first. +set(CMAKE_FIND_FRAMEWORK FIRST) +# Set up the default search directories for frameworks. +set(CMAKE_FRAMEWORK_PATH + ${CMAKE_DEVELOPER_ROOT}/Library/PrivateFrameworks + ${CMAKE_OSX_SYSROOT_INT}/System/Library/Frameworks + ${CMAKE_FRAMEWORK_PATH} CACHE STRING "Frameworks search paths" ${FORCE_CACHE}) + +set(IOS_TOOLCHAIN_HAS_RUN TRUE CACHE BOOL "Has the CMake toolchain run already?" ${FORCE_CACHE}) + +# By default, search both the specified iOS SDK and the remainder of the host filesystem. +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH CACHE STRING "" ${FORCE_CACHE}) +endif() +if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH CACHE STRING "" ${FORCE_CACHE}) +endif() +if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH CACHE STRING "" ${FORCE_CACHE}) +endif() +if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH CACHE STRING "" ${FORCE_CACHE}) +endif() + +# +# Some helper-macros below to simplify and beautify the CMakeFile +# + +# This little macro lets you set any Xcode specific property. +macro(set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE XCODE_RELVERSION) + set(XCODE_RELVERSION_I "${XCODE_RELVERSION}") + if(XCODE_RELVERSION_I STREQUAL "All") + set_property(TARGET ${TARGET} PROPERTY + XCODE_ATTRIBUTE_${XCODE_PROPERTY} "${XCODE_VALUE}") + else() + set_property(TARGET ${TARGET} PROPERTY + XCODE_ATTRIBUTE_${XCODE_PROPERTY}[variant=${XCODE_RELVERSION_I}] "${XCODE_VALUE}") + endif() +endmacro(set_xcode_property) + +# This macro lets you find executable programs on the host system. +macro(find_host_package) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) + set(IOS FALSE) + find_package(${ARGN}) + set(IOS TRUE) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH) + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH) +endmacro(find_host_package) diff --git a/contrib/epee/CMakeLists.txt b/contrib/epee/CMakeLists.txt index 035b24b36..2af962ad5 100644 --- a/contrib/epee/CMakeLists.txt +++ b/contrib/epee/CMakeLists.txt @@ -27,4 +27,4 @@ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. add_subdirectory(src) - +target_include_directories(epee PUBLIC include) diff --git a/contrib/epee/include/console_handler.h b/contrib/epee/include/epee/console_handler.h similarity index 100% rename from contrib/epee/include/console_handler.h rename to contrib/epee/include/epee/console_handler.h diff --git a/contrib/epee/include/copyable_atomic.h b/contrib/epee/include/epee/copyable_atomic.h similarity index 100% rename from contrib/epee/include/copyable_atomic.h rename to contrib/epee/include/epee/copyable_atomic.h diff --git a/contrib/epee/include/fnv1.h b/contrib/epee/include/epee/fnv1.h similarity index 100% rename from contrib/epee/include/fnv1.h rename to contrib/epee/include/epee/fnv1.h diff --git a/contrib/epee/include/gzip_encoding.h b/contrib/epee/include/epee/gzip_encoding.h similarity index 100% rename from contrib/epee/include/gzip_encoding.h rename to contrib/epee/include/epee/gzip_encoding.h diff --git a/contrib/epee/include/hex.h b/contrib/epee/include/epee/hex.h similarity index 100% rename from contrib/epee/include/hex.h rename to contrib/epee/include/epee/hex.h diff --git a/contrib/epee/include/hmac-md5.h b/contrib/epee/include/epee/hmac-md5.h similarity index 100% rename from contrib/epee/include/hmac-md5.h rename to contrib/epee/include/epee/hmac-md5.h diff --git a/contrib/epee/include/int-util.h b/contrib/epee/include/epee/int-util.h similarity index 100% rename from contrib/epee/include/int-util.h rename to contrib/epee/include/epee/int-util.h diff --git a/contrib/epee/include/md5_l.h b/contrib/epee/include/epee/md5_l.h similarity index 100% rename from contrib/epee/include/md5_l.h rename to contrib/epee/include/epee/md5_l.h diff --git a/contrib/epee/include/md5_l.inl b/contrib/epee/include/epee/md5_l.inl similarity index 100% rename from contrib/epee/include/md5_l.inl rename to contrib/epee/include/epee/md5_l.inl diff --git a/contrib/epee/include/md5global.h b/contrib/epee/include/epee/md5global.h similarity index 100% rename from contrib/epee/include/md5global.h rename to contrib/epee/include/epee/md5global.h diff --git a/contrib/epee/include/memwipe.h b/contrib/epee/include/epee/memwipe.h similarity index 100% rename from contrib/epee/include/memwipe.h rename to contrib/epee/include/epee/memwipe.h diff --git a/contrib/epee/include/misc_language.h b/contrib/epee/include/epee/misc_language.h similarity index 100% rename from contrib/epee/include/misc_language.h rename to contrib/epee/include/epee/misc_language.h diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/epee/misc_log_ex.h similarity index 100% rename from contrib/epee/include/misc_log_ex.h rename to contrib/epee/include/epee/misc_log_ex.h diff --git a/contrib/epee/include/misc_os_dependent.h b/contrib/epee/include/epee/misc_os_dependent.h similarity index 100% rename from contrib/epee/include/misc_os_dependent.h rename to contrib/epee/include/epee/misc_os_dependent.h diff --git a/contrib/epee/include/mlocker.h b/contrib/epee/include/epee/mlocker.h similarity index 100% rename from contrib/epee/include/mlocker.h rename to contrib/epee/include/epee/mlocker.h diff --git a/contrib/epee/include/net/abstract_tcp_server2.h b/contrib/epee/include/epee/net/abstract_tcp_server2.h similarity index 100% rename from contrib/epee/include/net/abstract_tcp_server2.h rename to contrib/epee/include/epee/net/abstract_tcp_server2.h diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/epee/net/abstract_tcp_server2.inl similarity index 99% rename from contrib/epee/include/net/abstract_tcp_server2.inl rename to contrib/epee/include/epee/net/abstract_tcp_server2.inl index 84b11a945..d54ad9b2b 100644 --- a/contrib/epee/include/net/abstract_tcp_server2.inl +++ b/contrib/epee/include/epee/net/abstract_tcp_server2.inl @@ -35,11 +35,11 @@ #include #include #include -#include "warnings.h" -#include "string_tools.h" -#include "misc_language.h" -#include "net/local_ip.h" -#include "pragma_comp_defs.h" +#include "../warnings.h" +#include "../string_tools.h" +#include "../misc_language.h" +#include "local_ip.h" +#include "../pragma_comp_defs.h" #include #include diff --git a/contrib/epee/include/net/buffer.h b/contrib/epee/include/epee/net/buffer.h similarity index 98% rename from contrib/epee/include/net/buffer.h rename to contrib/epee/include/epee/net/buffer.h index 8d3bd25f4..c989a4115 100644 --- a/contrib/epee/include/net/buffer.h +++ b/contrib/epee/include/epee/net/buffer.h @@ -29,8 +29,8 @@ #pragma once #include -#include "misc_log_ex.h" -#include "span.h" +#include "../misc_log_ex.h" +#include "../span.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "net.buffer" diff --git a/contrib/epee/include/net/connection_basic.hpp b/contrib/epee/include/epee/net/connection_basic.hpp similarity index 99% rename from contrib/epee/include/net/connection_basic.hpp rename to contrib/epee/include/epee/net/connection_basic.hpp index 6555b6fe9..1f11ed20c 100644 --- a/contrib/epee/include/net/connection_basic.hpp +++ b/contrib/epee/include/epee/net/connection_basic.hpp @@ -50,7 +50,7 @@ #include -#include "shared_sv.h" +#include "../shared_sv.h" namespace epee { diff --git a/contrib/epee/include/net/enums.h b/contrib/epee/include/epee/net/enums.h similarity index 100% rename from contrib/epee/include/net/enums.h rename to contrib/epee/include/epee/net/enums.h diff --git a/contrib/epee/include/net/jsonrpc_structs.h b/contrib/epee/include/epee/net/jsonrpc_structs.h similarity index 93% rename from contrib/epee/include/net/jsonrpc_structs.h rename to contrib/epee/include/epee/net/jsonrpc_structs.h index 8996cab9a..c00d99db2 100644 --- a/contrib/epee/include/net/jsonrpc_structs.h +++ b/contrib/epee/include/epee/net/jsonrpc_structs.h @@ -3,8 +3,8 @@ #include #include -#include "serialization/keyvalue_serialization.h" -#include "storages/portable_storage_base.h" +#include "../serialization/keyvalue_serialization.h" +#include "../storages/portable_storage_base.h" namespace epee { diff --git a/contrib/epee/include/net/levin_base.h b/contrib/epee/include/epee/net/levin_base.h similarity index 99% rename from contrib/epee/include/net/levin_base.h rename to contrib/epee/include/epee/net/levin_base.h index af5ef4345..98ba2f960 100644 --- a/contrib/epee/include/net/levin_base.h +++ b/contrib/epee/include/epee/net/levin_base.h @@ -34,7 +34,7 @@ #include #include "net_utils_base.h" -#include "span.h" +#include "../span.h" #define LEVIN_SIGNATURE 0x0101010101012101LL //Bender's nightmare diff --git a/contrib/epee/include/net/levin_protocol_handler.h b/contrib/epee/include/epee/net/levin_protocol_handler.h similarity index 99% rename from contrib/epee/include/net/levin_protocol_handler.h rename to contrib/epee/include/epee/net/levin_protocol_handler.h index f9b765f71..bcc37e4e1 100644 --- a/contrib/epee/include/net/levin_protocol_handler.h +++ b/contrib/epee/include/epee/net/levin_protocol_handler.h @@ -31,7 +31,7 @@ #include #include "levin_base.h" -#include "int-util.h" +#include "../int-util.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "net" diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/epee/net/levin_protocol_handler_async.h similarity index 99% rename from contrib/epee/include/net/levin_protocol_handler_async.h rename to contrib/epee/include/epee/net/levin_protocol_handler_async.h index f3c10a40f..504013da8 100644 --- a/contrib/epee/include/net/levin_protocol_handler_async.h +++ b/contrib/epee/include/epee/net/levin_protocol_handler_async.h @@ -35,9 +35,9 @@ #include "levin_base.h" #include "buffer.h" -#include "misc_language.h" -#include "misc_os_dependent.h" -#include "int-util.h" +#include "../misc_language.h" +#include "../misc_os_dependent.h" +#include "../int-util.h" #include #include diff --git a/contrib/epee/include/net/local_ip.h b/contrib/epee/include/epee/net/local_ip.h similarity index 99% rename from contrib/epee/include/net/local_ip.h rename to contrib/epee/include/epee/net/local_ip.h index 200f6249a..b65ab72e7 100644 --- a/contrib/epee/include/net/local_ip.h +++ b/contrib/epee/include/epee/net/local_ip.h @@ -30,7 +30,7 @@ #include #include #include -#include "int-util.h" +#include "../int-util.h" namespace epee { diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/epee/net/net_utils_base.h similarity index 99% rename from contrib/epee/include/net/net_utils_base.h rename to contrib/epee/include/epee/net/net_utils_base.h index dd4821877..459be2875 100644 --- a/contrib/epee/include/net/net_utils_base.h +++ b/contrib/epee/include/epee/net/net_utils_base.h @@ -34,11 +34,11 @@ #include #include #include -#include "shared_sv.h" +#include "../shared_sv.h" #include "enums.h" -#include "misc_log_ex.h" -#include "serialization/keyvalue_serialization.h" -#include "int-util.h" +#include "../misc_log_ex.h" +#include "../serialization/keyvalue_serialization.h" +#include "../int-util.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "net" diff --git a/contrib/epee/include/net/network_throttle-detail.hpp b/contrib/epee/include/epee/net/network_throttle-detail.hpp similarity index 100% rename from contrib/epee/include/net/network_throttle-detail.hpp rename to contrib/epee/include/epee/net/network_throttle-detail.hpp diff --git a/contrib/epee/include/net/network_throttle.hpp b/contrib/epee/include/epee/net/network_throttle.hpp similarity index 100% rename from contrib/epee/include/net/network_throttle.hpp rename to contrib/epee/include/epee/net/network_throttle.hpp diff --git a/contrib/epee/include/pragma_comp_defs.h b/contrib/epee/include/epee/pragma_comp_defs.h similarity index 100% rename from contrib/epee/include/pragma_comp_defs.h rename to contrib/epee/include/epee/pragma_comp_defs.h diff --git a/contrib/epee/include/profile_tools.h b/contrib/epee/include/epee/profile_tools.h similarity index 100% rename from contrib/epee/include/profile_tools.h rename to contrib/epee/include/epee/profile_tools.h diff --git a/contrib/epee/include/readline_buffer.h b/contrib/epee/include/epee/readline_buffer.h similarity index 100% rename from contrib/epee/include/readline_buffer.h rename to contrib/epee/include/epee/readline_buffer.h diff --git a/contrib/epee/include/readline_suspend.h b/contrib/epee/include/epee/readline_suspend.h similarity index 100% rename from contrib/epee/include/readline_suspend.h rename to contrib/epee/include/epee/readline_suspend.h diff --git a/contrib/epee/include/rolling_median.h b/contrib/epee/include/epee/rolling_median.h similarity index 100% rename from contrib/epee/include/rolling_median.h rename to contrib/epee/include/epee/rolling_median.h diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/epee/serialization/keyvalue_serialization.h similarity index 99% rename from contrib/epee/include/serialization/keyvalue_serialization.h rename to contrib/epee/include/epee/serialization/keyvalue_serialization.h index 9bbf46f5d..76822d6b9 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization.h +++ b/contrib/epee/include/epee/serialization/keyvalue_serialization.h @@ -26,8 +26,7 @@ #pragma once -#include "misc_log_ex.h" -#include "enableable.h" +#include "../misc_log_ex.h" #include "keyvalue_serialization_overloads.h" #include "../storages/portable_storage.h" diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/epee/serialization/keyvalue_serialization_overloads.h similarity index 94% rename from contrib/epee/include/serialization/keyvalue_serialization_overloads.h rename to contrib/epee/include/epee/serialization/keyvalue_serialization_overloads.h index 5332840df..044fe1587 100644 --- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h +++ b/contrib/epee/include/epee/serialization/keyvalue_serialization_overloads.h @@ -33,8 +33,8 @@ #include #include #include -#include "span.h" -#include "storages/portable_storage_base.h" +#include "../span.h" +#include "../storages/portable_storage_base.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "serialization" @@ -128,24 +128,6 @@ namespace epee return obj._load(stg, child_section); } //------------------------------------------------------------------------------------------------------------------- - template - static bool serialize_t_obj(enableable& obj, t_storage& stg, section* parent_section, const char* pname) - { - if(!obj.enabled) - return true; - return serialize_t_obj(obj.v, stg, parent_section, pname); - } - //------------------------------------------------------------------------------------------------------------------- - template - static bool unserialize_t_obj(enableable& obj, t_storage& stg, section* parent_section, const char* pname) - { - obj.enabled = false; - section* child_section = stg.open_section(pname, parent_section, false); - if(!child_section) return false; - obj.enabled = true; - return obj.v._load(stg, child_section); - } - //------------------------------------------------------------------------------------------------------------------- template static bool serialize_stl_container_t_val(const stl_container& container, t_storage& stg, section* parent_section, const char* pname) { diff --git a/contrib/epee/include/shared_sv.h b/contrib/epee/include/epee/shared_sv.h similarity index 100% rename from contrib/epee/include/shared_sv.h rename to contrib/epee/include/epee/shared_sv.h diff --git a/contrib/epee/include/span.h b/contrib/epee/include/epee/span.h similarity index 100% rename from contrib/epee/include/span.h rename to contrib/epee/include/epee/span.h diff --git a/contrib/epee/include/stats.h b/contrib/epee/include/epee/stats.h similarity index 100% rename from contrib/epee/include/stats.h rename to contrib/epee/include/epee/stats.h diff --git a/contrib/epee/include/stats.inl b/contrib/epee/include/epee/stats.inl similarity index 100% rename from contrib/epee/include/stats.inl rename to contrib/epee/include/epee/stats.inl diff --git a/contrib/epee/include/storages/levin_abstract_invoke2.h b/contrib/epee/include/epee/storages/levin_abstract_invoke2.h similarity index 99% rename from contrib/epee/include/storages/levin_abstract_invoke2.h rename to contrib/epee/include/epee/storages/levin_abstract_invoke2.h index c5d396b4c..3552c3b44 100644 --- a/contrib/epee/include/storages/levin_abstract_invoke2.h +++ b/contrib/epee/include/epee/storages/levin_abstract_invoke2.h @@ -27,8 +27,8 @@ #pragma once #include "portable_storage_template_helper.h" -#include "span.h" -#include "net/levin_base.h" +#include "../span.h" +#include "../net/levin_base.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "net" diff --git a/contrib/epee/include/storages/parserse_base_utils.h b/contrib/epee/include/epee/storages/parserse_base_utils.h similarity index 99% rename from contrib/epee/include/storages/parserse_base_utils.h rename to contrib/epee/include/epee/storages/parserse_base_utils.h index e2b762ea1..50b8a8d04 100644 --- a/contrib/epee/include/storages/parserse_base_utils.h +++ b/contrib/epee/include/epee/storages/parserse_base_utils.h @@ -31,7 +31,7 @@ #include #include #include -#include "misc_log_ex.h" +#include "../misc_log_ex.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "serialization" diff --git a/contrib/epee/include/storages/portable_storage.h b/contrib/epee/include/epee/storages/portable_storage.h similarity index 99% rename from contrib/epee/include/storages/portable_storage.h rename to contrib/epee/include/epee/storages/portable_storage.h index e46e26ccb..67bb89a0f 100644 --- a/contrib/epee/include/storages/portable_storage.h +++ b/contrib/epee/include/epee/storages/portable_storage.h @@ -28,14 +28,14 @@ #pragma once -#include "misc_language.h" +#include "../misc_language.h" #include "portable_storage_base.h" #include "portable_storage_to_bin.h" #include "portable_storage_from_bin.h" #include "portable_storage_to_json.h" #include "portable_storage_from_json.h" #include "portable_storage_val_converters.h" -#include "span.h" +#include "../span.h" namespace epee { diff --git a/contrib/epee/include/storages/portable_storage_base.h b/contrib/epee/include/epee/storages/portable_storage_base.h similarity index 99% rename from contrib/epee/include/storages/portable_storage_base.h rename to contrib/epee/include/epee/storages/portable_storage_base.h index c5793f074..deb0aae50 100644 --- a/contrib/epee/include/storages/portable_storage_base.h +++ b/contrib/epee/include/epee/storages/portable_storage_base.h @@ -33,8 +33,8 @@ #include #include #include -#include "misc_log_ex.h" -#include "int-util.h" +#include "../misc_log_ex.h" +#include "../int-util.h" namespace epee { diff --git a/contrib/epee/include/storages/portable_storage_from_bin.h b/contrib/epee/include/epee/storages/portable_storage_from_bin.h similarity index 99% rename from contrib/epee/include/storages/portable_storage_from_bin.h rename to contrib/epee/include/epee/storages/portable_storage_from_bin.h index 473b12359..26dd0ef66 100644 --- a/contrib/epee/include/storages/portable_storage_from_bin.h +++ b/contrib/epee/include/epee/storages/portable_storage_from_bin.h @@ -28,7 +28,7 @@ #pragma once -#include "misc_language.h" +#include "../misc_language.h" #include "portable_storage_base.h" #include diff --git a/contrib/epee/include/storages/portable_storage_from_json.h b/contrib/epee/include/epee/storages/portable_storage_from_json.h similarity index 99% rename from contrib/epee/include/storages/portable_storage_from_json.h rename to contrib/epee/include/epee/storages/portable_storage_from_json.h index 16293c803..596f4129a 100644 --- a/contrib/epee/include/storages/portable_storage_from_json.h +++ b/contrib/epee/include/epee/storages/portable_storage_from_json.h @@ -28,7 +28,6 @@ #include #include #include "parserse_base_utils.h" -#include "file_io_utils.h" #define EPEE_JSON_RECURSION_LIMIT_INTERNAL 100 diff --git a/contrib/epee/include/storages/portable_storage_template_helper.h b/contrib/epee/include/epee/storages/portable_storage_template_helper.h similarity index 78% rename from contrib/epee/include/storages/portable_storage_template_helper.h rename to contrib/epee/include/epee/storages/portable_storage_template_helper.h index 52b63fa51..17ab01ac5 100644 --- a/contrib/epee/include/storages/portable_storage_template_helper.h +++ b/contrib/epee/include/epee/storages/portable_storage_template_helper.h @@ -31,7 +31,6 @@ #include "parserse_base_utils.h" #include "portable_storage.h" -#include "file_io_utils.h" namespace epee { @@ -50,16 +49,6 @@ namespace epee } //----------------------------------------------------------------------------------------------------------- template - bool load_t_from_json_file(t_struct& out, const std::string& json_file) - { - std::string f_buff; - if(!file_io_utils::load_file_to_string(json_file, f_buff)) - return false; - - return load_t_from_json(out, f_buff); - } - //----------------------------------------------------------------------------------------------------------- - template bool store_t_to_json(t_struct& str_in, std::string& json_buff, size_t indent = 0, bool insert_newlines = true) { portable_storage ps; @@ -77,14 +66,6 @@ namespace epee } //----------------------------------------------------------------------------------------------------------- template - bool store_t_to_json_file(t_struct& str_in, const std::string& fpath) - { - std::string json_buff; - store_t_to_json(str_in, json_buff); - return file_io_utils::save_string_to_file(fpath, json_buff); - } - //----------------------------------------------------------------------------------------------------------- - template bool load_t_from_binary(t_struct& out, const epee::span binary_buff) { portable_storage ps; @@ -106,16 +87,6 @@ namespace epee } //----------------------------------------------------------------------------------------------------------- template - bool load_t_from_binary_file(t_struct& out, const std::string& binary_file) - { - std::string f_buff; - if(!file_io_utils::load_file_to_string(binary_file, f_buff)) - return false; - - return load_t_from_binary(out, f_buff); - } - //----------------------------------------------------------------------------------------------------------- - template bool store_t_to_binary(t_struct& str_in, std::string& binary_buff, size_t indent = 0) { portable_storage ps; diff --git a/contrib/epee/include/storages/portable_storage_to_bin.h b/contrib/epee/include/epee/storages/portable_storage_to_bin.h similarity index 98% rename from contrib/epee/include/storages/portable_storage_to_bin.h rename to contrib/epee/include/epee/storages/portable_storage_to_bin.h index adc2cbe52..00a844278 100644 --- a/contrib/epee/include/storages/portable_storage_to_bin.h +++ b/contrib/epee/include/epee/storages/portable_storage_to_bin.h @@ -28,8 +28,8 @@ #pragma once -#include "pragma_comp_defs.h" -#include "misc_language.h" +#include "../pragma_comp_defs.h" +#include "../misc_language.h" #include "portable_storage_base.h" #include #include diff --git a/contrib/epee/include/storages/portable_storage_to_json.h b/contrib/epee/include/epee/storages/portable_storage_to_json.h similarity index 100% rename from contrib/epee/include/storages/portable_storage_to_json.h rename to contrib/epee/include/epee/storages/portable_storage_to_json.h diff --git a/contrib/epee/include/storages/portable_storage_val_converters.h b/contrib/epee/include/epee/storages/portable_storage_val_converters.h similarity index 98% rename from contrib/epee/include/storages/portable_storage_val_converters.h rename to contrib/epee/include/epee/storages/portable_storage_val_converters.h index 41466aee9..231581868 100644 --- a/contrib/epee/include/storages/portable_storage_val_converters.h +++ b/contrib/epee/include/epee/storages/portable_storage_val_converters.h @@ -33,10 +33,10 @@ #include #include -#include "misc_language.h" +#include "../misc_language.h" #include "portable_storage_base.h" #include "parserse_base_utils.h" -#include "warnings.h" +#include "../warnings.h" namespace epee { diff --git a/contrib/epee/include/string_coding.h b/contrib/epee/include/epee/string_coding.h similarity index 100% rename from contrib/epee/include/string_coding.h rename to contrib/epee/include/epee/string_coding.h diff --git a/contrib/epee/include/string_tools.h b/contrib/epee/include/epee/string_tools.h similarity index 63% rename from contrib/epee/include/string_tools.h rename to contrib/epee/include/epee/string_tools.h index f0a0490a7..67d784671 100644 --- a/contrib/epee/include/string_tools.h +++ b/contrib/epee/include/epee/string_tools.h @@ -42,6 +42,7 @@ #include #include #include +#include #include "storages/parserse_base_utils.h" #include "hex.h" #include "mlocker.h" @@ -60,11 +61,6 @@ using namespace std::literals; namespace string_tools { - //---------------------------------------------------------------------------- - inline std::string buff_to_hex_nodelimer(const std::string& src) - { - return to_hex::string(to_byte_span(to_span(src))); - } //---------------------------------------------------------------------------- inline bool parse_hexstr_to_binbuff(const epee::span s, epee::span& res) { @@ -128,21 +124,6 @@ DISABLE_GCC_WARNING(maybe-uninitialized) return true; } POP_WARNINGS - //---------------------------------------------------------------------------- - template - inline bool xtype_to_string(const XType& val, std::string& str) - { - try - { - str = boost::lexical_cast(val); - } - catch(...) - { - return false; - } - - return true; - } //---------------------------------------------------------------------------- std::string get_ip_string_from_int32(uint32_t ip); //---------------------------------------------------------------------------- @@ -176,14 +157,6 @@ POP_WARNINGS return true; } - inline std::string num_to_string_fast(int64_t val) - { - /* - char buff[30] = {0}; - i64toa_s(val, buff, sizeof(buff)-1, 10); - return buff;*/ - return boost::lexical_cast(val); - } //---------------------------------------------------------------------------- template inline std::string to_string_hex(const T &val) @@ -246,37 +219,33 @@ POP_WARNINGS } - //---------------------------------------------------------------------------- - inline bool trim_left(std::string& str) - { - for(std::string::iterator it = str.begin(); it!= str.end() && isspace(static_cast(*it));) - str.erase(str.begin()); - - return true; - } - //---------------------------------------------------------------------------- - inline bool trim_right(std::string& str) - { - - for(std::string::reverse_iterator it = str.rbegin(); it!= str.rend() && isspace(static_cast(*it));) - str.erase( --((it++).base())); - - return true; - } - //---------------------------------------------------------------------------- - inline std::string& trim(std::string& str) - { - - trim_left(str); - trim_right(str); - return str; - } + //---------------------------------------------------------------------------- + inline std::string& trim_left(std::string& str) + { + auto it = str.begin(); + while (it != str.end() && std::isspace(static_cast(*it))) + it++; + if (it != str.begin()) + str.erase(str.begin(), it); + return str; + } + //---------------------------------------------------------------------------- + inline std::string& trim_right(std::string& str) + { + while (!str.empty() && std::isspace(static_cast(str.back()))) + str.pop_back(); + return str; + } + //---------------------------------------------------------------------------- + inline std::string& trim(std::string& str) + { + return trim_left(trim_right(str)); + } //---------------------------------------------------------------------------- inline std::string trim(const std::string& str_) { std::string str = str_; - trim_left(str); - trim_right(str); + trim(str); return str; } //---------------------------------------------------------------------------- @@ -291,94 +260,6 @@ POP_WARNINGS } return s; } - //---------------------------------------------------------------------------- - template - std::string pod_to_hex(const t_pod_type& s) - { - static_assert(std::is_standard_layout(), "expected standard layout type"); - return to_hex::string(as_byte_span(s)); - } - //---------------------------------------------------------------------------- - template - bool hex_to_pod(const std::string& hex_str, t_pod_type& s) - { - static_assert(std::is_pod::value, "expected pod type"); - if(sizeof(s)*2 != hex_str.size()) - return false; - epee::span rspan((char*)&s, sizeof(s)); - return parse_hexstr_to_binbuff(epee::to_span(hex_str), rspan); - } - //---------------------------------------------------------------------------- - template - bool hex_to_pod(const std::string& hex_str, tools::scrubbed& s) - { - return hex_to_pod(hex_str, unwrap(s)); - } - //---------------------------------------------------------------------------- - template - bool hex_to_pod(const std::string& hex_str, epee::mlocked& s) - { - return hex_to_pod(hex_str, unwrap(s)); - } - //---------------------------------------------------------------------------- - bool validate_hex(uint64_t length, const std::string& str); - //---------------------------------------------------------------------------- - inline std::string get_extension(const std::string& str) - { - std::string res; - std::string::size_type pos = str.rfind('.'); - if(std::string::npos == pos) - return res; - - res = str.substr(pos+1, str.size()-pos); - return res; - } - //---------------------------------------------------------------------------- - inline std::string cut_off_extension(const std::string& str) - { - std::string res; - std::string::size_type pos = str.rfind('.'); - if(std::string::npos == pos) - return str; - - res = str.substr(0, pos); - return res; - } - //---------------------------------------------------------------------------- -#ifdef _WIN32 - inline std::wstring utf8_to_utf16(const std::string& str) - { - if (str.empty()) - return {}; - int wstr_size = MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), NULL, 0); - if (wstr_size == 0) - { - throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); - } - std::wstring wstr(wstr_size, wchar_t{}); - if (!MultiByteToWideChar(CP_UTF8, 0, &str[0], str.size(), &wstr[0], wstr_size)) - { - throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); - } - return wstr; - } - inline std::string utf16_to_utf8(const std::wstring& wstr) - { - if (wstr.empty()) - return {}; - int str_size = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), NULL, 0, NULL, NULL); - if (str_size == 0) - { - throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); - } - std::string str(str_size, char{}); - if (!WideCharToMultiByte(CP_UTF8, 0, &wstr[0], wstr.size(), &str[0], str_size, NULL, NULL)) - { - throw std::runtime_error(std::error_code(GetLastError(), std::system_category()).message()); - } - return str; - } -#endif } } #endif //_STRING_TOOLS_H_ diff --git a/contrib/epee/include/time_helper.h b/contrib/epee/include/epee/time_helper.h similarity index 100% rename from contrib/epee/include/time_helper.h rename to contrib/epee/include/epee/time_helper.h diff --git a/contrib/epee/include/to_nonconst_iterator.h b/contrib/epee/include/epee/to_nonconst_iterator.h similarity index 100% rename from contrib/epee/include/to_nonconst_iterator.h rename to contrib/epee/include/epee/to_nonconst_iterator.h diff --git a/contrib/epee/include/warnings.h b/contrib/epee/include/epee/warnings.h similarity index 100% rename from contrib/epee/include/warnings.h rename to contrib/epee/include/epee/warnings.h diff --git a/contrib/epee/include/wipeable_string.h b/contrib/epee/include/epee/wipeable_string.h similarity index 100% rename from contrib/epee/include/wipeable_string.h rename to contrib/epee/include/epee/wipeable_string.h diff --git a/contrib/epee/include/file_io_utils.h b/contrib/epee/include/file_io_utils.h deleted file mode 100644 index 25f8c648b..000000000 --- a/contrib/epee/include/file_io_utils.h +++ /dev/null @@ -1,235 +0,0 @@ -// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the Andrey N. Sabelnikov nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - - -#ifndef _FILE_IO_UTILS_H_ -#define _FILE_IO_UTILS_H_ - -#include -#include -#include -#ifdef WIN32 -#include -#include "string_tools.h" -#endif - -// On Windows there is a problem with non-ASCII characters in path and file names -// as far as support by the standard components used is concerned: - -// The various file stream classes, e.g. std::ifstream and std::ofstream, are -// part of the GNU C++ Library / libstdc++. On the most basic level they use the -// fopen() call as defined / made accessible to programs compiled within MSYS2 -// by the stdio.h header file maintained by the MinGW project. - -// The critical point: The implementation of fopen() is part of MSVCRT, the -// Microsoft Visual C/C++ Runtime Library, and this method does NOT offer any -// Unicode support. - -// Monero code that would want to continue to use the normal file stream classes -// but WITH Unicode support could therefore not solve this problem on its own, -// but 2 different projects from 2 different maintaining groups would need changes -// in this particular direction - something probably difficult to achieve and -// with a long time to wait until all new versions / releases arrive. - -// Implemented solution approach: Circumvent the problem by stopping to use std -// file stream classes on Windows and directly use Unicode-capable WIN32 API -// calls. Most of the code doing so is concentrated in this header file here. - -namespace epee -{ -namespace file_io_utils -{ - inline - bool is_file_exist(const std::string& path) - { - boost::filesystem::path p(path); - return boost::filesystem::exists(p); - } - - inline - bool save_string_to_file(const std::string& path_to_file, const std::string& str) - { -#ifdef WIN32 - std::wstring wide_path; - try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; } - HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (file_handle == INVALID_HANDLE_VALUE) - return false; - DWORD bytes_written; - DWORD bytes_to_write = (DWORD)str.size(); - BOOL result = WriteFile(file_handle, str.data(), bytes_to_write, &bytes_written, NULL); - CloseHandle(file_handle); - if (bytes_written != bytes_to_write) - result = FALSE; - return result; -#else - try - { - std::ofstream fstream; - fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit); - fstream.open(path_to_file, std::ios_base::binary | std::ios_base::out | std::ios_base::trunc); - fstream << str; - fstream.close(); - return true; - } - - catch(...) - { - return false; - } -#endif - } - - inline - bool get_file_time(const std::string& path_to_file, time_t& ft) - { - boost::system::error_code ec; - ft = boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ec); - if(!ec) - return true; - else - return false; - } - - inline - bool set_file_time(const std::string& path_to_file, const time_t& ft) - { - boost::system::error_code ec; - boost::filesystem::last_write_time(boost::filesystem::path(path_to_file), ft, ec); - if(!ec) - return true; - else - return false; - } - - - inline - bool load_file_to_string(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000) - { -#ifdef WIN32 - std::wstring wide_path; - try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; } - HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (file_handle == INVALID_HANDLE_VALUE) - return false; - DWORD file_size = GetFileSize(file_handle, NULL); - if ((file_size == INVALID_FILE_SIZE) || (uint64_t)file_size > (uint64_t)max_size) { - CloseHandle(file_handle); - return false; - } - target_str.resize(file_size); - DWORD bytes_read; - BOOL result = ReadFile(file_handle, &target_str[0], file_size, &bytes_read, NULL); - CloseHandle(file_handle); - if (bytes_read != file_size) - result = FALSE; - return result; -#else - try - { - std::ifstream fstream; - fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit); - fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate); - - std::ifstream::pos_type file_size = fstream.tellg(); - - if((uint64_t)file_size > (uint64_t)max_size) // ensure a large domain for comparison, and negative -> too large - return false;//don't go crazy - size_t file_size_t = static_cast(file_size); - - target_str.resize(file_size_t); - - fstream.seekg (0, std::ios::beg); - fstream.read((char*)target_str.data(), target_str.size()); - fstream.close(); - return true; - } - - catch(...) - { - return false; - } -#endif - } - - inline - bool append_string_to_file(const std::string& path_to_file, const std::string& str) - { - // No special Windows implementation because so far not used in Monero code - try - { - std::ofstream fstream; - fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit); - fstream.open(path_to_file.c_str(), std::ios_base::binary | std::ios_base::out | std::ios_base::app); - fstream << str; - fstream.close(); - return true; - } - - catch(...) - { - return false; - } - } - - inline - bool get_file_size(const std::string& path_to_file, uint64_t &size) - { -#ifdef WIN32 - std::wstring wide_path; - try { wide_path = string_tools::utf8_to_utf16(path_to_file); } catch (...) { return false; } - HANDLE file_handle = CreateFileW(wide_path.c_str(), GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (file_handle == INVALID_HANDLE_VALUE) - return false; - LARGE_INTEGER file_size; - BOOL result = GetFileSizeEx(file_handle, &file_size); - CloseHandle(file_handle); - if (result) { - size = file_size.QuadPart; - } - return size; -#else - try - { - std::ifstream fstream; - fstream.exceptions(std::ifstream::failbit | std::ifstream::badbit); - fstream.open(path_to_file, std::ios_base::binary | std::ios_base::in | std::ios::ate); - size = fstream.tellg(); - fstream.close(); - return true; - } - - catch(...) - { - return false; - } -#endif - } - -} -} - -#endif //_FILE_IO_UTILS_H_ diff --git a/contrib/epee/include/include_base_utils.h b/contrib/epee/include/include_base_utils.h deleted file mode 100644 index 8412a0083..000000000 --- a/contrib/epee/include/include_base_utils.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the Andrey N. Sabelnikov nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -#pragma once - -#define BOOST_FILESYSTEM_VERSION 3 -#define ENABLE_RELEASE_LOGGING - -#include "misc_log_ex.h" - - diff --git a/contrib/epee/include/serialization/enableable.h b/contrib/epee/include/serialization/enableable.h deleted file mode 100644 index e1be2a774..000000000 --- a/contrib/epee/include/serialization/enableable.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2006-2013, Andrey N. Sabelnikov, www.sabelnikov.net -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of the Andrey N. Sabelnikov nor the -// names of its contributors may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER BE LIABLE FOR ANY -// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// - -#pragma once - -namespace epee -{ - - template - struct enableable - { - t_obj v; - bool enabled; - - enableable() - : v(t_obj()), enabled(true) - { // construct from defaults - } - - enableable(const t_obj& _v) - : v(_v), enabled(true) - { // construct from specified values - } - - enableable(const enableable& _v) - : v(_v.v), enabled(_v.enabled) - { // construct from specified values - } - }; -} diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt index fdf900f15..bb1ab0580 100644 --- a/contrib/epee/src/CMakeLists.txt +++ b/contrib/epee/src/CMakeLists.txt @@ -64,11 +64,9 @@ endif() target_link_libraries(epee PUBLIC easylogging + lokimq::lokimq PRIVATE lokimq::lokimq - Boost::filesystem + filesystem Boost::thread extra) - -target_include_directories(epee PUBLIC ../include) - diff --git a/contrib/epee/src/buffer.cpp b/contrib/epee/src/buffer.cpp index 604c3177d..ca521135f 100644 --- a/contrib/epee/src/buffer.cpp +++ b/contrib/epee/src/buffer.cpp @@ -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. -#include "net/buffer.h" +#include "epee/net/buffer.h" #include #include #include diff --git a/contrib/epee/src/connection_basic.cpp b/contrib/epee/src/connection_basic.cpp index 29e91b26e..f30b87448 100644 --- a/contrib/epee/src/connection_basic.cpp +++ b/contrib/epee/src/connection_basic.cpp @@ -32,20 +32,20 @@ /* rfree: implementation for the non-template base, can be used by connection<> template class in abstract_tcp_server2 file */ -#include "net/connection_basic.hpp" +#include "epee/net/connection_basic.hpp" -#include "net/net_utils_base.h" -#include "misc_log_ex.h" +#include "epee/net/net_utils_base.h" +#include "epee/misc_log_ex.h" #include #include -#include "misc_language.h" -#include "pragma_comp_defs.h" +#include "epee/misc_language.h" +#include "epee/pragma_comp_defs.h" #include #include // TODO: -#include "net/network_throttle-detail.hpp" +#include "epee/net/network_throttle-detail.hpp" #if BOOST_VERSION >= 107000 #define GET_IO_SERVICE(s) ((boost::asio::io_context&)(s).get_executor().context()) diff --git a/contrib/epee/src/hex.cpp b/contrib/epee/src/hex.cpp index edbab645c..aa5af161f 100644 --- a/contrib/epee/src/hex.cpp +++ b/contrib/epee/src/hex.cpp @@ -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. -#include "hex.h" +#include "epee/hex.h" #include #include diff --git a/contrib/epee/src/levin_base.cpp b/contrib/epee/src/levin_base.cpp index b013ec62c..e8e876abd 100644 --- a/contrib/epee/src/levin_base.cpp +++ b/contrib/epee/src/levin_base.cpp @@ -26,10 +26,10 @@ // 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 "net/levin_base.h" +#include "epee/net/levin_base.h" #include -#include "int-util.h" +#include "epee/int-util.h" namespace epee { diff --git a/contrib/epee/src/memwipe.c b/contrib/epee/src/memwipe.c index c2a26c392..4ae1daaaa 100644 --- a/contrib/epee/src/memwipe.c +++ b/contrib/epee/src/memwipe.c @@ -36,7 +36,7 @@ #ifdef HAVE_EXPLICIT_BZERO #include #endif -#include "memwipe.h" +#include "epee/memwipe.h" #if defined(_MSC_VER) #define SCARECROW \ diff --git a/contrib/epee/src/mlocker.cpp b/contrib/epee/src/mlocker.cpp index d0df63ea4..023fe0fce 100644 --- a/contrib/epee/src/mlocker.cpp +++ b/contrib/epee/src/mlocker.cpp @@ -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. -#if defined __GNUC__ && !defined _WIN32 +#if defined __GNUC__ && !defined _WIN32 && !defined __ANDROID__ #define HAVE_MLOCK 1 #endif @@ -34,8 +34,8 @@ #if defined HAVE_MLOCK #include #endif -#include "misc_log_ex.h" -#include "mlocker.h" +#include "epee/misc_log_ex.h" +#include "epee/mlocker.h" #include #include @@ -111,25 +111,34 @@ namespace epee size_t mlocker::get_page_size() { +#if defined(HAVE_MLOCK) std::lock_guard lock{mutex()}; if (page_size == 0) page_size = query_page_size(); return page_size; +#else + return 0; +#endif } mlocker::mlocker(void *ptr, size_t len): ptr(ptr), len(len) { +#if defined(HAVE_MLOCK) lock(ptr, len); +#endif } mlocker::~mlocker() { +#if defined(HAVE_MLOCK) try { unlock(ptr, len); } catch (...) { /* ignore and do not propagate through the dtor */ } +#endif } void mlocker::lock(void *ptr, size_t len) { +#if defined(HAVE_MLOCK) TRY_ENTRY(); size_t page_size = get_page_size(); @@ -144,10 +153,12 @@ namespace epee ++num_locked_objects; CATCH_ENTRY_L1("mlocker::lock", void()); +#endif } void mlocker::unlock(void *ptr, size_t len) { +#if defined(HAVE_MLOCK) TRY_ENTRY(); size_t page_size = get_page_size(); @@ -161,22 +172,32 @@ namespace epee --num_locked_objects; CATCH_ENTRY_L1("mlocker::lock", void()); +#endif } size_t mlocker::get_num_locked_pages() { +#if defined(HAVE_MLOCK) std::lock_guard lock{mutex()}; return map().size(); +#else + return 0; +#endif } size_t mlocker::get_num_locked_objects() { +#if defined(HAVE_MLOCK) std::lock_guard lock{mutex()}; return num_locked_objects; +#else + return 0; +#endif } void mlocker::lock_page(size_t page) { +#if defined(HAVE_MLOCK) std::pair::iterator, bool> p = map().insert(std::make_pair(page, 1)); if (p.second) { @@ -186,10 +207,12 @@ namespace epee { ++p.first->second; } +#endif } void mlocker::unlock_page(size_t page) { +#if defined(HAVE_MLOCK) std::map::iterator i = map().find(page); if (i == map().end()) { @@ -203,5 +226,6 @@ namespace epee do_unlock((void*)(page * page_size), page_size); } } +#endif } } diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp index fcf181359..697031ad5 100644 --- a/contrib/epee/src/mlog.cpp +++ b/contrib/epee/src/mlog.cpp @@ -37,11 +37,18 @@ #include #include -#include #include -#include "string_tools.h" -#include "misc_os_dependent.h" -#include "misc_log_ex.h" +#include "epee/string_tools.h" +#include "epee/misc_os_dependent.h" +#include "epee/misc_log_ex.h" + +#ifndef USE_GHC_FILESYSTEM +#include +namespace fs { using namespace std::filesystem; } +#else +#include +namespace fs = ghc::filesystem; +#endif #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "logging" @@ -82,7 +89,7 @@ std::string mlog_get_default_log_path(const char *default_filename) else default_log_file = default_filename; - return (boost::filesystem::path(default_log_folder) / boost::filesystem::path(default_log_file)).string(); + return (fs::u8path(default_log_folder) / fs::u8path(default_log_file)).u8string(); } static void mlog_set_common_prefix() @@ -173,52 +180,27 @@ void mlog_configure(const std::string &filename_base, bool console, const std::s } if (max_log_files != 0) { - std::vector found_files; - const boost::filesystem::directory_iterator end_itr; - const boost::filesystem::path filename_base_path(filename_base); - const boost::filesystem::path parent_path = filename_base_path.has_parent_path() ? filename_base_path.parent_path() : "."; - for (boost::filesystem::directory_iterator iter(parent_path); iter != end_itr; ++iter) + std::vector found_files; + const auto filename_base_path = fs::u8path(filename_base); + const auto parent_path = filename_base_path.has_parent_path() ? filename_base_path.parent_path() : fs::path("."); + for (const auto& p : fs::directory_iterator{parent_path}) { - const std::string filename = iter->path().string(); + const std::string filename = p.path().u8string(); if (filename.size() >= filename_base.size() && std::memcmp(filename.data(), filename_base.data(), filename_base.size()) == 0) - { - found_files.push_back(iter->path()); - } + found_files.push_back(p.path()); } + if (found_files.size() >= max_log_files) { - std::sort(found_files.begin(), found_files.end(), [](const boost::filesystem::path &a, const boost::filesystem::path &b) { - boost::system::error_code ec; - std::time_t ta = boost::filesystem::last_write_time(boost::filesystem::path(a), ec); - if (ec) - { - MERROR("Failed to get timestamp from " << a << ": " << ec); - ta = std::time(nullptr); - } - std::time_t tb = boost::filesystem::last_write_time(boost::filesystem::path(b), ec); - if (ec) - { - MERROR("Failed to get timestamp from " << b << ": " << ec); - tb = std::time(nullptr); - } - static_assert(std::is_integral(), "bad time_t"); - return ta < tb; + std::sort(found_files.begin(), found_files.end(), [](auto& a, auto& b) { + std::error_code ec; + return fs::last_write_time(a, ec) < fs::last_write_time(b, ec); }); for (size_t i = 0; i <= found_files.size() - max_log_files; ++i) { - try - { - boost::system::error_code ec; - boost::filesystem::remove(found_files[i], ec); - if (ec) - { - MERROR("Failed to remove " << found_files[i] << ": " << ec); - } - } - catch (const std::exception &e) - { - MERROR("Failed to remove " << found_files[i] << ": " << e.what()); - } + std::error_code ec; + if (!fs::remove(found_files[i], ec)) + MERROR("Failed to remove " << found_files[i] << ": " << ec.message()); } } } diff --git a/contrib/epee/src/net_utils_base.cpp b/contrib/epee/src/net_utils_base.cpp index 8ffbc17bd..746c2d5e9 100644 --- a/contrib/epee/src/net_utils_base.cpp +++ b/contrib/epee/src/net_utils_base.cpp @@ -1,10 +1,10 @@ -#include "net/net_utils_base.h" +#include "epee/net/net_utils_base.h" #include -#include "string_tools.h" -#include "net/local_ip.h" +#include "epee/string_tools.h" +#include "epee/net/local_ip.h" namespace epee { namespace net_utils { diff --git a/contrib/epee/src/network_throttle-detail.cpp b/contrib/epee/src/network_throttle-detail.cpp index ae235befb..177fcfa67 100644 --- a/contrib/epee/src/network_throttle-detail.cpp +++ b/contrib/epee/src/network_throttle-detail.cpp @@ -38,15 +38,15 @@ #include #include -#include "net/net_utils_base.h" -#include "misc_log_ex.h" -#include "misc_language.h" -#include "pragma_comp_defs.h" +#include "epee/net/net_utils_base.h" +#include "epee/misc_log_ex.h" +#include "epee/misc_language.h" +#include "epee/pragma_comp_defs.h" -#include "net/abstract_tcp_server2.h" +#include "epee/net/abstract_tcp_server2.h" // TODO: -#include "net/network_throttle-detail.hpp" +#include "epee/net/network_throttle-detail.hpp" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "net.throttle" diff --git a/contrib/epee/src/network_throttle.cpp b/contrib/epee/src/network_throttle.cpp index c1979d4d4..01c2eafeb 100644 --- a/contrib/epee/src/network_throttle.cpp +++ b/contrib/epee/src/network_throttle.cpp @@ -54,7 +54,7 @@ Throttling work by: // 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 "net/network_throttle-detail.hpp" +#include "epee/net/network_throttle-detail.hpp" namespace epee { diff --git a/contrib/epee/src/portable_storage.cpp b/contrib/epee/src/portable_storage.cpp index 2bb0e41e1..e0fb3f932 100644 --- a/contrib/epee/src/portable_storage.cpp +++ b/contrib/epee/src/portable_storage.cpp @@ -1,5 +1,5 @@ -#include "storages/portable_storage_to_json.h" -#include "storages/portable_storage.h" +#include "epee/storages/portable_storage_to_json.h" +#include "epee/storages/portable_storage.h" #include namespace epee { diff --git a/contrib/epee/src/readline_buffer.cpp b/contrib/epee/src/readline_buffer.cpp index 0760358e3..f22b2dffe 100644 --- a/contrib/epee/src/readline_buffer.cpp +++ b/contrib/epee/src/readline_buffer.cpp @@ -1,5 +1,5 @@ -#include "readline_buffer.h" -#include "readline_suspend.h" +#include "epee/readline_buffer.h" +#include "epee/readline_suspend.h" #include #include #include diff --git a/contrib/epee/src/string_tools.cpp b/contrib/epee/src/string_tools.cpp index fd0254016..95fad4bd9 100644 --- a/contrib/epee/src/string_tools.cpp +++ b/contrib/epee/src/string_tools.cpp @@ -24,7 +24,7 @@ // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -#include "string_tools.h" +#include "epee/string_tools.h" #include diff --git a/contrib/epee/src/time_helper.cpp b/contrib/epee/src/time_helper.cpp index 1bd84b74d..1ac7f9623 100644 --- a/contrib/epee/src/time_helper.cpp +++ b/contrib/epee/src/time_helper.cpp @@ -1,5 +1,5 @@ -#include "time_helper.h" -#include "pragma_comp_defs.h" +#include "epee/time_helper.h" +#include "epee/pragma_comp_defs.h" namespace epee::misc_utils { diff --git a/contrib/epee/src/wipeable_string.cpp b/contrib/epee/src/wipeable_string.cpp index b165da5d7..7034db8a7 100644 --- a/contrib/epee/src/wipeable_string.cpp +++ b/contrib/epee/src/wipeable_string.cpp @@ -34,9 +34,9 @@ #include #include #include -#include "memwipe.h" -#include "misc_log_ex.h" -#include "wipeable_string.h" +#include "epee/memwipe.h" +#include "epee/misc_log_ex.h" +#include "epee/wipeable_string.h" static constexpr const char hex[] = u8"0123456789abcdef"; diff --git a/external/CMakeLists.txt b/external/CMakeLists.txt index 4177eeb05..7a90f578e 100644 --- a/external/CMakeLists.txt +++ b/external/CMakeLists.txt @@ -33,14 +33,26 @@ # ...except for FreeBSD, because FreeBSD is a special case that doesn't play well with # others. +set(DEFAULT_WITH_MINIUPNPC ON) +if(ANDROID OR IOS) + set(DEFAULT_WITH_MINIUPNPC OFF) +endif() + +option(WITH_MINIUPNPC "Enable miniupnpc support for IGD NAT hole punching" ${DEFAULT_WITH_MINIUPNPC}) + if(NOT STATIC AND NOT BUILD_STATIC_DEPS) find_package(PkgConfig REQUIRED) - pkg_check_modules(MINIUPNPC miniupnpc>=2.1) + if(WITH_MINIUPNPC) + pkg_check_modules(MINIUPNPC miniupnpc>=2.1) + endif() pkg_check_modules(UNBOUND libunbound) pkg_check_modules(LOKIMQ liblokimq>=1.2) endif() -if(MINIUPNPC_FOUND) +if(NOT WITH_MINIUPNPC) + message(STATUS "miniupnpc support disabled") + target_compile_definitions(miniupnpc INTERFACE WITHOUT_MINIUPNPC) +elseif(MINIUPNPC_FOUND) message(STATUS "Found miniupnpc") link_dep_libs(miniupnpc INTERFACE "${MINIUPNPC_LIBRARY_DIRS}" ${MINIUPNPC_LIBRARIES}) target_include_directories(miniupnpc INTERFACE ${MINIUPNPC_INCLUDE_DIRS}) @@ -88,7 +100,7 @@ else() endif() add_subdirectory(db_drivers) -add_subdirectory(easylogging++) +add_subdirectory(easylogging++ easyloggingpp) add_subdirectory(randomx EXCLUDE_FROM_ALL) # uSockets doesn't really have a proper build system (just a very simple Makefile) so build it diff --git a/external/ghc-filesystem b/external/ghc-filesystem new file mode 160000 index 000000000..7e37433f3 --- /dev/null +++ b/external/ghc-filesystem @@ -0,0 +1 @@ +Subproject commit 7e37433f318488ae4bc80f80e12df12a01579874 diff --git a/external/libuv b/external/libuv index 25f4b8b8a..e8b989ea1 160000 --- a/external/libuv +++ b/external/libuv @@ -1 +1 @@ -Subproject commit 25f4b8b8a3c0f934158cd37a37b0525d75ca488e +Subproject commit e8b989ea1f7f9d4083511a2caec7791e9abd1871 diff --git a/external/randomx b/external/randomx index 81fda4ece..41db8c93d 160000 --- a/external/randomx +++ b/external/randomx @@ -1 +1 @@ -Subproject commit 81fda4ecea1921e6b6376f16a3d0cb30c7810bd4 +Subproject commit 41db8c93d8ccb3b5c85e7f8e9ac424437fb201b7 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index bff425927..05c04a7d3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -74,19 +74,17 @@ add_subdirectory(net) add_subdirectory(mnemonics) add_subdirectory(wallet) add_subdirectory(cryptonote_protocol) +add_subdirectory(blockchain_db) +add_subdirectory(rpc) +add_subdirectory(serialization) +add_subdirectory(p2p) +add_subdirectory(daemonizer) +add_subdirectory(daemon) +add_subdirectory(simplewallet) -if(NOT IOS) - if (NOT BUILD_INTEGRATION) - add_subdirectory(gen_multisig) - add_subdirectory(blockchain_utilities) - endif() - add_subdirectory(blockchain_db) - add_subdirectory(rpc) - add_subdirectory(serialization) - add_subdirectory(p2p) - add_subdirectory(daemonizer) - add_subdirectory(daemon) - add_subdirectory(simplewallet) +if (NOT BUILD_INTEGRATION) + add_subdirectory(gen_multisig) + add_subdirectory(blockchain_utilities) endif() # We'll always add, but with EXCLUDE_FROM_ALL if you didn't ask for them (but this lets you do a diff --git a/src/blockchain_db/CMakeLists.txt b/src/blockchain_db/CMakeLists.txt index bfd12b3d5..ef3820d9b 100644 --- a/src/blockchain_db/CMakeLists.txt +++ b/src/blockchain_db/CMakeLists.txt @@ -37,7 +37,7 @@ target_link_libraries(blockchain_db common ringct lmdb - Boost::filesystem + filesystem Boost::thread extra) diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index 6c5ff9cc6..9a5a7b176 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -29,19 +29,18 @@ #include "cryptonote_core/service_node_rules.h" #include "checkpoints/checkpoints.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "blockchain_db.h" #include "cryptonote_basic/cryptonote_format_utils.h" -#include "profile_tools.h" +#include "epee/profile_tools.h" #include "ringct/rctOps.h" +#include "common/hex.h" #include "lmdb/db_lmdb.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "blockchain.db" -using epee::string_tools::pod_to_hex; - namespace cryptonote { @@ -307,7 +306,7 @@ transaction BlockchainDB::get_tx(const crypto::hash& h) const { transaction tx; if (!get_tx(h, tx)) - throw TX_DNE(std::string("tx with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str()); + throw TX_DNE("tx with hash " + tools::type_to_hex(h) + " not found in db"); return tx; } @@ -321,7 +320,7 @@ transaction BlockchainDB::get_pruned_tx(const crypto::hash& h) const { transaction tx; if (!get_pruned_tx(h, tx)) - throw TX_DNE(std::string("pruned tx with hash ").append(epee::string_tools::pod_to_hex(h)).append(" not found in db").c_str()); + throw TX_DNE("pruned tx with hash " + tools::type_to_hex(h) + " not found in db"); return tx; } @@ -399,7 +398,7 @@ uint64_t BlockchainDB::get_tx_block_height(const crypto::hash &h) const auto result = get_tx_block_heights({{h}}).front(); if (result == std::numeric_limits::max()) { - std::string err = "tx_data_t with hash " + epee::string_tools::pod_to_hex(h) + " not found in db"; + std::string err = "tx_data_t with hash " + tools::type_to_hex(h) + " not found in db"; LOG_PRINT_L1(err); throw TX_DNE(std::move(err)); } @@ -411,7 +410,7 @@ bool BlockchainDB::get_alt_block_header(const crypto::hash &blkid, alt_block_dat cryptonote::blobdata blob; if (!get_alt_block(blkid, data, &blob, checkpoint)) { - throw BLOCK_DNE("Alt-block with hash "s.append(epee::string_tools::pod_to_hex(blkid)).append(" not found in db").c_str()); + throw BLOCK_DNE("Alt-block with hash " + tools::type_to_hex(blkid) + " not found in db"); return false; } diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 07d56721e..682357bbf 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -34,6 +34,7 @@ #include #include #include "common/command_line.h" +#include "common/fs.h" #include "crypto/hash.h" #include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" @@ -589,10 +590,6 @@ public: * The subclass implementing this will handle all file opening/creation, * and is responsible for maintaining its state. * - * The parameter may not refer to a file name, necessarily, but - * could be an IP:PORT for a database which needs it, and so on. Calling it - * is convenient and should be descriptive enough, however. - * * For now, db_flags are * specific to the subclass being instantiated. This is subject to change, * and the db_flags parameter may be deprecated. @@ -600,10 +597,10 @@ public: * If any of this cannot be done, the subclass should throw the corresponding * subclass of DB_EXCEPTION * - * @param filename a string referring to the BlockchainDB to open + * @param filename a path referring to the BlockchainDB to open * @param db_flags flags relevant to how to open/use the BlockchainDB */ - virtual void open(const std::string& filename, cryptonote::network_type nettype, const int db_flags = 0) = 0; + virtual void open(const fs::path& filename, cryptonote::network_type nettype, const int db_flags = 0) = 0; /** * @brief Gets the current open/ready state of the BlockchainDB @@ -665,7 +662,7 @@ public: * * @return a list of filenames */ - virtual std::vector get_filenames() const = 0; + virtual std::vector get_filenames() const = 0; /** * @brief remove file(s) storing the database @@ -679,7 +676,7 @@ public: * * @return true if the operation is succesfull */ - virtual bool remove_data_file(const std::string& folder) const = 0; + virtual bool remove_data_file(const fs::path& folder) const = 0; // return the name of the folder the db's file(s) should reside in /** diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 54579b8dc..84ddb523a 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -28,21 +28,19 @@ #include "db_lmdb.h" -#include #include #include #include #include #include -#include "string_tools.h" -#include "file_io_utils.h" +#include "epee/string_tools.h" #include "common/file.h" #include "common/pruning.h" #include "common/hex.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "crypto/crypto.h" -#include "profile_tools.h" +#include "epee/profile_tools.h" #include "ringct/rctOps.h" #include "checkpoints/checkpoints.h" @@ -54,7 +52,6 @@ #define LOKI_DEFAULT_LOG_CATEGORY "blockchain.db.lmdb" -using epee::string_tools::pod_to_hex; using namespace crypto; using namespace boost::endian; @@ -260,10 +257,10 @@ constexpr unsigned int LMDB_DB_COUNT = 23; // Should agree with the number of db const char zerokey[8] = {0}; const MDB_val zerokval = { sizeof(zerokey), (void *)zerokey }; -const std::string lmdb_error(const std::string& error_string, int mdb_res) +const std::string lmdb_error(std::string error_string, int mdb_res) { - const std::string full_string = error_string + mdb_strerror(mdb_res); - return full_string; + error_string += mdb_strerror(mdb_res); + return error_string; } void lmdb_db_open(MDB_txn* txn, const char* name, int flags, MDB_dbi& dbi, const std::string& error_string) @@ -608,8 +605,7 @@ void BlockchainLMDB::do_resize(uint64_t increase_size) // check disk capacity try { - boost::filesystem::path path(m_folder); - boost::filesystem::space_info si = boost::filesystem::space(path); + auto si = fs::space(m_folder); if(si.available < add_size) { MERROR("!! WARNING: Insufficient free space to extend database !!: " << @@ -957,9 +953,9 @@ uint64_t BlockchainLMDB::add_transaction_data(const crypto::hash& blk_hash, cons result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &val_h, MDB_GET_BOTH); if (result == 0) { txindex *tip = (txindex *)val_h.mv_data; - throw1(TX_EXISTS(std::string("Attempting to add transaction that's already in the db (tx id ").append(boost::lexical_cast(tip->data.tx_id)).append(")").c_str())); + throw1(TX_EXISTS(std::string("Attempting to add transaction that's already in the db (tx id ").append(std::to_string(tip->data.tx_id)).append(")").c_str())); } else if (result != MDB_NOTFOUND) { - throw1(DB_ERROR(lmdb_error(std::string("Error checking if tx index exists for tx hash ") + epee::string_tools::pod_to_hex(tx_hash) + ": ", result).c_str())); + throw1(DB_ERROR(lmdb_error("Error checking if tx index exists for tx hash " + tools::type_to_hex(tx_hash) + ": ", result))); } const cryptonote::transaction &tx = txp.first; @@ -1243,12 +1239,12 @@ void BlockchainLMDB::remove_output(const uint64_t amount, const uint64_t& out_in } result = mdb_cursor_del(m_cur_output_txs, 0); if (result) - throw0(DB_ERROR(lmdb_error(std::string("Error deleting output index ").append(boost::lexical_cast(out_index).append(": ")).c_str(), result).c_str())); + throw0(DB_ERROR(lmdb_error(std::string("Error deleting output index ").append(std::to_string(out_index).append(": ")).c_str(), result).c_str())); // now delete the amount result = mdb_cursor_del(m_cur_output_amounts, 0); if (result) - throw0(DB_ERROR(lmdb_error(std::string("Error deleting amount for output index ").append(boost::lexical_cast(out_index).append(": ")).c_str(), result).c_str())); + throw0(DB_ERROR(lmdb_error(std::string("Error deleting amount for output index ").append(std::to_string(out_index).append(": ")).c_str(), result).c_str())); } void BlockchainLMDB::prune_outputs(uint64_t amount) @@ -1375,7 +1371,7 @@ BlockchainLMDB::BlockchainLMDB(bool batch_transactions): BlockchainDB() m_hardfork = nullptr; } -void BlockchainLMDB::open(const std::string& filename, cryptonote::network_type nettype, const int db_flags) +void BlockchainLMDB::open(const fs::path& filename, cryptonote::network_type nettype, const int db_flags) { int result; int mdb_flags = MDB_NORDAHEAD; @@ -1385,24 +1381,23 @@ void BlockchainLMDB::open(const std::string& filename, cryptonote::network_type if (m_open) throw0(DB_OPEN_FAILURE("Attempted to open db, but it's already open")); - boost::filesystem::path direc(filename); - if (boost::filesystem::exists(direc)) + if (fs::exists(filename)) { - if (!boost::filesystem::is_directory(direc)) + if (!fs::is_directory(filename)) throw0(DB_OPEN_FAILURE("LMDB needs a directory path, but a file was passed")); } else { - if (!boost::filesystem::create_directories(direc)) - throw0(DB_OPEN_FAILURE(std::string("Failed to create directory ").append(filename).c_str())); + if (std::error_code ec; !fs::create_directories(filename, ec)) + throw0(DB_OPEN_FAILURE("Failed to create directory " + filename.u8string())); } // check for existing LMDB files in base directory - boost::filesystem::path old_files = direc.parent_path(); - if (boost::filesystem::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_FILENAME) - || boost::filesystem::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME)) + auto old_files = filename.parent_path(); + if (fs::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_FILENAME) + || fs::exists(old_files / CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME)) { - LOG_PRINT_L0("Found existing LMDB files in " << old_files.string()); + LOG_PRINT_L0("Found existing LMDB files in " << old_files.u8string()); LOG_PRINT_L0("Move " << CRYPTONOTE_BLOCKCHAINDATA_FILENAME << " and/or " << CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME << " to " << filename << ", or delete them, and then restart"); throw DB_ERROR("Database could not be opened"); } @@ -1437,7 +1432,9 @@ void BlockchainLMDB::open(const std::string& filename, cryptonote::network_type if (db_flags & DBF_SALVAGE) mdb_flags |= MDB_PREVSNAPSHOT; - if (auto result = mdb_env_open(m_env, filename.c_str(), mdb_flags, 0644)) + // This .string() is probably just going to hard fail on Windows with non-ASCII unicode filenames, + // but lmdb doesn't support anything else (and so really we're just hitting an underlying lmdb bug). + if (auto result = mdb_env_open(m_env, filename.string().c_str(), mdb_flags, 0644)) throw0(DB_ERROR(lmdb_error("Failed to open lmdb environment: ", result).c_str())); MDB_envinfo mei; @@ -1705,28 +1702,21 @@ void BlockchainLMDB::reset() m_cum_count = 0; } -std::vector BlockchainLMDB::get_filenames() const +std::vector BlockchainLMDB::get_filenames() const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); - std::vector filenames; - - boost::filesystem::path datafile(m_folder); - datafile /= CRYPTONOTE_BLOCKCHAINDATA_FILENAME; - boost::filesystem::path lockfile(m_folder); - lockfile /= CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME; - - filenames.push_back(datafile.string()); - filenames.push_back(lockfile.string()); - - return filenames; + std::vector paths; + paths.push_back(m_folder / CRYPTONOTE_BLOCKCHAINDATA_FILENAME); + paths.push_back(m_folder / CRYPTONOTE_BLOCKCHAINDATA_LOCK_FILENAME); + return paths; } -bool BlockchainLMDB::remove_data_file(const std::string& folder) const +bool BlockchainLMDB::remove_data_file(const fs::path& folder) const { - const std::string filename = folder + "/data.mdb"; + auto filename = folder / CRYPTONOTE_BLOCKCHAINDATA_FILENAME; try { - boost::filesystem::remove(filename); + fs::remove(filename); } catch (const std::exception &e) { @@ -1740,7 +1730,7 @@ std::string BlockchainLMDB::get_db_name() const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); - return std::string("lmdb"); + return "lmdb"s; } void BlockchainLMDB::lock() @@ -2498,7 +2488,7 @@ bool BlockchainLMDB::block_exists(const crypto::hash& h, uint64_t *height) const auto get_result = mdb_cursor_get(m_cur_block_heights, (MDB_val *)&zerokval, &key, MDB_GET_BOTH); if (get_result == MDB_NOTFOUND) { - LOG_PRINT_L3("Block with hash " << epee::string_tools::pod_to_hex(h) << " not found in db"); + LOG_PRINT_L3("Block with hash " << tools::type_to_hex(h) << " not found in db"); } else if (get_result) throw0(DB_ERROR(lmdb_error("DB error attempting to fetch block index from hash", get_result).c_str())); @@ -2623,7 +2613,7 @@ uint64_t BlockchainLMDB::get_block_timestamp(const uint64_t& height) const auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH); if (get_result == MDB_NOTFOUND) { - throw0(BLOCK_DNE(std::string("Attempt to get timestamp from height ").append(boost::lexical_cast(height)).append(" failed -- timestamp not in db").c_str())); + throw0(BLOCK_DNE(std::string("Attempt to get timestamp from height ").append(std::to_string(height)).append(" failed -- timestamp not in db").c_str())); } else if (get_result) throw0(DB_ERROR("Error attempting to retrieve a timestamp from the db")); @@ -2721,7 +2711,7 @@ size_t BlockchainLMDB::get_block_weight(const uint64_t& height) const auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH); if (get_result == MDB_NOTFOUND) { - throw0(BLOCK_DNE(std::string("Attempt to get block size from height ").append(boost::lexical_cast(height)).append(" failed -- block size not in db").c_str())); + throw0(BLOCK_DNE(std::string("Attempt to get block size from height ").append(std::to_string(height)).append(" failed -- block size not in db").c_str())); } else if (get_result) throw0(DB_ERROR("Error attempting to retrieve a block size from the db")); @@ -2857,7 +2847,7 @@ difficulty_type BlockchainLMDB::get_block_cumulative_difficulty(const uint64_t& auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH); if (get_result == MDB_NOTFOUND) { - throw0(BLOCK_DNE(std::string("Attempt to get cumulative difficulty from height ").append(boost::lexical_cast(height)).append(" failed -- difficulty not in db").c_str())); + throw0(BLOCK_DNE(std::string("Attempt to get cumulative difficulty from height ").append(std::to_string(height)).append(" failed -- difficulty not in db").c_str())); } else if (get_result) throw0(DB_ERROR("Error attempting to retrieve a cumulative difficulty from the db")); @@ -2896,7 +2886,7 @@ uint64_t BlockchainLMDB::get_block_already_generated_coins(const uint64_t& heigh auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH); if (get_result == MDB_NOTFOUND) { - throw0(BLOCK_DNE(std::string("Attempt to get generated coins from height ").append(boost::lexical_cast(height)).append(" failed -- block size not in db").c_str())); + throw0(BLOCK_DNE(std::string("Attempt to get generated coins from height ").append(std::to_string(height)).append(" failed -- block size not in db").c_str())); } else if (get_result) throw0(DB_ERROR("Error attempting to retrieve a total generated coins from the db")); @@ -2918,7 +2908,7 @@ uint64_t BlockchainLMDB::get_block_long_term_weight(const uint64_t& height) cons auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH); if (get_result == MDB_NOTFOUND) { - throw0(BLOCK_DNE(std::string("Attempt to get block long term weight from height ").append(boost::lexical_cast(height)).append(" failed -- block info not in db").c_str())); + throw0(BLOCK_DNE(std::string("Attempt to get block long term weight from height ").append(std::to_string(height)).append(" failed -- block info not in db").c_str())); } else if (get_result) throw0(DB_ERROR("Error attempting to retrieve a long term block weight from the db")); @@ -2940,7 +2930,7 @@ crypto::hash BlockchainLMDB::get_block_hash_from_height(const uint64_t& height) auto get_result = mdb_cursor_get(m_cur_block_info, (MDB_val *)&zerokval, &result, MDB_GET_BOTH); if (get_result == MDB_NOTFOUND) { - throw0(BLOCK_DNE(std::string("Attempt to get hash from height ").append(boost::lexical_cast(height)).append(" failed -- hash not in db").c_str())); + throw0(BLOCK_DNE(std::string("Attempt to get hash from height ").append(std::to_string(height)).append(" failed -- hash not in db").c_str())); } else if (get_result) throw0(DB_ERROR(lmdb_error("Error attempting to retrieve a block hash from the db: ", get_result).c_str())); @@ -3060,14 +3050,14 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h) const if (get_result == 0) tx_found = true; else if (get_result != MDB_NOTFOUND) - throw0(DB_ERROR(lmdb_error(std::string("DB error attempting to fetch transaction index from hash ") + epee::string_tools::pod_to_hex(h) + ": ", get_result).c_str())); + throw0(DB_ERROR(lmdb_error(std::string("DB error attempting to fetch transaction index from hash ") + tools::type_to_hex(h) + ": ", get_result).c_str())); TIME_MEASURE_FINISH(time1); time_tx_exists += time1; if (! tx_found) { - LOG_PRINT_L1("transaction with hash " << epee::string_tools::pod_to_hex(h) << " not found in db"); + LOG_PRINT_L1("transaction with hash " << tools::type_to_hex(h) << " not found in db"); return false; } @@ -3096,7 +3086,7 @@ bool BlockchainLMDB::tx_exists(const crypto::hash& h, uint64_t& tx_id) const bool ret = false; if (get_result == MDB_NOTFOUND) { - LOG_PRINT_L1("transaction with hash " << epee::string_tools::pod_to_hex(h) << " not found in db"); + LOG_PRINT_L1("transaction with hash " << tools::type_to_hex(h) << " not found in db"); } else if (get_result) throw0(DB_ERROR(lmdb_error("DB error attempting to fetch transaction from hash", get_result).c_str())); @@ -3117,7 +3107,7 @@ uint64_t BlockchainLMDB::get_tx_unlock_time(const crypto::hash& h) const MDB_val_set(v, h); auto get_result = mdb_cursor_get(m_cur_tx_indices, (MDB_val *)&zerokval, &v, MDB_GET_BOTH); if (get_result == MDB_NOTFOUND) - throw1(TX_DNE(lmdb_error(std::string("tx data with hash ") + epee::string_tools::pod_to_hex(h) + " not found in db: ", get_result).c_str())); + throw1(TX_DNE(lmdb_error(std::string("tx data with hash ") + tools::type_to_hex(h) + " not found in db: ", get_result).c_str())); else if (get_result) throw0(DB_ERROR(lmdb_error("DB error attempting to fetch tx data from hash: ", get_result).c_str())); @@ -4302,7 +4292,7 @@ void BlockchainLMDB::get_output_key(const epee::span &amounts, c MDEBUG("Partial result: " << outputs.size() << "/" << offsets.size()); break; } - throw1(OUTPUT_DNE((std::string("Attempting to get output pubkey by global index (amount ") + boost::lexical_cast(amount) + ", index " + boost::lexical_cast(offsets[i]) + ", count " + boost::lexical_cast(get_num_outputs(amount)) + "), but key does not exist (current height " + boost::lexical_cast(height()) + ")").c_str())); + throw1(OUTPUT_DNE((std::string("Attempting to get output pubkey by global index (amount ") + std::to_string(amount) + ", index " + std::to_string(offsets[i]) + ", count " + std::to_string(get_num_outputs(amount)) + "), but key does not exist (current height " + std::to_string(height()) + ")").c_str())); } else if (get_result) throw0(DB_ERROR(lmdb_error("Error attempting to retrieve an output pubkey from the db", get_result).c_str())); @@ -4610,7 +4600,7 @@ uint8_t BlockchainLMDB::get_hard_fork_version(uint64_t height) const MDB_val val_ret; auto result = mdb_cursor_get(m_cur_hf_versions, &val_key, &val_ret, MDB_SET); if (result == MDB_NOTFOUND || result) - throw0(DB_ERROR(lmdb_error("Error attempting to retrieve a hard fork version at height " + boost::lexical_cast(height) + " from the db: ", result).c_str())); + throw0(DB_ERROR(lmdb_error("Error attempting to retrieve a hard fork version at height " + std::to_string(height) + " from the db: ", result).c_str())); uint8_t ret = *(const uint8_t*)val_ret.mv_data; return ret; @@ -4674,7 +4664,7 @@ bool BlockchainLMDB::get_alt_block(const crypto::hash &blkid, alt_block_data_t * return false; if (result) - throw0(DB_ERROR(lmdb_error("Error attempting to retrieve alternate block " + epee::string_tools::pod_to_hex(blkid) + " from the db: ", result).c_str())); + throw0(DB_ERROR(lmdb_error("Error attempting to retrieve alternate block " + tools::type_to_hex(blkid) + " from the db: ", result).c_str())); if (!read_alt_block_data_from_mdb_val(v, data, block, checkpoint)) throw0(DB_ERROR("Record size is less than expected")); return true; @@ -4692,10 +4682,10 @@ void BlockchainLMDB::remove_alt_block(const crypto::hash &blkid) MDB_val v; int result = mdb_cursor_get(m_cur_alt_blocks, &k, &v, MDB_SET); if (result) - throw0(DB_ERROR(lmdb_error("Error locating alternate block " + epee::string_tools::pod_to_hex(blkid) + " in the db: ", result).c_str())); + throw0(DB_ERROR(lmdb_error("Error locating alternate block " + tools::type_to_hex(blkid) + " in the db: ", result).c_str())); result = mdb_cursor_del(m_cur_alt_blocks, 0); if (result) - throw0(DB_ERROR(lmdb_error("Error deleting alternate block " + epee::string_tools::pod_to_hex(blkid) + " from the db: ", result).c_str())); + throw0(DB_ERROR(lmdb_error("Error deleting alternate block " + tools::type_to_hex(blkid) + " from the db: ", result).c_str())); } uint64_t BlockchainLMDB::get_alt_block_count() @@ -4747,12 +4737,7 @@ bool BlockchainLMDB::is_read_only() const uint64_t BlockchainLMDB::get_database_size() const { - uint64_t size = 0; - boost::filesystem::path datafile(m_folder); - datafile /= CRYPTONOTE_BLOCKCHAINDATA_FILENAME; - if (!epee::file_io_utils::get_file_size(datafile.string(), size)) - size = 0; - return size; + return fs::file_size(m_folder / CRYPTONOTE_BLOCKCHAINDATA_FILENAME); } void BlockchainLMDB::fixup(cryptonote::network_type nettype) diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 85af9c3fd..b50d88acf 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -31,6 +31,7 @@ #include "blockchain_db/blockchain_db.h" #include "cryptonote_basic/blobdatatype.h" // for type blobdata #include "ringct/rctTypes.h" +#include "common/fs.h" #include #include @@ -177,7 +178,7 @@ public: BlockchainLMDB(bool batch_transactions=true); ~BlockchainLMDB(); - void open(const std::string& filename, cryptonote::network_type nettype, const int mdb_flags=0) override; + void open(const fs::path& filename, cryptonote::network_type nettype, const int mdb_flags=0) override; void close() override; @@ -187,9 +188,9 @@ public: void reset() override; - std::vector get_filenames() const override; + std::vector get_filenames() const override; - bool remove_data_file(const std::string& folder) const override; + bool remove_data_file(const fs::path& folder) const override; std::string get_db_name() const override; @@ -490,7 +491,7 @@ private: mutable uint64_t m_cum_size; // used in batch size estimation mutable unsigned int m_cum_count; - std::string m_folder; + fs::path m_folder; mdb_txn_safe* m_write_txn; // may point to either a short-lived txn or a batch txn mdb_txn_safe* m_write_batch_txn; // persist batch txn outside of BlockchainLMDB boost::thread::id m_writer; diff --git a/src/blockchain_db/testdb.h b/src/blockchain_db/testdb.h index 0db52f087..68111fe53 100644 --- a/src/blockchain_db/testdb.h +++ b/src/blockchain_db/testdb.h @@ -35,6 +35,7 @@ #include #include "blockchain_db.h" #include "cryptonote_core/service_node_list.h" +#include "cryptonote_basic/cryptonote_format_utils.h" namespace cryptonote { @@ -42,13 +43,13 @@ namespace cryptonote class BaseTestDB: public cryptonote::BlockchainDB { public: BaseTestDB() {} - virtual void open(const std::string& filename, network_type nettype = FAKECHAIN, const int db_flags = 0) override { } + virtual void open(const fs::path& filename, network_type nettype = FAKECHAIN, const int db_flags = 0) override { } virtual void close() override {} virtual void sync() override {} virtual void safesyncmode(const bool onoff) override {} virtual void reset() override {} - virtual std::vector get_filenames() const override { return std::vector(); } - virtual bool remove_data_file(const std::string& folder) const override { return true; } + virtual std::vector get_filenames() const override { return {}; } + virtual bool remove_data_file(const fs::path& folder) const override { return true; } virtual std::string get_db_name() const override { return std::string(); } virtual void lock() override { } virtual bool try_lock() override { return true; } diff --git a/src/blockchain_utilities/CMakeLists.txt b/src/blockchain_utilities/CMakeLists.txt index 67f07fa28..274789fc8 100644 --- a/src/blockchain_utilities/CMakeLists.txt +++ b/src/blockchain_utilities/CMakeLists.txt @@ -32,7 +32,7 @@ target_link_libraries(blockchain_tools_common_libs INTERFACE cryptonote_core blockchain_db version - Boost::filesystem + filesystem Boost::program_options extra) @@ -110,7 +110,7 @@ target_link_libraries(blockchain_stats PRIVATE blockchain_tools_common_libs) if (TARGET sodium_vendor OR NOT SODIUM_VERSION VERSION_LESS 1.0.17) loki_add_executable(sn_key_tool "loki-sn-keys" sn_key_tool.cpp) - target_link_libraries(sn_key_tool PRIVATE sodium lokimq) + target_link_libraries(sn_key_tool PRIVATE sodium lokimq filesystem) else() message(STATUS "Not building loki-sn-keys tool (requires libsodium >= 1.0.17)") endif() diff --git a/src/blockchain_utilities/blockchain_ancestry.cpp b/src/blockchain_utilities/blockchain_ancestry.cpp index 31bac442d..bdc6a8471 100644 --- a/src/blockchain_utilities/blockchain_ancestry.cpp +++ b/src/blockchain_utilities/blockchain_ancestry.cpp @@ -32,13 +32,13 @@ #include #include -#include #include #include #include "common/unordered_containers_boost_serialization.h" #include "common/command_line.h" #include "common/varint.h" #include "common/signal_handler.h" +#include "common/fs.h" #include "serialization/boost_std_variant.h" #include "cryptonote_basic/cryptonote_boost_serialization.h" #include "cryptonote_core/cryptonote_core.h" @@ -337,8 +337,6 @@ int main(int argc, char* argv[]) tools::on_startup(); - boost::filesystem::path output_file_path; - auto opt_size = command_line::boost_option_sizes(); po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second); @@ -421,7 +419,7 @@ int main(int argc, char* argv[]) uint64_t output_amount = 0, output_offset = 0; if (!opt_txid_string.empty()) { - if (!epee::string_tools::hex_to_pod(opt_txid_string, opt_txid)) + if (!tools::hex_to_type(opt_txid_string, opt_txid)) { std::cerr << "Invalid txid" << std::endl; return 1; @@ -447,7 +445,7 @@ int main(int argc, char* argv[]) } LOG_PRINT_L0("database: LMDB"); - const std::string filename = (boost::filesystem::path(opt_data_dir) / db->get_db_name()).string(); + fs::path filename = fs::u8path(opt_data_dir) / db->get_db_name(); LOG_PRINT_L0("Loading blockchain from folder " << filename << " ..."); try @@ -468,9 +466,9 @@ int main(int argc, char* argv[]) ancestry_state_t state; - const std::string state_file_path = (boost::filesystem::path(opt_data_dir) / "ancestry-state.bin").string(); + fs::path state_file_path = fs::u8path(opt_data_dir) / "ancestry-state.bin"; LOG_PRINT_L0("Loading state data from " << state_file_path); - std::ifstream state_data_in; + fs::ifstream state_data_in; state_data_in.open(state_file_path, std::ios_base::binary | std::ios_base::in); if (!state_data_in.fail()) { diff --git a/src/blockchain_utilities/blockchain_blackball.cpp b/src/blockchain_utilities/blockchain_blackball.cpp index 1d5746055..4de187272 100644 --- a/src/blockchain_utilities/blockchain_blackball.cpp +++ b/src/blockchain_utilities/blockchain_blackball.cpp @@ -37,6 +37,7 @@ #include "common/varint.h" #include "common/file.h" #include "common/signal_handler.h" +#include "common/hex.h" #include "serialization/crypto.h" #include "cryptonote_basic/cryptonote_boost_serialization.h" #include "cryptonote_core/cryptonote_core.h" @@ -132,20 +133,19 @@ static bool parse_db_sync_mode(std::string db_sync_mode) return true; } -static std::string get_default_db_path() +static fs::path get_default_db_path() { - boost::filesystem::path dir = tools::get_default_data_dir(); // remove .loki, replace with .shared-ringdb - dir = dir.remove_filename(); - dir /= ".shared-ringdb"; - return dir.string(); + fs::path p = tools::get_default_data_dir(); + p.replace_filename(".shared-ringdb"); + return p; } -static std::string get_cache_filename(boost::filesystem::path filename) +static fs::path get_cache_filename(fs::path filename) { - if (!boost::filesystem::is_directory(filename)) + if (!fs::is_directory(filename)) filename.remove_filename(); - return filename.string(); + return filename; } static int compare_hash32(const MDB_val *a, const MDB_val *b) @@ -202,11 +202,10 @@ static int resize_env(const char *db_path) { try { - boost::filesystem::path path(db_path); - boost::filesystem::space_info si = boost::filesystem::space(path); + auto si = fs::space(fs::u8path(db_path)); if(si.available < needed) { - MERROR("!! WARNING: Insufficient free space to extend database !!: " << (si.available >> 20L) << " MB available"); + MERROR("!! WARNING: Insufficient free space to extend database !!: " << (si.available / 1000000) << " MB available"); return ENOSPC; } } @@ -221,7 +220,7 @@ static int resize_env(const char *db_path) return mdb_env_set_mapsize(env, mapsize); } -static void init(std::string cache_filename) +static void init(fs::path cache_filename) { MDB_txn *txn; bool tx_active = false; @@ -229,7 +228,8 @@ static void init(std::string cache_filename) MINFO("Creating spent output cache in " << cache_filename); - tools::create_directories_if_necessary(cache_filename); + if (std::error_code ec; !fs::create_directories(cache_filename, ec)) + MWARNING("Failed to create output cache directory " << cache_filename << ": " << ec.message()); int flags = 0; if (db_flags & DBF_FAST) @@ -241,10 +241,10 @@ static void init(std::string cache_filename) CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LDMB environment: " + std::string(mdb_strerror(dbr))); dbr = mdb_env_set_maxdbs(env, 7); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to set max env dbs: " + std::string(mdb_strerror(dbr))); - const std::string actual_filename = get_cache_filename(cache_filename); - dbr = mdb_env_open(env, actual_filename.c_str(), flags, 0664); + auto actual_filename = get_cache_filename(cache_filename); + dbr = mdb_env_open(env, actual_filename.string().c_str(), flags, 0664); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to open rings database file '" - + actual_filename + "': " + std::string(mdb_strerror(dbr))); + + actual_filename.string() + "': " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env, NULL, 0, &txn); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -330,7 +330,7 @@ static std::vector decompress_ring(const std::string &s) return ring; } -static bool for_all_transactions(const std::string &filename, uint64_t &start_idx, uint64_t &n_txes, const std::function &f) +static bool for_all_transactions(const fs::path& filename, uint64_t& start_idx, uint64_t& n_txes, const std::function& f) { MDB_env *env; MDB_dbi dbi; @@ -345,10 +345,9 @@ static bool for_all_transactions(const std::string &filename, uint64_t &start_id if (dbr) throw std::runtime_error("Failed to create LDMB environment: " + std::string(mdb_strerror(dbr))); dbr = mdb_env_set_maxdbs(env, 2); if (dbr) throw std::runtime_error("Failed to set max env dbs: " + std::string(mdb_strerror(dbr))); - const std::string actual_filename = filename; - dbr = mdb_env_open(env, actual_filename.c_str(), 0, 0664); + dbr = mdb_env_open(env, filename.string().c_str(), 0, 0664); if (dbr) throw std::runtime_error("Failed to open rings database file '" - + actual_filename + "': " + std::string(mdb_strerror(dbr))); + + filename.u8string() + "': " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -411,7 +410,7 @@ static bool for_all_transactions(const std::string &filename, uint64_t &start_id return fret; } -static bool for_all_transactions(const std::string &filename, const uint64_t &start_idx, uint64_t &n_txes, const std::function &f) +static bool for_all_transactions(const fs::path& filename, const uint64_t& start_idx, uint64_t& n_txes, const std::function& f) { MDB_env *env; MDB_dbi dbi_blocks, dbi_txs; @@ -426,14 +425,13 @@ static bool for_all_transactions(const std::string &filename, const uint64_t &st if (dbr) throw std::runtime_error("Failed to create LDMB environment: " + std::string(mdb_strerror(dbr))); dbr = mdb_env_set_maxdbs(env, 3); if (dbr) throw std::runtime_error("Failed to set max env dbs: " + std::string(mdb_strerror(dbr))); - const std::string actual_filename = filename; - dbr = mdb_env_open(env, actual_filename.c_str(), 0, 0664); + dbr = mdb_env_open(env, filename.string().c_str(), 0, 0664); if (dbr) throw std::runtime_error("Failed to open rings database file '" - + actual_filename + "': " + std::string(mdb_strerror(dbr))); + + filename.u8string() + "': " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); - epee::misc_utils::auto_scope_leave_caller txn_dtor = epee::misc_utils::create_scope_leave_handler([&](){if (tx_active) mdb_txn_abort(txn);}); + LOKI_DEFER { if (tx_active) mdb_txn_abort(txn); }; tx_active = true; dbr = mdb_dbi_open(txn, "blocks", MDB_INTEGERKEY, &dbi_blocks); @@ -479,7 +477,7 @@ static bool for_all_transactions(const std::string &filename, const uint64_t &st ret = mdb_cursor_get(cur_txs, &k, &v, op_txs); if (ret) - throw std::runtime_error("Failed to fetch transaction " + epee::string_tools::pod_to_hex(get_transaction_hash(b.miner_tx)) + ": " + std::string(mdb_strerror(ret))); + throw std::runtime_error("Failed to fetch transaction " + tools::type_to_hex(get_transaction_hash(b.miner_tx)) + ": " + std::string(mdb_strerror(ret))); op_txs = MDB_NEXT; bool last_block = height == n_blocks - 1; @@ -493,7 +491,7 @@ static bool for_all_transactions(const std::string &filename, const uint64_t &st const crypto::hash& txid = b.tx_hashes[i]; ret = mdb_cursor_get(cur_txs, &k, &v, op_txs); if (ret) - throw std::runtime_error("Failed to fetch transaction " + epee::string_tools::pod_to_hex(txid) + ": " + std::string(mdb_strerror(ret))); + throw std::runtime_error("Failed to fetch transaction " + tools::type_to_hex(txid) + ": " + std::string(mdb_strerror(ret))); if (start_idx <= tx_idx++) { cryptonote::transaction_prefix tx; @@ -520,7 +518,7 @@ static bool for_all_transactions(const std::string &filename, const uint64_t &st return fret; } -static uint64_t find_first_diverging_transaction(const std::string &first_filename, const std::string &second_filename) +static uint64_t find_first_diverging_transaction(const fs::path& first_filename, const fs::path& second_filename) { MDB_env *env[2]; MDB_dbi dbi[2]; @@ -543,10 +541,10 @@ static uint64_t find_first_diverging_transaction(const std::string &first_filena if (dbr) throw std::runtime_error("Failed to create LDMB environment: " + std::string(mdb_strerror(dbr))); dbr = mdb_env_set_maxdbs(env[i], 2); if (dbr) throw std::runtime_error("Failed to set max env dbs: " + std::string(mdb_strerror(dbr))); - const std::string actual_filename = i ? second_filename : first_filename; - dbr = mdb_env_open(env[i], actual_filename.c_str(), 0, 0664); + const fs::path& actual_filename = i ? second_filename : first_filename; + dbr = mdb_env_open(env[i], actual_filename.string().c_str(), 0, 0664); if (dbr) throw std::runtime_error("Failed to open rings database file '" - + actual_filename + "': " + std::string(mdb_strerror(dbr))); + + actual_filename.u8string() + "': " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env[i], NULL, MDB_RDONLY, &txn[i]); if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -951,7 +949,7 @@ static void inc_stat(MDB_txn *txn, const char *key) set_stat(txn, key, data); } -static void open_db(const std::string &filename, MDB_env **env, MDB_txn **txn, MDB_cursor **cur, MDB_dbi *dbi) +static void open_db(const fs::path& filename, MDB_env** env, MDB_txn** txn, MDB_cursor** cur, MDB_dbi* dbi) { tools::create_directories_if_necessary(filename); @@ -965,11 +963,10 @@ static void open_db(const std::string &filename, MDB_env **env, MDB_txn **txn, M CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LDMB environment: " + std::string(mdb_strerror(dbr))); dbr = mdb_env_set_maxdbs(*env, 1); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to set max env dbs: " + std::string(mdb_strerror(dbr))); - const std::string actual_filename = filename; - MINFO("Opening monero blockchain at " << actual_filename); - dbr = mdb_env_open(*env, actual_filename.c_str(), flags, 0664); + MINFO("Opening loki blockchain at " << filename); + dbr = mdb_env_open(*env, filename.string().c_str(), flags, 0664); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to open rings database file '" - + actual_filename + "': " + std::string(mdb_strerror(dbr))); + + filename.u8string() + "': " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(*env, NULL, MDB_RDONLY, txn); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -1014,7 +1011,7 @@ static void get_num_outputs(MDB_txn *txn, MDB_cursor *cur, MDB_dbi dbi, uint64_t pre_rct = s.ms_entries - rct; } -static crypto::hash get_genesis_block_hash(const std::string &filename) +static crypto::hash get_genesis_block_hash(const fs::path& filename) { MDB_env *env; MDB_dbi dbi; @@ -1026,10 +1023,9 @@ static crypto::hash get_genesis_block_hash(const std::string &filename) if (dbr) throw std::runtime_error("Failed to create LDMB environment: " + std::string(mdb_strerror(dbr))); dbr = mdb_env_set_maxdbs(env, 1); if (dbr) throw std::runtime_error("Failed to set max env dbs: " + std::string(mdb_strerror(dbr))); - const std::string actual_filename = filename; - dbr = mdb_env_open(env, actual_filename.c_str(), 0, 0664); + dbr = mdb_env_open(env, filename.string().c_str(), 0, 0664); if (dbr) throw std::runtime_error("Failed to open rings database file '" - + actual_filename + "': " + std::string(mdb_strerror(dbr))); + + filename.u8string() + "': " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn); if (dbr) throw std::runtime_error("Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -1051,13 +1047,18 @@ static crypto::hash get_genesis_block_hash(const std::string &filename) return genesis_block_hash; } -static std::vector> load_outputs(const std::string &filename) +static std::vector> load_outputs(const fs::path& filename) { std::vector> outputs; uint64_t amount = std::numeric_limits::max(); - FILE *f; - f = fopen(filename.c_str(), "r"); + FILE* f = +#ifdef _WIN32 + _wfopen(filename.c_str(), L"r"); +#else + fopen(filename.c_str(), "r"); +#endif + if (!f) { MERROR("Failed to load outputs from " << filename << ": " << strerror(errno)); @@ -1108,9 +1109,15 @@ static std::vector> load_outputs(const std::string return outputs; } -static bool export_spent_outputs(MDB_cursor *cur, const std::string &filename) +static bool export_spent_outputs(MDB_cursor* cur, const fs::path& filename) { - FILE *f = fopen(filename.c_str(), "w"); + FILE* f = +#ifdef _WIN32 + _wfopen(filename.c_str(), L"w"); +#else + fopen(filename.c_str(), "w"); +#endif + if (!f) { MERROR("Failed to open " << filename << ": " << strerror(errno)); @@ -1172,15 +1179,13 @@ int main(int argc, char* argv[]) tools::on_startup(); - boost::filesystem::path output_file_path; - auto opt_size = command_line::boost_option_sizes(); po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second); po::options_description desc_cmd_sett("Command line options and settings options", opt_size.first, opt_size.second); const command_line::arg_descriptor arg_blackball_db_dir = { "spent-output-db-dir", "Specify spent output database directory", - get_default_db_path(), + get_default_db_path().u8string(), }; const command_line::arg_descriptor arg_log_level = {"log-level", "0-4 or categories", ""}; const command_line::arg_descriptor arg_rct_only = {"rct-only", "Only work on ringCT outputs", false}; @@ -1242,7 +1247,7 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("Starting..."); - output_file_path = command_line::get_arg(vm, arg_blackball_db_dir); + fs::path output_file_path = fs::u8path(command_line::get_arg(vm, arg_blackball_db_dir)); bool opt_rct_only = command_line::get_arg(vm, arg_rct_only); bool opt_check_subsets = command_line::get_arg(vm, arg_check_subsets); bool opt_verbose = command_line::get_arg(vm, arg_verbose); @@ -1260,7 +1265,9 @@ int main(int argc, char* argv[]) return 1; } - const std::vector inputs = command_line::get_arg(vm, arg_inputs); + std::vector inputs; + for (auto& in : command_line::get_arg(vm, arg_inputs)) + inputs.push_back(fs::u8path(in)); if (inputs.empty()) { LOG_PRINT_L0("No inputs given"); @@ -1274,7 +1281,7 @@ int main(int argc, char* argv[]) core_storage[n] = &(blockchain_objects->m_blockchain); } - const std::string cache_dir = (output_file_path / "spent-outputs-cache").string(); + fs::path cache_dir = output_file_path / "spent-outputs-cache"; init(cache_dir); LOG_PRINT_L0("Scanning for spent outputs..."); @@ -1283,14 +1290,14 @@ int main(int argc, char* argv[]) const uint64_t start_blackballed_outputs = get_num_spent_outputs(); - tools::ringdb ringdb(output_file_path.string(), epee::string_tools::pod_to_hex(get_genesis_block_hash(inputs[0]))); + tools::ringdb ringdb(output_file_path.string(), tools::type_to_hex(get_genesis_block_hash(inputs[0]))); bool stop_requested = false; tools::signal_handler::install([&stop_requested](int type) { stop_requested = true; }); - int dbr = resize_env(cache_dir.c_str()); + int dbr = resize_env(cache_dir.string().c_str()); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to resize LMDB database: " + std::string(mdb_strerror(dbr))); // open first db @@ -1395,7 +1402,7 @@ int main(int argc, char* argv[]) for (size_t n = 0; n < inputs.size(); ++n) { - const std::string canonical = boost::filesystem::canonical(inputs[n]).string(); + const std::string canonical = fs::canonical(inputs[n]).u8string(); uint64_t start_idx = get_processed_txidx(canonical); if (n > 0 && start_idx == 0) { @@ -1410,10 +1417,9 @@ int main(int argc, char* argv[]) dbr = mdb_cursor_open(txn, dbi_spent, &cur); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to open LMDB cursor: " + std::string(mdb_strerror(dbr))); size_t records = 0; - const std::string filename = inputs[n]; std::vector> blackballs; uint64_t n_txes; - for_all_transactions(filename, start_idx, n_txes, [&](const cryptonote::transaction_prefix &tx)->bool + for_all_transactions(inputs[n], start_idx, n_txes, [&](const cryptonote::transaction_prefix &tx)->bool { std::cout << "\r" << start_idx << "/" << n_txes << " \r" << std::flush; for (const auto &in: tx.vin) @@ -1573,7 +1579,7 @@ int main(int argc, char* argv[]) mdb_cursor_close(cur); dbr = mdb_txn_commit(txn); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to commit txn creating/opening database: " + std::string(mdb_strerror(dbr))); - int dbr = resize_env(cache_dir.c_str()); + int dbr = resize_env(cache_dir.string().c_str()); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to resize LMDB database: " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env, NULL, 0, &txn); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -1613,7 +1619,7 @@ int main(int argc, char* argv[]) { LOG_PRINT_L0("Secondary pass on " << work_spent.size() << " spent outputs"); - int dbr = resize_env(cache_dir.c_str()); + int dbr = resize_env(cache_dir.string().c_str()); CHECK_AND_ASSERT_THROW_MES(!dbr, "Failed to resize LMDB database: " + std::string(mdb_strerror(dbr))); MDB_txn *txn; diff --git a/src/blockchain_utilities/blockchain_depth.cpp b/src/blockchain_utilities/blockchain_depth.cpp index 155ea572d..aa9b505f7 100644 --- a/src/blockchain_utilities/blockchain_depth.cpp +++ b/src/blockchain_utilities/blockchain_depth.cpp @@ -49,8 +49,6 @@ int main(int argc, char* argv[]) tools::on_startup(); - boost::filesystem::path output_file_path; - auto opt_size = command_line::boost_option_sizes(); po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second); @@ -98,7 +96,6 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("Starting..."); - std::string opt_data_dir = command_line::get_arg(vm, cryptonote::arg_data_dir); bool opt_testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on); bool opt_devnet = command_line::get_arg(vm, cryptonote::arg_devnet_on); network_type net_type = opt_testnet ? TESTNET : opt_devnet ? DEVNET : MAINNET; @@ -114,7 +111,7 @@ int main(int argc, char* argv[]) crypto::hash opt_txid = crypto::null_hash; if (!opt_txid_string.empty()) { - if (!epee::string_tools::hex_to_pod(opt_txid_string, opt_txid)) + if (!tools::hex_to_type(opt_txid_string, opt_txid)) { std::cerr << "Invalid txid" << std::endl; return 1; @@ -132,7 +129,7 @@ int main(int argc, char* argv[]) } LOG_PRINT_L0("database: LMDB"); - const std::string filename = (boost::filesystem::path(opt_data_dir) / db->get_db_name()).string(); + const fs::path filename = fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir)) / db->get_db_name(); LOG_PRINT_L0("Loading blockchain from folder " << filename << " ..."); try diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp index fa58dd3d1..88af125fe 100644 --- a/src/blockchain_utilities/blockchain_export.cpp +++ b/src/blockchain_utilities/blockchain_export.cpp @@ -51,8 +51,6 @@ int main(int argc, char* argv[]) tools::on_startup(); - boost::filesystem::path output_file_path; - auto opt_size = command_line::boost_option_sizes(); po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second); @@ -111,14 +109,13 @@ int main(int argc, char* argv[]) } bool opt_blocks_dat = command_line::get_arg(vm, arg_blocks_dat); - std::string m_config_folder; - - m_config_folder = command_line::get_arg(vm, cryptonote::arg_data_dir); + auto config_folder = fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir)); + fs::path output_file_path; if (command_line::has_arg(vm, arg_output_file)) - output_file_path = boost::filesystem::path(command_line::get_arg(vm, arg_output_file)); + output_file_path = fs::u8path(command_line::get_arg(vm, arg_output_file)); else - output_file_path = boost::filesystem::path(m_config_folder) / "export" / BLOCKCHAIN_RAW; + output_file_path = config_folder / "export" / BLOCKCHAIN_RAW; LOG_PRINT_L0("Export output file: " << output_file_path.string()); LOG_PRINT_L0("Initializing source blockchain (BlockchainDB)"); @@ -132,9 +129,7 @@ int main(int argc, char* argv[]) } LOG_PRINT_L0("database: LMDB"); - boost::filesystem::path folder(m_config_folder); - folder /= db->get_db_name(); - const std::string filename = folder.string(); + auto filename = config_folder / db->get_db_name(); LOG_PRINT_L0("Loading blockchain from folder " << filename << " ..."); try diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index c6c62266c..302c715d2 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -32,18 +32,17 @@ #include #include -#include #include #include #include "cryptonote_protocol/quorumnet.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "bootstrap_file.h" #include "bootstrap_serialization.h" #include "blocks/blocks.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "serialization/binary_utils.h" -#include "include_base_utils.h" #include "cryptonote_core/cryptonote_core.h" +#include "common/hex.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "bcutil" @@ -143,7 +142,7 @@ int check_flush(cryptonote::core &core, std::vector &block if (!parse_and_validate_block_from_blob(b.block, block)) { MERROR("Failed to parse block: " - << epee::string_tools::pod_to_hex(get_blob_hash(b.block))); + << tools::type_to_hex(get_blob_hash(b.block))); core.cleanup_handle_incoming_blocks(); return 1; } @@ -176,7 +175,7 @@ int check_flush(cryptonote::core &core, std::vector &block if(tvc.m_verifivation_failed) { MERROR("transaction verification failed, tx_id = " - << epee::string_tools::pod_to_hex(get_blob_hash(tx_blob))); + << tools::type_to_hex(get_blob_hash(tx_blob))); core.cleanup_handle_incoming_blocks(); return 1; } @@ -191,7 +190,7 @@ int check_flush(cryptonote::core &core, std::vector &block if(bvc.m_verifivation_failed) { MERROR("Block verification failed, id = " - << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block))); + << tools::type_to_hex(get_blob_hash(block_entry.block))); core.cleanup_handle_incoming_blocks(); return 1; } @@ -210,18 +209,16 @@ int check_flush(cryptonote::core &core, std::vector &block return 0; } -int import_from_file(cryptonote::core& core, const std::string& import_file_path, uint64_t block_stop=0) +int import_from_file(cryptonote::core& core, const fs::path& import_file_path, uint64_t block_stop=0) { // Reset stats, in case we're using newly created db, accumulating stats // from addition of genesis block. // This aligns internal db counts with importer counts. core.get_blockchain_storage().get_db().reset_stats(); - boost::filesystem::path fs_import_file_path(import_file_path); - boost::system::error_code ec; - if (!boost::filesystem::exists(fs_import_file_path, ec)) + if (std::error_code ec; !fs::exists(import_file_path, ec)) { - MFATAL("bootstrap file not found: " << fs_import_file_path); + MFATAL("bootstrap file not found: " << import_file_path); return false; } @@ -243,11 +240,8 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path std::cout << "\nPreparing to read blocks...\n\n"; - std::ifstream import_file; - import_file.open(import_file_path, std::ios_base::binary | std::ifstream::in); + fs::ifstream import_file{import_file_path, std::ios::binary}; - uint64_t h = 0; - uint64_t num_imported = 0; if (import_file.fail()) { MFATAL("import_file.open() fail"); @@ -284,6 +278,9 @@ int import_from_file(cryptonote::core& core, const std::string& import_file_path std::vector blocks; + uint64_t h = 0; + uint64_t num_imported = 0; + // Skip to start_height before we start adding. { bool q2 = false; @@ -542,8 +539,6 @@ int main(int argc, char* argv[]) tools::on_startup(); - std::string import_file_path; - auto opt_size = command_line::boost_option_sizes(); po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second); @@ -653,14 +648,12 @@ int main(int argc, char* argv[]) MINFO("Starting..."); - boost::filesystem::path fs_import_file_path; + fs::path import_file_path; if (command_line::has_arg(vm, arg_input_file)) - fs_import_file_path = boost::filesystem::path(command_line::get_arg(vm, arg_input_file)); + import_file_path = fs::u8path(command_line::get_arg(vm, arg_input_file)); else - fs_import_file_path = boost::filesystem::path(m_config_folder) / "export" / BLOCKCHAIN_RAW; - - import_file_path = fs_import_file_path.string(); + import_file_path = fs::u8path(m_config_folder) / "export" / BLOCKCHAIN_RAW; if (command_line::has_arg(vm, arg_count_blocks)) { diff --git a/src/blockchain_utilities/blockchain_prune.cpp b/src/blockchain_utilities/blockchain_prune.cpp index 2a1499645..276db1ae8 100644 --- a/src/blockchain_utilities/blockchain_prune.cpp +++ b/src/blockchain_utilities/blockchain_prune.cpp @@ -31,6 +31,7 @@ #include "common/command_line.h" #include "common/pruning.h" #include "common/string_util.h" +#include "common/fs.h" #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_core/blockchain.h" #include "blockchain_db/blockchain_db.h" @@ -46,21 +47,21 @@ namespace po = boost::program_options; using namespace cryptonote; -static std::string db_path; +static fs::path db_path; // default to fast:1 static uint64_t records_per_sync = 128; static const size_t slack = 512 * 1024 * 1024; -static std::error_code replace_file(const boost::filesystem::path& replacement_name, const boost::filesystem::path& replaced_name) +static std::error_code replace_file(const fs::path& replacement_name, const fs::path& replaced_name) { - std::error_code ec = tools::replace_file(replacement_name.string(), replaced_name.string()); + std::error_code ec = fs::rename(replacement_name, replaced_name); if (ec) MERROR("Error renaming " << replacement_name << " to " << replaced_name << ": " << ec.message()); return ec; } -static void open(MDB_env *&env, const boost::filesystem::path &path, uint64_t db_flags, bool readonly) +static void open(MDB_env *&env, const fs::path &path, uint64_t db_flags, bool readonly) { int dbr; int flags = 0; @@ -90,8 +91,7 @@ static void add_size(MDB_env *env, uint64_t bytes) { try { - boost::filesystem::path path(db_path); - boost::filesystem::space_info si = boost::filesystem::space(path); + auto si = fs::space(db_path); if(si.available < bytes) { MERROR("!! WARNING: Insufficient free space to extend database !!: " << @@ -443,8 +443,6 @@ int main(int argc, char* argv[]) tools::on_startup(); - boost::filesystem::path output_file_path; - auto opt_size = command_line::boost_option_sizes(); po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second); @@ -523,7 +521,7 @@ int main(int argc, char* argv[]) // tx_memory_pool, Blockchain's constructor takes tx_memory_pool object. MINFO("Initializing source blockchain (BlockchainDB)"); std::array core_storage; - boost::filesystem::path paths[2]; + fs::path paths[2]; bool already_pruned = false; for (size_t n = 0; n < core_storage.size(); ++n) { @@ -539,10 +537,10 @@ int main(int argc, char* argv[]) if (n == 1) { - paths[1] = boost::filesystem::path(data_dir) / (db->get_db_name() + "-pruned"); - if (boost::filesystem::exists(paths[1])) + paths[1] = fs::u8path(data_dir) / (db->get_db_name() + "-pruned"); + if (fs::exists(paths[1])) { - if (!boost::filesystem::is_directory(paths[1])) + if (!fs::is_directory(paths[1])) { MERROR("LMDB needs a directory path, but a file was passed: " << paths[1].string()); return 1; @@ -550,17 +548,17 @@ int main(int argc, char* argv[]) } else { - if (!boost::filesystem::create_directories(paths[1])) + if (!fs::create_directories(paths[1])) { MERROR("Failed to create directory: " << paths[1].string()); return 1; } } - db_path = paths[1].string(); + db_path = paths[1]; } else { - paths[0] = boost::filesystem::path(data_dir) / db->get_db_name(); + paths[0] = fs::u8path(data_dir) / db->get_db_name(); } MINFO("Loading blockchain from folder " << paths[n] << " ..."); @@ -627,7 +625,9 @@ int main(int argc, char* argv[]) close(env0); MINFO("Swapping databases, pre-pruning blockchain will be left in " << paths[0].string() + "-old and can be removed if desired"); - if (replace_file(paths[0].string(), paths[0].string() + "-old") || replace_file(paths[1].string(), paths[0].string())) + fs::path old = paths[0]; + old += "-old"; + if (replace_file(paths[0], old) || replace_file(paths[1], paths[0])) { MERROR("Blockchain pruned OK, but renaming failed"); return 1; diff --git a/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp b/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp index dc1175df5..0f94a7c62 100644 --- a/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp +++ b/src/blockchain_utilities/blockchain_prune_known_spent_data.cpp @@ -30,7 +30,6 @@ #define __STDC_FORMAT_MACROS // NOTE(loki): Explicitly define the PRIu64 macro on Mingw #endif -#include #include "common/command_line.h" #include "serialization/crypto.h" #include "cryptonote_core/cryptonote_core.h" @@ -44,13 +43,18 @@ namespace po = boost::program_options; using namespace cryptonote; -static std::map load_outputs(const std::string &filename) +static std::map load_outputs(const fs::path& filename) { std::map outputs; uint64_t amount = std::numeric_limits::max(); - FILE *f; - f = fopen(filename.c_str(), "r"); + FILE *f = +#ifdef _WIN32 + _wfopen(filename.c_str(), L"r"); +#else + fopen(filename.c_str(), "r"); +#endif + if (!f) { MERROR("Failed to load outputs from " << filename << ": " << strerror(errno)); @@ -154,14 +158,13 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("Starting..."); - std::string opt_data_dir = command_line::get_arg(vm, cryptonote::arg_data_dir); bool opt_testnet = command_line::get_arg(vm, cryptonote::arg_testnet_on); bool opt_devnet = command_line::get_arg(vm, cryptonote::arg_devnet_on); network_type net_type = opt_testnet ? TESTNET : opt_devnet ? DEVNET : MAINNET; bool opt_verbose = command_line::get_arg(vm, arg_verbose); bool opt_dry_run = command_line::get_arg(vm, arg_dry_run); - const std::string input = command_line::get_arg(vm, arg_input); + const auto input = fs::u8path(command_line::get_arg(vm, arg_input)); LOG_PRINT_L0("Initializing source blockchain (BlockchainDB)"); blockchain_objects_t blockchain_objects = {}; @@ -173,7 +176,7 @@ int main(int argc, char* argv[]) throw std::runtime_error("Failed to initialize a database"); } - const std::string filename = (boost::filesystem::path(opt_data_dir) / db->get_db_name()).string(); + const fs::path filename = fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir)) / db->get_db_name(); LOG_PRINT_L0("Loading blockchain from folder " << filename << " ..."); try diff --git a/src/blockchain_utilities/blockchain_stats.cpp b/src/blockchain_utilities/blockchain_stats.cpp index ee27d8301..8f055a62e 100644 --- a/src/blockchain_utilities/blockchain_stats.cpp +++ b/src/blockchain_utilities/blockchain_stats.cpp @@ -35,7 +35,7 @@ #include "blockchain_objects.h" #include "blockchain_db/blockchain_db.h" #include "version.h" -#include "misc_os_dependent.h" +#include "epee/misc_os_dependent.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "bcutil" @@ -57,8 +57,6 @@ int main(int argc, char* argv[]) tools::on_startup(); - boost::filesystem::path output_file_path; - auto opt_size = command_line::boost_option_sizes(); po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second); @@ -133,7 +131,7 @@ int main(int argc, char* argv[]) throw std::runtime_error("Failed to initialize a database"); } - const std::string filename = (boost::filesystem::path(opt_data_dir) / db->get_db_name()).string(); + const fs::path filename = fs::u8path(opt_data_dir) / db->get_db_name(); LOG_PRINT_L0("Loading blockchain from folder " << filename << " ..."); try diff --git a/src/blockchain_utilities/blockchain_usage.cpp b/src/blockchain_utilities/blockchain_usage.cpp index 521ff77f8..d0c6b9e01 100644 --- a/src/blockchain_utilities/blockchain_usage.cpp +++ b/src/blockchain_utilities/blockchain_usage.cpp @@ -82,8 +82,6 @@ int main(int argc, char* argv[]) tools::on_startup(); - boost::filesystem::path output_file_path; - auto opt_size = command_line::boost_option_sizes(); po::options_description desc_cmd_only("Command line options", opt_size.first, opt_size.second); @@ -160,7 +158,7 @@ int main(int argc, char* argv[]) } LOG_PRINT_L0("database: LMDB"); - const std::string filename = input; + const fs::path filename = fs::u8path(input); LOG_PRINT_L0("Loading blockchain from folder " << filename << " ..."); try diff --git a/src/blockchain_utilities/blocksdat_file.cpp b/src/blockchain_utilities/blocksdat_file.cpp index a3a69bd44..673d2c0ac 100644 --- a/src/blockchain_utilities/blocksdat_file.cpp +++ b/src/blockchain_utilities/blocksdat_file.cpp @@ -43,14 +43,14 @@ namespace -bool BlocksdatFile::open_writer(const boost::filesystem::path& file_path, uint64_t block_stop) +bool BlocksdatFile::open_writer(const fs::path& file_path, uint64_t block_stop) { - const boost::filesystem::path dir_path = file_path.parent_path(); + const fs::path dir_path = file_path.parent_path(); if (!dir_path.empty()) { - if (boost::filesystem::exists(dir_path)) + if (fs::exists(dir_path)) { - if (!boost::filesystem::is_directory(dir_path)) + if (!fs::is_directory(dir_path)) { MFATAL("export directory path is a file: " << dir_path); return false; @@ -58,7 +58,7 @@ bool BlocksdatFile::open_writer(const boost::filesystem::path& file_path, uint64 } else { - if (!boost::filesystem::create_directory(dir_path)) + if (!fs::create_directory(dir_path)) { MFATAL("Failed to create directory " << dir_path); return false; @@ -124,7 +124,7 @@ bool BlocksdatFile::close() } -bool BlocksdatFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop) +bool BlocksdatFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, fs::path& output_file, uint64_t requested_block_stop) { uint64_t num_blocks_written = 0; m_blockchain_storage = _blockchain_storage; diff --git a/src/blockchain_utilities/blocksdat_file.h b/src/blockchain_utilities/blocksdat_file.h index 315713424..021403d93 100644 --- a/src/blockchain_utilities/blocksdat_file.h +++ b/src/blockchain_utilities/blocksdat_file.h @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_boost_serialization.h" @@ -47,6 +45,7 @@ #include #include "common/command_line.h" +#include "common/fs.h" #include "version.h" #include "blockchain_utilities.h" @@ -60,7 +59,7 @@ class BlocksdatFile public: bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp, - boost::filesystem::path& output_file, uint64_t use_block_height=0); + fs::path& output_file, uint64_t use_block_height=0); protected: @@ -69,7 +68,7 @@ protected: std::ofstream * m_raw_data_file; // open export file for write - bool open_writer(const boost::filesystem::path& file_path, uint64_t block_stop); + bool open_writer(const fs::path& file_path, uint64_t block_stop); bool initialize_file(uint64_t block_stop); bool close(); void write_block(const crypto::hash &block_hash); diff --git a/src/blockchain_utilities/bootstrap_file.cpp b/src/blockchain_utilities/bootstrap_file.cpp index f390436de..f30739eee 100644 --- a/src/blockchain_utilities/bootstrap_file.cpp +++ b/src/blockchain_utilities/bootstrap_file.cpp @@ -51,14 +51,14 @@ namespace -bool BootstrapFile::open_writer(const boost::filesystem::path& file_path) +bool BootstrapFile::open_writer(const fs::path& file_path) { - const boost::filesystem::path dir_path = file_path.parent_path(); + const auto dir_path = file_path.parent_path(); if (!dir_path.empty()) { - if (boost::filesystem::exists(dir_path)) + if (fs::exists(dir_path)) { - if (!boost::filesystem::is_directory(dir_path)) + if (!fs::is_directory(dir_path)) { MFATAL("export directory path is a file: " << dir_path); return false; @@ -66,7 +66,7 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path) } else { - if (!boost::filesystem::create_directory(dir_path)) + if (!fs::create_directory(dir_path)) { MFATAL("Failed to create directory " << dir_path); return false; @@ -79,7 +79,7 @@ bool BootstrapFile::open_writer(const boost::filesystem::path& file_path) bool do_initialize_file = false; uint64_t num_blocks = 0; - if (! boost::filesystem::exists(file_path)) + if (! fs::exists(file_path)) { MDEBUG("creating file"); do_initialize_file = true; @@ -264,7 +264,7 @@ bool BootstrapFile::close() } -bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop) +bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, fs::path& output_file, uint64_t requested_block_stop) { uint64_t num_blocks_written = 0; m_max_chunk = 0; @@ -326,7 +326,7 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem return BootstrapFile::close(); } -uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file) +uint64_t BootstrapFile::seek_to_first_chunk(fs::ifstream& import_file) { uint32_t file_magic; @@ -386,7 +386,7 @@ uint64_t BootstrapFile::seek_to_first_chunk(std::ifstream& import_file) return full_header_size; } -uint64_t BootstrapFile::count_bytes(std::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit) +uint64_t BootstrapFile::count_bytes(fs::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit) { uint64_t bytes_read = 0; uint32_t chunk_size; @@ -445,7 +445,7 @@ uint64_t BootstrapFile::count_bytes(std::ifstream& import_file, uint64_t blocks, return bytes_read; } -uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) +uint64_t BootstrapFile::count_blocks(const fs::path& import_file_path) { std::streampos dummy_pos; uint64_t dummy_height = 0; @@ -455,17 +455,14 @@ uint64_t BootstrapFile::count_blocks(const std::string& import_file_path) // If seek_height is non-zero on entry, return a stream position <= this height when finished. // And return the actual height corresponding to this position. Allows the caller to locate its // starting position without having to reread the entire file again. -uint64_t BootstrapFile::count_blocks(const std::string& import_file_path, std::streampos &start_pos, uint64_t& seek_height) +uint64_t BootstrapFile::count_blocks(const fs::path& import_file_path, std::streampos &start_pos, uint64_t& seek_height) { - boost::filesystem::path raw_file_path(import_file_path); - boost::system::error_code ec; - if (!boost::filesystem::exists(raw_file_path, ec)) + if (std::error_code ec; !fs::exists(import_file_path, ec)) { - MFATAL("bootstrap file not found: " << raw_file_path); + MFATAL("bootstrap file not found: " << import_file_path); throw std::runtime_error("Aborting"); } - std::ifstream import_file; - import_file.open(import_file_path, std::ios_base::binary | std::ifstream::in); + fs::ifstream import_file{import_file_path, std::ios::binary}; uint64_t start_height = seek_height; uint64_t h = 0; diff --git a/src/blockchain_utilities/bootstrap_file.h b/src/blockchain_utilities/bootstrap_file.h index 5fb2cf366..9510a21bb 100644 --- a/src/blockchain_utilities/bootstrap_file.h +++ b/src/blockchain_utilities/bootstrap_file.h @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_core/blockchain.h" @@ -45,6 +43,7 @@ #include #include "common/command_line.h" +#include "common/fs.h" #include "version.h" #include "blockchain_utilities.h" @@ -57,13 +56,13 @@ class BootstrapFile { public: - uint64_t count_bytes(std::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit); - uint64_t count_blocks(const std::string& dir_path, std::streampos& start_pos, uint64_t& seek_height); - uint64_t count_blocks(const std::string& dir_path); - uint64_t seek_to_first_chunk(std::ifstream& import_file); + uint64_t count_bytes(fs::ifstream& import_file, uint64_t blocks, uint64_t& h, bool& quit); + uint64_t count_blocks(const fs::path& dir_path, std::streampos& start_pos, uint64_t& seek_height); + uint64_t count_blocks(const fs::path& dir_path); + uint64_t seek_to_first_chunk(fs::ifstream& import_file); bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp, - boost::filesystem::path& output_file, uint64_t use_block_height=0); + fs::path& output_file, uint64_t use_block_height=0); protected: @@ -76,7 +75,7 @@ protected: boost::iostreams::stream>* m_output_stream; // open export file for write - bool open_writer(const boost::filesystem::path& file_path); + bool open_writer(const fs::path& file_path); bool initialize_file(); bool close(); void write_block(block& block); diff --git a/src/blockchain_utilities/sn_key_tool.cpp b/src/blockchain_utilities/sn_key_tool.cpp index aae5ec20f..16b980d3f 100644 --- a/src/blockchain_utilities/sn_key_tool.cpp +++ b/src/blockchain_utilities/sn_key_tool.cpp @@ -12,6 +12,7 @@ extern "C" { #include #include #include +#include "common/fs.h" std::string_view arg0; @@ -115,11 +116,8 @@ int generate(bool ed25519, std::list args) { if (pubkey_pos != std::string::npos) overwrite = true; - if (!overwrite) { - std::ifstream f{filename}; - if (f.good()) - return error(2, filename + " to generate already exists, pass `--overwrite' if you want to overwrite it"); - } + if (!overwrite && fs::exists(fs::u8path(filename))) + return error(2, filename + " to generate already exists, pass `--overwrite' if you want to overwrite it"); std::array pubkey; std::array seckey; @@ -140,7 +138,7 @@ int generate(bool ed25519, std::list args) { if (pubkey_pos != std::string::npos) filename.replace(pubkey_pos, 6, lokimq::to_hex(pubkey.begin(), pubkey.end())); - std::ofstream out{filename, std::ios::trunc | std::ios::binary}; + fs::ofstream out{fs::u8path(filename), std::ios::trunc | std::ios::binary}; if (!out.good()) return error(2, "Failed to open output file '" + filename + "': " + std::strerror(errno)); if (ed25519) @@ -191,10 +189,10 @@ int show(std::list args) { else if (args.size() > 1) return error(2, "unknown arguments to 'show'"); - std::string filename{args.front()}; - std::ifstream in{filename, std::ios::binary}; + fs::path filename = fs::u8path(args.front()); + fs::ifstream in{filename, std::ios::binary}; if (!in.good()) - return error(2, "Unable to open '" + filename + "': " + std::strerror(errno)); + return error(2, "Unable to open '" + filename.u8string() + "': " + std::strerror(errno)); in.seekg(0, std::ios::end); auto size = in.tellg(); @@ -216,12 +214,12 @@ int show(std::list args) { std::array seckey; in.read(reinterpret_cast(seckey.data()), size >= 64 ? 64 : 32); if (!in.good()) - return error(2, "Failed to read from " + filename + ": " + std::strerror(errno)); + return error(2, "Failed to read from " + filename.u8string() + ": " + std::strerror(errno)); if (legacy) { pubkey = pubkey_from_privkey(seckey); - std::cout << filename << " (legacy SN keypair)" << "\n==========" << + std::cout << filename.u8string() << " (legacy SN keypair)" << "\n==========" << "\nPrivate key: " << lokimq::to_hex(seckey.begin(), seckey.begin() + 32) << "\nPublic key: " << lokimq::to_hex(pubkey.begin(), pubkey.end()) << "\n\n"; return 0; @@ -318,13 +316,11 @@ int restore(bool ed25519, std::list args) { if (pubkey_pos != std::string::npos) filename.replace(pubkey_pos, 6, lokimq::to_hex(pubkey.begin(), pubkey.end())); - if (!overwrite) { - std::ifstream f{filename}; - if (f.good()) - return error(2, filename + " to generate already exists, pass `--overwrite' if you want to overwrite it"); - } + auto filepath = fs::u8path(filename); + if (!overwrite && fs::exists(filepath)) + return error(2, filename + " to generate already exists, pass `--overwrite' if you want to overwrite it"); - std::ofstream out{filename, std::ios::trunc | std::ios::binary}; + fs::ofstream out{filepath, std::ios::trunc | std::ios::binary}; if (!out.good()) return error(2, "Failed to open output file '" + filename + "': " + std::strerror(errno)); if (ed25519) diff --git a/src/checkpoints/CMakeLists.txt b/src/checkpoints/CMakeLists.txt index cc8503c40..e9e9d072b 100644 --- a/src/checkpoints/CMakeLists.txt +++ b/src/checkpoints/CMakeLists.txt @@ -35,8 +35,7 @@ target_link_libraries(checkpoints PRIVATE common cryptonote_basic - Boost::date_time Boost::program_options Boost::serialization - Boost::filesystem + filesystem extra) diff --git a/src/checkpoints/checkpoints.cpp b/src/checkpoints/checkpoints.cpp index 63e572ab4..25a4ad05d 100644 --- a/src/checkpoints/checkpoints.cpp +++ b/src/checkpoints/checkpoints.cpp @@ -31,9 +31,9 @@ #include "checkpoints.h" -#include "string_tools.h" -#include "storages/portable_storage_template_helper.h" // epee json include -#include "serialization/keyvalue_serialization.h" +#include "epee/string_tools.h" +#include "epee/storages/portable_storage_template_helper.h" // epee json include +#include "epee/serialization/keyvalue_serialization.h" #include "cryptonote_core/service_node_rules.h" #include #include "blockchain_db/blockchain_db.h" @@ -41,6 +41,8 @@ #include "common/loki_integration_test_hooks.h" #include "common/loki.h" +#include "common/file.h" +#include "common/hex.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "checkpoints" @@ -82,23 +84,24 @@ namespace cryptonote uint64_t last_index = loki::array_count(HARDCODED_MAINNET_CHECKPOINTS) - 1; height_to_hash const &entry = HARDCODED_MAINNET_CHECKPOINTS[last_index]; - if (epee::string_tools::hex_to_pod(entry.hash, result)) + if (tools::hex_to_type(entry.hash, result)) *height = entry.height; } return result; } - bool load_checkpoints_from_json(const std::string &json_hashfile_fullpath, std::vector &checkpoint_hashes) + bool load_checkpoints_from_json(const fs::path& json_hashfile_fullpath, std::vector& checkpoint_hashes) { - boost::system::error_code errcode; - if (! (boost::filesystem::exists(json_hashfile_fullpath, errcode))) + if (std::error_code ec; !fs::exists(json_hashfile_fullpath, ec)) { LOG_PRINT_L1("Blockchain checkpoints file not found"); return true; } height_to_hash_json hashes; - if (!epee::serialization::load_t_from_json_file(hashes, json_hashfile_fullpath)) + if (std::string contents; + !tools::slurp_file(json_hashfile_fullpath, contents) || + !epee::serialization::load_t_from_json(hashes, contents)) { MERROR("Error loading checkpoints from " << json_hashfile_fullpath); return false; @@ -125,7 +128,7 @@ namespace cryptonote bool checkpoints::add_checkpoint(uint64_t height, const std::string& hash_str) { crypto::hash h = crypto::null_hash; - bool r = epee::string_tools::hex_to_pod(hash_str, h); + bool r = tools::hex_to_type(hash_str, h); CHECK_AND_ASSERT_MES(r, false, "Failed to parse checkpoint hash string into binary representation!"); checkpoint_t checkpoint = {}; diff --git a/src/checkpoints/checkpoints.h b/src/checkpoints/checkpoints.h index 332617669..0d557c0d0 100644 --- a/src/checkpoints/checkpoints.h +++ b/src/checkpoints/checkpoints.h @@ -31,11 +31,12 @@ #pragma once #include -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "crypto/hash.h" #include "cryptonote_config.h" #include "cryptonote_core/service_node_voting.h" #include "cryptonote_basic/cryptonote_basic_impl.h" +#include "common/fs.h" #define ADD_CHECKPOINT(h, hash) CHECK_AND_ASSERT(add_checkpoint(h, hash), false); #define JSON_HASH_FILE_NAME "checkpoints.json" @@ -100,7 +101,7 @@ namespace cryptonote }; crypto::hash get_newest_hardcoded_checkpoint(cryptonote::network_type nettype, uint64_t *height); - bool load_checkpoints_from_json (const std::string &json_hashfile_fullpath, std::vector &checkpoint_hashes); + bool load_checkpoints_from_json (const fs::path& json_hashfile_fullpath, std::vector& checkpoint_hashes); /** * @brief A container for blockchain checkpoints diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index bb566645d..7c5bcd5cc 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -49,7 +49,6 @@ add_library(common spawn.cpp string_util.cpp threadpool.cpp - timings.cc util.cpp ${PROJECT_BINARY_DIR}/translations/translation_files.cpp ) @@ -73,6 +72,7 @@ target_link_libraries(common PUBLIC cncrypto lokimq::lokimq + filesystem PRIVATE libunbound OpenSSL::SSL diff --git a/src/common/apply_permutation.h b/src/common/apply_permutation.h index a4b2c8b78..a6058286e 100644 --- a/src/common/apply_permutation.h +++ b/src/common/apply_permutation.h @@ -34,7 +34,7 @@ #include #include -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" namespace tools { diff --git a/src/common/base58.cpp b/src/common/base58.cpp index e12b78991..89880c631 100644 --- a/src/common/base58.cpp +++ b/src/common/base58.cpp @@ -36,7 +36,7 @@ #include #include "crypto/hash.h" -#include "int-util.h" +#include "epee/int-util.h" #include "varint.h" namespace tools diff --git a/src/common/boost_serialization_helper.h b/src/common/boost_serialization_helper.h index 2280f3312..caa017164 100644 --- a/src/common/boost_serialization_helper.h +++ b/src/common/boost_serialization_helper.h @@ -30,93 +30,58 @@ #pragma once +#include "epee/misc_log_ex.h" #include #include #include -#include +#include "fs.h" namespace tools { - template - bool serialize_obj_to_file(t_object& obj, const std::string& file_path) + template + bool serialize_obj_to_file(T& obj, const fs::path& file_path) { TRY_ENTRY(); -#if defined(_MSC_VER) - // Need to know HANDLE of file to call FlushFileBuffers - HANDLE data_file_handle = ::CreateFile(file_path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (INVALID_HANDLE_VALUE == data_file_handle) - return false; - - int data_file_descriptor = _open_osfhandle((intptr_t)data_file_handle, 0); - if (-1 == data_file_descriptor) - { - ::CloseHandle(data_file_handle); - return false; - } - - const std::unique_ptr data_file_file{_fdopen(data_file_descriptor, "wb")}; - if (nullptr == data_file_file) - { - // Call CloseHandle is not necessary - _close(data_file_descriptor); - return false; - } - - // HACK: undocumented constructor, this code may not compile - std::ofstream data_file(data_file_file.get()); - if (data_file.fail()) - { - // Call CloseHandle and _close are not necessary - return false; - } -#else - std::ofstream data_file; - data_file.open(file_path , std::ios_base::binary | std::ios_base::out| std::ios::trunc); + fs::ofstream data_file{file_path, std::ios::binary | std::ios::trunc}; if (data_file.fail()) return false; -#endif - boost::archive::portable_binary_oarchive a(data_file); - a << obj; + boost::archive::portable_binary_oarchive{data_file} << obj; + if (data_file.fail()) return false; data_file.flush(); -#if defined(_MSC_VER) - // To make sure the file is fully stored on disk - ::FlushFileBuffers(data_file_handle); -#endif return true; CATCH_ENTRY_L0("serialize_obj_to_file", false); } - template - bool unserialize_obj_from_file(t_object& obj, const std::string& file_path) + template + bool unserialize_obj_from_file(T& obj, const fs::path& file_path) { TRY_ENTRY(); - std::ifstream data_file; - data_file.open( file_path, std::ios_base::binary | std::ios_base::in); - if(data_file.fail()) + fs::ifstream data_file{file_path, std::ios_base::binary}; + if (data_file.fail()) return false; try { // first try reading in portable mode - boost::archive::portable_binary_iarchive a(data_file); - a >> obj; + boost::archive::portable_binary_iarchive{data_file} >> obj; } catch(...) { // if failed, try reading in unportable mode - boost::filesystem::copy_file(file_path, file_path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists); + auto unportable = file_path; + unportable += ".unportable"; + fs::copy_file(file_path, unportable, fs::copy_options::overwrite_existing); data_file.close(); - data_file.open( file_path, std::ios_base::binary | std::ios_base::in); - if(data_file.fail()) + data_file.open(file_path, std::ios_base::binary); + if (data_file.fail()) return false; - boost::archive::binary_iarchive a(data_file); - a >> obj; + boost::archive::binary_iarchive{data_file} >> obj; } return !data_file.fail(); CATCH_ENTRY_L0("unserialize_obj_from_file", false); diff --git a/src/common/command_line.cpp b/src/common/command_line.cpp index 0c418fd06..24a0b45b0 100644 --- a/src/common/command_line.cpp +++ b/src/common/command_line.cpp @@ -32,7 +32,7 @@ #include "common/i18n.h" #include "common/string_util.h" #ifdef HAVE_READLINE -# include "readline_buffer.h" +# include "epee/readline_buffer.h" #endif namespace command_line diff --git a/src/common/command_line.h b/src/common/command_line.h index 0bc0be3aa..b22940002 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -38,7 +38,7 @@ #include #include #include -#include "include_base_utils.h" +#include "epee/misc_log_ex.h" #include "common/string_util.h" #include "common/i18n.h" @@ -69,7 +69,7 @@ namespace command_line template struct arg_descriptor { - typedef T value_type; + using value_type = T; const char* name; const char* description; @@ -77,21 +77,12 @@ namespace command_line bool not_use_default; }; - template - struct arg_descriptor, false> - { - typedef std::vector value_type; - - const char* name; - const char* description; - }; - template struct arg_descriptor { static_assert(!std::is_same_v, "Boolean switch can't be required"); - typedef T value_type; + using value_type = T; const char* name; const char* description; @@ -100,7 +91,7 @@ namespace command_line template struct arg_descriptor { - typedef T value_type; + using value_type = T; const char* name; const char* description; @@ -116,7 +107,7 @@ namespace command_line template struct arg_descriptor { - typedef T value_type; + using value_type = T; const char* name; const char* description; @@ -144,14 +135,37 @@ namespace command_line return semantic; } + namespace { + template + struct arg_stringify { + const T& v; + arg_stringify(const T& val) : v{val} {} + }; + template + std::ostream& operator<<(std::ostream& o, const arg_stringify& a) { + return o << a.v; + } + template + std::ostream& operator<<(std::ostream& o, const arg_stringify>& a) { + o << '{'; + bool first = true; + for (auto& x : a.v) { + if (first) first = false; + else o << ","; + o << x; + } + return o << '}'; + } + } + template boost::program_options::typed_value* make_semantic(const arg_descriptor& arg) { auto semantic = boost::program_options::value(); if (!arg.not_use_default) { std::ostringstream format; - format << arg.depf(false, true, arg.default_value) << ", " - << arg.depf(true, true, arg.default_value) << " if '" + format << arg_stringify{arg.depf(false, true, arg.default_value)} << ", " + << arg_stringify{arg.depf(true, true, arg.default_value)} << " if '" << arg.ref.name << "'"; semantic->default_value(arg.depf(arg.ref.default_value, true, arg.default_value), format.str()); } @@ -166,12 +180,12 @@ namespace command_line std::array depval; depval.fill(false); std::ostringstream format; - format << arg.depf(depval, true, arg.default_value); + format << arg_stringify{arg.depf(depval, true, arg.default_value)}; for (size_t i = 0; i < depval.size(); ++i) { depval.fill(false); depval[i] = true; - format << ", " << arg.depf(depval, true, arg.default_value) << " if '" << arg.ref[i]->name << "'"; + format << ", " << arg_stringify{arg.depf(depval, true, arg.default_value)} << " if '" << arg.ref[i]->name << "'"; } for (size_t i = 0; i < depval.size(); ++i) depval[i] = arg.ref[i]->default_value; diff --git a/src/common/dns_utils.cpp b/src/common/dns_utils.cpp index 034b15291..a67926f89 100644 --- a/src/common/dns_utils.cpp +++ b/src/common/dns_utils.cpp @@ -37,7 +37,7 @@ #include #include #include -#include "include_base_utils.h" +#include "epee/misc_log_ex.h" #include "common/threadpool.h" #include "crypto/crypto.h" diff --git a/src/common/file.cpp b/src/common/file.cpp index ecc4dfd77..ce1f80811 100644 --- a/src/common/file.cpp +++ b/src/common/file.cpp @@ -30,12 +30,12 @@ // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers // #include "file.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include #include #ifdef WIN32 -#include "string_tools.h" +#include "epee/string_tools.h" #ifndef STRSAFE_NO_DEPRECATE #define STRSAFE_NO_DEPRECATE #endif @@ -47,7 +47,6 @@ #include #include #endif -#include #ifdef __GLIBC__ #include @@ -85,10 +84,10 @@ namespace tools { private_file::private_file() noexcept : m_handle(), m_filename() {} - private_file::private_file(std::FILE* handle, std::string&& filename) noexcept + private_file::private_file(std::FILE* handle, fs::path filename) noexcept : m_handle(handle), m_filename(std::move(filename)) {} - private_file private_file::create(std::string name) + private_file private_file::create(fs::path name) { #ifdef WIN32 struct close_handle @@ -137,7 +136,7 @@ namespace tools { SECURITY_ATTRIBUTES attributes{sizeof(SECURITY_ATTRIBUTES), std::addressof(descriptor), false}; std::unique_ptr file{ - CreateFile( + CreateFileW( name.c_str(), GENERIC_WRITE, FILE_SHARE_READ, std::addressof(attributes), @@ -193,29 +192,15 @@ namespace tools { private_file::~private_file() noexcept { - try - { - boost::system::error_code ec{}; - boost::filesystem::remove(filename(), ec); - } - catch (...) {} + std::error_code ignored; + fs::remove(filename(), ignored); } - file_locker::file_locker(const std::string &filename) + file_locker::file_locker(const fs::path& filename) { #ifdef WIN32 m_fd = INVALID_HANDLE_VALUE; - std::wstring filename_wide; - try - { - filename_wide = epee::string_tools::utf8_to_utf16(filename); - } - catch (const std::exception &e) - { - MERROR("Failed to convert path \"" << filename << "\" to UTF-16: " << e.what()); - return; - } - m_fd = CreateFileW(filename_wide.c_str(), GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + m_fd = CreateFileW(filename.c_str(), GENERIC_READ, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (m_fd != INVALID_HANDLE_VALUE) { OVERLAPPED ov; @@ -270,64 +255,43 @@ namespace tools { #ifdef WIN32 - std::string get_special_folder_path(int nfolder, bool iscreate) + fs::path get_special_folder_path(int nfolder, bool iscreate) { WCHAR psz_path[MAX_PATH] = L""; if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate)) { - try - { - return epee::string_tools::utf16_to_utf8(psz_path); - } - catch (const std::exception &e) - { - MERROR("utf16_to_utf8 failed: " << e.what()); - return ""; - } + return fs::path{psz_path}; } LOG_ERROR("SHGetSpecialFolderPathW() failed, could not obtain requested path."); return ""; } -#endif - - std::string get_default_data_dir() + + // Windows < Vista: C:\Documents and Settings\Username\Application Data\CRYPTONOTE_NAME + // Windows >= Vista: C:\Users\Username\AppData\Roaming\CRYPTONOTE_NAME + fs::path get_default_data_dir() { - /* Please for the love of god refactor the ifdefs out of this */ - - // namespace fs = boost::filesystem; - // Windows < Vista: C:\Documents and Settings\Username\Application Data\CRYPTONOTE_NAME - // Windows >= Vista: C:\Users\Username\AppData\Roaming\CRYPTONOTE_NAME - // Unix & Mac: ~/.CRYPTONOTE_NAME - std::string config_folder; - -#ifdef WIN32 - config_folder = get_special_folder_path(CSIDL_COMMON_APPDATA, true) + "\\" + CRYPTONOTE_NAME; -#else - std::string pathRet; - char* pszHome = getenv("HOME"); - if (pszHome == NULL || strlen(pszHome) == 0) - pathRet = "/"; - else - pathRet = pszHome; - config_folder = (pathRet + "/." + CRYPTONOTE_NAME); -#endif - - return config_folder; + return get_special_folder_path(CSIDL_COMMON_APPDATA, true) / fs::u8path(CRYPTONOTE_NAME); } - - bool create_directories_if_necessary(const std::string& path) +#else + // Non-windows: ~/.CRYPTONOTE_NAME + fs::path get_default_data_dir() { - namespace fs = boost::filesystem; - boost::system::error_code ec; - fs::path fs_path(path); - if (fs::is_directory(fs_path, ec)) + char* home = std::getenv("HOME"); + return (home && std::strlen(home) ? fs::u8path(home) : fs::current_path()) / fs::u8path("." CRYPTONOTE_NAME); + } +#endif + + bool create_directories_if_necessary(const fs::path& path) + { + std::error_code ec; + if (fs::is_directory(path, ec)) { return true; } - bool res = fs::create_directories(fs_path, ec); + bool res = fs::create_directories(path, ec); if (res) { LOG_PRINT_L2("Created directory: " << path); @@ -340,33 +304,6 @@ namespace tools { return res; } - std::error_code replace_file(const std::string& old_name, const std::string& new_name) - { - int code; -#if defined(WIN32) - // Maximizing chances for success - std::wstring wide_replacement_name; - try { wide_replacement_name = epee::string_tools::utf8_to_utf16(old_name); } - catch (...) { return std::error_code(GetLastError(), std::system_category()); } - std::wstring wide_replaced_name; - try { wide_replaced_name = epee::string_tools::utf8_to_utf16(new_name); } - catch (...) { return std::error_code(GetLastError(), std::system_category()); } - - DWORD attributes = ::GetFileAttributesW(wide_replaced_name.c_str()); - if (INVALID_FILE_ATTRIBUTES != attributes) - { - ::SetFileAttributesW(wide_replaced_name.c_str(), attributes & (~FILE_ATTRIBUTE_READONLY)); - } - - bool ok = 0 != ::MoveFileExW(wide_replacement_name.c_str(), wide_replaced_name.c_str(), MOVEFILE_REPLACE_EXISTING); - code = ok ? 0 : static_cast(::GetLastError()); -#else - bool ok = 0 == std::rename(old_name.c_str(), new_name.c_str()); - code = ok ? 0 : errno; -#endif - return std::error_code(code, std::system_category()); - } - void set_strict_default_file_permissions(bool strict) { #if defined(__MINGW32__) || defined(__MINGW__) @@ -377,4 +314,36 @@ namespace tools { #endif } + bool slurp_file(const fs::path& filename, std::string& contents) + { + fs::ifstream in; + in.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try { + in.open(filename, std::ios::binary | std::ios::in | std::ios::ate); + contents.clear(); + contents.resize(in.tellg()); + in.seekg(0); + in.read(contents.data(), contents.size()); + auto bytes_read = in.gcount(); + if (static_cast(bytes_read) < contents.size()) + contents.resize(bytes_read); + return true; + } catch (...) { + return false; + } + } + + bool dump_file(const fs::path& filename, std::string_view contents) + { + fs::ofstream out; + out.exceptions(std::ifstream::failbit | std::ifstream::badbit); + try { + out.open(filename, std::ios::binary | std::ios::out | std::ios::trunc); + out.write(contents.data(), contents.size()); + return true; + } catch (...) { + return false; + } + } + } diff --git a/src/common/file.h b/src/common/file.h index 8b7e6e67c..4aa05b039 100644 --- a/src/common/file.h +++ b/src/common/file.h @@ -36,6 +36,7 @@ #include #include #include +#include "fs.h" #ifdef _WIN32 #include "windows.h" @@ -63,9 +64,9 @@ namespace tools { //! A file restricted to process owner AND process. Deletes file on destruction. class private_file { std::unique_ptr m_handle; - std::string m_filename; + fs::path m_filename; - private_file(std::FILE* handle, std::string&& filename) noexcept; + private_file(std::FILE* handle, fs::path filename) noexcept; public: //! `handle() == nullptr && filename.empty()`. @@ -73,7 +74,7 @@ namespace tools { /*! \return File only readable by owner and only used by this process OR `private_file{}` on error. */ - static private_file create(std::string filename); + static private_file create(fs::path filename); private_file(private_file&&) = default; private_file& operator=(private_file&&) = default; @@ -82,13 +83,13 @@ namespace tools { ~private_file() noexcept; std::FILE* handle() const noexcept { return m_handle.get(); } - const std::string& filename() const noexcept { return m_filename; } + const fs::path& filename() const noexcept { return m_filename; } }; class file_locker { public: - file_locker(const std::string &filename); + file_locker(const fs::path& filename); ~file_locker(); bool locked() const; private: @@ -109,7 +110,7 @@ namespace tools { * * Unix: ~/.CRYPTONOTE_NAME */ - std::string get_default_data_dir(); + fs::path get_default_data_dir(); #ifdef WIN32 /** @@ -120,21 +121,24 @@ namespace tools { * * @return */ - std::string get_special_folder_path(int nfolder, bool iscreate); + fs::path get_special_folder_path(int nfolder, bool iscreate); #endif /*! \brief creates directories for a path * - * wrapper around boost::filesyste::create_directories. - * (ensure-directory-exists): greenspun's tenth rule in action! + * wrapper around fs::create_directories. */ - bool create_directories_if_necessary(const std::string& path); - /*! \brief std::rename wrapper for nix and something strange for windows. - */ - std::error_code replace_file(const std::string& old_name, const std::string& new_name); + bool create_directories_if_necessary(const fs::path& path); void set_strict_default_file_permissions(bool strict); void closefrom(int fd); + /// Reads a (binary) file from disk into the string `contents`. Aborts if the file is larger than + /// `max_size`. + bool slurp_file(const fs::path& filename, std::string& contents); + + /// Dumps (binary) string contents to disk. The file is overwritten if it already exists. + bool dump_file(const fs::path& filename, std::string_view contents); + } diff --git a/src/common/fs.h b/src/common/fs.h new file mode 100644 index 000000000..ebb27ea7b --- /dev/null +++ b/src/common/fs.h @@ -0,0 +1,25 @@ +#pragma once + +// Header to load the std::filesystem namespace (or something compatible with it) as the `fs` +// namespace. For older compilers (which generally just means macos before pre-10.15) we can't +// actually use std::filesystem because Apple's libc++ developers are incompetent. +// +// Also provides fs::ifstream/ofstream/fstream which will be either directly +// std::ifstream/ofstream/fstream (if under a proper C++17), or a simple wrapper around them that +// supports a C++17-style fs::path filename argument. + +#ifndef USE_GHC_FILESYSTEM + +#include +namespace fs { + using namespace std::filesystem; + using ifstream = std::ifstream; + using ofstream = std::ofstream; + using fstream = std::fstream; +} +#else + +#include +namespace fs = ghc::filesystem; + +#endif diff --git a/src/common/hex.h b/src/common/hex.h index a2e601bb7..deb5f36a1 100644 --- a/src/common/hex.h +++ b/src/common/hex.h @@ -1,7 +1,7 @@ #pragma once #include #include -#include "span.h" // epee +#include "epee/span.h" // epee namespace tools { // Reads a hex string directly into a trivially copyable type T without performing any temporary diff --git a/src/common/i18n.cpp b/src/common/i18n.cpp index feeabed98..fe8f9e678 100644 --- a/src/common/i18n.cpp +++ b/src/common/i18n.cpp @@ -35,7 +35,8 @@ #include #include #include -#include "file_io_utils.h" +#include +#include "file.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "i18n" @@ -134,51 +135,40 @@ static std::string utf8(const unsigned char *data, uint32_t len) int i18n_set_language(const char *directory, const char *base, std::string language) { - std::string filename, contents; - const unsigned char *data; - size_t datalen; - size_t idx; - unsigned char chunk_type; - uint32_t chunk_size; - uint32_t num_messages = (uint32_t)-1; - uint32_t messages_idx = (uint32_t)-1; - uint32_t offsets_idx = (uint32_t)-1; - std::string translation, source, context; - i18n_log("i18n_set_language(" << directory << "," << base << ")"); if (!directory || !base) return -1; if (language.empty()) language = i18n_get_language(); - filename = std::string(directory) + "/" + base + "_" + language + ".qm"; + std::string basename = base + "_"s + language + ".qm"; + auto filename = fs::u8path(directory) / fs::u8path(basename); i18n_log("Loading translations for language " << language); - boost::system::error_code ignored_ec; - if (boost::filesystem::exists(filename, ignored_ec)) { - if (!epee::file_io_utils::load_file_to_string(filename, contents)) { + std::string contents; + if (std::error_code ec; fs::exists(filename, ec)) { + if (!tools::slurp_file(filename, contents)) { i18n_log("Failed to load translations file: " << filename); return -1; } } else { i18n_log("Translations file not found: " << filename); - filename = std::string(base) + "_" + language + ".qm"; - if (!find_embedded_file(filename, contents)) { - i18n_log("Embedded translations file not found: " << filename); + if (!find_embedded_file(basename, contents)) { + i18n_log("Embedded translations file not found: " << basename); const char *underscore = strchr(language.c_str(), '_'); if (underscore) { std::string fallback_language = std::string(language, 0, underscore - language.c_str()); - filename = std::string(directory) + "/" + base + "_" + fallback_language + ".qm"; + basename = base + "_"s + fallback_language + ".qm"; + filename.replace_filename(fs::u8path(basename)); i18n_log("Loading translations for language " << fallback_language); - if (boost::filesystem::exists(filename, ignored_ec)) { - if (!epee::file_io_utils::load_file_to_string(filename, contents)) { + if (std::error_code ec; fs::exists(filename, ec)) { + if (!tools::slurp_file(filename, contents)) { i18n_log("Failed to load translations file: " << filename); return -1; } } else { i18n_log("Translations file not found: " << filename); - filename = std::string(base) + "_" + fallback_language + ".qm"; - if (!find_embedded_file(filename, contents)) { + if (!find_embedded_file(basename, contents)) { i18n_log("Embedded translations file not found: " << filename); return -1; } @@ -189,9 +179,9 @@ int i18n_set_language(const char *directory, const char *base, std::string langu } } - data = (const unsigned char*)contents.c_str(); - datalen = contents.size(); - idx = 0; + const unsigned char *data = reinterpret_cast(contents.c_str()); + size_t datalen = contents.size(); + size_t idx = 0; i18n_log("Translations file size: " << datalen); /* Format of the QM file (AFAICT): @@ -225,6 +215,11 @@ int i18n_set_language(const char *directory, const char *base, std::string langu } idx += sizeof(qm_magic); + unsigned char chunk_type; + uint32_t chunk_size; + uint32_t num_messages = (uint32_t)-1; + uint32_t messages_idx = (uint32_t)-1; + uint32_t offsets_idx = (uint32_t)-1; while (idx < datalen) { if (idx + 5 > datalen) { i18n_log("Bad translations file format: " << filename); @@ -268,6 +263,7 @@ int i18n_set_language(const char *directory, const char *base, std::string langu return -1; } + std::string translation, source, context; for (uint32_t m = 0; m < num_messages; ++m) { be32(data+offsets_idx+m*8); // unused idx = be32(data+offsets_idx+m*8+4); @@ -287,9 +283,9 @@ int i18n_set_language(const char *directory, const char *base, std::string langu chunk_size = 0; if (chunk_type == 0x01) { i18n_entries[context + "\0"s + source] = translation; - context = std::string(); - source = std::string(); - translation = std::string(); + context.clear(); + source.clear(); + translation.clear(); break; } diff --git a/src/common/notify.cpp b/src/common/notify.cpp index d800cbd1d..a2c0c640f 100644 --- a/src/common/notify.cpp +++ b/src/common/notify.cpp @@ -28,8 +28,7 @@ #include #include -#include "misc_log_ex.h" -#include "file_io_utils.h" +#include "epee/misc_log_ex.h" #include "spawn.h" #include "notify.h" @@ -52,8 +51,8 @@ Notify::Notify(const char *spec) CHECK_AND_ASSERT_THROW_MES(args.size() > 0, "Failed to parse spec"); if (strchr(spec, '\'') || strchr(spec, '\"') || strchr(spec, '\\')) MWARNING("A notification spec contains a quote or backslash: note that these are handled verbatim, which may not be the intent"); - filename = args[0]; - CHECK_AND_ASSERT_THROW_MES(epee::file_io_utils::is_file_exist(filename), "File not found: " << filename); + filename = fs::u8path(args[0]); + CHECK_AND_ASSERT_THROW_MES(fs::exists(filename), "File not found: " << filename); } static void replace(std::vector &v, const char *tag, const char *s) @@ -77,7 +76,7 @@ int Notify::notify(const char *tag, const char *s, ...) } va_end(ap); - return tools::spawn(filename.c_str(), margs, false); + return tools::spawn(filename, margs, false); } } diff --git a/src/common/notify.h b/src/common/notify.h index e213239cb..467187274 100644 --- a/src/common/notify.h +++ b/src/common/notify.h @@ -30,6 +30,7 @@ #include #include +#include "fs.h" namespace tools { @@ -42,7 +43,7 @@ public: int notify(const char *tag, const char *s, ...); private: - std::string filename; + fs::path filename; std::vector args; }; diff --git a/src/common/password.h b/src/common/password.h index 362592f19..6fa363b61 100644 --- a/src/common/password.h +++ b/src/common/password.h @@ -35,7 +35,7 @@ #include #include #include -#include "wipeable_string.h" +#include "epee/wipeable_string.h" namespace tools { diff --git a/src/common/perf_timer.cpp b/src/common/perf_timer.cpp index 77b36109f..c9fbf3659 100644 --- a/src/common/perf_timer.cpp +++ b/src/common/perf_timer.cpp @@ -28,7 +28,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include "misc_os_dependent.h" +#include "epee/misc_os_dependent.h" #include "perf_timer.h" #undef LOKI_DEFAULT_LOG_CATEGORY diff --git a/src/common/perf_timer.h b/src/common/perf_timer.h index e72a2ea50..3e03e724b 100644 --- a/src/common/perf_timer.h +++ b/src/common/perf_timer.h @@ -32,7 +32,7 @@ #include #include #include -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" namespace tools { diff --git a/src/common/pruning.cpp b/src/common/pruning.cpp index 583e20e6d..527c62c4d 100644 --- a/src/common/pruning.cpp +++ b/src/common/pruning.cpp @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "cryptonote_config.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "crypto/crypto.h" #include "pruning.h" diff --git a/src/common/scoped_message_writer.h b/src/common/scoped_message_writer.h index 484136a25..99c3a1f3a 100644 --- a/src/common/scoped_message_writer.h +++ b/src/common/scoped_message_writer.h @@ -28,8 +28,8 @@ #pragma once -#include "misc_log_ex.h" -#include "readline_suspend.h" +#include "epee/misc_log_ex.h" +#include "epee/readline_suspend.h" #include #include "common/loki_integration_test_hooks.h" diff --git a/src/common/sha256sum.cpp b/src/common/sha256sum.cpp index 65929c5e5..bad01a0f5 100644 --- a/src/common/sha256sum.cpp +++ b/src/common/sha256sum.cpp @@ -2,7 +2,7 @@ #include "sha256sum.h" #include #include "crypto/hash.h" -#include "file_io_utils.h" // epee +#include "fs.h" extern "C" { #include @@ -22,11 +22,11 @@ namespace tools { return true; } - bool sha256sum_file(const std::string &filename, crypto::hash &hash) + bool sha256sum_file(const fs::path& filename, crypto::hash& hash) { - if (!epee::file_io_utils::is_file_exist(filename)) + if (std::error_code ec; !fs::exists(filename, ec) || ec) return false; - std::ifstream f; + fs::ifstream f; f.exceptions(std::ifstream::failbit | std::ifstream::badbit); f.open(filename, std::ios_base::binary | std::ios_base::in | std::ios::ate); if (!f) diff --git a/src/common/sha256sum.h b/src/common/sha256sum.h index 6934eda20..6c410c8c4 100644 --- a/src/common/sha256sum.h +++ b/src/common/sha256sum.h @@ -2,14 +2,15 @@ #include #include #include +#include "fs.h" namespace crypto { struct hash; } namespace tools { // This used to be really dangerously overloaded with very different purposes: - //bool sha256sum(const uint8_t *data, size_t len, crypto::hash &hash); - //bool sha256sum(const std::string &filename, crypto::hash &hash); + //bool sha256sum(const uint8_t* data, size_t len, crypto::hash& hash); + //bool sha256sum(const fs::path& filename, crypto::hash& hash); // which is incredibly dangerous if you happen to have a string you want to hash and see that // there is both a pointer+size and std::string overload. Renamed *both* of these to prevent any // existing code from compiling. @@ -34,6 +35,6 @@ namespace tools { } // Opens the given file and calculates a sha256sum of its contents - bool sha256sum_file(const std::string &filename, crypto::hash& hash); + bool sha256sum_file(const fs::path& filename, crypto::hash& hash); } diff --git a/src/common/spawn.cpp b/src/common/spawn.cpp index 4c5c059b3..498db1be6 100644 --- a/src/common/spawn.cpp +++ b/src/common/spawn.cpp @@ -36,7 +36,7 @@ #include #endif -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "util.h" #include "spawn.h" #include "loki.h" @@ -70,7 +70,7 @@ static void closefrom(int fd) #endif -int spawn(const char *filename, const std::vector& args, bool wait) +int spawn(const fs::path& filename, const std::vector& args, bool wait) { #ifdef _WIN32 std::string joined = tools::join(" ", args); @@ -78,12 +78,15 @@ int spawn(const char *filename, const std::vector& args, bool wait) STARTUPINFOA si = {}; si.cb = sizeof(si); PROCESS_INFORMATION pi; - if (!CreateProcessA(filename, commandLine, nullptr, nullptr, false, 0, nullptr, nullptr, &si, &pi)) + // This .string() is wrong for non-ascii paths, but if we switch to CreateProcessW and use + // .c_str() directly our commandLine argument will not be accepted (because it then has to be a + // wchar_t* but out input is utf-8). Shame on you for this garbage API, Windows. + if (!CreateProcessA(filename.string().c_str(), commandLine, nullptr, nullptr, false, 0, nullptr, nullptr, &si, &pi)) { MERROR("CreateProcess failed. Error code " << GetLastError()); return -1; } - + LOKI_DEFER { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); @@ -129,7 +132,7 @@ int spawn(const char *filename, const std::vector& args, bool wait) tools::closefrom(3); close(0); char *envp[] = {NULL}; - execve(filename, argv.data(), envp); + execve(filename.c_str(), argv.data(), envp); MERROR("Failed to execve: " << strerror(errno)); return -1; } diff --git a/src/common/spawn.h b/src/common/spawn.h index a0d534a67..4ea3c9e03 100644 --- a/src/common/spawn.h +++ b/src/common/spawn.h @@ -29,10 +29,11 @@ #pragma once #include #include +#include "common/fs.h" namespace tools { -int spawn(const char *filename, const std::vector& args, bool wait); +int spawn(const fs::path& filename, const std::vector& args, bool wait); } diff --git a/src/common/stack_trace.cpp b/src/common/stack_trace.cpp index 6d1f6969e..a7c5363e2 100644 --- a/src/common/stack_trace.cpp +++ b/src/common/stack_trace.cpp @@ -45,7 +45,7 @@ #endif #include #include "common/stack_trace.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "stacktrace" diff --git a/src/common/string_util.h b/src/common/string_util.h index 035a734c3..a4b089e37 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h @@ -5,7 +5,7 @@ #include #include #include -#include "span.h" // epee +#include "epee/span.h" // epee namespace tools { diff --git a/src/common/threadpool.cpp b/src/common/threadpool.cpp index 477fdbe43..ed93ee239 100644 --- a/src/common/threadpool.cpp +++ b/src/common/threadpool.cpp @@ -25,7 +25,7 @@ // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "common/threadpool.h" #include "cryptonote_config.h" diff --git a/src/common/util.cpp b/src/common/util.cpp index b7f127330..b63941d55 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -37,16 +37,14 @@ #include "unbound.h" -#include "include_base_utils.h" -#include "string_tools.h" -#include "wipeable_string.h" +#include "epee/string_tools.h" +#include "epee/wipeable_string.h" #include "crypto/crypto.h" #include "util.h" #include "stack_trace.h" -#include "misc_os_dependent.h" -#include "readline_buffer.h" +#include "epee/misc_os_dependent.h" +#include "epee/readline_buffer.h" #include "string_util.h" -#include #include "i18n.h" @@ -76,29 +74,6 @@ namespace tools return with_threads; } - bool sanitize_locale() - { - // boost::filesystem throws for "invalid" locales, such as en_US.UTF-8, or kjsdkfs, - // so reset it here before any calls to it - try - { - boost::filesystem::path p {std::string("test")}; - p /= std::string("test"); - } - catch (...) - { -#if defined(__MINGW32__) || defined(__MINGW__) - putenv("LC_ALL=C"); - putenv("LANG=C"); -#else - setenv("LC_ALL", "C", 1); - setenv("LANG", "C", 1); -#endif - return true; - } - return false; - } - #ifdef STACK_TRACE #ifdef _WIN32 // https://stackoverflow.com/questions/1992816/how-to-handle-seg-faults-under-windows @@ -170,8 +145,6 @@ namespace tools setup_crash_dump(); - sanitize_locale(); - #ifdef __GLIBC__ const char *ver = ::gnu_get_libc_version(); if (!strcmp(ver, "2.25")) diff --git a/src/common/util.h b/src/common/util.h index b2e7b6582..3b28013b7 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -47,8 +47,6 @@ */ namespace tools { - bool sanitize_locale(); - bool disable_core_dumps(); bool on_startup(); diff --git a/src/crypto/CMakeLists.txt b/src/crypto/CMakeLists.txt index 7f761b01c..d0a75b91d 100644 --- a/src/crypto/CMakeLists.txt +++ b/src/crypto/CMakeLists.txt @@ -51,13 +51,13 @@ add_library(cncrypto cn_heavy_hash_soft.cpp cn_turtle_hash.c rx-slow-hash.c + cn_monero_slow_hash.c tree-hash.c) target_link_libraries(cncrypto PUBLIC epee randomx - Boost::system Boost::thread sodium PRIVATE @@ -74,16 +74,26 @@ if (CMAKE_CXX_COMPILER_ID MATCHES Clang OR CMAKE_CXX_COMPILER_ID STREQUAL GNU) check_cxx_compiler_flag(-maes COMPILER_SUPPORTS_AES) if(COMPILER_SUPPORTS_AES) set_source_files_properties(cn_heavy_hash_hard_intel.cpp PROPERTIES COMPILE_FLAGS "-maes -msse2") + set_source_files_properties(cn_monero_slow_hash.c PROPERTIES COMPILE_FLAGS "-maes -msse2") endif() endif() endif() +if (ARCH STREQUAL "armv8-a" AND (CMAKE_CXX_COMPILER_ID MATCHES Clang OR CMAKE_CXX_COMPILER_ID STREQUAL GNU)) + # Similarly use +crypto extensions for the arm hash code (it also has a run-time check before + # enabling). + include(CheckCXXCompilerFlag) + check_cxx_compiler_flag(-march=armv8-a+crypto COMPILER_SUPPORTS_PLUS_CRYPTO) + if (COMPILER_SUPPORTS_PLUS_CRYPTO) + set_source_files_properties(cn_heavy_hash_hard_arm.cpp PROPERTIES COMPILE_FLAGS "-march=armv8-a+crypto") + endif() +endif() + + # Because of the way Qt works on android with JNI, the code does not live in the main android thread # So this code runs with a 1 MB default stack size. # This will force the use of the heap for the allocation of the scratchpad if (ANDROID OR IOS) - if( BUILD_GUI_DEPS ) - target_compile_definitions(cncrypto PUBLIC FORCE_USE_HEAP=1) - endif() + target_compile_definitions(cncrypto PUBLIC FORCE_USE_HEAP=1) endif() diff --git a/src/crypto/aesb.c b/src/crypto/aesb.c index 6d4905ad5..b4cd54d42 100644 --- a/src/crypto/aesb.c +++ b/src/crypto/aesb.c @@ -19,7 +19,7 @@ Issue Date: 20/12/2007 */ #include -#include "int-util.h" +#include "epee/int-util.h" #if defined(__cplusplus) extern "C" diff --git a/src/crypto/blake256.c b/src/crypto/blake256.c index c9d59e8e7..0df1d0115 100644 --- a/src/crypto/blake256.c +++ b/src/crypto/blake256.c @@ -39,7 +39,7 @@ #include #include -#include +#include "epee/memwipe.h" #include "blake256.h" #define U8TO32(p) \ diff --git a/src/crypto/chacha.c b/src/crypto/chacha.c index e0d69c6d7..064807e60 100644 --- a/src/crypto/chacha.c +++ b/src/crypto/chacha.c @@ -12,8 +12,8 @@ Public domain. #endif #include "chacha.h" -#include "int-util.h" -#include "warnings.h" +#include "epee/int-util.h" +#include "epee/warnings.h" /* * The following macros are used to obtain exact-width results. diff --git a/src/crypto/chacha.h b/src/crypto/chacha.h index d2c3313d5..f24be3dcb 100644 --- a/src/crypto/chacha.h +++ b/src/crypto/chacha.h @@ -39,8 +39,8 @@ #if defined(__cplusplus) #include -#include "memwipe.h" -#include "mlocker.h" +#include "epee/memwipe.h" +#include "epee/mlocker.h" #include "hash.h" #include "cn_heavy_hash.hpp" diff --git a/src/crypto/cn_heavy_hash_hard_arm.cpp b/src/crypto/cn_heavy_hash_hard_arm.cpp index 2a492c00a..3347c34a2 100644 --- a/src/crypto/cn_heavy_hash_hard_arm.cpp +++ b/src/crypto/cn_heavy_hash_hard_arm.cpp @@ -31,10 +31,6 @@ #if defined(__aarch64__) -#ifndef __clang__ -# pragma GCC target ("+crypto") -#endif - #include "cn_heavy_hash.hpp" extern "C" { #include "keccak.h" @@ -42,13 +38,19 @@ extern "C" { #include "skein.h" } +#if !defined(__APPLE__) #include #include +#endif #include static bool hw_check_aes() { +#if !defined(__APPLE__) return (getauxval(AT_HWCAP) & HWCAP_AES) != 0; +#else + return true; +#endif } extern "C" const bool cpu_aes_enabled = hw_check_aes() && !force_software_aes(); diff --git a/src/crypto/cn_monero_slow_hash.c b/src/crypto/cn_monero_slow_hash.c new file mode 100644 index 000000000..997f7c031 --- /dev/null +++ b/src/crypto/cn_monero_slow_hash.c @@ -0,0 +1,1575 @@ +// Copyright (c) 2014-2018, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#include +#include +#include +#include +#include +#include + +#include "epee/int-util.h" +#include "hash-ops.h" +#include "oaes_lib.h" +#include "variant2_int_sqrt.h" + +#define MEMORY (1 << 21) // 2MB scratchpad +#define ITER (1 << 20) +#define AES_BLOCK_SIZE 16 +#define AES_KEY_SIZE 32 +#define INIT_SIZE_BLK 8 +#define INIT_SIZE_BYTE (INIT_SIZE_BLK * AES_BLOCK_SIZE) + +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); + +#define VARIANT1_1(p) \ + do if (variant == 1) \ + { \ + const uint8_t tmp = ((const uint8_t*)(p))[11]; \ + static const uint32_t table = 0x75310; \ + const uint8_t index = (((tmp >> 3) & 6) | (tmp & 1)) << 1; \ + ((uint8_t*)(p))[11] = tmp ^ ((table >> index) & 0x30); \ + } while(0) + +#define VARIANT1_2(p) \ + do if (variant == 1) \ + { \ + xor64(p, tweak1_2); \ + } while(0) + +#define VARIANT1_CHECK() \ + do if (length < 43) \ + { \ + fprintf(stderr, "Cryptonight variant 1 needs at least 43 bytes of data"); \ + _exit(1); \ + } while(0) + +#define NONCE_POINTER (((const uint8_t*)data)+35) + +#define VARIANT1_PORTABLE_INIT() \ + uint8_t tweak1_2[8]; \ + do if (variant == 1) \ + { \ + VARIANT1_CHECK(); \ + memcpy(&tweak1_2, &state.hs.b[192], sizeof(tweak1_2)); \ + xor64(tweak1_2, NONCE_POINTER); \ + } while(0) + +#define VARIANT1_INIT64() \ + if (variant == 1) \ + { \ + VARIANT1_CHECK(); \ + } \ + const uint64_t tweak1_2 = (variant == 1) ? (state.hs.w[24] ^ (*((const uint64_t*)NONCE_POINTER))) : 0 + +#define VARIANT2_INIT64() \ + uint64_t division_result = 0; \ + uint64_t sqrt_result = 0; \ + do if (variant >= 2) \ + { \ + U64(b)[2] = state.hs.w[8] ^ state.hs.w[10]; \ + U64(b)[3] = state.hs.w[9] ^ state.hs.w[11]; \ + division_result = state.hs.w[12]; \ + sqrt_result = state.hs.w[13]; \ + } while (0) + +#define VARIANT2_PORTABLE_INIT() \ + uint64_t division_result = 0; \ + uint64_t sqrt_result = 0; \ + do if (variant >= 2) \ + { \ + memcpy(b + AES_BLOCK_SIZE, state.hs.b + 64, AES_BLOCK_SIZE); \ + xor64(b + AES_BLOCK_SIZE, state.hs.b + 80); \ + xor64(b + AES_BLOCK_SIZE + 8, state.hs.b + 88); \ + division_result = state.hs.w[12]; \ + sqrt_result = state.hs.w[13]; \ + } while (0) + +#define VARIANT2_SHUFFLE_ADD_SSE2(base_ptr, offset) \ + do if (variant >= 2) \ + { \ + const __m128i chunk1 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10))); \ + const __m128i chunk2 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20))); \ + const __m128i chunk3 = _mm_load_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30))); \ + _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x10)), _mm_add_epi64(chunk3, _b1)); \ + _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x20)), _mm_add_epi64(chunk1, _b)); \ + _mm_store_si128((__m128i *)((base_ptr) + ((offset) ^ 0x30)), _mm_add_epi64(chunk2, _a)); \ + } while (0) + +#define VARIANT2_SHUFFLE_ADD_NEON(base_ptr, offset) \ + do if (variant >= 2) \ + { \ + const uint64x2_t chunk1 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x10))); \ + const uint64x2_t chunk2 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x20))); \ + const uint64x2_t chunk3 = vld1q_u64(U64((base_ptr) + ((offset) ^ 0x30))); \ + vst1q_u64(U64((base_ptr) + ((offset) ^ 0x10)), vaddq_u64(chunk3, vreinterpretq_u64_u8(_b1))); \ + vst1q_u64(U64((base_ptr) + ((offset) ^ 0x20)), vaddq_u64(chunk1, vreinterpretq_u64_u8(_b))); \ + vst1q_u64(U64((base_ptr) + ((offset) ^ 0x30)), vaddq_u64(chunk2, vreinterpretq_u64_u8(_a))); \ + } while (0) + +#define VARIANT2_PORTABLE_SHUFFLE_ADD(base_ptr, offset) \ + do if (variant >= 2) \ + { \ + uint64_t* chunk1 = U64((base_ptr) + ((offset) ^ 0x10)); \ + uint64_t* chunk2 = U64((base_ptr) + ((offset) ^ 0x20)); \ + uint64_t* chunk3 = U64((base_ptr) + ((offset) ^ 0x30)); \ + \ + const uint64_t chunk1_old[2] = { chunk1[0], chunk1[1] }; \ + \ + uint64_t b1[2]; \ + memcpy(b1, b + 16, 16); \ + chunk1[0] = chunk3[0] + b1[0]; \ + chunk1[1] = chunk3[1] + b1[1]; \ + \ + uint64_t a0[2]; \ + memcpy(a0, a, 16); \ + chunk3[0] = chunk2[0] + a0[0]; \ + chunk3[1] = chunk2[1] + a0[1]; \ + \ + uint64_t b0[2]; \ + memcpy(b0, b, 16); \ + chunk2[0] = chunk1_old[0] + b0[0]; \ + chunk2[1] = chunk1_old[1] + b0[1]; \ + } while (0) + +#define VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr) \ + ((uint64_t*)(b))[0] ^= division_result ^ (sqrt_result << 32); \ + { \ + const uint64_t dividend = ((uint64_t*)(ptr))[1]; \ + const uint32_t divisor = (((uint64_t*)(ptr))[0] + (uint32_t)(sqrt_result << 1)) | 0x80000001UL; \ + division_result = ((uint32_t)(dividend / divisor)) + \ + (((uint64_t)(dividend % divisor)) << 32); \ + } \ + const uint64_t sqrt_input = ((uint64_t*)(ptr))[0] + division_result + +#define VARIANT2_INTEGER_MATH_SSE2(b, ptr) \ + do if (variant >= 2) \ + { \ + VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \ + VARIANT2_INTEGER_MATH_SQRT_STEP_SSE2(); \ + VARIANT2_INTEGER_MATH_SQRT_FIXUP(sqrt_result); \ + } while(0) + +#if defined DBL_MANT_DIG && (DBL_MANT_DIG >= 50) + // double precision floating point type has enough bits of precision on current platform + #define VARIANT2_PORTABLE_INTEGER_MATH(b, ptr) \ + do if (variant >= 2) \ + { \ + VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \ + VARIANT2_INTEGER_MATH_SQRT_STEP_FP64(); \ + VARIANT2_INTEGER_MATH_SQRT_FIXUP(sqrt_result); \ + } while (0) +#else + // double precision floating point type is not good enough on current platform + // fall back to the reference code (integer only) + #define VARIANT2_PORTABLE_INTEGER_MATH(b, ptr) \ + do if (variant >= 2) \ + { \ + VARIANT2_INTEGER_MATH_DIVISION_STEP(b, ptr); \ + VARIANT2_INTEGER_MATH_SQRT_STEP_REF(); \ + } while (0) +#endif + +#define VARIANT2_2_PORTABLE() \ + if (variant >= 2) { \ + xor_blocks(long_state + (j ^ 0x10), d); \ + xor_blocks(d, long_state + (j ^ 0x20)); \ + } + +#define VARIANT2_2() \ + do if (variant >= 2) \ + { \ + *U64(hp_state + (j ^ 0x10)) ^= hi; \ + *(U64(hp_state + (j ^ 0x10)) + 1) ^= lo; \ + hi ^= *U64(hp_state + (j ^ 0x20)); \ + lo ^= *(U64(hp_state + (j ^ 0x20)) + 1); \ + } while (0) + + +#if !defined NO_AES && (defined(__x86_64__) || (defined(_MSC_VER) && defined(_WIN64))) +// Optimised code below, uses x86-specific intrinsics, SSE2, AES-NI +// Fall back to more portable code is down at the bottom + +#include + +#if defined(_MSC_VER) +#include +#include +#define STATIC +#define INLINE __inline +#if !defined(RDATA_ALIGN16) +#define RDATA_ALIGN16 __declspec(align(16)) +#endif +#elif defined(__MINGW32__) +#include +#include +#define STATIC static +#define INLINE inline +#if !defined(RDATA_ALIGN16) +#define RDATA_ALIGN16 __attribute__ ((aligned(16))) +#endif +#else +#include +#include +#define STATIC static +#define INLINE inline +#if !defined(RDATA_ALIGN16) +#define RDATA_ALIGN16 __attribute__ ((aligned(16))) +#endif +#endif + +#if defined(__INTEL_COMPILER) +#define ASM __asm__ +#elif !defined(_MSC_VER) +#define ASM __asm__ +#else +#define ASM __asm +#endif + +#define TOTALBLOCKS (MEMORY / AES_BLOCK_SIZE) + +#define U64(x) ((uint64_t *) (x)) +#define R128(x) ((__m128i *) (x)) + +#define state_index(x) (((*((uint64_t *)x) >> 4) & (TOTALBLOCKS - 1)) << 4) +#if defined(_MSC_VER) +#if !defined(_WIN64) +#define __mul() lo = mul128(c[0], b[0], &hi); +#else +#define __mul() lo = _umul128(c[0], b[0], &hi); +#endif +#else +#if defined(__x86_64__) +#define __mul() ASM("mulq %3\n\t" : "=d"(hi), "=a"(lo) : "%a" (c[0]), "rm" (b[0]) : "cc"); +#else +#define __mul() lo = mul128(c[0], b[0], &hi); +#endif +#endif + +#define pre_aes() \ + j = state_index(a); \ + _c = _mm_load_si128(R128(&hp_state[j])); \ + _a = _mm_load_si128(R128(a)); \ + +/* + * An SSE-optimized implementation of the second half of CryptoNight step 3. + * After using AES to mix a scratchpad value into _c (done by the caller), + * this macro xors it with _b and stores the result back to the same index (j) that it + * loaded the scratchpad value from. It then performs a second random memory + * read/write from the scratchpad, but this time mixes the values using a 64 + * bit multiply. + * This code is based upon an optimized implementation by dga. + */ +#define post_aes() \ + VARIANT2_SHUFFLE_ADD_SSE2(hp_state, j); \ + _mm_store_si128(R128(c), _c); \ + _mm_store_si128(R128(&hp_state[j]), _mm_xor_si128(_b, _c)); \ + VARIANT1_1(&hp_state[j]); \ + j = state_index(c); \ + p = U64(&hp_state[j]); \ + b[0] = p[0]; b[1] = p[1]; \ + VARIANT2_INTEGER_MATH_SSE2(b, c); \ + __mul(); \ + VARIANT2_2(); \ + VARIANT2_SHUFFLE_ADD_SSE2(hp_state, j); \ + a[0] += hi; a[1] += lo; \ + p = U64(&hp_state[j]); \ + p[0] = a[0]; p[1] = a[1]; \ + a[0] ^= b[0]; a[1] ^= b[1]; \ + VARIANT1_2(p + 1); \ + _b1 = _b; \ + _b = _c; \ + +#if defined(_MSC_VER) +#define THREADV __declspec(thread) +#else +#define THREADV __thread +#endif + +#pragma pack(push, 1) +union cn_monero_hash_state +{ + union hash_state hs; + struct + { + uint8_t k[64]; + uint8_t init[INIT_SIZE_BYTE]; + }; +}; +#pragma pack(pop) + +static THREADV uint8_t *hp_state = NULL; +static THREADV int hp_allocated = 0; + +#if defined(_MSC_VER) +#define cpuid(info,x) __cpuidex(info,x,0) +#else +static void cpuid(int CPUInfo[4], int InfoType) +{ + ASM __volatile__ + ( + "cpuid": + "=a" (CPUInfo[0]), + "=b" (CPUInfo[1]), + "=c" (CPUInfo[2]), + "=d" (CPUInfo[3]) : + "a" (InfoType), "c" (0) + ); +} +#endif + +/** + * @brief a = (a xor b), where a and b point to 128 bit values + */ + +STATIC INLINE void xor_blocks(uint8_t *a, const uint8_t *b) +{ + U64(a)[0] ^= U64(b)[0]; + U64(a)[1] ^= U64(b)[1]; +} + +STATIC INLINE void xor64(uint64_t *a, const uint64_t b) +{ + *a ^= b; +} + +/** + * @brief uses cpuid to determine if the CPU supports the AES instructions + * @return true if the CPU supports AES, false otherwise + */ + +STATIC INLINE int force_software_aes(void) +{ + static int use = -1; + + if (use != -1) + return use; + + const char *env = getenv("LOKI_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) +{ + int cpuid_results[4]; + static int supported = -1; + + if(supported >= 0) + return supported; + + cpuid(cpuid_results,1); + return supported = cpuid_results[2] & (1 << 25); +} + +STATIC INLINE void aes_256_assist1(__m128i* t1, __m128i * t2) +{ + __m128i t4; + *t2 = _mm_shuffle_epi32(*t2, 0xff); + t4 = _mm_slli_si128(*t1, 0x04); + *t1 = _mm_xor_si128(*t1, t4); + t4 = _mm_slli_si128(t4, 0x04); + *t1 = _mm_xor_si128(*t1, t4); + t4 = _mm_slli_si128(t4, 0x04); + *t1 = _mm_xor_si128(*t1, t4); + *t1 = _mm_xor_si128(*t1, *t2); +} + +STATIC INLINE void aes_256_assist2(__m128i* t1, __m128i * t3) +{ + __m128i t2, t4; + t4 = _mm_aeskeygenassist_si128(*t1, 0x00); + t2 = _mm_shuffle_epi32(t4, 0xaa); + t4 = _mm_slli_si128(*t3, 0x04); + *t3 = _mm_xor_si128(*t3, t4); + t4 = _mm_slli_si128(t4, 0x04); + *t3 = _mm_xor_si128(*t3, t4); + t4 = _mm_slli_si128(t4, 0x04); + *t3 = _mm_xor_si128(*t3, t4); + *t3 = _mm_xor_si128(*t3, t2); +} + +/** + * @brief expands 'key' into a form it can be used for AES encryption. + * + * This is an SSE-optimized implementation of AES key schedule generation. It + * expands the key into multiple round keys, each of which is used in one round + * of the AES encryption used to fill (and later, extract randomness from) + * the large 2MB buffer. Note that CryptoNight does not use a completely + * standard AES encryption for its buffer expansion, so do not copy this + * function outside of Monero without caution! This version uses the hardware + * AESKEYGENASSIST instruction to speed key generation, and thus requires + * CPU AES support. + * For more information about these functions, see page 19 of Intel's AES instructions + * white paper: + * https://www.intel.com/content/dam/doc/white-paper/advanced-encryption-standard-new-instructions-set-paper.pdf + * + * @param key the input 128 bit key + * @param expandedKey An output buffer to hold the generated key schedule + */ + +STATIC INLINE void aes_expand_key(const uint8_t *key, uint8_t *expandedKey) +{ + __m128i *ek = R128(expandedKey); + __m128i t1, t2, t3; + + t1 = _mm_loadu_si128(R128(key)); + t3 = _mm_loadu_si128(R128(key + 16)); + + ek[0] = t1; + ek[1] = t3; + + t2 = _mm_aeskeygenassist_si128(t3, 0x01); + aes_256_assist1(&t1, &t2); + ek[2] = t1; + aes_256_assist2(&t1, &t3); + ek[3] = t3; + + t2 = _mm_aeskeygenassist_si128(t3, 0x02); + aes_256_assist1(&t1, &t2); + ek[4] = t1; + aes_256_assist2(&t1, &t3); + ek[5] = t3; + + t2 = _mm_aeskeygenassist_si128(t3, 0x04); + aes_256_assist1(&t1, &t2); + ek[6] = t1; + aes_256_assist2(&t1, &t3); + ek[7] = t3; + + t2 = _mm_aeskeygenassist_si128(t3, 0x08); + aes_256_assist1(&t1, &t2); + ek[8] = t1; + aes_256_assist2(&t1, &t3); + ek[9] = t3; + + t2 = _mm_aeskeygenassist_si128(t3, 0x10); + aes_256_assist1(&t1, &t2); + ek[10] = t1; +} + +/** + * @brief a "pseudo" round of AES (similar to but slightly different from normal AES encryption) + * + * To fill its 2MB scratch buffer, CryptoNight uses a nonstandard implementation + * of AES encryption: It applies 10 rounds of the basic AES encryption operation + * to an input 128 bit chunk of data . Unlike normal AES, however, this is + * all it does; it does not perform the initial AddRoundKey step (this is done + * in subsequent steps by aesenc_si128), and it does not use the simpler final round. + * Hence, this is a "pseudo" round - though the function actually implements 10 rounds together. + * + * Note that unlike aesb_pseudo_round, this function works on multiple data chunks. + * + * @param in a pointer to nblocks * 128 bits of data to be encrypted + * @param out a pointer to an nblocks * 128 bit buffer where the output will be stored + * @param expandedKey the expanded AES key + * @param nblocks the number of 128 blocks of data to be encrypted + */ + +STATIC INLINE void aes_pseudo_round(const uint8_t *in, uint8_t *out, + const uint8_t *expandedKey, int nblocks) +{ + __m128i *k = R128(expandedKey); + __m128i d; + int i; + + for(i = 0; i < nblocks; i++) + { + d = _mm_loadu_si128(R128(in + i * AES_BLOCK_SIZE)); + d = _mm_aesenc_si128(d, *R128(&k[0])); + d = _mm_aesenc_si128(d, *R128(&k[1])); + d = _mm_aesenc_si128(d, *R128(&k[2])); + d = _mm_aesenc_si128(d, *R128(&k[3])); + d = _mm_aesenc_si128(d, *R128(&k[4])); + d = _mm_aesenc_si128(d, *R128(&k[5])); + d = _mm_aesenc_si128(d, *R128(&k[6])); + d = _mm_aesenc_si128(d, *R128(&k[7])); + d = _mm_aesenc_si128(d, *R128(&k[8])); + d = _mm_aesenc_si128(d, *R128(&k[9])); + _mm_storeu_si128((R128(out + i * AES_BLOCK_SIZE)), d); + } +} + +/** + * @brief aes_pseudo_round that loads data from *in and xors it with *xor first + * + * This function performs the same operations as aes_pseudo_round, but before + * performing the encryption of each 128 bit block from , it xors + * it with the corresponding block from . + * + * @param in a pointer to nblocks * 128 bits of data to be encrypted + * @param out a pointer to an nblocks * 128 bit buffer where the output will be stored + * @param expandedKey the expanded AES key + * @param xor a pointer to an nblocks * 128 bit buffer that is xored into in before encryption (in is left unmodified) + * @param nblocks the number of 128 blocks of data to be encrypted + */ + +STATIC INLINE void aes_pseudo_round_xor(const uint8_t *in, uint8_t *out, + const uint8_t *expandedKey, const uint8_t *xor, int nblocks) +{ + __m128i *k = R128(expandedKey); + __m128i *x = R128(xor); + __m128i d; + int i; + + for(i = 0; i < nblocks; i++) + { + d = _mm_loadu_si128(R128(in + i * AES_BLOCK_SIZE)); + d = _mm_xor_si128(d, *R128(x++)); + d = _mm_aesenc_si128(d, *R128(&k[0])); + d = _mm_aesenc_si128(d, *R128(&k[1])); + d = _mm_aesenc_si128(d, *R128(&k[2])); + d = _mm_aesenc_si128(d, *R128(&k[3])); + d = _mm_aesenc_si128(d, *R128(&k[4])); + d = _mm_aesenc_si128(d, *R128(&k[5])); + d = _mm_aesenc_si128(d, *R128(&k[6])); + d = _mm_aesenc_si128(d, *R128(&k[7])); + d = _mm_aesenc_si128(d, *R128(&k[8])); + d = _mm_aesenc_si128(d, *R128(&k[9])); + _mm_storeu_si128((R128(out + i * AES_BLOCK_SIZE)), d); + } +} + +#if defined(_MSC_VER) || defined(__MINGW32__) +BOOL SetLockPagesPrivilege(HANDLE hProcess, BOOL bEnable) +{ + struct + { + DWORD count; + LUID_AND_ATTRIBUTES privilege[1]; + } info; + + HANDLE token; + if(!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &token)) + return FALSE; + + info.count = 1; + info.privilege[0].Attributes = bEnable ? SE_PRIVILEGE_ENABLED : 0; + + if(!LookupPrivilegeValue(NULL, SE_LOCK_MEMORY_NAME, &(info.privilege[0].Luid))) + return FALSE; + + if(!AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &info, 0, NULL, NULL)) + return FALSE; + + if (GetLastError() != ERROR_SUCCESS) + return FALSE; + + CloseHandle(token); + + return TRUE; + +} +#endif + +/** + * @brief allocate the 2MB scratch buffer using OS support for huge pages, if available + * + * This function tries to allocate the 2MB scratch buffer using a single + * 2MB "huge page" (instead of the usual 4KB page sizes) to reduce TLB misses + * during the random accesses to the scratch buffer. This is one of the + * important speed optimizations needed to make CryptoNight faster. + * + * No parameters. Updates a thread-local pointer, hp_state, to point to + * the allocated buffer. + */ + +void monero_hash_allocate_state(void) +{ + if(hp_state != NULL) + return; + +#if defined(_MSC_VER) || defined(__MINGW32__) + SetLockPagesPrivilege(GetCurrentProcess(), TRUE); + hp_state = (uint8_t *) VirtualAlloc(hp_state, MEMORY, MEM_LARGE_PAGES | + MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); +#else +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \ + defined(__DragonFly__) || defined(__NetBSD__) + hp_state = mmap(0, MEMORY, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, 0, 0); +#else + hp_state = mmap(0, MEMORY, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, 0, 0); +#endif + if(hp_state == MAP_FAILED) + hp_state = NULL; +#endif + hp_allocated = 1; + if(hp_state == NULL) + { + hp_allocated = 0; + hp_state = (uint8_t *) malloc(MEMORY); + } +} + +/** + *@brief frees the state allocated by monero_hash_allocate_state + */ + +void monero_hash_free_state(void) +{ + if(hp_state == NULL) + return; + + if(!hp_allocated) + free(hp_state); + else + { +#if defined(_MSC_VER) || defined(__MINGW32__) + VirtualFree(hp_state, 0, MEM_RELEASE); +#else + munmap(hp_state, MEMORY); +#endif + } + + hp_state = NULL; + hp_allocated = 0; +} + +/** + * @brief the hash function implementing CryptoNight, used for the Monero proof-of-work + * + * Computes the hash of (which consists of bytes), returning the + * hash in . The CryptoNight hash operates by first using Keccak 1600, + * the 1600 bit variant of the Keccak hash used in SHA-3, to create a 200 byte + * buffer of pseudorandom data by hashing the supplied data. It then uses this + * random data to fill a large 2MB buffer with pseudorandom data by iteratively + * encrypting it using 10 rounds of AES per entry. After this initialization, + * it executes 524,288 rounds of mixing through the random 2MB buffer using + * AES (typically provided in hardware on modern CPUs) and a 64 bit multiply. + * Finally, it re-mixes this large buffer back into + * the 200 byte "text" buffer, and then hashes this buffer using one of four + * pseudorandomly selected hash functions (Blake, Groestl, JH, or Skein) + * to populate the output. + * + * The 2MB buffer and choice of functions for mixing are designed to make the + * algorithm "CPU-friendly" (and thus, reduce the advantage of GPU, FPGA, + * or ASIC-based implementations): the functions used are fast on modern + * CPUs, and the 2MB size matches the typical amount of L3 cache available per + * core on 2013-era CPUs. When available, this implementation will use hardware + * AES support on x86 CPUs. + * + * A diagram of the inner loop of this function can be found at + * https://www.cs.cmu.edu/~dga/crypto/xmr/cryptonight.png + * + * @param data the data to hash + * @param length the length in bytes of the data + * @param hash a pointer to a buffer in which the final 256 bit hash will be stored + */ +void cn_monero_hash(const void *data, size_t length, char *hash, int variant, int prehashed) +{ + RDATA_ALIGN16 uint8_t expandedKey[240]; /* These buffers are aligned to use later with SSE functions */ + + uint8_t text[INIT_SIZE_BYTE]; + RDATA_ALIGN16 uint64_t a[2]; + RDATA_ALIGN16 uint64_t b[4]; + RDATA_ALIGN16 uint64_t c[2]; + union cn_monero_hash_state state; + __m128i _a, _b, _b1, _c; + uint64_t hi, lo; + + 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) + monero_hash_allocate_state(); + + /* CryptoNight Step 1: Use Keccak1600 to initialize the 'state' (and 'text') buffers from the data. */ + if (prehashed) { + memcpy(&state.hs, data, length); + } else { + hash_process(&state.hs, data, length); + } + memcpy(text, state.init, INIT_SIZE_BYTE); + + VARIANT1_INIT64(); + VARIANT2_INIT64(); + + /* CryptoNight Step 2: Iteratively encrypt the results from Keccak to fill + * the 2MB large random access buffer. + */ + + if(useAes) + { + 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(&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(&hp_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE); + } + } + + U64(a)[0] = U64(&state.k[0])[0] ^ U64(&state.k[32])[0]; + U64(a)[1] = U64(&state.k[0])[1] ^ U64(&state.k[32])[1]; + U64(b)[0] = U64(&state.k[16])[0] ^ U64(&state.k[48])[0]; + U64(b)[1] = U64(&state.k[16])[1] ^ U64(&state.k[48])[1]; + + /* CryptoNight Step 3: Bounce randomly 1,048,576 times (1<<20) through the mixing buffer, + * using 524,288 iterations of the following mixing function. Each execution + * performs two reads and writes from the mixing buffer. + */ + + _b = _mm_load_si128(R128(b)); + _b1 = _mm_load_si128(R128(b) + 1); + // Two independent versions, one with AES, one without, to ensure that + // the useAes test is only performed once, not every iteration. + if(useAes) + { + for(i = 0; i < ITER / 2; i++) + { + pre_aes(); + _c = _mm_aesenc_si128(_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 + * of AES encryption to mix the random data back into the 'text' buffer. 'text' + * was originally created with the output of Keccak1600. */ + + memcpy(text, state.init, INIT_SIZE_BYTE); + if(useAes) + { + 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, &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], &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 + * use the resulting data to select which of four finalizer + * hash functions to apply to the data (Blake, Groestl, JH, or Skein). + * Use this hash to squeeze the state array down + * to the final 256 bit hash output. + */ + + memcpy(state.init, text, INIT_SIZE_BYTE); + hash_permutation(&state.hs); + extra_hashes[state.hs.b[0] & 3](&state, 200, hash); +} + +#elif !defined NO_AES && (defined(__arm__) || defined(__aarch64__)) +void monero_hash_allocate_state(void) +{ + // Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c + return; +} + +void monero_hash_free_state(void) +{ + // As above + return; +} + +#if defined(__GNUC__) +#define RDATA_ALIGN16 __attribute__ ((aligned(16))) +#define STATIC static +#define INLINE inline +#else +#define RDATA_ALIGN16 +#define STATIC static +#define INLINE +#endif + +#define U64(x) ((uint64_t *) (x)) + +STATIC INLINE void xor64(uint64_t *a, const uint64_t b) +{ + *a ^= b; +} + +#pragma pack(push, 1) +union cn_monero_hash_state +{ + union hash_state hs; + struct + { + uint8_t k[64]; + uint8_t init[INIT_SIZE_BYTE]; + }; +}; +#pragma pack(pop) + +#if defined(__aarch64__) && defined(__ARM_FEATURE_CRYPTO) + +/* ARMv8-A optimized with NEON and AES instructions. + * Copied from the x86-64 AES-NI implementation. It has much the same + * characteristics as x86-64: there's no 64x64=128 multiplier for vectors, + * and moving between vector and regular registers stalls the pipeline. + */ +#include + +#define TOTALBLOCKS (MEMORY / AES_BLOCK_SIZE) + +#define state_index(x) (((*((uint64_t *)x) >> 4) & (TOTALBLOCKS - 1)) << 4) +#define __mul() __asm__("mul %0, %1, %2\n\t" : "=r"(lo) : "r"(c[0]), "r"(b[0]) ); \ + __asm__("umulh %0, %1, %2\n\t" : "=r"(hi) : "r"(c[0]), "r"(b[0]) ); + +#define pre_aes() \ + j = state_index(a); \ + _c = vld1q_u8(&hp_state[j]); \ + _a = vld1q_u8((const uint8_t *)a); \ + +#define post_aes() \ + VARIANT2_SHUFFLE_ADD_NEON(hp_state, j); \ + vst1q_u8((uint8_t *)c, _c); \ + vst1q_u8(&hp_state[j], veorq_u8(_b, _c)); \ + VARIANT1_1(&hp_state[j]); \ + j = state_index(c); \ + p = U64(&hp_state[j]); \ + b[0] = p[0]; b[1] = p[1]; \ + VARIANT2_PORTABLE_INTEGER_MATH(b, c); \ + __mul(); \ + VARIANT2_2(); \ + VARIANT2_SHUFFLE_ADD_NEON(hp_state, j); \ + a[0] += hi; a[1] += lo; \ + p = U64(&hp_state[j]); \ + p[0] = a[0]; p[1] = a[1]; \ + a[0] ^= b[0]; a[1] ^= b[1]; \ + VARIANT1_2(p + 1); \ + _b1 = _b; \ + _b = _c; \ + + +/* Note: this was based on a standard 256bit key schedule but + * it's been shortened since Cryptonight doesn't use the full + * key schedule. Don't try to use this for vanilla AES. +*/ +static void aes_expand_key(const uint8_t *key, uint8_t *expandedKey) { +static const int rcon[] = { + 0x01,0x01,0x01,0x01, + 0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d,0x0c0f0e0d, // rotate-n-splat + 0x1b,0x1b,0x1b,0x1b }; +__asm__( +" eor v0.16b,v0.16b,v0.16b\n" +" ld1 {v3.16b},[%0],#16\n" +" ld1 {v1.4s,v2.4s},[%2],#32\n" +" ld1 {v4.16b},[%0]\n" +" mov w2,#5\n" +" st1 {v3.4s},[%1],#16\n" +"\n" +"1:\n" +" tbl v6.16b,{v4.16b},v2.16b\n" +" ext v5.16b,v0.16b,v3.16b,#12\n" +" st1 {v4.4s},[%1],#16\n" +" aese v6.16b,v0.16b\n" +" subs w2,w2,#1\n" +"\n" +" eor v3.16b,v3.16b,v5.16b\n" +" ext v5.16b,v0.16b,v5.16b,#12\n" +" eor v3.16b,v3.16b,v5.16b\n" +" ext v5.16b,v0.16b,v5.16b,#12\n" +" eor v6.16b,v6.16b,v1.16b\n" +" eor v3.16b,v3.16b,v5.16b\n" +" shl v1.16b,v1.16b,#1\n" +" eor v3.16b,v3.16b,v6.16b\n" +" st1 {v3.4s},[%1],#16\n" +" b.eq 2f\n" +"\n" +" dup v6.4s,v3.s[3] // just splat\n" +" ext v5.16b,v0.16b,v4.16b,#12\n" +" aese v6.16b,v0.16b\n" +"\n" +" eor v4.16b,v4.16b,v5.16b\n" +" ext v5.16b,v0.16b,v5.16b,#12\n" +" eor v4.16b,v4.16b,v5.16b\n" +" ext v5.16b,v0.16b,v5.16b,#12\n" +" eor v4.16b,v4.16b,v5.16b\n" +"\n" +" eor v4.16b,v4.16b,v6.16b\n" +" b 1b\n" +"\n" +"2:\n" : : "r"(key), "r"(expandedKey), "r"(rcon)); +} + +/* An ordinary AES round is a sequence of SubBytes, ShiftRows, MixColumns, AddRoundKey. There + * is also an InitialRound which consists solely of AddRoundKey. The ARM instructions slice + * this sequence differently; the aese instruction performs AddRoundKey, SubBytes, ShiftRows. + * The aesmc instruction does the MixColumns. Since the aese instruction moves the AddRoundKey + * up front, and Cryptonight's hash skips the InitialRound step, we have to kludge it here by + * feeding in a vector of zeros for our first step. Also we have to do our own Xor explicitly + * at the last step, to provide the AddRoundKey that the ARM instructions omit. + */ +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; ikey->exp_data, aes_ctx->key->exp_data_len); + 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], expandedKey); + memcpy(&long_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE); + } + + U64(a)[0] = U64(&state.k[0])[0] ^ U64(&state.k[32])[0]; + U64(a)[1] = U64(&state.k[0])[1] ^ U64(&state.k[32])[1]; + U64(b)[0] = U64(&state.k[16])[0] ^ U64(&state.k[48])[0]; + U64(b)[1] = U64(&state.k[16])[1] ^ U64(&state.k[48])[1]; + + for(i = 0; i < ITER / 2; i++) + { + #define MASK ((uint32_t)(((MEMORY / AES_BLOCK_SIZE) - 1) << 4)) + #define state_index(x) ((*(uint32_t *) x) & MASK) + + // Iteration 1 + j = state_index(a); + p = &long_state[j]; + aesb_single_round(p, p, a); + copy_block(c1, p); + + VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j); + xor_blocks(p, b); + VARIANT1_1(p); + + // Iteration 2 + j = state_index(c1); + p = &long_state[j]; + copy_block(c, p); + + VARIANT2_PORTABLE_INTEGER_MATH(c, c1); + mul(c1, c, d); + VARIANT2_2_PORTABLE(); + VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j); + sum_half_blocks(a, d); + swap_blocks(a, c); + xor_blocks(a, c); + VARIANT1_2(U64(c) + 1); + copy_block(p, c); + + if (variant >= 2) { + copy_block(b + AES_BLOCK_SIZE, b); + } + copy_block(b, c1); + } + + memcpy(text, state.init, INIT_SIZE_BYTE); + oaes_key_import_data(aes_ctx, &state.hs.b[32], AES_KEY_SIZE); + memcpy(expandedKey, aes_ctx->key->exp_data, aes_ctx->key->exp_data_len); + for(i = 0; i < MEMORY / INIT_SIZE_BYTE; i++) + { + for(j = 0; j < INIT_SIZE_BLK; j++) + { + xor_blocks(&text[j * AES_BLOCK_SIZE], &long_state[i * INIT_SIZE_BYTE + j * AES_BLOCK_SIZE]); + aesb_pseudo_round(&text[AES_BLOCK_SIZE * j], &text[AES_BLOCK_SIZE * j], expandedKey); + } + } + + oaes_free((OAES_CTX **) &aes_ctx); + 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 + free(long_state); +#endif +} +#endif /* !aarch64 || !crypto */ + +#else +// Portable implementation as a fallback + +void monero_hash_allocate_state(void) +{ + // Do nothing, this is just to maintain compatibility with the upgraded slow-hash.c + return; +} + +void monero_hash_free_state(void) +{ + // As above + return; +} + +static void (*const extra_hashes[4])(const void *, size_t, char *) = { + hash_extra_blake, hash_extra_groestl, hash_extra_jh, hash_extra_skein +}; + +static size_t e2i(const uint8_t* a, size_t count) { return (*((uint64_t*)a) / AES_BLOCK_SIZE) & (count - 1); } + +static void mul(const uint8_t* a, const uint8_t* b, uint8_t* res) { + uint64_t a0, b0; + uint64_t hi, lo; + + a0 = SWAP64LE(((uint64_t*)a)[0]); + b0 = SWAP64LE(((uint64_t*)b)[0]); + lo = mul128(a0, b0, &hi); + ((uint64_t*)res)[0] = SWAP64LE(hi); + ((uint64_t*)res)[1] = SWAP64LE(lo); +} + +static void sum_half_blocks(uint8_t* a, const uint8_t* b) { + uint64_t a0, a1, b0, b1; + + a0 = SWAP64LE(((uint64_t*)a)[0]); + a1 = SWAP64LE(((uint64_t*)a)[1]); + b0 = SWAP64LE(((uint64_t*)b)[0]); + b1 = SWAP64LE(((uint64_t*)b)[1]); + a0 += b0; + a1 += b1; + ((uint64_t*)a)[0] = SWAP64LE(a0); + ((uint64_t*)a)[1] = SWAP64LE(a1); +} +#define U64(x) ((uint64_t *) (x)) + +static void copy_block(uint8_t* dst, const uint8_t* src) { + memcpy(dst, src, AES_BLOCK_SIZE); +} + +static void swap_blocks(uint8_t *a, uint8_t *b){ + uint64_t t[2]; + U64(t)[0] = U64(a)[0]; + U64(t)[1] = U64(a)[1]; + U64(a)[0] = U64(b)[0]; + U64(a)[1] = U64(b)[1]; + U64(b)[0] = U64(t)[0]; + U64(b)[1] = U64(t)[1]; +} + +static void xor_blocks(uint8_t* a, const uint8_t* b) { + size_t i; + for (i = 0; i < AES_BLOCK_SIZE; i++) { + a[i] ^= b[i]; + } +} + +static void xor64(uint8_t* left, const uint8_t* right) +{ + size_t i; + for (i = 0; i < 8; ++i) + { + left[i] ^= right[i]; + } +} + +#pragma pack(push, 1) +union cn_monero_hash_state { + union hash_state hs; + struct { + uint8_t k[64]; + uint8_t init[INIT_SIZE_BYTE]; + }; +}; +#pragma pack(pop) + +void cn_monero_hash(const void *data, size_t length, char *hash, int variant, int prehashed) { +#ifndef FORCE_USE_HEAP + uint8_t long_state[MEMORY]; +#else + uint8_t *long_state = (uint8_t *)malloc(MEMORY); +#endif + + union cn_monero_hash_state state; + uint8_t text[INIT_SIZE_BYTE]; + uint8_t a[AES_BLOCK_SIZE]; + uint8_t b[AES_BLOCK_SIZE * 2]; + uint8_t c1[AES_BLOCK_SIZE]; + uint8_t c2[AES_BLOCK_SIZE]; + uint8_t d[AES_BLOCK_SIZE]; + size_t i, j; + uint8_t aes_key[AES_KEY_SIZE]; + oaes_ctx *aes_ctx; + + if (prehashed) { + memcpy(&state.hs, data, length); + } else { + hash_process(&state.hs, data, length); + } + memcpy(text, state.init, INIT_SIZE_BYTE); + memcpy(aes_key, state.hs.b, AES_KEY_SIZE); + aes_ctx = (oaes_ctx *) oaes_alloc(); + + VARIANT1_PORTABLE_INIT(); + VARIANT2_PORTABLE_INIT(); + + oaes_key_import_data(aes_ctx, aes_key, 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(&long_state[i * INIT_SIZE_BYTE], text, INIT_SIZE_BYTE); + } + + for (i = 0; i < AES_BLOCK_SIZE; i++) { + a[i] = state.k[ i] ^ state.k[AES_BLOCK_SIZE * 2 + i]; + b[i] = state.k[AES_BLOCK_SIZE + i] ^ state.k[AES_BLOCK_SIZE * 3 + i]; + } + + for (i = 0; i < ITER / 2; i++) { + /* Dependency chain: address -> read value ------+ + * written value <-+ hard function (AES or MUL) <+ + * next address <-+ + */ + /* Iteration 1 */ + j = e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; + copy_block(c1, &long_state[j]); + aesb_single_round(c1, c1, a); + VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j); + copy_block(&long_state[j], c1); + xor_blocks(&long_state[j], b); + assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE); + VARIANT1_1(&long_state[j]); + /* Iteration 2 */ + j = e2i(c1, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; + copy_block(c2, &long_state[j]); + VARIANT2_PORTABLE_INTEGER_MATH(c2, c1); + mul(c1, c2, d); + VARIANT2_2_PORTABLE(); + VARIANT2_PORTABLE_SHUFFLE_ADD(long_state, j); + swap_blocks(a, c1); + sum_half_blocks(c1, d); + swap_blocks(c1, c2); + xor_blocks(c1, c2); + VARIANT1_2(c2 + 8); + copy_block(&long_state[j], c2); + assert(j == e2i(a, MEMORY / AES_BLOCK_SIZE) * AES_BLOCK_SIZE); + if (variant >= 2) { + copy_block(b + AES_BLOCK_SIZE, b); + } + copy_block(b, a); + copy_block(a, c1); + } + + memcpy(text, state.init, INIT_SIZE_BYTE); + 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], &long_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); + } + } + memcpy(state.init, text, INIT_SIZE_BYTE); + hash_permutation(&state.hs); + /*memcpy(hash, &state, 32);*/ + extra_hashes[state.hs.b[0] & 3](&state, 200, hash); + oaes_free((OAES_CTX **) &aes_ctx); + +#ifdef FORCE_USE_HEAP + free(long_state); +#endif +} + +#endif diff --git a/src/crypto/cn_turtle_hash.c b/src/crypto/cn_turtle_hash.c index 46596eada..a5e0232b6 100644 --- a/src/crypto/cn_turtle_hash.c +++ b/src/crypto/cn_turtle_hash.c @@ -11,7 +11,7 @@ #include #include -#include "int-util.h" +#include "epee/int-util.h" #include "hash-ops.h" #include "oaes_lib.h" #include "variant2_int_sqrt.h" diff --git a/src/crypto/crypto-ops.c b/src/crypto/crypto-ops.c index 31b522cf5..0b838401c 100644 --- a/src/crypto/crypto-ops.c +++ b/src/crypto/crypto-ops.c @@ -30,7 +30,7 @@ #include -#include "warnings.h" +#include "epee/warnings.h" #include "crypto-ops.h" DISABLE_VS_WARNINGS(4146 4244) diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp index 3fbf6dc1d..01e3b0a7c 100644 --- a/src/crypto/crypto.cpp +++ b/src/crypto/crypto.cpp @@ -39,7 +39,7 @@ #include #include "common/varint.h" -#include "warnings.h" +#include "epee/warnings.h" #include "crypto.h" #include "hash.h" diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h index 215a52a9f..baa9c9f6b 100644 --- a/src/crypto/crypto.h +++ b/src/crypto/crypto.h @@ -37,11 +37,11 @@ #include #include -#include "memwipe.h" -#include "mlocker.h" +#include "epee/memwipe.h" +#include "epee/mlocker.h" #include "generic-ops.h" -#include "hex.h" -#include "span.h" +#include "epee/hex.h" +#include "epee/span.h" #include "hash.h" namespace crypto { diff --git a/src/crypto/groestl_tables.h b/src/crypto/groestl_tables.h index ca0c4fca6..57f3b1c58 100644 --- a/src/crypto/groestl_tables.h +++ b/src/crypto/groestl_tables.h @@ -29,7 +29,7 @@ #ifndef __tables_h #define __tables_h -#include "int-util.h" +#include "epee/int-util.h" #if BYTE_ORDER == LITTLE_ENDIAN diff --git a/src/crypto/hash-ops.h b/src/crypto/hash-ops.h index 984c1c41d..3778c83c2 100644 --- a/src/crypto/hash-ops.h +++ b/src/crypto/hash-ops.h @@ -63,6 +63,7 @@ enum #define CN_TURTLE_PAGE_SIZE 262144 void cn_fast_hash(const void *data, size_t length, char *hash); void cn_turtle_hash(const void *data, size_t length, char *hash, int light, int variant, int prehashed, uint32_t scratchpad, uint32_t iterations); +void cn_monero_hash(const void *data, size_t length, char *hash, int variant, int prehashed); void hash_extra_blake(const void *data, size_t length, char *hash); void hash_extra_groestl(const void *data, size_t length, char *hash); diff --git a/src/crypto/hash.c b/src/crypto/hash.c index 4e20e3ebc..61b0e17ae 100644 --- a/src/crypto/hash.c +++ b/src/crypto/hash.c @@ -32,7 +32,7 @@ #include #include -#include "int-util.h" +#include "epee/int-util.h" #include "hash-ops.h" #include "keccak.h" diff --git a/src/crypto/hash.h b/src/crypto/hash.h index 440bf38ec..52ae4bb6f 100644 --- a/src/crypto/hash.h +++ b/src/crypto/hash.h @@ -34,8 +34,8 @@ #include #include "generic-ops.h" -#include "hex.h" -#include "span.h" +#include "epee/hex.h" +#include "epee/span.h" #include "crypto/cn_heavy_hash.hpp" namespace crypto { @@ -72,6 +72,11 @@ namespace crypto { enum struct cn_slow_hash_type { + // NOTE: Monero's slow hash for Android only, we still use the old hashing algorithm for hashing the KeyStore containing private keys + cryptonight_v0, + cryptonight_v0_prehashed, + cryptonight_v1_prehashed, + heavy_v1, heavy_v2, turtle_lite_v2, @@ -91,6 +96,24 @@ namespace crypto { } break; + case cn_slow_hash_type::cryptonight_v0: + case cn_slow_hash_type::cryptonight_v1_prehashed: + { + int variant = 0, prehashed = 0; + if (type == cn_slow_hash_type::cryptonight_v1_prehashed) + { + prehashed = 1; + variant = 1; + } + else if (type == cn_slow_hash_type::cryptonight_v0_prehashed) + { + prehashed = 1; + } + + cn_monero_hash(data, length, hash.data, variant, prehashed); + } + break; + case cn_slow_hash_type::turtle_lite_v2: default: { diff --git a/src/crypto/hmac-keccak.c b/src/crypto/hmac-keccak.c index edcb2065e..be0425f26 100644 --- a/src/crypto/hmac-keccak.c +++ b/src/crypto/hmac-keccak.c @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "hmac-keccak.h" -#include "memwipe.h" +#include "epee/memwipe.h" #define KECCAK_BLOCKLEN 136 #define HASH_SIZE 32 diff --git a/src/crypto/keccak.c b/src/crypto/keccak.c index 887651012..3d7d8d0f2 100644 --- a/src/crypto/keccak.c +++ b/src/crypto/keccak.c @@ -7,7 +7,7 @@ #include #include #include -#include "int-util.h" +#include "epee/int-util.h" #include "hash-ops.h" #include "keccak.h" diff --git a/src/crypto/rx-slow-hash.c b/src/crypto/rx-slow-hash.c index 4aa16125f..25bcf9e2a 100644 --- a/src/crypto/rx-slow-hash.c +++ b/src/crypto/rx-slow-hash.c @@ -37,7 +37,7 @@ #include "randomx.h" #include "c_threads.h" #include "hash-ops.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #define RX_LOGCAT "randomx" diff --git a/src/crypto/skein_port.h b/src/crypto/skein_port.h index 1ec07a4d1..0a25205d0 100644 --- a/src/crypto/skein_port.h +++ b/src/crypto/skein_port.h @@ -114,7 +114,7 @@ typedef uint64_t u64b_t; /* 64-bit unsigned integer */ #ifndef SKEIN_NEED_SWAP /* compile-time "override" for endianness? */ -#include "int-util.h" +#include "epee/int-util.h" #define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ #define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt index 88868a466..0bc9c38ed 100644 --- a/src/cryptonote_basic/CMakeLists.txt +++ b/src/cryptonote_basic/CMakeLists.txt @@ -39,8 +39,7 @@ target_link_libraries(cryptonote_basic PRIVATE common device - Boost::date_time Boost::program_options Boost::serialization - Boost::filesystem + filesystem extra) diff --git a/src/cryptonote_basic/account.cpp b/src/cryptonote_basic/account.cpp index fa1745c18..4ea312cbe 100644 --- a/src/cryptonote_basic/account.cpp +++ b/src/cryptonote_basic/account.cpp @@ -31,9 +31,8 @@ #include -#include "include_base_utils.h" #include "account.h" -#include "warnings.h" +#include "epee/warnings.h" #include "crypto/crypto.h" extern "C" { diff --git a/src/cryptonote_basic/account.h b/src/cryptonote_basic/account.h index 11078135c..735dec9bd 100644 --- a/src/cryptonote_basic/account.h +++ b/src/cryptonote_basic/account.h @@ -32,7 +32,7 @@ #include "cryptonote_basic.h" #include "crypto/crypto.h" -#include "serialization/keyvalue_serialization.h" +#include "epee/serialization/keyvalue_serialization.h" namespace cryptonote { @@ -94,9 +94,6 @@ namespace cryptonote uint64_t get_createtime() const { return m_creation_timestamp; } void set_createtime(uint64_t val) { m_creation_timestamp = val; } - bool load(const std::string& file_path); - bool store(const std::string& file_path); - void forget_spend_key(); const std::vector &get_multisig_keys() const { return m_keys.m_multisig_keys; } diff --git a/src/cryptonote_basic/blobdatatype.h b/src/cryptonote_basic/blobdatatype.h index f2b645b9c..43421197f 100644 --- a/src/cryptonote_basic/blobdatatype.h +++ b/src/cryptonote_basic/blobdatatype.h @@ -31,7 +31,7 @@ #pragma once #include -#include "span.h" +#include "epee/span.h" namespace cryptonote { diff --git a/src/cryptonote_basic/connection_context.h b/src/cryptonote_basic/connection_context.h index 3252bf134..2af3ad0fa 100644 --- a/src/cryptonote_basic/connection_context.h +++ b/src/cryptonote_basic/connection_context.h @@ -32,8 +32,8 @@ #include #include #include -#include "net/net_utils_base.h" -#include "copyable_atomic.h" +#include "epee/net/net_utils_base.h" +#include "epee/copyable_atomic.h" #include "crypto/hash.h" namespace cryptonote diff --git a/src/cryptonote_basic/cryptonote_basic.h b/src/cryptonote_basic/cryptonote_basic.h index 1bda149b6..58ed54527 100644 --- a/src/cryptonote_basic/cryptonote_basic.h +++ b/src/cryptonote_basic/cryptonote_basic.h @@ -38,7 +38,7 @@ #include "serialization/binary_archive.h" #include "serialization/json_archive.h" #include "serialization/crypto.h" -#include "serialization/keyvalue_serialization.h" // eepe named serialization +#include "epee/serialization/keyvalue_serialization.h" // eepe named serialization #include "cryptonote_config.h" #include "crypto/crypto.h" #include "crypto/hash.h" diff --git a/src/cryptonote_basic/cryptonote_basic_impl.cpp b/src/cryptonote_basic/cryptonote_basic_impl.cpp index d0ed3b56f..c4b479506 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.cpp +++ b/src/cryptonote_basic/cryptonote_basic_impl.cpp @@ -29,18 +29,16 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "include_base_utils.h" - #include "cryptonote_basic_impl.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "serialization/binary_utils.h" #include "serialization/container.h" #include "cryptonote_format_utils.h" #include "cryptonote_config.h" -#include "misc_language.h" +#include "epee/misc_language.h" #include "common/base58.h" #include "crypto/hash.h" -#include "int-util.h" +#include "epee/int-util.h" #include "common/dns_utils.h" #include "common/loki.h" #include diff --git a/src/cryptonote_basic/cryptonote_basic_impl.h b/src/cryptonote_basic/cryptonote_basic_impl.h index 727ae4f2e..5bab61872 100644 --- a/src/cryptonote_basic/cryptonote_basic_impl.h +++ b/src/cryptonote_basic/cryptonote_basic_impl.h @@ -65,18 +65,6 @@ namespace cryptonote { public: virtual bool alt_block_added(const block &block, const std::vector& txs, struct checkpoint_t const *checkpoint) = 0; }; - /************************************************************************/ - /* */ - /************************************************************************/ - template - struct array_hasher: std::unary_function - { - std::size_t operator()(const t_array& val) const - { - return boost::hash_range(&val.data[0], &val.data[sizeof(val.data)]); - } - }; - #pragma pack(push, 1) struct public_address_outer_blob diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index d470ed53a..23ceef763 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -34,8 +34,9 @@ #include #include #include -#include "wipeable_string.h" -#include "string_tools.h" +#include "common/hex.h" +#include "epee/wipeable_string.h" +#include "epee/string_tools.h" #include "common/i18n.h" #include "common/meta.h" #include "serialization/string.h" @@ -972,11 +973,7 @@ namespace cryptonote //--------------------------------------------------------------- std::string short_hash_str(const crypto::hash& h) { - std::string res = epee::string_tools::pod_to_hex(h); - CHECK_AND_ASSERT_MES(res.size() == 64, res, "wrong hash256 with string_tools::pod_to_hex conversion"); - auto erased_pos = res.erase(8, 48); - res.insert(8, "...."); - return res; + return lokimq::to_hex(tools::view_guts(h).substr(0, 4)) + "...."; } //--------------------------------------------------------------- bool is_out_to_acc(const account_keys& acc, const txout_to_key& out_key, const crypto::public_key& tx_pub_key, const std::vector& additional_tx_pub_keys, size_t output_index) @@ -1553,7 +1550,7 @@ std::string lns::generic_owner::to_string(cryptonote::network_type nettype) cons if (type == lns::generic_owner_sig_type::monero) return cryptonote::get_account_address_as_str(nettype, wallet.is_subaddress, wallet.address); else - return epee::to_hex::string(epee::as_byte_span(ed25519)); + return tools::type_to_hex(ed25519); } bool lns::generic_owner::operator==(generic_owner const &other) const diff --git a/src/cryptonote_basic/cryptonote_format_utils.h b/src/cryptonote_basic/cryptonote_format_utils.h index 841527624..8fa38705c 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.h +++ b/src/cryptonote_basic/cryptonote_format_utils.h @@ -34,7 +34,6 @@ #include "tx_extra.h" #include "account.h" #include "subaddress_index.h" -#include "include_base_utils.h" #include "crypto/crypto.h" #include "crypto/hash.h" #include "common/meta.h" diff --git a/src/cryptonote_basic/difficulty.cpp b/src/cryptonote_basic/difficulty.cpp index 0fcf5fe36..4d6d3b2fa 100644 --- a/src/cryptonote_basic/difficulty.cpp +++ b/src/cryptonote_basic/difficulty.cpp @@ -32,7 +32,7 @@ #include #include "common/loki.h" -#include "int-util.h" +#include "epee/int-util.h" #include "crypto/hash.h" #include "difficulty.h" #include "hardfork.h" diff --git a/src/cryptonote_basic/miner.cpp b/src/cryptonote_basic/miner.cpp index 6895cb9b8..e18fcf4a5 100644 --- a/src/cryptonote_basic/miner.cpp +++ b/src/cryptonote_basic/miner.cpp @@ -31,17 +31,17 @@ // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers #include -#include "lokimq/base64.h" -#include "misc_language.h" +#include +#include "epee/misc_language.h" #include "cryptonote_basic/cryptonote_format_utils.h" -#include "misc_os_dependent.h" -#include "file_io_utils.h" +#include "epee/misc_os_dependent.h" #include "common/command_line.h" #include "common/util.h" +#include "common/file.h" #include "common/string_util.h" -#include "string_coding.h" -#include "string_tools.h" -#include "storages/portable_storage_template_helper.h" +#include "epee/string_coding.h" +#include "epee/string_tools.h" +#include "epee/storages/portable_storage_template_helper.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "miner" @@ -245,7 +245,7 @@ namespace cryptonote if(command_line::has_arg(vm, arg_extra_messages)) { std::string buff; - bool r = epee::file_io_utils::load_file_to_string(command_line::get_arg(vm, arg_extra_messages), buff); + bool r = tools::slurp_file(fs::u8path(command_line::get_arg(vm, arg_extra_messages)), buff); CHECK_AND_ASSERT_MES(r, false, "Failed to load file with extra messages: " << command_line::get_arg(vm, arg_extra_messages)); auto extra_vec = tools::split_any(buff, "\n"sv, true); m_extra_messages.resize(extra_vec.size()); @@ -264,10 +264,16 @@ namespace cryptonote if(buff != "0") m_extra_messages[i] = buff; } - m_config_folder_path = boost::filesystem::path(command_line::get_arg(vm, arg_extra_messages)).parent_path().string(); + m_config_dir = fs::u8path(command_line::get_arg(vm, arg_extra_messages)).parent_path(); m_config = {}; - const std::string filename = m_config_folder_path + "/" + MINER_CONFIG_FILE_NAME; - CHECK_AND_ASSERT_MES(epee::serialization::load_t_from_json_file(m_config, filename), false, "Failed to load data from " << filename); + fs::path filename = m_config_dir / MINER_CONFIG_FILE_NAME; + if (std::string contents; + !tools::slurp_file(filename, contents) || + !epee::serialization::load_t_from_json(m_config, contents)) + { + MERROR("Failed to load data from " << filename); + return false; + } MINFO("Loaded " << m_extra_messages.size() << " extra messages, current index " << m_config.current_extra_message_index); } @@ -493,14 +499,11 @@ namespace cryptonote MGINFO_GREEN("Found block " << get_block_hash(b) << " at height " << height << " for difficulty: " << local_diff); cryptonote::block_verification_context bvc; if(!m_phandler->handle_block_found(b, bvc) || !bvc.m_added_to_main_chain) - { --m_config.current_extra_message_index; - }else - { + else if (!m_config_dir.empty()) //success update, lets update config - if (!m_config_folder_path.empty()) - epee::serialization::store_t_to_json_file(m_config, m_config_folder_path + "/" + MINER_CONFIG_FILE_NAME); - } + if (std::string json; epee::serialization::store_t_to_json(m_config, json)) + tools::dump_file(m_config_dir / fs::u8path(MINER_CONFIG_FILE_NAME), json); } nonce+=m_threads_total; diff --git a/src/cryptonote_basic/miner.h b/src/cryptonote_basic/miner.h index 400d7002d..6ce919b2c 100644 --- a/src/cryptonote_basic/miner.h +++ b/src/cryptonote_basic/miner.h @@ -37,6 +37,7 @@ #include "cryptonote_basic/verification_context.h" #include "cryptonote_basic/difficulty.h" #include "common/periodic_task.h" +#include "common/fs.h" #ifdef _WIN32 #include #endif @@ -123,7 +124,7 @@ namespace cryptonote tools::periodic_task m_autodetect_interval{1s}; std::vector m_extra_messages; miner_config m_config; - std::string m_config_folder_path; + fs::path m_config_dir; std::atomic m_last_hr_merge_time; std::atomic m_hashes; std::atomic m_total_hashes; diff --git a/src/cryptonote_basic/subaddress_index.h b/src/cryptonote_basic/subaddress_index.h index b052c9b68..34cf4392e 100644 --- a/src/cryptonote_basic/subaddress_index.h +++ b/src/cryptonote_basic/subaddress_index.h @@ -28,7 +28,7 @@ #pragma once -#include "serialization/keyvalue_serialization.h" +#include "epee/serialization/keyvalue_serialization.h" #include #include #include diff --git a/src/cryptonote_basic/verification_context.h b/src/cryptonote_basic/verification_context.h index a103294ce..2108d045c 100644 --- a/src/cryptonote_basic/verification_context.h +++ b/src/cryptonote_basic/verification_context.h @@ -29,7 +29,7 @@ // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers #pragma once -#include "serialization/keyvalue_serialization.h" +#include "epee/serialization/keyvalue_serialization.h" namespace cryptonote { diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 558ff99ad..9085ac212 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -31,12 +31,10 @@ #include #include -#include #include #include "common/rules.h" #include "common/hex.h" -#include "include_base_utils.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "cryptonote_core/cryptonote_tx_utils.h" #include "ringct/rctTypes.h" @@ -46,13 +44,12 @@ #include "cryptonote_basic/cryptonote_boost_serialization.h" #include "cryptonote_config.h" #include "cryptonote_basic/miner.h" -#include "misc_language.h" -#include "profile_tools.h" -#include "file_io_utils.h" -#include "int-util.h" +#include "epee/misc_language.h" +#include "epee/profile_tools.h" +#include "epee/int-util.h" #include "common/threadpool.h" #include "common/boost_serialization_helper.h" -#include "warnings.h" +#include "epee/warnings.h" #include "crypto/hash.h" #include "cryptonote_core.h" #include "ringct/rctSigs.h" @@ -88,7 +85,6 @@ using namespace crypto; */ using namespace cryptonote; -using epee::string_tools::pod_to_hex; DISABLE_VS_WARNINGS(4267) @@ -1173,7 +1169,7 @@ bool Blockchain::switch_to_alternative_blockchain(const std::list block_notify = m_block_notify; if (block_notify) for (const auto &bei: alt_chain) - block_notify->notify("%s", epee::string_tools::pod_to_hex(get_block_hash(bei.bl)).c_str(), NULL); + block_notify->notify("%s", tools::type_to_hex(get_block_hash(bei.bl)).c_str(), NULL); MGINFO_GREEN("REORGANIZE SUCCESS! on height: " << split_height << ", new blockchain size: " << m_db->height()); return true; @@ -1958,7 +1954,7 @@ bool Blockchain::handle_alternative_block(const block& b, const crypto::hash& id cryptonote::transaction tx; if (!cryptonote::parse_and_validate_tx_base_from_blob(blob, tx)) { - MERROR_VER("Block with id: " << epee::string_tools::pod_to_hex(id) << " (as alternative) refers to unparsable transaction hash " << txid << "."); + MERROR_VER("Block with id: " << tools::type_to_hex(id) << " (as alternative) refers to unparsable transaction hash " << txid << "."); bvc.m_verifivation_failed = true; return false; } @@ -3206,7 +3202,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr } else { - CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + boost::lexical_cast(rv.type)); + CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + std::to_string(rv.type)); } // II @@ -3239,7 +3235,7 @@ bool Blockchain::expand_transaction_2(transaction &tx, const crypto::hash &tx_pr } else { - CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + boost::lexical_cast(rv.type)); + CHECK_AND_ASSERT_MES(false, false, "Unsupported rct tx type: " + std::to_string(rv.type)); } // outPk was already done by handle_incoming_tx @@ -3327,7 +3323,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, if(have_tx_keyimg_as_spent(in_to_key.k_image)) { - MERROR_VER("Key image already spent in blockchain: " << epee::string_tools::pod_to_hex(in_to_key.k_image)); + MERROR_VER("Key image already spent in blockchain: " << tools::type_to_hex(in_to_key.k_image)); if (key_image_conflicts) key_image_conflicts->insert(in_to_key.k_image); else @@ -3361,7 +3357,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, { if (in_to_key.k_image == entry.key_image) // Check if key image is on the blacklist { - MERROR_VER("Key image: " << epee::string_tools::pod_to_hex(entry.key_image) << " is blacklisted by the service node network"); + MERROR_VER("Key image: " << tools::type_to_hex(entry.key_image) << " is blacklisted by the service node network"); tvc.m_key_image_blacklisted = true; return false; } @@ -3370,7 +3366,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, uint64_t unlock_height = 0; if (m_service_node_list.is_key_image_locked(in_to_key.k_image, &unlock_height)) { - MERROR_VER("Key image: " << epee::string_tools::pod_to_hex(in_to_key.k_image) << " is locked in a stake until height: " << unlock_height); + MERROR_VER("Key image: " << tools::type_to_hex(in_to_key.k_image) << " is locked in a stake until height: " << unlock_height); tvc.m_key_image_locked_by_snode = true; return false; } @@ -3627,7 +3623,7 @@ bool Blockchain::check_tx_inputs(transaction& tx, tx_verification_context &tvc, uint64_t unlock_height = 0; if (!m_service_node_list.is_key_image_locked(unlock.key_image, &unlock_height, &contribution)) { - MERROR_VER("Requested key image: " << epee::string_tools::pod_to_hex(unlock.key_image) << " to unlock is not locked"); + MERROR_VER("Requested key image: " << tools::type_to_hex(unlock.key_image) << " to unlock is not locked"); tvc.m_invalid_input = true; return false; } @@ -4524,7 +4520,7 @@ bool Blockchain::handle_block_to_main_chain(const block& bl, const crypto::hash& { std::shared_ptr block_notify = m_block_notify; if (block_notify) - block_notify->notify("%s", epee::string_tools::pod_to_hex(id).c_str(), NULL); + block_notify->notify("%s", tools::type_to_hex(id).c_str(), NULL); } return true; @@ -4696,7 +4692,7 @@ bool Blockchain::add_new_block(const block& bl, block_verification_context& bvc, // returns false if any of the checkpoints loading returns false. // That should happen only if a checkpoint is added that conflicts // with an existing checkpoint. -bool Blockchain::update_checkpoints_from_json_file(const std::string& file_path) +bool Blockchain::update_checkpoints_from_json_file(const fs::path& file_path) { std::vector checkpoint_hashes; if (!cryptonote::load_checkpoints_from_json(file_path, checkpoint_hashes)) diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index d11d8da41..2cabc605b 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -49,9 +49,9 @@ #include #include -#include "span.h" -#include "string_tools.h" -#include "rolling_median.h" +#include "epee/span.h" +#include "epee/string_tools.h" +#include "epee/rolling_median.h" #include "cryptonote_basic/cryptonote_basic.h" #include "common/util.h" #include "cryptonote_protocol/cryptonote_protocol_defs.h" @@ -769,7 +769,7 @@ namespace cryptonote * * @return false if any enforced checkpoint type fails to load, otherwise true */ - bool update_checkpoints_from_json_file(const std::string& file_path); + bool update_checkpoints_from_json_file(const fs::path& file_path); bool update_checkpoint(checkpoint_t const &checkpoint); diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 41a26649a..243ff4929 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -32,7 +32,7 @@ #include #include -#include "string_tools.h" +#include "epee/string_tools.h" #include #include @@ -53,11 +53,10 @@ extern "C" { #include "common/threadpool.h" #include "common/command_line.h" #include "common/hex.h" -#include "warnings.h" +#include "epee/warnings.h" #include "crypto/crypto.h" #include "cryptonote_config.h" -#include "misc_language.h" -#include "file_io_utils.h" +#include "epee/misc_language.h" #include #include "checkpoints/checkpoints.h" #include "ringct/rctTypes.h" @@ -65,9 +64,9 @@ extern "C" { #include "ringct/rctSigs.h" #include "common/notify.h" #include "version.h" -#include "memwipe.h" +#include "epee/memwipe.h" #include "common/i18n.h" -#include "net/local_ip.h" +#include "epee/net/local_ip.h" #include "common/loki_integration_test_hooks.h" @@ -118,13 +117,13 @@ namespace cryptonote const command_line::arg_descriptor arg_data_dir = { "data-dir" , "Specify data directory" - , tools::get_default_data_dir() + , tools::get_default_data_dir().u8string() , {{ &arg_testnet_on, &arg_devnet_on }} , [](std::array testnet_devnet, bool defaulted, std::string val)->std::string { if (testnet_devnet[0]) - return (boost::filesystem::path(val) / "testnet").string(); + return (fs::u8path(val) / "testnet").u8string(); else if (testnet_devnet[1]) - return (boost::filesystem::path(val) / "devnet").string(); + return (fs::u8path(val) / "devnet").u8string(); return val; } }; @@ -279,7 +278,6 @@ namespace cryptonote , m_pprotocol(&m_protocol_stub) , m_starter_message_showed(false) , m_target_blockchain_height(0) - , m_checkpoints_path("") , m_last_json_checkpoints_update(0) , m_nettype(UNDEFINED) , m_last_storage_server_ping(0) @@ -377,7 +375,7 @@ namespace cryptonote m_nettype = testnet ? TESTNET : devnet ? DEVNET : MAINNET; } - m_config_folder = command_line::get_arg(vm, arg_data_dir); + m_config_folder = fs::u8path(command_line::get_arg(vm, arg_data_dir)); test_drop_download_height(command_line::get_arg(vm, arg_test_drop_download_height)); m_pad_transactions = get_arg(vm, arg_pad_transactions); @@ -616,16 +614,20 @@ namespace cryptonote m_service_node_list.set_my_service_node_keys(&m_service_keys); } - boost::filesystem::path folder(m_config_folder); + auto folder = m_config_folder; if (m_nettype == FAKECHAIN) folder /= "fake"; // make sure the data directory exists, and try to lock it - CHECK_AND_ASSERT_MES (boost::filesystem::exists(folder) || boost::filesystem::create_directories(folder), false, - std::string("Failed to create directory ").append(folder.string()).c_str()); + + if (std::error_code ec; !fs::create_directories(folder, ec) && ec) + { + MERROR("Failed to create directory " + folder.u8string() + (ec ? ": " + ec.message() : ""s)); + return false; + } std::unique_ptr db(new_db()); - if (db == NULL) + if (!db) { LOG_ERROR("Failed to initialize a database"); return false; @@ -634,9 +636,8 @@ namespace cryptonote auto lns_db_file_path = folder / "lns.db"; folder /= db->get_db_name(); - MGINFO("Loading blockchain from folder " << folder.string() << " ..."); + MGINFO("Loading blockchain from folder " << folder << " ..."); - const std::string filename = folder.string(); // default to fast:async:1 if overridden blockchain_db_sync_mode sync_mode = db_defaultsync; bool sync_on_blocks = true; @@ -646,12 +647,12 @@ namespace cryptonote if (m_nettype == FAKECHAIN && !keep_fakechain) { // reset the db by removing the database file before opening it - if (!db->remove_data_file(filename)) + if (!db->remove_data_file(folder)) { - MERROR("Failed to remove data file in " << filename); + MERROR("Failed to remove data file in " << folder); return false; } - boost::filesystem::remove(lns_db_file_path); + fs::remove(lns_db_file_path); } #endif @@ -732,7 +733,7 @@ namespace cryptonote if (db_salvage) db_flags |= DBF_SALVAGE; - db->open(filename, m_nettype, db_flags); + db->open(folder, m_nettype, db_flags); if(!db->m_open) return false; } @@ -800,14 +801,9 @@ namespace cryptonote } // Checkpoints - { - auto data_dir = boost::filesystem::path(m_config_folder); - boost::filesystem::path json(JSON_HASH_FILE_NAME); - boost::filesystem::path checkpoint_json_hashfile_fullpath = data_dir / json; - m_checkpoints_path = checkpoint_json_hashfile_fullpath.string(); - } + m_checkpoints_path = m_config_folder / fs::u8path(JSON_HASH_FILE_NAME); - sqlite3 *lns_db = lns::init_loki_name_system(lns_db_file_path.string().c_str(), db->is_read_only()); + sqlite3 *lns_db = lns::init_loki_name_system(lns_db_file_path, db->is_read_only()); if (!lns_db) return false; init_lokimq(vm); @@ -863,16 +859,17 @@ namespace cryptonote /// returns true for success/false for failure /// generate_pair - a void function taking (privkey &, pubkey &) that sets them to the generated values; can throw on error. template - bool init_key(const std::string &keypath, Privkey &privkey, Pubkey &pubkey, GetPubkey get_pubkey, GeneratePair generate_pair) { - if (epee::file_io_utils::is_file_exist(keypath)) + bool init_key(const fs::path &keypath, Privkey &privkey, Pubkey &pubkey, GetPubkey get_pubkey, GeneratePair generate_pair) { + std::error_code ec; + if (fs::exists(keypath, ec)) { std::string keystr; - bool r = epee::file_io_utils::load_file_to_string(keypath, keystr); + bool r = tools::slurp_file(keypath, keystr); memcpy(&unwrap(unwrap(privkey)), keystr.data(), sizeof(privkey)); memwipe(&keystr[0], keystr.size()); - CHECK_AND_ASSERT_MES(r, false, "failed to load service node key from " + keypath); + CHECK_AND_ASSERT_MES(r, false, "failed to load service node key from " + keypath.u8string()); CHECK_AND_ASSERT_MES(keystr.size() == sizeof(privkey), false, - "service node key file " + keypath + " has an invalid size"); + "service node key file " + keypath.u8string() + " has an invalid size"); r = get_pubkey(privkey, pubkey); CHECK_AND_ASSERT_MES(r, false, "failed to generate pubkey from secret key"); @@ -886,13 +883,10 @@ namespace cryptonote return false; } - std::string keystr(reinterpret_cast(&privkey), sizeof(privkey)); - bool r = epee::file_io_utils::save_string_to_file(keypath, keystr); - memwipe(&keystr[0], keystr.size()); - CHECK_AND_ASSERT_MES(r, false, "failed to save service node key to " + keypath); + bool r = tools::dump_file(keypath, tools::view_guts(privkey)); + CHECK_AND_ASSERT_MES(r, false, "failed to save service node key to " + keypath.u8string()); - using namespace boost::filesystem; - permissions(keypath, owner_read); + fs::permissions(keypath, fs::perms::owner_read, ec); } return true; } @@ -919,7 +913,7 @@ namespace cryptonote // only contains the private key value but not the secret key value that we need for full // Ed25519 signing). // - if (!init_key(m_config_folder + "/key_ed25519", keys.key_ed25519, keys.pub_ed25519, + if (!init_key(m_config_folder / "key_ed25519", keys.key_ed25519, keys.pub_ed25519, [](crypto::ed25519_secret_key &sk, crypto::ed25519_public_key &pk) { crypto_sign_ed25519_sk_to_pk(pk.data, sk.data); return true; }, [](crypto::ed25519_secret_key &sk, crypto::ed25519_public_key &pk) { crypto_sign_ed25519_keypair(pk.data, sk.data); }) ) @@ -936,7 +930,7 @@ namespace cryptonote // *just* the private point, but not the seed, and so cannot be used for full Ed25519 signatures // (which rely on the seed for signing). if (m_service_node) { - if (!epee::file_io_utils::is_file_exist(m_config_folder + "/key")) { + if (std::error_code ec; !fs::exists(m_config_folder / "key", ec)) { epee::wipeable_string privkey_signhash; privkey_signhash.resize(crypto_hash_sha512_BYTES); unsigned char* pk_sh_data = reinterpret_cast(privkey_signhash.data()); @@ -952,7 +946,7 @@ namespace cryptonote if (!crypto::secret_key_to_public_key(keys.key, keys.pub)) throw std::runtime_error{"Failed to derive primary key from ed25519 key"}; assert(0 == std::memcmp(keys.pub.data, keys.pub_ed25519.data, 32)); - } else if (!init_key(m_config_folder + "/key", keys.key, keys.pub, + } else if (!init_key(m_config_folder / "key", keys.key, keys.pub, crypto::secret_key_to_public_key, [](crypto::secret_key &key, crypto::public_key &pubkey) { throw std::runtime_error{"Internal error: old-style public keys are no longer generated"}; @@ -2491,9 +2485,7 @@ namespace cryptonote //----------------------------------------------------------------------------------------------- uint64_t core::get_free_space() const { - boost::filesystem::path path(m_config_folder); - boost::filesystem::space_info si = boost::filesystem::space(path); - return si.available; + return fs::space(m_config_folder).available; } //----------------------------------------------------------------------------------------------- std::shared_ptr core::get_quorum(service_nodes::quorum_type type, uint64_t height, bool include_old, std::vector> *alt_states) const diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 8b154a4b4..059c98405 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -40,7 +40,7 @@ #include #include "cryptonote_protocol/cryptonote_protocol_handler_common.h" -#include "storages/portable_storage_template_helper.h" +#include "epee/storages/portable_storage_template_helper.h" #include "common/command_line.h" #include "tx_pool.h" #include "blockchain.h" @@ -50,7 +50,7 @@ #include "pulse.h" #include "cryptonote_basic/miner.h" #include "cryptonote_basic/connection_context.h" -#include "warnings.h" +#include "epee/warnings.h" #include "crypto/hash.h" #include "cryptonote_protocol/quorumnet.h" PUSH_WARNINGS @@ -1020,7 +1020,7 @@ namespace cryptonote /** * @brief returns the lokid config directory */ - const std::string& get_config_directory() const { return m_config_folder; } + const fs::path& get_config_directory() const { return m_config_folder; } private: @@ -1188,7 +1188,7 @@ namespace cryptonote //m_miner and m_miner_addres are probably temporary here miner m_miner; //!< miner instance - std::string m_config_folder; //!< folder to look in for configs and other files + fs::path m_config_folder; //!< folder to look in for configs and other files tools::periodic_task m_store_blockchain_interval{12h, false}; //!< interval for manual storing of Blockchain, if enabled @@ -1208,7 +1208,7 @@ namespace cryptonote network_type m_nettype; //!< which network are we on? - std::string m_checkpoints_path; //!< path to json checkpoints file + fs::path m_checkpoints_path; //!< path to json checkpoints file time_t m_last_json_checkpoints_update; //!< time when json checkpoints were last updated std::atomic_flag m_checkpoints_updating; //!< set if checkpoints are currently updating to avoid multiple threads attempting to update at once diff --git a/src/cryptonote_core/cryptonote_tx_utils.cpp b/src/cryptonote_core/cryptonote_tx_utils.cpp index fadf99cf2..c8951ef61 100644 --- a/src/cryptonote_core/cryptonote_tx_utils.cpp +++ b/src/cryptonote_core/cryptonote_tx_utils.cpp @@ -30,8 +30,7 @@ #include #include -#include "include_base_utils.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "common/apply_permutation.h" #include "common/hex.h" #include "cryptonote_tx_utils.h" @@ -43,7 +42,7 @@ #include "crypto/hash.h" #include "ringct/rctSigs.h" #include "multisig/multisig.h" -#include "int-util.h" +#include "epee/int-util.h" using namespace crypto; @@ -755,8 +754,8 @@ namespace cryptonote if(!msout && !(in_ephemeral.pub == src_entr.outputs[src_entr.real_output].second.dest) ) { LOG_ERROR("derived public key mismatch with output public key at index " << idx << ", real out " << src_entr.real_output << "!\nderived_key:" - << epee::string_tools::pod_to_hex(in_ephemeral.pub) << "\nreal output_public_key:" - << epee::string_tools::pod_to_hex(src_entr.outputs[src_entr.real_output].second.dest) ); + << tools::type_to_hex(in_ephemeral.pub) << "\nreal output_public_key:" + << tools::type_to_hex(src_entr.outputs[src_entr.real_output].second.dest) ); LOG_ERROR("amount " << src_entr.amount << ", rct " << src_entr.rct); LOG_ERROR("tx pubkey " << src_entr.real_out_tx_key << ", real_output_in_tx_index " << src_entr.real_output_in_tx_index); return false; diff --git a/src/cryptonote_core/loki_name_system.cpp b/src/cryptonote_core/loki_name_system.cpp index be2a7f78e..a6ba05d36 100644 --- a/src/cryptonote_core/loki_name_system.cpp +++ b/src/cryptonote_core/loki_name_system.cpp @@ -555,7 +555,7 @@ sql_compiled_statement::~sql_compiled_statement() sqlite3_finalize(statement); } -sqlite3 *init_loki_name_system(char const *file_path, bool read_only) +sqlite3 *init_loki_name_system(const fs::path& file_path, bool read_only) { sqlite3 *result = nullptr; int sql_init = sqlite3_initialize(); @@ -566,7 +566,7 @@ sqlite3 *init_loki_name_system(char const *file_path, bool read_only) } int const flags = read_only ? SQLITE_OPEN_READONLY : SQLITE_OPEN_CREATE | SQLITE_OPEN_READWRITE; - int sql_open = sqlite3_open_v2(file_path, &result, flags, nullptr); + int sql_open = sqlite3_open_v2(file_path.u8string().c_str(), &result, flags, nullptr); if (sql_open != SQLITE_OK) { MERROR("Failed to open LNS db at: " << file_path << ", reason: " << sqlite3_errstr(sql_open)); diff --git a/src/cryptonote_core/loki_name_system.h b/src/cryptonote_core/loki_name_system.h index 2d2de1217..59dfd0ca8 100644 --- a/src/cryptonote_core/loki_name_system.h +++ b/src/cryptonote_core/loki_name_system.h @@ -3,8 +3,9 @@ #include "crypto/crypto.h" #include "cryptonote_config.h" -#include "span.h" +#include "epee/span.h" #include "cryptonote_basic/tx_extra.h" +#include "common/fs.h" #include #include @@ -130,7 +131,7 @@ constexpr bool mapping_type_allowed(uint8_t hf_version, mapping_type type) { // relevant within a LNS buy tx). std::vector all_mapping_types(uint8_t hf_version); -sqlite3 *init_loki_name_system(char const *file_path, bool read_only); +sqlite3 *init_loki_name_system(const fs::path& file_path, bool read_only); /// Returns the integer value used in the database and in RPC lookup calls for the given mapping /// type. In particularly this maps all mapping_type::lokinet_Xyears values to the underlying value diff --git a/src/cryptonote_core/pulse.cpp b/src/cryptonote_core/pulse.cpp index 79815b1a8..be7e50237 100644 --- a/src/cryptonote_core/pulse.cpp +++ b/src/cryptonote_core/pulse.cpp @@ -2,9 +2,9 @@ #include #include -#include "wipeable_string.h" -#include "memwipe.h" -#include "misc_log_ex.h" +#include "epee/wipeable_string.h" +#include "epee/memwipe.h" +#include "epee/misc_log_ex.h" #include "common/random.h" #include "cryptonote_core.h" diff --git a/src/cryptonote_core/service_node_list.cpp b/src/cryptonote_core/service_node_list.cpp index deace3f15..faa10c82f 100644 --- a/src/cryptonote_core/service_node_list.cpp +++ b/src/cryptonote_core/service_node_list.cpp @@ -40,17 +40,18 @@ extern "C" { } #include "ringct/rctSigs.h" -#include "net/local_ip.h" +#include "epee/net/local_ip.h" #include "cryptonote_tx_utils.h" #include "cryptonote_basic/tx_extra.h" #include "cryptonote_basic/hardfork.h" -#include "int-util.h" +#include "epee/int-util.h" #include "common/scoped_message_writer.h" #include "common/i18n.h" #include "common/util.h" #include "common/random.h" #include "common/lock.h" -#include "misc_os_dependent.h" +#include "common/hex.h" +#include "epee/misc_os_dependent.h" #include "blockchain.h" #include "service_node_quorum_cop.h" @@ -355,10 +356,10 @@ namespace service_nodes throw invalid_contributions{"Failed to generate registration hash"}; if (!crypto::check_key(service_node_key)) - throw invalid_contributions{"Service Node Key was not a valid crypto key" + epee::string_tools::pod_to_hex(service_node_key)}; + throw invalid_contributions{"Service Node Key was not a valid crypto key" + tools::type_to_hex(service_node_key)}; if (!crypto::check_signature(hash, service_node_key, signature)) - throw invalid_contributions{"Failed to validate service node with key:" + epee::string_tools::pod_to_hex(service_node_key) + " and hash: " + epee::string_tools::pod_to_hex(hash)}; + throw invalid_contributions{"Failed to validate service node with key:" + tools::type_to_hex(service_node_key) + " and hash: " + tools::type_to_hex(hash)}; } struct parsed_tx_contribution @@ -2884,7 +2885,7 @@ namespace service_nodes crypto::x25519_public_key derived_x25519_pubkey = crypto::x25519_public_key::null(); if (!proof.pubkey_ed25519) - REJECT_PROOF("required ed25519 auxiliary pubkey " << epee::string_tools::pod_to_hex(proof.pubkey_ed25519) << " not included in proof"); + REJECT_PROOF("required ed25519 auxiliary pubkey " << proof.pubkey_ed25519 << " not included in proof"); if (0 != crypto_sign_verify_detached(proof.sig_ed25519.data, reinterpret_cast(hash.data), sizeof(hash.data), proof.pubkey_ed25519.data)) REJECT_PROOF("ed25519 signature validation failed"); @@ -3555,9 +3556,7 @@ namespace service_nodes stream << " " << args[i]; } - stream << " " << exp_timestamp << " "; - stream << epee::string_tools::pod_to_hex(keys.pub) << " "; - stream << epee::string_tools::pod_to_hex(signature); + stream << " " << exp_timestamp << " " << tools::type_to_hex(keys.pub) << " " << tools::type_to_hex(signature); if (make_friendly) { diff --git a/src/cryptonote_core/service_node_quorum_cop.cpp b/src/cryptonote_core/service_node_quorum_cop.cpp index 745132d8b..461ac29a5 100644 --- a/src/cryptonote_core/service_node_quorum_cop.cpp +++ b/src/cryptonote_core/service_node_quorum_cop.cpp @@ -34,7 +34,7 @@ #include "version.h" #include "common/loki.h" #include "common/util.h" -#include "net/local_ip.h" +#include "epee/net/local_ip.h" #include #include "common/loki_integration_test_hooks.h" diff --git a/src/cryptonote_core/service_node_rules.cpp b/src/cryptonote_core/service_node_rules.cpp index 740e1a63b..ad1318b37 100644 --- a/src/cryptonote_core/service_node_rules.cpp +++ b/src/cryptonote_core/service_node_rules.cpp @@ -1,6 +1,6 @@ #include "cryptonote_config.h" #include "common/loki.h" -#include "int-util.h" +#include "epee/int-util.h" #include #include #include diff --git a/src/cryptonote_core/service_node_voting.cpp b/src/cryptonote_core/service_node_voting.cpp index 9fa060a83..8c6010ef4 100644 --- a/src/cryptonote_core/service_node_voting.cpp +++ b/src/cryptonote_core/service_node_voting.cpp @@ -35,9 +35,10 @@ #include "cryptonote_protocol/cryptonote_protocol_defs.h" #include "checkpoints/checkpoints.h" #include "common/util.h" +#include "common/hex.h" -#include "misc_log_ex.h" -#include "string_tools.h" +#include "epee/misc_log_ex.h" +#include "epee/string_tools.h" #include #include @@ -329,7 +330,7 @@ namespace service_nodes if (unique_vote_set[quorum_signature.voter_index]++) { - MGINFO("Voter: " << epee::string_tools::pod_to_hex(key) << ", quorum index is duplicated: " << quorum_signature.voter_index << ", failed verification at height: " << height); + MGINFO("Voter: " << tools::type_to_hex(key) << ", quorum index is duplicated: " << quorum_signature.voter_index << ", failed verification at height: " << height); return false; } diff --git a/src/cryptonote_core/tx_pool.cpp b/src/cryptonote_core/tx_pool.cpp index b685b62a4..83859d687 100644 --- a/src/cryptonote_core/tx_pool.cpp +++ b/src/cryptonote_core/tx_pool.cpp @@ -30,7 +30,6 @@ // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers #include -#include #include #include @@ -44,9 +43,10 @@ #include "blockchain_db/blockchain_db.h" #include "common/boost_serialization_helper.h" #include "common/lock.h" -#include "int-util.h" -#include "misc_language.h" -#include "warnings.h" +#include "common/hex.h" +#include "epee/int-util.h" +#include "epee/misc_language.h" +#include "epee/warnings.h" #include "common/perf_timer.h" #include "crypto/hash.h" @@ -1271,7 +1271,7 @@ namespace cryptonote } tx_infos.emplace_back(); auto& txi = tx_infos.back(); - txi.id_hash = epee::string_tools::pod_to_hex(txid); + txi.id_hash = tools::type_to_hex(txid); txi.tx_blob = *bd; tx.set_hash(txid); txi.tx_json = obj_to_json_str(tx); @@ -1280,9 +1280,9 @@ namespace cryptonote txi.fee = meta.fee; txi.kept_by_block = meta.kept_by_block; txi.max_used_block_height = meta.max_used_block_height; - txi.max_used_block_id_hash = epee::string_tools::pod_to_hex(meta.max_used_block_id); + txi.max_used_block_id_hash = tools::type_to_hex(meta.max_used_block_id); txi.last_failed_height = meta.last_failed_height; - txi.last_failed_id_hash = epee::string_tools::pod_to_hex(meta.last_failed_id); + txi.last_failed_id_hash = tools::type_to_hex(meta.last_failed_id); // In restricted mode we do not include this data: txi.receive_time = include_sensitive_data ? meta.receive_time : 0; txi.relayed = meta.relayed; @@ -1301,7 +1301,7 @@ namespace cryptonote const crypto::key_image& k_image = kee.first; const std::unordered_set& kei_image_set = kee.second; rpc::spent_key_image_info ki{}; - ki.id_hash = epee::string_tools::pod_to_hex(k_image); + ki.id_hash = tools::type_to_hex(k_image); for (const crypto::hash& tx_id_hash : kei_image_set) { if (!include_sensitive_data) @@ -1323,7 +1323,7 @@ namespace cryptonote return false; } } - ki.txs_hashes.push_back(epee::string_tools::pod_to_hex(tx_id_hash)); + ki.txs_hashes.push_back(tools::type_to_hex(tx_id_hash)); } // Only return key images for which we have at least one tx that we can show for them if (!ki.txs_hashes.empty()) diff --git a/src/cryptonote_core/tx_pool.h b/src/cryptonote_core/tx_pool.h index 85a88b149..37ec63af2 100644 --- a/src/cryptonote_core/tx_pool.h +++ b/src/cryptonote_core/tx_pool.h @@ -29,7 +29,6 @@ // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers #pragma once -#include "include_base_utils.h" #include #include @@ -38,7 +37,7 @@ #include #include -#include "string_tools.h" +#include "epee/string_tools.h" #include "common/periodic_task.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "cryptonote_basic/verification_context.h" diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp index 8df59f4ab..3448a67de 100644 --- a/src/cryptonote_protocol/block_queue.cpp +++ b/src/cryptonote_protocol/block_queue.cpp @@ -33,7 +33,7 @@ #include #include #include -#include "string_tools.h" +#include "epee/string_tools.h" #include "cryptonote_protocol_defs.h" #include "common/pruning.h" #include "block_queue.h" diff --git a/src/cryptonote_protocol/cryptonote_protocol_defs.h b/src/cryptonote_protocol/cryptonote_protocol_defs.h index f11a9be75..cbf29578b 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_defs.h +++ b/src/cryptonote_protocol/cryptonote_protocol_defs.h @@ -31,9 +31,9 @@ #pragma once #include -#include "serialization/keyvalue_serialization.h" +#include "epee/serialization/keyvalue_serialization.h" #include "cryptonote_basic/cryptonote_basic.h" -#include "net/net_utils_base.h" +#include "epee/net/net_utils_base.h" #include "cryptonote_basic/blobdatatype.h" #include "common/loki.h" diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.h b/src/cryptonote_protocol/cryptonote_protocol_handler.h index 6bdd92300..95b133b80 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.h +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.h @@ -40,8 +40,8 @@ #include #include "common/periodic_task.h" -#include "storages/levin_abstract_invoke2.h" -#include "warnings.h" +#include "epee/storages/levin_abstract_invoke2.h" +#include "epee/warnings.h" #include "cryptonote_protocol_defs.h" #include "cryptonote_protocol_handler_common.h" #include "block_queue.h" diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 289c519b8..e648f9e86 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -46,8 +46,8 @@ #include "cryptonote_basic/verification_context.h" #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_core/tx_pool.h" -#include "profile_tools.h" -#include "net/network_throttle-detail.hpp" +#include "epee/profile_tools.h" +#include "epee/net/network_throttle-detail.hpp" #include "common/pruning.h" #include "common/random.h" #include "common/lock.h" @@ -319,7 +319,7 @@ namespace cryptonote cnx.current_download = cntxt.m_current_speed_down / 1024; cnx.current_upload = cntxt.m_current_speed_up / 1024; - cnx.connection_id = epee::string_tools::pod_to_hex(cntxt.m_connection_id); + cnx.connection_id = tools::type_to_hex(cntxt.m_connection_id); cnx.height = cntxt.m_remote_blockchain_height; cnx.pruning_seed = cntxt.m_pruning_seed; @@ -578,7 +578,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT ( "NOTIFY_NEW_FLUFFY_BLOCK -> request/response mismatch, " - << "block = " << epee::string_tools::pod_to_hex(get_blob_hash(arg.b.block)) + << "block = " << tools::type_to_hex(get_blob_hash(arg.b.block)) << ", requested = " << context.m_requested_objects.size() << ", received = " << new_block.tx_hashes.size() << ", dropping connection" @@ -690,7 +690,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT ( "sent wrong tx: failed to parse and validate transaction: " - << epee::string_tools::buff_to_hex_nodelimer(tx_blob) + << lokimq::to_hex(tx_blob) << ", dropping connection" ); @@ -832,7 +832,7 @@ namespace cryptonote LOG_ERROR_CCONTEXT ( "sent wrong block: failed to parse and validate block: " - << epee::string_tools::buff_to_hex_nodelimer(arg.b.block) + << lokimq::to_hex(arg.b.block) << ", dropping connection" ); @@ -1220,7 +1220,7 @@ namespace cryptonote if(!parse_and_validate_block_from_blob(block_entry.block, b, block_hash)) { LOG_ERROR_CCONTEXT("sent wrong block: failed to parse and validate block: " - << epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection"); + << lokimq::to_hex(block_entry.block) << ", dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; return 1; @@ -1228,7 +1228,7 @@ namespace cryptonote if (b.miner_tx.vin.size() != 1 || !std::holds_alternative(b.miner_tx.vin.front())) { LOG_ERROR_CCONTEXT("sent wrong block: block: miner tx does not have exactly one txin_gen input" - << epee::string_tools::buff_to_hex_nodelimer(block_entry.block) << ", dropping connection"); + << lokimq::to_hex(block_entry.block) << ", dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; return 1; @@ -1239,7 +1239,7 @@ namespace cryptonote auto req_it = context.m_requested_objects.find(block_hash); if(req_it == context.m_requested_objects.end()) { - LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_BLOCKS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) + LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_BLOCKS: block with id=" << tools::type_to_hex(get_blob_hash(block_entry.block)) << " wasn't requested, dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; @@ -1247,7 +1247,7 @@ namespace cryptonote } if(b.tx_hashes.size() != block_entry.txs.size()) { - LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_BLOCKS: block with id=" << epee::string_tools::pod_to_hex(get_blob_hash(block_entry.block)) + LOG_ERROR_CCONTEXT("sent wrong NOTIFY_RESPONSE_GET_BLOCKS: block with id=" << tools::type_to_hex(get_blob_hash(block_entry.block)) << ", tx_hashes.size()=" << b.tx_hashes.size() << " mismatch with block_complete_entry.m_txs.size()=" << block_entry.txs.size() << ", dropping connection"); drop_connection(context, false, false); ++m_sync_bad_spans_downloaded; @@ -1511,7 +1511,7 @@ namespace cryptonote cryptonote::transaction tx; parse_and_validate_tx_from_blob(block_entry.txs[i], tx); // must succeed if we got here LOG_ERROR_CCONTEXT("transaction verification failed on NOTIFY_RESPONSE_GET_BLOCKS, tx_id = " - << epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(tx)) << ", dropping connection"); + << tools::type_to_hex(cryptonote::get_transaction_hash(tx)) << ", dropping connection"); drop_connection(context, false, true); return 1; })) diff --git a/src/cryptonote_protocol/levin_notify.h b/src/cryptonote_protocol/levin_notify.h index b578079e9..df3fbb0ca 100644 --- a/src/cryptonote_protocol/levin_notify.h +++ b/src/cryptonote_protocol/levin_notify.h @@ -33,10 +33,10 @@ #include #include -#include "shared_sv.h" +#include "epee/shared_sv.h" #include "cryptonote_basic/blobdatatype.h" -#include "net/enums.h" -#include "span.h" +#include "epee/net/enums.h" +#include "epee/span.h" namespace epee { diff --git a/src/daemon/CMakeLists.txt b/src/daemon/CMakeLists.txt index 78a73472a..cbd4ac8a7 100644 --- a/src/daemon/CMakeLists.txt +++ b/src/daemon/CMakeLists.txt @@ -46,8 +46,7 @@ target_link_libraries(daemon serialization daemon_rpc_server version - Boost::filesystem + filesystem Boost::program_options - Boost::system systemd extra) diff --git a/src/daemon/command_line_args.h b/src/daemon/command_line_args.h index b78df9ef2..de7811af7 100644 --- a/src/daemon/command_line_args.h +++ b/src/daemon/command_line_args.h @@ -44,11 +44,9 @@ namespace daemon_args , {{ &cryptonote::arg_testnet_on, &cryptonote::arg_devnet_on }} , [](std::array testnet_devnet, bool defaulted, std::string val)->std::string { if (testnet_devnet[0] && defaulted) - return (daemonizer::get_default_data_dir() / "testnet" / - std::string(CRYPTONOTE_NAME ".conf")).string(); + return (daemonizer::get_default_data_dir() / "testnet" / (CRYPTONOTE_NAME ".conf")).u8string(); else if (testnet_devnet[1] && defaulted) - return (daemonizer::get_default_data_dir() / "devnet" / - std::string(CRYPTONOTE_NAME ".conf")).string(); + return (daemonizer::get_default_data_dir() / "devnet" / (CRYPTONOTE_NAME ".conf")).u8string(); return val; } }; @@ -59,11 +57,9 @@ namespace daemon_args , {{ &cryptonote::arg_testnet_on, &cryptonote::arg_devnet_on }} , [](std::array testnet_devnet, bool defaulted, std::string val)->std::string { if (testnet_devnet[0] && defaulted) - return (daemonizer::get_default_data_dir() / "testnet" / - std::string(CRYPTONOTE_NAME ".log")).string(); + return (daemonizer::get_default_data_dir() / "testnet" / (CRYPTONOTE_NAME ".log")).u8string(); else if (testnet_devnet[1] && defaulted) - return (daemonizer::get_default_data_dir() / "devnet" / - std::string(CRYPTONOTE_NAME ".log")).string(); + return (daemonizer::get_default_data_dir() / "devnet" / (CRYPTONOTE_NAME ".log")).u8string(); return val; } }; diff --git a/src/daemon/command_server.cpp b/src/daemon/command_server.cpp index 79a5e4540..7bcefe771 100644 --- a/src/daemon/command_server.cpp +++ b/src/daemon/command_server.cpp @@ -30,7 +30,7 @@ #include #include "cryptonote_config.h" #include "version.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "daemon/command_server.h" #include "common/loki_integration_test_hooks.h" diff --git a/src/daemon/command_server.h b/src/daemon/command_server.h index 03a4bbbd2..4f2c12380 100644 --- a/src/daemon/command_server.h +++ b/src/daemon/command_server.h @@ -31,7 +31,7 @@ #include #include "common/common_fwd.h" -#include "console_handler.h" +#include "epee/console_handler.h" #include "daemon/command_parser_executor.h" namespace daemonize { diff --git a/src/daemon/daemon.cpp b/src/daemon/daemon.cpp index 268acc287..aaa2fed05 100644 --- a/src/daemon/daemon.cpp +++ b/src/daemon/daemon.cpp @@ -29,12 +29,15 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers +#include #include #include #include #include -#include "misc_log_ex.h" +#include "cryptonote_config.h" +#include "cryptonote_core/cryptonote_core.h" +#include "epee/misc_log_ex.h" #if defined(PER_BLOCK_CHECKPOINT) #include "blocks/blocks.h" #endif @@ -69,46 +72,41 @@ using namespace std::literals; namespace daemonize { -static uint16_t parse_public_rpc_port(const boost::program_options::variables_map& vm) +// Parse an IP:PORT string into a {IP,PORT} pair. Throws if the string value is not valid. Accepts +// both IPv4 and IPv6 addresses, but the latter must be specified in square brackets, e.g. [::1]:2345, +// and will be returned *without* square brackets. +static std::pair parse_ip_port(std::string_view ip_port, const std::string& argname) { - const auto& public_node_arg = cryptonote::rpc::http_server::arg_public_node; - const bool public_node = command_line::get_arg(vm, public_node_arg); - if (!public_node) - return 0; + std::pair result; + auto& [ip, port] = result; - uint16_t rpc_port = 0; - const auto &arg_rpc_restricted_bind_port = cryptonote::rpc::http_server::arg_rpc_restricted_bind_port; - const auto &arg_rpc_bind_port = cryptonote::rpc::http_server::arg_rpc_bind_port; - const auto &arg_restricted_rpc = cryptonote::rpc::http_server::arg_restricted_rpc; - - bool specified_restricted_port = !command_line::is_arg_defaulted(vm, arg_rpc_restricted_bind_port); - if (specified_restricted_port) - rpc_port = command_line::get_arg(vm, arg_rpc_restricted_bind_port); - else if (command_line::get_arg(vm, arg_restricted_rpc)) - rpc_port = command_line::get_arg(vm, arg_rpc_bind_port); + if (auto colon = ip_port.rfind(":"); colon != std::string::npos && tools::parse_int(ip_port.substr(colon+1), port)) + ip_port.remove_suffix(ip_port.size() - colon); else - throw std::runtime_error("Restricted RPC is required for --"s + public_node_arg.name + ", specify a restricted port via --" + arg_rpc_restricted_bind_port.name + " or restrict server via --" + arg_restricted_rpc.name); + throw std::runtime_error{"Invalid IP/port value specified to " + argname + ": " + std::string(ip_port)}; - if (rpc_port == 0) - throw std::runtime_error("Please specify a non-zero port for restricted rpc via --"s + (specified_restricted_port ? arg_rpc_restricted_bind_port.name : arg_rpc_bind_port.name)); + if (!ip_port.empty() && ip_port.front() == '[' && ip_port.back() == ']') { + ip_port.remove_prefix(1); + ip_port.remove_suffix(1); + } - const auto rpc_bind_address = command_line::get_arg(vm, cryptonote::rpc_args::descriptors().rpc_bind_ip); - const auto address = net::get_network_address(rpc_bind_address, rpc_port); - if (!address) - throw std::runtime_error("Failed to parse RPC bind address "s + rpc_bind_address + ":" + std::to_string(rpc_port)); - if (address->get_zone() != epee::net_utils::zone::public_) - throw std::runtime_error(std::string(zone_to_string(address->get_zone())) - + " network zone is not supported, please check RPC server bind address"); + std::string ip_str{ip_port}; + boost::system::error_code ec; + auto addr = +#if BOOST_VERSION >= 106600 + boost::asio::ip::make_address +#else + boost::asio::ip::address::from_string +#endif + (ip_str, ec); + if (ec) + throw std::runtime_error{"Invalid IP address specified: " + ip_str}; - if (address->is_loopback() || address->is_local()) - MLOG_RED(el::Level::Warning, "--" << public_node_arg.name - << " is enabled, but RPC server " << address->str() - << " may be unreachable from outside, please check RPC server bind address"); + ip = addr.to_string(); - return rpc_port; + return result; } - daemon::daemon(boost::program_options::variables_map vm_) : vm{std::move(vm_)}, core{std::make_unique()}, @@ -130,19 +128,98 @@ daemon::daemon(boost::program_options::variables_map vm_) : protocol->set_p2p_endpoint(p2p.get()); core->set_cryptonote_protocol(protocol.get()); + auto rpc_config = cryptonote::rpc_args::process(vm); + bool new_rpc_options = !is_arg_defaulted(vm, cryptonote::rpc::http_server::arg_rpc_admin) + || !is_arg_defaulted(vm, cryptonote::rpc::http_server::arg_rpc_public); + // TODO: Remove these options, perhaps starting in loki 9.0 + bool deprecated_rpc_options = !is_arg_defaulted(vm, cryptonote::rpc::http_server::arg_rpc_bind_port) + || !is_arg_defaulted(vm, cryptonote::rpc::http_server::arg_rpc_restricted_bind_port) + || !is_arg_defaulted(vm, cryptonote::rpc::http_server::arg_restricted_rpc) + || !is_arg_defaulted(vm, cryptonote::rpc::http_server::arg_public_node) + || rpc_config.bind_ip.has_value() + || rpc_config.bind_ipv6_address.has_value() + || rpc_config.use_ipv6; + + constexpr std::string_view deprecated_option_names = "--rpc-bind-ip/--rpc-bind-port/--rpc-restricted-bind-port/--restricted-rpc/--public-node/--rpc-use-ipv6"sv; + + if (new_rpc_options && deprecated_rpc_options) + throw std::runtime_error{"Failed to initialize rpc settings: --rpc-public/--rpc-admin cannot be combined with deprecated " + std::string{deprecated_option_names} + " options"}; + + // bind ip, listen addr, required + std::vector> rpc_listen_admin, rpc_listen_public; + if (deprecated_rpc_options) { - const auto restricted = command_line::get_arg(vm, cryptonote::rpc::http_server::arg_restricted_rpc); - const auto main_rpc_port = command_line::get_arg(vm, cryptonote::rpc::http_server::arg_rpc_bind_port); - MGINFO("- core HTTP RPC server"); - http_rpcs.emplace_back(std::piecewise_construct, std::tie("core"), std::tie(*rpc, vm, restricted, main_rpc_port)); + MGINFO_RED(deprecated_option_names << " options are deprecated and will be removed from a future lokid version; use --rpc-public/--rpc-admin instead"); + + // These old options from Monero are really janky: --restricted-rpc turns the main port + // restricted, but then we also have --rpc-restricted-bind-port but both are stuck with + // --rpc-bind-ip, and then half of the options get parsed here but the IP option used to get + // parsed in the http_server code. + auto restricted = command_line::get_arg(vm, cryptonote::rpc::http_server::arg_restricted_rpc); + auto main_rpc_port = command_line::get_arg(vm, cryptonote::rpc::http_server::arg_rpc_bind_port); + auto restricted_rpc_port = command_line::get_arg(vm, cryptonote::rpc::http_server::arg_rpc_restricted_bind_port); + + if (main_rpc_port == 0) { + if (restricted && restricted_rpc_port != 0) + std::swap(main_rpc_port, restricted_rpc_port); + else if (command_line::get_arg(vm, cryptonote::arg_testnet_on)) + main_rpc_port = config::testnet::RPC_DEFAULT_PORT; + else if (command_line::get_arg(vm, cryptonote::arg_devnet_on)) + main_rpc_port = config::devnet::RPC_DEFAULT_PORT; + else + main_rpc_port = config::testnet::RPC_DEFAULT_PORT; + } + if (main_rpc_port && main_rpc_port == restricted_rpc_port) + restricted = true; + + std::vector public_ports; + if (restricted) + public_ports.push_back(main_rpc_port); + if (restricted_rpc_port && restricted_rpc_port != main_rpc_port) + public_ports.push_back(restricted_rpc_port); + + for (uint16_t port : public_ports) { + rpc_listen_public.emplace_back(rpc_config.bind_ip.value_or("127.0.0.1"), main_rpc_port, rpc_config.require_ipv4); + if (rpc_config.bind_ipv6_address || rpc_config.use_ipv6) + rpc_listen_public.emplace_back(rpc_config.bind_ipv6_address.value_or("::1"), main_rpc_port, true); + } + + if (!restricted && main_rpc_port) { + rpc_listen_admin.emplace_back(rpc_config.bind_ip.value_or("127.0.0.1"), main_rpc_port, rpc_config.require_ipv4); + if (rpc_config.bind_ipv6_address || rpc_config.use_ipv6) + rpc_listen_public.emplace_back(rpc_config.bind_ipv6_address.value_or("::1"), main_rpc_port, true); + } + } + else + { // no deprecated options + + for (auto& bind : command_line::get_arg(vm, cryptonote::rpc::http_server::arg_rpc_admin)) { + if (bind == "none") continue; + auto [ip, port] = parse_ip_port(bind, "--rpc-admin"); + bool ipv4 = ip.find(':') == std::string::npos; + // If using the default admin setting then don't require the bind to IPv6 localhost, or the + // IPv4 localhost bind if --rpc-ignore-ipv4 is given. + bool required = !command_line::is_arg_defaulted(vm, cryptonote::rpc::http_server::arg_rpc_admin) + || (ipv4 && rpc_config.require_ipv4); + rpc_listen_admin.emplace_back(std::move(ip), port, required); + } + for (auto& bind : command_line::get_arg(vm, cryptonote::rpc::http_server::arg_rpc_public)) { + // Much simpler, since this is default empty: everything specified is required. + auto [ip, port] = parse_ip_port(bind, "--rpc-public"); + rpc_listen_public.emplace_back(std::move(ip), port, true); + } } - if (!command_line::is_arg_defaulted(vm, cryptonote::rpc::http_server::arg_rpc_restricted_bind_port)) + if (!rpc_listen_admin.empty()) { - bool restricted = true; - auto restricted_rpc_port = command_line::get_arg(vm, cryptonote::rpc::http_server::arg_rpc_restricted_bind_port); - MGINFO("- restricted HTTP RPC server"); - http_rpcs.emplace_back(std::piecewise_construct, std::tie("restricted"), std::tie(*rpc, vm, restricted, restricted_rpc_port)); + MGINFO("- admin HTTP RPC server"); + http_rpc_admin.emplace(*rpc, rpc_config, false /*not restricted*/, std::move(rpc_listen_admin)); + } + + if (!rpc_listen_public.empty()) + { + MGINFO("- public HTTP RPC server"); + http_rpc_public.emplace(*rpc, rpc_config, true /*restricted*/, std::move(rpc_listen_public)); } MGINFO_BLUE("Done daemon object initialization"); @@ -152,9 +229,13 @@ daemon::~daemon() { MGINFO_BLUE("Deinitializing daemon objects..."); - while (!http_rpcs.empty()) { - MGINFO("- " << http_rpcs.back().first << " HTTP RPC server"); - http_rpcs.pop_back(); + if (http_rpc_public) { + MGINFO("- public HTTP RPC server"); + http_rpc_public.reset(); + } + if (http_rpc_admin) { + MGINFO("- admin HTTP RPC server"); + http_rpc_admin.reset(); } MGINFO("- p2p"); @@ -192,7 +273,7 @@ void daemon::init_options(boost::program_options::options_description& option_sp cryptonote::core::init_options(option_spec); node_server::init_options(option_spec); cryptonote::rpc::core_rpc_server::init_options(option_spec, hidden); - cryptonote::rpc::http_server::init_options(option_spec); + cryptonote::rpc::http_server::init_options(option_spec, hidden); cryptonote::rpc::init_lmq_options(option_spec); quorumnet::init_core_callbacks(); } @@ -233,21 +314,18 @@ bool daemon::run(bool interactive) lmq_rpc = std::make_unique(*core, *rpc, vm); core->start_lokimq(); - for(auto& [desc, rpc]: http_rpcs) - { - MGINFO("Starting " << desc << " HTTP RPC server"); - rpc.start(); + if (http_rpc_admin) { + MGINFO("Starting admin HTTP RPC server"); + http_rpc_admin->start(); + } + if (http_rpc_public) { + MGINFO("Starting public HTTP RPC server"); + http_rpc_public->start(); } MGINFO("Starting RPC daemon handler"); cryptonote::rpc::DaemonHandler rpc_daemon_handler(*core, *p2p); - if (uint16_t public_rpc_port = parse_public_rpc_port(vm)) - { - MGINFO("Public RPC port " << public_rpc_port << " will be advertised to other peers over P2P"); - p2p->set_rpc_port(public_rpc_port); - } - std::unique_ptr rpc_commands; if (interactive) { @@ -271,10 +349,13 @@ bool daemon::run(bool interactive) rpc_commands->stop_handling(); } - for (auto& [desc, rpc] : http_rpcs) - { - MGINFO("Stopping " << desc << " HTTP RPC server..."); - rpc.shutdown(); + if (http_rpc_public) { + MGINFO("Stopping public HTTP RPC server..."); + http_rpc_public->shutdown(); + } + if (http_rpc_admin) { + MGINFO("Stopping admin HTTP RPC server..."); + http_rpc_admin->shutdown(); } MGINFO("Node stopped."); diff --git a/src/daemon/daemon.h b/src/daemon/daemon.h index 254c4d38d..3d8891a98 100644 --- a/src/daemon/daemon.h +++ b/src/daemon/daemon.h @@ -40,7 +40,7 @@ #include "rpc/core_rpc_server.h" #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_protocol/cryptonote_protocol_handler.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "daemon" @@ -72,7 +72,7 @@ private: std::unique_ptr protocol; std::unique_ptr p2p; std::unique_ptr rpc; - std::list> http_rpcs; + std::optional http_rpc_admin, http_rpc_public; std::unique_ptr lmq_rpc; }; diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp index 4f13abb19..0dc4d360b 100644 --- a/src/daemon/main.cpp +++ b/src/daemon/main.cpp @@ -34,9 +34,10 @@ #include "common/scoped_message_writer.h" #include "common/password.h" #include "common/util.h" +#include "common/fs.h" #include "cryptonote_core/cryptonote_core.h" #include "daemonizer/daemonizer.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "p2p/net_node.h" #include "rpc/rpc_args.h" #include "rpc/core_rpc_server.h" @@ -54,7 +55,6 @@ #define LOKI_DEFAULT_LOG_CATEGORY "daemon" namespace po = boost::program_options; -namespace bf = boost::filesystem; using namespace std::literals; @@ -133,15 +133,16 @@ int main(int argc, char const * argv[]) return 0; } - std::string config = command_line::get_arg(vm, daemon_args::arg_config_file); - boost::filesystem::path config_path(config); - boost::system::error_code ec; - if (bf::exists(config_path, ec)) + auto config = fs::u8path(command_line::get_arg(vm, daemon_args::arg_config_file)); + if (std::error_code ec; fs::exists(config, ec)) { try { + fs::ifstream cfg{config}; + if (!cfg.is_open()) + throw std::runtime_error{"Unable to open file"}; po::store(po::parse_config_file( - config_path.string().c_str(), + cfg, po::options_description{}.add(core_settings).add(hidden_options)), vm); } @@ -174,12 +175,11 @@ int main(int argc, char const * argv[]) // relative path: relative to cwd // Create data dir if it doesn't exist - boost::filesystem::path data_dir = boost::filesystem::absolute( - command_line::get_arg(vm, cryptonote::arg_data_dir)); + auto data_dir = fs::absolute(fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir))); // FIXME: not sure on windows implementation default, needs further review - //bf::path relative_path_base = daemonizer::get_relative_path_base(vm); - bf::path relative_path_base = data_dir; + //fs::path relative_path_base = daemonizer::get_relative_path_base(vm); + fs::path relative_path_base = data_dir; po::notify(vm); @@ -188,11 +188,11 @@ int main(int argc, char const * argv[]) // if log-file argument given: // absolute path // relative path: relative to data_dir - bf::path log_file_path {data_dir / std::string(CRYPTONOTE_NAME ".log")}; + auto log_file_path = data_dir / CRYPTONOTE_NAME ".log"; if (!command_line::is_arg_defaulted(vm, daemon_args::arg_log_file)) log_file_path = command_line::get_arg(vm, daemon_args::arg_log_file); - if (!log_file_path.has_parent_path()) - log_file_path = bf::absolute(log_file_path, relative_path_base); + if (log_file_path.is_relative()) + log_file_path = fs::absolute(fs::relative(log_file_path, relative_path_base)); mlog_configure(log_file_path.string(), true, command_line::get_arg(vm, daemon_args::arg_max_log_file_size), command_line::get_arg(vm, daemon_args::arg_max_log_files)); // Set log level @@ -202,7 +202,7 @@ int main(int argc, char const * argv[]) } // after logs initialized - tools::create_directories_if_necessary(data_dir.string()); + tools::create_directories_if_necessary(data_dir); #ifdef STACK_TRACE tools::set_stack_trace_log(log_file_path.filename().string()); diff --git a/src/daemon/rpc_command_executor.cpp b/src/daemon/rpc_command_executor.cpp index bfc6b0904..c9016b17b 100644 --- a/src/daemon/rpc_command_executor.cpp +++ b/src/daemon/rpc_command_executor.cpp @@ -29,13 +29,13 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "string_tools.h" +#include "epee/string_tools.h" #include "common/password.h" #include "common/scoped_message_writer.h" #include "common/pruning.h" #include "common/hex.h" #include "daemon/rpc_command_executor.h" -#include "int-util.h" +#include "epee/int-util.h" #include "rpc/core_rpc_server_commands_defs.h" #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_core/service_node_rules.h" @@ -45,8 +45,6 @@ #include "common/loki_integration_test_hooks.h" -#include - #include #include #include @@ -138,9 +136,7 @@ namespace { std::string elapsed = peer.last_seen == 0 ? "never" : epee::misc_utils::get_time_interval_string(now - last_seen); std::string id_str = epee::string_tools::pad_string(epee::string_tools::to_string_hex(peer.id), 16, '0', true); - std::string port_str; - epee::string_tools::xtype_to_string(peer.port, port_str); - std::string addr_str = peer.host + ":" + port_str; + std::string addr_str = peer.host + ":" + std::to_string(peer.port); std::string rpc_port = peer.rpc_port ? std::to_string(peer.rpc_port) : "-"; std::string pruning_seed = epee::string_tools::to_string_hex(peer.pruning_seed); tools::msg_writer() << boost::format("%-10s %-25s %-25s %-5s %-4s %s") % prefix % id_str % addr_str % rpc_port % pruning_seed % elapsed; @@ -149,15 +145,15 @@ namespace { void print_block_header(block_header_response const & header) { tools::success_msg_writer() - << "timestamp: " << boost::lexical_cast(header.timestamp) << " (" << tools::get_human_readable_timestamp(header.timestamp) << ")" << "\n" + << "timestamp: " << header.timestamp << " (" << tools::get_human_readable_timestamp(header.timestamp) << ")" << "\n" << "previous hash: " << header.prev_hash << "\n" - << "nonce: " << boost::lexical_cast(header.nonce) << "\n" + << "nonce: " << header.nonce << "\n" << "is orphan: " << header.orphan_status << "\n" - << "height: " << boost::lexical_cast(header.height) << "\n" - << "depth: " << boost::lexical_cast(header.depth) << "\n" + << "height: " << header.height << "\n" + << "depth: " << header.depth << "\n" << "hash: " << header.hash << "\n" - << "difficulty: " << boost::lexical_cast(header.difficulty) << "\n" - << "cumulative_difficulty: " << boost::lexical_cast(header.cumulative_difficulty) << "\n" + << "difficulty: " << header.difficulty << "\n" + << "cumulative_difficulty: " << header.cumulative_difficulty << "\n" << "POW hash: " << header.pow_hash.value_or("N/A") << "\n" << "block size: " << header.block_size << "\n" << "block weight: " << header.block_weight << "\n" @@ -176,7 +172,7 @@ namespace { time_t dt = t > now ? t - now : now - t; std::string s; if (dt < 90) - s = boost::lexical_cast(dt) + (abbreviate ? "sec" : dt == 1 ? " second" : " seconds"); + s = std::to_string(dt) + (abbreviate ? "sec" : dt == 1 ? " second" : " seconds"); else if (dt < 90 * 60) s = (boost::format(abbreviate ? "%.1fmin" : "%.1f minutes") % ((float)dt/60)).str(); else if (dt < 36 * 3600) @@ -822,7 +818,7 @@ bool rpc_command_executor::print_block(GET_BLOCK::request&& req, bool include_he bool rpc_command_executor::print_block_by_hash(const crypto::hash& block_hash, bool include_hex) { GET_BLOCK::request req{}; - req.hash = epee::string_tools::pod_to_hex(block_hash); + req.hash = tools::type_to_hex(block_hash); return print_block(std::move(req), include_hex); } @@ -902,7 +898,7 @@ bool rpc_command_executor::print_transaction(const crypto::hash& transaction_has bool rpc_command_executor::is_key_image_spent(const crypto::key_image &ki) { IS_KEY_IMAGE_SPENT::response res{}; - if (!invoke({{epee::string_tools::pod_to_hex(ki)}}, res, "Failed to retrieve key image status")) + if (!invoke({{tools::type_to_hex(ki)}}, res, "Failed to retrieve key image status")) return false; if (1 == res.spent_status.size()) @@ -937,7 +933,7 @@ static void print_pool(const std::vector &transactions /// (we can't back out the individual per_out and per_byte that got used anyway). << "fee/byte: " << cryptonote::print_money(tx_info.fee / (double)tx_info.weight) << "\n" << "receive_time: " << tx_info.receive_time << " (" << get_human_time_ago(tx_info.receive_time, now) << ")\n" - << "relayed: " << (tx_info.relayed ? boost::lexical_cast(tx_info.last_relayed_time) + " (" + get_human_time_ago(tx_info.last_relayed_time, now) + ")" : "no") << "\n" + << "relayed: " << (tx_info.relayed ? std::to_string(tx_info.last_relayed_time) + " (" + get_human_time_ago(tx_info.last_relayed_time, now) + ")" : "no") << "\n" << std::boolalpha << "do_not_relay: " << tx_info.do_not_relay << "\n" << "blink: " << tx_info.blink << "\n" @@ -1338,7 +1334,7 @@ bool rpc_command_executor::alt_chain_info(const std::string &tip, size_t above, continue; display.push_back(i); } - tools::msg_writer() << boost::lexical_cast(display.size()) << " alternate chains found:"; + tools::msg_writer() << display.size() << " alternate chains found:"; for (const size_t idx: display) { const auto &chain = chains[idx]; diff --git a/src/daemonizer/CMakeLists.txt b/src/daemonizer/CMakeLists.txt index 480a5c057..e33108fe7 100644 --- a/src/daemonizer/CMakeLists.txt +++ b/src/daemonizer/CMakeLists.txt @@ -35,7 +35,7 @@ if(MSVC OR MINGW) target_link_libraries(daemonizer PUBLIC common - Boost::filesystem + filesystem Boost::program_options PRIVATE extra) diff --git a/src/daemonizer/daemonizer.h b/src/daemonizer/daemonizer.h index 4d575b9e8..f2631f2f4 100644 --- a/src/daemonizer/daemonizer.h +++ b/src/daemonizer/daemonizer.h @@ -28,9 +28,9 @@ #pragma once -#include #include #include +#include "common/fs.h" namespace daemonizer { @@ -39,9 +39,9 @@ namespace daemonizer , boost::program_options::options_description & normal_options ); - boost::filesystem::path get_default_data_dir(); + fs::path get_default_data_dir(); - boost::filesystem::path get_relative_path_base( + fs::path get_relative_path_base( boost::program_options::variables_map const & vm ); diff --git a/src/daemonizer/posix_daemonizer.inl b/src/daemonizer/posix_daemonizer.inl index a22bed979..cdff675f8 100644 --- a/src/daemonizer/posix_daemonizer.inl +++ b/src/daemonizer/posix_daemonizer.inl @@ -33,9 +33,6 @@ #include "common/file.h" #include "common/command_line.h" -#include -#include - namespace daemonizer { namespace @@ -59,16 +56,16 @@ namespace daemonizer command_line::add_arg(normal_options, arg_non_interactive); } - inline boost::filesystem::path get_default_data_dir() + inline fs::path get_default_data_dir() { - return boost::filesystem::absolute(tools::get_default_data_dir()); + return fs::absolute(tools::get_default_data_dir()); } - inline boost::filesystem::path get_relative_path_base( + inline fs::path get_relative_path_base( boost::program_options::variables_map const & vm ) { - return boost::filesystem::current_path(); + return fs::current_path(); } template diff --git a/src/daemonizer/windows_daemonizer.inl b/src/daemonizer/windows_daemonizer.inl index 1f7969133..f93f19d90 100644 --- a/src/daemonizer/windows_daemonizer.inl +++ b/src/daemonizer/windows_daemonizer.inl @@ -36,8 +36,6 @@ #include "cryptonote_core/cryptonote_core.h" #include -#include -#include namespace daemonizer { @@ -92,7 +90,7 @@ namespace daemonizer command_line::add_arg(hidden_options, arg_non_interactive); } - inline boost::filesystem::path get_default_data_dir() + inline fs::path get_default_data_dir() { bool admin; if (!windows::check_admin(admin)) @@ -101,19 +99,19 @@ namespace daemonizer } if (admin) { - return boost::filesystem::absolute( - tools::get_special_folder_path(CSIDL_COMMON_APPDATA, true) + "\\" + CRYPTONOTE_NAME + return fs::absolute( + tools::get_special_folder_path(CSIDL_COMMON_APPDATA, true) / CRYPTONOTE_NAME ); } else { - return boost::filesystem::absolute( - tools::get_special_folder_path(CSIDL_APPDATA, true) + "\\" + CRYPTONOTE_NAME + return fs::absolute( + tools::get_special_folder_path(CSIDL_APPDATA, true) / CRYPTONOTE_NAME ); } } - inline boost::filesystem::path get_relative_path_base( + inline fs::path get_relative_path_base( boost::program_options::variables_map const & vm ) { @@ -130,7 +128,7 @@ namespace daemonizer } else { - return boost::filesystem::current_path(); + return fs::current_path(); } } diff --git a/src/daemonizer/windows_service.cpp b/src/daemonizer/windows_service.cpp index 35ee2bb6a..3e3eca269 100644 --- a/src/daemonizer/windows_service.cpp +++ b/src/daemonizer/windows_service.cpp @@ -31,7 +31,7 @@ #include "common/scoped_message_writer.h" #include "daemonizer/windows_service.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include #include #include diff --git a/src/debug_utilities/CMakeLists.txt b/src/debug_utilities/CMakeLists.txt index d9f8c0306..69dcdd78d 100644 --- a/src/debug_utilities/CMakeLists.txt +++ b/src/debug_utilities/CMakeLists.txt @@ -61,5 +61,4 @@ target_link_libraries(dns_checks epee version Boost::program_options - Boost::system Boost::thread) diff --git a/src/debug_utilities/cn_deserialize.cpp b/src/debug_utilities/cn_deserialize.cpp index 5893af581..908bc6fe5 100644 --- a/src/debug_utilities/cn_deserialize.cpp +++ b/src/debug_utilities/cn_deserialize.cpp @@ -27,7 +27,6 @@ // 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 #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/tx_extra.h" #include "cryptonote_core/blockchain.h" @@ -47,10 +46,10 @@ using namespace cryptonote; static std::string extra_nonce_to_string(const cryptonote::tx_extra_nonce &extra_nonce) { if (extra_nonce.nonce.size() == 9 && extra_nonce.nonce[0] == TX_EXTRA_NONCE_ENCRYPTED_PAYMENT_ID) - return "encrypted payment ID: " + epee::string_tools::buff_to_hex_nodelimer(extra_nonce.nonce.substr(1)); + return "encrypted payment ID: " + lokimq::to_hex(extra_nonce.nonce.begin() + 1, extra_nonce.nonce.end()); if (extra_nonce.nonce.size() == 33 && extra_nonce.nonce[0] == TX_EXTRA_NONCE_PAYMENT_ID) - return "plaintext payment ID: " + epee::string_tools::buff_to_hex_nodelimer(extra_nonce.nonce.substr(1)); - return epee::string_tools::buff_to_hex_nodelimer(extra_nonce.nonce); + return "plaintext payment ID: " + lokimq::to_hex(extra_nonce.nonce.begin() + 1, extra_nonce.nonce.end()); + return lokimq::to_hex(extra_nonce.nonce); } struct extra_printer { @@ -126,8 +125,6 @@ int main(int argc, char* argv[]) tools::on_startup(); - boost::filesystem::path output_file_path; - po::options_description desc_cmd_only("Command line options"); po::options_description desc_cmd_sett("Command line options and settings options"); const command_line::arg_descriptor arg_log_level = {"log-level", "", log_level}; diff --git a/src/debug_utilities/dns_checks.cpp b/src/debug_utilities/dns_checks.cpp index 66428eb5f..a04573244 100644 --- a/src/debug_utilities/dns_checks.cpp +++ b/src/debug_utilities/dns_checks.cpp @@ -31,7 +31,7 @@ #include #include #include -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "common/util.h" #include "common/command_line.h" #include "common/dns_utils.h" diff --git a/src/debug_utilities/object_sizes.cpp b/src/debug_utilities/object_sizes.cpp index 8620a31cc..1524953d9 100644 --- a/src/debug_utilities/object_sizes.cpp +++ b/src/debug_utilities/object_sizes.cpp @@ -33,7 +33,7 @@ #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_core/blockchain.h" #include "p2p/p2p_protocol_defs.h" -#include "net/connection_basic.hpp" +#include "epee/net/connection_basic.hpp" #include "p2p/net_peerlist.h" #include "p2p/net_node.h" #include "cryptonote_protocol/cryptonote_protocol_handler.h" @@ -111,12 +111,12 @@ int main(int argc, char* argv[]) SL(wallet::unsigned_tx_set); SL(wallet::signed_tx_set); - SL(Monero::WalletImpl); - SL(Monero::AddressBookRow); - SL(Monero::TransactionInfoImpl); - SL(Monero::TransactionHistoryImpl); - SL(Monero::PendingTransactionImpl); - SL(Monero::UnsignedTransactionImpl); + SL(Wallet::WalletImpl); + SL(Wallet::AddressBookRow); + SL(Wallet::TransactionInfoImpl); + SL(Wallet::TransactionHistoryImpl); + SL(Wallet::PendingTransactionImpl); + SL(Wallet::UnsignedTransactionImpl); return 0; } diff --git a/src/device/device.cpp b/src/device/device.cpp index fbd77dab9..2809a2756 100644 --- a/src/device/device.cpp +++ b/src/device/device.cpp @@ -32,7 +32,7 @@ #ifdef WITH_DEVICE_LEDGER #include "device_ledger.hpp" #endif -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" namespace hw { diff --git a/src/device/device_default.cpp b/src/device/device_default.cpp index caef897a3..fe5a4e87e 100644 --- a/src/device/device_default.cpp +++ b/src/device/device_default.cpp @@ -31,7 +31,7 @@ #include "device_default.hpp" -#include "int-util.h" +#include "epee/int-util.h" #include "cryptonote_basic/account.h" #include "cryptonote_basic/subaddress_index.h" #include "cryptonote_core/cryptonote_tx_utils.h" diff --git a/src/device/log.cpp b/src/device/log.cpp index 608e02a6e..19c737f98 100644 --- a/src/device/log.cpp +++ b/src/device/log.cpp @@ -28,7 +28,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "log.hpp" namespace hw { diff --git a/src/device_trezor/device_trezor_base.cpp b/src/device_trezor/device_trezor_base.cpp index 5809e266b..73ca425f2 100644 --- a/src/device_trezor/device_trezor_base.cpp +++ b/src/device_trezor/device_trezor_base.cpp @@ -28,7 +28,7 @@ // #include "device_trezor_base.hpp" -#include "memwipe.h" +#include "epee/memwipe.h" #include "common/lock.h" #include "common/string_util.h" diff --git a/src/device_trezor/trezor/protocol.cpp b/src/device_trezor/trezor/protocol.cpp index 299d31268..0662e1c46 100644 --- a/src/device_trezor/trezor/protocol.cpp +++ b/src/device_trezor/trezor/protocol.cpp @@ -39,6 +39,7 @@ #include #include #include "cryptonote_config.h" +#include "common/hex.h" #include #include #include @@ -269,12 +270,12 @@ namespace ki { pkeys.push_back(&out_key); CHECK_AND_ASSERT_THROW_MES(rct::scalarmultKey(rct::ki2rct(ki), rct::curveOrder()) == rct::identity(), - "Key image out of validity domain: key image " << epee::string_tools::pod_to_hex(ki)); + "Key image out of validity domain: key image " << tools::type_to_hex(ki)); CHECK_AND_ASSERT_THROW_MES(::crypto::check_ring_signature((const ::crypto::hash&)ki, ki, pkeys, &sig), - "Signature failed for key image " << epee::string_tools::pod_to_hex(ki) - << ", signature " + epee::string_tools::pod_to_hex(sig) - << ", pubkey " + epee::string_tools::pod_to_hex(*pkeys[0])); + "Signature failed for key image " << tools::type_to_hex(ki) + << ", signature " + tools::type_to_hex(sig) + << ", pubkey " + tools::type_to_hex(*pkeys[0])); } } diff --git a/src/device_trezor/trezor/transport.hpp b/src/device_trezor/trezor/transport.hpp index 7de2fdcf0..0e0f6abf0 100644 --- a/src/device_trezor/trezor/transport.hpp +++ b/src/device_trezor/trezor/transport.hpp @@ -40,8 +40,8 @@ #include -#include "wipeable_string.h" -#include "misc_log_ex.h" +#include "epee/wipeable_string.h" +#include "epee/misc_log_ex.h" #include "rapidjson/document.h" #include "rapidjson/writer.h" diff --git a/src/gen_multisig/CMakeLists.txt b/src/gen_multisig/CMakeLists.txt index df97c8855..e6446e575 100644 --- a/src/gen_multisig/CMakeLists.txt +++ b/src/gen_multisig/CMakeLists.txt @@ -38,6 +38,6 @@ target_link_libraries(gen_multisig cryptonote_core epee Boost::program_options - Boost::filesystem + filesystem version extra) diff --git a/src/gen_multisig/gen_multisig.cpp b/src/gen_multisig/gen_multisig.cpp index 8cb957ceb..1f76bcf30 100644 --- a/src/gen_multisig/gen_multisig.cpp +++ b/src/gen_multisig/gen_multisig.cpp @@ -39,7 +39,6 @@ #include #include #include -#include "include_base_utils.h" #include "crypto/crypto.h" // for crypto::secret_key definition #include "common/i18n.h" #include "common/command_line.h" @@ -77,7 +76,7 @@ namespace const command_line::arg_descriptor< std::vector > arg_command = {"command", ""}; } -static bool generate_multisig(uint32_t threshold, uint32_t total, const std::string &basename, network_type nettype, bool create_address_file) +static bool generate_multisig(uint32_t threshold, uint32_t total, const fs::path& basename, network_type nettype, bool create_address_file) { tools::msg_writer() << (boost::format(genms::tr("Generating %u %u/%u multisig wallets")) % total % threshold % total).str(); @@ -89,7 +88,8 @@ static bool generate_multisig(uint32_t threshold, uint32_t total, const std::str std::vector> wallets(total); for (size_t n = 0; n < total; ++n) { - std::string name = basename + "-" + std::to_string(n + 1); + fs::path name = basename; + name += "-" + std::to_string(n + 1); wallets[n].reset(new tools::wallet2(nettype, 1, false)); wallets[n]->init(""); wallets[n]->generate(name, pwd_container->password(), rct::rct2sk(rct::skGen()), false, false, create_address_file); @@ -114,7 +114,8 @@ static bool generate_multisig(uint32_t threshold, uint32_t total, const std::str std::stringstream ss; for (size_t n = 0; n < total; ++n) { - std::string name = basename + "-" + std::to_string(n + 1); + fs::path name = basename; + name += "-" + std::to_string(n + 1); std::vector skn; std::vector pkn; for (size_t k = 0; k < total; ++k) @@ -190,7 +191,6 @@ int main(int argc, char* argv[]) bool testnet, devnet; uint32_t threshold = 0, total = 0; - std::string basename; testnet = command_line::get_arg(*vm, arg_testnet); devnet = command_line::get_arg(*vm, arg_devnet); @@ -230,9 +230,10 @@ int main(int argc, char* argv[]) tools::fail_msg_writer() << (boost::format(genms::tr("Error: expected N > 1 and N <= M, but got N==%u and M==%d")) % threshold % total).str(); return 1; } + fs::path basename; if (!(*vm)["filename-base"].defaulted() && !command_line::get_arg(*vm, arg_filename_base).empty()) { - basename = command_line::get_arg(*vm, arg_filename_base); + basename = fs::u8path(command_line::get_arg(*vm, arg_filename_base)); } else { diff --git a/src/lmdb/key_stream.h b/src/lmdb/key_stream.h index 40434d3a1..65921701b 100644 --- a/src/lmdb/key_stream.h +++ b/src/lmdb/key_stream.h @@ -34,7 +34,7 @@ #include #include "lmdb/value_stream.h" -#include "span.h" +#include "epee/span.h" namespace lmdb { diff --git a/src/lmdb/util.h b/src/lmdb/util.h index 4efb6063d..6a332f8d0 100644 --- a/src/lmdb/util.h +++ b/src/lmdb/util.h @@ -32,7 +32,7 @@ #include #include -#include "span.h" +#include "epee/span.h" /*! Calculates types and offset of struct field. Use in template arguments for `table::get_value`, `value_iterator::get_value`, diff --git a/src/lmdb/value_stream.h b/src/lmdb/value_stream.h index 01090aa67..df73ceee1 100644 --- a/src/lmdb/value_stream.h +++ b/src/lmdb/value_stream.h @@ -33,7 +33,7 @@ #include #include -#include "span.h" +#include "epee/span.h" namespace lmdb { diff --git a/src/mnemonics/electrum-words.cpp b/src/mnemonics/electrum-words.cpp index cd9f3c663..7dc67542e 100644 --- a/src/mnemonics/electrum-words.cpp +++ b/src/mnemonics/electrum-words.cpp @@ -40,9 +40,9 @@ #include #include #include -#include "wipeable_string.h" -#include "misc_language.h" -#include "int-util.h" +#include "epee/wipeable_string.h" +#include "epee/misc_language.h" +#include "epee/int-util.h" #include "mnemonics/electrum-words.h" #include "common/loki.h" #include diff --git a/src/mnemonics/language_base.h b/src/mnemonics/language_base.h index 41ac44ee0..313ac3afa 100644 --- a/src/mnemonics/language_base.h +++ b/src/mnemonics/language_base.h @@ -38,8 +38,8 @@ #include #include #include -#include "misc_log_ex.h" -#include "fnv1.h" +#include "epee/misc_log_ex.h" +#include "epee/fnv1.h" /*! * \namespace Language diff --git a/src/multisig/multisig.cpp b/src/multisig/multisig.cpp index 93918dba4..1e92fc7a4 100644 --- a/src/multisig/multisig.cpp +++ b/src/multisig/multisig.cpp @@ -28,7 +28,6 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include "include_base_utils.h" #include "crypto/crypto.h" #include "ringct/rctOps.h" #include "cryptonote_basic/account.h" diff --git a/src/net/dandelionpp.h b/src/net/dandelionpp.h index 75b63bc0c..e156b5857 100644 --- a/src/net/dandelionpp.h +++ b/src/net/dandelionpp.h @@ -34,7 +34,7 @@ #include #include -#include "span.h" +#include "epee/span.h" namespace net { diff --git a/src/net/epee_network_address_hack.cpp b/src/net/epee_network_address_hack.cpp index 968842439..564dc088e 100644 --- a/src/net/epee_network_address_hack.cpp +++ b/src/net/epee_network_address_hack.cpp @@ -1,5 +1,5 @@ -#include "net/net_utils_base.h" -#include "storages/portable_storage.h" +#include "epee/net/net_utils_base.h" +#include "epee/storages/portable_storage.h" #include "tor_address.h" #include "i2p_address.h" diff --git a/src/net/i2p_address.cpp b/src/net/i2p_address.cpp index 2f49a12dd..193e440e9 100644 --- a/src/net/i2p_address.cpp +++ b/src/net/i2p_address.cpp @@ -35,10 +35,9 @@ #include #include -#include "net/error.h" -#include "serialization/keyvalue_serialization.h" -#include "storages/portable_storage.h" -#include "string_tools.h" +#include "epee/serialization/keyvalue_serialization.h" +#include "epee/storages/portable_storage.h" +#include "epee/string_tools.h" #include "common/string_util.h" namespace net diff --git a/src/net/i2p_address.h b/src/net/i2p_address.h index 6160268cf..a30202215 100644 --- a/src/net/i2p_address.h +++ b/src/net/i2p_address.h @@ -33,8 +33,8 @@ #include #include "common/expect.h" -#include "net/enums.h" -#include "net/error.h" +#include "epee/net/enums.h" +#include "error.h" namespace epee { diff --git a/src/net/parse.cpp b/src/net/parse.cpp index 42e630a4b..189ca33bf 100644 --- a/src/net/parse.cpp +++ b/src/net/parse.cpp @@ -33,7 +33,7 @@ #include "net/tor_address.h" #include "net/i2p_address.h" #include "common/string_util.h" -#include "string_tools.h" // epee +#include "epee/string_tools.h" namespace net { diff --git a/src/net/parse.h b/src/net/parse.h index efa2a23c8..7f9363bc3 100644 --- a/src/net/parse.h +++ b/src/net/parse.h @@ -32,7 +32,7 @@ #include #include "common/expect.h" -#include "net/net_utils_base.h" +#include "epee/net/net_utils_base.h" namespace net { diff --git a/src/net/socks.cpp b/src/net/socks.cpp index 46b31c40f..5dac3385b 100644 --- a/src/net/socks.cpp +++ b/src/net/socks.cpp @@ -39,7 +39,7 @@ #include #include -#include "net/net_utils_base.h" +#include "epee/net/net_utils_base.h" #include "net/tor_address.h" #include "net/i2p_address.h" diff --git a/src/net/socks.h b/src/net/socks.h index 79aba81b9..d9ffe26c0 100644 --- a/src/net/socks.h +++ b/src/net/socks.h @@ -39,7 +39,7 @@ #include #include "net/fwd.h" -#include "span.h" +#include "epee/span.h" namespace epee { diff --git a/src/net/tor_address.cpp b/src/net/tor_address.cpp index ebbd7e660..2b12686d8 100644 --- a/src/net/tor_address.cpp +++ b/src/net/tor_address.cpp @@ -36,10 +36,9 @@ #include #include -#include "net/error.h" -#include "serialization/keyvalue_serialization.h" -#include "storages/portable_storage.h" -#include "string_tools.h" +#include "epee/serialization/keyvalue_serialization.h" +#include "epee/storages/portable_storage.h" +#include "epee/string_tools.h" #include "common/string_util.h" namespace net diff --git a/src/net/tor_address.h b/src/net/tor_address.h index 6639849f0..be5ec4077 100644 --- a/src/net/tor_address.h +++ b/src/net/tor_address.h @@ -33,8 +33,8 @@ #include #include "common/expect.h" -#include "net/enums.h" -#include "net/error.h" +#include "epee/net/enums.h" +#include "error.h" namespace epee { diff --git a/src/p2p/CMakeLists.txt b/src/p2p/CMakeLists.txt index e3922c12d..f89db92d5 100644 --- a/src/p2p/CMakeLists.txt +++ b/src/p2p/CMakeLists.txt @@ -41,6 +41,6 @@ target_link_libraries(p2p net miniupnpc Boost::program_options - Boost::filesystem + filesystem Boost::serialization extra) diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp index b7f398bf7..ac13d4d54 100644 --- a/src/p2p/net_node.cpp +++ b/src/p2p/net_node.cpp @@ -40,13 +40,13 @@ #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_protocol/cryptonote_protocol_defs.h" #include "net_node.h" -#include "net/net_utils_base.h" +#include "epee/net/net_utils_base.h" #include "net/socks.h" #include "net/parse.h" #include "net/tor_address.h" #include "net/i2p_address.h" #include "p2p/p2p_protocol_defs.h" -#include "string_tools.h" +#include "epee/string_tools.h" namespace { diff --git a/src/p2p/net_node.h b/src/p2p/net_node.h index 25e914295..4d095d6f6 100644 --- a/src/p2p/net_node.h +++ b/src/p2p/net_node.h @@ -43,18 +43,19 @@ #include "cryptonote_config.h" #include "cryptonote_protocol/levin_notify.h" -#include "warnings.h" -#include "net/abstract_tcp_server2.h" -#include "net/levin_protocol_handler.h" -#include "net/levin_protocol_handler_async.h" +#include "epee/warnings.h" +#include "epee/net/abstract_tcp_server2.h" +#include "epee/net/levin_protocol_handler.h" +#include "epee/net/levin_protocol_handler_async.h" #include "p2p_protocol_defs.h" -#include "storages/levin_abstract_invoke2.h" +#include "epee/storages/levin_abstract_invoke2.h" #include "net_peerlist.h" #include "net_node_common.h" -#include "net/enums.h" +#include "epee/net/enums.h" #include "net/fwd.h" #include "common/command_line.h" #include "common/periodic_task.h" +#include "common/fs.h" PUSH_WARNINGS DISABLE_VS_WARNINGS(4355) @@ -415,7 +416,7 @@ namespace nodetool } private: - std::string m_config_folder; + fs::path m_config_folder; bool m_have_address; bool m_first_connection_maker_call; diff --git a/src/p2p/net_node.inl b/src/p2p/net_node.inl index 17d42b2fe..18dd0a05f 100644 --- a/src/p2p/net_node.inl +++ b/src/p2p/net_node.inl @@ -33,7 +33,6 @@ #include #include -#include #include #include #include @@ -42,24 +41,27 @@ #include #include +#include "cryptonote_config.h" #include "version.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "common/file.h" #include "common/dns_utils.h" #include "common/pruning.h" #include "net/error.h" #include "common/periodic_task.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "p2p_protocol_defs.h" -#include "net/local_ip.h" +#include "epee/net/local_ip.h" #include "crypto/crypto.h" -#include "storages/levin_abstract_invoke2.h" +#include "epee/storages/levin_abstract_invoke2.h" #include "cryptonote_core/cryptonote_core.h" #include "net/parse.h" +#ifndef WITHOUT_MINIUPNPC #include #include #include +#endif #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "net.p2p" @@ -119,7 +121,7 @@ namespace nodetool bool node_server::init_config() { TRY_ENTRY(); - auto storage = peerlist_storage::open(m_config_folder + "/" + P2P_NET_DATA_FILENAME); + auto storage = peerlist_storage::open(m_config_folder / P2P_NET_DATA_FILENAME); if (storage) m_peerlist_storage = std::move(*storage); @@ -708,14 +710,11 @@ namespace nodetool memcpy(&m_network_id, &::config::NETWORK_ID, 16); } - m_config_folder = command_line::get_arg(vm, cryptonote::arg_data_dir); + m_config_folder = fs::u8path(command_line::get_arg(vm, cryptonote::arg_data_dir)); network_zone& public_zone = m_network_zones.at(epee::net_utils::zone::public_); - if ((m_nettype == cryptonote::MAINNET && public_zone.m_port != std::to_string(::config::P2P_DEFAULT_PORT)) - || (m_nettype == cryptonote::TESTNET && public_zone.m_port != std::to_string(::config::testnet::P2P_DEFAULT_PORT)) - || (m_nettype == cryptonote::DEVNET && public_zone.m_port != std::to_string(::config::devnet::P2P_DEFAULT_PORT))) { - m_config_folder = m_config_folder + "/" + public_zone.m_port; - } + if (public_zone.m_port != std::to_string(cryptonote::get_config(m_nettype).P2P_DEFAULT_PORT)) + m_config_folder /= public_zone.m_port; res = init_config(); CHECK_AND_ASSERT_MES(res, false, "Failed to init config."); @@ -905,7 +904,7 @@ namespace nodetool if (!tools::create_directories_if_necessary(m_config_folder)) { - MWARNING("Failed to create data directory \"" << m_config_folder); + MWARNING("Failed to create data directory " << m_config_folder); return false; } @@ -913,7 +912,7 @@ namespace nodetool for (auto& zone : m_network_zones) zone.second.m_peerlist.get_peerlist(active); - const std::string state_file_path = m_config_folder + "/" + P2P_NET_DATA_FILENAME; + const auto state_file_path = m_config_folder / P2P_NET_DATA_FILENAME; if (!m_peerlist_storage.store(state_file_path, active)) { MWARNING("Failed to save config to file " << state_file_path); @@ -2060,7 +2059,7 @@ namespace nodetool if(!zone.m_peerlist.is_host_allowed(context.m_remote_address)) return false; - std::string port = epee::string_tools::num_to_string_fast(node_data.my_port); + std::string port = std::to_string(node_data.my_port); epee::net_utils::network_address address; if (ipv4_addr) @@ -2657,6 +2656,10 @@ namespace nodetool template void node_server::add_upnp_port_mapping_impl(uint32_t port, bool ipv6) // if ipv6 false, do ipv4 { +#ifdef WITHOUT_MINIUPNPC + (void) port; + (void) ipv6; +#else std::string ipversion = ipv6 ? "(IPv6)" : "(IPv4)"; MDEBUG("Attempting to add IGD port mapping " << ipversion << "."); int result; @@ -2701,6 +2704,7 @@ namespace nodetool } else { MINFO("No IGD was found."); } +#endif } template @@ -2726,6 +2730,10 @@ namespace nodetool template void node_server::delete_upnp_port_mapping_impl(uint32_t port, bool ipv6) { +#ifdef WITHOUT_MINIUPNPC + (void) port; + (void) ipv6; +#else std::string ipversion = ipv6 ? "(IPv6)" : "(IPv4)"; MDEBUG("Attempting to delete IGD port mapping " << ipversion << "."); int result; @@ -2766,6 +2774,7 @@ namespace nodetool } else { MINFO("No IGD was found."); } +#endif } template @@ -2817,13 +2826,13 @@ namespace nodetool { const epee::net_utils::ipv4_network_address &ipv4 = na.as(); address = epee::string_tools::get_ip_string_from_int32(ipv4.ip()); - port = epee::string_tools::num_to_string_fast(ipv4.port()); + port = std::to_string(ipv4.port()); } else { const epee::net_utils::ipv6_network_address &ipv6 = na.as(); address = ipv6.ip().to_string(); - port = epee::string_tools::num_to_string_fast(ipv6.port()); + port = std::to_string(ipv6.port()); } typename net_server::t_connection_context con{}; diff --git a/src/p2p/net_node_common.h b/src/p2p/net_node_common.h index e0046cd86..7d48ff984 100644 --- a/src/p2p/net_node_common.h +++ b/src/p2p/net_node_common.h @@ -34,8 +34,8 @@ #include #include #include "cryptonote_basic/blobdatatype.h" -#include "net/enums.h" -#include "net/net_utils_base.h" +#include "epee/net/enums.h" +#include "epee/net/net_utils_base.h" #include "p2p_protocol_defs.h" namespace nodetool diff --git a/src/p2p/net_peerlist.cpp b/src/p2p/net_peerlist.cpp index 97b235e41..f50b86943 100644 --- a/src/p2p/net_peerlist.cpp +++ b/src/p2p/net_peerlist.cpp @@ -36,11 +36,11 @@ #include #include #include -#include #include #include #include "net_peerlist_boost_serialization.h" +#include "common/fs.h" namespace nodetool @@ -188,10 +188,9 @@ namespace nodetool return std::nullopt; } - std::optional peerlist_storage::open(const std::string& path) + std::optional peerlist_storage::open(const fs::path& path) { - std::ifstream src_file{}; - src_file.open( path , std::ios_base::binary | std::ios_base::in); + fs::ifstream src_file{path, std::ios::binary}; if(src_file.fail()) return std::nullopt; @@ -199,9 +198,11 @@ namespace nodetool if (!out) { // if failed, try reading in unportable mode - boost::filesystem::copy_file(path, path + ".unportable", boost::filesystem::copy_option::overwrite_if_exists); + auto unportable = path; + unportable += ".unportable"; + fs::copy_file(path, unportable, fs::copy_options::overwrite_existing); src_file.close(); - src_file.open( path , std::ios_base::binary | std::ios_base::in); + src_file.open(path, std::ios_base::binary); if(src_file.fail()) return std::nullopt; @@ -237,10 +238,9 @@ namespace nodetool return false; } - bool peerlist_storage::store(const std::string& path, const peerlist_types& other) const + bool peerlist_storage::store(const fs::path& path, const peerlist_types& other) const { - std::ofstream dest_file{}; - dest_file.open( path , std::ios_base::binary | std::ios_base::out| std::ios::trunc); + fs::ofstream dest_file{path, std::ios::binary | std::ios::trunc}; if(dest_file.fail()) return false; diff --git a/src/p2p/net_peerlist.h b/src/p2p/net_peerlist.h index 18fd8ee26..e4f3ff6c7 100644 --- a/src/p2p/net_peerlist.h +++ b/src/p2p/net_peerlist.h @@ -45,10 +45,11 @@ #include "crypto/crypto.h" #include "cryptonote_config.h" -#include "net/enums.h" -#include "net/local_ip.h" +#include "epee/net/enums.h" +#include "epee/net/local_ip.h" #include "p2p_protocol_defs.h" #include "common/random.h" +#include "common/fs.h" namespace nodetool { @@ -70,7 +71,7 @@ namespace nodetool static std::optional open(std::istream& src, const bool new_format); //! \return Peers stored in file at `path` - static std::optional open(const std::string& path); + static std::optional open(const fs::path& path); peerlist_storage(peerlist_storage&&) = default; peerlist_storage(const peerlist_storage&) = delete; @@ -84,7 +85,7 @@ namespace nodetool bool store(std::ostream& dest, const peerlist_types& other) const; //! Save peers from `this` and `other` in one file at `path`. - bool store(const std::string& path, const peerlist_types& other) const; + bool store(const fs::path& path, const peerlist_types& other) const; //! \return Peers in `zone` and from remove from `this`. peerlist_types take_zone(epee::net_utils::zone zone); diff --git a/src/p2p/net_peerlist_boost_serialization.h b/src/p2p/net_peerlist_boost_serialization.h index c2773981c..f88030dd9 100644 --- a/src/p2p/net_peerlist_boost_serialization.h +++ b/src/p2p/net_peerlist_boost_serialization.h @@ -33,7 +33,7 @@ #include #include "common/expect.h" -#include "net/net_utils_base.h" +#include "epee/net/net_utils_base.h" #include "net/tor_address.h" #include "net/i2p_address.h" #include "p2p/p2p_protocol_defs.h" diff --git a/src/p2p/p2p_protocol_defs.h b/src/p2p/p2p_protocol_defs.h index 96b8f1ef0..859a86b62 100644 --- a/src/p2p/p2p_protocol_defs.h +++ b/src/p2p/p2p_protocol_defs.h @@ -32,13 +32,13 @@ #include #include -#include "serialization/keyvalue_serialization.h" -#include "net/net_utils_base.h" +#include "epee/serialization/keyvalue_serialization.h" +#include "epee/net/net_utils_base.h" #include "net/tor_address.h" // needed for serialization #include "net/i2p_address.h" // needed for serialization -#include "misc_language.h" -#include "string_tools.h" -#include "time_helper.h" +#include "epee/misc_language.h" +#include "epee/string_tools.h" +#include "epee/time_helper.h" #include "cryptonote_config.h" #include "crypto/crypto.h" diff --git a/src/ringct/bulletproofs.cc b/src/ringct/bulletproofs.cc index d953932cd..c93356f94 100644 --- a/src/ringct/bulletproofs.cc +++ b/src/ringct/bulletproofs.cc @@ -30,8 +30,8 @@ // Paper references are to https://eprint.iacr.org/2017/1066 (revision 1 July 2018) #include -#include "misc_log_ex.h" -#include "span.h" +#include "epee/misc_log_ex.h" +#include "epee/span.h" #include "common/perf_timer.h" #include "common/varint.h" #include "cryptonote_config.h" diff --git a/src/ringct/multiexp.cc b/src/ringct/multiexp.cc index 04b04fcf3..9d3de0206 100644 --- a/src/ringct/multiexp.cc +++ b/src/ringct/multiexp.cc @@ -28,7 +28,7 @@ // // Adapted from Python code by Sarang Noether -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "common/perf_timer.h" extern "C" { diff --git a/src/ringct/multiexp.h b/src/ringct/multiexp.h index b52707933..6c73446d9 100644 --- a/src/ringct/multiexp.h +++ b/src/ringct/multiexp.h @@ -36,7 +36,7 @@ #include #include "crypto/crypto.h" #include "rctTypes.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" namespace rct { diff --git a/src/ringct/rctOps.cpp b/src/ringct/rctOps.cpp index 4d1dd51d7..46a8a2345 100644 --- a/src/ringct/rctOps.cpp +++ b/src/ringct/rctOps.cpp @@ -29,7 +29,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "rctOps.h" using namespace crypto; diff --git a/src/ringct/rctSigs.cpp b/src/ringct/rctSigs.cpp index f6005a3c2..95e5d0e3f 100644 --- a/src/ringct/rctSigs.cpp +++ b/src/ringct/rctSigs.cpp @@ -28,7 +28,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 "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "common/perf_timer.h" #include "common/threadpool.h" #include "common/util.h" diff --git a/src/ringct/rctTypes.cpp b/src/ringct/rctTypes.cpp index 4cd020853..65a0096d7 100644 --- a/src/ringct/rctTypes.cpp +++ b/src/ringct/rctTypes.cpp @@ -28,10 +28,10 @@ // 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 "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "cryptonote_config.h" #include "rctTypes.h" -#include "int-util.h" +#include "epee/int-util.h" using namespace crypto; using namespace std; diff --git a/src/ringct/rctTypes.h b/src/ringct/rctTypes.h index 492db9375..f42fd2333 100644 --- a/src/ringct/rctTypes.h +++ b/src/ringct/rctTypes.h @@ -44,8 +44,8 @@ extern "C" { #include "crypto/generic-ops.h" #include "crypto/crypto.h" -#include "hex.h" -#include "span.h" +#include "epee/hex.h" +#include "epee/span.h" #include "serialization/variant.h" #include "common/util.h" diff --git a/src/rpc/bootstrap_daemon.cpp b/src/rpc/bootstrap_daemon.cpp index 9efa3333a..6f46cd987 100644 --- a/src/rpc/bootstrap_daemon.cpp +++ b/src/rpc/bootstrap_daemon.cpp @@ -5,7 +5,7 @@ #include "common/string_util.h" #include "crypto/crypto.h" #include "cryptonote_core/cryptonote_core.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #undef MONERO_DEFAULT_LOG_CATEGORY #define MONERO_DEFAULT_LOG_CATEGORY "daemon.rpc.bootstrap_daemon" diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index b033e4902..f181780ca 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -43,9 +43,8 @@ #include "cryptonote_basic/tx_extra.h" #include "cryptonote_core/loki_name_system.h" #include "cryptonote_core/pulse.h" -#include "include_base_utils.h" #include "loki_economy.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "core_rpc_server.h" #include "common/command_line.h" #include "common/loki.h" @@ -57,7 +56,7 @@ #include "cryptonote_basic/account.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "cryptonote_core/tx_sanity_check.h" -#include "misc_language.h" +#include "epee/misc_language.h" #include "net/parse.h" #include "crypto/hash.h" #include "rpc/rpc_args.h" @@ -190,8 +189,6 @@ namespace cryptonote { namespace rpc { const std::unordered_map> rpc_commands = register_rpc_commands(rpc::core_rpc_types{}); - namespace string_tools = epee::string_tools; - const command_line::arg_descriptor core_rpc_server::arg_bootstrap_daemon_address = { "bootstrap-daemon-address" , "URL of a 'bootstrap' remote daemon that the connected wallets can use while this daemon is still not fully synced.\n" @@ -328,7 +325,7 @@ namespace cryptonote { namespace rpc { crypto::hash hash; m_core.get_blockchain_top(res.height, hash); ++res.height; // block height to chain height - res.hash = string_tools::pod_to_hex(hash); + res.hash = tools::type_to_hex(hash); res.status = STATUS_OK; res.immutable_height = 0; @@ -336,7 +333,7 @@ namespace cryptonote { namespace rpc { if (m_core.get_blockchain_storage().get_db().get_immutable_checkpoint(&checkpoint, res.height - 1)) { res.immutable_height = checkpoint.height; - res.immutable_hash = string_tools::pod_to_hex(checkpoint.block_hash); + res.immutable_hash = tools::type_to_hex(checkpoint.block_hash); } return res; @@ -369,7 +366,7 @@ namespace cryptonote { namespace rpc { m_core.get_blockchain_top(res.height, top_hash); auto prev_ts = m_core.get_blockchain_storage().get_db().get_block_timestamp(res.height); ++res.height; // turn top block height into blockchain height - res.top_block_hash = string_tools::pod_to_hex(top_hash); + res.top_block_hash = tools::type_to_hex(top_hash); res.target_height = m_core.get_target_blockchain_height(); bool next_block_is_pulse = false; @@ -384,7 +381,7 @@ namespace cryptonote { namespace rpc { if (m_core.get_blockchain_storage().get_db().get_immutable_checkpoint(&checkpoint, res.height - 1)) { res.immutable_height = checkpoint.height; - res.immutable_block_hash = string_tools::pod_to_hex(checkpoint.block_hash); + res.immutable_block_hash = tools::type_to_hex(checkpoint.block_hash); } res.difficulty = m_core.get_blockchain_storage().get_difficulty_for_next_block(next_block_is_pulse); @@ -554,7 +551,7 @@ namespace cryptonote { namespace rpc { for (auto const& blk: blks) { - res.blks_hashes.push_back(epee::string_tools::pod_to_hex(get_block_hash(blk))); + res.blks_hashes.push_back(tools::type_to_hex(get_block_hash(blk))); } MDEBUG("on_get_alt_blocks_hashes: " << blks.size() << " blocks " ); @@ -662,11 +659,11 @@ namespace cryptonote { namespace rpc { { res.outs.emplace_back(); auto& outkey = res.outs.back(); - outkey.key = epee::string_tools::pod_to_hex(i.key); - outkey.mask = epee::string_tools::pod_to_hex(i.mask); + outkey.key = tools::type_to_hex(i.key); + outkey.mask = tools::type_to_hex(i.mask); outkey.unlocked = i.unlocked; outkey.height = i.height; - outkey.txid = epee::string_tools::pod_to_hex(i.txid); + outkey.txid = tools::type_to_hex(i.txid); } res.status = STATUS_OK; @@ -1048,7 +1045,7 @@ namespace cryptonote { namespace rpc { for(const auto& ki_hex_str: req.key_images) { blobdata b; - if(!string_tools::parse_hexstr_to_binbuff(ki_hex_str, b)) + if(!epee::string_tools::parse_hexstr_to_binbuff(ki_hex_str, b)) { res.status = "Failed to parse hex representation of key image"; return res; @@ -1117,7 +1114,7 @@ namespace cryptonote { namespace rpc { CHECK_CORE_READY(); std::string tx_blob; - if(!string_tools::parse_hexstr_to_binbuff(req.tx_as_hex, tx_blob)) + if(!epee::string_tools::parse_hexstr_to_binbuff(req.tx_as_hex, tx_blob)) { LOG_PRINT_L0("[on_send_raw_tx]: Failed to parse tx from hexbuff: " << req.tx_as_hex); res.status = "Failed"; @@ -1484,7 +1481,7 @@ namespace cryptonote { namespace rpc { m_core.get_pool().get_transaction_hashes(tx_hashes, context.admin); res.tx_hashes.reserve(tx_hashes.size()); for (const crypto::hash &tx_hash: tx_hashes) - res.tx_hashes.push_back(epee::string_tools::pod_to_hex(tx_hash)); + res.tx_hashes.push_back(tools::type_to_hex(tx_hash)); res.status = STATUS_OK; return res; } @@ -1590,7 +1587,7 @@ namespace cryptonote { namespace rpc { throw rpc_error{ERROR_TOO_BIG_HEIGHT, "Requested block height: " + std::to_string(h) + " greater than current top block height: " + std::to_string(m_core.get_current_blockchain_height() - 1)}; - res = string_tools::pod_to_hex(m_core.get_block_id_by_height(h)); + res = tools::type_to_hex(m_core.get_block_id_by_height(h)); return res; } //------------------------------------------------------------------------------------------------------------------------------ @@ -1625,7 +1622,7 @@ namespace cryptonote { namespace rpc { cryptonote::blobdata blob_reserve; if(!req.extra_nonce.empty()) { - if(!string_tools::parse_hexstr_to_binbuff(req.extra_nonce, blob_reserve)) + if(!epee::string_tools::parse_hexstr_to_binbuff(req.extra_nonce, blob_reserve)) throw rpc_error{ERROR_WRONG_PARAM, "Parameter extra_nonce should be a hex string"}; } else @@ -1634,7 +1631,7 @@ namespace cryptonote { namespace rpc { crypto::hash prev_block; if (!req.prev_block.empty()) { - if (!epee::string_tools::hex_to_pod(req.prev_block, prev_block)) + if (!tools::hex_to_type(req.prev_block, prev_block)) throw rpc_error{ERROR_INTERNAL, "Invalid prev_block"}; } if(!m_core.create_miner_block_template(b, req.prev_block.empty() ? NULL : &prev_block, info.address, diff, res.height, res.expected_reward, blob_reserve)) @@ -1649,10 +1646,10 @@ namespace cryptonote { namespace rpc { crypto::hash seed_hash; crypto::rx_seedheights(res.height, &seed_height, &next_height); seed_hash = m_core.get_block_id_by_height(seed_height); - res.seed_hash = string_tools::pod_to_hex(seed_hash); + res.seed_hash = tools::type_to_hex(seed_hash); if (next_height != seed_height) { seed_hash = m_core.get_block_id_by_height(next_height); - res.next_seed_hash = string_tools::pod_to_hex(seed_hash); + res.next_seed_hash = tools::type_to_hex(seed_hash); } } res.difficulty = diff; @@ -1680,9 +1677,9 @@ namespace cryptonote { namespace rpc { throw rpc_error{ERROR_INTERNAL, "Internal error: failed to create block template"}; } blobdata hashing_blob = get_block_hashing_blob(b); - res.prev_hash = string_tools::pod_to_hex(b.prev_id); - res.blocktemplate_blob = string_tools::buff_to_hex_nodelimer(block_blob); - res.blockhashing_blob = string_tools::buff_to_hex_nodelimer(hashing_blob); + res.prev_hash = tools::type_to_hex(b.prev_id); + res.blocktemplate_blob = lokimq::to_hex(block_blob); + res.blockhashing_blob = lokimq::to_hex(hashing_blob); res.status = STATUS_OK; return res; } @@ -1704,7 +1701,7 @@ namespace cryptonote { namespace rpc { if(req.blob.size()!=1) throw rpc_error{ERROR_WRONG_PARAM, "Wrong param"}; blobdata blockblob; - if(!string_tools::parse_hexstr_to_binbuff(req.blob[0], blockblob)) + if(!epee::string_tools::parse_hexstr_to_binbuff(req.blob[0], blockblob)) throw rpc_error{ERROR_WRONG_BLOCKBLOB, "Wrong block blob"}; // Fixing of high orphan issue for most pools @@ -1753,7 +1750,7 @@ namespace cryptonote { namespace rpc { res.status = template_res.status; blobdata blockblob; - if(!string_tools::parse_hexstr_to_binbuff(template_res.blocktemplate_blob, blockblob)) + if(!epee::string_tools::parse_hexstr_to_binbuff(template_res.blocktemplate_blob, blockblob)) throw rpc_error{ERROR_WRONG_BLOCKBLOB, "Wrong block blob"}; block b; if(!parse_and_validate_block_from_blob(blockblob, b)) @@ -1764,11 +1761,11 @@ namespace cryptonote { namespace rpc { return true; }, b, template_res.difficulty, template_res.height); - submit_req.blob[0] = string_tools::buff_to_hex_nodelimer(block_to_blob(b)); + submit_req.blob[0] = lokimq::to_hex(block_to_blob(b)); auto submit_res = invoke(std::move(submit_req), context); res.status = submit_res.status; - res.blocks.push_back(epee::string_tools::pod_to_hex(get_block_hash(b))); + res.blocks.push_back(tools::type_to_hex(get_block_hash(b))); res.height = template_res.height; } @@ -1791,12 +1788,12 @@ namespace cryptonote { namespace rpc { response.major_version = blk.major_version; response.minor_version = blk.minor_version; response.timestamp = blk.timestamp; - response.prev_hash = string_tools::pod_to_hex(blk.prev_id); + response.prev_hash = tools::type_to_hex(blk.prev_id); response.nonce = blk.nonce; response.orphan_status = orphan_status; response.height = height; response.depth = m_core.get_current_blockchain_height() - height - 1; - response.hash = string_tools::pod_to_hex(hash); + response.hash = tools::type_to_hex(hash); response.difficulty = m_core.get_blockchain_storage().block_difficulty(height); response.cumulative_difficulty = m_core.get_blockchain_storage().get_db().get_block_cumulative_difficulty(height); response.block_weight = m_core.get_blockchain_storage().get_db().get_block_weight(height); @@ -1805,10 +1802,10 @@ namespace cryptonote { namespace rpc { response.block_size = response.block_weight = m_core.get_blockchain_storage().get_db().get_block_weight(height); response.num_txes = blk.tx_hashes.size(); if (fill_pow_hash) - response.pow_hash = string_tools::pod_to_hex(get_block_longhash_w_blockchain(m_core.get_nettype(), &(m_core.get_blockchain_storage()), blk, height, 0)); + response.pow_hash = tools::type_to_hex(get_block_longhash_w_blockchain(m_core.get_nettype(), &(m_core.get_blockchain_storage()), blk, height, 0)); response.long_term_weight = m_core.get_blockchain_storage().get_db().get_block_long_term_weight(height); - response.miner_tx_hash = string_tools::pod_to_hex(cryptonote::get_transaction_hash(blk.miner_tx)); - response.service_node_winner = string_tools::pod_to_hex(cryptonote::get_service_node_winner_from_tx_extra(blk.miner_tx.extra)); + response.miner_tx_hash = tools::type_to_hex(cryptonote::get_transaction_hash(blk.miner_tx)); + response.service_node_winner = tools::type_to_hex(cryptonote::get_service_node_winner_from_tx_extra(blk.miner_tx.extra)); if (get_tx_hashes) { response.tx_hashes.reserve(blk.tx_hashes.size()); @@ -2371,10 +2368,10 @@ namespace cryptonote { namespace rpc { std::vector>> chains = m_core.get_blockchain_storage().get_alternative_chains(); for (const auto &i: chains) { - res.chains.push_back(GET_ALTERNATE_CHAINS::chain_info{epee::string_tools::pod_to_hex(get_block_hash(i.first.bl)), i.first.height, i.second.size(), i.first.cumulative_difficulty, {}, std::string()}); + res.chains.push_back(GET_ALTERNATE_CHAINS::chain_info{tools::type_to_hex(get_block_hash(i.first.bl)), i.first.height, i.second.size(), i.first.cumulative_difficulty, {}, std::string()}); res.chains.back().block_hashes.reserve(i.second.size()); for (const crypto::hash &block_id: i.second) - res.chains.back().block_hashes.push_back(epee::string_tools::pod_to_hex(block_id)); + res.chains.back().block_hashes.push_back(tools::type_to_hex(block_id)); if (i.first.height < i.second.size()) { res.status = "Error finding alternate chain attachment point"; @@ -2383,7 +2380,7 @@ namespace cryptonote { namespace rpc { cryptonote::block main_chain_parent_block; try { main_chain_parent_block = m_core.get_blockchain_storage().get_db().get_block_from_height(i.first.height - i.second.size()); } catch (const std::exception &e) { res.status = "Error finding alternate chain attachment point"; return res; } - res.chains.back().main_chain_parent_block = epee::string_tools::pod_to_hex(get_block_hash(main_chain_parent_block)); + res.chains.back().main_chain_parent_block = tools::type_to_hex(get_block_hash(main_chain_parent_block)); } res.status = STATUS_OK; } @@ -2526,7 +2523,7 @@ namespace cryptonote { namespace rpc { res.peers.push_back({c}); const cryptonote::block_queue &block_queue = m_p2p.get_payload_object().get_block_queue(); block_queue.foreach([&](const cryptonote::block_queue::span &span) { - const std::string span_connection_id = epee::string_tools::pod_to_hex(span.connection_id); + const std::string span_connection_id = tools::type_to_hex(span.connection_id); uint32_t speed = (uint32_t)(100.0f * block_queue.get_speed(span.connection_id) + 0.5f); std::string address = ""; for (const auto &c: m_p2p.get_payload_object().get_connections()) @@ -2857,7 +2854,7 @@ namespace cryptonote { namespace rpc { { res.blacklist.emplace_back(); auto &new_entry = res.blacklist.back(); - new_entry.key_image = epee::string_tools::pod_to_hex(entry.key_image); + new_entry.key_image = tools::type_to_hex(entry.key_image); new_entry.unlock_height = entry.unlock_height; new_entry.amount = entry.amount; } @@ -2872,9 +2869,9 @@ namespace cryptonote { namespace rpc { const auto& keys = m_core.get_service_keys(); if (keys.pub) - res.service_node_pubkey = string_tools::pod_to_hex(keys.pub); - res.service_node_ed25519_pubkey = string_tools::pod_to_hex(keys.pub_ed25519); - res.service_node_x25519_pubkey = string_tools::pod_to_hex(keys.pub_x25519); + res.service_node_pubkey = tools::type_to_hex(keys.pub); + res.service_node_ed25519_pubkey = tools::type_to_hex(keys.pub_ed25519); + res.service_node_x25519_pubkey = tools::type_to_hex(keys.pub_x25519); res.status = STATUS_OK; return res; } @@ -2887,9 +2884,9 @@ namespace cryptonote { namespace rpc { const auto& keys = m_core.get_service_keys(); if (keys.key != crypto::null_skey) - res.service_node_privkey = string_tools::pod_to_hex(keys.key.data); - res.service_node_ed25519_privkey = string_tools::pod_to_hex(keys.key_ed25519.data); - res.service_node_x25519_privkey = string_tools::pod_to_hex(keys.key_x25519.data); + res.service_node_privkey = tools::type_to_hex(keys.key.data); + res.service_node_ed25519_privkey = tools::type_to_hex(keys.key_ed25519.data); + res.service_node_x25519_privkey = tools::type_to_hex(keys.key_x25519.data); res.status = STATUS_OK; return res; } @@ -2897,7 +2894,7 @@ namespace cryptonote { namespace rpc { void core_rpc_server::fill_sn_response_entry(GET_SERVICE_NODES::response::entry& entry, const service_nodes::service_node_pubkey_info &sn_info, uint64_t current_height) { const auto &info = *sn_info.info; - entry.service_node_pubkey = string_tools::pod_to_hex(sn_info.pubkey); + entry.service_node_pubkey = tools::type_to_hex(sn_info.pubkey); entry.registration_height = info.registration_height; entry.requested_unlock_height = info.requested_unlock_height; entry.last_reward_block_height = info.last_reward_block_height; @@ -2911,12 +2908,12 @@ namespace cryptonote { namespace rpc { m_core.get_service_node_list().access_proof(sn_info.pubkey, [&entry](const auto &proof) { entry.service_node_version = proof.version; - entry.public_ip = string_tools::get_ip_string_from_int32(proof.public_ip); + entry.public_ip = epee::string_tools::get_ip_string_from_int32(proof.public_ip); entry.storage_port = proof.storage_port; entry.storage_lmq_port = proof.storage_lmq_port; entry.storage_server_reachable = proof.storage_server_reachable; - entry.pubkey_ed25519 = proof.pubkey_ed25519 ? string_tools::pod_to_hex(proof.pubkey_ed25519) : ""; - entry.pubkey_x25519 = proof.pubkey_x25519 ? string_tools::pod_to_hex(proof.pubkey_x25519) : ""; + entry.pubkey_ed25519 = proof.pubkey_ed25519 ? tools::type_to_hex(proof.pubkey_ed25519) : ""; + entry.pubkey_x25519 = proof.pubkey_x25519 ? tools::type_to_hex(proof.pubkey_x25519) : ""; entry.quorumnet_port = proof.quorumnet_port; // NOTE: Service Node Testing @@ -2947,8 +2944,8 @@ namespace cryptonote { namespace rpc { new_contributor.locked_contributions.push_back({}); auto &dest = new_contributor.locked_contributions.back(); dest.amount = src.amount; - dest.key_image = string_tools::pod_to_hex(src.key_image); - dest.key_image_pub_key = string_tools::pod_to_hex(src.key_image_pub_key); + dest.key_image = tools::type_to_hex(src.key_image); + dest.key_image_pub_key = tools::type_to_hex(src.key_image_pub_key); } } @@ -2971,7 +2968,7 @@ namespace cryptonote { namespace rpc { res.status = STATUS_OK; res.height = m_core.get_current_blockchain_height() - 1; res.target_height = m_core.get_target_blockchain_height(); - res.block_hash = string_tools::pod_to_hex(m_core.get_block_id_by_height(res.height)); + res.block_hash = tools::type_to_hex(m_core.get_block_id_by_height(res.height)); res.hardfork = m_core.get_hard_fork_version(res.height); if (!req.poll_block_hash.empty()) { @@ -2986,7 +2983,7 @@ namespace cryptonote { namespace rpc { std::vector pubkeys(req.service_node_pubkeys.size()); for (size_t i = 0; i < req.service_node_pubkeys.size(); i++) { - if (!string_tools::hex_to_pod(req.service_node_pubkeys[i], pubkeys[i])) + if (!tools::hex_to_type(req.service_node_pubkeys[i], pubkeys[i])) throw rpc_error{ERROR_WRONG_PARAM, "Could not convert to a public key, arg: " + std::to_string(i) + " which is pubkey: " + req.service_node_pubkeys[i]}; @@ -3347,7 +3344,7 @@ namespace cryptonote { namespace rpc { REPORT_PEER_SS_STATUS::response res{}; crypto::public_key pubkey; - if (!string_tools::hex_to_pod(req.pubkey, pubkey)) { + if (!tools::hex_to_type(req.pubkey, pubkey)) { MERROR("Could not parse public key: " << req.pubkey); throw rpc_error{ERROR_WRONG_PARAM, "Could not parse public key"}; } diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 45af2dd65..5d0571875 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -32,7 +32,7 @@ #pragma once #include "crypto/crypto.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "cryptonote_protocol/cryptonote_protocol_defs.h" #include "cryptonote_basic/cryptonote_basic.h" @@ -45,6 +45,7 @@ #include "common/varint.h" #include "common/perf_timer.h" #include "common/meta.h" +#include "common/hex.h" #include "checkpoints/checkpoints.h" #include "cryptonote_core/service_node_quorum_cop.h" @@ -2288,7 +2289,7 @@ namespace rpc { quorum_signature_serialized() = default; quorum_signature_serialized(service_nodes::quorum_signature const &entry) : voter_index(entry.voter_index) - , signature(epee::string_tools::pod_to_hex(entry.signature)) { } + , signature(tools::type_to_hex(entry.signature)) { } KV_MAP_SERIALIZABLE @@ -2312,7 +2313,7 @@ namespace rpc { : version(checkpoint.version) , type(checkpoint_t::type_to_string(checkpoint.type)) , height(checkpoint.height) - , block_hash(epee::string_tools::pod_to_hex(checkpoint.block_hash)) + , block_hash(tools::type_to_hex(checkpoint.block_hash)) , prev_height(checkpoint.prev_height) { signatures.reserve(checkpoint.signatures.size()); diff --git a/src/rpc/http_client.h b/src/rpc/http_client.h index 7061f22db..b46032dda 100644 --- a/src/rpc/http_client.h +++ b/src/rpc/http_client.h @@ -5,9 +5,9 @@ #include #include -#include "storages/portable_storage_template_helper.h" -#include "net/jsonrpc_structs.h" -#include "memwipe.h" +#include "epee/storages/portable_storage_template_helper.h" +#include "epee/net/jsonrpc_structs.h" +#include "epee/memwipe.h" #include "common/meta.h" #include "version.h" diff --git a/src/rpc/http_server.cpp b/src/rpc/http_server.cpp index 7a46ea20c..187f2b925 100644 --- a/src/rpc/http_server.cpp +++ b/src/rpc/http_server.cpp @@ -5,8 +5,11 @@ #include #include #include +#include "common/command_line.h" #include "common/string_util.h" -#include "net/jsonrpc_structs.h" // epee +#include "cryptonote_config.h" +#include "cryptonote_core/cryptonote_core.h" +#include "epee/net/jsonrpc_structs.h" #include "rpc/core_rpc_server_commands_defs.h" #include "rpc/rpc_args.h" #include "version.h" @@ -16,47 +19,64 @@ namespace cryptonote::rpc { - const command_line::arg_descriptor http_server::arg_rpc_bind_port = { - "rpc-bind-port" - , "Port for RPC server" - , config::RPC_DEFAULT_PORT - , {{ &cryptonote::arg_testnet_on, &cryptonote::arg_devnet_on }} - , [](std::array testnet_devnet, bool defaulted, uint16_t val) { - auto [testnet, devnet] = testnet_devnet; - return - (defaulted && testnet) ? config::testnet::RPC_DEFAULT_PORT : - (defaulted && devnet) ? config::devnet::RPC_DEFAULT_PORT : - val; + const command_line::arg_descriptor> http_server::arg_rpc_public{ + "rpc-public", + "Specifies an IP:PORT to listen on for public (restricted) RPC requests; can be specified multiple times." + }; + + const command_line::arg_descriptor, false, true, 2> http_server::arg_rpc_admin{ + "rpc-admin", + "Specifies an IP:PORT to listen on for admin (unrestricted) RPC requests; can be specified multiple times. Specify \"none\" to disable.", + {"127.0.0.1:" + std::to_string(config::RPC_DEFAULT_PORT), "[::1]:" + std::to_string(config::RPC_DEFAULT_PORT)}, + {{ &cryptonote::arg_testnet_on, &cryptonote::arg_devnet_on }}, + [](std::array testnet_devnet, bool defaulted, std::vector val) { + auto& [testnet, devnet] = testnet_devnet; + if (defaulted && (testnet || devnet)) { + auto port = std::to_string(testnet ? config::testnet::RPC_DEFAULT_PORT : config::devnet::RPC_DEFAULT_PORT); + val = {"127.0.0.1:" + port, "[::1]:" + port}; } - }; + return val; + } + }; + + const command_line::arg_descriptor http_server::arg_rpc_bind_port = { + "rpc-bind-port", + "Port for RPC server; deprecated, use --rpc-public or --rpc-admin instead.", + 0 + }; const command_line::arg_descriptor http_server::arg_rpc_restricted_bind_port = { "rpc-restricted-bind-port" - , "Port for restricted RPC server" + , "Port for restricted RPC server; deprecated, use --rpc-public instead" , 0 }; const command_line::arg_descriptor http_server::arg_restricted_rpc = { "restricted-rpc" - , "Restrict RPC to view only commands and do not return privacy sensitive data in RPC calls" + , "Deprecated, use --rpc-public instead" , false }; + // This option doesn't do anything anymore, but keep it here for now in case people added it to + // config files/startup flags. const command_line::arg_descriptor http_server::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" + , "Deprecated; use --rpc-public option instead" , false }; namespace { void long_poll_trigger(cryptonote::tx_memory_pool&); } //----------------------------------------------------------------------------------- - void http_server::init_options(boost::program_options::options_description& desc) + void http_server::init_options(boost::program_options::options_description& desc, boost::program_options::options_description& hidden) { - command_line::add_arg(desc, arg_rpc_bind_port); - command_line::add_arg(desc, arg_rpc_restricted_bind_port); - command_line::add_arg(desc, arg_restricted_rpc); - command_line::add_arg(desc, arg_public_node); + command_line::add_arg(desc, arg_rpc_public); + command_line::add_arg(desc, arg_rpc_admin); + + command_line::add_arg(hidden, arg_rpc_bind_port); + command_line::add_arg(hidden, arg_rpc_restricted_bind_port); + command_line::add_arg(hidden, arg_restricted_rpc); + command_line::add_arg(hidden, arg_public_node); cryptonote::long_poll_trigger = long_poll_trigger; } @@ -64,10 +84,10 @@ namespace cryptonote::rpc { //------------------------------------------------------------------------------------------------------------------------------ http_server::http_server( core_rpc_server& server, - const boost::program_options::variables_map& vm, - const bool restricted, - uint16_t port - ) : m_server{server}, m_restricted{restricted} + rpc_args rpc_config, + bool restricted, + std::vector> bind) + : m_server{server}, m_restricted{restricted} { // uWS is designed to work from a single thread, which is good (we pull off the requests and // then stick them into the LMQ job queue to be scheduled along with other jobs). But as a @@ -93,7 +113,7 @@ namespace cryptonote::rpc { // start()). //m_startup_promise - m_rpc_thread = std::thread{[this, rpc_config=cryptonote::rpc_args::process(vm), port] ( + m_rpc_thread = std::thread{[this, rpc_config=std::move(rpc_config), bind=std::move(bind)] ( std::promise loop_promise, std::future startup_future, std::promise> startup_success) { @@ -102,42 +122,33 @@ namespace cryptonote::rpc { create_rpc_endpoints(http); } catch (...) { loop_promise.set_exception(std::current_exception()); + return; } loop_promise.set_value(uWS::Loop::get()); if (!startup_future.get()) // False means cancel, i.e. we got destroyed/shutdown without start() being called return; - std::vector> bind_addr; - if (!rpc_config.bind_ip.empty()) - bind_addr.emplace_back(rpc_config.bind_ip, rpc_config.require_ipv4); - if (rpc_config.use_ipv6 && !rpc_config.bind_ipv6_address.empty()) - bind_addr.emplace_back(rpc_config.bind_ipv6_address, true); - m_login = rpc_config.login; m_cors = {rpc_config.access_control_origins.begin(), rpc_config.access_control_origins.end()}; std::vector listening; try { - bool bad = false; - int good = 0; - for (const auto& [addr, required] : bind_addr) - http.listen(addr, port, [&listening, req=required, &good, &bad](us_listen_socket_t* sock) { - listening.push_back(sock); - if (sock != nullptr) good++; - else if (req) bad = true; + bool required_bind_failed = false; + for (const auto& [addr, port, required] : bind) + http.listen(addr, port, [&listening, req=required, &required_bind_failed](us_listen_socket_t* sock) { + if (sock) listening.push_back(sock); + else if (req) required_bind_failed = true; }); - if (!good || bad) { + if (listening.empty() || required_bind_failed) { std::ostringstream error; error << "RPC HTTP server failed to bind; "; if (listening.empty()) error << "no valid bind address(es) given"; - else { - error << "tried to bind to:"; - for (const auto& [addr, required] : bind_addr) - error << ' ' << addr << ':' << port; - } + error << "tried to bind to:"; + for (const auto& [addr, port, required] : bind) + error << ' ' << addr << ':' << port; throw std::runtime_error(error.str()); } } catch (...) { @@ -601,6 +612,7 @@ namespace cryptonote::rpc { MTRACE("closing " << m_listen_socks.size() << " listening sockets"); for (auto* s : m_listen_socks) us_listen_socket_close(/*ssl=*/false, s); + m_listen_socks.clear(); m_closing = true; diff --git a/src/rpc/http_server.h b/src/rpc/http_server.h index b3a166c92..4347d1650 100644 --- a/src/rpc/http_server.h +++ b/src/rpc/http_server.h @@ -35,6 +35,7 @@ #include "common/password.h" #include "core_rpc_server.h" #include "http_server_base.h" +#include "rpc/rpc_args.h" namespace cryptonote::rpc { @@ -44,18 +45,22 @@ namespace cryptonote::rpc { class http_server : public http_server_base { public: - static const command_line::arg_descriptor arg_rpc_bind_port; + static const command_line::arg_descriptor> arg_rpc_public; + static const command_line::arg_descriptor, false, true, 2> arg_rpc_admin; + + // Deprecated: + static const command_line::arg_descriptor arg_rpc_bind_port; static const command_line::arg_descriptor arg_rpc_restricted_bind_port; static const command_line::arg_descriptor arg_restricted_rpc; static const command_line::arg_descriptor arg_public_node; - static void init_options(boost::program_options::options_description& desc); + static void init_options(boost::program_options::options_description& desc, boost::program_options::options_description& hidden); http_server( core_rpc_server& server, - const boost::program_options::variables_map& vm, - const bool restricted, - uint16_t port + rpc_args rpc_config, + bool restricted, + std::vector> bind // {IP,port,required} ); ~http_server(); diff --git a/src/rpc/http_server_base.cpp b/src/rpc/http_server_base.cpp index 03fd952b3..02ab2b77a 100644 --- a/src/rpc/http_server_base.cpp +++ b/src/rpc/http_server_base.cpp @@ -5,8 +5,8 @@ #include "common/string_util.h" // epee: -#include "net/jsonrpc_structs.h" -#include "storages/portable_storage_template_helper.h" +#include "epee/net/jsonrpc_structs.h" +#include "epee/storages/portable_storage_template_helper.h" namespace cryptonote::rpc { diff --git a/src/rpc/http_server_base.h b/src/rpc/http_server_base.h index 384717c7a..a27886083 100644 --- a/src/rpc/http_server_base.h +++ b/src/rpc/http_server_base.h @@ -3,7 +3,7 @@ #include #include #include -#include "storages/portable_storage.h" +#include "epee/storages/portable_storage.h" #include "common/password.h" #include "version.h" diff --git a/src/rpc/lmq_server.cpp b/src/rpc/lmq_server.cpp index 34adad40f..332601787 100644 --- a/src/rpc/lmq_server.cpp +++ b/src/rpc/lmq_server.cpp @@ -128,7 +128,7 @@ lmq_rpc::lmq_rpc(cryptonote::core& core, core_rpc_server& rpc, const boost::prog // windows. In theory we could do some runtime detection to see if the Windows version is new // enough to support unix domain sockets, but for now the Windows default is just "don't listen" #ifndef _WIN32 - locals.push_back("ipc://" + core.get_config_directory() + "/lokid.sock"); + locals.push_back("ipc://" + core.get_config_directory().u8string() + "/lokid.sock"); #endif } else if (locals.size() == 1 && locals[0] == "none") { locals.clear(); diff --git a/src/rpc/rpc_args.cpp b/src/rpc/rpc_args.cpp index abfefff1c..47ac04c01 100644 --- a/src/rpc/rpc_args.cpp +++ b/src/rpc/rpc_args.cpp @@ -45,9 +45,8 @@ namespace cryptonote , rpc_use_ipv6({"rpc-use-ipv6", rpc_args::tr("Allow IPv6 for RPC"), false}) , rpc_ignore_ipv4({"rpc-ignore-ipv4", rpc_args::tr("Ignore unsuccessful IPv4 bind for RPC"), false}) , rpc_login({"rpc-login", rpc_args::tr("Specify username[:password] required for RPC server"), "", true}) - , confirm_external_bind({"confirm-external-bind", rpc_args::tr("Confirm rpc-bind-ip value is NOT a loopback (local) IP")}) + , confirm_external_bind({"confirm-external-bind", rpc_args::tr("Confirm rpc bind IP value is NOT a loopback (local) IP")}) , rpc_access_control_origins({"rpc-access-control-origins", rpc_args::tr("Specify a comma separated list of origins to allow cross origin resource sharing"), ""}) - , rpc_public_node({"public-node", rpc_args::tr("Allow other users to use the node as a remote (restricted RPC mode, view-only commands) and advertise it over P2P"), false}) , zmq_rpc_bind_ip({"zmq-rpc-bind-ip", rpc_args::tr("Deprecated option, ignored."), ""}) , zmq_rpc_bind_port({"zmq-rpc-bind-port", rpc_args::tr("Deprecated option, ignored."), ""}) {} @@ -90,20 +89,22 @@ namespace cryptonote { const descriptors arg{}; rpc_args config{}; - - config.bind_ip = command_line::get_arg(vm, arg.rpc_bind_ip); - config.bind_ipv6_address = command_line::get_arg(vm, arg.rpc_bind_ipv6_address); + + if (!command_line::is_arg_defaulted(vm, arg.rpc_bind_ip)) { + config.bind_ip = command_line::get_arg(vm, arg.rpc_bind_ip); + check_ip(*config.bind_ip, command_line::get_arg(vm, arg.confirm_external_bind), arg.rpc_bind_ip.name); + } + if (!command_line::is_arg_defaulted(vm, arg.rpc_bind_ipv6_address)) + config.bind_ipv6_address = command_line::get_arg(vm, arg.rpc_bind_ipv6_address); config.use_ipv6 = command_line::get_arg(vm, arg.rpc_use_ipv6); config.require_ipv4 = !command_line::get_arg(vm, arg.rpc_ignore_ipv4); - if (!config.bind_ip.empty()) - check_ip(config.bind_ip, command_line::get_arg(vm, arg.confirm_external_bind), arg.rpc_bind_ip.name); - - if (!config.bind_ipv6_address.empty()) + if (config.bind_ipv6_address && !config.bind_ipv6_address->empty()) { // allow square braces, but remove them here if present - if (config.bind_ipv6_address.find('[') != std::string::npos && config.bind_ipv6_address.rfind(']') != std::string::npos) - config.bind_ipv6_address = config.bind_ipv6_address.substr(1, config.bind_ipv6_address.size() - 2); - check_ip(config.bind_ipv6_address, command_line::get_arg(vm, arg.confirm_external_bind), arg.rpc_bind_ipv6_address.name); + auto& ipv6 = *config.bind_ipv6_address; + if (ipv6.size() > 2 && ipv6.front() == '[' && ipv6.back() == ']') + ipv6 = ipv6.substr(1, ipv6.size() - 2); + check_ip(ipv6, command_line::get_arg(vm, arg.confirm_external_bind), arg.rpc_bind_ipv6_address.name); } auto verify = [](bool verify) { return tools::password_container::prompt(verify, "RPC server password"); }; diff --git a/src/rpc/rpc_args.h b/src/rpc/rpc_args.h index f02ed2971..37affaa36 100644 --- a/src/rpc/rpc_args.h +++ b/src/rpc/rpc_args.h @@ -57,7 +57,6 @@ namespace cryptonote const command_line::arg_descriptor rpc_login; const command_line::arg_descriptor confirm_external_bind; const command_line::arg_descriptor rpc_access_control_origins; - const command_line::arg_descriptor rpc_public_node; const command_line::arg_descriptor zmq_rpc_bind_ip; // Deprecated & ignored const command_line::arg_descriptor zmq_rpc_bind_port; // Deprecated & ignored }; @@ -68,8 +67,9 @@ namespace cryptonote //! \return Arguments specified by user. Throws on error. static rpc_args process(const boost::program_options::variables_map& vm); - std::string bind_ip; - std::string bind_ipv6_address; + // std::nullopt if not explicitly specified + std::optional bind_ip; + std::optional bind_ipv6_address; bool use_ipv6; bool require_ipv4; std::vector access_control_origins; diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp index 107870c27..82fe0c17d 100644 --- a/src/serialization/json_object.cpp +++ b/src/serialization/json_object.cpp @@ -30,7 +30,7 @@ #include #include -#include "string_tools.h" +#include "epee/string_tools.h" namespace cryptonote { diff --git a/src/serialization/json_object.h b/src/serialization/json_object.h index 22bc015cb..812c8e9ad 100644 --- a/src/serialization/json_object.h +++ b/src/serialization/json_object.h @@ -28,12 +28,13 @@ #pragma once -#include "string_tools.h" +#include "epee/string_tools.h" #include "rapidjson/document.h" #include "cryptonote_basic/cryptonote_basic.h" #include "rpc/message_data_structs.h" #include "cryptonote_protocol/cryptonote_protocol_defs.h" #include "common/sfinae_helpers.h" +#include "common/hex.h" namespace cryptonote { @@ -76,24 +77,17 @@ constexpr bool is_to_hex = std::is_standard_layout_v && std::is_trivial_v< template typename std::enable_if_t> toJsonValue(rapidjson::Document& doc, const Type& pod, rapidjson::Value& value) { - value = rapidjson::Value(epee::string_tools::pod_to_hex(pod).c_str(), doc.GetAllocator()); + value = rapidjson::Value(tools::type_to_hex(pod).c_str(), doc.GetAllocator()); } template typename std::enable_if_t> fromJsonValue(const rapidjson::Value& val, Type& t) { if (!val.IsString()) - { throw WRONG_TYPE("string"); - } - //TODO: handle failure to convert hex string to POD type - bool success = epee::string_tools::hex_to_pod(val.GetString(), t); - - if (!success) - { + if (!tools::hex_to_type(val.GetString(), t)) throw BAD_INPUT(); - } } void toJsonValue(rapidjson::Document& doc, const std::string& i, rapidjson::Value& val); diff --git a/src/serialization/serialization.h b/src/serialization/serialization.h index dbf07192e..6bddb3f74 100644 --- a/src/serialization/serialization.h +++ b/src/serialization/serialization.h @@ -154,7 +154,7 @@ #include #include #include "base.h" -#include "span.h" // for detecting epee-wrapped byte spannable objects +#include "epee/span.h" // for detecting epee-wrapped byte spannable objects namespace serialization { diff --git a/src/simplewallet/CMakeLists.txt b/src/simplewallet/CMakeLists.txt index 6d6848c79..bef6a6c79 100644 --- a/src/simplewallet/CMakeLists.txt +++ b/src/simplewallet/CMakeLists.txt @@ -38,11 +38,7 @@ target_link_libraries(simplewallet cryptonote_core mnemonics Boost::program_options - Boost::filesystem + filesystem icu Boost::thread extra) - -if (WIN32) - target_link_libraries(simplewallet PRIVATE Boost::locale) -endif() diff --git a/src/simplewallet/simplewallet.cpp b/src/simplewallet/simplewallet.cpp index 5b797fa0e..ef75f655e 100644 --- a/src/simplewallet/simplewallet.cpp +++ b/src/simplewallet/simplewallet.cpp @@ -54,8 +54,7 @@ #include #include #include -#include "include_base_utils.h" -#include "console_handler.h" +#include "epee/console_handler.h" #include "common/i18n.h" #include "common/command_line.h" #include "common/util.h" @@ -80,16 +79,11 @@ #include "wallet/wallet_args.h" #include "version.h" #include -#include "int-util.h" -#include "readline_suspend.h" +#include "epee/int-util.h" +#include "epee/readline_suspend.h" #include "wallet/message_store.h" #include "wallet/wallet_rpc_server_commands_defs.h" -#include "string_coding.h" - -#ifdef WIN32 -#include -#include -#endif +#include "epee/string_coding.h" extern "C" { @@ -130,14 +124,6 @@ using sw = cryptonote::simple_wallet; #define PRINT_USAGE(usage_help) fail_msg_writer() << boost::format(tr("usage: %s")) % usage_help; -#define LONG_PAYMENT_ID_SUPPORT_CHECK() \ - do { \ - fail_msg_writer() << tr("Error: Long payment IDs are obsolete."); \ - fail_msg_writer() << tr("Long payment IDs were not encrypted on the blockchain and would harm your privacy."); \ - fail_msg_writer() << tr("If the party you're sending to still requires a long payment ID, please notify them."); \ - return true; \ - } while(0) - namespace { const auto arg_wallet_file = wallet_args::arg_wallet_file(); @@ -282,7 +268,8 @@ namespace else std::cout << prompt << ": "; integration_test::write_buffered_stdout(); std::string buf = integration_test::read_from_pipe(); - return epee::string_tools::trim(buf); + epee::string_tools::trim(buf); + return buf; } #else // LOKI_ENABLE_INTEGRATION_TEST_HOOKS std::string input_line(const std::string& prompt, bool yesno = false) @@ -301,7 +288,8 @@ namespace std::getline(std::cin, buf); #endif - return epee::string_tools::trim(buf); + epee::string_tools::trim(buf); + return buf; } #endif // LOKI_ENABLE_INTEGRATION_TEST_HOOKS @@ -611,17 +599,16 @@ namespace fail_msg_writer() << sw::tr("There was an error, which could mean the node may be trying to get you to retry creating a transaction, and zero in on which outputs you own. Or it could be a bona fide error. It may be prudent to disconnect from this node, and not try to send a transaction immediately. Alternatively, connect to another node so the original node cannot correlate information."); } - bool check_file_overwrite(const std::string &filename) + bool check_file_overwrite(const fs::path& filename) { - boost::system::error_code errcode; - if (boost::filesystem::exists(filename, errcode)) + if (std::error_code ec; fs::exists(filename, ec)) { - if (boost::ends_with(filename, ".keys")) + if (filename.extension() == ".keys") { - fail_msg_writer() << boost::format(sw::tr("File %s likely stores wallet private keys! Use a different file name.")) % filename; + fail_msg_writer() << boost::format(sw::tr("File %s likely stores wallet private keys! Use a different file name.")) % filename.u8string(); return false; } - return command_line::is_yes(input_line((boost::format(sw::tr("File %s already exists. Are you sure to overwrite it?")) % filename).str(), true)); + return command_line::is_yes(input_line((boost::format(sw::tr("File %s already exists. Are you sure to overwrite it?")) % filename.u8string()).str(), true)); } return true; } @@ -632,6 +619,14 @@ namespace std::ostream_iterator osi{std::cout}; lokimq::to_hex(data.begin(), data.end(), osi); } + + bool long_payment_id_failure(bool ret) + { + fail_msg_writer() << tr("Error: Long payment IDs are obsolete."); + fail_msg_writer() << tr("Long payment IDs were not encrypted on the blockchain and would harm your privacy."); + fail_msg_writer() << tr("If the party you're sending to still requires a long payment ID, please notify them."); + return ret; + } } std::string join_priority_strings(const char *delimiter) @@ -691,7 +686,7 @@ bool simple_wallet::viewkey(const std::vector &args/* = std::vector print_secret_key(m_wallet->get_account().get_keys().m_view_secret_key); std::cout << '\n'; } - std::cout << "public: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_view_public_key) << std::endl; + std::cout << "public: " << tools::type_to_hex(m_wallet->get_account().get_keys().m_account_address.m_view_public_key) << std::endl; return true; } @@ -713,7 +708,7 @@ bool simple_wallet::spendkey(const std::vector &args/* = std::vecto print_secret_key(m_wallet->get_account().get_keys().m_spend_secret_key); std::cout << '\n'; } - std::cout << "public: " << string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_spend_public_key) << std::endl; + std::cout << "public: " << tools::type_to_hex(m_wallet->get_account().get_keys().m_account_address.m_spend_public_key) << std::endl; return true; } @@ -872,11 +867,6 @@ bool simple_wallet::change_password(const std::vector &args) return true; } -bool simple_wallet::payment_id(const std::vector &args/* = std::vector()*/) -{ - LONG_PAYMENT_ID_SUPPORT_CHECK(); -} - bool simple_wallet::print_fee_info(const std::vector &args/* = std::vector()*/) { if (!try_connect_to_daemon()) @@ -1201,7 +1191,7 @@ bool simple_wallet::export_multisig_main(const std::vector &args, b return false; } - const std::string filename = args[0]; + const fs::path filename = fs::u8path(args[0]); if (!called_by_mms && m_wallet->confirm_export_overwrite() && !check_file_overwrite(filename)) return true; @@ -1220,7 +1210,7 @@ bool simple_wallet::export_multisig_main(const std::vector &args, b bool r = m_wallet->save_to_file(filename, ciphertext); if (!r) { - fail_msg_writer() << tr("failed to save file ") << filename; + fail_msg_writer() << tr("failed to save file ") << filename.u8string(); return false; } } @@ -1232,7 +1222,7 @@ bool simple_wallet::export_multisig_main(const std::vector &args, b return false; } - success_msg_writer() << tr("Multisig info exported to ") << filename; + success_msg_writer() << tr("Multisig info exported to ") << filename.u8string(); return true; } @@ -1276,12 +1266,12 @@ bool simple_wallet::import_multisig_main(const std::vector &args, b } else { - const std::string &filename = args[n]; + const fs::path filename = fs::u8path(args[n]); std::string data; bool r = m_wallet->load_from_file(filename, data); if (!r) { - fail_msg_writer() << tr("failed to read file ") << filename; + fail_msg_writer() << tr("failed to read file ") << filename.u8string(); return false; } info.push_back(std::move(data)); @@ -1363,7 +1353,7 @@ bool simple_wallet::sign_multisig_main(const std::vector &args, boo SCOPED_WALLET_UNLOCK_ON_BAD_PASSWORD(return false;); - std::string filename = args[0]; + fs::path filename = fs::u8path(args[0]); std::vector txids; uint32_t signers = 0; try @@ -1427,7 +1417,7 @@ bool simple_wallet::sign_multisig_main(const std::vector &args, boo uint32_t threshold{0}; m_wallet->multisig(NULL, &threshold); uint32_t signers_needed = threshold - signers - 1; - success_msg_writer(true) << tr("Transaction successfully signed to file ") << filename << ", " + success_msg_writer(true) << tr("Transaction successfully signed to file ") << filename.u8string() << ", " << signers_needed << " more signer(s) needed"; return true; } @@ -1438,9 +1428,9 @@ bool simple_wallet::sign_multisig_main(const std::vector &args, boo { if (!txids_as_text.empty()) txids_as_text += (", "); - txids_as_text += epee::string_tools::pod_to_hex(txid); + txids_as_text += tools::type_to_hex(txid); } - success_msg_writer(true) << tr("Transaction successfully signed to file ") << filename << ", txid " << txids_as_text; + success_msg_writer(true) << tr("Transaction successfully signed to file ") << filename.u8string() << ", txid " << txids_as_text; success_msg_writer(true) << tr("It may be relayed to the network with submit_multisig"); } return true; @@ -1482,7 +1472,7 @@ bool simple_wallet::submit_multisig_main(const std::vector &args, b SCOPED_WALLET_UNLOCK_ON_BAD_PASSWORD(return false;); - std::string filename = args[0]; + fs::path filename = fs::u8path(args[0]); try { tools::wallet2::multisig_tx_set txs; @@ -1560,7 +1550,7 @@ bool simple_wallet::export_raw_multisig(const std::vector &args) return true; } - std::string filename = args[0]; + fs::path filename = fs::u8path(args[0]); if (m_wallet->confirm_export_overwrite() && !check_file_overwrite(filename)) return true; @@ -1587,13 +1577,13 @@ bool simple_wallet::export_raw_multisig(const std::vector &args) for (auto &ptx: txs.m_ptx) { const crypto::hash txid = cryptonote::get_transaction_hash(ptx.tx); - const std::string filename = std::string("raw_multisig_loki_tx_") + epee::string_tools::pod_to_hex(txid); + const fs::path fn = fs::u8path("raw_multisig_loki_tx_" + tools::type_to_hex(txid)); if (!filenames.empty()) filenames += ", "; - filenames += filename; - if (!m_wallet->save_to_file(filename, cryptonote::tx_to_blob(ptx.tx))) + filenames += fn.u8string(); + if (!m_wallet->save_to_file(fn, cryptonote::tx_to_blob(ptx.tx))) { - fail_msg_writer() << tr("Failed to export multisig transaction to file ") << filename; + fail_msg_writer() << tr("Failed to export multisig transaction to file ") << fn.u8string(); return true; } } @@ -1623,13 +1613,13 @@ bool simple_wallet::print_ring(const std::vector &args) return true; } - if (!epee::string_tools::hex_to_pod(args[0], key_image)) + if (!tools::hex_to_type(args[0], key_image)) { fail_msg_writer() << tr("Invalid key image"); return true; } // this one will always work, they're all 32 byte hex - if (!epee::string_tools::hex_to_pod(args[0], txid)) + if (!tools::hex_to_type(args[0], txid)) { fail_msg_writer() << tr("Invalid txid"); return true; @@ -1653,7 +1643,7 @@ bool simple_wallet::print_ring(const std::vector &args) for (const auto &x: ring.second) str << x<< " "; // do NOT translate this "absolute" below, the lin can be used as input to set_ring - success_msg_writer() << epee::string_tools::pod_to_hex(ring.first) << " absolute " << str.str(); + success_msg_writer() << tools::type_to_hex(ring.first) << " absolute " << str.str(); } } catch (const std::exception &e) @@ -1671,7 +1661,8 @@ bool simple_wallet::set_ring(const std::vector &args) // try filename first if (args.size() == 1) { - if (!epee::file_io_utils::is_file_exist(args[0])) + auto ring_path = fs::u8path(args[0]); + if (std::error_code ec; !fs::exists(ring_path, ec) || ec) { fail_msg_writer() << tr("File doesn't exist"); return true; @@ -1701,7 +1692,7 @@ bool simple_wallet::set_ring(const std::vector &args) key_image_str[64] = 0; type_str[8] = 0; crypto::key_image key_image; - if (read_after_key_image == 0 || !epee::string_tools::hex_to_pod(key_image_str, key_image)) + if (read_after_key_image == 0 || !tools::hex_to_type(key_image_str, key_image)) { fail_msg_writer() << tr("Invalid key image: ") << str; continue; @@ -1780,7 +1771,7 @@ bool simple_wallet::set_ring(const std::vector &args) return true; } - if (!epee::string_tools::hex_to_pod(args[0], key_image)) + if (!tools::hex_to_type(args[0], key_image)) { fail_msg_writer() << tr("Invalid key image"); return true; @@ -1860,7 +1851,7 @@ bool simple_wallet::unset_ring(const std::vector &args) key_images.resize(args.size()); for (size_t i = 0; i < args.size(); ++i) { - if (!epee::string_tools::hex_to_pod(args[i], key_images[i])) + if (!tools::hex_to_type(args[i], key_images[i])) { fail_msg_writer() << tr("Invalid key image or txid"); return true; @@ -1893,7 +1884,7 @@ bool simple_wallet::blackball(const std::vector &args) { m_wallet->blackball_output(std::make_pair(amount, offset)); } - else if (epee::file_io_utils::is_file_exist(args[0])) + else if (std::error_code ec; fs::exists(fs::u8path(args[0]), ec) && !ec) { std::vector> outputs; char str[256]; @@ -2046,7 +2037,7 @@ bool simple_wallet::freeze_thaw(const std::vector &args, bool freez return true; } crypto::key_image ki; - if (!epee::string_tools::hex_to_pod(args[0], ki)) + if (!tools::hex_to_type(args[0], ki)) { fail_msg_writer() << tr("failed to parse key image"); return true; @@ -2093,7 +2084,7 @@ bool simple_wallet::frozen(const std::vector &args) else { crypto::key_image ki; - if (!epee::string_tools::hex_to_pod(args[0], ki)) + if (!tools::hex_to_type(args[0], ki)) { fail_msg_writer() << tr("failed to parse key image"); return true; @@ -2928,10 +2919,6 @@ Pending or Failed: "failed"|"pending", "out", Lock, Checkpointed, Time, Amount* m_cmd_binder.set_handler("password", [this](const auto& x) { return change_password(x); }, tr("Change the wallet's password.")); - m_cmd_binder.set_handler("payment_id", - [this](const auto& x) { return payment_id(x); }, - tr(USAGE_PAYMENT_ID), - tr("Generate a new random full size payment id (obsolete). These will be unencrypted on the blockchain, see integrated_address for encrypted short payment ids.")); m_cmd_binder.set_handler("fee", [this](const auto& x) { return print_fee_info(x); }, tr("Print information about the current transaction fees.")); @@ -3322,7 +3309,7 @@ bool simple_wallet::set_log(const std::vector &args) bool simple_wallet::ask_wallet_create_if_needed() { LOG_PRINT_L3("simple_wallet::ask_wallet_create_if_needed() started"); - std::string wallet_path; + fs::path wallet_path; std::string confirm_creation; bool wallet_name_valid = false; bool keys_file_exists; @@ -3330,26 +3317,26 @@ bool simple_wallet::ask_wallet_create_if_needed() do{ LOG_PRINT_L3("User asked to specify wallet file name."); - wallet_path = input_line( + wallet_path = fs::u8path(input_line( tr(m_restoring ? "Specify a new wallet file name for your restored wallet (e.g., MyWallet).\n" "Wallet file name (or Ctrl-C to quit)" : "Specify wallet file name (e.g., MyWallet). If the wallet doesn't exist, it will be created.\n" "Wallet file name (or Ctrl-C to quit)") - ); + )); if(std::cin.eof()) { LOG_ERROR("Unexpected std::cin.eof() - Exited simple_wallet::ask_wallet_create_if_needed()"); return false; } - if(!tools::wallet2::wallet_valid_path_format(wallet_path)) + if(wallet_path.empty()) { - fail_msg_writer() << tr("Wallet name not valid. Please try again or use Ctrl-C to quit."); + fail_msg_writer() << tr("No wallet name provided. Please try again or use Ctrl-C to quit."); wallet_name_valid = false; } else { tools::wallet2::wallet_exists(wallet_path, keys_file_exists, wallet_file_exists); - LOG_PRINT_L3("wallet_path: " << wallet_path << ""); + LOG_PRINT_L3("wallet_path: " << wallet_path); LOG_PRINT_L3("keys_file_exists: " << std::boolalpha << keys_file_exists << std::noboolalpha << " wallet_file_exists: " << std::boolalpha << wallet_file_exists << std::noboolalpha); @@ -3372,7 +3359,7 @@ bool simple_wallet::ask_wallet_create_if_needed() } else if(wallet_file_exists && !keys_file_exists) //Yes wallet, no keys { - fail_msg_writer() << tr("Key file not found. Failed to open wallet: ") << "\"" << wallet_path << "\". Exiting."; + fail_msg_writer() << tr("Key file not found. Failed to open wallet: ") << wallet_path << ". Exiting."; return false; } else if(!wallet_file_exists && !keys_file_exists) //No wallet, no keys @@ -3381,7 +3368,7 @@ bool simple_wallet::ask_wallet_create_if_needed() if (!m_restoring) { std::string prompt = tr("No wallet found with that name. Confirm creation of new wallet named: "); - prompt += "\"" + wallet_path + "\""; + prompt += "\"" + wallet_path.u8string() + "\""; confirm_creation = input_line(prompt, true); if(std::cin.eof()) { @@ -4094,14 +4081,14 @@ bool simple_wallet::deinit() //---------------------------------------------------------------------------------------------------- bool simple_wallet::handle_command_line(const boost::program_options::variables_map& vm) { - m_wallet_file = command_line::get_arg(vm, arg_wallet_file); - m_generate_new = command_line::get_arg(vm, arg_generate_new_wallet); - m_generate_from_device = command_line::get_arg(vm, arg_generate_from_device); - m_generate_from_view_key = command_line::get_arg(vm, arg_generate_from_view_key); - m_generate_from_spend_key = command_line::get_arg(vm, arg_generate_from_spend_key); - m_generate_from_keys = command_line::get_arg(vm, arg_generate_from_keys); - m_generate_from_multisig_keys = command_line::get_arg(vm, arg_generate_from_multisig_keys); - m_generate_from_json = command_line::get_arg(vm, arg_generate_from_json); + m_wallet_file = fs::u8path(command_line::get_arg(vm, arg_wallet_file)); + m_generate_new = fs::u8path(command_line::get_arg(vm, arg_generate_new_wallet)); + m_generate_from_device = fs::u8path(command_line::get_arg(vm, arg_generate_from_device)); + m_generate_from_view_key = fs::u8path(command_line::get_arg(vm, arg_generate_from_view_key)); + m_generate_from_spend_key = fs::u8path(command_line::get_arg(vm, arg_generate_from_spend_key)); + m_generate_from_keys = fs::u8path(command_line::get_arg(vm, arg_generate_from_keys)); + m_generate_from_multisig_keys = fs::u8path(command_line::get_arg(vm, arg_generate_from_multisig_keys)); + m_generate_from_json = fs::u8path(command_line::get_arg(vm, arg_generate_from_json)); m_mnemonic_language = command_line::get_arg(vm, arg_mnemonic_language); m_electrum_seed = command_line::get_arg(vm, arg_electrum_seed); m_restore_deterministic_wallet = command_line::get_arg(vm, arg_restore_deterministic_wallet); @@ -4469,9 +4456,9 @@ std::optional simple_wallet::new_wallet(const boost::prog //---------------------------------------------------------------------------------------------------- std::optional simple_wallet::open_wallet(const boost::program_options::variables_map& vm) { - if (!tools::wallet2::wallet_valid_path_format(m_wallet_file)) + if (m_wallet_file.empty()) { - fail_msg_writer() << tr("wallet file path not valid: ") << m_wallet_file; + fail_msg_writer() << tr("no wallet file provided"); return {}; } @@ -4637,9 +4624,9 @@ bool simple_wallet::save_watch_only(const std::vector &args/* = std try { - std::string new_keys_filename; + fs::path new_keys_filename; m_wallet->write_watch_only_wallet(m_wallet_file, pwd_container->password(), new_keys_filename); - success_msg_writer() << tr("Watch only wallet saved as: ") << new_keys_filename; + success_msg_writer() << tr("Watch only wallet saved as: ") << new_keys_filename.u8string(); } catch (const std::exception &e) { @@ -4842,7 +4829,7 @@ void simple_wallet::on_money_received(uint64_t height, const crypto::hash &txid, tr("WARNING: this transaction uses an unencrypted payment ID: these are obsolete and ignored. Use subaddresses instead."); } if (unlock_time && !cryptonote::is_coinbase(tx)) - message_writer() << tr("NOTE: This transaction is locked, see details with: show_transfer ") + epee::string_tools::pod_to_hex(txid); + message_writer() << tr("NOTE: This transaction is locked, see details with: show_transfer ") + tools::type_to_hex(txid); if (m_auto_refresh_refreshing) m_cmd_binder.print_prompt(); else @@ -5220,7 +5207,7 @@ bool simple_wallet::show_incoming_transfers(const std::vector& args } std::string extra_string; if (verbose) - extra_string += (boost::format("%68s%68s") % td.get_public_key() % (td.m_key_image_known ? epee::string_tools::pod_to_hex(td.m_key_image) : td.m_key_image_partial ? (epee::string_tools::pod_to_hex(td.m_key_image) + "/p") : std::string(64, '?'))).str(); + extra_string += (boost::format("%68s%68s") % td.get_public_key() % (td.m_key_image_known ? tools::type_to_hex(td.m_key_image) : td.m_key_image_partial ? (tools::type_to_hex(td.m_key_image) + "/p") : std::string(64, '?'))).str(); if (uses) { std::vector heights; @@ -5518,7 +5505,7 @@ bool simple_wallet::process_ring_members(const std::vector absolute_offsets = cryptonote::relative_output_offsets_to_absolute(in_key.key_offsets); @@ -5847,21 +5834,12 @@ bool simple_wallet::transfer_main(Transfer transfer_type, const std::vector extra; - bool payment_id_seen = false; if (!local_args.empty()) { std::string payment_id_str = local_args.back(); crypto::hash payment_id; - bool r = true; - if (tools::wallet2::parse_long_payment_id(payment_id_str, payment_id)) - { - LONG_PAYMENT_ID_SUPPORT_CHECK(); - } - if(!r) - { - fail_msg_writer() << tr("payment id failed to encode"); - return false; - } + if (tools::hex_to_type(payment_id_str, payment_id)) + return long_payment_id_failure(false); } uint64_t locked_blocks = 0; @@ -5880,6 +5858,7 @@ bool simple_wallet::transfer_main(Transfer transfer_type, const std::vector dsts_info; std::vector dsts; size_t num_subaddresses = 0; @@ -5900,7 +5879,7 @@ bool simple_wallet::transfer_main(Transfer transfer_type, const std::vectornettype(), address_uri, oa_prompter); if (payment_id_uri.size() == 16) { - if (!tools::wallet2::parse_short_payment_id(payment_id_uri, info.payment_id)) + if (!tools::hex_to_type(payment_id_uri, info.payment_id)) { fail_msg_writer() << tr("failed to parse short payment ID from URI"); return false; @@ -5959,7 +5938,7 @@ bool simple_wallet::transfer_main(Transfer transfer_type, const std::vector &args_) return true; } - if (!epee::string_tools::hex_to_pod(local_args[0], service_node_key)) + if (!tools::hex_to_type(local_args[0], service_node_key)) { fail_msg_writer() << tr("failed to parse service node pubkey"); return true; @@ -6217,7 +6196,7 @@ bool simple_wallet::request_stake_unlock(const std::vector &args_) } crypto::public_key snode_key; - if (!epee::string_tools::hex_to_pod(args_[0], snode_key)) + if (!tools::hex_to_type(args_[0], snode_key)) { fail_msg_writer() << tr("failed to parse service node pubkey: ") << args_[0]; return true; @@ -6869,7 +6848,7 @@ bool simple_wallet::lns_make_update_mapping_signature(std::vector a signature_binary, m_current_subaddress_account, &reason)) - tools::success_msg_writer() << "signature=" << epee::string_tools::pod_to_hex(signature_binary.ed25519); + tools::success_msg_writer() << "signature=" << tools::type_to_hex(signature_binary.ed25519); else fail_msg_writer() << reason; @@ -7445,26 +7424,19 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, Transfer transf } std::vector extra; - bool payment_id_seen = false; if (local_args.size() >= 2) { std::string payment_id_str = local_args.back(); - crypto::hash payment_id; - bool r = tools::wallet2::parse_long_payment_id(payment_id_str, payment_id); - if(r) - { - LONG_PAYMENT_ID_SUPPORT_CHECK(); - } + if (crypto::hash payment_id; tools::hex_to_type(payment_id_str, payment_id)) + return long_payment_id_failure(true); - if(!r && local_args.size() == 3) + if(local_args.size() == 3) { - fail_msg_writer() << tr("payment id has invalid format, expected 16 or 64 character hex string: ") << payment_id_str; + fail_msg_writer() << tr("Standalone payment IDs are not longer supported; please use an integrated address or subaddress instead"); print_usage(); return true; } - if (payment_id_seen) - local_args.pop_back(); } cryptonote::address_parse_info info; @@ -7483,12 +7455,6 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, Transfer transf if (info.has_payment_id) { - if (payment_id_seen) - { - fail_msg_writer() << tr("a single transaction cannot use more than one payment id: ") << local_args[0]; - return true; - } - std::string extra_nonce; set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, info.payment_id); bool r = add_extra_nonce_to_tx_extra(extra, extra_nonce); @@ -7497,7 +7463,6 @@ bool simple_wallet::sweep_main(uint32_t account, uint64_t below, Transfer transf fail_msg_writer() << tr("failed to set up payment id, though it was decoded correctly"); return true; } - payment_id_seen = true; } SCOPED_WALLET_UNLOCK(); @@ -7557,30 +7522,10 @@ bool simple_wallet::sweep_single(const std::vector &args_) } std::vector extra; - bool payment_id_seen = false; if (local_args.size() == 3) { - crypto::hash payment_id; - crypto::hash8 payment_id8; - std::string extra_nonce; - if (tools::wallet2::parse_long_payment_id(local_args.back(), payment_id)) - { - LONG_PAYMENT_ID_SUPPORT_CHECK(); - } - else - { - fail_msg_writer() << tr("failed to parse Payment ID"); - return true; - } - - if (!add_extra_nonce_to_tx_extra(extra, extra_nonce)) - { - fail_msg_writer() << tr("failed to set up payment id, though it was decoded correctly"); - return true; - } - - local_args.pop_back(); - payment_id_seen = true; + fail_msg_writer() << tr("Standalone payment IDs are not longer supported; please use an integrated address or subaddress instead"); + return true; } if (local_args.size() != 2) @@ -7590,7 +7535,7 @@ bool simple_wallet::sweep_single(const std::vector &args_) } crypto::key_image ki; - if (!epee::string_tools::hex_to_pod(local_args[0], ki)) + if (!tools::hex_to_type(local_args[0], ki)) { fail_msg_writer() << tr("failed to parse key image"); return true; @@ -7605,12 +7550,6 @@ bool simple_wallet::sweep_single(const std::vector &args_) if (info.has_payment_id) { - if (payment_id_seen) - { - fail_msg_writer() << tr("a single transaction cannot use more than one payment id: ") << local_args[0]; - return true; - } - std::string extra_nonce; set_encrypted_payment_id_to_tx_extra_nonce(extra_nonce, info.payment_id); if (!add_extra_nonce_to_tx_extra(extra, extra_nonce)) @@ -7618,7 +7557,6 @@ bool simple_wallet::sweep_single(const std::vector &args_) fail_msg_writer() << tr("failed to set up payment id, though it was decoded correctly"); return true; } - payment_id_seen = true; } SCOPED_WALLET_UNLOCK(); @@ -7721,7 +7659,7 @@ bool simple_wallet::accept_loaded_tx(const std::function get_num_txes, } else { - payment_id_string += std::string("encrypted payment ID ") + epee::string_tools::pod_to_hex(payment_id8); + payment_id_string += std::string("encrypted payment ID ") + tools::type_to_hex(payment_id8); has_encrypted_payment_id = true; } } @@ -7729,7 +7667,7 @@ bool simple_wallet::accept_loaded_tx(const std::function get_num_txes, { if (!payment_id_string.empty()) payment_id_string += ", "; - payment_id_string += std::string("unencrypted payment ID ") + epee::string_tools::pod_to_hex(payment_id); + payment_id_string += std::string("unencrypted payment ID ") + tools::type_to_hex(payment_id); payment_id_string += " (OBSOLETE)"; } } @@ -7749,7 +7687,7 @@ bool simple_wallet::accept_loaded_tx(const std::function get_num_txes, if (has_encrypted_payment_id && !entry.is_subaddress && standard_address != entry.original) { address = get_account_integrated_address_as_str(m_wallet->nettype(), entry.addr, payment_id8); - address += std::string(" (" + standard_address + " with encrypted payment id " + epee::string_tools::pod_to_hex(payment_id8) + ")"); + address += std::string(" (" + standard_address + " with encrypted payment id " + tools::type_to_hex(payment_id8) + ")"); } else address = standard_address; @@ -7893,7 +7831,7 @@ bool simple_wallet::sign_transfer(const std::vector &args_) { if (!txids_as_text.empty()) txids_as_text += (", "); - txids_as_text += epee::string_tools::pod_to_hex(get_transaction_hash(t.tx)); + txids_as_text += tools::type_to_hex(get_transaction_hash(t.tx)); } success_msg_writer(true) << tr("Transaction successfully signed to file ") << "signed_loki_tx" << ", txid " << txids_as_text; if (export_raw) @@ -7963,7 +7901,7 @@ bool simple_wallet::get_tx_key(const std::vector &args_) } crypto::hash txid; - if (!epee::string_tools::hex_to_pod(local_args[0], txid)) + if (!tools::hex_to_type(local_args[0], txid)) { fail_msg_writer() << tr("failed to parse txid"); return true; @@ -7978,9 +7916,9 @@ bool simple_wallet::get_tx_key(const std::vector &args_) if (found_tx_key) { std::ostringstream oss; - oss << epee::string_tools::pod_to_hex(tx_key); + oss << tools::type_to_hex(tx_key); for (size_t i = 0; i < additional_tx_keys.size(); ++i) - oss << epee::string_tools::pod_to_hex(additional_tx_keys[i]); + oss << tools::type_to_hex(additional_tx_keys[i]); success_msg_writer() << tr("Tx key: ") << oss.str(); return true; } @@ -8001,7 +7939,7 @@ bool simple_wallet::set_tx_key(const std::vector &args_) } crypto::hash txid; - if (!epee::string_tools::hex_to_pod(local_args[0], txid)) + if (!tools::hex_to_type(local_args[0], txid)) { fail_msg_writer() << tr("failed to parse txid"); return true; @@ -8011,7 +7949,7 @@ bool simple_wallet::set_tx_key(const std::vector &args_) std::vector additional_tx_keys; try { - if (!epee::string_tools::hex_to_pod(local_args[1].substr(0, 64), tx_key)) + if (!tools::hex_to_type(local_args[1].substr(0, 64), tx_key)) { fail_msg_writer() << tr("failed to parse tx_key"); return true; @@ -8022,7 +7960,7 @@ bool simple_wallet::set_tx_key(const std::vector &args_) if (local_args[1].empty()) break; additional_tx_keys.resize(additional_tx_keys.size() + 1); - if (!epee::string_tools::hex_to_pod(local_args[1].substr(0, 64), additional_tx_keys.back())) + if (!tools::hex_to_type(local_args[1].substr(0, 64), additional_tx_keys.back())) { fail_msg_writer() << tr("failed to parse tx_key"); return true; @@ -8058,7 +7996,7 @@ bool simple_wallet::get_tx_proof(const std::vector &args) } crypto::hash txid; - if(!epee::string_tools::hex_to_pod(args[0], txid)) + if(!tools::hex_to_type(args[0], txid)) { fail_msg_writer() << tr("failed to parse txid"); return true; @@ -8076,9 +8014,9 @@ bool simple_wallet::get_tx_proof(const std::vector &args) try { std::string sig_str = m_wallet->get_tx_proof(txid, info.address, info.is_subaddress, args.size() == 3 ? args[2] : ""); - const std::string filename = "loki_tx_proof"; + const fs::path filename{"loki_tx_proof"}; if (m_wallet->save_to_file(filename, sig_str, true)) - success_msg_writer() << tr("signature file saved to: ") << filename; + success_msg_writer() << tr("signature file saved to: ") << filename.u8string(); else fail_msg_writer() << tr("failed to save signature file"); } @@ -8107,7 +8045,7 @@ bool simple_wallet::check_tx_key(const std::vector &args_) return true; } crypto::hash txid; - if(!epee::string_tools::hex_to_pod(local_args[0], txid)) + if(!tools::hex_to_type(local_args[0], txid)) { fail_msg_writer() << tr("failed to parse txid"); return true; @@ -8115,7 +8053,7 @@ bool simple_wallet::check_tx_key(const std::vector &args_) crypto::secret_key tx_key; std::vector additional_tx_keys; - if(!epee::string_tools::hex_to_pod(local_args[1].substr(0, 64), tx_key)) + if(!tools::hex_to_type(local_args[1].substr(0, 64), tx_key)) { fail_msg_writer() << tr("failed to parse tx key"); return true; @@ -8124,7 +8062,7 @@ bool simple_wallet::check_tx_key(const std::vector &args_) while (!local_args[1].empty()) { additional_tx_keys.resize(additional_tx_keys.size() + 1); - if(!epee::string_tools::hex_to_pod(local_args[1].substr(0, 64), additional_tx_keys.back())) + if(!tools::hex_to_type(local_args[1].substr(0, 64), additional_tx_keys.back())) { fail_msg_writer() << tr("failed to parse tx key"); return true; @@ -8189,7 +8127,7 @@ bool simple_wallet::check_tx_proof(const std::vector &args) // parse txid crypto::hash txid; - if(!epee::string_tools::hex_to_pod(args[0], txid)) + if(!tools::hex_to_type(args[0], txid)) { fail_msg_writer() << tr("failed to parse txid"); return true; @@ -8274,7 +8212,7 @@ bool simple_wallet::get_spend_proof(const std::vector &args) } crypto::hash txid; - if (!epee::string_tools::hex_to_pod(args[0], txid)) + if (!tools::hex_to_type(args[0], txid)) { fail_msg_writer() << tr("failed to parse txid"); return true; @@ -8288,9 +8226,9 @@ bool simple_wallet::get_spend_proof(const std::vector &args) try { const std::string sig_str = m_wallet->get_spend_proof(txid, args.size() == 2 ? args[1] : ""); - const std::string filename = "loki_spend_proof"; + const fs::path filename{"loki_spend_proof"}; if (m_wallet->save_to_file(filename, sig_str, true)) - success_msg_writer() << tr("signature file saved to: ") << filename; + success_msg_writer() << tr("signature file saved to: ") << filename.u8string(); else fail_msg_writer() << tr("failed to save signature file"); } @@ -8309,7 +8247,7 @@ bool simple_wallet::check_spend_proof(const std::vector &args) } crypto::hash txid; - if (!epee::string_tools::hex_to_pod(args[0], txid)) + if (!tools::hex_to_type(args[0], txid)) { fail_msg_writer() << tr("failed to parse txid"); return true; @@ -8377,9 +8315,9 @@ bool simple_wallet::get_reserve_proof(const std::vector &args) try { const std::string sig_str = m_wallet->get_reserve_proof(account_minreserve, args.size() == 2 ? args[1] : ""); - const std::string filename = "loki_reserve_proof"; + const fs::path filename{"loki_reserve_proof"}; if (m_wallet->save_to_file(filename, sig_str, true)) - success_msg_writer() << tr("signature file saved to: ") << filename; + success_msg_writer() << tr("signature file saved to: ") << filename.u8string(); else fail_msg_writer() << tr("failed to save signature file"); } @@ -8624,7 +8562,7 @@ bool simple_wallet::show_transfers(const std::vector &args_) % (transfer.checkpointed ? "checkpointed" : transfer.was_blink ? "blink" : "no") % tools::get_human_readable_timestamp(transfer.timestamp) % print_money(transfer.amount) - % string_tools::pod_to_hex(transfer.hash) + % tools::type_to_hex(transfer.hash) % transfer.payment_id % print_money(transfer.fee) % destinations @@ -8654,20 +8592,20 @@ bool simple_wallet::export_transfers(const std::vector& args_) return true; // output filename - std::string filename = (boost::format("output%u.csv") % m_current_subaddress_account).str(); + std::string filename_str = (boost::format("output%u.csv") % m_current_subaddress_account).str(); if (local_args.size() > 0 && local_args[0].substr(0, 7) == "output=") { - filename = local_args[0].substr(7, -1); + filename_str = local_args[0].substr(7); local_args.erase(local_args.begin()); } - std::ofstream file(filename); + fs::ofstream file{fs::u8path(filename_str)}; const bool formatting = true; file << m_wallet->transfers_to_csv(all_transfers, formatting); file.close(); - success_msg_writer() << tr("CSV exported to ") << filename; + success_msg_writer() << tr("CSV exported to ") << filename_str; return true; } @@ -9439,7 +9377,7 @@ bool simple_wallet::print_integrated_address(const std::vector &arg device_show_integrated(payment_id); return true; } - if(tools::wallet2::parse_short_payment_id(local_args.back(), payment_id)) + if(tools::hex_to_type(local_args.back(), payment_id)) { if (m_current_subaddress_account != 0) { @@ -9457,7 +9395,7 @@ bool simple_wallet::print_integrated_address(const std::vector &arg if (info.has_payment_id) { success_msg_writer() << boost::format(tr("Integrated address: %s, payment ID: %s")) % - get_account_address_as_str(m_wallet->nettype(), false, info.address) % epee::string_tools::pod_to_hex(info.payment_id); + get_account_address_as_str(m_wallet->nettype(), false, info.address) % tools::type_to_hex(info.payment_id); device_show_integrated(info.payment_id); } else @@ -9705,12 +9643,12 @@ bool simple_wallet::sign(const std::vector &args) index.minor = b; } - const std::string &filename = args.back(); + const fs::path filename = fs::u8path(args.back()); std::string data; bool r = m_wallet->load_from_file(filename, data); if (!r) { - fail_msg_writer() << tr("failed to read file ") << filename; + fail_msg_writer() << tr("failed to read file ") << filename.u8string(); return true; } @@ -9728,7 +9666,7 @@ bool simple_wallet::verify(const std::vector &args) PRINT_USAGE(USAGE_VERIFY); return true; } - std::string filename = args[0]; + fs::path filename = fs::u8path(args[0]); std::string address_string = args[1]; std::string signature= args[2]; @@ -9736,7 +9674,7 @@ bool simple_wallet::verify(const std::vector &args) bool r = m_wallet->load_from_file(filename, data); if (!r) { - fail_msg_writer() << tr("failed to read file ") << filename; + fail_msg_writer() << tr("failed to read file ") << filename.u8string(); return true; } @@ -9777,7 +9715,7 @@ bool simple_wallet::export_key_images(const std::vector &args) return true; } - std::string filename = args[0]; + fs::path filename = fs::u8path(args[0]); if (m_wallet->confirm_export_overwrite() && !check_file_overwrite(filename)) return true; @@ -9789,7 +9727,7 @@ bool simple_wallet::export_key_images(const std::vector &args) bool requested_only = (args.size() == 2 && args[1] == "requested-only"); if (!m_wallet->export_key_images_to_file(filename, requested_only)) { - fail_msg_writer() << tr("failed to save file ") << filename; + fail_msg_writer() << tr("failed to save file ") << filename.u8string(); return true; } } @@ -9800,7 +9738,7 @@ bool simple_wallet::export_key_images(const std::vector &args) return true; } - success_msg_writer() << tr("Signed key images exported to ") << filename; + success_msg_writer() << tr("Signed key images exported to ") << filename.u8string(); return true; } //---------------------------------------------------------------------------------------------------- @@ -9823,7 +9761,7 @@ bool simple_wallet::import_key_images(const std::vector &args) return true; } - std::string const &filename = args[0]; + const fs::path filename = fs::u8path(args[0]); LOCK_IDLE_SCOPE(); try { @@ -9934,7 +9872,7 @@ bool simple_wallet::export_outputs(const std::vector &args) all = true; } - std::string const &filename = args[filename_index]; + const fs::path filename = fs::u8path(args[filename_index]); if (m_wallet->confirm_export_overwrite() && !check_file_overwrite(filename)) return true; @@ -9946,7 +9884,7 @@ bool simple_wallet::export_outputs(const std::vector &args) bool r = m_wallet->save_to_file(filename, data); if (!r) { - fail_msg_writer() << tr("failed to save file ") << filename; + fail_msg_writer() << tr("failed to save file ") << filename.u8string(); return true; } } @@ -9957,7 +9895,7 @@ bool simple_wallet::export_outputs(const std::vector &args) return true; } - success_msg_writer() << tr("Outputs exported to ") << filename; + success_msg_writer() << tr("Outputs exported to ") << filename.u8string(); return true; } //---------------------------------------------------------------------------------------------------- @@ -9973,13 +9911,13 @@ bool simple_wallet::import_outputs(const std::vector &args) PRINT_USAGE(USAGE_IMPORT_OUTPUTS); return true; } - std::string filename = args[0]; + const fs::path filename = fs::u8path(args[0]); std::string data; bool r = m_wallet->load_from_file(filename, data); if (!r) { - fail_msg_writer() << tr("failed to read file ") << filename; + fail_msg_writer() << tr("failed to read file ") << filename.u8string(); return true; } @@ -9991,7 +9929,7 @@ bool simple_wallet::import_outputs(const std::vector &args) } catch (const std::exception &e) { - fail_msg_writer() << "Failed to import outputs " << filename << ": " << e.what(); + fail_msg_writer() << "Failed to import outputs " << filename.u8string() << ": " << e.what(); return true; } @@ -10021,7 +9959,7 @@ bool simple_wallet::show_transfer(const std::vector &args) for (std::list>::const_iterator i = payments.begin(); i != payments.end(); ++i) { const tools::wallet2::payment_details &pd = i->second; if (pd.m_tx_hash == txid) { - std::string payment_id = string_tools::pod_to_hex(i->first); + std::string payment_id = tools::type_to_hex(i->first); if (payment_id.substr(16).find_first_not_of('0') == std::string::npos) payment_id = payment_id.substr(0,16); success_msg_writer() << "Incoming transaction found"; @@ -10079,7 +10017,7 @@ bool simple_wallet::show_transfer(const std::vector &args) dests += ", "; dests += d.address(m_wallet->nettype(), pd.m_payment_id) + ": " + print_money(d.amount); } - std::string payment_id = string_tools::pod_to_hex(i->second.m_payment_id); + std::string payment_id = tools::type_to_hex(i->second.m_payment_id); if (payment_id.substr(16).find_first_not_of('0') == std::string::npos) payment_id = payment_id.substr(0,16); success_msg_writer() << "Outgoing transaction found"; @@ -10121,7 +10059,7 @@ bool simple_wallet::show_transfer(const std::vector &args) const tools::wallet2::payment_details &pd = i->second.m_pd; if (pd.m_tx_hash == txid) { - std::string payment_id = string_tools::pod_to_hex(i->first); + std::string payment_id = tools::type_to_hex(i->first); if (payment_id.substr(16).find_first_not_of('0') == std::string::npos) payment_id = payment_id.substr(0,16); success_msg_writer() << "Unconfirmed incoming transaction found in the txpool"; @@ -10150,7 +10088,7 @@ bool simple_wallet::show_transfer(const std::vector &args) const tools::wallet2::unconfirmed_transfer_details &pd = i->second; uint64_t amount = pd.m_amount_in; uint64_t fee = amount - pd.m_amount_out; - std::string payment_id = string_tools::pod_to_hex(i->second.m_payment_id); + std::string payment_id = tools::type_to_hex(i->second.m_payment_id); if (payment_id.substr(16).find_first_not_of('0') == std::string::npos) payment_id = payment_id.substr(0,16); bool is_failed = pd.m_state == tools::wallet2::unconfirmed_transfer_details::failed; @@ -10198,16 +10136,17 @@ void simple_wallet::commit_or_save(std::vector& ptx_ { cryptonote::blobdata blob; tx_to_blob(ptx.tx, blob); - const std::string blob_hex = epee::string_tools::buff_to_hex_nodelimer(blob); - const std::string filename = "raw_loki_tx" + (ptx_vector.size() == 1 ? "" : ("_" + std::to_string(i++))); + const std::string blob_hex = lokimq::to_hex(blob); + fs::path filename = fs::u8path("raw_loki_tx"); + if (ptx_vector.size() > 1) filename += "_" + std::to_string(i++); bool success = m_wallet->save_to_file(filename, blob_hex, true); if (success) msg_buf += tr("Transaction successfully saved to "); else msg_buf += tr("Failed to save transaction to "); - msg_buf += filename; + msg_buf += filename.u8string(); msg_buf += tr(", txid <"); - msg_buf += epee::string_tools::pod_to_hex(txid); + msg_buf += tools::type_to_hex(txid); msg_buf += ">"; if (success) success_msg_writer(true) << msg_buf; @@ -10217,7 +10156,7 @@ void simple_wallet::commit_or_save(std::vector& ptx_ { m_wallet->commit_tx(ptx, blink); msg_buf += tr("Transaction successfully submitted, transaction <"); - msg_buf += epee::string_tools::pod_to_hex(txid); + msg_buf += tools::type_to_hex(txid); msg_buf += ">\n"; msg_buf += tr("You can check its status by using the `show_transfers` command."); success_msg_writer(true) << msg_buf; @@ -10231,11 +10170,6 @@ int main(int argc, char* argv[]) { TRY_ENTRY(); -#ifdef WIN32 - // Activate UTF-8 support for Boost filesystem classes on Windows - std::locale::global(boost::locale::generator().generate("")); - boost::filesystem::path::imbue(std::locale()); -#endif setlocale(LC_CTYPE, ""); auto opt_size = command_line::boost_option_sizes(); @@ -10996,7 +10930,7 @@ void simple_wallet::mms_export(const std::vector &args) bool valid_id = get_message_from_arg(args[0], m); if (valid_id) { - const std::string filename = "mms_message_content"; + fs::path filename = fs::u8path("mms_message_content"); if (m_wallet->save_to_file(filename, m.content)) { success_msg_writer() << tr("Message content saved to: ") << filename; diff --git a/src/simplewallet/simplewallet.h b/src/simplewallet/simplewallet.h index ea2a45ce0..1e6f729d9 100644 --- a/src/simplewallet/simplewallet.h +++ b/src/simplewallet/simplewallet.h @@ -47,9 +47,9 @@ #include "cryptonote_basic/account.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "wallet/wallet2.h" -#include "console_handler.h" +#include "epee/console_handler.h" #include "common/periodic_task.h" -#include "wipeable_string.h" +#include "epee/wipeable_string.h" #include "common/i18n.h" #include "common/password.h" #include "crypto/crypto.h" // for definition of crypto::secret_key @@ -402,16 +402,15 @@ namespace cryptonote }; private: - std::string m_wallet_file; - std::string m_generate_new; - std::string m_generate_from_device; - std::string m_generate_from_view_key; - std::string m_generate_from_spend_key; - std::string m_generate_from_keys; - std::string m_generate_from_multisig_keys; - std::string m_generate_from_json; + fs::path m_wallet_file; + fs::path m_generate_new; + fs::path m_generate_from_device; + fs::path m_generate_from_view_key; + fs::path m_generate_from_spend_key; + fs::path m_generate_from_keys; + fs::path m_generate_from_multisig_keys; + fs::path m_generate_from_json; std::string m_mnemonic_language; - std::string m_import_path; std::string m_subaddress_lookahead; std::string m_restore_date; // optional - converted to m_restore_height diff --git a/src/wallet/CMakeLists.txt b/src/wallet/CMakeLists.txt index 97e1b05e1..523ba2816 100644 --- a/src/wallet/CMakeLists.txt +++ b/src/wallet/CMakeLists.txt @@ -49,7 +49,7 @@ target_link_libraries(wallet lmdb rpc_http_client Boost::serialization - Boost::filesystem + filesystem Boost::thread PRIVATE OpenSSL::SSL @@ -70,59 +70,4 @@ target_link_libraries(wallet_rpc_server extra) -function(combine_archives output_archive) - set(mri_file ${CMAKE_CURRENT_BINARY_DIR}/${output_archive}.mri) - set(FULL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR}/lib${output_archive}.a) - set(mri_content "create ${FULL_OUTPUT_PATH}\n") - FOREACH(in_archive ${ARGN}) - string(APPEND mri_content "addlib $\n") - ENDFOREACH() - string(APPEND mri_content "save\nend\n") - file(GENERATE OUTPUT ${mri_file} CONTENT "${mri_content}") - - set(output_archive_dummy_file ${CMAKE_CURRENT_BINARY_DIR}/${output_archive}.dummy.cpp) - add_custom_command(OUTPUT ${output_archive_dummy_file} - COMMAND touch ${output_archive_dummy_file} - DEPENDS ${ARGN}) - - add_library(${output_archive} STATIC ${output_archive_dummy_file}) - add_custom_command(TARGET ${output_archive} - POST_BUILD - COMMAND ar -M < ${mri_file}) -endfunction(combine_archives) - -# build and install libwallet_merged only if we building for GUI -if (BUILD_GUI_DEPS AND STATIC) - combine_archives(wallet_merged - wallet_api - wallet - multisig - cryptonote_core - cryptonote_basic - mnemonics - common - cncrypto - device - ringct - ringct_basic - checkpoints - version - net - device_trezor) - - 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/CMakeLists.txt b/src/wallet/api/CMakeLists.txt index 84b2e259a..d3170089b 100644 --- a/src/wallet/api/CMakeLists.txt +++ b/src/wallet/api/CMakeLists.txt @@ -46,7 +46,7 @@ target_link_libraries(wallet_api mnemonics lmdb Boost::serialization - Boost::filesystem + filesystem Boost::thread PRIVATE extra) @@ -61,3 +61,86 @@ endif() install(FILES ${wallet_api_headers} DESTINATION include/wallet/api) + +function(combine_archives output_archive) + set(FULL_OUTPUT_PATH ${CMAKE_CURRENT_BINARY_DIR}/lib${output_archive}.a) + set(output_archive_dummy_file ${CMAKE_CURRENT_BINARY_DIR}/${output_archive}.dummy.cpp) + add_custom_command(OUTPUT ${output_archive_dummy_file} + COMMAND touch ${output_archive_dummy_file} + DEPENDS ${ARGN}) + add_library(${output_archive} STATIC EXCLUDE_FROM_ALL ${output_archive_dummy_file}) + + if(NOT APPLE) + set(mri_file ${CMAKE_CURRENT_BINARY_DIR}/${output_archive}.mri) + set(mri_content "create ${FULL_OUTPUT_PATH}\n") + foreach(in_archive ${ARGN}) + string(APPEND mri_content "addlib $\n") + endforeach() + string(APPEND mri_content "save\nend\n") + file(GENERATE OUTPUT ${mri_file} CONTENT "${mri_content}") + + add_custom_command(TARGET ${output_archive} + POST_BUILD + COMMAND ar -M < ${mri_file}) + else() + set(merge_libs) + foreach(in_archive ${ARGN}) + list(APPEND merge_libs $) + endforeach() + add_custom_command(TARGET ${output_archive} + POST_BUILD + COMMAND /usr/bin/libtool -static -o ${FULL_OUTPUT_PATH} ${merge_libs}) + endif() +endfunction(combine_archives) + +if (STATIC AND BUILD_STATIC_DEPS) + combine_archives(wallet_merged + wallet_api + wallet + multisig + cryptonote_core + cryptonote_basic + cryptonote_protocol + mnemonics + common + cncrypto + device + ringct + ringct_basic + checkpoints + version + net + device_trezor + epee + blockchain_db + rpc_http_client + rpc_commands + + # Static deps: + Boost::program_options Boost::serialization Boost::system Boost::thread + zlib + OpenSSL::SSL OpenSSL::Crypto + expat + libunbound + sqlite3 + protobuf_lite + sodium + libzmq + CURL::libcurl + lokimq::lokimq + lmdb + easylogging + randomx + uSockets + cpr + ) + + if(IOS) + set(lib_folder lib-${ARCH}) + else() + set(lib_folder lib) + endif() + install(TARGETS wallet_merged + ARCHIVE DESTINATION ${lib_folder} + EXCLUDE_FROM_ALL) +endif() diff --git a/src/wallet/api/address_book.cpp b/src/wallet/api/address_book.cpp index 005ddf7ee..98490786c 100644 --- a/src/wallet/api/address_book.cpp +++ b/src/wallet/api/address_book.cpp @@ -37,14 +37,14 @@ #include -namespace Monero { +namespace Wallet { AddressBook::~AddressBook() {} AddressBookImpl::AddressBookImpl(WalletImpl *wallet) : m_wallet(wallet), m_errorCode(Status_Ok) {} -bool AddressBookImpl::addRow(const std::string &dst_addr , const std::string &payment_id_str, const std::string &description) +bool AddressBookImpl::addRow(const std::string &dst_addr, const std::string &description) { clearStatus(); @@ -55,13 +55,6 @@ bool AddressBookImpl::addRow(const std::string &dst_addr , const std::string &pa return false; } - if (!payment_id_str.empty()) - { - m_errorString = tr("Payment ID supplied: this is obsolete"); - m_errorCode = Invalid_Payment_Id; - return false; - } - bool r = m_wallet->m_wallet->add_address_book_row(info.address, info.has_payment_id ? &info.payment_id : NULL,description,info.is_subaddress); if (r) refresh(); @@ -86,7 +79,7 @@ void AddressBookImpl::refresh() address = cryptonote::get_account_integrated_address_as_str(m_wallet->m_wallet->nettype(), row->m_address, row->m_payment_id); else address = get_account_address_as_str(m_wallet->m_wallet->nettype(), row->m_is_subaddress, row->m_address); - AddressBookRow * abr = new AddressBookRow(i, address, "", row->m_description); + AddressBookRow* abr = new AddressBookRow(i, address, row->m_description); m_rows.push_back(abr); } @@ -101,28 +94,6 @@ bool AddressBookImpl::deleteRow(std::size_t rowId) return r; } -int AddressBookImpl::lookupPaymentID(const std::string &payment_id) const -{ - // turn short ones into long ones for comparison - const std::string long_payment_id = payment_id + std::string(64 - payment_id.size(), '0'); - - int idx = -1; - for (const auto &row: m_rows) { - ++idx; - // this does short/short and long/long - if (payment_id == row->getPaymentId()) - return idx; - // short/long - if (long_payment_id == row->getPaymentId()) - return idx; - // one case left: payment_id was long, row's is short - const std::string long_row_payment_id = row->getPaymentId() + std::string(64 - row->getPaymentId().size(), '0'); - if (payment_id == long_row_payment_id) - return idx; - } - return -1; -} - void AddressBookImpl::clearRows() { for (auto r : m_rows) { delete r; @@ -147,5 +118,3 @@ AddressBookImpl::~AddressBookImpl() } } // namespace - -namespace Bitmonero = Monero; diff --git a/src/wallet/api/address_book.h b/src/wallet/api/address_book.h index 92e6eaa17..084c5874f 100644 --- a/src/wallet/api/address_book.h +++ b/src/wallet/api/address_book.h @@ -31,7 +31,7 @@ #include "wallet/api/wallet2_api.h" #include "wallet/wallet2.h" -namespace Monero { +namespace Wallet { class WalletImpl; @@ -44,14 +44,12 @@ public: // Fetches addresses from Wallet2 void refresh() override; std::vector getAll() const override; - bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) override; + bool addRow(const std::string &dst_addr, const std::string &description) override; bool deleteRow(std::size_t rowId) override; // Error codes. See AddressBook:ErrorCode enum in wallet2_api.h std::string errorString() const override {return m_errorString;} int errorCode() const override {return m_errorCode;} - - int lookupPaymentID(const std::string &payment_id) const override; private: void clearRows(); @@ -65,6 +63,3 @@ private: }; } - -namespace Bitmonero = Monero; - diff --git a/src/wallet/api/pending_transaction.cpp b/src/wallet/api/pending_transaction.cpp index 6606ff2f3..c56152964 100644 --- a/src/wallet/api/pending_transaction.cpp +++ b/src/wallet/api/pending_transaction.cpp @@ -35,23 +35,21 @@ #include "cryptonote_basic/cryptonote_format_utils.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "common/base58.h" +#include "common/fs.h" #include #include #include #include -using namespace std; - -namespace Monero { +namespace Wallet { PendingTransaction::~PendingTransaction() {} PendingTransactionImpl::PendingTransactionImpl(WalletImpl &wallet) - : m_wallet(wallet) + : m_wallet(wallet), m_status{Status_Ok, ""} { - m_status = Status_Ok; } PendingTransactionImpl::~PendingTransactionImpl() @@ -59,53 +57,41 @@ PendingTransactionImpl::~PendingTransactionImpl() } -int PendingTransactionImpl::status() const -{ - return m_status; -} - -string PendingTransactionImpl::errorString() const -{ - return m_errorString; -} - std::vector PendingTransactionImpl::txid() const { std::vector txid; for (const auto &pt: m_pending_tx) - txid.push_back(epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(pt.tx))); + txid.push_back(tools::type_to_hex(cryptonote::get_transaction_hash(pt.tx))); return txid; } -bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite, bool blink) +bool PendingTransactionImpl::commit(std::string_view filename_, bool overwrite, bool blink) { LOG_PRINT_L3("m_pending_tx size: " << m_pending_tx.size()); + auto filename = fs::u8path(filename_); + try { // Save tx to file if (!filename.empty()) { - boost::system::error_code ignore; - bool tx_file_exists = boost::filesystem::exists(filename, ignore); - if(tx_file_exists && !overwrite){ - m_errorString = string(tr("Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:")) + filename; - m_status = Status_Error; - LOG_ERROR(m_errorString); + if (std::error_code ec_ignore; fs::exists(filename, ec_ignore) && !overwrite){ + m_status = {Status_Error, tr("Attempting to save transaction to file, but specified file(s) exist. Exiting to not risk overwriting. File:") + filename.u8string()}; + LOG_ERROR(m_status.second); return false; } bool r = m_wallet.m_wallet->save_tx(m_pending_tx, filename); if (!r) { - m_errorString = tr("Failed to write transaction(s) to file"); - m_status = Status_Error; + m_status = {Status_Error, tr("Failed to write transaction(s) to file")}; } else { - m_status = Status_Ok; + m_status = {Status_Ok, ""}; } } // Commit tx else { auto multisigState = m_wallet.multisig(); if (multisigState.isMultisig && m_signers.size() < multisigState.threshold) { - throw runtime_error("Not enough signers to send multisig transaction"); + throw std::runtime_error("Not enough signers to send multisig transaction"); } m_wallet.pauseRefresh(); @@ -122,7 +108,7 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite, m_wallet.m_wallet->cold_tx_aux_import(m_pending_tx, m_tx_device_aux); bool r = m_wallet.m_wallet->import_key_images(m_key_images, 0, selected_transfers); if (!r){ - throw runtime_error("Cold sign transaction submit failed - key image sync fail"); + throw std::runtime_error("Cold sign transaction submit failed - key image sync fail"); } } @@ -134,31 +120,24 @@ bool PendingTransactionImpl::commit(const std::string &filename, bool overwrite, } // TODO: extract method; } } catch (const tools::error::daemon_busy&) { - // TODO: make it translatable with "tr"? - m_errorString = tr("daemon is busy. Please try again later."); - m_status = Status_Error; + m_status = {Status_Error, tr("daemon is busy. Please try again later.")}; } catch (const tools::error::no_connection_to_daemon&) { - m_errorString = tr("no connection to daemon. Please make sure daemon is running."); - m_status = Status_Error; + m_status = {Status_Error, tr("no connection to daemon. Please make sure daemon is running.")}; } catch (const tools::error::tx_rejected& e) { - std::ostringstream writer(m_errorString); - writer << (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())) << e.status(); - std::string reason = e.reason(); - m_status = Status_Error; - m_errorString = writer.str(); - if (!reason.empty()) - m_errorString += string(tr(". Reason: ")) + reason; + m_status.first = Status_Error; + m_status.second += (boost::format(tr("transaction %s was rejected by daemon with status: ")) % get_transaction_hash(e.tx())).str(); + m_status.second += e.status(); + if (auto& reason = e.reason(); !reason.empty()) + m_status.second += tr(". Reason: ") + reason; } catch (const std::exception &e) { - m_errorString = string(tr("Unknown exception: ")) + e.what(); - m_status = Status_Error; + m_status = {Status_Error, std::string(tr("Unknown exception: ")) + e.what()}; } catch (...) { - m_errorString = tr("Unhandled exception"); - LOG_ERROR(m_errorString); - m_status = Status_Error; + m_status = {Status_Error, tr("Unhandled exception")}; + LOG_ERROR(m_status.second); } m_wallet.startRefresh(); - return m_status == Status_Ok; + return good(); } uint64_t PendingTransactionImpl::amount() const @@ -222,10 +201,9 @@ std::string PendingTransactionImpl::multisigSignData() { txSet.m_signers = m_signers; auto cipher = m_wallet.m_wallet->save_multisig_tx(txSet); - return epee::string_tools::buff_to_hex_nodelimer(cipher); + return lokimq::to_hex(cipher); } catch (const std::exception& e) { - m_status = Status_Error; - m_errorString = std::string(tr("Couldn't multisig sign data: ")) + e.what(); + m_status = {Status_Error, std::string(tr("Couldn't multisig sign data: ")) + e.what()}; } return std::string(); @@ -246,8 +224,7 @@ void PendingTransactionImpl::signMultisigTx() { std::swap(m_pending_tx, txSet.m_ptx); std::swap(m_signers, txSet.m_signers); } catch (const std::exception& e) { - m_status = Status_Error; - m_errorString = std::string(tr("Couldn't sign multisig transaction: ")) + e.what(); + m_status = {Status_Error, std::string(tr("Couldn't sign multisig transaction: ")) + e.what()}; } } @@ -263,6 +240,3 @@ std::vector PendingTransactionImpl::signersKeys() const { } } - -namespace Bitmonero = Monero; - diff --git a/src/wallet/api/pending_transaction.h b/src/wallet/api/pending_transaction.h index e8009fc26..894e92b08 100644 --- a/src/wallet/api/pending_transaction.h +++ b/src/wallet/api/pending_transaction.h @@ -28,14 +28,14 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "wallet/api/wallet2_api.h" -#include "wallet/wallet2.h" +#include "wallet2_api.h" +#include "../wallet2.h" #include #include -namespace Monero { +namespace Wallet { class WalletImpl; class PendingTransactionImpl : public PendingTransaction @@ -43,9 +43,9 @@ class PendingTransactionImpl : public PendingTransaction public: PendingTransactionImpl(WalletImpl &wallet); ~PendingTransactionImpl(); - int status() const override; - std::string errorString() const override; - bool commit(const std::string &filename = "", bool overwrite = false, bool blink = false) override; + std::pair status() const override { return m_status; } + bool good() const override { return m_status.first == Status_Ok; } + bool commit(std::string_view filename = "", bool overwrite = false, bool blink = false) override; uint64_t amount() const override; uint64_t dust() const override; uint64_t fee() const override; @@ -63,15 +63,11 @@ private: friend class WalletImpl; WalletImpl &m_wallet; - int m_status; - std::string m_errorString; + std::pair m_status; std::vector m_pending_tx; std::unordered_set m_signers; std::vector m_tx_device_aux; std::vector m_key_images; }; - } - -namespace Bitmonero = Monero; diff --git a/src/wallet/api/subaddress.cpp b/src/wallet/api/subaddress.cpp index 8a1d34864..d4ff10759 100644 --- a/src/wallet/api/subaddress.cpp +++ b/src/wallet/api/subaddress.cpp @@ -34,7 +34,7 @@ #include -namespace Monero { +namespace Wallet { Subaddress::~Subaddress() {} diff --git a/src/wallet/api/subaddress.h b/src/wallet/api/subaddress.h index 87585ec16..a158d4435 100644 --- a/src/wallet/api/subaddress.h +++ b/src/wallet/api/subaddress.h @@ -29,7 +29,7 @@ #include "wallet/api/wallet2_api.h" #include "wallet/wallet2.h" -namespace Monero { +namespace Wallet { class WalletImpl; diff --git a/src/wallet/api/subaddress_account.cpp b/src/wallet/api/subaddress_account.cpp index eaaddc11f..4cfa9807f 100644 --- a/src/wallet/api/subaddress_account.cpp +++ b/src/wallet/api/subaddress_account.cpp @@ -34,7 +34,7 @@ #include -namespace Monero { +namespace Wallet { SubaddressAccount::~SubaddressAccount() {} diff --git a/src/wallet/api/subaddress_account.h b/src/wallet/api/subaddress_account.h index 358e446d4..f03a3efc1 100644 --- a/src/wallet/api/subaddress_account.h +++ b/src/wallet/api/subaddress_account.h @@ -29,7 +29,7 @@ #include "wallet/api/wallet2_api.h" #include "wallet/wallet2.h" -namespace Monero { +namespace Wallet { class WalletImpl; diff --git a/src/wallet/api/transaction_history.cpp b/src/wallet/api/transaction_history.cpp index 796620d3d..f00d8b33b 100644 --- a/src/wallet/api/transaction_history.cpp +++ b/src/wallet/api/transaction_history.cpp @@ -40,7 +40,7 @@ #include #include -namespace Monero { +namespace Wallet { TransactionHistory::~TransactionHistory() {} @@ -74,7 +74,7 @@ TransactionInfo *TransactionHistoryImpl::transaction(int index) const return index_ < m_history.size() ? m_history[index_] : nullptr; } -TransactionInfo *TransactionHistoryImpl::transaction(const std::string &id) const +TransactionInfo *TransactionHistoryImpl::transaction(std::string_view id) const { std::shared_lock lock{m_historyMutex}; auto itr = std::find_if(m_history.begin(), m_history.end(), @@ -251,5 +251,3 @@ void TransactionHistoryImpl::refresh() } } // namespace - -namespace Bitmonero = Monero; diff --git a/src/wallet/api/transaction_history.h b/src/wallet/api/transaction_history.h index 20712b460..52946fd96 100644 --- a/src/wallet/api/transaction_history.h +++ b/src/wallet/api/transaction_history.h @@ -31,7 +31,7 @@ #include "wallet/api/wallet2_api.h" #include -namespace Monero { +namespace Wallet { class WalletImpl; @@ -40,11 +40,11 @@ class TransactionHistoryImpl : public TransactionHistory public: TransactionHistoryImpl(WalletImpl * wallet); ~TransactionHistoryImpl(); - virtual int count() const; - virtual TransactionInfo * transaction(int index) const; - virtual TransactionInfo * transaction(const std::string &id) const; - virtual std::vector getAll() const; - virtual void refresh(); + int count() const override; + TransactionInfo* transaction(int index) const override; + TransactionInfo* transaction(std::string_view id) const override; + std::vector getAll() const override; + void refresh() override; private: @@ -55,6 +55,3 @@ private: }; } - -namespace Bitmonero = Monero; - diff --git a/src/wallet/api/transaction_info.cpp b/src/wallet/api/transaction_info.cpp index bd431f88f..eaff81d8f 100644 --- a/src/wallet/api/transaction_info.cpp +++ b/src/wallet/api/transaction_info.cpp @@ -31,12 +31,12 @@ #include "transaction_info.h" -namespace Monero { +namespace Wallet { TransactionInfo::~TransactionInfo() {} -TransactionInfo::Transfer::Transfer(uint64_t _amount, const std::string &_address) - : amount(_amount), address(_address) {} +TransactionInfo::Transfer::Transfer(uint64_t _amount, std::string _address) + : amount(_amount), address(std::move(_address)) {} TransactionInfoImpl::TransactionInfoImpl() @@ -147,5 +147,3 @@ uint64_t TransactionInfoImpl::unlockTime() const } } // namespace - -namespace Bitmonero = Monero; diff --git a/src/wallet/api/transaction_info.h b/src/wallet/api/transaction_info.h index c2c24188a..7b6e28aa7 100644 --- a/src/wallet/api/transaction_info.h +++ b/src/wallet/api/transaction_info.h @@ -32,7 +32,7 @@ #include #include -namespace Monero { +namespace Wallet { enum class reward_type { unspecified, @@ -90,5 +90,3 @@ private: }; } // namespace - -namespace Bitmonero = Monero; diff --git a/src/wallet/api/unsigned_transaction.cpp b/src/wallet/api/unsigned_transaction.cpp index c237182f4..9191e8bd9 100644 --- a/src/wallet/api/unsigned_transaction.cpp +++ b/src/wallet/api/unsigned_transaction.cpp @@ -40,17 +40,14 @@ #include #include -using namespace std; - -namespace Monero { +namespace Wallet { UnsignedTransaction::~UnsignedTransaction() {} UnsignedTransactionImpl::UnsignedTransactionImpl(WalletImpl &wallet) - : m_wallet(wallet) + : m_wallet(wallet), m_status{Status_Ok, ""} { - m_status = Status_Ok; } UnsignedTransactionImpl::~UnsignedTransactionImpl() @@ -58,23 +55,13 @@ UnsignedTransactionImpl::~UnsignedTransactionImpl() LOG_PRINT_L3("Unsigned tx deleted"); } -int UnsignedTransactionImpl::status() const -{ - return m_status; -} - -string UnsignedTransactionImpl::errorString() const -{ - return m_errorString; -} - -bool UnsignedTransactionImpl::sign(const std::string &signedFileName) +bool UnsignedTransactionImpl::sign(std::string_view signedFileName_) { + auto signedFileName = fs::u8path(signedFileName_); if(m_wallet.watchOnly()) { - m_errorString = tr("This is a watch only wallet"); - m_status = Status_Error; - return false; + m_status = {Status_Error, tr("This is a watch only wallet")}; + return false; } std::vector ptx; try @@ -82,15 +69,13 @@ bool UnsignedTransactionImpl::sign(const std::string &signedFileName) bool r = m_wallet.m_wallet->sign_tx(m_unsigned_tx_set, signedFileName, ptx); if (!r) { - m_errorString = tr("Failed to sign transaction"); - m_status = Status_Error; + m_status = {Status_Error, tr("Failed to sign transaction")}; return false; } } catch (const std::exception &e) { - m_errorString = string(tr("Failed to sign transaction")) + e.what(); - m_status = Status_Error; + m_status = {Status_Error, std::string(tr("Failed to sign transaction")) + e.what()}; return false; } return true; @@ -122,14 +107,14 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function get_nu { if (!payment_id_string.empty()) payment_id_string += ", "; - payment_id_string = std::string("encrypted payment ID ") + epee::string_tools::pod_to_hex(payment_id8); + payment_id_string = std::string("encrypted payment ID ") + tools::type_to_hex(payment_id8); has_encrypted_payment_id = true; } else if (cryptonote::get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) { if (!payment_id_string.empty()) payment_id_string += ", "; - payment_id_string = std::string("unencrypted payment ID ") + epee::string_tools::pod_to_hex(payment_id); + payment_id_string = std::string("unencrypted payment ID ") + tools::type_to_hex(payment_id); } } } @@ -148,7 +133,7 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function get_nu if (has_encrypted_payment_id && !entry.is_subaddress) { address = get_account_integrated_address_as_str(m_wallet.m_wallet->nettype(), entry.addr, payment_id8); - address += std::string(" (" + standard_address + " with encrypted payment id " + epee::string_tools::pod_to_hex(payment_id8) + ")"); + address += std::string(" (" + standard_address + " with encrypted payment id " + tools::type_to_hex(payment_id8) + ")"); } else address = standard_address; @@ -164,15 +149,13 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function get_nu auto it = dests.find(cd.change_dts.addr); if (it == dests.end()) { - m_status = Status_Error; - m_errorString = tr("Claimed change does not go to a paid address"); + m_status = {Status_Error, tr("Claimed change does not go to a paid address")}; return false; } if (it->second.second < cd.change_dts.amount) { - m_status = Status_Error; - m_errorString = tr("Claimed change is larger than payment to the change address"); - return false; + m_status = {Status_Error, tr("Claimed change is larger than payment to the change address")}; + return false; } if (cd.change_dts.amount > 0) { @@ -180,8 +163,7 @@ bool UnsignedTransactionImpl::checkLoadedTx(const std::function get_nu first_known_non_zero_change_index = n; if (memcmp(&cd.change_dts.addr, &get_tx(first_known_non_zero_change_index).change_dts.addr, sizeof(cd.change_dts.addr))) { - m_status = Status_Error; - m_errorString = tr("Change goes to more than one address"); + m_status = {Status_Error, tr("Change goes to more than one address")}; return false; } } @@ -261,7 +243,7 @@ uint64_t UnsignedTransactionImpl::txCount() const std::vector UnsignedTransactionImpl::paymentId() const { - std::vector result; + std::vector result; for (const auto &utx: m_unsigned_tx_set.txes) { crypto::hash payment_id = crypto::null_hash; cryptonote::tx_extra_nonce extra_nonce; @@ -281,7 +263,7 @@ std::vector UnsignedTransactionImpl::paymentId() const } } if(payment_id != crypto::null_hash) - result.push_back(epee::string_tools::pod_to_hex(payment_id)); + result.push_back(tools::type_to_hex(payment_id)); else result.push_back(""); } @@ -291,7 +273,7 @@ std::vector UnsignedTransactionImpl::paymentId() const std::vector UnsignedTransactionImpl::recipientAddress() const { // TODO: return integrated address if short payment ID exists - std::vector result; + std::vector result; for (const auto &utx: m_unsigned_tx_set.txes) { if (utx.dests.empty()) { MERROR("empty destinations, skipped"); @@ -316,6 +298,3 @@ uint64_t UnsignedTransactionImpl::minMixinCount() const } } // namespace - -namespace Bitmonero = Monero; - diff --git a/src/wallet/api/unsigned_transaction.h b/src/wallet/api/unsigned_transaction.h index 1a5067419..634535abd 100644 --- a/src/wallet/api/unsigned_transaction.h +++ b/src/wallet/api/unsigned_transaction.h @@ -35,7 +35,7 @@ #include -namespace Monero { +namespace Wallet { class WalletImpl; class UnsignedTransactionImpl : public UnsignedTransaction @@ -43,8 +43,8 @@ class UnsignedTransactionImpl : public UnsignedTransaction public: UnsignedTransactionImpl(WalletImpl &wallet); ~UnsignedTransactionImpl(); - int status() const override; - std::string errorString() const override; + bool good() const override { return m_status.first == Status_Ok; } + std::pair status() const override { return m_status; } std::vector amount() const override; std::vector fee() const override; std::vector mixin() const override; @@ -52,7 +52,7 @@ public: std::vector recipientAddress() const override; uint64_t txCount() const override; // sign txs and save to file - bool sign(const std::string &signedFileName) override; + bool sign(std::string_view signedFileName) override; std::string confirmationMessage() const override {return m_confirmationMessage;} uint64_t minMixinCount() const override; @@ -63,13 +63,10 @@ private: friend class WalletImpl; WalletImpl &m_wallet; - int m_status; - std::string m_errorString; + std::pair m_status; tools::wallet2::unsigned_tx_set m_unsigned_tx_set; std::string m_confirmationMessage; }; } - -namespace Bitmonero = Monero; diff --git a/src/wallet/api/utils.cpp b/src/wallet/api/utils.cpp index 24252868a..5b8689f35 100644 --- a/src/wallet/api/utils.cpp +++ b/src/wallet/api/utils.cpp @@ -28,14 +28,10 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers - - -#include "include_base_utils.h" // LOG_PRINT_x +#include "epee/misc_log_ex.h" #include "common/util.h" -using namespace std; - -namespace Monero { +namespace Wallet { namespace Utils { bool isAddressLocal(const std::string &address) @@ -58,7 +54,4 @@ void onStartup() } - } // namespace - -namespace Bitmonero = Monero; diff --git a/src/wallet/api/wallet.cpp b/src/wallet/api/wallet.cpp index 0e637a955..4e40f57b3 100644 --- a/src/wallet/api/wallet.cpp +++ b/src/wallet/api/wallet.cpp @@ -42,6 +42,7 @@ #include "subaddress_account.h" #include "common_defines.h" #include "common/util.h" +#include "common/fs.h" #include "mnemonics/electrum-words.h" #include "mnemonics/english.h" @@ -50,18 +51,12 @@ #include #include -#ifdef WIN32 -#include -#include -#endif - -using namespace std; using namespace cryptonote; #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "WalletAPI" -namespace Monero { +namespace Wallet { namespace { static const int DEFAULT_REFRESH_INTERVAL_MILLIS = 1000 * 10; @@ -72,50 +67,43 @@ namespace { // Connection timeout 30 sec static const int DEFAULT_CONNECTION_TIMEOUT_MILLIS = 1000 * 30; - std::string get_default_ringdb_path(cryptonote::network_type nettype) + fs::path get_default_ringdb_path(cryptonote::network_type nettype) { - boost::filesystem::path dir = tools::get_default_data_dir(); + auto dir = tools::get_default_data_dir(); // remove .loki, replace with .shared-ringdb - dir = dir.remove_filename(); - dir /= ".shared-ringdb"; + dir.replace_filename(".shared-ringdb"); if (nettype == cryptonote::TESTNET) dir /= "testnet"; else if (nettype == cryptonote::DEVNET) dir /= "devnet"; - return dir.string(); + return dir; } void checkMultisigWalletReady(const tools::wallet2* wallet) { - if (!wallet) { - throw runtime_error("Wallet is not initialized yet"); - } + if (!wallet) + throw std::runtime_error("Wallet is not initialized yet"); bool ready; - if (!wallet->multisig(&ready)) { - throw runtime_error("Wallet is not multisig"); - } + if (!wallet->multisig(&ready)) + throw std::runtime_error("Wallet is not multisig"); - if (!ready) { - throw runtime_error("Multisig wallet is not finalized yet"); - } + if (!ready) + throw std::runtime_error("Multisig wallet is not finalized yet"); } void checkMultisigWalletReady(const std::unique_ptr &wallet) { return checkMultisigWalletReady(wallet.get()); } void checkMultisigWalletNotReady(const tools::wallet2* wallet) { - if (!wallet) { - throw runtime_error("Wallet is not initialized yet"); - } + if (!wallet) + throw std::runtime_error("Wallet is not initialized yet"); bool ready; - if (!wallet->multisig(&ready)) { - throw runtime_error("Wallet is not multisig"); - } + if (!wallet->multisig(&ready)) + throw std::runtime_error("Wallet is not multisig"); - if (ready) { - throw runtime_error("Multisig wallet is already finalized"); - } + if (ready) + throw std::runtime_error("Multisig wallet is already finalized"); } void checkMultisigWalletNotReady(const std::unique_ptr &wallet) { return checkMultisigWalletNotReady(wallet.get()); @@ -162,7 +150,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback void on_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount, const cryptonote::subaddress_index& subaddr_index, uint64_t unlock_time, bool blink) override { - std::string tx_hash = epee::string_tools::pod_to_hex(txid); + std::string tx_hash = tools::type_to_hex(txid); LOG_PRINT_L3(__FUNCTION__ << ": money received." << (blink ? "blink: " : "height: ") << height << ", tx: " << tx_hash @@ -178,7 +166,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback void on_unconfirmed_money_received(uint64_t height, const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t amount, const cryptonote::subaddress_index& subaddr_index) override { - std::string tx_hash = epee::string_tools::pod_to_hex(txid); + std::string tx_hash = tools::type_to_hex(txid); LOG_PRINT_L3(__FUNCTION__ << ": unconfirmed money received. height: " << height << ", tx: " << tx_hash @@ -199,7 +187,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback const cryptonote::subaddress_index &subaddr_index) override { // TODO; - std::string tx_hash = epee::string_tools::pod_to_hex(txid); + std::string tx_hash = tools::type_to_hex(txid); LOG_PRINT_L3(__FUNCTION__ << ": money spent. height: " << height << ", tx: " << tx_hash << ", amount: " << print_money(amount) @@ -227,7 +215,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback void on_lw_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount) override { if (m_listener) { - std::string tx_hash = epee::string_tools::pod_to_hex(txid); + std::string tx_hash = tools::type_to_hex(txid); m_listener->moneyReceived(tx_hash, amount); } } @@ -235,7 +223,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback void on_lw_unconfirmed_money_received(uint64_t height, const crypto::hash &txid, uint64_t amount) override { if (m_listener) { - std::string tx_hash = epee::string_tools::pod_to_hex(txid); + std::string tx_hash = tools::type_to_hex(txid); m_listener->unconfirmedMoneyReceived(tx_hash, amount); } } @@ -243,7 +231,7 @@ struct Wallet2CallbackImpl : public tools::i_wallet2_callback void on_lw_money_spent(uint64_t height, const crypto::hash &txid, uint64_t amount) override { if (m_listener) { - std::string tx_hash = epee::string_tools::pod_to_hex(txid); + std::string tx_hash = tools::type_to_hex(txid); m_listener->moneySpent(tx_hash, amount); } } @@ -302,12 +290,12 @@ Wallet::~Wallet() {} WalletListener::~WalletListener() {} -string Wallet::displayAmount(uint64_t amount) +std::string Wallet::displayAmount(uint64_t amount) { return cryptonote::print_money(amount); } -uint64_t Wallet::amountFromString(const string &amount) +uint64_t Wallet::amountFromString(const std::string &amount) { uint64_t result = 0; cryptonote::parse_amount(result, amount); @@ -324,25 +312,19 @@ uint64_t Wallet::amountFromDouble(double amount) std::string Wallet::genPaymentId() { crypto::hash8 payment_id = crypto::rand(); - return epee::string_tools::pod_to_hex(payment_id); + return tools::type_to_hex(payment_id); } -bool Wallet::paymentIdValid(const string &paiment_id) +bool Wallet::paymentIdValid(const std::string &payment_id) { - crypto::hash8 pid8; - if (tools::wallet2::parse_short_payment_id(paiment_id, pid8)) - return true; - crypto::hash pid; - if (tools::wallet2::parse_long_payment_id(paiment_id, pid)) - return true; - return false; + return payment_id.size() == 16 && lokimq::is_hex(payment_id); } bool Wallet::serviceNodePubkeyValid(const std::string &str) { crypto::public_key sn_key; - return epee::string_tools::hex_to_pod(str, sn_key); + return str.size() == 64 && lokimq::is_hex(str); } bool Wallet::addressValid(const std::string &str, NetworkType nettype) @@ -394,7 +376,7 @@ std::string Wallet::paymentIdFromAddress(const std::string &str, NetworkType net return ""; if (!info.has_payment_id) return ""; - return epee::string_tools::pod_to_hex(info.payment_id); + return tools::type_to_hex(info.payment_id); } uint64_t Wallet::maximumAllowedAmount() @@ -402,14 +384,9 @@ uint64_t Wallet::maximumAllowedAmount() return std::numeric_limits::max(); } -void Wallet::init(const char *argv0, const char *default_log_base_name, const std::string &log_path, bool console) { -#ifdef WIN32 - // Activate UTF-8 support for Boost filesystem classes on Windows - std::locale::global(boost::locale::generator().generate("")); - boost::filesystem::path::imbue(std::locale()); -#endif +void Wallet::init(const char *argv0, const char *default_log_base_name, const std::string& log_path, bool console) { epee::string_tools::set_module_name_and_folder(argv0); - mlog_configure(log_path.empty() ? mlog_get_default_log_path(default_log_base_name) : log_path.c_str(), console); + mlog_configure(log_path.empty() ? mlog_get_default_log_path(default_log_base_name) : log_path, console); } void Wallet::debug(const std::string &category, const std::string &str) { @@ -431,7 +408,7 @@ void Wallet::error(const std::string &category, const std::string &str) { ///////////////////////// WalletImpl implementation //////////////////////// WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds) :m_wallet(nullptr) - , m_status(Wallet::Status_Ok) + , m_status(Wallet::Status_Ok, "") , m_wallet2Callback(nullptr) , m_recoveringFromSeed(false) , m_recoveringFromDevice(false) @@ -458,21 +435,14 @@ WalletImpl::WalletImpl(NetworkType nettype, uint64_t kdf_rounds) m_longPollThread = std::thread([this]() { for (;;) { - if (!m_refreshEnabled) - { - std::this_thread::sleep_for(std::chrono::seconds(10)); - continue; - } - - try - { - if (m_wallet->long_poll_pool_state()) + if (m_wallet->m_long_poll_disabled) + return true; + try { + if (m_refreshEnabled && m_wallet->long_poll_pool_state()) m_refreshCV.notify_one(); - } - catch (...) - { - // Ignore - } + } catch (...) { /* ignore */ } + + std::this_thread::sleep_for(std::chrono::seconds(1)); } }); } @@ -489,6 +459,10 @@ WalletImpl::~WalletImpl() // Stop refresh thread stopRefresh(); + m_wallet->cancel_long_poll(); + if (m_longPollThread.joinable()) + m_longPollThread.join(); + if (m_wallet2Callback->getListener()) { m_wallet2Callback->getListener()->onSetWallet(nullptr); } @@ -496,16 +470,17 @@ WalletImpl::~WalletImpl() LOG_PRINT_L1(__FUNCTION__ << " finished"); } -bool WalletImpl::create(const std::string &path, const std::string &password, const std::string &language) +bool WalletImpl::create(std::string_view path_, const std::string &password, const std::string &language) { + auto path = fs::u8path(path_); clearStatus(); m_recoveringFromSeed = false; m_recoveringFromDevice = false; bool keys_file_exists; bool wallet_file_exists; tools::wallet2::wallet_exists(path, keys_file_exists, wallet_file_exists); - LOG_PRINT_L3("wallet_path: " << path << ""); + LOG_PRINT_L3("wallet_path: " << path); LOG_PRINT_L3("keys_file_exists: " << std::boolalpha << keys_file_exists << std::noboolalpha << " wallet_file_exists: " << std::boolalpha << wallet_file_exists << std::noboolalpha); @@ -533,8 +508,9 @@ bool WalletImpl::create(const std::string &path, const std::string &password, co return true; } -bool WalletImpl::createWatchOnly(const std::string &path, const std::string &password, const std::string &language) const +bool WalletImpl::createWatchOnly(std::string_view path_, const std::string &password, const std::string &language) const { + auto path = fs::u8path(path_); clearStatus(); std::unique_ptr view_wallet(new tools::wallet2(m_wallet->nettype())); @@ -544,7 +520,7 @@ bool WalletImpl::createWatchOnly(const std::string &path, const std::string &pas bool keys_file_exists; bool wallet_file_exists; tools::wallet2::wallet_exists(path, keys_file_exists, wallet_file_exists); - LOG_PRINT_L3("wallet_path: " << path << ""); + LOG_PRINT_L3("wallet_path: " << path); LOG_PRINT_L3("keys_file_exists: " << std::boolalpha << keys_file_exists << std::noboolalpha << " wallet_file_exists: " << std::boolalpha << wallet_file_exists << std::noboolalpha); @@ -599,22 +575,14 @@ bool WalletImpl::createWatchOnly(const std::string &path, const std::string &pas return true; } -bool WalletImpl::recoverFromKeys(const std::string &path, - const std::string &language, - const std::string &address_string, - const std::string &viewkey_string, - const std::string &spendkey_string) -{ - return recoverFromKeysWithPassword(path, "", language, address_string, viewkey_string, spendkey_string); -} - -bool WalletImpl::recoverFromKeysWithPassword(const std::string &path, +bool WalletImpl::recoverFromKeysWithPassword(std::string_view path_, const std::string &password, const std::string &language, const std::string &address_string, const std::string &viewkey_string, const std::string &spendkey_string) { + auto path = fs::u8path(path_); cryptonote::address_parse_info info; if(!get_account_address_from_str(info, m_wallet->nettype(), address_string)) { @@ -698,14 +666,15 @@ bool WalletImpl::recoverFromKeysWithPassword(const std::string &path, } catch (const std::exception& e) { - setStatusError(string(tr("failed to generate new wallet: ")) + e.what()); + setStatusError(std::string(tr("failed to generate new wallet: ")) + e.what()); return false; } return true; } -bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &password, const std::string &device_name) +bool WalletImpl::recoverFromDevice(std::string_view path_, const std::string &password, const std::string &device_name) { + auto path = fs::u8path(path_); clearStatus(); m_recoveringFromSeed = false; m_recoveringFromDevice = true; @@ -715,7 +684,7 @@ bool WalletImpl::recoverFromDevice(const std::string &path, const std::string &p LOG_PRINT_L1("Generated new wallet from device: " + device_name); } catch (const std::exception& e) { - setStatusError(string(tr("failed to generate new wallet: ")) + e.what()); + setStatusError(std::string(tr("failed to generate new wallet: ")) + e.what()); return false; } return true; @@ -726,8 +695,9 @@ Wallet::Device WalletImpl::getDeviceType() const return static_cast(m_wallet->get_device_type()); } -bool WalletImpl::open(const std::string &path, const std::string &password) +bool WalletImpl::open(std::string_view path_, const std::string &password) { + auto path = fs::u8path(path_); clearStatus(); m_recoveringFromSeed = false; m_recoveringFromDevice = false; @@ -749,18 +719,13 @@ bool WalletImpl::open(const std::string &path, const std::string &password) LOG_ERROR("Error opening wallet: " << e.what()); setStatusCritical(e.what()); } - return status() == Status_Ok; + return good(); } -bool WalletImpl::recover(const std::string &path, const std::string &seed) -{ - return recover(path, "", seed); -} - -bool WalletImpl::recover(const std::string &path, const std::string &password, const std::string &seed, const std::string &seed_offset/* = {}*/) +bool WalletImpl::recover(std::string_view path_, const std::string &password, const std::string &seed, const std::string &seed_offset/* = {}*/) { + auto path = fs::u8path(path_); clearStatus(); - m_errorString.clear(); if (seed.empty()) { LOG_ERROR("Electrum seed is empty"); setStatusError(tr("Electrum seed is empty")); @@ -790,7 +755,7 @@ bool WalletImpl::recover(const std::string &path, const std::string &password, c } catch (const std::exception &e) { setStatusCritical(e.what()); } - return status() == Status_Ok; + return good(); } bool WalletImpl::close(bool store) @@ -802,7 +767,7 @@ bool WalletImpl::close(bool store) if (store) { // Do not store wallet with invalid status // Status Critical refers to errors on opening or creating wallets. - if (status() != Status_Critical) + if (status().first != Status_Critical) m_wallet->store(); else LOG_ERROR("Status_Critical - not saving wallet"); @@ -839,22 +804,13 @@ void WalletImpl::setSeedLanguage(const std::string &arg) m_wallet->set_seed_language(arg); } -int WalletImpl::status() const -{ +std::pair WalletImpl::status() const { std::lock_guard l{m_statusMutex}; return m_status; } - -std::string WalletImpl::errorString() const -{ +bool WalletImpl::good() const { std::lock_guard l{m_statusMutex}; - return m_errorString; -} - -void WalletImpl::statusWithErrorString(int& status, std::string& errorString) const { - std::lock_guard l{m_statusMutex}; - status = m_status; - errorString = m_errorString; + return m_status.first == Status_Ok; } bool WalletImpl::setPassword(const std::string &password) @@ -866,7 +822,7 @@ bool WalletImpl::setPassword(const std::string &password) } catch (const std::exception &e) { setStatusError(e.what()); } - return status() == Status_Ok; + return good(); } bool WalletImpl::setDevicePin(const std::string &pin) @@ -877,7 +833,7 @@ bool WalletImpl::setDevicePin(const std::string &pin) } catch (const std::exception &e) { setStatusError(e.what()); } - return status() == Status_Ok; + return good(); } bool WalletImpl::setDevicePassphrase(const std::string &passphrase) @@ -888,7 +844,7 @@ bool WalletImpl::setDevicePassphrase(const std::string &passphrase) } catch (const std::exception &e) { setStatusError(e.what()); } - return status() == Status_Ok; + return good(); } std::string WalletImpl::address(uint32_t accountIndex, uint32_t addressIndex) const @@ -899,37 +855,36 @@ std::string WalletImpl::address(uint32_t accountIndex, uint32_t addressIndex) co std::string WalletImpl::integratedAddress(const std::string &payment_id) const { crypto::hash8 pid; - if (!tools::wallet2::parse_short_payment_id(payment_id, pid)) { + if (!tools::hex_to_type(payment_id, pid)) return ""; - } return m_wallet->get_integrated_address_as_str(pid); } std::string WalletImpl::secretViewKey() const { - return epee::string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_view_secret_key); + return tools::type_to_hex(m_wallet->get_account().get_keys().m_view_secret_key); } std::string WalletImpl::publicViewKey() const { - return epee::string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_view_public_key); + return tools::type_to_hex(m_wallet->get_account().get_keys().m_account_address.m_view_public_key); } std::string WalletImpl::secretSpendKey() const { - return epee::string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_spend_secret_key); + return tools::type_to_hex(m_wallet->get_account().get_keys().m_spend_secret_key); } std::string WalletImpl::publicSpendKey() const { - return epee::string_tools::pod_to_hex(m_wallet->get_account().get_keys().m_account_address.m_spend_public_key); + return tools::type_to_hex(m_wallet->get_account().get_keys().m_account_address.m_spend_public_key); } std::string WalletImpl::publicMultisigSignerKey() const { try { crypto::public_key signer = m_wallet->get_multisig_signer_public_key(); - return epee::string_tools::pod_to_hex(signer); + return tools::type_to_hex(signer); } catch (const std::exception&) { return ""; } @@ -937,11 +892,12 @@ std::string WalletImpl::publicMultisigSignerKey() const std::string WalletImpl::path() const { - return m_wallet->path(); + return m_wallet->path().u8string(); } -bool WalletImpl::store(const std::string &path) +bool WalletImpl::store(std::string_view path_) { + auto path = fs::u8path(path_); clearStatus(); try { if (path.empty()) { @@ -958,14 +914,14 @@ bool WalletImpl::store(const std::string &path) return true; } -string WalletImpl::filename() const +std::string WalletImpl::filename() const { - return m_wallet->get_wallet_file(); + return m_wallet->get_wallet_file().u8string(); } -string WalletImpl::keysFilename() const +std::string WalletImpl::keysFilename() const { - return m_wallet->get_keys_file(); + return m_wallet->get_keys_file().u8string(); } bool WalletImpl::init(const std::string &daemon_address, uint64_t upper_transaction_size_limit, const std::string &daemon_username, const std::string &daemon_password, bool use_ssl, bool lightWallet) @@ -1114,7 +1070,7 @@ bool WalletImpl::refresh() //TODO: make doRefresh return bool to know whether the error occured during refresh or not //otherwise one may try, say, to send transaction, transfer fails and this method returns false doRefresh(); - return status() == Status_Ok; + return good(); } void WalletImpl::refreshAsync() @@ -1129,7 +1085,7 @@ bool WalletImpl::rescanBlockchain() clearStatus(); m_refreshShouldRescan = true; doRefresh(); - return status() == Status_Ok; + return good(); } void WalletImpl::rescanBlockchainAsync() @@ -1154,13 +1110,13 @@ int WalletImpl::autoRefreshInterval() const return m_refreshIntervalMillis; } -UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_filename) { +UnsignedTransaction* WalletImpl::loadUnsignedTx(std::string_view unsigned_filename_) { + auto unsigned_filename = fs::u8path(unsigned_filename_); clearStatus(); - UnsignedTransactionImpl * transaction = new UnsignedTransactionImpl(*this); + UnsignedTransactionImpl* transaction = new UnsignedTransactionImpl(*this); if (!m_wallet->load_unsigned_tx(unsigned_filename, transaction->m_unsigned_tx_set)){ setStatusError(tr("Failed to load unsigned transactions")); - transaction->m_status = UnsignedTransaction::Status::Status_Error; - transaction->m_errorString = errorString(); + transaction->m_status = {UnsignedTransaction::Status::Status_Error, status().second}; return transaction; } @@ -1170,31 +1126,34 @@ UnsignedTransaction *WalletImpl::loadUnsignedTx(const std::string &unsigned_file if (!transaction->m_unsigned_tx_set.transfers.second.empty()) extra_message = (boost::format("%u outputs to import. ") % (unsigned)transaction->m_unsigned_tx_set.transfers.second.size()).str(); transaction->checkLoadedTx([&transaction](){return transaction->m_unsigned_tx_set.txes.size();}, [&transaction](size_t n)->const wallet::tx_construction_data&{return transaction->m_unsigned_tx_set.txes[n];}, extra_message); - setStatus(transaction->status(), transaction->errorString()); - + auto [code, msg] = transaction->status(); + setStatus(code, std::move(msg)); + return transaction; } -bool WalletImpl::submitTransaction(const string &fileName) { +bool WalletImpl::submitTransaction(std::string_view filename_) { + auto fileName = fs::u8path(filename_); clearStatus(); std::unique_ptr transaction(new PendingTransactionImpl(*this)); bool r = m_wallet->load_tx(fileName, transaction->m_pending_tx); if (!r) { - setStatus(Status_Ok, tr("Failed to load transaction from file")); + setStatus(Status_Error, tr("Failed to load transaction from file")); return false; } if(!transaction->commit()) { - setStatusError(transaction->m_errorString); + setStatusError(transaction->status().second); return false; } return true; } -bool WalletImpl::exportKeyImages(const string &filename) +bool WalletImpl::exportKeyImages(std::string_view filename_) { + auto filename = fs::u8path(filename_); if (m_wallet->watch_only()) { setStatusError(tr("Wallet is view only")); @@ -1205,7 +1164,7 @@ bool WalletImpl::exportKeyImages(const string &filename) { if (!m_wallet->export_key_images_to_file(filename, false /* requested_ki_only */)) { - setStatusError(tr("failed to save file ") + filename); + setStatusError(tr("failed to save file ") + filename.u8string()); return false; } } @@ -1218,8 +1177,9 @@ bool WalletImpl::exportKeyImages(const string &filename) return true; } -bool WalletImpl::importKeyImages(const string &filename) +bool WalletImpl::importKeyImages(std::string_view filename_) { + auto filename = fs::u8path(filename_); if (!trustedDaemon()) { setStatusError(tr("Key images can only be imported with a trusted daemon")); return false; @@ -1234,7 +1194,7 @@ bool WalletImpl::importKeyImages(const string &filename) catch (const std::exception &e) { LOG_ERROR("Error exporting key images: " << e.what()); - setStatusError(string(tr("Failed to import key images: ")) + e.what()); + setStatusError(std::string(tr("Failed to import key images: ")) + e.what()); return false; } @@ -1266,7 +1226,7 @@ std::string WalletImpl::getSubaddressLabel(uint32_t accountIndex, uint32_t addre catch (const std::exception &e) { LOG_ERROR("Error getting subaddress label: " << e.what()); - setStatusError(string(tr("Failed to get subaddress label: ")) + e.what()); + setStatusError(std::string(tr("Failed to get subaddress label: ")) + e.what()); return ""; } } @@ -1279,7 +1239,7 @@ void WalletImpl::setSubaddressLabel(uint32_t accountIndex, uint32_t addressIndex catch (const std::exception &e) { LOG_ERROR("Error setting subaddress label: " << e.what()); - setStatusError(string(tr("Failed to set subaddress label: ")) + e.what()); + setStatusError(std::string(tr("Failed to set subaddress label: ")) + e.what()); } } @@ -1290,33 +1250,32 @@ MultisigState WalletImpl::multisig() const { return state; } -string WalletImpl::getMultisigInfo() const { +std::string WalletImpl::getMultisigInfo() const { try { clearStatus(); return m_wallet->get_multisig_info(); - } catch (const exception& e) { + } catch (const std::exception& e) { LOG_ERROR("Error on generating multisig info: " << e.what()); - setStatusError(string(tr("Failed to get multisig info: ")) + e.what()); + setStatusError(std::string(tr("Failed to get multisig info: ")) + e.what()); } - return string(); + return {}; } -string WalletImpl::makeMultisig(const vector& info, uint32_t threshold) { +std::string WalletImpl::makeMultisig(const std::vector& info, uint32_t threshold) { try { clearStatus(); - if (m_wallet->multisig()) { - throw runtime_error("Wallet is already multisig"); - } + if (m_wallet->multisig()) + throw std::runtime_error("Wallet is already multisig"); return m_wallet->make_multisig(epee::wipeable_string(m_password), info, threshold); - } catch (const exception& e) { + } catch (const std::exception& e) { LOG_ERROR("Error on making multisig wallet: " << e.what()); - setStatusError(string(tr("Failed to make multisig: ")) + e.what()); + setStatusError(std::string(tr("Failed to make multisig: ")) + e.what()); } - return string(); + return {}; } std::string WalletImpl::exchangeMultisigKeys(const std::vector &info) { @@ -1325,15 +1284,15 @@ std::string WalletImpl::exchangeMultisigKeys(const std::vector &inf checkMultisigWalletNotReady(m_wallet); return m_wallet->exchange_multisig_keys(epee::wipeable_string(m_password), info); - } catch (const exception& e) { + } catch (const std::exception& e) { LOG_ERROR("Error on exchanging multisig keys: " << e.what()); - setStatusError(string(tr("Failed to make multisig: ")) + e.what()); + setStatusError(std::string(tr("Failed to make multisig: ")) + e.what()); } - return string(); + return {}; } -bool WalletImpl::finalizeMultisig(const vector& extraMultisigInfo) { +bool WalletImpl::finalizeMultisig(const std::vector& extraMultisigInfo) { try { clearStatus(); checkMultisigWalletNotReady(m_wallet); @@ -1343,31 +1302,31 @@ bool WalletImpl::finalizeMultisig(const vector& extraMultisigInfo) { } setStatusError(tr("Failed to finalize multisig wallet creation")); - } catch (const exception& e) { + } catch (const std::exception& e) { LOG_ERROR("Error on finalizing multisig wallet creation: " << e.what()); - setStatusError(string(tr("Failed to finalize multisig wallet creation: ")) + e.what()); + setStatusError(std::string(tr("Failed to finalize multisig wallet creation: ")) + e.what()); } return false; } -bool WalletImpl::exportMultisigImages(string& images) { +bool WalletImpl::exportMultisigImages(std::string& images) { try { clearStatus(); checkMultisigWalletReady(m_wallet); auto blob = m_wallet->export_multisig(); - images = epee::string_tools::buff_to_hex_nodelimer(blob); + images = lokimq::to_hex(blob); return true; - } catch (const exception& e) { + } catch (const std::exception& e) { LOG_ERROR("Error on exporting multisig images: " << e.what()); - setStatusError(string(tr("Failed to export multisig images: ")) + e.what()); + setStatusError(std::string(tr("Failed to export multisig images: ")) + e.what()); } return false; } -size_t WalletImpl::importMultisigImages(const vector& images) { +size_t WalletImpl::importMultisigImages(const std::vector& images) { try { clearStatus(); checkMultisigWalletReady(m_wallet); @@ -1387,9 +1346,9 @@ size_t WalletImpl::importMultisigImages(const vector& images) { } return m_wallet->import_multisig(blobs); - } catch (const exception& e) { + } catch (const std::exception& e) { LOG_ERROR("Error on importing multisig images: " << e.what()); - setStatusError(string(tr("Failed to import multisig images: ")) + e.what()); + setStatusError(std::string(tr("Failed to import multisig images: ")) + e.what()); } return 0; @@ -1401,45 +1360,42 @@ bool WalletImpl::hasMultisigPartialKeyImages() const { checkMultisigWalletReady(m_wallet); return m_wallet->has_multisig_partial_key_images(); - } catch (const exception& e) { + } catch (const std::exception& e) { LOG_ERROR("Error on checking for partial multisig key images: " << e.what()); - setStatusError(string(tr("Failed to check for partial multisig key images: ")) + e.what()); + setStatusError(std::string(tr("Failed to check for partial multisig key images: ")) + e.what()); } return false; } -PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signData) { +PendingTransaction* WalletImpl::restoreMultisigTransaction(const std::string& signData) { try { clearStatus(); checkMultisigWalletReady(m_wallet); - string binary; - if (!epee::string_tools::parse_hexstr_to_binbuff(signData, binary)) { - throw runtime_error("Failed to deserialize multisig transaction"); - } + std::string binary; + if (!epee::string_tools::parse_hexstr_to_binbuff(signData, binary)) + throw std::runtime_error("Failed to deserialize multisig transaction"); tools::wallet2::multisig_tx_set txSet; - if (!m_wallet->load_multisig_tx(binary, txSet, {})) { - throw runtime_error("couldn't parse multisig transaction data"); - } + if (!m_wallet->load_multisig_tx(binary, txSet, {})) + throw std::runtime_error("couldn't parse multisig transaction data"); auto ptx = new PendingTransactionImpl(*this); ptx->m_pending_tx = txSet.m_ptx; ptx->m_signers = txSet.m_signers; return ptx; - } catch (exception& e) { + } catch (std::exception& e) { LOG_ERROR("Error on restoring multisig transaction: " << e.what()); - setStatusError(string(tr("Failed to restore multisig transaction: ")) + e.what()); + setStatusError(std::string(tr("Failed to restore multisig transaction: ")) + e.what()); } return nullptr; } // TODO: -// 1 - properly handle payment id (add another menthod with explicit 'payment_id' param) -// 2 - check / design how "Transaction" can be single interface +// - check / design how "Transaction" can be single interface // (instead of few different data structures within wallet2 implementation: // - pending_tx; // - transfer_details; @@ -1447,7 +1403,7 @@ PendingTransaction* WalletImpl::restoreMultisigTransaction(const string& signDat // - unconfirmed_transfer_details; // - confirmed_transfer_details) -PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector &dst_addr, const string &payment_id, std::optional> amount, uint32_t priority, uint32_t subaddr_account, std::set subaddr_indices) +PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector &dst_addr, std::optional> amount, uint32_t priority, uint32_t subaddr_account, std::set subaddr_indices) { clearStatus(); @@ -1461,7 +1417,7 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vector extra; std::string extra_nonce; - vector dsts; + std::vector dsts; if (!amount && dst_addr.size() > 1) { setStatusError(tr("Sending all requires one destination address")); break; @@ -1470,15 +1426,6 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vectornettype(), dst_addr[i])) { @@ -1597,27 +1544,27 @@ PendingTransaction *WalletImpl::createTransactionMultDest(const std::vectorm_status, transaction->m_errorString); + transaction->m_status = status(); // Resume refresh thread startRefresh(); return transaction; } -PendingTransaction *WalletImpl::createTransaction(const string &dst_addr, const string &payment_id, std::optional amount, +PendingTransaction *WalletImpl::createTransaction(const std::string &dst_addr, std::optional amount, uint32_t priority, uint32_t subaddr_account, std::set subaddr_indices) { - return createTransactionMultDest(std::vector {dst_addr}, payment_id, amount ? (std::vector {*amount}) : (optional>()), priority, subaddr_account, subaddr_indices); + return createTransactionMultDest(std::vector {dst_addr}, amount ? (std::vector {*amount}) : (std::optional>()), priority, subaddr_account, subaddr_indices); } PendingTransaction *WalletImpl::createSweepUnmixableTransaction() @@ -1628,7 +1575,7 @@ PendingTransaction *WalletImpl::createSweepUnmixableTransaction() PendingTransactionImpl * transaction = new PendingTransactionImpl(*this); - do { + { try { transaction->m_pending_tx = m_wallet->create_unmixable_sweep_transactions(); pendingTxPostProcess(transaction); @@ -1688,17 +1635,17 @@ PendingTransaction *WalletImpl::createSweepUnmixableTransaction() } catch (const tools::error::tx_too_big& e) { setStatusError(tr("failed to find a suitable way to split transactions")); } catch (const tools::error::transfer_error& e) { - setStatusError(string(tr("unknown transfer error: ")) + e.what()); + setStatusError(std::string(tr("unknown transfer error: ")) + e.what()); } catch (const tools::error::wallet_internal_error& e) { - setStatusError(string(tr("internal error: ")) + e.what()); + setStatusError(std::string(tr("internal error: ")) + e.what()); } catch (const std::exception& e) { - setStatusError(string(tr("unexpected error: ")) + e.what()); + setStatusError(std::string(tr("unexpected error: ")) + e.what()); } catch (...) { setStatusError(tr("unknown error")); } - } while (false); + } - statusWithErrorString(transaction->m_status, transaction->m_errorString); + transaction->m_status = status(); return transaction; } @@ -1707,28 +1654,13 @@ void WalletImpl::disposeTransaction(PendingTransaction *t) delete t; } -#if 0 -uint64_t WalletImpl::estimateTransactionFee(const std::vector> &destinations, uint32_t priority) const +uint64_t WalletImpl::estimateTransactionFee(uint32_t priority, uint32_t recipients) const { -#if 0 - const size_t pubkey_size = 33; - const size_t encrypted_paymentid_size = 11; - const size_t extra_size = pubkey_size + encrypted_paymentid_size; - - return m_wallet->estimate_fee( - 1 /*inputs*/, - CRYPTONOTE_DEFAULT_TX_MIXIN /*mixin*/, - destinations.size() + 1 /*outputs*/, - extra_size, - m_wallet->use_fork_rules(HF_VERSION_CLSAG, 0), - m_wallet->get_base_fees(), - m_wallet->get_fee_percent(priority), - m_wallet->get_fee_quantization_mask()); -#else - return 0; // TODO: IMPLEMENT -#endif + constexpr uint32_t typical_size = 2000; + const auto base_fee = m_wallet->get_base_fees(); + uint64_t pct = m_wallet->get_fee_percent(priority == 1 ? 1 : 5, txtype::standard); + return (base_fee.first * typical_size + base_fee.second * (recipients + 1)) * pct / 100; } -#endif TransactionHistory *WalletImpl::history() { @@ -1793,7 +1725,7 @@ std::string WalletImpl::getUserNote(const std::string &txid) const std::string WalletImpl::getTxKey(const std::string &txid_str) const { crypto::hash txid; - if(!epee::string_tools::hex_to_pod(txid_str, txid)) + if(!tools::hex_to_type(txid_str, txid)) { setStatusError(tr("Failed to parse txid")); return ""; @@ -1808,9 +1740,9 @@ std::string WalletImpl::getTxKey(const std::string &txid_str) const { clearStatus(); std::ostringstream oss; - oss << epee::string_tools::pod_to_hex(tx_key); + oss << tools::type_to_hex(tx_key); for (size_t i = 0; i < additional_tx_keys.size(); ++i) - oss << epee::string_tools::pod_to_hex(additional_tx_keys[i]); + oss << tools::type_to_hex(additional_tx_keys[i]); return oss.str(); } else @@ -1826,10 +1758,10 @@ std::string WalletImpl::getTxKey(const std::string &txid_str) const } } -bool WalletImpl::checkTxKey(const std::string &txid_str, std::string tx_key_str, const std::string &address_str, uint64_t &received, bool &in_pool, uint64_t &confirmations) +bool WalletImpl::checkTxKey(const std::string &txid_str, std::string_view tx_key_str, const std::string &address_str, uint64_t &received, bool &in_pool, uint64_t &confirmations) { crypto::hash txid; - if (!epee::string_tools::hex_to_pod(txid_str, txid)) + if (!tools::hex_to_type(txid_str, txid)) { setStatusError(tr("Failed to parse txid")); return false; @@ -1837,21 +1769,18 @@ bool WalletImpl::checkTxKey(const std::string &txid_str, std::string tx_key_str, crypto::secret_key tx_key; std::vector additional_tx_keys; - if (!epee::string_tools::hex_to_pod(tx_key_str.substr(0, 64), tx_key)) + bool first = true; + while (first || !tx_key_str.empty()) { - setStatusError(tr("Failed to parse tx key")); - return false; - } - tx_key_str = tx_key_str.substr(64); - while (!tx_key_str.empty()) - { - additional_tx_keys.resize(additional_tx_keys.size() + 1); - if (!epee::string_tools::hex_to_pod(tx_key_str.substr(0, 64), additional_tx_keys.back())) + auto& key = first ? tx_key : additional_tx_keys.emplace_back(); + if (first) first = false; + + if (!tools::hex_to_type(tx_key_str.substr(0, 64), key)) { setStatusError(tr("Failed to parse tx key")); return false; } - tx_key_str = tx_key_str.substr(64); + tx_key_str.remove_prefix(64); } cryptonote::address_parse_info info; @@ -1877,7 +1806,7 @@ bool WalletImpl::checkTxKey(const std::string &txid_str, std::string tx_key_str, std::string WalletImpl::getTxProof(const std::string &txid_str, const std::string &address_str, const std::string &message) const { crypto::hash txid; - if (!epee::string_tools::hex_to_pod(txid_str, txid)) + if (!tools::hex_to_type(txid_str, txid)) { setStatusError(tr("Failed to parse txid")); return ""; @@ -1905,7 +1834,7 @@ std::string WalletImpl::getTxProof(const std::string &txid_str, const std::strin bool WalletImpl::checkTxProof(const std::string &txid_str, const std::string &address_str, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations) { crypto::hash txid; - if (!epee::string_tools::hex_to_pod(txid_str, txid)) + if (!tools::hex_to_type(txid_str, txid)) { setStatusError(tr("Failed to parse txid")); return false; @@ -1933,7 +1862,7 @@ bool WalletImpl::checkTxProof(const std::string &txid_str, const std::string &ad std::string WalletImpl::getSpendProof(const std::string &txid_str, const std::string &message) const { crypto::hash txid; - if(!epee::string_tools::hex_to_pod(txid_str, txid)) + if(!tools::hex_to_type(txid_str, txid)) { setStatusError(tr("Failed to parse txid")); return ""; @@ -1954,7 +1883,7 @@ std::string WalletImpl::getSpendProof(const std::string &txid_str, const std::st bool WalletImpl::checkSpendProof(const std::string &txid_str, const std::string &message, const std::string &signature, bool &good) const { good = false; crypto::hash txid; - if(!epee::string_tools::hex_to_pod(txid_str, txid)) + if(!tools::hex_to_type(txid_str, txid)) { setStatusError(tr("Failed to parse txid")); return false; @@ -2039,16 +1968,14 @@ std::string WalletImpl::signMultisigParticipant(const std::string &message) cons bool ready = false; if (!m_wallet->multisig(&ready) || !ready) { - m_status = Status_Error; - m_errorString = tr("The wallet must be in multisig ready state"); + setStatusError(tr("The wallet must be in multisig ready state")); return {}; } try { return m_wallet->sign_multisig_participant(message); } catch (const std::exception& e) { - m_status = Status_Error; - m_errorString = e.what(); + setStatusError(e.what()); } return {}; @@ -2060,18 +1987,13 @@ bool WalletImpl::verifyMessageWithPublicKey(const std::string &message, const st cryptonote::blobdata pkeyData; if(!epee::string_tools::parse_hexstr_to_binbuff(publicKey, pkeyData) || pkeyData.size() != sizeof(crypto::public_key)) - { - m_status = Status_Error; - m_errorString = tr("Given string is not a key"); - return false; - } + return setStatusError(tr("Given string is not a key")); try { crypto::public_key pkey = *reinterpret_cast(pkeyData.data()); return m_wallet->verify_with_public_key(message, pkey, signature); } catch (const std::exception& e) { - m_status = Status_Error; - m_errorString = e.what(); + return setStatusError(e.what()); } return false; @@ -2119,25 +2041,25 @@ bool WalletImpl::watchOnly() const void WalletImpl::clearStatus() const { std::lock_guard l{m_statusMutex}; - m_status = Status_Ok; - m_errorString.clear(); + m_status = {Status_Ok, ""}; } -void WalletImpl::setStatusError(const std::string& message) const +bool WalletImpl::setStatusError(std::string message) const { - setStatus(Status_Error, message); + return setStatus(Status_Error, std::move(message)); } -void WalletImpl::setStatusCritical(const std::string& message) const +bool WalletImpl::setStatusCritical(std::string message) const { - setStatus(Status_Critical, message); + return setStatus(Status_Critical, std::move(message)); } -void WalletImpl::setStatus(int status, const std::string& message) const +bool WalletImpl::setStatus(int status, std::string message) const { std::lock_guard l{m_statusMutex}; - m_status = status; - m_errorString = message; + m_status.first = status; + m_status.second = std::move(message); + return status == Status_Ok; } void WalletImpl::refreshThreadFunc() @@ -2161,7 +2083,8 @@ void WalletImpl::refreshThreadFunc() LOG_PRINT_L3(__FUNCTION__ << ": refresh lock acquired..."); LOG_PRINT_L3(__FUNCTION__ << ": m_refreshEnabled: " << m_refreshEnabled); - LOG_PRINT_L3(__FUNCTION__ << ": m_status: " << status()); + auto st = status(); + LOG_PRINT_L3(__FUNCTION__ << ": m_status: " << st.first << ": " << st.second); LOG_PRINT_L3(__FUNCTION__ << ": m_refreshShouldRescan: " << m_refreshShouldRescan); if (m_refreshEnabled) { LOG_PRINT_L3(__FUNCTION__ << ": refreshing..."); @@ -2176,31 +2099,33 @@ void WalletImpl::doRefresh() bool rescan = m_refreshShouldRescan.exchange(false); // synchronizing async and sync refresh calls std::lock_guard guard{m_refreshMutex2}; - do try { - LOG_PRINT_L3(__FUNCTION__ << ": doRefresh, rescan = "<light_wallet() || daemonSynced()) { - if(rescan) - m_wallet->rescan_blockchain(false); - m_wallet->refresh(trustedDaemon()); - if (!m_synchronized) { - m_synchronized = true; + do { + try { + LOG_PRINT_L3(__FUNCTION__ << ": doRefresh, rescan = "<light_wallet() || daemonSynced()) { + if(rescan) + m_wallet->rescan_blockchain(false); + m_wallet->refresh(trustedDaemon()); + if (!m_synchronized) { + m_synchronized = true; + } + // assuming if we have empty history, it wasn't initialized yet + // for further history changes client need to update history in + // "on_money_received" and "on_money_sent" callbacks + if (m_history->count() == 0) { + m_history->refresh(); + } + m_wallet->find_and_save_rings(false); + } else { + LOG_PRINT_L3(__FUNCTION__ << ": skipping refresh - daemon is not synced"); } - // assuming if we have empty history, it wasn't initialized yet - // for further history changes client need to update history in - // "on_money_received" and "on_money_sent" callbacks - if (m_history->count() == 0) { - m_history->refresh(); - } - m_wallet->find_and_save_rings(false); - } else { - LOG_PRINT_L3(__FUNCTION__ << ": skipping refresh - daemon is not synced"); + } catch (const std::exception &e) { + setStatusError(e.what()); + break; } - } catch (const std::exception &e) { - setStatusError(e.what()); - break; - }while(!rescan && (rescan=m_refreshShouldRescan.exchange(false))); // repeat if not rescanned and rescan was requested + } while (!rescan && (rescan=m_refreshShouldRescan.exchange(false))); // repeat if not rescanned and rescan was requested if (m_wallet2Callback->getListener()) { m_wallet2Callback->getListener()->refreshed(); @@ -2264,7 +2189,7 @@ void WalletImpl::pendingTxPostProcess(PendingTransactionImpl * pending) pending->m_pending_tx = exported_txs.ptx; } -bool WalletImpl::doInit(const string &daemon_address, uint64_t upper_transaction_size_limit, bool ssl) +bool WalletImpl::doInit(const std::string &daemon_address, uint64_t upper_transaction_size_limit, bool ssl) { if (!m_wallet->init(daemon_address, m_daemon_login, /*proxy=*/ "", upper_transaction_size_limit)) return false; @@ -2413,7 +2338,7 @@ bool WalletImpl::unblackballOutput(const std::string &amount, const std::string bool WalletImpl::getRing(const std::string &key_image, std::vector &ring) const { crypto::key_image raw_key_image; - if (!epee::string_tools::hex_to_pod(key_image, raw_key_image)) + if (!tools::hex_to_type(key_image, raw_key_image)) { setStatusError(tr("Failed to parse key image")); return false; @@ -2430,7 +2355,7 @@ bool WalletImpl::getRing(const std::string &key_image, std::vector &ri bool WalletImpl::getRings(const std::string &txid, std::vector>> &rings) const { crypto::hash raw_txid; - if (!epee::string_tools::hex_to_pod(txid, raw_txid)) + if (!tools::hex_to_type(txid, raw_txid)) { setStatusError(tr("Failed to parse txid")); return false; @@ -2444,7 +2369,7 @@ bool WalletImpl::getRings(const std::string &txid, std::vector &ring, bool relative) { crypto::key_image raw_key_image; - if (!epee::string_tools::hex_to_pod(key_image, raw_key_image)) + if (!tools::hex_to_type(key_image, raw_key_image)) { setStatusError(tr("Failed to parse key image")); return false; @@ -2499,7 +2424,7 @@ bool WalletImpl::isKeysFileLocked() PendingTransaction* WalletImpl::stakePending(const std::string& sn_key_str, const std::string& address_str, const std::string& amount_str, std::string& error_msg) { crypto::public_key sn_key; - if (!epee::string_tools::hex_to_pod(sn_key_str, sn_key)) + if (!tools::hex_to_type(sn_key_str, sn_key)) { error_msg = "Failed to parse service node pubkey"; LOG_ERROR(error_msg); @@ -2517,7 +2442,7 @@ PendingTransaction* WalletImpl::stakePending(const std::string& sn_key_str, cons uint64_t amount; if (!cryptonote::parse_amount(amount, amount_str)) { - stringstream str; + std::stringstream str; str << boost::format("Incorrect amount: %1%, expected a nubmber from %2% to %3%") % amount_str % print_money(1) % print_money(std::numeric_limits::max()); error_msg = str.str(); LOG_ERROR(error_msg); @@ -2548,18 +2473,9 @@ void WalletImpl::deviceShowAddress(uint32_t accountIndex, uint32_t addressIndex, { std::optional payment_id_param = std::nullopt; if (!paymentId.empty()) - { - crypto::hash8 payment_id; - bool res = tools::wallet2::parse_short_payment_id(paymentId, payment_id); - if (!res) - { - throw runtime_error("Invalid payment ID"); - } - payment_id_param = payment_id; - } + if (!tools::hex_to_type(paymentId, payment_id_param.emplace())) + throw std::runtime_error("Invalid payment ID"); m_wallet->device_show_address(accountIndex, addressIndex, payment_id_param); } } // namespace - -namespace Bitmonero = Monero; diff --git a/src/wallet/api/wallet.h b/src/wallet/api/wallet.h index 2202c261f..7f4a2f2d0 100644 --- a/src/wallet/api/wallet.h +++ b/src/wallet/api/wallet.h @@ -28,8 +28,7 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#ifndef WALLET_IMPL_H -#define WALLET_IMPL_H +#pragma once #include "wallet/api/wallet2_api.h" #include "wallet/wallet2.h" @@ -40,7 +39,7 @@ #include -namespace Monero { +namespace Wallet { class TransactionHistoryImpl; class PendingTransactionImpl; class UnsignedTransactionImpl; @@ -54,29 +53,20 @@ class WalletImpl : public Wallet public: WalletImpl(NetworkType nettype = MAINNET, uint64_t kdf_rounds = 1); ~WalletImpl(); - bool create(const std::string &path, const std::string &password, + bool create(const std::string_view path, const std::string &password, const std::string &language); - bool createWatchOnly(const std::string &path, const std::string &password, + bool createWatchOnly(std::string_view path, const std::string &password, const std::string &language) const override; - bool open(const std::string &path, const std::string &password); - bool recover(const std::string &path,const std::string &password, + bool open(std::string_view path, const std::string &password); + bool recover(std::string_view path,const std::string &password, const std::string &seed, const std::string &seed_offset = {}); - bool recoverFromKeysWithPassword(const std::string &path, + bool recoverFromKeysWithPassword(std::string_view path, const std::string &password, const std::string &language, const std::string &address_string, const std::string &viewkey_string, const std::string &spendkey_string = ""); - // following two methods are deprecated since they create passwordless wallets - // use the two equivalent methods above - bool recover(const std::string &path, const std::string &seed); - // deprecated: use recoverFromKeysWithPassword() instead - bool recoverFromKeys(const std::string &path, - const std::string &language, - const std::string &address_string, - const std::string &viewkey_string, - const std::string &spendkey_string = ""); - bool recoverFromDevice(const std::string &path, + bool recoverFromDevice(std::string_view path, const std::string &password, const std::string &device_name); Device getDeviceType() const override; @@ -84,10 +74,8 @@ public: std::string seed() const override; std::string getSeedLanguage() const override; void setSeedLanguage(const std::string &arg) override; - // void setListener(Listener *) {} - int status() const override; - std::string errorString() const override; - void statusWithErrorString(int& status, std::string& errorString) const override; + bool good() const override; + std::pair status() const override; bool setPassword(const std::string &password) override; bool setDevicePin(const std::string &password) override; bool setDevicePassphrase(const std::string &password) override; @@ -99,7 +87,7 @@ public: std::string publicSpendKey() const override; std::string publicMultisigSignerKey() const override; std::string path() const override; - bool store(const std::string &path) override; + bool store(std::string_view path) override; std::string filename() const override; std::string keysFilename() const override; bool init(const std::string &daemon_address, uint64_t upper_transaction_size_limit = 0, const std::string &daemon_username = "", const std::string &daemon_password = "", bool use_ssl = false, bool lightWallet = false) override; @@ -149,27 +137,26 @@ public: bool exportMultisigImages(std::string& images) override; size_t importMultisigImages(const std::vector& images) override; bool hasMultisigPartialKeyImages() const override; - PendingTransaction* restoreMultisigTransaction(const std::string& signData) override; + PendingTransaction* restoreMultisigTransaction(const std::string& signData) override; - PendingTransaction * createTransactionMultDest(const std::vector &dst_addr, const std::string &payment_id, + PendingTransaction* createTransactionMultDest(const std::vector &dst_addr, std::optional> amount, uint32_t priority = 0, uint32_t subaddr_account = 0, std::set subaddr_indices = {}) override; - PendingTransaction * createTransaction(const std::string &dst_addr, const std::string &payment_id, + PendingTransaction* createTransaction(const std::string &dst_addr, std::optional amount, uint32_t priority = 0, uint32_t subaddr_account = 0, std::set subaddr_indices = {}) override; - virtual PendingTransaction * createSweepUnmixableTransaction() override; - bool submitTransaction(const std::string &fileName) override; - virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) override; - bool exportKeyImages(const std::string &filename) override; - bool importKeyImages(const std::string &filename) override; + PendingTransaction* createSweepUnmixableTransaction() override; + bool submitTransaction(std::string_view filename) override; + UnsignedTransaction* loadUnsignedTx(std::string_view unsigned_filename) override; + bool exportKeyImages(std::string_view filename) override; + bool importKeyImages(std::string_view filename) override; void disposeTransaction(PendingTransaction * t) override; - // TODO(loki): Implement - // uint64_t estimateTransactionFee(const std::vector> &destinations, PendingTransaction::Priority priority) const override; + uint64_t estimateTransactionFee(uint32_t priority, uint32_t recipients = 1) const override; TransactionHistory * history() override; AddressBook * addressBook() override; Subaddress * subaddress() override; @@ -180,7 +167,7 @@ public: bool setUserNote(const std::string &txid, const std::string ¬e) override; std::string getUserNote(const std::string &txid) const override; std::string getTxKey(const std::string &txid) const override; - bool checkTxKey(const std::string &txid, std::string tx_key, const std::string &address, uint64_t &received, bool &in_pool, uint64_t &confirmations) override; + bool checkTxKey(const std::string &txid, std::string_view tx_key, const std::string &address, uint64_t &received, bool &in_pool, uint64_t &confirmations) override; std::string getTxProof(const std::string &txid, const std::string &address, const std::string &message) const override; bool checkTxProof(const std::string &txid, const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations) override; std::string getSpendProof(const std::string &txid, const std::string &message) const override; @@ -214,9 +201,9 @@ public: private: void clearStatus() const; - void setStatusError(const std::string& message) const; - void setStatusCritical(const std::string& message) const; - void setStatus(int status, const std::string& message) const; + bool setStatusError(std::string message) const; + bool setStatusCritical(std::string message) const; + bool setStatus(int status, std::string message) const; void refreshThreadFunc(); void doRefresh(); bool daemonSynced() const; @@ -236,8 +223,7 @@ private: std::unique_ptr m_wallet; mutable std::mutex m_statusMutex; - mutable int m_status; - mutable std::string m_errorString; + mutable std::pair m_status; std::string m_password; std::unique_ptr m_history; std::unique_ptr m_wallet2Callback; @@ -273,8 +259,3 @@ private: } // namespace - -namespace Bitmonero = Monero; - -#endif - diff --git a/src/wallet/api/wallet2_api.h b/src/wallet/api/wallet2_api.h index 1664555a3..4f7568c76 100644 --- a/src/wallet/api/wallet2_api.h +++ b/src/wallet/api/wallet2_api.h @@ -32,6 +32,7 @@ #include +#include #include #include #include @@ -41,7 +42,7 @@ #include // Public interface for libwallet library -namespace Monero { +namespace Wallet { enum NetworkType : uint8_t { MAINNET = 0, @@ -66,10 +67,13 @@ struct PendingTransaction }; virtual ~PendingTransaction() = 0; - virtual int status() const = 0; - virtual std::string errorString() const = 0; - // commit transaction or save to file if filename is provided. - virtual bool commit(const std::string &filename = "", bool overwrite = false, bool blink = false) = 0; + /// returns true if the status is currently set to Status_Ok, false otherwise. + /// For more details, call status() instead. + virtual bool good() const = 0; + /// returns error status code (Status_Ok, Status_Error, or Status_Critical) and error string. + virtual std::pair status() const = 0; + // commit transaction or save to file if filename (utf-8) is provided. + virtual bool commit(std::string_view filename = "", bool overwrite = false, bool blink = false) = 0; virtual uint64_t amount() const = 0; virtual uint64_t dust() const = 0; virtual uint64_t fee() const = 0; @@ -119,8 +123,11 @@ struct UnsignedTransaction }; virtual ~UnsignedTransaction() = 0; - virtual int status() const = 0; - virtual std::string errorString() const = 0; + /// returns true if the status is currently set to Status_Ok, false otherwise. + /// For more details, call status() instead. + virtual bool good() const = 0; + /// returns error status code (Status_Ok, Status_Error, or Status_Critical) and error string. + virtual std::pair status() const = 0; virtual std::vector amount() const = 0; virtual std::vector fee() const = 0; virtual std::vector mixin() const = 0; @@ -136,10 +143,10 @@ struct UnsignedTransaction virtual uint64_t txCount() const = 0; /*! * @brief sign - Sign txs and saves to file - * @param signedFileName + * @param signedFileName - utf8 filename to write to * return - true on success */ - virtual bool sign(const std::string &signedFileName) = 0; + virtual bool sign(std::string_view signedFileName) = 0; }; /** @@ -153,7 +160,7 @@ struct TransactionInfo }; struct Transfer { - Transfer(uint64_t _amount, const std::string &address); + Transfer(uint64_t _amount, std::string address); const uint64_t amount; const std::string address; }; @@ -187,7 +194,7 @@ struct TransactionHistory virtual ~TransactionHistory() = 0; virtual int count() const = 0; virtual TransactionInfo * transaction(int index) const = 0; - virtual TransactionInfo * transaction(const std::string &id) const = 0; + virtual TransactionInfo * transaction(std::string_view id) const = 0; virtual std::vector getAll() const = 0; virtual void refresh() = 0; }; @@ -197,23 +204,20 @@ struct TransactionHistory */ struct AddressBookRow { public: - AddressBookRow(std::size_t _rowId, const std::string &_address, const std::string &_paymentId, const std::string &_description): + AddressBookRow(std::size_t _rowId, std::string _address, std::string _description): m_rowId(_rowId), - m_address(_address), - m_paymentId(_paymentId), - m_description(_description) {} + m_address(std::move(_address)), + m_description(std::move(_description)) {} private: std::size_t m_rowId; std::string m_address; - std::string m_paymentId; std::string m_description; public: std::string extra; - std::string getAddress() const {return m_address;} - std::string getDescription() const {return m_description;} - std::string getPaymentId() const {return m_paymentId;} - std::size_t getRowId() const {return m_rowId;} + const std::string& getAddress() const { return m_address; } + const std::string& getDescription() const { return m_description; } + std::size_t getRowId() const { return m_rowId; } }; /** @@ -225,25 +229,23 @@ struct AddressBook enum ErrorCode { Status_Ok, General_Error, - Invalid_Address, - Invalid_Payment_Id + Invalid_Address }; virtual ~AddressBook() = 0; virtual std::vector getAll() const = 0; - virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0; + virtual bool addRow(const std::string &dst_addr, const std::string &description) = 0; virtual bool deleteRow(std::size_t rowId) = 0; virtual void refresh() = 0; virtual std::string errorString() const = 0; virtual int errorCode() const = 0; - virtual int lookupPaymentID(const std::string &payment_id) const = 0; }; struct SubaddressRow { public: - SubaddressRow(std::size_t _rowId, const std::string &_address, const std::string &_label): + SubaddressRow(std::size_t _rowId, std::string _address, std::string _label): m_rowId(_rowId), - m_address(_address), - m_label(_label) {} + m_address(std::move(_address)), + m_label(std::move(_label)) {} private: std::size_t m_rowId; @@ -251,8 +253,8 @@ private: std::string m_label; public: std::string extra; - std::string getAddress() const {return m_address;} - std::string getLabel() const {return m_label;} + const std::string& getAddress() const {return m_address;} + const std::string& getLabel() const {return m_label;} std::size_t getRowId() const {return m_rowId;} }; @@ -267,12 +269,12 @@ struct Subaddress struct SubaddressAccountRow { public: - SubaddressAccountRow(std::size_t _rowId, const std::string &_address, const std::string &_label, const std::string &_balance, const std::string &_unlockedBalance): + SubaddressAccountRow(std::size_t _rowId, std::string _address, std::string _label, std::string _balance, std::string _unlockedBalance): m_rowId(_rowId), - m_address(_address), - m_label(_label), - m_balance(_balance), - m_unlockedBalance(_unlockedBalance) {} + m_address(std::move(_address)), + m_label(std::move(_label)), + m_balance(std::move(_balance)), + m_unlockedBalance(std::move(_unlockedBalance)) {} private: std::size_t m_rowId; @@ -282,10 +284,10 @@ private: std::string m_unlockedBalance; public: std::string extra; - std::string getAddress() const {return m_address;} - std::string getLabel() const {return m_label;} - std::string getBalance() const {return m_balance;} - std::string getUnlockedBalance() const {return m_unlockedBalance;} + const std::string& getAddress() const {return m_address;} + const std::string& getLabel() const {return m_label;} + const std::string& getBalance() const {return m_balance;} + const std::string& getUnlockedBalance() const {return m_unlockedBalance;} std::size_t getRowId() const {return m_rowId;} }; @@ -427,12 +429,11 @@ struct Wallet virtual std::string seed() const = 0; virtual std::string getSeedLanguage() const = 0; virtual void setSeedLanguage(const std::string &arg) = 0; - //! returns wallet status (Status_Ok | Status_Error) - virtual int status() const = 0; //deprecated: use safe alternative statusWithErrorString - //! in case error status, returns error string - virtual std::string errorString() const = 0; //deprecated: use safe alternative statusWithErrorString - //! returns both error and error string atomically. suggested to use in instead of status() and errorString() - virtual void statusWithErrorString(int& status, std::string& errorString) const = 0; + /// returns true if the wallet status is currently set to Status_Ok, false otherwise. + /// For more details, call status() instead. + virtual bool good() const = 0; + /// returns error status code (Status_Ok, Status_Error, or Status_Critical) and error string. + virtual std::pair status() const = 0; virtual bool setPassword(const std::string &password) = 0; virtual bool setDevicePin(const std::string &pin) { (void)pin; return false; }; virtual bool setDevicePassphrase(const std::string &passphrase) { (void)passphrase; return false; }; @@ -494,7 +495,7 @@ struct Wallet * to store to the same file - just pass empty string; * \return */ - virtual bool store(const std::string &path) = 0; + virtual bool store(std::string_view path) = 0; /*! * \brief filename - returns wallet filename * \return @@ -521,12 +522,12 @@ struct Wallet /*! * \brief createWatchOnly - Creates a watch only wallet - * \param path - where to store the wallet + * \param path - where to store the wallet (utf8) * \param password * \param language * \return - true if created successfully */ - virtual bool createWatchOnly(const std::string &path, const std::string &password, const std::string &language) const = 0; + virtual bool createWatchOnly(std::string_view path, const std::string& password, const std::string& language) const = 0; /*! * \brief setRefreshFromBlockHeight - start refresh from block height on recover @@ -618,14 +619,14 @@ struct Wallet /** * @brief daemonBlockChainHeight - returns daemon blockchain height * @return 0 - in case error communicating with the daemon. - * status() will return Status_Error and errorString() will return verbose error description + * status() will return Status_Error and a return verbose error description */ virtual uint64_t daemonBlockChainHeight() const = 0; /** * @brief daemonBlockChainTargetHeight - returns daemon blockchain target height * @return 0 - in case error communicating with the daemon. - * status() will return Status_Error and errorString() will return verbose error description + * status() will return Status_Error and a verbose error description */ virtual uint64_t daemonBlockChainTargetHeight() const = 0; @@ -643,24 +644,12 @@ struct Wallet /// Check if the string represents a valid public key (regardless of whether the service node actually exists or not) static bool serviceNodePubkeyValid(const std::string &str); static bool addressValid(const std::string &str, NetworkType nettype); - static bool addressValid(const std::string &str, bool testnet) // deprecated - { - return addressValid(str, testnet ? TESTNET : MAINNET); - } static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, NetworkType nettype, std::string &error); - static bool keyValid(const std::string &secret_key_string, const std::string &address_string, bool isViewKey, bool testnet, std::string &error) // deprecated - { - return keyValid(secret_key_string, address_string, isViewKey, testnet ? TESTNET : MAINNET, error); - } static std::string paymentIdFromAddress(const std::string &str, NetworkType nettype); - static std::string paymentIdFromAddress(const std::string &str, bool testnet) // deprecated - { - return paymentIdFromAddress(str, testnet ? TESTNET : MAINNET); - } static uint64_t maximumAllowedAmount(); // Easylogger wrapper - static void init(const char *argv0, const char *default_log_base_name) { init(argv0, default_log_base_name, "", true); } - static void init(const char *argv0, const char *default_log_base_name, const std::string &log_path, bool console); + static void init(const char* argv0, const char* default_log_base_name) { init(argv0, default_log_base_name, "", true); } + static void init(const char* argv0, const char* default_log_base_name, const std::string& log_path, bool console); static void debug(const std::string &category, const std::string &str); static void info(const std::string &category, const std::string &str); static void warning(const std::string &category, const std::string &str); @@ -798,9 +787,8 @@ struct Wallet virtual PendingTransaction* restoreMultisigTransaction(const std::string& signData) = 0; /*! - * \brief createTransactionMultDest creates transaction with multiple destinations. if dst_addr is an integrated address, payment_id is ignored + * \brief createTransactionMultDest creates transaction with multiple destinations * \param dst_addr vector of destination address as string - * \param payment_id optional payment_id, can be empty string * \param amount vector of amounts * \param subaddr_account subaddress account from which the input funds are taken * \param subaddr_indices set of subaddress indices to use for transfer or sweeping. if set empty, all are chosen when sweeping, and one or more are automatically chosen when transferring. after execution, returns the set of actually used indices @@ -809,16 +797,15 @@ struct Wallet * after object returned */ - virtual PendingTransaction * createTransactionMultDest(const std::vector &dst_addr, const std::string &payment_id, + virtual PendingTransaction * createTransactionMultDest(const std::vector &dst_addr, std::optional> amount, uint32_t priority = 0, uint32_t subaddr_account = 0, std::set subaddr_indices = {}) = 0; /*! - * \brief createTransaction creates transaction. if dst_addr is an integrated address, payment_id is ignored + * \brief createTransaction creates transaction * \param dst_addr destination address as string - * \param payment_id optional payment_id, can be empty string * \param amount amount * \param subaddr_account subaddress account from which the input funds are taken * \param subaddr_indices set of subaddress indices to use for transfer or sweeping. if set empty, all are chosen when sweeping, and one or more are automatically chosen when transferring. after execution, returns the set of actually used indices @@ -828,7 +815,6 @@ struct Wallet */ virtual PendingTransaction *createTransaction(const std::string &dst_addr, - const std::string &payment_id, std::optional amount, uint32_t priority = 0, uint32_t subaddr_account = 0, @@ -843,17 +829,18 @@ struct Wallet virtual PendingTransaction * createSweepUnmixableTransaction() = 0; /*! - * \brief loadUnsignedTx - creates transaction from unsigned tx file + * \brief loadUnsignedTx - creates transaction from unsigned tx file (utf8 filename) * \return - UnsignedTransaction object. caller is responsible to check UnsignedTransaction::status() * after object returned */ - virtual UnsignedTransaction * loadUnsignedTx(const std::string &unsigned_filename) = 0; + virtual UnsignedTransaction * loadUnsignedTx(std::string_view unsigned_filename) = 0; /*! - * \brief submitTransaction - submits transaction in signed tx file + * \brief submitTransaction - submits transaction in signed tx file (utf8 filename) + * \param filename - utf8 filename to read from * \return - true on success */ - virtual bool submitTransaction(const std::string &fileName) = 0; + virtual bool submitTransaction(std::string_view filename) = 0; /*! @@ -864,28 +851,25 @@ struct Wallet /*! * \brief Estimates transaction fee. - * \param destinations Vector consisting of pairs. - * \return Estimated fee. + * \param priority - the tx priority. 1 = low priority, 5 = blink. + * \param recipients - number of recipients *not* counting the return address for change. Defaults to 1. + * \return Estimated fee in atomic units. */ - // TODO(loki): Implement -#if 0 - virtual uint64_t estimateTransactionFee(const std::vector> &destinations, - uint32_t priority) const = 0; -#endif + virtual uint64_t estimateTransactionFee(uint32_t priority, uint32_t recipients = 1) const = 0; /*! * \brief exportKeyImages - exports key images to file - * \param filename + * \param filename - utf8 filename to write to * \return - true on success */ - virtual bool exportKeyImages(const std::string &filename) = 0; + virtual bool exportKeyImages(std::string_view filename) = 0; /*! * \brief importKeyImages - imports key images from file - * \param filename + * \param filename - utf8 filename to read from * \return - true on success */ - virtual bool importKeyImages(const std::string &filename) = 0; + virtual bool importKeyImages(std::string_view filename) = 0; virtual TransactionHistory * history() = 0; @@ -921,7 +905,7 @@ struct Wallet */ virtual std::string getUserNote(const std::string &txid) const = 0; virtual std::string getTxKey(const std::string &txid) const = 0; - virtual bool checkTxKey(const std::string &txid, std::string tx_key, const std::string &address, uint64_t &received, bool &in_pool, uint64_t &confirmations) = 0; + virtual bool checkTxKey(const std::string &txid, std::string_view tx_key, const std::string &address, uint64_t &received, bool &in_pool, uint64_t &confirmations) = 0; virtual std::string getTxProof(const std::string &txid, const std::string &address, const std::string &message) const = 0; virtual bool checkTxProof(const std::string &txid, const std::string &address, const std::string &message, const std::string &signature, bool &good, uint64_t &received, bool &in_pool, uint64_t &confirmations) = 0; virtual std::string getSpendProof(const std::string &txid, const std::string &message) const = 0; @@ -1036,18 +1020,14 @@ struct WalletManagerBase /*! * \brief Creates new wallet - * \param path Name of wallet file + * \param path Name of wallet file (utf-8) * \param password Password of wallet file * \param language Language to be used to generate electrum seed mnemonic * \param nettype Network type * \param kdf_rounds Number of rounds for key derivation function * \return Wallet instance (Wallet::status() needs to be called to check if created successfully) */ - virtual Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, NetworkType nettype, uint64_t kdf_rounds = 1) = 0; - Wallet * createWallet(const std::string &path, const std::string &password, const std::string &language, bool testnet = false) // deprecated - { - return createWallet(path, password, language, testnet ? TESTNET : MAINNET); - } + virtual Wallet* createWallet(std::string_view path, const std::string& password, const std::string& language, NetworkType nettype, uint64_t kdf_rounds = 1) = 0; /*! * \brief Opens existing wallet @@ -1058,15 +1038,11 @@ struct WalletManagerBase * \param listener Wallet listener to set to the wallet after creation * \return Wallet instance (Wallet::status() needs to be called to check if opened successfully) */ - virtual Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) = 0; - Wallet * openWallet(const std::string &path, const std::string &password, bool testnet = false) // deprecated - { - return openWallet(path, password, testnet ? TESTNET : MAINNET); - } + virtual Wallet* openWallet(std::string_view path, const std::string& password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) = 0; /*! * \brief recovers existing wallet using mnemonic (electrum seed) - * \param path Name of wallet file to be created + * \param path Name of wallet file to be created (utf-8) * \param password Password of wallet file * \param mnemonic mnemonic (25 words electrum seed) * \param nettype Network type @@ -1075,33 +1051,13 @@ struct WalletManagerBase * \param seed_offset Seed offset passphrase (optional) * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) */ - virtual Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic, + virtual Wallet* recoveryWallet(std::string_view path, const std::string& password, const std::string& mnemonic, NetworkType nettype = MAINNET, uint64_t restoreHeight = 0, uint64_t kdf_rounds = 1, const std::string &seed_offset = {}) = 0; - Wallet * recoveryWallet(const std::string &path, const std::string &password, const std::string &mnemonic, - bool testnet = false, uint64_t restoreHeight = 0) // deprecated - { - return recoveryWallet(path, password, mnemonic, testnet ? TESTNET : MAINNET, restoreHeight); - } - - /*! - * \deprecated this method creates a wallet WITHOUT a passphrase, use the alternate recoverWallet() method - * \brief recovers existing wallet using mnemonic (electrum seed) - * \param path Name of wallet file to be created - * \param mnemonic mnemonic (25 words electrum seed) - * \param nettype Network type - * \param restoreHeight restore from start height - * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) - */ - virtual Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight = 0) = 0; - Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, bool testnet = false, uint64_t restoreHeight = 0) // deprecated - { - return recoveryWallet(path, mnemonic, testnet ? TESTNET : MAINNET, restoreHeight); - } /*! * \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted - * \param path Name of wallet file to be created + * \param path Name of wallet file to be created (utf-8) * \param password Password of wallet file * \param language language * \param nettype Network type @@ -1112,60 +1068,20 @@ struct WalletManagerBase * \param kdf_rounds Number of rounds for key derivation function * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) */ - virtual Wallet * createWalletFromKeys(const std::string &path, - const std::string &password, - const std::string &language, - NetworkType nettype, - uint64_t restoreHeight, - const std::string &addressString, - const std::string &viewKeyString, - const std::string &spendKeyString = "", - uint64_t kdf_rounds = 1) = 0; - Wallet * createWalletFromKeys(const std::string &path, - const std::string &password, - const std::string &language, - bool testnet, - uint64_t restoreHeight, - const std::string &addressString, - const std::string &viewKeyString, - const std::string &spendKeyString = "") // deprecated - { - return createWalletFromKeys(path, password, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString); - } - - /*! - * \deprecated this method creates a wallet WITHOUT a passphrase, use createWalletFromKeys(..., password, ...) instead - * \brief recovers existing wallet using keys. Creates a view only wallet if spend key is omitted - * \param path Name of wallet file to be created - * \param language language - * \param nettype Network type - * \param restoreHeight restore from start height - * \param addressString public address - * \param viewKeyString view key - * \param spendKeyString spend key (optional) - * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) - */ - virtual Wallet * createWalletFromKeys(const std::string &path, - const std::string &language, - NetworkType nettype, - uint64_t restoreHeight, - const std::string &addressString, - const std::string &viewKeyString, - const std::string &spendKeyString = "") = 0; - Wallet * createWalletFromKeys(const std::string &path, - const std::string &language, - bool testnet, - uint64_t restoreHeight, - const std::string &addressString, - const std::string &viewKeyString, - const std::string &spendKeyString = "") // deprecated - { - return createWalletFromKeys(path, language, testnet ? TESTNET : MAINNET, restoreHeight, addressString, viewKeyString, spendKeyString); - } + virtual Wallet* createWalletFromKeys( + std::string_view path, + const std::string& password, + const std::string& language, + NetworkType nettype, + uint64_t restoreHeight, + const std::string& addressString, + const std::string& viewKeyString, + const std::string& spendKeyString = "", + uint64_t kdf_rounds = 1) = 0; /*! * \brief creates wallet using hardware device. - * \param path Name of wallet file to be created + * \param path Name of wallet file to be created (utf-8) * \param password Password of wallet file * \param nettype Network type * \param deviceName Device name @@ -1175,21 +1091,22 @@ struct WalletManagerBase * \param listener Wallet listener to set to the wallet after creation * \return Wallet instance (Wallet::status() needs to be called to check if recovered successfully) */ - virtual Wallet * createWalletFromDevice(const std::string &path, - const std::string &password, - NetworkType nettype, - const std::string &deviceName, - uint64_t restoreHeight = 0, - const std::string &subaddressLookahead = "", - uint64_t kdf_rounds = 1, - WalletListener * listener = nullptr) = 0; + virtual Wallet* createWalletFromDevice( + std::string_view path, + const std::string& password, + NetworkType nettype, + const std::string& deviceName, + uint64_t restoreHeight = 0, + const std::string& subaddressLookahead = "", + uint64_t kdf_rounds = 1, + WalletListener* listener = nullptr) = 0; /*! * \brief Closes wallet. In case operation succeeded, wallet object deleted. in case operation failed, wallet object not deleted * \param wallet previously opened / created wallet instance * \return None */ - virtual bool closeWallet(Wallet *wallet, bool store = true) = 0; + virtual bool closeWallet(Wallet* wallet, bool store = true) = 0; /* * ! checks if wallet with the given name already exists @@ -1197,14 +1114,14 @@ struct WalletManagerBase /*! * @brief TODO: delme walletExists - check if the given filename is the wallet - * @param path - filename + * @param path - filename (utf-8) * @return - true if wallet exists */ - virtual bool walletExists(const std::string &path) = 0; + virtual bool walletExists(std::string_view path) = 0; /*! * @brief verifyWalletPassword - check if the given filename is the wallet - * @param keys_file_name - location of keys file + * @param keys_file_name - location of keys file (utf-8) * @param password - password to verify * @param no_spend_key - verify only view keys? * @param kdf_rounds - number of rounds for key derivation function @@ -1214,26 +1131,26 @@ struct WalletManagerBase * This function will fail when the wallet keys file is opened because the wallet program locks the keys file. * In this case, Wallet::unlockKeysFile() and Wallet::lockKeysFile() need to be called before and after the call to this function, respectively. */ - virtual bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const = 0; + virtual bool verifyWalletPassword(std::string_view keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const = 0; /*! * \brief determine the key storage for the specified wallet file * \param device_type (OUT) wallet backend as enumerated in Wallet::Device - * \param keys_file_name Keys file to verify password for + * \param keys_file_name Keys file to verify password for (utf-8) * \param password Password to verify * \return true if password correct, else false * * for verification only - determines key storage hardware * */ - virtual bool queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const = 0; + virtual bool queryWalletDevice(Wallet::Device& device_type, std::string_view keys_file_name, const std::string& password, uint64_t kdf_rounds = 1) const = 0; /*! * \brief findWallets - searches for the wallet files by given path name recursively - * \param path - starting point to search + * \param path - starting point to search (utf-8) * \return - list of strings with found wallets (absolute paths); */ - virtual std::vector findWallets(const std::string &path) = 0; + virtual std::vector findWallets(std::string_view path) = 0; //! returns verbose error string regarding last error; virtual std::string errorString() const = 0; @@ -1242,7 +1159,7 @@ struct WalletManagerBase virtual void setDaemonAddress(std::string address) = 0; //! returns whether the daemon can be reached, and its version number - virtual bool connected(uint32_t *version = NULL) = 0; + virtual bool connected(uint32_t *version = nullptr) = 0; //! returns current blockchain height virtual uint64_t blockchainHeight() = 0; @@ -1263,20 +1180,13 @@ struct WalletManagerBase virtual bool isMining() = 0; //! starts mining with the set number of threads - virtual bool startMining(const std::string &address, uint32_t threads = 1) = 0; + virtual bool startMining(const std::string& address, uint32_t threads = 1) = 0; //! stops mining virtual bool stopMining() = 0; //! resolves an OpenAlias address to a monero address virtual std::string resolveOpenAlias(const std::string &address, bool &dnssec_valid) const = 0; - - //! checks for an update and returns version, hash and url - static std::tuple checkUpdates( - const std::string &software, - std::string subdir, - const char *buildtag = nullptr, - const char *current_version = nullptr); }; struct WalletManagerFactory @@ -1293,13 +1203,9 @@ struct WalletManagerFactory LogLevel_Max = LogLevel_4 }; - static WalletManagerBase * getWalletManager(); + static WalletManagerBase* getWalletManager(); static void setLogLevel(int level); static void setLogCategories(const std::string &categories); }; - -} - -namespace Bitmonero = Monero; - +} // namespace Wallet diff --git a/src/wallet/api/wallet_manager.cpp b/src/wallet/api/wallet_manager.cpp index c57f3fb38..60f4578f1 100644 --- a/src/wallet/api/wallet_manager.cpp +++ b/src/wallet/api/wallet_manager.cpp @@ -38,24 +38,24 @@ #include "common/dns_utils.h" #include "common/util.h" #include "version.h" -#include +#include "common/fs.h" #undef LOKI_DEFAULT_LOG_CATEGORY #define LOKI_DEFAULT_LOG_CATEGORY "WalletAPI" -namespace Monero { +namespace Wallet { -Wallet *WalletManagerImpl::createWallet(const std::string &path, const std::string &password, +Wallet* WalletManagerImpl::createWallet(std::string_view path, const std::string &password, const std::string &language, NetworkType nettype, uint64_t kdf_rounds) { - WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds); + WalletImpl* wallet = new WalletImpl(nettype, kdf_rounds); wallet->create(path, password, language); return wallet; } -Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds, WalletListener * listener) +Wallet* WalletManagerImpl::openWallet(std::string_view path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds, WalletListener * listener) { - WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds); + WalletImpl* wallet = new WalletImpl(nettype, kdf_rounds); wallet->setListener(listener); if (listener){ listener->onSetWallet(wallet); @@ -67,24 +67,7 @@ Wallet *WalletManagerImpl::openWallet(const std::string &path, const std::string return wallet; } -Wallet *WalletManagerImpl::recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight) -{ - return recoveryWallet(path, "", mnemonic, nettype, restoreHeight); -} - -Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path, - const std::string &language, - NetworkType nettype, - uint64_t restoreHeight, - const std::string &addressString, - const std::string &viewKeyString, - const std::string &spendKeyString) -{ - return createWalletFromKeys(path, "", language, nettype, restoreHeight, - addressString, viewKeyString, spendKeyString); -} - -Wallet *WalletManagerImpl::recoveryWallet(const std::string &path, +Wallet* WalletManagerImpl::recoveryWallet(std::string_view path, const std::string &password, const std::string &mnemonic, NetworkType nettype, @@ -92,7 +75,7 @@ Wallet *WalletManagerImpl::recoveryWallet(const std::string &path, uint64_t kdf_rounds, const std::string &seed_offset/* = {}*/) { - WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds); + WalletImpl* wallet = new WalletImpl(nettype, kdf_rounds); if(restoreHeight > 0){ wallet->setRefreshFromBlockHeight(restoreHeight); } @@ -100,7 +83,7 @@ Wallet *WalletManagerImpl::recoveryWallet(const std::string &path, return wallet; } -Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path, +Wallet* WalletManagerImpl::createWalletFromKeys(std::string_view path, const std::string &password, const std::string &language, NetworkType nettype, @@ -110,7 +93,7 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path, const std::string &spendKeyString, uint64_t kdf_rounds) { - WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds); + WalletImpl* wallet = new WalletImpl(nettype, kdf_rounds); if(restoreHeight > 0){ wallet->setRefreshFromBlockHeight(restoreHeight); } @@ -118,7 +101,7 @@ Wallet *WalletManagerImpl::createWalletFromKeys(const std::string &path, return wallet; } -Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path, +Wallet* WalletManagerImpl::createWalletFromDevice(std::string_view path, const std::string &password, NetworkType nettype, const std::string &deviceName, @@ -127,7 +110,7 @@ Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path, uint64_t kdf_rounds, WalletListener * listener) { - WalletImpl * wallet = new WalletImpl(nettype, kdf_rounds); + WalletImpl* wallet = new WalletImpl(nettype, kdf_rounds); wallet->setListener(listener); if (listener){ listener->onSetWallet(wallet); @@ -147,67 +130,66 @@ Wallet *WalletManagerImpl::createWalletFromDevice(const std::string &path, return wallet; } -bool WalletManagerImpl::closeWallet(Wallet *wallet, bool store) +bool WalletManagerImpl::closeWallet(Wallet* wallet, bool store) { - WalletImpl * wallet_ = dynamic_cast(wallet); + WalletImpl* wallet_ = dynamic_cast(wallet); if (!wallet_) return false; bool result = wallet_->close(store); if (!result) { - m_errorString = wallet_->errorString(); + m_errorString = wallet_->status().second; } else { delete wallet_; } return result; } -bool WalletManagerImpl::walletExists(const std::string &path) +bool WalletManagerImpl::walletExists(std::string_view path) { bool keys_file_exists; bool wallet_file_exists; - tools::wallet2::wallet_exists(path, keys_file_exists, wallet_file_exists); + tools::wallet2::wallet_exists(fs::u8path(path), keys_file_exists, wallet_file_exists); if(keys_file_exists){ return true; } return false; } -bool WalletManagerImpl::verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds) const +bool WalletManagerImpl::verifyWalletPassword(std::string_view keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds) const { - return tools::wallet2::verify_password(keys_file_name, password, no_spend_key, hw::get_device("default"), kdf_rounds); + return tools::wallet2::verify_password(fs::u8path(keys_file_name), password, no_spend_key, hw::get_device("default"), kdf_rounds); } -bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds) const +bool WalletManagerImpl::queryWalletDevice(Wallet::Device& device_type, std::string_view keys_file_name, const std::string &password, uint64_t kdf_rounds) const { hw::device::device_type type; - bool r = tools::wallet2::query_device(type, keys_file_name, password, kdf_rounds); + bool r = tools::wallet2::query_device(type, fs::u8path(keys_file_name), password, kdf_rounds); device_type = static_cast(type); return r; } -std::vector WalletManagerImpl::findWallets(const std::string &path) +std::vector WalletManagerImpl::findWallets(std::string_view path_) { + auto path = fs::u8path(path_); std::vector result; - boost::filesystem::path work_dir(path); // return empty result if path doesn't exist - if(!boost::filesystem::is_directory(path)){ + if (!fs::is_directory(path)){ return result; } - boost::filesystem::recursive_directory_iterator end_itr; // Default ctor yields past-the-end - for (boost::filesystem::recursive_directory_iterator itr(path); itr != end_itr; ++itr) { + for (auto& p : fs::recursive_directory_iterator{path}) { // Skip if not a file - if (!boost::filesystem::is_regular_file(itr->status())) + if (!p.is_regular_file()) continue; - std::string filename = itr->path().filename().string(); + auto filename = p.path(); LOG_PRINT_L3("Checking filename: " << filename); - if (tools::ends_with(filename, ".keys")) { + if (filename.extension() == ".keys") { // if keys file found, checking if there's wallet file itself - filename.erase(filename.size() - 5); - if (boost::filesystem::exists(filename)) { + filename.replace_extension(); + if (fs::exists(filename)) { LOG_PRINT_L3("Found wallet: " << filename); - result.push_back(std::move(filename)); + result.push_back(filename.u8string()); } } } @@ -341,5 +323,3 @@ void WalletManagerFactory::setLogCategories(const std::string &categories) } - -namespace Bitmonero = Monero; diff --git a/src/wallet/api/wallet_manager.h b/src/wallet/api/wallet_manager.h index 4bcb8c219..fb8cb75d1 100644 --- a/src/wallet/api/wallet_manager.h +++ b/src/wallet/api/wallet_manager.h @@ -33,22 +33,22 @@ #include "rpc/http_client.h" #include -namespace Monero { +namespace Wallet { class WalletManagerImpl : public WalletManagerBase { public: - Wallet * createWallet(const std::string &path, const std::string &password, + Wallet* createWallet(std::string_view path, const std::string &password, const std::string &language, NetworkType nettype, uint64_t kdf_rounds = 1) override; - Wallet * openWallet(const std::string &path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) override; - virtual Wallet * recoveryWallet(const std::string &path, + Wallet* openWallet(std::string_view path, const std::string &password, NetworkType nettype, uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) override; + Wallet * recoveryWallet(std::string_view path, const std::string &password, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight, uint64_t kdf_rounds = 1, const std::string &seed_offset = {}) override; - virtual Wallet * createWalletFromKeys(const std::string &path, + Wallet * createWalletFromKeys(std::string_view path, const std::string &password, const std::string &language, NetworkType nettype, @@ -57,17 +57,7 @@ public: const std::string &viewKeyString, const std::string &spendKeyString = "", uint64_t kdf_rounds = 1) override; - // next two methods are deprecated - use the above version which allow setting of a password - virtual Wallet * recoveryWallet(const std::string &path, const std::string &mnemonic, NetworkType nettype, uint64_t restoreHeight) override; - // deprecated: use createWalletFromKeys(..., password, ...) instead - virtual Wallet * createWalletFromKeys(const std::string &path, - const std::string &language, - NetworkType nettype, - uint64_t restoreHeight, - const std::string &addressString, - const std::string &viewKeyString, - const std::string &spendKeyString = "") override; - virtual Wallet * createWalletFromDevice(const std::string &path, + Wallet * createWalletFromDevice(std::string_view path, const std::string &password, NetworkType nettype, const std::string &deviceName, @@ -75,11 +65,11 @@ public: const std::string &subaddressLookahead = "", uint64_t kdf_rounds = 1, WalletListener * listener = nullptr) override; - virtual bool closeWallet(Wallet *wallet, bool store = true) override; - bool walletExists(const std::string &path) override; - bool verifyWalletPassword(const std::string &keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override; - bool queryWalletDevice(Wallet::Device& device_type, const std::string &keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const override; - std::vector findWallets(const std::string &path) override; + bool closeWallet(Wallet *wallet, bool store = true) override; + bool walletExists(std::string_view path) override; + bool verifyWalletPassword(std::string_view keys_file_name, const std::string &password, bool no_spend_key, uint64_t kdf_rounds = 1) const override; + bool queryWalletDevice(Wallet::Device& device_type, std::string_view keys_file_name, const std::string &password, uint64_t kdf_rounds = 1) const override; + std::vector findWallets(std::string_view path) override; std::string errorString() const override; void setDaemonAddress(std::string address) override; bool connected(uint32_t *version = NULL) override; @@ -101,5 +91,3 @@ private: }; } // namespace - -namespace Bitmonero = Monero; diff --git a/src/wallet/message_store.cpp b/src/wallet/message_store.cpp index e336a4d47..8ddc243b0 100644 --- a/src/wallet/message_store.cpp +++ b/src/wallet/message_store.cpp @@ -33,12 +33,12 @@ #include #include #include -#include "file_io_utils.h" #include "wallet_errors.h" #include "serialization/binary_utils.h" #include "common/base58.h" #include "common/util.h" -#include "string_tools.h" +#include "common/file.h" +#include "epee/string_tools.h" #undef LOKI_DEFAULT_LOG_CATEGORY @@ -336,7 +336,7 @@ std::string message_store::create_auto_config_token() const crypto::hash &hash = crypto::cn_fast_hash(token_bytes.data(), token_bytes.size()); token_bytes += hash.data[0]; std::string prefix(AUTO_CONFIG_TOKEN_PREFIX); - return prefix + epee::string_tools::buff_to_hex_nodelimer(token_bytes); + return prefix + lokimq::to_hex(token_bytes); } // Add a message for sending "me" address data to the auto-config transport address @@ -688,7 +688,7 @@ void message_store::get_sanitized_message_text(const message &m, std::string &sa } } -void message_store::write_to_file(const multisig_wallet_state &state, const std::string &filename) +void message_store::write_to_file(const multisig_wallet_state &state, const fs::path &filename) { std::stringstream oss; boost::archive::portable_binary_oarchive ar(oss); @@ -711,15 +711,13 @@ void message_store::write_to_file(const multisig_wallet_state &state, const std: boost::archive::portable_binary_oarchive file_ar(file_oss); file_ar << write_file_data; - bool success = epee::file_io_utils::save_string_to_file(filename, file_oss.str()); + bool success = tools::dump_file(filename, file_oss.str()); THROW_WALLET_EXCEPTION_IF(!success, tools::error::file_save_error, filename); } -void message_store::read_from_file(const multisig_wallet_state &state, const std::string &filename) +void message_store::read_from_file(const multisig_wallet_state &state, const fs::path &filename) { - boost::system::error_code ignored_ec; - bool file_exists = boost::filesystem::exists(filename, ignored_ec); - if (!file_exists) + if (std::error_code ec; !fs::exists(filename, ec)) { // Simply do nothing if the file is not there; allows e.g. easy recovery // from problems with the MMS by deleting the file @@ -728,7 +726,7 @@ void message_store::read_from_file(const multisig_wallet_state &state, const std } std::string buf; - bool success = epee::file_io_utils::load_file_to_string(filename, buf); + bool success = tools::slurp_file(filename, buf); THROW_WALLET_EXCEPTION_IF(!success, tools::error::file_read_error, filename); file_data read_file_data; diff --git a/src/wallet/message_store.h b/src/wallet/message_store.h index 9539a7618..cae74429b 100644 --- a/src/wallet/message_store.h +++ b/src/wallet/message_store.h @@ -42,6 +42,7 @@ #include "cryptonote_basic/cryptonote_basic.h" #include "common/i18n.h" #include "common/command_line.h" +#include "common/fs.h" #include "message_transporter.h" #undef LOKI_DEFAULT_LOG_CATEGORY @@ -195,7 +196,7 @@ namespace mms bool has_multisig_partial_key_images; uint32_t multisig_rounds_passed; size_t num_transfer_details; - std::string mms_file; + fs::path mms_file; }; class message_store @@ -279,8 +280,8 @@ namespace mms bool check_for_messages(const multisig_wallet_state &state, std::vector &messages); void stop() { m_run.store(false, std::memory_order_relaxed); m_transporter.stop(); } - void write_to_file(const multisig_wallet_state &state, const std::string &filename); - void read_from_file(const multisig_wallet_state &state, const std::string &filename); + void write_to_file(const multisig_wallet_state &state, const fs::path &filename); + void read_from_file(const multisig_wallet_state &state, const fs::path &filename); template inline void serialize(t_archive &a, const unsigned int ver) @@ -312,7 +313,7 @@ namespace mms std::vector m_signers; std::vector m_messages; uint32_t m_next_message_id; - std::string m_filename; + fs::path m_filename; message_transporter m_transporter; std::atomic m_run; diff --git a/src/wallet/message_transporter.cpp b/src/wallet/message_transporter.cpp index dea88b017..b917828ff 100644 --- a/src/wallet/message_transporter.cpp +++ b/src/wallet/message_transporter.cpp @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "message_transporter.h" -#include "string_coding.h" +#include "epee/string_coding.h" #include #include "wallet_errors.h" #include @@ -196,7 +196,7 @@ std::string message_transporter::derive_transport_address(const std::string &see // case of a PyBitmessage instance used by multiple unrelated people // If an auto-config token gets hashed in another context use different salt instead of "chan" std::string salted_seed = seed + "chan"; - std::string chan_name = epee::string_tools::pod_to_hex(crypto::cn_fast_hash(salted_seed.data(), salted_seed.size())); + std::string chan_name = tools::type_to_hex(crypto::cn_fast_hash(salted_seed.data(), salted_seed.size())); // Calculate the Bitmessage address that the chan will get for being able to // use 'joinChain', as 'createChan' will fail and not tell the address if the chan diff --git a/src/wallet/message_transporter.h b/src/wallet/message_transporter.h index a7980c3c8..8674d21e4 100644 --- a/src/wallet/message_transporter.h +++ b/src/wallet/message_transporter.h @@ -27,14 +27,14 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #pragma once -#include "serialization/keyvalue_serialization.h" +#include "epee/serialization/keyvalue_serialization.h" #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_boost_serialization.h" #include "cryptonote_basic/account_boost_serialization.h" #include "cryptonote_basic/cryptonote_basic.h" #include "rpc/http_client.h" #include "common/util.h" -#include "wipeable_string.h" +#include "epee/wipeable_string.h" #include namespace mms diff --git a/src/wallet/node_rpc_proxy.h b/src/wallet/node_rpc_proxy.h index 884e61727..b400c211b 100644 --- a/src/wallet/node_rpc_proxy.h +++ b/src/wallet/node_rpc_proxy.h @@ -32,7 +32,6 @@ #include #include #include -#include "include_base_utils.h" #include "rpc/http_client.h" #include "rpc/core_rpc_server_commands_defs.h" diff --git a/src/wallet/ringdb.cpp b/src/wallet/ringdb.cpp index ff010c541..83906a5f3 100644 --- a/src/wallet/ringdb.cpp +++ b/src/wallet/ringdb.cpp @@ -28,10 +28,9 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include #include "common/file.h" -#include "misc_log_ex.h" -#include "misc_language.h" +#include "epee/misc_log_ex.h" +#include "epee/misc_language.h" #include "wallet_errors.h" #include "ringdb.h" #include "cryptonote_config.h" @@ -96,11 +95,11 @@ static std::vector decompress_ring(const std::string &s, uint64_t tag) return ring; } -std::string get_rings_filename(boost::filesystem::path filename) +fs::path get_rings_filename(fs::path filename) { - if (!boost::filesystem::is_directory(filename)) + if (!fs::is_directory(filename)) filename.remove_filename(); - return filename.string(); + return filename; } static crypto::chacha_iv make_iv(const crypto::key_image &key_image, const crypto::chacha_key &key, uint8_t field) @@ -158,13 +157,13 @@ static void store_relative_ring(MDB_txn *txn, MDB_dbi &dbi, const crypto::key_im THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set ring for key image in LMDB table: " + std::string(mdb_strerror(dbr))); } -static int resize_env(MDB_env *env, const char *db_path, size_t needed) +static int resize_env(MDB_env *env, const fs::path& db_path, size_t needed) { MDB_envinfo mei; MDB_stat mst; int ret; - needed = std::max(needed, (size_t)(100ul * 1024 * 1024)); // at least 100 MB + needed = std::max(needed, 100 * 1024 * 1024); // at least 100 MB ret = mdb_env_info(env, &mei); if (ret) @@ -178,11 +177,10 @@ static int resize_env(MDB_env *env, const char *db_path, size_t needed) { try { - boost::filesystem::path path(db_path); - boost::filesystem::space_info si = boost::filesystem::space(path); + auto si = fs::space(db_path); if(si.available < needed) { - MERROR("!! WARNING: Insufficient free space to extend database !!: " << (si.available >> 20L) << " MB available"); + MERROR("!! WARNING: Insufficient free space to extend database !!: " << (si.available / 1000000) << " MB available"); return ENOSPC; } } @@ -207,24 +205,22 @@ enum { BLACKBALL_BLACKBALL, BLACKBALL_UNBLACKBALL, BLACKBALL_QUERY, BLACKBALL_CL namespace tools { -ringdb::ringdb(std::string filename, const std::string &genesis): - filename(filename), - env(NULL) +ringdb::ringdb(fs::path fn_, const std::string &genesis) : filename_{std::move(fn_)} { MDB_txn *txn; bool tx_active = false; int dbr; - tools::create_directories_if_necessary(filename); + tools::create_directories_if_necessary(filename_); dbr = mdb_env_create(&env); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LDMB environment: " + std::string(mdb_strerror(dbr))); dbr = mdb_env_set_maxdbs(env, 2); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set max env dbs: " + std::string(mdb_strerror(dbr))); - const std::string actual_filename = get_rings_filename(filename); - dbr = mdb_env_open(env, actual_filename.c_str(), 0, 0664); + const fs::path actual_filename = get_rings_filename(filename_); + dbr = mdb_env_open(env, actual_filename.string().c_str(), 0, 0664); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to open rings database file '" - + actual_filename + "': " + std::string(mdb_strerror(dbr))); + + actual_filename.u8string() + "': " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env, NULL, 0, &txn); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -266,7 +262,7 @@ bool ringdb::add_rings(const crypto::chacha_key &chacha_key, const cryptonote::t int dbr; bool tx_active = false; - dbr = resize_env(env, filename.c_str(), get_ring_data_size(tx.vin.size())); + dbr = resize_env(env, filename_, get_ring_data_size(tx.vin.size())); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size"); dbr = mdb_txn_begin(env, NULL, 0, &txn); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -297,7 +293,7 @@ bool ringdb::remove_rings(const crypto::chacha_key &chacha_key, const std::vecto int dbr; bool tx_active = false; - dbr = resize_env(env, filename.c_str(), 0); + dbr = resize_env(env, filename_, 0); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size"); dbr = mdb_txn_begin(env, NULL, 0, &txn); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -351,7 +347,7 @@ bool ringdb::get_ring(const crypto::chacha_key &chacha_key, const crypto::key_im int dbr; bool tx_active = false; - dbr = resize_env(env, filename.c_str(), 0); + dbr = resize_env(env, filename_, 0); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size: " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env, NULL, 0, &txn); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -394,7 +390,7 @@ bool ringdb::set_ring(const crypto::chacha_key &chacha_key, const crypto::key_im int dbr; bool tx_active = false; - dbr = resize_env(env, filename.c_str(), outs.size() * 64); + dbr = resize_env(env, filename_, outs.size() * 64); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size: " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env, NULL, 0, &txn); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); @@ -419,7 +415,7 @@ bool ringdb::blackball_worker(const std::vector> & THROW_WALLET_EXCEPTION_IF(outputs.size() > 1 && op == BLACKBALL_QUERY, tools::error::wallet_internal_error, "Blackball query only makes sense for a single output"); - dbr = resize_env(env, filename.c_str(), 32 * 2 * outputs.size()); // a pubkey, and some slack + dbr = resize_env(env, filename_, 32 * 2 * outputs.size()); // a pubkey, and some slack THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to set env map size: " + std::string(mdb_strerror(dbr))); dbr = mdb_txn_begin(env, NULL, 0, &txn); THROW_WALLET_EXCEPTION_IF(dbr, tools::error::wallet_internal_error, "Failed to create LMDB transaction: " + std::string(mdb_strerror(dbr))); diff --git a/src/wallet/ringdb.h b/src/wallet/ringdb.h index 690704282..dd50fb428 100644 --- a/src/wallet/ringdb.h +++ b/src/wallet/ringdb.h @@ -31,19 +31,22 @@ #include #include #include -#include "wipeable_string.h" +#include "epee/wipeable_string.h" #include "crypto/crypto.h" #include "cryptonote_basic/cryptonote_basic.h" +#include "common/fs.h" namespace tools { class ringdb { public: - ringdb(std::string filename, const std::string &genesis); + ringdb(fs::path filename, const std::string &genesis); void close(); ~ringdb(); + const fs::path& filename() { return filename_; } + bool add_rings(const crypto::chacha_key &chacha_key, const cryptonote::transaction_prefix &tx); bool remove_rings(const crypto::chacha_key &chacha_key, const std::vector &key_images); bool remove_rings(const crypto::chacha_key &chacha_key, const cryptonote::transaction_prefix &tx); @@ -60,8 +63,8 @@ namespace tools bool blackball_worker(const std::vector> &outputs, int op); private: - std::string filename; - MDB_env *env; + fs::path filename_; + MDB_env *env = nullptr; MDB_dbi dbi_rings; MDB_dbi dbi_blackballs; }; diff --git a/src/wallet/transfer_destination.h b/src/wallet/transfer_destination.h index 25294b696..1da67a843 100644 --- a/src/wallet/transfer_destination.h +++ b/src/wallet/transfer_destination.h @@ -31,7 +31,7 @@ #include "common/loki.h" #include #include -#include "serialization/keyvalue_serialization.h" +#include "epee/serialization/keyvalue_serialization.h" namespace wallet { diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index d7652fa45..454d73348 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -43,7 +43,6 @@ #include "common/password.h" #include "common/string_util.h" #include "cryptonote_core/loki_name_system.h" -#include "include_base_utils.h" #include "common/rules.h" #include "cryptonote_config.h" #include "cryptonote_core/tx_sanity_check.h" @@ -51,14 +50,14 @@ #include "wallet2.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "rpc/core_rpc_server_commands_defs.h" -#include "misc_language.h" +#include "epee/misc_language.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "cryptonote_basic/hardfork.h" #include "multisig/multisig.h" #include "common/boost_serialization_helper.h" #include "common/command_line.h" #include "common/threadpool.h" -#include "profile_tools.h" +#include "epee/profile_tools.h" #include "crypto/crypto.h" #include "serialization/binary_utils.h" #include "serialization/string.h" @@ -73,7 +72,7 @@ #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #include "common/json_util.h" -#include "memwipe.h" +#include "epee/memwipe.h" #include "common/base58.h" #include "common/combinator.h" #include "common/dns_utils.h" @@ -90,7 +89,7 @@ #include "common/loki.h" #include "common/loki_integration_test_hooks.h" #include "loki_economy.h" -#include "string_coding.h" +#include "epee/string_coding.h" extern "C" { @@ -160,11 +159,8 @@ namespace { std::string get_default_ringdb_path() { - boost::filesystem::path dir = tools::get_default_data_dir(); // remove .loki, replace with .shared-ringdb - dir = dir.remove_filename(); - dir /= ".shared-ringdb"; - return dir.string(); + return tools::get_default_data_dir().replace_filename(".shared-ringdb").u8string(); } std::string pack_multisignature_keys(const std::vector& keys, const crypto::secret_key& signer_secret_key) @@ -276,11 +272,11 @@ struct options { {{ &testnet, &devnet, ®test }}, [](std::array test_dev_fake, bool defaulted, std::string val)->std::string { if (test_dev_fake[0]) - return (boost::filesystem::path(val) / "testnet").string(); + return (fs::u8path(val) / "testnet").u8string(); else if (test_dev_fake[1]) - return (boost::filesystem::path(val) / "devnet").string(); + return (fs::u8path(val) / "devnet").u8string(); else if (test_dev_fake[2]) - return (boost::filesystem::path(val) / "fake").string(); + return (fs::u8path(val) / "fake").u8string(); return val; } }; @@ -292,19 +288,17 @@ struct options { const command_line::arg_descriptor extra_entropy = {"extra-entropy", tools::wallet2::tr("File containing extra entropy to initialize the PRNG (any data, aim for 256 bits of entropy to be useful, wihch typically means more than 256 bits of data)")}; }; -void do_prepare_file_names(const std::string& file_path, std::string& keys_file, std::string& wallet_file, std::string &mms_file) +void do_prepare_file_names(const fs::path& file_path, fs::path& keys_file, fs::path& wallet_file, fs::path &mms_file) { keys_file = file_path; wallet_file = file_path; - boost::system::error_code e; - if(string_tools::get_extension(keys_file) == "keys") - {//provided keys file name - wallet_file = string_tools::cut_off_extension(wallet_file); - }else - {//provided wallet file name + + if (keys_file.extension() == ".keys") // provided keys file name + wallet_file.replace_extension(); + else // provided wallet file name keys_file += ".keys"; - } - mms_file = file_path + ".mms"; + + (mms_file = keys_file).replace_extension(".mms"); } uint64_t calculate_fee_from_weight(byte_and_output_fees base_fees, uint64_t weight, uint64_t outputs, uint64_t fee_percent, uint64_t fee_fixed, uint64_t fee_quantization_mask) @@ -413,8 +407,8 @@ std::unique_ptr make_basic(const boost::program_options::variabl auto wallet = std::make_unique(nettype, kdf_rounds, unattended); wallet->init(std::move(daemon_address), std::move(login), std::move(proxy), 0, trusted_daemon); - boost::filesystem::path ringdb_path = command_line::get_arg(vm, opts.shared_ringdb_dir); - wallet->set_ring_database(ringdb_path.string()); + auto ringdb_path = fs::u8path(command_line::get_arg(vm, opts.shared_ringdb_dir)); + wallet->set_ring_database(ringdb_path); wallet->get_message_store().set_options(vm); wallet->device_name(device_name); wallet->device_derivation_path(device_derivation_path); @@ -430,7 +424,7 @@ std::unique_ptr make_basic(const boost::program_options::variabl if (!extra_entropy.empty()) { std::string data; - THROW_WALLET_EXCEPTION_IF(!epee::file_io_utils::load_file_to_string(extra_entropy, data), + THROW_WALLET_EXCEPTION_IF(!tools::slurp_file(fs::u8path(extra_entropy), data), tools::error::wallet_internal_error, "Failed to load extra entropy from " + extra_entropy); add_extra_entropy_thread_safe(data.data(), data.size()); } @@ -463,8 +457,7 @@ std::optional get_password(const boost::program_optio if (command_line::has_arg(vm, opts.password_file)) { std::string password; - bool r = epee::file_io_utils::load_file_to_string(command_line::get_arg(vm, opts.password_file), - password); + bool r = tools::slurp_file(fs::u8path(command_line::get_arg(vm, opts.password_file)), password); THROW_WALLET_EXCEPTION_IF(!r, tools::error::wallet_internal_error, tools::wallet2::tr("the password file specified could not be read")); // Remove line breaks the user might have inserted @@ -478,7 +471,7 @@ std::optional get_password(const boost::program_optio return password_prompter(verify ? tools::wallet2::tr("Enter a new password for the wallet") : tools::wallet2::tr("Wallet password"), verify); } -std::pair, tools::password_container> generate_from_json(const std::string& json_file, const boost::program_options::variables_map& vm, bool unattended, const options& opts, const std::function(const char *, bool)> &password_prompter) +std::pair, tools::password_container> generate_from_json(const fs::path& json_file, const boost::program_options::variables_map& vm, bool unattended, const options& opts, const std::function(const char *, bool)> &password_prompter) { const bool testnet = command_line::get_arg(vm, opts.testnet); const bool devnet = command_line::get_arg(vm, opts.devnet); @@ -491,8 +484,8 @@ std::pair, tools::password_container> generate_f epee::wipeable_string password; const auto do_generate = [&]() -> bool { std::string buf; - if (!epee::file_io_utils::load_file_to_string(json_file, buf)) { - THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("Failed to load file ")) + json_file); + if (!tools::slurp_file(json_file, buf)) { + THROW_WALLET_EXCEPTION(tools::error::wallet_internal_error, std::string(tools::wallet2::tr("Failed to load file ")) + json_file.u8string()); return false; } @@ -867,7 +860,7 @@ bool get_pruned_tx(const rpc::GET_TRANSACTIONS::entry &entry, cryptonote::transa CHECK_AND_ASSERT_MES(cryptonote::parse_and_validate_tx_from_blob(bd, tx), false, "Invalid tx data"); tx_hash = cryptonote::get_transaction_hash(tx); // if the hash was given, check it matches - CHECK_AND_ASSERT_MES(entry.tx_hash.empty() || epee::string_tools::pod_to_hex(tx_hash) == entry.tx_hash, false, + CHECK_AND_ASSERT_MES(entry.tx_hash.empty() || tools::type_to_hex(tx_hash) == entry.tx_hash, false, "Response claims a different hash than the data yields"); return true; } @@ -875,7 +868,7 @@ bool get_pruned_tx(const rpc::GET_TRANSACTIONS::entry &entry, cryptonote::transa if (entry.pruned_as_hex && entry.prunable_hash) { crypto::hash ph; - CHECK_AND_ASSERT_MES(epee::string_tools::hex_to_pod(*entry.prunable_hash, ph), false, "Failed to parse prunable hash"); + CHECK_AND_ASSERT_MES(tools::hex_to_type(*entry.prunable_hash, ph), false, "Failed to parse prunable hash"); CHECK_AND_ASSERT_MES(epee::string_tools::parse_hexstr_to_binbuff(*entry.pruned_as_hex, bd), false, "Failed to parse pruned data"); CHECK_AND_ASSERT_MES(parse_and_validate_tx_base_from_blob(bd, tx), false, "Invalid base tx data"); // only v2 txes can calculate their txid after pruned @@ -886,7 +879,7 @@ bool get_pruned_tx(const rpc::GET_TRANSACTIONS::entry &entry, cryptonote::transa else { // for v1, we trust the dameon - CHECK_AND_ASSERT_MES(epee::string_tools::hex_to_pod(entry.tx_hash, tx_hash), false, "Failed to parse tx hash"); + CHECK_AND_ASSERT_MES(tools::hex_to_type(entry.tx_hash, tx_hash), false, "Failed to parse tx hash"); } return true; } @@ -1170,14 +1163,14 @@ void wallet2::init_options(boost::program_options::options_description& desc_par command_line::add_arg(desc_params, opts.extra_entropy); } -std::pair, tools::password_container> wallet2::make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function(const char *, bool)> &password_prompter) +std::pair, tools::password_container> wallet2::make_from_json(const boost::program_options::variables_map& vm, bool unattended, const fs::path& json_file, const std::function(const char *, bool)> &password_prompter) { const options opts{}; return generate_from_json(json_file, vm, unattended, opts, password_prompter); } std::pair, password_container> wallet2::make_from_file( - const boost::program_options::variables_map& vm, bool unattended, const std::string& wallet_file, const std::function(const char *, bool)> &password_prompter) + const boost::program_options::variables_map& vm, bool unattended, const fs::path& wallet_file, const std::function(const char *, bool)> &password_prompter) { const options opts{}; auto pwd = get_password(vm, opts, password_prompter, false); @@ -2127,7 +2120,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote { if (transfer.amount() > tx_scan_info[o].amount) { - LOG_ERROR("Public key " << epee::string_tools::pod_to_hex(kit->first) + LOG_ERROR("Public key " << tools::type_to_hex(kit->first) << " from received " << print_money(tx_scan_info[o].amount) << " output already exists with " << (transfer.m_spent ? "spent" : "unspent") << " " << print_money(transfer.amount()) << " in tx " << transfer.m_txid << ", received output ignored"); @@ -2139,7 +2132,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote THROW_WALLET_EXCEPTION_IF(transfer.amount() != tx_scan_info[o].amount, error::wallet_internal_error, "A blink should credit the amount exactly as we recorded it when it arrived in the mempool"); THROW_WALLET_EXCEPTION_IF(transfer.m_spent, error::wallet_internal_error, "Blink can not be spent before it is mined, this should never happen"); - MINFO("Public key " << epee::string_tools::pod_to_hex(kit->first) + MINFO("Public key " << tools::type_to_hex(kit->first) << " of blink tx " << transfer.m_txid << " (for " << print_money(tx_scan_info[o].amount) << ")" << " status updated: now mined in block " << height); @@ -2164,7 +2157,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote } else if (transfer.m_spent || transfer.amount() >= tx_scan_info[o].amount) { - LOG_ERROR("Public key " << epee::string_tools::pod_to_hex(kit->first) + LOG_ERROR("Public key " << tools::type_to_hex(kit->first) << " from received " << print_money(tx_scan_info[o].amount) << " output already exists with " << (transfer.m_spent ? "spent" : "unspent") << " " << print_money(transfer.amount()) << " in tx " << transfer.m_txid << ", received output ignored"); @@ -2185,7 +2178,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote } else { - LOG_ERROR("Public key " << epee::string_tools::pod_to_hex(kit->first) + LOG_ERROR("Public key " << tools::type_to_hex(kit->first) << " from received " << print_money(tx_scan_info[o].amount) << " output already exists with " << print_money(transfer.amount()) << ", replacing with new output"); @@ -2382,7 +2375,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote { auto i = m_confirmed_txs.find(txid); THROW_WALLET_EXCEPTION_IF(i == m_confirmed_txs.end(), error::wallet_internal_error, - "confirmed tx wasn't found: " + string_tools::pod_to_hex(txid)); + "confirmed tx wasn't found: " + tools::type_to_hex(txid)); i->second.m_change = self_received; } } @@ -2539,7 +2532,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote { std::shared_ptr tx_notify = m_tx_notify; if (tx_notify) - tx_notify->notify("%s", epee::string_tools::pod_to_hex(txid).c_str(), NULL); + tx_notify->notify("%s", tools::type_to_hex(txid).c_str(), NULL); } } //---------------------------------------------------------------------------------------------------- @@ -2875,16 +2868,16 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector wallet2::get_pool_state(bool refreshed) { std::vector process_txs; MTRACE("get_pool_state: take hashes from cache"); - std::vector tx_hashes; + std::vector blink_hashes, pool_hashes; { - // NOTE: Only request blinked transactions, normal transactions will appear - // in the wallet when it arrives in a block. This is to prevent pulling down - // TX's that are awaiting blink approval being cached in the wallet as - // non-blink and external applications failing to respect this. + // We make two requests here: one for all pool txes, and then (assuming there are any) a second + // one for blink txes. cryptonote::rpc::GET_TRANSACTION_POOL_HASHES_BIN::request req{}; - req.blinked_txs_only = true; - cryptonote::rpc::GET_TRANSACTION_POOL_HASHES_BIN::response res{}; bool r = invoke_http(req, res); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_transaction_pool_hashes.bin"); THROW_WALLET_EXCEPTION_IF(res.status == rpc::STATUS_BUSY, error::daemon_busy, "get_transaction_pool_hashes.bin"); THROW_WALLET_EXCEPTION_IF(res.status != rpc::STATUS_OK, error::get_tx_pool_error); - MTRACE("get_pool_state got pool"); - tx_hashes = std::move(res.tx_hashes); + MTRACE("get_pool_state got full pool"); + pool_hashes = std::move(res.tx_hashes); + + // NOTE: Only request blinked transactions, normal transactions will appear + // in the wallet when it arrives in a block. This is to prevent pulling down + // TX's that are awaiting blink approval being cached in the wallet as + // non-blink and external applications failing to respect this. + req.blinked_txs_only = true; + res = {}; + r = invoke_http(req, res); + THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_transaction_pool_hashes.bin"); + THROW_WALLET_EXCEPTION_IF(res.status == rpc::STATUS_BUSY, error::daemon_busy, "get_transaction_pool_hashes.bin"); + THROW_WALLET_EXCEPTION_IF(res.status != rpc::STATUS_OK, error::get_tx_pool_error); + MTRACE("get_pool_state got blinks"); + blink_hashes = std::move(res.tx_hashes); } LOKI_DEFER { @@ -3123,15 +3125,7 @@ std::vector wallet2::get_pool_state(bool refreshed) while (it != m_unconfirmed_txs.end()) { const crypto::hash &txid = it->first; - bool found = false; - for (const auto &it2: tx_hashes) - { - if (it2 == txid) - { - found = true; - break; - } - } + bool found = std::find(pool_hashes.begin(), pool_hashes.end(), txid) != pool_hashes.end(); auto pit = it++; if (!found) { @@ -3179,13 +3173,14 @@ std::vector wallet2::get_pool_state(bool refreshed) // the in transfers list instead (or nowhere if it just // disappeared without being mined) if (refreshed) - remove_obsolete_pool_txs(tx_hashes); + remove_obsolete_pool_txs(pool_hashes); MTRACE("get_pool_state done second loop"); - // gather txids of new pool txes to us + // gather txids of new blink txes to us. We just ignore non-blinks here (we pick them up when they + // get mined into a block). std::vector> txids; - for (const auto &txid: tx_hashes) + for (const auto &txid: blink_hashes) { bool txid_found_in_up = false; for (const auto &up: m_unconfirmed_payments) @@ -3789,7 +3784,7 @@ void wallet2::detach_blockchain(uint64_t height, std::map keys_file_data = get_keys_file_data(password, watch_only); CHECK_AND_ASSERT_MES(keys_file_data, false, "failed to generate wallet keys data"); - std::string tmp_file_name = keys_file_name + ".new"; + fs::path tmp_file_name = keys_file_name; + tmp_file_name += ".new"; std::string buf; bool r = false; try { @@ -3896,11 +3892,12 @@ bool wallet2::store_keys(const std::string& keys_file_name, const epee::wipeable CHECK_AND_ASSERT_MES(r, false, "failed to generate wallet keys file " << tmp_file_name); unlock_keys_file(); - std::error_code e = tools::replace_file(tmp_file_name, keys_file_name); + std::error_code e; + fs::rename(tmp_file_name, keys_file_name, e); lock_keys_file(); if (e) { - boost::filesystem::remove(tmp_file_name); + fs::remove(tmp_file_name); LOG_ERROR("failed to update wallet keys file " << keys_file_name); return false; } @@ -4083,7 +4080,7 @@ std::optional wallet2::get_keys_file_data(const epee::w original_address = get_account_address_as_str(m_nettype, false, m_original_address); value.SetString(original_address.c_str(), original_address.length()); json.AddMember("original_address", value, json.GetAllocator()); - original_view_secret_key = epee::string_tools::pod_to_hex(m_original_view_secret_key); + original_view_secret_key = tools::type_to_hex(m_original_view_secret_key); value.SetString(original_view_secret_key.c_str(), original_view_secret_key.length()); json.AddMember("original_view_secret_key", value, json.GetAllocator()); } @@ -4122,7 +4119,7 @@ void wallet2::setup_keys(const epee::wipeable_string &password) get_ringdb_key(); } //---------------------------------------------------------------------------------------------------- -void wallet2::change_password(const std::string &filename, const epee::wipeable_string &original_password, const epee::wipeable_string &new_password) +void wallet2::change_password(const fs::path& filename, const epee::wipeable_string& original_password, const epee::wipeable_string& new_password) { if (m_ask_password == AskPasswordToDecrypt && !m_unattended && !m_watch_only) decrypt_keys(original_password); @@ -4137,7 +4134,7 @@ void wallet2::change_password(const std::string &filename, const epee::wipeable_ * \param keys_file_name Name of wallet file * \param password Password of wallet file */ -bool wallet2::load_keys(const std::string& keys_file_name, const epee::wipeable_string& password) +bool wallet2::load_keys(const fs::path& keys_file_name, const epee::wipeable_string& password) { std::string keys_file_buf; bool r = load_from_file(keys_file_name, keys_file_buf); @@ -4424,7 +4421,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st } m_original_address = info.address; GET_FIELD_FROM_JSON_RETURN_ON_ERROR(json, original_view_secret_key, std::string, String, true, std::string()); - ok = epee::string_tools::hex_to_pod(field_original_view_secret_key, m_original_view_secret_key); + ok = tools::hex_to_type(field_original_view_secret_key, m_original_view_secret_key); if (!ok) { LOG_ERROR("Failed to parse original_view_secret_key from JSON"); @@ -4523,7 +4520,7 @@ bool wallet2::verify_password(const epee::wipeable_string& password) * can be used prior to rewriting wallet keys file, to ensure user has entered the correct password * */ -bool wallet2::verify_password(const std::string& keys_file_name, const epee::wipeable_string& password, bool no_spend_key, hw::device &hwdev, uint64_t kdf_rounds) +bool wallet2::verify_password(const fs::path& keys_file_name, const epee::wipeable_string& password, bool no_spend_key, hw::device &hwdev, uint64_t kdf_rounds) { rapidjson::Document json; wallet2::keys_file_data keys_file_data; @@ -4536,7 +4533,7 @@ bool wallet2::verify_password(const std::string& keys_file_name, const epee::wip try { serialization::parse_binary(buf, keys_file_data); } catch (const std::exception& e) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, "internal error: failed to deserialize \"" + keys_file_name + "\": " + e.what()); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, "internal error: failed to deserialize \"" + keys_file_name.u8string() + "\": " + e.what()); } crypto::chacha_key key; crypto::generate_chacha_key(password.data(), password.size(), key, kdf_rounds); @@ -4614,7 +4611,7 @@ void wallet2::setup_new_blockchain() add_subaddress_account(tr("Primary account")); } -void wallet2::create_keys_file(const std::string &wallet_, bool watch_only, const epee::wipeable_string &password, bool create_address_file) +void wallet2::create_keys_file(const fs::path &wallet_, bool watch_only, const epee::wipeable_string &password, bool create_address_file) { if (!wallet_.empty()) { @@ -4623,7 +4620,9 @@ void wallet2::create_keys_file(const std::string &wallet_, bool watch_only, cons if (create_address_file) { - r = save_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype), true); + auto addrfile = m_wallet_file; + addrfile += ".address.txt"; + r = save_to_file(addrfile, m_account.get_public_address_str(m_nettype), true); if(!r) MERROR("String with address text not saved"); } } @@ -4640,7 +4639,7 @@ void wallet2::create_keys_file(const std::string &wallet_, bool watch_only, cons * for verification only - determines key storage hardware * */ -bool wallet2::query_device(hw::device::device_type& device_type, const std::string& keys_file_name, const epee::wipeable_string& password, uint64_t kdf_rounds) +bool wallet2::query_device(hw::device::device_type& device_type, const fs::path& keys_file_name, const epee::wipeable_string& password, uint64_t kdf_rounds) { rapidjson::Document json; wallet2::keys_file_data keys_file_data; @@ -4652,7 +4651,7 @@ bool wallet2::query_device(hw::device::device_type& device_type, const std::stri try { serialization::parse_binary(buf, keys_file_data); } catch (const std::exception& e) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, "internal error: failed to deserialize \"" + keys_file_name + "\": " + e.what()); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, "internal error: failed to deserialize \"" + keys_file_name.u8string() + "\": " + e.what()); } crypto::chacha_key key; crypto::generate_chacha_key(password.data(), password.size(), key, kdf_rounds); @@ -4705,7 +4704,7 @@ void wallet2::init_type(hw::device::device_type device_type) * \param multisig_data The multisig restore info and keys * \param create_address_file Whether to create an address file */ -void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password, +void wallet2::generate(const fs::path& wallet_, const epee::wipeable_string& password, const epee::wipeable_string& multisig_data, bool create_address_file) { clear(); @@ -4713,9 +4712,9 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& if (!wallet_.empty()) { - boost::system::error_code ignored_ec; - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); + std::error_code ignored_ec; + THROW_WALLET_EXCEPTION_IF(fs::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); + THROW_WALLET_EXCEPTION_IF(fs::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); } m_account.generate(rct::rct2sk(rct::zero()), true, false); @@ -4793,7 +4792,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& * \param create_address_file Whether to create an address file * \return The secret key of the generated wallet */ -crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password, +crypto::secret_key wallet2::generate(const fs::path& wallet_, const epee::wipeable_string& password, const crypto::secret_key& recovery_param, bool recover, bool two_random, bool create_address_file) { clear(); @@ -4801,9 +4800,9 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip if (!wallet_.empty()) { - boost::system::error_code ignored_ec; - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); + std::error_code ignored_ec; + THROW_WALLET_EXCEPTION_IF(fs::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); + THROW_WALLET_EXCEPTION_IF(fs::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); } crypto::secret_key retval = m_account.generate(recovery_param, recover, two_random); @@ -4872,7 +4871,7 @@ crypto::secret_key wallet2::generate(const std::string& wallet_, const epee::wip * \param viewkey view secret key * \param create_address_file Whether to create an address file */ -void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password, +void wallet2::generate(const fs::path& wallet_, const epee::wipeable_string& password, const cryptonote::account_public_address &account_public_address, const crypto::secret_key& viewkey, bool create_address_file) { @@ -4881,9 +4880,9 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& if (!wallet_.empty()) { - boost::system::error_code ignored_ec; - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); + std::error_code ignored_ec; + THROW_WALLET_EXCEPTION_IF(fs::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); + THROW_WALLET_EXCEPTION_IF(fs::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); } m_account.create_from_viewkey(account_public_address, viewkey); @@ -4909,7 +4908,7 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& * \param viewkey view secret key * \param create_address_file Whether to create an address file */ -void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& password, +void wallet2::generate(const fs::path& wallet_, const epee::wipeable_string& password, const cryptonote::account_public_address &account_public_address, const crypto::secret_key& spendkey, const crypto::secret_key& viewkey, bool create_address_file) { @@ -4918,9 +4917,9 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& if (!wallet_.empty()) { - boost::system::error_code ignored_ec; - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); + std::error_code ignored_ec; + THROW_WALLET_EXCEPTION_IF(fs::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); + THROW_WALLET_EXCEPTION_IF(fs::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); } m_account.create_from_keys(account_public_address, spendkey, viewkey); @@ -4942,15 +4941,15 @@ void wallet2::generate(const std::string& wallet_, const epee::wipeable_string& * \param password Password of wallet file * \param device_name device string address */ -void wallet2::restore(const std::string& wallet_, const epee::wipeable_string& password, const std::string &device_name, bool create_address_file) +void wallet2::restore(const fs::path& wallet_, const epee::wipeable_string& password, const std::string &device_name, bool create_address_file) { clear(); prepare_file_names(wallet_); - boost::system::error_code ignored_ec; + std::error_code ignored_ec; if (!wallet_.empty()) { - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); - THROW_WALLET_EXCEPTION_IF(boost::filesystem::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); + THROW_WALLET_EXCEPTION_IF(fs::exists(m_wallet_file, ignored_ec), error::file_exists, m_wallet_file); + THROW_WALLET_EXCEPTION_IF(fs::exists(m_keys_file, ignored_ec), error::file_exists, m_keys_file); } auto &hwdev = lookup_device(device_name); @@ -5111,7 +5110,11 @@ std::string wallet2::make_multisig(const epee::wipeable_string &password, keys_reencryptor.invoke(); if (!m_wallet_file.empty()) - create_keys_file(m_wallet_file, false, password, boost::filesystem::exists(m_wallet_file + ".address.txt")); + { + fs::path addrfile = m_wallet_file; + addrfile += ".address.txt"; + create_keys_file(m_wallet_file, false, password, fs::exists(addrfile)); + } setup_new_blockchain(); @@ -5208,9 +5211,11 @@ std::string wallet2::exchange_multisig_keys(const epee::wipeable_string &passwor bool r = store_keys(m_keys_file, password, false); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); - if (boost::filesystem::exists(m_wallet_file + ".address.txt")) + fs::path addrfile = m_wallet_file; + addrfile += ".address.txt"; + if (fs::exists(addrfile)) { - r = save_to_file(m_wallet_file + ".address.txt", m_account.get_public_address_str(m_nettype), true); + r = save_to_file(addrfile, m_account.get_public_address_str(m_nettype), true); if(!r) MERROR("String with address text not saved"); } } @@ -5260,7 +5265,11 @@ std::string wallet2::exchange_multisig_keys(const epee::wipeable_string &passwor ++m_multisig_rounds_passed; if (!m_wallet_file.empty()) - create_keys_file(m_wallet_file, false, password, boost::filesystem::exists(m_wallet_file + ".address.txt")); + { + fs::path addrfile = m_wallet_file; + addrfile += ".address.txt"; + create_keys_file(m_wallet_file, false, password, fs::exists(addrfile)); + } return extra_multisig_info; } @@ -5520,13 +5529,13 @@ bool wallet2::has_unknown_key_images() const * \param wallet_name Name of wallet file (should exist) * \param password Password for wallet file */ -void wallet2::rewrite(const std::string& wallet_name, const epee::wipeable_string& password) +void wallet2::rewrite(const fs::path& wallet_name, const epee::wipeable_string& password) { if (wallet_name.empty()) return; prepare_file_names(wallet_name); - boost::system::error_code ignored_ec; - THROW_WALLET_EXCEPTION_IF(!boost::filesystem::exists(m_keys_file, ignored_ec), error::file_not_found, m_keys_file); + std::error_code ignored_ec; + THROW_WALLET_EXCEPTION_IF(!fs::exists(m_keys_file, ignored_ec), error::file_not_found, m_keys_file); bool r = store_keys(m_keys_file, password, m_watch_only); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); } @@ -5536,54 +5545,33 @@ void wallet2::rewrite(const std::string& wallet_name, const epee::wipeable_strin * \param password Password for wallet file * \param new_keys_filename [OUT] Name of new keys file */ -void wallet2::write_watch_only_wallet(const std::string& wallet_name, const epee::wipeable_string& password, std::string &new_keys_filename) +void wallet2::write_watch_only_wallet(const fs::path& wallet_name, const epee::wipeable_string& password, fs::path& new_keys_filename) { prepare_file_names(wallet_name); - boost::system::error_code ignored_ec; - new_keys_filename = m_wallet_file + "-watchonly.keys"; - bool watch_only_keys_file_exists = boost::filesystem::exists(new_keys_filename, ignored_ec); - THROW_WALLET_EXCEPTION_IF(watch_only_keys_file_exists, error::file_save_error, new_keys_filename); + std::error_code ec; + new_keys_filename = m_wallet_file; + new_keys_filename += "-watchonly.keys"; + THROW_WALLET_EXCEPTION_IF(fs::exists(new_keys_filename, ec), error::file_save_error, new_keys_filename); bool r = store_keys(new_keys_filename, password, true); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, new_keys_filename); } //---------------------------------------------------------------------------------------------------- -void wallet2::wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists) +void wallet2::wallet_exists(const fs::path& file_path, bool& keys_file_exists, bool& wallet_file_exists) { - std::string keys_file, wallet_file, mms_file; + fs::path keys_file, wallet_file, mms_file; do_prepare_file_names(file_path, keys_file, wallet_file, mms_file); - boost::system::error_code ignore; - keys_file_exists = boost::filesystem::exists(keys_file, ignore); - wallet_file_exists = boost::filesystem::exists(wallet_file, ignore); -} -//---------------------------------------------------------------------------------------------------- -bool wallet2::wallet_valid_path_format(std::string_view file_path) -{ - return !file_path.empty(); -} -//---------------------------------------------------------------------------------------------------- -bool wallet2::parse_long_payment_id(std::string_view payment_id_str, crypto::hash& payment_id) -{ - if (!lokimq::is_hex(payment_id_str) || payment_id_str.size() != 2*sizeof(crypto::hash)) - return false; - lokimq::from_hex(payment_id_str.begin(), payment_id_str.end(), reinterpret_cast(&payment_id)); - return true; -} -//---------------------------------------------------------------------------------------------------- -bool wallet2::parse_short_payment_id(std::string_view payment_id_str, crypto::hash8& payment_id) -{ - if (!lokimq::is_hex(payment_id_str) || payment_id_str.size() != 2*sizeof(crypto::hash8)) - return false; - lokimq::from_hex(payment_id_str.begin(), payment_id_str.end(), reinterpret_cast(&payment_id)); - return true; + std::error_code ignore; + keys_file_exists = fs::exists(keys_file, ignore); + wallet_file_exists = fs::exists(wallet_file, ignore); } //---------------------------------------------------------------------------------------------------- bool wallet2::parse_payment_id(std::string_view payment_id_str, crypto::hash& payment_id) { - if (parse_long_payment_id(payment_id_str, payment_id)) + if (tools::hex_to_type(payment_id_str, payment_id)) return true; crypto::hash8 payment_id8; - if (parse_short_payment_id(payment_id_str, payment_id8)) + if (tools::hex_to_type(payment_id_str, payment_id8)) { payment_id = crypto::null_hash; std::memcpy(payment_id.data, payment_id8.data, sizeof(payment_id8)); @@ -5592,7 +5580,7 @@ bool wallet2::parse_payment_id(std::string_view payment_id_str, crypto::hash& pa return false; } //---------------------------------------------------------------------------------------------------- -bool wallet2::prepare_file_names(const std::string& file_path) +bool wallet2::prepare_file_names(const fs::path& file_path) { do_prepare_file_names(file_path, m_keys_file, m_wallet_file, m_mms_file); return true; @@ -5656,7 +5644,7 @@ void wallet2::generate_chacha_key_from_password(const epee::wipeable_string &pas crypto::generate_chacha_key(pass.data(), pass.size(), key, m_kdf_rounds); } //---------------------------------------------------------------------------------------------------- -void wallet2::load(const std::string& wallet_, const epee::wipeable_string& password, const std::string& keys_buf, const std::string& cache_buf) +void wallet2::load(const fs::path& wallet_, const epee::wipeable_string& password, const std::string& keys_buf, const std::string& cache_buf) { clear(); prepare_file_names(wallet_); @@ -5665,13 +5653,13 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass bool use_fs = !wallet_.empty(); THROW_WALLET_EXCEPTION_IF((use_fs && !keys_buf.empty()) || (!use_fs && keys_buf.empty()), error::file_read_error, "must load keys either from file system or from buffer");\ - boost::system::error_code e; + std::error_code e; if (use_fs) { - bool exists = boost::filesystem::exists(m_keys_file, e); + bool exists = fs::exists(m_keys_file, e); THROW_WALLET_EXCEPTION_IF(e || !exists, error::file_not_found, m_keys_file); lock_keys_file(); - THROW_WALLET_EXCEPTION_IF(!is_keys_file_locked(), error::wallet_internal_error, "internal error: \"" + m_keys_file + "\" is opened by another wallet program"); + THROW_WALLET_EXCEPTION_IF(!is_keys_file_locked(), error::wallet_internal_error, "internal error: \"" + m_keys_file.u8string() + "\" is opened by another wallet program"); // this temporary unlocking is necessary for Windows (otherwise the file couldn't be loaded). unlock_keys_file(); @@ -5691,7 +5679,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass //keys loaded ok! //try to load wallet file. but even if we failed, it is not big problem - if (use_fs && (!boost::filesystem::exists(m_wallet_file, e) || e)) + if (use_fs && (!fs::exists(m_wallet_file, e) || e)) { LOG_PRINT_L0("file not found: " << m_wallet_file << ", starting with empty blockchain"); m_account_public_address = m_account.get_keys().m_account_address; @@ -5703,7 +5691,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass bool r = true; if (use_fs) { - load_from_file(m_wallet_file, cache_file_buf, std::numeric_limits::max()); + load_from_file(m_wallet_file, cache_file_buf); THROW_WALLET_EXCEPTION_IF(!r, error::file_read_error, m_wallet_file); } @@ -5715,7 +5703,7 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass try { serialization::parse_binary(use_fs ? cache_file_buf : cache_buf, cache_file_data); } catch (const std::exception& e) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, "internal error: failed to deserialize \"" + m_wallet_file + "\": " + e.what()); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, "internal error: failed to deserialize \"" + m_wallet_file.u8string() + "\": " + e.what()); } std::string cache_data; cache_data.resize(cache_file_data.cache_data.size()); @@ -5752,9 +5740,10 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass catch (...) { LOG_PRINT_L0("Failed to open portable binary, trying unportable"); - if (use_fs) boost::filesystem::copy_file(m_wallet_file, m_wallet_file + ".unportable", boost::filesystem::copy_option::overwrite_if_exists); + auto unportable = m_wallet_file; + unportable += ".unportable"; + if (use_fs) fs::copy_file(m_wallet_file, unportable, fs::copy_options::overwrite_existing); std::stringstream iss; - iss.str(""); iss << cache_data; boost::archive::binary_iarchive ar(iss); ar >> *this; @@ -5774,9 +5763,10 @@ void wallet2::load(const std::string& wallet_, const epee::wipeable_string& pass catch (...) { LOG_PRINT_L0("Failed to open portable binary, trying unportable"); - if (use_fs) boost::filesystem::copy_file(m_wallet_file, m_wallet_file + ".unportable", boost::filesystem::copy_option::overwrite_if_exists); + auto unportable = m_wallet_file; + unportable += ".unportable"; + if (use_fs) fs::copy_file(m_wallet_file, unportable, fs::copy_options::overwrite_existing); std::stringstream iss; - iss.str(""); iss << cache_file_buf; boost::archive::binary_iarchive ar(iss); ar >> *this; @@ -5846,7 +5836,7 @@ void wallet2::trim_hashchain() if (r && res.status == rpc::STATUS_OK) { crypto::hash hash; - epee::string_tools::hex_to_pod(res.block_header->hash, hash); + tools::hex_to_type(res.block_header->hash, hash); m_blockchain.refill(hash); } else @@ -5868,7 +5858,7 @@ void wallet2::check_genesis(const crypto::hash& genesis_hash) const { THROW_WALLET_EXCEPTION_IF(genesis_hash != m_blockchain.genesis(), error::wallet_internal_error, what); } //---------------------------------------------------------------------------------------------------- -std::string wallet2::path() const +const fs::path& wallet2::path() const { return m_wallet_file; } @@ -5879,7 +5869,7 @@ void wallet2::store() store_to("", epee::wipeable_string()); } //---------------------------------------------------------------------------------------------------- -void wallet2::store_to(const std::string &path, const epee::wipeable_string &password) +void wallet2::store_to(const fs::path &path, const epee::wipeable_string &password) { trim_hashchain(); @@ -5889,40 +5879,28 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas // 3. rename *.new to wallet_name // handle if we want just store wallet state to current files (ex store() replacement); - bool same_file = true; - if (!path.empty()) - { - std::string canonical_path = boost::filesystem::canonical(m_wallet_file).string(); - size_t pos = canonical_path.find(path); - same_file = pos != std::string::npos; - } - + std::error_code ec; + bool same_file = path.empty() || (fs::exists(path, ec) && fs::equivalent(m_wallet_file, path, ec)); if (!same_file) { // check if we want to store to directory which doesn't exists yet - boost::filesystem::path parent_path = boost::filesystem::path(path).parent_path(); + auto parent_path = path.parent_path(); // if path is not exists, try to create it - if (!parent_path.empty() && !boost::filesystem::exists(parent_path)) - { - boost::system::error_code ec; - if (!boost::filesystem::create_directories(parent_path, ec)) - { - throw std::logic_error(ec.message()); - } - } + if (!parent_path.empty() && !fs::exists(parent_path)) + fs::create_directories(parent_path); } // get wallet cache data std::optional cache_file_data = get_cache_file_data(password); THROW_WALLET_EXCEPTION_IF(!cache_file_data, error::wallet_internal_error, "failed to generate wallet cache data"); - const std::string new_file = same_file ? m_wallet_file + ".new" : path; - const std::string old_file = m_wallet_file; - const std::string old_keys_file = m_keys_file; - const std::string old_address_file = m_wallet_file + ".address.txt"; - const std::string old_mms_file = m_mms_file; + const auto& old_file = m_wallet_file; + const auto& old_keys_file = m_keys_file; + fs::path old_address_file = m_wallet_file; + old_address_file += ".address.txt"; + const auto& old_mms_file = m_mms_file; // save keys to the new file // if we here, main wallet file is saved and we only need to save keys and address files @@ -5930,63 +5908,45 @@ void wallet2::store_to(const std::string &path, const epee::wipeable_string &pas prepare_file_names(path); bool r = store_keys(m_keys_file, password, false); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_keys_file); - if (boost::filesystem::exists(old_address_file)) + if (fs::exists(old_address_file)) { // save address to the new file - const std::string address_file = m_wallet_file + ".address.txt"; + fs::path address_file = path; + address_file += ".address.txt"; r = save_to_file(address_file, m_account.get_public_address_str(m_nettype), true); THROW_WALLET_EXCEPTION_IF(!r, error::file_save_error, m_wallet_file); // remove old address file - r = boost::filesystem::remove(old_address_file); - if (!r) { - LOG_ERROR("error removing file: " << old_address_file); - } + if (!fs::remove(old_address_file, ec)) + LOG_ERROR("error removing file: " << old_address_file << ": " << ec.message()); } // remove old wallet file - r = boost::filesystem::remove(old_file); - if (!r) { - LOG_ERROR("error removing file: " << old_file); - } + if (!fs::remove(old_file, ec)) + LOG_ERROR("error removing file: " << old_file << ": " << ec.message()); // remove old keys file - r = boost::filesystem::remove(old_keys_file); - if (!r) { - LOG_ERROR("error removing file: " << old_keys_file); - } + if (!fs::remove(old_keys_file, ec)) + LOG_ERROR("error removing file: " << old_keys_file << ": " << ec.message()); // remove old message store file - if (boost::filesystem::exists(old_mms_file)) - { - r = boost::filesystem::remove(old_mms_file); - if (!r) { - LOG_ERROR("error removing file: " << old_mms_file); - } - } + if (fs::exists(old_mms_file, ec) && !fs::remove(old_mms_file, ec)) + LOG_ERROR("error removing file: " << old_mms_file << ": " << ec.message()); } else { // save to new file -#ifdef WIN32 - // On Windows avoid using std::ofstream which does not work with UTF-8 filenames - // The price to pay is temporary higher memory consumption for string stream + binary archive - bool success = false; + fs::path new_file = m_wallet_file; + new_file += ".new"; + try { - serialization::binary_string_archiver oar; - serialization::serialize(oar, *cache_file_data); - success = save_to_file(new_file, oar.str()); - } catch (...) {} - THROW_WALLET_EXCEPTION_IF(!success, error::file_save_error, new_file); -#else - try { - std::ofstream ostr{new_file, std::ios_base::binary | std::ios_base::trunc}; + fs::ofstream ostr{new_file, std::ios_base::binary | std::ios_base::trunc}; serialization::binary_archiver oar{ostr}; serialization::serialize(oar, *cache_file_data); } catch (const std::exception& e) { THROW_WALLET_EXCEPTION(error::file_save_error, new_file); } -#endif // here we have "*.new" file, we need to rename it to be without ".new" - std::error_code e = tools::replace_file(new_file, m_wallet_file); + std::error_code e; + fs::rename(new_file, m_wallet_file, e); THROW_WALLET_EXCEPTION_IF(e, error::file_save_error, m_wallet_file, e); } - + if (m_message_store.get_active()) { // While the "m_message_store" object of course always exist, a file for the message @@ -6170,9 +6130,9 @@ static void set_confirmations(wallet::transfer_view &entry, uint64_t blockchain_ wallet::transfer_view wallet2::make_transfer_view(const crypto::hash &txid, const crypto::hash &payment_id, const tools::wallet2::payment_details &pd) const { wallet::transfer_view result = {}; - result.txid = string_tools::pod_to_hex(pd.m_tx_hash); + result.txid = tools::type_to_hex(pd.m_tx_hash); result.hash = txid; - result.payment_id = string_tools::pod_to_hex(payment_id); + result.payment_id = tools::type_to_hex(payment_id); if (result.payment_id.substr(16).find_first_not_of('0') == std::string::npos) result.payment_id = result.payment_id.substr(0,16); result.height = pd.m_block_height; @@ -6200,9 +6160,9 @@ wallet::transfer_view wallet2::make_transfer_view(const crypto::hash &txid, cons wallet::transfer_view wallet2::wallet2::make_transfer_view(const crypto::hash &txid, const tools::wallet2::confirmed_transfer_details &pd) const { wallet::transfer_view result = {}; - result.txid = string_tools::pod_to_hex(txid); + result.txid = tools::type_to_hex(txid); result.hash = txid; - result.payment_id = string_tools::pod_to_hex(pd.m_payment_id); + result.payment_id = tools::type_to_hex(pd.m_payment_id); if (result.payment_id.substr(16).find_first_not_of('0') == std::string::npos) result.payment_id = result.payment_id.substr(0,16); result.height = pd.m_block_height; @@ -6236,10 +6196,10 @@ wallet::transfer_view wallet2::make_transfer_view(const crypto::hash &txid, cons { wallet::transfer_view result = {}; bool is_failed = pd.m_state == tools::wallet2::unconfirmed_transfer_details::failed; - result.txid = string_tools::pod_to_hex(txid); + result.txid = tools::type_to_hex(txid); result.hash = txid; - result.payment_id = string_tools::pod_to_hex(pd.m_payment_id); - result.payment_id = string_tools::pod_to_hex(pd.m_payment_id); + result.payment_id = tools::type_to_hex(pd.m_payment_id); + result.payment_id = tools::type_to_hex(pd.m_payment_id); if (result.payment_id.substr(16).find_first_not_of('0') == std::string::npos) result.payment_id = result.payment_id.substr(0,16); result.height = 0; @@ -6271,9 +6231,9 @@ wallet::transfer_view wallet2::make_transfer_view(const crypto::hash &payment_id { wallet::transfer_view result = {}; const tools::wallet2::payment_details &pd = ppd.m_pd; - result.txid = string_tools::pod_to_hex(pd.m_tx_hash); + result.txid = tools::type_to_hex(pd.m_tx_hash); result.hash = pd.m_tx_hash; - result.payment_id = string_tools::pod_to_hex(payment_id); + result.payment_id = tools::type_to_hex(payment_id); if (result.payment_id.substr(16).find_first_not_of('0') == std::string::npos) result.payment_id = result.payment_id.substr(0,16); result.height = 0; @@ -6564,7 +6524,7 @@ void wallet2::rescan_spent() rpc::IS_KEY_IMAGE_SPENT::request req{}; rpc::IS_KEY_IMAGE_SPENT::response daemon_resp{}; for (size_t n = start_offset; n < start_offset + n_outputs; ++n) - req.key_images.push_back(string_tools::pod_to_hex(m_transfers[n].m_key_image)); + req.key_images.push_back(tools::type_to_hex(m_transfers[n].m_key_image)); bool r = invoke_http(req, daemon_resp); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "is_key_image_spent"); THROW_WALLET_EXCEPTION_IF(daemon_resp.status == rpc::STATUS_BUSY, error::daemon_busy, "is_key_image_spent"); @@ -6944,8 +6904,8 @@ void wallet2::commit_tx(pending_tx& ptx, bool blink) light_rpc::SUBMIT_RAW_TX::request oreq{}; light_rpc::SUBMIT_RAW_TX::response ores{}; oreq.address = get_account().get_public_address_str(m_nettype); - oreq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); - oreq.tx = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx)); + oreq.view_key = tools::type_to_hex(get_account().get_keys().m_view_secret_key); + oreq.tx = lokimq::to_hex(tx_to_blob(ptx.tx)); oreq.blink = blink; bool r = invoke_http(oreq, ores); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "submit_raw_tx"); @@ -6956,7 +6916,7 @@ void wallet2::commit_tx(pending_tx& ptx, bool blink) { // Normal submit rpc::SEND_RAW_TX::request req{}; - req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx)); + req.tx_as_hex = lokimq::to_hex(tx_to_blob(ptx.tx)); req.do_not_relay = false; req.do_sanity_checks = true; req.blink = blink; @@ -7022,7 +6982,7 @@ void wallet2::commit_tx(std::vector& ptx_vector, bool blink) } } //---------------------------------------------------------------------------------------------------- -bool wallet2::save_tx(const std::vector& ptx_vector, const std::string &filename) const +bool wallet2::save_tx(const std::vector& ptx_vector, const fs::path& filename) const { LOG_PRINT_L0("saving " << ptx_vector.size() << " transactions"); std::string ciphertext = dump_tx_to_str(ptx_vector); @@ -7060,17 +7020,16 @@ std::string wallet2::dump_tx_to_str(const std::vector &ptx_vector) c return std::string(UNSIGNED_TX_PREFIX) + ciphertext; } //---------------------------------------------------------------------------------------------------- -bool wallet2::load_unsigned_tx(const std::string &unsigned_filename, unsigned_tx_set &exported_txs) const +bool wallet2::load_unsigned_tx(const fs::path& unsigned_filename, unsigned_tx_set& exported_txs) const { - std::string s; - boost::system::error_code errcode; - - if (!boost::filesystem::exists(unsigned_filename, errcode)) + if (std::error_code ec; !fs::exists(unsigned_filename, ec)) { - LOG_PRINT_L0("File " << unsigned_filename << " does not exist: " << errcode); + LOG_PRINT_L0("File " << unsigned_filename << " does not exist: " << ec.message()); return false; } - if (!load_from_file(unsigned_filename.c_str(), s)) + + std::string s; + if (!load_from_file(unsigned_filename, s)) { LOG_PRINT_L0("Failed to load from " << unsigned_filename); return false; @@ -7137,7 +7096,7 @@ bool wallet2::parse_unsigned_tx_from_str(std::string_view s, unsigned_tx_set &ex return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::vector &txs, std::function accept_func, bool export_raw) +bool wallet2::sign_tx(const fs::path& unsigned_filename, const fs::path& signed_filename, std::vector& txs, std::function accept_func, bool export_raw) { unsigned_tx_set exported_txs; if(!load_unsigned_tx(unsigned_filename, exported_txs)) @@ -7283,7 +7242,7 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, std::vector &txs, bool export_raw) +bool wallet2::sign_tx(unsigned_tx_set& exported_txs, const fs::path& signed_filename, std::vector& txs, bool export_raw) { // sign the transactions signed_tx_set signed_txes; @@ -7304,8 +7263,10 @@ bool wallet2::sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_f { for (size_t i = 0; i < signed_txes.ptx.size(); ++i) { - std::string tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(signed_txes.ptx[i].tx)); - std::string raw_filename = signed_filename + "_raw" + (signed_txes.ptx.size() == 1 ? "" : ("_" + std::to_string(i))); + std::string tx_as_hex = lokimq::to_hex(tx_to_blob(signed_txes.ptx[i].tx)); + fs::path raw_filename = signed_filename; + raw_filename += "_raw"; + if (signed_txes.ptx.size() > 1) raw_filename += "_" + std::to_string(i); if (!save_to_file(raw_filename, tx_as_hex)) { LOG_PRINT_L0("Failed to save file to " << raw_filename); @@ -7342,19 +7303,16 @@ std::string wallet2::sign_tx_dump_to_str(unsigned_tx_set &exported_txs, std::vec return std::string(SIGNED_TX_PREFIX) + ciphertext; } //---------------------------------------------------------------------------------------------------- -bool wallet2::load_tx(const std::string &signed_filename, std::vector &ptx, std::function accept_func) +bool wallet2::load_tx(const fs::path& signed_filename, std::vector& ptx, std::function accept_func) { - std::string s; - boost::system::error_code errcode; - signed_tx_set signed_txs; - - if (!boost::filesystem::exists(signed_filename, errcode)) + if (std::error_code ec; !fs::exists(signed_filename, ec)) { - LOG_PRINT_L0("File " << signed_filename << " does not exist: " << errcode); + LOG_PRINT_L0("File " << signed_filename << " does not exist: " << ec); return false; } - if (!load_from_file(signed_filename.c_str(), s)) + std::string s; + if (!load_from_file(signed_filename, s)) { LOG_PRINT_L0("Failed to load from " << signed_filename); return false; @@ -7478,7 +7436,7 @@ std::string wallet2::save_multisig_tx(multisig_tx_set txs) return std::string(MULTISIG_UNSIGNED_TX_PREFIX) + ciphertext; } //---------------------------------------------------------------------------------------------------- -bool wallet2::save_multisig_tx(const multisig_tx_set &txs, const std::string &filename) +bool wallet2::save_multisig_tx(const multisig_tx_set& txs, const fs::path& filename) { std::string ciphertext = save_multisig_tx(txs); if (ciphertext.empty()) @@ -7506,7 +7464,7 @@ std::string wallet2::save_multisig_tx(const std::vector& ptx_vector) return save_multisig_tx(make_multisig_tx_set(ptx_vector)); } //---------------------------------------------------------------------------------------------------- -bool wallet2::save_multisig_tx(const std::vector& ptx_vector, const std::string &filename) +bool wallet2::save_multisig_tx(const std::vector& ptx_vector, const fs::path& filename) { std::string ciphertext = save_multisig_tx(ptx_vector); if (ciphertext.empty()) @@ -7591,17 +7549,16 @@ bool wallet2::load_multisig_tx(cryptonote::blobdata s, multisig_tx_set &exported return true; } //---------------------------------------------------------------------------------------------------- -bool wallet2::load_multisig_tx_from_file(const std::string &filename, multisig_tx_set &exported_txs, std::function accept_func) +bool wallet2::load_multisig_tx_from_file(const fs::path& filename, multisig_tx_set& exported_txs, std::function accept_func) { - std::string s; - boost::system::error_code errcode; - - if (!boost::filesystem::exists(filename, errcode)) + if (std::error_code ec; !fs::exists(filename, ec)) { - LOG_PRINT_L0("File " << filename << " does not exist: " << errcode); + LOG_PRINT_L0("File " << filename << " does not exist: " << ec.message()); return false; } - if (!load_from_file(filename.c_str(), s)) + + std::string s; + if (!load_from_file(filename, s)) { LOG_PRINT_L0("Failed to load from " << filename); return false; @@ -7722,7 +7679,7 @@ bool wallet2::sign_multisig_tx(multisig_tx_set &exported_txs, std::vector &txids) +bool wallet2::sign_multisig_tx_to_file(multisig_tx_set& exported_txs, const fs::path& filename, std::vector& txids) { bool r = sign_multisig_tx(exported_txs, txids); if (!r) @@ -7730,7 +7687,7 @@ bool wallet2::sign_multisig_tx_to_file(multisig_tx_set &exported_txs, const std: return save_multisig_tx(exported_txs, filename); } //---------------------------------------------------------------------------------------------------- -bool wallet2::sign_multisig_tx_from_file(const std::string &filename, std::vector &txids, std::function accept_func) +bool wallet2::sign_multisig_tx_from_file(const fs::path& filename, std::vector &txids, std::function accept_func) { multisig_tx_set exported_txs; if(!load_multisig_tx_from_file(filename, exported_txs)) @@ -7842,10 +7799,10 @@ loki_construct_tx_params wallet2::construct_params(uint8_t hf_version, txtype tx //---------------------------------------------------------------------------------------------------- -bool wallet2::set_ring_database(const std::string &filename) +bool wallet2::set_ring_database(fs::path filename) { - m_ring_database = filename; - MINFO("ringdb path set to " << filename); + m_ring_database = std::move(filename); + MINFO("ringdb path set to " << m_ring_database.u8string()); m_ringdb.reset(); if (!m_ring_database.empty()) { @@ -7853,12 +7810,12 @@ bool wallet2::set_ring_database(const std::string &filename) { cryptonote::block b; generate_genesis(b); - m_ringdb.reset(new tools::ringdb(m_ring_database, epee::string_tools::pod_to_hex(get_block_hash(b)))); + m_ringdb = std::make_unique(m_ring_database, tools::type_to_hex(get_block_hash(b))); } catch (const std::exception &e) { MERROR("Failed to initialize ringdb: " << e.what()); - m_ring_database = ""; + m_ring_database.clear(); return false; } } @@ -8430,14 +8387,14 @@ wallet2::register_service_node_result wallet2::create_register_service_node_tx(c return result; } - if (!epee::string_tools::hex_to_pod(local_args[key_index], service_node_key)) + if (!tools::hex_to_type(local_args[key_index], service_node_key)) { result.status = register_service_node_result_status::service_node_key_parse_fail; result.msg = tr("Failed to parse service node pubkey"); return result; } - if (!epee::string_tools::hex_to_pod(local_args[signature_index], signature)) + if (!tools::hex_to_type(local_args[signature_index], signature)) { result.status = register_service_node_result_status::service_node_signature_parse_fail; result.msg = tr("Failed to parse service node signature"); @@ -8767,7 +8724,7 @@ static lns_prepared_args prepare_tx_extra_loki_name_system_values(wallet2 const if (response->size()) { - if (!epee::string_tools::hex_to_pod((*response)[0].txid, result.prev_txid)) + if (!tools::hex_to_type((*response)[0].txid, result.prev_txid)) { if (reason) *reason = "Failed to convert response txid=" + (*response)[0].txid + " from the daemon into a 32 byte hash, it must be a 64 char hex string"; return result; @@ -8945,7 +8902,7 @@ std::vector wallet2::lns_create_update_mapping_tx(lns::mapp if (!make_signature) { - if (!epee::string_tools::hex_to_pod(*signature, prepared_args.signature.ed25519)) + if (!tools::hex_to_type(*signature, prepared_args.signature.ed25519)) { if (reason) *reason = "Hex signature provided failed to convert to a signature, signature=" + *signature; return {}; @@ -9128,7 +9085,7 @@ void wallet2::light_wallet_get_outs(std::vector order; @@ -9163,8 +9120,9 @@ void wallet2::light_wallet_get_outs(std::vector(request, response); @@ -10346,7 +10304,7 @@ bool wallet2::light_wallet_import_wallet_request(light_rpc::IMPORT_WALLET_REQUES MDEBUG("Light wallet import wallet request"); light_rpc::IMPORT_WALLET_REQUEST::request oreq{}; oreq.address = get_account().get_public_address_str(m_nettype); - oreq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); + oreq.view_key = tools::type_to_hex(get_account().get_keys().m_view_secret_key); bool r = invoke_http(oreq, response); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "import_wallet_request"); @@ -10363,7 +10321,7 @@ void wallet2::light_wallet_get_unspent_outs() oreq.amount = "0"; oreq.address = get_account().get_public_address_str(m_nettype); - oreq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); + oreq.view_key = tools::type_to_hex(get_account().get_keys().m_view_secret_key); // openMonero specific oreq.dust_threshold = boost::lexical_cast(::config::DEFAULT_DUST_THRESHOLD); // below are required by openMonero api - but are not used. @@ -10395,15 +10353,15 @@ void wallet2::light_wallet_get_unspent_outs() bool add_transfer = true; crypto::key_image unspent_key_image; crypto::public_key tx_public_key{}; - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, o.tx_pub_key), error::wallet_internal_error, "Invalid tx_pub_key field"); - string_tools::hex_to_pod(o.tx_pub_key, tx_public_key); + THROW_WALLET_EXCEPTION_IF(o.tx_pub_key.size() != 64 || !lokimq::is_hex(o.tx_pub_key), error::wallet_internal_error, "Invalid tx_pub_key field"); + tools::hex_to_type(o.tx_pub_key, tx_public_key); for (const std::string &ski: o.spend_key_images) { spent = false; // Check if key image is ours - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, ski), error::wallet_internal_error, "Invalid key image"); - string_tools::hex_to_pod(ski, unspent_key_image); + THROW_WALLET_EXCEPTION_IF(ski.size() != 64 || !lokimq::is_hex(ski), error::wallet_internal_error, "Invalid key image"); + tools::hex_to_type(ski, unspent_key_image); if(light_wallet_key_image_is_ours(unspent_key_image, tx_public_key, o.index)){ MTRACE("Output " << o.public_key << " is spent. Key image: " << ski); spent = true; @@ -10417,12 +10375,12 @@ void wallet2::light_wallet_get_unspent_outs() crypto::hash txid; crypto::public_key tx_pub_key; crypto::public_key public_key; - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, o.tx_hash), error::wallet_internal_error, "Invalid tx_hash field"); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, o.public_key), error::wallet_internal_error, "Invalid public_key field"); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, o.tx_pub_key), error::wallet_internal_error, "Invalid tx_pub_key field"); - string_tools::hex_to_pod(o.tx_hash, txid); - string_tools::hex_to_pod(o.public_key, public_key); - string_tools::hex_to_pod(o.tx_pub_key, tx_pub_key); + THROW_WALLET_EXCEPTION_IF(o.tx_hash.size() != 64 || !lokimq::is_hex(o.tx_hash), error::wallet_internal_error, "Invalid tx_hash field"); + THROW_WALLET_EXCEPTION_IF(o.public_key.size() != 64 || !lokimq::is_hex(o.public_key), error::wallet_internal_error, "Invalid public_key field"); + THROW_WALLET_EXCEPTION_IF(o.tx_pub_key.size() != 64 || !lokimq::is_hex(o.tx_pub_key), error::wallet_internal_error, "Invalid tx_pub_key field"); + tools::hex_to_type(o.tx_hash, txid); + tools::hex_to_type(o.public_key, public_key); + tools::hex_to_type(o.tx_pub_key, tx_pub_key); for(auto &t: m_transfers){ if(t.get_public_key() == public_key) { @@ -10487,9 +10445,9 @@ void wallet2::light_wallet_get_unspent_outs() if(!valid_commit) { MDEBUG("output index: " << o.global_index); - MDEBUG("mask: " + string_tools::pod_to_hex(td.m_mask)); - MDEBUG("calculated commit: " + string_tools::pod_to_hex(rct::commit(td.amount(), td.m_mask))); - MDEBUG("expected commit: " + string_tools::pod_to_hex(rct_commit)); + MDEBUG("mask: " + tools::type_to_hex(td.m_mask)); + MDEBUG("calculated commit: " + tools::type_to_hex(rct::commit(td.amount(), td.m_mask))); + MDEBUG("expected commit: " + tools::type_to_hex(rct_commit)); MDEBUG("amount: " << td.amount()); } THROW_WALLET_EXCEPTION_IF(!valid_commit, error::wallet_internal_error, "Lightwallet: rct commit hash mismatch!"); @@ -10515,7 +10473,7 @@ bool wallet2::light_wallet_get_address_info(light_rpc::GET_ADDRESS_INFO::respons light_rpc::GET_ADDRESS_INFO::request request{}; request.address = get_account().get_public_address_str(m_nettype); - request.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); + request.view_key = tools::type_to_hex(get_account().get_keys().m_view_secret_key); bool r = invoke_http(request, response); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_address_info"); // TODO: Validate result @@ -10530,7 +10488,7 @@ void wallet2::light_wallet_get_address_txs() light_rpc::GET_ADDRESS_TXS::response ires{}; ireq.address = get_account().get_public_address_str(m_nettype); - ireq.view_key = string_tools::pod_to_hex(get_account().get_keys().m_view_secret_key); + ireq.view_key = tools::type_to_hex(get_account().get_keys().m_view_secret_key); bool r = invoke_http(ireq, ires); THROW_WALLET_EXCEPTION_IF(!r, error::no_connection_to_daemon, "get_address_txs"); //OpenMonero sends status=success, Mymonero doesn't. @@ -10563,10 +10521,10 @@ void wallet2::light_wallet_get_address_txs() { crypto::public_key tx_public_key; crypto::key_image key_image; - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, so.tx_pub_key), error::wallet_internal_error, "Invalid tx_pub_key field"); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, so.key_image), error::wallet_internal_error, "Invalid key_image field"); - string_tools::hex_to_pod(so.tx_pub_key, tx_public_key); - string_tools::hex_to_pod(so.key_image, key_image); + THROW_WALLET_EXCEPTION_IF(so.tx_pub_key.size() != 64 || !lokimq::is_hex(so.tx_pub_key), error::wallet_internal_error, "Invalid tx_pub_key field"); + THROW_WALLET_EXCEPTION_IF(so.key_image.size() != 64 || !lokimq::is_hex(so.key_image), error::wallet_internal_error, "Invalid key_image field"); + tools::hex_to_type(so.tx_pub_key, tx_public_key); + tools::hex_to_type(so.key_image, key_image); if(!light_wallet_key_image_is_ours(key_image, tx_public_key, so.out_index)) { THROW_WALLET_EXCEPTION_IF(so.amount > t.total_sent, error::wallet_internal_error, "Lightwallet: total sent is negative!"); @@ -10581,10 +10539,10 @@ void wallet2::light_wallet_get_address_txs() crypto::hash payment_id = null_hash; crypto::hash tx_hash; - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, t.payment_id), error::wallet_internal_error, "Invalid payment_id field"); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, t.hash), error::wallet_internal_error, "Invalid hash field"); - string_tools::hex_to_pod(t.payment_id, payment_id); - string_tools::hex_to_pod(t.hash, tx_hash); + THROW_WALLET_EXCEPTION_IF(t.payment_id.size() != 64 || !lokimq::is_hex(t.payment_id), error::wallet_internal_error, "Invalid payment_id field"); + THROW_WALLET_EXCEPTION_IF(t.hash.size() != 64 || !lokimq::is_hex(t.hash), error::wallet_internal_error, "Invalid hash field"); + tools::hex_to_type(t.payment_id, payment_id); + tools::hex_to_type(t.hash, tx_hash); // lightwallet specific info bool incoming = (total_received > total_sent); @@ -10621,7 +10579,7 @@ void wallet2::light_wallet_get_address_txs() pool_txs.push_back(tx_hash); // assume false as we don't get that info from the light wallet server crypto::hash payment_id; - THROW_WALLET_EXCEPTION_IF(!epee::string_tools::hex_to_pod(t.payment_id, payment_id), + THROW_WALLET_EXCEPTION_IF(!tools::hex_to_type(t.payment_id, payment_id), error::wallet_internal_error, "Failed to parse payment id"); emplace_or_replace(m_unconfirmed_payments, payment_id, pool_payment_details{payment, false}); if (0 != m_callback) { @@ -10721,10 +10679,10 @@ bool wallet2::light_wallet_parse_rct_str(const std::string& rct_string, const cr rct::key encrypted_mask; std::string rct_commit_str = rct_string.substr(0,64); std::string encrypted_mask_str = rct_string.substr(64,64); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, rct_commit_str), error::wallet_internal_error, "Invalid rct commit hash: " + rct_commit_str); - THROW_WALLET_EXCEPTION_IF(string_tools::validate_hex(64, encrypted_mask_str), error::wallet_internal_error, "Invalid rct mask: " + encrypted_mask_str); - string_tools::hex_to_pod(rct_commit_str, rct_commit); - string_tools::hex_to_pod(encrypted_mask_str, encrypted_mask); + THROW_WALLET_EXCEPTION_IF(rct_commit_str.size() != 64 || !lokimq::is_hex(rct_commit_str), error::wallet_internal_error, "Invalid rct commit hash: " + rct_commit_str); + THROW_WALLET_EXCEPTION_IF(encrypted_mask_str.size() != 64 || !lokimq::is_hex(encrypted_mask_str), error::wallet_internal_error, "Invalid rct mask: " + encrypted_mask_str); + tools::hex_to_type(rct_commit_str, rct_commit); + tools::hex_to_type(encrypted_mask_str, encrypted_mask); if (decrypt) { // Decrypt the mask crypto::key_derivation derivation; @@ -12825,7 +12783,7 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr rpc::IS_KEY_IMAGE_SPENT::request kispent_req{}; rpc::IS_KEY_IMAGE_SPENT::response kispent_res{}; for (size_t i = 0; i < proofs.size(); ++i) - kispent_req.key_images.push_back(epee::string_tools::pod_to_hex(proofs[i].key_image)); + kispent_req.key_images.push_back(tools::type_to_hex(proofs[i].key_image)); bool ok = invoke_http(kispent_req, kispent_res); THROW_WALLET_EXCEPTION_IF(!ok || kispent_res.spent_status.size() != proofs.size(), error::wallet_internal_error, "Failed to get key image spent status from daemon"); @@ -12931,12 +12889,12 @@ bool wallet2::check_reserve_proof(const cryptonote::account_public_address &addr return true; } -std::string wallet2::get_wallet_file() const +const fs::path& wallet2::get_wallet_file() const { return m_wallet_file; } -std::string wallet2::get_keys_file() const +const fs::path& wallet2::get_keys_file() const { return m_keys_file; } @@ -13242,7 +13200,7 @@ crypto::public_key wallet2::get_tx_pub_key_from_received_outs(const tools::walle return tx_pub_key; } -bool wallet2::export_key_images_to_file(const std::string &filename, bool requested_only) const +bool wallet2::export_key_images_to_file(const fs::path& filename, bool requested_only) const { // NOTE: Exported Key Image File // [(magic bytes) (ciphertext..................................................................................) (hashed ciphertext signature)] @@ -13332,17 +13290,17 @@ std::pair>> return std::make_pair(offset, ski); } -uint64_t wallet2::import_key_images_from_file(const std::string &filename, uint64_t &spent, uint64_t &unspent) +uint64_t wallet2::import_key_images_from_file(const fs::path& filename, uint64_t& spent, uint64_t& unspent) { PERF_TIMER(__FUNCTION__); std::string data; bool r = load_from_file(filename, data); - THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename); + THROW_WALLET_EXCEPTION_IF(!r, error::wallet_internal_error, std::string(tr("failed to read file ")) + filename.u8string()); if (!tools::starts_with(data, KEY_IMAGE_EXPORT_FILE_MAGIC)) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Bad key image export file magic in ") + filename.u8string()); } try @@ -13352,11 +13310,11 @@ uint64_t wallet2::import_key_images_from_file(const std::string &filename, uint6 } catch (const std::exception &e) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename + ": " + e.what()); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string("Failed to decrypt ") + filename.u8string() + ": " + e.what()); } const size_t headerlen = 4 + 2 * sizeof(crypto::public_key); - THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename); + THROW_WALLET_EXCEPTION_IF(data.size() < headerlen, error::wallet_internal_error, std::string("Bad data size from file ") + filename.u8string()); uint32_t offset; std::memcpy(&offset, data.data(), sizeof(offset)); @@ -13372,13 +13330,13 @@ uint64_t wallet2::import_key_images_from_file(const std::string &filename, uint6 const cryptonote::account_public_address &keys = get_account().get_keys().m_account_address; if (public_spend_key != keys.m_spend_public_key || public_view_key != keys.m_view_public_key) { - THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename + " are for a different account"); + THROW_WALLET_EXCEPTION(error::wallet_internal_error, std::string( "Key images from ") + filename.u8string() + " are for a different account"); } } const size_t record_size = sizeof(crypto::key_image) + sizeof(crypto::signature); const size_t record_buffer_size = data.size() - headerlen; - THROW_WALLET_EXCEPTION_IF(record_buffer_size % record_size, error::wallet_internal_error, std::string("Bad data size from file ") + filename); + THROW_WALLET_EXCEPTION_IF(record_buffer_size % record_size, error::wallet_internal_error, std::string("Bad data size from file ") + filename.u8string()); const size_t num_records = record_buffer_size / record_size; std::vector> ski(num_records); @@ -13427,7 +13385,7 @@ uint64_t wallet2::import_key_images(const std::vector(out.target).key; - std::string const key_image_str = epee::string_tools::pod_to_hex(key_image); + std::string const key_image_str = tools::type_to_hex(key_image); if (!td.m_key_image_known || !(key_image == td.m_key_image)) { std::vector pkeys; @@ -13448,7 +13406,7 @@ uint64_t wallet2::import_key_images(const std::vector(binary.data()), binary.length()); fclose(fp); - if (write_result == 0) - { - return false; - } - else - { - return true; - } + return write_result != 0; } //---------------------------------------------------------------------------------------------------- -bool wallet2::load_from_file(const std::string& path_to_file, std::string& target_str, - size_t max_size) +bool wallet2::load_from_file(const fs::path& path_to_file, std::string& target_str) { std::string data; - bool r = epee::file_io_utils::load_file_to_string(path_to_file, data, max_size); - if (!r) - { + if (!tools::slurp_file(path_to_file, data)) return false; - } if (data.find(ASCII_OUTPUT_MAGIC) == std::string::npos) { diff --git a/src/wallet/wallet2.h b/src/wallet/wallet2.h index ecf689962..896198b8b 100644 --- a/src/wallet/wallet2.h +++ b/src/wallet/wallet2.h @@ -41,7 +41,6 @@ #include #include -#include "include_base_utils.h" #include "cryptonote_basic/account.h" #include "cryptonote_basic/account_boost_serialization.h" #include "cryptonote_basic/cryptonote_basic_impl.h" @@ -74,7 +73,7 @@ #include "multisig_sig.h" #include "common/loki_integration_test_hooks.h" -#include "wipeable_string.h" +#include "epee/wipeable_string.h" #include "rpc/http_client.h" @@ -268,20 +267,36 @@ private: static void init_options(boost::program_options::options_description& desc_params, boost::program_options::options_description& hidden_params); //! Uses stdin and stdout. Returns a wallet2 if no errors. - static std::pair, password_container> make_from_json(const boost::program_options::variables_map& vm, bool unattended, const std::string& json_file, const std::function(const char *, bool)> &password_prompter); + static std::pair, password_container> + make_from_json( + const boost::program_options::variables_map& vm, + bool unattended, + const fs::path& json_file, + const std::function(const char *, bool)> &password_prompter); //! Uses stdin and stdout. Returns a wallet2 and password for `wallet_file` if no errors. static std::pair, password_container> - make_from_file(const boost::program_options::variables_map& vm, bool unattended, const std::string& wallet_file, const std::function(const char *, bool)> &password_prompter); + make_from_file( + const boost::program_options::variables_map& vm, + bool unattended, + const fs::path& wallet_file, + const std::function(const char *, bool)> &password_prompter); //! Uses stdin and stdout. Returns a wallet2 and password for wallet with no file if no errors. - static std::pair, password_container> make_new(const boost::program_options::variables_map& vm, bool unattended, const std::function(const char *, bool)> &password_prompter); + static std::pair, password_container> + make_new( + const boost::program_options::variables_map& vm, + bool unattended, + const std::function(const char *, bool)> &password_prompter); //! Just parses variables. - static std::unique_ptr make_dummy(const boost::program_options::variables_map& vm, bool unattended, const std::function(const char *, bool)> &password_prompter); + static std::unique_ptr make_dummy( + const boost::program_options::variables_map& vm, + bool unattended, + const std::function(const char *, bool)> &password_prompter); - static bool verify_password(const std::string& keys_file_name, const epee::wipeable_string& password, bool no_spend_key, hw::device &hwdev, uint64_t kdf_rounds); - static bool query_device(hw::device::device_type& device_type, const std::string& keys_file_name, const epee::wipeable_string& password, uint64_t kdf_rounds = 1); + static bool verify_password(const fs::path& keys_file_name, const epee::wipeable_string& password, bool no_spend_key, hw::device &hwdev, uint64_t kdf_rounds); + static bool query_device(hw::device::device_type& device_type, const fs::path& keys_file_name, const epee::wipeable_string& password, uint64_t kdf_rounds = 1); wallet2(cryptonote::network_type nettype = cryptonote::MAINNET, uint64_t kdf_rounds = 1, bool unattended = false); ~wallet2(); @@ -462,10 +477,10 @@ private: * \param wallet_ Name of wallet file * \param password Password of wallet file * \param multisig_data The multisig restore info and keys - * \param create_address_file Whether to create an address file + * \param create_address_file Whether to create an address file (defaults to yes) */ - void generate(const std::string& wallet_, const epee::wipeable_string& password, - const epee::wipeable_string& multisig_data, bool create_address_file = false); + void generate(const fs::path& wallet_, const epee::wipeable_string& password, + const epee::wipeable_string& multisig_data, bool create_address_file = true); /*! * \brief Generates a wallet or restores one. @@ -474,12 +489,12 @@ private: * \param recovery_param If it is a restore, the recovery key * \param recover Whether it is a restore * \param two_random Whether it is a non-deterministic wallet - * \param create_address_file Whether to create an address file + * \param create_address_file Whether to create an address file (defaults to yes) * \return The secret key of the generated wallet */ - crypto::secret_key generate(const std::string& wallet, const epee::wipeable_string& password, + crypto::secret_key generate(const fs::path& wallet, const epee::wipeable_string& password, const crypto::secret_key& recovery_param = crypto::secret_key(), bool recover = false, - bool two_random = false, bool create_address_file = false); + bool two_random = false, bool create_address_file = true); /*! * \brief Creates a wallet from a public address and a spend/view secret key pair. * \param wallet_ Name of wallet file @@ -487,11 +502,11 @@ private: * \param account_public_address The account's public address * \param spendkey spend secret key * \param viewkey view secret key - * \param create_address_file Whether to create an address file + * \param create_address_file Whether to create an address file (defaults to yes) */ - void generate(const std::string& wallet, const epee::wipeable_string& password, + void generate(const fs::path& wallet, const epee::wipeable_string& password, const cryptonote::account_public_address &account_public_address, - const crypto::secret_key& spendkey, const crypto::secret_key& viewkey, bool create_address_file = false); + const crypto::secret_key& spendkey, const crypto::secret_key& viewkey, bool create_address_file = true); /*! * \brief Creates a watch only wallet from a public address and a view secret key. * \param wallet_ Name of wallet file @@ -500,9 +515,9 @@ private: * \param viewkey view secret key * \param create_address_file Whether to create an address file */ - void generate(const std::string& wallet, const epee::wipeable_string& password, + void generate(const fs::path& wallet, const epee::wipeable_string& password, const cryptonote::account_public_address &account_public_address, - const crypto::secret_key& viewkey = crypto::secret_key(), bool create_address_file = false); + const crypto::secret_key& viewkey = crypto::secret_key(), bool create_address_file = true); /*! * \brief Restore a wallet hold by an HW. * \param wallet_ Name of wallet file @@ -510,7 +525,7 @@ private: * \param device_name name of HW to use * \param create_address_file Whether to create an address file */ - void restore(const std::string& wallet_, const epee::wipeable_string& password, const std::string &device_name, bool create_address_file = false); + void restore(const fs::path& wallet_, const epee::wipeable_string& password, const std::string &device_name, bool create_address_file = true); /*! * \brief Creates a multisig wallet @@ -572,16 +587,16 @@ private: * \param wallet_name Name of wallet file (should exist) * \param password Password for wallet file */ - void rewrite(const std::string& wallet_name, const epee::wipeable_string& password); - void write_watch_only_wallet(const std::string& wallet_name, const epee::wipeable_string& password, std::string &new_keys_filename); - void load(const std::string& wallet, const epee::wipeable_string& password, const std::string& keys_buf = "", const std::string& cache_buf = ""); + void rewrite(const fs::path& wallet_name, const epee::wipeable_string& password); + void write_watch_only_wallet(const fs::path& wallet_name, const epee::wipeable_string& password, fs::path& new_keys_filename); + void load(const fs::path& wallet, const epee::wipeable_string& password, const std::string& keys_buf = "", const std::string& cache_buf = ""); void store(); /*! * \brief store_to Stores wallet to another file(s), deleting old ones * \param path Path to the wallet file (keys and address filenames will be generated based on this filename) * \param password Password to protect new wallet (TODO: probably better save the password in the wallet object?) */ - void store_to(const std::string &path, const epee::wipeable_string &password); + void store_to(const fs::path &path, const epee::wipeable_string &password); /*! * \brief get_keys_file_data Get wallet keys data which can be stored to a wallet file. * \param password Password of the encrypted wallet buffer (TODO: probably better save the password in the wallet object?) @@ -596,7 +611,7 @@ private: */ std::optional get_cache_file_data(const epee::wipeable_string& password); - std::string path() const; + const fs::path& path() const; /*! * \brief verifies given password is correct for default wallet keys file @@ -718,23 +733,23 @@ private: void commit_tx(pending_tx& ptx_vector, bool blink = false); void commit_tx(std::vector& ptx_vector, bool blink = false); - bool save_tx(const std::vector& ptx_vector, const std::string &filename) const; + bool save_tx(const std::vector& ptx_vector, const fs::path& filename) const; std::string dump_tx_to_str(const std::vector &ptx_vector) const; std::string save_multisig_tx(multisig_tx_set txs); - bool save_multisig_tx(const multisig_tx_set &txs, const std::string &filename); + bool save_multisig_tx(const multisig_tx_set& txs, const fs::path& filename); std::string save_multisig_tx(const std::vector& ptx_vector); - bool save_multisig_tx(const std::vector& ptx_vector, const std::string &filename); + bool save_multisig_tx(const std::vector& ptx_vector, const fs::path& filename); multisig_tx_set make_multisig_tx_set(const std::vector& ptx_vector) const; // load unsigned tx from file and sign it. Takes confirmation callback as argument. Used by the cli wallet - bool sign_tx(const std::string &unsigned_filename, const std::string &signed_filename, std::vector &ptx, std::function accept_func = NULL, bool export_raw = false); + bool sign_tx(const fs::path& unsigned_filename, const fs::path& signed_filename, std::vector &ptx, std::function accept_func = NULL, bool export_raw = false); // sign unsigned tx. Takes unsigned_tx_set as argument. Used by GUI - bool sign_tx(unsigned_tx_set &exported_txs, const std::string &signed_filename, std::vector &ptx, bool export_raw = false); + bool sign_tx(unsigned_tx_set& exported_txs, const fs::path& signed_filename, std::vector &ptx, bool export_raw = false); bool sign_tx(unsigned_tx_set &exported_txs, std::vector &ptx, signed_tx_set &signed_txs); std::string sign_tx_dump_to_str(unsigned_tx_set &exported_txs, std::vector &ptx, signed_tx_set &signed_txes); // load unsigned_tx_set from file. - bool load_unsigned_tx(const std::string &unsigned_filename, unsigned_tx_set &exported_txs) const; + bool load_unsigned_tx(const fs::path& unsigned_filename, unsigned_tx_set& exported_txs) const; bool parse_unsigned_tx_from_str(std::string_view unsigned_tx_st, unsigned_tx_set &exported_txs) const; - bool load_tx(const std::string &signed_filename, std::vector &ptx, std::function accept_func = NULL); + bool load_tx(const fs::path& signed_filename, std::vector& ptx, std::function accept_func = NULL); bool parse_tx_from_str(std::string_view signed_tx_st, std::vector &ptx, std::function accept_func); std::vector create_transactions_2(std::vector dsts, const size_t fake_outs_count, const uint64_t unlock_time, uint32_t priority, const std::vector& extra_base, uint32_t subaddr_account, std::set subaddr_indices, cryptonote::loki_construct_tx_params &tx_params); @@ -749,10 +764,10 @@ private: void device_show_address(uint32_t account_index, uint32_t address_index, const std::optional &payment_id); bool parse_multisig_tx_from_str(std::string_view multisig_tx_st, multisig_tx_set &exported_txs) const; bool load_multisig_tx(cryptonote::blobdata blob, multisig_tx_set &exported_txs, std::function accept_func = NULL); - bool load_multisig_tx_from_file(const std::string &filename, multisig_tx_set &exported_txs, std::function accept_func = NULL); - bool sign_multisig_tx_from_file(const std::string &filename, std::vector &txids, std::function accept_func); + bool load_multisig_tx_from_file(const fs::path& filename, multisig_tx_set &exported_txs, std::function accept_func = NULL); + bool sign_multisig_tx_from_file(const fs::path& filename, std::vector &txids, std::function accept_func); bool sign_multisig_tx(multisig_tx_set &exported_txs, std::vector &txids); - bool sign_multisig_tx_to_file(multisig_tx_set &exported_txs, const std::string &filename, std::vector &txids); + bool sign_multisig_tx_to_file(multisig_tx_set &exported_txs, const fs::path& filename, std::vector &txids); std::vector create_unmixable_sweep_transactions(); void discard_unmixable_outputs(); bool check_connection(cryptonote::rpc::version_t *version = nullptr, bool *ssl = nullptr, bool throw_on_http_error = false); @@ -948,15 +963,7 @@ private: * \param keys_file_exists Whether keys file exists * \param wallet_file_exists Whether bin file exists */ - static void wallet_exists(const std::string& file_path, bool& keys_file_exists, bool& wallet_file_exists); - /*! - * \brief Check if wallet file path is valid format - * \param file_path Wallet file path - * \return Whether path is valid format - */ - static bool wallet_valid_path_format(std::string_view file_path); - static bool parse_long_payment_id(std::string_view payment_id_str, crypto::hash& payment_id); - static bool parse_short_payment_id(std::string_view payment_id_str, crypto::hash8& payment_id); + static void wallet_exists(const fs::path& file_path, bool& keys_file_exists, bool& wallet_file_exists); static bool parse_payment_id(std::string_view payment_id_str, crypto::hash& payment_id); bool always_confirm_transfers() const { return m_always_confirm_transfers; } @@ -1055,8 +1062,8 @@ private: std::optional get_hard_fork_version() const { return m_node_rpc_proxy.get_hardfork_version(); } bool use_fork_rules(uint8_t version, uint64_t early_blocks = 0) const; - std::string get_wallet_file() const; - std::string get_keys_file() const; + const fs::path& get_wallet_file() const; + const fs::path& get_keys_file() const; std::string get_daemon_address() const; uint64_t get_daemon_blockchain_height(std::string& err) const; uint64_t get_daemon_blockchain_target_height(std::string& err); @@ -1129,10 +1136,10 @@ private: void import_payments_out(const std::list> &confirmed_payments); std::tuple> export_blockchain() const; void import_blockchain(const std::tuple> &bc); - bool export_key_images_to_file(const std::string &filename, bool requested_only) const; + bool export_key_images_to_file(const fs::path &filename, bool requested_only) const; std::pair>> export_key_images(bool requested_only) const; uint64_t import_key_images(const std::vector> &signed_key_images, size_t offset, uint64_t &spent, uint64_t &unspent, bool check_spent = true); - uint64_t import_key_images_from_file(const std::string &filename, uint64_t &spent, uint64_t &unspent); + uint64_t import_key_images_from_file(const fs::path& filename, uint64_t &spent, uint64_t &unspent); bool import_key_images(std::vector key_images, size_t offset=0, std::optional> selected_transfers=std::nullopt); bool import_key_images(signed_tx_set & signed_tx, size_t offset=0, bool only_selected_transfers=false); crypto::public_key get_tx_pub_key_from_received_outs(const transfer_details &td) const; @@ -1269,8 +1276,8 @@ private: return false; } - bool set_ring_database(const std::string &filename); - const std::string get_ring_database() const { return m_ring_database; } + bool set_ring_database(fs::path filename); + const fs::path& get_ring_database() const { return m_ring_database; } bool get_ring(const crypto::key_image &key_image, std::vector &outs); bool get_rings(const crypto::hash &txid, std::vector>> &outs); bool set_ring(const crypto::key_image &key_image, const std::vector &outs, bool relative); @@ -1380,8 +1387,8 @@ private: bool frozen(const crypto::key_image &ki) const; bool frozen(const transfer_details &td) const; - bool save_to_file(const std::string& path_to_file, const std::string& binary, bool is_printable = false) const; - static bool load_from_file(const std::string& path_to_file, std::string& target_str, size_t max_size = 1000000000); + bool save_to_file(const fs::path& path_to_file, std::string_view binary, bool is_printable = false) const; + static bool load_from_file(const fs::path& path_to_file, std::string& target_str); uint64_t get_bytes_sent() const; uint64_t get_bytes_received() const; @@ -1395,7 +1402,7 @@ private: bool unlock_keys_file(); bool is_keys_file_locked() const; - void change_password(const std::string &filename, const epee::wipeable_string &original_password, const epee::wipeable_string &new_password); + void change_password(const fs::path& filename, const epee::wipeable_string& original_password, const epee::wipeable_string& new_password); void set_tx_notify(std::shared_ptr notify) { m_tx_notify = std::move(notify); } @@ -1431,13 +1438,13 @@ private: * \param watch_only true to save only view key, false to save both spend and view keys * \return Whether it was successful. */ - bool store_keys(const std::string& keys_file_name, const epee::wipeable_string& password, bool watch_only = false); + bool store_keys(const fs::path& keys_file_name, const epee::wipeable_string& password, bool watch_only = false); /*! * \brief Load wallet keys information from wallet file. * \param keys_file_name Name of wallet file * \param password Password of wallet file */ - bool load_keys(const std::string& keys_file_name, const epee::wipeable_string& password); + bool load_keys(const fs::path& keys_file_name, const epee::wipeable_string& password); /*! * \brief Load wallet keys information from a string buffer. * \param keys_buf Keys buffer to load @@ -1458,7 +1465,7 @@ private: void pull_and_parse_next_blocks(uint64_t start_height, uint64_t &blocks_start_height, std::list &short_chain_history, const std::vector &prev_blocks, const std::vector &prev_parsed_blocks, std::vector &blocks, std::vector &parsed_blocks, bool &last, bool &error, std::exception_ptr &exception); void process_parsed_blocks(uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added, std::map, size_t> *output_tracker_cache = NULL); uint64_t select_transfers(uint64_t needed_money, std::vector unused_transfers_indices, std::vector& selected_transfers) const; - bool prepare_file_names(const std::string& file_path); + bool prepare_file_names(const fs::path& file_path); void process_unconfirmed(const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t height); void process_outgoing(const crypto::hash &txid, const cryptonote::transaction& tx, uint64_t height, uint64_t ts, uint64_t spent, uint64_t received, uint32_t subaddr_account, const std::set& subaddr_indices); void add_unconfirmed_tx(const cryptonote::transaction& tx, uint64_t amount_in, const std::vector &dests, const crypto::hash &payment_id, uint64_t change_amount, uint32_t subaddr_account, const std::set& subaddr_indices); @@ -1519,7 +1526,7 @@ private: void init_type(hw::device::device_type device_type); void setup_new_blockchain(); - void create_keys_file(const std::string &wallet_, bool watch_only, const epee::wipeable_string &password, bool create_address_file); + void create_keys_file(const fs::path &wallet_, bool watch_only, const epee::wipeable_string &password, bool create_address_file); wallet_device_callback * get_device_callback(); void on_device_button_request(uint64_t code); @@ -1533,9 +1540,9 @@ private: bool should_expand(const cryptonote::subaddress_index &index) const; cryptonote::account_base m_account; - std::string m_wallet_file; - std::string m_keys_file; - std::string m_mms_file; + fs::path m_wallet_file; + fs::path m_keys_file; + fs::path m_mms_file; hashchain m_blockchain; std::unordered_map m_unconfirmed_txs; std::unordered_map m_confirmed_txs; @@ -1634,7 +1641,7 @@ private: // store calculated key image for faster lookup std::unordered_map > m_key_image_cache; - std::string m_ring_database; + fs::path m_ring_database; bool m_ring_history_saved; std::unique_ptr m_ringdb; std::optional m_ringdb_key; diff --git a/src/wallet/wallet_args.cpp b/src/wallet/wallet_args.cpp index 4345acd96..6762e68ca 100644 --- a/src/wallet/wallet_args.cpp +++ b/src/wallet/wallet_args.cpp @@ -28,14 +28,12 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "wallet/wallet_args.h" -#include -#include #include #include "common/i18n.h" #include "common/util.h" #include "common/file.h" -#include "misc_log_ex.h" -#include "string_tools.h" +#include "epee/misc_log_ex.h" +#include "epee/string_tools.h" #include "version.h" #include "common/loki_integration_test_hooks.h" @@ -98,7 +96,6 @@ namespace wallet_args bool log_to_console) { - namespace bf = boost::filesystem; namespace po = boost::program_options; #ifdef WIN32 _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); @@ -173,12 +170,13 @@ namespace wallet_args if(command_line::has_arg(vm, arg_config_file)) { - std::string config = command_line::get_arg(vm, arg_config_file); - bf::path config_path(config); - boost::system::error_code ec; - if (bf::exists(config_path, ec)) + fs::path config = fs::u8path(command_line::get_arg(vm, arg_config_file)); + if (std::error_code ec; fs::exists(config, ec)) { - po::store(po::parse_config_file(config_path.string().c_str(), desc_params), vm); + fs::ifstream cfg{config}; + if (!cfg.is_open()) + throw std::runtime_error{"Unable to open config file: " + config.u8string()}; + po::store(po::parse_config_file(cfg, desc_params), vm); } else { diff --git a/src/wallet/wallet_errors.h b/src/wallet/wallet_errors.h index f5e617737..d6d1c28cb 100644 --- a/src/wallet/wallet_errors.h +++ b/src/wallet/wallet_errors.h @@ -38,7 +38,6 @@ #include "cryptonote_basic/cryptonote_format_utils.h" #include "cryptonote_core/cryptonote_tx_utils.h" #include "rpc/core_rpc_server_commands_defs.h" -#include "include_base_utils.h" namespace tools @@ -249,24 +248,17 @@ namespace tools template struct file_error_base : public wallet_logic_error { - explicit file_error_base(std::string&& loc, const std::string& file) - : wallet_logic_error(std::move(loc), std::string(file_error_messages[msg_index]) + " \"" + file + '\"') - , m_file(file) + file_error_base(std::string loc, fs::path file, std::error_code e = {}) + : wallet_logic_error(std::move(loc), std::string(file_error_messages[msg_index]) + " \"" + file.u8string() + '"' + + (e ? ": " + e.message() : "")) + , m_file(std::move(file)) { } - explicit file_error_base(std::string&& loc, const std::string& file, const std::error_code &e) - : wallet_logic_error(std::move(loc), std::string(file_error_messages[msg_index]) + " \"" + file + "\": " + e.message()) - , m_file(file) - { - } - - const std::string& file() const { return m_file; } - - std::string to_string() const { return wallet_logic_error::to_string(); } + const fs::path& file() const { return m_file; } private: - std::string m_file; + fs::path m_file; }; //---------------------------------------------------------------------------------------------------- typedef file_error_base file_exists; @@ -604,12 +596,12 @@ namespace tools // It's not good, if logs will contain such much data //ss << "\n real_output: " << src.real_output; //ss << "\n real_output_in_tx_index: " << src.real_output_in_tx_index; - //ss << "\n real_out_tx_key: " << epee::string_tools::pod_to_hex(src.real_out_tx_key); + //ss << "\n real_out_tx_key: " << tools::type_to_hex(src.real_out_tx_key); //ss << "\n outputs:"; //for (size_t j = 0; j < src.outputs.size(); ++j) //{ // const cryptonote::tx_source_entry::output_entry& out = src.outputs[j]; - // ss << "\n " << j << ": " << out.first << ", " << epee::string_tools::pod_to_hex(out.second); + // ss << "\n " << j << ": " << out.first << ", " << tools::type_to_hex(out.second); //} } @@ -847,19 +839,10 @@ namespace tools //---------------------------------------------------------------------------------------------------- struct wallet_files_doesnt_correspond : public wallet_logic_error { - explicit wallet_files_doesnt_correspond(std::string&& loc, const std::string& keys_file, const std::string& wallet_file) - : wallet_logic_error(std::move(loc), "File " + wallet_file + " does not correspond to " + keys_file) + explicit wallet_files_doesnt_correspond(std::string&& loc, const fs::path& keys_file, const fs::path& wallet_file) + : wallet_logic_error(std::move(loc), "File " + wallet_file.u8string() + " does not correspond to " + keys_file.u8string()) { } - - const std::string& keys_file() const { return m_keys_file; } - const std::string& wallet_file() const { return m_wallet_file; } - - std::string to_string() const { return wallet_logic_error::to_string(); } - - private: - std::string m_keys_file; - std::string m_wallet_file; }; //---------------------------------------------------------------------------------------------------- struct mms_error : public wallet_logic_error diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index bd55ef2a1..5aeaa1c3b 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -30,12 +30,9 @@ // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers #include #include -#include #include -#include #include #include "cryptonote_basic/cryptonote_basic_impl.h" -#include "include_base_utils.h" #include #include @@ -49,9 +46,9 @@ #include "cryptonote_basic/cryptonote_format_utils.h" #include "cryptonote_basic/account.h" #include "multisig/multisig.h" -#include "misc_language.h" -#include "string_coding.h" -#include "string_tools.h" +#include "epee/misc_language.h" +#include "epee/string_coding.h" +#include "epee/string_tools.h" #include "crypto/hash.h" #include "mnemonics/electrum-words.h" #include "rpc/rpc_args.h" @@ -491,10 +488,10 @@ namespace tools return false; } - if (!rpc_config.bind_ip.empty()) - m_bind.emplace_back(rpc_config.bind_ip, port, rpc_config.require_ipv4); - if (rpc_config.use_ipv6 && !rpc_config.bind_ipv6_address.empty()) - m_bind.emplace_back(rpc_config.bind_ipv6_address, port, true); + if (rpc_config.bind_ip && !rpc_config.bind_ip->empty()) + m_bind.emplace_back(*rpc_config.bind_ip, port, rpc_config.require_ipv4); + if (rpc_config.use_ipv6 && rpc_config.bind_ipv6_address && !rpc_config.bind_ipv6_address->empty()) + m_bind.emplace_back(*rpc_config.bind_ipv6_address, port, true); const bool disable_auth = command_line::get_arg(m_vm, arg_disable_rpc_login); @@ -511,20 +508,17 @@ namespace tools MERROR(arg_wallet_dir.name << " and " << wallet_args::arg_wallet_file().name << " are incompatible, use only one of them"); return false; } - m_wallet_dir = command_line::get_arg(m_vm, arg_wallet_dir); -#ifdef _WIN32 -#define MKDIR(path, mode) mkdir(path) -#else -#define MKDIR(path, mode) mkdir(path, mode) -#endif - if (!m_wallet_dir.empty() && MKDIR(m_wallet_dir.c_str(), 0700) < 0 && errno != EEXIST) + m_wallet_dir = fs::u8path(command_line::get_arg(m_vm, arg_wallet_dir)); + if (!m_wallet_dir.empty()) { -#ifdef _WIN32 - LOG_ERROR(tr("Failed to create directory ") + m_wallet_dir); -#else - LOG_ERROR((boost::format(tr("Failed to create directory %s: %s")) % m_wallet_dir % strerror(errno)).str()); -#endif - return false; + std::error_code ec; + if (fs::create_directories(m_wallet_dir, ec)) + fs::permissions(m_wallet_dir, fs::perms::owner_all, ec); + else if (ec) + { + LOG_ERROR(tr("Failed to create directory ") << m_wallet_dir << ": " << ec.message()); + return false; + } } } @@ -917,7 +911,7 @@ namespace tools { return ""; } - return epee::string_tools::buff_to_hex_nodelimer(oss.str()); + return lokimq::to_hex(oss.str()); } //------------------------------------------------------------------------------------------------------------------------------ template static bool is_error_value(const T &val) { return false; } @@ -967,14 +961,14 @@ namespace tools if (m_wallet->multisig()) { - multisig_txset = epee::string_tools::buff_to_hex_nodelimer(m_wallet->save_multisig_tx(ptx_vector)); + multisig_txset = lokimq::to_hex(m_wallet->save_multisig_tx(ptx_vector)); if (multisig_txset.empty()) throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Failed to save multisig tx set after creation"}; } else { if (m_wallet->watch_only()){ - unsigned_txset = epee::string_tools::buff_to_hex_nodelimer(m_wallet->dump_tx_to_str(ptx_vector)); + unsigned_txset = lokimq::to_hex(m_wallet->dump_tx_to_str(ptx_vector)); if (unsigned_txset.empty()) throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Failed to save unsigned tx set after creation"}; } @@ -984,8 +978,8 @@ namespace tools // populate response with tx hashes for (auto & ptx : ptx_vector) { - bool r = fill(tx_hash, epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx))); - r = r && (!get_tx_hex || fill(tx_blob, epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(ptx.tx)))); + bool r = fill(tx_hash, tools::type_to_hex(cryptonote::get_transaction_hash(ptx.tx))); + r = r && (!get_tx_hex || fill(tx_blob, lokimq::to_hex(tx_to_blob(ptx.tx)))); r = r && (!get_tx_metadata || fill(tx_metadata, ptx_to_string(ptx))); if (!r) throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Failed to save tx info"}; @@ -1085,17 +1079,17 @@ namespace tools if (ciphertext.empty()) throw wallet_rpc_error{error_code::SIGN_UNSIGNED, "Failed to sign unsigned tx"}; - res.signed_txset = epee::string_tools::buff_to_hex_nodelimer(ciphertext); + res.signed_txset = lokimq::to_hex(ciphertext); } for (auto &ptx: ptxs) { - res.tx_hash_list.push_back(epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx))); + res.tx_hash_list.push_back(tools::type_to_hex(cryptonote::get_transaction_hash(ptx.tx))); if (req.get_tx_keys) { - res.tx_key_list.push_back(epee::string_tools::pod_to_hex(ptx.tx_key)); + res.tx_key_list.push_back(tools::type_to_hex(ptx.tx_key)); for (const crypto::secret_key& additional_tx_key : ptx.additional_tx_keys) - res.tx_key_list.back() += epee::string_tools::pod_to_hex(additional_tx_key); + res.tx_key_list.back() += tools::type_to_hex(additional_tx_key); } } @@ -1103,7 +1097,7 @@ namespace tools { for (auto &ptx: ptxs) { - res.tx_raw_list.push_back(epee::string_tools::buff_to_hex_nodelimer(cryptonote::tx_to_blob(ptx.tx))); + res.tx_raw_list.push_back(lokimq::to_hex(cryptonote::tx_to_blob(ptx.tx))); } } @@ -1177,13 +1171,13 @@ namespace tools { if (payment_id8 != crypto::null_hash8) { - desc.payment_id = epee::string_tools::pod_to_hex(payment_id8); + desc.payment_id = tools::type_to_hex(payment_id8); has_encrypted_payment_id = true; } } else if (cryptonote::get_payment_id_from_tx_extra_nonce(extra_nonce.nonce, payment_id)) { - desc.payment_id = epee::string_tools::pod_to_hex(payment_id); + desc.payment_id = tools::type_to_hex(payment_id); } } } @@ -1284,7 +1278,7 @@ namespace tools for (auto &ptx: ptx_vector) { m_wallet->commit_tx(ptx); - res.tx_hash_list.push_back(epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx))); + res.tx_hash_list.push_back(tools::type_to_hex(cryptonote::get_transaction_hash(ptx.tx))); } } catch (const std::exception &e) @@ -1366,7 +1360,7 @@ namespace tools validate_transfer(destination, req.payment_id, dsts, extra, true); crypto::key_image ki; - if (!epee::string_tools::hex_to_pod(req.key_image, ki)) + if (!tools::hex_to_type(req.key_image, ki)) throw wallet_rpc_error{error_code::WRONG_KEY_IMAGE, "failed to parse key image"}; { @@ -1417,7 +1411,7 @@ namespace tools throw wallet_rpc_error{error_code::GENERIC_TRANSFER_ERROR, "Failed to commit tx."}; } - res.tx_hash = epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx)); + res.tx_hash = tools::type_to_hex(cryptonote::get_transaction_hash(ptx.tx)); return res; } @@ -1434,7 +1428,7 @@ namespace tools } else { - if (!tools::wallet2::parse_short_payment_id(req.payment_id,payment_id)) + if (!tools::hex_to_type(req.payment_id,payment_id)) throw wallet_rpc_error{error_code::WRONG_PAYMENT_ID, "Invalid payment ID"}; } @@ -1455,7 +1449,7 @@ namespace tools throw wallet_rpc_error{error_code::WRONG_PAYMENT_ID, "Payment ID shouldn't be left unspecified"}; res.integrated_address = get_account_integrated_address_as_str(m_wallet->nettype(), info.address, payment_id); } - res.payment_id = epee::string_tools::pod_to_hex(payment_id); + res.payment_id = tools::type_to_hex(payment_id); } return res; } @@ -1472,7 +1466,7 @@ namespace tools if(!info.has_payment_id) throw wallet_rpc_error{error_code::WRONG_ADDRESS, "Address is not an integrated address"}; res.standard_address = get_account_address_as_str(m_wallet->nettype(), info.is_subaddress, info.address); - res.payment_id = epee::string_tools::pod_to_hex(info.payment_id); + res.payment_id = tools::type_to_hex(info.payment_id); } return res; } @@ -1515,7 +1509,7 @@ namespace tools { wallet_rpc::payment_details& rpc_payment = res.payments.emplace_back(); rpc_payment.payment_id = req.payment_id; - rpc_payment.tx_hash = epee::string_tools::pod_to_hex(payment.m_tx_hash); + rpc_payment.tx_hash = tools::type_to_hex(payment.m_tx_hash); rpc_payment.amount = payment.m_amount; rpc_payment.block_height = payment.m_block_height; rpc_payment.unlock_time = payment.m_unlock_time; @@ -1541,8 +1535,8 @@ namespace tools for (auto & payment : payment_list) { wallet_rpc::payment_details& rpc_payment = res.payments.emplace_back(); - rpc_payment.payment_id = epee::string_tools::pod_to_hex(payment.first); - rpc_payment.tx_hash = epee::string_tools::pod_to_hex(payment.second.m_tx_hash); + rpc_payment.payment_id = tools::type_to_hex(payment.first); + rpc_payment.tx_hash = tools::type_to_hex(payment.second.m_tx_hash); rpc_payment.amount = payment.second.m_amount; rpc_payment.block_height = payment.second.m_block_height; rpc_payment.unlock_time = payment.second.m_unlock_time; @@ -1564,11 +1558,11 @@ namespace tools bool r; if (payment_id_str.size() == 2 * sizeof(payment_id)) { - r = epee::string_tools::hex_to_pod(payment_id_str, payment_id); + r = tools::hex_to_type(payment_id_str, payment_id); } else if (payment_id_str.size() == 2 * sizeof(payment_id8)) { - r = epee::string_tools::hex_to_pod(payment_id_str, payment_id8); + r = tools::hex_to_type(payment_id_str, payment_id8); if (r) { memcpy(payment_id.data, payment_id8.data, 8); @@ -1588,7 +1582,7 @@ namespace tools { wallet_rpc::payment_details& rpc_payment = res.payments.emplace_back(); rpc_payment.payment_id = payment_id_str; - rpc_payment.tx_hash = epee::string_tools::pod_to_hex(payment.m_tx_hash); + rpc_payment.tx_hash = tools::type_to_hex(payment.m_tx_hash); rpc_payment.amount = payment.m_amount; rpc_payment.block_height = payment.m_block_height; rpc_payment.unlock_time = payment.m_unlock_time; @@ -1634,9 +1628,9 @@ namespace tools rpc_transfers.amount = td.amount(); rpc_transfers.spent = td.m_spent; rpc_transfers.global_index = td.m_global_output_index; - rpc_transfers.tx_hash = epee::string_tools::pod_to_hex(td.m_txid); + rpc_transfers.tx_hash = tools::type_to_hex(td.m_txid); rpc_transfers.subaddr_index = {td.m_subaddr_index.major, td.m_subaddr_index.minor}; - rpc_transfers.key_image = td.m_key_image_known ? epee::string_tools::pod_to_hex(td.m_key_image) : ""; + rpc_transfers.key_image = td.m_key_image_known ? tools::type_to_hex(td.m_key_image) : ""; rpc_transfers.block_height = td.m_block_height; rpc_transfers.frozen = td.m_frozen; rpc_transfers.unlocked = m_wallet->is_transfer_unlocked(td); @@ -1800,7 +1794,7 @@ namespace tools GET_TX_KEY::response res{}; crypto::hash txid; - if (!epee::string_tools::hex_to_pod(req.txid, txid)) + if (!tools::hex_to_type(req.txid, txid)) throw wallet_rpc_error{error_code::WRONG_TXID, "TX ID has invalid format"}; crypto::secret_key tx_key; @@ -1822,7 +1816,7 @@ namespace tools CHECK_TX_KEY::response res{}; crypto::hash txid; - if (!epee::string_tools::hex_to_pod(req.txid, txid)) + if (!tools::hex_to_type(req.txid, txid)) throw wallet_rpc_error{error_code::WRONG_TXID, "TX ID has invalid format"}; epee::wipeable_string tx_key_str = req.tx_key; @@ -1856,7 +1850,7 @@ namespace tools GET_TX_PROOF::response res{}; crypto::hash txid; - if (!epee::string_tools::hex_to_pod(req.txid, txid)) + if (!tools::hex_to_type(req.txid, txid)) throw wallet_rpc_error{error_code::WRONG_TXID, "TX ID has invalid format"}; cryptonote::address_parse_info info; @@ -1873,7 +1867,7 @@ namespace tools CHECK_TX_PROOF::response res{}; crypto::hash txid; - if (!epee::string_tools::hex_to_pod(req.txid, txid)) + if (!tools::hex_to_type(req.txid, txid)) throw wallet_rpc_error{error_code::WRONG_TXID, "TX ID has invalid format"}; cryptonote::address_parse_info info; @@ -1892,7 +1886,7 @@ namespace tools GET_SPEND_PROOF::response res{}; crypto::hash txid; - if (!epee::string_tools::hex_to_pod(req.txid, txid)) + if (!tools::hex_to_type(req.txid, txid)) throw wallet_rpc_error{error_code::WRONG_TXID, "TX ID has invalid format"}; res.signature = m_wallet->get_spend_proof(txid, req.message); @@ -1905,7 +1899,7 @@ namespace tools CHECK_SPEND_PROOF::response res{}; crypto::hash txid; - if (!epee::string_tools::hex_to_pod(req.txid, txid)) + if (!tools::hex_to_type(req.txid, txid)) throw wallet_rpc_error{error_code::WRONG_TXID, "TX ID has invalid format"}; res.good = m_wallet->check_spend_proof(txid, req.message, req.signature); @@ -2099,7 +2093,7 @@ namespace tools if (m_wallet->key_on_device()) throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "command not supported by HW wallet"}; - res.outputs_data_hex = epee::string_tools::buff_to_hex_nodelimer(m_wallet->export_outputs_to_str(req.all)); + res.outputs_data_hex = lokimq::to_hex(m_wallet->export_outputs_to_str(req.all)); return res; } @@ -2130,8 +2124,8 @@ namespace tools res.signed_key_images.resize(ski.second.size()); for (size_t n = 0; n < ski.second.size(); ++n) { - res.signed_key_images[n].key_image = epee::string_tools::pod_to_hex(ski.second[n].first); - res.signed_key_images[n].signature = epee::string_tools::pod_to_hex(ski.second[n].second); + res.signed_key_images[n].key_image = tools::type_to_hex(ski.second[n].first); + res.signed_key_images[n].signature = tools::type_to_hex(ski.second[n].second); } } @@ -2149,10 +2143,10 @@ namespace tools ski.resize(req.signed_key_images.size()); for (size_t n = 0; n < ski.size(); ++n) { - if (!epee::string_tools::hex_to_pod(req.signed_key_images[n].key_image, ski[n].first)) + if (!tools::hex_to_type(req.signed_key_images[n].key_image, ski[n].first)) throw wallet_rpc_error{error_code::WRONG_KEY_IMAGE, "failed to parse key image"}; - if (!epee::string_tools::hex_to_pod(req.signed_key_images[n].signature, ski[n].second)) + if (!tools::hex_to_type(req.signed_key_images[n].signature, ski[n].second)) throw wallet_rpc_error{error_code::WRONG_SIGNATURE, "failed to parse signature"}; } uint64_t spent = 0, unspent = 0; @@ -2370,7 +2364,7 @@ namespace { #endif if (ptr) throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Invalid filename"}; - std::string wallet_file = req.filename.empty() ? "" : (m_wallet_dir + "/" + req.filename); + fs::path wallet_file = req.filename.empty() ? fs::path{} : m_wallet_dir / fs::u8path(req.filename); { std::vector languages; crypto::ElectrumWords::get_language_list(languages, false); @@ -2431,7 +2425,7 @@ namespace { m_wallet.reset(); } - std::string wallet_file = m_wallet_dir + "/" + req.filename; + fs::path wallet_file = m_wallet_dir / fs::u8path(req.filename); auto vm2 = password_arg_hack(req.password, m_vm); std::unique_ptr wal = tools::wallet2::make_from_file(vm2, true, wallet_file, nullptr).first; if (!wal) @@ -2466,6 +2460,18 @@ namespace { throw wallet_rpc_error{error_code::INVALID_PASSWORD, "Invalid original password."}; return {}; } + + static fs::path get_wallet_path(fs::path dir, fs::path filename) + { + if (filename.has_parent_path()) + throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Invalid filename"}; + auto wallet_file = filename.empty() ? filename : dir / filename; + // check if wallet file already exists + if (std::error_code ec; !wallet_file.empty() && fs::exists(wallet_file, ec)) + throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Wallet already exists."}; + return wallet_file; + } + //------------------------------------------------------------------------------------------------------------------------------ GENERATE_FROM_KEYS::response wallet_rpc_server::invoke(GENERATE_FROM_KEYS::request&& req) { @@ -2480,23 +2486,7 @@ namespace { GENERATE_FROM_KEYS::response res{}; - const char *ptr = strchr(req.filename.c_str(), '/'); - #ifdef _WIN32 - if (!ptr) - ptr = strchr(req.filename.c_str(), '\\'); - if (!ptr) - ptr = strchr(req.filename.c_str(), ':'); - #endif - if (ptr) - throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Invalid filename"}; - std::string wallet_file = req.filename.empty() ? "" : (m_wallet_dir + "/" + req.filename); - // check if wallet file already exists - if (!wallet_file.empty()) - { - boost::system::error_code ignored_ec; - if (boost::filesystem::exists(wallet_file, ignored_ec)) - throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Wallet already exists."}; - } + auto wallet_file = get_wallet_path(m_wallet_dir, fs::u8path(req.filename)); auto vm2 = password_arg_hack(req.password, m_vm); auto rc = tools::wallet2::make_new(vm2, true, nullptr); @@ -2562,23 +2552,8 @@ namespace { RESTORE_DETERMINISTIC_WALLET::response res{}; - const char *ptr = strchr(req.filename.c_str(), '/'); - #ifdef _WIN32 - if (!ptr) - ptr = strchr(req.filename.c_str(), '\\'); - if (!ptr) - ptr = strchr(req.filename.c_str(), ':'); - #endif - if (ptr) - throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Invalid filename"}; - std::string wallet_file = req.filename.empty() ? "" : (m_wallet_dir + "/" + req.filename); - // check if wallet file already exists - if (!wallet_file.empty()) - { - boost::system::error_code ignored_ec; - if (boost::filesystem::exists(wallet_file, ignored_ec)) - throw wallet_rpc_error{error_code::UNKNOWN_ERROR, "Wallet already exists."}; - } + auto wallet_file = get_wallet_path(m_wallet_dir, fs::u8path(req.filename)); + crypto::secret_key recovery_key; std::string old_language; @@ -2704,7 +2679,7 @@ namespace { cryptonote::blobdata info; info = m_wallet->export_multisig(); - res.info = epee::string_tools::buff_to_hex_nodelimer(info); + res.info = lokimq::to_hex(info); return res; } @@ -2823,11 +2798,11 @@ namespace { throw wallet_rpc_error{error_code::MULTISIG_SIGNATURE, "Failed to sign multisig tx: "s + e.what()}; } - res.tx_data_hex = epee::string_tools::buff_to_hex_nodelimer(m_wallet->save_multisig_tx(txs)); + res.tx_data_hex = lokimq::to_hex(m_wallet->save_multisig_tx(txs)); if (!txids.empty()) { for (const crypto::hash &txid: txids) - res.tx_hash_list.push_back(epee::string_tools::pod_to_hex(txid)); + res.tx_hash_list.push_back(tools::type_to_hex(txid)); } return res; @@ -2861,7 +2836,7 @@ namespace { for (auto &ptx: txs.m_ptx) { m_wallet->commit_tx(ptx); - res.tx_hash_list.push_back(epee::string_tools::pod_to_hex(cryptonote::get_transaction_hash(ptx.tx))); + res.tx_hash_list.push_back(tools::type_to_hex(cryptonote::get_transaction_hash(ptx.tx))); } } catch (const std::exception &e) @@ -2967,7 +2942,7 @@ namespace { if (!cryptonote::get_account_address_from_str(addr_info, m_wallet->nettype(), req.destination)) throw wallet_rpc_error{error_code::WRONG_ADDRESS, std::string("Unparsable address given: ") + req.destination}; - if (!epee::string_tools::hex_to_pod(req.service_node_key, snode_key)) + if (!tools::hex_to_type(req.service_node_key, snode_key)) throw wallet_rpc_error{error_code::WRONG_KEY, std::string("Unparsable service node key given: ") + req.service_node_key}; // NOTE(loki): Pre-emptively set subaddr_account to 0. We don't support onwards from Infinite Staking which is when this call was implemented. @@ -3015,7 +2990,7 @@ namespace { CAN_REQUEST_STAKE_UNLOCK::response res{}; crypto::public_key snode_key = {}; - if (!epee::string_tools::hex_to_pod(req.service_node_key, snode_key)) + if (!tools::hex_to_type(req.service_node_key, snode_key)) throw wallet_rpc_error{error_code::WRONG_KEY, std::string("Unparsable service node key given: ") + req.service_node_key}; tools::wallet2::request_stake_unlock_result unlock_result = m_wallet->can_request_stake_unlock(snode_key); @@ -3031,7 +3006,7 @@ namespace { REQUEST_STAKE_UNLOCK::response res{}; crypto::public_key snode_key = {}; - if (!epee::string_tools::hex_to_pod(req.service_node_key, snode_key)) + if (!tools::hex_to_type(req.service_node_key, snode_key)) throw wallet_rpc_error{error_code::WRONG_KEY, std::string("Unparsable service node key given: ") + req.service_node_key}; tools::wallet2::request_stake_unlock_result unlock_result = m_wallet->can_request_stake_unlock(snode_key); @@ -3211,7 +3186,7 @@ namespace { &reason)) throw wallet_rpc_error{error_code::TX_NOT_POSSIBLE, "Failed to create signature for LNS update transaction: " + reason}; - res.signature = epee::string_tools::pod_to_hex(signature.ed25519); + res.signature = tools::type_to_hex(signature.ed25519); return res; } diff --git a/src/wallet/wallet_rpc_server.h b/src/wallet/wallet_rpc_server.h index 675923de6..35eeb0604 100644 --- a/src/wallet/wallet_rpc_server.h +++ b/src/wallet/wallet_rpc_server.h @@ -38,6 +38,7 @@ #include #include "common/util.h" +#include "common/fs.h" #include "common/periodic_task.h" #include "wallet_rpc_server_commands_defs.h" #include "wallet2.h" @@ -203,7 +204,7 @@ namespace tools void stop_long_poll_thread(); std::unique_ptr m_wallet; - std::string m_wallet_dir; + fs::path m_wallet_dir; std::vector> m_bind; tools::private_file rpc_login_file; std::atomic m_stop; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 908e55015..630470e55 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -63,7 +63,7 @@ add_subdirectory(block_weight) add_subdirectory(hash) add_subdirectory(net_load_tests) add_subdirectory(network_tests) -if (BUILD_GUI_DEPS) +if (ANDROID) # Currently failed to compile # add_subdirectory(libwallet_api_tests) endif() diff --git a/tests/core_proxy/core_proxy.cpp b/tests/core_proxy/core_proxy.cpp index 74ebb116b..f1f4e906f 100644 --- a/tests/core_proxy/core_proxy.cpp +++ b/tests/core_proxy/core_proxy.cpp @@ -32,7 +32,6 @@ // -#include "include_base_utils.h" #include "version.h" #include #include @@ -40,7 +39,7 @@ #include #include "common/command_line.h" -#include "console_handler.h" +#include "epee/console_handler.h" #include "p2p/net_node.h" #include "p2p/net_node.inl" //#include "cryptonote_core/cryptonote_core.h" @@ -172,7 +171,7 @@ std::vector tests::proxy_core::par std::cout << txi.tx_hash << "\n"; std::cout << tx_prefix_hash << "\n"; std::cout << tx_blobs[i].size() << "\n"; - //std::cout << string_tools::buff_to_hex_nodelimer(tx_blob) << "\n\n"; + //std::cout << lokimq::to_hex(tx_blob) << "\n\n"; std::cout << obj_to_json_str(txi.tx) << "\n"; std::cout << "\nENDTX\n"; txi.result = txi.parsed = true; diff --git a/tests/core_tests/bulletproofs.cpp b/tests/core_tests/bulletproofs.cpp index e6a3253d0..d80ebf386 100644 --- a/tests/core_tests/bulletproofs.cpp +++ b/tests/core_tests/bulletproofs.cpp @@ -515,7 +515,7 @@ bool gen_rct2_tx_clsag_malleability::generate(std::vector& eve CHECK_TEST_CONDITION(tx.rct_signatures.type == rct::RCTTypeCLSAG); CHECK_TEST_CONDITION(!tx.rct_signatures.p.CLSAGs.empty()); rct::key x; - CHECK_TEST_CONDITION(epee::string_tools::hex_to_pod("c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa", x)); + CHECK_TEST_CONDITION(tools::hex_to_type("c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa", x)); tx.rct_signatures.p.CLSAGs[0].D = rct::addKeys(tx.rct_signatures.p.CLSAGs[0].D, x); return true; }); diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp index c9d38b287..458e0834d 100644 --- a/tests/core_tests/chaingen.cpp +++ b/tests/core_tests/chaingen.cpp @@ -39,7 +39,7 @@ #include #include "common/string_util.h" -#include "console_handler.h" +#include "epee/console_handler.h" #include "common/rules.h" #include "cryptonote_config.h" diff --git a/tests/core_tests/chaingen.h b/tests/core_tests/chaingen.h index 766a58a5a..905167933 100644 --- a/tests/core_tests/chaingen.h +++ b/tests/core_tests/chaingen.h @@ -42,7 +42,6 @@ #include #include "cryptonote_protocol/quorumnet.h" -#include "include_base_utils.h" #include "common/boost_serialization_helper.h" #include "common/command_line.h" #include "common/threadpool.h" @@ -56,7 +55,7 @@ #include "cryptonote_protocol/quorumnet.h" #include "serialization/boost_std_variant.h" #include "serialization/boost_std_optional.h" -#include "misc_language.h" +#include "epee/misc_language.h" #include "blockchain_db/testdb.h" diff --git a/tests/core_tests/chaingen001.cpp b/tests/core_tests/chaingen001.cpp index f9513623f..9674c417e 100644 --- a/tests/core_tests/chaingen001.cpp +++ b/tests/core_tests/chaingen001.cpp @@ -31,9 +31,7 @@ #include #include -#include "include_base_utils.h" - -#include "console_handler.h" +#include "epee/console_handler.h" #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_format_utils.h" diff --git a/tests/core_tests/transaction_tests.cpp b/tests/core_tests/transaction_tests.cpp index efdd10549..eb8c18c3c 100644 --- a/tests/core_tests/transaction_tests.cpp +++ b/tests/core_tests/transaction_tests.cpp @@ -28,11 +28,10 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "include_base_utils.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "cryptonote_basic/account.h" #include "cryptonote_core/cryptonote_tx_utils.h" -#include "misc_language.h" +#include "epee/misc_language.h" using namespace cryptonote; diff --git a/tests/core_tests/tx_validation.cpp b/tests/core_tests/tx_validation.cpp index 3b8d2967e..352e81f6b 100644 --- a/tests/core_tests/tx_validation.cpp +++ b/tests/core_tests/tx_validation.cpp @@ -171,7 +171,7 @@ namespace { crypto::key_image key_image; // a random key image plucked from the blockchain - if (!epee::string_tools::hex_to_pod("6b9f5d1be7c950dc6e4e258c6ef75509412ba9ecaaf90e6886140151d1365b5e", key_image)) + if (!tools::hex_to_type("6b9f5d1be7c950dc6e4e258c6ef75509412ba9ecaaf90e6886140151d1365b5e", key_image)) throw std::runtime_error("invalid key image wasn't found"); return key_image; } diff --git a/tests/crypto/main.cpp b/tests/crypto/main.cpp index 65705b7a0..25b55bbaf 100644 --- a/tests/crypto/main.cpp +++ b/tests/crypto/main.cpp @@ -34,8 +34,8 @@ #include #include -#include "warnings.h" -#include "misc_log_ex.h" +#include "epee/warnings.h" +#include "epee/misc_log_ex.h" #include "crypto/crypto.h" #include "crypto/hash.h" #include "crypto-tests.h" diff --git a/tests/daemon_tests/transfers.cpp b/tests/daemon_tests/transfers.cpp index fc929c8e5..e6ff16eb6 100644 --- a/tests/daemon_tests/transfers.cpp +++ b/tests/daemon_tests/transfers.cpp @@ -33,7 +33,7 @@ #include "wallet/wallet.h" #include "rpc/core_rpc_server.h" #include "cryptonote_basic/account.h" -#include "net/http_client_abstract_invoke.h" +#include "epee/net/http_client_abstract_invoke.h" using namespace cryptonote; string daemon_address = "http://localhost:23400"; diff --git a/tests/difficulty/difficulty.cpp b/tests/difficulty/difficulty.cpp index ccbdc7020..c31f244ad 100644 --- a/tests/difficulty/difficulty.cpp +++ b/tests/difficulty/difficulty.cpp @@ -36,7 +36,7 @@ #include #include -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "common/util.h" #include "cryptonote_config.h" #include "cryptonote_basic/difficulty.h" diff --git a/tests/functional_tests/main.cpp b/tests/functional_tests/main.cpp index 684f58f27..4921f4629 100644 --- a/tests/functional_tests/main.cpp +++ b/tests/functional_tests/main.cpp @@ -30,8 +30,7 @@ #include -#include "include_base_utils.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "common/command_line.h" #include "common/util.h" diff --git a/tests/functional_tests/transactions_flow_test.cpp b/tests/functional_tests/transactions_flow_test.cpp index 648b8ff36..74cc50140 100644 --- a/tests/functional_tests/transactions_flow_test.cpp +++ b/tests/functional_tests/transactions_flow_test.cpp @@ -33,7 +33,6 @@ #include #include -#include "include_base_utils.h" #include "wallet/wallet2.h" using namespace cryptonote; diff --git a/tests/functional_tests/transactions_generation_from_blockchain.cpp b/tests/functional_tests/transactions_generation_from_blockchain.cpp index d4f5b978f..9d01bcb1a 100644 --- a/tests/functional_tests/transactions_generation_from_blockchain.cpp +++ b/tests/functional_tests/transactions_generation_from_blockchain.cpp @@ -28,7 +28,6 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "include_base_utils.h" #include "wallet/wallet2.h" using namespace cryptonote; @@ -135,7 +134,7 @@ bool make_tx(blockchain_storage& bch) } rpc::SEND_RAW_TX::request req; - req.tx_as_hex = epee::string_tools::buff_to_hex_nodelimer(tx_to_blob(tx)); + req.tx_as_hex = lokimq::to_hex(tx_to_blob(tx)); rpc::SEND_RAW_TX::response daemon_send_resp; r = net_utils::http::invoke_http_json_remote_command(m_daemon_address + "/sendrawtransaction", req, daemon_send_resp, m_http_client); CHECK_AND_ASSERT_MES(r, false, "failed to send transaction"); diff --git a/tests/fuzz/base58.cpp b/tests/fuzz/base58.cpp index a4857bdd1..654a0bf39 100644 --- a/tests/fuzz/base58.cpp +++ b/tests/fuzz/base58.cpp @@ -26,10 +26,11 @@ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "include_base_utils.h" -#include "file_io_utils.h" +#include "epee/misc_log_ex.h" +#include "common/file.h" #include "common/base58.h" #include "fuzzer.h" +#include class Base58Fuzzer: public Fuzzer { @@ -48,7 +49,7 @@ int Base58Fuzzer::run(const std::string &filename) { std::string s; - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(filename, s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/fuzz/block.cpp b/tests/fuzz/block.cpp index 50635cc5a..33c75a211 100644 --- a/tests/fuzz/block.cpp +++ b/tests/fuzz/block.cpp @@ -26,11 +26,10 @@ // 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 "include_base_utils.h" -#include "file_io_utils.h" #include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_format_utils.h" +#include "common/file.h" #include "fuzzer.h" class BlockFuzzer: public Fuzzer @@ -45,7 +44,7 @@ int BlockFuzzer::run(const std::string &filename) { std::string s; - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(fs::u8path(filename), s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/fuzz/bulletproof.cpp b/tests/fuzz/bulletproof.cpp index 2c892a971..157fb04c0 100644 --- a/tests/fuzz/bulletproof.cpp +++ b/tests/fuzz/bulletproof.cpp @@ -26,8 +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 "include_base_utils.h" -#include "file_io_utils.h" +#include "common/file.h" #include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_format_utils.h" @@ -45,7 +44,7 @@ int BulletproofFuzzer::run(const std::string &filename) { std::string s; - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(filename, s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/fuzz/cold-outputs.cpp b/tests/fuzz/cold-outputs.cpp index 431c946c1..64bd67a8a 100644 --- a/tests/fuzz/cold-outputs.cpp +++ b/tests/fuzz/cold-outputs.cpp @@ -26,8 +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 "include_base_utils.h" -#include "file_io_utils.h" +#include "common/file.h" #include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_format_utils.h" @@ -50,7 +49,7 @@ int ColdOutputsFuzzer::init() { static const char * const spendkey_hex = "0b4f47697ec99c3de6579304e5f25c68b07afbe55b71d99620bf6cbf4e45a80f"; crypto::secret_key spendkey; - epee::string_tools::hex_to_pod(spendkey_hex, spendkey); + tools::hex_to_type(spendkey_hex, spendkey); try { @@ -70,7 +69,7 @@ int ColdOutputsFuzzer::run(const std::string &filename) { std::string s; - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(filename, s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/fuzz/cold-transaction.cpp b/tests/fuzz/cold-transaction.cpp index 9e1999c70..bba814ed6 100644 --- a/tests/fuzz/cold-transaction.cpp +++ b/tests/fuzz/cold-transaction.cpp @@ -26,8 +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 "include_base_utils.h" -#include "file_io_utils.h" +#include "common/file.h" #include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_format_utils.h" @@ -51,7 +50,7 @@ int ColdTransactionFuzzer::init() { static const char * const spendkey_hex = "0b4f47697ec99c3de6579304e5f25c68b07afbe55b71d99620bf6cbf4e45a80f"; crypto::secret_key spendkey; - epee::string_tools::hex_to_pod(spendkey_hex, spendkey); + tools::hex_to_type(spendkey_hex, spendkey); try { @@ -71,7 +70,7 @@ int ColdTransactionFuzzer::run(const std::string &filename) { std::string s; - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(filename, s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/fuzz/fuzzer.cpp b/tests/fuzz/fuzzer.cpp index ab14e2b79..7bb580f32 100644 --- a/tests/fuzz/fuzzer.cpp +++ b/tests/fuzz/fuzzer.cpp @@ -27,8 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include -#include "include_base_utils.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "common/command_line.h" #include "common/util.h" #include "fuzzer.h" diff --git a/tests/fuzz/levin.cpp b/tests/fuzz/levin.cpp index 0c2c9490a..a8ce47374 100644 --- a/tests/fuzz/levin.cpp +++ b/tests/fuzz/levin.cpp @@ -26,12 +26,11 @@ // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include "include_base_utils.h" -#include "file_io_utils.h" -#include "net/net_utils_base.h" -#include "net/abstract_tcp_server2.h" -#include "storages/levin_abstract_invoke2.h" -#include "net/levin_protocol_handler_async.h" +#include "common/file.h" +#include "epee/net/net_utils_base.h" +#include "epee/net/abstract_tcp_server2.h" +#include "epee/storages/levin_abstract_invoke2.h" +#include "epee/net/levin_protocol_handler_async.h" #include "fuzzer.h" namespace @@ -313,7 +312,7 @@ int LevinFuzzer::run(const std::string &filename) fwrite(&req_head,sizeof(req_head),1, f); fclose(f); #endif - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(filename, s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/fuzz/load_from_binary.cpp b/tests/fuzz/load_from_binary.cpp index 89f122902..28c4b89af 100644 --- a/tests/fuzz/load_from_binary.cpp +++ b/tests/fuzz/load_from_binary.cpp @@ -26,11 +26,10 @@ // 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 "include_base_utils.h" -#include "file_io_utils.h" -#include "serialization/keyvalue_serialization.h" -#include "storages/portable_storage_template_helper.h" -#include "storages/portable_storage_base.h" +#include "common/file.h" +#include "epee/serialization/keyvalue_serialization.h" +#include "epee/storages/portable_storage_template_helper.h" +#include "epee/storages/portable_storage_base.h" #include "fuzzer.h" class PortableStorageFuzzer: public Fuzzer @@ -50,7 +49,7 @@ int PortableStorageFuzzer::run(const std::string &filename) { std::string s; - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(filename, s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/fuzz/load_from_json.cpp b/tests/fuzz/load_from_json.cpp index 083555f7e..5beb48d35 100644 --- a/tests/fuzz/load_from_json.cpp +++ b/tests/fuzz/load_from_json.cpp @@ -26,11 +26,10 @@ // 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 "include_base_utils.h" -#include "file_io_utils.h" -#include "serialization/keyvalue_serialization.h" -#include "storages/portable_storage_template_helper.h" -#include "storages/portable_storage_base.h" +#include "common/file.h" +#include "epee/serialization/keyvalue_serialization.h" +#include "epee/storages/portable_storage_template_helper.h" +#include "epee/storages/portable_storage_base.h" #include "fuzzer.h" class PortableStorageFuzzer: public Fuzzer @@ -50,7 +49,7 @@ int PortableStorageFuzzer::run(const std::string &filename) { std::string s; - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(filename, s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/fuzz/signature.cpp b/tests/fuzz/signature.cpp index f82ada8b4..c8659f70b 100644 --- a/tests/fuzz/signature.cpp +++ b/tests/fuzz/signature.cpp @@ -26,13 +26,12 @@ // 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 "include_base_utils.h" -#include "file_io_utils.h" #include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "wallet/wallet2.h" #include "fuzzer.h" +#include "common/hex.h" class SignatureFuzzer: public Fuzzer { @@ -48,9 +47,8 @@ private: int SignatureFuzzer::init() { - static const char * const spendkey_hex = "0b4f47697ec99c3de6579304e5f25c68b07afbe55b71d99620bf6cbf4e45a80f"; crypto::secret_key spendkey; - epee::string_tools::hex_to_pod(spendkey_hex, spendkey); + tools::hex_to_type("0b4f47697ec99c3de6579304e5f25c68b07afbe55b71d99620bf6cbf4e45a80f"sv, spendkey); try { @@ -78,7 +76,7 @@ int SignatureFuzzer::run(const std::string &filename) { std::string s; - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(filename, s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/fuzz/transaction.cpp b/tests/fuzz/transaction.cpp index 298927ae2..ed8b86b7d 100644 --- a/tests/fuzz/transaction.cpp +++ b/tests/fuzz/transaction.cpp @@ -26,11 +26,10 @@ // 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 "include_base_utils.h" -#include "file_io_utils.h" #include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/cryptonote_basic.h" #include "cryptonote_basic/cryptonote_format_utils.h" +#include "common/file.h" #include "fuzzer.h" class TransactionFuzzer: public Fuzzer @@ -45,7 +44,7 @@ int TransactionFuzzer::run(const std::string &filename) { std::string s; - if (!epee::file_io_utils::load_file_to_string(filename, s)) + if (!tools::slurp_file(fs::u8path(filename), s)) { std::cout << "Error: failed to load file " << filename << std::endl; return 1; diff --git a/tests/hash-target.cpp b/tests/hash-target.cpp index 02ff4794b..a4c19f80a 100644 --- a/tests/hash-target.cpp +++ b/tests/hash-target.cpp @@ -32,7 +32,7 @@ #include #include #include -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "crypto/hash.h" #include "cryptonote_basic/difficulty.h" diff --git a/tests/hash/main.cpp b/tests/hash/main.cpp index fae7cdc80..4cf28b721 100644 --- a/tests/hash/main.cpp +++ b/tests/hash/main.cpp @@ -35,8 +35,8 @@ #include #include -#include "misc_log_ex.h" -#include "warnings.h" +#include "epee/misc_log_ex.h" +#include "epee/warnings.h" #include "crypto/hash.h" #include "crypto/variant2_int_sqrt.h" #include "cryptonote_core/cryptonote_tx_utils.h" diff --git a/tests/libwallet_api_tests/CMakeLists.txt b/tests/libwallet_api_tests/CMakeLists.txt index 345ea92ed..a2a3e9454 100644 --- a/tests/libwallet_api_tests/CMakeLists.txt +++ b/tests/libwallet_api_tests/CMakeLists.txt @@ -38,8 +38,7 @@ target_link_libraries(libwallet_api_tests version epee Boost::serialization - Boost::filesystem - Boost::locale + filesystem icu gtest extra) diff --git a/tests/libwallet_api_tests/main.cpp b/tests/libwallet_api_tests/main.cpp index 21205b29c..07650a618 100644 --- a/tests/libwallet_api_tests/main.cpp +++ b/tests/libwallet_api_tests/main.cpp @@ -32,10 +32,9 @@ #include "wallet/api/wallet2_api.h" #include "wallet/wallet2.h" -#include "include_base_utils.h" #include "common/util.h" -#include +#include "common/fs.h" #include #include #include @@ -99,26 +98,26 @@ struct Utils static void deleteWallet(const std::string & walletname) { std::cout << "** deleting wallet: " << walletname << std::endl; - boost::filesystem::remove(walletname); - boost::filesystem::remove(walletname + ".address.txt"); - boost::filesystem::remove(walletname + ".keys"); + fs::remove(walletname); + fs::remove(walletname + ".address.txt"); + fs::remove(walletname + ".keys"); } static void deleteDir(const std::string &path) { std::cout << "** removing dir recursively: " << path << std::endl; - boost::filesystem::remove_all(path); + fs::remove_all(path); } - static void print_transaction(Monero::TransactionInfo * t) + static void print_transaction(Wallet::TransactionInfo * t) { std::cout << "d: " - << (t->direction() == Monero::TransactionInfo::Direction_In ? "in" : "out") + << (t->direction() == Wallet::TransactionInfo::Direction_In ? "in" : "out") << ", pe: " << (t->isPending() ? "true" : "false") << ", bh: " << t->blockHeight() - << ", a: " << Monero::Wallet::displayAmount(t->amount()) - << ", f: " << Monero::Wallet::displayAmount(t->fee()) + << ", a: " << Wallet::Wallet::displayAmount(t->amount()) + << ", f: " << Wallet::Wallet::displayAmount(t->fee()) << ", h: " << t->hash() << ", pid: " << t->paymentId() << std::endl; @@ -126,8 +125,8 @@ struct Utils static std::string get_wallet_address(const std::string &filename, const std::string &password) { - Monero::WalletManager *wmgr = Monero::WalletManagerFactory::getWalletManager(); - Monero::Wallet * w = wmgr->openWallet(filename, password, Monero::NetworkType::TESTNET); + Wallet::WalletManager *wmgr = Wallet::WalletManagerFactory::getWalletManager(); + Wallet::Wallet * w = wmgr->openWallet(filename, password, Wallet::NetworkType::TESTNET); std::string result = w->mainAddress(); wmgr->closeWallet(w); return result; @@ -137,16 +136,16 @@ struct Utils struct WalletManagerTest : public testing::Test { - Monero::WalletManager * wmgr; + Wallet::WalletManager * wmgr; WalletManagerTest() { std::cout << __FUNCTION__ << std::endl; - wmgr = Monero::WalletManagerFactory::getWalletManager(); - // Monero::WalletManagerFactory::setLogLevel(Monero::WalletManagerFactory::LogLevel_4); + wmgr = Wallet::WalletManagerFactory::getWalletManager(); + // Wallet::WalletManagerFactory::setLogLevel(Wallet::WalletManagerFactory::LogLevel_4); Utils::deleteWallet(WALLET_NAME); - Utils::deleteDir(boost::filesystem::path(WALLET_NAME_WITH_DIR).parent_path().string()); + Utils::deleteDir(fs::path(WALLET_NAME_WITH_DIR).parent_path().string()); } @@ -160,13 +159,13 @@ struct WalletManagerTest : public testing::Test struct WalletManagerMainnetTest : public testing::Test { - Monero::WalletManager * wmgr; + Wallet::WalletManager * wmgr; WalletManagerMainnetTest() { std::cout << __FUNCTION__ << std::endl; - wmgr = Monero::WalletManagerFactory::getWalletManager(); + wmgr = Wallet::WalletManagerFactory::getWalletManager(); Utils::deleteWallet(WALLET_NAME_MAINNET); } @@ -180,11 +179,11 @@ struct WalletManagerMainnetTest : public testing::Test struct WalletTest1 : public testing::Test { - Monero::WalletManager * wmgr; + Wallet::WalletManager * wmgr; WalletTest1() { - wmgr = Monero::WalletManagerFactory::getWalletManager(); + wmgr = Wallet::WalletManagerFactory::getWalletManager(); } @@ -193,11 +192,11 @@ struct WalletTest1 : public testing::Test struct WalletTest2 : public testing::Test { - Monero::WalletManager * wmgr; + Wallet::WalletManager * wmgr; WalletTest2() { - wmgr = Monero::WalletManagerFactory::getWalletManager(); + wmgr = Wallet::WalletManagerFactory::getWalletManager(); } }; @@ -205,8 +204,8 @@ struct WalletTest2 : public testing::Test TEST_F(WalletManagerTest, WalletManagerCreatesWallet) { - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet->status() == Monero::Wallet::Status_Ok); + Wallet::Wallet * wallet = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(!wallet->seed().empty()); std::vector words; std::string seed = wallet->seed(); @@ -222,11 +221,11 @@ TEST_F(WalletManagerTest, WalletManagerCreatesWallet) TEST_F(WalletManagerTest, WalletManagerOpensWallet) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); + Wallet::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet2->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); std::cout << "** seed: " << wallet2->seed() << std::endl; } @@ -234,31 +233,31 @@ TEST_F(WalletManagerTest, WalletManagerOpensWallet) TEST_F(WalletManagerTest, WalletMaxAmountAsString) { - LOG_PRINT_L3("max amount: " << Monero::Wallet::displayAmount( - Monero::Wallet::maximumAllowedAmount())); + LOG_PRINT_L3("max amount: " << Wallet::Wallet::displayAmount( + Wallet::Wallet::maximumAllowedAmount())); } TEST_F(WalletManagerTest, WalletAmountFromString) { - uint64_t amount = Monero::Wallet::amountFromString("18446740"); + uint64_t amount = Wallet::Wallet::amountFromString("18446740"); ASSERT_TRUE(amount > 0); - amount = Monero::Wallet::amountFromString("11000000000000"); + amount = Wallet::Wallet::amountFromString("11000000000000"); ASSERT_FALSE(amount > 0); - amount = Monero::Wallet::amountFromString("0.0"); + amount = Wallet::Wallet::amountFromString("0.0"); ASSERT_FALSE(amount > 0); - amount = Monero::Wallet::amountFromString("10.1"); + amount = Wallet::Wallet::amountFromString("10.1"); ASSERT_TRUE(amount > 0); } -void open_wallet_helper(Monero::WalletManager *wmgr, Monero::Wallet **wallet, const std::string &pass, std::mutex *mutex) +void open_wallet_helper(Wallet::WalletManager *wmgr, Wallet::Wallet **wallet, const std::string &pass, std::mutex *mutex) { if (mutex) mutex->lock(); LOG_PRINT_L3("opening wallet in thread: " << boost::this_thread::get_id()); - *wallet = wmgr->openWallet(WALLET_NAME, pass, Monero::NetworkType::TESTNET); + *wallet = wmgr->openWallet(WALLET_NAME, pass, Wallet::NetworkType::TESTNET); LOG_PRINT_L3("wallet address: " << (*wallet)->mainAddress()); LOG_PRINT_L3("wallet status: " << (*wallet)->status()); LOG_PRINT_L3("closing wallet in thread: " << boost::this_thread::get_id()); @@ -274,23 +273,23 @@ void open_wallet_helper(Monero::WalletManager *wmgr, Monero::Wallet **wallet, co // // create password protected wallet // std::string wallet_pass = "password"; // std::string wrong_wallet_pass = "1111"; -// Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, Monero::NetworkType::TESTNET); +// Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, Wallet::NetworkType::TESTNET); // std::string seed1 = wallet1->seed(); // ASSERT_TRUE(wmgr->closeWallet(wallet1)); -// Monero::Wallet *wallet2 = nullptr; -// Monero::Wallet *wallet3 = nullptr; +// Wallet::Wallet *wallet2 = nullptr; +// Wallet::Wallet *wallet3 = nullptr; // std::mutex mutex; // std::thread thread1(open_wallet, wmgr, &wallet2, wrong_wallet_pass, &mutex); // thread1.join(); -// ASSERT_TRUE(wallet2->status() != Monero::Wallet::Status_Ok); +// ASSERT_TRUE(wallet2->status() != Wallet::Wallet::Status_Ok); // ASSERT_TRUE(wmgr->closeWallet(wallet2)); // std::thread thread2(open_wallet, wmgr, &wallet3, wallet_pass, &mutex); // thread2.join(); -// ASSERT_TRUE(wallet3->status() == Monero::Wallet::Status_Ok); +// ASSERT_TRUE(wallet3->status() == Wallet::Wallet::Status_Ok); // ASSERT_TRUE(wmgr->closeWallet(wallet3)); //} @@ -300,22 +299,22 @@ TEST_F(WalletManagerTest, WalletManagerOpensWalletWithPasswordAndReopen) // create password protected wallet std::string wallet_pass = "password"; std::string wrong_wallet_pass = "1111"; - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, wallet_pass, WALLET_LANG, Wallet::NetworkType::TESTNET); std::string seed1 = wallet1->seed(); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet *wallet2 = nullptr; - Monero::Wallet *wallet3 = nullptr; + Wallet::Wallet *wallet2 = nullptr; + Wallet::Wallet *wallet3 = nullptr; std::mutex mutex; open_wallet_helper(wmgr, &wallet2, wrong_wallet_pass, nullptr); ASSERT_TRUE(wallet2 != nullptr); - ASSERT_TRUE(wallet2->status() != Monero::Wallet::Status_Ok); + ASSERT_TRUE(wallet2->status() != Wallet::Wallet::Status_Ok); ASSERT_TRUE(wmgr->closeWallet(wallet2)); open_wallet_helper(wmgr, &wallet3, wallet_pass, nullptr); ASSERT_TRUE(wallet3 != nullptr); - ASSERT_TRUE(wallet3->status() == Monero::Wallet::Status_Ok); + ASSERT_TRUE(wallet3->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wmgr->closeWallet(wallet3)); } @@ -323,12 +322,12 @@ TEST_F(WalletManagerTest, WalletManagerOpensWalletWithPasswordAndReopen) TEST_F(WalletManagerTest, WalletManagerStoresWallet) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); wallet1->store(""); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); + Wallet::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet2->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); } @@ -336,45 +335,45 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet) TEST_F(WalletManagerTest, WalletManagerMovesWallet) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); std::string WALLET_NAME_MOVED = std::string("/tmp/") + WALLET_NAME + ".moved"; std::string seed1 = wallet1->seed(); ASSERT_TRUE(wallet1->store(WALLET_NAME_MOVED)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME_MOVED, WALLET_PASS, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME_MOVED, WALLET_PASS, Wallet::NetworkType::MAINNET); ASSERT_TRUE(wallet2->filename() == WALLET_NAME_MOVED); ASSERT_TRUE(wallet2->keysFilename() == WALLET_NAME_MOVED + ".keys"); - ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); + ASSERT_TRUE(wallet2->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); } TEST_F(WalletManagerTest, WalletManagerChangesPassword) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); ASSERT_TRUE(wallet1->setPassword(WALLET_PASS2)); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS2, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); + Wallet::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME, WALLET_PASS2, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet2->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); ASSERT_TRUE(wmgr->closeWallet(wallet2)); - Monero::Wallet * wallet3 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); - ASSERT_FALSE(wallet3->status() == Monero::Wallet::Status_Ok); + Wallet::Wallet * wallet3 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Wallet::NetworkType::MAINNET); + ASSERT_FALSE(wallet3->status() == Wallet::Wallet::Status_Ok); } TEST_F(WalletManagerTest, WalletManagerRecoversWallet) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); ASSERT_FALSE(address1.empty()); ASSERT_TRUE(wmgr->closeWallet(wallet1)); Utils::deleteWallet(WALLET_NAME); - Monero::Wallet * wallet2 = wmgr->recoveryWallet(WALLET_NAME, seed1, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); + Wallet::Wallet * wallet2 = wmgr->recoveryWallet(WALLET_NAME, seed1, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet2->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); ASSERT_TRUE(wallet2->mainAddress() == address1); ASSERT_TRUE(wmgr->closeWallet(wallet2)); @@ -383,15 +382,15 @@ TEST_F(WalletManagerTest, WalletManagerRecoversWallet) TEST_F(WalletManagerTest, WalletManagerStoresWallet1) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); ASSERT_TRUE(wallet1->store("")); ASSERT_TRUE(wallet1->store(WALLET_NAME_COPY)); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME_COPY, WALLET_PASS, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet2->status() == Monero::Wallet::Status_Ok); + Wallet::Wallet * wallet2 = wmgr->openWallet(WALLET_NAME_COPY, WALLET_PASS, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet2->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet2->seed() == seed1); ASSERT_TRUE(wallet2->mainAddress() == address1); ASSERT_TRUE(wmgr->closeWallet(wallet2)); @@ -400,15 +399,15 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet1) TEST_F(WalletManagerTest, WalletManagerStoresWallet2) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); ASSERT_TRUE(wallet1->store(WALLET_NAME_WITH_DIR)); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - wallet1 = wmgr->openWallet(WALLET_NAME_WITH_DIR, WALLET_PASS, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet1->status() == Monero::Wallet::Status_Ok); + wallet1 = wmgr->openWallet(WALLET_NAME_WITH_DIR, WALLET_PASS, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet1->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet1->seed() == seed1); ASSERT_TRUE(wallet1->mainAddress() == address1); ASSERT_TRUE(wmgr->closeWallet(wallet1)); @@ -417,21 +416,21 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet2) TEST_F(WalletManagerTest, WalletManagerStoresWallet3) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); ASSERT_FALSE(wallet1->store(WALLET_NAME_WITH_DIR_NON_WRITABLE)); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - wallet1 = wmgr->openWallet(WALLET_NAME_WITH_DIR_NON_WRITABLE, WALLET_PASS, Monero::NetworkType::MAINNET); - ASSERT_FALSE(wallet1->status() == Monero::Wallet::Status_Ok); + wallet1 = wmgr->openWallet(WALLET_NAME_WITH_DIR_NON_WRITABLE, WALLET_PASS, Wallet::NetworkType::MAINNET); + ASSERT_FALSE(wallet1->status() == Wallet::Wallet::Status_Ok); // "close" always returns true; ASSERT_TRUE(wmgr->closeWallet(wallet1)); - wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet1->status() == Monero::Wallet::Status_Ok); + wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet1->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet1->seed() == seed1); ASSERT_TRUE(wallet1->mainAddress() == address1); ASSERT_TRUE(wmgr->closeWallet(wallet1)); @@ -441,20 +440,20 @@ TEST_F(WalletManagerTest, WalletManagerStoresWallet3) TEST_F(WalletManagerTest, WalletManagerStoresWallet4) { - Monero::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet1 = wmgr->createWallet(WALLET_NAME, WALLET_PASS, WALLET_LANG, Wallet::NetworkType::MAINNET); std::string seed1 = wallet1->seed(); std::string address1 = wallet1->mainAddress(); ASSERT_TRUE(wallet1->store("")); - ASSERT_TRUE(wallet1->status() == Monero::Wallet::Status_Ok); + ASSERT_TRUE(wallet1->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet1->store("")); - ASSERT_TRUE(wallet1->status() == Monero::Wallet::Status_Ok); + ASSERT_TRUE(wallet1->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet1->status() == Monero::Wallet::Status_Ok); + wallet1 = wmgr->openWallet(WALLET_NAME, WALLET_PASS, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet1->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet1->seed() == seed1); ASSERT_TRUE(wallet1->mainAddress() == address1); ASSERT_TRUE(wmgr->closeWallet(wallet1)); @@ -476,16 +475,16 @@ TEST_F(WalletManagerTest, WalletManagerFindsWallet) TEST_F(WalletTest1, WalletGeneratesPaymentId) { - std::string payment_id = Monero::Wallet::genPaymentId(); + std::string payment_id = Wallet::Wallet::genPaymentId(); ASSERT_TRUE(payment_id.length() == 16); } TEST_F(WalletTest1, WalletGeneratesIntegratedAddress) { - std::string payment_id = Monero::Wallet::genPaymentId(); + std::string payment_id = Wallet::Wallet::genPaymentId(); - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); std::string integrated_address = wallet1->integratedAddress(payment_id); ASSERT_TRUE(integrated_address.length() == 106); } @@ -493,14 +492,14 @@ TEST_F(WalletTest1, WalletGeneratesIntegratedAddress) TEST_F(WalletTest1, WalletShowsBalance) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); ASSERT_TRUE(wallet1->balance(0) > 0); ASSERT_TRUE(wallet1->unlockedBalance(0) > 0); uint64_t balance1 = wallet1->balance(0); uint64_t unlockedBalance1 = wallet1->unlockedBalance(0); ASSERT_TRUE(wmgr->closeWallet(wallet1)); - Monero::Wallet * wallet2 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet2 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); ASSERT_TRUE(balance1 == wallet2->balance(0)); std::cout << "wallet balance: " << wallet2->balance(0) << std::endl; @@ -511,7 +510,7 @@ TEST_F(WalletTest1, WalletShowsBalance) TEST_F(WalletTest1, WalletReturnsCurrentBlockHeight) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); ASSERT_TRUE(wallet1->blockChainHeight() > 0); wmgr->closeWallet(wallet1); } @@ -519,14 +518,14 @@ TEST_F(WalletTest1, WalletReturnsCurrentBlockHeight) TEST_F(WalletTest1, WalletReturnsDaemonBlockHeight) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // wallet not connected to daemon ASSERT_TRUE(wallet1->daemonBlockChainHeight() == 0); - ASSERT_TRUE(wallet1->status() != Monero::Wallet::Status_Ok); + ASSERT_TRUE(wallet1->status() != Wallet::Wallet::Status_Ok); ASSERT_FALSE(wallet1->errorString().empty()); wmgr->closeWallet(wallet1); - wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // wallet connected to daemon wallet1->init(TESTNET_DAEMON_ADDRESS, 0); ASSERT_TRUE(wallet1->daemonBlockChainHeight() > 0); @@ -539,7 +538,7 @@ TEST_F(WalletTest1, WalletRefresh) { std::cout << "Opening wallet: " << CURRENT_SRC_WALLET << std::endl; - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running std::cout << "connecting to daemon: " << TESTNET_DAEMON_ADDRESS << std::endl; ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0)); @@ -549,12 +548,12 @@ TEST_F(WalletTest1, WalletRefresh) TEST_F(WalletTest1, WalletConvertsToString) { - std::string strAmount = Monero::Wallet::displayAmount(AMOUNT_5XMR); - ASSERT_TRUE(AMOUNT_5XMR == Monero::Wallet::amountFromString(strAmount)); + std::string strAmount = Wallet::Wallet::displayAmount(AMOUNT_5XMR); + ASSERT_TRUE(AMOUNT_5XMR == Wallet::Wallet::amountFromString(strAmount)); - ASSERT_TRUE(AMOUNT_5XMR == Monero::Wallet::amountFromDouble(5.0)); - ASSERT_TRUE(AMOUNT_10XMR == Monero::Wallet::amountFromDouble(10.0)); - ASSERT_TRUE(AMOUNT_1XMR == Monero::Wallet::amountFromDouble(1.0)); + ASSERT_TRUE(AMOUNT_5XMR == Wallet::Wallet::amountFromDouble(5.0)); + ASSERT_TRUE(AMOUNT_10XMR == Wallet::Wallet::amountFromDouble(10.0)); + ASSERT_TRUE(AMOUNT_1XMR == Wallet::Wallet::amountFromDouble(1.0)); } @@ -563,25 +562,25 @@ TEST_F(WalletTest1, WalletConvertsToString) TEST_F(WalletTest1, WalletTransaction) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet1->refresh()); uint64_t balance = wallet1->balance(0); - ASSERT_TRUE(wallet1->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(wallet1->status() == Wallet::PendingTransaction::Status_Ok); std::string recepient_address = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS); const int MIXIN_COUNT = 4; - Monero::PendingTransaction * transaction = wallet1->createTransaction(recepient_address, + Wallet::PendingTransaction * transaction = wallet1->createTransaction(recepient_address, PAYMENT_ID_EMPTY, AMOUNT_10XMR, MIXIN_COUNT, - Monero::PendingTransaction::Priority_Medium, + Wallet::PendingTransaction::Priority_Medium, 0, std::set{}); - ASSERT_TRUE(transaction->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(transaction->status() == Wallet::PendingTransaction::Status_Ok); wallet1->refresh(); ASSERT_TRUE(wallet1->balance(0) == balance); @@ -605,26 +604,26 @@ TEST_F(WalletTest1, WalletTransactionWithMixin) std::string payment_id = ""; - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet1->refresh()); uint64_t balance = wallet1->balance(0); - ASSERT_TRUE(wallet1->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(wallet1->status() == Wallet::PendingTransaction::Status_Ok); std::string recepient_address = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS); for (auto mixin : mixins) { std::cerr << "Transaction mixin count: " << mixin << std::endl; - Monero::PendingTransaction * transaction = wallet1->createTransaction( - recepient_address, payment_id, AMOUNT_5XMR, mixin, Monero::PendingTransaction::Priority_Medium, 0, std::set{}); + Wallet::PendingTransaction * transaction = wallet1->createTransaction( + recepient_address, payment_id, AMOUNT_5XMR, mixin, Wallet::PendingTransaction::Priority_Medium, 0, std::set{}); std::cerr << "Transaction status: " << transaction->status() << std::endl; - std::cerr << "Transaction fee: " << Monero::Wallet::displayAmount(transaction->fee()) << std::endl; + std::cerr << "Transaction fee: " << Wallet::Wallet::displayAmount(transaction->fee()) << std::endl; std::cerr << "Transaction error: " << transaction->errorString() << std::endl; - ASSERT_TRUE(transaction->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(transaction->status() == Wallet::PendingTransaction::Status_Ok); wallet1->disposeTransaction(transaction); } @@ -639,34 +638,34 @@ TEST_F(WalletTest1, WalletTransactionWithPriority) std::string payment_id = ""; - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet1->refresh()); uint64_t balance = wallet1->balance(0); - ASSERT_TRUE(wallet1->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(wallet1->status() == Wallet::PendingTransaction::Status_Ok); std::string recepient_address = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS); uint32_t mixin = 2; uint64_t fee = 0; - std::vector priorities = { - Monero::PendingTransaction::Priority_Low, - Monero::PendingTransaction::Priority_Medium, - Monero::PendingTransaction::Priority_High + std::vector priorities = { + Wallet::PendingTransaction::Priority_Low, + Wallet::PendingTransaction::Priority_Medium, + Wallet::PendingTransaction::Priority_High }; for (auto it = priorities.begin(); it != priorities.end(); ++it) { std::cerr << "Transaction priority: " << *it << std::endl; - Monero::PendingTransaction * transaction = wallet1->createTransaction( + Wallet::PendingTransaction * transaction = wallet1->createTransaction( recepient_address, payment_id, AMOUNT_5XMR, mixin, *it, 0, std::set{}); std::cerr << "Transaction status: " << transaction->status() << std::endl; - std::cerr << "Transaction fee: " << Monero::Wallet::displayAmount(transaction->fee()) << std::endl; + std::cerr << "Transaction fee: " << Wallet::Wallet::displayAmount(transaction->fee()) << std::endl; std::cerr << "Transaction error: " << transaction->errorString() << std::endl; ASSERT_TRUE(transaction->fee() > fee); - ASSERT_TRUE(transaction->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(transaction->status() == Wallet::PendingTransaction::Status_Ok); fee = transaction->fee(); wallet1->disposeTransaction(transaction); } @@ -679,11 +678,11 @@ TEST_F(WalletTest1, WalletTransactionWithPriority) TEST_F(WalletTest1, WalletHistory) { - Monero::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet1 = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet1->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet1->refresh()); - Monero::TransactionHistory * history = wallet1->history(); + Wallet::TransactionHistory * history = wallet1->history(); history->refresh(); ASSERT_TRUE(history->count() > 0); @@ -697,11 +696,11 @@ TEST_F(WalletTest1, WalletHistory) TEST_F(WalletTest1, WalletTransactionAndHistory) { return; - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); - Monero::TransactionHistory * history = wallet_src->history(); + Wallet::TransactionHistory * history = wallet_src->history(); history->refresh(); ASSERT_TRUE(history->count() > 0); size_t count1 = history->count(); @@ -715,11 +714,11 @@ TEST_F(WalletTest1, WalletTransactionAndHistory) std::string wallet4_addr = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS); - Monero::PendingTransaction * tx = wallet_src->createTransaction(wallet4_addr, + Wallet::PendingTransaction * tx = wallet_src->createTransaction(wallet4_addr, PAYMENT_ID_EMPTY, - AMOUNT_10XMR * 5, 1, Monero::PendingTransaction::Priority_Medium, 0, std::set{}); + AMOUNT_10XMR * 5, 1, Wallet::PendingTransaction::Priority_Medium, 0, std::set{}); - ASSERT_TRUE(tx->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(tx->status() == Wallet::PendingTransaction::Status_Ok); ASSERT_TRUE(tx->commit()); history = wallet_src->history(); history->refresh(); @@ -736,11 +735,11 @@ TEST_F(WalletTest1, WalletTransactionAndHistory) TEST_F(WalletTest1, WalletTransactionWithPaymentId) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); - Monero::TransactionHistory * history = wallet_src->history(); + Wallet::TransactionHistory * history = wallet_src->history(); history->refresh(); ASSERT_TRUE(history->count() > 0); size_t count1 = history->count(); @@ -753,15 +752,15 @@ TEST_F(WalletTest1, WalletTransactionWithPaymentId) std::string wallet4_addr = Utils::get_wallet_address(CURRENT_DST_WALLET, TESTNET_WALLET_PASS); - std::string payment_id = Monero::Wallet::genPaymentId(); + std::string payment_id = Wallet::Wallet::genPaymentId(); ASSERT_TRUE(payment_id.length() == 16); - Monero::PendingTransaction * tx = wallet_src->createTransaction(wallet4_addr, + Wallet::PendingTransaction * tx = wallet_src->createTransaction(wallet4_addr, payment_id, - AMOUNT_1XMR, 1, Monero::PendingTransaction::Priority_Medium, 0, std::set{}); + AMOUNT_1XMR, 1, Wallet::PendingTransaction::Priority_Medium, 0, std::set{}); - ASSERT_TRUE(tx->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(tx->status() == Wallet::PendingTransaction::Status_Ok); ASSERT_TRUE(tx->commit()); history = wallet_src->history(); history->refresh(); @@ -782,10 +781,10 @@ TEST_F(WalletTest1, WalletTransactionWithPaymentId) } -struct MyWalletListener : public Monero::WalletListener +struct MyWalletListener : public Wallet::WalletListener { - Monero::Wallet * wallet; + Wallet::Wallet * wallet; uint64_t total_tx; uint64_t total_rx; std::mutex mutex; @@ -802,7 +801,7 @@ struct MyWalletListener : public Monero::WalletListener - MyWalletListener(Monero::Wallet * wallet) + MyWalletListener(Wallet::Wallet * wallet) : total_tx(0), total_rx(0) { reset(); @@ -878,7 +877,7 @@ struct MyWalletListener : public Monero::WalletListener TEST_F(WalletTest2, WalletCallBackRefreshedSync) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); MyWalletListener * wallet_src_listener = new MyWalletListener(wallet_src); ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src_listener->refresh_triggered); @@ -894,7 +893,7 @@ TEST_F(WalletTest2, WalletCallBackRefreshedSync) TEST_F(WalletTest2, WalletCallBackRefreshedAsync) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); MyWalletListener * wallet_src_listener = new MyWalletListener(wallet_src); std::unique_lock lock{wallet_src_listener->mutex}; @@ -915,26 +914,26 @@ TEST_F(WalletTest2, WalletCallBackRefreshedAsync) TEST_F(WalletTest2, WalletCallbackSent) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); MyWalletListener * wallet_src_listener = new MyWalletListener(wallet_src); uint64_t balance = wallet_src->balance(0); std::cout << "** Balance: " << wallet_src->displayAmount(wallet_src->balance(0)) << std::endl; - Monero::Wallet * wallet_dst = wmgr->openWallet(CURRENT_DST_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet_dst = wmgr->openWallet(CURRENT_DST_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); uint64_t amount = AMOUNT_1XMR * 5; - std::cout << "** Sending " << Monero::Wallet::displayAmount(amount) << " to " << wallet_dst->mainAddress(); + std::cout << "** Sending " << Wallet::Wallet::displayAmount(amount) << " to " << wallet_dst->mainAddress(); - Monero::PendingTransaction * tx = wallet_src->createTransaction(wallet_dst->mainAddress(), + Wallet::PendingTransaction * tx = wallet_src->createTransaction(wallet_dst->mainAddress(), PAYMENT_ID_EMPTY, - amount, 1, Monero::PendingTransaction::Priority_Medium, 0, std::set{}); - std::cout << "** Committing transaction: " << Monero::Wallet::displayAmount(tx->amount()) - << " with fee: " << Monero::Wallet::displayAmount(tx->fee()); + amount, 1, Wallet::PendingTransaction::Priority_Medium, 0, std::set{}); + std::cout << "** Committing transaction: " << Wallet::Wallet::displayAmount(tx->amount()) + << " with fee: " << Wallet::Wallet::displayAmount(tx->fee()); - ASSERT_TRUE(tx->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(tx->status() == Wallet::PendingTransaction::Status_Ok); ASSERT_TRUE(tx->commit()); std::unique_lock lock{wallet_src_listener->mutex}; @@ -953,13 +952,13 @@ TEST_F(WalletTest2, WalletCallbackSent) TEST_F(WalletTest2, WalletCallbackReceived) { - Monero::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet_src = wmgr->openWallet(CURRENT_SRC_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); std::cout << "** Balance src1: " << wallet_src->displayAmount(wallet_src->balance(0)) << std::endl; - Monero::Wallet * wallet_dst = wmgr->openWallet(CURRENT_DST_WALLET, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet_dst = wmgr->openWallet(CURRENT_DST_WALLET, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); ASSERT_TRUE(wallet_dst->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_dst->refresh()); uint64_t balance = wallet_dst->balance(0); @@ -967,15 +966,15 @@ TEST_F(WalletTest2, WalletCallbackReceived) std::unique_ptr wallet_dst_listener (new MyWalletListener(wallet_dst)); uint64_t amount = AMOUNT_1XMR * 5; - std::cout << "** Sending " << Monero::Wallet::displayAmount(amount) << " to " << wallet_dst->mainAddress(); - Monero::PendingTransaction * tx = wallet_src->createTransaction(wallet_dst->mainAddress(), + std::cout << "** Sending " << Wallet::Wallet::displayAmount(amount) << " to " << wallet_dst->mainAddress(); + Wallet::PendingTransaction * tx = wallet_src->createTransaction(wallet_dst->mainAddress(), PAYMENT_ID_EMPTY, - amount, 1, Monero::PendingTransaction::Priority_Medium, 0, std::set{}); + amount, 1, Wallet::PendingTransaction::Priority_Medium, 0, std::set{}); - std::cout << "** Committing transaction: " << Monero::Wallet::displayAmount(tx->amount()) - << " with fee: " << Monero::Wallet::displayAmount(tx->fee()); + std::cout << "** Committing transaction: " << Wallet::Wallet::displayAmount(tx->amount()) + << " with fee: " << Wallet::Wallet::displayAmount(tx->fee()); - ASSERT_TRUE(tx->status() == Monero::PendingTransaction::Status_Ok); + ASSERT_TRUE(tx->status() == Wallet::PendingTransaction::Status_Ok); ASSERT_TRUE(tx->commit()); std::unique_lock lock{wallet_dst_listener->mutex}; @@ -999,7 +998,7 @@ TEST_F(WalletTest2, WalletCallbackReceived) TEST_F(WalletTest2, WalletCallbackNewBlock) { - Monero::Wallet * wallet_src = wmgr->openWallet(TESTNET_WALLET5_NAME, TESTNET_WALLET_PASS, Monero::NetworkType::TESTNET); + Wallet::Wallet * wallet_src = wmgr->openWallet(TESTNET_WALLET5_NAME, TESTNET_WALLET_PASS, Wallet::NetworkType::TESTNET); // make sure testnet daemon is running ASSERT_TRUE(wallet_src->init(TESTNET_DAEMON_ADDRESS, 0)); ASSERT_TRUE(wallet_src->refresh()); @@ -1025,7 +1024,7 @@ TEST_F(WalletTest2, WalletCallbackNewBlock) TEST_F(WalletManagerMainnetTest, CreateOpenAndRefreshWalletMainNetSync) { - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Wallet::NetworkType::MAINNET); std::unique_ptr wallet_listener (new MyWalletListener(wallet)); wallet->init(MAINNET_DAEMON_ADDRESS, 0); std::cerr << "TEST: waiting on refresh lock...\n"; @@ -1044,7 +1043,7 @@ TEST_F(WalletManagerMainnetTest, CreateAndRefreshWalletMainNetAsync) // supposing 2 minutes should be enough for fast refresh constexpr auto wait_for = 2min; - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Wallet::NetworkType::MAINNET); std::unique_ptr wallet_listener (new MyWalletListener(wallet)); std::unique_lock lock{wallet_listener->mutex}; @@ -1053,7 +1052,7 @@ TEST_F(WalletManagerMainnetTest, CreateAndRefreshWalletMainNetAsync) std::cerr << "TEST: waiting on refresh lock...\n"; wallet_listener->cv_refresh.wait_for(lock, wait_for); std::cerr << "TEST: refresh lock acquired...\n"; - ASSERT_TRUE(wallet->status() == Monero::Wallet::Status_Ok); + ASSERT_TRUE(wallet->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet_listener->refresh_triggered); ASSERT_TRUE(wallet->connected()); ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight()); @@ -1067,9 +1066,9 @@ TEST_F(WalletManagerMainnetTest, OpenAndRefreshWalletMainNetAsync) // supposing 2 minutes should be enough for fast refresh constexpr auto wait_for = 2min; - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Wallet::NetworkType::MAINNET); wmgr->closeWallet(wallet); - wallet = wmgr->openWallet(WALLET_NAME_MAINNET, "", Monero::NetworkType::MAINNET); + wallet = wmgr->openWallet(WALLET_NAME_MAINNET, "", Wallet::NetworkType::MAINNET); std::unique_ptr wallet_listener (new MyWalletListener(wallet)); @@ -1079,7 +1078,7 @@ TEST_F(WalletManagerMainnetTest, OpenAndRefreshWalletMainNetAsync) std::cerr << "TEST: waiting on refresh lock...\n"; wallet_listener->cv_refresh.wait_for(lock, wait_for); std::cerr << "TEST: refresh lock acquired...\n"; - ASSERT_TRUE(wallet->status() == Monero::Wallet::Status_Ok); + ASSERT_TRUE(wallet->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet_listener->refresh_triggered); ASSERT_TRUE(wallet->connected()); ASSERT_TRUE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight()); @@ -1093,7 +1092,7 @@ TEST_F(WalletManagerMainnetTest, RecoverAndRefreshWalletMainNetAsync) // supposing 2 minutes should be enough for fast refresh constexpr auto wait_for = 2min; - Monero::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Monero::NetworkType::MAINNET); + Wallet::Wallet * wallet = wmgr->createWallet(WALLET_NAME_MAINNET, "", WALLET_LANG, Wallet::NetworkType::MAINNET); std::string seed = wallet->seed(); std::string address = wallet->mainAddress(); wmgr->closeWallet(wallet); @@ -1102,8 +1101,8 @@ TEST_F(WalletManagerMainnetTest, RecoverAndRefreshWalletMainNetAsync) Utils::deleteWallet(WALLET_NAME_MAINNET); // ..and recovering wallet from seed - wallet = wmgr->recoveryWallet(WALLET_NAME_MAINNET, seed, Monero::NetworkType::MAINNET); - ASSERT_TRUE(wallet->status() == Monero::Wallet::Status_Ok); + wallet = wmgr->recoveryWallet(WALLET_NAME_MAINNET, seed, Wallet::NetworkType::MAINNET); + ASSERT_TRUE(wallet->status() == Wallet::Wallet::Status_Ok); ASSERT_TRUE(wallet->mainAddress() == address); std::unique_ptr wallet_listener (new MyWalletListener(wallet)); std::unique_lock lock{wallet_listener->mutex}; @@ -1115,7 +1114,7 @@ TEST_F(WalletManagerMainnetTest, RecoverAndRefreshWalletMainNetAsync) // as it needs much more than 120 seconds for mainnet wallet_listener->cv_refresh.wait_for(lock, wait_for); - ASSERT_TRUE(wallet->status() == Monero::Wallet::Status_Ok); + ASSERT_TRUE(wallet->status() == Wallet::Wallet::Status_Ok); ASSERT_FALSE(wallet_listener->refresh_triggered); ASSERT_TRUE(wallet->connected()); ASSERT_FALSE(wallet->blockChainHeight() == wallet->daemonBlockChainHeight()); @@ -1163,7 +1162,7 @@ int main(int argc, char** argv) CURRENT_DST_WALLET = TESTNET_WALLET1_NAME; ::testing::InitGoogleTest(&argc, argv); - Monero::WalletManagerFactory::setLogLevel(Monero::WalletManagerFactory::LogLevel_Max); + Wallet::WalletManagerFactory::setLogLevel(Wallet::WalletManagerFactory::LogLevel_Max); return RUN_ALL_TESTS(); CATCH_ENTRY_L0("main", 1); } diff --git a/tests/net_load_tests/CMakeLists.txt b/tests/net_load_tests/CMakeLists.txt index d2445682c..569fc75bd 100644 --- a/tests/net_load_tests/CMakeLists.txt +++ b/tests/net_load_tests/CMakeLists.txt @@ -34,7 +34,6 @@ target_link_libraries(net_load_tests_clt cryptonote_core epee gtest - Boost::date_time Boost::thread extra) @@ -46,7 +45,6 @@ target_link_libraries(net_load_tests_srv cryptonote_core epee gtest - Boost::date_time extra) set_property(TARGET net_load_tests_clt net_load_tests_srv diff --git a/tests/net_load_tests/clt.cpp b/tests/net_load_tests/clt.cpp index 69638c469..91ebe7eef 100644 --- a/tests/net_load_tests/clt.cpp +++ b/tests/net_load_tests/clt.cpp @@ -37,10 +37,9 @@ #include "gtest/gtest.h" -#include "include_base_utils.h" -#include "misc_language.h" -#include "misc_log_ex.h" -#include "storages/levin_abstract_invoke2.h" +#include "epee/misc_language.h" +#include "epee/misc_log_ex.h" +#include "epee/storages/levin_abstract_invoke2.h" #include "common/util.h" #include "net_load_tests.h" diff --git a/tests/net_load_tests/net_load_tests.h b/tests/net_load_tests/net_load_tests.h index 6c4f7cb76..11b03ae94 100644 --- a/tests/net_load_tests/net_load_tests.h +++ b/tests/net_load_tests/net_load_tests.h @@ -35,11 +35,10 @@ #include #include -#include "include_base_utils.h" -#include "string_tools.h" -#include "net/levin_protocol_handler_async.h" -#include "net/abstract_tcp_server2.h" -#include "serialization/keyvalue_serialization.h" +#include "epee/string_tools.h" +#include "epee/net/levin_protocol_handler_async.h" +#include "epee/net/abstract_tcp_server2.h" +#include "epee/serialization/keyvalue_serialization.h" #include "../unit_tests/unit_tests_utils.h" diff --git a/tests/net_load_tests/srv.cpp b/tests/net_load_tests/srv.cpp index 114f3b90e..13a55cb26 100644 --- a/tests/net_load_tests/srv.cpp +++ b/tests/net_load_tests/srv.cpp @@ -31,9 +31,8 @@ #include #include -#include "include_base_utils.h" -#include "misc_log_ex.h" -#include "storages/levin_abstract_invoke2.h" +#include "epee/misc_log_ex.h" +#include "epee/storages/levin_abstract_invoke2.h" #include "common/util.h" #include "net_load_tests.h" diff --git a/tests/performance_tests/CMakeLists.txt b/tests/performance_tests/CMakeLists.txt index 30d1c6a89..c7e8d7f37 100644 --- a/tests/performance_tests/CMakeLists.txt +++ b/tests/performance_tests/CMakeLists.txt @@ -27,7 +27,8 @@ # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. add_executable(performance_tests - main.cpp) + main.cpp + timings.cc) target_link_libraries(performance_tests PRIVATE wallet diff --git a/tests/performance_tests/cn_slow_hash.h b/tests/performance_tests/cn_slow_hash.h index 5d75977a0..25dc54dbe 100644 --- a/tests/performance_tests/cn_slow_hash.h +++ b/tests/performance_tests/cn_slow_hash.h @@ -30,9 +30,9 @@ #pragma once -#include "string_tools.h" #include "crypto/crypto.h" #include "cryptonote_basic/cryptonote_basic.h" +#include "common/hex.h" class test_cn_slow_hash { @@ -50,10 +50,10 @@ public: bool init() { - if (!epee::string_tools::hex_to_pod("63617665617420656d70746f72", m_data)) + if (!tools::hex_to_type("63617665617420656d70746f72", m_data)) return false; - if (!epee::string_tools::hex_to_pod("bbec2cacf69866a8e740380fe7b818fc78f8571221742d729d9d02d7f8989b87", m_expected_hash)) + if (!tools::hex_to_type("bbec2cacf69866a8e740380fe7b818fc78f8571221742d729d9d02d7f8989b87", m_expected_hash)) return false; return true; diff --git a/tests/performance_tests/performance_tests.h b/tests/performance_tests/performance_tests.h index d2b88982f..2e75a55f7 100644 --- a/tests/performance_tests/performance_tests.h +++ b/tests/performance_tests/performance_tests.h @@ -36,10 +36,10 @@ #include #include -#include "misc_language.h" -#include "stats.h" +#include "epee/misc_language.h" +#include "epee/stats.h" #include "common/perf_timer.h" -#include "common/timings.h" +#include "timings.h" struct Params { diff --git a/src/common/timings.cc b/tests/performance_tests/timings.cc similarity index 99% rename from src/common/timings.cc rename to tests/performance_tests/timings.cc index a78b96bb7..6c0c16e5e 100644 --- a/src/common/timings.cc +++ b/tests/performance_tests/timings.cc @@ -3,7 +3,7 @@ #include #include #include "common/string_util.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "timings.h" #define N_EXPECTED_FIELDS (8+11) diff --git a/src/common/timings.h b/tests/performance_tests/timings.h similarity index 100% rename from src/common/timings.h rename to tests/performance_tests/timings.h diff --git a/tests/trezor/CMakeLists.txt b/tests/trezor/CMakeLists.txt index 2ffb05cbf..3d97d066d 100644 --- a/tests/trezor/CMakeLists.txt +++ b/tests/trezor/CMakeLists.txt @@ -47,7 +47,7 @@ target_link_libraries(trezor_tests rpc cryptonote_protocol daemon_rpc_server - Boost::filesystem + filesystem Boost::program_options ${ZMQ_LIB} extra) diff --git a/tests/trezor/daemon.h b/tests/trezor/daemon.h index 91b86d210..adada129c 100644 --- a/tests/trezor/daemon.h +++ b/tests/trezor/daemon.h @@ -28,7 +28,7 @@ #pragma once -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "daemon/daemon.h" #include "rpc/daemon_handler.h" #include "rpc/zmq_server.h" diff --git a/tests/trezor/tools.h b/tests/trezor/tools.h index d348a5137..b4d7ce6ce 100644 --- a/tests/trezor/tools.h +++ b/tests/trezor/tools.h @@ -28,7 +28,7 @@ #pragma once -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "daemon/daemon.h" #include "rpc/daemon_handler.h" #include "rpc/zmq_server.h" diff --git a/tests/trezor/trezor_tests.cpp b/tests/trezor/trezor_tests.cpp index a5fe0f235..5b9213bca 100644 --- a/tests/trezor/trezor_tests.cpp +++ b/tests/trezor/trezor_tests.cpp @@ -28,12 +28,11 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include "include_base_utils.h" #include "cryptonote_basic/cryptonote_basic_impl.h" #include "cryptonote_basic/account.h" #include "cryptonote_core/cryptonote_tx_utils.h" -#include "misc_language.h" -#include "string_tools.h" +#include "epee/misc_language.h" +#include "epee/string_tools.h" using namespace cryptonote; @@ -329,7 +328,7 @@ static void setup_chain(cryptonote::core * core, gen_trezor_base & trezor_base, { std::vector events; const bool do_serialize = !chain_path.empty(); - const bool chain_file_exists = do_serialize && boost::filesystem::exists(chain_path); + const bool chain_file_exists = do_serialize && fs::exists(chain_path); bool loaded = false; bool generated = false; @@ -687,7 +686,7 @@ void gen_trezor_base::init_fields() DEFAULT_HARDFORKS(m_hard_forks); crypto::secret_key master_seed{}; - CHECK_AND_ASSERT_THROW_MES(epee::string_tools::hex_to_pod(m_master_seed_str, master_seed), "Hexdecode fails"); + CHECK_AND_ASSERT_THROW_MES(tools::hex_to_type(m_master_seed_str, master_seed), "Hexdecode fails"); m_alice_account.generate(master_seed, true); m_alice_account.set_createtime(m_wallet_ts); @@ -1832,17 +1831,17 @@ bool gen_trezor_many_utxo::generate(std::vector& events) void wallet_api_tests::init() { - m_wallet_dir = boost::filesystem::unique_path(); - boost::filesystem::create_directories(m_wallet_dir); + m_wallet_dir = fs::unique_path(); + fs::create_directories(m_wallet_dir); } wallet_api_tests::~wallet_api_tests() { try { - if (!m_wallet_dir.empty() && boost::filesystem::exists(m_wallet_dir)) + if (!m_wallet_dir.empty() && fs::exists(m_wallet_dir)) { - boost::filesystem::remove_all(m_wallet_dir); + fs::remove_all(m_wallet_dir); } } catch(...) diff --git a/tests/trezor/trezor_tests.h b/tests/trezor/trezor_tests.h index bc05ed041..35da9fc81 100644 --- a/tests/trezor/trezor_tests.h +++ b/tests/trezor/trezor_tests.h @@ -33,6 +33,7 @@ #include #include #include "daemon.h" +#include "common/fs.h" #include "../core_tests/chaingen.h" #include "../core_tests/wallet_tools.h" @@ -321,5 +322,5 @@ public: bool generate(std::vector& events) override; protected: - boost::filesystem::path m_wallet_dir; + fs::path m_wallet_dir; }; diff --git a/tests/unit_tests/blockchain_db.cpp b/tests/unit_tests/blockchain_db.cpp index b61652b91..d3ee04164 100644 --- a/tests/unit_tests/blockchain_db.cpp +++ b/tests/unit_tests/blockchain_db.cpp @@ -26,24 +26,27 @@ // 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 #include #include #include #include +#include #include #include "gtest/gtest.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "blockchain_db/blockchain_db.h" #include "blockchain_db/lmdb/db_lmdb.h" #include "cryptonote_basic/cryptonote_format_utils.h" +#include "common/fs.h" +#include "common/hex.h" + +#include "random_path.h" using namespace cryptonote; -using epee::string_tools::pod_to_hex; -#define ASSERT_HASH_EQ(a,b) ASSERT_EQ(pod_to_hex(a), pod_to_hex(b)) +#define ASSERT_HASH_EQ(a,b) ASSERT_EQ(tools::type_to_hex(a), tools::type_to_hex(b)) namespace { // anonymous namespace @@ -84,8 +87,8 @@ const std::vector> t_transactions = // from std::string, this might break. bool compare_blocks(const block& a, const block& b) { - auto hash_a = pod_to_hex(get_block_hash(a)); - auto hash_b = pod_to_hex(get_block_hash(b)); + auto hash_a = tools::type_to_hex(get_block_hash(a)); + auto hash_b = tools::type_to_hex(get_block_hash(b)); return hash_a == hash_b; } @@ -94,8 +97,8 @@ bool compare_blocks(const block& a, const block& b) void print_block(const block& blk, const std::string& prefix = "") { std::cerr << prefix << ": " << std::endl - << "\thash - " << pod_to_hex(get_block_hash(blk)) << std::endl - << "\tparent - " << pod_to_hex(blk.prev_id) << std::endl + << "\thash - " << tools::type_to_hex(get_block_hash(blk)) << std::endl + << "\tparent - " << tools::type_to_hex(blk.prev_id) << std::endl << "\ttimestamp - " << blk.timestamp << std::endl ; } @@ -183,10 +186,10 @@ protected: BlockchainDB* m_db; HardFork m_hardfork; - std::string m_prefix; + fs::path m_prefix; std::vector> m_blocks; std::vector>> m_txs; - std::vector m_filenames; + std::vector m_filenames; void init_hard_fork() { @@ -208,9 +211,9 @@ protected: // remove each file the db created, making sure it starts with fname. for (auto& f : m_filenames) { - if (boost::starts_with(f, m_prefix)) + if (tools::starts_with(f.u8string(), m_prefix.u8string())) { - boost::filesystem::remove(f); + fs::remove(f); } else { @@ -219,12 +222,12 @@ protected: } // remove directory if it still exists - boost::filesystem::remove_all(m_prefix); + fs::remove_all(m_prefix); } void set_prefix(const std::string& prefix) { - m_prefix = prefix; + m_prefix = fs::u8path(prefix); } }; @@ -236,7 +239,7 @@ TYPED_TEST_CASE(BlockchainDBTest, implementations); TYPED_TEST(BlockchainDBTest, OpenAndClose) { - boost::filesystem::path tempPath = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); + fs::path tempPath = random_tmp_file(); std::string dirPath = tempPath.string(); this->set_prefix(dirPath); @@ -254,7 +257,7 @@ TYPED_TEST(BlockchainDBTest, OpenAndClose) TYPED_TEST(BlockchainDBTest, AddBlock) { - boost::filesystem::path tempPath = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); + fs::path tempPath = random_tmp_file(); std::string dirPath = tempPath.string(); this->set_prefix(dirPath); @@ -302,7 +305,7 @@ TYPED_TEST(BlockchainDBTest, AddBlock) TYPED_TEST(BlockchainDBTest, RetrieveBlockData) { - boost::filesystem::path tempPath = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); + fs::path tempPath = random_tmp_file(); std::string dirPath = tempPath.string(); this->set_prefix(dirPath); diff --git a/tests/unit_tests/bulletproofs.cpp b/tests/unit_tests/bulletproofs.cpp index 55deaff1f..285030b8f 100644 --- a/tests/unit_tests/bulletproofs.cpp +++ b/tests/unit_tests/bulletproofs.cpp @@ -30,14 +30,15 @@ #include "gtest/gtest.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "ringct/rctOps.h" #include "ringct/rctSigs.h" #include "ringct/bulletproofs.h" #include "cryptonote_basic/blobdatatype.h" #include "cryptonote_basic/cryptonote_format_utils.h" #include "device/device.hpp" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" +#include "common/hex.h" TEST(bulletproofs, valid_zero) { @@ -197,7 +198,7 @@ TEST(bulletproofs, invalid_torsion) for (const auto &xs: torsion_elements) { rct::key x; - ASSERT_TRUE(epee::string_tools::hex_to_pod(xs, x)); + ASSERT_TRUE(tools::hex_to_type(xs, x)); ASSERT_FALSE(rct::isInMainSubgroup(x)); for (auto &k: proof.V) { diff --git a/tests/unit_tests/difficulty.cpp b/tests/unit_tests/difficulty.cpp index e9e3272f0..b520690a4 100644 --- a/tests/unit_tests/difficulty.cpp +++ b/tests/unit_tests/difficulty.cpp @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "gtest/gtest.h" -#include "int-util.h" +#include "epee/int-util.h" #include "cryptonote_basic/difficulty.h" static cryptonote::difficulty_type MKDIFF(uint64_t high, uint64_t low) diff --git a/tests/unit_tests/epee_boosted_tcp_server.cpp b/tests/unit_tests/epee_boosted_tcp_server.cpp index a07f87b70..dd1667525 100644 --- a/tests/unit_tests/epee_boosted_tcp_server.cpp +++ b/tests/unit_tests/epee_boosted_tcp_server.cpp @@ -34,9 +34,8 @@ #include "gtest/gtest.h" -#include "include_base_utils.h" -#include "string_tools.h" -#include "net/abstract_tcp_server2.h" +#include "epee/string_tools.h" +#include "epee/net/abstract_tcp_server2.h" using namespace std::literals; diff --git a/tests/unit_tests/epee_levin_protocol_handler_async.cpp b/tests/unit_tests/epee_levin_protocol_handler_async.cpp index 0bd1a1a8d..afdf255af 100644 --- a/tests/unit_tests/epee_levin_protocol_handler_async.cpp +++ b/tests/unit_tests/epee_levin_protocol_handler_async.cpp @@ -32,10 +32,9 @@ #include "gtest/gtest.h" -#include "include_base_utils.h" -#include "string_tools.h" -#include "net/levin_protocol_handler_async.h" -#include "net/net_utils_base.h" +#include "epee/string_tools.h" +#include "epee/net/levin_protocol_handler_async.h" +#include "epee/net/net_utils_base.h" #include "unit_tests_utils.h" namespace diff --git a/tests/unit_tests/epee_utils.cpp b/tests/unit_tests/epee_utils.cpp index c5e09746f..e4e34b1ac 100644 --- a/tests/unit_tests/epee_utils.cpp +++ b/tests/unit_tests/epee_utils.cpp @@ -45,16 +45,16 @@ #include "boost/archive/portable_binary_iarchive.hpp" #include "boost/archive/portable_binary_oarchive.hpp" -#include "shared_sv.h" +#include "epee/shared_sv.h" #include "crypto/crypto.h" -#include "hex.h" -#include "net/net_utils_base.h" -#include "net/local_ip.h" -#include "net/buffer.h" +#include "epee/hex.h" +#include "epee/net/net_utils_base.h" +#include "epee/net/local_ip.h" +#include "epee/net/buffer.h" #include "p2p/net_peerlist_boost_serialization.h" -#include "span.h" -#include "string_tools.h" -#include "storages/parserse_base_utils.h" +#include "epee/span.h" +#include "epee/string_tools.h" +#include "epee/storages/parserse_base_utils.h" namespace { @@ -502,40 +502,6 @@ TEST(ToHex, Formatted) EXPECT_EQ(expected, out.str()); } -TEST(StringTools, BuffToHex) -{ - const std::vector all_bytes = get_all_bytes(); - - EXPECT_EQ( - std_to_hex(all_bytes), - (epee::string_tools::buff_to_hex_nodelimer( - std::string{reinterpret_cast(all_bytes.data()), all_bytes.size()} - )) - ); -} - -TEST(StringTools, PodToHex) -{ - struct some_pod { unsigned char data[4]; }; - EXPECT_EQ( - std::string{"ffab0100"}, - (epee::string_tools::pod_to_hex(some_pod{{0xFF, 0xAB, 0x01, 0x00}})) - ); -} - -TEST(StringTools, ParseHex) -{ - static const char data[] = "a10b68c2"; - for (size_t i = 0; i < sizeof(data); i += 2) - { - std::string res; - ASSERT_TRUE(epee::string_tools::parse_hexstr_to_binbuff(std::string(data, i), res)); - std::string hex = epee::string_tools::buff_to_hex_nodelimer(res); - ASSERT_EQ(hex.size(), i); - ASSERT_EQ(memcmp(data, hex.data(), i), 0); - } -} - TEST(StringTools, ParseNotHex) { std::string res; diff --git a/tests/unit_tests/get_xtype_from_string.cpp b/tests/unit_tests/get_xtype_from_string.cpp index 44b1883ed..21197329f 100644 --- a/tests/unit_tests/get_xtype_from_string.cpp +++ b/tests/unit_tests/get_xtype_from_string.cpp @@ -30,7 +30,7 @@ #include "gtest/gtest.h" -#include "string_tools.h" +#include "epee/string_tools.h" namespace { diff --git a/tests/unit_tests/levin.cpp b/tests/unit_tests/levin.cpp index 12668642b..8b149324b 100644 --- a/tests/unit_tests/levin.cpp +++ b/tests/unit_tests/levin.cpp @@ -35,17 +35,17 @@ #include #include -#include "shared_sv.h" +#include "epee/shared_sv.h" #include "crypto/crypto.h" #include "cryptonote_basic/connection_context.h" #include "cryptonote_core/cryptonote_core.h" #include "cryptonote_protocol/cryptonote_protocol_defs.h" #include "cryptonote_protocol/levin_notify.h" -#include "int-util.h" +#include "epee/int-util.h" #include "p2p/net_node.h" #include "net/dandelionpp.h" -#include "net/levin_base.h" -#include "span.h" +#include "epee/net/levin_base.h" +#include "epee/span.h" namespace { diff --git a/tests/unit_tests/logging.cpp b/tests/unit_tests/logging.cpp index 859e6a802..bee0b36a9 100644 --- a/tests/unit_tests/logging.cpp +++ b/tests/unit_tests/logging.cpp @@ -28,16 +28,17 @@ // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include #include "gtest/gtest.h" -#include "file_io_utils.h" -#include "misc_log_ex.h" +#include "common/file.h" +#include "epee/misc_log_ex.h" + +#include "random_path.h" static std::string log_filename; static void init() { - boost::filesystem::path p = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path(); + fs::path p = random_tmp_file(); log_filename = p.string(); mlog_configure(log_filename, false, 0); } @@ -46,7 +47,7 @@ static void cleanup() { // windows does not let files be deleted if still in use, so leave droppings there #ifndef _WIN32 - boost::filesystem::remove(log_filename); + fs::remove(log_filename); #endif } @@ -61,7 +62,7 @@ static size_t nlines(const std::string &str) static bool load_log_to_string(const std::string &filename, std::string &str) { - if (!epee::file_io_utils::load_file_to_string(filename, str)) + if (!tools::slurp_file(filename, str)) return false; for (const char *ptr = str.c_str(); *ptr; ++ptr) { diff --git a/tests/unit_tests/main.cpp b/tests/unit_tests/main.cpp index a647ccf7e..179cddb49 100644 --- a/tests/unit_tests/main.cpp +++ b/tests/unit_tests/main.cpp @@ -30,23 +30,21 @@ #include "gtest/gtest.h" -#include -#include +#include "common/fs.h" #include #include "p2p/net_node.h" #include "p2p/net_node.inl" #include "cryptonote_protocol/cryptonote_protocol_handler.h" #include "cryptonote_protocol/cryptonote_protocol_handler.inl" -#include "include_base_utils.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "common/command_line.h" #include "common/util.h" #include "unit_tests_utils.h" namespace po = boost::program_options; -boost::filesystem::path unit_test::data_dir; +fs::path unit_test::data_dir; namespace nodetool { template class node_server>; } namespace cryptonote { template class t_cryptonote_protocol_handler; } diff --git a/tests/unit_tests/memwipe.cpp b/tests/unit_tests/memwipe.cpp index dd98b8142..99d792f22 100644 --- a/tests/unit_tests/memwipe.cpp +++ b/tests/unit_tests/memwipe.cpp @@ -29,8 +29,8 @@ #include "gtest/gtest.h" #include -#include "misc_log_ex.h" -#include "memwipe.h" +#include "epee/misc_log_ex.h" +#include "epee/memwipe.h" // Probably won't catch the optimized out case, but at least we test // it works in the normal case diff --git a/tests/unit_tests/mlocker.cpp b/tests/unit_tests/mlocker.cpp index c97dc2c1d..0b0b9eb69 100644 --- a/tests/unit_tests/mlocker.cpp +++ b/tests/unit_tests/mlocker.cpp @@ -28,8 +28,8 @@ #include "gtest/gtest.h" -#include "misc_log_ex.h" -#include "mlocker.h" +#include "epee/misc_log_ex.h" +#include "epee/mlocker.h" #if defined __GNUC__ && !defined _WIN32 #define HAVE_MLOCK 1 diff --git a/tests/unit_tests/mnemonics.cpp b/tests/unit_tests/mnemonics.cpp index 4b0737ffd..45433a741 100644 --- a/tests/unit_tests/mnemonics.cpp +++ b/tests/unit_tests/mnemonics.cpp @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "gtest/gtest.h" -#include "wipeable_string.h" +#include "epee/wipeable_string.h" #include "mnemonics/language_base.h" #include "mnemonics/electrum-words.h" #include "crypto/crypto.h" diff --git a/tests/unit_tests/mul_div.cpp b/tests/unit_tests/mul_div.cpp index 39f00131a..9a5cdfc71 100644 --- a/tests/unit_tests/mul_div.cpp +++ b/tests/unit_tests/mul_div.cpp @@ -30,7 +30,7 @@ #include "gtest/gtest.h" -#include "int-util.h" +#include "epee/int-util.h" namespace { diff --git a/tests/unit_tests/multisig.cpp b/tests/unit_tests/multisig.cpp index 9fe936608..d32df6a8a 100644 --- a/tests/unit_tests/multisig.cpp +++ b/tests/unit_tests/multisig.cpp @@ -67,7 +67,7 @@ static void make_wallet(unsigned int idx, tools::wallet2 &wallet) ASSERT_TRUE(idx < sizeof(test_addresses) / sizeof(test_addresses[0])); crypto::secret_key spendkey; - epee::string_tools::hex_to_pod(test_addresses[idx].spendkey, spendkey); + tools::hex_to_type(test_addresses[idx].spendkey, spendkey); try { @@ -76,7 +76,7 @@ static void make_wallet(unsigned int idx, tools::wallet2 &wallet) wallet.generate("", "", spendkey, true, false); ASSERT_TRUE(test_addresses[idx].address == wallet.get_account().get_public_address_str(cryptonote::TESTNET)); wallet.decrypt_keys(""); - ASSERT_TRUE(test_addresses[idx].spendkey == epee::string_tools::pod_to_hex(wallet.get_account().get_keys().m_spend_secret_key)); + ASSERT_TRUE(test_addresses[idx].spendkey == tools::type_to_hex(wallet.get_account().get_keys().m_spend_secret_key)); wallet.encrypt_keys(""); } catch (const std::exception &e) diff --git a/tests/unit_tests/net.cpp b/tests/unit_tests/net.cpp index 568039f12..c7aba2aa5 100644 --- a/tests/unit_tests/net.cpp +++ b/tests/unit_tests/net.cpp @@ -55,12 +55,12 @@ #include "net/dandelionpp.h" #include "net/error.h" #include "net/i2p_address.h" -#include "net/net_utils_base.h" +#include "epee/net/net_utils_base.h" #include "net/parse.h" #include "net/tor_address.h" #include "p2p/net_peerlist_boost_serialization.h" -#include "serialization/keyvalue_serialization.h" -#include "storages/portable_storage.h" +#include "epee/serialization/keyvalue_serialization.h" +#include "epee/storages/portable_storage.h" namespace { diff --git a/tests/unit_tests/notify.cpp b/tests/unit_tests/notify.cpp index 4de4a8d0a..16234b3ec 100644 --- a/tests/unit_tests/notify.cpp +++ b/tests/unit_tests/notify.cpp @@ -32,11 +32,9 @@ #include "gtest/gtest.h" -#include - -#include "misc_language.h" -#include "string_tools.h" -#include "file_io_utils.h" +#include "epee/misc_language.h" +#include "epee/string_tools.h" +#include "common/file.h" #include "common/notify.h" TEST(notify, works) @@ -75,7 +73,7 @@ TEST(notify, works) epee::misc_utils::sleep_no_w(100); std::string s; - if (epee::file_io_utils::load_file_to_string(name_template, s)) + if (tools::slurp_file(name_template, s)) { if (s == "1111111111111111111111111111111111111111111111111111111111111111") { @@ -84,6 +82,6 @@ TEST(notify, works) } } } - boost::filesystem::remove(name_template); + fs::remove(name_template); ASSERT_TRUE(ok); } diff --git a/tests/unit_tests/output_distribution.cpp b/tests/unit_tests/output_distribution.cpp index 4b53dd4b3..15bcac17f 100644 --- a/tests/unit_tests/output_distribution.cpp +++ b/tests/unit_tests/output_distribution.cpp @@ -27,7 +27,7 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "gtest/gtest.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "rpc/rpc_handler.h" #include "blockchain_db/blockchain_db.h" #include "cryptonote_core/cryptonote_core.h" diff --git a/tests/unit_tests/pruning.cpp b/tests/unit_tests/pruning.cpp index 83c35df68..0a007cb8e 100644 --- a/tests/unit_tests/pruning.cpp +++ b/tests/unit_tests/pruning.cpp @@ -28,7 +28,7 @@ #include "gtest/gtest.h" -#include "misc_log_ex.h" +#include "epee/misc_log_ex.h" #include "cryptonote_config.h" #include "common/pruning.h" diff --git a/tests/unit_tests/random_path.h b/tests/unit_tests/random_path.h new file mode 100644 index 000000000..8c896f7d3 --- /dev/null +++ b/tests/unit_tests/random_path.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include +#include +#include "common/fs.h" + +inline fs::path random_tmp_file() { + // Not the more secure, but fine for test suite code: + static std::mt19937_64 rng{std::random_device{}()}; + using namespace std::literals; + constexpr auto chars = "abcdefghijklmnopqrstuvwxyz0123456789"sv; + std::uniform_int_distribution r_idx(0, chars.size() - 1); + std::string result; + for (int i = 0; i < 12; i++) + result += chars[r_idx(rng)]; + return fs::temp_directory_path() / result; +} diff --git a/tests/unit_tests/ringct.cpp b/tests/unit_tests/ringct.cpp index c85e5e743..ac1c9b78d 100644 --- a/tests/unit_tests/ringct.cpp +++ b/tests/unit_tests/ringct.cpp @@ -38,7 +38,7 @@ #include "ringct/rctSigs.h" #include "ringct/rctOps.h" #include "device/device.hpp" -#include "string_tools.h" +#include "common/hex.h" using namespace crypto; using namespace rct; @@ -284,7 +284,7 @@ TEST(ringct, CLSAG) // D not in main subgroup in clsag at verification backup_key = clsag.D; rct::key x; - ASSERT_TRUE(epee::string_tools::hex_to_pod("c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa", x)); + ASSERT_TRUE(tools::hex_to_type("c7176a703d4dd84fba3c0b760d10670f2a2053fa2c39ccc64ec7fd7792ac03fa", x)); clsag.D = rct::addKeys(clsag.D, x); ASSERT_FALSE(rct::verRctCLSAGSimple(message,clsag,pubs,Cout)); clsag.D = backup_key; diff --git a/tests/unit_tests/ringdb.cpp b/tests/unit_tests/ringdb.cpp index 99669b550..971b9a2ee 100644 --- a/tests/unit_tests/ringdb.cpp +++ b/tests/unit_tests/ringdb.cpp @@ -31,11 +31,11 @@ #include #include #include -#include +#include "common/fs.h" #include "gtest/gtest.h" -#include "string_tools.h" +#include "epee/string_tools.h" #include "crypto/crypto.h" #include "crypto/random.h" #include "crypto/chacha.h" @@ -43,6 +43,8 @@ #include "cryptonote_basic/cryptonote_basic.h" #include "wallet/ringdb.h" +#include "random_path.h" + namespace { crypto::chacha_key generate_chacha_key() @@ -86,27 +88,8 @@ lazy_init &get_context() class RingDB: public tools::ringdb { public: - RingDB(const char *genesis = ""): tools::ringdb(make_filename(), genesis) { } - ~RingDB() { close(); boost::filesystem::remove_all(filename); free(filename); } - -private: - std::string make_filename() - { - boost::filesystem::path path = - boost::filesystem::temp_directory_path(); -#if defined(__MINGW32__) || defined(__MINGW__) - filename = tempnam(path.string().c_str(), "monero-ringdb-test-"); - EXPECT_TRUE(filename != NULL); -#else - path /= "monero-ringdb-test-XXXXXX"; - filename = strdup(path.string().c_str()); - EXPECT_TRUE(mkdtemp(filename) != NULL); -#endif - return filename; - } - -private: - char *filename; + RingDB(const char *genesis = ""): tools::ringdb(random_tmp_file(), genesis) { } + ~RingDB() { close(); fs::remove_all(filename()); } }; TEST(ringdb, not_found) diff --git a/tests/unit_tests/rolling_median.cpp b/tests/unit_tests/rolling_median.cpp index 9e4cf87b8..839b1c741 100644 --- a/tests/unit_tests/rolling_median.cpp +++ b/tests/unit_tests/rolling_median.cpp @@ -28,8 +28,8 @@ #include #include "gtest/gtest.h" -#include "misc_language.h" -#include "rolling_median.h" +#include "epee/misc_language.h" +#include "epee/rolling_median.h" #include "crypto/crypto.h" TEST(rolling_median, one) diff --git a/tests/unit_tests/serialization.cpp b/tests/unit_tests/serialization.cpp index 548e3d44b..7a17dcdb0 100644 --- a/tests/unit_tests/serialization.cpp +++ b/tests/unit_tests/serialization.cpp @@ -650,7 +650,7 @@ TEST(Serialization, portability_wallet) { const cryptonote::network_type nettype = cryptonote::TESTNET; tools::wallet2 w(nettype); - const boost::filesystem::path wallet_file = unit_test::data_dir / "wallet_testnet"; + const fs::path wallet_file = unit_test::data_dir / "wallet_testnet"; std::string password = "test"; bool r = false; try @@ -680,25 +680,25 @@ TEST(Serialization, portability_wallet) ASSERT_TRUE(w.m_blockchain.size() == 11652); - ASSERT_TRUE(epee::string_tools::pod_to_hex(w.m_blockchain[0]) == "da0d7c7824d82c15fc1e046259ce16a7d216e0c0f4406122e207127cf9a77bec"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(w.m_blockchain[1]) == "ca9fcde568ad56e01342fa951db7cd0b8f8bdb8a7bf64eb3aa16af79fd44cfab"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(w.m_blockchain[11635]) == "84adf6f5a518fcebfea31c304334f7f9358fed610b40034576c46a8c4870b310"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(w.m_blockchain[11636]) == "e991be0387c636496ebd224fa9d135dfa917c4b6129bfcfed1458b77666d8b5c"); + ASSERT_TRUE(tools::type_to_hex(w.m_blockchain[0]) == "da0d7c7824d82c15fc1e046259ce16a7d216e0c0f4406122e207127cf9a77bec"); + ASSERT_TRUE(tools::type_to_hex(w.m_blockchain[1]) == "ca9fcde568ad56e01342fa951db7cd0b8f8bdb8a7bf64eb3aa16af79fd44cfab"); + ASSERT_TRUE(tools::type_to_hex(w.m_blockchain[11635]) == "84adf6f5a518fcebfea31c304334f7f9358fed610b40034576c46a8c4870b310"); + ASSERT_TRUE(tools::type_to_hex(w.m_blockchain[11636]) == "e991be0387c636496ebd224fa9d135dfa917c4b6129bfcfed1458b77666d8b5c"); // transfers (TODO) ASSERT_TRUE(w.m_transfers.size() == 3); // account public address - ASSERT_TRUE(epee::string_tools::pod_to_hex(w.m_account_public_address.m_view_public_key) == "fa871f6af764d2b3fc43eddb9f311b73b387652809992afa5ca3acacc6ff44b0"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(w.m_account_public_address.m_spend_public_key) == "efb5d51e3ab4a7c09c207f85650c970eeb671f03d98defcb70265930c0d86240"); + ASSERT_TRUE(tools::type_to_hex(w.m_account_public_address.m_view_public_key) == "fa871f6af764d2b3fc43eddb9f311b73b387652809992afa5ca3acacc6ff44b0"); + ASSERT_TRUE(tools::type_to_hex(w.m_account_public_address.m_spend_public_key) == "efb5d51e3ab4a7c09c207f85650c970eeb671f03d98defcb70265930c0d86240"); // key images ASSERT_TRUE(w.m_key_images.size() == 3); { crypto::key_image ki[3]; - epee::string_tools::hex_to_pod("05e1050df8262068682951b459a722495bfd5d070300e96a8d52c6255e300f11", ki[0]); - epee::string_tools::hex_to_pod("21dfe89b3dbde221eccd9b71e7f6383c81f9ada224a670956c895b230749a8d8", ki[1]); - epee::string_tools::hex_to_pod("92194cadfbb4f1317d25d39d6216cbf1030a2170a3edb47b5f008345a879150d", ki[2]); + tools::hex_to_type("05e1050df8262068682951b459a722495bfd5d070300e96a8d52c6255e300f11", ki[0]); + tools::hex_to_type("21dfe89b3dbde221eccd9b71e7f6383c81f9ada224a670956c895b230749a8d8", ki[1]); + tools::hex_to_type("92194cadfbb4f1317d25d39d6216cbf1030a2170a3edb47b5f008345a879150d", ki[2]); ASSERT_EQ_MAP(0, w.m_key_images, ki[0]); ASSERT_EQ_MAP(1, w.m_key_images, ki[1]); ASSERT_EQ_MAP(2, w.m_key_images, ki[2]); @@ -712,8 +712,8 @@ TEST(Serialization, portability_wallet) { auto pd0 = w.m_payments.begin(); - ASSERT_TRUE(epee::string_tools::pod_to_hex(pd0->first) == "0000000000000000000000000000000000000000000000000000000000000000"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(pd0->second.m_tx_hash) == "b77633fe663a07283b071d16c3b783fe838389273fde373a569ad08cb214ab1b"); + ASSERT_TRUE(tools::type_to_hex(pd0->first) == "0000000000000000000000000000000000000000000000000000000000000000"); + ASSERT_TRUE(tools::type_to_hex(pd0->second.m_tx_hash) == "b77633fe663a07283b071d16c3b783fe838389273fde373a569ad08cb214ab1b"); ASSERT_TRUE(pd0->second.m_amount == 100000000000); ASSERT_TRUE(pd0->second.m_block_height == 8478); ASSERT_TRUE(pd0->second.m_unlock_time == 0); @@ -732,8 +732,8 @@ TEST(Serialization, portability_wallet) { crypto::hash txid; crypto::secret_key txkey; - epee::string_tools::hex_to_pod(txid_txkey[i].first, txid); - epee::string_tools::hex_to_pod(txid_txkey[i].second, txkey); + tools::hex_to_type(txid_txkey[i].first, txid); + tools::hex_to_type(txid_txkey[i].second, txkey); ASSERT_EQ_MAP(txkey, w.m_tx_keys, txid); } } @@ -745,7 +745,7 @@ TEST(Serialization, portability_wallet) ASSERT_TRUE(w.m_tx_notes.size() == 1); { crypto::hash h[1]; - epee::string_tools::hex_to_pod("d986bc2e49ed83a990424ac42b2db9be0264be54c7ce13f7a8dca5177aa4781c", h[0]); + tools::hex_to_type("d986bc2e49ed83a990424ac42b2db9be0264be54c7ce13f7a8dca5177aa4781c", h[0]); ASSERT_EQ_MAP("Unconfirmed transaction test", w.m_tx_notes, h[0]); } @@ -756,9 +756,9 @@ TEST(Serialization, portability_wallet) ASSERT_TRUE(w.m_pub_keys.size() == 3); { crypto::public_key pubkey[3]; - epee::string_tools::hex_to_pod("cc6ac78ac21c034210dcce72a96909b8ba7abd1b3d3917b5ee0c5bc0fe1f6a55", pubkey[0]); - epee::string_tools::hex_to_pod("4cea6373d27bdde002a745ef025375e36ca4b1042c4defdaf2fc56a48ef67230", pubkey[1]); - epee::string_tools::hex_to_pod("b143a6f53cf20f986cbfe87ace7d33143275457dfaa5ea6f14cb78861302dbff", pubkey[2]); + tools::hex_to_type("cc6ac78ac21c034210dcce72a96909b8ba7abd1b3d3917b5ee0c5bc0fe1f6a55", pubkey[0]); + tools::hex_to_type("4cea6373d27bdde002a745ef025375e36ca4b1042c4defdaf2fc56a48ef67230", pubkey[1]); + tools::hex_to_type("b143a6f53cf20f986cbfe87ace7d33143275457dfaa5ea6f14cb78861302dbff", pubkey[2]); ASSERT_EQ_MAP(0, w.m_pub_keys, pubkey[0]); ASSERT_EQ_MAP(1, w.m_pub_keys, pubkey[1]); ASSERT_EQ_MAP(2, w.m_pub_keys, pubkey[2]); @@ -769,13 +769,13 @@ TEST(Serialization, portability_wallet) { auto address_book_row = w.m_address_book.begin(); <<<<<<< HEAD - ASSERT_TRUE(epee::string_tools::pod_to_hex(address_book_row->m_address.m_spend_public_key) == "938fc84cbacb271fdbc9bfc34e9d887f4bdb89f20a9d4e2c05916d6b9f6a7cb8"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(address_book_row->m_address.m_view_public_key) == "9eec0bbb1728bce79209e1ae995cbae8e3f6cf78f7262b5db049594e4907bb33"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(address_book_row->m_payment_id) == "e0470453783dd65dc16bb740f82902b9a26a48216e4c89278586637011c858a3"); + ASSERT_TRUE(tools::type_to_hex(address_book_row->m_address.m_spend_public_key) == "938fc84cbacb271fdbc9bfc34e9d887f4bdb89f20a9d4e2c05916d6b9f6a7cb8"); + ASSERT_TRUE(tools::type_to_hex(address_book_row->m_address.m_view_public_key) == "9eec0bbb1728bce79209e1ae995cbae8e3f6cf78f7262b5db049594e4907bb33"); + ASSERT_TRUE(tools::type_to_hex(address_book_row->m_payment_id) == "e0470453783dd65dc16bb740f82902b9a26a48216e4c89278586637011c858a3"); ASSERT_TRUE(address_book_row->m_description == "A test address"); ======= - ASSERT_TRUE(epee::string_tools::pod_to_hex(address_book_row->m_address.m_spend_public_key) == "9bc53a6ff7b0831c9470f71b6b972dbe5ad1e8606f72682868b1dda64e119fb3"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(address_book_row->m_address.m_view_public_key) == "49fece1ef97dc0c0f7a5e2106e75e96edd910f7e86b56e1e308cd0cf734df191"); + ASSERT_TRUE(tools::type_to_hex(address_book_row->m_address.m_spend_public_key) == "9bc53a6ff7b0831c9470f71b6b972dbe5ad1e8606f72682868b1dda64e119fb3"); + ASSERT_TRUE(tools::type_to_hex(address_book_row->m_address.m_view_public_key) == "49fece1ef97dc0c0f7a5e2106e75e96edd910f7e86b56e1e308cd0cf734df191"); ASSERT_TRUE(address_book_row->m_description == "testnet wallet 9y52S6"); >>>>>>> a26e5b3 } @@ -787,14 +787,14 @@ TEST(Serialization, portability_outputs) const bool restricted = false; tools::wallet2 w(cryptonote::TESTNET, restricted); - const boost::filesystem::path wallet_file = unit_test::data_dir / "wallet_testnet"; + const fs::path wallet_file = unit_test::data_dir / "wallet_testnet"; const std::string password = "test"; w.load(wallet_file.string(), password); // read file - const boost::filesystem::path filename = unit_test::data_dir / "outputs"; + const fs::path filename = unit_test::data_dir / "outputs"; std::string data; - bool r = epee::file_io_utils::load_file_to_string(filename.string(), data); + bool r = tools::slurp_file(filename.string(), data); ASSERT_TRUE(r); const size_t magiclen = strlen(OUTPUT_EXPORT_FILE_MAGIC); @@ -824,7 +824,7 @@ TEST(Serialization, portability_outputs) return plaintext; }; crypto::secret_key view_secret_key; - epee::string_tools::hex_to_pod("cb979d21cde0fbcafb9ff083791a6771b750534948ede6d66058609884b27604", view_secret_key); + tools::hex_to_type("cb979d21cde0fbcafb9ff083791a6771b750534948ede6d66058609884b27604", view_secret_key); bool authenticated = true; data = decrypt(std::string(data, magiclen), view_secret_key, authenticated); ASSERT_FALSE(data.empty()); @@ -834,8 +834,8 @@ TEST(Serialization, portability_outputs) const crypto::public_key &public_spend_key = *(const crypto::public_key*)&data[0]; const crypto::public_key &public_view_key = *(const crypto::public_key*)&data[sizeof(crypto::public_key)]; - ASSERT_TRUE(epee::string_tools::pod_to_hex(public_spend_key) == "efb5d51e3ab4a7c09c207f85650c970eeb671f03d98defcb70265930c0d86240"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(public_view_key) == "fa871f6af764d2b3fc43eddb9f311b73b387652809992afa5ca3acacc6ff44b0"); + ASSERT_TRUE(tools::type_to_hex(public_spend_key) == "efb5d51e3ab4a7c09c207f85650c970eeb671f03d98defcb70265930c0d86240"); + ASSERT_TRUE(tools::type_to_hex(public_view_key) == "fa871f6af764d2b3fc43eddb9f311b73b387652809992afa5ca3acacc6ff44b0"); r = false; std::vector outputs; @@ -881,9 +881,9 @@ TEST(Serialization, portability_outputs) ASSERT_TRUE(td0.m_block_height == 8478); ASSERT_TRUE(td1.m_block_height == 11034); ASSERT_TRUE(td2.m_block_height == 11651); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_txid) == "b77633fe663a07283b071d16c3b783fe838389273fde373a569ad08cb214ab1b"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_txid) == "4baf027b724623c524c539c5aec441a41c5c76730e4074280189005797a7329d"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_txid) == "d986bc2e49ed83a990424ac42b2db9be0264be54c7ce13f7a8dca5177aa4781c"); + ASSERT_TRUE(tools::type_to_hex(td0.m_txid) == "b77633fe663a07283b071d16c3b783fe838389273fde373a569ad08cb214ab1b"); + ASSERT_TRUE(tools::type_to_hex(td1.m_txid) == "4baf027b724623c524c539c5aec441a41c5c76730e4074280189005797a7329d"); + ASSERT_TRUE(tools::type_to_hex(td2.m_txid) == "d986bc2e49ed83a990424ac42b2db9be0264be54c7ce13f7a8dca5177aa4781c"); ASSERT_TRUE(td0.m_internal_output_index == 1); ASSERT_TRUE(td1.m_internal_output_index == 1); ASSERT_TRUE(td2.m_internal_output_index == 1); @@ -896,12 +896,12 @@ TEST(Serialization, portability_outputs) ASSERT_TRUE(td0.m_spent_height == 11034); ASSERT_TRUE(td1.m_spent_height == 11651); ASSERT_TRUE(td2.m_spent_height == 0); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_key_image) == "05e1050df8262068682951b459a722495bfd5d070300e96a8d52c6255e300f11"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_key_image) == "21dfe89b3dbde221eccd9b71e7f6383c81f9ada224a670956c895b230749a8d8"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_key_image) == "92194cadfbb4f1317d25d39d6216cbf1030a2170a3edb47b5f008345a879150d"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_mask) == "e87548646fdca2caf508c7036e975593063beb38ce6345dcebf6a4f78ac6690a"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_mask) == "270fbc097ac0ce6d46f7d731ef8f6c28e7d29091106d50d8db5a96c2b43b0009"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_mask) == "fedf66717b339fdcdd70809a20af7b4314645c859f3c71738567c0c0372f3509"); + ASSERT_TRUE(tools::type_to_hex(td0.m_key_image) == "05e1050df8262068682951b459a722495bfd5d070300e96a8d52c6255e300f11"); + ASSERT_TRUE(tools::type_to_hex(td1.m_key_image) == "21dfe89b3dbde221eccd9b71e7f6383c81f9ada224a670956c895b230749a8d8"); + ASSERT_TRUE(tools::type_to_hex(td2.m_key_image) == "92194cadfbb4f1317d25d39d6216cbf1030a2170a3edb47b5f008345a879150d"); + ASSERT_TRUE(tools::type_to_hex(td0.m_mask) == "e87548646fdca2caf508c7036e975593063beb38ce6345dcebf6a4f78ac6690a"); + ASSERT_TRUE(tools::type_to_hex(td1.m_mask) == "270fbc097ac0ce6d46f7d731ef8f6c28e7d29091106d50d8db5a96c2b43b0009"); + ASSERT_TRUE(tools::type_to_hex(td2.m_mask) == "fedf66717b339fdcdd70809a20af7b4314645c859f3c71738567c0c0372f3509"); ASSERT_TRUE(td0.m_amount == 100000000000); ASSERT_TRUE(td1.m_amount == 47531982120); ASSERT_TRUE(td2.m_amount == 35464004140); @@ -934,14 +934,14 @@ TEST(Serialization, portability_unsigned_tx) const bool restricted = false; tools::wallet2 w(cryptonote::TESTNET, restricted); - const boost::filesystem::path filename = unit_test::data_dir / "unsigned_loki_tx"; - const boost::filesystem::path wallet_file = unit_test::data_dir / "wallet_testnet"; + const fs::path filename = unit_test::data_dir / "unsigned_loki_tx"; + const fs::path wallet_file = unit_test::data_dir / "wallet_testnet"; const std::string password = "test"; w.load(wallet_file.string(), password); std::string s; const cryptonote::network_type nettype = cryptonote::TESTNET; - bool r = epee::file_io_utils::load_file_to_string(filename.string(), s); + bool r = tools::slurp_file(filename.string(), s); ASSERT_TRUE(r); size_t const magiclen = strlen(UNSIGNED_TX_PREFIX); ASSERT_FALSE(strncmp(s.c_str(), UNSIGNED_TX_PREFIX, magiclen)); @@ -1029,27 +1029,27 @@ TEST(Serialization, portability_unsigned_tx) ASSERT_TRUE(out8.first == 23236); ASSERT_TRUE(out9.first == 23560); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out0.second) == "b92dd8689d86f3ddf4a21998f9f206dfa478b2944a5a272be6ac0896a406b0186b94ba5f17c6aa64a4cc1332825e1176952417f671ea04342fe6f156c951417d"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out1.second) == "50cb891b4cda04360647b4e0c764de48c7ec82807f844f2fe5446d2684b8df403cba128103c46f40f1564e78b640d8fa11bb2a9d40579e792de30f4febae5ac0"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out2.second) == "fb046f73105eca35aac2ea9befb1be75649456e8e69b78a7104c925f0546e890ea03efb93dddd97a9527248f423d3c1a7afffdf0efff8c844feecf0fe72449fe"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out3.second) == "49c0d412f994b69d09458a8af7602f2ed2fd41d8e430a694d6c0fa5e17bc507ab096d83facce8e3f6381244fe97070e344d71a9d7380f74b9bef209c20308549"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out4.second) == "f4c96b02d97e480fd20d9ad063f10787114ddda3d7a200b532283c4f25707d7ae49bc555dbd83d17a089c1c3acde66dce6a163f75e19835d58f15c2d2cb90c42"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out5.second) == "0e7ca50fec28b7a6f47ee293b7ef9c9522f85fd5bb60ac3105edb9ef8d1e3c079ded4d5d3a45cf6a67200b0e434e7b057230274fed40305e96cab710319bf5cc"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out6.second) == "806d57c9a2ab3402c171332c3fad13838dd125df846f076ca4545e0304b121525525ce94d662ab1eff88cbce06d1bcec37bf1042c3d9b20d04f743bd7392c05e"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out7.second) == "92306e8714fb9c958e3e1df44e798b8c64bb09264d2c97e994b18af4c2fc89e4eab67da527dd194e087a811ae419e5012e32eea80d0c54ef6e39e389bad14edb"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out8.second) == "e29aeceb86042442cbaf15e3907e8bcd254a8740810a75b5583f853a9fdc2228bc74f6a7198c89f7cf770f6c76755f7285fdb13761abaa72d5c79be33d0bd199"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out9.second) == "b143a6f53cf20f986cbfe87ace7d33143275457dfaa5ea6f14cb78861302dbffd013ecf4ffecb0bc694eb4e12cf36b55c80b150acae7a3da42a99b9932dcdd22"); + ASSERT_TRUE(tools::type_to_hex(out0.second) == "b92dd8689d86f3ddf4a21998f9f206dfa478b2944a5a272be6ac0896a406b0186b94ba5f17c6aa64a4cc1332825e1176952417f671ea04342fe6f156c951417d"); + ASSERT_TRUE(tools::type_to_hex(out1.second) == "50cb891b4cda04360647b4e0c764de48c7ec82807f844f2fe5446d2684b8df403cba128103c46f40f1564e78b640d8fa11bb2a9d40579e792de30f4febae5ac0"); + ASSERT_TRUE(tools::type_to_hex(out2.second) == "fb046f73105eca35aac2ea9befb1be75649456e8e69b78a7104c925f0546e890ea03efb93dddd97a9527248f423d3c1a7afffdf0efff8c844feecf0fe72449fe"); + ASSERT_TRUE(tools::type_to_hex(out3.second) == "49c0d412f994b69d09458a8af7602f2ed2fd41d8e430a694d6c0fa5e17bc507ab096d83facce8e3f6381244fe97070e344d71a9d7380f74b9bef209c20308549"); + ASSERT_TRUE(tools::type_to_hex(out4.second) == "f4c96b02d97e480fd20d9ad063f10787114ddda3d7a200b532283c4f25707d7ae49bc555dbd83d17a089c1c3acde66dce6a163f75e19835d58f15c2d2cb90c42"); + ASSERT_TRUE(tools::type_to_hex(out5.second) == "0e7ca50fec28b7a6f47ee293b7ef9c9522f85fd5bb60ac3105edb9ef8d1e3c079ded4d5d3a45cf6a67200b0e434e7b057230274fed40305e96cab710319bf5cc"); + ASSERT_TRUE(tools::type_to_hex(out6.second) == "806d57c9a2ab3402c171332c3fad13838dd125df846f076ca4545e0304b121525525ce94d662ab1eff88cbce06d1bcec37bf1042c3d9b20d04f743bd7392c05e"); + ASSERT_TRUE(tools::type_to_hex(out7.second) == "92306e8714fb9c958e3e1df44e798b8c64bb09264d2c97e994b18af4c2fc89e4eab67da527dd194e087a811ae419e5012e32eea80d0c54ef6e39e389bad14edb"); + ASSERT_TRUE(tools::type_to_hex(out8.second) == "e29aeceb86042442cbaf15e3907e8bcd254a8740810a75b5583f853a9fdc2228bc74f6a7198c89f7cf770f6c76755f7285fdb13761abaa72d5c79be33d0bd199"); + ASSERT_TRUE(tools::type_to_hex(out9.second) == "b143a6f53cf20f986cbfe87ace7d33143275457dfaa5ea6f14cb78861302dbffd013ecf4ffecb0bc694eb4e12cf36b55c80b150acae7a3da42a99b9932dcdd22"); // tcd.sources[0].{real_output, real_out_tx_key, real_output_in_tx_index, amount, rct, mask} ASSERT_TRUE(tse.real_output == 9); - ASSERT_TRUE(epee::string_tools::pod_to_hex(tse.real_out_tx_key) == "1e2092d2e8a72eaec814d8e7ecab9276f2779a5c58324a0fb057e24ffa11a14e"); + ASSERT_TRUE(tools::type_to_hex(tse.real_out_tx_key) == "1e2092d2e8a72eaec814d8e7ecab9276f2779a5c58324a0fb057e24ffa11a14e"); ASSERT_TRUE(tse.real_output_in_tx_index == 1); ASSERT_TRUE(tse.amount == 35464004140); ASSERT_TRUE(tse.rct); - ASSERT_TRUE(epee::string_tools::pod_to_hex(tse.mask) == "fedf66717b339fdcdd70809a20af7b4314645c859f3c71738567c0c0372f3509"); + ASSERT_TRUE(tools::type_to_hex(tse.mask) == "fedf66717b339fdcdd70809a20af7b4314645c859f3c71738567c0c0372f3509"); // tcd.change_dts ASSERT_TRUE(tcd.change_dts.amount == 25396028820); @@ -1092,9 +1092,9 @@ TEST(Serialization, portability_unsigned_tx) ASSERT_TRUE(td0.m_block_height == 8478); ASSERT_TRUE(td1.m_block_height == 11034); ASSERT_TRUE(td2.m_block_height == 11651); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_txid) == "b77633fe663a07283b071d16c3b783fe838389273fde373a569ad08cb214ab1b"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_txid) == "4baf027b724623c524c539c5aec441a41c5c76730e4074280189005797a7329d"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_txid) == "d986bc2e49ed83a990424ac42b2db9be0264be54c7ce13f7a8dca5177aa4781c"); + ASSERT_TRUE(tools::type_to_hex(td0.m_txid) == "b77633fe663a07283b071d16c3b783fe838389273fde373a569ad08cb214ab1b"); + ASSERT_TRUE(tools::type_to_hex(td1.m_txid) == "4baf027b724623c524c539c5aec441a41c5c76730e4074280189005797a7329d"); + ASSERT_TRUE(tools::type_to_hex(td2.m_txid) == "d986bc2e49ed83a990424ac42b2db9be0264be54c7ce13f7a8dca5177aa4781c"); ASSERT_TRUE(td0.m_internal_output_index == 1); ASSERT_TRUE(td1.m_internal_output_index == 1); ASSERT_TRUE(td2.m_internal_output_index == 1); @@ -1107,12 +1107,12 @@ TEST(Serialization, portability_unsigned_tx) ASSERT_TRUE(td0.m_spent_height == 11034); ASSERT_TRUE(td1.m_spent_height == 11651); ASSERT_TRUE(td2.m_spent_height == 0); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_key_image) == "05e1050df8262068682951b459a722495bfd5d070300e96a8d52c6255e300f11"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_key_image) == "21dfe89b3dbde221eccd9b71e7f6383c81f9ada224a670956c895b230749a8d8"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_key_image) == "92194cadfbb4f1317d25d39d6216cbf1030a2170a3edb47b5f008345a879150d"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td0.m_mask) == "e87548646fdca2caf508c7036e975593063beb38ce6345dcebf6a4f78ac6690a"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td1.m_mask) == "270fbc097ac0ce6d46f7d731ef8f6c28e7d29091106d50d8db5a96c2b43b0009"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(td2.m_mask) == "fedf66717b339fdcdd70809a20af7b4314645c859f3c71738567c0c0372f3509"); + ASSERT_TRUE(tools::type_to_hex(td0.m_key_image) == "05e1050df8262068682951b459a722495bfd5d070300e96a8d52c6255e300f11"); + ASSERT_TRUE(tools::type_to_hex(td1.m_key_image) == "21dfe89b3dbde221eccd9b71e7f6383c81f9ada224a670956c895b230749a8d8"); + ASSERT_TRUE(tools::type_to_hex(td2.m_key_image) == "92194cadfbb4f1317d25d39d6216cbf1030a2170a3edb47b5f008345a879150d"); + ASSERT_TRUE(tools::type_to_hex(td0.m_mask) == "e87548646fdca2caf508c7036e975593063beb38ce6345dcebf6a4f78ac6690a"); + ASSERT_TRUE(tools::type_to_hex(td1.m_mask) == "270fbc097ac0ce6d46f7d731ef8f6c28e7d29091106d50d8db5a96c2b43b0009"); + ASSERT_TRUE(tools::type_to_hex(td2.m_mask) == "fedf66717b339fdcdd70809a20af7b4314645c859f3c71738567c0c0372f3509"); ASSERT_TRUE(td0.m_amount == 100000000000); ASSERT_TRUE(td1.m_amount == 47531982120); ASSERT_TRUE(td2.m_amount == 35464004140); @@ -1133,14 +1133,14 @@ TEST(Serialization, portability_signed_tx) const bool restricted = false; tools::wallet2 w(cryptonote::TESTNET, restricted); - const boost::filesystem::path filename = unit_test::data_dir / "signed_loki_tx"; - const boost::filesystem::path wallet_file = unit_test::data_dir / "wallet_testnet"; + const fs::path filename = unit_test::data_dir / "signed_loki_tx"; + const fs::path wallet_file = unit_test::data_dir / "wallet_testnet"; const std::string password = "test"; w.load(wallet_file.string(), password); const cryptonote::network_type nettype = cryptonote::TESTNET; std::string s; - bool r = epee::file_io_utils::load_file_to_string(filename.string(), s); + bool r = tools::slurp_file(filename.string(), s); ASSERT_TRUE(r); size_t const magiclen = strlen(SIGNED_TX_PREFIX); ASSERT_FALSE(strncmp(s.c_str(), SIGNED_TX_PREFIX, magiclen)); @@ -1203,7 +1203,7 @@ TEST(Serialization, portability_signed_tx) // ptx.{key_images, tx_key} ASSERT_TRUE(ptx.key_images == "<92194cadfbb4f1317d25d39d6216cbf1030a2170a3edb47b5f008345a879150d> "); - ASSERT_TRUE(epee::string_tools::pod_to_hex(ptx.tx_key) == "0100000000000000000000000000000000000000000000000000000000000000"); + ASSERT_TRUE(tools::type_to_hex(ptx.tx_key) == "0100000000000000000000000000000000000000000000000000000000000000"); // ptx.dests ASSERT_TRUE(ptx.dests.size() == 1); @@ -1239,24 +1239,24 @@ TEST(Serialization, portability_signed_tx) ASSERT_TRUE(out8.first == 23236); ASSERT_TRUE(out9.first == 23560); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out0.second) == "b92dd8689d86f3ddf4a21998f9f206dfa478b2944a5a272be6ac0896a406b0186b94ba5f17c6aa64a4cc1332825e1176952417f671ea04342fe6f156c951417d"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out1.second) == "50cb891b4cda04360647b4e0c764de48c7ec82807f844f2fe5446d2684b8df403cba128103c46f40f1564e78b640d8fa11bb2a9d40579e792de30f4febae5ac0"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out2.second) == "fb046f73105eca35aac2ea9befb1be75649456e8e69b78a7104c925f0546e890ea03efb93dddd97a9527248f423d3c1a7afffdf0efff8c844feecf0fe72449fe"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out3.second) == "49c0d412f994b69d09458a8af7602f2ed2fd41d8e430a694d6c0fa5e17bc507ab096d83facce8e3f6381244fe97070e344d71a9d7380f74b9bef209c20308549"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out4.second) == "f4c96b02d97e480fd20d9ad063f10787114ddda3d7a200b532283c4f25707d7ae49bc555dbd83d17a089c1c3acde66dce6a163f75e19835d58f15c2d2cb90c42"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out5.second) == "0e7ca50fec28b7a6f47ee293b7ef9c9522f85fd5bb60ac3105edb9ef8d1e3c079ded4d5d3a45cf6a67200b0e434e7b057230274fed40305e96cab710319bf5cc"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out6.second) == "806d57c9a2ab3402c171332c3fad13838dd125df846f076ca4545e0304b121525525ce94d662ab1eff88cbce06d1bcec37bf1042c3d9b20d04f743bd7392c05e"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out7.second) == "92306e8714fb9c958e3e1df44e798b8c64bb09264d2c97e994b18af4c2fc89e4eab67da527dd194e087a811ae419e5012e32eea80d0c54ef6e39e389bad14edb"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out8.second) == "e29aeceb86042442cbaf15e3907e8bcd254a8740810a75b5583f853a9fdc2228bc74f6a7198c89f7cf770f6c76755f7285fdb13761abaa72d5c79be33d0bd199"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(out9.second) == "b143a6f53cf20f986cbfe87ace7d33143275457dfaa5ea6f14cb78861302dbffd013ecf4ffecb0bc694eb4e12cf36b55c80b150acae7a3da42a99b9932dcdd22"); + ASSERT_TRUE(tools::type_to_hex(out0.second) == "b92dd8689d86f3ddf4a21998f9f206dfa478b2944a5a272be6ac0896a406b0186b94ba5f17c6aa64a4cc1332825e1176952417f671ea04342fe6f156c951417d"); + ASSERT_TRUE(tools::type_to_hex(out1.second) == "50cb891b4cda04360647b4e0c764de48c7ec82807f844f2fe5446d2684b8df403cba128103c46f40f1564e78b640d8fa11bb2a9d40579e792de30f4febae5ac0"); + ASSERT_TRUE(tools::type_to_hex(out2.second) == "fb046f73105eca35aac2ea9befb1be75649456e8e69b78a7104c925f0546e890ea03efb93dddd97a9527248f423d3c1a7afffdf0efff8c844feecf0fe72449fe"); + ASSERT_TRUE(tools::type_to_hex(out3.second) == "49c0d412f994b69d09458a8af7602f2ed2fd41d8e430a694d6c0fa5e17bc507ab096d83facce8e3f6381244fe97070e344d71a9d7380f74b9bef209c20308549"); + ASSERT_TRUE(tools::type_to_hex(out4.second) == "f4c96b02d97e480fd20d9ad063f10787114ddda3d7a200b532283c4f25707d7ae49bc555dbd83d17a089c1c3acde66dce6a163f75e19835d58f15c2d2cb90c42"); + ASSERT_TRUE(tools::type_to_hex(out5.second) == "0e7ca50fec28b7a6f47ee293b7ef9c9522f85fd5bb60ac3105edb9ef8d1e3c079ded4d5d3a45cf6a67200b0e434e7b057230274fed40305e96cab710319bf5cc"); + ASSERT_TRUE(tools::type_to_hex(out6.second) == "806d57c9a2ab3402c171332c3fad13838dd125df846f076ca4545e0304b121525525ce94d662ab1eff88cbce06d1bcec37bf1042c3d9b20d04f743bd7392c05e"); + ASSERT_TRUE(tools::type_to_hex(out7.second) == "92306e8714fb9c958e3e1df44e798b8c64bb09264d2c97e994b18af4c2fc89e4eab67da527dd194e087a811ae419e5012e32eea80d0c54ef6e39e389bad14edb"); + ASSERT_TRUE(tools::type_to_hex(out8.second) == "e29aeceb86042442cbaf15e3907e8bcd254a8740810a75b5583f853a9fdc2228bc74f6a7198c89f7cf770f6c76755f7285fdb13761abaa72d5c79be33d0bd199"); + ASSERT_TRUE(tools::type_to_hex(out9.second) == "b143a6f53cf20f986cbfe87ace7d33143275457dfaa5ea6f14cb78861302dbffd013ecf4ffecb0bc694eb4e12cf36b55c80b150acae7a3da42a99b9932dcdd22"); // ptx.construction_data.sources[0].{real_output, real_out_tx_key, real_output_in_tx_index, amount, rct, mask} ASSERT_TRUE(tse.real_output == 9); - ASSERT_TRUE(epee::string_tools::pod_to_hex(tse.real_out_tx_key) == "1e2092d2e8a72eaec814d8e7ecab9276f2779a5c58324a0fb057e24ffa11a14e"); + ASSERT_TRUE(tools::type_to_hex(tse.real_out_tx_key) == "1e2092d2e8a72eaec814d8e7ecab9276f2779a5c58324a0fb057e24ffa11a14e"); ASSERT_TRUE(tse.real_output_in_tx_index == 1); ASSERT_TRUE(tse.amount == 35464004140); ASSERT_TRUE(tse.rct); - ASSERT_TRUE(epee::string_tools::pod_to_hex(tse.mask) == "fedf66717b339fdcdd70809a20af7b4314645c859f3c71738567c0c0372f3509"); + ASSERT_TRUE(tools::type_to_hex(tse.mask) == "fedf66717b339fdcdd70809a20af7b4314645c859f3c71738567c0c0372f3509"); // ptx.construction_data.change_dts ASSERT_TRUE(tcd.change_dts.amount == 25396028820); @@ -1294,8 +1294,8 @@ TEST(Serialization, portability_signed_tx) auto& ki1 = exported_txs.key_images[1]; auto& ki2 = exported_txs.key_images[2]; - ASSERT_TRUE(epee::string_tools::pod_to_hex(ki0) == "05e1050df8262068682951b459a722495bfd5d070300e96a8d52c6255e300f11"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(ki1) == "21dfe89b3dbde221eccd9b71e7f6383c81f9ada224a670956c895b230749a8d8"); - ASSERT_TRUE(epee::string_tools::pod_to_hex(ki2) == "92194cadfbb4f1317d25d39d6216cbf1030a2170a3edb47b5f008345a879150d"); + ASSERT_TRUE(tools::type_to_hex(ki0) == "05e1050df8262068682951b459a722495bfd5d070300e96a8d52c6255e300f11"); + ASSERT_TRUE(tools::type_to_hex(ki1) == "21dfe89b3dbde221eccd9b71e7f6383c81f9ada224a670956c895b230749a8d8"); + ASSERT_TRUE(tools::type_to_hex(ki2) == "92194cadfbb4f1317d25d39d6216cbf1030a2170a3edb47b5f008345a879150d"); } #endif diff --git a/tests/unit_tests/sha256.cpp b/tests/unit_tests/sha256.cpp index 58d71d46c..48353114a 100644 --- a/tests/unit_tests/sha256.cpp +++ b/tests/unit_tests/sha256.cpp @@ -30,12 +30,12 @@ #include "common/sha256sum.h" #include "crypto/hash.h" -#include "string_tools.h" +#include "common/hex.h" static bool check(const std::string &data, const char *expected_hash_hex) { crypto::hash hash, expected_hash; - if (!epee::string_tools::hex_to_pod(expected_hash_hex, expected_hash)) + if (!tools::hex_to_type(expected_hash_hex, expected_hash)) return false; return tools::sha256sum_str(data, hash) && hash == expected_hash; } diff --git a/tests/unit_tests/subaddress.cpp b/tests/unit_tests/subaddress.cpp index 67802d736..433653b49 100644 --- a/tests/unit_tests/subaddress.cpp +++ b/tests/unit_tests/subaddress.cpp @@ -27,10 +27,8 @@ // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // // Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers -#include #include "gtest/gtest.h" -#include "include_base_utils.h" #include "wallet/wallet2.h" #include "crypto/crypto.h" #include "cryptonote_basic/account.h" diff --git a/tests/unit_tests/test_peerlist.cpp b/tests/unit_tests/test_peerlist.cpp index 462944b97..5e69a5a17 100644 --- a/tests/unit_tests/test_peerlist.cpp +++ b/tests/unit_tests/test_peerlist.cpp @@ -32,7 +32,7 @@ #include "common/util.h" #include "p2p/net_peerlist.h" -#include "net/net_utils_base.h" +#include "epee/net/net_utils_base.h" TEST(peer_list, peer_list_general) { diff --git a/tests/unit_tests/test_protocol_pack.cpp b/tests/unit_tests/test_protocol_pack.cpp index 78d7f3a7a..06721586f 100644 --- a/tests/unit_tests/test_protocol_pack.cpp +++ b/tests/unit_tests/test_protocol_pack.cpp @@ -30,9 +30,8 @@ #include "gtest/gtest.h" -#include "include_base_utils.h" #include "cryptonote_protocol/cryptonote_protocol_defs.h" -#include "storages/portable_storage_template_helper.h" +#include "epee/storages/portable_storage_template_helper.h" TEST(protocol_pack, protocol_pack_command) { diff --git a/tests/unit_tests/threadpool.cpp b/tests/unit_tests/threadpool.cpp index 1307cd738..3eb7abf8c 100644 --- a/tests/unit_tests/threadpool.cpp +++ b/tests/unit_tests/threadpool.cpp @@ -28,7 +28,7 @@ #include #include "gtest/gtest.h" -#include "misc_language.h" +#include "epee/misc_language.h" #include "common/threadpool.h" TEST(threadpool, wait_nothing) diff --git a/tests/unit_tests/unit_tests_utils.h b/tests/unit_tests/unit_tests_utils.h index ecd97e3d5..a076c998d 100644 --- a/tests/unit_tests/unit_tests_utils.h +++ b/tests/unit_tests/unit_tests_utils.h @@ -31,11 +31,11 @@ #pragma once #include -#include +#include "common/fs.h" namespace unit_test { - extern boost::filesystem::path data_dir; + extern fs::path data_dir; class call_counter { diff --git a/tests/unit_tests/wipeable_string.cpp b/tests/unit_tests/wipeable_string.cpp index 2e1824052..4b65e327d 100644 --- a/tests/unit_tests/wipeable_string.cpp +++ b/tests/unit_tests/wipeable_string.cpp @@ -30,9 +30,9 @@ #include #include "gtest/gtest.h" -#include "misc_log_ex.h" -#include "wipeable_string.h" -#include "hex.h" +#include "epee/misc_log_ex.h" +#include "epee/wipeable_string.h" +#include "epee/hex.h" TEST(wipeable_string, ctor) { diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt index ff31ed91c..b43391622 100644 --- a/translations/CMakeLists.txt +++ b/translations/CMakeLists.txt @@ -26,6 +26,19 @@ # 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. +if (ANDROID) + # Override the stuff (locally, inside this subdir) because we want to find the host system Qt5 to + # build the translation files. + set(CMAKE_FIND_ROOT_PATH "") + # This might be wrong, but cmake gives us no easy way to find this, so for now we only support + # doing the android builds with translations on amd64 linux + set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu") + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(ANDROID_PLATFORM FALSE) +endif() find_package(Qt5 QUIET COMPONENTS Core LinguistTools) if(NOT Qt5_FOUND OR NOT Qt5LinguistTools_FOUND) set(qm_files "") diff --git a/utils/build_scripts/boost-darwin-libtool-path.patch b/utils/build_scripts/boost-darwin-libtool-path.patch new file mode 100644 index 000000000..727b5e735 --- /dev/null +++ b/utils/build_scripts/boost-darwin-libtool-path.patch @@ -0,0 +1,11 @@ +--- a/tools/build/src/tools/darwin.jam 2020-10-29 23:37:52.000000000 -0300 ++++ b/tools/build/src/tools/darwin.jam 2020-10-29 23:37:43.000000000 -0300 +@@ -192,7 +192,7 @@ + # archives in darwin is complicated. + local archiver = + [ common.get-invocation-command darwin +- : libtool : [ feature.get-values : $(options) ] : $(bin) : search-path ] ; ++ : /usr/bin/libtool : [ feature.get-values : $(options) ] : $(bin) : search-path ] ; + flags darwin.archive .LIBTOOL $(condition) : $(archiver[1]) ; + if $(.debug-configuration) + { diff --git a/utils/build_scripts/drone-android-static-upload.sh b/utils/build_scripts/drone-android-static-upload.sh new file mode 100755 index 000000000..9bfadbfb9 --- /dev/null +++ b/utils/build_scripts/drone-android-static-upload.sh @@ -0,0 +1,58 @@ +#!/usr/bin/env bash + +# Script used with Drone CI to upload build artifacts (because specifying all this in +# .drone.jsonnet is too painful). + + + +set -o errexit + +if [ -z "$SSH_KEY" ]; then + echo -e "\n\n\n\e[31;1mUnable to upload artifact: SSH_KEY not set\e[0m" + # Just warn but don't fail, so that this doesn't trigger a build failure for untrusted builds + exit 0 +fi + +echo "$SSH_KEY" >ssh_key + +set -o xtrace # Don't start tracing until *after* we write the ssh key + +chmod 600 ssh_key + +branch_or_tag=${DRONE_BRANCH:-${DRONE_TAG:-unknown}} + +upload_to="builds.lokinet.dev/${DRONE_REPO// /_}/${branch_or_tag// /_}" + +tmpdir=android-deps-${DRONE_COMMIT} +mkdir -p $tmpdir +cp src/wallet/api/wallet2_api.h $tmpdir + +for android_abi in "$@"; do + mkdir -p $tmpdir/${android_abi} + ln -s ../../build-${android_abi}/src/wallet/api/libwallet_merged.a $tmpdir/${android_abi}/libwallet_api.a +done + +filename=android-deps-${DRONE_COMMIT}.tar.xz +XZ_OPT="--threads=6" tar --dereference -cJvf $filename $tmpdir + +# sftp doesn't have any equivalent to mkdir -p, so we have to split the above up into a chain of +# -mkdir a/, -mkdir a/b/, -mkdir a/b/c/, ... commands. The leading `-` allows the command to fail +# without error. +upload_dirs=(${upload_to//\// }) +mkdirs= +dir_tmp="" +for p in "${upload_dirs[@]}"; do + dir_tmp="$dir_tmp$p/" + mkdirs="$mkdirs +-mkdir $dir_tmp" +done + +sftp -i ssh_key -b - -o StrictHostKeyChecking=off drone@builds.lokinet.dev <ssh_key + +set -o xtrace # Don't start tracing until *after* we write the ssh key + +chmod 600 ssh_key + +branch_or_tag=${DRONE_BRANCH:-${DRONE_TAG:-unknown}} + +upload_to="builds.lokinet.dev/${DRONE_REPO// /_}/${branch_or_tag// /_}" + +tmpdir=ios-deps-${DRONE_COMMIT} +mkdir -p $tmpdir/lib +mkdir -p $tmpdir/include + +# Merge the arm64 and simulator libs into a single multi-arch merged lib: +lipo -create build/{arm64,sim64}/src/wallet/api/libwallet_merged.a -o $tmpdir/lib/libwallet_merged.a + +# Collect all the headers +# Loki core: +cd src +find . \( -name '*.h' -or -name '*.hpp' \) -exec cp -v --parents {} ../$tmpdir/include \; +cp -v daemonizer/posix_daemonizer.inl ../$tmpdir/include/daemonizer +cd .. +# epee: +cp -rv contrib/epee/include/epee $tmpdir/include +# external libs: +mkdir $tmpdir/include/lokimq +cp -v external/{easylogging++/*.h,db_drivers/liblmdb/lmdb.h,randomx/src/randomx.h} $tmpdir/include +cp -v external/loki-mq/lokimq/*.h $tmpdir/include/lokimq +cp -rv external/{boost,cpr/include/cpr,ghc-filesystem/include/ghc,libuv/include/*,rapidjson/include/rapidjson} $tmpdir/include +cp -rv build/arm64/external/uWebSockets/* $tmpdir/include +# static libs: +cp -rv build/arm64/static-deps/include/* $tmpdir/include + + +filename=ios-deps-${DRONE_COMMIT}.tar.xz +XZ_OPTS="--threads=6" tar --dereference -cJvf $filename $tmpdir + +# sftp doesn't have any equivalent to mkdir -p, so we have to split the above up into a chain of +# -mkdir a/, -mkdir a/b/, -mkdir a/b/c/, ... commands. The leading `-` allows the command to fail +# without error. +upload_dirs=(${upload_to//\// }) +mkdirs= +dir_tmp="" +for p in "${upload_dirs[@]}"; do + dir_tmp="$dir_tmp$p/" + mkdirs="$mkdirs +-mkdir $dir_tmp" +done + +sftp -i ssh_key -b - -o StrictHostKeyChecking=off drone@builds.lokinet.dev <