Merge pull request #13694 from ethereum/evmhost_set_storage

test: Improve precision of SSTORE cost in EVMHost
This commit is contained in:
Daniel 2022-11-09 11:41:23 +01:00 committed by GitHub
commit 5c139b60b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 41 additions and 50 deletions

View File

@ -179,7 +179,7 @@ void EVMHost::newTransactionFrame()
for (auto& [slot, value]: account.storage) for (auto& [slot, value]: account.storage)
{ {
value.access_status = EVMC_ACCESS_COLD; // Clear EIP-2929 storage access indicator value.access_status = EVMC_ACCESS_COLD; // Clear EIP-2929 storage access indicator
value.dirty = false; // Clear EIP-2200 dirty slot flag value.original = value.current; // Clear EIP-2200 dirty slot
} }
// Process selfdestruct list // Process selfdestruct list
for (auto& [address, _]: recorded_selfdestructs) for (auto& [address, _]: recorded_selfdestructs)
@ -1195,7 +1195,7 @@ void EVMHostPrinter::storage()
m_stateStream << " " m_stateStream << " "
<< m_host.convertFromEVMC(slot) << m_host.convertFromEVMC(slot)
<< ": " << ": "
<< m_host.convertFromEVMC(value.value) << m_host.convertFromEVMC(value.current)
<< endl; << endl;
} }

View File

@ -282,7 +282,7 @@ bool ExecutionFramework::storageEmpty(h160 const& _addr) const
if (it != m_evmcHost->accounts.end()) if (it != m_evmcHost->accounts.end())
{ {
for (auto const& entry: it->second.storage) for (auto const& entry: it->second.storage)
if (!(entry.second.value == evmc::bytes32{})) if (entry.second.current != evmc::bytes32{})
return false; return false;
} }
return true; return true;

View File

@ -15,30 +15,20 @@ namespace evmc
/// The string of bytes. /// The string of bytes.
using bytes = std::basic_string<uint8_t>; using bytes = std::basic_string<uint8_t>;
/// Extended value (by dirty flag) for account storage. /// Extended value (with original value and access flag) for account storage.
struct storage_value struct storage_value
{ {
/// The storage value. /// The current storage value.
bytes32 value; bytes32 current;
/// True means this value has been modified already by the current transaction. /// The original storage value.
bool dirty{false}; bytes32 original;
/// Is the storage key cold or warm. /// Is the storage key cold or warm.
evmc_access_status access_status{EVMC_ACCESS_COLD}; evmc_access_status access_status = EVMC_ACCESS_COLD;
/// Default constructor. /// Default constructor.
storage_value() noexcept = default; storage_value() noexcept = default;
/// Constructor.
storage_value(const bytes32& _value, bool _dirty = false) noexcept // NOLINT
: 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.
@ -176,7 +166,7 @@ public:
const auto storage_iter = account_iter->second.storage.find(key); const auto storage_iter = account_iter->second.storage.find(key);
if (storage_iter != account_iter->second.storage.end()) if (storage_iter != account_iter->second.storage.end())
return storage_iter->second.value; return storage_iter->second.current;
return {}; return {};
} }
@ -195,14 +185,13 @@ public:
// Follow https://eips.ethereum.org/EIPS/eip-1283 specification. // Follow https://eips.ethereum.org/EIPS/eip-1283 specification.
// WARNING! This is not complete implementation as refund is not handled here. // WARNING! This is not complete implementation as refund is not handled here.
if (old.value == value) if (old.current == value)
return EVMC_STORAGE_UNCHANGED; return EVMC_STORAGE_UNCHANGED;
evmc_storage_status status{}; evmc_storage_status status{};
if (!old.dirty) if (old.original == old.current) // Storage slot not dirty
{ {
old.dirty = true; if (!old.current)
if (!old.value)
status = EVMC_STORAGE_ADDED; status = EVMC_STORAGE_ADDED;
else if (value) else if (value)
status = EVMC_STORAGE_MODIFIED; status = EVMC_STORAGE_MODIFIED;
@ -212,7 +201,7 @@ public:
else else
status = EVMC_STORAGE_MODIFIED_AGAIN; status = EVMC_STORAGE_MODIFIED_AGAIN;
old.value = value; old.current = value;
return status; return status;
} }

View File

@ -46,8 +46,8 @@ contract c {
// storageEmpty -> 0 // storageEmpty -> 0
// test_long() -> 67 // test_long() -> 67
// gas irOptimized: 89148 // gas irOptimized: 89148
// gas legacy: 105839 // gas legacy: 108639
// gas legacyOptimized: 103293 // gas legacyOptimized: 106093
// storageEmpty -> 0 // storageEmpty -> 0
// test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020 // test_pop() -> 1780731860627700044960722568376592200742329637303199754547598369979433020
// gas legacy: 61930 // gas legacy: 61930

View File

@ -24,5 +24,5 @@ contract c {
// ---- // ----
// test() -> 3, 4 // test() -> 3, 4
// gas irOptimized: 189690 // gas irOptimized: 189690
// gas legacy: 195353 // gas legacy: 215253
// gas legacyOptimized: 192441 // gas legacyOptimized: 212341

View File

@ -46,6 +46,6 @@ contract C {
} }
// ---- // ----
// f() -> 0xff // f() -> 0xff
// gas irOptimized: 119584 // gas irOptimized: 179284
// gas legacy: 132274 // gas legacy: 191974
// gas legacyOptimized: 123756 // gas legacyOptimized: 183456

View File

@ -15,3 +15,5 @@ contract C {
// ---- // ----
// f() -> 0, 0, 0 // f() -> 0, 0, 0
// gas irOptimized: 90992 // gas irOptimized: 90992
// gas legacy: 111037
// gas legacyOptimized: 109633

View File

@ -42,10 +42,10 @@ contract C {
} }
// ---- // ----
// f() -> // f() ->
// gas irOptimized: 121657 // gas irOptimized: 141557
// gas legacy: 122132 // gas legacy: 142032
// gas legacyOptimized: 121500 // gas legacyOptimized: 141400
// g() -> // g() ->
// gas irOptimized: 145472 // gas irOptimized: 148272
// gas legacy: 145707 // gas legacy: 148507
// gas legacyOptimized: 144940 // gas legacyOptimized: 147740

View File

@ -52,18 +52,18 @@ contract C {
// ---- // ----
// test_zeroed_indicies(uint256): 1 -> // test_zeroed_indicies(uint256): 1 ->
// test_zeroed_indicies(uint256): 5 -> // test_zeroed_indicies(uint256): 5 ->
// gas irOptimized: 153874 // gas irOptimized: 165074
// gas legacy: 155001 // gas legacy: 166201
// gas legacyOptimized: 152239 // gas legacyOptimized: 163439
// test_zeroed_indicies(uint256): 10 -> // test_zeroed_indicies(uint256): 10 ->
// gas irOptimized: 277077 // gas irOptimized: 282677
// gas legacy: 279488 // gas legacy: 285088
// gas legacyOptimized: 274412 // gas legacyOptimized: 280012
// test_zeroed_indicies(uint256): 15 -> // test_zeroed_indicies(uint256): 15 ->
// gas irOptimized: 399822 // gas irOptimized: 405422
// gas legacy: 403538 // gas legacy: 409138
// gas legacyOptimized: 396227 // gas legacyOptimized: 401827
// test_zeroed_indicies(uint256): 0xFF -> // test_zeroed_indicies(uint256): 0xFF ->
// gas irOptimized: 6399212 // gas irOptimized: 6404812
// gas legacy: 6460633 // gas legacy: 6466233
// gas legacyOptimized: 6327477 // gas legacyOptimized: 6333077