diff options
30 files changed, 337 insertions, 388 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 36eab5027..7c28a71ce 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -5,6 +5,9 @@ on: [push, pull_request] # The below variables reduce repetitions across similar targets env: REMOVE_BUNDLED_BOOST : rm -rf /usr/local/share/boost + BUILD_DEFAULT_LINUX: | + ccache --max-size=150M + cmake -S . -B build -D ARCH="default" -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release && cmake --build build -j3 APT_INSTALL_LINUX: 'sudo apt -y install build-essential cmake libboost-all-dev miniupnpc libunbound-dev graphviz doxygen libunwind8-dev pkg-config libssl-dev libzmq3-dev libsodium-dev libhidapi-dev libnorm-dev libusb-1.0-0-dev libpgm-dev libprotobuf-dev protobuf-compiler ccache' APT_SET_CONF: | echo "Acquire::Retries \"3\";" | sudo tee -a /etc/apt/apt.conf.d/80-custom @@ -60,11 +63,17 @@ jobs: ccache --max-size=150M make release-static-win64 -j2 +# See the OS labels and monitor deprecations here: +# https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources + build-ubuntu: - runs-on: ubuntu-latest + runs-on: ${{ matrix.os }} env: CCACHE_COMPRESS: 1 CCACHE_TEMPDIR: /tmp/.ccache-temp + strategy: + matrix: + os: [ubuntu-latest, ubuntu-18.04] steps: - uses: actions/checkout@v1 with: @@ -72,8 +81,8 @@ jobs: - uses: actions/cache@v2 with: path: ~/.ccache - key: ccache-ubuntu-build-${{ github.sha }} - restore-keys: ccache-ubuntu-build- + key: ccache-ubuntu-build-${{ matrix.os }}-${{ github.sha }} + restore-keys: ccache-ubuntu-build-${{ matrix.os }} - name: remove bundled boost run: ${{env.REMOVE_BUNDLED_BOOST}} - name: set apt conf @@ -83,9 +92,7 @@ jobs: - name: install monero dependencies run: ${{env.APT_INSTALL_LINUX}} - name: build - run: | - ccache --max-size=150M - make -j3 + run: ${{env.BUILD_DEFAULT_LINUX}} libwallet-ubuntu: runs-on: ubuntu-latest @@ -112,8 +119,8 @@ jobs: - name: build run: | ccache --max-size=150M - cmake -DBUILD_GUI_DEPS=ON - make -j3 + cmake . + make wallet_api -j3 test-ubuntu: needs: build-ubuntu @@ -129,8 +136,8 @@ jobs: uses: actions/cache@v2 with: path: ~/.ccache - key: test-ubuntu-ccache-${{ github.sha }} - restore-keys: test-ubuntu-ccache- + key: ccache-ubuntu-build-ubuntu-latest-${{ github.sha }} + restore-keys: ccache-ubuntu-build-ubuntu-latest - name: remove bundled boost run: ${{env.REMOVE_BUNDLED_BOOST}} - name: set apt conf @@ -145,11 +152,8 @@ jobs: env: CTEST_OUTPUT_ON_FAILURE: ON run: | - ccache --max-size=150M - DIR_BUILD="build/ci/release" - DIR_SRC="`pwd`" - mkdir -p "${DIR_BUILD}" && cd "${DIR_BUILD}" - cmake -S "${DIR_SRC}" -D ARCH="default" -D BUILD_SHARED_LIBS=ON -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=release && make -j3 && make test + ${{env.BUILD_DEFAULT_LINUX}} + cmake --build build --target test # ARCH="default" (not "native") ensures, that a different execution host can execute binaries compiled elsewhere. # BUILD_SHARED_LIBS=ON speeds up the linkage part a bit, reduces size, and is the only place where the dynamic linkage is tested. diff --git a/CMakeLists.txt b/CMakeLists.txt index 29576a5bd..e3e31767d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,16 +106,18 @@ function (die msg) endfunction () function (add_c_flag_if_supported flag var) - string(REPLACE "-" "_" supported ${flag}_c) - check_c_compiler_flag(${flag} ${supported}) + set(TMP "-Werror ${flag}") + string(REGEX REPLACE "[- ]" "_" supported ${TMP}_c) + check_c_compiler_flag(${TMP} ${supported}) if(${${supported}}) set(${var} "${${var}} ${flag}" PARENT_SCOPE) endif() endfunction() function (add_cxx_flag_if_supported flag var) - string(REPLACE "-" "_" supported ${flag}_cxx) - check_cxx_compiler_flag(${flag} ${supported}) + set(TMP "-Werror ${flag}") + string(REGEX REPLACE "[- ]" "_" supported ${TMP}_cxx) + check_cxx_compiler_flag(${TMP} ${supported}) if(${${supported}}) set(${var} "${${var}} ${flag}" PARENT_SCOPE) endif() @@ -188,6 +190,66 @@ macro (monero_find_all_headers headers_found module_root_dir) ) endmacro() +# Function to forbid undefined symbols and also verify +# 1) Test project with all types of libraries and without undefined symbols can compile successfully +# 2) Test project with all types of libraries and undefined symbols can not compile successfully +function(forbid_undefined_symbols) + unset(TMP) + # https://www.unix.com/man-page/linux/1/ld, --no-undefined, Report unresolved symbol references from regular object files. + add_linker_flag_if_supported(-Wl,--no-undefined TMP) + # https://www.unix.com/man-page/osx/1/ld/, -undefined, Specifies how undefined symbols are to be treated. + add_linker_flag_if_supported(-Wl,-undefined,error TMP) + string(APPEND CMAKE_SHARED_LINKER_FLAGS ${TMP}) + string(APPEND CMAKE_MODULE_LINKER_FLAGS ${TMP}) + set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} PARENT_SCOPE) + set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} PARENT_SCOPE) + set(TEST_PROJECT "${CMAKE_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/CMakeTmp/test_project") + foreach(EXPECT IN ITEMS TRUE FALSE) + file(REMOVE_RECURSE "${TEST_PROJECT}") + file(MAKE_DIRECTORY "${TEST_PROJECT}") + file(WRITE "${TEST_PROJECT}/CMakeLists.txt" + [=[ +cmake_minimum_required(VERSION 3.1) +project(test) +option(EXPECT_SUCCESS "" ON) +file(WRITE "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" "void undefined_symbol(); void symbol() { undefined_symbol(); }") +if (EXPECT_SUCCESS) + file(APPEND "${CMAKE_SOURCE_DIR}/incorrect_source.cpp" " void undefined_symbol() {}; ") +endif() +add_library(l0 SHARED incorrect_source.cpp) +add_library(l1 MODULE incorrect_source.cpp) +add_library(l2 STATIC incorrect_source.cpp) +add_library(l3 OBJECT incorrect_source.cpp) +]=] + ) + try_compile(SUCCESS "${TEST_PROJECT}/build" "${TEST_PROJECT}" test + CMAKE_FLAGS + "-DCMAKE_SHARED_LINKER_FLAGS=${CMAKE_SHARED_LINKER_FLAGS}" + "-DCMAKE_MODULE_LINKER_FLAGS=${CMAKE_MODULE_LINKER_FLAGS}" + "-DEXPECT_SUCCESS=${EXPECT}" + ) + if (NOT ${SUCCESS} STREQUAL ${EXPECT}) + message(FATAL_ERROR "Undefined symbols test failure: expect(${EXPECT}), success(${SUCCESS})") + endif() + file(REMOVE_RECURSE "${TEST_PROJECT}") + endforeach() +endfunction() +if (NOT (CMAKE_SYSTEM_NAME MATCHES "kOpenBSD.*|OpenBSD.*") AND NOT OSSFUZZ) + forbid_undefined_symbols() +endif() + +if (MINGW) + function(export_all_symbols) + unset(TMP) + add_linker_flag_if_supported(-Wl,--export-all-symbols TMP) + string(APPEND CMAKE_SHARED_LINKER_FLAGS ${TMP}) + string(APPEND CMAKE_MODULE_LINKER_FLAGS ${TMP}) + set(CMAKE_SHARED_LINKER_FLAGS ${CMAKE_SHARED_LINKER_FLAGS} PARENT_SCOPE) + set(CMAKE_MODULE_LINKER_FLAGS ${CMAKE_MODULE_LINKER_FLAGS} PARENT_SCOPE) + endfunction() + export_all_symbols() +endif() + if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE) message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}") @@ -526,6 +588,10 @@ if(STATIC AND NOT IOS) endif() endif() +if (WIN32) + list(APPEND OPENSSL_LIBRARIES ws2_32 crypt32) +endif() + find_package(HIDAPI) add_definition_if_library_exists(c memset_s "string.h" HAVE_MEMSET_S) @@ -508,19 +508,6 @@ cd ../.. Then you can run make as usual. -### On Linux for Android (using docker): - -```bash -# Build image (for ARM 32-bit) -docker build -f utils/build_scripts/android32.Dockerfile -t monero-android . -# Build image (for ARM 64-bit) -docker build -f utils/build_scripts/android64.Dockerfile -t monero-android . -# Create container -docker create -it --name monero-android monero-android bash -# Get binaries -docker cp monero-android:/src/build/release/bin . -``` - ### Building portable statically linked binaries By default, in either dynamically or statically linked builds, binaries target the specific host processor on which the build happens and are not portable to other processors. Portable binaries can be built using the following targets: diff --git a/cmake/FindCcache.cmake b/cmake/FindCcache.cmake index 2eb2fa2fd..d98518134 100644 --- a/cmake/FindCcache.cmake +++ b/cmake/FindCcache.cmake @@ -50,7 +50,7 @@ option (CCACHE "") file(WRITE "${CMAKE_SOURCE_DIR}/test.cpp" "int main() { return 0; }") set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CCACHE}") set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CCACHE}") -add_executable(test test.cpp) +add_executable(main test.cpp) ]=]) try_compile(RET "${TEST_PROJECT}/build" "${TEST_PROJECT}" "test" CMAKE_FLAGS -DCCACHE="${CCACHE_FOUND}") unset(TEST_PROJECT) diff --git a/cmake/FindHIDAPI.cmake b/cmake/FindHIDAPI.cmake index 9b45dcc4c..f56bab482 100644 --- a/cmake/FindHIDAPI.cmake +++ b/cmake/FindHIDAPI.cmake @@ -39,19 +39,28 @@ find_package_handle_standard_args(HIDAPI if(HIDAPI_FOUND) set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARY}") - if((STATIC AND UNIX AND NOT APPLE) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux")) + if((STATIC AND UNIX AND NOT APPLE) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux") OR ANDROID) find_library(LIBUSB-1.0_LIBRARY usb-1.0) find_library(LIBUDEV_LIBRARY udev) if(LIBUSB-1.0_LIBRARY) set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARIES};${LIBUSB-1.0_LIBRARY}") if(LIBUDEV_LIBRARY) set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARIES};${LIBUDEV_LIBRARY}") - else() + elseif(NOT ANDROID) message(WARNING "libudev library not found, binaries may fail to link.") endif() else() message(WARNING "libusb-1.0 library not found, binaries may fail to link.") endif() + if(ANDROID) + # libusb uses android log library + find_library(ANDROID_LOG_LIBRARY log) + if(ANDROID_LOG_LIBRARY) + set(HIDAPI_LIBRARIES "${HIDAPI_LIBRARIES};${ANDROID_LOG_LIBRARY}") + else() + message(WARNING "Android log library not found, binaries may fail to link.") + endif() + endif() endif() set(HIDAPI_INCLUDE_DIRS "${HIDAPI_INCLUDE_DIR}") diff --git a/cmake/FindLibUSB.cmake b/cmake/FindLibUSB.cmake index 6944c6c45..7f8a11460 100644 --- a/cmake/FindLibUSB.cmake +++ b/cmake/FindLibUSB.cmake @@ -99,7 +99,7 @@ if ( 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) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux")) + if((STATIC AND UNIX AND NOT APPLE) OR (DEPENDS AND CMAKE_SYSTEM_NAME STREQUAL "Linux") OR ANDROID) find_library(LIBUDEV_LIBRARY udev) if(LIBUDEV_LIBRARY) set(LibUSB_LIBRARIES "${LibUSB_LIBRARIES};${LIBUDEV_LIBRARY}") diff --git a/contrib/depends/Makefile b/contrib/depends/Makefile index 0d71ddb13..9ffe8a106 100644 --- a/contrib/depends/Makefile +++ b/contrib/depends/Makefile @@ -3,7 +3,7 @@ SOURCES_PATH ?= $(BASEDIR)/sources BASE_CACHE ?= $(BASEDIR)/built SDK_PATH ?= $(BASEDIR)/SDKs -FALLBACK_DOWNLOAD_PATH ?= https://bitcoincore.org/depends-sources +FALLBACK_DOWNLOAD_PATH ?= https://downloads.getmonero.org/depends-sources BUILD = $(shell ./config.guess) HOST ?= $(BUILD) diff --git a/contrib/depends/funcs.mk b/contrib/depends/funcs.mk index 2d6b37190..ffda2b5b2 100644 --- a/contrib/depends/funcs.mk +++ b/contrib/depends/funcs.mk @@ -32,7 +32,7 @@ endef define fetch_file ( test -f $$($(1)_source_dir)/$(4) || \ ( $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5)) || \ - $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(3),$(4),$(5)))) + $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(4),$(4),$(5)))) endef define int_get_build_recipe_hash diff --git a/contrib/depends/packages/eudev.mk b/contrib/depends/packages/eudev.mk index 0e930df93..6b6887e98 100644 --- a/contrib/depends/packages/eudev.mk +++ b/contrib/depends/packages/eudev.mk @@ -1,7 +1,8 @@ package=eudev $(package)_version=v3.2.6 $(package)_download_path=https://github.com/gentoo/eudev/archive/ -$(package)_file_name=$($(package)_version).tar.gz +$(package)_download_file=$($(package)_version).tar.gz +$(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=a96ecb8637667897b8bd4dee4c22c7c5f08b327be45186e912ce6bc768385852 define $(package)_set_vars diff --git a/contrib/depends/packages/gtest.mk b/contrib/depends/packages/gtest.mk index 5df07a32e..1208d7c03 100644 --- a/contrib/depends/packages/gtest.mk +++ b/contrib/depends/packages/gtest.mk @@ -1,7 +1,8 @@ package=gtest $(package)_version=1.8.1 $(package)_download_path=https://github.com/google/googletest/archive/ -$(package)_file_name=release-$($(package)_version).tar.gz +$(package)_download_file=release-$($(package)_version).tar.gz +$(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=9bf1fe5182a604b4135edc1a425ae356c9ad15e9b23f9f12a02e80184c3a249c $(package)_cxxflags=-std=c++11 $(package)_cxxflags_linux=-fPIC diff --git a/contrib/depends/packages/native_cctools.mk b/contrib/depends/packages/native_cctools.mk index 8bf71254f..64a72e484 100644 --- a/contrib/depends/packages/native_cctools.mk +++ b/contrib/depends/packages/native_cctools.mk @@ -1,7 +1,8 @@ package=native_cctools $(package)_version=807d6fd1be5d2224872e381870c0a75387fe05e6 $(package)_download_path=https://github.com/theuni/cctools-port/archive -$(package)_file_name=$($(package)_version).tar.gz +$(package)_download_file=$($(package)_version).tar.gz +$(package)_file_name=$(package)-$($(package)_version).tar.gz $(package)_sha256_hash=a09c9ba4684670a0375e42d9d67e7f12c1f62581a27f28f7c825d6d7032ccc6a $(package)_build_subdir=cctools $(package)_clang_version=3.7.1 diff --git a/src/blockchain_utilities/blockchain-stats-readme.md b/src/blockchain_utilities/blockchain-stats-readme.md index e02cd5560..9552a3e67 100644 --- a/src/blockchain_utilities/blockchain-stats-readme.md +++ b/src/blockchain_utilities/blockchain-stats-readme.md @@ -10,8 +10,10 @@ From the command line run: `$ monero-blockchain-stats` -This loads the existing blockchain and prints the results to the terminal. Default printed data includes Blocks per Day, Total Blocks, Transactions per Day, Total Transactions, Bytes per Day and Total Bytes. The format of the output is in tab delimited csv which is printed to the console. Piping the output of the command to a csv file allows for saving the output of the utilty to a file. -i.e. `monero-blockchain-stats > stats.csv` +This loads the existing blockchain and prints the results to the terminal. Default printed data includes Blocks per Day, Total Blocks, Transactions per Day, Total Transactions, Bytes per Day and Total Bytes. The format of the output is in tab delimited csv which is printed to the console. Redirecting or piping the output of the command allows for saving the output to a csv file or feeding your own script accordingly, i.e.: + +- `monero-blockchain-stats > stats-$(date +'%Y-%m-%d').csv` +- `monero-blockchain-stats | save-to-database.sh` ### Options `--data-dir arg` diff --git a/src/blocks/CMakeLists.txt b/src/blocks/CMakeLists.txt index 445596a66..d2003316d 100644 --- a/src/blocks/CMakeLists.txt +++ b/src/blocks/CMakeLists.txt @@ -28,20 +28,32 @@ set(GENERATED_SOURCES "") +set(GENERATOR "${CMAKE_CURRENT_BINARY_DIR}/blocks_generator.cmake") +file(GENERATE OUTPUT ${GENERATOR} CONTENT [=[ +file(READ "${INPUT_DAT_FILE}" DATA HEX) +string(REGEX REPLACE "[0-9a-fA-F][0-9a-fA-F]" "0x\\0," DATA "${DATA}") +file(WRITE "${OUTPUT_C_SOURCE}" " +#include <stddef.h> +const unsigned char ${BLOB_NAME}[]={ + ${DATA} +}; +const size_t ${BLOB_NAME}_len = sizeof(${BLOB_NAME}); +" +) +]=]) foreach(BLOB_NAME checkpoints testnet_blocks stagenet_blocks) set(OUTPUT_C_SOURCE "generated_${BLOB_NAME}.c") list(APPEND GENERATED_SOURCES ${OUTPUT_C_SOURCE}) set(INPUT_DAT_FILE "${BLOB_NAME}.dat") add_custom_command( - OUTPUT ${OUTPUT_C_SOURCE} - MAIN_DEPENDENCY ${INPUT_DAT_FILE} - COMMAND - cd ${CMAKE_CURRENT_BINARY_DIR} && - echo "'#include\t<stddef.h>'" > ${OUTPUT_C_SOURCE} && - echo "'const\tunsigned\tchar\t${BLOB_NAME}[]={'" >> ${OUTPUT_C_SOURCE} && - od -v -An -tx1 ${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE} | sed -e "'s/[0-9a-fA-F]\\{1,\\}/0x&,/g'" -e "'$$s/.$$//'" >> ${OUTPUT_C_SOURCE} && - echo "'};'" >> ${OUTPUT_C_SOURCE} && - echo "'const\tsize_t\t${BLOB_NAME}_len\t=\tsizeof(${BLOB_NAME});'" >> ${OUTPUT_C_SOURCE} + OUTPUT ${OUTPUT_C_SOURCE} + MAIN_DEPENDENCY ${INPUT_DAT_FILE} + DEPENDS ${GENERATOR} + COMMAND ${CMAKE_COMMAND} + "-DINPUT_DAT_FILE=${CMAKE_CURRENT_SOURCE_DIR}/${INPUT_DAT_FILE}" + "-DBLOB_NAME=${BLOB_NAME}" + "-DOUTPUT_C_SOURCE=${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT_C_SOURCE}" + -P "${GENERATOR}" ) endforeach() diff --git a/src/cryptonote_basic/CMakeLists.txt b/src/cryptonote_basic/CMakeLists.txt index c9fb1433c..e386ec4ea 100644 --- a/src/cryptonote_basic/CMakeLists.txt +++ b/src/cryptonote_basic/CMakeLists.txt @@ -36,6 +36,14 @@ if(APPLE) endif() endif() +monero_add_library(cryptonote_format_utils_basic + cryptonote_format_utils_basic.cpp +) +target_link_libraries(cryptonote_format_utils_basic + PUBLIC + cncrypto +) + set(cryptonote_basic_sources account.cpp connection_context.cpp @@ -74,6 +82,7 @@ target_link_libraries(cryptonote_basic common cncrypto checkpoints + cryptonote_format_utils_basic device ${Boost_DATE_TIME_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} diff --git a/src/cryptonote_basic/cryptonote_format_utils.cpp b/src/cryptonote_basic/cryptonote_format_utils.cpp index 5cd40ce79..17adcdc35 100644 --- a/src/cryptonote_basic/cryptonote_format_utils.cpp +++ b/src/cryptonote_basic/cryptonote_format_utils.cpp @@ -139,22 +139,6 @@ namespace cryptonote return h; } - //--------------------------------------------------------------- - void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h) - { - std::ostringstream s; - binary_archive<true> a(s); - ::serialization::serialize(a, const_cast<transaction_prefix&>(tx)); - crypto::cn_fast_hash(s.str().data(), s.str().size(), h); - } - //--------------------------------------------------------------- - crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx) - { - crypto::hash h = null_hash; - get_transaction_prefix_hash(tx, h); - return h; - } - //--------------------------------------------------------------- bool expand_transaction_1(transaction &tx, bool base_only) { if (tx.version >= 2 && !is_coinbase(tx)) diff --git a/src/cryptonote_basic/cryptonote_format_utils_basic.cpp b/src/cryptonote_basic/cryptonote_format_utils_basic.cpp new file mode 100644 index 000000000..29130ce46 --- /dev/null +++ b/src/cryptonote_basic/cryptonote_format_utils_basic.cpp @@ -0,0 +1,49 @@ +// Copyright (c) 2014-2021, The Monero Project +// +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without modification, are +// permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright notice, this list of +// conditions and the following disclaimer. +// +// 2. Redistributions in binary form must reproduce the above copyright notice, this list +// of conditions and the following disclaimer in the documentation and/or other +// materials provided with the distribution. +// +// 3. Neither the name of the copyright holder nor the names of its contributors may be +// used to endorse or promote products derived from this software without specific +// prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL +// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF +// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers + +#include "cryptonote_format_utils.h" + +namespace cryptonote +{ + void get_transaction_prefix_hash(const transaction_prefix& tx, crypto::hash& h) + { + std::ostringstream s; + binary_archive<true> a(s); + ::serialization::serialize(a, const_cast<transaction_prefix&>(tx)); + crypto::cn_fast_hash(s.str().data(), s.str().size(), h); + } + + crypto::hash get_transaction_prefix_hash(const transaction_prefix& tx) + { + crypto::hash h = crypto::null_hash; + get_transaction_prefix_hash(tx, h); + return h; + } +} diff --git a/src/cryptonote_protocol/cryptonote_protocol_handler.inl b/src/cryptonote_protocol/cryptonote_protocol_handler.inl index 685968c08..106253082 100644 --- a/src/cryptonote_protocol/cryptonote_protocol_handler.inl +++ b/src/cryptonote_protocol/cryptonote_protocol_handler.inl @@ -2081,6 +2081,8 @@ skip: } MDEBUG(context << "Nothing to get from this peer, and it's not ahead of us, all done"); context.m_state = cryptonote_connection_context::state_normal; + if (m_core.get_current_blockchain_height() >= m_core.get_target_blockchain_height()) + on_connection_synchronized(); return true; } uint64_t next_needed_height = m_block_queue.get_next_needed_height(bc_height); @@ -2228,6 +2230,8 @@ skip: } MDEBUG(context << "Nothing to get from this peer, and it's not ahead of us, all done"); context.m_state = cryptonote_connection_context::state_normal; + if (m_core.get_current_blockchain_height() >= m_core.get_target_blockchain_height()) + on_connection_synchronized(); return true; } @@ -2419,10 +2423,7 @@ skip: if (context.m_remote_blockchain_height >= m_core.get_target_blockchain_height()) { if (m_core.get_current_blockchain_height() >= m_core.get_target_blockchain_height()) - { - MGINFO_GREEN("SYNCHRONIZED OK"); on_connection_synchronized(); - } } else { diff --git a/src/device/CMakeLists.txt b/src/device/CMakeLists.txt index ff2afba4b..3597ab336 100644 --- a/src/device/CMakeLists.txt +++ b/src/device/CMakeLists.txt @@ -71,6 +71,7 @@ target_link_libraries(device PUBLIC ${HIDAPI_LIBRARIES} cncrypto + cryptonote_format_utils_basic ringct_basic wallet-crypto ${OPENSSL_CRYPTO_LIBRARIES} diff --git a/src/device/device_ledger.cpp b/src/device/device_ledger.cpp index 384b776ee..5caad3a1a 100644 --- a/src/device/device_ledger.cpp +++ b/src/device/device_ledger.cpp @@ -518,9 +518,7 @@ namespace hw { } bool device_ledger::init(void) { - #ifdef DEBUG_HWDEVICE this->controle_device = &hw::get_device("default"); - #endif this->release(); hw_device.init(); MDEBUG( "Device "<<this->id <<" HIDUSB inited"); @@ -686,7 +684,6 @@ namespace hw { /* ======================================================================= */ bool device_ledger::derive_subaddress_public_key(const crypto::public_key &pub, const crypto::key_derivation &derivation, const std::size_t output_index, crypto::public_key &derived_pub){ - AUTO_LOCK_CMD(); #ifdef DEBUG_HWDEVICE const crypto::public_key pub_x = pub; crypto::key_derivation derivation_x; @@ -710,7 +707,7 @@ namespace hw { MDEBUG( "derive_subaddress_public_key : PARSE mode with known viewkey"); crypto::derive_subaddress_public_key(pub, derivation, output_index,derived_pub); } else { - + AUTO_LOCK_CMD(); int offset = set_command_header_noopt(INS_DERIVE_SUBADDRESS_PUBLIC_KEY); //pub memmove(this->buffer_send+offset, pub.data, 32); @@ -739,6 +736,12 @@ namespace hw { } crypto::public_key device_ledger::get_subaddress_spend_public_key(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { + if (has_view_key) { + cryptonote::account_keys keys_{keys}; + keys_.m_view_secret_key = this->viewkey; + return this->controle_device->get_subaddress_spend_public_key(keys_, index); + } + AUTO_LOCK_CMD(); crypto::public_key D; @@ -790,6 +793,12 @@ namespace hw { } cryptonote::account_public_address device_ledger::get_subaddress(const cryptonote::account_keys& keys, const cryptonote::subaddress_index &index) { + if (has_view_key) { + cryptonote::account_keys keys_{keys}; + keys_.m_view_secret_key = this->viewkey; + return this->controle_device->get_subaddress(keys_, index); + } + AUTO_LOCK_CMD(); cryptonote::account_public_address address; @@ -1038,7 +1047,6 @@ namespace hw { } bool device_ledger::generate_key_derivation(const crypto::public_key &pub, const crypto::secret_key &sec, crypto::key_derivation &derivation) { - AUTO_LOCK_CMD(); bool r = false; #ifdef DEBUG_HWDEVICE @@ -1059,6 +1067,7 @@ namespace hw { assert(is_fake_view_key(sec)); r = crypto::generate_key_derivation(pub, this->viewkey, derivation); } else { + AUTO_LOCK_CMD(); int offset = set_command_header_noopt(INS_GEN_KEY_DERIVATION); //pub memmove(this->buffer_send+offset, pub.data, 32); diff --git a/src/device/device_ledger.hpp b/src/device/device_ledger.hpp index 00ff05ec5..3b6cc505f 100644 --- a/src/device/device_ledger.hpp +++ b/src/device/device_ledger.hpp @@ -181,11 +181,8 @@ namespace hw { // To speed up blockchain parsing the view key maybe handle here. crypto::secret_key viewkey; bool has_view_key; - - //extra debug - #ifdef DEBUG_HWDEVICE + device *controle_device; - #endif public: device_ledger(); diff --git a/src/device_trezor/device_trezor_base.cpp b/src/device_trezor/device_trezor_base.cpp index 5f21ecd49..b0b4342f5 100644 --- a/src/device_trezor/device_trezor_base.cpp +++ b/src/device_trezor/device_trezor_base.cpp @@ -511,7 +511,7 @@ namespace trezor { const auto data_cleaner = epee::misc_utils::create_scope_leave_handler([&]() { if (m.has_passphrase()) - memwipe(&(m.mutable_passphrase())[0], m.mutable_passphrase()->size()); + memwipe(&(*m.mutable_passphrase())[0], m.mutable_passphrase()->size()); }); resp = call_raw(&m); diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt index aa4102481..15e433e10 100644 --- a/src/rpc/CMakeLists.txt +++ b/src/rpc/CMakeLists.txt @@ -39,7 +39,7 @@ set(rpc_sources core_rpc_server.cpp rpc_payment.cpp rpc_version_str.cpp - instanciations) + instanciations.cpp) set(daemon_messages_sources message.cpp diff --git a/src/serialization/json_object.cpp b/src/serialization/json_object.cpp index 67f042c2e..28e207ff2 100644 --- a/src/serialization/json_object.cpp +++ b/src/serialization/json_object.cpp @@ -1091,9 +1091,12 @@ void toJsonValue(rapidjson::Writer<epee::byte_stream>& dest, const rct::rctSig& }; INSERT_INTO_JSON_OBJECT(dest, type, sig.type); - INSERT_INTO_JSON_OBJECT(dest, encrypted, sig.ecdhInfo); - INSERT_INTO_JSON_OBJECT(dest, commitments, transform(sig.outPk, just_mask)); - INSERT_INTO_JSON_OBJECT(dest, fee, sig.txnFee); + if (sig.type != rct::RCTTypeNull) + { + INSERT_INTO_JSON_OBJECT(dest, encrypted, sig.ecdhInfo); + INSERT_INTO_JSON_OBJECT(dest, commitments, transform(sig.outPk, just_mask)); + INSERT_INTO_JSON_OBJECT(dest, fee, sig.txnFee); + } // prunable if (!sig.p.bulletproofs.empty() || !sig.p.rangeSigs.empty() || !sig.p.MGs.empty() || !sig.get_pseudo_outs().empty()) @@ -1122,9 +1125,12 @@ void fromJsonValue(const rapidjson::Value& val, rct::rctSig& sig) } GET_FROM_JSON_OBJECT(val, sig.type, type); - GET_FROM_JSON_OBJECT(val, sig.ecdhInfo, encrypted); - GET_FROM_JSON_OBJECT(val, sig.outPk, commitments); - GET_FROM_JSON_OBJECT(val, sig.txnFee, fee); + if (sig.type != rct::RCTTypeNull) + { + GET_FROM_JSON_OBJECT(val, sig.ecdhInfo, encrypted); + GET_FROM_JSON_OBJECT(val, sig.outPk, commitments); + GET_FROM_JSON_OBJECT(val, sig.txnFee, fee); + } // prunable const auto prunable = val.FindMember("prunable"); diff --git a/src/wallet/api/CMakeLists.txt b/src/wallet/api/CMakeLists.txt index 30eb4ce03..655cdfefd 100644 --- a/src/wallet/api/CMakeLists.txt +++ b/src/wallet/api/CMakeLists.txt @@ -71,10 +71,13 @@ target_link_libraries(wallet_api mnemonics ${LMDB_LIBRARY} ${Boost_CHRONO_LIBRARY} + ${Boost_LOCALE_LIBRARY} + ${ICU_LIBRARIES} ${Boost_SERIALIZATION_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${Boost_THREAD_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} ${Boost_REGEX_LIBRARY} PRIVATE ${EXTRA_LIBRARIES}) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 05fe0a1ad..217a22027 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -1213,6 +1213,7 @@ wallet2::wallet2(network_type nettype, uint64_t kdf_rounds, bool unattended, std wallet2::~wallet2() { + deinit(); } bool wallet2::has_testnet_option(const boost::program_options::variables_map& vm) @@ -1320,6 +1321,9 @@ bool wallet2::set_daemon(std::string daemon_address, boost::optional<epee::net_u m_trusted_daemon = trusted_daemon; if (changed) { + if (!m_persistent_rpc_client_id) { + set_rpc_client_secret_key(rct::rct2sk(rct::skGen())); + } m_rpc_payment_state.expected_spent = 0; m_rpc_payment_state.discrepancy = 0; m_node_rpc_proxy.invalidate(); @@ -2773,9 +2777,8 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector<cry { if (tx_cache_data[i].empty()) continue; - tpool.submit(&waiter, [&hwdev, &gender, &tx_cache_data, i]() { + tpool.submit(&waiter, [&gender, &tx_cache_data, i]() { auto &slot = tx_cache_data[i]; - boost::unique_lock<hw::device> hwdev_lock(hwdev); for (auto &iod: slot.primary) gender(iod); for (auto &iod: slot.additional) @@ -3491,14 +3494,6 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo blocks_fetched += added_blocks; } THROW_WALLET_EXCEPTION_IF(!waiter.wait(), error::wallet_internal_error, "Exception in thread pool"); - if(!first && blocks_start_height == next_blocks_start_height) - { - m_node_rpc_proxy.set_height(m_blockchain.size()); - refreshed = true; - break; - } - - first = false; // handle error from async fetching thread if (error) @@ -3509,6 +3504,15 @@ void wallet2::refresh(bool trusted_daemon, uint64_t start_height, uint64_t & blo throw std::runtime_error("proxy exception in refresh thread"); } + if(!first && blocks_start_height == next_blocks_start_height) + { + m_node_rpc_proxy.set_height(m_blockchain.size()); + refreshed = true; + break; + } + + first = false; + if (!next_blocks.empty()) { const uint64_t expected_start_height = std::max(static_cast<uint64_t>(m_blockchain.size()), uint64_t(1)) - 1; @@ -3745,9 +3749,11 @@ void wallet2::detach_blockchain(uint64_t height, std::map<std::pair<uint64_t, ui //---------------------------------------------------------------------------------------------------- bool wallet2::deinit() { - m_is_initialized=false; - unlock_keys_file(); - m_account.deinit(); + if(m_is_initialized) { + m_is_initialized = false; + unlock_keys_file(); + m_account.deinit(); + } return true; } //---------------------------------------------------------------------------------------------------- @@ -4422,7 +4428,7 @@ bool wallet2::load_keys_buf(const std::string& keys_buf, const epee::wipeable_st account_public_address device_account_public_address; THROW_WALLET_EXCEPTION_IF(!hwdev.get_public_address(device_account_public_address), error::wallet_internal_error, "Cannot get a device address"); - THROW_WALLET_EXCEPTION_IF(device_account_public_address != m_account.get_keys().m_account_address, error::wallet_internal_error, "Device wallet does not match wallet address. " + THROW_WALLET_EXCEPTION_IF(device_account_public_address != m_account.get_keys().m_account_address, error::wallet_internal_error, "Device wallet does not match wallet address. If the device uses the passphrase feature, please check whether the passphrase was entered correctly (it may have been misspelled - different passphrases generate different wallets, passphrase is case-sensitive). " "Device address: " + cryptonote::get_account_address_as_str(m_nettype, false, device_account_public_address) + ", wallet address: " + m_account.get_public_address_str(m_nettype)); LOG_PRINT_L0("Device inited..."); @@ -8587,18 +8593,30 @@ void wallet2::get_outs(std::vector<std::vector<tools::wallet2::get_outs_entry>> } // get the keys for those - req.get_txid = false; - + // the response can get large and end up rejected by the anti DoS limits, so chunk it if needed + size_t offset = 0; + while (offset < req.outputs.size()) { + static const size_t chunk_size = 1000; + COMMAND_RPC_GET_OUTPUTS_BIN::request chunk_req = AUTO_VAL_INIT(chunk_req); + COMMAND_RPC_GET_OUTPUTS_BIN::response chunk_daemon_resp = AUTO_VAL_INIT(chunk_daemon_resp); + chunk_req.get_txid = false; + for (size_t i = 0; i < std::min<size_t>(req.outputs.size() - offset, chunk_size); ++i) + chunk_req.outputs.push_back(req.outputs[offset + i]); + const boost::lock_guard<boost::recursive_mutex> lock{m_daemon_rpc_mutex}; uint64_t pre_call_credits = m_rpc_payment_state.credits; - req.client = get_client_signature(); - bool r = epee::net_utils::invoke_http_bin("/get_outs.bin", req, daemon_resp, *m_http_client, rpc_timeout); - THROW_ON_RPC_RESPONSE_ERROR(r, {}, daemon_resp, "get_outs.bin", error::get_outs_error, get_rpc_status(daemon_resp.status)); - THROW_WALLET_EXCEPTION_IF(daemon_resp.outs.size() != req.outputs.size(), error::wallet_internal_error, + chunk_req.client = get_client_signature(); + bool r = epee::net_utils::invoke_http_bin("/get_outs.bin", chunk_req, chunk_daemon_resp, *m_http_client, rpc_timeout); + THROW_ON_RPC_RESPONSE_ERROR(r, {}, chunk_daemon_resp, "get_outs.bin", error::get_outs_error, get_rpc_status(chunk_daemon_resp.status)); + THROW_WALLET_EXCEPTION_IF(chunk_daemon_resp.outs.size() != chunk_req.outputs.size(), error::wallet_internal_error, "daemon returned wrong response for get_outs.bin, wrong amounts count = " + - std::to_string(daemon_resp.outs.size()) + ", expected " + std::to_string(req.outputs.size())); - check_rpc_cost("/get_outs.bin", daemon_resp.credits, pre_call_credits, daemon_resp.outs.size() * COST_PER_OUT); + std::to_string(chunk_daemon_resp.outs.size()) + ", expected " + std::to_string(chunk_req.outputs.size())); + check_rpc_cost("/get_outs.bin", chunk_daemon_resp.credits, pre_call_credits, chunk_daemon_resp.outs.size() * COST_PER_OUT); + + offset += chunk_size; + for (size_t i = 0; i < chunk_daemon_resp.outs.size(); ++i) + daemon_resp.outs.push_back(std::move(chunk_daemon_resp.outs[i])); } std::unordered_map<uint64_t, uint64_t> scanty_outs; diff --git a/src/wallet/wallet_rpc_server.cpp b/src/wallet/wallet_rpc_server.cpp index b72817ba0..e1a06886b 100644 --- a/src/wallet/wallet_rpc_server.cpp +++ b/src/wallet/wallet_rpc_server.cpp @@ -1292,13 +1292,20 @@ namespace tools try { // gather info to ask the user - std::unordered_map<cryptonote::account_public_address, std::pair<std::string, uint64_t>> dests; + std::unordered_map<cryptonote::account_public_address, std::pair<std::string, uint64_t>> tx_dests; + std::unordered_map<cryptonote::account_public_address, std::pair<std::string, uint64_t>> all_dests; int first_known_non_zero_change_index = -1; + res.summary.amount_in = 0; + res.summary.amount_out = 0; + res.summary.change_amount = 0; + res.summary.fee = 0; for (size_t n = 0; n < tx_constructions.size(); ++n) { const tools::wallet2::tx_construction_data &cd = tx_constructions[n]; res.desc.push_back({0, 0, std::numeric_limits<uint32_t>::max(), 0, {}, "", 0, "", 0, 0, ""}); wallet_rpc::COMMAND_RPC_DESCRIBE_TRANSFER::transfer_description &desc = res.desc.back(); + // Clear the recipients collection ready for this loop iteration + tx_dests.clear(); std::vector<cryptonote::tx_extra_field> tx_extra_fields; bool has_encrypted_payment_id = false; @@ -1337,17 +1344,17 @@ namespace tools std::string address = cryptonote::get_account_address_as_str(m_wallet->nettype(), entry.is_subaddress, entry.addr); if (has_encrypted_payment_id && !entry.is_subaddress && address != entry.original) address = cryptonote::get_account_integrated_address_as_str(m_wallet->nettype(), entry.addr, payment_id8); - auto i = dests.find(entry.addr); - if (i == dests.end()) - dests.insert(std::make_pair(entry.addr, std::make_pair(address, entry.amount))); + auto i = tx_dests.find(entry.addr); + if (i == tx_dests.end()) + tx_dests.insert(std::make_pair(entry.addr, std::make_pair(address, entry.amount))); else i->second.second += entry.amount; desc.amount_out += entry.amount; } if (cd.change_dts.amount > 0) { - auto it = dests.find(cd.change_dts.addr); - if (it == dests.end()) + auto it = tx_dests.find(cd.change_dts.addr); + if (it == tx_dests.end()) { er.code = WALLET_RPC_ERROR_CODE_BAD_UNSIGNED_TX_DATA; er.message = "Claimed change does not go to a paid address"; @@ -1374,29 +1381,45 @@ namespace tools desc.change_amount += cd.change_dts.amount; it->second.second -= cd.change_dts.amount; if (it->second.second == 0) - dests.erase(cd.change_dts.addr); + tx_dests.erase(cd.change_dts.addr); } - for (auto i = dests.begin(); i != dests.end(); ) + for (auto i = tx_dests.begin(); i != tx_dests.end(); ++i) { if (i->second.second > 0) { desc.recipients.push_back({i->second.first, i->second.second}); + auto it_in_all = all_dests.find(i->first); + if (it_in_all == all_dests.end()) + all_dests.insert(std::make_pair(i->first, i->second)); + else + it_in_all->second.second += i->second.second; } else ++desc.dummy_outputs; - ++i; } if (desc.change_amount > 0) { const tools::wallet2::tx_construction_data &cd0 = tx_constructions[0]; desc.change_address = get_account_address_as_str(m_wallet->nettype(), cd0.subaddr_account > 0, cd0.change_dts.addr); + res.summary.change_address = desc.change_address; } desc.fee = desc.amount_in - desc.amount_out; desc.unlock_time = cd.unlock_time; desc.extra = epee::to_hex::string({cd.extra.data(), cd.extra.size()}); + + // Update summary items + res.summary.amount_in += desc.amount_in; + res.summary.amount_out += desc.amount_out; + res.summary.change_amount += desc.change_amount; + res.summary.fee += desc.fee; + } + // Populate the summary recipients list + for (auto i = all_dests.begin(); i != all_dests.end(); ++i) + { + res.summary.recipients.push_back({i->second.first, i->second.second}); } } catch (const std::exception &e) diff --git a/src/wallet/wallet_rpc_server_commands_defs.h b/src/wallet/wallet_rpc_server_commands_defs.h index 6640441ed..248d31aa4 100644 --- a/src/wallet/wallet_rpc_server_commands_defs.h +++ b/src/wallet/wallet_rpc_server_commands_defs.h @@ -47,7 +47,7 @@ // advance which version they will stop working with // Don't go over 32767 for any of these #define WALLET_RPC_VERSION_MAJOR 1 -#define WALLET_RPC_VERSION_MINOR 22 +#define WALLET_RPC_VERSION_MINOR 23 #define MAKE_WALLET_RPC_VERSION(major,minor) (((major)<<16)|(minor)) #define WALLET_RPC_VERSION MAKE_WALLET_RPC_VERSION(WALLET_RPC_VERSION_MAJOR, WALLET_RPC_VERSION_MINOR) namespace tools @@ -701,6 +701,25 @@ namespace wallet_rpc END_KV_SERIALIZE_MAP() }; + struct txset_summary + { + uint64_t amount_in; + uint64_t amount_out; + std::list<recipient> recipients; + uint64_t change_amount; + std::string change_address; + uint64_t fee; + + BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(amount_in) + KV_SERIALIZE(amount_out) + KV_SERIALIZE(recipients) + KV_SERIALIZE(change_amount) + KV_SERIALIZE(change_address) + KV_SERIALIZE(fee) + END_KV_SERIALIZE_MAP() + }; + struct request_t { std::string unsigned_txset; @@ -716,8 +735,10 @@ namespace wallet_rpc struct response_t { std::list<transfer_description> desc; + struct txset_summary summary; BEGIN_KV_SERIALIZE_MAP() + KV_SERIALIZE(summary) KV_SERIALIZE(desc) END_KV_SERIALIZE_MAP() }; diff --git a/tests/unit_tests/logging.cpp b/tests/unit_tests/logging.cpp index b3afba243..f11b17412 100644 --- a/tests/unit_tests/logging.cpp +++ b/tests/unit_tests/logging.cpp @@ -195,3 +195,16 @@ TEST(logging, multiline) cleanup(); } +// These operations might segfault +TEST(logging, copy_ctor_segfault) +{ + const el::Logger log1("id1", nullptr); + const el::Logger log2(log1); +} + +TEST(logging, operator_equals_segfault) +{ + const el::Logger log1("id1", nullptr); + el::Logger log2("id2", nullptr); + log2 = log1; +} diff --git a/utils/build_scripts/android32.Dockerfile b/utils/build_scripts/android32.Dockerfile deleted file mode 100644 index c0931ce05..000000000 --- a/utils/build_scripts/android32.Dockerfile +++ /dev/null @@ -1,134 +0,0 @@ -FROM debian:stable - -RUN apt-get update && apt-get install -y unzip automake build-essential curl file pkg-config git python libtool libtinfo5 - -WORKDIR /opt/android -## INSTALL ANDROID SDK -ENV ANDROID_SDK_REVISION 4333796 -ENV ANDROID_SDK_HASH 92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9 -RUN curl -s -O https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \ - && echo "${ANDROID_SDK_HASH} sdk-tools-linux-${ANDROID_SDK_REVISION}.zip" | sha256sum -c \ - && unzip sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \ - && rm -f sdk-tools-linux-${ANDROID_SDK_REVISION}.zip - -## INSTALL ANDROID NDK -ENV ANDROID_NDK_REVISION 17b -ENV ANDROID_NDK_HASH 5dfbbdc2d3ba859fed90d0e978af87c71a91a5be1f6e1c40ba697503d48ccecd -RUN curl -s -O https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \ - && echo "${ANDROID_NDK_HASH} android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip" | sha256sum -c \ - && unzip android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \ - && rm -f android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip - -ENV WORKDIR /opt/android -ENV ANDROID_SDK_ROOT ${WORKDIR}/tools -ENV ANDROID_NDK_ROOT ${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION} -ENV PREFIX /opt/android/prefix - -ENV TOOLCHAIN_DIR ${WORKDIR}/toolchain-arm -RUN ${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py \ - --arch arm \ - --api 21 \ - --install-dir ${TOOLCHAIN_DIR} \ - --stl=libc++ - -#INSTALL cmake -ENV CMAKE_VERSION 3.12.1 -RUN cd /usr \ - && curl -s -O https://cmake.org/files/v3.12/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \ - && tar -xzf /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \ - && rm -f /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz -ENV PATH /usr/cmake-${CMAKE_VERSION}-Linux-x86_64/bin:$PATH - -## Boost -ARG BOOST_VERSION=1_68_0 -ARG BOOST_VERSION_DOT=1.68.0 -ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7 -RUN set -ex \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \ - && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ - && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ - && rm -f boost_${BOOST_VERSION}.tar.bz2 \ - && cd boost_${BOOST_VERSION} \ - && ./bootstrap.sh --prefix=${PREFIX} - -ENV HOST_PATH $PATH -ENV PATH $TOOLCHAIN_DIR/arm-linux-androideabi/bin:$TOOLCHAIN_DIR/bin:$PATH - -ARG NPROC=1 - -# Build iconv for lib boost locale -ENV ICONV_VERSION 1.15 -ENV ICONV_HASH ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178 -RUN curl -s -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz \ - && echo "${ICONV_HASH} libiconv-${ICONV_VERSION}.tar.gz" | sha256sum -c \ - && tar -xzf libiconv-${ICONV_VERSION}.tar.gz \ - && rm -f libiconv-${ICONV_VERSION}.tar.gz \ - && cd libiconv-${ICONV_VERSION} \ - && CC=arm-linux-androideabi-clang CXX=arm-linux-androideabi-clang++ ./configure --build=x86_64-linux-gnu --host=arm-eabi --prefix=${PREFIX} --disable-rpath \ - && make -j${NPROC} && make install - -## Build BOOST -RUN cd boost_${BOOST_VERSION} \ - && ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale --build-dir=android --stagedir=android toolset=clang threading=multi threadapi=pthread target-os=android -sICONV_PATH=${PREFIX} install -j${NPROC} - -#Note : we build openssl because the default lacks DSA1 - -# download, configure and make Zlib -ENV ZLIB_VERSION 1.2.11 -ENV ZLIB_HASH c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 -RUN curl -s -O https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz \ - && echo "${ZLIB_HASH} zlib-${ZLIB_VERSION}.tar.gz" | sha256sum -c \ - && tar -xzf zlib-${ZLIB_VERSION}.tar.gz \ - && rm zlib-${ZLIB_VERSION}.tar.gz \ - && mv zlib-${ZLIB_VERSION} zlib \ - && cd zlib && CC=clang CXX=clang++ ./configure --static \ - && make -j${NPROC} - -# open ssl -ARG OPENSSL_VERSION=1.0.2p -ARG OPENSSL_HASH=50a98e07b1a89eb8f6a99477f262df71c6fa7bef77df4dc83025a2845c827d00 -RUN curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \ - && echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \ - && tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \ - && rm openssl-${OPENSSL_VERSION}.tar.gz \ - && cd openssl-${OPENSSL_VERSION} \ - && sed -i -e "s/mandroid/target\ armv7\-none\-linux\-androideabi/" Configure \ - && CC=clang CXX=clang++ \ - ./Configure android-armv7 \ - no-asm \ - no-shared --static \ - --with-zlib-include=${WORKDIR}/zlib/include --with-zlib-lib=${WORKDIR}/zlib/lib \ - --prefix=${PREFIX} --openssldir=${PREFIX} \ - && make -j${NPROC} \ - && make install - -# ZMQ -ARG ZMQ_VERSION=v4.2.5 -ARG ZMQ_HASH=d062edd8c142384792955796329baf1e5a3377cd -RUN git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} \ - && cd libzmq \ - && test `git rev-parse HEAD` = ${ZMQ_HASH} || exit 1 \ - && ./autogen.sh \ - && CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=arm-linux-androideabi --enable-static --disable-shared \ - && make -j${NPROC} \ - && make install - -# Sodium -ARG SODIUM_VERSION=1.0.16 -ARG SODIUM_HASH=675149b9b8b66ff44152553fb3ebf9858128363d -RUN set -ex \ - && git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} \ - && cd libsodium \ - && test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 \ - && ./autogen.sh \ - && CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=arm-linux-androideabi --enable-static --disable-shared \ - && make -j${NPROC} \ - && make install - -ADD . /src -RUN cd /src \ - && CMAKE_INCLUDE_PATH="${PREFIX}/include" \ - CMAKE_LIBRARY_PATH="${PREFIX}/lib" \ - ANDROID_STANDALONE_TOOLCHAIN_PATH=${TOOLCHAIN_DIR} \ - USE_SINGLE_BUILDDIR=1 \ - PATH=${HOST_PATH} make release-static-android-armv7 -j${NPROC} diff --git a/utils/build_scripts/android64.Dockerfile b/utils/build_scripts/android64.Dockerfile deleted file mode 100644 index 3a62da464..000000000 --- a/utils/build_scripts/android64.Dockerfile +++ /dev/null @@ -1,134 +0,0 @@ -FROM debian:stable - -RUN apt-get update && apt-get install -y unzip automake build-essential curl file pkg-config git python libtool libtinfo5 - -WORKDIR /opt/android -## INSTALL ANDROID SDK -ENV ANDROID_SDK_REVISION 4333796 -ENV ANDROID_SDK_HASH 92ffee5a1d98d856634e8b71132e8a95d96c83a63fde1099be3d86df3106def9 -RUN curl -s -O https://dl.google.com/android/repository/sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \ - && echo "${ANDROID_SDK_HASH} sdk-tools-linux-${ANDROID_SDK_REVISION}.zip" | sha256sum -c \ - && unzip sdk-tools-linux-${ANDROID_SDK_REVISION}.zip \ - && rm -f sdk-tools-linux-${ANDROID_SDK_REVISION}.zip - -## INSTALL ANDROID NDK -ENV ANDROID_NDK_REVISION 17b -ENV ANDROID_NDK_HASH 5dfbbdc2d3ba859fed90d0e978af87c71a91a5be1f6e1c40ba697503d48ccecd -RUN curl -s -O https://dl.google.com/android/repository/android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \ - && echo "${ANDROID_NDK_HASH} android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip" | sha256sum -c \ - && unzip android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip \ - && rm -f android-ndk-r${ANDROID_NDK_REVISION}-linux-x86_64.zip - -ENV WORKDIR /opt/android -ENV ANDROID_SDK_ROOT ${WORKDIR}/tools -ENV ANDROID_NDK_ROOT ${WORKDIR}/android-ndk-r${ANDROID_NDK_REVISION} -ENV PREFIX /opt/android/prefix - -ENV TOOLCHAIN_DIR ${WORKDIR}/toolchain-arm -RUN ${ANDROID_NDK_ROOT}/build/tools/make_standalone_toolchain.py \ - --arch arm64 \ - --api 21 \ - --install-dir ${TOOLCHAIN_DIR} \ - --stl=libc++ - -#INSTALL cmake -ENV CMAKE_VERSION 3.12.1 -RUN cd /usr \ - && curl -s -O https://cmake.org/files/v3.12/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \ - && tar -xzf /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz \ - && rm -f /usr/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz -ENV PATH /usr/cmake-${CMAKE_VERSION}-Linux-x86_64/bin:$PATH - -## Boost -ARG BOOST_VERSION=1_68_0 -ARG BOOST_VERSION_DOT=1.68.0 -ARG BOOST_HASH=7f6130bc3cf65f56a618888ce9d5ea704fa10b462be126ad053e80e553d6d8b7 -RUN set -ex \ - && curl -s -L -o boost_${BOOST_VERSION}.tar.bz2 https://downloads.sourceforge.net/project/boost/boost/${BOOST_VERSION_DOT}/boost_${BOOST_VERSION}.tar.bz2 \ - && echo "${BOOST_HASH} boost_${BOOST_VERSION}.tar.bz2" | sha256sum -c \ - && tar -xvf boost_${BOOST_VERSION}.tar.bz2 \ - && rm -f boost_${BOOST_VERSION}.tar.bz2 \ - && cd boost_${BOOST_VERSION} \ - && ./bootstrap.sh --prefix=${PREFIX} - -ENV HOST_PATH $PATH -ENV PATH $TOOLCHAIN_DIR/aarch64-linux-android/bin:$TOOLCHAIN_DIR/bin:$PATH - -ARG NPROC=1 - -# Build iconv for lib boost locale -ENV ICONV_VERSION 1.15 -ENV ICONV_HASH ccf536620a45458d26ba83887a983b96827001e92a13847b45e4925cc8913178 -RUN curl -s -O http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz \ - && echo "${ICONV_HASH} libiconv-${ICONV_VERSION}.tar.gz" | sha256sum -c \ - && tar -xzf libiconv-${ICONV_VERSION}.tar.gz \ - && rm -f libiconv-${ICONV_VERSION}.tar.gz \ - && cd libiconv-${ICONV_VERSION} \ - && CC=aarch64-linux-android-clang CXX=aarch64-linux-android-clang++ ./configure --build=x86_64-linux-gnu --host=arm-eabi --prefix=${PREFIX} --disable-rpath \ - && make -j${NPROC} && make install - -## Build BOOST -RUN cd boost_${BOOST_VERSION} \ - && ./b2 --build-type=minimal link=static runtime-link=static --with-chrono --with-date_time --with-filesystem --with-program_options --with-regex --with-serialization --with-system --with-thread --with-locale --build-dir=android --stagedir=android toolset=clang threading=multi threadapi=pthread target-os=android -sICONV_PATH=${PREFIX} install -j${NPROC} - -#Note : we build openssl because the default lacks DSA1 - -# download, configure and make Zlib -ENV ZLIB_VERSION 1.2.11 -ENV ZLIB_HASH c3e5e9fdd5004dcb542feda5ee4f0ff0744628baf8ed2dd5d66f8ca1197cb1a1 -RUN curl -s -O https://zlib.net/zlib-${ZLIB_VERSION}.tar.gz \ - && echo "${ZLIB_HASH} zlib-${ZLIB_VERSION}.tar.gz" | sha256sum -c \ - && tar -xzf zlib-${ZLIB_VERSION}.tar.gz \ - && rm zlib-${ZLIB_VERSION}.tar.gz \ - && mv zlib-${ZLIB_VERSION} zlib \ - && cd zlib && CC=clang CXX=clang++ ./configure --static \ - && make -j${NPROC} - -# open ssl -ARG OPENSSL_VERSION=1.0.2p -ARG OPENSSL_HASH=50a98e07b1a89eb8f6a99477f262df71c6fa7bef77df4dc83025a2845c827d00 -RUN curl -s -O https://www.openssl.org/source/openssl-${OPENSSL_VERSION}.tar.gz \ - && echo "${OPENSSL_HASH} openssl-${OPENSSL_VERSION}.tar.gz" | sha256sum -c \ - && tar -xzf openssl-${OPENSSL_VERSION}.tar.gz \ - && rm openssl-${OPENSSL_VERSION}.tar.gz \ - && cd openssl-${OPENSSL_VERSION} \ - && sed -i -e "s/mandroid/target\ aarch64\-linux\-android/" Configure \ - && CC=clang CXX=clang++ \ - ./Configure android \ - no-asm \ - no-shared --static \ - --with-zlib-include=${WORKDIR}/zlib/include --with-zlib-lib=${WORKDIR}/zlib/lib \ - --prefix=${PREFIX} --openssldir=${PREFIX} \ - && make -j${NPROC} \ - && make install - -# ZMQ -ARG ZMQ_VERSION=master -ARG ZMQ_HASH=501d0815bf2b0abb93be8214fc66519918ef6c40 -RUN git clone https://github.com/zeromq/libzmq.git -b ${ZMQ_VERSION} \ - && cd libzmq \ - && git checkout ${ZMQ_HASH} \ - && ./autogen.sh \ - && CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=aarch64-linux-android --enable-static --disable-shared \ - && make -j${NPROC} \ - && make install - -# Sodium -ARG SODIUM_VERSION=1.0.16 -ARG SODIUM_HASH=675149b9b8b66ff44152553fb3ebf9858128363d -RUN set -ex \ - && git clone https://github.com/jedisct1/libsodium.git -b ${SODIUM_VERSION} \ - && cd libsodium \ - && test `git rev-parse HEAD` = ${SODIUM_HASH} || exit 1 \ - && ./autogen.sh \ - && CC=clang CXX=clang++ ./configure --prefix=${PREFIX} --host=aarch64-linux-android --enable-static --disable-shared \ - && make -j${NPROC} \ - && make install - -ADD . /src -RUN cd /src \ - && CMAKE_INCLUDE_PATH="${PREFIX}/include" \ - CMAKE_LIBRARY_PATH="${PREFIX}/lib" \ - ANDROID_STANDALONE_TOOLCHAIN_PATH=${TOOLCHAIN_DIR} \ - USE_SINGLE_BUILDDIR=1 \ - PATH=${HOST_PATH} make release-static-android-armv8 -j${NPROC} |