#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(); _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 #ifndef NDEBUG
const son_schedule_object& ssobitcoin = 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(); _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 counters
create<fba_accumulator_object>([&]( fba_accumulator_object& acc ) 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(); time_point_sec now = head_block_time();
const dynamic_global_property_object& dpo = get_dynamic_global_properties(); 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 // 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()))) { 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()); for(const auto& active_sidechain_type : active_sidechain_types)
// After SON2 HF
uint64_t total_votes = 0;
for( const son_object& son : sons )
{ {
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);
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 ) {
auto get_weight = [&bits_to_drop]( uint64_t son_votes ) { uint16_t weight = std::max((son_votes >> bits_to_drop), uint64_t(1) );
uint16_t weight = std::max((son_votes >> bits_to_drop), uint64_t(1) ); return weight;
return weight; };
}; // Before SON2 HF
// Before SON2 HF auto get_weight_before_son2_hf = []( uint64_t son_votes ) {
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);
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) );
uint16_t weight = std::max((son_votes >> bits_to_drop), uint64_t(1) ); return weight;
return weight; };
}; uint64_t weighted_total_txs_signed = 0;
uint64_t weighted_total_txs_signed = 0; share_type son_budget = dpo.son_budget;
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) {
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 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){
const auto& idx = get_index_type<son_index>().indices().get<by_id>(); const auto& idx = get_index_type<son_index>().indices().get<by_id>();
auto son_obj = idx.find( s.owner ); auto son_obj = idx.find( s.owner );
uint16_t son_weight = 0; uint16_t son_weight = 0;
if( now >= HARDFORK_SON2_TIME ) { if( now >= HARDFORK_SON2_TIME ) {
for (const auto& vote_id : son_obj->sidechain_vote_ids) { son_weight += get_weight(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]);
son_weight += get_weight(_vote_tally_buffer[vote_id.second]);
}
} }
else { else {
for (const auto& vote_id : son_obj->sidechain_vote_ids) { son_weight += get_weight_before_son2_hf(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]);
son_weight += get_weight_before_son2_hf(_vote_tally_buffer[vote_id.second]);
}
} }
share_type pay = (txs_signed * son_weight * son_budget.value)/weighted_total_txs_signed; uint64_t txs_signed = 0;
modify( *son_obj, [&]( son_object& _son_obj) for (const auto &ts : s.txs_signed) {
{ txs_signed = txs_signed + ts.second;
_son_obj.pay_son_fee(pay, *this); }
}); weighted_total_txs_signed += (txs_signed * son_weight);
//Remove the amount paid out to SON from global SON Budget });
modify( dpo, [&]( dynamic_global_property_object& _dpo )
{ // Now pay off each SON proportional to the number of transactions signed.
_dpo.son_budget -= pay; 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);
//Reset the tx counter in each son statistics object uint64_t txs_signed = 0;
modify( s, [&]( son_statistics_object& _s) for (const auto &ts : s.txs_signed) {
{ txs_signed = txs_signed + ts.second;
for (const auto &ts : s.txs_signed) { }
_s.txs_signed.at(ts.first) = 0;
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)]);
} }
}); else {
} son_weight += get_weight_before_son2_hf(_vote_tally_buffer[son_obj->sidechain_vote_ids.at(active_sidechain_type)]);
}); }
//Note the last son pay out time share_type pay = (txs_signed * son_weight * son_budget.value)/weighted_total_txs_signed;
modify( dpo, [&]( dynamic_global_property_object& _dpo ) modify( *son_obj, [&]( son_object& _son_obj)
{ {
_dpo.last_son_payout_time = now; _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 global_property_object& gpo = get_global_properties();
const chain_parameters& cp = gpo.parameters; 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(); 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; auto& local_vote_buffer_ref = _vote_tally_buffer;
for( const son_object& son : all_sons ) 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); const son_schedule_object& sso = son_schedule_id_type()(*this);
modify(sso, [&](son_schedule_object& _sso) 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 for(const auto& active_sidechain_type : active_sidechain_types)
// 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)
{ {
flat_set<son_id_type> active_sons; const son_schedule_object& sidechain_sso = son_schedule_id_type(get_son_schedule_id(active_sidechain_type))(*this);
active_sons.reserve(gpo.active_sons.at(sidechain_type::hive).size()); modify(sidechain_sso, [&](son_schedule_object& _sso)
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)
{ {
witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV); flat_set<son_id_type> active_sons;
for( size_t i=0; i<new_active_sons.at(sidechain_type::hive).size(); ++i ) active_sons.reserve(gpo.active_sons.at(active_sidechain_type).size());
_sso.scheduler.produce_schedule(rng); 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;
// 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 _sso.scheduler.update(active_sons);
// active_sons that are bitcoin // similar to witness, produce schedule for sons
const son_schedule_object& ssobitcoin = son_schedule_id_type(2)(*this); if(cur_active_sons.at(active_sidechain_type).size() == 0 && new_active_sons.at(active_sidechain_type).size() > 0)
modify(ssobitcoin, [&](son_schedule_object& _sso) {
{ witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV);
flat_set<son_id_type> active_sons; for( size_t i=0; i<new_active_sons.at(active_sidechain_type).size(); ++i )
active_sons.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size()); _sso.scheduler.produce_schedule(rng);
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;
}); });
_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() } } FC_CAPTURE_AND_RETHROW() }
void database::initialize_budget_record( fc::time_point_sec now, budget_record& rec )const 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; 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 database::get_scheduled_son( sidechain_type type, uint32_t slot_num )const
{ {
son_id_type sid; 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) if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SHUFFLED_ALGORITHM)
{ {
const dynamic_global_property_object& dpo = get_dynamic_global_properties(); 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; uint64_t current_aslot = dpo.current_aslot + slot_num;
return sso.current_shuffled_sons.at(type)[ current_aslot % sso.current_shuffled_sons.size() ]; return sso.current_shuffled_sons.at(type)[ current_aslot % sso.current_shuffled_sons.size() ];
} }
if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM && if (gpo.parameters.witness_schedule_algorithm == GRAPHENE_WITNESS_SCHEDULED_ALGORITHM &&
slot_num != 0 ) 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 // ask the near scheduler who goes in the given slot
bool slot_is_near = sso.scheduler.get_slot(slot_num-1, sid); bool slot_is_near = sso.scheduler.get_slot(slot_num-1, sid);
if(! slot_is_near) if(! slot_is_near)
@ -192,8 +202,8 @@ void database::update_witness_schedule()
void database::update_son_schedule() void database::update_son_schedule()
{ {
const son_schedule_object& sso = son_schedule_id_type()(*this); 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& ssohive = son_schedule_id_type(get_son_schedule_id(sidechain_type::hive))(*this);
const son_schedule_object& ssobitcoin = son_schedule_id_type(2)(*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(); const global_property_object& gpo = get_global_properties();
//! Fixme - here we should take active_sons size for sidechain //! 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(); auto start = fc::time_point::now();
const global_property_object& gpo = get_global_properties(); const global_property_object& gpo = get_global_properties();
const son_schedule_object& sso = get(son_schedule_id_type()); 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]() const flat_map<sidechain_type, uint32_t> schedule_needs_filled = [&gpo]()
{ {
flat_map<sidechain_type, uint32_t> schedule_needs_filled; 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 ); bool slot_is_near = sso.scheduler.get_slot( schedule_slot-1, first_son );
son_id_type 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(); const dynamic_global_property_object& dpo = get_dynamic_global_properties();
assert( dpo.random.data_size() == witness_scheduler_rng::seed_length ); assert( dpo.random.data_size() == witness_scheduler_rng::seed_length );
assert( witness_scheduler_rng::seed_length == sso.rng_seed.size() ); assert( witness_scheduler_rng::seed_length == sso.rng_seed.size() );
//! Fixme - this schedule (delete it?)
modify(sso, [&](son_schedule_object& _sso) modify(sso, [&](son_schedule_object& _sso)
{ {
_sso.slots_since_genesis += schedule_slot; _sso.slots_since_genesis += schedule_slot;
@ -471,71 +472,47 @@ void database::update_son_schedule(const signed_block& next_block)
+ 1) << (schedule_slot - 1); + 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; const son_schedule_object& sidechain_sso = get(son_schedule_id_type(get_son_schedule_id(active_sidechain_type)));
witness_scheduler_rng rng(ssohive.rng_seed.data, _sso.slots_since_genesis); 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 ) _sso.scheduler._min_token_count = std::max(int(gpo.active_sons.at(active_sidechain_type).size()) / 2, 1);
{
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);
});
modify(ssobitcoin, [&](son_schedule_object& _sso) if( slot_is_near_hive )
{ {
_sso.slots_since_genesis += schedule_slot; uint32_t drain = schedule_slot;
witness_scheduler_rng rng(ssohive.rng_seed.data, _sso.slots_since_genesis); 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(); auto end = fc::time_point::now();
static uint64_t total_time = 0; static uint64_t total_time = 0;
static uint64_t calls = 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; 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. * @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; uint32_t next_available_vote_id = 0;
vector<committee_member_id_type> active_committee_members; // updated once per maintenance interval 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 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 = []() // updated once per maintenance interval
{ {
flat_map<sidechain_type, vector<son_info> > active_sons; flat_map<sidechain_type, vector<son_info> > active_sons;
active_sons[sidechain_type::bitcoin] = vector<son_info>(); for(const auto& active_sidechain_type : active_sidechain_types)
active_sons[sidechain_type::hive] = vector<son_info>(); {
active_sons[active_sidechain_type] = vector<son_info>();
}
return active_sons; return active_sons;
}(); }();
// n.b. witness scheduling is done by witness_schedule object // n.b. witness scheduling is done by witness_schedule object

View file

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

View file

@ -71,12 +71,13 @@ namespace graphene { namespace chain {
public_key_type signing_key; public_key_type signing_key;
vesting_balance_id_type pay_vb; vesting_balance_id_type pay_vb;
son_statistics_id_type statistics; 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 = []()
{ {
flat_map<sidechain_type, son_status> statuses; flat_map<sidechain_type, son_status> statuses;
statuses[sidechain_type::bitcoin] = son_status::inactive; for(const auto& active_sidechain_type : active_sidechain_types)
statuses[sidechain_type::hive] = son_status::inactive; {
statuses[active_sidechain_type] = son_status::inactive;
}
return statuses; return statuses;
}(); }();
flat_map<sidechain_type, string> sidechain_public_keys; 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; 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) { 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>(); const auto &idx = plugin.database().get_index_type<chain::son_index>().indices().get<by_id>();
auto son_obj = idx.find(son_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 //! Fixme - now only bitcoin, fix according to sidechain_type
const chain::global_property_object &gpo = plugin.database().get_global_properties(); const chain::global_property_object &gpo = plugin.database().get_global_properties();
vector<son_id_type> active_son_ids; set<son_id_type> active_son_ids;
active_son_ids.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size()); for(const auto& active_sidechain_type : active_sidechain_types) {
std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(), 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()), std::inserter(active_son_ids, active_son_ids.end()),
[](const son_info &swi) { [](const son_info &swi) {
return swi.son_id; return swi.son_id;
}); });
}
auto it = std::find(active_son_ids.begin(), active_son_ids.end(), 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() { void peerplays_sidechain_plugin_impl::son_processing() {
//! Fixme - here we must check size for every sidechain //! Check whether we have active SONs
if (plugin.database().get_global_properties().active_sons.at(sidechain_type::bitcoin).size() <= 0 && bool have_active_sons = false;
plugin.database().get_global_properties().active_sons.at(sidechain_type::hive).size() <= 0) { 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; return;
} }

View file

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