Skip to content

Commit

Permalink
EIP-3541: Reject new contracts starting with the 0xEF byte (#247)
Browse files Browse the repository at this point in the history
* EIP-3541: Reject new contracts starting with the 0xEF byte

* Little more readability over std::optional  and reuse bool contract_creation

Co-authored-by: Andrea Lanfranchi <[email protected]>
  • Loading branch information
yperbasis and AndreaLanfranchi authored May 27, 2021
1 parent 5aa430a commit 80a6c22
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 18 deletions.
6 changes: 6 additions & 0 deletions core/silkworm/chain/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ std::optional<uint64_t> ChainConfig::revision_block(evmc_revision rev) const noe
return fork_blocks.at(i);
}

void ChainConfig::set_revision_block(evmc_revision rev, std::optional<uint64_t> block) {
if (rev > 0) { // Frontier block is always 0
fork_blocks[rev - 1] = block;
}
}

bool operator==(const ChainConfig& a, const ChainConfig& b) { return a.to_json() == b.to_json(); }

std::ostream& operator<<(std::ostream& out, const ChainConfig& obj) { return out << obj.to_json(); }
Expand Down
2 changes: 2 additions & 0 deletions core/silkworm/chain/config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ struct ChainConfig {
// it means the actual chain either does not support such revision
std::optional<uint64_t> revision_block(evmc_revision rev) const noexcept;

void set_revision_block(evmc_revision rev, std::optional<uint64_t> block);

nlohmann::json to_json() const noexcept;

/*Sample JSON input:
Expand Down
31 changes: 17 additions & 14 deletions core/silkworm/execution/evm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,18 +45,18 @@ EVM::~EVM() { evm1_->destroy(evm1_); }
CallResult EVM::execute(const Transaction& txn, uint64_t gas) noexcept {
txn_ = &txn;

bool contract_creation{!txn.to};
bool contract_creation{!txn.to.has_value()};

evmc_message message{
contract_creation ? EVMC_CREATE : EVMC_CALL, // kind
0, // flags
0, // depth
static_cast<int64_t>(gas), // gas
txn.to ? *txn.to : evmc::address{}, // destination
*txn.from, // sender
&txn.data[0], // input_data
txn.data.size(), // input_size
intx::be::store<evmc::uint256be>(txn.value), // value
contract_creation ? EVMC_CREATE : EVMC_CALL, // kind
0, // flags
0, // depth
static_cast<int64_t>(gas), // gas
contract_creation ? evmc::address{} : *txn.to, // destination
*txn.from, // sender
&txn.data[0], // input_data
txn.data.size(), // input_size
intx::be::store<evmc::uint256be>(txn.value), // value
};

evmc::result res{contract_creation ? create(message) : call(message)};
Expand Down Expand Up @@ -105,7 +105,7 @@ evmc::result EVM::create(const evmc_message& message) noexcept {
state_.subtract_from_balance(message.sender, value);
state_.add_to_balance(contract_addr, value);

evmc_message deploy_message{
const evmc_message deploy_message{
EVMC_CALL, // kind
0, // flags
message.depth, // depth
Expand All @@ -120,10 +120,13 @@ evmc::result EVM::create(const evmc_message& message) noexcept {
res = execute(deploy_message, ByteView{message.input_data, message.input_size}, /*code_hash=*/std::nullopt);

if (res.status_code == EVMC_SUCCESS) {
size_t code_len{res.output_size};
uint64_t code_deploy_gas{code_len * fee::kGCodeDeposit};
const size_t code_len{res.output_size};
const uint64_t code_deploy_gas{code_len * fee::kGCodeDeposit};

if (rev >= EVMC_SPURIOUS_DRAGON && code_len > param::kMaxCodeSize) {
if (rev >= EVMC_LONDON && code_len > 0 && res.output_data[0] == 0xEF) {
// https://eips.ethereum.org/EIPS/eip-3541
res.status_code = EVMC_CONTRACT_VALIDATION_FAILURE;
} else if (rev >= EVMC_SPURIOUS_DRAGON && code_len > param::kMaxCodeSize) {
// https://eips.ethereum.org/EIPS/eip-170
res.status_code = EVMC_OUT_OF_GAS;
} else if (res.gas_left >= 0 && static_cast<uint64_t>(res.gas_left) >= code_deploy_gas) {
Expand Down
33 changes: 32 additions & 1 deletion core/silkworm/execution/evm_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@

#include <catch2/catch.hpp>

#include <silkworm/common/util.hpp>
#include <silkworm/chain/protocol_param.hpp>
#include <silkworm/common/util.hpp>
#include <silkworm/state/memory_buffer.hpp>

#include "address.hpp"
Expand Down Expand Up @@ -328,4 +328,35 @@ TEST_CASE("Contract overwrite") {
CHECK(res.data == Bytes{});
}

TEST_CASE("EIP-3541: Reject new contracts starting with the 0xEF byte") {
ChainConfig config{kMainnetConfig};
config.set_revision_block(EVMC_LONDON, 13'000'000);

Block block;
block.header.number = 13'500'000;

MemoryBuffer db;
IntraBlockState state{db};
EVM evm{block, state, config};

Transaction txn;
const uint64_t gas{50'000};

// https://eips.ethereum.org/EIPS/eip-3541#test-cases
txn.data = *from_hex("0x60ef60005360016000f3");
CHECK(evm.execute(txn, gas).status == EVMC_CONTRACT_VALIDATION_FAILURE);

txn.data = *from_hex("0x60ef60005360026000f3");
CHECK(evm.execute(txn, gas).status == EVMC_CONTRACT_VALIDATION_FAILURE);

txn.data = *from_hex("0x60ef60005360036000f3");
CHECK(evm.execute(txn, gas).status == EVMC_CONTRACT_VALIDATION_FAILURE);

txn.data = *from_hex("0x60ef60005360206000f3");
CHECK(evm.execute(txn, gas).status == EVMC_CONTRACT_VALIDATION_FAILURE);

txn.data = *from_hex("0x60fe60005360016000f3");
CHECK(evm.execute(txn, gas).status == EVMC_SUCCESS);
}

} // namespace silkworm
4 changes: 1 addition & 3 deletions wasm/silkworm_wasm_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,9 +66,7 @@ ChainConfig* new_config(uint64_t chain_id) {
void delete_config(ChainConfig* x) { delete x; }

void config_set_fork_block(ChainConfig* config, evmc_revision fork, uint64_t block) {
if (fork > 0) { // Frontier block is always 0
config->fork_blocks[fork - 1] = block;
}
config->set_revision_block(fork, block);
}

void config_set_muir_glacier_block(ChainConfig* config, uint64_t block) { config->muir_glacier_block = block; }
Expand Down

0 comments on commit 80a6c22

Please sign in to comment.