Skip to content

Commit 08c97c8

Browse files
authored
Merge pull request #492 from ethereum/instructions_storage
Move storage instructions implementations to .cpp
2 parents cc6b692 + 5350ed2 commit 08c97c8

File tree

3 files changed

+103
-90
lines changed

3 files changed

+103
-90
lines changed

lib/evmone/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ add_library(evmone
2222
eof.hpp
2323
instructions.hpp
2424
instructions_calls.cpp
25+
instructions_storage.cpp
2526
instructions_traits.hpp
2627
instructions_xmacro.hpp
2728
opcodes_helpers.h

lib/evmone/instructions.hpp

+2-90
Original file line numberDiff line numberDiff line change
@@ -670,97 +670,9 @@ inline evmc_status_code mstore8(StackTop stack, ExecutionState& state) noexcept
670670
return EVMC_SUCCESS;
671671
}
672672

673-
inline evmc_status_code sload(StackTop stack, ExecutionState& state) noexcept
674-
{
675-
auto& x = stack.top();
676-
const auto key = intx::be::store<evmc::bytes32>(x);
677-
678-
if (state.rev >= EVMC_BERLIN &&
679-
state.host.access_storage(state.msg->recipient, key) == EVMC_ACCESS_COLD)
680-
{
681-
// The warm storage access cost is already applied (from the cost table).
682-
// Here we need to apply additional cold storage access cost.
683-
constexpr auto additional_cold_sload_cost =
684-
instr::cold_sload_cost - instr::warm_storage_read_cost;
685-
if ((state.gas_left -= additional_cold_sload_cost) < 0)
686-
return EVMC_OUT_OF_GAS;
687-
}
688-
689-
x = intx::be::load<uint256>(state.host.get_storage(state.msg->recipient, key));
690-
691-
return EVMC_SUCCESS;
692-
}
693-
694-
inline evmc_status_code sstore(StackTop stack, ExecutionState& state) noexcept
695-
{
696-
if (state.in_static_mode())
697-
return EVMC_STATIC_MODE_VIOLATION;
698-
699-
if (state.rev >= EVMC_ISTANBUL && state.gas_left <= 2300)
700-
return EVMC_OUT_OF_GAS;
673+
evmc_status_code sload(StackTop stack, ExecutionState& state) noexcept;
701674

702-
const auto key = intx::be::store<evmc::bytes32>(stack.pop());
703-
const auto value = intx::be::store<evmc::bytes32>(stack.pop());
704-
705-
int cost = 0;
706-
if (state.rev >= EVMC_BERLIN &&
707-
state.host.access_storage(state.msg->recipient, key) == EVMC_ACCESS_COLD)
708-
cost = instr::cold_sload_cost;
709-
710-
const auto status = state.host.set_storage(state.msg->recipient, key, value);
711-
712-
if (state.rev <= EVMC_BYZANTIUM || state.rev == EVMC_PETERSBURG) // legacy
713-
{
714-
switch (status)
715-
{
716-
case EVMC_STORAGE_ASSIGNED:
717-
case EVMC_STORAGE_MODIFIED_DELETED:
718-
case EVMC_STORAGE_ADDED_DELETED:
719-
case EVMC_STORAGE_MODIFIED_RESTORED:
720-
case EVMC_STORAGE_MODIFIED:
721-
case EVMC_STORAGE_DELETED:
722-
cost = 5000;
723-
break;
724-
case EVMC_STORAGE_ADDED:
725-
case EVMC_STORAGE_DELETED_ADDED:
726-
case EVMC_STORAGE_DELETED_RESTORED:
727-
cost = 20000;
728-
break;
729-
}
730-
}
731-
else // net gas cost metering
732-
{
733-
switch (status)
734-
{
735-
case EVMC_STORAGE_ASSIGNED:
736-
case EVMC_STORAGE_DELETED_ADDED:
737-
case EVMC_STORAGE_DELETED_RESTORED:
738-
case EVMC_STORAGE_MODIFIED_DELETED:
739-
case EVMC_STORAGE_ADDED_DELETED:
740-
case EVMC_STORAGE_MODIFIED_RESTORED:
741-
if (state.rev >= EVMC_BERLIN)
742-
cost += instr::warm_storage_read_cost;
743-
else if (state.rev == EVMC_ISTANBUL)
744-
cost = 800;
745-
else
746-
cost = 200; // Constantinople
747-
break;
748-
case EVMC_STORAGE_MODIFIED:
749-
case EVMC_STORAGE_DELETED:
750-
if (state.rev >= EVMC_BERLIN)
751-
cost += 5000 - instr::cold_sload_cost;
752-
else
753-
cost = 5000;
754-
break;
755-
case EVMC_STORAGE_ADDED:
756-
cost += 20000;
757-
break;
758-
}
759-
}
760-
if ((state.gas_left -= cost) < 0)
761-
return EVMC_OUT_OF_GAS;
762-
return EVMC_SUCCESS;
763-
}
675+
evmc_status_code sstore(StackTop stack, ExecutionState& state) noexcept;
764676

765677
/// Internal jump implementation for JUMP/JUMPI instructions.
766678
inline code_iterator jump_impl(ExecutionState& state, const uint256& dst) noexcept

lib/evmone/instructions_storage.cpp

+100
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
// evmone: Fast Ethereum Virtual Machine implementation
2+
// Copyright 2019 The evmone Authors.
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
#include "instructions.hpp"
6+
7+
namespace evmone::instr::core
8+
{
9+
evmc_status_code sload(StackTop stack, ExecutionState& state) noexcept
10+
{
11+
auto& x = stack.top();
12+
const auto key = intx::be::store<evmc::bytes32>(x);
13+
14+
if (state.rev >= EVMC_BERLIN &&
15+
state.host.access_storage(state.msg->recipient, key) == EVMC_ACCESS_COLD)
16+
{
17+
// The warm storage access cost is already applied (from the cost table).
18+
// Here we need to apply additional cold storage access cost.
19+
constexpr auto additional_cold_sload_cost =
20+
instr::cold_sload_cost - instr::warm_storage_read_cost;
21+
if ((state.gas_left -= additional_cold_sload_cost) < 0)
22+
return EVMC_OUT_OF_GAS;
23+
}
24+
25+
x = intx::be::load<uint256>(state.host.get_storage(state.msg->recipient, key));
26+
27+
return EVMC_SUCCESS;
28+
}
29+
30+
evmc_status_code sstore(StackTop stack, ExecutionState& state) noexcept
31+
{
32+
if (state.in_static_mode())
33+
return EVMC_STATIC_MODE_VIOLATION;
34+
35+
if (state.rev >= EVMC_ISTANBUL && state.gas_left <= 2300)
36+
return EVMC_OUT_OF_GAS;
37+
38+
const auto key = intx::be::store<evmc::bytes32>(stack.pop());
39+
const auto value = intx::be::store<evmc::bytes32>(stack.pop());
40+
41+
int cost = 0;
42+
if (state.rev >= EVMC_BERLIN &&
43+
state.host.access_storage(state.msg->recipient, key) == EVMC_ACCESS_COLD)
44+
cost = instr::cold_sload_cost;
45+
46+
const auto status = state.host.set_storage(state.msg->recipient, key, value);
47+
48+
if (state.rev <= EVMC_BYZANTIUM || state.rev == EVMC_PETERSBURG) // legacy
49+
{
50+
switch (status)
51+
{
52+
case EVMC_STORAGE_ASSIGNED:
53+
case EVMC_STORAGE_MODIFIED_DELETED:
54+
case EVMC_STORAGE_ADDED_DELETED:
55+
case EVMC_STORAGE_MODIFIED_RESTORED:
56+
case EVMC_STORAGE_MODIFIED:
57+
case EVMC_STORAGE_DELETED:
58+
cost = 5000;
59+
break;
60+
case EVMC_STORAGE_ADDED:
61+
case EVMC_STORAGE_DELETED_ADDED:
62+
case EVMC_STORAGE_DELETED_RESTORED:
63+
cost = 20000;
64+
break;
65+
}
66+
}
67+
else // net gas cost metering
68+
{
69+
switch (status)
70+
{
71+
case EVMC_STORAGE_ASSIGNED:
72+
case EVMC_STORAGE_DELETED_ADDED:
73+
case EVMC_STORAGE_DELETED_RESTORED:
74+
case EVMC_STORAGE_MODIFIED_DELETED:
75+
case EVMC_STORAGE_ADDED_DELETED:
76+
case EVMC_STORAGE_MODIFIED_RESTORED:
77+
if (state.rev >= EVMC_BERLIN)
78+
cost += instr::warm_storage_read_cost;
79+
else if (state.rev == EVMC_ISTANBUL)
80+
cost = 800;
81+
else
82+
cost = 200; // Constantinople
83+
break;
84+
case EVMC_STORAGE_MODIFIED:
85+
case EVMC_STORAGE_DELETED:
86+
if (state.rev >= EVMC_BERLIN)
87+
cost += 5000 - instr::cold_sload_cost;
88+
else
89+
cost = 5000;
90+
break;
91+
case EVMC_STORAGE_ADDED:
92+
cost += 20000;
93+
break;
94+
}
95+
}
96+
if ((state.gas_left -= cost) < 0)
97+
return EVMC_OUT_OF_GAS;
98+
return EVMC_SUCCESS;
99+
}
100+
} // namespace evmone::instr::core

0 commit comments

Comments
 (0)