Skip to content

Commit

Permalink
Improve account maintenance performance (#130)
Browse files Browse the repository at this point in the history
* Improve account maintenance performance

* merge fixes

* Fixed merge issue

* Fixed indentations and extra ';'
  • Loading branch information
srpatel19590 authored and bobinson committed Nov 7, 2019
1 parent 50b80e9 commit 0bcfaa3
Show file tree
Hide file tree
Showing 13 changed files with 231 additions and 106 deletions.
87 changes: 50 additions & 37 deletions libraries/chain/account_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -162,33 +162,39 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
if( referrer_percent > GRAPHENE_100_PERCENT )
referrer_percent = GRAPHENE_100_PERCENT;
}
const auto& global_properties = d.get_global_properties();

const auto& new_acnt_object = db().create<account_object>( [&]( account_object& obj ){
obj.registrar = o.registrar;
obj.referrer = o.referrer;
obj.lifetime_referrer = o.referrer(db()).lifetime_referrer;

auto& params = db().get_global_properties().parameters;
obj.network_fee_percentage = params.network_percent_of_fee;
obj.lifetime_referrer_fee_percentage = params.lifetime_referrer_percent_of_fee;
obj.referrer_rewards_percentage = referrer_percent;

obj.name = o.name;
obj.owner = o.owner;
obj.active = o.active;
obj.options = o.options;
obj.statistics = db().create<account_statistics_object>([&](account_statistics_object& s){s.owner = obj.id;}).id;

if( o.extensions.value.owner_special_authority.valid() )
obj.owner_special_authority = *(o.extensions.value.owner_special_authority);
if( o.extensions.value.active_special_authority.valid() )
obj.active_special_authority = *(o.extensions.value.active_special_authority);
if( o.extensions.value.buyback_options.valid() )
{
obj.allowed_assets = o.extensions.value.buyback_options->markets;
obj.allowed_assets->emplace( o.extensions.value.buyback_options->asset_to_buy );
}
obj.affiliate_distributions = o.extensions.value.affiliate_distributions;
const auto& new_acnt_object = d.create<account_object>( [&o,&d,&global_properties,referrer_percent]( account_object& obj )
{
obj.registrar = o.registrar;
obj.referrer = o.referrer;
obj.lifetime_referrer = o.referrer(d).lifetime_referrer;

const auto& params = global_properties.parameters;
obj.network_fee_percentage = params.network_percent_of_fee;
obj.lifetime_referrer_fee_percentage = params.lifetime_referrer_percent_of_fee;
obj.referrer_rewards_percentage = referrer_percent;

obj.name = o.name;
obj.owner = o.owner;
obj.active = o.active;
obj.options = o.options;
obj.statistics = d.create<account_statistics_object>([&obj](account_statistics_object& s){
s.owner = obj.id;
s.name = obj.name;
s.is_voting = obj.options.is_voting();
}).id;

if( o.extensions.value.owner_special_authority.valid() )
obj.owner_special_authority = *(o.extensions.value.owner_special_authority);
if( o.extensions.value.active_special_authority.valid() )
obj.active_special_authority = *(o.extensions.value.active_special_authority);
if( o.extensions.value.buyback_options.valid() )
{
obj.allowed_assets = o.extensions.value.buyback_options->markets;
obj.allowed_assets->emplace( o.extensions.value.buyback_options->asset_to_buy );
}
obj.affiliate_distributions = o.extensions.value.affiliate_distributions;
});

if( has_small_percent )
Expand All @@ -200,17 +206,18 @@ object_id_type account_create_evaluator::do_apply( const account_create_operatio
wlog( "Affected account object is ${o}", ("o", new_acnt_object) );
}

const auto& dynamic_properties = db().get_dynamic_global_properties();
db().modify(dynamic_properties, [](dynamic_global_property_object& p) {
const auto& dynamic_properties = d.get_dynamic_global_properties();
d.modify(dynamic_properties, [](dynamic_global_property_object& p) {
++p.accounts_registered_this_interval;
});

const auto& global_properties = db().get_global_properties();
if( dynamic_properties.accounts_registered_this_interval %
global_properties.parameters.accounts_per_fee_scale == 0 )
db().modify(global_properties, [&dynamic_properties](global_property_object& p) {
if( dynamic_properties.accounts_registered_this_interval % global_properties.parameters.accounts_per_fee_scale == 0
&& global_properties.parameters.account_fee_scale_bitshifts != 0 )
{
d.modify(global_properties, [&dynamic_properties](global_property_object& p) {
p.parameters.current_fees->get<account_create_operation>().basic_fee <<= p.parameters.account_fee_scale_bitshifts;
});
}

if( o.extensions.value.owner_special_authority.valid()
|| o.extensions.value.active_special_authority.valid() )
Expand Down Expand Up @@ -280,18 +287,24 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
{ try {
database& d = db();

bool sa_before = acnt->has_special_authority();

// update account statistics
if( o.new_options.valid() )
{
d.modify( acnt->statistics( d ), [&]( account_statistics_object& aso )
{
if(o.new_options->is_voting() != acnt->options.is_voting())
aso.is_voting = !aso.is_voting;

if((o.new_options->votes != acnt->options.votes ||
o.new_options->voting_account != acnt->options.voting_account))
o.new_options->voting_account != acnt->options.voting_account))
aso.last_vote_time = d.head_block_time();
} );
}

bool sa_before, sa_after;
d.modify( *acnt, [&](account_object& a){
// update account object
d.modify( *acnt, [&o](account_object& a){
if( o.owner )
{
a.owner = *o.owner;
Expand All @@ -303,7 +316,6 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
a.top_n_control_flags = 0;
}
if( o.new_options ) a.options = *o.new_options;
sa_before = a.has_special_authority();
if( o.extensions.value.owner_special_authority.valid() )
{
a.owner_special_authority = *(o.extensions.value.owner_special_authority);
Expand All @@ -314,9 +326,10 @@ void_result account_update_evaluator::do_apply( const account_update_operation&
a.active_special_authority = *(o.extensions.value.active_special_authority);
a.top_n_control_flags = 0;
}
sa_after = a.has_special_authority();
});

bool sa_after = acnt->has_special_authority();

if( sa_before & (!sa_after) )
{
const auto& sa_idx = d.get_index_type< special_authority_index >().indices().get<by_account>();
Expand Down
2 changes: 2 additions & 0 deletions libraries/chain/account_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ void account_balance_object::adjust_balance(const asset& delta)
{
assert(delta.asset_id == asset_type);
balance += delta.amount;
if( asset_type == asset_id_type() ) // CORE asset
maintenance_flag = true;
}

void account_statistics_object::process_fees(const account_object& a, database& d) const
Expand Down
9 changes: 8 additions & 1 deletion libraries/chain/db_balance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ void database::adjust_balance(account_id_type account, asset delta )
b.owner = account;
b.asset_type = delta.asset_id;
b.balance = delta.amount.value;
if( b.asset_type == asset_id_type() ) // CORE asset
b.maintenance_flag = true;
});
} else {
if( delta.amount < 0 )
Expand Down Expand Up @@ -223,10 +225,15 @@ void database::deposit_cashback(const account_object& acct, share_type amount, b

if( new_vbid.valid() )
{
modify( acct, [&]( account_object& _acct )
modify( acct, [&new_vbid]( account_object& _acct )
{
_acct.cashback_vb = *new_vbid;
} );

modify( acct.statistics( *this ), []( account_statistics_object& aso )
{
aso.has_cashback_vb = true;
} );
}

return;
Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/db_debug.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void database::debug_dump()
const asset_dynamic_data_object& core_asset_data = db.get_core_asset().dynamic_asset_data_id(db);

const auto& balance_index = db.get_index_type<account_balance_index>().indices();
const simple_index<account_statistics_object>& statistics_index = db.get_index_type<simple_index<account_statistics_object>>();
const auto& statistics_index = db.get_index_type<account_stats_index>().indices();
map<asset_id_type,share_type> total_balances;
map<asset_id_type,share_type> total_debts;
share_type core_in_orders;
Expand Down
9 changes: 9 additions & 0 deletions libraries/chain/db_getter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,4 +141,13 @@ const std::vector<uint32_t> database::get_winner_numbers( asset_id_type for_asse
return result;
}

const account_statistics_object& database::get_account_stats_by_owner( account_id_type owner )const
{
auto& idx = get_index_type<account_stats_index>().indices().get<by_owner>();
auto itr = idx.find( owner );
FC_ASSERT( itr != idx.end(), "Can not find account statistics object for owner ${a}", ("a",owner) );
return *itr;
}


} }
57 changes: 41 additions & 16 deletions libraries/chain/db_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ void database::initialize_indexes()
add_index< primary_index<asset_dividend_data_object_index > >();
add_index< primary_index<simple_index<global_property_object >> >();
add_index< primary_index<simple_index<dynamic_global_property_object >> >();
add_index< primary_index<simple_index<account_statistics_object >> >();
add_index< primary_index<account_stats_index > >();
add_index< primary_index<simple_index<asset_dynamic_data_object >> >();
add_index< primary_index<flat_index< block_summary_object >> >();
add_index< primary_index<simple_index<chain_property_object > > >();
Expand Down Expand Up @@ -355,12 +355,19 @@ void database::init_genesis(const genesis_state_type& genesis_state)
n.owner.weight_threshold = 1;
n.active.weight_threshold = 1;
n.name = "committee-account";
n.statistics = create<account_statistics_object>( [&](account_statistics_object& s){ s.owner = n.id; }).id;
n.statistics = create<account_statistics_object>( [&n](account_statistics_object& s){
s.owner = n.id;
s.name = n.name;
s.core_in_balance = GRAPHENE_MAX_SHARE_SUPPLY;
}).id;
});
FC_ASSERT(committee_account.get_id() == GRAPHENE_COMMITTEE_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "witness-account";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_WITNESS_ACCOUNT;
Expand All @@ -370,7 +377,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_WITNESS_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "relaxed-committee-account";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_RELAXED_COMMITTEE_ACCOUNT;
Expand All @@ -380,7 +390,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_RELAXED_COMMITTEE_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "null-account";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_NULL_ACCOUNT;
Expand All @@ -390,7 +403,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_NULL_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "temp-account";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 0;
a.active.weight_threshold = 0;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_TEMP_ACCOUNT;
Expand All @@ -400,7 +416,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_TEMP_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "proxy-to-self";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_NULL_ACCOUNT;
Expand All @@ -410,7 +429,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
}).get_id() == GRAPHENE_PROXY_TO_SELF_ACCOUNT);
FC_ASSERT(create<account_object>([this](account_object& a) {
a.name = "default-dividend-distribution";
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = GRAPHENE_PROXY_TO_SELF_ACCOUNT;
Expand All @@ -424,9 +446,12 @@ void database::init_genesis(const genesis_state_type& genesis_state)
uint64_t id = get_index<account_object>().get_next_id().instance();
if( id >= genesis_state.immutable_parameters.num_special_accounts )
break;
const account_object& acct = create<account_object>([&](account_object& a) {
const account_object& acct = create<account_object>([this,id](account_object& a) {
a.name = "special-account-" + std::to_string(id);
a.statistics = create<account_statistics_object>([&](account_statistics_object& s){s.owner = a.id;}).id;
a.statistics = create<account_statistics_object>([&a](account_statistics_object& s){
s.owner = a.id;
s.name = a.name;
}).id;
a.owner.weight_threshold = 1;
a.active.weight_threshold = 1;
a.registrar = a.lifetime_referrer = a.referrer = account_id_type(id);
Expand All @@ -440,12 +465,12 @@ void database::init_genesis(const genesis_state_type& genesis_state)

// Create core asset
const asset_dynamic_data_object& dyn_asset =
create<asset_dynamic_data_object>([&](asset_dynamic_data_object& a) {
create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
a.current_supply = GRAPHENE_MAX_SHARE_SUPPLY;
});

const asset_dividend_data_object& div_asset =
create<asset_dividend_data_object>([&](asset_dividend_data_object& a) {
create<asset_dividend_data_object>([&genesis_state](asset_dividend_data_object& a) {
a.options.minimum_distribution_interval = 3*24*60*60;
a.options.minimum_fee_percentage = 10*GRAPHENE_1_PERCENT;
a.options.next_payout_time = genesis_state.initial_timestamp + fc::days(1);
Expand All @@ -454,7 +479,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
});

const asset_object& core_asset =
create<asset_object>( [&]( asset_object& a ) {
create<asset_object>( [&genesis_state,&div_asset,&dyn_asset]( asset_object& a ) {
a.symbol = GRAPHENE_SYMBOL;
a.options.max_supply = genesis_state.max_core_supply;
a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
Expand Down Expand Up @@ -512,10 +537,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
if( id >= genesis_state.immutable_parameters.num_special_assets )
break;
const asset_dynamic_data_object& dyn_asset =
create<asset_dynamic_data_object>([&](asset_dynamic_data_object& a) {
create<asset_dynamic_data_object>([](asset_dynamic_data_object& a) {
a.current_supply = 0;
});
const asset_object& asset_obj = create<asset_object>( [&]( asset_object& a ) {
const asset_object& asset_obj = create<asset_object>( [id,&dyn_asset]( asset_object& a ) {
a.symbol = "SPECIAL" + std::to_string( id );
a.options.max_supply = 0;
a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS;
Expand Down Expand Up @@ -679,7 +704,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
cop.active = cop.owner;
account_id_type owner_account_id = apply_operation(genesis_eval_state, cop).get<object_id_type>();

modify( owner_account_id(*this).statistics(*this), [&]( account_statistics_object& o ) {
modify( owner_account_id(*this).statistics(*this), [&collateral_rec]( account_statistics_object& o ) {
o.total_core_in_orders = collateral_rec.collateral;
});

Expand Down
Loading

0 comments on commit 0bcfaa3

Please sign in to comment.