Compare commits
87 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2222bea92f | |||
| f12e75b5e4 | |||
| 0ae1cd2413 | |||
| 317eceb725 | |||
| d98787eb1b | |||
| ca1b1b7332 | |||
| 27c5013acd | |||
| c0ce4d5089 | |||
| 3c15eb8e81 | |||
| c61c09a567 | |||
| b864817629 | |||
| a520234c51 | |||
| 715ebcb744 | |||
| 4073599aaf | |||
| 2285c66ef1 | |||
| 99bee1ccf0 | |||
| e48fae3177 | |||
| be6c61e2ee | |||
| 1e037d372a | |||
| 6ec9fd6c08 | |||
| ccfed6008a | |||
| f0fa959383 | |||
| 8dbe2e57ac | |||
| 64c320130f | |||
| 8f95eaa0b0 | |||
| 9f93fe1539 | |||
| db6688f584 | |||
| f00db20a5f | |||
| adcf440dcd | |||
| 925c6b60e3 | |||
| 94bad34c26 | |||
| 3c23aca26b | |||
| 49beb8da17 | |||
| d188b5f51f | |||
| 8eb2b79bad | |||
| 3eb8f1458b | |||
| a395f363e7 | |||
| 0fecd7eb86 | |||
| 76824bf827 | |||
| 67ba733de1 | |||
| 402ba046e0 | |||
| 1565bcb1fb | |||
| 2e9af2a1c8 | |||
| db564efe0b | |||
| 85079173db | |||
| 8716d2ad9d | |||
| 5a34eae063 | |||
| 1510b1e550 | |||
| 7128f73ec2 | |||
| 8b63bb3c75 | |||
| 56ce7fca6f | |||
| bc252794f0 | |||
| 07d82af979 | |||
| 9b840439b9 | |||
| 7e3f211791 | |||
| 2161bd0f3a | |||
| ec6ff0d002 | |||
| ceb8e7c508 | |||
| 72af8a5fce | |||
| 4f7c38a444 | |||
| 7d2e717ee8 | |||
| 83e378740a | |||
| c28d2f7c11 | |||
| a2d8f876ca | |||
| 3701257d61 | |||
| 90703ba8bd | |||
| a080c0be9c | |||
| de7565069e | |||
| 1d6f2114b8 | |||
| cb9a2e4471 | |||
| 70c5c81670 | |||
| d59cd3d222 | |||
| dedcd6304c | |||
| 6e22710f0e | |||
| 02e9a41cbe | |||
| def58196da | |||
| 73959c623c | |||
| 712f362150 | |||
| 153d08d026 | |||
| 2abd7b174b | |||
| 9a50bef3cd | |||
| 22bb6a654d | |||
| 38958f722b | |||
| 36a68b0cba | |||
| 6305b90596 | |||
| 9fc9c7d695 | |||
| df032882a8 |
@@ -23,7 +23,7 @@ jobs:
|
||||
- uses: actions/checkout@v1
|
||||
with:
|
||||
submodules: recursive
|
||||
- uses: eine/setup-msys2@v1
|
||||
- uses: msys2/setup-msys2@v2
|
||||
with:
|
||||
update: true
|
||||
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-boost mingw-w64-x86_64-openssl mingw-w64-x86_64-zeromq mingw-w64-x86_64-libsodium mingw-w64-x86_64-hidapi mingw-w64-x86_64-protobuf-c mingw-w64-x86_64-libusb git
|
||||
|
||||
+73
-5
@@ -71,16 +71,18 @@ function (die msg)
|
||||
endfunction ()
|
||||
|
||||
function (add_c_flag_if_supported flag var)
|
||||
string(REPLACE "-" "_" supported ${flag}_c)
|
||||
check_c_compiler_flag(${flag} ${supported})
|
||||
set(TMP "-Werror ${flag}")
|
||||
string(REGEX REPLACE "[- ]" "_" supported ${TMP}_c)
|
||||
check_c_compiler_flag(${TMP} ${supported})
|
||||
if(${${supported}})
|
||||
set(${var} "${${var}} ${flag}" PARENT_SCOPE)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
function (add_cxx_flag_if_supported flag var)
|
||||
string(REPLACE "-" "_" supported ${flag}_cxx)
|
||||
check_cxx_compiler_flag(${flag} ${supported})
|
||||
set(TMP "-Werror ${flag}")
|
||||
string(REGEX REPLACE "[- ]" "_" supported ${TMP}_cxx)
|
||||
check_cxx_compiler_flag(${TMP} ${supported})
|
||||
if(${${supported}})
|
||||
set(${var} "${${var}} ${flag}" PARENT_SCOPE)
|
||||
endif()
|
||||
@@ -111,6 +113,66 @@ function (add_definition_if_library_exists library function header var)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
# Function to forbid undefined symbols and also verify
|
||||
# 1) Test project with all types of libraries and without undefined symbols can compile successfully
|
||||
# 2) Test project with all types of libraries and undefined symbols can not compile successfully
|
||||
function(forbid_undefined_symbols)
|
||||
unset(TMP)
|
||||
# https://www.unix.com/man-page/linux/1/ld, --no-undefined, Report unresolved symbol references from regular object files.
|
||||
add_linker_flag_if_supported(-Wl,--no-undefined TMP)
|
||||
# https://www.unix.com/man-page/osx/1/ld/, -undefined, Specifies how undefined symbols are to be treated.
|
||||
add_linker_flag_if_supported(-Wl,-undefined,error TMP)
|
||||
string(APPEND CMAKE_SHARED_LINKER_FLAGS ${TMP})
|
||||
string(APPEND CMAKE_MODULE_LINKER_FLAGS ${TMP})
|
||||
set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} PARENT_SCOPE)
|
||||
set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} PARENT_SCOPE)
|
||||
set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/test_project")
|
||||
foreach(EXPECT IN ITEMS TRUE FALSE)
|
||||
file(REMOVE_RECURSE "${TEST_PROJECT}")
|
||||
file(MAKE_DIRECTORY "${TEST_PROJECT}")
|
||||
file(WRITE "${TEST_PROJECT}/CMakeLists.txt"
|
||||
[=[
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(test)
|
||||
option(EXPECT_SUCCESS "" ON)
|
||||
file(WRITE "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }")
|
||||
if (EXPECT_SUCCESS)
|
||||
file(APPEND "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" " void undefined_symbol() {}; ")
|
||||
endif()
|
||||
add_library(l0 SHARED incorrect_source.cpp)
|
||||
add_library(l1 MODULE incorrect_source.cpp)
|
||||
add_library(l2 STATIC incorrect_source.cpp)
|
||||
add_library(l3 OBJECT incorrect_source.cpp)
|
||||
]=]
|
||||
)
|
||||
try_compile(SUCCESS "${TEST_PROJECT}/build" "${TEST_PROJECT}" test
|
||||
CMAKE_FLAGS
|
||||
"-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}"
|
||||
"-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}"
|
||||
"-DEXPECT_SUCCESS=${EXPECT}"
|
||||
)
|
||||
if (NOT ${SUCCESS} STREQUAL ${EXPECT})
|
||||
message(FATAL_ERROR "Undefined symbols test failure: expect(${EXPECT}), success(${SUCCESS})")
|
||||
endif()
|
||||
file(REMOVE_RECURSE "${TEST_PROJECT}")
|
||||
endforeach()
|
||||
endfunction()
|
||||
if (NOT (CMAKE_SYSTEM_NAME MATCHES "kOpenBSD.*|OpenBSD.*"))
|
||||
forbid_undefined_symbols()
|
||||
endif()
|
||||
|
||||
if (MINGW)
|
||||
function(export_all_symbols)
|
||||
unset(TMP)
|
||||
add_linker_flag_if_supported(-Wl,--export-all-symbols TMP)
|
||||
string(APPEND CMAKE_SHARED_LINKER_FLAGS ${TMP})
|
||||
string(APPEND CMAKE_MODULE_LINKER_FLAGS ${TMP})
|
||||
set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} PARENT_SCOPE)
|
||||
set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} PARENT_SCOPE)
|
||||
endfunction()
|
||||
export_all_symbols()
|
||||
endif()
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)
|
||||
message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}")
|
||||
@@ -449,6 +511,10 @@ if(STATIC AND NOT IOS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
list(APPEND OPENSSL_LIBRARIES ws2_32 crypt32)
|
||||
endif()
|
||||
|
||||
find_package(HIDAPI)
|
||||
|
||||
add_definition_if_library_exists(c memset_s "string.h" HAVE_MEMSET_S)
|
||||
@@ -931,10 +997,12 @@ list(APPEND EXTRA_LIBRARIES ${CMAKE_DL_LIBS})
|
||||
if (HIDAPI_FOUND OR LibUSB_COMPILE_TEST_PASSED)
|
||||
if (APPLE)
|
||||
if(DEPENDS)
|
||||
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework IOKit")
|
||||
list(APPEND EXTRA_LIBRARIES "-framework Foundation -framework AppKit -framework IOKit")
|
||||
else()
|
||||
find_library(COREFOUNDATION CoreFoundation)
|
||||
find_library(APPKIT AppKit)
|
||||
find_library(IOKIT IOKit)
|
||||
list(APPEND EXTRA_LIBRARIES ${APPKIT})
|
||||
list(APPEND EXTRA_LIBRARIES ${IOKIT})
|
||||
list(APPEND EXTRA_LIBRARIES ${COREFOUNDATION})
|
||||
endif()
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ ARG BOOST_VERSION=1_70_0
|
||||
ARG BOOST_VERSION_DOT=1.70.0
|
||||
ARG BOOST_HASH=430ae8354789de4fd19ee52f3b1f739e1fba576f0aded0897c3c2bc00fb38778
|
||||
RUN set -ex \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
|
||||
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& cd boost_${BOOST_VERSION} \
|
||||
|
||||
@@ -134,8 +134,8 @@ Dates are provided in the format YYYY-MM-DD.
|
||||
| 1788000 | 2019-03-09 | v10 | v0.14.0.0 | v0.14.1.2 | New PoW based on Cryptonight-R, new block weight algorithm, slightly more efficient RingCT format
|
||||
| 1788720 | 2019-03-10 | v11 | v0.14.0.0 | v0.14.1.2 | forbid old RingCT transaction format
|
||||
| 1978433 | 2019-11-30* | v12 | v0.15.0.0 | v0.16.0.0 | New PoW based on RandomX, only allow >= 2 outputs, change to the block median used to calculate penalty, v1 coinbases are forbidden, rct sigs in coinbase forbidden, 10 block lock time for incoming outputs
|
||||
| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.2.0 | New CLSAG transaction format
|
||||
| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.2.0 | forbid old MLSAG transaction format
|
||||
| 2210000 | 2020-10-17 | v13 | v0.17.0.0 | v0.17.2.3 | New CLSAG transaction format
|
||||
| 2210720 | 2020-10-18 | v14 | v0.17.1.1 | v0.17.2.3 | forbid old MLSAG transaction format
|
||||
| XXXXXXX | XXX-XX-XX | XXX | vX.XX.X.X | vX.XX.X.X | XXX |
|
||||
|
||||
X's indicate that these details have not been determined as of commit date.
|
||||
@@ -295,7 +295,7 @@ Tested on a Raspberry Pi Zero with a clean install of minimal Raspbian Stretch (
|
||||
```bash
|
||||
git clone https://github.com/monero-project/monero.git
|
||||
cd monero
|
||||
git checkout tags/v0.17.2.0
|
||||
git checkout tags/v0.17.2.3
|
||||
```
|
||||
|
||||
* Build:
|
||||
@@ -412,10 +412,10 @@ application.
|
||||
cd monero
|
||||
```
|
||||
|
||||
* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.17.2.0'. If you don't care about the version and just want binaries from master, skip this step:
|
||||
* If you would like a specific [version/tag](https://github.com/monero-project/monero/tags), do a git checkout for that version. eg. 'v0.17.2.3'. If you don't care about the version and just want binaries from master, skip this step:
|
||||
|
||||
```bash
|
||||
git checkout v0.17.2.0
|
||||
git checkout v0.17.2.3
|
||||
```
|
||||
|
||||
* If you are on a 64-bit system, run:
|
||||
|
||||
+13
-6
@@ -42,12 +42,19 @@
|
||||
find_program(CCACHE_FOUND ccache)
|
||||
if (CCACHE_FOUND)
|
||||
# Try to compile a test program with ccache, in order to verify if it really works. (needed on exotic setups)
|
||||
# Create a temporary file with a simple program.
|
||||
set(TEMP_CPP_FILE "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/test-program.cpp")
|
||||
file(WRITE "${TEMP_CPP_FILE}" "int main() { return 0; }")
|
||||
# And run the found ccache on it.
|
||||
execute_process(COMMAND "${CCACHE_FOUND}" "${CMAKE_CXX_COMPILER}" "${TEMP_CPP_FILE}" RESULT_VARIABLE RET)
|
||||
if (${RET} EQUAL 0)
|
||||
set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp")
|
||||
file(WRITE "${TEST_PROJECT}/CMakeLists.txt" [=[
|
||||
cmake_minimum_required(VERSION 3.1)
|
||||
project(test)
|
||||
option (CCACHE "")
|
||||
file(WRITE "${CMAKE_SOURCE_DIR}/test.cpp" "int main() { return 0; }")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE}")
|
||||
add_executable(main test.cpp)
|
||||
]=])
|
||||
try_compile(RET "${TEST_PROJECT}/build" "${TEST_PROJECT}" "test" CMAKE_FLAGS -DCCACHE="${CCACHE_FOUND}")
|
||||
unset(TEST_PROJECT)
|
||||
if (${RET})
|
||||
# Success
|
||||
message(STATUS "Found usable ccache: ${CCACHE_FOUND}")
|
||||
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE_FOUND}")
|
||||
|
||||
@@ -134,7 +134,7 @@ if ( LibUSB_FOUND )
|
||||
|
||||
try_compile(LibUSB_COMPILE_TEST_PASSED
|
||||
${CMAKE_BINARY_DIR}
|
||||
"${CMAKE_SOURCE_DIR}/cmake/test-libusb-version.c"
|
||||
"${CMAKE_CURRENT_LIST_DIR}/test-libusb-version.c"
|
||||
CMAKE_FLAGS
|
||||
"-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}"
|
||||
"-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
SOURCES_PATH ?= $(BASEDIR)/sources
|
||||
BASE_CACHE ?= $(BASEDIR)/built
|
||||
SDK_PATH ?= $(BASEDIR)/SDKs
|
||||
FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources
|
||||
FALLBACK_DOWNLOAD_PATH ?= https://downloads.getmonero.org/depends-sources
|
||||
|
||||
BUILD = $(shell ./config.guess)
|
||||
HOST ?= $(BUILD)
|
||||
|
||||
@@ -32,7 +32,7 @@ endef
|
||||
define fetch_file
|
||||
( test -f $$($(1)_source_dir)/$(4) || \
|
||||
( $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5)) || \
|
||||
$(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(3),$(4),$(5))))
|
||||
$(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(4),$(4),$(5))))
|
||||
endef
|
||||
|
||||
define int_get_build_recipe_hash
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package=boost
|
||||
$(package)_version=1_64_0
|
||||
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.64.0/source/
|
||||
$(package)_download_path=https://downloads.sourceforge.net/project/boost/boost/1.64.0/
|
||||
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
|
||||
$(package)_sha256_hash=7bcc5caace97baa948931d712ea5f37038dbb1c5d89b43ad4def4ed7cb683332
|
||||
$(package)_dependencies=libiconv
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package=eudev
|
||||
$(package)_version=v3.2.6
|
||||
$(package)_download_path=https://github.com/gentoo/eudev/archive/
|
||||
$(package)_file_name=$($(package)_version).tar.gz
|
||||
$(package)_download_file=$($(package)_version).tar.gz
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=a96ecb8637667897b8bd4dee4c22c7c5f08b327be45186e912ce6bc768385852
|
||||
|
||||
define $(package)_set_vars
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package=gtest
|
||||
$(package)_version=1.8.1
|
||||
$(package)_download_path=https://github.com/google/googletest/archive/
|
||||
$(package)_file_name=release-$($(package)_version).tar.gz
|
||||
$(package)_download_file=release-$($(package)_version).tar.gz
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c
|
||||
$(package)_cxxflags=-std=c++11
|
||||
$(package)_cxxflags_linux=-fPIC
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
package=native_cctools
|
||||
$(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6
|
||||
$(package)_download_path=https://github.com/theuni/cctools-port/archive
|
||||
$(package)_file_name=$($(package)_version).tar.gz
|
||||
$(package)_download_file=$($(package)_version).tar.gz
|
||||
$(package)_file_name=$(package)-$($(package)_version).tar.gz
|
||||
$(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a
|
||||
$(package)_build_subdir=cctools
|
||||
$(package)_clang_version=3.7.1
|
||||
|
||||
@@ -236,6 +236,7 @@ namespace net_utils
|
||||
virtual address_type get_type_id() const = 0;
|
||||
virtual zone get_zone() const = 0;
|
||||
virtual bool is_blockable() const = 0;
|
||||
virtual std::uint16_t port() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
@@ -266,6 +267,7 @@ namespace net_utils
|
||||
virtual address_type get_type_id() const override { return value.get_type_id(); }
|
||||
virtual zone get_zone() const override { return value.get_zone(); }
|
||||
virtual bool is_blockable() const override { return value.is_blockable(); }
|
||||
virtual std::uint16_t port() const override { return value.port(); }
|
||||
};
|
||||
|
||||
std::shared_ptr<interface> self;
|
||||
@@ -312,6 +314,7 @@ namespace net_utils
|
||||
address_type get_type_id() const { return self ? self->get_type_id() : address_type::invalid; }
|
||||
zone get_zone() const { return self ? self->get_zone() : zone::invalid; }
|
||||
bool is_blockable() const { return self ? self->is_blockable() : false; }
|
||||
std::uint16_t port() const { return self ? self->port() : 0; }
|
||||
template<typename Type> const Type &as() const { return as_mutable<const Type>(); }
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
|
||||
@@ -40,6 +40,8 @@
|
||||
#include "span.h"
|
||||
#include "int-util.h"
|
||||
|
||||
#include <boost/mpl/contains.hpp>
|
||||
|
||||
namespace epee
|
||||
{
|
||||
namespace serialization
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
|
||||
add_library(epee STATIC byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
|
||||
add_library(epee byte_slice.cpp byte_stream.cpp hex.cpp abstract_http_client.cpp http_auth.cpp mlog.cpp net_helper.cpp net_utils_base.cpp string_tools.cpp
|
||||
wipeable_string.cpp levin_base.cpp memwipe.c connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp
|
||||
int-util.cpp)
|
||||
|
||||
@@ -60,14 +60,23 @@ target_link_libraries(epee
|
||||
${Boost_CHRONO_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_THREAD_LIBRARY}
|
||||
PRIVATE
|
||||
${Boost_REGEX_LIBRARY}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${OPENSSL_LIBRARIES}
|
||||
PRIVATE
|
||||
${EXTRA_LIBRARIES})
|
||||
|
||||
if (USE_READLINE AND (GNU_READLINE_FOUND OR (DEPENDS AND NOT MINGW)))
|
||||
target_link_libraries(epee_readline
|
||||
PUBLIC
|
||||
easylogging
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
PRIVATE
|
||||
${GNU_READLINE_LIBRARY})
|
||||
endif()
|
||||
|
||||
target_include_directories(epee
|
||||
PUBLIC
|
||||
"${EPEE_INCLUDE_DIR_BASE}"
|
||||
"${OPENSSL_INCLUDE_DIR}")
|
||||
|
||||
|
||||
@@ -94,10 +94,6 @@ def build():
|
||||
os.chdir('builder')
|
||||
os.makedirs('inputs', exist_ok=True)
|
||||
|
||||
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://downloads.sourceforge.net/project/osslsigncode/osslsigncode/osslsigncode-1.7.1.tar.gz'])
|
||||
subprocess.check_call(['wget', '-N', '-P', 'inputs', 'https://bitcoincore.org/cfields/osslsigncode-Backports-to-1.7.1.patch'])
|
||||
subprocess.check_output(["echo 'a8c4e9cafba922f89de0df1f2152e7be286aba73f78505169bc351a7938dd911 inputs/osslsigncode-Backports-to-1.7.1.patch' | sha256sum -c"], shell=True)
|
||||
subprocess.check_output(["echo 'f9a8cdb38b9c309326764ebc937cba1523a3a751a7ab05df3ecc99d18ae466c9 inputs/osslsigncode-1.7.1.tar.gz' | sha256sum -c"], shell=True)
|
||||
subprocess.check_call(['make', '-C', 'inputs/monero/contrib/depends', 'download', 'SOURCES_PATH=' + os.getcwd() + '/cache/common'])
|
||||
|
||||
rebuild()
|
||||
|
||||
Vendored
+3
-3
@@ -4882,9 +4882,6 @@ mdb_env_open2(MDB_env *env, int prev)
|
||||
#endif
|
||||
env->me_maxpg = env->me_mapsize / env->me_psize;
|
||||
|
||||
if (env->me_txns)
|
||||
env->me_txns->mti_txnid = meta.mm_txnid;
|
||||
|
||||
#if MDB_DEBUG
|
||||
{
|
||||
MDB_meta *meta = mdb_env_pick_meta(env);
|
||||
@@ -4984,6 +4981,9 @@ static int ESECT
|
||||
mdb_env_share_locks(MDB_env *env, int *excl)
|
||||
{
|
||||
int rc = 0;
|
||||
MDB_meta *meta = mdb_env_pick_meta(env);
|
||||
|
||||
env->me_txns->mti_txnid = meta->mm_txnid;
|
||||
|
||||
#ifdef _WIN32
|
||||
{
|
||||
|
||||
Vendored
+1
-1
Submodule external/randomx updated: 5ce5f4906c...fe4324e8c0
@@ -28,20 +28,32 @@
|
||||
|
||||
set(GENERATED_SOURCES "")
|
||||
|
||||
set(GENERATOR "${CMAKE_CURRENT_BINARY_DIR}/blocks_generator.cmake")
|
||||
file(GENERATE OUTPUT ${GENERATOR} CONTENT [=[
|
||||
file(READ "${INPUT_DAT_FILE}" DATA HEX)
|
||||
string(REGEX REPLACE "[0-9a-fA-F][0-9a-fA-F]" "0x\\0," DATA "${DATA}")
|
||||
file(WRITE "${OUTPUT_C_SOURCE}" "
|
||||
#include <stddef.h>
|
||||
const unsigned char ${BLOB_NAME}[]={
|
||||
${DATA}
|
||||
};
|
||||
const size_t ${BLOB_NAME}_len = sizeof(${BLOB_NAME});
|
||||
"
|
||||
)
|
||||
]=])
|
||||
foreach(BLOB_NAME checkpoints testnet_blocks stagenet_blocks)
|
||||
set(OUTPUT_C_SOURCE "generated_${BLOB_NAME}.c")
|
||||
list(APPEND GENERATED_SOURCES ${OUTPUT_C_SOURCE})
|
||||
set(INPUT_DAT_FILE "${BLOB_NAME}.dat")
|
||||
add_custom_command(
|
||||
OUTPUT ${OUTPUT_C_SOURCE}
|
||||
MAIN_DEPENDENCY ${INPUT_DAT_FILE}
|
||||
COMMAND
|
||||
cd ${CMAKE_CURRENT_BINARY_DIR} &&
|
||||
echo "'#include\t<stddef.h>'" > ${OUTPUT_C_SOURCE} &&
|
||||
echo "'const\tunsigned\tchar\t${BLOB_NAME}[]={'" >> ${OUTPUT_C_SOURCE} &&
|
||||
od -v -An -tx1 ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE} | sed -e "'s/[0-9a-fA-F]\\{1,\\}/0x&,/g'" -e "'$$s/.$$//'" >> ${OUTPUT_C_SOURCE} &&
|
||||
echo "'};'" >> ${OUTPUT_C_SOURCE} &&
|
||||
echo "'const\tsize_t\t${BLOB_NAME}_len\t=\tsizeof(${BLOB_NAME});'" >> ${OUTPUT_C_SOURCE}
|
||||
OUTPUT ${OUTPUT_C_SOURCE}
|
||||
MAIN_DEPENDENCY ${INPUT_DAT_FILE}
|
||||
DEPENDS ${GENERATOR}
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
"-DINPUT_DAT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE}"
|
||||
"-DBLOB_NAME=${BLOB_NAME}"
|
||||
"-DOUTPUT_C_SOURCE=${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_C_SOURCE}"
|
||||
-P "${GENERATOR}"
|
||||
)
|
||||
endforeach()
|
||||
|
||||
|
||||
Binary file not shown.
@@ -247,6 +247,7 @@ namespace cryptonote
|
||||
ADD_CHECKPOINT2(2257500, "99643c32f27b157c6952a67af7dbe07ca819e71df386fa9379a344686d2950cf", "0x11c2f448d4f8830");
|
||||
ADD_CHECKPOINT2(2265000, "727a6228a71f5b35c899553ee19d60bfc10c126a009ffd633afb30666e8edbe6", "0x121a33e656ecad4");
|
||||
ADD_CHECKPOINT2(2325000, "f61261994b368700f0cbbfb4477433fa36a3c7537908ab2d1a06ac2987cc8b01", "0x154bceeffaff847");
|
||||
ADD_CHECKPOINT2(2430000, "5f7f4273eb6be024df3c4311a8d28482220a253190efa1719f35b7782587740c", "0x1c3f14ba9b0bebc");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#include "file_io_utils.h"
|
||||
#include "common/i18n.h"
|
||||
#include "translation_files.h"
|
||||
#include <algorithm>
|
||||
|
||||
#undef MONERO_DEFAULT_LOG_CATEGORY
|
||||
#define MONERO_DEFAULT_LOG_CATEGORY "i18n"
|
||||
|
||||
+6
-2
@@ -1355,8 +1355,12 @@ std::string get_nix_version_display_string()
|
||||
100743, 92152, 57565, 22533, 37564, 21823, 19980, 18277, 18402, 14344,
|
||||
12142, 15842, 13677, 17631, 18294, 22270, 41422, 39296, 36688, 33512,
|
||||
33831, 27582, 22276, 27516, 27317, 25505, 24426, 20566, 23045, 26766,
|
||||
28185, 26169, 27011,
|
||||
28642 // Blocks 1,990,000 to 1,999,999 in December 2019
|
||||
28185, 26169, 27011, 28642, 34994, 34442, 30682, 34357, 31640, 41167,
|
||||
41301, 48616, 51075, 55061, 49909, 44606, 47091, 53828, 42520, 39023,
|
||||
55245, 56145, 51119, 60398, 71821, 48142, 60310, 56041, 54176, 66220,
|
||||
56336, 55248, 56656, 63305, 54029, 77136, 71902, 71618, 83587, 81068,
|
||||
69062, 54848, 53681, 53555,
|
||||
50616 // Blocks 2,400,000 to 2,409,999 in July 2021
|
||||
};
|
||||
const uint64_t block_range_size = 10000;
|
||||
|
||||
|
||||
@@ -36,6 +36,14 @@ if(APPLE)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
monero_add_library(cryptonote_format_utils_basic
|
||||
cryptonote_format_utils_basic.cpp
|
||||
)
|
||||
target_link_libraries(cryptonote_format_utils_basic
|
||||
PUBLIC
|
||||
cncrypto
|
||||
)
|
||||
|
||||
set(cryptonote_basic_sources
|
||||
account.cpp
|
||||
connection_context.cpp
|
||||
@@ -72,6 +80,7 @@ target_link_libraries(cryptonote_basic
|
||||
common
|
||||
cncrypto
|
||||
checkpoints
|
||||
cryptonote_format_utils_basic
|
||||
device
|
||||
${Boost_DATE_TIME_LIBRARY}
|
||||
${Boost_PROGRAM_OPTIONS_LIBRARY}
|
||||
|
||||
@@ -139,22 +139,6 @@ namespace cryptonote
|
||||
return h;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
|
||||
{
|
||||
std::ostringstream s;
|
||||
binary_archive<true> a(s);
|
||||
::serialization::serialize(a, const_cast<transaction_prefix&>(tx));
|
||||
crypto::cn_fast_hash(s.str().data(), s.str().size(), h);
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
|
||||
{
|
||||
crypto::hash h = null_hash;
|
||||
get_transaction_prefix_hash(tx, h);
|
||||
return h;
|
||||
}
|
||||
//---------------------------------------------------------------
|
||||
bool expand_transaction_1(transaction &tx, bool base_only)
|
||||
{
|
||||
if (tx.version >= 2 && !is_coinbase(tx))
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
// Copyright (c) 2014-2021, 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 "cryptonote_format_utils.h"
|
||||
|
||||
namespace cryptonote
|
||||
{
|
||||
void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h)
|
||||
{
|
||||
std::ostringstream s;
|
||||
binary_archive<true> a(s);
|
||||
::serialization::serialize(a, const_cast<transaction_prefix&>(tx));
|
||||
crypto::cn_fast_hash(s.str().data(), s.str().size(), h);
|
||||
}
|
||||
|
||||
crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx)
|
||||
{
|
||||
crypto::hash h = crypto::null_hash;
|
||||
get_transaction_prefix_hash(tx, h);
|
||||
return h;
|
||||
}
|
||||
}
|
||||
@@ -5390,7 +5390,7 @@ void Blockchain::cancel()
|
||||
}
|
||||
|
||||
#if defined(PER_BLOCK_CHECKPOINT)
|
||||
static const char expected_block_hashes_hash[] = "b198c2514bed71ca0a43cba6590090068daf6d207b351d8a4c7d0f0f791c095f";
|
||||
static const char expected_block_hashes_hash[] = "ff99bc76e59e0d6268e2d8ed54a2206d828de643fcb13be8d296611fc051a540";
|
||||
void Blockchain::load_compiled_in_block_hashes(const GetCheckpointsCallback& get_checkpoints)
|
||||
{
|
||||
if (get_checkpoints == nullptr || !m_fast_sync)
|
||||
|
||||
@@ -71,6 +71,7 @@ target_link_libraries(device
|
||||
PUBLIC
|
||||
${HIDAPI_LIBRARIES}
|
||||
cncrypto
|
||||
cryptonote_format_utils_basic
|
||||
ringct_basic
|
||||
wallet-crypto
|
||||
${OPENSSL_CRYPTO_LIBRARIES}
|
||||
|
||||
@@ -529,9 +529,7 @@ namespace hw {
|
||||
}
|
||||
|
||||
bool device_ledger::init(void) {
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
this->controle_device = &hw::get_device("default");
|
||||
#endif
|
||||
this->release();
|
||||
hw_device.init();
|
||||
MDEBUG( "Device "<<this->id <<" HIDUSB inited");
|
||||
@@ -697,7 +695,6 @@ namespace hw {
|
||||
/* ======================================================================= */
|
||||
|
||||
bool device_ledger::derive_subaddress_public_key(const crypto::public_key &pub, const crypto::key_derivation &derivation, const std::size_t output_index, crypto::public_key &derived_pub){
|
||||
AUTO_LOCK_CMD();
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
const crypto::public_key pub_x = pub;
|
||||
crypto::key_derivation derivation_x;
|
||||
@@ -721,7 +718,7 @@ namespace hw {
|
||||
MDEBUG( "derive_subaddress_public_key : PARSE mode with known viewkey");
|
||||
crypto::derive_subaddress_public_key(pub, derivation, output_index,derived_pub);
|
||||
} else {
|
||||
|
||||
AUTO_LOCK_CMD();
|
||||
int offset = set_command_header_noopt(INS_DERIVE_SUBADDRESS_PUBLIC_KEY);
|
||||
//pub
|
||||
memmove(this->buffer_send+offset, pub.data, 32);
|
||||
@@ -750,6 +747,12 @@ namespace hw {
|
||||
}
|
||||
|
||||
crypto::public_key device_ledger::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) {
|
||||
if (has_view_key) {
|
||||
cryptonote::account_keys keys_{keys};
|
||||
keys_.m_view_secret_key = this->viewkey;
|
||||
return this->controle_device->get_subaddress_spend_public_key(keys_, index);
|
||||
}
|
||||
|
||||
AUTO_LOCK_CMD();
|
||||
crypto::public_key D;
|
||||
|
||||
@@ -801,6 +804,12 @@ namespace hw {
|
||||
}
|
||||
|
||||
cryptonote::account_public_address device_ledger::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) {
|
||||
if (has_view_key) {
|
||||
cryptonote::account_keys keys_{keys};
|
||||
keys_.m_view_secret_key = this->viewkey;
|
||||
return this->controle_device->get_subaddress(keys_, index);
|
||||
}
|
||||
|
||||
AUTO_LOCK_CMD();
|
||||
cryptonote::account_public_address address;
|
||||
|
||||
@@ -1049,7 +1058,6 @@ namespace hw {
|
||||
}
|
||||
|
||||
bool device_ledger::generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) {
|
||||
AUTO_LOCK_CMD();
|
||||
bool r = false;
|
||||
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
@@ -1070,6 +1078,7 @@ namespace hw {
|
||||
assert(is_fake_view_key(sec));
|
||||
r = crypto::generate_key_derivation(pub, this->viewkey, derivation);
|
||||
} else {
|
||||
AUTO_LOCK_CMD();
|
||||
int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION);
|
||||
//pub
|
||||
memmove(this->buffer_send+offset, pub.data, 32);
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace hw {
|
||||
|
||||
/* Minimal supported version */
|
||||
#define MINIMAL_APP_VERSION_MAJOR 1
|
||||
#define MINIMAL_APP_VERSION_MINOR 6
|
||||
#define MINIMAL_APP_VERSION_MICRO 0
|
||||
#define MINIMAL_APP_VERSION_MINOR 7
|
||||
#define MINIMAL_APP_VERSION_MICRO 6
|
||||
|
||||
#define VERSION(M,m,u) ((M)<<16|(m)<<8|(u))
|
||||
#define VERSION_MAJOR(v) (((v)>>16)&0xFF)
|
||||
@@ -192,11 +192,8 @@ namespace hw {
|
||||
// To speed up blockchain parsing the view key maybe handle here.
|
||||
crypto::secret_key viewkey;
|
||||
bool has_view_key;
|
||||
|
||||
//extra debug
|
||||
#ifdef DEBUG_HWDEVICE
|
||||
|
||||
device *controle_device;
|
||||
#endif
|
||||
|
||||
public:
|
||||
device_ledger();
|
||||
|
||||
@@ -510,7 +510,7 @@ namespace trezor {
|
||||
|
||||
const auto data_cleaner = epee::misc_utils::create_scope_leave_handler([&]() {
|
||||
if (m.has_passphrase())
|
||||
memwipe(&(m.mutable_passphrase())[0], m.mutable_passphrase()->size());
|
||||
memwipe(&(*m.mutable_passphrase())[0], m.mutable_passphrase()->size());
|
||||
});
|
||||
|
||||
resp = call_raw(&m);
|
||||
|
||||
+18
-3
@@ -269,9 +269,17 @@ namespace nodetool
|
||||
|
||||
peerlist_entry pe{};
|
||||
pe.adr = addr;
|
||||
zone.second.m_peerlist.remove_from_peer_white(pe);
|
||||
zone.second.m_peerlist.remove_from_peer_gray(pe);
|
||||
zone.second.m_peerlist.remove_from_peer_anchor(addr);
|
||||
if (addr.port() == 0)
|
||||
{
|
||||
zone.second.m_peerlist.evict_host_from_peerlist(true, pe);
|
||||
zone.second.m_peerlist.evict_host_from_peerlist(false, pe);
|
||||
}
|
||||
else
|
||||
{
|
||||
zone.second.m_peerlist.remove_from_peer_white(pe);
|
||||
zone.second.m_peerlist.remove_from_peer_gray(pe);
|
||||
zone.second.m_peerlist.remove_from_peer_anchor(addr);
|
||||
}
|
||||
|
||||
for (const auto &c: conns)
|
||||
zone.second.m_net_server.get_config_object().close(c);
|
||||
@@ -331,6 +339,13 @@ namespace nodetool
|
||||
for (const auto &c: conns)
|
||||
zone.second.m_net_server.get_config_object().close(c);
|
||||
|
||||
for (int i = 0; i < 2; ++i)
|
||||
zone.second.m_peerlist.filter(i == 0, [&subnet](const peerlist_entry &pe){
|
||||
if (pe.adr.get_type_id() != epee::net_utils::ipv4_network_address::get_type_id())
|
||||
return false;
|
||||
return subnet.matches(pe.adr.as<const epee::net_utils::ipv4_network_address>());
|
||||
});
|
||||
|
||||
conns.clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -289,17 +289,9 @@ namespace nodetool
|
||||
copy_peers(peers.anchor, m_peers_anchor.get<by_addr>());
|
||||
}
|
||||
|
||||
void peerlist_manager::evict_host_from_white_peerlist(const peerlist_entry& pr)
|
||||
void peerlist_manager::evict_host_from_peerlist(bool use_white, const peerlist_entry& pr)
|
||||
{
|
||||
peers_indexed::index<by_time>::type& sorted_index=m_peers_white.get<by_time>();
|
||||
auto i = sorted_index.begin();
|
||||
while (i != sorted_index.end())
|
||||
{
|
||||
if (i->adr.is_same_host(pr.adr))
|
||||
i = sorted_index.erase(i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
filter(use_white, [&pr](const peerlist_entry& pe){ return pe.adr.is_same_host(pr.adr); });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+24
-2
@@ -109,7 +109,7 @@ namespace nodetool
|
||||
bool get_white_peer_by_index(peerlist_entry& p, size_t i);
|
||||
bool get_gray_peer_by_index(peerlist_entry& p, size_t i);
|
||||
template<typename F> bool foreach(bool white, const F &f);
|
||||
void evict_host_from_white_peerlist(const peerlist_entry& pr);
|
||||
void evict_host_from_peerlist(bool white, const peerlist_entry& pr);
|
||||
bool append_with_peer_white(const peerlist_entry& pr);
|
||||
bool append_with_peer_gray(const peerlist_entry& pr);
|
||||
bool append_with_peer_anchor(const anchor_peerlist_entry& ple);
|
||||
@@ -120,6 +120,7 @@ namespace nodetool
|
||||
bool get_and_empty_anchor_peerlist(std::vector<anchor_peerlist_entry>& apl);
|
||||
bool remove_from_peer_anchor(const epee::net_utils::network_address& addr);
|
||||
bool remove_from_peer_white(const peerlist_entry& pe);
|
||||
template<typename F> size_t filter(bool white, const F &f); // f returns true: drop, false: keep
|
||||
|
||||
private:
|
||||
struct by_time{};
|
||||
@@ -346,7 +347,7 @@ namespace nodetool
|
||||
if(by_addr_it_wt == m_peers_white.get<by_addr>().end())
|
||||
{
|
||||
//put new record into white list
|
||||
evict_host_from_white_peerlist(ple);
|
||||
evict_host_from_peerlist(true, ple);
|
||||
m_peers_white.insert(ple);
|
||||
trim_white_peerlist();
|
||||
}else
|
||||
@@ -519,5 +520,26 @@ namespace nodetool
|
||||
CATCH_ENTRY_L0("peerlist_manager::remove_from_peer_anchor()", false);
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
template<typename F> size_t peerlist_manager::filter(bool white, const F &f)
|
||||
{
|
||||
size_t filtered = 0;
|
||||
TRY_ENTRY();
|
||||
CRITICAL_REGION_LOCAL(m_peerlist_lock);
|
||||
peers_indexed::index<by_addr>::type& sorted_index = white ? m_peers_gray.get<by_addr>() : m_peers_white.get<by_addr>();
|
||||
auto i = sorted_index.begin();
|
||||
while (i != sorted_index.end())
|
||||
{
|
||||
if (f(*i))
|
||||
{
|
||||
i = sorted_index.erase(i);
|
||||
++filtered;
|
||||
}
|
||||
else
|
||||
++i;
|
||||
}
|
||||
CATCH_ENTRY_L0("peerlist_manager::filter()", filtered);
|
||||
return filtered;
|
||||
}
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
|
||||
@@ -1091,9 +1091,12 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::rctSig&
|
||||
};
|
||||
|
||||
INSERT_INTO_JSON_OBJECT(dest, type, sig.type);
|
||||
INSERT_INTO_JSON_OBJECT(dest, encrypted, sig.ecdhInfo);
|
||||
INSERT_INTO_JSON_OBJECT(dest, commitments, transform(sig.outPk, just_mask));
|
||||
INSERT_INTO_JSON_OBJECT(dest, fee, sig.txnFee);
|
||||
if (sig.type != rct::RCTTypeNull)
|
||||
{
|
||||
INSERT_INTO_JSON_OBJECT(dest, encrypted, sig.ecdhInfo);
|
||||
INSERT_INTO_JSON_OBJECT(dest, commitments, transform(sig.outPk, just_mask));
|
||||
INSERT_INTO_JSON_OBJECT(dest, fee, sig.txnFee);
|
||||
}
|
||||
|
||||
// prunable
|
||||
if (!sig.p.bulletproofs.empty() || !sig.p.rangeSigs.empty() || !sig.p.MGs.empty() || !sig.get_pseudo_outs().empty())
|
||||
@@ -1122,9 +1125,12 @@ void fromJsonValue(const rapidjson::Value& val, rct::rctSig& sig)
|
||||
}
|
||||
|
||||
GET_FROM_JSON_OBJECT(val, sig.type, type);
|
||||
GET_FROM_JSON_OBJECT(val, sig.ecdhInfo, encrypted);
|
||||
GET_FROM_JSON_OBJECT(val, sig.outPk, commitments);
|
||||
GET_FROM_JSON_OBJECT(val, sig.txnFee, fee);
|
||||
if (sig.type != rct::RCTTypeNull)
|
||||
{
|
||||
GET_FROM_JSON_OBJECT(val, sig.ecdhInfo, encrypted);
|
||||
GET_FROM_JSON_OBJECT(val, sig.outPk, commitments);
|
||||
GET_FROM_JSON_OBJECT(val, sig.txnFee, fee);
|
||||
}
|
||||
|
||||
// prunable
|
||||
const auto prunable = val.FindMember("prunable");
|
||||
|
||||
@@ -5800,7 +5800,7 @@ bool simple_wallet::refresh_main(uint64_t start_height, enum ResetType reset, bo
|
||||
if (reset != ResetNone)
|
||||
{
|
||||
if (reset == ResetSoftKeepKI)
|
||||
height_pre = m_wallet->hash_m_transfers(-1, transfer_hash_pre);
|
||||
height_pre = m_wallet->hash_m_transfers(boost::none, transfer_hash_pre);
|
||||
|
||||
m_wallet->rescan_blockchain(reset == ResetHard, false, reset == ResetSoftKeepKI);
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#define DEF_MONERO_VERSION_TAG "@VERSIONTAG@"
|
||||
#define DEF_MONERO_VERSION "0.17.2.0"
|
||||
#define DEF_MONERO_VERSION "0.17.2.3"
|
||||
#define DEF_MONERO_RELEASE_NAME "Oxygen Orion"
|
||||
#define DEF_MONERO_VERSION_FULL DEF_MONERO_VERSION "-" DEF_MONERO_VERSION_TAG
|
||||
#define DEF_MONERO_VERSION_IS_RELEASE @VERSION_IS_RELEASE@
|
||||
|
||||
@@ -71,10 +71,13 @@ target_link_libraries(wallet_api
|
||||
mnemonics
|
||||
${LMDB_LIBRARY}
|
||||
${Boost_CHRONO_LIBRARY}
|
||||
${Boost_LOCALE_LIBRARY}
|
||||
${ICU_LIBRARIES}
|
||||
${Boost_SERIALIZATION_LIBRARY}
|
||||
${Boost_FILESYSTEM_LIBRARY}
|
||||
${Boost_SYSTEM_LIBRARY}
|
||||
${Boost_THREAD_LIBRARY}
|
||||
${CMAKE_THREAD_LIBS_INIT}
|
||||
${Boost_REGEX_LIBRARY}
|
||||
PRIVATE
|
||||
${EXTRA_LIBRARIES})
|
||||
|
||||
@@ -70,6 +70,25 @@ bool AddressBookImpl::addRow(const std::string &dst_addr , const std::string &pa
|
||||
return r;
|
||||
}
|
||||
|
||||
bool AddressBookImpl::setDescription(std::size_t index, const std::string &description)
|
||||
{
|
||||
clearStatus();
|
||||
|
||||
const auto ab = m_wallet->m_wallet->get_address_book();
|
||||
if (index >= ab.size()){
|
||||
return false;
|
||||
}
|
||||
|
||||
tools::wallet2::address_book_row entry = ab[index];
|
||||
entry.m_description = description;
|
||||
bool r = m_wallet->m_wallet->set_address_book_row(index, entry.m_address, NULL, entry.m_description, entry.m_is_subaddress);
|
||||
if (r)
|
||||
refresh();
|
||||
else
|
||||
m_errorCode = General_Error;
|
||||
return r;
|
||||
}
|
||||
|
||||
void AddressBookImpl::refresh()
|
||||
{
|
||||
LOG_PRINT_L2("Refreshing addressbook");
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
void refresh() override;
|
||||
std::vector<AddressBookRow*> getAll() const override;
|
||||
bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) override;
|
||||
bool setDescription(std::size_t index, const std::string &description) override;
|
||||
bool deleteRow(std::size_t rowId) override;
|
||||
|
||||
// Error codes. See AddressBook:ErrorCode enum in wallet2_api.h
|
||||
|
||||
@@ -92,6 +92,17 @@ std::vector<TransactionInfo *> TransactionHistoryImpl::getAll() const
|
||||
return m_history;
|
||||
}
|
||||
|
||||
void TransactionHistoryImpl::setTxNote(const std::string &txid, const std::string ¬e)
|
||||
{
|
||||
cryptonote::blobdata txid_data;
|
||||
if(!epee::string_tools::parse_hexstr_to_binbuff(txid, txid_data) || txid_data.size() != sizeof(crypto::hash))
|
||||
return;
|
||||
const crypto::hash htxid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
|
||||
|
||||
m_wallet->m_wallet->set_tx_note(htxid, note);
|
||||
refresh();
|
||||
}
|
||||
|
||||
void TransactionHistoryImpl::refresh()
|
||||
{
|
||||
// multithreaded access:
|
||||
@@ -126,10 +137,13 @@ void TransactionHistoryImpl::refresh()
|
||||
payment_id = payment_id.substr(0,16);
|
||||
TransactionInfoImpl * ti = new TransactionInfoImpl();
|
||||
ti->m_paymentid = payment_id;
|
||||
ti->m_coinbase = pd.m_coinbase;
|
||||
ti->m_amount = pd.m_amount;
|
||||
ti->m_fee = pd.m_fee;
|
||||
ti->m_direction = TransactionInfo::Direction_In;
|
||||
ti->m_hash = string_tools::pod_to_hex(pd.m_tx_hash);
|
||||
ti->m_blockheight = pd.m_block_height;
|
||||
ti->m_description = m_wallet->m_wallet->get_tx_note(pd.m_tx_hash);
|
||||
ti->m_subaddrIndex = { pd.m_subaddr_index.minor };
|
||||
ti->m_subaddrAccount = pd.m_subaddr_index.major;
|
||||
ti->m_label = m_wallet->m_wallet->get_subaddress_label(pd.m_subaddr_index);
|
||||
@@ -173,6 +187,7 @@ void TransactionHistoryImpl::refresh()
|
||||
ti->m_direction = TransactionInfo::Direction_Out;
|
||||
ti->m_hash = string_tools::pod_to_hex(hash);
|
||||
ti->m_blockheight = pd.m_block_height;
|
||||
ti->m_description = m_wallet->m_wallet->get_tx_note(hash);
|
||||
ti->m_subaddrIndex = pd.m_subaddr_indices;
|
||||
ti->m_subaddrAccount = pd.m_subaddr_account;
|
||||
ti->m_label = pd.m_subaddr_indices.size() == 1 ? m_wallet->m_wallet->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "";
|
||||
@@ -183,6 +198,7 @@ void TransactionHistoryImpl::refresh()
|
||||
for (const auto &d: pd.m_dests) {
|
||||
ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id)});
|
||||
}
|
||||
|
||||
m_history.push_back(ti);
|
||||
}
|
||||
|
||||
@@ -207,11 +223,16 @@ void TransactionHistoryImpl::refresh()
|
||||
ti->m_failed = is_failed;
|
||||
ti->m_pending = true;
|
||||
ti->m_hash = string_tools::pod_to_hex(hash);
|
||||
ti->m_description = m_wallet->m_wallet->get_tx_note(hash);
|
||||
ti->m_subaddrIndex = pd.m_subaddr_indices;
|
||||
ti->m_subaddrAccount = pd.m_subaddr_account;
|
||||
ti->m_label = pd.m_subaddr_indices.size() == 1 ? m_wallet->m_wallet->get_subaddress_label({pd.m_subaddr_account, *pd.m_subaddr_indices.begin()}) : "";
|
||||
ti->m_timestamp = pd.m_timestamp;
|
||||
ti->m_confirmations = 0;
|
||||
for (const auto &d : pd.m_dests)
|
||||
{
|
||||
ti->m_transfers.push_back({d.amount, d.address(m_wallet->m_wallet->nettype(), pd.m_payment_id)});
|
||||
}
|
||||
m_history.push_back(ti);
|
||||
}
|
||||
|
||||
@@ -230,6 +251,7 @@ void TransactionHistoryImpl::refresh()
|
||||
ti->m_direction = TransactionInfo::Direction_In;
|
||||
ti->m_hash = string_tools::pod_to_hex(pd.m_tx_hash);
|
||||
ti->m_blockheight = pd.m_block_height;
|
||||
ti->m_description = m_wallet->m_wallet->get_tx_note(pd.m_tx_hash);
|
||||
ti->m_pending = true;
|
||||
ti->m_subaddrIndex = { pd.m_subaddr_index.minor };
|
||||
ti->m_subaddrAccount = pd.m_subaddr_index.major;
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
virtual TransactionInfo * transaction(const std::string &id) const;
|
||||
virtual std::vector<TransactionInfo*> getAll() const;
|
||||
virtual void refresh();
|
||||
virtual void setTxNote(const std::string &txid, const std::string ¬e);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ TransactionInfoImpl::TransactionInfoImpl()
|
||||
: m_direction(Direction_Out)
|
||||
, m_pending(false)
|
||||
, m_failed(false)
|
||||
, m_coinbase(false)
|
||||
, m_amount(0)
|
||||
, m_fee(0)
|
||||
, m_blockheight(0)
|
||||
@@ -77,6 +78,11 @@ bool TransactionInfoImpl::isFailed() const
|
||||
return m_failed;
|
||||
}
|
||||
|
||||
bool TransactionInfoImpl::isCoinbase() const
|
||||
{
|
||||
return m_coinbase;
|
||||
}
|
||||
|
||||
uint64_t TransactionInfoImpl::amount() const
|
||||
{
|
||||
return m_amount;
|
||||
@@ -92,6 +98,11 @@ uint64_t TransactionInfoImpl::blockHeight() const
|
||||
return m_blockheight;
|
||||
}
|
||||
|
||||
std::string TransactionInfoImpl::description() const
|
||||
{
|
||||
return m_description;
|
||||
}
|
||||
|
||||
std::set<uint32_t> TransactionInfoImpl::subaddrIndex() const
|
||||
{
|
||||
return m_subaddrIndex;
|
||||
|
||||
@@ -46,10 +46,12 @@ public:
|
||||
//! true if hold
|
||||
virtual bool isPending() const override;
|
||||
virtual bool isFailed() const override;
|
||||
virtual bool isCoinbase() const override;
|
||||
virtual uint64_t amount() const override;
|
||||
//! always 0 for incoming txes
|
||||
virtual uint64_t fee() const override;
|
||||
virtual uint64_t blockHeight() const override;
|
||||
virtual std::string description() const override;
|
||||
virtual std::set<uint32_t> subaddrIndex() const override;
|
||||
virtual uint32_t subaddrAccount() const override;
|
||||
virtual std::string label() const override;
|
||||
@@ -65,9 +67,11 @@ private:
|
||||
int m_direction;
|
||||
bool m_pending;
|
||||
bool m_failed;
|
||||
bool m_coinbase;
|
||||
uint64_t m_amount;
|
||||
uint64_t m_fee;
|
||||
uint64_t m_blockheight;
|
||||
std::string m_description;
|
||||
std::set<uint32_t> m_subaddrIndex; // always unique index for incoming transfers; can be multiple indices for outgoing transfers
|
||||
uint32_t m_subaddrAccount;
|
||||
std::string m_label;
|
||||
|
||||
@@ -791,11 +791,11 @@ bool WalletImpl::close(bool store)
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string WalletImpl::seed() const
|
||||
std::string WalletImpl::seed(const std::string& seed_offset) const
|
||||
{
|
||||
epee::wipeable_string seed;
|
||||
if (m_wallet)
|
||||
m_wallet->get_seed(seed);
|
||||
m_wallet->get_seed(seed, seed_offset);
|
||||
return std::string(seed.data(), seed.size()); // TODO
|
||||
}
|
||||
|
||||
@@ -839,6 +839,11 @@ bool WalletImpl::setPassword(const std::string &password)
|
||||
return status() == Status_Ok;
|
||||
}
|
||||
|
||||
const std::string& WalletImpl::getPassword() const
|
||||
{
|
||||
return m_password;
|
||||
}
|
||||
|
||||
bool WalletImpl::setDevicePin(const std::string &pin)
|
||||
{
|
||||
clearStatus();
|
||||
@@ -1168,7 +1173,7 @@ bool WalletImpl::submitTransaction(const string &fileName) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WalletImpl::exportKeyImages(const string &filename)
|
||||
bool WalletImpl::exportKeyImages(const string &filename, bool all)
|
||||
{
|
||||
if (m_wallet->watch_only())
|
||||
{
|
||||
@@ -1178,7 +1183,7 @@ bool WalletImpl::exportKeyImages(const string &filename)
|
||||
|
||||
try
|
||||
{
|
||||
if (!m_wallet->export_key_images(filename))
|
||||
if (!m_wallet->export_key_images(filename, all))
|
||||
{
|
||||
setStatusError(tr("failed to save file ") + filename);
|
||||
return false;
|
||||
@@ -1216,6 +1221,68 @@ bool WalletImpl::importKeyImages(const string &filename)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WalletImpl::exportOutputs(const string &filename, bool all)
|
||||
{
|
||||
if (m_wallet->key_on_device())
|
||||
{
|
||||
setStatusError(string(tr("Not supported on HW wallets.")) + filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
std::string data = m_wallet->export_outputs_to_str(all);
|
||||
bool r = m_wallet->save_to_file(filename, data);
|
||||
if (!r)
|
||||
{
|
||||
LOG_ERROR("Failed to save file " << filename);
|
||||
setStatusError(string(tr("Failed to save file: ")) + filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG_ERROR("Error exporting outputs: " << e.what());
|
||||
setStatusError(string(tr("Error exporting outputs: ")) + e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG_PRINT_L2("Outputs exported to " << filename);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WalletImpl::importOutputs(const string &filename)
|
||||
{
|
||||
if (m_wallet->key_on_device())
|
||||
{
|
||||
setStatusError(string(tr("Not supported on HW wallets.")) + filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string data;
|
||||
bool r = m_wallet->load_from_file(filename, data);
|
||||
if (!r)
|
||||
{
|
||||
LOG_ERROR("Failed to read file: " << filename);
|
||||
setStatusError(string(tr("Failed to read file: ")) + filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
size_t n_outputs = m_wallet->import_outputs_from_str(data);
|
||||
LOG_PRINT_L2(std::to_string(n_outputs) << " outputs imported");
|
||||
}
|
||||
catch (const std::exception &e)
|
||||
{
|
||||
LOG_ERROR("Failed to import outputs: " << e.what());
|
||||
setStatusError(string(tr("Failed to import outputs: ")) + e.what());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WalletImpl::addSubaddressAccount(const std::string& label)
|
||||
{
|
||||
m_wallet->add_subaddress_account(label);
|
||||
@@ -2104,6 +2171,11 @@ bool WalletImpl::watchOnly() const
|
||||
return m_wallet->watch_only();
|
||||
}
|
||||
|
||||
bool WalletImpl::isDeterministic() const
|
||||
{
|
||||
return m_wallet->is_deterministic();
|
||||
}
|
||||
|
||||
void WalletImpl::clearStatus() const
|
||||
{
|
||||
boost::lock_guard<boost::mutex> l(m_statusMutex);
|
||||
@@ -2283,6 +2355,11 @@ bool WalletImpl::parse_uri(const std::string &uri, std::string &address, std::st
|
||||
return m_wallet->parse_uri(uri, address, payment_id, amount, tx_description, recipient_name, unknown_parameters, error);
|
||||
}
|
||||
|
||||
std::string WalletImpl::make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const
|
||||
{
|
||||
return m_wallet->make_uri(address, payment_id, amount, tx_description, recipient_name, error);
|
||||
}
|
||||
|
||||
std::string WalletImpl::getDefaultDataDir() const
|
||||
{
|
||||
return tools::get_default_data_dir();
|
||||
@@ -2305,6 +2382,10 @@ bool WalletImpl::rescanSpent()
|
||||
return true;
|
||||
}
|
||||
|
||||
void WalletImpl::setOffline(bool offline)
|
||||
{
|
||||
m_wallet->set_offline(offline);
|
||||
}
|
||||
|
||||
void WalletImpl::hardForkInfo(uint8_t &version, uint64_t &earliest_height) const
|
||||
{
|
||||
|
||||
@@ -81,7 +81,7 @@ public:
|
||||
const std::string &device_name);
|
||||
Device getDeviceType() const override;
|
||||
bool close(bool store = true);
|
||||
std::string seed() const override;
|
||||
std::string seed(const std::string& seed_offset = "") const override;
|
||||
std::string getSeedLanguage() const override;
|
||||
void setSeedLanguage(const std::string &arg) override;
|
||||
// void setListener(Listener *) {}
|
||||
@@ -89,6 +89,7 @@ public:
|
||||
std::string errorString() const override;
|
||||
void statusWithErrorString(int& status, std::string& errorString) const override;
|
||||
bool setPassword(const std::string &password) override;
|
||||
const std::string& getPassword() const override;
|
||||
bool setDevicePin(const std::string &password) override;
|
||||
bool setDevicePassphrase(const std::string &password) override;
|
||||
std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const override;
|
||||
@@ -129,6 +130,7 @@ public:
|
||||
void setRecoveringFromDevice(bool recoveringFromDevice) override;
|
||||
void setSubaddressLookahead(uint32_t major, uint32_t minor) override;
|
||||
bool watchOnly() const override;
|
||||
bool isDeterministic() const override;
|
||||
bool rescanSpent() override;
|
||||
NetworkType nettype() const override {return static_cast<NetworkType>(m_wallet->nettype());}
|
||||
void hardForkInfo(uint8_t &version, uint64_t &earliest_height) const override;
|
||||
@@ -164,8 +166,10 @@ public:
|
||||
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 exportKeyImages(const std::string &filename, bool all = false) override;
|
||||
bool importKeyImages(const std::string &filename) override;
|
||||
bool exportOutputs(const std::string &filename, bool all = false) override;
|
||||
bool importOutputs(const std::string &filename) override;
|
||||
|
||||
virtual void disposeTransaction(PendingTransaction * t) override;
|
||||
virtual uint64_t estimateTransactionFee(const std::vector<std::pair<std::string, uint64_t>> &destinations,
|
||||
@@ -181,6 +185,8 @@ public:
|
||||
virtual bool setCacheAttribute(const std::string &key, const std::string &val) override;
|
||||
virtual std::string getCacheAttribute(const std::string &key) const override;
|
||||
|
||||
virtual void setOffline(bool offline) override;
|
||||
|
||||
virtual bool setUserNote(const std::string &txid, const std::string ¬e) override;
|
||||
virtual std::string getUserNote(const std::string &txid) const override;
|
||||
virtual std::string getTxKey(const std::string &txid) const override;
|
||||
@@ -198,6 +204,7 @@ public:
|
||||
virtual void startRefresh() override;
|
||||
virtual void pauseRefresh() override;
|
||||
virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error) override;
|
||||
virtual std::string make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const override;
|
||||
virtual std::string getDefaultDataDir() const override;
|
||||
virtual bool lightWalletLogin(bool &isNewWallet) const override;
|
||||
virtual bool lightWalletImportWalletRequest(std::string &payment_id, uint64_t &fee, bool &new_request, bool &request_fulfilled, std::string &payment_address, std::string &status) override;
|
||||
|
||||
@@ -182,9 +182,11 @@ struct TransactionInfo
|
||||
virtual int direction() const = 0;
|
||||
virtual bool isPending() const = 0;
|
||||
virtual bool isFailed() const = 0;
|
||||
virtual bool isCoinbase() const = 0;
|
||||
virtual uint64_t amount() const = 0;
|
||||
virtual uint64_t fee() const = 0;
|
||||
virtual uint64_t blockHeight() const = 0;
|
||||
virtual std::string description() const = 0;
|
||||
virtual std::set<uint32_t> subaddrIndex() const = 0;
|
||||
virtual uint32_t subaddrAccount() const = 0;
|
||||
virtual std::string label() const = 0;
|
||||
@@ -208,6 +210,7 @@ struct TransactionHistory
|
||||
virtual TransactionInfo * transaction(const std::string &id) const = 0;
|
||||
virtual std::vector<TransactionInfo*> getAll() const = 0;
|
||||
virtual void refresh() = 0;
|
||||
virtual void setTxNote(const std::string &txid, const std::string ¬e) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -250,6 +253,7 @@ struct AddressBook
|
||||
virtual std::vector<AddressBookRow*> getAll() const = 0;
|
||||
virtual bool addRow(const std::string &dst_addr , const std::string &payment_id, const std::string &description) = 0;
|
||||
virtual bool deleteRow(std::size_t rowId) = 0;
|
||||
virtual bool setDescription(std::size_t index, const std::string &description) = 0;
|
||||
virtual void refresh() = 0;
|
||||
virtual std::string errorString() const = 0;
|
||||
virtual int errorCode() const = 0;
|
||||
@@ -442,7 +446,7 @@ struct Wallet
|
||||
};
|
||||
|
||||
virtual ~Wallet() = 0;
|
||||
virtual std::string seed() const = 0;
|
||||
virtual std::string seed(const std::string& seed_offset = "") const = 0;
|
||||
virtual std::string getSeedLanguage() const = 0;
|
||||
virtual void setSeedLanguage(const std::string &arg) = 0;
|
||||
//! returns wallet status (Status_Ok | Status_Error)
|
||||
@@ -452,6 +456,7 @@ struct Wallet
|
||||
//! 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;
|
||||
virtual bool setPassword(const std::string &password) = 0;
|
||||
virtual const std::string& getPassword() const = 0;
|
||||
virtual bool setDevicePin(const std::string &pin) { (void)pin; return false; };
|
||||
virtual bool setDevicePassphrase(const std::string &passphrase) { (void)passphrase; return false; };
|
||||
virtual std::string address(uint32_t accountIndex = 0, uint32_t addressIndex = 0) const = 0;
|
||||
@@ -622,6 +627,12 @@ struct Wallet
|
||||
*/
|
||||
virtual bool watchOnly() const = 0;
|
||||
|
||||
/**
|
||||
* @brief isDeterministic - checks if wallet keys are deterministic
|
||||
* @return - true if deterministic
|
||||
*/
|
||||
virtual bool isDeterministic() const = 0;
|
||||
|
||||
/**
|
||||
* @brief blockChainHeight - returns current blockchain height
|
||||
* @return
|
||||
@@ -897,9 +908,10 @@ struct Wallet
|
||||
/*!
|
||||
* \brief exportKeyImages - exports key images to file
|
||||
* \param filename
|
||||
* \param all - export all key images or only those that have not yet been exported
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool exportKeyImages(const std::string &filename) = 0;
|
||||
virtual bool exportKeyImages(const std::string &filename, bool all = false) = 0;
|
||||
|
||||
/*!
|
||||
* \brief importKeyImages - imports key images from file
|
||||
@@ -908,6 +920,19 @@ struct Wallet
|
||||
*/
|
||||
virtual bool importKeyImages(const std::string &filename) = 0;
|
||||
|
||||
/*!
|
||||
* \brief importOutputs - exports outputs to file
|
||||
* \param filename
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool exportOutputs(const std::string &filename, bool all = false) = 0;
|
||||
|
||||
/*!
|
||||
* \brief importOutputs - imports outputs from file
|
||||
* \param filename
|
||||
* \return - true on success
|
||||
*/
|
||||
virtual bool importOutputs(const std::string &filename) = 0;
|
||||
|
||||
virtual TransactionHistory * history() = 0;
|
||||
virtual AddressBook * addressBook() = 0;
|
||||
@@ -995,6 +1020,7 @@ struct Wallet
|
||||
virtual bool verifyMessageWithPublicKey(const std::string &message, const std::string &publicKey, const std::string &signature) const = 0;
|
||||
|
||||
virtual bool parse_uri(const std::string &uri, std::string &address, std::string &payment_id, uint64_t &amount, std::string &tx_description, std::string &recipient_name, std::vector<std::string> &unknown_parameters, std::string &error) = 0;
|
||||
virtual std::string make_uri(const std::string &address, const std::string &payment_id, uint64_t amount, const std::string &tx_description, const std::string &recipient_name, std::string &error) const = 0;
|
||||
|
||||
virtual std::string getDefaultDataDir() const = 0;
|
||||
|
||||
@@ -1003,6 +1029,12 @@ struct Wallet
|
||||
* \return true on success
|
||||
*/
|
||||
virtual bool rescanSpent() = 0;
|
||||
|
||||
/*
|
||||
* \brief setOffline - toggle set offline on/off
|
||||
* \param offline - true/false
|
||||
*/
|
||||
virtual void setOffline(bool offline) = 0;
|
||||
|
||||
//! blackballs a set of outputs
|
||||
virtual bool blackballOutputs(const std::vector<std::string> &outputs, bool add) = 0;
|
||||
|
||||
+113
-39
@@ -142,6 +142,9 @@ using namespace cryptonote;
|
||||
|
||||
#define IGNORE_LONG_PAYMENT_ID_FROM_BLOCK_VERSION 12
|
||||
|
||||
#define DEFAULT_UNLOCK_TIME (CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE * DIFFICULTY_TARGET_V2)
|
||||
#define RECENT_SPEND_WINDOW (50 * DIFFICULTY_TARGET_V2)
|
||||
|
||||
static const std::string MULTISIG_SIGNATURE_MAGIC = "SigMultisigPkV1";
|
||||
static const std::string MULTISIG_EXTRA_INFO_MAGIC = "MultisigxV1";
|
||||
|
||||
@@ -1022,7 +1025,13 @@ gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets, double shap
|
||||
end = rct_offsets.data() + rct_offsets.size() - CRYPTONOTE_DEFAULT_TX_SPENDABLE_AGE;
|
||||
num_rct_outputs = *(end - 1);
|
||||
THROW_WALLET_EXCEPTION_IF(num_rct_outputs == 0, error::wallet_internal_error, "No rct outputs");
|
||||
THROW_WALLET_EXCEPTION_IF(outputs_to_consider == 0, error::wallet_internal_error, "No rct outputs to consider");
|
||||
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / outputs_to_consider; // this assumes constant target over the whole rct range
|
||||
if (average_output_time == 0) {
|
||||
// TODO: apply this to all cases; do so alongside a hard fork, where all clients will update at the same time, preventing anonymity puddle formation
|
||||
average_output_time = DIFFICULTY_TARGET_V2 * blocks_to_consider / static_cast<double>(outputs_to_consider);
|
||||
}
|
||||
THROW_WALLET_EXCEPTION_IF(average_output_time == 0, error::wallet_internal_error, "Average seconds per output cannot be 0.");
|
||||
};
|
||||
|
||||
gamma_picker::gamma_picker(const std::vector<uint64_t> &rct_offsets): gamma_picker(rct_offsets, GAMMA_SHAPE, GAMMA_SCALE) {}
|
||||
@@ -1031,6 +1040,34 @@ uint64_t gamma_picker::pick()
|
||||
{
|
||||
double x = gamma(engine);
|
||||
x = exp(x);
|
||||
|
||||
if (x > DEFAULT_UNLOCK_TIME)
|
||||
{
|
||||
// We are trying to select an output from the chain that appeared 'x' seconds before the
|
||||
// current chain tip, where 'x' is selected from the gamma distribution recommended in Miller et al.
|
||||
// (https://arxiv.org/pdf/1704.04299/).
|
||||
// Our method is to get the average time delta between outputs in the recent past, estimate the number of
|
||||
// outputs 'n' that would have appeared between 'chain_tip - x' and 'chain_tip', select the real output at
|
||||
// 'current_num_outputs - n', then randomly select an output from the block where that output appears.
|
||||
// Source code to paper: https://github.com/maltemoeser/moneropaper
|
||||
//
|
||||
// Due to the 'default spendable age' mechanic in Monero, 'current_num_outputs' only contains
|
||||
// currently *unlocked* outputs, which means the earliest output that can be selected is not at the chain tip!
|
||||
// Therefore, we must offset 'x' so it matches up with the timing of the outputs being considered. We do
|
||||
// this by saying if 'x` equals the expected age of the first unlocked output (compared to the current
|
||||
// chain tip - i.e. DEFAULT_UNLOCK_TIME), then select the first unlocked output.
|
||||
x -= DEFAULT_UNLOCK_TIME;
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the spent time suggested by the gamma is less than the unlock time, that means the gamma is suggesting an output
|
||||
// that is no longer feasible to be spent (possible since the gamma was constructed when consensus rules did not enforce the
|
||||
// lock time). The assumption made in this code is that an output expected spent quicker than the unlock time would likely
|
||||
// be spent within RECENT_SPEND_WINDOW after allowed. So it returns an output that falls between 0 and the RECENT_SPEND_WINDOW.
|
||||
// The RECENT_SPEND_WINDOW was determined with empirical analysis of observed data.
|
||||
x = crypto::rand_idx(static_cast<uint64_t>(RECENT_SPEND_WINDOW));
|
||||
}
|
||||
|
||||
uint64_t output_index = x / average_output_time;
|
||||
if (output_index >= num_rct_outputs)
|
||||
return std::numeric_limits<uint64_t>::max(); // bad pick
|
||||
@@ -1215,6 +1252,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std
|
||||
|
||||
wallet2::~wallet2()
|
||||
{
|
||||
deinit();
|
||||
}
|
||||
|
||||
bool wallet2::has_testnet_option(const boost::program_options::variables_map& vm)
|
||||
@@ -1858,7 +1896,7 @@ void wallet2::cache_tx_data(const cryptonote::transaction& tx, const crypto::has
|
||||
const bool is_miner = tx.vin.size() == 1 && tx.vin[0].type() == typeid(cryptonote::txin_gen);
|
||||
if (!is_miner || m_refresh_type != RefreshType::RefreshNoCoinbase)
|
||||
{
|
||||
const size_t rec_size = is_miner && m_refresh_type == RefreshType::RefreshOptimizeCoinbase ? 1 : tx.vout.size();
|
||||
const size_t rec_size = (is_miner && m_refresh_type == RefreshType::RefreshOptimizeCoinbase && tx.version < 2) ? 1 : tx.vout.size();
|
||||
if (!tx.vout.empty())
|
||||
{
|
||||
// if tx.vout is not empty, we loop through all tx pubkeys
|
||||
@@ -2007,7 +2045,7 @@ void wallet2::process_new_transaction(const crypto::hash &txid, const cryptonote
|
||||
{
|
||||
// assume coinbase isn't for us
|
||||
}
|
||||
else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase)
|
||||
else if (miner_tx && m_refresh_type == RefreshOptimizeCoinbase && tx.version < 2)
|
||||
{
|
||||
check_acc_out_precomp_once(tx.vout[0], derivation, additional_derivations, 0, is_out_data_ptr, tx_scan_info[0], output_found[0]);
|
||||
THROW_WALLET_EXCEPTION_IF(tx_scan_info[0].error, error::acc_outs_lookup_error, tx, tx_pub_key, m_account.get_keys());
|
||||
@@ -2734,9 +2772,8 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
|
||||
{
|
||||
if (tx_cache_data[i].empty())
|
||||
continue;
|
||||
tpool.submit(&waiter, [&hwdev, &gender, &tx_cache_data, i]() {
|
||||
tpool.submit(&waiter, [&gender, &tx_cache_data, i]() {
|
||||
auto &slot = tx_cache_data[i];
|
||||
boost::unique_lock<hw::device> hwdev_lock(hwdev);
|
||||
for (auto &iod: slot.primary)
|
||||
gender(iod);
|
||||
for (auto &iod: slot.additional)
|
||||
@@ -2779,8 +2816,9 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry
|
||||
if (m_refresh_type != RefreshType::RefreshNoCoinbase)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(txidx >= tx_cache_data.size(), error::wallet_internal_error, "txidx out of range");
|
||||
const size_t n_vouts = m_refresh_type == RefreshType::RefreshOptimizeCoinbase ? 1 : parsed_blocks[i].block.miner_tx.vout.size();
|
||||
tpool.submit(&waiter, [&, i, n_vouts, txidx](){ geniod(parsed_blocks[i].block.miner_tx, n_vouts, txidx); }, true);
|
||||
const cryptonote::transaction& tx = parsed_blocks[i].block.miner_tx;
|
||||
const size_t n_vouts = (m_refresh_type == RefreshType::RefreshOptimizeCoinbase && tx.version < 2) ? 1 : tx.vout.size();
|
||||
tpool.submit(&waiter, [&, i, n_vouts, txidx](){ geniod(tx, n_vouts, txidx); }, true);
|
||||
}
|
||||
++txidx;
|
||||
for (size_t j = 0; j < parsed_blocks[i].txes.size(); ++j)
|
||||
@@ -3692,9 +3730,11 @@ void wallet2::detach_blockchain(uint64_t height, std::map<std::pair<uint64_t, ui
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
bool wallet2::deinit()
|
||||
{
|
||||
m_is_initialized=false;
|
||||
unlock_keys_file();
|
||||
m_account.deinit();
|
||||
if(m_is_initialized) {
|
||||
m_is_initialized = false;
|
||||
unlock_keys_file();
|
||||
m_account.deinit();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
@@ -4364,7 +4404,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st
|
||||
|
||||
account_public_address device_account_public_address;
|
||||
THROW_WALLET_EXCEPTION_IF(!hwdev.get_public_address(device_account_public_address), error::wallet_internal_error, "Cannot get a device address");
|
||||
THROW_WALLET_EXCEPTION_IF(device_account_public_address != m_account.get_keys().m_account_address, error::wallet_internal_error, "Device wallet does not match wallet address. "
|
||||
THROW_WALLET_EXCEPTION_IF(device_account_public_address != m_account.get_keys().m_account_address, error::wallet_internal_error, "Device wallet does not match wallet address. If the device uses the passphrase feature, please check whether the passphrase was entered correctly (it may have been misspelled - different passphrases generate different wallets, passphrase is case-sensitive). "
|
||||
"Device address: " + cryptonote::get_account_address_as_str(m_nettype, false, device_account_public_address) +
|
||||
", wallet address: " + m_account.get_public_address_str(m_nettype));
|
||||
LOG_PRINT_L0("Device inited...");
|
||||
@@ -8583,7 +8623,8 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>>
|
||||
if (req.outputs[i].index == td.m_global_output_index)
|
||||
if (daemon_resp.outs[i].key == boost::get<txout_to_key>(td.m_tx.vout[td.m_internal_output_index].target).key)
|
||||
if (daemon_resp.outs[i].mask == mask)
|
||||
real_out_found = true;
|
||||
if (daemon_resp.outs[i].unlocked)
|
||||
real_out_found = true;
|
||||
}
|
||||
THROW_WALLET_EXCEPTION_IF(!real_out_found, error::wallet_internal_error,
|
||||
"Daemon response did not include the requested real output");
|
||||
@@ -9768,13 +9809,18 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
|
||||
TX() : weight(0), needed_fee(0) {}
|
||||
|
||||
void add(const cryptonote::tx_destination_entry &de, uint64_t amount, unsigned int original_output_index, bool merge_destinations) {
|
||||
/* Add an output to the transaction.
|
||||
* Returns True if the output was added, False if there are no more available output slots.
|
||||
*/
|
||||
bool add(const cryptonote::tx_destination_entry &de, uint64_t amount, unsigned int original_output_index, bool merge_destinations, size_t max_dsts) {
|
||||
if (merge_destinations)
|
||||
{
|
||||
std::vector<cryptonote::tx_destination_entry>::iterator i;
|
||||
i = std::find_if(dsts.begin(), dsts.end(), [&](const cryptonote::tx_destination_entry &d) { return !memcmp (&d.addr, &de.addr, sizeof(de.addr)); });
|
||||
if (i == dsts.end())
|
||||
{
|
||||
if (dsts.size() >= max_dsts)
|
||||
return false;
|
||||
dsts.push_back(de);
|
||||
i = dsts.end() - 1;
|
||||
i->amount = 0;
|
||||
@@ -9787,12 +9833,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
std::string("original_output_index too large: ") + std::to_string(original_output_index) + " > " + std::to_string(dsts.size()));
|
||||
if (original_output_index == dsts.size())
|
||||
{
|
||||
if (dsts.size() >= max_dsts)
|
||||
return false;
|
||||
dsts.push_back(de);
|
||||
dsts.back().amount = 0;
|
||||
}
|
||||
THROW_WALLET_EXCEPTION_IF(memcmp(&dsts[original_output_index].addr, &de.addr, sizeof(de.addr)), error::wallet_internal_error, "Mismatched destination address");
|
||||
dsts[original_output_index].amount += amount;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
std::vector<TX> txes;
|
||||
@@ -10062,6 +10111,7 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
// clear any fake outs we'd already gathered, since we'll need a new set
|
||||
outs.clear();
|
||||
|
||||
bool out_slots_exhausted = false;
|
||||
if (adding_fee)
|
||||
{
|
||||
LOG_PRINT_L2("We need more fee, adding it to fee");
|
||||
@@ -10074,20 +10124,32 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
// we can fully pay that destination
|
||||
LOG_PRINT_L2("We can fully pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) <<
|
||||
" for " << print_money(dsts[0].amount));
|
||||
tx.add(dsts[0], dsts[0].amount, original_output_index, m_merge_destinations);
|
||||
if (!tx.add(dsts[0], dsts[0].amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1))
|
||||
{
|
||||
LOG_PRINT_L2("Didn't pay: ran out of output slots");
|
||||
out_slots_exhausted = true;
|
||||
break;
|
||||
}
|
||||
available_amount -= dsts[0].amount;
|
||||
dsts[0].amount = 0;
|
||||
pop_index(dsts, 0);
|
||||
++original_output_index;
|
||||
}
|
||||
|
||||
if (available_amount > 0 && !dsts.empty() && estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag) < TX_WEIGHT_TARGET(upper_transaction_weight_limit)) {
|
||||
if (!out_slots_exhausted && available_amount > 0 && !dsts.empty() && estimate_tx_weight(use_rct, tx.selected_transfers.size(), fake_outs_count, tx.dsts.size()+1, extra.size(), bulletproof, clsag) < TX_WEIGHT_TARGET(upper_transaction_weight_limit)) {
|
||||
// we can partially fill that destination
|
||||
LOG_PRINT_L2("We can partially pay " << get_account_address_as_str(m_nettype, dsts[0].is_subaddress, dsts[0].addr) <<
|
||||
" for " << print_money(available_amount) << "/" << print_money(dsts[0].amount));
|
||||
tx.add(dsts[0], available_amount, original_output_index, m_merge_destinations);
|
||||
dsts[0].amount -= available_amount;
|
||||
available_amount = 0;
|
||||
if (tx.add(dsts[0], available_amount, original_output_index, m_merge_destinations, BULLETPROOF_MAX_OUTPUTS-1))
|
||||
{
|
||||
dsts[0].amount -= available_amount;
|
||||
available_amount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG_PRINT_L2("Didn't pay: ran out of output slots");
|
||||
out_slots_exhausted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10095,8 +10157,15 @@ std::vector<wallet2::pending_tx> wallet2::create_transactions_2(std::vector<cryp
|
||||
LOG_PRINT_L2("Considering whether to create a tx now, " << tx.selected_transfers.size() << " inputs, tx limit "
|
||||
<< upper_transaction_weight_limit);
|
||||
bool try_tx = false;
|
||||
|
||||
// If the new transaction is full, create it and start a new one
|
||||
if (out_slots_exhausted)
|
||||
{
|
||||
LOG_PRINT_L2("Transaction is full, will create it and start a new tx");
|
||||
try_tx = true;
|
||||
}
|
||||
// if we have preferred picks, but haven't yet used all of them, continue
|
||||
if (preferred_inputs.empty())
|
||||
else if (preferred_inputs.empty())
|
||||
{
|
||||
if (adding_fee)
|
||||
{
|
||||
@@ -14100,15 +14169,15 @@ void wallet2::hash_m_transfer(const transfer_details & transfer, crypto::hash &h
|
||||
KECCAK_CTX state;
|
||||
keccak_init(&state);
|
||||
keccak_update(&state, (const uint8_t *) transfer.m_txid.data, sizeof(transfer.m_txid.data));
|
||||
keccak_update(&state, (const uint8_t *) transfer.m_internal_output_index, sizeof(transfer.m_internal_output_index));
|
||||
keccak_update(&state, (const uint8_t *) transfer.m_global_output_index, sizeof(transfer.m_global_output_index));
|
||||
keccak_update(&state, (const uint8_t *) transfer.m_amount, sizeof(transfer.m_amount));
|
||||
keccak_update(&state, (const uint8_t *) &transfer.m_internal_output_index, sizeof(transfer.m_internal_output_index));
|
||||
keccak_update(&state, (const uint8_t *) &transfer.m_global_output_index, sizeof(transfer.m_global_output_index));
|
||||
keccak_update(&state, (const uint8_t *) &transfer.m_amount, sizeof(transfer.m_amount));
|
||||
keccak_finish(&state, (uint8_t *) hash.data);
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const
|
||||
uint64_t wallet2::hash_m_transfers(boost::optional<uint64_t> transfer_height, crypto::hash &hash) const
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(transfer_height > (int64_t)m_transfers.size(), "Hash height is greater than number of transfers");
|
||||
CHECK_AND_ASSERT_THROW_MES(!transfer_height || *transfer_height <= m_transfers.size(), "Hash height is greater than number of transfers");
|
||||
|
||||
KECCAK_CTX state;
|
||||
crypto::hash tmp_hash{};
|
||||
@@ -14116,12 +14185,12 @@ uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash)
|
||||
|
||||
keccak_init(&state);
|
||||
for(const transfer_details & transfer : m_transfers){
|
||||
if (transfer_height >= 0 && current_height >= (uint64_t)transfer_height){
|
||||
if (transfer_height && current_height >= *transfer_height){
|
||||
break;
|
||||
}
|
||||
|
||||
hash_m_transfer(transfer, tmp_hash);
|
||||
keccak_update(&state, (const uint8_t *) transfer.m_block_height, sizeof(transfer.m_block_height));
|
||||
keccak_update(&state, (const uint8_t *) &transfer.m_block_height, sizeof(transfer.m_block_height));
|
||||
keccak_update(&state, (const uint8_t *) tmp_hash.data, sizeof(tmp_hash.data));
|
||||
current_height += 1;
|
||||
}
|
||||
@@ -14133,23 +14202,28 @@ uint64_t wallet2::hash_m_transfers(int64_t transfer_height, crypto::hash &hash)
|
||||
void wallet2::finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash)
|
||||
{
|
||||
// Compute hash of m_transfers, if differs there had to be BC reorg.
|
||||
crypto::hash new_transfers_hash{};
|
||||
hash_m_transfers((int64_t) transfer_height, new_transfers_hash);
|
||||
if (transfer_height <= m_transfers.size()) {
|
||||
crypto::hash new_transfers_hash{};
|
||||
hash_m_transfers(transfer_height, new_transfers_hash);
|
||||
|
||||
if (new_transfers_hash != hash)
|
||||
{
|
||||
// Soft-Reset to avoid inconsistency in case of BC reorg.
|
||||
clear_soft(false); // keep_key_images works only with soft reset.
|
||||
THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Transfers changed during rescan, soft or hard rescan is needed");
|
||||
if (new_transfers_hash == hash) {
|
||||
// Restore key images in m_transfers from m_key_images
|
||||
for(auto it = m_key_images.begin(); it != m_key_images.end(); it++)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(it->second >= m_transfers.size(),
|
||||
error::wallet_internal_error,
|
||||
"Key images cache contains illegal transfer offset");
|
||||
m_transfers[it->second].m_key_image = it->first;
|
||||
m_transfers[it->second].m_key_image_known = true;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Restore key images in m_transfers from m_key_images
|
||||
for(auto it = m_key_images.begin(); it != m_key_images.end(); it++)
|
||||
{
|
||||
THROW_WALLET_EXCEPTION_IF(it->second >= m_transfers.size(), error::wallet_internal_error, "Key images cache contains illegal transfer offset");
|
||||
m_transfers[it->second].m_key_image = it->first;
|
||||
m_transfers[it->second].m_key_image_known = true;
|
||||
}
|
||||
// Soft-Reset to avoid inconsistency in case of BC reorg.
|
||||
clear_soft(false); // keep_key_images works only with soft reset.
|
||||
THROW_WALLET_EXCEPTION_IF(true, error::wallet_internal_error, "Transfers changed during rescan, soft or hard rescan is needed");
|
||||
}
|
||||
//----------------------------------------------------------------------------------------------------
|
||||
uint64_t wallet2::get_bytes_sent() const
|
||||
|
||||
@@ -1542,7 +1542,7 @@ private:
|
||||
|
||||
bool is_tx_spendtime_unlocked(uint64_t unlock_time, uint64_t block_height);
|
||||
void hash_m_transfer(const transfer_details & transfer, crypto::hash &hash) const;
|
||||
uint64_t hash_m_transfers(int64_t transfer_height, crypto::hash &hash) const;
|
||||
uint64_t hash_m_transfers(boost::optional<uint64_t> transfer_height, crypto::hash &hash) const;
|
||||
void finish_rescan_bc_keep_key_images(uint64_t transfer_height, const crypto::hash &hash);
|
||||
void enable_dns(bool enable) { m_use_dns = enable; }
|
||||
void set_offline(bool offline = true);
|
||||
|
||||
@@ -762,6 +762,90 @@ namespace tools
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_freeze(const wallet_rpc::COMMAND_RPC_FREEZE::request& req, wallet_rpc::COMMAND_RPC_FREEZE::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
||||
{
|
||||
if (!m_wallet) return not_open(er);
|
||||
try
|
||||
{
|
||||
if (req.key_image.empty())
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
|
||||
er.message = std::string("Must specify key image to freeze");
|
||||
return false;
|
||||
}
|
||||
crypto::key_image ki;
|
||||
if (!epee::string_tools::hex_to_pod(req.key_image, ki))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||
er.message = "failed to parse key image";
|
||||
return false;
|
||||
}
|
||||
m_wallet->freeze(ki);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_thaw(const wallet_rpc::COMMAND_RPC_THAW::request& req, wallet_rpc::COMMAND_RPC_THAW::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
||||
{
|
||||
if (!m_wallet) return not_open(er);
|
||||
try
|
||||
{
|
||||
if (req.key_image.empty())
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
|
||||
er.message = std::string("Must specify key image to thaw");
|
||||
return false;
|
||||
}
|
||||
crypto::key_image ki;
|
||||
if (!epee::string_tools::hex_to_pod(req.key_image, ki))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||
er.message = "failed to parse key image";
|
||||
return false;
|
||||
}
|
||||
m_wallet->thaw(ki);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::on_frozen(const wallet_rpc::COMMAND_RPC_FROZEN::request& req, wallet_rpc::COMMAND_RPC_FROZEN::response& res, epee::json_rpc::error& er, const connection_context *ctx)
|
||||
{
|
||||
if (!m_wallet) return not_open(er);
|
||||
try
|
||||
{
|
||||
if (req.key_image.empty())
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR;
|
||||
er.message = std::string("Must specify key image to check if frozen");
|
||||
return false;
|
||||
}
|
||||
crypto::key_image ki;
|
||||
if (!epee::string_tools::hex_to_pod(req.key_image, ki))
|
||||
{
|
||||
er.code = WALLET_RPC_ERROR_CODE_WRONG_KEY_IMAGE;
|
||||
er.message = "failed to parse key image";
|
||||
return false;
|
||||
}
|
||||
res.frozen = m_wallet->frozen(ki);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
handle_rpc_exception(std::current_exception(), er, WALLET_RPC_ERROR_CODE_UNKNOWN_ERROR);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
bool wallet_rpc_server::validate_transfer(const std::list<wallet_rpc::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er)
|
||||
{
|
||||
crypto::hash8 integrated_payment_id = crypto::null_hash8;
|
||||
@@ -877,10 +961,10 @@ namespace tools
|
||||
return amount;
|
||||
}
|
||||
//------------------------------------------------------------------------------------------------------------------------------
|
||||
template<typename Ts, typename Tu>
|
||||
template<typename Ts, typename Tu, typename Tk>
|
||||
bool wallet_rpc_server::fill_response(std::vector<tools::wallet2::pending_tx> &ptx_vector,
|
||||
bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, Tu &weight, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay,
|
||||
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, epee::json_rpc::error &er)
|
||||
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, Tk &spent_key_images, epee::json_rpc::error &er)
|
||||
{
|
||||
for (const auto & ptx : ptx_vector)
|
||||
{
|
||||
@@ -895,6 +979,17 @@ namespace tools
|
||||
fill(amount, total_amount(ptx));
|
||||
fill(fee, ptx.fee);
|
||||
fill(weight, cryptonote::get_transaction_weight(ptx.tx));
|
||||
|
||||
// add spent key images
|
||||
tools::wallet_rpc::key_image_list key_image_list;
|
||||
bool all_are_txin_to_key = std::all_of(ptx.tx.vin.begin(), ptx.tx.vin.end(), [&](const cryptonote::txin_v& s_e) -> bool
|
||||
{
|
||||
CHECKED_GET_SPECIFIC_VARIANT(s_e, const cryptonote::txin_to_key, in, false);
|
||||
key_image_list.key_images.push_back(epee::string_tools::pod_to_hex(in.k_image));
|
||||
return true;
|
||||
});
|
||||
THROW_WALLET_EXCEPTION_IF(!all_are_txin_to_key, error::unexpected_txin_type, ptx.tx);
|
||||
fill(spent_key_images, key_image_list);
|
||||
}
|
||||
|
||||
if (m_wallet->multisig())
|
||||
@@ -981,7 +1076,7 @@ namespace tools
|
||||
}
|
||||
|
||||
return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
|
||||
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er);
|
||||
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, res.spent_key_images, er);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -1027,7 +1122,7 @@ namespace tools
|
||||
}
|
||||
|
||||
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
|
||||
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er);
|
||||
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -1390,7 +1485,7 @@ namespace tools
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_unmixable_sweep_transactions();
|
||||
|
||||
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
|
||||
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er);
|
||||
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -1448,7 +1543,7 @@ namespace tools
|
||||
std::vector<wallet2::pending_tx> ptx_vector = m_wallet->create_transactions_all(req.below_amount, dsts[0].addr, dsts[0].is_subaddress, req.outputs, mixin, req.unlock_time, priority, extra, req.account_index, subaddr_indices);
|
||||
|
||||
return fill_response(ptx_vector, req.get_tx_keys, res.tx_key_list, res.amount_list, res.fee_list, res.weight_list, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
|
||||
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, er);
|
||||
res.tx_hash_list, req.get_tx_hex, res.tx_blob_list, req.get_tx_metadata, res.tx_metadata_list, res.spent_key_images_list, er);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -1523,7 +1618,7 @@ namespace tools
|
||||
}
|
||||
|
||||
return fill_response(ptx_vector, req.get_tx_key, res.tx_key, res.amount, res.fee, res.weight, res.multisig_txset, res.unsigned_txset, req.do_not_relay,
|
||||
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, er);
|
||||
res.tx_hash, req.get_tx_hex, res.tx_blob, req.get_tx_metadata, res.tx_metadata, res.spent_key_images, er);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
|
||||
@@ -84,6 +84,9 @@ namespace tools
|
||||
MAP_JON_RPC_WE("set_account_tag_description", on_set_account_tag_description, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION)
|
||||
MAP_JON_RPC_WE("get_height", on_getheight, wallet_rpc::COMMAND_RPC_GET_HEIGHT)
|
||||
MAP_JON_RPC_WE("getheight", on_getheight, wallet_rpc::COMMAND_RPC_GET_HEIGHT)
|
||||
MAP_JON_RPC_WE("freeze", on_freeze, wallet_rpc::COMMAND_RPC_FREEZE)
|
||||
MAP_JON_RPC_WE("thaw", on_thaw, wallet_rpc::COMMAND_RPC_THAW)
|
||||
MAP_JON_RPC_WE("frozen", on_frozen, wallet_rpc::COMMAND_RPC_FROZEN)
|
||||
MAP_JON_RPC_WE("transfer", on_transfer, wallet_rpc::COMMAND_RPC_TRANSFER)
|
||||
MAP_JON_RPC_WE("transfer_split", on_transfer_split, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT)
|
||||
MAP_JON_RPC_WE("sign_transfer", on_sign_transfer, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER)
|
||||
@@ -173,6 +176,9 @@ namespace tools
|
||||
bool on_untag_accounts(const wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::request& req, wallet_rpc::COMMAND_RPC_UNTAG_ACCOUNTS::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_set_account_tag_description(const wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::request& req, wallet_rpc::COMMAND_RPC_SET_ACCOUNT_TAG_DESCRIPTION::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_getheight(const wallet_rpc::COMMAND_RPC_GET_HEIGHT::request& req, wallet_rpc::COMMAND_RPC_GET_HEIGHT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_freeze(const wallet_rpc::COMMAND_RPC_FREEZE::request& req, wallet_rpc::COMMAND_RPC_FREEZE::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_thaw(const wallet_rpc::COMMAND_RPC_THAW::request& req, wallet_rpc::COMMAND_RPC_THAW::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_frozen(const wallet_rpc::COMMAND_RPC_FROZEN::request& req, wallet_rpc::COMMAND_RPC_FROZEN::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_transfer(const wallet_rpc::COMMAND_RPC_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_transfer_split(const wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::request& req, wallet_rpc::COMMAND_RPC_TRANSFER_SPLIT::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
bool on_sign_transfer(const wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::request& req, wallet_rpc::COMMAND_RPC_SIGN_TRANSFER::response& res, epee::json_rpc::error& er, const connection_context *ctx = NULL);
|
||||
@@ -255,10 +261,10 @@ namespace tools
|
||||
bool not_open(epee::json_rpc::error& er);
|
||||
void handle_rpc_exception(const std::exception_ptr& e, epee::json_rpc::error& er, int default_error_code);
|
||||
|
||||
template<typename Ts, typename Tu>
|
||||
template<typename Ts, typename Tu, typename Tk>
|
||||
bool fill_response(std::vector<tools::wallet2::pending_tx> &ptx_vector,
|
||||
bool get_tx_key, Ts& tx_key, Tu &amount, Tu &fee, Tu &weight, std::string &multisig_txset, std::string &unsigned_txset, bool do_not_relay,
|
||||
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, epee::json_rpc::error &er);
|
||||
Ts &tx_hash, bool get_tx_hex, Ts &tx_blob, bool get_tx_metadata, Ts &tx_metadata, Tk &spent_key_images, epee::json_rpc::error &er);
|
||||
|
||||
bool validate_transfer(const std::list<wallet_rpc::transfer_destination>& destinations, const std::string& payment_id, std::vector<cryptonote::tx_destination_entry>& dsts, std::vector<uint8_t>& extra, bool at_least_one_destination, epee::json_rpc::error& er);
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
// advance which version they will stop working with
|
||||
// Don't go over 32767 for any of these
|
||||
#define WALLET_RPC_VERSION_MAJOR 1
|
||||
#define WALLET_RPC_VERSION_MINOR 20
|
||||
#define WALLET_RPC_VERSION_MINOR 22
|
||||
#define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor))
|
||||
#define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR)
|
||||
namespace tools
|
||||
@@ -456,6 +456,78 @@ namespace wallet_rpc
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_FREEZE
|
||||
{
|
||||
struct request_t
|
||||
{
|
||||
std::string key_image;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(key_image)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_THAW
|
||||
{
|
||||
struct request_t
|
||||
{
|
||||
std::string key_image;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(key_image)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t
|
||||
{
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_FROZEN
|
||||
{
|
||||
struct request_t
|
||||
{
|
||||
std::string key_image;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(key_image)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<request_t> request;
|
||||
|
||||
struct response_t
|
||||
{
|
||||
bool frozen;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(frozen)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
};
|
||||
|
||||
struct key_image_list
|
||||
{
|
||||
std::list<std::string> key_images;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(key_images)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
|
||||
struct COMMAND_RPC_TRANSFER
|
||||
{
|
||||
struct request_t
|
||||
@@ -499,6 +571,7 @@ namespace wallet_rpc
|
||||
std::string tx_metadata;
|
||||
std::string multisig_txset;
|
||||
std::string unsigned_txset;
|
||||
key_image_list spent_key_images;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tx_hash)
|
||||
@@ -510,6 +583,7 @@ namespace wallet_rpc
|
||||
KV_SERIALIZE(tx_metadata)
|
||||
KV_SERIALIZE(multisig_txset)
|
||||
KV_SERIALIZE(unsigned_txset)
|
||||
KV_SERIALIZE(spent_key_images)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
@@ -567,6 +641,7 @@ namespace wallet_rpc
|
||||
std::list<std::string> tx_metadata_list;
|
||||
std::string multisig_txset;
|
||||
std::string unsigned_txset;
|
||||
std::list<key_image_list> spent_key_images_list;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tx_hash_list)
|
||||
@@ -578,6 +653,7 @@ namespace wallet_rpc
|
||||
KV_SERIALIZE(tx_metadata_list)
|
||||
KV_SERIALIZE(multisig_txset)
|
||||
KV_SERIALIZE(unsigned_txset)
|
||||
KV_SERIALIZE(spent_key_images_list)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
@@ -742,6 +818,7 @@ namespace wallet_rpc
|
||||
std::list<std::string> tx_metadata_list;
|
||||
std::string multisig_txset;
|
||||
std::string unsigned_txset;
|
||||
std::list<key_image_list> spent_key_images_list;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tx_hash_list)
|
||||
@@ -753,6 +830,7 @@ namespace wallet_rpc
|
||||
KV_SERIALIZE(tx_metadata_list)
|
||||
KV_SERIALIZE(multisig_txset)
|
||||
KV_SERIALIZE(unsigned_txset)
|
||||
KV_SERIALIZE(spent_key_images_list)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
@@ -816,6 +894,7 @@ namespace wallet_rpc
|
||||
std::list<std::string> tx_metadata_list;
|
||||
std::string multisig_txset;
|
||||
std::string unsigned_txset;
|
||||
std::list<key_image_list> spent_key_images_list;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tx_hash_list)
|
||||
@@ -827,6 +906,7 @@ namespace wallet_rpc
|
||||
KV_SERIALIZE(tx_metadata_list)
|
||||
KV_SERIALIZE(multisig_txset)
|
||||
KV_SERIALIZE(unsigned_txset)
|
||||
KV_SERIALIZE(spent_key_images_list)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
@@ -875,6 +955,7 @@ namespace wallet_rpc
|
||||
std::string tx_metadata;
|
||||
std::string multisig_txset;
|
||||
std::string unsigned_txset;
|
||||
key_image_list spent_key_images;
|
||||
|
||||
BEGIN_KV_SERIALIZE_MAP()
|
||||
KV_SERIALIZE(tx_hash)
|
||||
@@ -886,6 +967,7 @@ namespace wallet_rpc
|
||||
KV_SERIALIZE(tx_metadata)
|
||||
KV_SERIALIZE(multisig_txset)
|
||||
KV_SERIALIZE(unsigned_txset)
|
||||
KV_SERIALIZE(spent_key_images)
|
||||
END_KV_SERIALIZE_MAP()
|
||||
};
|
||||
typedef epee::misc_utils::struct_init<response_t> response;
|
||||
|
||||
@@ -111,8 +111,7 @@ TEST(boosted_tcp_server, worker_threads_are_exception_resistant)
|
||||
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mtx);
|
||||
ASSERT_NE(boost::cv_status::timeout, cond.wait_for(lock, boost::chrono::seconds(5)));
|
||||
ASSERT_EQ(4, counter);
|
||||
ASSERT_TRUE(cond.wait_for(lock, boost::chrono::seconds(5), [&counter]{ return counter == 4; }));
|
||||
}
|
||||
|
||||
// Check if threads are alive
|
||||
@@ -125,8 +124,7 @@ TEST(boosted_tcp_server, worker_threads_are_exception_resistant)
|
||||
|
||||
{
|
||||
boost::unique_lock<boost::mutex> lock(mtx);
|
||||
ASSERT_NE(boost::cv_status::timeout, cond.wait_for(lock, boost::chrono::seconds(5)));
|
||||
ASSERT_EQ(4, counter);
|
||||
ASSERT_TRUE(cond.wait_for(lock, boost::chrono::seconds(5), [&counter]{ return counter == 4; }));
|
||||
}
|
||||
|
||||
srv.send_stop_signal();
|
||||
|
||||
@@ -1503,6 +1503,7 @@ TEST(NetUtils, NetworkAddress)
|
||||
constexpr static epee::net_utils::address_type get_type_id() noexcept { return epee::net_utils::address_type(-1); }
|
||||
constexpr static epee::net_utils::zone get_zone() noexcept { return epee::net_utils::zone::invalid; }
|
||||
constexpr static bool is_blockable() noexcept { return false; }
|
||||
constexpr static uint16_t port() { return 0; }
|
||||
};
|
||||
|
||||
const epee::net_utils::network_address empty;
|
||||
|
||||
@@ -352,7 +352,7 @@ TEST(cryptonote_protocol_handler, race_condition)
|
||||
acceptor.set_option(boost::asio::ip::tcp::acceptor::reuse_address(true));
|
||||
acceptor.bind(endpoint, ec);
|
||||
EXPECT_EQ(ec.value(), 0);
|
||||
acceptor.listen(boost::asio::socket_base::max_listen_connections, ec);
|
||||
acceptor.listen(boost::asio::socket_base::max_connections, ec);
|
||||
EXPECT_EQ(ec.value(), 0);
|
||||
out->socket().open(endpoint.protocol(), ec);
|
||||
EXPECT_EQ(ec.value(), 0);
|
||||
@@ -803,9 +803,11 @@ TEST(cryptonote_protocol_handler, race_condition)
|
||||
workers_t workers;
|
||||
} check;
|
||||
check.work = std::make_shared<work_t>(check.io_context);
|
||||
check.workers.emplace_back([&check]{
|
||||
check.io_context.run();
|
||||
});
|
||||
while (check.workers.size() < 2) {
|
||||
check.workers.emplace_back([&check]{
|
||||
check.io_context.run();
|
||||
});
|
||||
}
|
||||
while (daemon.main.conn.size() < 1) {
|
||||
daemon.main.conn.emplace_back(new connection_t(check.io_context, daemon.main.shared_state, {}, {}));
|
||||
daemon.alt.conn.emplace_back(new connection_t(io_context, daemon.alt.shared_state, {}, {}));
|
||||
@@ -864,7 +866,7 @@ TEST(cryptonote_protocol_handler, race_condition)
|
||||
}
|
||||
}
|
||||
while (daemon.main.conn.size() < 2) {
|
||||
daemon.main.conn.emplace_back(new connection_t(io_context, daemon.main.shared_state, {}, {}));
|
||||
daemon.main.conn.emplace_back(new connection_t(check.io_context, daemon.main.shared_state, {}, {}));
|
||||
daemon.alt.conn.emplace_back(new connection_t(io_context, daemon.alt.shared_state, {}, {}));
|
||||
create_conn_pair(daemon.main.conn.back(), daemon.alt.conn.back());
|
||||
conduct_handshake(daemon.alt.net_node, daemon.alt.conn.back());
|
||||
|
||||
@@ -189,20 +189,20 @@ TEST(wipeable_string, parse_hexstr)
|
||||
{
|
||||
boost::optional<epee::wipeable_string> s;
|
||||
|
||||
ASSERT_EQ(boost::none, epee::wipeable_string("x").parse_hexstr());
|
||||
ASSERT_EQ(boost::none, epee::wipeable_string("x0000000000000000").parse_hexstr());
|
||||
ASSERT_EQ(boost::none, epee::wipeable_string("0000000000000000x").parse_hexstr());
|
||||
ASSERT_EQ(boost::none, epee::wipeable_string("0").parse_hexstr());
|
||||
ASSERT_EQ(boost::none, epee::wipeable_string("000").parse_hexstr());
|
||||
ASSERT_TRUE(boost::none == epee::wipeable_string("x").parse_hexstr());
|
||||
ASSERT_TRUE(boost::none == epee::wipeable_string("x0000000000000000").parse_hexstr());
|
||||
ASSERT_TRUE(boost::none == epee::wipeable_string("0000000000000000x").parse_hexstr());
|
||||
ASSERT_TRUE(boost::none == epee::wipeable_string("0").parse_hexstr());
|
||||
ASSERT_TRUE(boost::none == epee::wipeable_string("000").parse_hexstr());
|
||||
|
||||
ASSERT_TRUE((s = epee::wipeable_string("").parse_hexstr()) != boost::none);
|
||||
ASSERT_EQ(*s, "");
|
||||
ASSERT_TRUE(*s == "");
|
||||
ASSERT_TRUE((s = epee::wipeable_string("00").parse_hexstr()) != boost::none);
|
||||
ASSERT_EQ(*s, epee::wipeable_string("", 1));
|
||||
ASSERT_TRUE(*s == epee::wipeable_string("", 1));
|
||||
ASSERT_TRUE((s = epee::wipeable_string("41").parse_hexstr()) != boost::none);
|
||||
ASSERT_EQ(*s, epee::wipeable_string("A"));
|
||||
ASSERT_TRUE(*s == epee::wipeable_string("A"));
|
||||
ASSERT_TRUE((s = epee::wipeable_string("414243").parse_hexstr()) != boost::none);
|
||||
ASSERT_EQ(*s, epee::wipeable_string("ABC"));
|
||||
ASSERT_TRUE(*s == epee::wipeable_string("ABC"));
|
||||
}
|
||||
|
||||
TEST(wipeable_string, to_hex)
|
||||
|
||||
@@ -44,7 +44,7 @@ ARG BOOST_VERSION=1_68_0
|
||||
ARG BOOST_VERSION_DOT=1.68.0
|
||||
ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7
|
||||
RUN set -ex \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
|
||||
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& rm -f boost_${BOOST_VERSION}.tar.bz2 \
|
||||
|
||||
@@ -44,7 +44,7 @@ ARG BOOST_VERSION=1_68_0
|
||||
ARG BOOST_VERSION_DOT=1.68.0
|
||||
ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7
|
||||
RUN set -ex \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://dl.bintray.com/boostorg/release/${BOOST_VERSION_DOT}/source/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \
|
||||
&& tar -xvf boost_${BOOST_VERSION}.tar.bz2 \
|
||||
&& rm -f boost_${BOOST_VERSION}.tar.bz2 \
|
||||
|
||||
@@ -1088,3 +1088,36 @@ class Wallet(object):
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(get_version)
|
||||
|
||||
def freeze(self, key_image):
|
||||
freeze = {
|
||||
'method': 'freeze',
|
||||
'jsonrpc': '2.0',
|
||||
'params' : {
|
||||
'key_image': key_image,
|
||||
},
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(freeze)
|
||||
|
||||
def thaw(self, key_image):
|
||||
thaw = {
|
||||
'method': 'thaw',
|
||||
'jsonrpc': '2.0',
|
||||
'params' : {
|
||||
'key_image': key_image,
|
||||
},
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(thaw)
|
||||
|
||||
def frozen(self, key_image):
|
||||
frozen = {
|
||||
'method': 'frozen',
|
||||
'jsonrpc': '2.0',
|
||||
'params' : {
|
||||
'key_image': key_image,
|
||||
},
|
||||
'id': '0'
|
||||
}
|
||||
return self.rpc.send_json_rpc_request(frozen)
|
||||
|
||||
Reference in New Issue
Block a user