31 #include <graphene/chain/hardfork.hpp>
51 namespace graphene {
namespace chain {
54 vector<std::reference_wrapper<const typename Index::object_type>> database::sort_votable_objects(
size_t count)
const
56 using ObjectType =
typename Index::object_type;
57 const auto& all_objects = get_index_type<Index>().indices();
58 count = std::min(count, all_objects.size());
59 vector<std::reference_wrapper<const ObjectType>> refs;
60 refs.reserve(all_objects.size());
62 std::back_inserter(refs),
63 [](
const ObjectType& o) { return std::cref(o); });
64 std::partial_sort(refs.begin(), refs.begin() + count, refs.end(),
65 [
this](
const ObjectType& a,
const ObjectType& b)->bool {
66 share_type oa_vote = _vote_tally_buffer[a.vote_id];
67 share_type ob_vote = _vote_tally_buffer[b.vote_id];
68 if( oa_vote != ob_vote )
69 return oa_vote > ob_vote;
70 return a.vote_id < b.vote_id;
73 refs.resize(count, refs.front());
78 void database::perform_account_maintenance(Type tally_helper)
80 const auto& bal_idx = get_index_type< account_balance_index >().indices().get< by_maintenance_flag >();
81 if( bal_idx.begin() != bal_idx.end() )
83 auto bal_itr = bal_idx.rbegin();
84 while( bal_itr->maintenance_flag )
86 const account_balance_object& bal_obj = *bal_itr;
89 aso.core_in_balance = bal_obj.balance;
92 modify( bal_obj, []( account_balance_object& abo ) {
93 abo.maintenance_flag =
false;
96 bal_itr = bal_idx.rbegin();
100 const auto& stats_idx = get_index_type< account_stats_index >().indices().get< by_maintenance_seq >();
101 auto stats_itr = stats_idx.lower_bound(
true );
103 while( stats_itr != stats_idx.end() )
105 const account_statistics_object& acc_stat = *stats_itr;
106 const account_object& acc_obj = acc_stat.owner( *
this );
109 if( acc_stat.has_some_core_voting() )
110 tally_helper( acc_obj, acc_stat );
112 if( acc_stat.has_pending_fees() )
113 acc_stat.process_fees( acc_obj, *
this );
127 : pay(pay), db(db) {}
133 worker.pay_worker(pay, db);
137 void database::update_worker_votes()
139 const auto& idx = get_index_type<worker_index>().indices().get<by_account>();
140 auto itr = idx.begin();
141 auto itr_end = idx.end();
143 while( itr != itr_end )
145 modify( *itr, [
this,allow_negative_votes]( worker_object& obj )
147 obj.total_votes_for = _vote_tally_buffer[obj.vote_for];
148 obj.total_votes_against = allow_negative_votes ? _vote_tally_buffer[obj.vote_against] : 0;
154 void database::pay_workers(
share_type& budget )
158 vector<std::reference_wrapper<const worker_object>> active_workers;
160 get_index_type<worker_index>().inspect_all_objects([head_time, &active_workers](
const object& o) {
161 const worker_object& w =
static_cast<const worker_object&
>(o);
162 if( w.is_active(head_time) && w.approving_stake() > 0 )
163 active_workers.emplace_back(w);
168 std::sort(active_workers.begin(), active_workers.end(), [](
const worker_object& wa,
const worker_object& wb) {
169 share_type wa_vote = wa.approving_stake();
170 share_type wb_vote = wb.approving_stake();
171 if( wa_vote != wb_vote )
172 return wa_vote > wb_vote;
173 return wa.id < wb.id;
177 const auto passed_time_ms = head_time - last_budget_time;
178 const auto passed_time_count = passed_time_ms.count();
180 for( uint32_t i = 0; i < active_workers.size() && budget > 0; ++i )
182 const worker_object& active_worker = active_workers[i];
183 share_type requested_pay = active_worker.daily_pay;
188 fc::uint128_t pay = requested_pay.
value;
189 pay *= passed_time_count;
191 requested_pay =
static_cast<uint64_t
>(pay);
193 share_type actual_pay = std::min(budget, requested_pay);
195 modify(active_worker, [&](worker_object& w) {
196 w.worker.visit(worker_pay_visitor(actual_pay, *
this));
199 budget -= actual_pay;
203 void database::update_active_witnesses()
205 assert( !_witness_count_histogram_buffer.empty() );
206 constexpr
size_t two = 2;
208 share_type stake_target = (_total_voting_stake[vid_witness]-_witness_count_histogram_buffer[0]) / two;
215 size_t witness_count = 0;
216 if( stake_target > 0 )
218 while( (witness_count < _witness_count_histogram_buffer.size() - 1)
219 && (stake_tally <= stake_target) )
221 stake_tally += _witness_count_histogram_buffer[++witness_count];
227 witness_count = std::max( ( witness_count * two ) + 1,
228 (
size_t)cpo.immutable_parameters.min_witness_count );
229 auto wits = sort_votable_objects<witness_index>( witness_count );
233 auto update_witness_total_votes = [
this](
const witness_object& wit ) {
234 modify( wit, [
this]( witness_object& obj )
236 obj.total_votes = _vote_tally_buffer[obj.vote_id];
240 if( _track_standby_votes )
242 const auto& all_witnesses = get_index_type<witness_index>().indices();
243 for(
const witness_object& wit : all_witnesses )
245 update_witness_total_votes( wit );
250 for(
const witness_object& wit : wits )
252 update_witness_total_votes( wit );
261 uint64_t total_votes = 0;
262 map<account_id_type, uint64_t> weights;
263 a.active.weight_threshold = 0;
266 for(
const witness_object& wit : wits )
268 weights.emplace(wit.witness_account, _vote_tally_buffer[wit.vote_id]);
269 total_votes += _vote_tally_buffer[wit.vote_id];
274 uint64_t votes_msb = boost::multiprecision::detail::find_msb(total_votes);
275 constexpr uint8_t bits_to_keep_minus_one = 15;
276 uint64_t bits_to_drop = (votes_msb > bits_to_keep_minus_one) ? (votes_msb - bits_to_keep_minus_one) : 0;
277 for(
const auto& weight : weights )
280 uint16_t votes = std::max((uint16_t)(weight.second >> bits_to_drop), uint16_t(1) );
281 a.active.account_auths[weight.first] += votes;
282 a.active.weight_threshold += votes;
285 a.active.weight_threshold /= two;
286 a.active.weight_threshold += 1;
291 for(
const witness_object& wit : wits )
292 vc.add( wit.witness_account, _vote_tally_buffer[wit.vote_id] );
293 vc.finish( a.active );
297 modify( gpo, [&wits]( global_property_object& gp )
299 gp.active_witnesses.clear();
300 gp.active_witnesses.reserve(wits.size());
302 std::inserter(gp.active_witnesses, gp.active_witnesses.end()),
303 [](
const witness_object& w) {
310 void database::update_active_committee_members()
312 assert( !_committee_count_histogram_buffer.empty() );
313 constexpr
size_t two = 2;
315 share_type stake_target = (_total_voting_stake[vid_committee]-_committee_count_histogram_buffer[0]) / two;
320 size_t committee_member_count = 0;
321 if( stake_target > 0 )
323 while( (committee_member_count < _committee_count_histogram_buffer.size() - 1)
324 && (stake_tally <= stake_target.value) )
326 stake_tally += _committee_count_histogram_buffer[++committee_member_count];
332 committee_member_count = std::max( ( committee_member_count * two ) + 1,
333 (
size_t)cpo.immutable_parameters.min_committee_member_count );
334 auto committee_members = sort_votable_objects<committee_member_index>( committee_member_count );
336 auto update_committee_member_total_votes = [
this](
const committee_member_object& cm ) {
337 modify( cm, [
this]( committee_member_object& obj )
339 obj.total_votes = _vote_tally_buffer[obj.vote_id];
343 if( _track_standby_votes )
345 const auto& all_committee_members = get_index_type<committee_member_index>().indices();
346 for(
const committee_member_object& cm : all_committee_members )
348 update_committee_member_total_votes( cm );
353 for(
const committee_member_object& cm : committee_members )
355 update_committee_member_total_votes( cm );
360 if( !committee_members.empty() )
363 modify( committee_account, [
this,&committee_members](account_object& a)
367 uint64_t total_votes = 0;
368 map<account_id_type, uint64_t> weights;
369 a.active.weight_threshold = 0;
372 for(
const committee_member_object& cm : committee_members )
374 weights.emplace( cm.committee_member_account, _vote_tally_buffer[cm.vote_id] );
375 total_votes += _vote_tally_buffer[cm.vote_id];
381 uint64_t votes_msb = boost::multiprecision::detail::find_msb(total_votes);
382 constexpr uint8_t bits_to_keep_minus_one = 15;
383 uint64_t bits_to_drop = (votes_msb > bits_to_keep_minus_one) ? (votes_msb - bits_to_keep_minus_one) : 0;
384 for(
const auto& weight : weights )
387 uint16_t votes = std::max((uint16_t)(weight.second >> bits_to_drop), uint16_t(1) );
388 a.active.account_auths[weight.first] += votes;
389 a.active.weight_threshold += votes;
392 a.active.weight_threshold /= two;
393 a.active.weight_threshold += 1;
398 for(
const committee_member_object& cm : committee_members )
399 vc.add( cm.committee_member_account, _vote_tally_buffer[cm.vote_id] );
400 vc.finish( a.active );
405 a.active = committee_account.active;
411 std::transform(committee_members.begin(), committee_members.end(),
412 std::inserter(gp.active_committee_members, gp.active_committee_members.begin()),
413 [](
const committee_member_object& d) { return d.get_id(); });
417 void database::initialize_budget_record(
fc::time_point_sec now, budget_record& rec )
const
423 rec.from_initial_reserve = core.reserved(*
this);
424 rec.from_accumulated_fees = core_dd.accumulated_fees;
425 rec.from_unused_witness_budget = dpo.witness_budget;
426 rec.max_supply = core.options.max_supply;
429 || (now <= dpo.last_budget_time) )
431 rec.time_since_last_budget = 0;
435 int64_t dt = (now - dpo.last_budget_time).to_seconds();
436 rec.time_since_last_budget = uint64_t( dt );
444 share_type reserve = rec.from_initial_reserve + core_dd.accumulated_fees;
447 reserve += dpo.witness_budget;
449 fc::uint128_t budget_u128 = reserve.
value;
450 budget_u128 *= uint64_t(dt);
457 if( budget_u128 <
static_cast<fc::uint128_t
>(reserve.value) )
458 rec.total_budget =
share_type(
static_cast<uint64_t
>(budget_u128));
460 rec.total_budget = reserve;
468 void database::process_budget()
477 int64_t time_to_maint = (dpo.next_maintenance_time - now).to_seconds();
483 assert( time_to_maint > 0 );
489 assert( gpo.parameters.block_interval > 0 );
490 uint64_t blocks_to_maint = ( ( uint64_t(time_to_maint) + gpo.parameters.block_interval ) - 1 )
491 / gpo.parameters.block_interval;
497 initialize_budget_record( now, rec );
498 share_type available_funds = rec.total_budget;
500 share_type witness_budget = gpo.parameters.witness_pay_per_block.
value * blocks_to_maint;
501 rec.requested_witness_budget = witness_budget;
502 witness_budget = std::min(witness_budget, available_funds);
503 rec.witness_budget = witness_budget;
504 available_funds -= witness_budget;
506 fc::uint128_t worker_budget_u128 = gpo.parameters.worker_budget_per_day.value;
507 worker_budget_u128 *= uint64_t(time_to_maint);
508 constexpr uint64_t seconds_per_day = 86400;
509 worker_budget_u128 /= seconds_per_day;
512 if( worker_budget_u128 >=
static_cast<fc::uint128_t
>(available_funds.value) )
513 worker_budget = available_funds;
515 worker_budget =
static_cast<uint64_t
>(worker_budget_u128);
516 rec.worker_budget = worker_budget;
517 available_funds -= worker_budget;
519 share_type leftover_worker_funds = worker_budget;
520 pay_workers(leftover_worker_funds);
521 rec.leftover_worker_funds = leftover_worker_funds;
522 available_funds += leftover_worker_funds;
524 rec.supply_delta = ((( rec.witness_budget
525 + rec.worker_budget )
526 - rec.leftover_worker_funds )
527 - rec.from_accumulated_fees )
528 - rec.from_unused_witness_budget;
532 ,&witness_budget,&worker_budget,&leftover_worker_funds,&dpo
534 ] ( asset_dynamic_data_object& _core )
536 _core.current_supply = (_core.current_supply + rec.supply_delta );
538 assert( rec.supply_delta ==
541 - leftover_worker_funds
542 - _core.accumulated_fees
545 _core.accumulated_fees = 0;
548 modify(dpo, [&witness_budget, &now]( dynamic_global_property_object& _dpo )
553 _dpo.witness_budget = witness_budget;
554 _dpo.last_budget_time = now;
557 rec.current_supply = core.current_supply;
558 create< budget_record_object >( [
this,&rec]( budget_record_object& _rec )
570 template<
typename Visitor >
597 const top_holders_special_authority& tha = auth.get< top_holders_special_authority >();
599 const auto& bal_idx = db.get_index_type< account_balance_index >().indices().get< by_asset_balance >();
600 uint8_t num_needed = tha.num_top_holders;
601 if( 0 == num_needed )
605 const auto range = bal_idx.equal_range( boost::make_tuple( tha.asset ) );
606 for( const account_balance_object& bal : boost::make_iterator_range( range.first, range.second ) )
608 assert( bal.asset_type == tha.asset );
609 if( bal.owner == acct.id )
611 vc.add( bal.owner, bal.balance.value );
613 if( 0 == num_needed )
619 vc.finish( is_owner ? a.owner : a.active );
621 a.top_n_control_flags |= (is_owner ? account_object::top_n_control_owner
622 : account_object::top_n_control_active);
631 uint16_t network_pct,
632 uint16_t designated_asset_buyback_pct,
633 uint16_t designated_asset_issuer_pct
636 FC_ASSERT( ( uint32_t(network_pct) + designated_asset_buyback_pct ) + designated_asset_issuer_pct
646 ilog(
"${n} core given to network at block ${b} due to non-configured FBA",
660 buyback_amount_128 *= designated_asset_buyback_pct;
662 share_type buyback_amount =
static_cast<uint64_t
>(buyback_amount_128);
665 issuer_amount_128 *= designated_asset_issuer_pct;
667 share_type issuer_amount =
static_cast<uint64_t
>(issuer_amount_128);
676 if( network_amount != 0 )
687 vop.
amount = buyback_amount;
696 vop.
amount = issuer_amount;
711 constexpr uint16_t twenty = 20;
713 constexpr uint16_t sixty = 60;
724 .get_secondary_index< balances_by_account_index >();
728 const asset_object& asset_to_buy = bbo.asset_to_buy(db);
735 wlog(
"skipping buyback account ${b} at block ${n} because allowed_assets does not exist",
740 for(
const auto& entry : bal_idx.get_account_balances( buyback_account.
get_id() ) )
742 const auto* it = entry.second;
743 asset_id_type asset_to_sell = it->asset_type;
745 if( asset_to_sell == asset_to_buy.
id )
747 if( amount_to_sell == 0 )
751 wlog(
"buyback account ${b} not selling disallowed holdings of asset ${a} at block ${n}",
752 (
"b", buyback_account)(
"a", asset_to_sell)(
"n", db.
head_block_num()) );
762 create_vop.
fee =
asset( 0, asset_id_type() );
763 create_vop.
seller = buyback_account.
id;
766 create_vop.
expiration = time_point_sec::maximum();
771 if( db.
find( order_id ) != nullptr )
774 cancel_vop.
fee =
asset( 0, asset_id_type() );
775 cancel_vop.
order = order_id;
785 wlog(
"Skipping buyback processing selling ${as} for ${ab} for buyback account ${b} at block ${n}; "
786 "exception was ${e}",
787 (
"as", asset_to_sell)(
"ab", asset_to_buy)(
"b", buyback_account)
807 if( acct.is_annual_member( now ) )
810 upgrade_vop.
fee =
asset( 0, asset_id_type() );
819 wlog(
"Skipping annual member deprecate processing for account ${a} (${an}) at block ${n}; exception was ${e}",
827 void database::process_bids(
const asset_bitasset_data_object& bad )
829 if( bad.is_prediction_market || bad.current_feed.settlement_price.is_null() )
832 asset_id_type to_revive_id = bad.asset_id;
833 const asset_object& to_revive = to_revive_id( *
this );
834 const asset_dynamic_data_object& bdd = to_revive.dynamic_data( *
this );
836 if( 0 == bdd.current_supply )
838 _cancel_bids_and_revive_mpa( to_revive, bad );
842 bool after_hf_core_2290 = HARDFORK_CORE_2290_PASSED( get_dynamic_global_properties().next_maintenance_time );
844 const auto& bid_idx = get_index_type< collateral_bid_index >().indices().get<by_price>();
845 const auto start = bid_idx.lower_bound( to_revive_id );
846 auto end = bid_idx.upper_bound( to_revive_id );
850 auto revive_ratio = after_hf_core_2290 ? bad.current_feed.initial_collateral_ratio
851 : bad.current_feed.maintenance_collateral_ratio;
852 while( covered < bdd.current_supply && itr != end )
854 const collateral_bid_object& bid = *itr;
855 asset debt_in_bid = bid.inv_swan_price.quote;
856 if( debt_in_bid.amount > bdd.current_supply )
857 debt_in_bid.amount = bdd.current_supply;
858 asset total_collateral = debt_in_bid * bad.settlement_price;
859 total_collateral += bid.inv_swan_price.base;
860 price call_price = price::call_price( debt_in_bid, total_collateral, revive_ratio );
861 if( ~call_price >= bad.current_feed.settlement_price )
break;
862 covered += debt_in_bid.amount;
865 if( covered < bdd.current_supply )
return;
869 share_type remaining_fund = bad.settlement_fund;
873 const collateral_bid_object& bid = *itr;
875 asset debt_in_bid = bid.inv_swan_price.quote;
876 if( debt_in_bid.amount > bdd.current_supply )
877 debt_in_bid.amount = bdd.current_supply;
879 share_type collateral = (debt_in_bid * bad.settlement_price).amount;
880 if( debt >= to_cover )
883 collateral = remaining_fund;
886 remaining_fund -= collateral;
887 execute_bid( bid, debt, collateral, bad.current_feed );
892 _cancel_bids_and_revive_mpa( to_revive, bad );
900 wlog(
"Updating all call orders for hardfork core-343 at block ${n}", (
"n",db.
head_block_num()) );
901 asset_id_type current_asset;
906 if( current_asset != call_obj.debt_type() )
908 current_asset = call_obj.debt_type();
909 abd = ¤t_asset(db).bitasset_data(db);
918 wlog(
"Done updating all call orders for hardfork core-343 at block ${n}", (
"n",db.
head_block_num()) );
941 auto itr = asset_idx.lower_bound(
true );
942 auto itr_end = asset_idx.end();
943 while( itr != itr_end )
953 void database::process_bitassets()
955 time_point_sec head_time = head_block_time();
956 uint32_t head_epoch_seconds = head_time.sec_since_epoch();
957 bool after_hf_core_518 = ( head_time >= HARDFORK_CORE_518_TIME );
959 const auto& update_bitasset = [
this,&head_time,head_epoch_seconds,after_hf_core_518]
960 ( asset_bitasset_data_object &o )
962 o.force_settled_volume = 0;
965 if( after_hf_core_518 && o.options.feed_lifetime_sec < head_epoch_seconds
969 auto itr = o.feeds.rbegin();
970 auto end = o.feeds.rend();
973 auto feed_time = itr->second.first;
974 std::advance( itr, 1 );
975 if( feed_time < calculated )
976 o.feeds.erase( itr.base() );
984 for(
const auto& d : get_index_type<asset_bitasset_data_index>().indices() )
986 modify( d, update_bitasset );
987 if( d.is_globally_settled() )
1002 auto asset_end = asset_idx.end();
1003 for(
auto asset_itr = asset_idx.lower_bound(
true); asset_itr != asset_end; ++asset_itr )
1005 const auto& current_asset = *asset_itr;
1010 wlog(
"Adjusting max_supply of ${asset} because current_supply (${current_supply}) is greater than ${old}.",
1011 (
"asset", current_asset.symbol)
1012 (
"current_supply", current_supply.
value)
1013 (
"old", max_supply));
1027 const balance_object* bal = db.
find( balance_id_type( HARDFORK_CORE_2103_BALANCE_ID ) );
1038 static void update_bitasset_current_feeds(database& db)
1042 db.update_bitasset_current_feed( bitasset );
1067 auto asset_end = asset_idx.end();
1068 for(
auto asset_itr = asset_idx.lower_bound(
true); asset_itr != asset_end; ++asset_itr )
1070 const auto& current_asset = *asset_itr;
1075 bool is_witness_or_committee_fed =
false;
1077 is_witness_or_committee_fed =
true;
1081 auto itr = bitasset_data.
feeds.begin();
1082 while( itr != bitasset_data.
feeds.end() )
1086 && ( is_witness_or_committee_fed || itr->second.second.settlement_price !=
price() ) )
1090 if( is_witness_or_committee_fed )
1093 itr = obj.
feeds.erase(itr);
1098 obj.
feeds[itr->first].second.settlement_price =
price();
1135 if( ticket_obj.current_type !=
liquid )
1138 aso.total_pol_value -= ticket_obj.value;
1150 auto bid_itr = bid_idx.begin();
1151 auto bid_end = bid_idx.end();
1153 asset_id_type current_asset_id;
1154 bool can_bid_collateral =
true;
1156 while( bid_itr != bid_end )
1163 can_bid_collateral = current_asset_id(db).can_bid_collateral();
1165 if( !can_bid_collateral )
1182 : full_power_seconds(f), recalc_steps(d), seconds_per_step(s)
1184 total_recalc_seconds = ( recalc_steps - 1 ) * seconds_per_step;
1185 power_percents_to_subtract.reserve( recalc_steps - 1 );
1186 for( uint32_t i = 1; i < recalc_steps; ++i )
1188 power_percents_to_subtract.push_back( (uint16_t)( (
GRAPHENE_100_PERCENT * i ) / recalc_steps ) );
1193 return { now - full_power_seconds, now - full_power_seconds - total_recalc_seconds };
1216 uint32_t steps_to_subtract_minus_1 = diff / seconds_per_step;
1217 fc::uint128_t stake_to_subtract( stake );
1218 stake_to_subtract *= power_percents_to_subtract[steps_to_subtract_minus_1];
1220 return stake -
static_cast<uint64_t
>(stake_to_subtract);
1246 void database::perform_chain_maintenance(
const signed_block& next_block )
1248 const auto& gpo = get_global_properties();
1249 const auto& dgpo = get_dynamic_global_properties();
1250 auto last_vote_tally_time = head_block_time();
1255 struct vote_tally_helper {
1260 const bool hf2103_passed;
1261 const bool hf2262_passed;
1262 const bool pob_activated;
1263 const size_t two = 2;
1264 const size_t vid_committee =
static_cast<size_t>( vote_id_type::committee );
1265 const size_t vid_witness =
static_cast<size_t>( vote_id_type::witness );
1266 const size_t vid_worker =
static_cast<size_t>( vote_id_type::worker );
1273 explicit vote_tally_helper(
database& db )
1274 : d(db), props( d.get_global_properties() ), dprops( d.get_dynamic_global_properties() ),
1275 now( d.head_block_time() ), hf2103_passed( HARDFORK_CORE_2103_PASSED( now ) ),
1276 hf2262_passed( HARDFORK_CORE_2262_PASSED( now ) ),
1277 pob_activated( dprops.total_pob > 0 || dprops.total_inactive > 0 )
1282 d._total_voting_stake[vid_committee] = 0;
1283 d._total_voting_stake[vid_witness] = 0;
1286 witness_recalc_times = detail::vote_recalc_options::witness().get_vote_recalc_times( now );
1287 committee_recalc_times = detail::vote_recalc_options::committee().get_vote_recalc_times( now );
1288 worker_recalc_times = detail::vote_recalc_options::worker().get_vote_recalc_times( now );
1289 delegator_recalc_times = detail::vote_recalc_options::delegator().get_vote_recalc_times( now );
1293 void operator()(
const account_object& stake_account,
const account_statistics_object& stats )
1296 if( pob_activated && stats.total_core_pob == 0 && stats.total_core_inactive == 0 )
1305 const account_object& opinion_account = ( directly_voting ? stake_account
1306 : d.
get(stake_account.options.voting_account) );
1308 std::array<uint64_t,3> voting_stake;
1309 uint64_t num_committee_voting_stake;
1310 voting_stake[vid_worker] = pob_activated ? 0 : stats.total_core_in_orders.value;
1311 voting_stake[vid_worker] += ( !hf2262_passed && stake_account.cashback_vb.valid() ) ?
1312 (*stake_account.cashback_vb)(d).balance.amount.value : 0;
1313 voting_stake[vid_worker] += hf2262_passed ? 0 : stats.core_in_balance.value;
1316 uint64_t vp_all = 0;
1317 uint64_t vp_active = 0;
1319 uint64_t vp_committee = 0;
1320 uint64_t vp_witness = 0;
1321 uint64_t vp_worker = 0;
1324 const uint64_t pol_amount = stats.total_core_pol.value;
1325 const uint64_t pol_value = stats.total_pol_value.value;
1326 const uint64_t pob_amount = stats.total_core_pob.value;
1327 const uint64_t pob_value = stats.total_pob_value.value;
1328 if( 0 == pob_amount )
1330 voting_stake[vid_worker] += pol_value;
1332 else if( 0 == pol_amount )
1334 if( pob_amount <= voting_stake[vid_worker] )
1336 voting_stake[vid_worker] += ( pob_value - pob_amount );
1340 auto base_value = (
static_cast<fc::uint128_t
>( voting_stake[vid_worker] ) * pob_value )
1342 voting_stake[vid_worker] =
static_cast<uint64_t
>( base_value );
1345 else if( pob_amount <= pol_amount )
1347 auto base_value = (
static_cast<fc::uint128_t
>( pob_value ) * pol_value ) / pol_amount;
1348 auto diff_value = (
static_cast<fc::uint128_t
>( pob_amount ) * pol_value ) / pol_amount;
1349 base_value += ( pol_value - diff_value );
1350 voting_stake[vid_worker] +=
static_cast<uint64_t
>( base_value );
1354 auto base_value = (
static_cast<fc::uint128_t
>( pol_value ) * pob_value ) / pob_amount;
1355 fc::uint128_t diff_amount = pob_amount - pol_amount;
1356 if( diff_amount <= voting_stake[vid_worker] )
1358 auto diff_value = (
static_cast<fc::uint128_t
>( pol_amount ) * pob_value ) / pob_amount;
1359 base_value += ( pob_value - diff_value );
1360 voting_stake[vid_worker] +=
static_cast<uint64_t
>( base_value - diff_amount );
1364 base_value += (
static_cast<fc::uint128_t
>( voting_stake[vid_worker] ) * pob_value ) / pob_amount;
1365 voting_stake[vid_worker] =
static_cast<uint64_t
>( base_value );
1370 if( 0 == voting_stake[vid_worker] )
1373 const auto& opinion_account_stats = ( directly_voting ? stats : opinion_account.statistics( d ) );
1376 if( !hf2103_passed )
1378 voting_stake[vid_committee] = voting_stake[vid_worker];
1379 voting_stake[vid_witness] = voting_stake[vid_worker];
1380 num_committee_voting_stake = voting_stake[vid_worker];
1381 vp_all = voting_stake[vid_worker];
1382 vp_active = voting_stake[vid_worker];
1383 vp_committee = voting_stake[vid_worker];
1384 vp_witness = voting_stake[vid_worker];
1385 vp_worker = voting_stake[vid_worker];
1389 vp_all = voting_stake[vid_worker];
1390 vp_active = voting_stake[vid_worker];
1391 if( !directly_voting )
1393 voting_stake[vid_worker] = detail::vote_recalc_options::delegator().get_recalced_voting_stake(
1394 voting_stake[vid_worker], stats.last_vote_time, *delegator_recalc_times );
1395 vp_active = voting_stake[vid_worker];
1397 voting_stake[vid_witness] = detail::vote_recalc_options::witness().get_recalced_voting_stake(
1398 voting_stake[vid_worker], opinion_account_stats.last_vote_time, *witness_recalc_times );
1399 vp_witness = voting_stake[vid_witness];
1400 voting_stake[vid_committee] = detail::vote_recalc_options::committee().get_recalced_voting_stake(
1401 voting_stake[vid_worker], opinion_account_stats.last_vote_time, *committee_recalc_times );
1402 vp_committee = voting_stake[vid_committee];
1403 num_committee_voting_stake = voting_stake[vid_committee];
1404 if( opinion_account.num_committee_voted > 1 )
1405 voting_stake[vid_committee] /= opinion_account.num_committee_voted;
1406 voting_stake[vid_worker] = detail::vote_recalc_options::worker().get_recalced_voting_stake(
1407 voting_stake[vid_worker], opinion_account_stats.last_vote_time, *worker_recalc_times );
1408 vp_worker = voting_stake[vid_worker];
1412 d.
modify( opinion_account_stats, [vp_all,vp_active,vp_committee,vp_witness,vp_worker,
this]
1413 ( account_statistics_object& update_stats ) {
1414 if (update_stats.vote_tally_time != now)
1416 update_stats.vp_all = vp_all;
1417 update_stats.vp_active = vp_active;
1418 update_stats.vp_committee = vp_committee;
1419 update_stats.vp_witness = vp_witness;
1420 update_stats.vp_worker = vp_worker;
1421 update_stats.vote_tally_time = now;
1425 update_stats.vp_all += vp_all;
1426 update_stats.vp_active += vp_active;
1427 update_stats.vp_committee += vp_committee;
1428 update_stats.vp_witness += vp_witness;
1429 update_stats.vp_worker += vp_worker;
1433 for( vote_id_type
id : opinion_account.options.votes )
1435 uint32_t offset =
id.instance();
1436 uint32_t type = std::min(
id.type(), vote_id_type::vote_type::worker );
1438 if( offset < d._vote_tally_buffer.size() )
1439 d._vote_tally_buffer[offset] += voting_stake[type];
1443 if( voting_stake[vid_witness] > 0
1446 uint16_t offset = opinion_account.options.num_witness / two;
1447 d._witness_count_histogram_buffer[offset] += voting_stake[vid_witness];
1450 if( num_committee_voting_stake > 0
1453 uint16_t offset = opinion_account.options.num_committee / two;
1454 d._committee_count_histogram_buffer[offset] += num_committee_voting_stake;
1457 d._total_voting_stake[vid_committee] += num_committee_voting_stake;
1458 d._total_voting_stake[vid_witness] += voting_stake[vid_witness];
1463 vote_tally_helper tally_helper(*
this);
1465 perform_account_maintenance( tally_helper );
1467 struct clear_canary {
1468 explicit clear_canary(vector<uint64_t>& target): target(target){}
1469 clear_canary(
const clear_canary& ) =
delete;
1470 ~clear_canary() { target.clear(); }
1472 vector<uint64_t>& target;
1474 clear_canary a(_witness_count_histogram_buffer);
1475 clear_canary b(_committee_count_histogram_buffer);
1476 clear_canary c(_vote_tally_buffer);
1479 update_active_witnesses();
1480 update_active_committee_members();
1481 update_worker_votes();
1483 modify(gpo, [&dgpo](global_property_object& p) {
1485 p.parameters.get_mutable_fees().get<account_create_operation>().basic_fee >>=
1486 p.parameters.account_fee_scale_bitshifts *
1487 (dgpo.accounts_registered_this_interval / p.parameters.accounts_per_fee_scale);
1489 if( p.pending_parameters )
1491 p.parameters = std::move(*p.pending_parameters);
1492 p.pending_parameters.reset();
1496 auto next_maintenance_time = dgpo.next_maintenance_time;
1497 auto maintenance_interval = gpo.parameters.maintenance_interval;
1499 if( next_maintenance_time <= next_block.
timestamp )
1502 next_maintenance_time = time_point_sec() +
1521 auto y = (head_block_time() - next_maintenance_time).to_seconds() / maintenance_interval;
1522 next_maintenance_time += (uint32_t)( (y+1) * maintenance_interval );
1526 if( (dgpo.next_maintenance_time < HARDFORK_613_TIME) && (next_maintenance_time >= HARDFORK_613_TIME) )
1530 bool to_process_hf_343 =
false;
1531 if( (dgpo.next_maintenance_time <= HARDFORK_CORE_343_TIME) && (next_maintenance_time > HARDFORK_CORE_343_TIME) )
1532 to_process_hf_343 =
true;
1535 if( (dgpo.next_maintenance_time <= HARDFORK_CORE_868_890_TIME)
1536 && (next_maintenance_time > HARDFORK_CORE_868_890_TIME) )
1540 bool to_process_hf_1270 =
false;
1541 if( (dgpo.next_maintenance_time <= HARDFORK_CORE_1270_TIME) && (next_maintenance_time > HARDFORK_CORE_1270_TIME) )
1542 to_process_hf_1270 =
true;
1545 if ( dgpo.next_maintenance_time <= HARDFORK_CORE_1465_TIME && next_maintenance_time > HARDFORK_CORE_1465_TIME )
1549 if ( dgpo.next_maintenance_time <= HARDFORK_CORE_2103_TIME && next_maintenance_time > HARDFORK_CORE_2103_TIME )
1553 if ( dgpo.next_maintenance_time <= HARDFORK_CORE_2262_TIME && next_maintenance_time > HARDFORK_CORE_2262_TIME )
1557 if ( dgpo.next_maintenance_time <= HARDFORK_CORE_2281_TIME && next_maintenance_time > HARDFORK_CORE_2281_TIME )
1561 bool match_call_orders_for_hf_2481 =
false;
1562 if( (dgpo.next_maintenance_time <= HARDFORK_CORE_2481_TIME) && (next_maintenance_time > HARDFORK_CORE_2481_TIME) )
1563 match_call_orders_for_hf_2481 =
true;
1565 modify(dgpo, [last_vote_tally_time, next_maintenance_time](dynamic_global_property_object& d) {
1566 d.next_maintenance_time = next_maintenance_time;
1567 d.last_vote_tally_time = last_vote_tally_time;
1568 d.accounts_registered_this_interval = 0;
1572 if( to_process_hf_343 )
1579 if( to_process_hf_1270 )
1582 update_bitasset_current_feeds(*
this);
1587 if( match_call_orders_for_hf_2481 )
1592 process_bitassets();