Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EIP-2929 consensus tests #298

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
[submodule "evmc"]
path = evmc
url = https://github.com/ethereum/evmc
url = https://github.com/torquem-ch/evmc
branch = eip-2929
38 changes: 5 additions & 33 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ commands:
steps:
- restore_cache:
name: "Restore Silkworm cache"
key: &silkworm-cache-key silkworm-v1
key: &silkworm-cache-key silkworm-20210407
- run:
name: "Check Silkworm cache"
command: |
Expand All @@ -38,11 +38,11 @@ commands:
working_directory: ~/silkworm/src
command: |
[ "$SILKWORM_BUILD" = true ] || exit 0
git clone --no-checkout --single-branch https://github.com/torquem-ch/silkworm.git .
git checkout 614fabfcf19b8e06f0dcbe3e9af2345dcf748f3e
git clone --no-checkout --single-branch --branch eip2929_update https://github.com/torquem-ch/silkworm.git .
git checkout b083086cd4692b2a7f54af06644324a833fb4d3e
git submodule init
git submodule deinit tests
git submodule update --recursive --depth=1 --progress
git submodule update --init --recursive --depth=1 --progress
- run:
name: "Configure Silkworm"
working_directory: ~/silkworm
Expand Down Expand Up @@ -239,41 +239,16 @@ jobs:
ghr -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME -n "$name" $prerelease_flag $CIRCLE_TAG ~/package

consensus-tests:
environment:
TESTS_REV: v7.0.0
executor: linux-gcc-latest
steps:
- build_silkworm
- unpack_package
- download_consensus_tests:
rev: v7.0.0
rev: 8.0.2
- run:
name: "Silkworm-driven consensus tests"
command: ~/silkworm/consensus --evm ~/package/lib/libevmone.so --tests ~/tests

state-tests:
environment:
TESTS_REV: ac8cf2cd8ba326d67101183060272e7f7b1eaa92
ALETH_REV: 1.8.0
docker:
- image: cimg/base:stable
steps:
- unpack_package
- run:
name: "Download Aleth"
background: true
command: curl -L https://github.com/ethereum/aleth/releases/download/v$ALETH_REV/aleth-$ALETH_REV-linux-x86_64.tar.gz | tar xz
- download_consensus_tests:
rev: ac8cf2cd8ba326d67101183060272e7f7b1eaa92
- run:
name: "Fixup consensus tests"
command: |
mkdir -p ~/tests/GeneralStateTests/stEWASMTests
mkdir -p ~/tests/src/GeneralStateTestsFiller/stEWASMTests
- run:
name: "Run State Tests"
command: bin/testeth -t GeneralStateTests -- --testpath ~/tests --vm ~/package/lib/libevmone.so


gcc-min:
executor: linux-gcc-7
Expand Down Expand Up @@ -382,9 +357,6 @@ workflows:
- consensus-tests:
requires:
- release-linux
- state-tests:
requires:
- release-linux
- gcc-min
- gcc-latest-coverage
- clang-latest-ubsan
Expand Down
2 changes: 1 addition & 1 deletion evmc
Submodule evmc updated from 649c66 to 7a772a
37 changes: 32 additions & 5 deletions lib/evmone/baseline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,15 @@ evmc_result baseline_execute(ExecutionState& state) noexcept
address(state);
break;
case OP_BALANCE:
balance(state);
{
const auto status_code = balance(state);
if (status_code != EVMC_SUCCESS)
{
state.status = status_code;
goto exit;
}
break;
}
case OP_ORIGIN:
origin(state);
break;
Expand Down Expand Up @@ -270,8 +277,15 @@ evmc_result baseline_execute(ExecutionState& state) noexcept
gasprice(state);
break;
case OP_EXTCODESIZE:
extcodesize(state);
{
const auto status_code = extcodesize(state);
if (status_code != EVMC_SUCCESS)
{
state.status = status_code;
goto exit;
}
break;
}
case OP_EXTCODECOPY:
{
const auto status_code = extcodecopy(state);
Expand All @@ -296,9 +310,15 @@ evmc_result baseline_execute(ExecutionState& state) noexcept
break;
}
case OP_EXTCODEHASH:
extcodehash(state);
{
const auto status_code = extcodehash(state);
if (status_code != EVMC_SUCCESS)
{
state.status = status_code;
goto exit;
}
break;

}
case OP_BLOCKHASH:
blockhash(state);
break;
Expand Down Expand Up @@ -381,8 +401,15 @@ evmc_result baseline_execute(ExecutionState& state) noexcept
msize(state);
break;
case OP_SLOAD:
sload(state);
{
const auto status_code = sload(state);
if (status_code != EVMC_SUCCESS)
{
state.status = status_code;
goto exit;
}
break;
}
case OP_SSTORE:
{
const auto status_code = sstore(state);
Expand Down
18 changes: 17 additions & 1 deletion lib/evmone/instruction_traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -333,5 +333,21 @@ constexpr inline std::array<int16_t, 256> gas_costs<EVMC_ISTANBUL> = []() noexce
}();

template <>
constexpr inline auto gas_costs<EVMC_BERLIN> = gas_costs<EVMC_ISTANBUL>;
constexpr inline std::array<int16_t, 256> gas_costs<EVMC_BERLIN> = []() noexcept {
auto table = gas_costs<EVMC_ISTANBUL>;

// EIP-2929 WARM_STORAGE_READ_COST
table[OP_EXTCODESIZE] = 100;
table[OP_EXTCODECOPY] = 100;
table[OP_EXTCODEHASH] = 100;
table[OP_BALANCE] = 100;
table[OP_CALL] = 100;
table[OP_CALLCODE] = 100;
table[OP_DELEGATECALL] = 100;
table[OP_STATICCALL] = 100;
table[OP_SLOAD] = 100;

return table;
}();

} // namespace evmone::instr
2 changes: 1 addition & 1 deletion lib/evmone/instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ constexpr std::array<instruction_exec_fn, 256> instruction_implementations = [](
table[OP_SHL] = op<shl>;
table[OP_SHR] = op<shr>;
table[OP_SAR] = op<sar>;
table[OP_EXTCODEHASH] = op<extcodehash>;

table[OP_CREATE2] = op_create<EVMC_CREATE2>;

table[OP_CHAINID] = op<chainid>;
Expand Down
107 changes: 85 additions & 22 deletions lib/evmone/instructions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,10 +279,20 @@ inline void address(ExecutionState& state) noexcept
state.stack.push(intx::be::load<uint256>(state.msg->destination));
}

inline void balance(ExecutionState& state) noexcept
inline evmc_status_code balance(ExecutionState& state) noexcept
{
auto& x = state.stack.top();
x = intx::be::load<uint256>(state.host.get_balance(intx::be::trunc<evmc::address>(x)));
const auto addr = intx::be::trunc<evmc::address>(x);

if (state.rev >= EVMC_BERLIN && state.host.access_account(addr) == EVMC_ACCESS_COLD)
{
// EIP-2929: COLD_ACCOUNT_ACCESS_COST - WARM_STORAGE_READ_COST = 2500
if ((state.gas_left -= 2500) < 0)
return EVMC_OUT_OF_GAS;
}

x = intx::be::load<uint256>(state.host.get_balance(addr));
return EVMC_SUCCESS;
}

inline void origin(ExecutionState& state) noexcept
Expand Down Expand Up @@ -394,10 +404,21 @@ inline void gasprice(ExecutionState& state) noexcept
state.stack.push(intx::be::load<uint256>(state.host.get_tx_context().tx_gas_price));
}

inline void extcodesize(ExecutionState& state) noexcept
inline evmc_status_code extcodesize(ExecutionState& state) noexcept
{
auto& x = state.stack.top();
x = state.host.get_code_size(intx::be::trunc<evmc::address>(x));
const auto addr = intx::be::trunc<evmc::address>(x);

if (state.rev >= EVMC_BERLIN && state.host.access_account(addr) == EVMC_ACCESS_COLD)
{
// EIP-2929: COLD_ACCOUNT_ACCESS_COST - WARM_STORAGE_READ_COST = 2500
if ((state.gas_left -= 2500) < 0)
return EVMC_OUT_OF_GAS;
}

x = state.host.get_code_size(addr);

return EVMC_SUCCESS;
}

inline evmc_status_code extcodecopy(ExecutionState& state) noexcept
Expand All @@ -418,6 +439,13 @@ inline evmc_status_code extcodecopy(ExecutionState& state) noexcept
if ((state.gas_left -= copy_cost) < 0)
return EVMC_OUT_OF_GAS;

if (state.rev >= EVMC_BERLIN && state.host.access_account(addr) == EVMC_ACCESS_COLD)
{
// EIP-2929: COLD_ACCOUNT_ACCESS_COST - WARM_STORAGE_READ_COST = 2500
if ((state.gas_left -= 2500) < 0)
return EVMC_OUT_OF_GAS;
}

auto data = s != 0 ? &state.memory[dst] : nullptr;
auto num_bytes_copied = state.host.copy_code(addr, src, data, s);
if (s - num_bytes_copied > 0)
Expand Down Expand Up @@ -460,10 +488,20 @@ inline evmc_status_code returndatacopy(ExecutionState& state) noexcept
return EVMC_SUCCESS;
}

inline void extcodehash(ExecutionState& state) noexcept
inline evmc_status_code extcodehash(ExecutionState& state) noexcept
{
auto& x = state.stack.top();
x = intx::be::load<uint256>(state.host.get_code_hash(intx::be::trunc<evmc::address>(x)));
const auto addr = intx::be::trunc<evmc::address>(x);

if (state.rev >= EVMC_BERLIN && state.host.access_account(addr) == EVMC_ACCESS_COLD)
{
// EIP-2929: COLD_ACCOUNT_ACCESS_COST - WARM_STORAGE_READ_COST = 2500
if ((state.gas_left -= 2500) < 0)
return EVMC_OUT_OF_GAS;
}

x = intx::be::load<uint256>(state.host.get_code_hash(addr));
return EVMC_SUCCESS;
}


Expand Down Expand Up @@ -561,11 +599,22 @@ inline evmc_status_code mstore8(ExecutionState& state) noexcept
return EVMC_SUCCESS;
}

inline void sload(ExecutionState& state) noexcept
inline evmc_status_code sload(ExecutionState& state) noexcept
{
auto& x = state.stack.top();
x = intx::be::load<uint256>(
state.host.get_storage(state.msg->destination, intx::be::store<evmc::bytes32>(x)));
const auto key = intx::be::store<evmc::bytes32>(x);

if (state.rev >= EVMC_BERLIN &&
state.host.access_storage(state.msg->destination, key) == EVMC_ACCESS_COLD)
{
// EIP-2929: COLD_SLOAD_COST - WARM_STORAGE_READ_COST = 2000
if ((state.gas_left -= 2000) < 0)
return EVMC_OUT_OF_GAS;
}

x = intx::be::load<uint256>(state.host.get_storage(state.msg->destination, key));

return EVMC_SUCCESS;
}

inline evmc_status_code sstore(ExecutionState& state) noexcept
Expand All @@ -578,34 +627,41 @@ inline evmc_status_code sstore(ExecutionState& state) noexcept

const auto key = intx::be::store<evmc::bytes32>(state.stack.pop());
const auto value = intx::be::store<evmc::bytes32>(state.stack.pop());
const auto status = state.host.set_storage(state.msg->destination, key, value);

// EIP-2929
static constexpr int COLD_SLOAD_COST = 2100;
static constexpr int WARM_STORAGE_READ_COST = 100;
int cost = 0;
if (state.rev >= EVMC_BERLIN &&
state.host.access_storage(state.msg->destination, key) == EVMC_ACCESS_COLD)
{
cost = COLD_SLOAD_COST;
}

const auto status = state.host.set_storage(state.msg->destination, key, value);

switch (status)
{
case EVMC_STORAGE_UNCHANGED:
if (state.rev >= EVMC_ISTANBUL)
case EVMC_STORAGE_MODIFIED_AGAIN:
if (state.rev >= EVMC_BERLIN)
cost += WARM_STORAGE_READ_COST;
else if (state.rev == EVMC_ISTANBUL)
cost = 800;
else if (state.rev == EVMC_CONSTANTINOPLE)
cost = 200;
else
cost = 5000;
break;
case EVMC_STORAGE_MODIFIED:
cost = 5000;
break;
case EVMC_STORAGE_MODIFIED_AGAIN:
if (state.rev >= EVMC_ISTANBUL)
cost = 800;
else if (state.rev == EVMC_CONSTANTINOPLE)
cost = 200;
case EVMC_STORAGE_DELETED:
if (state.rev >= EVMC_BERLIN)
cost += 5000 - COLD_SLOAD_COST;
else
cost = 5000;
break;
case EVMC_STORAGE_ADDED:
cost = 20000;
break;
case EVMC_STORAGE_DELETED:
cost = 5000;
cost += 20000;
break;
}
if ((state.gas_left -= cost) < 0)
Expand Down Expand Up @@ -680,6 +736,13 @@ inline evmc_status_code selfdestruct(ExecutionState& state) noexcept

const auto beneficiary = intx::be::trunc<evmc::address>(state.stack[0]);

if (state.rev >= EVMC_BERLIN && state.host.access_account(beneficiary) == EVMC_ACCESS_COLD)
{
// EIP-2929: COLD_ACCOUNT_ACCESS_COST = 2600
if ((state.gas_left -= 2600) < 0)
return EVMC_OUT_OF_GAS;
}

if (state.rev >= EVMC_TANGERINE_WHISTLE)
{
if (state.rev == EVMC_TANGERINE_WHISTLE || state.host.get_balance(state.msg->destination))
Expand Down
7 changes: 7 additions & 0 deletions lib/evmone/instructions_calls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ evmc_status_code call(ExecutionState& state) noexcept

state.stack.push(0); // Assume failure.

if (state.rev >= EVMC_BERLIN && state.host.access_account(dst) == EVMC_ACCESS_COLD)
{
// EIP-2929: COLD_ACCOUNT_ACCESS_COST - WARM_STORAGE_READ_COST = 2500
if ((state.gas_left -= 2500) < 0)
return EVMC_OUT_OF_GAS;
}

if (!check_memory(state, input_offset, input_size))
return EVMC_OUT_OF_GAS;

Expand Down
Loading