diff --git a/.circleci/config.yml b/.circleci/config.yml index e2e10267a732..8a771e69596f 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -9,20 +9,20 @@ version: 2.1 parameters: ubuntu-2004-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-20 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:7a1e1b01eda0d1e20704279672bcfd53dbbc481898ff960958a225dea76345bd" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-21 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:6f64c7b35aabddb416d28f621a3c4bbae768c257d6866f6a7f05f8225acc94f0" ubuntu-2204-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-5 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:4df420b7ccd96f540a4300a4fae0fcac2f4d3f23ffff9e3777c1f2d7c37ef901" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204-6 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:6eee10420382588b274374c6a18cb2e5d4f8a9fef5cf440b3a1acfc32bf52837" ubuntu-2204-clang-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-4 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:538596bf55961197f8b5670d8a6742d9bcd502b6a1045ae9d372cdf35ce69d93" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu2204.clang-5 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:e991421ce9f44d6476b29588fc355da1c3b3fedcc424fd12d844bbe310ad7851" ubuntu-clang-ossfuzz-docker-image: type: string - # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-3 - default: "solbuildpackpusher/solidity-buildpack-deps@sha256:46a6df64a21dc8914a8e4d43f50a1f56a942b01cbc1c30741ca28239e4ae081a" + # solbuildpackpusher/solidity-buildpack-deps:ubuntu.clang.ossfuzz-4 + default: "solbuildpackpusher/solidity-buildpack-deps@sha256:b122ef9dca71a8f90b74f3ba13cda4453681506e4a4ff047e7bc2130c76b0d1e" emscripten-docker-image: type: string # NOTE: Please remember to update the `build_emscripten.sh` whenever the hash of this image changes. diff --git a/.circleci/osx_install_dependencies.sh b/.circleci/osx_install_dependencies.sh index 61ac4a106610..3e3f3b1bbd80 100755 --- a/.circleci/osx_install_dependencies.sh +++ b/.circleci/osx_install_dependencies.sh @@ -76,10 +76,10 @@ then rm -r "$z3_dir" # evmone - evmone_version="0.10.0" + evmone_version="0.11.0" evmone_package="evmone-${evmone_version}-darwin-x86_64.tar.gz" wget "https://github.com/ethereum/evmone/releases/download/v${evmone_version}/${evmone_package}" - validate_checksum "$evmone_package" 1b7773779287d7908baca6b8d556a98800cbd7d6e5c910b55fa507642bc0a15c + validate_checksum "$evmone_package" 83ed20676681d9a31bd30cac399ab7c615ccab8adb8087cc2c7e9cd22b4d2efc tar xzpf "$evmone_package" -C /usr/local rm "$evmone_package" diff --git a/scripts/install_evmone.ps1 b/scripts/install_evmone.ps1 index 0bf2fa1de37d..acbacdafbd01 100644 --- a/scripts/install_evmone.ps1 +++ b/scripts/install_evmone.ps1 @@ -3,7 +3,7 @@ $ErrorActionPreference = "Stop" # Needed for Invoke-WebRequest to work via CI. $progressPreference = "silentlyContinue" -Invoke-WebRequest -URI "https://github.com/ethereum/evmone/releases/download/v0.10.0/evmone-0.10.0-windows-amd64.zip" -OutFile "evmone.zip" +Invoke-WebRequest -URI "https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-windows-amd64.zip" -OutFile "evmone.zip" tar -xf evmone.zip "bin/evmone.dll" mkdir deps mv bin/evmone.dll deps diff --git a/test/Common.h b/test/Common.h index d82ff9c6b71f..28ec4e219939 100644 --- a/test/Common.h +++ b/test/Common.h @@ -33,13 +33,13 @@ namespace solidity::test #ifdef _WIN32 static constexpr auto evmoneFilename = "evmone.dll"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.10.0/evmone-0.10.0-windows-amd64.zip"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-windows-amd64.zip"; #elif defined(__APPLE__) static constexpr auto evmoneFilename = "libevmone.dylib"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.10.0/evmone-0.10.0-darwin-x86_64.tar.gz"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-darwin-x86_64.tar.gz"; #else static constexpr auto evmoneFilename = "libevmone.so"; -static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.10.0/evmone-0.10.0-linux-x86_64.tar.gz"; +static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.11.0/evmone-0.11.0-linux-x86_64.tar.gz"; #endif struct ConfigException: public util::Exception {}; diff --git a/test/evmc/README.md b/test/evmc/README.md index cdddb3444083..9381b4f53eda 100644 --- a/test/evmc/README.md +++ b/test/evmc/README.md @@ -1,5 +1,10 @@ # EVMC -This is an import of [EVMC](https://github.com/ethereum/evmc) version [10.1.0](https://github.com/ethereum/evmc/releases/tag/v10.1.0). +This is an import of [EVMC](https://github.com/ethereum/evmc) version [11.0.0](https://github.com/ethereum/evmc/releases/tag/v11.0.0). -Important: The `MockedAccount.storage` is changed to a `map` from `unordered_map` as ordering is important for fuzzing. +Steps when upgrading: +- Copy all from [include/evmc](https://github.com/ethereum/evmc/tree/master/include/evmc) to [test/evmc](https://github.com/ethereum/solidity/tree/develop/test/evmc) + - Note that you should delete (or not copy in the first place) `tooling.hpp` and `instructions.h`. +- Copy [`loader.c`](https://github.com/ethereum/evmc/blob/master/lib/loader/loader.c) to [test/evmc](https://github.com/ethereum/solidity/tree/develop/test/evmc) +- `MockedAccount.storage` in `mocked_host.hpp` should be changed to a `map` from `unordered_map` as ordering is important for fuzzing. You'll also need to include ``. + See [PR #11094](https://github.com/ethereum/solidity/pull/11094) for more details. diff --git a/test/evmc/evmc.h b/test/evmc/evmc.h index 60c3aeecc978..48b03e554556 100644 --- a/test/evmc/evmc.h +++ b/test/evmc/evmc.h @@ -44,7 +44,7 @@ enum * * @see @ref versioning */ - EVMC_ABI_VERSION = 10 + EVMC_ABI_VERSION = 11 }; @@ -202,6 +202,9 @@ struct evmc_tx_context evmc_uint256be block_prev_randao; /**< The block previous RANDAO (EIP-4399). */ evmc_uint256be chain_id; /**< The blockchain's ChainID. */ evmc_uint256be block_base_fee; /**< The block base fee per gas (EIP-1559, EIP-3198). */ + evmc_uint256be blob_base_fee; /**< The blob base fee (EIP-7516). */ + const evmc_bytes32* blob_hashes; /**< The array of blob hashes (EIP-4844). */ + size_t blob_hashes_count; /**< The number of blob hashes (EIP-4844). */ }; /** @@ -503,6 +506,22 @@ typedef evmc_bytes32 (*evmc_get_storage_fn)(struct evmc_host_context* context, const evmc_address* address, const evmc_bytes32* key); +/** + * Get transient storage callback function. + * + * This callback function is used by a VM to query + * the given account transient storage (EIP-1153) entry. + * + * @param context The Host execution context. + * @param address The address of the account. + * @param key The index of the account's transient storage entry. + * @return The transient storage value at the given storage key or null bytes + * if the account does not exist. + */ +typedef evmc_bytes32 (*evmc_get_transient_storage_fn)(struct evmc_host_context* context, + const evmc_address* address, + const evmc_bytes32* key); + /** * The effect of an attempt to modify a contract storage item. @@ -620,6 +639,25 @@ typedef enum evmc_storage_status (*evmc_set_storage_fn)(struct evmc_host_context const evmc_bytes32* key, const evmc_bytes32* value); +/** + * Set transient storage callback function. + * + * This callback function is used by a VM to update + * the given account's transient storage (EIP-1153) entry. + * The VM MUST make sure that the account exists. This requirement is only a formality because + * VM implementations only modify storage of the account of the current execution context + * (i.e. referenced by evmc_message::recipient). + * + * @param context The pointer to the Host execution context. + * @param address The address of the account. + * @param key The index of the transient storage entry. + * @param value The value to be stored. + */ +typedef void (*evmc_set_transient_storage_fn)(struct evmc_host_context* context, + const evmc_address* address, + const evmc_bytes32* key, + const evmc_bytes32* value); + /** * Get balance callback function. * @@ -825,6 +863,12 @@ struct evmc_host_interface /** Access storage callback function. */ evmc_access_storage_fn access_storage; + + /** Get transient storage callback function. */ + evmc_get_transient_storage_fn get_transient_storage; + + /** Set transient storage callback function. */ + evmc_set_transient_storage_fn set_transient_storage; }; diff --git a/test/evmc/evmc.hpp b/test/evmc/evmc.hpp index a29f802d27a7..91386c46f857 100644 --- a/test/evmc/evmc.hpp +++ b/test/evmc/evmc.hpp @@ -493,6 +493,15 @@ class HostInterface /// @copydoc evmc_host_interface::access_storage virtual evmc_access_status access_storage(const address& addr, const bytes32& key) noexcept = 0; + + /// @copydoc evmc_host_interface::get_transient_storage + virtual bytes32 get_transient_storage(const address& addr, + const bytes32& key) const noexcept = 0; + + /// @copydoc evmc_host_interface::set_transient_storage + virtual void set_transient_storage(const address& addr, + const bytes32& key, + const bytes32& value) noexcept = 0; }; @@ -591,6 +600,18 @@ class HostContext : public HostInterface { return host->access_storage(context, &address, &key); } + + bytes32 get_transient_storage(const address& address, const bytes32& key) const noexcept final + { + return host->get_transient_storage(context, &address, &key); + } + + void set_transient_storage(const address& address, + const bytes32& key, + const bytes32& value) noexcept final + { + host->set_transient_storage(context, &address, &key, &value); + } }; @@ -844,18 +865,42 @@ inline evmc_access_status access_storage(evmc_host_context* h, { return Host::from_context(h)->access_storage(*addr, *key); } + +inline evmc_bytes32 get_transient_storage(evmc_host_context* h, + const evmc_address* addr, + const evmc_bytes32* key) noexcept +{ + return Host::from_context(h)->get_transient_storage(*addr, *key); +} + +inline void set_transient_storage(evmc_host_context* h, + const evmc_address* addr, + const evmc_bytes32* key, + const evmc_bytes32* value) noexcept +{ + Host::from_context(h)->set_transient_storage(*addr, *key, *value); +} } // namespace internal inline const evmc_host_interface& Host::get_interface() noexcept { static constexpr evmc_host_interface interface = { - ::evmc::internal::account_exists, ::evmc::internal::get_storage, - ::evmc::internal::set_storage, ::evmc::internal::get_balance, - ::evmc::internal::get_code_size, ::evmc::internal::get_code_hash, - ::evmc::internal::copy_code, ::evmc::internal::selfdestruct, - ::evmc::internal::call, ::evmc::internal::get_tx_context, - ::evmc::internal::get_block_hash, ::evmc::internal::emit_log, - ::evmc::internal::access_account, ::evmc::internal::access_storage, + ::evmc::internal::account_exists, + ::evmc::internal::get_storage, + ::evmc::internal::set_storage, + ::evmc::internal::get_balance, + ::evmc::internal::get_code_size, + ::evmc::internal::get_code_hash, + ::evmc::internal::copy_code, + ::evmc::internal::selfdestruct, + ::evmc::internal::call, + ::evmc::internal::get_tx_context, + ::evmc::internal::get_block_hash, + ::evmc::internal::emit_log, + ::evmc::internal::access_account, + ::evmc::internal::access_storage, + ::evmc::internal::get_transient_storage, + ::evmc::internal::set_transient_storage, }; return interface; } diff --git a/test/evmc/mocked_host.hpp b/test/evmc/mocked_host.hpp index 173b793ac7a6..205a136b3800 100644 --- a/test/evmc/mocked_host.hpp +++ b/test/evmc/mocked_host.hpp @@ -63,6 +63,9 @@ struct MockedAccount /// The account storage map. std::map storage; + /// The account transient storage. + std::unordered_map transient_storage; + /// Helper method for setting balance by numeric type. void set_balance(uint64_t x) noexcept { @@ -467,8 +470,7 @@ class MockedHost : public Host /// /// @param addr The account address. /// @param key The account's storage key. - /// @return The ::EVMC_ACCESS_WARM if the storage key has been accessed - /// before, + /// @return The ::EVMC_ACCESS_WARM if the storage key has been accessed before, /// the ::EVMC_ACCESS_COLD otherwise. evmc_access_status access_storage(const address& addr, const bytes32& key) noexcept override { @@ -477,5 +479,37 @@ class MockedHost : public Host value.access_status = EVMC_ACCESS_WARM; return access_status; } + + /// Get account's transient storage. + /// + /// @param addr The account address. + /// @param key The account's transient storage key. + /// @return The transient storage value. Null value in case the account does not exist. + bytes32 get_transient_storage(const address& addr, const bytes32& key) const noexcept override + { + record_account_access(addr); + + const auto account_iter = accounts.find(addr); + if (account_iter == accounts.end()) + return {}; + + const auto storage_iter = account_iter->second.transient_storage.find(key); + if (storage_iter != account_iter->second.transient_storage.end()) + return storage_iter->second; + return {}; + } + + /// Set account's transient storage. + /// + /// @param addr The account address. + /// @param key The account's transient storage key. + /// @param value The value to be stored. + void set_transient_storage(const address& addr, + const bytes32& key, + const bytes32& value) noexcept override + { + record_account_access(addr); + accounts[addr].transient_storage[key] = value; + } }; } // namespace evmc