diff --git a/.clang-tidy b/.clang-tidy index 26c7995631..dd95153ff5 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -14,6 +14,7 @@ Checks: "-*, bugprone-fold-init-type, bugprone-forward-declaration-namespace, bugprone-inaccurate-erase, + bugprone-inc-dec-in-conditions, bugprone-incorrect-enable-if, bugprone-incorrect-roundings, bugprone-infinite-loop, @@ -30,9 +31,12 @@ Checks: "-*, bugprone-multiple-statement-macro, bugprone-no-escape, bugprone-non-zero-enum-to-bool-conversion, + bugprone-optional-value-conversion, bugprone-parent-virtual-call, + bugprone-pointer-arithmetic-on-polymorphic-object, bugprone-posix-return, bugprone-redundant-branch-condition, + bugprone-reserved-identifier, bugprone-return-const-ref-from-parameter, bugprone-shared-ptr-array-mismatch, bugprone-signal-handler, @@ -49,17 +53,23 @@ Checks: "-*, bugprone-suspicious-include, bugprone-suspicious-memory-comparison, bugprone-suspicious-memset-usage, + bugprone-suspicious-missing-comma, bugprone-suspicious-realloc-usage, bugprone-suspicious-semicolon, bugprone-suspicious-string-compare, + bugprone-suspicious-stringview-data-usage, bugprone-swapped-arguments, bugprone-terminating-continue, bugprone-throw-keyword-missing, + bugprone-too-small-loop-variable, bugprone-undefined-memory-manipulation, bugprone-undelegated-constructor, bugprone-unhandled-exception-at-new, + bugprone-unhandled-self-assignment, bugprone-unique-ptr-array-mismatch, bugprone-unsafe-functions, + bugprone-unused-raii, + bugprone-unused-local-non-trivial-variable, bugprone-virtual-near-miss, cppcoreguidelines-no-suspend-with-lock, cppcoreguidelines-virtual-class-destructor, @@ -85,22 +95,13 @@ Checks: "-*, performance-trivially-destructible " # --- -# more checks that have some issues that need to be resolved: +# checks that have some issues that need to be resolved: # # bugprone-crtp-constructor-accessibility, -# bugprone-inc-dec-in-conditions, -# bugprone-reserved-identifier, # bugprone-move-forwarding-reference, -# bugprone-unused-local-non-trivial-variable, # bugprone-switch-missing-default-case, -# bugprone-suspicious-stringview-data-usage, -# bugprone-suspicious-missing-comma, -# bugprone-pointer-arithmetic-on-polymorphic-object, -# bugprone-optional-value-conversion, -# bugprone-too-small-loop-variable, # bugprone-unused-return-value, # bugprone-use-after-move, -# bugprone-unhandled-self-assignment, # bugprone-unused-raii, # # cppcoreguidelines-misleading-capture-default-by-value, diff --git a/.github/scripts/strategy-matrix/generate.py b/.github/scripts/strategy-matrix/generate.py index 27eb60c005..532bf2ed57 100755 --- a/.github/scripts/strategy-matrix/generate.py +++ b/.github/scripts/strategy-matrix/generate.py @@ -55,7 +55,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list: # fee to 500. # - Bookworm using GCC 15: Debug on linux/amd64, enable code # coverage (which will be done below). - # - Bookworm using Clang 16: Debug on linux/arm64, enable voidstar. + # - Bookworm using Clang 16: Debug on linux/amd64, enable voidstar. # - Bookworm using Clang 17: Release on linux/amd64, set the # reference fee to 1000. # - Bookworm using Clang 20: Debug on linux/amd64. @@ -78,7 +78,7 @@ def generate_strategy_matrix(all: bool, config: Config) -> list: if ( f"{os['compiler_name']}-{os['compiler_version']}" == "clang-16" and build_type == "Debug" - and architecture["platform"] == "linux/arm64" + and architecture["platform"] == "linux/amd64" ): cmake_args = f"-Dvoidstar=ON {cmake_args}" skip = False diff --git a/.github/workflows/check-pr-title.yml b/.github/workflows/check-pr-title.yml new file mode 100644 index 0000000000..5c7cbd1d48 --- /dev/null +++ b/.github/workflows/check-pr-title.yml @@ -0,0 +1,10 @@ +name: Check PR title + +on: + pull_request: + types: [opened, edited, reopened, synchronize] + branches: [develop] + +jobs: + check_title: + uses: XRPLF/actions/.github/workflows/check-pr-title.yml@943eb8277e8f4b010fde0c826ce4154c36c39509 diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml index be6a92eea2..b0010fe0ba 100644 --- a/.github/workflows/on-pr.yml +++ b/.github/workflows/on-pr.yml @@ -46,7 +46,7 @@ jobs: # that Github considers any skipped jobs to have passed, and in # turn the required checks as well. id: changes - uses: tj-actions/changed-files@7dee1b0c1557f278e5c7dc244927139d78c0e22a # v47.0.4 + uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5 with: files: | # These paths are unique to `on-pr.yml`. diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index 54a84a426a..0989ecd1a9 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -11,7 +11,7 @@ on: jobs: # Call the workflow in the XRPLF/actions repo that runs the pre-commit hooks. run-hooks: - uses: XRPLF/actions/.github/workflows/pre-commit.yml@56de1bdf19639e009639a50b8d17c28ca954f267 + uses: XRPLF/actions/.github/workflows/pre-commit.yml@44856eb0d6ecb7d376370244324ab3dc8b863bad with: runs_on: ubuntu-latest container: '{ "image": "ghcr.io/xrplf/ci/tools-rippled-pre-commit:sha-41ec7c1" }' diff --git a/.github/workflows/reusable-clang-tidy.yml b/.github/workflows/reusable-clang-tidy.yml index 7050d3509f..5319c1627a 100644 --- a/.github/workflows/reusable-clang-tidy.yml +++ b/.github/workflows/reusable-clang-tidy.yml @@ -31,7 +31,7 @@ jobs: - name: Get changed C++ files id: changed_files - uses: tj-actions/changed-files@7dee1b0c1557f278e5c7dc244927139d78c0e22a # v47.0.4 + uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5 with: files: | **/*.cpp @@ -41,7 +41,7 @@ jobs: - name: Get changed clang-tidy configuration id: changed_clang_tidy - uses: tj-actions/changed-files@7dee1b0c1557f278e5c7dc244927139d78c0e22a # v47.0.4 + uses: tj-actions/changed-files@22103cc46bda19c2b464ffe86db46df6922fd323 # v47.0.5 with: files: | .clang-tidy diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ca0798ae4..33f68451c5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,7 +131,6 @@ if(coverage) include(XrplCov) endif() -set(PROJECT_EXPORT_SET XrplExports) include(XrplCore) include(XrplInstall) include(XrplValidatorKeys) diff --git a/cmake/XrplConfig.cmake b/cmake/XrplConfig.cmake deleted file mode 100644 index 76f9af14b1..0000000000 --- a/cmake/XrplConfig.cmake +++ /dev/null @@ -1,60 +0,0 @@ -include(CMakeFindDependencyMacro) -# need to represent system dependencies of the lib here -#[=========================================================[ - Boost -#]=========================================================] -if(static OR APPLE OR MSVC) - set(Boost_USE_STATIC_LIBS ON) -endif() -set(Boost_USE_MULTITHREADED ON) -if(static OR MSVC) - set(Boost_USE_STATIC_RUNTIME ON) -else() - set(Boost_USE_STATIC_RUNTIME OFF) -endif() -find_dependency( - Boost - COMPONENTS - chrono - container - context - coroutine - date_time - filesystem - program_options - regex - system - thread -) -#[=========================================================[ - OpenSSL -#]=========================================================] -if(NOT DEFINED OPENSSL_ROOT_DIR) - if(DEFINED ENV{OPENSSL_ROOT}) - set(OPENSSL_ROOT_DIR $ENV{OPENSSL_ROOT}) - elseif(APPLE) - find_program(homebrew brew) - if(homebrew) - execute_process( - COMMAND ${homebrew} --prefix openssl - OUTPUT_VARIABLE OPENSSL_ROOT_DIR - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - endif() - endif() - file(TO_CMAKE_PATH "${OPENSSL_ROOT_DIR}" OPENSSL_ROOT_DIR) -endif() - -if(static OR APPLE OR MSVC) - set(OPENSSL_USE_STATIC_LIBS ON) -endif() -set(OPENSSL_MSVC_STATIC_RT ON) -find_dependency(OpenSSL REQUIRED) -find_dependency(ZLIB) -find_dependency(date) -if(TARGET ZLIB::ZLIB) - set_target_properties( - OpenSSL::Crypto - PROPERTIES INTERFACE_LINK_LIBRARIES ZLIB::ZLIB - ) -endif() diff --git a/cmake/XrplInstall.cmake b/cmake/XrplInstall.cmake index 3ada00862a..339cdb51ec 100644 --- a/cmake/XrplInstall.cmake +++ b/cmake/XrplInstall.cmake @@ -2,101 +2,38 @@ install stuff #]===================================================================] -include(create_symbolic_link) +include(GNUInstallDirs) -# If no suffix is defined for executables (e.g. Windows uses .exe but Linux -# and macOS use none), then explicitly set it to the empty string. -if(NOT DEFINED suffix) - set(suffix "") +if(is_root_project AND TARGET xrpld) + install( + TARGETS xrpld + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT runtime + ) + + install( + FILES "${CMAKE_CURRENT_SOURCE_DIR}/cfg/xrpld-example.cfg" + DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/xrpld" + RENAME xrpld.cfg + COMPONENT runtime + ) + + install( + FILES "${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt" + DESTINATION "${CMAKE_INSTALL_SYSCONFDIR}/xrpld" + RENAME validators.txt + COMPONENT runtime + ) endif() install( - TARGETS - common - opts - xrpl_boost - xrpl_libs - xrpl_syslibs - xrpl.imports.main - xrpl.libpb - xrpl.libxrpl - xrpl.libxrpl.basics - xrpl.libxrpl.beast - xrpl.libxrpl.conditions - xrpl.libxrpl.core - xrpl.libxrpl.crypto - xrpl.libxrpl.git - xrpl.libxrpl.json - xrpl.libxrpl.rdb - xrpl.libxrpl.ledger - xrpl.libxrpl.net - xrpl.libxrpl.nodestore - xrpl.libxrpl.protocol - xrpl.libxrpl.protocol_autogen - xrpl.libxrpl.resource - xrpl.libxrpl.server - xrpl.libxrpl.shamap - xrpl.libxrpl.tx - antithesis-sdk-cpp - EXPORT XrplExports - LIBRARY DESTINATION lib - ARCHIVE DESTINATION lib - RUNTIME DESTINATION bin - INCLUDES DESTINATION include + TARGETS xrpl.libpb xrpl.libxrpl + LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT development + ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}" COMPONENT development + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT development ) install( DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include/xrpl" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" -) - -install( - EXPORT XrplExports - FILE XrplTargets.cmake - NAMESPACE Xrpl:: - DESTINATION lib/cmake/xrpl -) -include(CMakePackageConfigHelpers) -write_basic_package_version_file( - XrplConfigVersion.cmake - VERSION ${xrpld_version} - COMPATIBILITY SameMajorVersion -) - -if(is_root_project AND TARGET xrpld) - install(TARGETS xrpld RUNTIME DESTINATION bin) - set_target_properties(xrpld PROPERTIES INSTALL_RPATH_USE_LINK_PATH ON) - # sample configs should not overwrite existing files - # install if-not-exists workaround as suggested by - # https://cmake.org/Bug/view.php?id=12646 - install( - CODE - " - macro (copy_if_not_exists SRC DEST NEWNAME) - if (NOT EXISTS \"\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${DEST}/\${NEWNAME}\") - file (INSTALL FILE_PERMISSIONS OWNER_READ OWNER_WRITE DESTINATION \"\${CMAKE_INSTALL_PREFIX}/\${DEST}\" FILES \"\${SRC}\" RENAME \"\${NEWNAME}\") - else () - message (\"-- Skipping : \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/\${DEST}/\${NEWNAME}\") - endif () - endmacro() - copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/xrpld-example.cfg\" etc xrpld.cfg) - copy_if_not_exists(\"${CMAKE_CURRENT_SOURCE_DIR}/cfg/validators-example.txt\" etc validators.txt) - " - ) - install( - CODE - " - set(CMAKE_MODULE_PATH \"${CMAKE_MODULE_PATH}\") - include(create_symbolic_link) - create_symbolic_link(xrpld${suffix} \ - \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/rippled${suffix}) - " - ) -endif() - -install( - FILES - ${CMAKE_CURRENT_SOURCE_DIR}/cmake/XrplConfig.cmake - ${CMAKE_CURRENT_BINARY_DIR}/XrplConfigVersion.cmake - DESTINATION lib/cmake/xrpl + COMPONENT development ) diff --git a/cmake/XrplSanity.cmake b/cmake/XrplSanity.cmake index 24b4d4d408..a35645ad5c 100644 --- a/cmake/XrplSanity.cmake +++ b/cmake/XrplSanity.cmake @@ -50,6 +50,13 @@ if(MSVC AND CMAKE_GENERATOR_PLATFORM STREQUAL "Win32") message(FATAL_ERROR "Visual Studio 32-bit build is not supported.") endif() +if(voidstar AND NOT is_amd64) + message( + FATAL_ERROR + "The voidstar library only supported on amd64/x86_64. Detected archictecture was: ${CMAKE_SYSTEM_PROCESSOR}" + ) +endif() + if(APPLE AND NOT HOMEBREW) find_program(HOMEBREW brew) endif() diff --git a/include/xrpl/basics/Mutex.hpp b/include/xrpl/basics/Mutex.hpp new file mode 100644 index 0000000000..18c57370b1 --- /dev/null +++ b/include/xrpl/basics/Mutex.hpp @@ -0,0 +1,155 @@ +/* + This file is part of clio: https://github.com/XRPLF/clio + Copyright (c) 2024, the clio developers. + + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. +*/ + +#pragma once + +#include +#include + +namespace xrpl { + +template +class Mutex; + +/** + * @brief A lock on a mutex that provides access to the protected data. + * + * @tparam ProtectedDataType data type to hold + * @tparam LockType type of lock + * @tparam MutexType type of mutex + */ +template typename LockType, typename MutexType> +class Lock +{ + LockType lock_; + ProtectedDataType& data_; + +public: + /** @cond */ + ProtectedDataType const& + operator*() const + { + return data_; + } + + ProtectedDataType& + operator*() + { + return data_; + } + + ProtectedDataType const& + get() const + { + return data_; + } + + ProtectedDataType& + get() + { + return data_; + } + + ProtectedDataType const* + operator->() const + { + return &data_; + } + + ProtectedDataType* + operator->() + { + return &data_; + } + + operator LockType&() & + { + return lock_; + } + + operator LockType const&() const& + { + return lock_; + } + /** @endcond */ + +private: + friend class Mutex, MutexType>; + + Lock(MutexType& mutex, ProtectedDataType& data) : lock_(mutex), data_(data) + { + } +}; + +/** + * @brief A container for data that is protected by a mutex. Inspired by Mutex in Rust. + * + * @tparam ProtectedDataType data type to hold + * @tparam MutexType type of mutex + */ +template +class Mutex +{ + mutable MutexType mutex_; + ProtectedDataType data_{}; + +public: + Mutex() = default; + + /** + * @brief Construct a new Mutex object with the given data + * + * @param data The data to protect + */ + explicit Mutex(ProtectedDataType data) : data_(std::move(data)) + { + } + + /** + * @brief Make a new Mutex object with the given data + * + * @tparam Args The types of the arguments to forward to the constructor of the protected data + * @param args The arguments to forward to the constructor of the protected data + * @return The Mutex object that protects the given data + */ + template + static Mutex + make(Args&&... args) + { + return Mutex{ProtectedDataType{std::forward(args)...}}; + } + + /** + * @brief Lock the mutex and get a lock object allowing access to the protected data + * + * @tparam LockType The type of lock to use + * @return A lock on the mutex and a reference to the protected data + */ + template