Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into elmato/implement-eo…
Browse files Browse the repository at this point in the history
…s-evm-gas-fee
  • Loading branch information
elmato committed Mar 1, 2024
2 parents 6f2bc51 + aaf7858 commit 8381cf6
Show file tree
Hide file tree
Showing 19 changed files with 355 additions and 6 deletions.
9 changes: 6 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,16 @@ if(NOT SILKWORM_HAS_PARENT)
CACHE FILEPATH "" FORCE
)
endif()

include(cmake/conan.cmake)

endif()

project(silkworm)
set(PROJECT_VERSION 0.1.0-dev)

# conan must be initiailzed after project definition to properly detect target architecture.
if(NOT SILKWORM_HAS_PARENT)
include(cmake/conan.cmake)
endif()

include(CableBuildInfo)

string(REGEX MATCH "([0-9]+)\\.([0-9]+)\\.([0-9]+)" _ ${PROJECT_VERSION})
Expand Down Expand Up @@ -92,6 +94,7 @@ endif()

# Silkworm itself
add_subdirectory(silkworm)
add_subdirectory(eosevm)

if(NOT SILKWORM_HAS_PARENT)
add_subdirectory(cmd)
Expand Down
6 changes: 5 additions & 1 deletion cmake/conan.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@

function(guess_conan_profile)
if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
set(PROFILE linux_gcc_11_release)
if(CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "aarch64")
set(PROFILE linux_arm_gcc_11_release)
else()
set(PROFILE linux_gcc_11_release)
endif()
elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
if(CMAKE_OSX_ARCHITECTURES STREQUAL "arm64")
set(PROFILE macos_arm_clang_13_release)
Expand Down
12 changes: 12 additions & 0 deletions cmake/profiles/linux_arm_gcc_11_debug
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[settings]
os=Linux
os_build=Linux
arch=armv8
arch_build=armv8
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
build_type=Debug
[options]
[build_requires]
[env]
12 changes: 12 additions & 0 deletions cmake/profiles/linux_arm_gcc_11_release
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[settings]
os=Linux
os_build=Linux
arch=armv8
arch_build=armv8
compiler=gcc
compiler.version=11
compiler.libcxx=libstdc++11
build_type=Release
[options]
[build_requires]
[env]
37 changes: 37 additions & 0 deletions eosevm/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

find_package(Microsoft.GSL REQUIRED)
find_package(nlohmann_json REQUIRED)
find_package(tl-expected REQUIRED)

if(MSVC)
add_compile_options(/EHsc)
else()
add_compile_options(-fno-exceptions)
endif()

file(
GLOB_RECURSE
EOS_EVM_SRC
CONFIGURE_DEPENDS
"*.cpp"
"*.hpp"
"*.c"
"*.h"
)
list(FILTER EOS_EVM_SRC EXCLUDE REGEX "_test\\.cpp$")
list(FILTER EOS_EVM_SRC EXCLUDE REGEX "_benchmark\\.cpp$")

add_library(eos_evm ${EOS_EVM_SRC})
target_include_directories(eos_evm PUBLIC ${SILKWORM_MAIN_DIR})

set(EOS_EVM_PUBLIC_LIBS
intx::intx
evmc
tl::expected
nlohmann_json::nlohmann_json
)

target_link_libraries(
eos_evm
PUBLIC ${EOS_EVM_PUBLIC_LIBS}
)
78 changes: 78 additions & 0 deletions eosevm/consensus_parameters.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "consensus_parameters.hpp"

#if not defined(ANTELOPE)
#include <silkworm/core/common/assert.hpp>
#include <silkworm/core/common/endian.hpp>
#endif

namespace eosevm {
bool operator==(const eosevm::GasFeeParameters& a, const eosevm::GasFeeParameters& b) {
return a.gas_codedeposit == b.gas_codedeposit && a.gas_newaccount == b.gas_newaccount &&
a.gas_sset == b.gas_sset && a.gas_txcreate == b.gas_txcreate && a.gas_txnewaccount == b.gas_txnewaccount;
}

bool operator==(const eosevm::ConsensusParameters& a, const eosevm::ConsensusParameters& b) {
return a.min_gas_price == b.min_gas_price && a.gas_fee_parameters == b.gas_fee_parameters; }


#if not defined(ANTELOPE)
[[nodiscard]] silkworm::Bytes GasFeeParameters::encode() const noexcept {
silkworm::Bytes ret(40, '\0');
silkworm::endian::store_big_u64(&ret[0], gas_txnewaccount);
silkworm::endian::store_big_u64(&ret[8], gas_newaccount);
silkworm::endian::store_big_u64(&ret[16], gas_txcreate);
silkworm::endian::store_big_u64(&ret[24], gas_codedeposit);
silkworm::endian::store_big_u64(&ret[32], gas_sset);

return ret;
}

std::optional<GasFeeParameters> GasFeeParameters::decode(silkworm::ByteView encoded) noexcept {
SILKWORM_ASSERT(encoded.length() >= 40);
GasFeeParameters feeParams;
feeParams.gas_txnewaccount = silkworm::endian::load_big_u64(&encoded[0]);
feeParams.gas_newaccount = silkworm::endian::load_big_u64(&encoded[8]);
feeParams.gas_txcreate = silkworm::endian::load_big_u64(&encoded[16]);
feeParams.gas_codedeposit = silkworm::endian::load_big_u64(&encoded[24]);
feeParams.gas_sset = silkworm::endian::load_big_u64(&encoded[32]);

return feeParams;
}
#endif

#if not defined(ANTELOPE)
[[nodiscard]] silkworm::Bytes ConsensusParameters::encode() const noexcept {
SILKWORM_ASSERT(min_gas_price.has_value());
SILKWORM_ASSERT(gas_fee_parameters.has_value());
constexpr size_t size_before_fee_param = 2 * sizeof(uint64_t);
auto value = gas_fee_parameters->encode();
silkworm::Bytes ret(value.length() + size_before_fee_param, '\0');
// Always store as latest supported version: currently 0.
silkworm::endian::store_big_u64(&ret[0], 0);
silkworm::endian::store_big_u64(&ret[sizeof(uint64_t)], *min_gas_price);
std::memcpy(&ret[size_before_fee_param], &value[0], value.length());
return ret;
};

std::optional<ConsensusParameters> ConsensusParameters::decode(silkworm::ByteView encoded) noexcept {
SILKWORM_ASSERT(encoded.length() > sizeof(uint64_t));
ConsensusParameters config{};
const auto version = silkworm::endian::load_big_u64(&encoded[0]);

// Parse according to version. For now, only 0.
switch (version) {
case 0: {
constexpr size_t size_before_fee_param = 2 * sizeof(uint64_t);
SILKWORM_ASSERT(encoded.length() > size_before_fee_param);
config.min_gas_price = silkworm::endian::load_big_u64(&encoded[sizeof(uint64_t)]);
config.gas_fee_parameters = GasFeeParameters::decode(silkworm::ByteView{&encoded[size_before_fee_param], encoded.length() - size_before_fee_param});
break;
}
default: SILKWORM_ASSERT(version <= 0);
}

return config;
}
#endif

} // namespace eosevm
57 changes: 57 additions & 0 deletions eosevm/consensus_parameters.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#pragma once

#include <cstdint>
#include <optional>
#include <string>

#include <intx/intx.hpp>


#if not defined(ANTELOPE)
#include <silkworm/core/common/base.hpp>
#endif


namespace eosevm {

// Note: GasFeeParameters struct is NOT versioned, version will be handled by ConsensusParameters.
// If we want to change this struct, create GasFeeParametersV2 and let ConsensusParameters use it.
struct GasFeeParameters {
// gas_txnewaccount = account_bytes * gas_per_byte
uint64_t gas_txnewaccount;
// gas_newaccount = account_bytes * gas_per_byte
uint64_t gas_newaccount;
// gas_txcreate = gas_create = contract_fixed_bytes * gas_per_byte
uint64_t gas_txcreate;
// gas_codedeposit = gas_per_byte
uint64_t gas_codedeposit;
// gas_sset = 100 + storage_slot_bytes * gas_per_byte
uint64_t gas_sset;

#if not defined(ANTELOPE)
// Encode for storage in db.
[[nodiscard]] silkworm::Bytes encode() const noexcept;

// Decode from storage in db.
static std::optional<GasFeeParameters> decode(silkworm::ByteView encoded) noexcept;
#endif

friend bool operator==(const GasFeeParameters&, const GasFeeParameters&);
};

struct ConsensusParameters {
std::optional<uint64_t> min_gas_price;
std::optional<GasFeeParameters> gas_fee_parameters;

#if not defined(ANTELOPE)
// Encode for storage in db.
[[nodiscard]] silkworm::Bytes encode() const noexcept;

// Decode from storage in db.
static std::optional<ConsensusParameters> decode(silkworm::ByteView encoded) noexcept;
#endif

friend bool operator==(const ConsensusParameters&, const ConsensusParameters&);
};

} // namespace eosevm
29 changes: 28 additions & 1 deletion silkworm/core/types/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ bool operator==(const BlockHeader& a, const BlockHeader& b) {
}

bool operator==(const BlockBody& a, const BlockBody& b) {
return a.transactions == b.transactions && a.ommers == b.ommers;
return a.transactions == b.transactions && a.ommers == b.ommers && a.consensus_parameter_index == b.consensus_parameter_index;
}

BlockNum height(const BlockId& b) { return b.number; }
Expand Down Expand Up @@ -241,6 +241,9 @@ namespace rlp {
Header rlp_head{.list = true};
rlp_head.payload_length += length(b.transactions);
rlp_head.payload_length += length(b.ommers);
if (b.consensus_parameter_index) {
rlp_head.payload_length += length(*b.consensus_parameter_index);
}
if (b.withdrawals) {
rlp_head.payload_length += length(*b.withdrawals);
}
Expand All @@ -256,6 +259,9 @@ namespace rlp {
encode_header(to, rlp_header_body(block_body));
encode(to, block_body.transactions);
encode(to, block_body.ommers);
if (block_body.consensus_parameter_index) {
encode(to, *block_body.consensus_parameter_index);
}
if (block_body.withdrawals) {
encode(to, *block_body.withdrawals);
}
Expand All @@ -278,6 +284,15 @@ namespace rlp {
return res;
}

to.consensus_parameter_index = std::nullopt;
if (from.length() > leftover) {
uint64_t consensus_parameter_index;
if (DecodingResult res{decode(from, consensus_parameter_index, Leftover::kAllow)}; !res) {
return res;
}
to.consensus_parameter_index = consensus_parameter_index;
}

to.withdrawals = std::nullopt;
if (from.length() > leftover) {
std::vector<Withdrawal> withdrawals;
Expand Down Expand Up @@ -310,6 +325,15 @@ namespace rlp {
return res;
}

to.consensus_parameter_index = std::nullopt;
if (from.length() > leftover) {
uint64_t consensus_parameter_index;
if (DecodingResult res{decode(from, consensus_parameter_index, Leftover::kAllow)}; !res) {
return res;
}
to.consensus_parameter_index = consensus_parameter_index;
}

to.withdrawals = std::nullopt;
if (from.length() > leftover) {
std::vector<Withdrawal> withdrawals;
Expand Down Expand Up @@ -341,6 +365,9 @@ namespace rlp {
encode(to, block.header);
encode(to, block.transactions);
encode(to, block.ommers);
if (block.consensus_parameter_index) {
encode(to, *block.consensus_parameter_index);
}
if (block.withdrawals) {
encode(to, *block.withdrawals);
}
Expand Down
6 changes: 6 additions & 0 deletions silkworm/core/types/block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#include <silkworm/core/types/transaction.hpp>
#include <silkworm/core/types/withdrawal.hpp>

#include <eosevm/consensus_parameters.hpp>

namespace silkworm {

using TotalDifficulty = intx::uint256;
Expand Down Expand Up @@ -94,13 +96,17 @@ struct BlockBody {
std::vector<BlockHeader> ommers;
std::optional<std::vector<Withdrawal>> withdrawals{std::nullopt};

// EOS-EVM
std::optional<uint64_t> consensus_parameter_index{std::nullopt};

friend bool operator==(const BlockBody&, const BlockBody&);
};

struct Block : public BlockBody {
BlockHeader header;

bool irreversible{false};
std::optional<eosevm::ConsensusParameters> consensus_parameters_cache;
void recover_senders();
};

Expand Down
2 changes: 2 additions & 0 deletions silkworm/core/types/block_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ TEST_CASE("BlockBody RLP 2") {
body.ommers[0].prev_randao = 0xf0a53dfdd6c2f2a661e718ef29092de60d81d45f84044bec7bf4b36630b2bc08_bytes32;
body.ommers[0].nonce[7] = 35;

body.consensus_parameter_index = 1234;

Bytes rlp{};
rlp::encode(rlp, body);

Expand Down
1 change: 1 addition & 0 deletions silkworm/node/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ endif()
target_include_directories(silkworm_node PUBLIC "${SILKWORM_MAIN_DIR}")

set(SILKWORM_NODE_PUBLIC_LIBS
eos_evm
silkworm_core
silkworm_infra
silkworm_sentry
Expand Down
20 changes: 20 additions & 0 deletions silkworm/node/db/access_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,7 @@ bool read_body(ROTxn& txn, const Bytes& key, bool read_senders, BlockBody& out)
if (!out.transactions.empty() && read_senders) {
parse_senders(txn, key, out.transactions);
}
out.consensus_parameter_index = body.consensus_parameter_index;
return true;
}

Expand Down Expand Up @@ -498,6 +499,7 @@ void write_body(RWTxn& txn, const BlockBody& body, const uint8_t (&hash)[kHashLe
body_for_storage.txn_count = body.transactions.size();
body_for_storage.base_txn_id =
increment_map_sequence(txn, table::kBlockTransactions.name, body_for_storage.txn_count);
body_for_storage.consensus_parameter_index = body.consensus_parameter_index;
Bytes value{body_for_storage.encode()};
auto key{db::block_key(number, hash)};

Expand Down Expand Up @@ -1217,4 +1219,22 @@ void write_runtime_states_u64(RWTxn& txn, uint64_t num, RuntimeState runtime_sta
write_runtime_states_bytes(txn, value, runtime_state);
}

std::optional<eosevm::ConsensusParameters> read_consensus_parameters(ROTxn& txn, BlockNum index) {
auto cursor = txn.ro_cursor(table::kConsensusParameters);
auto key{db::block_key(index)};
auto data{cursor->find(to_slice(key), /*throw_notfound=*/false)};
if (!data) {
return std::nullopt;
}
const auto encoded = from_slice(data.value);
return eosevm::ConsensusParameters::decode(encoded);
}

void update_consensus_parameters(RWTxn& txn, BlockNum index, const eosevm::ConsensusParameters& config) {
auto cursor = txn.rw_cursor(table::kConsensusParameters);
auto key{db::block_key(index)};

cursor->upsert(to_slice(key), mdbx::slice(config.encode()));
}

} // namespace silkworm::db
Loading

0 comments on commit 8381cf6

Please sign in to comment.