From 3b90f0474cdb8a2f4593ab53f8a4b9389a4c43ab Mon Sep 17 00:00:00 2001 From: Andrew Ashikhmin <34320705+yperbasis@users.noreply.github.com> Date: Wed, 9 Aug 2023 00:20:11 +0200 Subject: [PATCH] build, core: switch to std::bit_cast + bump min Clang to 14 (#1378) --- .circleci/config.yml | 4 ++-- .github/workflows/macOS.yml | 4 +++- README.md | 3 ++- cmd/state-transition/state_transition.cpp | 24 ++++++++++--------- cmd/test/ethereum.cpp | 4 ++-- silkworm/core/common/base_test.cpp | 9 +++---- silkworm/core/common/cast.hpp | 13 ---------- silkworm/core/protocol/validation.cpp | 5 ++-- silkworm/core/state/intra_block_state.cpp | 5 ++-- .../core/state/intra_block_state_test.cpp | 6 ++--- silkworm/core/trie/hash_builder.cpp | 3 +-- silkworm/core/types/block.cpp | 5 ++-- silkworm/core/types/transaction.cpp | 5 ++-- silkworm/node/db/access_layer.cpp | 4 ++-- silkworm/silkrpc/commands/rpc_api_test.cpp | 9 ++++--- silkworm/silkrpc/core/override_state.cpp | 4 ++-- .../silkrpc/storage/local_chain_storage.cpp | 5 ++-- 17 files changed, 54 insertions(+), 58 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 7dca7a5979..a3b411239b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -275,7 +275,7 @@ jobs: linux-wasm-build: environment: - WASI_SDK_VERSION: 14 + WASI_SDK_VERSION: 15 machine: image: ubuntu-2204:2023.04.2 steps: @@ -327,7 +327,7 @@ jobs: parameters: clang_version_min: type: integer - default: 13 + default: 14 clang_version_latest: type: integer default: 15 diff --git a/.github/workflows/macOS.yml b/.github/workflows/macOS.yml index 49e7174da0..e2ffd10bfa 100644 --- a/.github/workflows/macOS.yml +++ b/.github/workflows/macOS.yml @@ -26,7 +26,9 @@ concurrency: jobs: osx: - runs-on: macOS-latest + runs-on: macos-13 + env: + DEVELOPER_DIR: /Applications/Xcode_14.3.app/Contents/Developer # Disable on external PRs if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.repository diff --git a/README.md b/README.md index 864a2da220..62e33b8419 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,8 @@ git submodule update --init --recursive ## Building on Linux & macOS Building Silkworm requires: -* C++20 compiler: [GCC](https://www.gnu.org/software/gcc/) >= 11.2 or [Clang](https://clang.llvm.org/) >= 13 +* C++20 compiler: [GCC](https://www.gnu.org/software/gcc/) >= 11.2 or [Clang](https://clang.llvm.org/) >= 14 +or AppleClang ([Xcode](https://developer.apple.com/xcode/) >= 14.3) * [CMake](https://cmake.org) * [Conan](https://conan.io) diff --git a/cmd/state-transition/state_transition.cpp b/cmd/state-transition/state_transition.cpp index 9e6f8c8d2c..7595db6e8e 100644 --- a/cmd/state-transition/state_transition.cpp +++ b/cmd/state-transition/state_transition.cpp @@ -16,22 +16,24 @@ #include "state_transition.hpp" +#include #include #include #include #include +#include #include -#include "cmd/state-transition/expected_state.hpp" -#include "silkworm/core/common/cast.hpp" -#include "silkworm/core/common/util.hpp" -#include "silkworm/core/execution/execution.hpp" -#include "silkworm/core/protocol/param.hpp" -#include "silkworm/core/protocol/rule_set.hpp" -#include "silkworm/core/rlp/encode_vector.hpp" -#include "silkworm/core/state/in_memory_state.hpp" -#include "silkworm/sentry/common/ecc_key_pair.hpp" +#include +#include +#include +#include +#include +#include +#include + +#include "expected_state.hpp" namespace silkworm::cmd::state_transition { @@ -154,7 +156,7 @@ std::unique_ptr StateTransition::get_state() { account.nonce = std::stoull(std::string(preStateValue.at("nonce")), nullptr, 16); const Bytes code{from_hex(std::string(preStateValue.at("code"))).value()}; - account.code_hash = bit_cast(keccak256(code)); + account.code_hash = std::bit_cast(keccak256(code)); account.incarnation = kDefaultIncarnation; state->update_account(address, /*initial=*/std::nullopt, account); @@ -269,7 +271,7 @@ void StateTransition::validate_transition(const Receipt& receipt, const Expected } else { Bytes encoded; rlp::encode(encoded, receipt.logs); - if (bit_cast(keccak256(encoded)) != expected_sub_state.logsHash) { + if (std::bit_cast(keccak256(encoded)) != expected_sub_state.logsHash) { print_error_message(expected_state, expected_sub_state, "Failed: Logs hash does not match"); failed_count_++; } else { diff --git a/cmd/test/ethereum.cpp b/cmd/test/ethereum.cpp index 9fed09da25..b304934770 100644 --- a/cmd/test/ethereum.cpp +++ b/cmd/test/ethereum.cpp @@ -15,6 +15,7 @@ */ #include +#include #include #include #include @@ -29,7 +30,6 @@ #include #include -#include #include #include #include @@ -80,7 +80,7 @@ void init_pre_state(const nlohmann::json& pre, State& state) { const Bytes code{from_hex(j["code"].get()).value()}; if (!code.empty()) { account.incarnation = kDefaultIncarnation; - account.code_hash = bit_cast(keccak256(code)); + account.code_hash = std::bit_cast(keccak256(code)); state.update_account_code(address, account.incarnation, account.code_hash, code); } diff --git a/silkworm/core/common/base_test.cpp b/silkworm/core/common/base_test.cpp index 3da4b1f7c9..7f3b895765 100644 --- a/silkworm/core/common/base_test.cpp +++ b/silkworm/core/common/base_test.cpp @@ -16,11 +16,12 @@ #include "base.hpp" +#include + #include #include -#include "cast.hpp" #include "util.hpp" namespace silkworm { @@ -40,16 +41,16 @@ TEST_CASE("Byteviews") { TEST_CASE("Empty hashes") { const ByteView empty_string; const ethash::hash256 hash_of_empty_string{keccak256(empty_string)}; - CHECK(bit_cast(hash_of_empty_string) == kEmptyHash); + CHECK(std::bit_cast(hash_of_empty_string) == kEmptyHash); const Bytes empty_list_rlp(1, rlp::kEmptyListCode); const ethash::hash256 hash_of_empty_list_rlp{keccak256(empty_list_rlp)}; - CHECK(bit_cast(hash_of_empty_list_rlp) == kEmptyListHash); + CHECK(std::bit_cast(hash_of_empty_list_rlp) == kEmptyListHash); // See https://github.com/ethereum/yellowpaper/pull/852 const Bytes empty_string_rlp(1, rlp::kEmptyStringCode); const ethash::hash256 hash_of_empty_string_rlp{keccak256(empty_string_rlp)}; - CHECK(bit_cast(hash_of_empty_string_rlp) == kEmptyRoot); + CHECK(std::bit_cast(hash_of_empty_string_rlp) == kEmptyRoot); } } // namespace silkworm diff --git a/silkworm/core/common/cast.hpp b/silkworm/core/common/cast.hpp index ed9f8dc774..1cba4876ac 100644 --- a/silkworm/core/common/cast.hpp +++ b/silkworm/core/common/cast.hpp @@ -18,9 +18,7 @@ // Utilities for type casting -#include #include -#include #include @@ -32,17 +30,6 @@ inline const char* byte_ptr_cast(const uint8_t* ptr) { return reinterpret_cast(ptr); } inline const uint8_t* byte_ptr_cast(const char* ptr) { return reinterpret_cast(ptr); } -// Backport of C++20 std::bit_cast -// https://en.cppreference.com/w/cpp/numeric/bit_cast -template -typename std::enable_if_t< - sizeof(To) == sizeof(From) && std::is_trivially_copyable_v && std::is_trivially_copyable_v, To> -bit_cast(const From& src) noexcept { - To dst; - std::memcpy(&dst, &src, sizeof(To)); - return dst; -} - inline ByteView string_view_to_byte_view(std::string_view v) { return {byte_ptr_cast(v.data()), v.length()}; } inline std::string_view byte_view_to_string_view(ByteView v) { return {byte_ptr_cast(v.data()), v.length()}; } diff --git a/silkworm/core/protocol/validation.cpp b/silkworm/core/protocol/validation.cpp index 6797ea02a0..a31e99d601 100644 --- a/silkworm/core/protocol/validation.cpp +++ b/silkworm/core/protocol/validation.cpp @@ -16,7 +16,8 @@ #include "validation.hpp" -#include +#include + #include #include #include @@ -235,7 +236,7 @@ evmc::bytes32 compute_ommers_hash(const BlockBody& body) { Bytes ommers_rlp; rlp::encode(ommers_rlp, body.ommers); - return bit_cast(keccak256(ommers_rlp)); + return std::bit_cast(keccak256(ommers_rlp)); } } // namespace silkworm::protocol diff --git a/silkworm/core/state/intra_block_state.cpp b/silkworm/core/state/intra_block_state.cpp index 1d7ad30b37..f976aaf070 100644 --- a/silkworm/core/state/intra_block_state.cpp +++ b/silkworm/core/state/intra_block_state.cpp @@ -16,9 +16,10 @@ #include "intra_block_state.hpp" +#include + #include -#include #include namespace silkworm { @@ -222,7 +223,7 @@ evmc::bytes32 IntraBlockState::get_code_hash(const evmc::address& address) const void IntraBlockState::set_code(const evmc::address& address, ByteView code) noexcept { auto& obj{get_or_create_object(address)}; journal_.emplace_back(new state::UpdateDelta{address, obj}); - obj.current->code_hash = bit_cast(keccak256(code)); + obj.current->code_hash = std::bit_cast(keccak256(code)); // Don't overwrite already existing code so that views of it // that were previously returned by get_code() are still valid. diff --git a/silkworm/core/state/intra_block_state_test.cpp b/silkworm/core/state/intra_block_state_test.cpp index 0576bcc116..6f9003e24e 100644 --- a/silkworm/core/state/intra_block_state_test.cpp +++ b/silkworm/core/state/intra_block_state_test.cpp @@ -16,13 +16,13 @@ #include "intra_block_state.hpp" +#include #include #include #include #include -#include #include #include "in_memory_state.hpp" @@ -61,7 +61,7 @@ TEST_CASE("Code view stability") { Bytes code(random_code()); existing_codes[i] = {addr, code}; - evmc_bytes32 code_hash{bit_cast(keccak256(code))}; + evmc_bytes32 code_hash{std::bit_cast(keccak256(code))}; Account account{.code_hash = code_hash, .incarnation = kDefaultIncarnation}; db.update_account(addr, /*initial=*/std::nullopt, /*current=*/account); db.update_account_code(addr, kDefaultIncarnation, code_hash, code); @@ -94,7 +94,7 @@ TEST_CASE("Code view stability") { // Check that all previously returned code views have correct code hashes for (const auto& cv : code_views) { - evmc_bytes32 code_hash{bit_cast(keccak256(cv.second))}; + evmc_bytes32 code_hash{std::bit_cast(keccak256(cv.second))}; CHECK(state.get_code_hash(cv.first) == code_hash); } } diff --git a/silkworm/core/trie/hash_builder.cpp b/silkworm/core/trie/hash_builder.cpp index fb3ed3ec5f..a630624bc3 100644 --- a/silkworm/core/trie/hash_builder.cpp +++ b/silkworm/core/trie/hash_builder.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include @@ -132,7 +131,7 @@ evmc::bytes32 HashBuilder::root_hash(bool auto_finalize) { if (node_ref.length() == kHashLength + 1) { std::memcpy(res.bytes, &node_ref[1], kHashLength); } else { - res = bit_cast(keccak256(node_ref)); + res = std::bit_cast(keccak256(node_ref)); } return res; } diff --git a/silkworm/core/types/block.cpp b/silkworm/core/types/block.cpp index da7f29f1d7..446c183400 100644 --- a/silkworm/core/types/block.cpp +++ b/silkworm/core/types/block.cpp @@ -16,7 +16,8 @@ #include "block.hpp" -#include +#include + #include #include #include @@ -28,7 +29,7 @@ BlockNum height(const BlockId& b) { return b.number; } evmc::bytes32 BlockHeader::hash(bool for_sealing, bool exclude_extra_data_sig) const { Bytes rlp; rlp::encode(rlp, *this, for_sealing, exclude_extra_data_sig); - return bit_cast(keccak256(rlp)); + return std::bit_cast(keccak256(rlp)); } ethash::hash256 BlockHeader::boundary() const { diff --git a/silkworm/core/types/transaction.cpp b/silkworm/core/types/transaction.cpp index ba12ef320b..5cd198fb0a 100644 --- a/silkworm/core/types/transaction.cpp +++ b/silkworm/core/types/transaction.cpp @@ -16,9 +16,10 @@ #include "transaction.hpp" +#include + #include -#include #include #include #include @@ -46,7 +47,7 @@ bool Transaction::set_v(const intx::uint256& v) { evmc::bytes32 Transaction::hash() const { Bytes rlp; rlp::encode(rlp, *this, /*wrap_eip2718_into_string=*/false); - return bit_cast(keccak256(rlp)); + return std::bit_cast(keccak256(rlp)); } namespace rlp { diff --git a/silkworm/node/db/access_layer.cpp b/silkworm/node/db/access_layer.cpp index d65833e608..c0204eb644 100644 --- a/silkworm/node/db/access_layer.cpp +++ b/silkworm/node/db/access_layer.cpp @@ -16,10 +16,10 @@ #include "access_layer.hpp" +#include #include #include -#include #include #include #include @@ -170,7 +170,7 @@ void write_header(RWTxn& txn, const BlockHeader& header, bool with_header_number evmc::bytes32 write_header_ex(RWTxn& txn, const BlockHeader& header, bool with_header_numbers) { Bytes value{}; rlp::encode(value, header); - auto header_hash = bit_cast(keccak256(value)); // avoid header.hash() because it re-does rlp encoding + auto header_hash = std::bit_cast(keccak256(value)); // avoid header.hash() because it re-does rlp encoding auto key{db::block_key(header.number, header_hash.bytes)}; auto skey = db::to_slice(key); auto svalue = db::to_slice(value); diff --git a/silkworm/silkrpc/commands/rpc_api_test.cpp b/silkworm/silkrpc/commands/rpc_api_test.cpp index c5479e0008..218ad27d57 100644 --- a/silkworm/silkrpc/commands/rpc_api_test.cpp +++ b/silkworm/silkrpc/commands/rpc_api_test.cpp @@ -16,6 +16,7 @@ #include "rpc_api.hpp" +#include #include #include #include @@ -28,20 +29,18 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include #include -#include "silkworm/core/common/cast.hpp" -#include "silkworm/core/execution/execution.hpp" -#include "silkworm/silkrpc/common/constants.hpp" - namespace silkworm::rpc::commands { using boost::asio::awaitable; @@ -98,7 +97,7 @@ std::unique_ptr populate_genesis(db::RWTxn& txn, const std::files if (account_alloc_json.contains("code")) { const auto acc_code{from_hex(std::string(account_alloc_json.at("code"))).value()}; - const auto acc_codehash{bit_cast(keccak256(acc_code))}; + const auto acc_codehash{std::bit_cast(keccak256(acc_code))}; account.code_hash = acc_codehash; state_buffer->update_account_code(account_address, account.incarnation, acc_codehash, acc_code); } diff --git a/silkworm/silkrpc/core/override_state.cpp b/silkworm/silkrpc/core/override_state.cpp index 793657193a..3efaf77389 100644 --- a/silkworm/silkrpc/core/override_state.cpp +++ b/silkworm/silkrpc/core/override_state.cpp @@ -16,6 +16,7 @@ #include "override_state.hpp" +#include #include #include #include @@ -24,7 +25,6 @@ #include #include -#include #include #include #include @@ -47,7 +47,7 @@ OverrideState::OverrideState(silkworm::State& inner_state, const AccountsOverrid : inner_state_{inner_state}, accounts_overrides_{accounts_overrides} { for (const auto& [key, value] : accounts_overrides_) { if (value.code) { - evmc::bytes32 code_hash{bit_cast(keccak256(value.code.value()))}; + evmc::bytes32 code_hash{std::bit_cast(keccak256(value.code.value()))}; code_hash_.emplace(code_hash, value.code.value()); } } diff --git a/silkworm/silkrpc/storage/local_chain_storage.cpp b/silkworm/silkrpc/storage/local_chain_storage.cpp index 01d1afb0bc..d9b8d9703e 100644 --- a/silkworm/silkrpc/storage/local_chain_storage.cpp +++ b/silkworm/silkrpc/storage/local_chain_storage.cpp @@ -16,7 +16,8 @@ #include "local_chain_storage.hpp" -#include +#include + #include #include @@ -130,7 +131,7 @@ Task LocalChainStorage::read_rlp_transaction(const evmc::bytes32& txn_hash co_return false; } for (const auto& rlp : rlp_txs) { - if (bit_cast(keccak256(rlp)) == txn_hash) { + if (std::bit_cast(keccak256(rlp)) == txn_hash) { rlp_tx = rlp; co_return true; }