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 storage and overhead price #750

Merged
merged 12 commits into from
Aug 8, 2024
Merged
10 changes: 7 additions & 3 deletions .github/workflows/contract.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ jobs:
with:
owner: AntelopeIO
repo: cdt
target: 'v3.1.0'
target: 'v4.0.1'
prereleases: false
file: 'cdt_.*amd64.deb'

- name: Install CDT
run: sudo apt-get install -y ./cdt*.deb
run: |
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y ./cdt*.deb

- name: Build EOS EVM Contract
run: .github/workflows/build-contract.sh
Expand All @@ -74,7 +76,9 @@ jobs:
artifact-name: leap-dev-ubuntu22-amd64

- name: Install Leap
run: sudo apt-get install -y ./leap*.deb
run: |
sudo apt-get update && sudo apt-get upgrade -y
sudo apt-get install -y ./leap*.deb

- name: Build EOS EVM Contract Tests
run: .github/workflows/build-contract-test.sh
Expand Down
13 changes: 11 additions & 2 deletions include/evm_runtime/config_wrapper.hpp
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#pragma once
#include <eosio/eosio.hpp>

#include <evm_runtime/tables.hpp>
#include <eosio/asset.hpp>
#include <eosio/time.hpp>
#include <eosio/singleton.hpp>
#include <evm_runtime/tables.hpp>
namespace evm_runtime {

struct fee_parameters;
Expand All @@ -27,10 +27,19 @@ struct config_wrapper {
const eosio::asset& get_ingress_bridge_fee()const;
void set_ingress_bridge_fee(const eosio::asset& ingress_bridge_fee);

gas_prices_type get_gas_prices()const;
void set_gas_prices(const gas_prices_type& price);

uint64_t get_gas_price()const;
void set_gas_price(uint64_t gas_price);

template <typename Q, typename Func>
void enqueue(Func&& update_fnc);
void enqueue_gas_price(uint64_t gas_price);
void enqueue_gas_prices(const gas_prices_type& prices);

template <typename Q, typename Func>
void process_queue(Func&& update_func);
void process_price_queue();

uint32_t get_miner_cut()const;
Expand Down
5 changes: 4 additions & 1 deletion include/evm_runtime/evm_contract.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include <eosio/eosio.hpp>
#include <eosio/asset.hpp>
#include <eosio/binary_extension.hpp>
#include <eosio/singleton.hpp>
Expand All @@ -18,6 +17,8 @@ using namespace eosio;

namespace evm_runtime {

struct gas_prices_type;

class [[eosio::contract]] evm_contract : public contract
{
public:
Expand Down Expand Up @@ -88,6 +89,8 @@ class [[eosio::contract]] evm_contract : public contract
[[eosio::action]] void updtgasparam(eosio::asset ram_price_mb, uint64_t gas_price);
[[eosio::action]] void setgasparam(uint64_t gas_txnewaccount, uint64_t gas_newaccount, uint64_t gas_txcreate, uint64_t gas_codedeposit, uint64_t gas_sset);

[[eosio::action]] void setgasprices(const gas_prices_type& prices);

// Events
[[eosio::action]] void evmtx(eosio::ignore<evm_runtime::evmtx_type> event){
eosio::check(get_sender() == get_self(), "forbidden to call");
Expand Down
114 changes: 24 additions & 90 deletions include/evm_runtime/tables.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once
#include <evm_runtime/value_promoter.hpp>

#include <eosio/eosio.hpp>
#include <eosio/fixed_bytes.hpp>
Expand All @@ -8,9 +9,11 @@

#include <evm_runtime/types.hpp>
#include <evm_runtime/runtime_config.hpp>

#include <eosevm/block_mapping.hpp>

#include <silkworm/core/common/base.hpp>

namespace evm_runtime {

using namespace eosio;
Expand Down Expand Up @@ -243,95 +246,15 @@ struct [[eosio::table]] [[eosio::contract("evm_contract")]] config2
EOSLIB_SERIALIZE(config2, (next_account_id));
};

struct evm_version_type {
struct pending {
uint64_t version;
time_point time;

bool is_active(time_point_sec genesis_time, time_point current_time)const {
eosevm::block_mapping bm(genesis_time.sec_since_epoch());
auto current_block_num = bm.timestamp_to_evm_block_num(current_time.time_since_epoch().count());
auto pending_block_num = bm.timestamp_to_evm_block_num(time.time_since_epoch().count());
return current_block_num > pending_block_num;
}
};

uint64_t get_version(time_point_sec genesis_time, time_point current_time)const {
uint64_t current_version = cached_version;
if(pending_version.has_value() && pending_version->is_active(genesis_time, current_time)) {
current_version = pending_version->version;
}
return current_version;
}

std::pair<uint64_t, bool> get_version_and_maybe_promote(time_point_sec genesis_time, time_point current_time) {
uint64_t current_version = cached_version;
bool promoted = false;
if(pending_version.has_value() && pending_version->is_active(genesis_time, current_time)) {
current_version = pending_version->version;
promote_pending();
promoted = true;
}
return std::make_pair(current_version, promoted);
}

void promote_pending() {
eosio::check(pending_version.has_value(), "no pending version");
cached_version = pending_version.value().version;
pending_version.reset();
}

std::optional<pending> pending_version;
uint64_t cached_version=0;
};

struct pending_consensus_parameter_data_type {
consensus_parameter_data_type data;
time_point pending_time;
struct gas_prices_type {
uint64_t overhead_price{0};
uint64_t storage_price{0};
};
struct consensus_parameter_type {

consensus_parameter_data_type current;
std::optional<pending_consensus_parameter_data_type> pending;

bool is_pending_active(time_point_sec genesis_time, time_point current_time)const {
if (!pending.has_value()) return false;
eosevm::block_mapping bm(genesis_time.sec_since_epoch());
auto current_block_num = bm.timestamp_to_evm_block_num(current_time.time_since_epoch().count());
auto pending_block_num = bm.timestamp_to_evm_block_num(pending->pending_time.time_since_epoch().count());
return current_block_num > pending_block_num;
}
using evm_version_type = uint64_t;

// Reference invalidated by get_consensus_param_and_maybe_promote and update_consensus_param.
const consensus_parameter_data_type& get_consensus_param(
time_point_sec genesis_time, time_point current_time) const {
if (is_pending_active(genesis_time, current_time)) {
return pending->data;
}
return current;
}

std::pair<const consensus_parameter_data_type &, bool> get_consensus_param_and_maybe_promote(
time_point_sec genesis_time, time_point current_time) {
if (is_pending_active(genesis_time, current_time)) {
current = pending->data;
pending.reset();
// don't use make_pair as it create ref to temp objects
return std::pair<const consensus_parameter_data_type &, bool>(current, true);
}
return std::pair<const consensus_parameter_data_type &, bool>(current, false);
}

template <typename Visitor>
void update_consensus_param(Visitor visitor_fn, time_point current_time) {
consensus_parameter_data_type new_pending = (pending.has_value() ? pending->data : current);
std::visit(visitor_fn, new_pending);
pending = pending_consensus_parameter_data_type{
.data = new_pending,
.pending_time = current_time
};
}
};
VALUE_PROMOTER(evm_version_type);
VALUE_PROMOTER_REV(consensus_parameter_data_type);

struct [[eosio::table]] [[eosio::contract("evm_contract")]] config
{
Expand All @@ -342,12 +265,13 @@ struct [[eosio::table]] [[eosio::contract("evm_contract")]] config
uint64_t gas_price = 0;
uint32_t miner_cut = 0;
uint32_t status = 0; // <- bit mask values from status_flags
binary_extension<evm_version_type> evm_version;
binary_extension<consensus_parameter_type> consensus_parameter;
binary_extension<value_promoter_evm_version_type> evm_version;
binary_extension<value_promoter_consensus_parameter_data_type> consensus_parameter;
binary_extension<eosio::name> token_contract; // <- default(unset) means eosio.token
binary_extension<uint32_t> queue_front_block;
binary_extension<gas_prices_type> gas_prices;

EOSLIB_SERIALIZE(config, (version)(chainid)(genesis_time)(ingress_bridge_fee)(gas_price)(miner_cut)(status)(evm_version)(consensus_parameter)(token_contract)(queue_front_block));
EOSLIB_SERIALIZE(config, (version)(chainid)(genesis_time)(ingress_bridge_fee)(gas_price)(miner_cut)(status)(evm_version)(consensus_parameter)(token_contract)(queue_front_block)(gas_prices));
};

struct [[eosio::table]] [[eosio::contract("evm_contract")]] price_queue
Expand All @@ -359,7 +283,17 @@ struct [[eosio::table]] [[eosio::contract("evm_contract")]] price_queue

EOSLIB_SERIALIZE(price_queue, (block)(price));
};

typedef eosio::multi_index<"pricequeue"_n, price_queue> price_queue_table;

struct [[eosio::table]] [[eosio::contract("evm_contract")]] prices_queue
{
uint64_t block;
gas_prices_type prices;

uint64_t primary_key()const { return block; }

EOSLIB_SERIALIZE(prices_queue, (block)(prices));
};
typedef eosio::multi_index<"pricesqueue"_n, prices_queue> prices_queue_table;

} //namespace evm_runtime
17 changes: 13 additions & 4 deletions include/evm_runtime/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,24 @@ namespace evm_runtime {

using bridge_message = std::variant<bridge_message_v0>;

struct evmtx_v0 {
struct evmtx_base {
uint64_t eos_evm_version;
bytes rlptx;
EOSLIB_SERIALIZE(evmtx_base, (eos_evm_version)(rlptx));
};

struct evmtx_v1 : evmtx_base {
uint64_t base_fee_per_gas;

EOSLIB_SERIALIZE(evmtx_v0, (eos_evm_version)(rlptx)(base_fee_per_gas));
EOSLIB_SERIALIZE_DERIVED(evmtx_v1, evmtx_base, (base_fee_per_gas));
};

struct evmtx_v3 : evmtx_base {
uint64_t overhead_price;
uint64_t storage_price;
EOSLIB_SERIALIZE_DERIVED(evmtx_v3, evmtx_base, (overhead_price)(storage_price));
};

using evmtx_type = std::variant<evmtx_v0>;
using evmtx_type = std::variant<evmtx_v1, evmtx_v3>;

struct fee_parameters
{
Expand Down
65 changes: 65 additions & 0 deletions include/evm_runtime/value_promoter.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#pragma once
#include <eosio/time.hpp>
#include <eosio/print.hpp>
#include <eosevm/block_mapping.hpp>

#define VALUE_PROMOTER_PENDING(T)\
struct T##_pending {\
T value;\
time_point time;\
bool is_active(time_point_sec genesis_time, time_point current_time)const {\
eosevm::block_mapping bm(genesis_time.sec_since_epoch());\
auto current_block_num = bm.timestamp_to_evm_block_num(current_time.time_since_epoch().count());\
auto pending_block_num = bm.timestamp_to_evm_block_num(time.time_since_epoch().count());\
return current_block_num > pending_block_num;\
}\
};

#define VALUE_PROMOTER_IMPL(T)\
T get_value(time_point_sec genesis_time, time_point current_time)const {\
T current_value = cached_value;\
if(pending_value.has_value() && pending_value->is_active(genesis_time, current_time)) {\
current_value = pending_value->value;\
}\
return current_value;\
}\
std::pair<T, bool> get_value_and_maybe_promote(time_point_sec genesis_time, time_point current_time) {\
T current_value = cached_value;\
bool promoted = false;\
if(pending_value.has_value() && pending_value->is_active(genesis_time, current_time)) {\
current_value = pending_value->value;\
promote_pending();\
promoted = true;\
}\
return std::pair<T, bool>(current_value, promoted);\
}\
template <typename Visitor>\
void update(Visitor&& visitor_fn, time_point_sec genesis_time, time_point current_time) {\
auto value = get_value_and_maybe_promote(genesis_time, current_time);\
visitor_fn(value.first);\
pending_value.emplace(T##_pending{\
.value = value.first,\
.time = current_time\
});\
}\
void promote_pending() {\
eosio::check(pending_value.has_value(), "no pending value");\
cached_value = pending_value.value().value;\
pending_value.reset();\
}

#define VALUE_PROMOTER(T)\
VALUE_PROMOTER_PENDING(T);\
struct value_promoter_##T {\
std::optional<T##_pending> pending_value;\
T cached_value = T{};\
VALUE_PROMOTER_IMPL(T)\
};

#define VALUE_PROMOTER_REV(T)\
VALUE_PROMOTER_PENDING(T);\
struct value_promoter_##T {\
T cached_value = T{};\
std::optional<T##_pending> pending_value;\
VALUE_PROMOTER_IMPL(T)\
};
2 changes: 1 addition & 1 deletion silkworm
Submodule silkworm updated 1 files
+2 −1 eosevm/version.hpp
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -92,5 +92,5 @@ target_compile_options(evm_runtime PUBLIC --no-missing-ricardian-clause)
if (WITH_LARGE_STACK)
target_link_options(evm_runtime PUBLIC --stack-size=50000000)
else()
target_link_options(evm_runtime PUBLIC --stack-size=37328)
target_link_options(evm_runtime PUBLIC --stack-size=35984)
endif()
Loading