Skip to content

Commit

Permalink
Merge pull request #194 from eosnetworkfoundation/elmato/store-overhe…
Browse files Browse the repository at this point in the history
…ad-storage-price

Add support for storing overhead/storage price in block extra data
  • Loading branch information
elmato committed Aug 16, 2024
2 parents 89e5a25 + 99b2ab4 commit 99edb9b
Show file tree
Hide file tree
Showing 9 changed files with 170 additions and 4 deletions.
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

0 comments on commit 99edb9b

Please sign in to comment.