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

Improve update_expired_feeds performance #1093 #1180

Merged
merged 16 commits into from
Jul 27, 2018
Merged
Show file tree
Hide file tree
Changes from 12 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
8 changes: 4 additions & 4 deletions libraries/chain/account_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ void account_statistics_object::process_fees(const account_object& a, database&
// Check the referrer -- if he's no longer a member, pay to the lifetime referrer instead.
// No need to check the registrar; registrars are required to be lifetime members.
if( account.referrer(d).is_basic_account(d.head_block_time()) )
d.modify(account, [](account_object& a) {
a.referrer = a.lifetime_referrer;
d.modify( account, [](account_object& acc) {
acc.referrer = acc.lifetime_referrer;
});

share_type network_cut = cut_fee(core_fee_total, account.network_fee_percentage);
Expand All @@ -76,8 +76,8 @@ void account_statistics_object::process_fees(const account_object& a, database&
share_type lifetime_cut = cut_fee(core_fee_total, account.lifetime_referrer_fee_percentage);
share_type referral = core_fee_total - network_cut - lifetime_cut;

d.modify(asset_dynamic_data_id_type()(d), [network_cut](asset_dynamic_data_object& d) {
d.accumulated_fees += network_cut;
d.modify( d.get_core_dynamic_data(), [network_cut](asset_dynamic_data_object& addo) {
addo.accumulated_fees += network_cut;
});

// Potential optimization: Skip some of this math and object lookups by special casing on the account type.
Expand Down
34 changes: 24 additions & 10 deletions libraries/chain/asset_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,14 +118,14 @@ object_id_type asset_create_evaluator::do_apply( const asset_create_operation& o
bool hf_429 = fee_is_odd && db().head_block_time() > HARDFORK_CORE_429_TIME;

const asset_dynamic_data_object& dyn_asset =
db().create<asset_dynamic_data_object>( [&]( asset_dynamic_data_object& a ) {
db().create<asset_dynamic_data_object>( [hf_429,this]( asset_dynamic_data_object& a ) {
a.current_supply = 0;
a.fee_pool = core_fee_paid - (hf_429 ? 1 : 0);
});
if( fee_is_odd && !hf_429 )
{
const auto& core_dd = db().get<asset_object>( asset_id_type() ).dynamic_data( db() );
db().modify( core_dd, [=]( asset_dynamic_data_object& dd ) {
const auto& core_dd = db().get_core_asset().dynamic_data( db() );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use db().get_core_dynamic_data() instead

db().modify( core_dd, []( asset_dynamic_data_object& dd ) {
dd.current_supply++;
});
}
Expand All @@ -135,14 +135,14 @@ object_id_type asset_create_evaluator::do_apply( const asset_create_operation& o
auto next_asset_id = db().get_index_type<asset_index>().get_next_id();

if( op.bitasset_opts.valid() )
bit_asset_id = db().create<asset_bitasset_data_object>( [&]( asset_bitasset_data_object& a ) {
bit_asset_id = db().create<asset_bitasset_data_object>( [&op,next_asset_id]( asset_bitasset_data_object& a ) {
a.options = *op.bitasset_opts;
a.is_prediction_market = op.is_prediction_market;
a.asset_id = next_asset_id;
}).id;

const asset_object& new_asset =
db().create<asset_object>( [&]( asset_object& a ) {
db().create<asset_object>( [&op,next_asset_id,&dyn_asset,bit_asset_id]( asset_object& a ) {
a.issuer = op.issuer;
a.symbol = op.symbol;
a.precision = op.precision;
Expand All @@ -155,7 +155,7 @@ object_id_type asset_create_evaluator::do_apply( const asset_create_operation& o
if( op.bitasset_opts.valid() )
a.bitasset_data_id = bit_asset_id;
});
assert( new_asset.id == next_asset_id );
FC_ASSERT( new_asset.id == next_asset_id );

return new_asset.id;
} FC_CAPTURE_AND_RETHROW( (op) ) }
Expand All @@ -181,7 +181,7 @@ void_result asset_issue_evaluator::do_apply( const asset_issue_operation& o )
{ try {
db().adjust_balance( o.issue_to_account, o.asset_to_issue );

db().modify( *asset_dyn_data, [&]( asset_dynamic_data_object& data ){
db().modify( *asset_dyn_data, [&o]( asset_dynamic_data_object& data ){
data.current_supply += o.asset_to_issue.amount;
});

Expand Down Expand Up @@ -213,7 +213,7 @@ void_result asset_reserve_evaluator::do_apply( const asset_reserve_operation& o
{ try {
db().adjust_balance( o.payer, -o.amount_to_reserve );

db().modify( *asset_dyn_data, [&]( asset_dynamic_data_object& data ){
db().modify( *asset_dyn_data, [&o]( asset_dynamic_data_object& data ){
data.current_supply -= o.amount_to_reserve.amount;
});

Expand All @@ -235,7 +235,7 @@ void_result asset_fund_fee_pool_evaluator::do_apply(const asset_fund_fee_pool_op
{ try {
db().adjust_balance(o.from_account, -o.amount);

db().modify( *asset_dyn_data, [&]( asset_dynamic_data_object& data ) {
db().modify( *asset_dyn_data, [&o]( asset_dynamic_data_object& data ) {
data.fee_pool += o.amount;
});

Expand Down Expand Up @@ -319,7 +319,21 @@ void_result asset_update_evaluator::do_apply(const asset_update_operation& o)
d.cancel_settle_order(*itr);
}

d.modify(*asset_to_update, [&](asset_object& a) {
// For market-issued assets, if core change rate changed, update flag in bitasset data
if( asset_to_update->is_market_issued()
&& asset_to_update->options.core_exchange_rate != o.new_options.core_exchange_rate )
{
const auto& bitasset = asset_to_update->bitasset_data(d);
if( !bitasset.asset_cer_updated )
{
d.modify( bitasset, [](asset_bitasset_data_object& b)
{
b.asset_cer_updated = true;
});
}
}

d.modify(*asset_to_update, [&o](asset_object& a) {
if( o.new_issuer )
a.issuer = *o.new_issuer;
a.options = o.new_options;
Expand Down
5 changes: 5 additions & 0 deletions libraries/chain/asset_object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,15 @@ void graphene::chain::asset_bitasset_data_object::update_median_feeds(time_point
if( current_feeds.size() < options.minimum_feeds )
{
//... don't calculate a median, and set a null feed
feed_cer_updated = false; // new median cer is null, won't update asset_object anyway, set to false for better performance
current_feed_publication_time = current_time;
current_feed = price_feed();
return;
}
if( current_feeds.size() == 1 )
{
if( current_feed.core_exchange_rate != current_feeds.front().get().core_exchange_rate )
feed_cer_updated = true;
current_feed = std::move(current_feeds.front());
return;
}
Expand All @@ -94,6 +97,8 @@ void graphene::chain::asset_bitasset_data_object::update_median_feeds(time_point
#undef CALCULATE_MEDIAN_VALUE
// *** End Median Calculations ***

if( current_feed.core_exchange_rate != median_feed.core_exchange_rate )
feed_cer_updated = true;
current_feed = median_feed;
}

Expand Down
2 changes: 1 addition & 1 deletion libraries/chain/db_balance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ void database::deposit_cashback(const account_object& acct, share_type amount, b
acct.get_id() == GRAPHENE_TEMP_ACCOUNT )
{
// The blockchain's accounts do not get cashback; it simply goes to the reserve pool.
modify(get(asset_id_type()).dynamic_asset_data_id(*this), [amount](asset_dynamic_data_object& d) {
modify( get_core_dynamic_data(), [amount](asset_dynamic_data_object& d) {
d.current_supply -= amount;
});
return;
Expand Down
7 changes: 5 additions & 2 deletions libraries/chain/db_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -503,12 +503,14 @@ void database::_apply_block( const signed_block& next_block )

const witness_object& signing_witness = validate_block_header(skip, next_block);
const auto& global_props = get_global_properties();
const auto& dynamic_global_props = get<dynamic_global_property_object>(dynamic_global_property_id_type());
const auto& dynamic_global_props = get_dynamic_global_properties();
bool maint_needed = (dynamic_global_props.next_maintenance_time <= next_block.timestamp);

_current_block_num = next_block_num;
_current_trx_in_block = 0;

_issue_453_affected_assets.clear();

for( const auto& trx : next_block.transactions )
{
/* We do not need to push the undo state for each transaction
Expand All @@ -534,7 +536,8 @@ void database::_apply_block( const signed_block& next_block )
clear_expired_transactions();
clear_expired_proposals();
clear_expired_orders();
update_expired_feeds();
update_expired_feeds(); // this will update expired feeds and some core exchange rates
update_core_exchange_rates(); // this will update remaining core exchange rates
update_withdraw_permissions();

// n.b., update_maintenance_flag() happens this late
Expand Down
26 changes: 18 additions & 8 deletions libraries/chain/db_getter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,27 @@ namespace graphene { namespace chain {

const asset_object& database::get_core_asset() const
{
return get(asset_id_type());
return *_p_core_asset_obj;
}

const asset_dynamic_data_object& database::get_core_dynamic_data() const
{
return *_p_core_dynamic_data_obj;
}

const global_property_object& database::get_global_properties()const
{
return get( global_property_id_type() );
return *_p_global_prop_obj;
}

const chain_property_object& database::get_chain_properties()const
{
return get( chain_property_id_type() );
return *_p_chain_property_obj;
}

const dynamic_global_property_object&database::get_dynamic_global_properties() const
const dynamic_global_property_object& database::get_dynamic_global_properties() const
{
return get( dynamic_global_property_id_type() );
return *_p_dyn_global_prop_obj;
}

const fee_schedule& database::current_fee_schedule()const
Expand All @@ -59,17 +64,17 @@ const fee_schedule& database::current_fee_schedule()const

time_point_sec database::head_block_time()const
{
return get( dynamic_global_property_id_type() ).time;
return get_dynamic_global_properties().time;
}

uint32_t database::head_block_num()const
{
return get( dynamic_global_property_id_type() ).head_block_number;
return get_dynamic_global_properties().head_block_number;
}

block_id_type database::head_block_id()const
{
return get( dynamic_global_property_id_type() ).head_block_id;
return get_dynamic_global_properties().head_block_id;
}

decltype( chain_parameters::block_interval ) database::block_interval( )const
Expand Down Expand Up @@ -105,4 +110,9 @@ const account_statistics_object& database::get_account_stats_by_owner( account_i
return *itr;
}

const witness_schedule_object& database::get_witness_schedule_object()const
{
return *_p_witness_schedule_obj;
}

} }
16 changes: 9 additions & 7 deletions libraries/chain/db_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,10 @@ void database::init_genesis(const genesis_state_type& genesis_state)
a.options.core_exchange_rate.quote.asset_id = asset_id_type(0);
a.dynamic_asset_data_id = dyn_asset.id;
});
assert( asset_id_type(core_asset.id) == asset().asset_id );
assert( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) );
FC_ASSERT( asset_id_type(core_asset.id) == asset().asset_id );
FC_ASSERT( get_balance(account_id_type(), asset_id_type()) == asset(dyn_asset.current_supply) );
_p_core_asset_obj = &core_asset;
_p_core_dynamic_data_obj = &dyn_asset;
// Create more special assets
while( true )
{
Expand Down Expand Up @@ -405,14 +407,14 @@ void database::init_genesis(const genesis_state_type& genesis_state)
chain_id_type chain_id = genesis_state.compute_chain_id();

// Create global properties
create<global_property_object>([&](global_property_object& p) {
_p_global_prop_obj = & create<global_property_object>([&genesis_state](global_property_object& p) {
p.parameters = genesis_state.initial_parameters;
// Set fees to zero initially, so that genesis initialization needs not pay them
// We'll fix it at the end of the function
p.parameters.current_fees->zero_all_fees();

});
create<dynamic_global_property_object>([&](dynamic_global_property_object& p) {
_p_dyn_global_prop_obj = & create<dynamic_global_property_object>([&genesis_state](dynamic_global_property_object& p) {
p.time = genesis_state.initial_timestamp;
p.dynamic_flags = 0;
p.witness_budget = 0;
Expand All @@ -422,7 +424,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
FC_ASSERT( (genesis_state.immutable_parameters.min_witness_count & 1) == 1, "min_witness_count must be odd" );
FC_ASSERT( (genesis_state.immutable_parameters.min_committee_member_count & 1) == 1, "min_committee_member_count must be odd" );

create<chain_property_object>([&](chain_property_object& p)
_p_chain_property_obj = & create<chain_property_object>([chain_id,&genesis_state](chain_property_object& p)
{
p.chain_id = chain_id;
p.immutable_parameters = genesis_state.immutable_parameters;
Expand Down Expand Up @@ -670,7 +672,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
});

// Set active witnesses
modify(get_global_properties(), [&](global_property_object& p) {
modify(get_global_properties(), [&genesis_state](global_property_object& p) {
for( uint32_t i = 1; i <= genesis_state.initial_active_witnesses; ++i )
{
p.active_witnesses.insert(witness_id_type(i));
Expand All @@ -683,7 +685,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
});

// Create witness scheduler
create<witness_schedule_object>([&]( witness_schedule_object& wso )
_p_witness_schedule_obj = & create<witness_schedule_object>([this]( witness_schedule_object& wso )
{
for( const witness_id_type& wid : get_global_properties().active_witnesses )
wso.current_shuffled_witnesses.push_back( wid );
Expand Down
Loading