Skip to content

Commit 5df92a3

Browse files
committed
Update EVMHost to match EVMC10 changes
1 parent 458857d commit 5df92a3

9 files changed

+94
-104
lines changed

test/EVMHost.cpp

Lines changed: 47 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
125125
else
126126
assertThrow(false, Exception, "Unsupported EVM version");
127127

128-
tx_context.block_difficulty = evmc::uint256be{200000000};
128+
tx_context.block_prev_randao = evmc::uint256be{200000000}; // TODO: should make it >2**64 for >Paris
129129
tx_context.block_gas_limit = 20000000;
130130
tx_context.block_coinbase = 0x7878787878787878787878787878787878787878_address;
131131
tx_context.tx_gas_price = evmc::uint256be{3000000000};
@@ -145,7 +145,6 @@ EVMHost::EVMHost(langutil::EVMVersion _evmVersion, evmc::VM& _vm):
145145
void EVMHost::reset()
146146
{
147147
accounts.clear();
148-
m_currentAddress = {};
149148
// Clear self destruct records
150149
recorded_selfdestructs.clear();
151150
// Clear call records
@@ -194,14 +193,14 @@ void EVMHost::transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recip
194193
_recipient.balance = convertToEVMC(u256(convertFromEVMC(_recipient.balance)) + _value);
195194
}
196195

197-
void EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept
196+
bool EVMHost::selfdestruct(const evmc::address& _addr, const evmc::address& _beneficiary) noexcept
198197
{
199198
// TODO actual selfdestruct is even more complicated.
200199

201200
transfer(accounts[_addr], accounts[_beneficiary], convertFromEVMC(accounts[_addr].balance));
202201

203202
// Record self destructs. Clearing will be done in newTransactionFrame().
204-
MockedHost::selfdestruct(_addr, _beneficiary);
203+
return MockedHost::selfdestruct(_addr, _beneficiary);
205204
}
206205

207206
void EVMHost::recordCalls(evmc_message const& _message) noexcept
@@ -212,34 +211,34 @@ void EVMHost::recordCalls(evmc_message const& _message) noexcept
212211

213212
// NOTE: this is used for both internal and external calls.
214213
// External calls are triggered from ExecutionFramework and contain only EVMC_CREATE or EVMC_CALL.
215-
evmc::result EVMHost::call(evmc_message const& _message) noexcept
214+
evmc::Result EVMHost::call(evmc_message const& _message) noexcept
216215
{
217216
recordCalls(_message);
218-
if (_message.destination == 0x0000000000000000000000000000000000000001_address)
217+
if (_message.recipient == 0x0000000000000000000000000000000000000001_address)
219218
return precompileECRecover(_message);
220-
else if (_message.destination == 0x0000000000000000000000000000000000000002_address)
219+
else if (_message.recipient == 0x0000000000000000000000000000000000000002_address)
221220
return precompileSha256(_message);
222-
else if (_message.destination == 0x0000000000000000000000000000000000000003_address)
221+
else if (_message.recipient == 0x0000000000000000000000000000000000000003_address)
223222
return precompileRipeMD160(_message);
224-
else if (_message.destination == 0x0000000000000000000000000000000000000004_address)
223+
else if (_message.recipient == 0x0000000000000000000000000000000000000004_address)
225224
return precompileIdentity(_message);
226-
else if (_message.destination == 0x0000000000000000000000000000000000000005_address && m_evmVersion >= langutil::EVMVersion::byzantium())
225+
else if (_message.recipient == 0x0000000000000000000000000000000000000005_address && m_evmVersion >= langutil::EVMVersion::byzantium())
227226
return precompileModExp(_message);
228-
else if (_message.destination == 0x0000000000000000000000000000000000000006_address && m_evmVersion >= langutil::EVMVersion::byzantium())
227+
else if (_message.recipient == 0x0000000000000000000000000000000000000006_address && m_evmVersion >= langutil::EVMVersion::byzantium())
229228
{
230229
if (m_evmVersion <= langutil::EVMVersion::istanbul())
231230
return precompileALTBN128G1Add<EVMC_ISTANBUL>(_message);
232231
else
233232
return precompileALTBN128G1Add<EVMC_LONDON>(_message);
234233
}
235-
else if (_message.destination == 0x0000000000000000000000000000000000000007_address && m_evmVersion >= langutil::EVMVersion::byzantium())
234+
else if (_message.recipient == 0x0000000000000000000000000000000000000007_address && m_evmVersion >= langutil::EVMVersion::byzantium())
236235
{
237236
if (m_evmVersion <= langutil::EVMVersion::istanbul())
238237
return precompileALTBN128G1Mul<EVMC_ISTANBUL>(_message);
239238
else
240239
return precompileALTBN128G1Mul<EVMC_LONDON>(_message);
241240
}
242-
else if (_message.destination == 0x0000000000000000000000000000000000000008_address && m_evmVersion >= langutil::EVMVersion::byzantium())
241+
else if (_message.recipient == 0x0000000000000000000000000000000000000008_address && m_evmVersion >= langutil::EVMVersion::byzantium())
243242
{
244243
if (m_evmVersion <= langutil::EVMVersion::istanbul())
245244
return precompileALTBN128PairingProduct<EVMC_ISTANBUL>(_message);
@@ -262,7 +261,7 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
262261
message.gas -= message.input_data[i] == 0 ? evmasm::GasCosts::txDataZeroGas : evmasm::GasCosts::txDataNonZeroGas(m_evmVersion);
263262
if (message.gas < 0)
264263
{
265-
evmc::result result({});
264+
evmc::Result result;
266265
result.status_code = EVMC_OUT_OF_GAS;
267266
accounts = stateBackup;
268267
return result;
@@ -299,8 +298,8 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
299298
encodedNonce
300299
), h160::AlignRight);
301300

302-
message.destination = convertToEVMC(createAddress);
303-
assertThrow(accounts.count(message.destination) == 0, Exception, "Account cannot exist");
301+
message.recipient = convertToEVMC(createAddress);
302+
assertThrow(accounts.count(message.recipient) == 0, Exception, "Account cannot exist");
304303

305304
code = evmc::bytes(message.input_data, message.input_data + message.input_size);
306305
}
@@ -313,35 +312,30 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
313312
keccak256(bytes(message.input_data, message.input_data + message.input_size)).asBytes()
314313
), h160::AlignRight);
315314

316-
message.destination = convertToEVMC(createAddress);
317-
if (accounts.count(message.destination) && (
318-
accounts[message.destination].nonce > 0 ||
319-
!accounts[message.destination].code.empty()
315+
message.recipient = convertToEVMC(createAddress);
316+
if (accounts.count(message.recipient) && (
317+
accounts[message.recipient].nonce > 0 ||
318+
!accounts[message.recipient].code.empty()
320319
))
321320
{
322-
evmc::result result({});
321+
evmc::Result result;
323322
result.status_code = EVMC_OUT_OF_GAS;
324323
accounts = stateBackup;
325324
return result;
326325
}
327326

328327
code = evmc::bytes(message.input_data, message.input_data + message.input_size);
329328
}
330-
else if (message.kind == EVMC_DELEGATECALL || message.kind == EVMC_CALLCODE)
331-
{
332-
code = accounts[message.destination].code;
333-
message.destination = m_currentAddress;
334-
}
335329
else
336-
code = accounts[message.destination].code;
330+
code = accounts[message.code_address].code;
337331

338-
auto& destination = accounts[message.destination];
332+
auto& destination = accounts[message.recipient];
339333

340334
if (value != 0 && message.kind != EVMC_DELEGATECALL && message.kind != EVMC_CALLCODE)
341335
{
342336
if (value > convertFromEVMC(sender.balance))
343337
{
344-
evmc::result result({});
338+
evmc::Result result;
345339
result.status_code = EVMC_INSUFFICIENT_BALANCE;
346340
accounts = stateBackup;
347341
return result;
@@ -355,12 +349,9 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
355349
if (m_evmRevision >= EVMC_BERLIN)
356350
{
357351
access_account(message.sender);
358-
access_account(message.destination);
352+
access_account(message.recipient);
359353
}
360-
evmc::address currentAddress = m_currentAddress;
361-
m_currentAddress = message.destination;
362-
evmc::result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size());
363-
m_currentAddress = currentAddress;
354+
evmc::Result result = m_vm.execute(*this, m_evmRevision, message, code.data(), code.size());
364355

365356
if (message.kind == EVMC_CREATE || message.kind == EVMC_CREATE2)
366357
{
@@ -373,7 +364,7 @@ evmc::result EVMHost::call(evmc_message const& _message) noexcept
373364
}
374365
else
375366
{
376-
result.create_address = message.destination;
367+
result.create_address = message.recipient;
377368
destination.code = evmc::bytes(result.output_data, result.output_data + result.output_size);
378369
destination.codehash = convertToEVMC(keccak256({result.output_data, result.output_size}));
379370
}
@@ -416,7 +407,7 @@ evmc::bytes32 EVMHost::convertToEVMC(h256 const& _data)
416407
return d;
417408
}
418409

419-
evmc::result EVMHost::precompileECRecover(evmc_message const& _message) noexcept
410+
evmc::Result EVMHost::precompileECRecover(evmc_message const& _message) noexcept
420411
{
421412
// NOTE this is a partial implementation for some inputs.
422413

@@ -449,20 +440,14 @@ evmc::result EVMHost::precompileECRecover(evmc_message const& _message) noexcept
449440
}
450441
}
451442
};
452-
evmc::result result = precompileGeneric(_message, inputOutput);
443+
evmc::Result result = precompileGeneric(_message, inputOutput);
453444
// ECRecover will return success with empty response in case of failure
454445
if (result.status_code != EVMC_SUCCESS && result.status_code != EVMC_OUT_OF_GAS)
455-
// return resultWithGas(_message.gas, gas_cost, {});
456-
{
457-
result.status_code = EVMC_SUCCESS;
458-
result.gas_left = _message.gas - gas_cost;
459-
result.output_data = {};
460-
result.output_size = 0;
461-
}
446+
return resultWithGas(_message.gas, gas_cost, {});
462447
return result;
463448
}
464449

465-
evmc::result EVMHost::precompileSha256(evmc_message const& _message) noexcept
450+
evmc::Result EVMHost::precompileSha256(evmc_message const& _message) noexcept
466451
{
467452
// static data so that we do not need a release routine...
468453
bytes static hash;
@@ -477,7 +462,7 @@ evmc::result EVMHost::precompileSha256(evmc_message const& _message) noexcept
477462
return resultWithGas(_message.gas, gas_cost, hash);
478463
}
479464

480-
evmc::result EVMHost::precompileRipeMD160(evmc_message const& _message) noexcept
465+
evmc::Result EVMHost::precompileRipeMD160(evmc_message const& _message) noexcept
481466
{
482467
// NOTE this is a partial implementation for some inputs.
483468

@@ -579,7 +564,7 @@ evmc::result EVMHost::precompileRipeMD160(evmc_message const& _message) noexcept
579564
return precompileGeneric(_message, inputOutput);
580565
}
581566

582-
evmc::result EVMHost::precompileIdentity(evmc_message const& _message) noexcept
567+
evmc::Result EVMHost::precompileIdentity(evmc_message const& _message) noexcept
583568
{
584569
// static data so that we do not need a release routine...
585570
bytes static data;
@@ -591,14 +576,14 @@ evmc::result EVMHost::precompileIdentity(evmc_message const& _message) noexcept
591576
return resultWithGas(_message.gas, gas_cost, data);
592577
}
593578

594-
evmc::result EVMHost::precompileModExp(evmc_message const&) noexcept
579+
evmc::Result EVMHost::precompileModExp(evmc_message const&) noexcept
595580
{
596581
// TODO implement
597582
return resultWithFailure();
598583
}
599584

600585
template <evmc_revision Revision>
601-
evmc::result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noexcept
586+
evmc::Result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noexcept
602587
{
603588
// NOTE this is a partial implementation for some inputs.
604589

@@ -866,7 +851,7 @@ evmc::result EVMHost::precompileALTBN128G1Add(evmc_message const& _message) noex
866851
}
867852

868853
template <evmc_revision Revision>
869-
evmc::result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noexcept
854+
evmc::Result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noexcept
870855
{
871856
// NOTE this is a partial implementation for some inputs.
872857

@@ -956,7 +941,7 @@ evmc::result EVMHost::precompileALTBN128G1Mul(evmc_message const& _message) noex
956941
}
957942

958943
template <evmc_revision Revision>
959-
evmc::result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _message) noexcept
944+
evmc::Result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _message) noexcept
960945
{
961946
// Base + per pairing gas.
962947
constexpr auto calc_cost = [](unsigned points) -> int64_t {
@@ -1124,7 +1109,7 @@ evmc::result EVMHost::precompileALTBN128PairingProduct(evmc_message const& _mess
11241109
return precompileGeneric(_message, inputOutput);
11251110
}
11261111

1127-
evmc::result EVMHost::precompileGeneric(
1112+
evmc::Result EVMHost::precompileGeneric(
11281113
evmc_message const& _message,
11291114
map<bytes, EVMPrecompileOutput> const& _inOut) noexcept
11301115
{
@@ -1138,20 +1123,20 @@ evmc::result EVMHost::precompileGeneric(
11381123
return resultWithFailure();
11391124
}
11401125

1141-
evmc::result EVMHost::resultWithFailure() noexcept
1126+
evmc::Result EVMHost::resultWithFailure() noexcept
11421127
{
1143-
evmc::result result({});
1128+
evmc::Result result;
11441129
result.status_code = EVMC_FAILURE;
11451130
return result;
11461131
}
11471132

1148-
evmc::result EVMHost::resultWithGas(
1133+
evmc::Result EVMHost::resultWithGas(
11491134
int64_t gas_limit,
11501135
int64_t gas_required,
11511136
bytes const& _data
11521137
) noexcept
11531138
{
1154-
evmc::result result({});
1139+
evmc::Result result;
11551140
if (gas_limit < gas_required)
11561141
{
11571142
result.status_code = EVMC_OUT_OF_GAS;
@@ -1162,7 +1147,7 @@ evmc::result EVMHost::resultWithGas(
11621147
result.status_code = EVMC_SUCCESS;
11631148
result.gas_left = gas_limit - gas_required;
11641149
}
1165-
result.output_data = _data.data();
1150+
result.output_data = _data.empty() ? nullptr : _data.data();
11661151
result.output_size = _data.size();
11671152
return result;
11681153
}
@@ -1209,10 +1194,11 @@ void EVMHostPrinter::balance()
12091194
void EVMHostPrinter::selfdestructRecords()
12101195
{
12111196
for (auto const& record: m_host.recorded_selfdestructs)
1212-
m_stateStream << "SELFDESTRUCT"
1213-
<< " BENEFICIARY "
1214-
<< m_host.convertFromEVMC(record.beneficiary)
1215-
<< endl;
1197+
for (auto const& beneficiary: record.second)
1198+
m_stateStream << "SELFDESTRUCT"
1199+
<< " BENEFICIARY "
1200+
<< m_host.convertFromEVMC(beneficiary)
1201+
<< endl;
12161202
}
12171203

12181204
void EVMHostPrinter::callRecords()

test/EVMHost.h

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
namespace solidity::test
3636
{
3737
using Address = util::h160;
38-
using StorageMap = std::map<evmc::bytes32, evmc::storage_value>;
38+
using StorageMap = std::map<evmc::bytes32, evmc::StorageValue>;
3939

4040
struct EVMPrecompileOutput {
4141
bytes const output;
@@ -59,8 +59,8 @@ class EVMHost: public evmc::MockedHost
5959
using MockedHost::access_storage;
6060

6161
// Modified features of MockedHost.
62-
void selfdestruct(evmc::address const& _addr, evmc::address const& _beneficiary) noexcept final;
63-
evmc::result call(evmc_message const& _message) noexcept final;
62+
bool selfdestruct(evmc::address const& _addr, evmc::address const& _beneficiary) noexcept final;
63+
evmc::Result call(evmc_message const& _message) noexcept final;
6464
evmc::bytes32 get_block_hash(int64_t number) const noexcept final;
6565

6666
// Solidity testing specific features.
@@ -98,35 +98,34 @@ class EVMHost: public evmc::MockedHost
9898
static util::h256 convertFromEVMC(evmc::bytes32 const& _data);
9999
static evmc::bytes32 convertToEVMC(util::h256 const& _data);
100100
private:
101-
evmc::address m_currentAddress = {};
102-
103101
/// Transfer value between accounts. Checks for sufficient balance.
104102
void transfer(evmc::MockedAccount& _sender, evmc::MockedAccount& _recipient, u256 const& _value) noexcept;
105103

106104
/// Start a new transaction frame.
107-
/// This will perform selfdestructs and clear account/storage access indicator for EIP-2929.
105+
/// This will perform selfdestructs, apply storage status changes across all accounts,
106+
/// and clear account/storage access indicator for EIP-2929.
108107
void newTransactionFrame();
109108

110109
/// Records calls made via @param _message.
111110
void recordCalls(evmc_message const& _message) noexcept;
112111

113-
static evmc::result precompileECRecover(evmc_message const& _message) noexcept;
114-
static evmc::result precompileSha256(evmc_message const& _message) noexcept;
115-
static evmc::result precompileRipeMD160(evmc_message const& _message) noexcept;
116-
static evmc::result precompileIdentity(evmc_message const& _message) noexcept;
117-
static evmc::result precompileModExp(evmc_message const& _message) noexcept;
112+
static evmc::Result precompileECRecover(evmc_message const& _message) noexcept;
113+
static evmc::Result precompileSha256(evmc_message const& _message) noexcept;
114+
static evmc::Result precompileRipeMD160(evmc_message const& _message) noexcept;
115+
static evmc::Result precompileIdentity(evmc_message const& _message) noexcept;
116+
static evmc::Result precompileModExp(evmc_message const& _message) noexcept;
118117
template <evmc_revision Revision>
119-
static evmc::result precompileALTBN128G1Add(evmc_message const& _message) noexcept;
118+
static evmc::Result precompileALTBN128G1Add(evmc_message const& _message) noexcept;
120119
template <evmc_revision Revision>
121-
static evmc::result precompileALTBN128G1Mul(evmc_message const& _message) noexcept;
120+
static evmc::Result precompileALTBN128G1Mul(evmc_message const& _message) noexcept;
122121
template <evmc_revision Revision>
123-
static evmc::result precompileALTBN128PairingProduct(evmc_message const& _message) noexcept;
124-
static evmc::result precompileGeneric(evmc_message const& _message, std::map<bytes, EVMPrecompileOutput> const& _inOut) noexcept;
122+
static evmc::Result precompileALTBN128PairingProduct(evmc_message const& _message) noexcept;
123+
static evmc::Result precompileGeneric(evmc_message const& _message, std::map<bytes, EVMPrecompileOutput> const& _inOut) noexcept;
125124
/// @returns a result object with gas usage and result data taken from @a _data.
126125
/// The outcome will be a failure if the limit < required.
127126
/// @note The return value is only valid as long as @a _data is alive!
128-
static evmc::result resultWithGas(int64_t gas_limit, int64_t gas_required, bytes const& _data) noexcept;
129-
static evmc::result resultWithFailure() noexcept;
127+
static evmc::Result resultWithGas(int64_t gas_limit, int64_t gas_required, bytes const& _data) noexcept;
128+
static evmc::Result resultWithFailure() noexcept;
130129

131130
evmc::VM& m_vm;
132131
/// EVM version requested by the testing tool

0 commit comments

Comments
 (0)