Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

Commit

Permalink
Implement SSTORE net gas metering in aleth-interpreter
Browse files Browse the repository at this point in the history
  • Loading branch information
gumb0 committed Sep 3, 2018
1 parent fdbb63a commit e14077b
Show file tree
Hide file tree
Showing 5 changed files with 142 additions and 23 deletions.
2 changes: 1 addition & 1 deletion evmc
Submodule evmc updated 1 files
+7 −2 include/evmc/evmc.h
21 changes: 9 additions & 12 deletions libaleth-interpreter/VM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1356,22 +1356,19 @@ void VM::interpretCases()
if (m_message->flags & EVMC_STATIC)
throwDisallowedStateChange();

static_assert(
VMSchedule::sstoreResetGas <= VMSchedule::sstoreSetGas, "Wrong SSTORE gas costs");
m_runGas = VMSchedule::sstoreResetGas; // Charge the modification cost up front.
updateIOGas();

evmc_uint256be key = toEvmC(m_SP[0]);
evmc_uint256be value = toEvmC(m_SP[1]);
evmc_uint256be const key = toEvmC(m_SP[0]);
evmc_uint256be const value = toEvmC(m_SP[1]);
auto status =
m_context->fn_table->set_storage(m_context, &m_message->destination, &key, &value);

if (status == EVMC_STORAGE_ADDED)
{
// Charge additional amount for added storage item.
m_runGas = VMSchedule::sstoreSetGas - VMSchedule::sstoreResetGas;
updateIOGas();
}
m_runGas = VMSchedule::sstoreSetGas;
else if (status == EVMC_STORAGE_MODIFIED || status == EVMC_STORAGE_DELETED)
m_runGas = VMSchedule::sstoreResetGas;
else
m_runGas = VMSchedule::sstoreUnchangedGas;

updateIOGas();
}
NEXT

Expand Down
1 change: 1 addition & 0 deletions libaleth-interpreter/VM.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ struct VMSchedule
static constexpr int64_t sloadGas = 50;
static constexpr int64_t sstoreSetGas = 20000;
static constexpr int64_t sstoreResetGas = 5000;
static constexpr int64_t sstoreUnchangedGas = 200;
static constexpr int64_t jumpdestGas = 1;
static constexpr int64_t logGas = 375;
static constexpr int64_t logDataGas = 8;
Expand Down
46 changes: 36 additions & 10 deletions libevm/ExtVMFace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,23 +58,49 @@ evmc_storage_status setStorage(evmc_context* _context, evmc_address const* _addr
(void)_addr;
auto& env = static_cast<ExtVMFace&>(*_context);
assert(fromEvmC(*_addr) == env.myAddress);
u256 index = fromEvmC(*_key);
u256 value = fromEvmC(*_value);
u256 oldValue = env.store(index);
u256 const index = fromEvmC(*_key);
u256 const newValue = fromEvmC(*_value);
u256 const currentValue = env.store(index);

if (value == oldValue)
if (newValue == currentValue)
return EVMC_STORAGE_UNCHANGED;

EVMSchedule const& schedule = env.evmSchedule();
auto status = EVMC_STORAGE_MODIFIED;
if (oldValue == 0)
status = EVMC_STORAGE_ADDED;
else if (value == 0)
u256 const originalValue = env.originalStorageValue(index);
if (originalValue == currentValue || !schedule.eip1283Mode)
{
status = EVMC_STORAGE_DELETED;
env.sub.refunds += env.evmSchedule().sstoreRefundGas;
if (currentValue == 0)
status = EVMC_STORAGE_ADDED;
else if (newValue == 0)
{
status = EVMC_STORAGE_DELETED;
env.sub.refunds += schedule.sstoreRefundGas;
}
}
else
{
status = EVMC_STORAGE_MODIFIED_DIRTY;
if (originalValue == 0)
{
if (currentValue == 0)
{
assert(env.sub.refunds >= schedule.sstoreRefundGas);
env.sub.refunds -= schedule.sstoreRefundGas;
}
else
env.sub.refunds += schedule.sstoreRefundGas;
}
if (originalValue == newValue)
{
if (originalValue == 0)
env.sub.refunds += schedule.sstoreRefundGas + schedule.sstoreRefundNonzeroGas;
else
env.sub.refunds += schedule.sstoreRefundNonzeroGas;
}
}

env.setStore(index, value); // Interface uses native endianness
env.setStore(index, newValue); // Interface uses native endianness

return status;
}
Expand Down
95 changes: 95 additions & 0 deletions test/unittests/libevm/VMTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,12 @@ class LegacyVMSstoreTestFixture : public SstoreTestFixture
LegacyVMSstoreTestFixture() : SstoreTestFixture{new LegacyVM} {}
};

class AlethInterpreterSstoreTestFixture : public SstoreTestFixture
{
public:
AlethInterpreterSstoreTestFixture() : SstoreTestFixture{new EVMC{evmc_create_interpreter()}} {}
};

} // namespace

BOOST_FIXTURE_TEST_SUITE(LegacyVMSuite, TestOutputHelperFixture)
Expand Down Expand Up @@ -638,4 +644,93 @@ BOOST_AUTO_TEST_CASE(AlethInterpreterExtCodeHashIgnoresHigh12Bytes)

BOOST_AUTO_TEST_SUITE_END()

BOOST_FIXTURE_TEST_SUITE(AlethInterpreterSstoreSuite, AlethInterpreterSstoreTestFixture)

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case1)
{
testEip1283Case1();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case2)
{
testEip1283Case2();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case3)
{
testEip1283Case3();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case4)
{
testEip1283Case4();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case5)
{
testEip1283Case5();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case6)
{
testEip1283Case6();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case7)
{
testEip1283Case7();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case8)
{
testEip1283Case8();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case9)
{
testEip1283Case9();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case10)
{
testEip1283Case10();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case11)
{
testEip1283Case11();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case12)
{
testEip1283Case12();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case13)
{
testEip1283Case13();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case14)
{
testEip1283Case14();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case15)
{
testEip1283Case15();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case16)
{
testEip1283Case16();
}

BOOST_AUTO_TEST_CASE(AlethInterpreterSstoreEip1283Case17)
{
testEip1283Case17();
}

BOOST_AUTO_TEST_SUITE_END()

BOOST_AUTO_TEST_SUITE_END()

0 comments on commit e14077b

Please sign in to comment.