Merge pull request #8752

c444a7e trezor: support v2.5.2+, add more trezor tests, fix chaingen and tests (Dusan Klinec)
056c996 fix chaingen tests (Dusan Klinec)
This commit is contained in:
luigi1111 2023-10-25 21:30:49 -04:00
commit 8f0343df16
No known key found for this signature in database
GPG Key ID: F4ACA0183641E010
41 changed files with 1221 additions and 738 deletions

View File

@ -23,6 +23,7 @@ env:
CCACHE_SETTINGS: | CCACHE_SETTINGS: |
ccache --max-size=150M ccache --max-size=150M
ccache --set-config=compression=true ccache --set-config=compression=true
USE_DEVICE_TREZOR_MANDATORY: ON
jobs: jobs:
build-macos: build-macos:
@ -39,7 +40,9 @@ jobs:
key: ccache-${{ runner.os }}-build-${{ github.sha }} key: ccache-${{ runner.os }}-build-${{ github.sha }}
restore-keys: ccache-${{ runner.os }}-build- restore-keys: ccache-${{ runner.os }}-build-
- name: install dependencies - name: install dependencies
run: HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi openssl zmq libpgm miniupnpc expat libunwind-headers protobuf ccache run: |
HOMEBREW_NO_AUTO_UPDATE=1 brew install boost hidapi openssl zmq libpgm miniupnpc expat libunwind-headers protobuf@21 ccache
brew link protobuf@21
- name: build - name: build
run: | run: |
${{env.CCACHE_SETTINGS}} ${{env.CCACHE_SETTINGS}}
@ -65,7 +68,12 @@ jobs:
- uses: msys2/setup-msys2@v2 - uses: msys2/setup-msys2@v2
with: with:
update: true update: true
install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-ccache 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 mingw-w64-x86_64-unbound git install: mingw-w64-x86_64-toolchain make mingw-w64-x86_64-cmake mingw-w64-x86_64-ccache 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-libusb mingw-w64-x86_64-unbound git
- shell: msys2 {0}
run: |
curl -O https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-protobuf-c-1.4.1-1-any.pkg.tar.zst
curl -O https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-protobuf-21.9-1-any.pkg.tar.zst
pacman --noconfirm -U mingw-w64-x86_64-protobuf-c-1.4.1-1-any.pkg.tar.zst mingw-w64-x86_64-protobuf-21.9-1-any.pkg.tar.zst
- name: build - name: build
run: | run: |
${{env.CCACHE_SETTINGS}} ${{env.CCACHE_SETTINGS}}

View File

@ -18,6 +18,7 @@ env:
CCACHE_SETTINGS: | CCACHE_SETTINGS: |
ccache --max-size=150M ccache --max-size=150M
ccache --set-config=compression=true ccache --set-config=compression=true
USE_DEVICE_TREZOR_MANDATORY: ON
jobs: jobs:
build-cross: build-cross:

View File

@ -590,6 +590,16 @@ Using `depends` might also be easier to compile Monero on Windows than using MSY
The produced binaries still link libc dynamically. If the binary is compiled on a current distribution, it might not run on an older distribution with an older installation of libc. Passing `-DBACKCOMPAT=ON` to cmake will make sure that the binary will run on systems having at least libc version 2.17. The produced binaries still link libc dynamically. If the binary is compiled on a current distribution, it might not run on an older distribution with an older installation of libc. Passing `-DBACKCOMPAT=ON` to cmake will make sure that the binary will run on systems having at least libc version 2.17.
### Trezor hardware wallet support
If you have an issue with building Monero with Trezor support, you can disable it by setting `USE_DEVICE_TREZOR=OFF`, e.g.,
```bash
USE_DEVICE_TREZOR=OFF make release
```
For more information, please check out Trezor [src/device_trezor/README.md](src/device_trezor/README.md).
### Gitian builds ### Gitian builds
See [contrib/gitian/README.md](contrib/gitian/README.md). See [contrib/gitian/README.md](contrib/gitian/README.md).

View File

@ -1,8 +1,27 @@
OPTION(USE_DEVICE_TREZOR "Trezor support compilation" ON) # Function for setting default options default values via env vars
OPTION(USE_DEVICE_TREZOR_LIBUSB "Trezor LibUSB compilation" ON) function(_trezor_default_val val_name val_default)
OPTION(USE_DEVICE_TREZOR_UDP_RELEASE "Trezor UdpTransport in release mode" OFF) if(NOT DEFINED ENV{${val_name}})
OPTION(USE_DEVICE_TREZOR_DEBUG "Trezor Debugging enabled" OFF) set(ENV{${val_name}} ${val_default})
OPTION(TREZOR_DEBUG "Main trezor debugging switch" OFF) endif()
endfunction()
# Define default options via env vars
_trezor_default_val(USE_DEVICE_TREZOR ON)
_trezor_default_val(USE_DEVICE_TREZOR_MANDATORY OFF)
_trezor_default_val(USE_DEVICE_TREZOR_PROTOBUF_TEST ON)
_trezor_default_val(USE_DEVICE_TREZOR_LIBUSB ON)
_trezor_default_val(USE_DEVICE_TREZOR_UDP_RELEASE OFF)
_trezor_default_val(USE_DEVICE_TREZOR_DEBUG OFF)
_trezor_default_val(TREZOR_DEBUG OFF)
# Main options
OPTION(USE_DEVICE_TREZOR "Trezor support compilation" $ENV{USE_DEVICE_TREZOR})
OPTION(USE_DEVICE_TREZOR_MANDATORY "Trezor compilation is mandatory, fail build if Trezor support cannot be compiled" $ENV{USE_DEVICE_TREZOR_MANDATORY})
OPTION(USE_DEVICE_TREZOR_PROTOBUF_TEST "Trezor Protobuf test" $ENV{USE_DEVICE_TREZOR_PROTOBUF_TEST})
OPTION(USE_DEVICE_TREZOR_LIBUSB "Trezor LibUSB compilation" $ENV{USE_DEVICE_TREZOR_LIBUSB})
OPTION(USE_DEVICE_TREZOR_UDP_RELEASE "Trezor UdpTransport in release mode" $ENV{USE_DEVICE_TREZOR_UDP_RELEASE})
OPTION(USE_DEVICE_TREZOR_DEBUG "Trezor Debugging enabled" $ENV{USE_DEVICE_TREZOR_DEBUG})
OPTION(TREZOR_DEBUG "Main Trezor debugging switch" $ENV{TREZOR_DEBUG})
# Helper function to fix cmake < 3.6.0 FindProtobuf variables # Helper function to fix cmake < 3.6.0 FindProtobuf variables
function(_trezor_protobuf_fix_vars) function(_trezor_protobuf_fix_vars)
@ -30,33 +49,62 @@ function(_trezor_protobuf_fix_vars)
endif() endif()
endfunction() endfunction()
macro(trezor_fatal_msg msg)
if ($ENV{USE_DEVICE_TREZOR_MANDATORY})
message(FATAL_ERROR
"${msg}\n"
"==========================================================================\n"
"[ERROR] To compile without Trezor support, set USE_DEVICE_TREZOR=OFF. "
"It is possible both via cmake variable and environment variable, e.g., "
"`USE_DEVICE_TREZOR=OFF make release`\n"
"For more information, please check src/device_trezor/README.md\n"
)
else()
message(WARNING
"${msg}\n"
"==========================================================================\n"
"[WARNING] Trezor support cannot be compiled! Skipping Trezor compilation. \n"
"For more information, please check src/device_trezor/README.md\n")
set(USE_DEVICE_TREZOR OFF)
return() # finish this cmake file processing (as this is macro).
endif()
endmacro()
# Use Trezor master switch # Use Trezor master switch
if (USE_DEVICE_TREZOR) if (USE_DEVICE_TREZOR)
# Protobuf is required to build protobuf messages for Trezor # Protobuf is required to build protobuf messages for Trezor
include(FindProtobuf OPTIONAL) include(FindProtobuf OPTIONAL)
find_package(Protobuf)
FIND_PACKAGE(Protobuf CONFIG)
if (NOT Protobuf_FOUND)
FIND_PACKAGE(Protobuf)
endif()
_trezor_protobuf_fix_vars() _trezor_protobuf_fix_vars()
# Protobuf handling the cache variables set in docker. # Early fail for optional Trezor support
if(NOT Protobuf_FOUND AND NOT Protobuf_LIBRARY AND NOT Protobuf_PROTOC_EXECUTABLE AND NOT Protobuf_INCLUDE_DIR) if(${Protobuf_VERSION} GREATER 21)
message(STATUS "Could not find Protobuf") trezor_fatal_msg("Trezor: Unsupported Protobuf version ${Protobuf_VERSION}. Please, use Protobuf v21.")
elseif(NOT Protobuf_FOUND AND NOT Protobuf_LIBRARY AND NOT Protobuf_PROTOC_EXECUTABLE AND NOT Protobuf_INCLUDE_DIR)
trezor_fatal_msg("Trezor: Could not find Protobuf")
elseif(NOT Protobuf_LIBRARY OR NOT EXISTS "${Protobuf_LIBRARY}") elseif(NOT Protobuf_LIBRARY OR NOT EXISTS "${Protobuf_LIBRARY}")
message(STATUS "Protobuf library not found: ${Protobuf_LIBRARY}") trezor_fatal_msg("Trezor: Protobuf library not found: ${Protobuf_LIBRARY}")
unset(Protobuf_FOUND) unset(Protobuf_FOUND)
elseif(NOT Protobuf_PROTOC_EXECUTABLE OR NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") elseif(NOT Protobuf_PROTOC_EXECUTABLE OR NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}")
message(STATUS "Protobuf executable not found: ${Protobuf_PROTOC_EXECUTABLE}") trezor_fatal_msg("Trezor: Protobuf executable not found: ${Protobuf_PROTOC_EXECUTABLE}")
unset(Protobuf_FOUND) unset(Protobuf_FOUND)
elseif(NOT Protobuf_INCLUDE_DIR OR NOT EXISTS "${Protobuf_INCLUDE_DIR}") elseif(NOT Protobuf_INCLUDE_DIR OR NOT EXISTS "${Protobuf_INCLUDE_DIR}")
message(STATUS "Protobuf include dir not found: ${Protobuf_INCLUDE_DIR}") trezor_fatal_msg("Trezor: Protobuf include dir not found: ${Protobuf_INCLUDE_DIR}")
unset(Protobuf_FOUND) unset(Protobuf_FOUND)
else() else()
message(STATUS "Protobuf lib: ${Protobuf_LIBRARY}, inc: ${Protobuf_INCLUDE_DIR}, protoc: ${Protobuf_PROTOC_EXECUTABLE}") message(STATUS "Trezor: Protobuf lib: ${Protobuf_LIBRARY}, inc: ${Protobuf_INCLUDE_DIR}, protoc: ${Protobuf_PROTOC_EXECUTABLE}")
set(Protobuf_INCLUDE_DIRS ${Protobuf_INCLUDE_DIR}) set(Protobuf_INCLUDE_DIRS ${Protobuf_INCLUDE_DIR})
set(Protobuf_FOUND 1) # override found if all rquired info was provided by variables set(Protobuf_FOUND 1) # override found if all required info was provided by variables
endif() endif()
if(TREZOR_DEBUG) if(TREZOR_DEBUG)
set(USE_DEVICE_TREZOR_DEBUG 1) set(USE_DEVICE_TREZOR_DEBUG 1)
message(STATUS "Trezor: debug build enabled")
endif() endif()
# Compile debugging support (for tests) # Compile debugging support (for tests)
@ -64,7 +112,7 @@ if (USE_DEVICE_TREZOR)
add_definitions(-DWITH_TREZOR_DEBUGGING=1) add_definitions(-DWITH_TREZOR_DEBUGGING=1)
endif() endif()
else() else()
message(STATUS "Trezor support disabled by USE_DEVICE_TREZOR") message(STATUS "Trezor: support disabled by USE_DEVICE_TREZOR")
endif() endif()
if(Protobuf_FOUND AND USE_DEVICE_TREZOR) if(Protobuf_FOUND AND USE_DEVICE_TREZOR)
@ -85,7 +133,7 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR)
endif() endif()
if(NOT TREZOR_PYTHON) if(NOT TREZOR_PYTHON)
message(STATUS "Trezor: Python not found") trezor_fatal_msg("Trezor: Python not found")
endif() endif()
endif() endif()
@ -93,27 +141,42 @@ endif()
if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON) if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_CURRENT_LIST_DIR}" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR) execute_process(COMMAND ${Protobuf_PROTOC_EXECUTABLE} -I "${CMAKE_CURRENT_LIST_DIR}" -I "${Protobuf_INCLUDE_DIR}" "${CMAKE_CURRENT_LIST_DIR}/test-protobuf.proto" --cpp_out ${CMAKE_BINARY_DIR} RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
if(RET) if(RET)
message(STATUS "Protobuf test generation failed: ${OUT} ${ERR}") trezor_fatal_msg("Trezor: Protobuf test generation failed: ${OUT} ${ERR}")
endif() endif()
try_compile(Protobuf_COMPILE_TEST_PASSED if(ANDROID)
"${CMAKE_BINARY_DIR}" set(CMAKE_TRY_COMPILE_LINKER_FLAGS "${CMAKE_TRY_COMPILE_LINKER_FLAGS} -llog")
SOURCES set(CMAKE_TRY_COMPILE_LINK_LIBRARIES "${CMAKE_TRY_COMPILE_LINK_LIBRARIES} log")
"${CMAKE_BINARY_DIR}/test-protobuf.pb.cc" endif()
"${CMAKE_CURRENT_LIST_DIR}/test-protobuf.cpp"
CMAKE_FLAGS if(USE_DEVICE_TREZOR_PROTOBUF_TEST)
"-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}" # For now, Protobuf v21 is the maximum supported version as v23 requires C++17. TODO: Remove once we move to C++17
"-DCMAKE_CXX_STANDARD=11" if(${Protobuf_VERSION} GREATER 21)
LINK_LIBRARIES ${Protobuf_LIBRARY} trezor_fatal_msg("Trezor: Unsupported Protobuf version ${Protobuf_VERSION}. Please, use Protobuf v21.")
OUTPUT_VARIABLE OUTPUT endif()
)
if(NOT Protobuf_COMPILE_TEST_PASSED) try_compile(Protobuf_COMPILE_TEST_PASSED
message(STATUS "Protobuf Compilation test failed: ${OUTPUT}.") "${CMAKE_BINARY_DIR}"
SOURCES
"${CMAKE_BINARY_DIR}/test-protobuf.pb.cc"
"${CMAKE_CURRENT_LIST_DIR}/test-protobuf.cpp"
CMAKE_FLAGS
CMAKE_EXE_LINKER_FLAGS ${CMAKE_TRY_COMPILE_LINKER_FLAGS}
"-DINCLUDE_DIRECTORIES=${Protobuf_INCLUDE_DIR};${CMAKE_BINARY_DIR}"
"-DCMAKE_CXX_STANDARD=${CMAKE_CXX_STANDARD}"
LINK_LIBRARIES ${Protobuf_LIBRARY} ${CMAKE_TRY_COMPILE_LINK_LIBRARIES}
OUTPUT_VARIABLE OUTPUT
)
if(NOT Protobuf_COMPILE_TEST_PASSED)
trezor_fatal_msg("Trezor: Protobuf Compilation test failed: ${OUTPUT}.")
endif()
else ()
message(STATUS "Trezor: Protobuf Compilation test skipped, build may fail later")
endif() endif()
endif() endif()
# Try to build protobuf messages # Try to build protobuf messages
if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON AND Protobuf_COMPILE_TEST_PASSED) if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON)
set(ENV{PROTOBUF_INCLUDE_DIRS} "${Protobuf_INCLUDE_DIR}") set(ENV{PROTOBUF_INCLUDE_DIRS} "${Protobuf_INCLUDE_DIR}")
set(ENV{PROTOBUF_PROTOC_EXECUTABLE} "${Protobuf_PROTOC_EXECUTABLE}") set(ENV{PROTOBUF_PROTOC_EXECUTABLE} "${Protobuf_PROTOC_EXECUTABLE}")
set(TREZOR_PROTOBUF_PARAMS "") set(TREZOR_PROTOBUF_PARAMS "")
@ -123,59 +186,62 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON AND Protobuf_COMPILE_T
execute_process(COMMAND ${TREZOR_PYTHON} tools/build_protob.py ${TREZOR_PROTOBUF_PARAMS} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR) execute_process(COMMAND ${TREZOR_PYTHON} tools/build_protob.py ${TREZOR_PROTOBUF_PARAMS} WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/../src/device_trezor/trezor RESULT_VARIABLE RET OUTPUT_VARIABLE OUT ERROR_VARIABLE ERR)
if(RET) if(RET)
message(WARNING "Trezor protobuf messages could not be regenerated (err=${RET}, python ${PYTHON})." trezor_fatal_msg("Trezor: protobuf messages could not be regenerated (err=${RET}, python ${PYTHON})."
"OUT: ${OUT}, ERR: ${ERR}." "OUT: ${OUT}, ERR: ${ERR}."
"Please read src/device_trezor/trezor/tools/README.md") "Please read src/device_trezor/trezor/tools/README.md")
else() endif()
message(STATUS "Trezor protobuf messages regenerated out: \"${OUT}.\"")
set(DEVICE_TREZOR_READY 1)
add_definitions(-DDEVICE_TREZOR_READY=1)
add_definitions(-DPROTOBUF_INLINE_NOT_IN_HEADERS=0)
if(CMAKE_BUILD_TYPE STREQUAL "Debug") message(STATUS "Trezor: protobuf messages regenerated out: \"${OUT}.\"")
add_definitions(-DTREZOR_DEBUG=1) set(DEVICE_TREZOR_READY 1)
add_definitions(-DDEVICE_TREZOR_READY=1)
add_definitions(-DPROTOBUF_INLINE_NOT_IN_HEADERS=0)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(-DTREZOR_DEBUG=1)
endif()
if(USE_DEVICE_TREZOR_UDP_RELEASE)
message(STATUS "Trezor: UDP transport enabled (emulator)")
add_definitions(-DUSE_DEVICE_TREZOR_UDP_RELEASE=1)
endif()
if (Protobuf_INCLUDE_DIR)
include_directories(${Protobuf_INCLUDE_DIR})
endif()
# LibUSB support, check for particular version
# Include support only if compilation test passes
if (USE_DEVICE_TREZOR_LIBUSB)
find_package(LibUSB)
endif()
if (LibUSB_COMPILE_TEST_PASSED)
add_definitions(-DHAVE_TREZOR_LIBUSB=1)
if(LibUSB_INCLUDE_DIRS)
include_directories(${LibUSB_INCLUDE_DIRS})
endif()
endif()
set(TREZOR_LIBUSB_LIBRARIES "")
if(LibUSB_COMPILE_TEST_PASSED)
list(APPEND TREZOR_LIBUSB_LIBRARIES ${LibUSB_LIBRARIES} ${LIBUSB_DEP_LINKER})
message(STATUS "Trezor: compatible LibUSB found at: ${LibUSB_INCLUDE_DIRS}")
elseif(USE_DEVICE_TREZOR_LIBUSB AND NOT ANDROID)
trezor_fatal_msg("Trezor: LibUSB not found or test failed, please install libusb-1.0.26")
endif()
if (BUILD_GUI_DEPS)
set(TREZOR_DEP_LIBS "")
set(TREZOR_DEP_LINKER "")
if (Protobuf_LIBRARY)
list(APPEND TREZOR_DEP_LIBS ${Protobuf_LIBRARY})
string(APPEND TREZOR_DEP_LINKER " -lprotobuf")
endif() endif()
if(USE_DEVICE_TREZOR_UDP_RELEASE) if (TREZOR_LIBUSB_LIBRARIES)
add_definitions(-DUSE_DEVICE_TREZOR_UDP_RELEASE=1) list(APPEND TREZOR_DEP_LIBS ${TREZOR_LIBUSB_LIBRARIES})
endif() string(APPEND TREZOR_DEP_LINKER " -lusb-1.0 ${LIBUSB_DEP_LINKER}")
if (Protobuf_INCLUDE_DIR)
include_directories(${Protobuf_INCLUDE_DIR})
endif()
# LibUSB support, check for particular version
# Include support only if compilation test passes
if (USE_DEVICE_TREZOR_LIBUSB)
find_package(LibUSB)
endif()
if (LibUSB_COMPILE_TEST_PASSED)
add_definitions(-DHAVE_TREZOR_LIBUSB=1)
if(LibUSB_INCLUDE_DIRS)
include_directories(${LibUSB_INCLUDE_DIRS})
endif()
endif()
set(TREZOR_LIBUSB_LIBRARIES "")
if(LibUSB_COMPILE_TEST_PASSED)
list(APPEND TREZOR_LIBUSB_LIBRARIES ${LibUSB_LIBRARIES} ${LIBUSB_DEP_LINKER})
message(STATUS "Trezor compatible LibUSB found at: ${LibUSB_INCLUDE_DIRS}")
endif()
if (BUILD_GUI_DEPS)
set(TREZOR_DEP_LIBS "")
set(TREZOR_DEP_LINKER "")
if (Protobuf_LIBRARY)
list(APPEND TREZOR_DEP_LIBS ${Protobuf_LIBRARY})
string(APPEND TREZOR_DEP_LINKER " -lprotobuf")
endif()
if (TREZOR_LIBUSB_LIBRARIES)
list(APPEND TREZOR_DEP_LIBS ${TREZOR_LIBUSB_LIBRARIES})
string(APPEND TREZOR_DEP_LINKER " -lusb-1.0 ${LIBUSB_DEP_LINKER}")
endif()
endif() endif()
endif() endif()
endif() endif()

View File

@ -95,11 +95,35 @@ if ( LibUSB_FOUND )
endif ( LibUSB_FOUND ) endif ( LibUSB_FOUND )
if ( LibUSB_FOUND ) if ( LibUSB_FOUND )
if (APPLE)
if(DEPENDS)
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES "-framework Foundation -framework IOKit -framework Security")
else()
find_library(COREFOUNDATION CoreFoundation)
find_library(IOKIT IOKit)
find_library(SECURITY_FRAMEWORK Security)
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${IOKIT})
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${COREFOUNDATION})
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${SECURITY_FRAMEWORK})
if(STATIC)
find_library(OBJC objc.a)
set(LIBUSB_DEP_LINKER ${OBJC})
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${LIBUSB_DEP_LINKER})
endif()
endif()
endif()
if (WIN32)
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES setupapi)
endif()
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${LibUSB_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${TEST_COMPILE_EXTRA_LIBRARIES})
check_library_exists ( "${LibUSB_LIBRARIES}" usb_open "" LibUSB_FOUND ) check_library_exists ( "${LibUSB_LIBRARIES}" usb_open "" LibUSB_FOUND )
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_device_list "" LibUSB_VERSION_1.0 ) check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_device_list "" LibUSB_VERSION_1.0 )
check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_port_numbers "" LibUSB_VERSION_1.0.16 ) check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_port_numbers "" LibUSB_VERSION_1.0.16 )
if((STATIC AND UNIX AND NOT APPLE) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux") OR ANDROID) if((STATIC AND UNIX AND NOT APPLE AND NOT FREEBSD) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux") OR ANDROID)
find_library(LIBUDEV_LIBRARY udev) find_library(LIBUDEV_LIBRARY udev)
if(LIBUDEV_LIBRARY) if(LIBUDEV_LIBRARY)
set(LibUSB_LIBRARIES "${LibUSB_LIBRARIES};${LIBUDEV_LIBRARY}") set(LibUSB_LIBRARIES "${LibUSB_LIBRARIES};${LIBUDEV_LIBRARY}")
@ -111,27 +135,6 @@ if ( LibUSB_FOUND )
# Library 1.0.16+ compilation test. # Library 1.0.16+ compilation test.
# The check_library_exists does not work well on Apple with shared libs. # The check_library_exists does not work well on Apple with shared libs.
if (APPLE OR LibUSB_VERSION_1.0.16 OR STATIC) if (APPLE OR LibUSB_VERSION_1.0.16 OR STATIC)
if (APPLE)
if(DEPENDS)
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES "-framework Foundation -framework IOKit -framework Security")
else()
find_library(COREFOUNDATION CoreFoundation)
find_library(IOKIT IOKit)
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${IOKIT})
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${COREFOUNDATION})
if(STATIC)
find_library(OBJC objc.a)
set(LIBUSB_DEP_LINKER ${OBJC})
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${LIBUSB_DEP_LINKER})
endif()
endif()
endif()
if (WIN32)
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES setupapi)
endif()
list(APPEND TEST_COMPILE_EXTRA_LIBRARIES ${LibUSB_LIBRARIES})
try_compile(LibUSB_COMPILE_TEST_PASSED try_compile(LibUSB_COMPILE_TEST_PASSED
${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}
"${CMAKE_CURRENT_LIST_DIR}/test-libusb-version.c" "${CMAKE_CURRENT_LIST_DIR}/test-libusb-version.c"

View File

@ -31,4 +31,5 @@ brew "doxygen"
brew "graphviz" brew "graphviz"
brew "libunwind-headers" brew "libunwind-headers"
brew "xz" brew "xz"
brew "protobuf" brew "protobuf@21", link: true
brew "libusb"

View File

@ -3,8 +3,10 @@ $(package)_version=1.0.26
$(package)_download_path=https://github.com/libusb/libusb/releases/download/v$($(package)_version) $(package)_download_path=https://github.com/libusb/libusb/releases/download/v$($(package)_version)
$(package)_file_name=$(package)-$($(package)_version).tar.bz2 $(package)_file_name=$(package)-$($(package)_version).tar.bz2
$(package)_sha256_hash=12ce7a61fc9854d1d2a1ffe095f7b5fac19ddba095c259e6067a46500381b5a5 $(package)_sha256_hash=12ce7a61fc9854d1d2a1ffe095f7b5fac19ddba095c259e6067a46500381b5a5
$(package)_patches=fix_osx_avail.patch
define $(package)_preprocess_cmds define $(package)_preprocess_cmds
patch -p1 < $($(package)_patch_dir)/fix_osx_avail.patch &&\
autoreconf -i autoreconf -i
endef endef
@ -13,6 +15,7 @@ define $(package)_set_vars
$(package)_config_opts_linux=--with-pic --disable-udev $(package)_config_opts_linux=--with-pic --disable-udev
$(package)_config_opts_mingw32=--disable-udev $(package)_config_opts_mingw32=--disable-udev
$(package)_config_opts_darwin=--disable-udev $(package)_config_opts_darwin=--disable-udev
$(package)_config_opts_freebsd=--with-pic --disable-udev
endef endef
ifneq ($(host_os),darwin) ifneq ($(host_os),darwin)

View File

@ -1,8 +1,9 @@
package=protobuf3 package=protobuf3
$(package)_version=3.6.1 $(package)_version=21.12
$(package)_version_protobuf_cpp=3.21.12
$(package)_download_path=https://github.com/protocolbuffers/protobuf/releases/download/v$($(package)_version)/ $(package)_download_path=https://github.com/protocolbuffers/protobuf/releases/download/v$($(package)_version)/
$(package)_file_name=protobuf-cpp-$($(package)_version).tar.gz $(package)_file_name=protobuf-cpp-$($(package)_version_protobuf_cpp).tar.gz
$(package)_sha256_hash=b3732e471a9bb7950f090fd0457ebd2536a9ba0891b7f3785919c654fe2a2529 $(package)_sha256_hash=4eab9b524aa5913c6fffb20b2a8abf5ef7f95a80bc0701f3a6dbb4c607f73460
$(package)_cxxflags=-std=c++11 $(package)_cxxflags=-std=c++11
define $(package)_set_vars define $(package)_set_vars

View File

@ -8,15 +8,15 @@ endif
hardware_packages := hidapi protobuf libusb hardware_packages := hidapi protobuf libusb
hardware_native_packages := native_protobuf hardware_native_packages := native_protobuf
android_native_packages = android_ndk android_native_packages = android_ndk $(hardware_native_packages)
android_packages = ncurses readline sodium android_packages = ncurses readline sodium protobuf
darwin_native_packages = $(hardware_native_packages) darwin_native_packages = $(hardware_native_packages)
darwin_packages = ncurses readline sodium $(hardware_packages) darwin_packages = ncurses readline sodium $(hardware_packages)
# not really native... # not really native...
freebsd_native_packages = freebsd_base freebsd_native_packages = freebsd_base $(hardware_native_packages)
freebsd_packages = ncurses readline sodium freebsd_packages = ncurses readline sodium protobuf libusb
linux_packages = eudev ncurses readline sodium $(hardware_packages) linux_packages = eudev ncurses readline sodium $(hardware_packages)
linux_native_packages = $(hardware_native_packages) linux_native_packages = $(hardware_native_packages)

View File

@ -1,21 +1,17 @@
package=protobuf package=protobuf
$(package)_version=$(native_$(package)_version) $(package)_version=$(native_$(package)_version)
$(package)_version_protobuf_cpp=$(native_$(package)_version_protobuf_cpp)
$(package)_download_path=$(native_$(package)_download_path) $(package)_download_path=$(native_$(package)_download_path)
$(package)_file_name=$(native_$(package)_file_name) $(package)_file_name=$(native_$(package)_file_name)
$(package)_sha256_hash=$(native_$(package)_sha256_hash) $(package)_sha256_hash=$(native_$(package)_sha256_hash)
$(package)_dependencies=native_$(package) $(package)_dependencies=native_$(package)
$(package)_cxxflags=-std=c++11 $(package)_cxxflags=-std=c++11
$(package)_patches=visibility.patch
define $(package)_set_vars define $(package)_set_vars
$(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc $(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc
$(package)_config_opts_linux=--with-pic $(package)_config_opts_linux=--with-pic
endef endef
define $(package)_preprocess_cmds
patch -p0 < $($(package)_patch_dir)/visibility.patch
endef
define $(package)_config_cmds define $(package)_config_cmds
$($(package)_autoconf) AR_FLAGS=$($(package)_arflags) $($(package)_autoconf) AR_FLAGS=$($(package)_arflags)
endef endef

View File

@ -0,0 +1,12 @@
--- a/libusb/os/darwin_usb.h 2023-03-19 12:07:53
+++ b/libusb/os/darwin_usb.h 2023-03-19 12:07:47
@@ -165,7 +165,8 @@
#define __has_builtin(x) 0 // Compatibility with non-clang compilers.
#endif
#if __has_builtin(__builtin_available)
- #define HAS_CAPTURE_DEVICE() __builtin_available(macOS 10.10, *)
+// #define HAS_CAPTURE_DEVICE() __builtin_available(macOS 10.10, *)
+ #define HAS_CAPTURE_DEVICE() 0
#else
#define HAS_CAPTURE_DEVICE() 0
#endif

View File

@ -1,159 +0,0 @@
--- src/google/protobuf/descriptor.cc.O 2018-07-30 22:16:10.000000000 +0000
+++ src/google/protobuf/descriptor.cc 2022-05-06 13:38:14.827309092 +0000
@@ -32,6 +32,9 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility push(hidden)
+#endif
#include <algorithm>
#include <functional>
#include <google/protobuf/stubs/hash.h>
@@ -7274,3 +7277,6 @@
} // namespace protobuf
} // namespace google
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility pop
+#endif
--- src/google/protobuf/extension_set.cc.O 2018-07-23 20:56:42.000000000 +0000
+++ src/google/protobuf/extension_set.cc 2022-05-06 14:48:55.369877050 +0000
@@ -32,6 +32,9 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility push(hidden)
+#endif
#include <google/protobuf/stubs/hash.h>
#include <tuple>
#include <utility>
@@ -1914,3 +1917,6 @@
} // namespace internal
} // namespace protobuf
} // namespace google
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility pop
+#endif
--- src/google/protobuf/extension_set_heavy.cc.O 2018-07-30 22:16:10.000000000 +0000
+++ src/google/protobuf/extension_set_heavy.cc 2022-05-06 14:14:27.847320946 +0000
@@ -35,6 +35,10 @@
// Contains methods defined in extension_set.h which cannot be part of the
// lite library because they use descriptors or reflection.
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility push(hidden)
+#endif
+
#include <google/protobuf/stubs/casts.h>
#include <google/protobuf/descriptor.pb.h>
#include <google/protobuf/io/coded_stream.h>
@@ -814,3 +818,6 @@
} // namespace internal
} // namespace protobuf
} // namespace google
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility pop
+#endif
--- src/google/protobuf/generated_message_reflection.cc.O 2018-07-23 20:56:42.000000000 +0000
+++ src/google/protobuf/generated_message_reflection.cc 2022-05-06 13:38:49.655540772 +0000
@@ -32,6 +32,9 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility push(hidden)
+#endif
#include <algorithm>
#include <set>
@@ -2420,3 +2423,6 @@
} // namespace internal
} // namespace protobuf
} // namespace google
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility pop
+#endif
--- src/google/protobuf/map_field.cc.O 2018-07-23 20:56:42.000000000 +0000
+++ src/google/protobuf/map_field.cc 2022-05-06 13:34:44.913905697 +0000
@@ -28,6 +28,10 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility push(hidden)
+#endif
+
#include <google/protobuf/map_field.h>
#include <google/protobuf/map_field_inl.h>
@@ -462,3 +466,6 @@
} // namespace internal
} // namespace protobuf
} // namespace google
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility pop
+#endif
--- src/google/protobuf/text_format.cc.O 2018-07-30 22:16:11.000000000 +0000
+++ src/google/protobuf/text_format.cc 2022-05-06 13:34:58.881999517 +0000
@@ -32,6 +32,10 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility push(hidden)
+#endif
+
#include <algorithm>
#include <float.h>
#include <math.h>
@@ -2258,3 +2262,6 @@
} // namespace protobuf
} // namespace google
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility pop
+#endif
--- src/google/protobuf/wire_format.cc.O 2018-07-23 20:56:42.000000000 +0000
+++ src/google/protobuf/wire_format.cc 2022-05-06 13:06:23.294219228 +0000
@@ -32,6 +32,10 @@
// Based on original Protocol Buffers design by
// Sanjay Ghemawat, Jeff Dean, and others.
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility push(hidden)
+#endif
+
#include <stack>
#include <string>
#include <vector>
@@ -1445,3 +1449,7 @@
} // namespace internal
} // namespace protobuf
} // namespace google
+
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility pop
+#endif
--- src/google/protobuf/stubs/status.cc.O 2018-07-23 20:56:42.000000000 +0000
+++ src/google/protobuf/stubs/status.cc 2022-05-06 15:18:53.393208814 +0000
@@ -27,6 +27,11 @@
// 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.
+
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility push(hidden)
+#endif
+
#include <google/protobuf/stubs/status.h>
#include <ostream>
@@ -132,3 +137,6 @@
} // namespace util
} // namespace protobuf
} // namespace google
+#if defined(__APPLE__) && defined(__arm64__)
+#pragma GCC visibility pop
+#endif

View File

@ -27,12 +27,6 @@ SET(Terminfo_LIBRARY @prefix@/lib/libtinfo.a)
SET(UNBOUND_INCLUDE_DIR @prefix@/include) SET(UNBOUND_INCLUDE_DIR @prefix@/include)
SET(UNBOUND_LIBRARIES @prefix@/lib/libunbound.a) SET(UNBOUND_LIBRARIES @prefix@/lib/libunbound.a)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
SET(LIBUNWIND_INCLUDE_DIR @prefix@/include)
SET(LIBUNWIND_LIBRARIES @prefix@/lib/libunwind.a)
SET(LIBUNWIND_LIBRARY_DIRS @prefix@/lib)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
SET(LIBUSB-1.0_LIBRARY @prefix@/lib/libusb-1.0.a) SET(LIBUSB-1.0_LIBRARY @prefix@/lib/libusb-1.0.a)
SET(LIBUDEV_LIBRARY @prefix@/lib/libudev.a) SET(LIBUDEV_LIBRARY @prefix@/lib/libudev.a)
@ -41,8 +35,11 @@ SET(Protobuf_PROTOC_EXECUTABLE @prefix@/native/bin/protoc CACHE FILEPATH "Path t
SET(Protobuf_INCLUDE_DIR @prefix@/include CACHE PATH "Protobuf include dir") SET(Protobuf_INCLUDE_DIR @prefix@/include CACHE PATH "Protobuf include dir")
SET(Protobuf_INCLUDE_DIRS @prefix@/include CACHE PATH "Protobuf include dir") SET(Protobuf_INCLUDE_DIRS @prefix@/include CACHE PATH "Protobuf include dir")
SET(Protobuf_LIBRARY @prefix@/lib/libprotobuf.a CACHE FILEPATH "Protobuf library") SET(Protobuf_LIBRARY @prefix@/lib/libprotobuf.a CACHE FILEPATH "Protobuf library")
endif()
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
SET(LIBUNWIND_INCLUDE_DIR @prefix@/include)
SET(LIBUNWIND_LIBRARIES @prefix@/lib/libunwind.a)
SET(LIBUNWIND_LIBRARY_DIRS @prefix@/lib)
endif() endif()
SET(ZMQ_INCLUDE_PATH @prefix@/include) SET(ZMQ_INCLUDE_PATH @prefix@/include)

@ -1 +1 @@
Subproject commit bff7fdfe436c727982cc553bdfb29a9021b423b0 Subproject commit bc28c316d05bf1e9ebfe3d7df1ab25831d98d168

View File

@ -65,12 +65,16 @@ set(trezor_private_headers)
# Protobuf and LibUSB processed by CheckTrezor # Protobuf and LibUSB processed by CheckTrezor
if(DEVICE_TREZOR_READY) if(DEVICE_TREZOR_READY)
message(STATUS "Trezor support enabled") message(STATUS "Trezor: support enabled")
if(USE_DEVICE_TREZOR_DEBUG) if(USE_DEVICE_TREZOR_DEBUG)
list(APPEND trezor_headers trezor/debug_link.hpp trezor/messages/messages-debug.pb.h) list(APPEND trezor_headers trezor/debug_link.hpp trezor/messages/messages-debug.pb.h)
list(APPEND trezor_sources trezor/debug_link.cpp trezor/messages/messages-debug.pb.cc) list(APPEND trezor_sources trezor/debug_link.cpp trezor/messages/messages-debug.pb.cc)
message(STATUS "Trezor debugging enabled") message(STATUS "Trezor: debugging enabled")
endif()
if(ANDROID)
set(TREZOR_EXTRA_LIBRARIES "log")
endif() endif()
monero_private_headers(device_trezor monero_private_headers(device_trezor
@ -93,10 +97,11 @@ if(DEVICE_TREZOR_READY)
${Protobuf_LIBRARY} ${Protobuf_LIBRARY}
${TREZOR_LIBUSB_LIBRARIES} ${TREZOR_LIBUSB_LIBRARIES}
PRIVATE PRIVATE
${EXTRA_LIBRARIES}) ${EXTRA_LIBRARIES}
${TREZOR_EXTRA_LIBRARIES})
else() else()
message(STATUS "Trezor support disabled") message(STATUS "Trezor: support disabled")
monero_private_headers(device_trezor) monero_private_headers(device_trezor)
monero_add_library(device_trezor device_trezor.cpp) monero_add_library(device_trezor device_trezor.cpp)
target_link_libraries(device_trezor PUBLIC cncrypto) target_link_libraries(device_trezor PUBLIC cncrypto)

View File

@ -0,0 +1,74 @@
# Trezor hardware wallet support
This module adds [Trezor] hardware support to Monero.
## Basic information
Trezor integration is based on the following original proposal: https://github.com/ph4r05/monero-trezor-doc
A custom high-level transaction signing protocol uses Trezor in a similar way a cold wallet is used.
Transaction is build incrementally on the device.
Trezor implements the signing protocol in [trezor-firmware] repository, in the [monero](https://github.com/trezor/trezor-firmware/tree/master/core/src/apps/monero) application.
Please, refer to [monero readme](https://github.com/trezor/trezor-firmware/blob/master/core/src/apps/monero/README.md) for more information.
## Dependencies
Trezor uses [Protobuf](https://protobuf.dev/) library. As Monero is compiled with C++14, the newest Protobuf library version cannot be compiled because it requires C++17 (through its dependency Abseil library).
This can result in a compilation failure.
Protobuf v21 is the latest compatible protobuf version.
If you want to compile Monero with Trezor support, please make sure the Protobuf v21 is installed.
More about this limitation: [PR #8752](https://github.com/monero-project/monero/pull/8752),
[1](https://github.com/monero-project/monero/pull/8752#discussion_r1246174755), [2](https://github.com/monero-project/monero/pull/8752#discussion_r1246480393)
### OSX
To build with installed, but not linked protobuf:
```bash
CMAKE_PREFIX_PATH=$(find /opt/homebrew/Cellar/protobuf@21 -maxdepth 1 -type d -name "21.*" -print -quit) \
make release
```
or to install and link as a default protobuf version:
```bash
# Either install all requirements as
brew update && brew bundle --file=contrib/brew/Brewfile
# or install protobufv21 specifically
brew install protobuf@21 && brew link protobuf@21
```
### MSYS32
```bash
curl -O https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-protobuf-c-1.4.1-1-any.pkg.tar.zst
curl -O https://repo.msys2.org/mingw/mingw64/mingw-w64-x86_64-protobuf-21.9-1-any.pkg.tar.zst
pacman --noconfirm -U mingw-w64-x86_64-protobuf-c-1.4.1-1-any.pkg.tar.zst mingw-w64-x86_64-protobuf-21.9-1-any.pkg.tar.zst
```
### Other systems
- install protobufv21
- point `CMAKE_PREFIX_PATH` environment variable to Protobuf v21 installation.
## Troubleshooting
To disable Trezor support, set `USE_DEVICE_TREZOR=OFF`, e.g.:
```shell
USE_DEVICE_TREZOR=OFF make release
```
## Resources:
- First pull request https://github.com/monero-project/monero/pull/4241
- Integration proposal https://github.com/ph4r05/monero-trezor-doc
- Integration readme in trezor-firmware https://github.com/trezor/trezor-firmware/blob/master/core/src/apps/monero/README.md
[Trezor]: https://trezor.io/
[trezor-firmware]: https://github.com/trezor/trezor-firmware/

View File

@ -165,7 +165,7 @@ namespace trezor {
auto res = get_address(); auto res = get_address();
cryptonote::address_parse_info info{}; cryptonote::address_parse_info info{};
bool r = cryptonote::get_account_address_from_str(info, this->network_type, res->address()); bool r = cryptonote::get_account_address_from_str(info, this->m_network_type, res->address());
CHECK_AND_ASSERT_MES(r, false, "Could not parse returned address. Address parse failed: " + res->address()); CHECK_AND_ASSERT_MES(r, false, "Could not parse returned address. Address parse failed: " + res->address());
CHECK_AND_ASSERT_MES(!info.is_subaddress, false, "Trezor returned a sub address"); CHECK_AND_ASSERT_MES(!info.is_subaddress, false, "Trezor returned a sub address");
@ -693,14 +693,11 @@ namespace trezor {
unsigned device_trezor::client_version() unsigned device_trezor::client_version()
{ {
auto trezor_version = get_version(); auto trezor_version = get_version();
if (trezor_version < pack_version(2, 4, 3)){ if (trezor_version < pack_version(2, 5, 2)){
throw exc::TrezorException("Minimal Trezor firmware version is 2.4.3. Please update."); throw exc::TrezorException("Minimal Trezor firmware version is 2.5.2. Please update.");
} }
unsigned client_version = 3; unsigned client_version = 4; // since 2.5.2
if (trezor_version >= pack_version(2, 5, 2)){
client_version = 4;
}
#ifdef WITH_TREZOR_DEBUGGING #ifdef WITH_TREZOR_DEBUGGING
// Override client version for tests // Override client version for tests

View File

@ -102,7 +102,7 @@ namespace trezor {
bool has_ki_cold_sync() const override { return true; } bool has_ki_cold_sync() const override { return true; }
bool has_tx_cold_sign() const override { return true; } bool has_tx_cold_sign() const override { return true; }
void set_network_type(cryptonote::network_type network_type) override { this->network_type = network_type; } void set_network_type(cryptonote::network_type network_type) override { this->m_network_type = network_type; }
void set_live_refresh_enabled(bool enabled) { m_live_refresh_enabled = enabled; } void set_live_refresh_enabled(bool enabled) { m_live_refresh_enabled = enabled; }
bool live_refresh_enabled() const { return m_live_refresh_enabled; } bool live_refresh_enabled() const { return m_live_refresh_enabled; }

View File

@ -300,9 +300,6 @@ namespace trezor {
case messages::MessageType_PassphraseRequest: case messages::MessageType_PassphraseRequest:
on_passphrase_request(input, dynamic_cast<const messages::common::PassphraseRequest*>(input.m_msg.get())); on_passphrase_request(input, dynamic_cast<const messages::common::PassphraseRequest*>(input.m_msg.get()));
return true; return true;
case messages::MessageType_Deprecated_PassphraseStateRequest:
on_passphrase_state_request(input, dynamic_cast<const messages::common::Deprecated_PassphraseStateRequest*>(input.m_msg.get()));
return true;
case messages::MessageType_PinMatrixRequest: case messages::MessageType_PinMatrixRequest:
on_pin_request(input, dynamic_cast<const messages::common::PinMatrixRequest*>(input.m_msg.get())); on_pin_request(input, dynamic_cast<const messages::common::PinMatrixRequest*>(input.m_msg.get()));
return true; return true;
@ -475,21 +472,9 @@ namespace trezor {
CHECK_AND_ASSERT_THROW_MES(msg, "Empty message"); CHECK_AND_ASSERT_THROW_MES(msg, "Empty message");
MDEBUG("on_passhprase_request"); MDEBUG("on_passhprase_request");
// Backward compatibility, migration clause.
if (msg->has__on_device() && msg->_on_device()){
messages::common::PassphraseAck m;
resp = call_raw(&m);
return;
}
m_seen_passphrase_entry_message = true; m_seen_passphrase_entry_message = true;
bool on_device = true; bool on_device = false;
if (msg->has__on_device() && !msg->_on_device()){ if (m_features){
on_device = false; // do not enter on device, old devices.
}
if (on_device && m_features && m_features->capabilities_size() > 0){
on_device = false;
for (auto it = m_features->capabilities().begin(); it != m_features->capabilities().end(); it++) { for (auto it = m_features->capabilities().begin(); it != m_features->capabilities().end(); it++) {
if (*it == messages::management::Features::Capability_PassphraseEntry){ if (*it == messages::management::Features::Capability_PassphraseEntry){
on_device = true; on_device = true;
@ -526,18 +511,6 @@ namespace trezor {
resp = call_raw(&m); resp = call_raw(&m);
} }
void device_trezor_base::on_passphrase_state_request(GenericMessage & resp, const messages::common::Deprecated_PassphraseStateRequest * msg)
{
MDEBUG("on_passhprase_state_request");
CHECK_AND_ASSERT_THROW_MES(msg, "Empty message");
if (msg->has_state()) {
m_device_session_id = msg->state();
}
messages::common::Deprecated_PassphraseStateAck m;
resp = call_raw(&m);
}
#ifdef WITH_TREZOR_DEBUGGING #ifdef WITH_TREZOR_DEBUGGING
void device_trezor_base::wipe_device() void device_trezor_base::wipe_device()
{ {

View File

@ -100,7 +100,7 @@ namespace trezor {
boost::optional<epee::wipeable_string> m_passphrase; boost::optional<epee::wipeable_string> m_passphrase;
messages::MessageType m_last_msg_type; messages::MessageType m_last_msg_type;
cryptonote::network_type network_type; cryptonote::network_type m_network_type;
bool m_reply_with_empty_passphrase; bool m_reply_with_empty_passphrase;
bool m_always_use_empty_passphrase; bool m_always_use_empty_passphrase;
bool m_seen_passphrase_entry_message; bool m_seen_passphrase_entry_message;
@ -227,9 +227,9 @@ namespace trezor {
} }
if (network_type){ if (network_type){
msg->set_network_type(static_cast<uint32_t>(network_type.get())); msg->set_network_type(static_cast<messages::monero::MoneroNetworkType>(network_type.get()));
} else { } else {
msg->set_network_type(static_cast<uint32_t>(this->network_type)); msg->set_network_type(static_cast<messages::monero::MoneroNetworkType>(this->m_network_type));
} }
} }
@ -318,7 +318,6 @@ namespace trezor {
void on_button_pressed(); void on_button_pressed();
void on_pin_request(GenericMessage & resp, const messages::common::PinMatrixRequest * msg); void on_pin_request(GenericMessage & resp, const messages::common::PinMatrixRequest * msg);
void on_passphrase_request(GenericMessage & resp, const messages::common::PassphraseRequest * msg); void on_passphrase_request(GenericMessage & resp, const messages::common::PassphraseRequest * msg);
void on_passphrase_state_request(GenericMessage & resp, const messages::common::Deprecated_PassphraseStateRequest * msg);
#ifdef WITH_TREZOR_DEBUGGING #ifdef WITH_TREZOR_DEBUGGING
void set_debug(bool debug){ void set_debug(bool debug){

View File

@ -67,7 +67,7 @@ namespace trezor{
void DebugLink::input_button(bool button){ void DebugLink::input_button(bool button){
messages::debug::DebugLinkDecision decision; messages::debug::DebugLinkDecision decision;
decision.set_yes_no(button); decision.set_button(button ? messages::debug::DebugLinkDecision_DebugButton_YES : messages::debug::DebugLinkDecision_DebugButton_NO);
call(decision, boost::none, true); call(decision, boost::none, true);
} }

View File

@ -154,6 +154,7 @@ namespace trezor{
// Helpers // Helpers
// //
#define PROTO_MAGIC_SIZE 3
#define PROTO_HEADER_SIZE 6 #define PROTO_HEADER_SIZE 6
static size_t message_size(const google::protobuf::Message &req){ static size_t message_size(const google::protobuf::Message &req){
@ -193,7 +194,7 @@ namespace trezor{
} }
serialize_message_header(buff, msg_wire_num, msg_size); serialize_message_header(buff, msg_wire_num, msg_size);
if (!req.SerializeToArray(buff + 6, msg_size)){ if (!req.SerializeToArray(buff + PROTO_HEADER_SIZE, msg_size)){
throw exc::EncodingException("Message serialization error"); throw exc::EncodingException("Message serialization error");
} }
} }
@ -252,16 +253,16 @@ namespace trezor{
throw exc::CommunicationException("Read chunk has invalid size"); throw exc::CommunicationException("Read chunk has invalid size");
} }
if (memcmp(chunk_buff_raw, "?##", 3) != 0){ if (memcmp(chunk_buff_raw, "?##", PROTO_MAGIC_SIZE) != 0){
throw exc::CommunicationException("Malformed chunk"); throw exc::CommunicationException("Malformed chunk");
} }
uint16_t tag; uint16_t tag;
uint32_t len; uint32_t len;
nread -= 3 + 6; nread -= PROTO_MAGIC_SIZE + PROTO_HEADER_SIZE;
deserialize_message_header(chunk_buff_raw + 3, tag, len); deserialize_message_header(chunk_buff_raw + PROTO_MAGIC_SIZE, tag, len);
epee::wipeable_string data_acc(chunk_buff_raw + 3 + 6, nread); epee::wipeable_string data_acc(chunk_buff_raw + PROTO_MAGIC_SIZE + PROTO_HEADER_SIZE, nread);
data_acc.reserve(len); data_acc.reserve(len);
while(nread < len){ while(nread < len){
@ -482,7 +483,7 @@ namespace trezor{
uint16_t msg_tag; uint16_t msg_tag;
uint32_t msg_len; uint32_t msg_len;
deserialize_message_header(bin_data->data(), msg_tag, msg_len); deserialize_message_header(bin_data->data(), msg_tag, msg_len);
if (bin_data->size() != msg_len + 6){ if (bin_data->size() != msg_len + PROTO_HEADER_SIZE){
throw exc::CommunicationException("Response is not well hexcoded"); throw exc::CommunicationException("Response is not well hexcoded");
} }
@ -491,7 +492,7 @@ namespace trezor{
} }
std::shared_ptr<google::protobuf::Message> msg_wrap(MessageMapper::get_message(msg_tag)); std::shared_ptr<google::protobuf::Message> msg_wrap(MessageMapper::get_message(msg_tag));
if (!msg_wrap->ParseFromArray(bin_data->data() + 6, msg_len)){ if (!msg_wrap->ParseFromArray(bin_data->data() + PROTO_HEADER_SIZE, msg_len)){
throw exc::EncodingException("Response is not well hexcoded"); throw exc::EncodingException("Response is not well hexcoded");
} }
msg = msg_wrap; msg = msg_wrap;

View File

@ -172,21 +172,21 @@ bool gen_block_reward::generate(std::vector<test_event_entry>& events) const
return false; return false;
// Test: fee increases block reward // Test: fee increases block reward
transaction tx_0(construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 3 * TESTS_DEFAULT_FEE)); transaction tx_0(construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 3 * TESTS_DEFAULT_FEE));
MAKE_NEXT_BLOCK_TX1(events, blk_6, blk_5r, miner_account, tx_0); MAKE_NEXT_BLOCK_TX1(events, blk_6, blk_5r, miner_account, tx_0);
DO_CALLBACK(events, "mark_checked_block"); DO_CALLBACK(events, "mark_checked_block");
// Test: fee from all block transactions increase block reward // Test: fee from all block transactions increase block reward
std::list<transaction> txs_0; std::list<transaction> txs_0;
txs_0.push_back(construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 5 * TESTS_DEFAULT_FEE)); txs_0.push_back(construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 5 * TESTS_DEFAULT_FEE));
txs_0.push_back(construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 7 * TESTS_DEFAULT_FEE)); txs_0.push_back(construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 7 * TESTS_DEFAULT_FEE));
MAKE_NEXT_BLOCK_TX_LIST(events, blk_7, blk_6, miner_account, txs_0); MAKE_NEXT_BLOCK_TX_LIST(events, blk_7, blk_6, miner_account, txs_0);
DO_CALLBACK(events, "mark_checked_block"); DO_CALLBACK(events, "mark_checked_block");
// Test: block reward == transactions fee // Test: block reward == transactions fee
{ {
transaction tx_1 = construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 11 * TESTS_DEFAULT_FEE); transaction tx_1 = construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 11 * TESTS_DEFAULT_FEE);
transaction tx_2 = construct_tx_with_fee(events, blk_5, miner_account, bob_account, MK_COINS(1), 13 * TESTS_DEFAULT_FEE); transaction tx_2 = construct_tx_with_fee(events, blk_5r, miner_account, bob_account, MK_COINS(1), 13 * TESTS_DEFAULT_FEE);
size_t txs_1_weight = get_transaction_weight(tx_1) + get_transaction_weight(tx_2); size_t txs_1_weight = get_transaction_weight(tx_1) + get_transaction_weight(tx_2);
uint64_t txs_fee = get_tx_fee(tx_1) + get_tx_fee(tx_2); uint64_t txs_fee = get_tx_fee(tx_1) + get_tx_fee(tx_2);

View File

@ -580,7 +580,7 @@ bool gen_block_invalid_binary_format::generate(std::vector<test_event_entry>& ev
while (diffic < 1500); while (diffic < 1500);
blk_last = boost::get<block>(events.back()); blk_last = boost::get<block>(events.back());
MAKE_TX(events, tx_0, miner_account, miner_account, MK_COINS(30), boost::get<block>(events[1])); MAKE_TX(events, tx_0, miner_account, miner_account, MK_COINS(30), blk_last);
DO_CALLBACK(events, "corrupt_blocks_boundary"); DO_CALLBACK(events, "corrupt_blocks_boundary");
block blk_test; block blk_test;

View File

@ -114,9 +114,9 @@ bool gen_simple_chain_split_1::generate(std::vector<test_event_entry> &events) c
REWIND_BLOCKS(events, blk_23r, blk_23, first_miner_account); // 30...N1 REWIND_BLOCKS(events, blk_23r, blk_23, first_miner_account); // 30...N1
GENERATE_ACCOUNT(alice); GENERATE_ACCOUNT(alice);
MAKE_TX(events, tx_0, first_miner_account, alice, MK_COINS(10), blk_23); // N1+1 MAKE_TX(events, tx_0, first_miner_account, alice, MK_COINS(10), blk_23r); // N1+1
MAKE_TX(events, tx_1, first_miner_account, alice, MK_COINS(20), blk_23); // N1+2 MAKE_TX(events, tx_1, first_miner_account, alice, MK_COINS(20), blk_23r); // N1+2
MAKE_TX(events, tx_2, first_miner_account, alice, MK_COINS(30), blk_23); // N1+3 MAKE_TX(events, tx_2, first_miner_account, alice, MK_COINS(30), blk_23r); // N1+3
DO_CALLBACK(events, "check_mempool_1"); // N1+4 DO_CALLBACK(events, "check_mempool_1"); // N1+4
MAKE_NEXT_BLOCK_TX1(events, blk_24, blk_23r, first_miner_account, tx_0); // N1+5 MAKE_NEXT_BLOCK_TX1(events, blk_24, blk_23r, first_miner_account, tx_0); // N1+5
DO_CALLBACK(events, "check_mempool_2"); // N1+6 DO_CALLBACK(events, "check_mempool_2"); // N1+6

View File

@ -72,37 +72,37 @@ bool gen_chain_switch_1::generate(std::vector<test_event_entry>& events) const
MAKE_ACCOUNT(events, recipient_account_3); // 3 MAKE_ACCOUNT(events, recipient_account_3); // 3
MAKE_ACCOUNT(events, recipient_account_4); // 4 MAKE_ACCOUNT(events, recipient_account_4); // 4
REWIND_BLOCKS(events, blk_0r, blk_0, miner_account) // <N blocks> REWIND_BLOCKS(events, blk_0r, blk_0, miner_account) // <N blocks>
MAKE_TX(events, tx_00, miner_account, recipient_account_1, MK_COINS(5), blk_0); // 5 + N MAKE_TX(events, tx_00, miner_account, recipient_account_1, MK_COINS(5), blk_0r); // 5 + N
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_account, tx_00); // 6 + N MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_account, tx_00); // 6 + N
MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_account); // 7 + N MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_account); // 7 + N
REWIND_BLOCKS(events, blk_2r, blk_2, miner_account) // <N blocks> REWIND_BLOCKS(events, blk_2r, blk_2, miner_account) // <N blocks>
// Transactions to test account balances after switch // Transactions to test account balances after switch
MAKE_TX_LIST_START(events, txs_blk_3, miner_account, recipient_account_2, MK_COINS(7), blk_2); // 8 + 2N MAKE_TX_LIST_START(events, txs_blk_3, miner_account, recipient_account_2, MK_COINS(7), blk_2r); // 8 + 2N
MAKE_TX_LIST_START(events, txs_blk_4, miner_account, recipient_account_3, MK_COINS(11), blk_2); // 9 + 2N MAKE_TX_LIST_START(events, txs_blk_4, miner_account, recipient_account_3, MK_COINS(11), blk_2r); // 9 + 2N
MAKE_TX_LIST_START(events, txs_blk_5, miner_account, recipient_account_4, MK_COINS(13), blk_2); // 10 + 2N MAKE_TX_LIST_START(events, txs_blk_5, miner_account, recipient_account_4, MK_COINS(13), blk_2r); // 10 + 2N
std::list<transaction> txs_blk_6; std::list<transaction> txs_blk_6;
txs_blk_6.push_back(txs_blk_4.front()); txs_blk_6.push_back(txs_blk_4.front());
// Transactions, that has different order in alt block chains // Transactions, that has different order in alt block chains
MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_1, MK_COINS(1), blk_2); // 11 + 2N MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_1, MK_COINS(1), blk_2r); // 11 + 2N
txs_blk_5.push_back(txs_blk_3.back()); txs_blk_5.push_back(txs_blk_3.back());
MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_1, MK_COINS(2), blk_2); // 12 + 2N MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_1, MK_COINS(2), blk_2r); // 12 + 2N
txs_blk_6.push_back(txs_blk_3.back()); txs_blk_6.push_back(txs_blk_3.back());
MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_2, MK_COINS(1), blk_2); // 13 + 2N MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_2, MK_COINS(1), blk_2r); // 13 + 2N
txs_blk_5.push_back(txs_blk_3.back()); txs_blk_5.push_back(txs_blk_3.back());
MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_2, MK_COINS(2), blk_2); // 14 + 2N MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_2, MK_COINS(2), blk_2r); // 14 + 2N
txs_blk_5.push_back(txs_blk_4.back()); txs_blk_5.push_back(txs_blk_4.back());
MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_3, MK_COINS(1), blk_2); // 15 + 2N MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_3, MK_COINS(1), blk_2r); // 15 + 2N
txs_blk_6.push_back(txs_blk_3.back()); txs_blk_6.push_back(txs_blk_3.back());
MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_3, MK_COINS(2), blk_2); // 16 + 2N MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_3, MK_COINS(2), blk_2r); // 16 + 2N
txs_blk_5.push_back(txs_blk_4.back()); txs_blk_5.push_back(txs_blk_4.back());
MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_4, MK_COINS(1), blk_2); // 17 + 2N MAKE_TX_LIST(events, txs_blk_4, miner_account, recipient_account_4, MK_COINS(1), blk_2r); // 17 + 2N
txs_blk_5.push_back(txs_blk_4.back()); txs_blk_5.push_back(txs_blk_4.back());
MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_4, MK_COINS(2), blk_2); // 18 + 2N MAKE_TX_LIST(events, txs_blk_3, miner_account, recipient_account_4, MK_COINS(2), blk_2r); // 18 + 2N
txs_blk_6.push_back(txs_blk_3.back()); txs_blk_6.push_back(txs_blk_3.back());
MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner_account, txs_blk_3); // 19 + 2N MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner_account, txs_blk_3); // 19 + 2N

View File

@ -504,7 +504,7 @@ bool init_spent_output_indices(map_output_idx_t& outs, map_output_t& outs_mine,
return true; return true;
} }
bool fill_output_entries(std::vector<output_index>& out_indices, size_t sender_out, size_t nmix, size_t& real_entry_idx, std::vector<tx_source_entry::output_entry>& output_entries) bool fill_output_entries(std::vector<output_index>& out_indices, size_t sender_out, size_t nmix, size_t& real_entry_idx, std::vector<tx_source_entry::output_entry>& output_entries, uint64_t cur_height, const boost::optional<fnc_accept_output_t>& fnc_accept = boost::none)
{ {
if (out_indices.size() <= nmix) if (out_indices.size() <= nmix)
return false; return false;
@ -516,6 +516,10 @@ bool fill_output_entries(std::vector<output_index>& out_indices, size_t sender_o
const output_index& oi = out_indices[i]; const output_index& oi = out_indices[i];
if (oi.spent) if (oi.spent)
continue; continue;
if (oi.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && oi.unlock_time > cur_height + 1)
continue;
if (fnc_accept && !(fnc_accept.get())({.oi=oi, .cur_height=cur_height}))
continue;
bool append = false; bool append = false;
if (i == sender_out) if (i == sender_out)
@ -542,7 +546,8 @@ bool fill_output_entries(std::vector<output_index>& out_indices, size_t sender_o
} }
bool fill_tx_sources(std::vector<tx_source_entry>& sources, const std::vector<test_event_entry>& events, bool fill_tx_sources(std::vector<tx_source_entry>& sources, const std::vector<test_event_entry>& events,
const block& blk_head, const cryptonote::account_base& from, uint64_t amount, size_t nmix) const block& blk_head, const cryptonote::account_base& from, uint64_t amount, size_t nmix,
bool check_unlock_time, const boost::optional<fnc_accept_output_t>& fnc_accept)
{ {
map_output_idx_t outs; map_output_idx_t outs;
map_output_t outs_mine; map_output_t outs_mine;
@ -559,6 +564,7 @@ bool fill_tx_sources(std::vector<tx_source_entry>& sources, const std::vector<te
return false; return false;
// Iterate in reverse is more efficiency // Iterate in reverse is more efficiency
uint64_t head_height = check_unlock_time ? get_block_height(blk_head) : std::numeric_limits<uint64_t>::max() - 1;
uint64_t sources_amount = 0; uint64_t sources_amount = 0;
bool sources_found = false; bool sources_found = false;
BOOST_REVERSE_FOREACH(const map_output_t::value_type o, outs_mine) BOOST_REVERSE_FOREACH(const map_output_t::value_type o, outs_mine)
@ -571,13 +577,17 @@ bool fill_tx_sources(std::vector<tx_source_entry>& sources, const std::vector<te
continue; continue;
if (oi.rct) if (oi.rct)
continue; continue;
if (oi.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && oi.unlock_time > head_height + 1)
continue;
if (fnc_accept && !(fnc_accept.get())({.oi=oi, .cur_height=head_height}))
continue;
cryptonote::tx_source_entry ts; cryptonote::tx_source_entry ts;
ts.amount = oi.amount; ts.amount = oi.amount;
ts.real_output_in_tx_index = oi.out_no; ts.real_output_in_tx_index = oi.out_no;
ts.real_out_tx_key = get_tx_pub_key_from_extra(*oi.p_tx); // incoming tx public key ts.real_out_tx_key = get_tx_pub_key_from_extra(*oi.p_tx); // incoming tx public key
size_t realOutput; size_t realOutput;
if (!fill_output_entries(outs[o.first], sender_out, nmix, realOutput, ts.outputs)) if (!fill_output_entries(outs[o.first], sender_out, nmix, realOutput, ts.outputs, head_height, fnc_accept))
continue; continue;
ts.real_output = realOutput; ts.real_output = realOutput;
@ -692,7 +702,7 @@ void block_tracker::global_indices(const cryptonote::transaction *tx, std::vecto
} }
} }
void block_tracker::get_fake_outs(size_t num_outs, uint64_t amount, uint64_t global_index, uint64_t cur_height, std::vector<get_outs_entry> &outs){ void block_tracker::get_fake_outs(size_t num_outs, uint64_t amount, uint64_t global_index, uint64_t cur_height, std::vector<get_outs_entry> &outs, const boost::optional<fnc_accept_output_t>& fnc_accept){
auto & vct = m_outs[amount]; auto & vct = m_outs[amount];
const size_t n_outs = vct.size(); const size_t n_outs = vct.size();
CHECK_AND_ASSERT_THROW_MES(n_outs > 0, "n_outs is 0"); CHECK_AND_ASSERT_THROW_MES(n_outs > 0, "n_outs is 0");
@ -717,15 +727,16 @@ void block_tracker::get_fake_outs(size_t num_outs, uint64_t amount, uint64_t glo
continue; continue;
if (oi.out.type() != typeid(cryptonote::txout_to_key)) if (oi.out.type() != typeid(cryptonote::txout_to_key))
continue; continue;
if (oi.unlock_time > cur_height) if (oi.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && oi.unlock_time > cur_height + 1)
continue; continue;
if (used.find(oi_idx) != used.end()) if (used.find(oi_idx) != used.end())
continue; continue;
if (fnc_accept && !(fnc_accept.get())({.oi=oi, .cur_height=cur_height}))
continue;
rct::key comm = oi.commitment(); rct::key comm = oi.commitment();
auto out = boost::get<txout_to_key>(oi.out); auto out = boost::get<txout_to_key>(oi.out);
auto item = std::make_tuple(oi.idx, out.key, comm); outs.emplace_back(oi.idx, out.key, comm);
outs.push_back(item);
used.insert(oi_idx); used.insert(oi_idx);
} }
} }
@ -924,13 +935,14 @@ void fill_tx_destinations(const var_addr_t& from, const cryptonote::account_publ
void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const block& blk_head, void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const block& blk_head,
const cryptonote::account_base& from, const cryptonote::account_public_address& to, const cryptonote::account_base& from, const cryptonote::account_public_address& to,
uint64_t amount, uint64_t fee, size_t nmix, std::vector<tx_source_entry>& sources, uint64_t amount, uint64_t fee, size_t nmix, std::vector<tx_source_entry>& sources,
std::vector<tx_destination_entry>& destinations) std::vector<tx_destination_entry>& destinations, bool check_unlock_time,
const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept)
{ {
sources.clear(); sources.clear();
destinations.clear(); destinations.clear();
if (!fill_tx_sources(sources, events, blk_head, from, amount + fee, nmix)) if (!fill_tx_sources(sources, events, blk_head, from, amount + fee, nmix, check_unlock_time, fnc_tx_in_accept))
throw std::runtime_error("couldn't fill transaction sources"); throw tx_construct_tx_fill_error();
fill_tx_destinations(from, to, amount, fee, sources, destinations, false); fill_tx_destinations(from, to, amount, fee, sources, destinations, false);
} }
@ -938,9 +950,10 @@ void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const block& blk_head, void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const block& blk_head,
const cryptonote::account_base& from, const cryptonote::account_base& to, const cryptonote::account_base& from, const cryptonote::account_base& to,
uint64_t amount, uint64_t fee, size_t nmix, std::vector<tx_source_entry>& sources, uint64_t amount, uint64_t fee, size_t nmix, std::vector<tx_source_entry>& sources,
std::vector<tx_destination_entry>& destinations) std::vector<tx_destination_entry>& destinations, bool check_unlock_time,
const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept)
{ {
fill_tx_sources_and_destinations(events, blk_head, from, to.get_keys().m_account_address, amount, fee, nmix, sources, destinations); fill_tx_sources_and_destinations(events, blk_head, from, to.get_keys().m_account_address, amount, fee, nmix, sources, destinations, check_unlock_time, fnc_tx_in_accept);
} }
cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr, uint64_t amount) cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr, uint64_t amount)
@ -952,10 +965,14 @@ cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr
return de; return de;
} }
std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1, uint64_t am1) std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1, uint64_t am1, size_t repeat)
{ {
std::vector<cryptonote::tx_destination_entry> res; std::vector<cryptonote::tx_destination_entry> res;
res.push_back(build_dst(to1, sub1, am1)); res.reserve(repeat);
for(size_t i = 0; i < repeat; ++i)
{
res.emplace_back(build_dst(to1, sub1, am1));
}
return res; return res;
} }
@ -1019,25 +1036,27 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins
bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, const cryptonote::block& blk_head, bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, const cryptonote::block& blk_head,
const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount, const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount,
uint64_t fee, size_t nmix, bool rct, rct::RangeProofType range_proof_type, int bp_version) uint64_t fee, size_t nmix, bool rct, rct::RangeProofType range_proof_type, int bp_version,
bool check_unlock_time, const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept)
{ {
vector<tx_source_entry> sources; vector<tx_source_entry> sources;
vector<tx_destination_entry> destinations; vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_head, from, get_address(to), amount, fee, nmix, sources, destinations); fill_tx_sources_and_destinations(events, blk_head, from, get_address(to), amount, fee, nmix, sources, destinations, check_unlock_time, fnc_tx_in_accept);
return construct_tx_rct(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version); return construct_tx_rct(from.get_keys(), sources, destinations, from.get_keys().m_account_address, std::vector<uint8_t>(), tx, 0, rct, range_proof_type, bp_version);
} }
bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, const cryptonote::block& blk_head, bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, const cryptonote::block& blk_head,
const cryptonote::account_base& from, std::vector<cryptonote::tx_destination_entry> destinations, const cryptonote::account_base& from, const std::vector<cryptonote::tx_destination_entry>& destinations,
uint64_t fee, size_t nmix, bool rct, rct::RangeProofType range_proof_type, int bp_version) uint64_t fee, size_t nmix, bool rct, rct::RangeProofType range_proof_type, int bp_version,
bool check_unlock_time, const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept)
{ {
vector<tx_source_entry> sources; vector<tx_source_entry> sources;
vector<tx_destination_entry> destinations_all; vector<tx_destination_entry> destinations_all;
uint64_t amount = sum_amount(destinations); uint64_t amount = sum_amount(destinations);
if (!fill_tx_sources(sources, events, blk_head, from, amount + fee, nmix)) if (!fill_tx_sources(sources, events, blk_head, from, amount + fee, nmix, check_unlock_time, fnc_tx_in_accept))
throw std::runtime_error("couldn't fill transaction sources"); throw tx_construct_tx_fill_error();
fill_tx_destinations(from, destinations, fee, sources, destinations_all, false); fill_tx_destinations(from, destinations, fee, sources, destinations_all, false);

View File

@ -372,6 +372,13 @@ typedef struct {
uint64_t amount; uint64_t amount;
} dest_wrapper_t; } dest_wrapper_t;
typedef struct {
const output_index &oi;
uint64_t cur_height;
} fnc_accept_output_crate_t;
typedef std::function<bool(const fnc_accept_output_crate_t &info)> fnc_accept_output_t;
// Daemon functionality // Daemon functionality
class block_tracker class block_tracker
{ {
@ -388,7 +395,7 @@ public:
void process(const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t& mtx); void process(const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t& mtx);
void process(const cryptonote::block* blk, const cryptonote::transaction * tx, size_t i); void process(const cryptonote::block* blk, const cryptonote::transaction * tx, size_t i);
void global_indices(const cryptonote::transaction *tx, std::vector<uint64_t> &indices); void global_indices(const cryptonote::transaction *tx, std::vector<uint64_t> &indices);
void get_fake_outs(size_t num_outs, uint64_t amount, uint64_t global_index, uint64_t cur_height, std::vector<get_outs_entry> &outs); void get_fake_outs(size_t num_outs, uint64_t amount, uint64_t global_index, uint64_t cur_height, std::vector<get_outs_entry> &outs, const boost::optional<fnc_accept_output_t>& fnc_accept = boost::none);
std::string dump_data(); std::string dump_data();
void dump_data(const std::string & fname); void dump_data(const std::string & fname);
@ -405,6 +412,19 @@ private:
} }
}; };
class tx_construct_error : public std::runtime_error
{
public:
tx_construct_error(const char *s) : runtime_error(s) { }
};
class tx_construct_tx_fill_error : public tx_construct_error
{
public:
tx_construct_tx_fill_error() : tx_construct_error("Couldn't fill transaction sources") { }
tx_construct_tx_fill_error(const char *s) : tx_construct_error(s) { }
};
std::string dump_data(const cryptonote::transaction &tx); std::string dump_data(const cryptonote::transaction &tx);
cryptonote::account_public_address get_address(const var_addr_t& inp); cryptonote::account_public_address get_address(const var_addr_t& inp);
cryptonote::account_public_address get_address(const cryptonote::account_public_address& inp); cryptonote::account_public_address get_address(const cryptonote::account_public_address& inp);
@ -416,7 +436,7 @@ inline cryptonote::difficulty_type get_test_difficulty(const boost::optional<uin
inline uint64_t current_difficulty_window(const boost::optional<uint8_t>& hf_ver=boost::none){ return !hf_ver || hf_ver.get() <= 1 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2; } inline uint64_t current_difficulty_window(const boost::optional<uint8_t>& hf_ver=boost::none){ return !hf_ver || hf_ver.get() <= 1 ? DIFFICULTY_TARGET_V1 : DIFFICULTY_TARGET_V2; }
cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr=false, uint64_t amount=0); cryptonote::tx_destination_entry build_dst(const var_addr_t& to, bool is_subaddr=false, uint64_t amount=0);
std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1=false, uint64_t am1=0); std::vector<cryptonote::tx_destination_entry> build_dsts(const var_addr_t& to1, bool sub1=false, uint64_t am1=0, size_t repeat=1);
std::vector<cryptonote::tx_destination_entry> build_dsts(std::initializer_list<dest_wrapper_t> inps); std::vector<cryptonote::tx_destination_entry> build_dsts(std::initializer_list<dest_wrapper_t> inps);
uint64_t sum_amount(const std::vector<cryptonote::tx_destination_entry>& destinations); uint64_t sum_amount(const std::vector<cryptonote::tx_destination_entry>& destinations);
uint64_t sum_amount(const std::vector<cryptonote::tx_source_entry>& sources); uint64_t sum_amount(const std::vector<cryptonote::tx_source_entry>& sources);
@ -428,11 +448,13 @@ bool construct_miner_tx_manually(size_t height, uint64_t already_generated_coins
bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx,
const cryptonote::block& blk_head, const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount, const cryptonote::block& blk_head, const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount,
uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0); uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0,
bool check_unlock_time = true, const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept = boost::none);
bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, const cryptonote::block& blk_head, bool construct_tx_to_key(const std::vector<test_event_entry>& events, cryptonote::transaction& tx, const cryptonote::block& blk_head,
const cryptonote::account_base& from, std::vector<cryptonote::tx_destination_entry> destinations, const cryptonote::account_base& from, const std::vector<cryptonote::tx_destination_entry>& destinations,
uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0); uint64_t fee, size_t nmix, bool rct=false, rct::RangeProofType range_proof_type=rct::RangeProofBorromean, int bp_version = 0,
bool check_unlock_time = true, const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept = boost::none);
bool construct_tx_to_key(cryptonote::transaction& tx, const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount, bool construct_tx_to_key(cryptonote::transaction& tx, const cryptonote::account_base& from, const var_addr_t& to, uint64_t amount,
std::vector<cryptonote::tx_source_entry> &sources, std::vector<cryptonote::tx_source_entry> &sources,
@ -463,6 +485,10 @@ bool trim_block_chain(std::vector<const cryptonote::block*>& blockchain, const c
bool find_block_chain(const std::vector<test_event_entry>& events, std::vector<cryptonote::block>& blockchain, map_hash2tx_t& mtx, const crypto::hash& head); bool find_block_chain(const std::vector<test_event_entry>& events, std::vector<cryptonote::block>& blockchain, map_hash2tx_t& mtx, const crypto::hash& head);
bool find_block_chain(const std::vector<test_event_entry>& events, std::vector<const cryptonote::block*>& blockchain, map_hash2tx_t& mtx, const crypto::hash& head); bool find_block_chain(const std::vector<test_event_entry>& events, std::vector<const cryptonote::block*>& blockchain, map_hash2tx_t& mtx, const crypto::hash& head);
bool fill_tx_sources(std::vector<cryptonote::tx_source_entry>& sources, const std::vector<test_event_entry>& events,
const cryptonote::block& blk_head, const cryptonote::account_base& from, uint64_t amount, size_t nmix,
bool check_unlock_time = true, const boost::optional<fnc_accept_output_t>& fnc_accept = boost::none);
void fill_tx_destinations(const var_addr_t& from, const cryptonote::account_public_address& to, void fill_tx_destinations(const var_addr_t& from, const cryptonote::account_public_address& to,
uint64_t amount, uint64_t fee, uint64_t amount, uint64_t fee,
const std::vector<cryptonote::tx_source_entry> &sources, const std::vector<cryptonote::tx_source_entry> &sources,
@ -486,13 +512,17 @@ void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& event
const cryptonote::account_base& from, const cryptonote::account_public_address& to, const cryptonote::account_base& from, const cryptonote::account_public_address& to,
uint64_t amount, uint64_t fee, size_t nmix, uint64_t amount, uint64_t fee, size_t nmix,
std::vector<cryptonote::tx_source_entry>& sources, std::vector<cryptonote::tx_source_entry>& sources,
std::vector<cryptonote::tx_destination_entry>& destinations); std::vector<cryptonote::tx_destination_entry>& destinations,
bool check_unlock_time = true,
const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept = boost::none);
void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, void fill_tx_sources_and_destinations(const std::vector<test_event_entry>& events, const cryptonote::block& blk_head,
const cryptonote::account_base& from, const cryptonote::account_base& to, const cryptonote::account_base& from, const cryptonote::account_base& to,
uint64_t amount, uint64_t fee, size_t nmix, uint64_t amount, uint64_t fee, size_t nmix,
std::vector<cryptonote::tx_source_entry>& sources, std::vector<cryptonote::tx_source_entry>& sources,
std::vector<cryptonote::tx_destination_entry>& destinations); std::vector<cryptonote::tx_destination_entry>& destinations,
bool check_unlock_time = true,
const boost::optional<fnc_accept_output_t>& fnc_tx_in_accept = boost::none);
uint64_t get_balance(const cryptonote::account_base& addr, const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx); uint64_t get_balance(const cryptonote::account_base& addr, const std::vector<cryptonote::block>& blockchain, const map_hash2tx_t& mtx);
@ -883,15 +913,6 @@ inline bool do_replay_file(const std::string& filename)
} \ } \
VEC_EVENTS.push_back(BLK_NAME); VEC_EVENTS.push_back(BLK_NAME);
#define MAKE_NEXT_BLOCK_TX1_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TX1, HF) \
cryptonote::block BLK_NAME; \
{ \
std::list<cryptonote::transaction> tx_list; \
tx_list.push_back(TX1); \
generator.construct_block(BLK_NAME, PREV_BLOCK, MINER_ACC, tx_list, HF); \
} \
VEC_EVENTS.push_back(BLK_NAME);
#define MAKE_NEXT_BLOCK_TX_LIST(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST) \ #define MAKE_NEXT_BLOCK_TX_LIST(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST) \
cryptonote::block BLK_NAME; \ cryptonote::block BLK_NAME; \
generator.construct_block(BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST); \ generator.construct_block(BLK_NAME, PREV_BLOCK, MINER_ACC, TXLIST); \
@ -916,18 +937,12 @@ inline bool do_replay_file(const std::string& filename)
#define REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT) REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT, boost::none) #define REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT) REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, COUNT, boost::none)
#define REWIND_BLOCKS(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC) REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW) #define REWIND_BLOCKS(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC) REWIND_BLOCKS_N(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW)
#define REWIND_BLOCKS_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, HF) REWIND_BLOCKS_N_HF(VEC_EVENTS, BLK_NAME, PREV_BLOCK, MINER_ACC, CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW, HF)
#define MAKE_TX_MIX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \ #define MAKE_TX_MIX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
cryptonote::transaction TX_NAME; \ cryptonote::transaction TX_NAME; \
construct_tx_to_key(VEC_EVENTS, TX_NAME, HEAD, FROM, TO, AMOUNT, TESTS_DEFAULT_FEE, NMIX); \ construct_tx_to_key(VEC_EVENTS, TX_NAME, HEAD, FROM, TO, AMOUNT, TESTS_DEFAULT_FEE, NMIX); \
VEC_EVENTS.push_back(TX_NAME); VEC_EVENTS.push_back(TX_NAME);
#define MAKE_TX_MIX_RCT(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
cryptonote::transaction TX_NAME; \
construct_tx_to_key(VEC_EVENTS, TX_NAME, HEAD, FROM, TO, AMOUNT, TESTS_DEFAULT_FEE, NMIX, true, rct::RangeProofPaddedBulletproof); \
VEC_EVENTS.push_back(TX_NAME);
#define MAKE_TX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, HEAD) MAKE_TX_MIX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, 0, HEAD) #define MAKE_TX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, HEAD) MAKE_TX_MIX(VEC_EVENTS, TX_NAME, FROM, TO, AMOUNT, 0, HEAD)
#define MAKE_TX_MIX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \ #define MAKE_TX_MIX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
@ -938,36 +953,12 @@ inline bool do_replay_file(const std::string& filename)
VEC_EVENTS.push_back(t); \ VEC_EVENTS.push_back(t); \
} }
#define MAKE_TX_MIX_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
MAKE_TX_MIX_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD, rct::RangeProofPaddedBulletproof, 1)
#define MAKE_TX_MIX_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD, RCT_TYPE, BP_VER) \
{ \
cryptonote::transaction t; \
construct_tx_to_key(VEC_EVENTS, t, HEAD, FROM, TO, AMOUNT, TESTS_DEFAULT_FEE, NMIX, true, RCT_TYPE, BP_VER); \
SET_NAME.push_back(t); \
VEC_EVENTS.push_back(t); \
}
#define MAKE_TX_MIX_DEST_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, NMIX, HEAD) \
MAKE_TX_MIX_DEST_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, NMIX, HEAD, rct::RangeProofPaddedBulletproof, 1)
#define MAKE_TX_MIX_DEST_LIST_RCT_EX(VEC_EVENTS, SET_NAME, FROM, TO, NMIX, HEAD, RCT_TYPE, BP_VER) \
{ \
cryptonote::transaction t; \
construct_tx_to_key(VEC_EVENTS, t, HEAD, FROM, TO, TESTS_DEFAULT_FEE, NMIX, true, RCT_TYPE, BP_VER); \
SET_NAME.push_back(t); \
VEC_EVENTS.push_back(t); \
}
#define MAKE_TX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD) MAKE_TX_MIX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, 0, HEAD) #define MAKE_TX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD) MAKE_TX_MIX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, 0, HEAD)
#define MAKE_TX_LIST_START(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD) \ #define MAKE_TX_LIST_START(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD) \
std::list<cryptonote::transaction> SET_NAME; \ std::list<cryptonote::transaction> SET_NAME; \
MAKE_TX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD); MAKE_TX_LIST(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, HEAD);
#define MAKE_TX_LIST_START_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD) \
std::list<cryptonote::transaction> SET_NAME; \
MAKE_TX_MIX_LIST_RCT(VEC_EVENTS, SET_NAME, FROM, TO, AMOUNT, NMIX, HEAD);
#define MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(TX, BLK, HF_VERSION, KEY) \ #define MAKE_MINER_TX_AND_KEY_AT_HF_MANUALLY(TX, BLK, HF_VERSION, KEY) \
transaction TX; \ transaction TX; \
if (!construct_miner_tx_manually(get_block_height(BLK) + 1, generator.get_already_generated_coins(BLK), \ if (!construct_miner_tx_manually(get_block_height(BLK) + 1, generator.get_already_generated_coins(BLK), \

View File

@ -120,18 +120,18 @@ bool gen_simple_chain_001::generate(std::vector<test_event_entry> &events)
std::cout << "BALANCE = " << get_balance(miner, chain, mtx) << std::endl; std::cout << "BALANCE = " << get_balance(miner, chain, mtx) << std::endl;
REWIND_BLOCKS(events, blk_2r, blk_2, miner); REWIND_BLOCKS(events, blk_2r, blk_2, miner);
MAKE_TX_LIST_START(events, txlist_0, miner, alice, MK_COINS(1), blk_2); MAKE_TX_LIST_START(events, txlist_0, miner, alice, MK_COINS(1), blk_2r);
MAKE_TX_LIST(events, txlist_0, miner, alice, MK_COINS(2), blk_2); MAKE_TX_LIST(events, txlist_0, miner, alice, MK_COINS(2), blk_2r);
MAKE_TX_LIST(events, txlist_0, miner, alice, MK_COINS(4), blk_2); MAKE_TX_LIST(events, txlist_0, miner, alice, MK_COINS(4), blk_2r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner, txlist_0); MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner, txlist_0);
REWIND_BLOCKS(events, blk_3r, blk_3, miner); REWIND_BLOCKS(events, blk_3r, blk_3, miner);
MAKE_TX(events, tx_1, miner, alice, MK_COINS(50), blk_3); MAKE_TX(events, tx_1, miner, alice, MK_COINS(50), blk_3r);
MAKE_NEXT_BLOCK_TX1(events, blk_4, blk_3r, miner, tx_1); MAKE_NEXT_BLOCK_TX1(events, blk_4, blk_3r, miner, tx_1);
REWIND_BLOCKS(events, blk_4r, blk_4, miner); REWIND_BLOCKS(events, blk_4r, blk_4, miner);
MAKE_TX(events, tx_2, miner, alice, MK_COINS(50), blk_4); MAKE_TX(events, tx_2, miner, alice, MK_COINS(50), blk_4r);
MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4r, miner, tx_2); MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4r, miner, tx_2);
REWIND_BLOCKS(events, blk_5r, blk_5, miner); REWIND_BLOCKS(events, blk_5r, blk_5, miner);
MAKE_TX(events, tx_3, miner, alice, MK_COINS(50), blk_5); MAKE_TX(events, tx_3, miner, alice, MK_COINS(50), blk_5r);
MAKE_NEXT_BLOCK_TX1(events, blk_6, blk_5r, miner, tx_3); MAKE_NEXT_BLOCK_TX1(events, blk_6, blk_5r, miner, tx_3);
DO_CALLBACK(events, "verify_callback_1"); DO_CALLBACK(events, "verify_callback_1");

View File

@ -144,7 +144,7 @@ public:
MAKE_ACCOUNT(events, bob_account); \ MAKE_ACCOUNT(events, bob_account); \
MAKE_ACCOUNT(events, alice_account); \ MAKE_ACCOUNT(events, alice_account); \
REWIND_BLOCKS(events, blk_0r, blk_0, miner_account); \ REWIND_BLOCKS(events, blk_0r, blk_0, miner_account); \
MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0); \ MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r); \
MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_account, tx_0); \ MAKE_NEXT_BLOCK_TX1(events, blk_1, blk_0r, miner_account, tx_0); \
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account); REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);

View File

@ -126,20 +126,14 @@ bool gen_double_spend_in_tx<txs_keeped_by_block>::generate(std::vector<test_even
DO_CALLBACK(events, "mark_last_valid_block"); DO_CALLBACK(events, "mark_last_valid_block");
std::vector<cryptonote::tx_source_entry> sources; std::vector<cryptonote::tx_source_entry> sources;
cryptonote::tx_source_entry se; CHECK_AND_ASSERT_THROW_MES(fill_tx_sources(sources, events, blk_1r, bob_account, send_amount, 0), "Source find error");
se.amount = tx_0.vout[0].amount;
se.push_output(0, boost::get<cryptonote::txout_to_key>(tx_0.vout[0].target).key, se.amount);
se.real_output = 0;
se.rct = false;
se.real_out_tx_key = get_tx_pub_key_from_extra(tx_0);
se.real_output_in_tx_index = 0;
sources.push_back(se);
// Double spend! // Double spend!
sources.push_back(se); sources.push_back(sources[0]);
cryptonote::tx_destination_entry de; cryptonote::tx_destination_entry de;
de.addr = alice_account.get_keys().m_account_address; de.addr = alice_account.get_keys().m_account_address;
de.amount = 2 * se.amount - TESTS_DEFAULT_FEE; de.amount = 2 * send_amount - TESTS_DEFAULT_FEE;
std::vector<cryptonote::tx_destination_entry> destinations; std::vector<cryptonote::tx_destination_entry> destinations;
destinations.push_back(de); destinations.push_back(de);

View File

@ -123,8 +123,8 @@ bool gen_uint_overflow_1::generate(std::vector<test_event_entry>& events) const
events.push_back(blk_2); events.push_back(blk_2);
REWIND_BLOCKS(events, blk_2r, blk_2, miner_account); REWIND_BLOCKS(events, blk_2r, blk_2, miner_account);
MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MONEY_SUPPLY, blk_2); MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MONEY_SUPPLY, blk_2r);
MAKE_TX_LIST(events, txs_0, miner_account, bob_account, MONEY_SUPPLY, blk_2); MAKE_TX_LIST(events, txs_0, miner_account, bob_account, MONEY_SUPPLY, blk_2r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner_account, txs_0); MAKE_NEXT_BLOCK_TX_LIST(events, blk_3, blk_2r, miner_account, txs_0);
REWIND_BLOCKS(events, blk_3r, blk_3, miner_account); REWIND_BLOCKS(events, blk_3r, blk_3, miner_account);

View File

@ -70,19 +70,19 @@ bool gen_ring_signature_1::generate(std::vector<test_event_entry>& events) const
MAKE_NEXT_BLOCK(events, blk_4, blk_3, miner_account); // 8 MAKE_NEXT_BLOCK(events, blk_4, blk_3, miner_account); // 8
REWIND_BLOCKS(events, blk_5, blk_4, miner_account); // <N blocks> REWIND_BLOCKS(events, blk_5, blk_4, miner_account); // <N blocks>
REWIND_BLOCKS(events, blk_5r, blk_5, miner_account); // <N blocks> REWIND_BLOCKS(events, blk_5r, blk_5, miner_account); // <N blocks>
MAKE_TX_LIST_START(events, txs_blk_6, miner_account, bob_account, MK_COINS(1), blk_5); // 9 + 2N MAKE_TX_LIST_START(events, txs_blk_6, miner_account, bob_account, MK_COINS(1), blk_5r); // 9 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(11) + rnd_11, blk_5); // 10 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(11) + rnd_11, blk_5r); // 10 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(11) + rnd_11, blk_5); // 11 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(11) + rnd_11, blk_5r); // 11 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(20) + rnd_20, blk_5); // 12 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(20) + rnd_20, blk_5r); // 12 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5); // 13 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5r); // 13 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5); // 14 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5r); // 14 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5); // 15 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, bob_account, MK_COINS(29) + rnd_29, blk_5r); // 15 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5); // 16 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5r); // 16 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5); // 17 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5r); // 17 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5); // 18 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5r); // 18 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5); // 19 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(11) + rnd_11, blk_5r); // 19 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(20) + rnd_20, blk_5); // 20 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_1, MK_COINS(20) + rnd_20, blk_5r); // 20 + 2N
MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_2, MK_COINS(20) + rnd_20, blk_5); // 21 + 2N MAKE_TX_LIST(events, txs_blk_6, miner_account, some_account_2, MK_COINS(20) + rnd_20, blk_5r); // 21 + 2N
MAKE_NEXT_BLOCK_TX_LIST(events, blk_6, blk_5r, miner_account, txs_blk_6); // 22 + 2N MAKE_NEXT_BLOCK_TX_LIST(events, blk_6, blk_5r, miner_account, txs_blk_6); // 22 + 2N
DO_CALLBACK(events, "check_balances_1"); // 23 + 2N DO_CALLBACK(events, "check_balances_1"); // 23 + 2N
REWIND_BLOCKS(events, blk_6r, blk_6, miner_account); // <N blocks> REWIND_BLOCKS(events, blk_6r, blk_6, miner_account); // <N blocks>
@ -161,14 +161,14 @@ bool gen_ring_signature_2::generate(std::vector<test_event_entry>& events) const
MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_account); // 4 MAKE_NEXT_BLOCK(events, blk_2, blk_1, miner_account); // 4
MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_account); // 5 MAKE_NEXT_BLOCK(events, blk_3, blk_2, miner_account); // 5
REWIND_BLOCKS(events, blk_3r, blk_3, miner_account); // <N blocks> REWIND_BLOCKS(events, blk_3r, blk_3, miner_account); // <N blocks>
MAKE_TX_LIST_START(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3); // 6 + N MAKE_TX_LIST_START(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3r); // 6 + N
MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3); // 7 + N MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3r); // 7 + N
MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3); // 8 + N MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3r); // 8 + N
MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3); // 9 + N MAKE_TX_LIST(events, txs_blk_4, miner_account, bob_account, MK_COINS(13), blk_3r); // 9 + N
MAKE_NEXT_BLOCK_TX_LIST(events, blk_4, blk_3r, miner_account, txs_blk_4); // 10 + N MAKE_NEXT_BLOCK_TX_LIST(events, blk_4, blk_3r, miner_account, txs_blk_4); // 10 + N
DO_CALLBACK(events, "check_balances_1"); // 11 + N DO_CALLBACK(events, "check_balances_1"); // 11 + N
REWIND_BLOCKS(events, blk_4r, blk_4, miner_account); // <N blocks> REWIND_BLOCKS(events, blk_4r, blk_4, miner_account); // <N blocks>
MAKE_TX_MIX(events, tx_0, bob_account, alice_account, MK_COINS(52) - TESTS_DEFAULT_FEE, 3, blk_4); // 12 + 2N MAKE_TX_MIX(events, tx_0, bob_account, alice_account, MK_COINS(52) - TESTS_DEFAULT_FEE, 3, blk_4r); // 12 + 2N
MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4r, miner_account, tx_0); // 13 + 2N MAKE_NEXT_BLOCK_TX1(events, blk_5, blk_4r, miner_account, tx_0); // 13 + 2N
DO_CALLBACK(events, "check_balances_2"); // 14 + 2N DO_CALLBACK(events, "check_balances_2"); // 14 + 2N

View File

@ -98,7 +98,7 @@ bool txpool_spend_key_public::generate(std::vector<test_event_entry>& events) co
INIT_MEMPOOL_TEST(); INIT_MEMPOOL_TEST();
DO_CALLBACK(events, "check_txpool_spent_keys"); DO_CALLBACK(events, "check_txpool_spent_keys");
MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0); MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_broadcasted_tx_count"); DO_CALLBACK(events, "increase_broadcasted_tx_count");
DO_CALLBACK(events, "increase_all_tx_count"); DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys"); DO_CALLBACK(events, "check_txpool_spent_keys");
@ -112,7 +112,7 @@ bool txpool_spend_key_all::generate(std::vector<test_event_entry>& events)
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_do_not_relay); SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_do_not_relay);
DO_CALLBACK(events, "check_txpool_spent_keys"); DO_CALLBACK(events, "check_txpool_spent_keys");
MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0); MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_all_tx_count"); DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys"); DO_CALLBACK(events, "check_txpool_spent_keys");
@ -502,7 +502,7 @@ bool txpool_double_spend_norelay::generate(std::vector<test_event_entry>& events
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_do_not_relay); SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_do_not_relay);
DO_CALLBACK(events, "mark_no_new"); DO_CALLBACK(events, "mark_no_new");
MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0); MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_all_tx_count"); DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys"); DO_CALLBACK(events, "check_txpool_spent_keys");
@ -539,7 +539,7 @@ bool txpool_double_spend_local::generate(std::vector<test_event_entry>& events)
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_local_relay); SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_local_relay);
DO_CALLBACK(events, "mark_no_new"); DO_CALLBACK(events, "mark_no_new");
MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0); MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_all_tx_count"); DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys"); DO_CALLBACK(events, "check_txpool_spent_keys");
@ -574,7 +574,7 @@ bool txpool_double_spend_keyimage::generate(std::vector<test_event_entry>& event
DO_CALLBACK(events, "mark_no_new"); DO_CALLBACK(events, "mark_no_new");
const std::size_t tx_index1 = events.size(); const std::size_t tx_index1 = events.size();
MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0); MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_stem); SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_stem);
DO_CALLBACK(events, "increase_all_tx_count"); DO_CALLBACK(events, "increase_all_tx_count");
@ -595,7 +595,7 @@ bool txpool_double_spend_keyimage::generate(std::vector<test_event_entry>& event
auto events_copy = events; auto events_copy = events;
events_copy.erase(events_copy.begin() + tx_index1); events_copy.erase(events_copy.begin() + tx_index1);
events_copy.erase(events_copy.begin() + tx_index2 - 1); events_copy.erase(events_copy.begin() + tx_index2 - 1);
MAKE_TX(events_copy, tx_temp, miner_account, bob_account, send_amount, blk_0); MAKE_TX(events_copy, tx_temp, miner_account, bob_account, send_amount, blk_0r);
tx_1 = tx_temp; tx_1 = tx_temp;
} }
@ -616,7 +616,7 @@ bool txpool_stem_loop::generate(std::vector<test_event_entry>& events) const
SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_stem); SET_EVENT_VISITOR_SETT(events, event_visitor_settings::set_txs_stem);
DO_CALLBACK(events, "mark_no_new"); DO_CALLBACK(events, "mark_no_new");
MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0); MAKE_TX(events, tx_0, miner_account, bob_account, send_amount, blk_0r);
DO_CALLBACK(events, "increase_all_tx_count"); DO_CALLBACK(events, "increase_all_tx_count");
DO_CALLBACK(events, "check_txpool_spent_keys"); DO_CALLBACK(events, "check_txpool_spent_keys");

View File

@ -141,7 +141,7 @@ namespace
{ {
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_head, from, to, amount, TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_head, from, to, amount, TESTS_DEFAULT_FEE, 0, sources, destinations, false);
tx_builder builder; tx_builder builder;
builder.step1_init(1, unlock_time); builder.step1_init(1, unlock_time);
@ -191,7 +191,7 @@ bool gen_tx_big_version::generate(std::vector<test_event_entry>& events) const
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder; tx_builder builder;
builder.step1_init(1 + 1, 0); builder.step1_init(1 + 1, 0);
@ -217,7 +217,7 @@ bool gen_tx_unlock_time::generate(std::vector<test_event_entry>& events) const
auto make_tx_with_unlock_time = [&](uint64_t unlock_time) -> transaction auto make_tx_with_unlock_time = [&](uint64_t unlock_time) -> transaction
{ {
return make_simple_tx_with_unlock_time(events, blk_1, miner_account, miner_account, MK_COINS(1), unlock_time); return make_simple_tx_with_unlock_time(events, blk_1r, miner_account, miner_account, MK_COINS(1), unlock_time);
}; };
std::list<transaction> txs_0; std::list<transaction> txs_0;
@ -266,7 +266,7 @@ bool gen_tx_input_is_not_txin_to_key::generate(std::vector<test_event_entry>& ev
{ {
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder; tx_builder builder;
builder.step1_init(); builder.step1_init();
@ -309,7 +309,7 @@ bool gen_tx_no_inputs_has_outputs::generate(std::vector<test_event_entry>& event
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_destinations(miner_account, miner_account.get_keys().m_account_address, MK_COINS(1), TESTS_DEFAULT_FEE, sources, destinations, false);
tx_builder builder; tx_builder builder;
builder.step1_init(); builder.step1_init();
@ -331,7 +331,7 @@ bool gen_tx_has_inputs_no_outputs::generate(std::vector<test_event_entry>& event
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
destinations.clear(); destinations.clear();
tx_builder builder; tx_builder builder;
@ -357,7 +357,7 @@ bool gen_tx_invalid_input_amount::generate(std::vector<test_event_entry>& events
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
sources.front().amount++; sources.front().amount++;
tx_builder builder; tx_builder builder;
@ -383,7 +383,7 @@ bool gen_tx_input_wo_key_offsets::generate(std::vector<test_event_entry>& events
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder; tx_builder builder;
builder.step1_init(); builder.step1_init();
@ -414,8 +414,8 @@ bool gen_tx_key_offest_points_to_foreign_key::generate(std::vector<test_event_en
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account); REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
MAKE_ACCOUNT(events, alice_account); MAKE_ACCOUNT(events, alice_account);
MAKE_ACCOUNT(events, bob_account); MAKE_ACCOUNT(events, bob_account);
MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(15) + 1, blk_1); MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(15) + 1, blk_1r);
MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(15) + 1, blk_1); MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(15) + 1, blk_1r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0); MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0);
std::vector<tx_source_entry> sources_bob; std::vector<tx_source_entry> sources_bob;
@ -451,7 +451,7 @@ bool gen_tx_sender_key_offest_not_exist::generate(std::vector<test_event_entry>&
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder; tx_builder builder;
builder.step1_init(); builder.step1_init();
@ -478,8 +478,8 @@ bool gen_tx_mixed_key_offest_not_exist::generate(std::vector<test_event_entry>&
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account); REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
MAKE_ACCOUNT(events, alice_account); MAKE_ACCOUNT(events, alice_account);
MAKE_ACCOUNT(events, bob_account); MAKE_ACCOUNT(events, bob_account);
MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1); MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1r);
MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1); MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0); MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0);
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
@ -511,7 +511,7 @@ bool gen_tx_key_image_not_derive_from_tx_key::generate(std::vector<test_event_en
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder; tx_builder builder;
builder.step1_init(); builder.step1_init();
@ -547,7 +547,7 @@ bool gen_tx_key_image_is_invalid::generate(std::vector<test_event_entry>& events
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder; tx_builder builder;
builder.step1_init(); builder.step1_init();
@ -591,7 +591,7 @@ bool gen_tx_check_input_unlock_time::generate(std::vector<test_event_entry>& eve
std::list<transaction> txs_0; std::list<transaction> txs_0;
auto make_tx_to_acc = [&](size_t acc_idx, uint64_t unlock_time) auto make_tx_to_acc = [&](size_t acc_idx, uint64_t unlock_time)
{ {
txs_0.push_back(make_simple_tx_with_unlock_time(events, blk_1, miner_account, accounts[acc_idx], txs_0.push_back(make_simple_tx_with_unlock_time(events, blk_1r, miner_account, accounts[acc_idx],
MK_COINS(1) + TESTS_DEFAULT_FEE, unlock_time)); MK_COINS(1) + TESTS_DEFAULT_FEE, unlock_time));
events.push_back(txs_0.back()); events.push_back(txs_0.back());
}; };
@ -641,7 +641,7 @@ bool gen_tx_txout_to_key_has_invalid_key::generate(std::vector<test_event_entry>
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder; tx_builder builder;
builder.step1_init(); builder.step1_init();
@ -670,7 +670,7 @@ bool gen_tx_output_with_zero_amount::generate(std::vector<test_event_entry>& eve
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder; tx_builder builder;
builder.step1_init(); builder.step1_init();
@ -698,7 +698,7 @@ bool gen_tx_output_is_not_txout_to_key::generate(std::vector<test_event_entry>&
std::vector<tx_source_entry> sources; std::vector<tx_source_entry> sources;
std::vector<tx_destination_entry> destinations; std::vector<tx_destination_entry> destinations;
fill_tx_sources_and_destinations(events, blk_0, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations); fill_tx_sources_and_destinations(events, blk_0r, miner_account, miner_account, MK_COINS(1), TESTS_DEFAULT_FEE, 0, sources, destinations);
tx_builder builder; tx_builder builder;
builder.step1_init(); builder.step1_init();
@ -740,8 +740,8 @@ bool gen_tx_signatures_are_invalid::generate(std::vector<test_event_entry>& even
REWIND_BLOCKS(events, blk_1r, blk_1, miner_account); REWIND_BLOCKS(events, blk_1r, blk_1, miner_account);
MAKE_ACCOUNT(events, alice_account); MAKE_ACCOUNT(events, alice_account);
MAKE_ACCOUNT(events, bob_account); MAKE_ACCOUNT(events, bob_account);
MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1); MAKE_TX_LIST_START(events, txs_0, miner_account, bob_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1r);
MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1); MAKE_TX_LIST(events, txs_0, miner_account, alice_account, MK_COINS(1) + TESTS_DEFAULT_FEE, blk_1r);
MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0); MAKE_NEXT_BLOCK_TX_LIST(events, blk_2, blk_1r, miner_account, txs_0);
MAKE_TX(events, tx_0, miner_account, miner_account, MK_COINS(60), blk_2); MAKE_TX(events, tx_0, miner_account, miner_account, MK_COINS(60), blk_2);

View File

@ -4,6 +4,7 @@
#include "wallet_tools.h" #include "wallet_tools.h"
#include <random> #include <random>
#include <boost/assign.hpp>
using namespace std; using namespace std;
using namespace epee; using namespace epee;
@ -31,10 +32,17 @@ void wallet_accessor_test::set_account(tools::wallet2 * wallet, cryptonote::acco
void wallet_accessor_test::process_parsed_blocks(tools::wallet2 * wallet, uint64_t start_height, const std::vector<cryptonote::block_complete_entry> &blocks, const std::vector<tools::wallet2::parsed_block> &parsed_blocks, uint64_t& blocks_added) void wallet_accessor_test::process_parsed_blocks(tools::wallet2 * wallet, uint64_t start_height, const std::vector<cryptonote::block_complete_entry> &blocks, const std::vector<tools::wallet2::parsed_block> &parsed_blocks, uint64_t& blocks_added)
{ {
wallet->process_parsed_blocks(start_height, blocks, parsed_blocks, blocks_added); if (wallet != nullptr) {
wallet->process_parsed_blocks(start_height, blocks, parsed_blocks, blocks_added);
}
} }
void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail) void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail)
{
process_transactions(boost::assign::list_of(wallet), events, blk_head, bt, blk_tail);
}
void wallet_tools::process_transactions(const std::vector<tools::wallet2*>& wallets, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail)
{ {
map_hash2tx_t mtx; map_hash2tx_t mtx;
std::vector<const cryptonote::block*> blockchain; std::vector<const cryptonote::block*> blockchain;
@ -44,10 +52,14 @@ void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vect
trim_block_chain(blockchain, blk_tail.get()); trim_block_chain(blockchain, blk_tail.get());
} }
process_transactions(wallet, blockchain, mtx, bt); process_transactions(wallets, blockchain, mtx, bt);
} }
void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt) void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt){
process_transactions(boost::assign::list_of(wallet), blockchain, mtx, bt);
}
void wallet_tools::process_transactions(const std::vector<tools::wallet2*>& wallets, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt)
{ {
uint64_t start_height=0, blocks_added=0; uint64_t start_height=0, blocks_added=0;
std::vector<cryptonote::block_complete_entry> v_bche; std::vector<cryptonote::block_complete_entry> v_bche;
@ -67,11 +79,12 @@ void wallet_tools::process_transactions(tools::wallet2 * wallet, const std::vect
wallet_tools::gen_block_data(bt, bl, mtx, v_bche.back(), v_parsed_block.back(), idx == 1 ? start_height : height); wallet_tools::gen_block_data(bt, bl, mtx, v_bche.back(), v_parsed_block.back(), idx == 1 ? start_height : height);
} }
if (wallet) for(auto wallet: wallets) {
wallet_accessor_test::process_parsed_blocks(wallet, start_height, v_bche, v_parsed_block, blocks_added); wallet_accessor_test::process_parsed_blocks(wallet, start_height, v_bche, v_parsed_block, blocks_added);
}
} }
bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptonote::tx_source_entry>& sources, size_t mixin, const boost::optional<size_t>& num_utxo, const boost::optional<uint64_t>& min_amount, block_tracker &bt, std::vector<size_t> &selected, uint64_t cur_height, ssize_t offset, int step, const boost::optional<fnc_accept_tx_source_t>& fnc_accept) bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptonote::tx_source_entry>& sources, size_t mixin, const boost::optional<size_t>& num_utxo, const boost::optional<uint64_t>& min_amount, block_tracker &bt, std::vector<size_t> &selected, uint64_t cur_height, ssize_t offset, int step, const boost::optional<fnc_accept_tx_source_t>& fnc_accept, const boost::optional<fnc_accept_output_t>& fnc_in_accept)
{ {
CHECK_AND_ASSERT_THROW_MES(step != 0, "Step is zero"); CHECK_AND_ASSERT_THROW_MES(step != 0, "Step is zero");
sources.clear(); sources.clear();
@ -84,7 +97,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
size_t iters = 0; size_t iters = 0;
uint64_t sum = 0; uint64_t sum = 0;
size_t cur_utxo = 0; size_t cur_utxo = 0;
bool abort = false; bool should_abort_search = false;
unsigned brk_cond = 0; unsigned brk_cond = 0;
unsigned brk_thresh = num_utxo && min_amount ? 2 : (num_utxo || min_amount ? 1 : 0); unsigned brk_thresh = num_utxo && min_amount ? 2 : (num_utxo || min_amount ? 1 : 0);
@ -96,7 +109,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
brk_cond += 1; \ brk_cond += 1; \
} while(0) } while(0)
for(ssize_t i = roffset; iters < ntrans && !abort; i += step, ++iters) for(ssize_t i = roffset; iters < ntrans && !should_abort_search; i += step, ++iters)
{ {
EVAL_BRK_COND(); EVAL_BRK_COND();
if (brk_cond >= brk_thresh) if (brk_cond >= brk_thresh)
@ -106,7 +119,7 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
auto & td = transfers[i]; auto & td = transfers[i];
if (td.m_spent) if (td.m_spent)
continue; continue;
if (td.m_block_height + CRYPTONOTE_MINED_MONEY_UNLOCK_WINDOW > cur_height) if (td.m_tx.unlock_time < CRYPTONOTE_MAX_BLOCK_NUMBER && td.m_tx.unlock_time > cur_height + 1)
continue; continue;
if (selected_idx.find((size_t)i) != selected_idx.end()){ if (selected_idx.find((size_t)i) != selected_idx.end()){
MERROR("Should not happen (selected_idx not found): " << i); MERROR("Should not happen (selected_idx not found): " << i);
@ -119,18 +132,12 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
try { try {
cryptonote::tx_source_entry src; cryptonote::tx_source_entry src;
wallet_tools::gen_tx_src(mixin, cur_height, td, src, bt); wallet_tools::gen_tx_src(mixin, cur_height, td, src, bt, fnc_in_accept);
// Acceptor function // Acceptor function
if (fnc_accept){ if (fnc_accept && !(fnc_accept.get())({.td=&td, .src=&src, .selected_idx=&selected_idx, .selected_kis=&selected_kis,
tx_source_info_crate_t c_info{.td=&td, .src=&src, .selected_idx=&selected_idx, .selected_kis=&selected_kis, .ntrans=ntrans, .iters=iters, .sum=sum, .cur_utxo=cur_utxo}, should_abort_search))
.ntrans=ntrans, .iters=iters, .sum=sum, .cur_utxo=cur_utxo};
bool take_it = (fnc_accept.get())(c_info, abort);
if (!take_it){
continue; continue;
}
}
MDEBUG("Selected " << i << " from tx: " << dump_keys(td.m_txid.data) MDEBUG("Selected " << i << " from tx: " << dump_keys(td.m_txid.data)
<< " ki: " << dump_keys(td.m_key_image.data) << " ki: " << dump_keys(td.m_key_image.data)
@ -154,18 +161,22 @@ bool wallet_tools::fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptono
} }
EVAL_BRK_COND(); EVAL_BRK_COND();
return brk_cond >= brk_thresh; const auto res = brk_cond >= brk_thresh;
if (!res) {
MDEBUG("fill_tx_sources fails, brk_cond: " << brk_cond << ", brk_thresh: " << brk_thresh << ", utxos: " << cur_utxo << ", sum: " << sum);
}
return res;
#undef EVAL_BRK_COND #undef EVAL_BRK_COND
} }
void wallet_tools::gen_tx_src(size_t mixin, uint64_t cur_height, const tools::wallet2::transfer_details & td, cryptonote::tx_source_entry & src, block_tracker &bt) void wallet_tools::gen_tx_src(size_t mixin, uint64_t cur_height, const tools::wallet2::transfer_details & td, cryptonote::tx_source_entry & src, block_tracker &bt, const boost::optional<fnc_accept_output_t>& fnc_accept)
{ {
CHECK_AND_ASSERT_THROW_MES(mixin != 0, "mixin is zero"); CHECK_AND_ASSERT_THROW_MES(mixin != 0, "mixin is zero");
src.amount = td.amount(); src.amount = td.amount();
src.rct = td.is_rct(); src.rct = td.is_rct();
std::vector<tools::wallet2::get_outs_entry> outs; std::vector<tools::wallet2::get_outs_entry> outs;
bt.get_fake_outs(mixin, td.is_rct() ? 0 : td.amount(), td.m_global_output_index, cur_height, outs); bt.get_fake_outs(mixin, td.is_rct() ? 0 : td.amount(), td.m_global_output_index, cur_height, outs, fnc_accept);
for (size_t n = 0; n < mixin; ++n) for (size_t n = 0; n < mixin; ++n)
{ {

View File

@ -68,12 +68,14 @@ public:
class wallet_tools class wallet_tools
{ {
public: public:
static void gen_tx_src(size_t mixin, uint64_t cur_height, const tools::wallet2::transfer_details & td, cryptonote::tx_source_entry & src, block_tracker &bt); static void gen_tx_src(size_t mixin, uint64_t cur_height, const tools::wallet2::transfer_details & td, cryptonote::tx_source_entry & src, block_tracker &bt, const boost::optional<fnc_accept_output_t>& fnc_accept = boost::none);
static void gen_block_data(block_tracker &bt, const cryptonote::block *bl, const map_hash2tx_t & mtx, cryptonote::block_complete_entry &bche, tools::wallet2::parsed_block &parsed_block, uint64_t &height); static void gen_block_data(block_tracker &bt, const cryptonote::block *bl, const map_hash2tx_t & mtx, cryptonote::block_complete_entry &bche, tools::wallet2::parsed_block &parsed_block, uint64_t &height);
static void compute_subaddresses(std::unordered_map<crypto::public_key, cryptonote::subaddress_index> &subaddresses, cryptonote::account_base & creds, size_t account, size_t minors); static void compute_subaddresses(std::unordered_map<crypto::public_key, cryptonote::subaddress_index> &subaddresses, cryptonote::account_base & creds, size_t account, size_t minors);
static void process_transactions(tools::wallet2 * wallet, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail=boost::none); static void process_transactions(tools::wallet2 * wallet, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail=boost::none);
static void process_transactions(const std::vector<tools::wallet2*>& wallets, const std::vector<test_event_entry>& events, const cryptonote::block& blk_head, block_tracker &bt, const boost::optional<crypto::hash>& blk_tail=boost::none);
static void process_transactions(tools::wallet2 * wallet, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt); static void process_transactions(tools::wallet2 * wallet, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt);
static bool fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptonote::tx_source_entry>& sources, size_t mixin, const boost::optional<size_t>& num_utxo, const boost::optional<uint64_t>& min_amount, block_tracker &bt, std::vector<size_t> &selected, uint64_t cur_height, ssize_t offset=0, int step=1, const boost::optional<fnc_accept_tx_source_t>& fnc_accept=boost::none); static void process_transactions(const std::vector<tools::wallet2*>& wallets, const std::vector<const cryptonote::block*>& blockchain, const map_hash2tx_t & mtx, block_tracker &bt);
static bool fill_tx_sources(tools::wallet2 * wallet, std::vector<cryptonote::tx_source_entry>& sources, size_t mixin, const boost::optional<size_t>& num_utxo, const boost::optional<uint64_t>& min_amount, block_tracker &bt, std::vector<size_t> &selected, uint64_t cur_height, ssize_t offset=0, int step=1, const boost::optional<fnc_accept_tx_source_t>& fnc_accept=boost::none, const boost::optional<fnc_accept_output_t>& fnc_in_accept = boost::none);
}; };
cryptonote::account_public_address get_address(const tools::wallet2*); cryptonote::account_public_address get_address(const tools::wallet2*);

View File

@ -309,11 +309,10 @@ void mock_daemon::stop_p2p()
m_server.send_stop_signal(); m_server.send_stop_signal();
} }
void mock_daemon::mine_blocks(size_t num_blocks, const std::string &miner_address) void mock_daemon::mine_blocks(size_t num_blocks, const std::string &miner_address, std::chrono::seconds timeout)
{ {
bool blocks_mined = false; bool blocks_mined = false;
const uint64_t start_height = get_height(); const uint64_t start_height = get_height();
const auto mining_timeout = std::chrono::seconds(360);
MDEBUG("Current height before mining: " << start_height); MDEBUG("Current height before mining: " << start_height);
start_mining(miner_address); start_mining(miner_address);
@ -331,14 +330,14 @@ void mock_daemon::mine_blocks(size_t num_blocks, const std::string &miner_addres
} }
auto current_time = std::chrono::system_clock::now(); auto current_time = std::chrono::system_clock::now();
if (mining_timeout < current_time - mining_started) if (timeout < current_time - mining_started)
{ {
break; break;
} }
} }
stop_mining(); stop_mining();
CHECK_AND_ASSERT_THROW_MES(blocks_mined, "Mining failed in the time limit"); CHECK_AND_ASSERT_THROW_MES(blocks_mined, "Mining failed in the time limit: " << timeout.count());
} }
constexpr const std::chrono::seconds mock_daemon::rpc_timeout; constexpr const std::chrono::seconds mock_daemon::rpc_timeout;

View File

@ -139,7 +139,7 @@ public:
void stop_and_deinit(); void stop_and_deinit();
void try_init_and_run(boost::optional<unsigned> initial_port=boost::none); void try_init_and_run(boost::optional<unsigned> initial_port=boost::none);
void mine_blocks(size_t num_blocks, const std::string &miner_address); void mine_blocks(size_t num_blocks, const std::string &miner_address, std::chrono::seconds timeout = std::chrono::seconds(360));
void start_mining(const std::string &miner_address, uint64_t threads_count=1, bool do_background_mining=false, bool ignore_battery=true); void start_mining(const std::string &miner_address, uint64_t threads_count=1, bool do_background_mining=false, bool ignore_battery=true);
void stop_mining(); void stop_mining();
uint64_t get_height(); uint64_t get_height();

File diff suppressed because it is too large Load Diff

View File

@ -36,16 +36,24 @@
#include "../core_tests/chaingen.h" #include "../core_tests/chaingen.h"
#include "../core_tests/wallet_tools.h" #include "../core_tests/wallet_tools.h"
#define TREZOR_TEST_FEE 90000000000
#define TREZOR_TEST_CLSAG_MIXIN 11 #define TREZOR_TEST_CLSAG_MIXIN 11
#define TREZOR_TEST_HF15_MIXIN 16 #define TREZOR_TEST_HF15_MIXIN 16
#define TREZOR_TEST_MIXIN TREZOR_TEST_CLSAG_MIXIN #define TREZOR_TEST_MIXIN TREZOR_TEST_CLSAG_MIXIN
#define TREZOR_TEST_MIN_HF_DEFAULT HF_VERSION_BULLETPROOF_PLUS
#define TREZOR_TEST_MAX_HF_DEFAULT HF_VERSION_BULLETPROOF_PLUS
#define TREZOR_TEST_KI_SYNC_DEFAULT 1
#define TREZOR_TEST_MINING_ENABLED_DEFAULT false
#define TREZOR_TEST_MINING_TIMEOUT_DEFAULT 360
#define MK_TCOINS(amount) ((unsigned long long) ((amount) * (COIN)))
#define TREZOR_TEST_FEE_FRAC 0.1
#define TREZOR_TEST_FEE MK_TCOINS(TREZOR_TEST_FEE_FRAC)
/************************************************************************/ /************************************************************************/
/* */ /* */
/************************************************************************/ /************************************************************************/
class tsx_builder; class tsx_builder;
class gen_trezor_base : public test_chain_unit_base class gen_trezor_base : public test_chain_unit_base, public hw::i_device_callback
{ {
public: public:
friend class tsx_builder; friend class tsx_builder;
@ -54,7 +62,7 @@ public:
gen_trezor_base(const gen_trezor_base &other); gen_trezor_base(const gen_trezor_base &other);
virtual ~gen_trezor_base() {}; virtual ~gen_trezor_base() {};
virtual void setup_args(const std::string & trezor_path, bool heavy_tests=false); virtual void setup_args(const std::string & trezor_path, bool heavy_tests, bool mining_enabled, long mining_timeout);
virtual bool generate(std::vector<test_event_entry>& events); virtual bool generate(std::vector<test_event_entry>& events);
virtual void load(std::vector<test_event_entry>& events); // load events, init test obj virtual void load(std::vector<test_event_entry>& events); // load events, init test obj
virtual void fix_hf(std::vector<test_event_entry>& events); virtual void fix_hf(std::vector<test_event_entry>& events);
@ -76,42 +84,58 @@ public:
std::vector<cryptonote::address_parse_info>& dsts_info, std::vector<cryptonote::address_parse_info>& dsts_info,
test_generator &generator, test_generator &generator,
std::vector<tools::wallet2*> wallets, std::vector<tools::wallet2*> wallets,
bool is_sweep=false); bool is_sweep=false,
size_t sender_idx=0);
virtual void test_get_tx( virtual void test_get_tx(
std::vector<test_event_entry>& events, std::vector<test_event_entry>& events,
std::vector<tools::wallet2*> wallets, std::vector<tools::wallet2*> wallets,
const cryptonote::account_base * account,
const std::vector<tools::wallet2::pending_tx> &ptxs, const std::vector<tools::wallet2::pending_tx> &ptxs,
const std::vector<std::string> &aux_tx_info); const std::vector<std::string> &aux_tx_info);
virtual void mine_and_test(std::vector<test_event_entry>& events); virtual void mine_and_test(std::vector<test_event_entry>& events);
virtual void rewind_blocks(std::vector<test_event_entry>& events, size_t rewind_n, uint8_t hf); virtual void rewind_blocks(std::vector<test_event_entry>& events, size_t rewind_n, uint8_t hf);
virtual cryptonote::block rewind_blocks_with_decoys(std::vector<test_event_entry>& events, cryptonote::block & head, size_t rewind_n, uint8_t hf, size_t num_decoys_per_block);
virtual void set_hard_fork(uint8_t hf); virtual void set_hard_fork(uint8_t hf);
crypto::hash head_hash() const { return get_block_hash(m_head); } crypto::hash head_hash() const { return get_block_hash(m_head); }
cryptonote::block head_block() const { return m_head; } cryptonote::block head_block() const { return m_head; }
bool heavy_tests() const { return m_heavy_tests; } bool heavy_tests() const { return m_heavy_tests; }
bool heavy_test_set() const { return m_gen_heavy_test_set; }
void heavy_test_set(bool set) { m_gen_heavy_test_set = set; }
void rct_config(rct::RCTConfig rct_config) { m_rct_config = rct_config; } void rct_config(rct::RCTConfig rct_config) { m_rct_config = rct_config; }
uint8_t cur_hf() const { return m_hard_forks.size() > 0 ? m_hard_forks.back().first : 0; } uint8_t cur_hf() const { return !m_hard_forks.empty() ? m_hard_forks.back().first : 0; }
size_t num_mixin() const { return m_top_hard_fork >= HF_VERSION_BULLETPROOF_PLUS ? TREZOR_TEST_HF15_MIXIN : TREZOR_TEST_CLSAG_MIXIN; } size_t num_mixin() const { return m_top_hard_fork >= HF_VERSION_BULLETPROOF_PLUS ? TREZOR_TEST_HF15_MIXIN : TREZOR_TEST_CLSAG_MIXIN; }
cryptonote::network_type nettype() const { return m_network_type; } cryptonote::network_type nettype() const { return m_network_type; }
std::shared_ptr<mock_daemon> daemon() const { return m_daemon; } std::shared_ptr<mock_daemon> daemon() const { return m_daemon; }
void daemon(std::shared_ptr<mock_daemon> daemon){ m_daemon = std::move(daemon); } void daemon(std::shared_ptr<mock_daemon> daemon){ m_daemon = std::move(daemon); }
boost::optional<epee::wipeable_string> on_pin_request() override;
boost::optional<epee::wipeable_string> on_passphrase_request(bool &on_device) override;
// Static configuration // Static configuration
static const uint64_t m_ts_start; static const uint64_t m_ts_start;
static const uint64_t m_wallet_ts; static const uint64_t m_wallet_ts;
static const std::string m_device_name; static const std::string m_device_name;
static const std::string m_miner_master_seed_str;
static const std::string m_master_seed_str; static const std::string m_master_seed_str;
static const std::string m_device_seed; static const std::string m_device_seed;
static const std::string m_alice_spend_private; static const std::string m_alice_spend_private;
static const std::string m_alice_view_private; static const std::string m_alice_view_private;
static const std::string m_alice2_passphrase;
static const std::string m_alice2_master_seed;
static const std::string m_bob_master_seed;
static const std::string m_eve_master_seed;
protected: protected:
virtual void setup_trezor(); virtual void setup_trezor(bool use_passphrase, const std::string & pin);
virtual void init_fields(); virtual void init_accounts();
virtual void init_wallets();
virtual void init_trezor_account();
virtual void log_wallets_desc();
virtual void update_client_settings(); virtual void update_client_settings();
virtual bool verify_tx_key(const ::crypto::secret_key & tx_priv, const ::crypto::public_key & tx_pub, const subaddresses_t & subs); virtual bool verify_tx_key(const ::crypto::secret_key & tx_priv, const ::crypto::public_key & tx_pub, const subaddresses_t & subs);
@ -126,17 +150,27 @@ protected:
std::vector<test_event_entry> m_events; std::vector<test_event_entry> m_events;
std::string m_trezor_path; std::string m_trezor_path;
std::string m_trezor_pin;
std::string m_trezor_passphrase;
bool m_trezor_use_passphrase = true;
bool m_trezor_use_alice2 = false;
bool m_heavy_tests; bool m_heavy_tests;
bool m_gen_heavy_test_set;
bool m_test_get_tx_key; bool m_test_get_tx_key;
rct::RCTConfig m_rct_config; rct::RCTConfig m_rct_config;
bool m_live_refresh_enabled; bool m_live_refresh_enabled;
bool m_mining_enabled = TREZOR_TEST_MINING_ENABLED_DEFAULT;
long m_mining_timeout = TREZOR_TEST_MINING_TIMEOUT_DEFAULT;
bool m_no_change_in_tested_tx = false;
cryptonote::account_base m_miner_account; cryptonote::account_base m_miner_account;
cryptonote::account_base m_bob_account; cryptonote::account_base m_bob_account;
cryptonote::account_base m_alice_account; cryptonote::account_base m_alice_account;
cryptonote::account_base m_eve_account; cryptonote::account_base m_eve_account;
cryptonote::account_base m_alice2_account;
hw::trezor::device_trezor * m_trezor; hw::trezor::device_trezor * m_trezor;
std::unique_ptr<tools::wallet2> m_wl_alice; std::unique_ptr<tools::wallet2> m_wl_alice;
std::unique_ptr<tools::wallet2> m_wl_alice2;
std::unique_ptr<tools::wallet2> m_wl_bob; std::unique_ptr<tools::wallet2> m_wl_bob;
std::unique_ptr<tools::wallet2> m_wl_eve; std::unique_ptr<tools::wallet2> m_wl_eve;
@ -165,9 +199,9 @@ public:
tsx_builder * payment_id(const std::string & payment_id) { m_payment_id = payment_id; return this; } tsx_builder * payment_id(const std::string & payment_id) { m_payment_id = payment_id; return this; }
tsx_builder * from(tools::wallet2 *from, uint32_t account=0) { m_from = from; m_account=account; return this; } tsx_builder * from(tools::wallet2 *from, uint32_t account=0) { m_from = from; m_account=account; return this; }
tsx_builder * sources(std::vector<cryptonote::tx_source_entry> & sources, std::vector<size_t> & selected_transfers); tsx_builder * sources(std::vector<cryptonote::tx_source_entry> & sources, std::vector<size_t> & selected_transfers);
tsx_builder * compute_sources(boost::optional<size_t> num_utxo=boost::none, boost::optional<uint64_t> min_amount=boost::none, ssize_t offset=-1, int step=1, boost::optional<fnc_accept_tx_source_t> fnc_accept=boost::none); tsx_builder * compute_sources(boost::optional<size_t> num_utxo=boost::none, uint64_t extra_amount=0, ssize_t offset=-1, int step=1, boost::optional<fnc_accept_tx_source_t> fnc_accept=boost::none);
tsx_builder * compute_sources_to_sub(boost::optional<size_t> num_utxo=boost::none, boost::optional<uint64_t> min_amount=boost::none, ssize_t offset=-1, int step=1, boost::optional<fnc_accept_tx_source_t> fnc_accept=boost::none); tsx_builder * compute_sources_to_sub(boost::optional<size_t> num_utxo=boost::none, uint64_t extra_amount=0, ssize_t offset=-1, int step=1, boost::optional<fnc_accept_tx_source_t> fnc_accept=boost::none);
tsx_builder * compute_sources_to_sub_acc(boost::optional<size_t> num_utxo=boost::none, boost::optional<uint64_t> min_amount=boost::none, ssize_t offset=-1, int step=1, boost::optional<fnc_accept_tx_source_t> fnc_accept=boost::none); tsx_builder * compute_sources_to_sub_acc(boost::optional<size_t> num_utxo=boost::none, uint64_t extra_amount=0, ssize_t offset=-1, int step=1, boost::optional<fnc_accept_tx_source_t> fnc_accept=boost::none);
tsx_builder * destinations(std::vector<cryptonote::tx_destination_entry> &dsts); tsx_builder * destinations(std::vector<cryptonote::tx_destination_entry> &dsts);
tsx_builder * add_destination(const cryptonote::tx_destination_entry &dst); tsx_builder * add_destination(const cryptonote::tx_destination_entry &dst);
@ -208,11 +242,12 @@ class device_trezor_test : public hw::trezor::device_trezor {
public: public:
size_t m_tx_sign_ctr; size_t m_tx_sign_ctr;
size_t m_compute_key_image_ctr; size_t m_compute_key_image_ctr;
std::unordered_set<crypto::key_image> m_live_synced_ki;
device_trezor_test(); device_trezor_test();
void clear_test_counters(); void clear_test_counters();
void setup_for_tests(const std::string & trezor_path, const std::string & seed, cryptonote::network_type network_type); void setup_for_tests(const std::string & trezor_path, const std::string & seed, cryptonote::network_type network_type, bool use_passphrase=false, const std::string & pin = "");
bool compute_key_image(const ::cryptonote::account_keys &ack, const ::crypto::public_key &out_key, bool compute_key_image(const ::cryptonote::account_keys &ack, const ::crypto::public_key &out_key,
const ::crypto::key_derivation &recv_derivation, size_t real_output_index, const ::crypto::key_derivation &recv_derivation, size_t real_output_index,
@ -315,6 +350,12 @@ public:
bool generate(std::vector<test_event_entry>& events) override; bool generate(std::vector<test_event_entry>& events) override;
}; };
class gen_trezor_16utxo_to_sub : public gen_trezor_base
{
public:
bool generate(std::vector<test_event_entry>& events) override;
};
class gen_trezor_many_utxo : public gen_trezor_base class gen_trezor_many_utxo : public gen_trezor_base
{ {
public: public:
@ -327,14 +368,52 @@ public:
bool generate(std::vector<test_event_entry>& events) override; bool generate(std::vector<test_event_entry>& events) override;
}; };
// Wallet::API tests class gen_trezor_no_passphrase : public gen_trezor_base
class wallet_api_tests : public gen_trezor_base
{ {
public: public:
virtual ~wallet_api_tests(); bool generate(std::vector<test_event_entry>& events) override;
};
class gen_trezor_wallet_passphrase : public gen_trezor_base, public tools::i_wallet2_callback
{
public:
~gen_trezor_wallet_passphrase() override;
bool generate(std::vector<test_event_entry>& events) override;
boost::optional<epee::wipeable_string> on_device_pin_request() override;
boost::optional<epee::wipeable_string> on_device_passphrase_request(bool &on_device) override;
protected:
boost::filesystem::path m_wallet_dir;
};
class gen_trezor_passphrase : public gen_trezor_base
{
public:
bool generate(std::vector<test_event_entry>& events) override;
};
class gen_trezor_pin : public gen_trezor_base
{
public:
bool generate(std::vector<test_event_entry>& events) override;
};
// Wallet::API tests
class wallet_api_tests : public gen_trezor_base, public Monero::WalletListener
{
public:
~wallet_api_tests() override;
void init(); void init();
bool generate(std::vector<test_event_entry>& events) override; bool generate(std::vector<test_event_entry>& events) override;
Monero::optional<std::string> onDevicePinRequest() override;
Monero::optional<std::string> onDevicePassphraseRequest(bool &on_device) override;
void moneySpent(const std::string &txId, uint64_t amount) override {};
void moneyReceived(const std::string &txId, uint64_t amount) override {};
void unconfirmedMoneyReceived(const std::string &txId, uint64_t amount) override {};
void newBlock(uint64_t height) override {};
void updated() override {};
void refreshed() override {};
protected: protected:
boost::filesystem::path m_wallet_dir; boost::filesystem::path m_wallet_dir;
}; };