Upgrade to EVMC 7.5.0

One important change: MockedAccount.storage is a map and not unordered_map
This commit is contained in:
Alex Beregszaszi 2021-03-23 23:39:47 +00:00
parent 83213e659d
commit f1aaae36ee
8 changed files with 93 additions and 80 deletions

View File

@ -173,7 +173,7 @@ void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _ben
accounts.erase(_addr);
accounts[_beneficiary].balance = balance;
// Record self destructs
recorded_selfdestructs.push_back({_addr, _beneficiary, balance});
recorded_selfdestructs.push_back({_addr, _beneficiary});
}
void EVMHost::recordCalls(evmc_message const& _message) noexcept
@ -814,8 +814,6 @@ void EVMHostPrinter::selfdestructRecords()
m_stateStream << "SELFDESTRUCT"
<< " BENEFICIARY "
<< m_host.convertFromEVMC(record.beneficiary)
<< " BALANCE "
<< m_host.convertFromEVMC(record.balance)
<< endl;
}

View File

@ -1,3 +1,5 @@
# EVMC
This is an import of [EVMC](https://github.com/ethereum/evmc) version [7.2.0](https://github.com/ethereum/evmc/releases/tag/v7.2.0).
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).
Important: The `MockedAccount.storage` is changed to a map from unordered_map as ordering is important for fuzzing.

View File

@ -28,7 +28,7 @@
#include <stddef.h> /* Definition of size_t. */
#include <stdint.h> /* Definition of int64_t, uint64_t. */
#if __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
@ -295,6 +295,9 @@ enum evmc_status_code
*/
EVMC_WASM_TRAP = 16,
/** The caller does not have enough funds for value transfer. */
EVMC_INSUFFICIENT_BALANCE = 17,
/** EVM implementation generic internal error. */
EVMC_INTERNAL_ERROR = -1,
@ -914,7 +917,7 @@ struct evmc_vm
/* END Python CFFI declarations */
#if EVMC_DOCUMENTATION
#ifdef EVMC_DOCUMENTATION
/**
* Example of a function creating an instance of an example EVM implementation.
*
@ -933,7 +936,7 @@ struct evmc_vm
struct evmc_vm* evmc_create_example_vm(void);
#endif
#if __cplusplus
#ifdef __cplusplus
}
#endif

View File

@ -1,5 +1,5 @@
/* EVMC: Ethereum Client-VM Connector API.
* Copyright 2018-2019 The EVMC Authors.
* Copyright 2018-2020 The EVMC Authors.
* Licensed under the Apache License, Version 2.0.
*/
#pragma once
@ -53,7 +53,7 @@ struct address : evmc_address
{}
/// Explicit operator converting to bool.
constexpr inline explicit operator bool() const noexcept;
inline constexpr explicit operator bool() const noexcept;
};
/// The fixed size array of 32 bytes for storing 256-bit EVM values.
@ -113,19 +113,34 @@ struct bytes32 : evmc_bytes32
using uint256be = bytes32;
/// Loads 64 bits / 8 bytes of data from the given @p bytes array in big-endian order.
constexpr inline uint64_t load64be(const uint8_t* bytes) noexcept
/// Loads 64 bits / 8 bytes of data from the given @p data array in big-endian order.
inline constexpr uint64_t load64be(const uint8_t* data) noexcept
{
return (uint64_t{bytes[0]} << 56) | (uint64_t{bytes[1]} << 48) | (uint64_t{bytes[2]} << 40) |
(uint64_t{bytes[3]} << 32) | (uint64_t{bytes[4]} << 24) | (uint64_t{bytes[5]} << 16) |
(uint64_t{bytes[6]} << 8) | uint64_t{bytes[7]};
return (uint64_t{data[0]} << 56) | (uint64_t{data[1]} << 48) | (uint64_t{data[2]} << 40) |
(uint64_t{data[3]} << 32) | (uint64_t{data[4]} << 24) | (uint64_t{data[5]} << 16) |
(uint64_t{data[6]} << 8) | uint64_t{data[7]};
}
/// Loads 32 bits / 4 bytes of data from the given @p bytes array in big-endian order.
constexpr inline uint32_t load32be(const uint8_t* bytes) noexcept
/// Loads 64 bits / 8 bytes of data from the given @p data array in little-endian order.
inline constexpr uint64_t load64le(const uint8_t* data) noexcept
{
return (uint32_t{bytes[0]} << 24) | (uint32_t{bytes[1]} << 16) | (uint32_t{bytes[2]} << 8) |
uint32_t{bytes[3]};
return uint64_t{data[0]} | (uint64_t{data[1]} << 8) | (uint64_t{data[2]} << 16) |
(uint64_t{data[3]} << 24) | (uint64_t{data[4]} << 32) | (uint64_t{data[5]} << 40) |
(uint64_t{data[6]} << 48) | (uint64_t{data[7]} << 56);
}
/// Loads 32 bits / 4 bytes of data from the given @p data array in big-endian order.
inline constexpr uint32_t load32be(const uint8_t* data) noexcept
{
return (uint32_t{data[0]} << 24) | (uint32_t{data[1]} << 16) | (uint32_t{data[2]} << 8) |
uint32_t{data[3]};
}
/// Loads 32 bits / 4 bytes of data from the given @p data array in little-endian order.
inline constexpr uint32_t load32le(const uint8_t* data) noexcept
{
return uint32_t{data[0]} | (uint32_t{data[1]} << 8) | (uint32_t{data[2]} << 16) |
(uint32_t{data[3]} << 24);
}
namespace fnv
@ -134,7 +149,7 @@ constexpr auto prime = 0x100000001b3; ///< The 64-bit FNV prime num
constexpr auto offset_basis = 0xcbf29ce484222325; ///< The 64-bit FNV offset basis.
/// The hashing transformation for 64-bit inputs based on the FNV-1a formula.
constexpr inline uint64_t fnv1a_by64(uint64_t h, uint64_t x) noexcept
inline constexpr uint64_t fnv1a_by64(uint64_t h, uint64_t x) noexcept
{
return (h ^ x) * prime;
}
@ -142,22 +157,21 @@ constexpr inline uint64_t fnv1a_by64(uint64_t h, uint64_t x) noexcept
/// The "equal to" comparison operator for the evmc::address type.
constexpr bool operator==(const address& a, const address& b) noexcept
inline constexpr bool operator==(const address& a, const address& b) noexcept
{
// TODO: Report bug in clang keeping unnecessary bswap.
return load64be(&a.bytes[0]) == load64be(&b.bytes[0]) &&
load64be(&a.bytes[8]) == load64be(&b.bytes[8]) &&
load32be(&a.bytes[16]) == load32be(&b.bytes[16]);
return load64le(&a.bytes[0]) == load64le(&b.bytes[0]) &&
load64le(&a.bytes[8]) == load64le(&b.bytes[8]) &&
load32le(&a.bytes[16]) == load32le(&b.bytes[16]);
}
/// The "not equal to" comparison operator for the evmc::address type.
constexpr bool operator!=(const address& a, const address& b) noexcept
inline constexpr bool operator!=(const address& a, const address& b) noexcept
{
return !(a == b);
}
/// The "less than" comparison operator for the evmc::address type.
constexpr bool operator<(const address& a, const address& b) noexcept
inline constexpr bool operator<(const address& a, const address& b) noexcept
{
return load64be(&a.bytes[0]) < load64be(&b.bytes[0]) ||
(load64be(&a.bytes[0]) == load64be(&b.bytes[0]) &&
@ -167,40 +181,40 @@ constexpr bool operator<(const address& a, const address& b) noexcept
}
/// The "greater than" comparison operator for the evmc::address type.
constexpr bool operator>(const address& a, const address& b) noexcept
inline constexpr bool operator>(const address& a, const address& b) noexcept
{
return b < a;
}
/// The "less than or equal to" comparison operator for the evmc::address type.
constexpr bool operator<=(const address& a, const address& b) noexcept
inline constexpr bool operator<=(const address& a, const address& b) noexcept
{
return !(b < a);
}
/// The "greater than or equal to" comparison operator for the evmc::address type.
constexpr bool operator>=(const address& a, const address& b) noexcept
inline constexpr bool operator>=(const address& a, const address& b) noexcept
{
return !(a < b);
}
/// The "equal to" comparison operator for the evmc::bytes32 type.
constexpr bool operator==(const bytes32& a, const bytes32& b) noexcept
inline constexpr bool operator==(const bytes32& a, const bytes32& b) noexcept
{
return load64be(&a.bytes[0]) == load64be(&b.bytes[0]) &&
load64be(&a.bytes[8]) == load64be(&b.bytes[8]) &&
load64be(&a.bytes[16]) == load64be(&b.bytes[16]) &&
load64be(&a.bytes[24]) == load64be(&b.bytes[24]);
return load64le(&a.bytes[0]) == load64le(&b.bytes[0]) &&
load64le(&a.bytes[8]) == load64le(&b.bytes[8]) &&
load64le(&a.bytes[16]) == load64le(&b.bytes[16]) &&
load64le(&a.bytes[24]) == load64le(&b.bytes[24]);
}
/// The "not equal to" comparison operator for the evmc::bytes32 type.
constexpr bool operator!=(const bytes32& a, const bytes32& b) noexcept
inline constexpr bool operator!=(const bytes32& a, const bytes32& b) noexcept
{
return !(a == b);
}
/// The "less than" comparison operator for the evmc::bytes32 type.
constexpr bool operator<(const bytes32& a, const bytes32& b) noexcept
inline constexpr bool operator<(const bytes32& a, const bytes32& b) noexcept
{
return load64be(&a.bytes[0]) < load64be(&b.bytes[0]) ||
(load64be(&a.bytes[0]) == load64be(&b.bytes[0]) &&
@ -212,41 +226,41 @@ constexpr bool operator<(const bytes32& a, const bytes32& b) noexcept
}
/// The "greater than" comparison operator for the evmc::bytes32 type.
constexpr bool operator>(const bytes32& a, const bytes32& b) noexcept
inline constexpr bool operator>(const bytes32& a, const bytes32& b) noexcept
{
return b < a;
}
/// The "less than or equal to" comparison operator for the evmc::bytes32 type.
constexpr bool operator<=(const bytes32& a, const bytes32& b) noexcept
inline constexpr bool operator<=(const bytes32& a, const bytes32& b) noexcept
{
return !(b < a);
}
/// The "greater than or equal to" comparison operator for the evmc::bytes32 type.
constexpr bool operator>=(const bytes32& a, const bytes32& b) noexcept
inline constexpr bool operator>=(const bytes32& a, const bytes32& b) noexcept
{
return !(a < b);
}
/// Checks if the given address is the zero address.
constexpr inline bool is_zero(const address& a) noexcept
inline constexpr bool is_zero(const address& a) noexcept
{
return a == address{};
}
constexpr address::operator bool() const noexcept
inline constexpr address::operator bool() const noexcept
{
return !is_zero(*this);
}
/// Checks if the given bytes32 object has all zero bytes.
constexpr inline bool is_zero(const bytes32& a) noexcept
inline constexpr bool is_zero(const bytes32& a) noexcept
{
return a == bytes32{};
}
constexpr bytes32::operator bool() const noexcept
inline constexpr bytes32::operator bool() const noexcept
{
return !is_zero(*this);
}
@ -255,11 +269,6 @@ namespace literals
{
namespace internal
{
constexpr size_t length(const char* s) noexcept
{
return (*s != '\0') ? length(s + 1) + 1 : 0;
}
constexpr int from_hex(char c) noexcept
{
return (c >= 'a' && c <= 'f') ? c - ('a' - 10) :
@ -294,28 +303,34 @@ constexpr address from_hex<address>(const char* s) noexcept
byte(s, 14), byte(s, 15), byte(s, 16), byte(s, 17), byte(s, 18), byte(s, 19)}}};
}
template <typename T>
constexpr T from_literal(const char* s)
template <typename T, char... c>
constexpr T from_literal() noexcept
{
return (s[0] == '0' && s[1] == '\0') ?
T{} :
!(s[0] == '0' && s[1] == 'x') ?
throw "literal must be in hexadecimal notation" :
(length(s + 2) != sizeof(T) * 2) ? throw "literal must match the result type size" :
from_hex<T>(s + 2);
constexpr auto size = sizeof...(c);
constexpr char literal[] = {c...};
constexpr bool is_simple_zero = size == 1 && literal[0] == '0';
static_assert(is_simple_zero || (literal[0] == '0' && literal[1] == 'x'),
"literal must be in hexadecimal notation");
static_assert(is_simple_zero || size == 2 * sizeof(T) + 2,
"literal must match the result type size");
return is_simple_zero ? T{} : from_hex<T>(&literal[2]);
}
} // namespace internal
/// Literal for evmc::address.
constexpr address operator""_address(const char* s) noexcept
template <char... c>
constexpr address operator""_address() noexcept
{
return internal::from_literal<address>(s);
return internal::from_literal<address, c...>();
}
/// Literal for evmc::bytes32.
constexpr bytes32 operator""_bytes32(const char* s) noexcept
template <char... c>
constexpr bytes32 operator""_bytes32() noexcept
{
return internal::from_literal<bytes32>(s);
return internal::from_literal<bytes32, c...>();
}
} // namespace literals
@ -641,7 +656,7 @@ public:
return (get_capabilities() & static_cast<evmc_capabilities_flagset>(capability)) != 0;
}
/// @copydoc evmc::vm::get_capabilities
/// @copydoc evmc_vm::get_capabilities
evmc_capabilities_flagset get_capabilities() const noexcept
{
return m_instance->get_capabilities(m_instance);
@ -818,8 +833,8 @@ struct hash<evmc::address>
using namespace evmc;
using namespace fnv;
return static_cast<size_t>(fnv1a_by64(
fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64be(&s.bytes[0])), load64be(&s.bytes[8])),
load32be(&s.bytes[16])));
fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64le(&s.bytes[0])), load64le(&s.bytes[8])),
load32le(&s.bytes[16])));
}
};
@ -833,10 +848,10 @@ struct hash<evmc::bytes32>
using namespace evmc;
using namespace fnv;
return static_cast<size_t>(
fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64be(&s.bytes[0])),
load64be(&s.bytes[8])),
load64be(&s.bytes[16])),
load64be(&s.bytes[24])));
fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv1a_by64(fnv::offset_basis, load64le(&s.bytes[0])),
load64le(&s.bytes[8])),
load64le(&s.bytes[16])),
load64le(&s.bytes[24])));
}
};
} // namespace std

View File

@ -15,7 +15,7 @@
#if defined(EVMC_LOADER_MOCK)
#include "../../test/unittests/loader_mock.h"
#elif _WIN32
#elif defined(_WIN32)
#include <Windows.h>
#define DLL_HANDLE HMODULE
#define DLL_OPEN(filename) LoadLibrary(filename)
@ -136,7 +136,7 @@ evmc_create_fn evmc_load(const char* filename, enum evmc_loader_error_code* erro
// Find filename in the path.
const char* sep_pos = strrchr(filename, '/');
#if _WIN32
#ifdef _WIN32
// On Windows check also Windows classic path separator.
const char* sep_pos_windows = strrchr(filename, '\\');
sep_pos = sep_pos_windows > sep_pos ? sep_pos_windows : sep_pos;

View File

@ -14,7 +14,7 @@
*/
#pragma once
#if __cplusplus
#ifdef __cplusplus
extern "C" {
#endif
@ -161,9 +161,9 @@ struct evmc_vm* evmc_load_and_configure(const char* config,
* @return Error message or NULL if no additional information is available.
* The returned pointer MUST NOT be freed by the caller.
*/
const char* evmc_last_error_msg();
const char* evmc_last_error_msg(void);
#if __cplusplus
#ifdef __cplusplus
}
#endif

View File

@ -92,15 +92,10 @@ public:
/// The address of the beneficiary account.
address beneficiary;
/// The balance of the self-destructed account.
uint256be balance;
/// Equal operator.
bool operator==(const selfdestuct_record& other) const noexcept
{
return selfdestructed == other.selfdestructed &&
beneficiary == other.beneficiary &&
balance == other.balance;
return selfdestructed == other.selfdestructed && beneficiary == other.beneficiary;
}
};
@ -271,7 +266,7 @@ public:
void selfdestruct(const address& addr, const address& beneficiary) noexcept override
{
record_account_access(addr);
recorded_selfdestructs.push_back({addr, beneficiary, get_balance(addr)});
recorded_selfdestructs.push_back({addr, beneficiary});
}
/// Call/create other contract (EVMC host method).

View File

@ -27,7 +27,7 @@
* @def EVMC_NOEXCEPT
* Safe way of marking a function with `noexcept` C++ specifier.
*/
#if __cplusplus
#ifdef __cplusplus
#define EVMC_NOEXCEPT noexcept
#else
#define EVMC_NOEXCEPT