mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #11286 from ethereum/evmc8
Upgrade to EVMC 8.0.0 + evmone 0.7.0
This commit is contained in:
commit
324caef53c
@ -9,20 +9,20 @@ version: 2.1
|
|||||||
parameters:
|
parameters:
|
||||||
ubuntu-2004-docker-image:
|
ubuntu-2004-docker-image:
|
||||||
type: string
|
type: string
|
||||||
# solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-5
|
# solbuildpackpusher/solidity-buildpack-deps:ubuntu2004-6
|
||||||
default: "solbuildpackpusher/solidity-buildpack-deps@sha256:2d306b8da3485c2584a8868d656dc36c1ae50f003ff085ad2e904e312534b9b7"
|
default: "solbuildpackpusher/solidity-buildpack-deps@sha256:da44d7f78e093f7f0415abf07f7c1fd1c2ed4fa65fefea428821a05186c42ec9"
|
||||||
ubuntu-2004-clang-docker-image:
|
ubuntu-2004-clang-docker-image:
|
||||||
type: string
|
type: string
|
||||||
# solbuildpackpusher/solidity-buildpack-deps:ubuntu2004.clang-5
|
# solbuildpackpusher/solidity-buildpack-deps:ubuntu2004.clang-6
|
||||||
default: "solbuildpackpusher/solidity-buildpack-deps@sha256:4fbc7a99dd0b204fef587856d89640e4b2060d459ba15c32b89733b2a6054d7f"
|
default: "solbuildpackpusher/solidity-buildpack-deps@sha256:c78dd9c48d393b57afe053aeb2d0d358a9f31ac85039a181724c2f8408d0bcf8"
|
||||||
ubuntu-1604-clang-ossfuzz-docker-image:
|
ubuntu-1604-clang-ossfuzz-docker-image:
|
||||||
type: string
|
type: string
|
||||||
# solbuildpackpusher/solidity-buildpack-deps:ubuntu1604.clang.ossfuzz-8
|
# solbuildpackpusher/solidity-buildpack-deps:ubuntu1604.clang.ossfuzz-9
|
||||||
default: "solbuildpackpusher/solidity-buildpack-deps@sha256:42f47b7ddafbf57b4e48357022cf34dc38ae477b05ddc2210e7ed68d821c2019"
|
default: "solbuildpackpusher/solidity-buildpack-deps@sha256:5078e1d74ab6f4329e9218c2d8c0ebe2d42817a3d4c3c62ce887100cbe9bc739"
|
||||||
emscripten-docker-image:
|
emscripten-docker-image:
|
||||||
type: string
|
type: string
|
||||||
# solbuildpackpusher/solidity-buildpack-deps:emscripten-4
|
# solbuildpackpusher/solidity-buildpack-deps:emscripten-5
|
||||||
default: "solbuildpackpusher/solidity-buildpack-deps@sha256:434719d8104cab47712dd1f56f255994d04eb65b802c0d382790071c1a0c074b"
|
default: "solbuildpackpusher/solidity-buildpack-deps@sha256:d28afb9624c2352ea40f157d1a321ffac77f54a21e33a8e8744f9126b780ded4"
|
||||||
|
|
||||||
orbs:
|
orbs:
|
||||||
win: circleci/windows@2.2.0
|
win: circleci/windows@2.2.0
|
||||||
|
@ -55,12 +55,12 @@ then
|
|||||||
rm -rf z3-4.8.10-x64-osx-10.15.7
|
rm -rf z3-4.8.10-x64-osx-10.15.7
|
||||||
|
|
||||||
# evmone
|
# evmone
|
||||||
wget https://github.com/ethereum/evmone/releases/download/v0.4.0/evmone-0.4.0-darwin-x86_64.tar.gz
|
wget https://github.com/ethereum/evmone/releases/download/v0.7.0/evmone-0.7.0-darwin-x86_64.tar.gz
|
||||||
tar xzpf evmone-0.4.0-darwin-x86_64.tar.gz -C /usr/local
|
tar xzpf evmone-0.7.0-darwin-x86_64.tar.gz -C /usr/local
|
||||||
rm -f evmone-0.4.0-darwin-x86_64.tar.gz
|
rm -f evmone-0.7.0-darwin-x86_64.tar.gz
|
||||||
|
|
||||||
# hera
|
# hera
|
||||||
wget https://github.com/ewasm/hera/releases/download/v0.3.2/hera-0.3.2-darwin-x86_64.tar.gz
|
wget https://github.com/ewasm/hera/releases/download/v0.3.2-evmc8/hera-0.3.2+commit.dc886eb7-darwin-x86_64.tar.gz
|
||||||
tar xzpf hera-0.3.2-darwin-x86_64.tar.gz -C /usr/local
|
tar xzpf hera-0.3.2+commit.dc886eb7-darwin-x86_64.tar.gz -C /usr/local
|
||||||
rm -f hera-0.3.2-darwin-x86_64.tar.gz
|
rm -f hera-0.3.2+commit.dc886eb7-darwin-x86_64.tar.gz
|
||||||
fi
|
fi
|
||||||
|
@ -112,7 +112,7 @@ starting from the current directory. The required file is called ``libevmone.so`
|
|||||||
``evmone.dll`` on Windows systems and ``libevmone.dylib`` on macOS. If it is not found, tests that
|
``evmone.dll`` on Windows systems and ``libevmone.dylib`` on macOS. If it is not found, tests that
|
||||||
use it are skipped. These tests are ``libsolididty/semanticTests``, ``libsolidity/GasCosts``,
|
use it are skipped. These tests are ``libsolididty/semanticTests``, ``libsolidity/GasCosts``,
|
||||||
``libsolidity/SolidityEndToEndTest``, part of the soltest suite. To run all tests, download the library from
|
``libsolidity/SolidityEndToEndTest``, part of the soltest suite. To run all tests, download the library from
|
||||||
`GitHub <https://github.com/ethereum/evmone/releases/tag/v0.4.1>`_
|
`GitHub <https://github.com/ethereum/evmone/releases/tag/v0.7.0>`_
|
||||||
and place it in the project root path or inside the ``deps`` folder.
|
and place it in the project root path or inside the ``deps`` folder.
|
||||||
|
|
||||||
If the ``libz3`` library is not installed on your system, you should disable the
|
If the ``libz3`` library is not installed on your system, you should disable the
|
||||||
|
@ -3,7 +3,7 @@ $ErrorActionPreference = "Stop"
|
|||||||
# Needed for Invoke-WebRequest to work via CI.
|
# Needed for Invoke-WebRequest to work via CI.
|
||||||
$progressPreference = "silentlyContinue"
|
$progressPreference = "silentlyContinue"
|
||||||
|
|
||||||
Invoke-WebRequest -URI "https://github.com/ethereum/evmone/releases/download/v0.5.0/evmone-0.5.0-windows-amd64.zip" -OutFile "evmone.zip"
|
Invoke-WebRequest -URI "https://github.com/ethereum/evmone/releases/download/v0.7.0/evmone-0.7.0-windows-amd64.zip" -OutFile "evmone.zip"
|
||||||
tar -xf evmone.zip "bin/evmone.dll"
|
tar -xf evmone.zip "bin/evmone.dll"
|
||||||
mkdir deps
|
mkdir deps
|
||||||
mv bin/evmone.dll deps
|
mv bin/evmone.dll deps
|
||||||
|
@ -31,19 +31,19 @@ namespace solidity::test
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
static constexpr auto evmoneFilename = "evmone.dll";
|
static constexpr auto evmoneFilename = "evmone.dll";
|
||||||
static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.4.1/evmone-0.4.1-windows-amd64.zip";
|
static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.7.0/evmone-0.7.0-windows-amd64.zip";
|
||||||
static constexpr auto heraFilename = "hera.dll";
|
static constexpr auto heraFilename = "hera.dll";
|
||||||
static constexpr auto heraDownloadLink = "https://github.com/ewasm/hera/archive/v0.3.2.tar.gz";
|
static constexpr auto heraDownloadLink = "https://github.com/ewasm/hera/archive/v0.3.2-evmc8.tar.gz";
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
static constexpr auto evmoneFilename = "libevmone.dylib";
|
static constexpr auto evmoneFilename = "libevmone.dylib";
|
||||||
static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.4.1/evmone-0.4.1-darwin-x86_64.tar.gz";
|
static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.7.0/evmone-0.7.0-darwin-x86_64.tar.gz";
|
||||||
static constexpr auto heraFilename = "libhera.dylib";
|
static constexpr auto heraFilename = "libhera.dylib";
|
||||||
static constexpr auto heraDownloadLink = "https://github.com/ewasm/hera/releases/download/v0.3.2/hera-0.3.2-darwin-x86_64.tar.gz";
|
static constexpr auto heraDownloadLink = "https://github.com/ewasm/hera/releases/download/v0.3.2-evmc8/hera-0.3.2+commit.dc886eb7-darwin-x86_64.tar.gz";
|
||||||
#else
|
#else
|
||||||
static constexpr auto evmoneFilename = "libevmone.so";
|
static constexpr auto evmoneFilename = "libevmone.so";
|
||||||
static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.4.1/evmone-0.4.1-linux-x86_64.tar.gz";
|
static constexpr auto evmoneDownloadLink = "https://github.com/ethereum/evmone/releases/download/v0.7.0/evmone-0.7.0-linux-x86_64.tar.gz";
|
||||||
static constexpr auto heraFilename = "libhera.so";
|
static constexpr auto heraFilename = "libhera.so";
|
||||||
static constexpr auto heraDownloadLink = "https://github.com/ewasm/hera/releases/download/v0.3.2/hera-0.3.2-linux-x86_64.tar.gz";
|
static constexpr auto heraDownloadLink = "https://github.com/ewasm/hera/releases/download/v0.3.2-evmc8/hera-0.3.2+commit.dc886eb7-linux-x86_64.tar.gz";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct ConfigException : public util::Exception {};
|
struct ConfigException : public util::Exception {};
|
||||||
|
@ -148,6 +148,8 @@ void EVMHost::reset()
|
|||||||
recorded_selfdestructs.clear();
|
recorded_selfdestructs.clear();
|
||||||
// Clear call records
|
// Clear call records
|
||||||
recorded_calls.clear();
|
recorded_calls.clear();
|
||||||
|
// Clear EIP-2929 account access indicator
|
||||||
|
recorded_account_accesses.clear();
|
||||||
|
|
||||||
// Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161).
|
// Mark all precompiled contracts as existing. Existing here means to have a balance (as per EIP-161).
|
||||||
// NOTE: keep this in sync with `EVMHost::call` below.
|
// NOTE: keep this in sync with `EVMHost::call` below.
|
||||||
@ -273,6 +275,14 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
|||||||
destination.balance = convertToEVMC(u256(convertFromEVMC(destination.balance)) + value);
|
destination.balance = convertToEVMC(u256(convertFromEVMC(destination.balance)) + value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Populate the access access list.
|
||||||
|
// Note, this will also properly touch the created address.
|
||||||
|
// TODO: support a user supplied access list too
|
||||||
|
if (m_evmRevision >= EVMC_BERLIN)
|
||||||
|
{
|
||||||
|
access_account(message.sender);
|
||||||
|
access_account(message.destination);
|
||||||
|
}
|
||||||
evmc::address currentAddress = m_currentAddress;
|
evmc::address currentAddress = m_currentAddress;
|
||||||
m_currentAddress = message.destination;
|
m_currentAddress = message.destination;
|
||||||
evmc::result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size());
|
evmc::result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size());
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# EVMC
|
# EVMC
|
||||||
|
|
||||||
This is an import of [EVMC](https://github.com/ethereum/evmc) version [7.5.0](https://github.com/ethereum/evmc/releases/tag/v7.5.0).
|
This is an import of [EVMC](https://github.com/ethereum/evmc) version [8.0.0](https://github.com/ethereum/evmc/releases/tag/v8.0.0).
|
||||||
|
|
||||||
Important: The `MockedAccount.storage` is changed to a map from unordered_map as ordering is important for fuzzing.
|
Important: The `MockedAccount.storage` is changed to a map from unordered_map as ordering is important for fuzzing.
|
||||||
|
@ -44,7 +44,7 @@ enum
|
|||||||
*
|
*
|
||||||
* @see @ref versioning
|
* @see @ref versioning
|
||||||
*/
|
*/
|
||||||
EVMC_ABI_VERSION = 7
|
EVMC_ABI_VERSION = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -603,6 +603,52 @@ typedef void (*evmc_emit_log_fn)(struct evmc_host_context* context,
|
|||||||
const evmc_bytes32 topics[],
|
const evmc_bytes32 topics[],
|
||||||
size_t topics_count);
|
size_t topics_count);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access status per EIP-2929: Gas cost increases for state access opcodes.
|
||||||
|
*/
|
||||||
|
enum evmc_access_status
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The entry hasn't been accessed before – it's the first access.
|
||||||
|
*/
|
||||||
|
EVMC_ACCESS_COLD = 0,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The entry is already in accessed_addresses or accessed_storage_keys.
|
||||||
|
*/
|
||||||
|
EVMC_ACCESS_WARM = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access account callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by a VM to add the given address
|
||||||
|
* to accessed_addresses substate (EIP-2929).
|
||||||
|
*
|
||||||
|
* @param context The Host execution context.
|
||||||
|
* @param address The address of the account.
|
||||||
|
* @return EVMC_ACCESS_WARM if accessed_addresses already contained the address
|
||||||
|
* or EVMC_ACCESS_COLD otherwise.
|
||||||
|
*/
|
||||||
|
typedef enum evmc_access_status (*evmc_access_account_fn)(struct evmc_host_context* context,
|
||||||
|
const evmc_address* address);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Access storage callback function.
|
||||||
|
*
|
||||||
|
* This callback function is used by a VM to add the given account storage entry
|
||||||
|
* to accessed_storage_keys substate (EIP-2929).
|
||||||
|
*
|
||||||
|
* @param context The Host execution context.
|
||||||
|
* @param address The address of the account.
|
||||||
|
* @param key The index of the account's storage entry.
|
||||||
|
* @return EVMC_ACCESS_WARM if accessed_storage_keys already contained the key
|
||||||
|
* or EVMC_ACCESS_COLD otherwise.
|
||||||
|
*/
|
||||||
|
typedef enum evmc_access_status (*evmc_access_storage_fn)(struct evmc_host_context* context,
|
||||||
|
const evmc_address* address,
|
||||||
|
const evmc_bytes32* key);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pointer to the callback function supporting EVM calls.
|
* Pointer to the callback function supporting EVM calls.
|
||||||
*
|
*
|
||||||
@ -658,6 +704,12 @@ struct evmc_host_interface
|
|||||||
|
|
||||||
/** Emit log callback function. */
|
/** Emit log callback function. */
|
||||||
evmc_emit_log_fn emit_log;
|
evmc_emit_log_fn emit_log;
|
||||||
|
|
||||||
|
/** Access account callback function. */
|
||||||
|
evmc_access_account_fn access_account;
|
||||||
|
|
||||||
|
/** Access storage callback function. */
|
||||||
|
evmc_access_storage_fn access_storage;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -465,6 +465,12 @@ public:
|
|||||||
size_t data_size,
|
size_t data_size,
|
||||||
const bytes32 topics[],
|
const bytes32 topics[],
|
||||||
size_t num_topics) noexcept = 0;
|
size_t num_topics) noexcept = 0;
|
||||||
|
|
||||||
|
/// @copydoc evmc_host_interface::access_account
|
||||||
|
virtual evmc_access_status access_account(const address& addr) noexcept = 0;
|
||||||
|
|
||||||
|
/// @copydoc evmc_host_interface::access_storage
|
||||||
|
virtual evmc_access_status access_storage(const address& addr, const bytes32& key) noexcept = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -564,6 +570,16 @@ public:
|
|||||||
{
|
{
|
||||||
host->emit_log(context, &addr, data, data_size, topics, topics_count);
|
host->emit_log(context, &addr, data, data_size, topics, topics_count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evmc_access_status access_account(const address& address) noexcept final
|
||||||
|
{
|
||||||
|
return host->access_account(context, &address);
|
||||||
|
}
|
||||||
|
|
||||||
|
evmc_access_status access_storage(const address& address, const bytes32& key) noexcept final
|
||||||
|
{
|
||||||
|
return host->access_storage(context, &address, &key);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -805,6 +821,18 @@ inline void emit_log(evmc_host_context* h,
|
|||||||
Host::from_context(h)->emit_log(*addr, data, data_size, static_cast<const bytes32*>(topics),
|
Host::from_context(h)->emit_log(*addr, data, data_size, static_cast<const bytes32*>(topics),
|
||||||
num_topics);
|
num_topics);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline evmc_access_status access_account(evmc_host_context* h, const evmc_address* addr) noexcept
|
||||||
|
{
|
||||||
|
return Host::from_context(h)->access_account(*addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline evmc_access_status access_storage(evmc_host_context* h,
|
||||||
|
const evmc_address* addr,
|
||||||
|
const evmc_bytes32* key) noexcept
|
||||||
|
{
|
||||||
|
return Host::from_context(h)->access_storage(*addr, *key);
|
||||||
|
}
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
|
|
||||||
inline const evmc_host_interface& Host::get_interface() noexcept
|
inline const evmc_host_interface& Host::get_interface() noexcept
|
||||||
@ -815,7 +843,9 @@ inline const evmc_host_interface& Host::get_interface() noexcept
|
|||||||
::evmc::internal::get_code_size, ::evmc::internal::get_code_hash,
|
::evmc::internal::get_code_size, ::evmc::internal::get_code_hash,
|
||||||
::evmc::internal::copy_code, ::evmc::internal::selfdestruct,
|
::evmc::internal::copy_code, ::evmc::internal::selfdestruct,
|
||||||
::evmc::internal::call, ::evmc::internal::get_tx_context,
|
::evmc::internal::call, ::evmc::internal::get_tx_context,
|
||||||
::evmc::internal::get_block_hash, ::evmc::internal::emit_log};
|
::evmc::internal::get_block_hash, ::evmc::internal::emit_log,
|
||||||
|
::evmc::internal::access_account, ::evmc::internal::access_storage,
|
||||||
|
};
|
||||||
return interface;
|
return interface;
|
||||||
}
|
}
|
||||||
} // namespace evmc
|
} // namespace evmc
|
||||||
|
@ -24,6 +24,9 @@ struct storage_value
|
|||||||
/// True means this value has been modified already by the current transaction.
|
/// True means this value has been modified already by the current transaction.
|
||||||
bool dirty{false};
|
bool dirty{false};
|
||||||
|
|
||||||
|
/// Is the storage key cold or warm.
|
||||||
|
evmc_access_status access_status{EVMC_ACCESS_COLD};
|
||||||
|
|
||||||
/// Default constructor.
|
/// Default constructor.
|
||||||
storage_value() noexcept = default;
|
storage_value() noexcept = default;
|
||||||
|
|
||||||
@ -31,6 +34,11 @@ struct storage_value
|
|||||||
storage_value(const bytes32& _value, bool _dirty = false) noexcept // NOLINT
|
storage_value(const bytes32& _value, bool _dirty = false) noexcept // NOLINT
|
||||||
: value{_value}, dirty{_dirty}
|
: value{_value}, dirty{_dirty}
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
/// Constructor with initial access status.
|
||||||
|
storage_value(const bytes32& _value, evmc_access_status _access_status) noexcept
|
||||||
|
: value{_value}, access_status{_access_status}
|
||||||
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Mocked account.
|
/// Mocked account.
|
||||||
@ -84,7 +92,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// SELFDESTRUCT record.
|
/// SELFDESTRUCT record.
|
||||||
struct selfdestuct_record
|
struct selfdestruct_record
|
||||||
{
|
{
|
||||||
/// The address of the account which has self-destructed.
|
/// The address of the account which has self-destructed.
|
||||||
address selfdestructed;
|
address selfdestructed;
|
||||||
@ -93,7 +101,7 @@ public:
|
|||||||
address beneficiary;
|
address beneficiary;
|
||||||
|
|
||||||
/// Equal operator.
|
/// Equal operator.
|
||||||
bool operator==(const selfdestuct_record& other) const noexcept
|
bool operator==(const selfdestruct_record& other) const noexcept
|
||||||
{
|
{
|
||||||
return selfdestructed == other.selfdestructed && beneficiary == other.beneficiary;
|
return selfdestructed == other.selfdestructed && beneficiary == other.beneficiary;
|
||||||
}
|
}
|
||||||
@ -132,13 +140,12 @@ public:
|
|||||||
std::vector<log_record> recorded_logs;
|
std::vector<log_record> recorded_logs;
|
||||||
|
|
||||||
/// The record of all SELFDESTRUCTs from the selfdestruct() method.
|
/// The record of all SELFDESTRUCTs from the selfdestruct() method.
|
||||||
std::vector<selfdestuct_record> recorded_selfdestructs;
|
std::vector<selfdestruct_record> recorded_selfdestructs;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The copy of call inputs for the recorded_calls record.
|
/// The copy of call inputs for the recorded_calls record.
|
||||||
std::vector<bytes> m_recorded_calls_inputs;
|
std::vector<bytes> m_recorded_calls_inputs;
|
||||||
|
|
||||||
public:
|
|
||||||
/// Record an account access.
|
/// Record an account access.
|
||||||
/// @param addr The address of the accessed account.
|
/// @param addr The address of the accessed account.
|
||||||
void record_account_access(const address& addr) const
|
void record_account_access(const address& addr) const
|
||||||
@ -150,6 +157,7 @@ public:
|
|||||||
recorded_account_accesses.emplace_back(addr);
|
recorded_account_accesses.emplace_back(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
/// Returns true if an account exists (EVMC Host method).
|
/// Returns true if an account exists (EVMC Host method).
|
||||||
bool account_exists(const address& addr) const noexcept override
|
bool account_exists(const address& addr) const noexcept override
|
||||||
{
|
{
|
||||||
@ -313,5 +321,59 @@ public:
|
|||||||
{
|
{
|
||||||
recorded_logs.push_back({addr, {data, data_size}, {topics, topics + topics_count}});
|
recorded_logs.push_back({addr, {data, data_size}, {topics, topics + topics_count}});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Record an account access.
|
||||||
|
///
|
||||||
|
/// This method is required by EIP-2929 introduced in ::EVMC_BERLIN. It will record the account
|
||||||
|
/// access in MockedHost::recorded_account_accesses and return previous access status.
|
||||||
|
/// This methods returns ::EVMC_ACCESS_WARM for known addresses of precompiles.
|
||||||
|
/// The EIP-2929 specifies that evmc_message::sender and evmc_message::destination are always
|
||||||
|
/// ::EVMC_ACCESS_WARM. Therefore, you should init the MockedHost with:
|
||||||
|
///
|
||||||
|
/// mocked_host.access_account(msg.sender);
|
||||||
|
/// mocked_host.access_account(msg.destination);
|
||||||
|
///
|
||||||
|
/// The same way you can mock transaction access list (EIP-2930) for account addresses.
|
||||||
|
///
|
||||||
|
/// @param addr The address of the accessed account.
|
||||||
|
/// @returns The ::EVMC_ACCESS_WARM if the account has been accessed before,
|
||||||
|
/// the ::EVMC_ACCESS_COLD otherwise.
|
||||||
|
evmc_access_status access_account(const address& addr) noexcept override
|
||||||
|
{
|
||||||
|
// Check if the address have been already accessed.
|
||||||
|
const auto already_accessed =
|
||||||
|
std::find(recorded_account_accesses.begin(), recorded_account_accesses.end(), addr) !=
|
||||||
|
recorded_account_accesses.end();
|
||||||
|
|
||||||
|
record_account_access(addr);
|
||||||
|
|
||||||
|
// Accessing precompiled contracts is always warm.
|
||||||
|
if (addr >= 0x0000000000000000000000000000000000000001_address &&
|
||||||
|
addr <= 0x0000000000000000000000000000000000000009_address)
|
||||||
|
return EVMC_ACCESS_WARM;
|
||||||
|
|
||||||
|
return already_accessed ? EVMC_ACCESS_WARM : EVMC_ACCESS_COLD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Access the account's storage value at the given key.
|
||||||
|
///
|
||||||
|
/// This method is required by EIP-2929 introduced in ::EVMC_BERLIN. In records that the given
|
||||||
|
/// account's storage key has been access and returns the previous access status.
|
||||||
|
/// To mock storage access list (EIP-2930), you can pre-init account's storage values with
|
||||||
|
/// the ::EVMC_ACCESS_WARM flag:
|
||||||
|
///
|
||||||
|
/// mocked_host.accounts[msg.destination].storage[key] = {value, EVMC_ACCESS_WARM};
|
||||||
|
///
|
||||||
|
/// @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,
|
||||||
|
/// the ::EVMC_ACCESS_COLD otherwise.
|
||||||
|
evmc_access_status access_storage(const address& addr, const bytes32& key) noexcept override
|
||||||
|
{
|
||||||
|
auto& value = accounts[addr].storage[key];
|
||||||
|
const auto access_status = value.access_status;
|
||||||
|
value.access_status = EVMC_ACCESS_WARM;
|
||||||
|
return access_status;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // namespace evmc
|
} // namespace evmc
|
||||||
|
Loading…
Reference in New Issue
Block a user