#339 refactor sidechain type #677

Merged
vampik merged 27 commits from feature/339-refactor-sidechain_type into feature/son-for-hive-voting 2022-04-12 16:39:05 +00:00
10 changed files with 207 additions and 233 deletions

View file

@ -1105,7 +1105,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
_sso.recent_slots_filled = fc::uint128::max_value();
});
assert( ssohive.id == son_schedule_id_type(1) );
assert( ssohive.id == son_schedule_id_type(get_son_schedule_id(sidechain_type::hive)) );
#ifndef NDEBUG
const son_schedule_object& ssobitcoin =
@ -1127,7 +1127,7 @@ void database::init_genesis(const genesis_state_type& genesis_state)
_sso.recent_slots_filled = fc::uint128::max_value();
});
assert( ssobitcoin.id == son_schedule_id_type(2) );
assert( ssobitcoin.id == son_schedule_id_type(get_son_schedule_id(sidechain_type::bitcoin)) );
// Create FBA counters
create<fba_accumulator_object>([&]( fba_accumulator_object& acc )

View file

@ -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<son_index>(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<son_index>(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<son_stats_index>().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<const son_statistics_object&>(o);
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
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<son_stats_index>().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<const son_statistics_object&>(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<son_stats_index>().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<const son_statistics_object&>(o);
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
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<son_stats_index>().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<const son_statistics_object&>(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<son_index>().indices().get<by_id>();
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;
});
}
}
}
@ -724,12 +716,12 @@ void database::update_active_sons()
const global_property_object& gpo = get_global_properties();
const chain_parameters& cp = gpo.parameters;
//! Fixme - sort_votable_objects - fix bitcoin + hive -> deduce auto
flat_map<sidechain_type, vector<std::reference_wrapper<const son_object> > > sons;
sons[sidechain_type::bitcoin] = sort_votable_objects<son_index>(sidechain_type::bitcoin, cp.maximum_son_count());
sons[sidechain_type::hive] = sort_votable_objects<son_index>(sidechain_type::hive, cp.maximum_son_count());
const auto& all_sons = get_index_type<son_index>().indices();
flat_map<sidechain_type, vector<std::reference_wrapper<const son_object> > > sons;
for(const auto& active_sidechain_type : active_sidechain_types)
{
sons[active_sidechain_type] = sort_votable_objects<son_index>(active_sidechain_type, cp.maximum_son_count());
}
auto& local_vote_buffer_ref = _vote_tally_buffer;
for( const son_object& son : all_sons )
@ -861,7 +853,7 @@ void database::update_active_sons()
}
});
//! Fixme - fix this schedule
//! Fixme - fix this schedule (delete it?)
const son_schedule_object& sso = son_schedule_id_type()(*this);
modify(sso, [&](son_schedule_object& _sso)
{
@ -882,51 +874,28 @@ void database::update_active_sons()
}
});
// for now put the all active_sons in hive schedule object
// later we will make here the change which will take only son's from
// active_sons that are hive
const son_schedule_object& ssohive = son_schedule_id_type(1)(*this);
modify(ssohive, [&](son_schedule_object& _sso)
for(const auto& active_sidechain_type : active_sidechain_types)
{
flat_set<son_id_type> active_sons;
active_sons.reserve(gpo.active_sons.at(sidechain_type::hive).size());
std::transform(gpo.active_sons.at(sidechain_type::hive).cbegin(), gpo.active_sons.at(sidechain_type::hive).cend(),
std::inserter(active_sons, active_sons.end()),
[](const son_info& swi) {
return swi.son_id;
});
_sso.scheduler.update(active_sons);
// similar to witness, produce schedule for sons
if(cur_active_sons.at(sidechain_type::hive).size() == 0 && new_active_sons.at(sidechain_type::hive).size() > 0)
const son_schedule_object& sidechain_sso = son_schedule_id_type(get_son_schedule_id(active_sidechain_type))(*this);
modify(sidechain_sso, [&](son_schedule_object& _sso)
{
witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV);
for( size_t i=0; i<new_active_sons.at(sidechain_type::hive).size(); ++i )
_sso.scheduler.produce_schedule(rng);
}
});
// for now put the all active_sons in bitcoin schedule object
// later we will make here the change which will take only son's from
// active_sons that are bitcoin
const son_schedule_object& ssobitcoin = son_schedule_id_type(2)(*this);
modify(ssobitcoin, [&](son_schedule_object& _sso)
{
flat_set<son_id_type> active_sons;
active_sons.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size());
std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(),
std::inserter(active_sons, active_sons.end()),
[](const son_info& swi) {
return swi.son_id;
flat_set<son_id_type> active_sons;
active_sons.reserve(gpo.active_sons.at(active_sidechain_type).size());
std::transform(gpo.active_sons.at(active_sidechain_type).cbegin(), gpo.active_sons.at(active_sidechain_type).cend(),
std::inserter(active_sons, active_sons.end()),
[](const son_info& swi) {
return swi.son_id;
});
_sso.scheduler.update(active_sons);
// similar to witness, produce schedule for sons
if(cur_active_sons.at(active_sidechain_type).size() == 0 && new_active_sons.at(active_sidechain_type).size() > 0)
{
witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV);
for( size_t i=0; i<new_active_sons.at(active_sidechain_type).size(); ++i )
_sso.scheduler.produce_schedule(rng);
}
});
_sso.scheduler.update(active_sons);
// similar to witness, produce schedule for sons
if(cur_active_sons.at(sidechain_type::bitcoin).size() == 0 && new_active_sons.at(sidechain_type::bitcoin).size() > 0)
{
witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV);
for( size_t i=0; i<new_active_sons.at(sidechain_type::bitcoin).size(); ++i )
_sso.scheduler.produce_schedule(rng);
}
});
}
} FC_CAPTURE_AND_RETHROW() }
void database::initialize_budget_record( fc::time_point_sec now, budget_record& rec )const

View file

@ -74,6 +74,16 @@ witness_id_type database::get_scheduled_witness( uint32_t slot_num )const
return wid;
}
unsigned_int database::get_son_schedule_id( sidechain_type type )const
{
static const map<sidechain_type, unsigned_int> schedule_map = {
{ sidechain_type::hive, 1 },
{ sidechain_type::bitcoin, 2 }
};
return schedule_map.at(type);
}
son_id_type database::get_scheduled_son( sidechain_type type, uint32_t slot_num )const
{
son_id_type sid;
@ -81,14 +91,14 @@ son_id_type database::get_scheduled_son( sidechain_type type, uint32_t slot_num
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM)
{
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
const son_schedule_object& sso = type == sidechain_type::hive ? son_schedule_id_type(1)(*this) : son_schedule_id_type(2)(*this);
const son_schedule_object& sso = son_schedule_id_type(get_son_schedule_id(type))(*this);
uint64_t current_aslot = dpo.current_aslot + slot_num;
return sso.current_shuffled_sons.at(type)[ current_aslot % sso.current_shuffled_sons.size() ];
}
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM &&
slot_num != 0 )
{
const son_schedule_object& sso = type == sidechain_type::hive ? son_schedule_id_type(1)(*this) : son_schedule_id_type(2)(*this);
const son_schedule_object& sso = son_schedule_id_type(get_son_schedule_id(type))(*this);
// ask the near scheduler who goes in the given slot
bool slot_is_near = sso.scheduler.get_slot(slot_num-1, sid);
if(! slot_is_near)
@ -192,8 +202,8 @@ void database::update_witness_schedule()
void database::update_son_schedule()
{
const son_schedule_object& sso = son_schedule_id_type()(*this);
const son_schedule_object& ssohive = son_schedule_id_type(1)(*this);
const son_schedule_object& ssobitcoin = son_schedule_id_type(2)(*this);
const son_schedule_object& ssohive = son_schedule_id_type(get_son_schedule_id(sidechain_type::hive))(*this);
const son_schedule_object& ssobitcoin = son_schedule_id_type(get_son_schedule_id(sidechain_type::bitcoin))(*this);
const global_property_object& gpo = get_global_properties();
//! Fixme - here we should take active_sons size for sidechain
@ -401,8 +411,6 @@ void database::update_son_schedule(const signed_block& next_block)
auto start = fc::time_point::now();
const global_property_object& gpo = get_global_properties();
const son_schedule_object& sso = get(son_schedule_id_type());
const son_schedule_object& ssohive = get(son_schedule_id_type(1));
const son_schedule_object& ssobitcoin = get(son_schedule_id_type(2));
const flat_map<sidechain_type, uint32_t> schedule_needs_filled = [&gpo]()
{
flat_map<sidechain_type, uint32_t> schedule_needs_filled;
@ -425,19 +433,12 @@ void database::update_son_schedule(const signed_block& next_block)
bool slot_is_near = sso.scheduler.get_slot( schedule_slot-1, first_son );
son_id_type son;
son_id_type first_son_hive;
bool slot_is_near_hive = ssohive.scheduler.get_slot( schedule_slot-1, first_son_hive );
son_id_type son_hive;
son_id_type first_son_bitcoin;
bool slot_is_near_bitcoin = ssobitcoin.scheduler.get_slot( schedule_slot-1, first_son_bitcoin );
son_id_type son_bitcoin;
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
assert( dpo.random.data_size() == witness_scheduler_rng::seed_length );
assert( witness_scheduler_rng::seed_length == sso.rng_seed.size() );
//! Fixme - this schedule (delete it?)
modify(sso, [&](son_schedule_object& _sso)
{
_sso.slots_since_genesis += schedule_slot;
@ -471,71 +472,47 @@ void database::update_son_schedule(const signed_block& next_block)
+ 1) << (schedule_slot - 1);
});
modify(ssohive, [&](son_schedule_object& _sso)
for(const auto& active_sidechain_type : active_sidechain_types)
{
_sso.slots_since_genesis += schedule_slot;
witness_scheduler_rng rng(ssohive.rng_seed.data, _sso.slots_since_genesis);
const son_schedule_object& sidechain_sso = get(son_schedule_id_type(get_son_schedule_id(active_sidechain_type)));
son_id_type first_son_idechain;
bool slot_is_near_hive = sidechain_sso.scheduler.get_slot( schedule_slot-1, first_son_idechain );
son_id_type son_idechain;
_sso.scheduler._min_token_count = std::max(int(gpo.active_sons.at(sidechain_type::hive).size()) / 2, 1);
modify(sidechain_sso, [&](son_schedule_object& _sso)
{
_sso.slots_since_genesis += schedule_slot;
witness_scheduler_rng rng(sidechain_sso.rng_seed.data, _sso.slots_since_genesis);
if( slot_is_near_hive )
{
uint32_t drain = schedule_slot;
while( drain > 0 )
{
if( _sso.scheduler.size() == 0 )
break;
_sso.scheduler.consume_schedule();
--drain;
}
}
else
{
_sso.scheduler.reset_schedule( first_son_hive );
}
while( !_sso.scheduler.get_slot(schedule_needs_filled.at(sidechain_type::hive), son_hive) )
{
if( _sso.scheduler.produce_schedule(rng) & emit_turn )
memcpy(_sso.rng_seed.begin(), dpo.random.data(), dpo.random.data_size());
}
_sso.last_scheduling_block = next_block.block_num();
_sso.recent_slots_filled = (
(_sso.recent_slots_filled << 1)
+ 1) << (schedule_slot - 1);
});
_sso.scheduler._min_token_count = std::max(int(gpo.active_sons.at(active_sidechain_type).size()) / 2, 1);
modify(ssobitcoin, [&](son_schedule_object& _sso)
{
_sso.slots_since_genesis += schedule_slot;
witness_scheduler_rng rng(ssohive.rng_seed.data, _sso.slots_since_genesis);
if( slot_is_near_hive )
{
uint32_t drain = schedule_slot;
while( drain > 0 )
{
if( _sso.scheduler.size() == 0 )
break;
_sso.scheduler.consume_schedule();
--drain;
}
}
else
{
_sso.scheduler.reset_schedule( first_son_idechain );
}
while( !_sso.scheduler.get_slot(schedule_needs_filled.at(active_sidechain_type), son_idechain) )
{
if( _sso.scheduler.produce_schedule(rng) & emit_turn )
memcpy(_sso.rng_seed.begin(), dpo.random.data(), dpo.random.data_size());
}
_sso.last_scheduling_block = next_block.block_num();
_sso.recent_slots_filled = (
(_sso.recent_slots_filled << 1)
+ 1) << (schedule_slot - 1);
});
}
_sso.scheduler._min_token_count = std::max(int(gpo.active_sons.at(sidechain_type::bitcoin).size()) / 2, 1);
if( slot_is_near_bitcoin )
{
uint32_t drain = schedule_slot;
while( drain > 0 )
{
if( _sso.scheduler.size() == 0 )
break;
_sso.scheduler.consume_schedule();
--drain;
}
}
else
{
_sso.scheduler.reset_schedule( first_son_bitcoin );
}
while( !_sso.scheduler.get_slot(schedule_needs_filled.at(sidechain_type::bitcoin), son_bitcoin) )
{
if( _sso.scheduler.produce_schedule(rng) & emit_turn )
memcpy(_sso.rng_seed.begin(), dpo.random.data(), dpo.random.data_size());
}
_sso.last_scheduling_block = next_block.block_num();
_sso.recent_slots_filled = (
(_sso.recent_slots_filled << 1)
+ 1) << (schedule_slot - 1);
});
auto end = fc::time_point::now();
static uint64_t total_time = 0;
static uint64_t calls = 0;

View file

@ -242,6 +242,15 @@ namespace graphene { namespace chain {
*/
witness_id_type get_scheduled_witness(uint32_t slot_num)const;
/**
* @brief Get son schedule id for the given sidechain_type.
*
* type sidechain_type we getting schedule.
*
* returns Id of the schedule object.
*/
unsigned_int get_son_schedule_id(sidechain_type type)const;
/**
* @brief Get the bitcoin or hive son scheduled for block production in a slot.
*

View file

@ -52,13 +52,13 @@ namespace graphene { namespace chain {
uint32_t next_available_vote_id = 0;
vector<committee_member_id_type> active_committee_members; // updated once per maintenance interval
flat_set<witness_id_type> active_witnesses; // updated once per maintenance interval
//! Fixme - delete sidechain type from here
flat_map<sidechain_type, vector<son_info> > active_sons = []() // updated once per maintenance interval
{
flat_map<sidechain_type, vector<son_info> > active_sons;
active_sons[sidechain_type::bitcoin] = vector<son_info>();
active_sons[sidechain_type::hive] = vector<son_info>();
for(const auto& active_sidechain_type : active_sidechain_types)
{
active_sons[active_sidechain_type] = vector<son_info>();
}
return active_sons;
}();
// n.b. witness scheduling is done by witness_schedule object

View file

@ -1,5 +1,6 @@
#pragma once
#include <set>
#include <fc/reflect/reflect.hpp>
namespace graphene { namespace chain {
@ -13,6 +14,8 @@ enum class sidechain_type {
hive
};
static const std::set<sidechain_type> active_sidechain_types = {sidechain_type::bitcoin, sidechain_type::hive};
} }
FC_REFLECT_ENUM(graphene::chain::sidechain_type,
@ -21,4 +24,4 @@ FC_REFLECT_ENUM(graphene::chain::sidechain_type,
(ethereum)
(eos)
(hive)
(peerplays) )
(peerplays) )

View file

@ -71,12 +71,13 @@ namespace graphene { namespace chain {
public_key_type signing_key;
vesting_balance_id_type pay_vb;
son_statistics_id_type statistics;
//! Fixme - delete sidechain type from here
flat_map<sidechain_type, son_status> statuses = []()
{
flat_map<sidechain_type, son_status> statuses;
statuses[sidechain_type::bitcoin] = son_status::inactive;
statuses[sidechain_type::hive] = son_status::inactive;
for(const auto& active_sidechain_type : active_sidechain_types)
{
statuses[active_sidechain_type] = son_status::inactive;
}
return statuses;
}();
flat_map<sidechain_type, string> sidechain_public_keys;

@ -1 +1 @@
Subproject commit 6171e973c7fcfc9e0a39eaee2f05da84416a90e6
Subproject commit 711b04fb4f21bcaf8fdf00f51f4d6410849bec92

View file

@ -310,6 +310,7 @@ const son_object peerplays_sidechain_plugin_impl::get_son_object(son_id_type son
return *son_obj;
}
//! Fixme - do we need to provide sidechain_type as param for this function?
bool peerplays_sidechain_plugin_impl::is_active_son(son_id_type son_id) {
const auto &idx = plugin.database().get_index_type<chain::son_index>().indices().get<by_id>();
auto son_obj = idx.find(son_id);
@ -319,13 +320,14 @@ bool peerplays_sidechain_plugin_impl::is_active_son(son_id_type son_id) {
//! Fixme - now only bitcoin, fix according to sidechain_type
const chain::global_property_object &gpo = plugin.database().get_global_properties();
vector<son_id_type> active_son_ids;
active_son_ids.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size());
std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(),
std::inserter(active_son_ids, active_son_ids.end()),
[](const son_info &swi) {
return swi.son_id;
});
set<son_id_type> active_son_ids;
for(const auto& active_sidechain_type : active_sidechain_types) {
std::transform(gpo.active_sons.at(active_sidechain_type).cbegin(), gpo.active_sons.at(active_sidechain_type).cend(),
std::inserter(active_son_ids, active_son_ids.end()),
[](const son_info &swi) {
return swi.son_id;
});
}
auto it = std::find(active_son_ids.begin(), active_son_ids.end(), son_id);
@ -456,9 +458,13 @@ void peerplays_sidechain_plugin_impl::schedule_son_processing() {
}
void peerplays_sidechain_plugin_impl::son_processing() {
//! Fixme - here we must check size for every sidechain
if (plugin.database().get_global_properties().active_sons.at(sidechain_type::bitcoin).size() <= 0 &&
plugin.database().get_global_properties().active_sons.at(sidechain_type::hive).size() <= 0) {
//! Check whether we have active SONs
bool have_active_sons = false;
for(const auto& active_sidechain_type : active_sidechain_types) {
if(plugin.database().get_global_properties().active_sons.at(active_sidechain_type).size() >= 0)
have_active_sons = true;
}
if (!have_active_sons) {
return;
}

View file

@ -2231,20 +2231,28 @@ public:
return sign_transaction( tx, broadcast );
} FC_CAPTURE_AND_RETHROW( (owner_account) ) }
//! Fixme - do we need to specify sidechain_type as params here?
map<string, son_id_type> list_active_sons()
{
try
{
//! Fixme - now only bitcoin, fix according to sidechain_type
const global_property_object& gpo = get_global_properties();
set<son_id_type> son_ids_set;
for(const auto& active_sidechain_type : active_sidechain_types)
{
std::transform(gpo.active_sons.at(active_sidechain_type).cbegin(), gpo.active_sons.at(active_sidechain_type).cend(),
std::inserter(son_ids_set, son_ids_set.end()),
[](const son_info &swi) {
return swi.son_id;
});
}
vector<son_id_type> son_ids;
son_ids.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size());
std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(),
std::inserter(son_ids, son_ids.end()),
[](const son_info& swi) {
return swi.son_id;
});
son_ids.reserve(son_ids_set.size());
for(const auto& son_id : son_ids_set)
{
son_ids.emplace_back(son_id);
}
std::vector<fc::optional<son_object>> son_objects = _remote_db->get_sons(son_ids);
vector<std::string> owners;
for(auto obj: son_objects)
@ -2267,6 +2275,7 @@ public:
FC_CAPTURE_AND_RETHROW()
}
//! Fixme - do we need to specify sidechain_type as params here?
map<son_id_type, string> get_son_network_status()
{
try