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

Add support for storing overhead/storage price in block extra data #194

Merged
merged 1 commit into from
Aug 16, 2024
Merged
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
7 changes: 6 additions & 1 deletion eosevm/block_extra_data.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ using namespace silkworm;

namespace eosevm {
bool operator==(const eosevm::block_extra_data& a, const eosevm::block_extra_data& b) {
return a.consensus_parameter_index == b.consensus_parameter_index;
return a.consensus_parameter_index == b.consensus_parameter_index && a.gas_prices_index == b.gas_prices_index;
}
}

Expand Down Expand Up @@ -40,11 +40,16 @@ namespace silkworm { namespace rlp {
silkworm::Bytes encode(const eosevm::block_extra_data& out) {
silkworm::Bytes to;
encode(to, out.consensus_parameter_index);
encode(to, out.gas_prices_index);
return to;
}

DecodingResult decode(silkworm::ByteView& from, eosevm::block_extra_data& to) noexcept{
decode(from, to.consensus_parameter_index);
to.gas_prices_index.reset();
if(from.length() > 0) {
decode(from, to.gas_prices_index);
}
return {};
}
} } //namespace silkworm::rlp
1 change: 1 addition & 0 deletions eosevm/block_extra_data.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace eosevm {

struct block_extra_data {
std::optional<evmc::bytes32> consensus_parameter_index;
std::optional<evmc::bytes32> gas_prices_index;
};

} // namespace eosevm
Expand Down
38 changes: 38 additions & 0 deletions eosevm/gas_prices.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include "gas_prices.hpp"

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

namespace eosevm {

bool operator==(const eosevm::gas_prices& a, const eosevm::gas_prices& b) {
return a.overhead_price == b.overhead_price && a.storage_price == b.storage_price;
}

#if not defined(ANTELOPE)
[[nodiscard]] silkworm::Bytes gas_prices::encode() const noexcept {
silkworm::Bytes ret(16, '\0');
silkworm::endian::store_big_u64(&ret[0], overhead_price);
silkworm::endian::store_big_u64(&ret[8], storage_price);
return ret;
}

std::optional<gas_prices> gas_prices::decode(silkworm::ByteView encoded) noexcept {
SILKWORM_ASSERT(encoded.length() >= 16);
gas_prices prices;
prices.overhead_price= silkworm::endian::load_big_u64(&encoded[0]);
prices.storage_price = silkworm::endian::load_big_u64(&encoded[8]);
return prices;
}

[[nodiscard]] evmc::bytes32 gas_prices::hash() const noexcept {
auto encoded = this->encode();
evmc::bytes32 header_hash = std::bit_cast<evmc_bytes32>(silkworm::keccak256(encoded));
return header_hash;
}
#endif

} // namespace eosevm
30 changes: 30 additions & 0 deletions eosevm/gas_prices.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#pragma once
#include <algorithm>

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

namespace eosevm {

struct gas_prices {
uint64_t overhead_price;
uint64_t storage_price;

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

// Decode from storage in db.
static std::optional<gas_prices> decode(silkworm::ByteView encoded) noexcept;
evmc::bytes32 hash() const noexcept;
#endif

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

inline uint64_t calculate_base_fee_per_gas(uint64_t overhead_price, uint64_t storage_price) {
return std::max(overhead_price, storage_price);
}

} // namespace eosevm
14 changes: 14 additions & 0 deletions silkworm/core/types/block.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,20 @@ struct BlockBody {
return eosevm_extra_data.value().consensus_parameter_index;
}

bool has_gas_prices_index() {
return eosevm_extra_data.has_value() && eosevm_extra_data->gas_prices_index.has_value();
}

void set_gas_prices_index(const std::optional<evmc::bytes32>& index) {
if(!eosevm_extra_data.has_value()) eosevm_extra_data=eosevm::block_extra_data{};
eosevm_extra_data->gas_prices_index = index;
}

std::optional<evmc::bytes32> get_gas_prices_index() const {
if(!eosevm_extra_data.has_value()) return {};
return eosevm_extra_data.value().gas_prices_index;
}

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

Expand Down
29 changes: 27 additions & 2 deletions silkworm/node/db/access_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1265,13 +1265,38 @@ std::optional<eosevm::ConsensusParameters> read_consensus_parameters(ROTxn& txn,
return consensus_parameter;
}



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

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

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

std::optional<eosevm::gas_prices> read_gas_prices(ROTxn& txn, const Block& block) {
std::optional<eosevm::gas_prices> prices;
auto gpi = block.get_gas_prices_index();
if(gpi.has_value()) {
prices = read_gas_prices(txn, gpi.value());
}
return prices;
}

void update_gas_prices(RWTxn& txn, const evmc::bytes32& index, const eosevm::gas_prices& prices) {
auto cursor = txn.rw_cursor(table::kGasPrices);
auto key{db::block_key(index.bytes)};

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

} // namespace silkworm::db
6 changes: 6 additions & 0 deletions silkworm/node/db/access_layer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include <silkworm/node/snapshot/repository.hpp>

#include <eosevm/consensus_parameters.hpp>
#include <eosevm/gas_prices.hpp>

namespace silkworm::db {

Expand Down Expand Up @@ -262,6 +263,11 @@ std::optional<eosevm::ConsensusParameters> read_consensus_parameters(ROTxn& txn,
//! \brief Write ConsensusParameters indexed by blocknum that it is added. Can overwrite during forks.
void update_consensus_parameters(RWTxn& txn, const evmc::bytes32&, const eosevm::ConsensusParameters& config);

std::optional<eosevm::gas_prices> read_gas_prices(ROTxn& txn, const evmc::bytes32& index);
std::optional<eosevm::gas_prices> read_gas_prices(ROTxn& txn, const Block& block);
void update_gas_prices(RWTxn& txn, const evmc::bytes32&, const eosevm::gas_prices& prices);


class DataModel {
public:
static void set_snapshot_repository(snapshot::SnapshotRepository* repository);
Expand Down
43 changes: 43 additions & 0 deletions silkworm/node/db/access_layer_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -987,4 +987,47 @@ TEST_CASE("ConsensusParameters") {
CHECK(read_consensus_parameters(txn, value2.hash()) == value2);
}

TEST_CASE("gas_prices") {
test::Context context;
auto& txn{context.rw_txn()};

constexpr eosevm::gas_prices value1{
.overhead_price = 1,
.storage_price = 1
};

auto tmp = value1.encode();

ByteView bv{tmp};
REQUIRE_NOTHROW(eosevm::gas_prices::decode(bv));

constexpr eosevm::gas_prices value2{
.overhead_price = 2,
.storage_price = 2
};

CHECK(read_gas_prices(txn, evmc::bytes32(0)) == std::nullopt);

update_gas_prices(txn, evmc::bytes32(0), value1 );
CHECK(read_gas_prices(txn, evmc::bytes32(0)) == value1);

update_gas_prices(txn, evmc::bytes32(0), value2 );
CHECK(read_gas_prices(txn, evmc::bytes32(0)) == value2);

CHECK(read_gas_prices(txn, evmc::bytes32(1)) == std::nullopt);

update_gas_prices(txn, evmc::bytes32(1), value2 );
CHECK(read_gas_prices(txn, evmc::bytes32(1)) == value2);

update_gas_prices(txn, evmc::bytes32(1), value1 );
CHECK(read_gas_prices(txn, evmc::bytes32(1)) == value1);

update_gas_prices(txn, value1.hash(), value1 );
CHECK(read_gas_prices(txn, value1.hash()) == value1);

update_gas_prices(txn, value2.hash(), value2 );
CHECK(read_gas_prices(txn, value2.hash()) == value2);
}


} // namespace silkworm::db
6 changes: 5 additions & 1 deletion silkworm/node/db/tables.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,9 @@ inline constexpr db::MapConfig kRuntimeStates{kRuntimeStatesName};
inline constexpr const char* kConsensusParametersName{"ConsensusParameters"};
inline constexpr db::MapConfig kConsensusParameters{kConsensusParametersName};

inline constexpr const char* kGasPricesName{"GasPrices"};
inline constexpr db::MapConfig kGasPrices{kGasPricesName};

inline constexpr db::MapConfig kChainDataTables[]{
kAccountChangeSet,
kAccountHistory,
Expand Down Expand Up @@ -435,7 +438,8 @@ inline constexpr db::MapConfig kChainDataTables[]{
kTxLookup,
kRuntimeStates,
kConsensusParameters,
kExtraBlockData
kExtraBlockData,
kGasPrices
};

//! \brief Ensures all defined tables are present in db with consistent flags. Should a table not exist it gets created
Expand Down
Loading