Skip to content
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
46 changes: 42 additions & 4 deletions libraries/chain/deep_mind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -242,22 +242,57 @@ namespace sysio::chain {
("data", state)
);
}
void deep_mind_handler::on_newaccount_resource_limits(const resource_limits::resource_limits_object& limits, const resource_limits::resource_usage_object& usage)
{

// maintain expected format
struct resource_limits_object {
account_name owner; //< owner should not be changed within a chainbase modifier lambda

int64_t net_weight = -1;
int64_t cpu_weight = -1;
int64_t ram_bytes = -1;
};
struct resource_usage_object {
account_name owner; //< owner should not be changed within a chainbase modifier lambda

resource_limits::usage_accumulator net_usage;
resource_limits::usage_accumulator cpu_usage;
uint64_t ram_usage = 0;
};

void deep_mind_handler::on_newaccount_resource_limits(const resource_limits::resource_object& obj)
{
resource_limits_object limits{
.owner = obj.owner,
.net_weight = obj.net_weight,
.cpu_weight = obj.cpu_weight,
.ram_bytes = obj.ram_bytes,
};
fc_dlog(_logger, "RLIMIT_OP ACCOUNT_LIMITS INS ${data}",
("data", limits)
);
resource_usage_object usage{
.owner = obj.owner,
.net_usage = obj.net_usage,
.cpu_usage = obj.cpu_usage,
.ram_usage = obj.ram_usage,
};
fc_dlog(_logger, "RLIMIT_OP ACCOUNT_USAGE INS ${data}",
("data", usage)
);
}
void deep_mind_handler::on_update_account_usage(const resource_limits::resource_usage_object& usage)
void deep_mind_handler::on_update_account_usage(const resource_limits::resource_object& obj)
{
resource_usage_object usage{
.owner = obj.owner,
.net_usage = obj.net_usage,
.cpu_usage = obj.cpu_usage,
.ram_usage = obj.ram_usage,
};
fc_dlog(_logger, "RLIMIT_OP ACCOUNT_USAGE UPD ${data}",
("data", usage)
);
}
void deep_mind_handler::on_set_account_limits(const resource_limits::resource_limits_object& limits)
void deep_mind_handler::on_set_account_limits(const resource_limits::resource_pending_object& limits)
{
fc_dlog(_logger, "RLIMIT_OP ACCOUNT_LIMITS UPD ${data}",
("data", limits)
Expand Down Expand Up @@ -311,3 +346,6 @@ namespace sysio::chain {
}

}

FC_REFLECT(sysio::chain::resource_limits_object, (owner)(net_weight)(cpu_weight)(ram_bytes));
FC_REFLECT(sysio::chain::resource_usage_object, (owner)(net_usage)(cpu_usage)(ram_usage));
10 changes: 5 additions & 5 deletions libraries/chain/include/sysio/chain/deep_mind.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ struct ram_trace;
namespace resource_limits {
class resource_limits_config_object;
class resource_limits_state_object;
struct resource_limits_object;
struct resource_usage_object;
struct resource_object;
struct resource_pending_object;
}

#define RAM_EVENT_ID( FORMAT, ... ) \
Expand Down Expand Up @@ -76,9 +76,9 @@ class deep_mind_handler
void on_init_resource_limits(const resource_limits::resource_limits_config_object& config, const resource_limits::resource_limits_state_object& state);
void on_update_resource_limits_config(const resource_limits::resource_limits_config_object& config);
void on_update_resource_limits_state(const resource_limits::resource_limits_state_object& state);
void on_newaccount_resource_limits(const resource_limits::resource_limits_object& limits, const resource_limits::resource_usage_object& usage);
void on_update_account_usage(const resource_limits::resource_usage_object& usage);
void on_set_account_limits(const resource_limits::resource_limits_object& limits);
void on_newaccount_resource_limits(const resource_limits::resource_object& limits);
void on_update_account_usage(const resource_limits::resource_object& usage);
void on_set_account_limits(const resource_limits::resource_pending_object& limits);
// The trace is consumed by the next ram_event or ram_correction
void on_ram_trace(std::string&& event_id, const char* family, const char* operation, const char* legacy_tag);
void on_ram_event(account_name account, uint64_t new_usage, int64_t delta);
Expand Down
54 changes: 22 additions & 32 deletions libraries/chain/include/sysio/chain/resource_limits_private.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,57 +190,47 @@ namespace sysio { namespace chain { namespace resource_limits {

using usage_accumulator = impl::exponential_moving_average_accumulator<>;

/**
* Every account that authorizes a transaction is billed for the full size of that transaction. This object
* tracks the average usage of that account.
*/
struct resource_limits_object : public chainbase::object<resource_limits_object_type, resource_limits_object> {

OBJECT_CTOR(resource_limits_object)
struct resource_object : public chainbase::object<resource_object_type, resource_object> {
OBJECT_CTOR(resource_object)

id_type id;
account_name owner; //< owner should not be changed within a chainbase modifier lambda
bool pending = false; //< pending should not be changed within a chainbase modifier lambda

int64_t net_weight = -1;
int64_t cpu_weight = -1;
int64_t ram_bytes = -1;

usage_accumulator net_usage;
usage_accumulator cpu_usage;
uint64_t ram_usage = 0;
};

struct by_owner;
struct by_dirty;

using resource_limits_index = chainbase::shared_multi_index_container<
resource_limits_object,
using resource_index = chainbase::shared_multi_index_container<
resource_object,
indexed_by<
ordered_unique<tag<by_id>, member<resource_limits_object, resource_limits_object::id_type, &resource_limits_object::id>>,
ordered_unique<tag<by_owner>,
composite_key<resource_limits_object,
BOOST_MULTI_INDEX_MEMBER(resource_limits_object, bool, pending),
BOOST_MULTI_INDEX_MEMBER(resource_limits_object, account_name, owner)
>
>
ordered_unique<tag<by_id>, member<resource_object, resource_object::id_type, &resource_object::id>>,
ordered_unique<tag<by_owner>, member<resource_object, account_name, &resource_object::owner> >
>
>;

struct resource_usage_object : public chainbase::object<resource_usage_object_type, resource_usage_object> {
OBJECT_CTOR(resource_usage_object)
struct resource_pending_object : public chainbase::object<resource_pending_object_type, resource_pending_object> {
OBJECT_CTOR(resource_pending_object)

id_type id;
account_name owner; //< owner should not be changed within a chainbase modifier lambda

usage_accumulator net_usage;
usage_accumulator cpu_usage;

uint64_t ram_usage = 0;
int64_t net_weight = -1;
int64_t cpu_weight = -1;
int64_t ram_bytes = -1;
};

using resource_usage_index = chainbase::shared_multi_index_container<
resource_usage_object,
using resource_pending_index = chainbase::shared_multi_index_container<
resource_pending_object,
indexed_by<
ordered_unique<tag<by_id>, member<resource_usage_object, resource_usage_object::id_type, &resource_usage_object::id>>,
ordered_unique<tag<by_owner>, member<resource_usage_object, account_name, &resource_usage_object::owner> >
ordered_unique<tag<by_id>, member<resource_pending_object, resource_pending_object::id_type, &resource_pending_object::id>>,
ordered_unique<tag<by_owner>, member<resource_pending_object, account_name, &resource_pending_object::owner> >
>
>;

Expand Down Expand Up @@ -326,15 +316,15 @@ namespace sysio { namespace chain { namespace resource_limits {

} } } /// sysio::chain::resource_limits

CHAINBASE_SET_INDEX_TYPE(sysio::chain::resource_limits::resource_limits_object, sysio::chain::resource_limits::resource_limits_index)
CHAINBASE_SET_INDEX_TYPE(sysio::chain::resource_limits::resource_usage_object, sysio::chain::resource_limits::resource_usage_index)
CHAINBASE_SET_INDEX_TYPE(sysio::chain::resource_limits::resource_object, sysio::chain::resource_limits::resource_index)
CHAINBASE_SET_INDEX_TYPE(sysio::chain::resource_limits::resource_pending_object, sysio::chain::resource_limits::resource_pending_index)
CHAINBASE_SET_INDEX_TYPE(sysio::chain::resource_limits::resource_limits_config_object, sysio::chain::resource_limits::resource_limits_config_index)
CHAINBASE_SET_INDEX_TYPE(sysio::chain::resource_limits::resource_limits_state_object, sysio::chain::resource_limits::resource_limits_state_index)

FC_REFLECT(sysio::chain::resource_limits::usage_accumulator, (last_ordinal)(value_ex)(consumed))

// @ignore pending
FC_REFLECT(sysio::chain::resource_limits::resource_limits_object, (owner)(net_weight)(cpu_weight)(ram_bytes))
FC_REFLECT(sysio::chain::resource_limits::resource_usage_object, (owner)(net_usage)(cpu_usage)(ram_usage))
FC_REFLECT(sysio::chain::resource_limits::resource_object, (owner)(net_weight)(cpu_weight)(ram_bytes)(net_usage)(cpu_usage)(ram_usage))
FC_REFLECT(sysio::chain::resource_limits::resource_pending_object, (owner)(net_weight)(cpu_weight)(ram_bytes))
FC_REFLECT(sysio::chain::resource_limits::resource_limits_config_object, (cpu_limit_parameters)(net_limit_parameters)(account_cpu_usage_average_window)(account_net_usage_average_window))
FC_REFLECT(sysio::chain::resource_limits::resource_limits_state_object, (average_block_net_usage)(average_block_cpu_usage)(pending_net_usage)(pending_cpu_usage)(total_net_weight)(total_cpu_weight)(total_ram_bytes)(virtual_net_limit)(virtual_cpu_limit))
4 changes: 2 additions & 2 deletions libraries/chain/include/sysio/chain/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,8 @@ namespace sysio::chain {
UNUSED_proxy_vote_object_type,
UNUSED_scope_sequence_object_type,
table_id_object_type,
resource_limits_object_type,
resource_usage_object_type,
resource_object_type,
resource_pending_object_type,
resource_limits_state_object_type,
resource_limits_config_object_type,
account_history_object_type, ///< Defined by history_plugin
Expand Down
58 changes: 25 additions & 33 deletions libraries/chain/resource_limits.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
namespace sysio { namespace chain { namespace resource_limits {

using resource_index_set = index_set<
resource_limits_index,
resource_usage_index,
resource_index,
resource_pending_index,
resource_limits_state_index,
resource_limits_config_index
>;
Expand Down Expand Up @@ -96,15 +96,12 @@ void resource_limits_manager::read_from_snapshot( const snapshot_reader_ptr& sna
}

void resource_limits_manager::initialize_account(const account_name& account, bool is_trx_transient) {
const auto& limits = _db.create<resource_limits_object>([&]( resource_limits_object& bl ) {
const auto& usage = _db.create<resource_object>([&]( resource_object& bl ) {
bl.owner = account;
});

const auto& usage = _db.create<resource_usage_object>([&]( resource_usage_object& bu ) {
bu.owner = account;
});
if (auto dm_logger = _get_deep_mind_logger(is_trx_transient)) {
dm_logger->on_newaccount_resource_limits(limits, usage);
dm_logger->on_newaccount_resource_limits(usage);
}
}

Expand All @@ -129,7 +126,7 @@ void resource_limits_manager::set_block_parameters(const elastic_limit_parameter
void resource_limits_manager::update_account_usage(const accounts_billing_t& accounts, uint32_t time_slot ) {
const auto& config = _db.get<resource_limits_config_object>();
for(const auto& a: accounts | std::views::keys) {
const auto& usage = _db.get<resource_usage_object,by_owner>( a );
const auto& usage = _db.get<resource_object,by_owner>( a );
_db.modify( usage, [&]( auto& bu ){
bu.net_usage.add( 0, time_slot, config.account_net_usage_average_window );
bu.cpu_usage.add( 0, time_slot, config.account_cpu_usage_average_window );
Expand All @@ -143,7 +140,7 @@ void resource_limits_manager::add_transaction_usage(const accounts_billing_t& ac

for( const auto& [a, billing] : accounts ) {

const auto& usage = _db.get<resource_usage_object,by_owner>( a );
const auto& usage = _db.get<resource_object,by_owner>( a );
int64_t unused;
int64_t net_weight;
int64_t cpu_weight;
Expand Down Expand Up @@ -215,7 +212,7 @@ void resource_limits_manager::add_pending_ram_usage( const account_name account,
}
// wlog("Adding pending RAM usage of ${ram_delta} to account ${account}", ("ram_delta", ram_delta)("account", account));

const auto& usage = _db.get<resource_usage_object,by_owner>( account );
const auto& usage = _db.get<resource_object,by_owner>( account );

SYS_ASSERT( ram_delta <= 0 || UINT64_MAX - usage.ram_usage >= (uint64_t)ram_delta, transaction_exception,
"Ram usage delta would overflow UINT64_MAX");
Expand All @@ -234,7 +231,7 @@ void resource_limits_manager::add_pending_ram_usage( const account_name account,
void resource_limits_manager::verify_account_ram_usage( const account_name account )const {
int64_t ram_bytes; int64_t net_weight; int64_t cpu_weight;
get_account_limits( account, ram_bytes, net_weight, cpu_weight );
const auto& usage = _db.get<resource_usage_object,by_owner>( account );
const auto& usage = _db.get<resource_object,by_owner>( account );

if( ram_bytes >= 0 ) {
SYS_ASSERT( usage.ram_usage <= static_cast<uint64_t>(ram_bytes), ram_usage_exceeded,
Expand All @@ -244,26 +241,24 @@ void resource_limits_manager::verify_account_ram_usage( const account_name accou
}

int64_t resource_limits_manager::get_account_ram_usage( const account_name& name )const {
return _db.get<resource_usage_object,by_owner>( name ).ram_usage;
return _db.get<resource_object,by_owner>( name ).ram_usage;
}

bool resource_limits_manager::set_account_limits( const account_name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight, bool is_trx_transient) {
//const auto& usage = _db.get<resource_usage_object,by_owner>( account );
/*
* Since we need to delay these until the next resource limiting boundary, these are created in a "pending"
* state or adjusted in an existing "pending" state. The chain controller will collapse "pending" state into
* Since we need to delay these until the next resource limiting boundary, these are created in a "pending" object
* or adjusted in an existing "pending" object. The chain controller will collapse "pending" objects into
* the actual state at the next appropriate boundary.
*/
auto find_or_create_pending_limits = [&]() -> const resource_limits_object& {
const auto* pending_limits = _db.find<resource_limits_object, by_owner>( boost::make_tuple(true, account) );
auto find_or_create_pending_limits = [&]() -> const resource_pending_object& {
const auto* pending_limits = _db.find<resource_pending_object, by_owner>( account );
if (pending_limits == nullptr) {
const auto& limits = _db.get<resource_limits_object, by_owner>( boost::make_tuple(false, account));
return _db.create<resource_limits_object>([&](resource_limits_object& pending_limits){
const auto& limits = _db.get<resource_object, by_owner>( account );
return _db.create<resource_pending_object>([&](resource_pending_object& pending_limits){
pending_limits.owner = limits.owner;
pending_limits.ram_bytes = limits.ram_bytes;
pending_limits.net_weight = limits.net_weight;
pending_limits.cpu_weight = limits.cpu_weight;
pending_limits.pending = true;
});
} else {
return *pending_limits;
Expand All @@ -288,7 +283,7 @@ bool resource_limits_manager::set_account_limits( const account_name& account, i
*/
}

_db.modify( limits, [&]( resource_limits_object& pending_limits ){
_db.modify( limits, [&]( resource_pending_object& pending_limits ){
pending_limits.ram_bytes = ram_bytes;
pending_limits.net_weight = net_weight;
pending_limits.cpu_weight = cpu_weight;
Expand All @@ -302,29 +297,29 @@ bool resource_limits_manager::set_account_limits( const account_name& account, i
}

void resource_limits_manager::get_account_limits( const account_name& account, int64_t& ram_bytes, int64_t& net_weight, int64_t& cpu_weight ) const {
const auto* pending_buo = _db.find<resource_limits_object,by_owner>( boost::make_tuple(true, account) );
const auto* pending_buo = _db.find<resource_pending_object,by_owner>( account );
if (pending_buo) {
ram_bytes = pending_buo->ram_bytes;
net_weight = pending_buo->net_weight;
cpu_weight = pending_buo->cpu_weight;
} else {
const auto& buo = _db.get<resource_limits_object,by_owner>( boost::make_tuple( false, account ) );
const auto& buo = _db.get<resource_object,by_owner>( account );
ram_bytes = buo.ram_bytes;
net_weight = buo.net_weight;
cpu_weight = buo.cpu_weight;
}
}

bool resource_limits_manager::is_unlimited_cpu( const account_name& account ) const {
const auto* buo = _db.find<resource_limits_object,by_owner>( boost::make_tuple(false, account) );
const auto* buo = _db.find<resource_object,by_owner>( account );
if (buo) {
return buo->cpu_weight == -1;
}
return false;
}

void resource_limits_manager::process_account_limit_updates() {
auto& multi_index = _db.get_mutable_index<resource_limits_index>();
auto& multi_index = _db.get_mutable_index<resource_pending_index>();
auto& by_owner_index = multi_index.indices().get<by_owner>();

// convenience local lambda to reduce clutter
Expand All @@ -345,13 +340,10 @@ void resource_limits_manager::process_account_limit_updates() {
const auto& state = _db.get<resource_limits_state_object>();
_db.modify(state, [&](resource_limits_state_object& rso){
while(!by_owner_index.empty()) {
const auto& itr = by_owner_index.lower_bound(boost::make_tuple(true));
if (itr == by_owner_index.end() || itr->pending!= true) {
break;
}
const auto& itr = by_owner_index.begin();

const auto& actual_entry = _db.get<resource_limits_object, by_owner>(boost::make_tuple(false, itr->owner));
_db.modify(actual_entry, [&](resource_limits_object& rlo){
const auto& actual_entry = _db.get<resource_object, by_owner>(itr->owner);
_db.modify(actual_entry, [&](resource_object& rlo){
update_state_and_value(rso.total_ram_bytes, rlo.ram_bytes, itr->ram_bytes, "ram_bytes");
update_state_and_value(rso.total_cpu_weight, rlo.cpu_weight, itr->cpu_weight, "cpu_weight");
update_state_and_value(rso.total_net_weight, rlo.net_weight, itr->net_weight, "net_weight");
Expand Down Expand Up @@ -432,7 +424,7 @@ std::pair<account_resource_limit, bool>
resource_limits_manager::get_account_cpu_limit_ex( const account_name& name, uint32_t greylist_limit, const std::optional<block_timestamp_type>& current_time) const {

const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name);
const auto& usage = _db.get<resource_object, by_owner>(name);
const auto& config = _db.get<resource_limits_config_object>();

int64_t cpu_weight, x, y;
Expand Down Expand Up @@ -494,7 +486,7 @@ std::pair<account_resource_limit, bool>
resource_limits_manager::get_account_net_limit_ex( const account_name& name, uint32_t greylist_limit, const std::optional<block_timestamp_type>& current_time) const {
const auto& config = _db.get<resource_limits_config_object>();
const auto& state = _db.get<resource_limits_state_object>();
const auto& usage = _db.get<resource_usage_object, by_owner>(name);
const auto& usage = _db.get<resource_object, by_owner>(name);

int64_t net_weight, x, y;
get_account_limits( name, x, net_weight, y );
Expand Down
Loading