void database::update_active_committee_members() { try { assert( _committee_count_histogram_buffer.size() > 0 ); share_type stake_target = (_total_voting_stake-_witness_count_histogram_buffer[0]) / 2; /// accounts that vote for 0 or 1 witness do not get to express an opinion on /// the number of witnesses to have (they abstain and are non-voting accounts) uint64_t stake_tally = 0; // _committee_count_histogram_buffer[0]; size_t committee_member_count = 0; if( stake_target > 0 ) while( (committee_member_count < _committee_count_histogram_buffer.size() - 1) && (stake_tally <= stake_target) ) stake_tally += _committee_count_histogram_buffer[++committee_member_count]; const chain_property_object& cpo = get_chain_properties(); auto committee_members = sort_votable_objects<committee_member_index>(std::max(committee_member_count*2+1, (size_t)cpo.immutable_parameters.min_committee_member_count)); for( const committee_member_object& del : committee_members ) { modify( del, [&]( committee_member_object& obj ){ obj.total_votes = _vote_tally_buffer[del.vote_id]; }); } // Update committee authorities if( !committee_members.empty() ) { modify(get(GRAPHENE_COMMITTEE_ACCOUNT), [&](account_object& a) { uint64_t total_votes = 0; map<account_id_type, uint64_t> weights; a.active.weight_threshold = 0; a.active.clear(); for( const committee_member_object& del : committee_members ) { weights.emplace(del.committee_member_account, _vote_tally_buffer[del.vote_id]); total_votes += _vote_tally_buffer[del.vote_id]; } // total_votes is 64 bits. Subtract the number of leading low bits from 64 to get the number of useful bits, // then I want to keep the most significant 16 bits of what's left. int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(total_votes)) - 15, 0); for( const auto& weight : weights ) { // Ensure that everyone has at least one vote. Zero weights aren't allowed. uint16_t votes = std::max((weight.second >> bits_to_drop), uint64_t(1) ); a.active.account_auths[weight.first] += votes; a.active.weight_threshold += votes; } a.active.weight_threshold /= 2; a.active.weight_threshold += 1; }); modify(get(GRAPHENE_RELAXED_COMMITTEE_ACCOUNT), [&](account_object& a) { a.active = get(GRAPHENE_COMMITTEE_ACCOUNT).active; }); }
void database::update_active_witnesses() { try { assert( _witness_count_histogram_buffer.size() > 0 ); share_type stake_target = _total_voting_stake / 2; share_type stake_tally = _witness_count_histogram_buffer[0]; size_t witness_count = 0; if( stake_target > 0 ) while( (witness_count < _witness_count_histogram_buffer.size() - 1) && (stake_tally <= stake_target) ) stake_tally += _witness_count_histogram_buffer[++witness_count]; const chain_property_object& cpo = get_chain_properties(); auto wits = sort_votable_objects<witness_index>(std::max(witness_count*2+1, (size_t)cpo.immutable_parameters.min_witness_count)); const global_property_object& gpo = get_global_properties(); for( const witness_object& wit : wits ) { modify( wit, [&]( witness_object& obj ){ obj.total_votes = _vote_tally_buffer[wit.vote_id]; }); } // Update witness authority modify( get(GRAPHENE_WITNESS_ACCOUNT), [&]( account_object& a ) { uint64_t total_votes = 0; map<account_id_type, uint64_t> weights; a.active.weight_threshold = 0; a.active.clear(); for( const witness_object& wit : wits ) { weights.emplace(wit.witness_account, _vote_tally_buffer[wit.vote_id]); total_votes += _vote_tally_buffer[wit.vote_id]; } // total_votes is 64 bits. Subtract the number of leading low bits from 64 to get the number of useful bits, // then I want to keep the most significant 16 bits of what's left. int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(total_votes)) - 15, 0); for( const auto& weight : weights ) { // Ensure that everyone has at least one vote. Zero weights aren't allowed. uint16_t votes = std::max((weight.second >> bits_to_drop), uint64_t(1) ); a.active.account_auths[weight.first] += votes; a.active.weight_threshold += votes; } a.active.weight_threshold /= 2; a.active.weight_threshold += 1; }); modify(gpo, [&]( global_property_object& gp ){ gp.active_witnesses.clear(); gp.active_witnesses.reserve(wits.size()); std::transform(wits.begin(), wits.end(), std::inserter(gp.active_witnesses, gp.active_witnesses.end()), [](const witness_object& w) { return w.id; }); gp.witness_accounts.clear(); gp.witness_accounts.reserve(wits.size()); std::transform(wits.begin(), wits.end(), std::inserter(gp.witness_accounts, gp.witness_accounts.end()), [](const witness_object& w) { return w.witness_account; }); }); } FC_CAPTURE_AND_RETHROW() }
const chain_id_type& database::get_chain_id( )const { return get_chain_properties().chain_id; }