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

Commit

Permalink
Merge pull request #5238 from ethereum/net-sstore-interpreter
Browse files Browse the repository at this point in the history
Implement SSTORE net gas metering in aleth-interpreter
  • Loading branch information
chfast authored Sep 5, 2018
2 parents 058ca6d + 02746a1 commit ebae1d7
Show file tree
Hide file tree
Showing 6 changed files with 200 additions and 79 deletions.
60 changes: 30 additions & 30 deletions libaleth-interpreter/VM.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -245,10 +245,7 @@ void VM::fetchInstruction()
evmc_tx_context const& VM::getTxContext()
{
if (!m_tx_context)
{
m_tx_context.emplace();
m_context->fn_table->get_tx_context(&m_tx_context.value(), m_context);
}
m_tx_context.emplace(m_context->host->get_tx_context(m_context));
return m_tx_context.value();
}

Expand Down Expand Up @@ -370,20 +367,20 @@ void VM::interpretCases()

// After EIP158 zero-value suicides do not have to pay account creation gas.
evmc_uint256be rawBalance;
m_context->fn_table->get_balance(&rawBalance, m_context, &m_message->destination);
m_context->host->get_balance(&rawBalance, m_context, &m_message->destination);
u256 balance = fromEvmC(rawBalance);
if (balance > 0 || m_rev < EVMC_SPURIOUS_DRAGON)
{
// After EIP150 hard fork charge additional cost of sending
// ethers to non-existing account.
int destinationExists =
m_context->fn_table->account_exists(m_context, &destination);
m_context->host->account_exists(m_context, &destination);
if (m_rev >= EVMC_TANGERINE_WHISTLE && !destinationExists)
m_runGas += VMSchedule::callNewAccount;
}

updateIOGas();
m_context->fn_table->selfdestruct(m_context, &m_message->destination, &destination);
m_context->host->selfdestruct(m_context, &m_message->destination, &destination);
m_bounce = nullptr;
}
BREAK
Expand Down Expand Up @@ -458,7 +455,7 @@ void VM::interpretCases()
uint8_t const* data = m_mem.data() + size_t(m_SP[0]);
size_t dataSize = size_t(m_SP[1]);

m_context->fn_table->emit_log(
m_context->host->emit_log(
m_context, &m_message->destination, data, dataSize, nullptr, 0);
}
NEXT
Expand All @@ -478,7 +475,7 @@ void VM::interpretCases()
evmc_uint256be topics[] = {toEvmC(m_SP[2])};
size_t numTopics = sizeof(topics) / sizeof(topics[0]);

m_context->fn_table->emit_log(
m_context->host->emit_log(
m_context, &m_message->destination, data, dataSize, topics, numTopics);
}
NEXT
Expand All @@ -498,7 +495,7 @@ void VM::interpretCases()
evmc_uint256be topics[] = {toEvmC(m_SP[2]), toEvmC(m_SP[3])};
size_t numTopics = sizeof(topics) / sizeof(topics[0]);

m_context->fn_table->emit_log(
m_context->host->emit_log(
m_context, &m_message->destination, data, dataSize, topics, numTopics);
}
NEXT
Expand All @@ -518,7 +515,7 @@ void VM::interpretCases()
evmc_uint256be topics[] = {toEvmC(m_SP[2]), toEvmC(m_SP[3]), toEvmC(m_SP[4])};
size_t numTopics = sizeof(topics) / sizeof(topics[0]);

m_context->fn_table->emit_log(
m_context->host->emit_log(
m_context, &m_message->destination, data, dataSize, topics, numTopics);
}
NEXT
Expand All @@ -539,7 +536,7 @@ void VM::interpretCases()
toEvmC(m_SP[2]), toEvmC(m_SP[3]), toEvmC(m_SP[4]), toEvmC(m_SP[5])};
size_t numTopics = sizeof(topics) / sizeof(topics[0]);

m_context->fn_table->emit_log(
m_context->host->emit_log(
m_context, &m_message->destination, data, dataSize, topics, numTopics);
}
NEXT
Expand Down Expand Up @@ -904,7 +901,7 @@ void VM::interpretCases()

evmc_address address = toEvmC(asAddress(m_SP[0]));
evmc_uint256be rawBalance;
m_context->fn_table->get_balance(&rawBalance, m_context, &address);
m_context->host->get_balance(&rawBalance, m_context, &address);
m_SPP[0] = fromEvmC(rawBalance);
}
NEXT
Expand Down Expand Up @@ -989,7 +986,7 @@ void VM::interpretCases()

evmc_address address = toEvmC(asAddress(m_SP[0]));

m_SPP[0] = m_context->fn_table->get_code_size(m_context, &address);
m_SPP[0] = m_context->host->get_code_size(m_context, &address);
}
NEXT

Expand Down Expand Up @@ -1033,7 +1030,7 @@ void VM::interpretCases()
evmc_address address = toEvmC(asAddress(m_SP[0]));

evmc_uint256be hash;
m_context->fn_table->get_code_hash(&hash, m_context, &address);
m_context->host->get_code_hash(&hash, m_context, &address);
m_SPP[0] = fromEvmC(hash);
}
NEXT
Expand Down Expand Up @@ -1066,7 +1063,7 @@ void VM::interpretCases()
m_SP[2] > codeOffsetMax ? codeOffsetMax : static_cast<size_t>(m_SP[2]);
size_t size = static_cast<size_t>(copyMemSize);

size_t numCopied = m_context->fn_table->copy_code(
size_t numCopied = m_context->host->copy_code(
m_context, &address, codeOffset, &m_mem[memoryOffset], size);

std::fill_n(&m_mem[memoryOffset + numCopied], size - numCopied, 0);
Expand Down Expand Up @@ -1095,7 +1092,7 @@ void VM::interpretCases()
if (number < blockNumber && number >= std::max(int64_t(256), blockNumber) - 256)
{
evmc_uint256be hash;
m_context->fn_table->get_block_hash(&hash, m_context, int64_t(number));
m_context->host->get_block_hash(&hash, m_context, int64_t(number));
m_SPP[0] = fromEvmC(hash);
}
else
Expand Down Expand Up @@ -1345,7 +1342,7 @@ void VM::interpretCases()

evmc_uint256be key = toEvmC(m_SP[0]);
evmc_uint256be value;
m_context->fn_table->get_storage(&value, m_context, &m_message->destination, &key);
m_context->host->get_storage(&value, m_context, &m_message->destination, &key);
m_SPP[0] = fromEvmC(value);
}
NEXT
Expand All @@ -1356,22 +1353,25 @@ 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]);
auto status =
m_context->fn_table->set_storage(m_context, &m_message->destination, &key, &value);
evmc_uint256be const key = toEvmC(m_SP[0]);
evmc_uint256be const value = toEvmC(m_SP[1]);
auto const status =
m_context->host->set_storage(m_context, &m_message->destination, &key, &value);

if (status == EVMC_STORAGE_ADDED)
m_runGas = VMSchedule::sstoreSetGas;
else if (status == EVMC_STORAGE_MODIFIED || status == EVMC_STORAGE_DELETED)
m_runGas = VMSchedule::sstoreResetGas;
else if (status == EVMC_STORAGE_UNCHANGED && m_rev < EVMC_CONSTANTINOPLE)
m_runGas = VMSchedule::sstoreResetGas;
else
{
// Charge additional amount for added storage item.
m_runGas = VMSchedule::sstoreSetGas - VMSchedule::sstoreResetGas;
updateIOGas();
assert(status == EVMC_STORAGE_UNCHANGED || status == EVMC_STORAGE_MODIFIED_DIRTY);
assert(m_rev >= EVMC_CONSTANTINOPLE);
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
12 changes: 5 additions & 7 deletions libaleth-interpreter/VMCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ void VM::caseCreate()
m_returnData.clear();

evmc_uint256be rawBalance;
m_context->fn_table->get_balance(&rawBalance, m_context, &m_message->destination);
m_context->host->get_balance(&rawBalance, m_context, &m_message->destination);
u256 balance = fromEvmC(rawBalance);
if (balance >= endowment && m_message->depth < 1024)
{
Expand All @@ -146,8 +146,7 @@ void VM::caseCreate()
msg.kind = m_OP == Instruction::CREATE ? EVMC_CREATE : EVMC_CREATE2; // FIXME: In EVMC move the kind to the top.
msg.value = toEvmC(endowment);

evmc_result result;
m_context->fn_table->call(&result, m_context, &msg);
evmc_result result = m_context->host->call(m_context, &msg);

if (result.status_code == EVMC_SUCCESS)
m_SPP[0] = fromAddress(fromEvmC(result.create_address));
Expand Down Expand Up @@ -177,8 +176,7 @@ void VM::caseCall()
bytesRef output;
if (caseCallSetup(msg, output))
{
evmc_result result;
m_context->fn_table->call(&result, m_context, &msg);
evmc_result result = m_context->host->call(m_context, &msg);

m_returnData.assign(result.output_data, result.output_data + result.output_size);
bytesConstRef{&m_returnData}.copyTo(output);
Expand Down Expand Up @@ -222,7 +220,7 @@ bool VM::caseCallSetup(evmc_message& o_msg, bytesRef& o_output)
bool const haveValueArg = m_OP == Instruction::CALL || m_OP == Instruction::CALLCODE;

evmc_address destination = toEvmC(asAddress(m_SP[1]));
int destinationExists = m_context->fn_table->account_exists(m_context, &destination);
int destinationExists = m_context->host->account_exists(m_context, &destination);

if (m_OP == Instruction::CALL && !destinationExists)
{
Expand Down Expand Up @@ -273,7 +271,7 @@ bool VM::caseCallSetup(evmc_message& o_msg, bytesRef& o_output)
o_msg.gas += VMSchedule::callStipend;
{
evmc_uint256be rawBalance;
m_context->fn_table->get_balance(&rawBalance, m_context, &m_message->destination);
m_context->host->get_balance(&rawBalance, m_context, &m_message->destination);
u256 balance = fromEvmC(rawBalance);
balanceOk = balance >= value;
}
Expand Down
Loading

0 comments on commit ebae1d7

Please sign in to comment.