Skip to content

Commit 199f365

Browse files
committed
test: Improve precision of SSTORE cost in EVMHost
Add "original" field to storage_value to precise track "dirty" state of a storage slot as defined in EIP-2200. In case a current storage value is restored to original (after multiple modifications in a single transaction), the storage slot is not considered "dirty" any more. Previously, we only had a bool dirty flag to model this and a storage slot was always considered "dirty" after first modification.
1 parent 9db2da0 commit 199f365

File tree

3 files changed

+14
-25
lines changed

3 files changed

+14
-25
lines changed

test/EVMHost.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ void EVMHost::newTransactionFrame()
179179
for (auto& [slot, value]: account.storage)
180180
{
181181
value.access_status = EVMC_ACCESS_COLD; // Clear EIP-2929 storage access indicator
182-
value.dirty = false; // Clear EIP-2200 dirty slot flag
182+
value.original = value.current; // Clear EIP-2200 dirty slot
183183
}
184184
// Process selfdestruct list
185185
for (auto& [address, _]: recorded_selfdestructs)
@@ -1195,7 +1195,7 @@ void EVMHostPrinter::storage()
11951195
m_stateStream << " "
11961196
<< m_host.convertFromEVMC(slot)
11971197
<< ": "
1198-
<< m_host.convertFromEVMC(value.value)
1198+
<< m_host.convertFromEVMC(value.current)
11991199
<< endl;
12001200
}
12011201

test/ExecutionFramework.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ bool ExecutionFramework::storageEmpty(h160 const& _addr) const
282282
if (it != m_evmcHost->accounts.end())
283283
{
284284
for (auto const& entry: it->second.storage)
285-
if (!(entry.second.value == evmc::bytes32{}))
285+
if (entry.second.current != evmc::bytes32{})
286286
return false;
287287
}
288288
return true;

test/evmc/mocked_host.hpp

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -15,30 +15,20 @@ namespace evmc
1515
/// The string of bytes.
1616
using bytes = std::basic_string<uint8_t>;
1717

18-
/// Extended value (by dirty flag) for account storage.
18+
/// Extended value (with original value and access flag) for account storage.
1919
struct storage_value
2020
{
21-
/// The storage value.
22-
bytes32 value;
21+
/// The current storage value.
22+
bytes32 current;
2323

24-
/// True means this value has been modified already by the current transaction.
25-
bool dirty{false};
24+
/// The original storage value.
25+
bytes32 original;
2626

2727
/// Is the storage key cold or warm.
28-
evmc_access_status access_status{EVMC_ACCESS_COLD};
28+
evmc_access_status access_status = EVMC_ACCESS_COLD;
2929

3030
/// Default constructor.
3131
storage_value() noexcept = default;
32-
33-
/// Constructor.
34-
storage_value(const bytes32& _value, bool _dirty = false) noexcept // NOLINT
35-
: value{_value}, dirty{_dirty}
36-
{}
37-
38-
/// Constructor with initial access status.
39-
storage_value(const bytes32& _value, evmc_access_status _access_status) noexcept
40-
: value{_value}, access_status{_access_status}
41-
{}
4232
};
4333

4434
/// Mocked account.
@@ -176,7 +166,7 @@ class MockedHost : public Host
176166

177167
const auto storage_iter = account_iter->second.storage.find(key);
178168
if (storage_iter != account_iter->second.storage.end())
179-
return storage_iter->second.value;
169+
return storage_iter->second.current;
180170
return {};
181171
}
182172

@@ -195,14 +185,13 @@ class MockedHost : public Host
195185
// Follow https://eips.ethereum.org/EIPS/eip-1283 specification.
196186
// WARNING! This is not complete implementation as refund is not handled here.
197187

198-
if (old.value == value)
188+
if (old.current == value)
199189
return EVMC_STORAGE_UNCHANGED;
200190

201191
evmc_storage_status status{};
202-
if (!old.dirty)
192+
if (old.original == old.current) // Storage slot not dirty
203193
{
204-
old.dirty = true;
205-
if (!old.value)
194+
if (!old.current)
206195
status = EVMC_STORAGE_ADDED;
207196
else if (value)
208197
status = EVMC_STORAGE_MODIFIED;
@@ -212,7 +201,7 @@ class MockedHost : public Host
212201
else
213202
status = EVMC_STORAGE_MODIFIED_AGAIN;
214203

215-
old.value = value;
204+
old.current = value;
216205
return status;
217206
}
218207

0 commit comments

Comments
 (0)