diff --git a/.gitmodules b/.gitmodules index b3b4d866..4d3518d1 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,6 +3,7 @@ url = https://github.com/bitshares/bitshares-core.wiki.git ignore = dirty [submodule "libraries/fc"] - path = libraries/fc - url = https://github.com/peerplays-network/peerplays-fc.git - ignore = dirty + path = libraries/fc + url = https://github.com/peerplays-network/peerplays-fc.git + branch = latest-fc + ignore = dirty diff --git a/libraries/app/application.cpp b/libraries/app/application.cpp index c652a798..bcbe6659 100644 --- a/libraries/app/application.cpp +++ b/libraries/app/application.cpp @@ -226,7 +226,7 @@ namespace detail { void new_connection( const fc::http::websocket_connection_ptr& c ) { - auto wsc = std::make_shared(c, GRAPHENE_MAX_NESTED_OBJECTS); + auto wsc = std::make_shared(*c, GRAPHENE_MAX_NESTED_OBJECTS); auto login = std::make_shared( std::ref(*_self) ); login->enable_api("database_api"); diff --git a/libraries/chain/account_evaluator.cpp b/libraries/chain/account_evaluator.cpp index 96429304..ad6ac5dc 100644 --- a/libraries/chain/account_evaluator.cpp +++ b/libraries/chain/account_evaluator.cpp @@ -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& obj ){ - obj.registrar = o.registrar; - obj.referrer = o.referrer; - obj.lifetime_referrer = o.referrer(db()).lifetime_referrer; + const auto& new_acnt_object = d.create( [&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; - 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; + 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 = db().create([&](account_statistics_object& s){s.owner = obj.id;}).id; + obj.name = o.name; + obj.owner = o.owner; + obj.active = o.active; + obj.options = o.options; + obj.statistics = d.create([&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( 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 ) @@ -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().basic_fee <<= p.parameters.account_fee_scale_bitshifts; }); + } if( o.extensions.value.owner_special_authority.valid() || o.extensions.value.active_special_authority.valid() ) @@ -280,6 +287,9 @@ 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 ) @@ -289,11 +299,14 @@ void_result account_update_evaluator::do_apply( const account_update_operation& o.new_options->voting_account != acnt->options.voting_account) || (flag.valid() && *flag)) aso.last_vote_time = d.head_block_time(); + + if(o.new_options->is_voting() != acnt->options.is_voting()) + aso.is_voting = !aso.is_voting; } ); } - 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; @@ -305,7 +318,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); @@ -316,9 +328,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(); diff --git a/libraries/chain/account_object.cpp b/libraries/chain/account_object.cpp index e51e1705..c25abdd8 100644 --- a/libraries/chain/account_object.cpp +++ b/libraries/chain/account_object.cpp @@ -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 diff --git a/libraries/chain/db_balance.cpp b/libraries/chain/db_balance.cpp index 7a46df17..5029d3b7 100644 --- a/libraries/chain/db_balance.cpp +++ b/libraries/chain/db_balance.cpp @@ -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 ) @@ -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; diff --git a/libraries/chain/db_debug.cpp b/libraries/chain/db_debug.cpp index 0fa5eb58..27beb3ed 100644 --- a/libraries/chain/db_debug.cpp +++ b/libraries/chain/db_debug.cpp @@ -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().indices(); - const simple_index& statistics_index = db.get_index_type>(); + const auto& statistics_index = db.get_index_type().indices(); map total_balances; map total_debts; share_type core_in_orders; diff --git a/libraries/chain/db_getter.cpp b/libraries/chain/db_getter.cpp index aa50b551..d2be25de 100644 --- a/libraries/chain/db_getter.cpp +++ b/libraries/chain/db_getter.cpp @@ -141,4 +141,13 @@ const std::vector 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().indices().get(); + auto itr = idx.find( owner ); + FC_ASSERT( itr != idx.end(), "Can not find account statistics object for owner ${a}", ("a",owner) ); + return *itr; +} + + } } diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index b1fa7424..49d0a69f 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -295,7 +295,7 @@ void database::initialize_indexes() add_index< primary_index >(); add_index< primary_index> >(); add_index< primary_index> >(); - add_index< primary_index> >(); + add_index< primary_index >(); add_index< primary_index> >(); add_index< primary_index> >(); add_index< primary_index > >(); @@ -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& s){ s.owner = n.id; }).id; + n.statistics = create( [&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([this](account_object& a) { a.name = "witness-account"; - a.statistics = create([&](account_statistics_object& s){s.owner = a.id;}).id; + a.statistics = create([&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; @@ -370,7 +377,10 @@ void database::init_genesis(const genesis_state_type& genesis_state) }).get_id() == GRAPHENE_WITNESS_ACCOUNT); FC_ASSERT(create([this](account_object& a) { a.name = "relaxed-committee-account"; - a.statistics = create([&](account_statistics_object& s){s.owner = a.id;}).id; + a.statistics = create([&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; @@ -380,7 +390,10 @@ void database::init_genesis(const genesis_state_type& genesis_state) }).get_id() == GRAPHENE_RELAXED_COMMITTEE_ACCOUNT); FC_ASSERT(create([this](account_object& a) { a.name = "null-account"; - a.statistics = create([&](account_statistics_object& s){s.owner = a.id;}).id; + a.statistics = create([&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; @@ -390,7 +403,10 @@ void database::init_genesis(const genesis_state_type& genesis_state) }).get_id() == GRAPHENE_NULL_ACCOUNT); FC_ASSERT(create([this](account_object& a) { a.name = "temp-account"; - a.statistics = create([&](account_statistics_object& s){s.owner = a.id;}).id; + a.statistics = create([&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; @@ -400,7 +416,10 @@ void database::init_genesis(const genesis_state_type& genesis_state) }).get_id() == GRAPHENE_TEMP_ACCOUNT); FC_ASSERT(create([this](account_object& a) { a.name = "proxy-to-self"; - a.statistics = create([&](account_statistics_object& s){s.owner = a.id;}).id; + a.statistics = create([&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; @@ -410,7 +429,10 @@ void database::init_genesis(const genesis_state_type& genesis_state) }).get_id() == GRAPHENE_PROXY_TO_SELF_ACCOUNT); FC_ASSERT(create([this](account_object& a) { a.name = "default-dividend-distribution"; - a.statistics = create([&](account_statistics_object& s){s.owner = a.id;}).id; + a.statistics = create([&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; @@ -424,9 +446,12 @@ void database::init_genesis(const genesis_state_type& genesis_state) uint64_t id = get_index().get_next_id().instance(); if( id >= genesis_state.immutable_parameters.num_special_accounts ) break; - const account_object& acct = create([&](account_object& a) { + const account_object& acct = create([this,id](account_object& a) { a.name = "special-account-" + std::to_string(id); - a.statistics = create([&](account_statistics_object& s){s.owner = a.id;}).id; + a.statistics = create([&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); @@ -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& a) { + create([](asset_dynamic_data_object& a) { a.current_supply = GRAPHENE_MAX_SHARE_SUPPLY; }); const asset_dividend_data_object& div_asset = - create([&](asset_dividend_data_object& a) { + create([&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); @@ -454,7 +479,7 @@ void database::init_genesis(const genesis_state_type& genesis_state) }); const asset_object& core_asset = - create( [&]( asset_object& a ) { + create( [&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; @@ -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& a) { + create([](asset_dynamic_data_object& a) { a.current_supply = 0; }); - const asset_object& asset_obj = create( [&]( asset_object& a ) { + const asset_object& asset_obj = create( [id,&dyn_asset]( asset_object& a ) { a.symbol = "SPECIAL" + std::to_string( id ); a.options.max_supply = 0; a.precision = GRAPHENE_BLOCKCHAIN_PRECISION_DIGITS; @@ -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(); - 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; }); diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index f733bf92..84951923 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -76,12 +76,44 @@ vector> database::sort return refs; } -template -void database::perform_account_maintenance(std::tuple helpers) +template +void database::perform_account_maintenance(Type tally_helper) { - const auto& idx = get_index_type().indices().get(); - for( const account_object& a : idx ) - detail::for_each(helpers, a, detail::gen_seq()); + const auto& bal_idx = get_index_type< account_balance_index >().indices().get< by_maintenance_flag >(); + if( bal_idx.begin() != bal_idx.end() ) + { + auto bal_itr = bal_idx.rbegin(); + while( bal_itr->maintenance_flag ) + { + const account_balance_object& bal_obj = *bal_itr; + + modify( get_account_stats_by_owner( bal_obj.owner ), [&bal_obj](account_statistics_object& aso) { + aso.core_in_balance = bal_obj.balance; + }); + + modify( bal_obj, []( account_balance_object& abo ) { + abo.maintenance_flag = false; + }); + + bal_itr = bal_idx.rbegin(); + } + } + + const auto& stats_idx = get_index_type< account_stats_index >().indices().get< by_maintenance_seq >(); + auto stats_itr = stats_idx.lower_bound( true ); + + while( stats_itr != stats_idx.end() ) + { + const account_statistics_object& acc_stat = *stats_itr; + const account_object& acc_obj = acc_stat.owner( *this ); + ++stats_itr; + + if( acc_stat.has_some_core_voting() ) + tally_helper( acc_obj, acc_stat ); + + if( acc_stat.has_pending_fees() ) + acc_stat.process_fees( acc_obj, *this ); + } } /// @brief A visitor for @ref worker_type which calls pay_worker on the worker within @@ -1496,7 +1528,8 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g #endif } - void operator()(const account_object& stake_account) { + void operator()( const account_object& stake_account, const account_statistics_object& stats ) + { if( props.parameters.count_non_member_votes || stake_account.is_member(d.head_block_time()) ) { // There may be a difference between the account whose stake is voting and the one specifying opinions. @@ -1569,23 +1602,8 @@ void database::perform_chain_maintenance(const signed_block& next_block, const g } } } tally_helper(*this, gpo); - struct process_fees_helper { - database& d; - const global_property_object& props; - - process_fees_helper(database& d, const global_property_object& gpo) - : d(d), props(gpo) {} - - void operator()(const account_object& a) { - a.statistics(d).process_fees(a, d); - } - } fee_helper(*this, gpo); - - perform_account_maintenance(std::tie( - tally_helper, - fee_helper - )); - + + perform_account_maintenance( tally_helper ); struct clear_canary { clear_canary(vector& target): target(target){} ~clear_canary() { target.clear(); } diff --git a/libraries/chain/include/graphene/chain/account_object.hpp b/libraries/chain/include/graphene/chain/account_object.hpp index 4e940326..94a1b98e 100644 --- a/libraries/chain/include/graphene/chain/account_object.hpp +++ b/libraries/chain/include/graphene/chain/account_object.hpp @@ -46,6 +46,8 @@ namespace graphene { namespace chain { account_id_type owner; + string name; ///< redundantly store account name here for better maintenance performance + /** * Keep the most recent operation as a root pointer to a linked list of the transaction history. */ @@ -62,6 +64,19 @@ namespace graphene { namespace chain { */ share_type total_core_in_orders; + share_type core_in_balance = 0; ///< redundantly store core balance here for better maintenance performance + + bool has_cashback_vb = false; ///< redundantly store this for better maintenance performance + + bool is_voting = false; ///< redundately store whether this account is voting for better maintenance performance + + + /// Whether this account owns some CORE asset and is voting + inline bool has_some_core_voting() const + { + return is_voting && ( total_core_in_orders > 0 || core_in_balance > 0 || has_cashback_vb ); + } + /** * Tracks the total fees paid by this account for the purpose of calculating bulk discounts. */ @@ -87,6 +102,12 @@ namespace graphene { namespace chain { */ time_point_sec last_vote_time; + /// Whether this account has pending fees, no matter vested or not + inline bool has_pending_fees() const { return pending_fees > 0 || pending_vested_fees > 0; } + + /// Whether need to process this account during the maintenance interval + inline bool need_maintenance() const { return has_some_core_voting() || has_pending_fees(); } + /// @brief Split up and pay out @ref pending_fees and @ref pending_vested_fees void process_fees(const account_object& a, database& d) const; @@ -112,6 +133,7 @@ namespace graphene { namespace chain { account_id_type owner; asset_id_type asset_type; share_type balance; + bool maintenance_flag = false; ///< Whether need to process this balance object in maintenance interval asset get_balance()const { return asset(balance, asset_type); } void adjust_balance(const asset& delta); @@ -388,6 +410,9 @@ namespace graphene { namespace chain { }; struct by_asset_balance; + struct by_maintenance_flag; + struct by_account_asset; + /** * @ingroup object_index */ @@ -395,6 +420,15 @@ namespace graphene { namespace chain { account_balance_object, indexed_by< ordered_unique< tag, member< object, object_id_type, &object::id > >, + ordered_non_unique< tag, + member< account_balance_object, bool, &account_balance_object::maintenance_flag > >, + ordered_unique< tag, + composite_key< + account_balance_object, + member, + member + > + >, ordered_unique< tag, composite_key< account_balance_object, @@ -434,26 +468,6 @@ namespace graphene { namespace chain { */ typedef generic_index account_index; - struct by_owner; - struct by_maintenance_seq; - - /** - * @ingroup object_index - */ - typedef multi_index_container< - account_statistics_object, - indexed_by< - ordered_unique< tag, member< object, object_id_type, &object::id > >, - ordered_unique< tag, - member< account_statistics_object, account_id_type, &account_statistics_object::owner > > - > - > account_stats_multi_index_type; - - /** - * @ingroup object_index - */ - typedef generic_index account_stats_index; - struct by_dividend_payout_account{}; // use when calculating pending payouts struct by_dividend_account_payout{}; // use when doing actual payouts struct by_account_dividend_payout{}; // use in get_full_accounts() @@ -497,6 +511,33 @@ namespace graphene { namespace chain { */ typedef generic_index pending_dividend_payout_balance_for_holder_object_index; + struct by_owner; + struct by_maintenance_seq; + + /** + * @ingroup object_index + */ + typedef multi_index_container< + account_statistics_object, + indexed_by< + ordered_unique< tag, member< object, object_id_type, &object::id > >, + ordered_unique< tag, + member< account_statistics_object, account_id_type, &account_statistics_object::owner > >, + ordered_unique< tag, + composite_key< + account_statistics_object, + const_mem_fun, + member + > + > + > + > account_stats_multi_index_type; + + /** + * @ingroup object_index + */ + typedef generic_index account_stats_index; + }} FC_REFLECT_DERIVED( graphene::chain::account_object, @@ -513,14 +554,17 @@ FC_REFLECT_DERIVED( graphene::chain::account_object, FC_REFLECT_DERIVED( graphene::chain::account_balance_object, (graphene::db::object), - (owner)(asset_type)(balance) ) + (owner)(asset_type)(balance)(maintenance_flag) ) FC_REFLECT_DERIVED( graphene::chain::account_statistics_object, (graphene::chain::object), - (owner) + (owner)(name) (most_recent_op) (total_ops)(removed_ops) (total_core_in_orders) + (core_in_balance) + (has_cashback_vb) + (is_voting) (lifetime_fees_paid) (pending_fees)(pending_vested_fees) (last_vote_time) diff --git a/libraries/chain/include/graphene/chain/config.hpp b/libraries/chain/include/graphene/chain/config.hpp index 933f5997..710db6c5 100644 --- a/libraries/chain/include/graphene/chain/config.hpp +++ b/libraries/chain/include/graphene/chain/config.hpp @@ -151,7 +151,7 @@ #define GRAPHENE_RECENTLY_MISSED_COUNT_INCREMENT 4 #define GRAPHENE_RECENTLY_MISSED_COUNT_DECREMENT 3 -#define GRAPHENE_CURRENT_DB_VERSION "PPY2.2" +#define GRAPHENE_CURRENT_DB_VERSION "PPY2.3" #define GRAPHENE_IRREVERSIBLE_THRESHOLD (70 * GRAPHENE_1_PERCENT) diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 571be20a..c293b11e 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -276,6 +276,7 @@ namespace graphene { namespace chain { const dynamic_global_property_object& get_dynamic_global_properties()const; const node_property_object& get_node_properties()const; const fee_schedule& current_fee_schedule()const; + const account_statistics_object& get_account_stats_by_owner( account_id_type owner )const; const std::vector get_winner_numbers( asset_id_type for_asset, uint32_t count_members, uint8_t count_winners ) const; std::vector get_seeds( asset_id_type for_asset, uint8_t count_winners )const; uint64_t get_random_bits( uint64_t bound ); @@ -527,8 +528,8 @@ namespace graphene { namespace chain { double calculate_vesting_factor(const account_object& stake_account); uint32_t get_gpos_current_subperiod(); - template - void perform_account_maintenance(std::tuple helpers); + template + void perform_account_maintenance(Type tally_helper); ///@} ///@} diff --git a/libraries/chain/include/graphene/chain/protocol/account.hpp b/libraries/chain/include/graphene/chain/protocol/account.hpp index 6a8aa20c..5f4c730a 100644 --- a/libraries/chain/include/graphene/chain/protocol/account.hpp +++ b/libraries/chain/include/graphene/chain/protocol/account.hpp @@ -56,6 +56,12 @@ namespace graphene { namespace chain { /// account's balance of core asset. flat_set votes; extensions_type extensions; + + /// Whether this account is voting + inline bool is_voting() const + { + return ( voting_account != GRAPHENE_PROXY_TO_SELF_ACCOUNT || !votes.empty() ); + } void validate()const; }; diff --git a/libraries/fc b/libraries/fc index 6096e94e..1f76279f 160000 --- a/libraries/fc +++ b/libraries/fc @@ -1 +1 @@ -Subproject commit 6096e94e1b4c48a393c9335580365df144f2758f +Subproject commit 1f76279f6373468ba7f672c92fb9d1626263fa61 diff --git a/libraries/plugins/delayed_node/delayed_node_plugin.cpp b/libraries/plugins/delayed_node/delayed_node_plugin.cpp index 2db7fa9b..f9db2ccd 100644 --- a/libraries/plugins/delayed_node/delayed_node_plugin.cpp +++ b/libraries/plugins/delayed_node/delayed_node_plugin.cpp @@ -65,7 +65,7 @@ void delayed_node_plugin::plugin_set_program_options(bpo::options_description& c void delayed_node_plugin::connect() { - my->client_connection = std::make_shared(my->client.connect(my->remote_endpoint), GRAPHENE_MAX_NESTED_OBJECTS); + my->client_connection = std::make_shared(*my->client.connect(my->remote_endpoint), GRAPHENE_MAX_NESTED_OBJECTS); my->database_api = my->client_connection->get_remote_api(0); my->client_connection_closed = my->client_connection->closed.connect([this] { connection_failed(); diff --git a/programs/cli_wallet/main.cpp b/programs/cli_wallet/main.cpp index d68f25b8..9cb8750d 100644 --- a/programs/cli_wallet/main.cpp +++ b/programs/cli_wallet/main.cpp @@ -174,7 +174,7 @@ int main( int argc, char** argv ) fc::http::websocket_client client; idump((wdata.ws_server)); auto con = client.connect( wdata.ws_server ); - auto apic = std::make_shared(con, GRAPHENE_MAX_NESTED_OBJECTS); + auto apic = std::make_shared(*con, GRAPHENE_MAX_NESTED_OBJECTS); auto remote_api = apic->get_remote_api< login_api >(1); edump((wdata.ws_user)(wdata.ws_password) ); @@ -213,7 +213,7 @@ int main( int argc, char** argv ) _websocket_server->on_connection([&wapi]( const fc::http::websocket_connection_ptr& c ){ std::cout << "here... \n"; wlog("." ); - auto wsc = std::make_shared(c, GRAPHENE_MAX_NESTED_OBJECTS); + auto wsc = std::make_shared(*c, GRAPHENE_MAX_NESTED_OBJECTS); wsc->register_api(wapi); c->set_session_data( wsc ); }); @@ -230,7 +230,7 @@ int main( int argc, char** argv ) if( options.count("rpc-tls-endpoint") ) { _websocket_tls_server->on_connection([&]( const fc::http::websocket_connection_ptr& c ){ - auto wsc = std::make_shared(c, GRAPHENE_MAX_NESTED_OBJECTS); + auto wsc = std::make_shared(*c, GRAPHENE_MAX_NESTED_OBJECTS); wsc->register_api(wapi); c->set_session_data( wsc ); }); diff --git a/tests/cli/main.cpp b/tests/cli/main.cpp index 8fd5b5f4..cfde25d6 100644 --- a/tests/cli/main.cpp +++ b/tests/cli/main.cpp @@ -222,7 +222,7 @@ public: wallet_data.ws_password = ""; websocket_connection = websocket_client.connect( wallet_data.ws_server ); - api_connection = std::make_shared(websocket_connection, GRAPHENE_MAX_NESTED_OBJECTS); + api_connection = std::make_shared(*websocket_connection, GRAPHENE_MAX_NESTED_OBJECTS); remote_login_api = api_connection->get_remote_api< graphene::app::login_api >(1); BOOST_CHECK(remote_login_api->login( wallet_data.ws_user, wallet_data.ws_password ) ); diff --git a/tests/common/database_fixture.cpp b/tests/common/database_fixture.cpp index d613bfba..0728ce2d 100644 --- a/tests/common/database_fixture.cpp +++ b/tests/common/database_fixture.cpp @@ -197,7 +197,7 @@ void database_fixture::verify_asset_supplies( const database& db ) const asset_dynamic_data_object& core_asset_data = db.get_core_asset().dynamic_asset_data_id(db); BOOST_CHECK(core_asset_data.fee_pool == 0); - const simple_index& statistics_index = db.get_index_type>(); + const auto& statistics_index = db.get_index_type().indices(); const auto& balance_index = db.get_index_type().indices(); const auto& settle_index = db.get_index_type().indices(); const auto& tournaments_index = db.get_index_type().indices(); diff --git a/tests/tests/voting_tests.cpp b/tests/tests/voting_tests.cpp index 870fd359..71c5e935 100644 --- a/tests/tests/voting_tests.cpp +++ b/tests/tests/voting_tests.cpp @@ -48,7 +48,7 @@ BOOST_AUTO_TEST_CASE(last_voting_date) // we are going to vote for this witness auto witness1 = witness_id_type(1)(db); - auto stats_obj = alice_id(db).statistics(db); + auto stats_obj = db.get_account_stats_by_owner(alice_id); BOOST_CHECK_EQUAL(stats_obj.last_vote_time.sec_since_epoch(), 0); // alice votes @@ -63,7 +63,7 @@ BOOST_AUTO_TEST_CASE(last_voting_date) auto now = db.head_block_time().sec_since_epoch(); // last_vote_time is updated for alice - stats_obj = alice_id(db).statistics(db); + stats_obj = db.get_account_stats_by_owner(alice_id); BOOST_CHECK_EQUAL(stats_obj.last_vote_time.sec_since_epoch(), now); } FC_LOG_AND_RETHROW()