mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Update EVMHost to match EVMC10 changes
This commit is contained in:
parent
458857d0d6
commit
5df92a374b
108
test/EVMHost.cpp
108
test/EVMHost.cpp
@ -125,7 +125,7 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
||||
else
|
||||
assertThrow(false, Exception, "Unsupported EVM version");
|
||||
|
||||
tx_context.block_difficulty = evmc::uint256be{200000000};
|
||||
tx_context.block_prev_randao = evmc::uint256be{200000000}; // TODO: should make it >2**64 for >Paris
|
||||
tx_context.block_gas_limit = 20000000;
|
||||
tx_context.block_coinbase = 0x7878787878787878787878787878787878787878_address;
|
||||
tx_context.tx_gas_price = evmc::uint256be{3000000000};
|
||||
@ -145,7 +145,6 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
|
||||
void EVMHost::reset()
|
||||
{
|
||||
accounts.clear();
|
||||
m_currentAddress = {};
|
||||
// Clear self destruct records
|
||||
recorded_selfdestructs.clear();
|
||||
// Clear call records
|
||||
@ -194,14 +193,14 @@ void EVMHost::transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recip
|
||||
_recipient.balance = convertToEVMC(u256(convertFromEVMC(_recipient.balance)) + _value);
|
||||
}
|
||||
|
||||
void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept
|
||||
bool EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept
|
||||
{
|
||||
// TODO actual selfdestruct is even more complicated.
|
||||
|
||||
transfer(accounts[_addr], accounts[_beneficiary], convertFromEVMC(accounts[_addr].balance));
|
||||
|
||||
// Record self destructs. Clearing will be done in newTransactionFrame().
|
||||
MockedHost::selfdestruct(_addr, _beneficiary);
|
||||
return MockedHost::selfdestruct(_addr, _beneficiary);
|
||||
}
|
||||
|
||||
void EVMHost::recordCalls(evmc_message const& _message) noexcept
|
||||
@ -212,34 +211,34 @@ void EVMHost::recordCalls(evmc_message const& _message) noexcept
|
||||
|
||||
// NOTE: this is used for both internal and external calls.
|
||||
// External calls are triggered from ExecutionFramework and contain only EVMC_CREATE or EVMC_CALL.
|
||||
evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
evmc::Result EVMHost::call(evmc_message const& _message) noexcept
|
||||
{
|
||||
recordCalls(_message);
|
||||
if (_message.destination == 0x0000000000000000000000000000000000000001_address)
|
||||
if (_message.recipient == 0x0000000000000000000000000000000000000001_address)
|
||||
return precompileECRecover(_message);
|
||||
else if (_message.destination == 0x0000000000000000000000000000000000000002_address)
|
||||
else if (_message.recipient == 0x0000000000000000000000000000000000000002_address)
|
||||
return precompileSha256(_message);
|
||||
else if (_message.destination == 0x0000000000000000000000000000000000000003_address)
|
||||
else if (_message.recipient == 0x0000000000000000000000000000000000000003_address)
|
||||
return precompileRipeMD160(_message);
|
||||
else if (_message.destination == 0x0000000000000000000000000000000000000004_address)
|
||||
else if (_message.recipient == 0x0000000000000000000000000000000000000004_address)
|
||||
return precompileIdentity(_message);
|
||||
else if (_message.destination == 0x0000000000000000000000000000000000000005_address && m_evmVersion >= langutil::EVMVersion::byzantium())
|
||||
else if (_message.recipient == 0x0000000000000000000000000000000000000005_address && m_evmVersion >= langutil::EVMVersion::byzantium())
|
||||
return precompileModExp(_message);
|
||||
else if (_message.destination == 0x0000000000000000000000000000000000000006_address && m_evmVersion >= langutil::EVMVersion::byzantium())
|
||||
else if (_message.recipient == 0x0000000000000000000000000000000000000006_address && m_evmVersion >= langutil::EVMVersion::byzantium())
|
||||
{
|
||||
if (m_evmVersion <= langutil::EVMVersion::istanbul())
|
||||
return precompileALTBN128G1Add<EVMC_ISTANBUL>(_message);
|
||||
else
|
||||
return precompileALTBN128G1Add<EVMC_LONDON>(_message);
|
||||
}
|
||||
else if (_message.destination == 0x0000000000000000000000000000000000000007_address && m_evmVersion >= langutil::EVMVersion::byzantium())
|
||||
else if (_message.recipient == 0x0000000000000000000000000000000000000007_address && m_evmVersion >= langutil::EVMVersion::byzantium())
|
||||
{
|
||||
if (m_evmVersion <= langutil::EVMVersion::istanbul())
|
||||
return precompileALTBN128G1Mul<EVMC_ISTANBUL>(_message);
|
||||
else
|
||||
return precompileALTBN128G1Mul<EVMC_LONDON>(_message);
|
||||
}
|
||||
else if (_message.destination == 0x0000000000000000000000000000000000000008_address && m_evmVersion >= langutil::EVMVersion::byzantium())
|
||||
else if (_message.recipient == 0x0000000000000000000000000000000000000008_address && m_evmVersion >= langutil::EVMVersion::byzantium())
|
||||
{
|
||||
if (m_evmVersion <= langutil::EVMVersion::istanbul())
|
||||
return precompileALTBN128PairingProduct<EVMC_ISTANBUL>(_message);
|
||||
@ -262,7 +261,7 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
message.gas -= message.input_data[i] == 0 ? evmasm::GasCosts::txDataZeroGas : evmasm::GasCosts::txDataNonZeroGas(m_evmVersion);
|
||||
if (message.gas < 0)
|
||||
{
|
||||
evmc::result result({});
|
||||
evmc::Result result;
|
||||
result.status_code = EVMC_OUT_OF_GAS;
|
||||
accounts = stateBackup;
|
||||
return result;
|
||||
@ -299,8 +298,8 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
encodedNonce
|
||||
), h160::AlignRight);
|
||||
|
||||
message.destination = convertToEVMC(createAddress);
|
||||
assertThrow(accounts.count(message.destination) == 0, Exception, "Account cannot exist");
|
||||
message.recipient = convertToEVMC(createAddress);
|
||||
assertThrow(accounts.count(message.recipient) == 0, Exception, "Account cannot exist");
|
||||
|
||||
code = evmc::bytes(message.input_data, message.input_data + message.input_size);
|
||||
}
|
||||
@ -313,13 +312,13 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
keccak256(bytes(message.input_data, message.input_data + message.input_size)).asBytes()
|
||||
), h160::AlignRight);
|
||||
|
||||
message.destination = convertToEVMC(createAddress);
|
||||
if (accounts.count(message.destination) && (
|
||||
accounts[message.destination].nonce > 0 ||
|
||||
!accounts[message.destination].code.empty()
|
||||
message.recipient = convertToEVMC(createAddress);
|
||||
if (accounts.count(message.recipient) && (
|
||||
accounts[message.recipient].nonce > 0 ||
|
||||
!accounts[message.recipient].code.empty()
|
||||
))
|
||||
{
|
||||
evmc::result result({});
|
||||
evmc::Result result;
|
||||
result.status_code = EVMC_OUT_OF_GAS;
|
||||
accounts = stateBackup;
|
||||
return result;
|
||||
@ -327,21 +326,16 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
|
||||
code = evmc::bytes(message.input_data, message.input_data + message.input_size);
|
||||
}
|
||||
else if (message.kind == EVMC_DELEGATECALL || message.kind == EVMC_CALLCODE)
|
||||
{
|
||||
code = accounts[message.destination].code;
|
||||
message.destination = m_currentAddress;
|
||||
}
|
||||
else
|
||||
code = accounts[message.destination].code;
|
||||
code = accounts[message.code_address].code;
|
||||
|
||||
auto& destination = accounts[message.destination];
|
||||
auto& destination = accounts[message.recipient];
|
||||
|
||||
if (value != 0 && message.kind != EVMC_DELEGATECALL && message.kind != EVMC_CALLCODE)
|
||||
{
|
||||
if (value > convertFromEVMC(sender.balance))
|
||||
{
|
||||
evmc::result result({});
|
||||
evmc::Result result;
|
||||
result.status_code = EVMC_INSUFFICIENT_BALANCE;
|
||||
accounts = stateBackup;
|
||||
return result;
|
||||
@ -355,12 +349,9 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
if (m_evmRevision >= EVMC_BERLIN)
|
||||
{
|
||||
access_account(message.sender);
|
||||
access_account(message.destination);
|
||||
access_account(message.recipient);
|
||||
}
|
||||
evmc::address currentAddress = m_currentAddress;
|
||||
m_currentAddress = message.destination;
|
||||
evmc::result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size());
|
||||
m_currentAddress = currentAddress;
|
||||
evmc::Result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size());
|
||||
|
||||
if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2)
|
||||
{
|
||||
@ -373,7 +364,7 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
|
||||
}
|
||||
else
|
||||
{
|
||||
result.create_address = message.destination;
|
||||
result.create_address = message.recipient;
|
||||
destination.code = evmc::bytes(result.output_data, result.output_data + result.output_size);
|
||||
destination.codehash = convertToEVMC(keccak256({result.output_data, result.output_size}));
|
||||
}
|
||||
@ -416,7 +407,7 @@ evmc::bytes32 EVMHost::convertToEVMC(h256 const& _data)
|
||||
return d;
|
||||
}
|
||||
|
||||
evmc::result EVMHost::precompileECRecover(evmc_message const& _message) noexcept
|
||||
evmc::Result EVMHost::precompileECRecover(evmc_message const& _message) noexcept
|
||||
{
|
||||
// NOTE this is a partial implementation for some inputs.
|
||||
|
||||
@ -449,20 +440,14 @@ evmc::result EVMHost::precompileECRecover(evmc_message const& _message) noexcept
|
||||
}
|
||||
}
|
||||
};
|
||||
evmc::result result = precompileGeneric(_message, inputOutput);
|
||||
evmc::Result result = precompileGeneric(_message, inputOutput);
|
||||
// ECRecover will return success with empty response in case of failure
|
||||
if (result.status_code != EVMC_SUCCESS && result.status_code != EVMC_OUT_OF_GAS)
|
||||
// return resultWithGas(_message.gas, gas_cost, {});
|
||||
{
|
||||
result.status_code = EVMC_SUCCESS;
|
||||
result.gas_left = _message.gas - gas_cost;
|
||||
result.output_data = {};
|
||||
result.output_size = 0;
|
||||
}
|
||||
return resultWithGas(_message.gas, gas_cost, {});
|
||||
return result;
|
||||
}
|
||||
|
||||
evmc::result EVMHost::precompileSha256(evmc_message const& _message) noexcept
|
||||
evmc::Result EVMHost::precompileSha256(evmc_message const& _message) noexcept
|
||||
{
|
||||
// static data so that we do not need a release routine...
|
||||
bytes static hash;
|
||||
@ -477,7 +462,7 @@ evmc::result EVMHost::precompileSha256(evmc_message const& _message) noexcept
|
||||
return resultWithGas(_message.gas, gas_cost, hash);
|
||||
}
|
||||
|
||||
evmc::result EVMHost::precompileRipeMD160(evmc_message const& _message) noexcept
|
||||
evmc::Result EVMHost::precompileRipeMD160(evmc_message const& _message) noexcept
|
||||
{
|
||||
// NOTE this is a partial implementation for some inputs.
|
||||
|
||||
@ -579,7 +564,7 @@ evmc::result EVMHost::precompileRipeMD160(evmc_message const& _message) noexcept
|
||||
return precompileGeneric(_message, inputOutput);
|
||||
}
|
||||
|
||||
evmc::result EVMHost::precompileIdentity(evmc_message const& _message) noexcept
|
||||
evmc::Result EVMHost::precompileIdentity(evmc_message const& _message) noexcept
|
||||
{
|
||||
// static data so that we do not need a release routine...
|
||||
bytes static data;
|
||||
@ -591,14 +576,14 @@ evmc::result EVMHost::precompileIdentity(evmc_message const& _message) noexcept
|
||||
return resultWithGas(_message.gas, gas_cost, data);
|
||||
}
|
||||
|
||||
evmc::result EVMHost::precompileModExp(evmc_message const&) noexcept
|
||||
evmc::Result EVMHost::precompileModExp(evmc_message const&) noexcept
|
||||
{
|
||||
// TODO implement
|
||||
return resultWithFailure();
|
||||
}
|
||||
|
||||
template <evmc_revision Revision>
|
||||
evmc::result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noexcept
|
||||
evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noexcept
|
||||
{
|
||||
// NOTE this is a partial implementation for some inputs.
|
||||
|
||||
@ -866,7 +851,7 @@ evmc::result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex
|
||||
}
|
||||
|
||||
template <evmc_revision Revision>
|
||||
evmc::result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noexcept
|
||||
evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noexcept
|
||||
{
|
||||
// NOTE this is a partial implementation for some inputs.
|
||||
|
||||
@ -956,7 +941,7 @@ evmc::result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex
|
||||
}
|
||||
|
||||
template <evmc_revision Revision>
|
||||
evmc::result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _message) noexcept
|
||||
evmc::Result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _message) noexcept
|
||||
{
|
||||
// Base + per pairing gas.
|
||||
constexpr auto calc_cost = [](unsigned points) -> int64_t {
|
||||
@ -1124,7 +1109,7 @@ evmc::result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _mess
|
||||
return precompileGeneric(_message, inputOutput);
|
||||
}
|
||||
|
||||
evmc::result EVMHost::precompileGeneric(
|
||||
evmc::Result EVMHost::precompileGeneric(
|
||||
evmc_message const& _message,
|
||||
map<bytes, EVMPrecompileOutput> const& _inOut) noexcept
|
||||
{
|
||||
@ -1138,20 +1123,20 @@ evmc::result EVMHost::precompileGeneric(
|
||||
return resultWithFailure();
|
||||
}
|
||||
|
||||
evmc::result EVMHost::resultWithFailure() noexcept
|
||||
evmc::Result EVMHost::resultWithFailure() noexcept
|
||||
{
|
||||
evmc::result result({});
|
||||
evmc::Result result;
|
||||
result.status_code = EVMC_FAILURE;
|
||||
return result;
|
||||
}
|
||||
|
||||
evmc::result EVMHost::resultWithGas(
|
||||
evmc::Result EVMHost::resultWithGas(
|
||||
int64_t gas_limit,
|
||||
int64_t gas_required,
|
||||
bytes const& _data
|
||||
) noexcept
|
||||
{
|
||||
evmc::result result({});
|
||||
evmc::Result result;
|
||||
if (gas_limit < gas_required)
|
||||
{
|
||||
result.status_code = EVMC_OUT_OF_GAS;
|
||||
@ -1162,7 +1147,7 @@ evmc::result EVMHost::resultWithGas(
|
||||
result.status_code = EVMC_SUCCESS;
|
||||
result.gas_left = gas_limit - gas_required;
|
||||
}
|
||||
result.output_data = _data.data();
|
||||
result.output_data = _data.empty() ? nullptr : _data.data();
|
||||
result.output_size = _data.size();
|
||||
return result;
|
||||
}
|
||||
@ -1209,10 +1194,11 @@ void EVMHostPrinter::balance()
|
||||
void EVMHostPrinter::selfdestructRecords()
|
||||
{
|
||||
for (auto const& record: m_host.recorded_selfdestructs)
|
||||
m_stateStream << "SELFDESTRUCT"
|
||||
<< " BENEFICIARY "
|
||||
<< m_host.convertFromEVMC(record.beneficiary)
|
||||
<< endl;
|
||||
for (auto const& beneficiary: record.second)
|
||||
m_stateStream << "SELFDESTRUCT"
|
||||
<< " BENEFICIARY "
|
||||
<< m_host.convertFromEVMC(beneficiary)
|
||||
<< endl;
|
||||
}
|
||||
|
||||
void EVMHostPrinter::callRecords()
|
||||
|
@ -35,7 +35,7 @@
|
||||
namespace solidity::test
|
||||
{
|
||||
using Address = util::h160;
|
||||
using StorageMap = std::map<evmc::bytes32, evmc::storage_value>;
|
||||
using StorageMap = std::map<evmc::bytes32, evmc::StorageValue>;
|
||||
|
||||
struct EVMPrecompileOutput {
|
||||
bytes const output;
|
||||
@ -59,8 +59,8 @@ public:
|
||||
using MockedHost::access_storage;
|
||||
|
||||
// Modified features of MockedHost.
|
||||
void selfdestruct(evmc::address const& _addr, evmc::address const& _beneficiary) noexcept final;
|
||||
evmc::result call(evmc_message const& _message) noexcept final;
|
||||
bool selfdestruct(evmc::address const& _addr, evmc::address const& _beneficiary) noexcept final;
|
||||
evmc::Result call(evmc_message const& _message) noexcept final;
|
||||
evmc::bytes32 get_block_hash(int64_t number) const noexcept final;
|
||||
|
||||
// Solidity testing specific features.
|
||||
@ -98,35 +98,34 @@ public:
|
||||
static util::h256 convertFromEVMC(evmc::bytes32 const& _data);
|
||||
static evmc::bytes32 convertToEVMC(util::h256 const& _data);
|
||||
private:
|
||||
evmc::address m_currentAddress = {};
|
||||
|
||||
/// Transfer value between accounts. Checks for sufficient balance.
|
||||
void transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recipient, u256 const& _value) noexcept;
|
||||
|
||||
/// Start a new transaction frame.
|
||||
/// This will perform selfdestructs and clear account/storage access indicator for EIP-2929.
|
||||
/// This will perform selfdestructs, apply storage status changes across all accounts,
|
||||
/// and clear account/storage access indicator for EIP-2929.
|
||||
void newTransactionFrame();
|
||||
|
||||
/// Records calls made via @param _message.
|
||||
void recordCalls(evmc_message const& _message) noexcept;
|
||||
|
||||
static evmc::result precompileECRecover(evmc_message const& _message) noexcept;
|
||||
static evmc::result precompileSha256(evmc_message const& _message) noexcept;
|
||||
static evmc::result precompileRipeMD160(evmc_message const& _message) noexcept;
|
||||
static evmc::result precompileIdentity(evmc_message const& _message) noexcept;
|
||||
static evmc::result precompileModExp(evmc_message const& _message) noexcept;
|
||||
static evmc::Result precompileECRecover(evmc_message const& _message) noexcept;
|
||||
static evmc::Result precompileSha256(evmc_message const& _message) noexcept;
|
||||
static evmc::Result precompileRipeMD160(evmc_message const& _message) noexcept;
|
||||
static evmc::Result precompileIdentity(evmc_message const& _message) noexcept;
|
||||
static evmc::Result precompileModExp(evmc_message const& _message) noexcept;
|
||||
template <evmc_revision Revision>
|
||||
static evmc::result precompileALTBN128G1Add(evmc_message const& _message) noexcept;
|
||||
static evmc::Result precompileALTBN128G1Add(evmc_message const& _message) noexcept;
|
||||
template <evmc_revision Revision>
|
||||
static evmc::result precompileALTBN128G1Mul(evmc_message const& _message) noexcept;
|
||||
static evmc::Result precompileALTBN128G1Mul(evmc_message const& _message) noexcept;
|
||||
template <evmc_revision Revision>
|
||||
static evmc::result precompileALTBN128PairingProduct(evmc_message const& _message) noexcept;
|
||||
static evmc::result precompileGeneric(evmc_message const& _message, std::map<bytes, EVMPrecompileOutput> const& _inOut) noexcept;
|
||||
static evmc::Result precompileALTBN128PairingProduct(evmc_message const& _message) noexcept;
|
||||
static evmc::Result precompileGeneric(evmc_message const& _message, std::map<bytes, EVMPrecompileOutput> const& _inOut) noexcept;
|
||||
/// @returns a result object with gas usage and result data taken from @a _data.
|
||||
/// The outcome will be a failure if the limit < required.
|
||||
/// @note The return value is only valid as long as @a _data is alive!
|
||||
static evmc::result resultWithGas(int64_t gas_limit, int64_t gas_required, bytes const& _data) noexcept;
|
||||
static evmc::result resultWithFailure() noexcept;
|
||||
static evmc::Result resultWithGas(int64_t gas_limit, int64_t gas_required, bytes const& _data) noexcept;
|
||||
static evmc::Result resultWithFailure() noexcept;
|
||||
|
||||
evmc::VM& m_vm;
|
||||
/// EVM version requested by the testing tool
|
||||
|
@ -165,7 +165,7 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
|
||||
cout << " value: " << _value << endl;
|
||||
cout << " in: " << util::toHex(_data) << endl;
|
||||
}
|
||||
evmc_message message = {};
|
||||
evmc_message message{};
|
||||
message.input_data = _data.data();
|
||||
message.input_size = _data.size();
|
||||
message.sender = EVMHost::convertToEVMC(m_sender);
|
||||
@ -174,16 +174,19 @@ void ExecutionFramework::sendMessage(bytes const& _data, bool _isCreation, u256
|
||||
if (_isCreation)
|
||||
{
|
||||
message.kind = EVMC_CREATE;
|
||||
message.destination = EVMHost::convertToEVMC(h160{});
|
||||
message.recipient = {};
|
||||
message.code_address = {};
|
||||
}
|
||||
else
|
||||
{
|
||||
message.kind = EVMC_CALL;
|
||||
message.destination = EVMHost::convertToEVMC(m_contractAddress);
|
||||
message.recipient = EVMHost::convertToEVMC(m_contractAddress);
|
||||
message.code_address = message.recipient;
|
||||
}
|
||||
|
||||
message.gas = InitialGas.convert_to<int64_t>();
|
||||
|
||||
evmc::result result = m_evmcHost->call(message);
|
||||
evmc::Result result = m_evmcHost->call(message);
|
||||
|
||||
m_output = bytes(result.output_data, result.output_data + result.output_size);
|
||||
if (_isCreation)
|
||||
@ -210,11 +213,12 @@ void ExecutionFramework::sendEther(h160 const& _addr, u256 const& _amount)
|
||||
if (_amount > 0)
|
||||
cout << " value: " << _amount << endl;
|
||||
}
|
||||
evmc_message message = {};
|
||||
evmc_message message{};
|
||||
message.sender = EVMHost::convertToEVMC(m_sender);
|
||||
message.value = EVMHost::convertToEVMC(_amount);
|
||||
message.kind = EVMC_CALL;
|
||||
message.destination = EVMHost::convertToEVMC(_addr);
|
||||
message.recipient = EVMHost::convertToEVMC(_addr);
|
||||
message.code_address = message.recipient;
|
||||
message.gas = InitialGas.convert_to<int64_t>();
|
||||
|
||||
m_evmcHost->call(message);
|
||||
|
@ -272,7 +272,6 @@ private:
|
||||
}
|
||||
|
||||
protected:
|
||||
u256 const GasPrice = 10 * gwei;
|
||||
u256 const InitialGas = 100000000;
|
||||
|
||||
void selectVM(evmc_capabilities _cap = evmc_capabilities::EVMC_CAPABILITY_EVM1);
|
||||
|
@ -83,31 +83,32 @@ evmc_message EvmoneUtility::initializeMessage(bytes const& _input)
|
||||
return msg;
|
||||
}
|
||||
|
||||
evmc::result EvmoneUtility::executeContract(
|
||||
evmc::Result EvmoneUtility::executeContract(
|
||||
bytes const& _functionHash,
|
||||
evmc_address _deployedAddress
|
||||
)
|
||||
{
|
||||
evmc_message message = initializeMessage(_functionHash);
|
||||
message.destination = _deployedAddress;
|
||||
message.recipient = _deployedAddress;
|
||||
message.code_address = _deployedAddress;
|
||||
message.kind = EVMC_CALL;
|
||||
return m_evmHost.call(message);
|
||||
}
|
||||
|
||||
evmc::result EvmoneUtility::deployContract(bytes const& _code)
|
||||
evmc::Result EvmoneUtility::deployContract(bytes const& _code)
|
||||
{
|
||||
evmc_message message = initializeMessage(_code);
|
||||
message.kind = EVMC_CREATE;
|
||||
return m_evmHost.call(message);
|
||||
}
|
||||
|
||||
evmc::result EvmoneUtility::deployAndExecute(
|
||||
evmc::Result EvmoneUtility::deployAndExecute(
|
||||
bytes const& _byteCode,
|
||||
string const& _hexEncodedInput
|
||||
)
|
||||
{
|
||||
// Deploy contract and signal failure if deploy failed
|
||||
evmc::result createResult = deployContract(_byteCode);
|
||||
evmc::Result createResult = deployContract(_byteCode);
|
||||
solAssert(
|
||||
createResult.status_code == EVMC_SUCCESS,
|
||||
"SolidityEvmoneInterface: Contract creation failed"
|
||||
@ -115,7 +116,7 @@ evmc::result EvmoneUtility::deployAndExecute(
|
||||
|
||||
// Execute test function and signal failure if EVM reverted or
|
||||
// did not return expected output on successful execution.
|
||||
evmc::result callResult = executeContract(
|
||||
evmc::Result callResult = executeContract(
|
||||
util::fromHex(_hexEncodedInput),
|
||||
createResult.create_address
|
||||
);
|
||||
@ -128,7 +129,7 @@ evmc::result EvmoneUtility::deployAndExecute(
|
||||
return callResult;
|
||||
}
|
||||
|
||||
evmc::result EvmoneUtility::compileDeployAndExecute(string _fuzzIsabelle)
|
||||
evmc::Result EvmoneUtility::compileDeployAndExecute(string _fuzzIsabelle)
|
||||
{
|
||||
map<string, h160> libraryAddressMap;
|
||||
// Stage 1: Compile and deploy library if present.
|
||||
@ -139,7 +140,7 @@ evmc::result EvmoneUtility::compileDeployAndExecute(string _fuzzIsabelle)
|
||||
solAssert(compilationOutput.has_value(), "Compiling library failed");
|
||||
CompilerOutput cOutput = compilationOutput.value();
|
||||
// Deploy contract and signal failure if deploy failed
|
||||
evmc::result createResult = deployContract(cOutput.byteCode);
|
||||
evmc::Result createResult = deployContract(cOutput.byteCode);
|
||||
solAssert(
|
||||
createResult.status_code == EVMC_SUCCESS,
|
||||
"SolidityEvmoneInterface: Library deployment failed"
|
||||
|
@ -122,7 +122,7 @@ public:
|
||||
/// and executing test configuration.
|
||||
/// @param _isabelleData contains encoding data to be passed to the
|
||||
/// isabelle test entry point.
|
||||
evmc::result compileDeployAndExecute(std::string _isabelleData = {});
|
||||
evmc::Result compileDeployAndExecute(std::string _isabelleData = {});
|
||||
/// Compares the contents of the memory address pointed to
|
||||
/// by `_result` of `_length` bytes to u256 zero.
|
||||
/// @returns true if `_result` is zero, false
|
||||
@ -138,17 +138,17 @@ private:
|
||||
/// @returns the result of the execution of the function whose
|
||||
/// keccak256 hash is @param _functionHash that is deployed at
|
||||
/// @param _deployedAddress in @param _hostContext.
|
||||
evmc::result executeContract(
|
||||
evmc::Result executeContract(
|
||||
bytes const& _functionHash,
|
||||
evmc_address _deployedAddress
|
||||
);
|
||||
/// @returns the result of deployment of @param _code on @param _hostContext.
|
||||
evmc::result deployContract(bytes const& _code);
|
||||
evmc::Result deployContract(bytes const& _code);
|
||||
/// Deploys and executes EVM byte code in @param _byteCode on
|
||||
/// EVM Host referenced by @param _hostContext. Input passed
|
||||
/// to execution context is @param _hexEncodedInput.
|
||||
/// @returns result returning by @param _hostContext.
|
||||
evmc::result deployAndExecute(
|
||||
evmc::Result deployAndExecute(
|
||||
bytes const& _byteCode,
|
||||
std::string const& _hexEncodedInput
|
||||
);
|
||||
|
@ -87,11 +87,11 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
||||
return;
|
||||
}
|
||||
|
||||
evmc::result deployResult = YulEvmoneUtility{}.deployCode(unoptimisedByteCode, hostContext);
|
||||
evmc::Result deployResult = YulEvmoneUtility{}.deployCode(unoptimisedByteCode, hostContext);
|
||||
if (deployResult.status_code != EVMC_SUCCESS)
|
||||
return;
|
||||
auto callMessage = YulEvmoneUtility{}.callMessage(deployResult.create_address);
|
||||
evmc::result callResult = hostContext.call(callMessage);
|
||||
evmc::Result callResult = hostContext.call(callMessage);
|
||||
// If the fuzzer synthesized input does not contain the revert opcode which
|
||||
// we lazily check by string find, the EVM call should not revert.
|
||||
bool noRevertInSource = yul_source.find("revert") == string::npos;
|
||||
@ -132,13 +132,13 @@ DEFINE_PROTO_FUZZER(Program const& _input)
|
||||
|
||||
// Reset host before running optimised code.
|
||||
hostContext.reset();
|
||||
evmc::result deployResultOpt = YulEvmoneUtility{}.deployCode(optimisedByteCode, hostContext);
|
||||
evmc::Result deployResultOpt = YulEvmoneUtility{}.deployCode(optimisedByteCode, hostContext);
|
||||
solAssert(
|
||||
deployResultOpt.status_code == EVMC_SUCCESS,
|
||||
"Evmone: Optimized contract creation failed"
|
||||
);
|
||||
auto callMessageOpt = YulEvmoneUtility{}.callMessage(deployResultOpt.create_address);
|
||||
evmc::result callResultOpt = hostContext.call(callMessageOpt);
|
||||
evmc::Result callResultOpt = hostContext.call(callMessageOpt);
|
||||
if (noRevertInSource)
|
||||
solAssert(
|
||||
callResultOpt.status_code != EVMC_REVERT,
|
||||
|
@ -38,7 +38,7 @@ bytes YulAssembler::assemble()
|
||||
return m_stack.assemble(YulStack::Machine::EVM).bytecode->bytecode;
|
||||
}
|
||||
|
||||
evmc::result YulEvmoneUtility::deployCode(bytes const& _input, EVMHost& _host)
|
||||
evmc::Result YulEvmoneUtility::deployCode(bytes const& _input, EVMHost& _host)
|
||||
{
|
||||
// Zero initialize all message fields
|
||||
evmc_message msg = {};
|
||||
@ -74,7 +74,8 @@ evmc_message YulEvmoneUtility::callMessage(evmc_address _address)
|
||||
{
|
||||
evmc_message call = {};
|
||||
call.gas = std::numeric_limits<int64_t>::max();
|
||||
call.destination = _address;
|
||||
call.recipient = _address;
|
||||
call.code_address = _address;
|
||||
call.kind = EVMC_CALL;
|
||||
return call;
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ private:
|
||||
struct YulEvmoneUtility
|
||||
{
|
||||
/// @returns the result of deploying bytecode @param _input on @param _host.
|
||||
static evmc::result deployCode(solidity::bytes const& _input, EVMHost& _host);
|
||||
static evmc::Result deployCode(solidity::bytes const& _input, EVMHost& _host);
|
||||
/// @returns call message to be sent to @param _address.
|
||||
static evmc_message callMessage(evmc_address _address);
|
||||
/// @returns true if call result indicates a serious error, false otherwise.
|
||||
|
Loading…
Reference in New Issue
Block a user