From e58b7d6916cf2aec169e46550f66eec44b77f506 Mon Sep 17 00:00:00 2001 From: Vlad Dobromyslov Date: Thu, 7 Apr 2022 14:29:57 +0300 Subject: [PATCH] #339 - fix database::pay_sons() --- libraries/chain/db_maint.cpp | 156 +++++++++++++++++------------------ 1 file changed, 74 insertions(+), 82 deletions(-) diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index 56a871e5..9d0cef27 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -185,99 +185,91 @@ void database::pay_sons() time_point_sec now = head_block_time(); const dynamic_global_property_object& dpo = get_dynamic_global_properties(); // Current requirement is that we have to pay every 24 hours, so the following check - if( dpo.son_budget.value > 0 && ((now - dpo.last_son_payout_time) >= fc::seconds(get_global_properties().parameters.son_pay_time()))) { - //! Fixme - sort_votable_objects only for bitcoin - auto sons = sort_votable_objects(sidechain_type::bitcoin, get_global_properties().parameters.maximum_son_count()); - // After SON2 HF - uint64_t total_votes = 0; - for( const son_object& son : sons ) + if( dpo.son_budget.value > 0 && ((now - dpo.last_son_payout_time) >= fc::seconds(get_global_properties().parameters.son_pay_time()))) + { + for(const auto& active_sidechain_type : active_sidechain_types) { - for(const auto& vote_id : son.sidechain_vote_ids) + auto sons = sort_votable_objects(active_sidechain_type, get_global_properties().parameters.maximum_son_count()); + // After SON2 HF + uint64_t total_votes = 0; + for( const son_object& son : sons ) { - total_votes += _vote_tally_buffer[vote_id.second]; + total_votes += _vote_tally_buffer[son.sidechain_vote_ids.at(active_sidechain_type)]; } - } - int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(total_votes)) - 15, 0); - auto get_weight = [&bits_to_drop]( uint64_t son_votes ) { - uint16_t weight = std::max((son_votes >> bits_to_drop), uint64_t(1) ); - return weight; - }; - // Before SON2 HF - auto get_weight_before_son2_hf = []( uint64_t son_votes ) { - int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(son_votes)) - 15, 0); - uint16_t weight = std::max((son_votes >> bits_to_drop), uint64_t(1) ); - return weight; - }; - uint64_t weighted_total_txs_signed = 0; - share_type son_budget = dpo.son_budget; - get_index_type().inspect_all_objects([this, &weighted_total_txs_signed, &get_weight, &now, &get_weight_before_son2_hf](const object& o) { - const son_statistics_object& s = static_cast(o); - const auto& idx = get_index_type().indices().get(); - auto son_obj = idx.find( s.owner ); - uint16_t son_weight = 0; - if( now >= HARDFORK_SON2_TIME ) { - for (const auto& vote_id : son_obj->sidechain_vote_ids) { - son_weight += get_weight(_vote_tally_buffer[vote_id.second]); - } - } - else { - for (const auto& vote_id : son_obj->sidechain_vote_ids) { - son_weight += get_weight_before_son2_hf(_vote_tally_buffer[vote_id.second]); - } - } - uint64_t txs_signed = 0; - for (const auto &ts : s.txs_signed) { - txs_signed = txs_signed + ts.second; - } - weighted_total_txs_signed += (txs_signed * son_weight); - }); - - // Now pay off each SON proportional to the number of transactions signed. - get_index_type().inspect_all_objects([this, &weighted_total_txs_signed, &dpo, &son_budget, &get_weight, &get_weight_before_son2_hf, &now](const object& o) { - const son_statistics_object& s = static_cast(o); - uint64_t txs_signed = 0; - for (const auto &ts : s.txs_signed) { - txs_signed = txs_signed + ts.second; - } - - if(txs_signed > 0){ + int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(total_votes)) - 15, 0); + auto get_weight = [&bits_to_drop]( uint64_t son_votes ) { + uint16_t weight = std::max((son_votes >> bits_to_drop), uint64_t(1) ); + return weight; + }; + // Before SON2 HF + auto get_weight_before_son2_hf = []( uint64_t son_votes ) { + int8_t bits_to_drop = std::max(int(boost::multiprecision::detail::find_msb(son_votes)) - 15, 0); + uint16_t weight = std::max((son_votes >> bits_to_drop), uint64_t(1) ); + return weight; + }; + uint64_t weighted_total_txs_signed = 0; + share_type son_budget = dpo.son_budget; + get_index_type().inspect_all_objects([this, &weighted_total_txs_signed, &get_weight, &now, &get_weight_before_son2_hf, &active_sidechain_type](const object& o) { + const son_statistics_object& s = static_cast(o); const auto& idx = get_index_type().indices().get(); auto son_obj = idx.find( s.owner ); uint16_t son_weight = 0; if( now >= HARDFORK_SON2_TIME ) { - for (const auto& vote_id : son_obj->sidechain_vote_ids) { - son_weight += get_weight(_vote_tally_buffer[vote_id.second]); - } + son_weight += get_weight(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]); } else { - for (const auto& vote_id : son_obj->sidechain_vote_ids) { - son_weight += get_weight_before_son2_hf(_vote_tally_buffer[vote_id.second]); - } + son_weight += get_weight_before_son2_hf(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]); } - share_type pay = (txs_signed * son_weight * son_budget.value)/weighted_total_txs_signed; - modify( *son_obj, [&]( son_object& _son_obj) - { - _son_obj.pay_son_fee(pay, *this); - }); - //Remove the amount paid out to SON from global SON Budget - modify( dpo, [&]( dynamic_global_property_object& _dpo ) - { - _dpo.son_budget -= pay; - } ); - //Reset the tx counter in each son statistics object - modify( s, [&]( son_statistics_object& _s) - { - for (const auto &ts : s.txs_signed) { - _s.txs_signed.at(ts.first) = 0; + uint64_t txs_signed = 0; + for (const auto &ts : s.txs_signed) { + txs_signed = txs_signed + ts.second; + } + weighted_total_txs_signed += (txs_signed * son_weight); + }); + + // Now pay off each SON proportional to the number of transactions signed. + get_index_type().inspect_all_objects([this, &weighted_total_txs_signed, &dpo, &son_budget, &get_weight, &get_weight_before_son2_hf, &now, &active_sidechain_type](const object& o) { + const son_statistics_object& s = static_cast(o); + uint64_t txs_signed = 0; + for (const auto &ts : s.txs_signed) { + txs_signed = txs_signed + ts.second; + } + + if(txs_signed > 0){ + const auto& idx = get_index_type().indices().get(); + auto son_obj = idx.find( s.owner ); + uint16_t son_weight = 0; + if( now >= HARDFORK_SON2_TIME ) { + son_weight += get_weight(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]); } - }); - } - }); - //Note the last son pay out time - modify( dpo, [&]( dynamic_global_property_object& _dpo ) - { - _dpo.last_son_payout_time = now; - }); + else { + son_weight += get_weight_before_son2_hf(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]); + } + share_type pay = (txs_signed * son_weight * son_budget.value)/weighted_total_txs_signed; + modify( *son_obj, [&]( son_object& _son_obj) + { + _son_obj.pay_son_fee(pay, *this); + }); + //Remove the amount paid out to SON from global SON Budget + modify( dpo, [&]( dynamic_global_property_object& _dpo ) + { + _dpo.son_budget -= pay; + } ); + //Reset the tx counter in each son statistics object + modify( s, [&]( son_statistics_object& _s) + { + for (const auto &ts : s.txs_signed) { + _s.txs_signed.at(ts.first) = 0; + } + }); + } + }); + //Note the last son pay out time + modify( dpo, [&]( dynamic_global_property_object& _dpo ) + { + _dpo.last_son_payout_time = now; + }); + } } }