From 4689ad2d3cf2fcc9ab1e499465ac306ea6d43f31 Mon Sep 17 00:00:00 2001 From: Dusan Klinec Date: Fri, 10 Nov 2023 00:36:31 +0100 Subject: [PATCH] trezor: support c++17 and protobuf v25, libusb fix - fix If there is no protobuf version installed, if fails - passphrase test fix, wallet keys init was missing --- cmake/CheckTrezor.cmake | 25 ++++++++++++++++--------- cmake/FindLibUSB.cmake | 10 +++++----- src/device_trezor/README.md | 22 ++++++++++++++++------ tests/core_tests/wallet_tools.h | 1 + tests/trezor/trezor_tests.cpp | 1 + 5 files changed, 39 insertions(+), 20 deletions(-) diff --git a/cmake/CheckTrezor.cmake b/cmake/CheckTrezor.cmake index 05b8ebd93..87582a713 100644 --- a/cmake/CheckTrezor.cmake +++ b/cmake/CheckTrezor.cmake @@ -75,7 +75,13 @@ if (USE_DEVICE_TREZOR) # Protobuf is required to build protobuf messages for Trezor include(FindProtobuf OPTIONAL) - FIND_PACKAGE(Protobuf CONFIG) + # PkgConfig works better with new Protobuf + find_package(PkgConfig QUIET) + pkg_check_modules(PROTOBUF protobuf) + + if (NOT Protobuf_FOUND) + FIND_PACKAGE(Protobuf CONFIG) + endif() if (NOT Protobuf_FOUND) FIND_PACKAGE(Protobuf) endif() @@ -83,11 +89,11 @@ if (USE_DEVICE_TREZOR) _trezor_protobuf_fix_vars() # Early fail for optional Trezor support - if(${Protobuf_VERSION} GREATER 21) - 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) + if(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(${CMAKE_CXX_STANDARD} LESS 17 AND ${Protobuf_VERSION} GREATER 21) + trezor_fatal_msg("Trezor: Unsupported Protobuf version ${Protobuf_VERSION} with C++ ${CMAKE_CXX_STANDARD}. Please, use Protobuf v21.") + elseif(NOT Protobuf_LIBRARY) trezor_fatal_msg("Trezor: Protobuf library not found: ${Protobuf_LIBRARY}") unset(Protobuf_FOUND) elseif(NOT Protobuf_PROTOC_EXECUTABLE OR NOT EXISTS "${Protobuf_PROTOC_EXECUTABLE}") @@ -150,9 +156,10 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON) endif() if(USE_DEVICE_TREZOR_PROTOBUF_TEST) - # For now, Protobuf v21 is the maximum supported version as v23 requires C++17. TODO: Remove once we move to C++17 - if(${Protobuf_VERSION} GREATER 21) - trezor_fatal_msg("Trezor: Unsupported Protobuf version ${Protobuf_VERSION}. Please, use Protobuf v21.") + if(PROTOBUF_LDFLAGS) + set(PROTOBUF_TRYCOMPILE_LINKER "${PROTOBUF_LDFLAGS}") + else() + set(PROTOBUF_TRYCOMPILE_LINKER "${Protobuf_LIBRARY}") endif() try_compile(Protobuf_COMPILE_TEST_PASSED @@ -164,7 +171,7 @@ if(Protobuf_FOUND AND USE_DEVICE_TREZOR AND TREZOR_PYTHON) 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} + LINK_LIBRARIES "${PROTOBUF_TRYCOMPILE_LINKER}" ${CMAKE_TRY_COMPILE_LINK_LIBRARIES} OUTPUT_VARIABLE OUTPUT ) if(NOT Protobuf_COMPILE_TEST_PASSED) diff --git a/cmake/FindLibUSB.cmake b/cmake/FindLibUSB.cmake index f701b6398..647f3c656 100644 --- a/cmake/FindLibUSB.cmake +++ b/cmake/FindLibUSB.cmake @@ -119,10 +119,6 @@ if ( LibUSB_FOUND ) 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}" libusb_get_device_list "" LibUSB_VERSION_1.0 ) - check_library_exists ( "${LibUSB_LIBRARIES}" libusb_get_port_numbers "" LibUSB_VERSION_1.0.16 ) - 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) if(LIBUDEV_LIBRARY) @@ -132,6 +128,10 @@ if ( LibUSB_FOUND ) endif() endif() + 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_port_numbers "" LibUSB_VERSION_1.0.16 ) + # Library 1.0.16+ compilation test. # The check_library_exists does not work well on Apple with shared libs. if (APPLE OR LibUSB_VERSION_1.0.16 OR STATIC) @@ -141,7 +141,7 @@ if ( LibUSB_FOUND ) CMAKE_FLAGS "-DINCLUDE_DIRECTORIES=${LibUSB_INCLUDE_DIRS}" "-DLINK_DIRECTORIES=${LibUSB_LIBRARIES}" - LINK_LIBRARIES ${TEST_COMPILE_EXTRA_LIBRARIES} + LINK_LIBRARIES ${LibUSB_LIBRARIES} ${TEST_COMPILE_EXTRA_LIBRARIES} OUTPUT_VARIABLE OUTPUT) unset(TEST_COMPILE_EXTRA_LIBRARIES) message(STATUS "LibUSB Compilation test: ${LibUSB_COMPILE_TEST_PASSED}") diff --git a/src/device_trezor/README.md b/src/device_trezor/README.md index ce08c0009..dede853ae 100644 --- a/src/device_trezor/README.md +++ b/src/device_trezor/README.md @@ -15,19 +15,29 @@ Please, refer to [monero readme](https://github.com/trezor/trezor-firmware/blob/ ## 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. +Trezor uses [Protobuf](https://protobuf.dev/) library. Monero is now compiled with C++ 17 by default. +Protobuf v21 is tested, older versions are not guaranteed to work. Note that Protobuf v23+ requires C++ 17. -Protobuf v21 is the latest compatible protobuf version. +If you are getting Trezor compilation errors, it may be caused by abseil (protobuf dependency) not being compiled with C++17. +To fix this try installing protobuf from sources: -If you want to compile Monero with Trezor support, please make sure the Protobuf v21 is installed. +```shell +git clone --recursive git@github.com:protocolbuffers/protobuf.git +cd protobuf +cmake -DABSL_PROPAGATE_CXX_STD=TRUE -DCMAKE_CXX_STANDARD=17 -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_BUILD_TESTS=OFF . +cmake --build . +sudo make install +``` + +If Monero is compiled with C++14, Protobuf v21 is the latest compatible protobuf version for C++ 14. +If you want to compile Monero with Trezor support with C++14, 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: +To build with installed, but not linked Protobuf v21: ```bash CMAKE_PREFIX_PATH=$(find /opt/homebrew/Cellar/protobuf@21 -maxdepth 1 -type d -name "21.*" -print -quit) \ @@ -53,7 +63,7 @@ pacman --noconfirm -U mingw-w64-x86_64-protobuf-c-1.4.1-1-any.pkg.tar.zst mingw- ### Other systems -- install protobufv21 +- install Protobuf v21 - point `CMAKE_PREFIX_PATH` environment variable to Protobuf v21 installation. ## Troubleshooting diff --git a/tests/core_tests/wallet_tools.h b/tests/core_tests/wallet_tools.h index 2201e11f4..b99e9e890 100644 --- a/tests/core_tests/wallet_tools.h +++ b/tests/core_tests/wallet_tools.h @@ -53,6 +53,7 @@ class wallet_accessor_test { public: static void set_account(tools::wallet2 * wallet, cryptonote::account_base& account); + static void set_password(tools::wallet2 * wallet, const epee::wipeable_string & password) { wallet->setup_keys(password); } static tools::wallet2::transfer_container & get_transfers(tools::wallet2 * wallet) { return wallet->m_transfers; } static subaddresses_t & get_subaddresses(tools::wallet2 * wallet) { return wallet->m_subaddresses; } static void process_parsed_blocks(tools::wallet2 * wallet, uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added); diff --git a/tests/trezor/trezor_tests.cpp b/tests/trezor/trezor_tests.cpp index b21da95c0..0fcd10cef 100644 --- a/tests/trezor/trezor_tests.cpp +++ b/tests/trezor/trezor_tests.cpp @@ -2206,6 +2206,7 @@ bool gen_trezor_wallet_passphrase::generate(std::vector& event const auto wallet_path = (m_wallet_dir / "alice2").string(); const epee::wipeable_string& password = epee::wipeable_string("test-pass"); + wallet_accessor_test::set_password(m_wl_alice2.get(), password); m_wl_alice2->store_to(wallet_path, password); // Positive load