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

Draft: Slim accounts #2328

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
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
32 changes: 17 additions & 15 deletions libraries/chain/apply_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ void apply_context::exec_one()

digest_type act_digest;

const account_metadata_object* receiver_account = nullptr;
const account_object* receiver_account = nullptr;
const account_metadata_object* receiver_account_metadata = nullptr;

auto handle_exception = [&](const auto& e)
{
Expand All @@ -80,9 +81,10 @@ void apply_context::exec_one()
try {
try {
action_return_value.clear();
receiver_account = &db.get<account_metadata_object,by_name>( receiver );
if( !(context_free && control.skip_trx_checks()) ) {
privileged = receiver_account->is_privileged();
receiver_account = &db.get<account_object,by_name>( receiver );
receiver_account_metadata = db.find<account_metadata_object,by_name>( receiver );
if( receiver_account_metadata != nullptr && !(context_free && control.skip_trx_checks()) ) {
privileged = receiver_account_metadata->is_privileged();
auto native = control.find_apply_handler( receiver, act->account, act->name );
if( native ) {
if( trx_context.enforce_whiteblacklist && control.is_speculative_block() ) {
Expand All @@ -92,7 +94,7 @@ void apply_context::exec_one()
(*native)( *this );
}

if( ( receiver_account->code_hash != digest_type() ) &&
if( ( receiver_account_metadata->code_hash != digest_type() ) &&
( !( act->account == config::system_account_name
&& act->name == "setcode"_n
&& receiver == config::system_account_name )
Expand All @@ -104,7 +106,7 @@ void apply_context::exec_one()
control.check_action_list( act->account, act->name );
}
try {
control.get_wasm_interface().apply( receiver_account->code_hash, receiver_account->vm_type, receiver_account->vm_version, *this );
control.get_wasm_interface().apply( receiver_account_metadata->code_hash, receiver_account_metadata->vm_type, receiver_account_metadata->vm_version, *this );
} catch( const wasm_exit& ) {}
}

Expand Down Expand Up @@ -170,15 +172,15 @@ void apply_context::exec_one()
r.global_sequence = next_global_sequence();
r.recv_sequence = next_recv_sequence( *receiver_account );

const account_metadata_object* first_receiver_account = nullptr;
const account_metadata_object* first_receiver_account_metadata = nullptr;
if( act->account == receiver ) {
first_receiver_account = receiver_account;
first_receiver_account_metadata = receiver_account_metadata;
} else {
first_receiver_account = &db.get<account_metadata_object, by_name>(act->account);
first_receiver_account_metadata = db.find<account_metadata_object, by_name>(act->account);
}

r.code_sequence = first_receiver_account->code_sequence; // could be modified by action execution above
r.abi_sequence = first_receiver_account->abi_sequence; // could be modified by action execution above
r.code_sequence = first_receiver_account_metadata != nullptr ? first_receiver_account_metadata->code_sequence : 0; // could be modified by action execution above
r.abi_sequence = first_receiver_account_metadata != nullptr ? first_receiver_account_metadata->abi_sequence: 0; // could be modified by action execution above

for( const auto& auth : act->authorization ) {
r.auth_sequence[auth.actor] = next_auth_sequence( auth.actor );
Expand Down Expand Up @@ -1053,7 +1055,7 @@ uint64_t apply_context::next_global_sequence() {
}
}

uint64_t apply_context::next_recv_sequence( const account_metadata_object& receiver_account ) {
uint64_t apply_context::next_recv_sequence( const account_object& receiver_account ) {
if ( trx_context.is_read_only() ) {
// To avoid confusion of duplicated receive sequence number, hard code to be 0.
return 0;
Expand All @@ -1065,11 +1067,11 @@ uint64_t apply_context::next_recv_sequence( const account_metadata_object& recei
}
}
uint64_t apply_context::next_auth_sequence( account_name actor ) {
const auto& amo = db.get<account_metadata_object,by_name>( actor );
db.modify( amo, [&](auto& am ){
const auto& ao = db.get<account_object,by_name>( actor );
db.modify( ao, [&](auto& am ){
++am.auth_sequence;
});
return amo.auth_sequence;
return ao.auth_sequence;
}

void apply_context::add_ram_usage( account_name account, int64_t ram_delta ) {
Expand Down
52 changes: 11 additions & 41 deletions libraries/chain/authorization_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ namespace eosio { namespace chain {

using authorization_index_set = index_set<
permission_index,
permission_usage_index,
permission_link_index
>;

Expand All @@ -28,8 +27,10 @@ namespace eosio { namespace chain {
authorization_index_set::add_indices(_db);
}

void authorization_manager::initialize_database() {
_db.create<permission_object>([](auto&){}); /// reserve perm 0 (used else where)
void authorization_manager::initialize_database(const fc::time_point& initial_timestamp) {
_db.create<permission_object>([&](auto& value){
value.last_used = initial_timestamp;
}); /// reserve perm 0 (used else where)
}

namespace detail {
Expand All @@ -50,8 +51,7 @@ namespace eosio { namespace chain {
res.parent = parent.name;

// lookup the usage object
const auto& usage = db.get<permission_usage_object>(value.usage_id);
res.last_used = usage.last_used;
res.last_used = value.last_used;

return res;
};
Expand All @@ -61,7 +61,7 @@ namespace eosio { namespace chain {
value.owner = row.owner;
value.last_updated = row.last_updated;
value.auth = row.auth;

value.last_used = row.last_used;
value.parent = 0;
if (value.id == 0) {
EOS_ASSERT(row.parent == permission_name(), snapshot_exception, "Unexpected parent name on reserved permission 0");
Expand All @@ -79,16 +79,6 @@ namespace eosio { namespace chain {
EOS_ASSERT(parent.id != 0, snapshot_exception, "Unexpected mapping to reserved permission 0");
value.parent = parent.id;
}

if (value.id != 0) {
// create the usage object
const auto& usage = db.create<permission_usage_object>([&](auto& p) {
p.last_used = row.last_used;
});
value.usage_id = usage.id;
} else {
value.usage_id = 0;
}
}
};
}
Expand All @@ -97,11 +87,6 @@ namespace eosio { namespace chain {
authorization_index_set::walk_indices([this, &snapshot]( auto utils ){
using section_t = typename decltype(utils)::index_t::value_type;

// skip the permission_usage_index as its inlined with permission_index
if (std::is_same<section_t, permission_usage_object>::value) {
return;
}

snapshot->write_section<section_t>([this]( auto& section ){
decltype(utils)::walk(_db, [this, &section]( const auto &row ) {
section.add_row(row, _db);
Expand All @@ -114,11 +99,6 @@ namespace eosio { namespace chain {
authorization_index_set::walk_indices([this, &snapshot]( auto utils ){
using section_t = typename decltype(utils)::index_t::value_type;

// skip the permission_usage_index as its inlined with permission_index
if (std::is_same<section_t, permission_usage_object>::value) {
return;
}

snapshot->read_section<section_t>([this]( auto& section ) {
bool more = !section.empty();
while(more) {
Expand Down Expand Up @@ -147,16 +127,12 @@ namespace eosio { namespace chain {
creation_time = _control.pending_block_time();
}

const auto& perm_usage = _db.create<permission_usage_object>([&](auto& p) {
p.last_used = creation_time;
});

const auto& perm = _db.create<permission_object>([&](auto& p) {
p.usage_id = perm_usage.id;
p.parent = parent;
p.owner = account;
p.name = name;
p.last_updated = creation_time;
p.last_used = creation_time;
p.auth = auth;

if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) {
Expand All @@ -183,16 +159,12 @@ namespace eosio { namespace chain {
creation_time = _control.pending_block_time();
}

const auto& perm_usage = _db.create<permission_usage_object>([&](auto& p) {
p.last_used = creation_time;
});

const auto& perm = _db.create<permission_object>([&](auto& p) {
p.usage_id = perm_usage.id;
p.parent = parent;
p.owner = account;
p.name = name;
p.last_updated = creation_time;
p.last_used = creation_time;
p.auth = std::move(auth);

if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) {
Expand Down Expand Up @@ -230,8 +202,6 @@ namespace eosio { namespace chain {
EOS_ASSERT( range.first == range.second, action_validate_exception,
"Cannot remove a permission which has children. Remove the children first.");

_db.get_mutable_index<permission_usage_index>().remove_object( permission.usage_id._id );

if (auto dm_logger = _control.get_deep_mind_logger(is_trx_transient)) {
dm_logger->on_remove_permission(permission);
}
Expand All @@ -240,14 +210,14 @@ namespace eosio { namespace chain {
}

void authorization_manager::update_permission_usage( const permission_object& permission ) {
const auto& puo = _db.get<permission_usage_object, by_id>( permission.usage_id );
_db.modify( puo, [&](permission_usage_object& p) {
const auto& po = _db.get<permission_object, by_id>( permission.id );
_db.modify( po, [&](permission_object& p) {
p.last_used = _control.pending_block_time();
});
}

fc::time_point authorization_manager::get_permission_last_used( const permission_object& permission )const {
return _db.get<permission_usage_object, by_id>( permission.usage_id ).last_used;
return _db.get<permission_object, by_id>( permission.id ).last_used;
}

const permission_object* authorization_manager::find_permission( const permission_level& level )const
Expand Down
69 changes: 63 additions & 6 deletions libraries/chain/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ struct controller_impl {
&BOOST_PP_CAT(apply_, BOOST_PP_CAT(contract, BOOST_PP_CAT(_,action) ) ) )

SET_APP_HANDLER( eosio, eosio, newaccount );
SET_APP_HANDLER( eosio, eosio, newslimacc );
SET_APP_HANDLER( eosio, eosio, setcode );
SET_APP_HANDLER( eosio, eosio, setabi );
SET_APP_HANDLER( eosio, eosio, updateauth );
Expand Down Expand Up @@ -999,6 +1000,63 @@ struct controller_impl {
}
}

if (std::is_same<value_t, account_object>::value) {
using v6 = snapshot_account_object_v6;

if (std::clamp(header.version, v6::minimum_version, v6::maximum_version) == header.version ) {
snapshot->read_section<account_object>([&db = this->db](auto& section) {
bool more = !section.empty();
while (more) {
v6 snapshot_account_object;
more = section.read_row(snapshot_account_object, db);
const auto *acct_itr = db.find<account_object, by_name>( snapshot_account_object.name );
if(acct_itr == nullptr){
db.create<account_object>([&snapshot_account_object](auto& value ){
value.name = snapshot_account_object.name;
value.creation_date = snapshot_account_object.creation_date;
});
db.create<account_metadata_object>([&](auto& value) {
value.name = snapshot_account_object.name;
value.abi = snapshot_account_object.abi;
});
}
}
});
return;
}
}
if (std::is_same<value_t, account_metadata_object>::value) {
using v6 = snapshot_account_metadata_object_v6;

if (std::clamp(header.version, v6::minimum_version, v6::maximum_version) == header.version ) {
snapshot->read_section<account_metadata_object>([&db = this->db](auto& section) {
bool more = !section.empty();
while (more) {
v6 snapshot_account_metadata_object;
more = section.read_row(snapshot_account_metadata_object, db);
const auto *acct_itr = db.find<account_object, by_name>( snapshot_account_metadata_object.name );
EOS_ASSERT(acct_itr != nullptr, snapshot_exception, "Unexpected snapshot_account_metadata_object1");
db.modify( *acct_itr, [&]( account_object& value ){
value.recv_sequence = snapshot_account_metadata_object.recv_sequence;
value.auth_sequence = snapshot_account_metadata_object.auth_sequence;
});
const auto *acct_metadata_itr = db.find<account_metadata_object, by_name>( snapshot_account_metadata_object.name );
EOS_ASSERT(acct_metadata_itr != nullptr, snapshot_exception, "Unexpected snapshot_account_metadata_object2");
db.modify( *acct_metadata_itr, [&](auto& value) {
value.code_sequence = snapshot_account_metadata_object.code_sequence;
value.abi_sequence = snapshot_account_metadata_object.abi_sequence;
value.code_hash = snapshot_account_metadata_object.code_hash;
value.last_code_update = snapshot_account_metadata_object.last_code_update;
value.flags = snapshot_account_metadata_object.flags;
value.vm_type = snapshot_account_metadata_object.vm_type;
value.vm_version = snapshot_account_metadata_object.vm_version;
});
}
});
return;
}
}

snapshot->read_section<value_t>([this]( auto& section ) {
bool more = !section.empty();
while(more) {
Expand Down Expand Up @@ -1039,17 +1097,16 @@ struct controller_impl {
db.create<account_object>([&](auto& a) {
a.name = name;
a.creation_date = initial_timestamp;

});
db.create<account_metadata_object>([&](auto & a) {
a.name = name;
a.set_privileged( is_privileged );
if( name == config::system_account_name ) {
// The initial eosio ABI value affects consensus; see https://github.com/EOSIO/eos/issues/7794
// TODO: This doesn't charge RAM; a fix requires a consensus upgrade.
a.abi.assign(eosio_abi_bin, sizeof(eosio_abi_bin));
}
});
db.create<account_metadata_object>([&](auto & a) {
a.name = name;
a.set_privileged( is_privileged );
});

const auto& owner_permission = authorization.create_permission(name, config::owner_name, 0,
owner, false, initial_timestamp );
Expand Down Expand Up @@ -1104,7 +1161,7 @@ struct controller_impl {

db.create<dynamic_global_property_object>([](auto&){});

authorization.initialize_database();
authorization.initialize_database(genesis.initial_timestamp);
resource_limits.initialize_database();

authority system_auth(genesis.initial_key);
Expand Down
18 changes: 9 additions & 9 deletions libraries/chain/deep_mind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ namespace eosio::chain {
("block_num", head_block_num)
("global_sequence_num", db.get<dynamic_global_property_object>().global_action_sequence)
);
const auto& idx = db.get_index<account_index>();
const auto& idx = db.get_index<account_metadata_index>();
for (auto& row : idx.indices()) {
if (row.abi.size() != 0) {
fc_dlog(_logger, "ABIDUMP ABI ${contract} ${abi}",
Expand Down Expand Up @@ -328,26 +328,26 @@ namespace eosio::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)
void deep_mind_handler::on_newaccount_resource_limits(const resource_limits::resource_limits_object& limits)
{
fc_dlog(_logger, "RLIMIT_OP ACCOUNT_LIMITS INS ${data}",
("data", limits)
);
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_limits_object& limits)
{
fc_dlog(_logger, "RLIMIT_OP ACCOUNT_USAGE UPD ${data}",
("data", usage)
fc_dlog(_logger, "RLIMIT_OP ACCOUNT_LIMITS UPD ${data}",
("data", limits)
);
}
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_limits_object& limits, const resource_limits::resource_pending_object& pending)
{
fc_dlog(_logger, "RLIMIT_OP ACCOUNT_LIMITS UPD ${data}",
("data", limits)
);
fc_dlog(_logger, "RLIMIT_OP ACCOUNT_PENDING UPD ${data}",
("data", pending)
);
}
void deep_mind_handler::on_ram_trace(std::string&& event_id, const char* family, const char* operation, const char* legacy_tag)
{
Expand Down
Loading
Loading