#308 - multiple lists of active_sons
This commit is contained in:
parent
00837a9a8b
commit
cbca83a90e
23 changed files with 448 additions and 410 deletions
|
|
@ -293,7 +293,7 @@ bool database::is_son_dereg_valid( son_id_type son_id )
|
||||||
(head_block_time() - son->statistics(*this).last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time())));
|
(head_block_time() - son->statistics(*this).last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time())));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool database::is_son_active( son_id_type son_id )
|
bool database::is_son_active( sidechain_type type, son_id_type son_id )
|
||||||
{
|
{
|
||||||
const auto& son_idx = get_index_type<son_index>().indices().get< by_id >();
|
const auto& son_idx = get_index_type<son_index>().indices().get< by_id >();
|
||||||
auto son = son_idx.find( son_id );
|
auto son = son_idx.find( son_id );
|
||||||
|
|
@ -303,9 +303,15 @@ bool database::is_son_active( son_id_type son_id )
|
||||||
}
|
}
|
||||||
|
|
||||||
const global_property_object& gpo = get_global_properties();
|
const global_property_object& gpo = get_global_properties();
|
||||||
|
if(!gpo.active_sons.contains(type))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& gpo_as = gpo.active_sons.at(type);
|
||||||
vector<son_id_type> active_son_ids;
|
vector<son_id_type> active_son_ids;
|
||||||
active_son_ids.reserve(gpo.active_sons.size());
|
active_son_ids.reserve(gpo_as.size());
|
||||||
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
|
std::transform(gpo_as.cbegin(), gpo_as.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;
|
||||||
|
|
|
||||||
|
|
@ -280,122 +280,121 @@ void database::pay_sons()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void database::update_son_metrics(const vector<son_info>& curr_active_sons)
|
void database::update_son_metrics(const flat_map<sidechain_type, vector<son_info> >& curr_active_sons)
|
||||||
{
|
{
|
||||||
vector<son_id_type> current_sons;
|
for(const auto& curr_active_sidechain_sons : curr_active_sons) {
|
||||||
|
const auto& sidechain = curr_active_sidechain_sons.first;
|
||||||
|
const auto& _curr_active_sidechain_sons = curr_active_sidechain_sons.second;
|
||||||
|
|
||||||
current_sons.reserve(curr_active_sons.size());
|
vector<son_id_type> current_sons;
|
||||||
std::transform(curr_active_sons.begin(), curr_active_sons.end(),
|
|
||||||
std::inserter(current_sons, current_sons.end()),
|
|
||||||
[](const son_info &swi) {
|
|
||||||
return swi.son_id;
|
|
||||||
});
|
|
||||||
|
|
||||||
const auto& son_idx = get_index_type<son_index>().indices().get< by_id >();
|
current_sons.reserve(_curr_active_sidechain_sons.size());
|
||||||
for( auto& son : son_idx )
|
std::transform(_curr_active_sidechain_sons.cbegin(), _curr_active_sidechain_sons.cend(),
|
||||||
{
|
std::inserter(current_sons, current_sons.end()),
|
||||||
auto& stats = son.statistics(*this);
|
[](const son_info &swi) {
|
||||||
bool is_active_son = (std::find(current_sons.begin(), current_sons.end(), son.id) != current_sons.end());
|
return swi.son_id;
|
||||||
modify( stats, [&]( son_statistics_object& _stats )
|
});
|
||||||
{
|
|
||||||
if(is_active_son) {
|
const auto &son_idx = get_index_type<son_index>().indices().get<by_id>();
|
||||||
_stats.total_voted_time = _stats.total_voted_time + get_global_properties().parameters.maintenance_interval;
|
for (auto &son : son_idx) {
|
||||||
}
|
auto &stats = son.statistics(*this);
|
||||||
_stats.total_downtime += _stats.current_interval_downtime;
|
bool is_active_son = (std::find(current_sons.begin(), current_sons.end(), son.id) != current_sons.end());
|
||||||
_stats.current_interval_downtime = 0;
|
modify(stats, [&](son_statistics_object &_stats) {
|
||||||
for (const auto &str : _stats.sidechain_txs_reported) {
|
if (is_active_son) {
|
||||||
_stats.sidechain_txs_reported.at(str.first) = 0;
|
_stats.total_voted_time[sidechain] = _stats.total_voted_time[sidechain] + get_global_properties().parameters.maintenance_interval;
|
||||||
}
|
}
|
||||||
});
|
_stats.total_downtime[sidechain] += _stats.current_interval_downtime[sidechain];
|
||||||
|
_stats.current_interval_downtime[sidechain] = 0;
|
||||||
|
_stats.sidechain_txs_reported[sidechain] = 0;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void database::update_son_statuses(const vector<son_info>& curr_active_sons, const vector<son_info>& new_active_sons)
|
void database::update_son_statuses( const flat_map<sidechain_type, vector<son_info> >& curr_active_sons,
|
||||||
|
const flat_map<sidechain_type, vector<son_info> >& new_active_sons )
|
||||||
{
|
{
|
||||||
vector<son_id_type> current_sons, new_sons;
|
FC_ASSERT(curr_active_sons.size() == new_active_sons.size(), "Invalid size in SON active lists,"
|
||||||
vector<son_id_type> sons_to_remove, sons_to_add;
|
" curr_active_sons_size={curr_active_sons_size}, new_active_sons_size={new_active_sons_size}",
|
||||||
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
|
("curr_active_sons_size", curr_active_sons.size())("new_active_sons_size", new_active_sons.size()));
|
||||||
|
|
||||||
current_sons.reserve(curr_active_sons.size());
|
for(const auto& curr_active_sidechain_sons : curr_active_sons) {
|
||||||
std::transform(curr_active_sons.begin(), curr_active_sons.end(),
|
const auto& sidechain = curr_active_sidechain_sons.first;
|
||||||
std::inserter(current_sons, current_sons.end()),
|
|
||||||
[](const son_info &swi) {
|
|
||||||
return swi.son_id;
|
|
||||||
});
|
|
||||||
|
|
||||||
new_sons.reserve(new_active_sons.size());
|
vector<son_id_type> current_sons, new_sons;
|
||||||
std::transform(new_active_sons.begin(), new_active_sons.end(),
|
vector<son_id_type> sons_to_remove, sons_to_add;
|
||||||
std::inserter(new_sons, new_sons.end()),
|
const auto &idx = get_index_type<son_index>().indices().get<by_id>();
|
||||||
[](const son_info &swi) {
|
|
||||||
return swi.son_id;
|
|
||||||
});
|
|
||||||
|
|
||||||
// find all cur_active_sons members that is not in new_active_sons
|
current_sons.reserve(curr_active_sons.at(sidechain).size());
|
||||||
for_each(current_sons.begin(), current_sons.end(),
|
std::transform(curr_active_sons.at(sidechain).cbegin(), curr_active_sons.at(sidechain).cend(),
|
||||||
[&sons_to_remove, &new_sons](const son_id_type& si)
|
std::inserter(current_sons, current_sons.end()),
|
||||||
{
|
[](const son_info &swi) {
|
||||||
if(std::find(new_sons.begin(), new_sons.end(), si) ==
|
return swi.son_id;
|
||||||
new_sons.end())
|
});
|
||||||
{
|
|
||||||
sons_to_remove.push_back(si);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
for( const auto& sid : sons_to_remove )
|
new_sons.reserve(new_active_sons.at(sidechain).size());
|
||||||
{
|
std::transform(new_active_sons.at(sidechain).cbegin(), new_active_sons.at(sidechain).cend(),
|
||||||
auto son = idx.find( sid );
|
std::inserter(new_sons, new_sons.end()),
|
||||||
if(son == idx.end()) // SON is deleted already
|
[](const son_info &swi) {
|
||||||
continue;
|
return swi.son_id;
|
||||||
// keep maintenance status for nodes becoming inactive
|
});
|
||||||
if(son->status == son_status::active)
|
|
||||||
{
|
|
||||||
modify( *son, [&]( son_object& obj ){
|
|
||||||
obj.status = son_status::inactive;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// find all new_active_sons members that is not in cur_active_sons
|
// find all cur_active_sons members that is not in new_active_sons
|
||||||
for_each(new_sons.begin(), new_sons.end(),
|
for_each(current_sons.begin(), current_sons.end(),
|
||||||
[&sons_to_add, ¤t_sons](const son_id_type& si)
|
[&sons_to_remove, &new_sons](const son_id_type &si) {
|
||||||
{
|
if (std::find(new_sons.begin(), new_sons.end(), si) ==
|
||||||
if(std::find(current_sons.begin(), current_sons.end(), si) ==
|
new_sons.end()) {
|
||||||
current_sons.end())
|
sons_to_remove.push_back(si);
|
||||||
{
|
}
|
||||||
sons_to_add.push_back(si);
|
});
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
for( const auto& sid : sons_to_add )
|
for (const auto &sid : sons_to_remove) {
|
||||||
{
|
auto son = idx.find(sid);
|
||||||
auto son = idx.find( sid );
|
if (son == idx.end()) // SON is deleted already
|
||||||
FC_ASSERT(son != idx.end(), "Invalid SON in active list, id={sonid}.", ("sonid", sid));
|
|
||||||
// keep maintenance status for new nodes
|
|
||||||
if(son->status == son_status::inactive)
|
|
||||||
{
|
|
||||||
modify( *son, [&]( son_object& obj ){
|
|
||||||
obj.status = son_status::active;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ilog("New SONS");
|
|
||||||
for(size_t i = 0; i < new_sons.size(); i++) {
|
|
||||||
auto son = idx.find( new_sons[i] );
|
|
||||||
if(son == idx.end()) // SON is deleted already
|
|
||||||
continue;
|
continue;
|
||||||
ilog( "${s}, status = ${ss}, total_votes = ${sv}", ("s", new_sons[i])("ss", son->status)("sv", son->total_votes) );
|
// keep maintenance status for nodes becoming inactive
|
||||||
}
|
if (son->status == son_status::active) {
|
||||||
|
modify(*son, [&](son_object &obj) {
|
||||||
|
obj.status = son_status::inactive;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( sons_to_remove.size() > 0 )
|
// find all new_active_sons members that is not in cur_active_sons
|
||||||
{
|
for_each(new_sons.begin(), new_sons.end(),
|
||||||
remove_inactive_son_proposals(sons_to_remove);
|
[&sons_to_add, ¤t_sons](const son_id_type &si) {
|
||||||
|
if (std::find(current_sons.begin(), current_sons.end(), si) ==
|
||||||
|
current_sons.end()) {
|
||||||
|
sons_to_add.push_back(si);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const auto &sid : sons_to_add) {
|
||||||
|
auto son = idx.find(sid);
|
||||||
|
FC_ASSERT(son != idx.end(), "Invalid SON in active list, id={sonid}.", ("sonid", sid));
|
||||||
|
// keep maintenance status for new nodes
|
||||||
|
if (son->status == son_status::inactive) {
|
||||||
|
modify(*son, [&](son_object &obj) {
|
||||||
|
obj.status = son_status::active;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ilog("New SONS for sidechain = ${sidechain}", ("sidechain", sidechain));
|
||||||
|
for (size_t i = 0; i < new_sons.size(); i++) {
|
||||||
|
auto son = idx.find(new_sons[i]);
|
||||||
|
if (son == idx.end()) // SON is deleted already
|
||||||
|
continue;
|
||||||
|
ilog("${s}, status = ${ss}, total_votes = ${sv}", ("s", new_sons[i])("ss", son->status)("sv", son->total_votes));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sons_to_remove.size() > 0) {
|
||||||
|
remove_inactive_son_proposals(sons_to_remove);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void database::update_son_wallet(const vector<son_info>& new_active_sons)
|
void database::update_son_wallet(const flat_map<sidechain_type, vector<son_info> >& new_active_sons)
|
||||||
{
|
{
|
||||||
bool should_recreate_pw = true;
|
bool should_recreate_pw = true;
|
||||||
|
|
||||||
|
|
@ -408,8 +407,16 @@ void database::update_son_wallet(const vector<son_info>& new_active_sons)
|
||||||
|
|
||||||
bool wallet_son_sets_equal = (cur_wallet_sons.size() == new_active_sons.size());
|
bool wallet_son_sets_equal = (cur_wallet_sons.size() == new_active_sons.size());
|
||||||
if (wallet_son_sets_equal) {
|
if (wallet_son_sets_equal) {
|
||||||
for( size_t i = 0; i < cur_wallet_sons.size(); i++ ) {
|
for( const auto& cur_wallet_sidechain_sons : cur_wallet_sons ) {
|
||||||
wallet_son_sets_equal = wallet_son_sets_equal && cur_wallet_sons.at(i) == new_active_sons.at(i);
|
const auto& sidechain = cur_wallet_sidechain_sons.first;
|
||||||
|
const auto& _cur_wallet_sidechain_sons = cur_wallet_sidechain_sons.second;
|
||||||
|
|
||||||
|
wallet_son_sets_equal = wallet_son_sets_equal && (_cur_wallet_sidechain_sons.size() == new_active_sons.at(sidechain).size());
|
||||||
|
if (wallet_son_sets_equal) {
|
||||||
|
for (size_t i = 0; i < _cur_wallet_sidechain_sons.size(); i++) {
|
||||||
|
wallet_son_sets_equal = wallet_son_sets_equal && (_cur_wallet_sidechain_sons.at(i) == new_active_sons.at(sidechain).at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -429,7 +436,12 @@ void database::update_son_wallet(const vector<son_info>& new_active_sons)
|
||||||
create<son_wallet_object>( [&]( son_wallet_object& obj ) {
|
create<son_wallet_object>( [&]( son_wallet_object& obj ) {
|
||||||
obj.valid_from = head_block_time();
|
obj.valid_from = head_block_time();
|
||||||
obj.expires = time_point_sec::maximum();
|
obj.expires = time_point_sec::maximum();
|
||||||
obj.sons.insert(obj.sons.end(), new_active_sons.begin(), new_active_sons.end());
|
for(const auto& new_active_sidechain_sons : new_active_sons){
|
||||||
|
const auto& sidechain = new_active_sidechain_sons.first;
|
||||||
|
const auto& _new_active_sidechain_sons = new_active_sidechain_sons.second;
|
||||||
|
|
||||||
|
obj.sons[sidechain].insert(obj.sons[sidechain].end(), _new_active_sidechain_sons.cbegin(), _new_active_sidechain_sons.cend());
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -701,7 +713,10 @@ 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;
|
||||||
auto sons = sort_votable_objects<son_index>(sidechain_type::bitcoin, cp.maximum_son_count());
|
//! 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();
|
||||||
|
|
||||||
|
|
@ -729,21 +744,24 @@ void database::update_active_sons()
|
||||||
{
|
{
|
||||||
modify( get(gpo.parameters.son_account()), [&]( account_object& a )
|
modify( get(gpo.parameters.son_account()), [&]( account_object& a )
|
||||||
{
|
{
|
||||||
|
set<account_id_type> account_ids;
|
||||||
|
for(const auto& sidechain_sons : sons)
|
||||||
|
{
|
||||||
|
for( const son_object& son : sidechain_sons.second )
|
||||||
|
{
|
||||||
|
account_ids.emplace(son.son_account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( head_block_time() < HARDFORK_533_TIME )
|
if( head_block_time() < HARDFORK_533_TIME )
|
||||||
{
|
{
|
||||||
map<account_id_type, uint64_t> weights;
|
|
||||||
a.active.weight_threshold = 0;
|
a.active.weight_threshold = 0;
|
||||||
a.active.account_auths.clear();
|
a.active.account_auths.clear();
|
||||||
|
|
||||||
for( const son_object& son : sons )
|
for( const auto& account_id : account_ids )
|
||||||
{
|
|
||||||
weights.emplace(son.son_account, uint64_t(1));
|
|
||||||
}
|
|
||||||
|
|
||||||
for( const auto& weight : weights )
|
|
||||||
{
|
{
|
||||||
// Ensure that everyone has at least one vote. Zero weights aren't allowed.
|
// Ensure that everyone has at least one vote. Zero weights aren't allowed.
|
||||||
a.active.account_auths[weight.first] += 1;
|
a.active.account_auths[account_id] += 1;
|
||||||
a.active.weight_threshold += 1;
|
a.active.weight_threshold += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -754,8 +772,10 @@ void database::update_active_sons()
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vote_counter vc;
|
vote_counter vc;
|
||||||
for( const son_object& son : sons )
|
for( const auto& account_id : account_ids )
|
||||||
vc.add( son.son_account, UINT64_C(1) );
|
{
|
||||||
|
vc.add(account_id, UINT64_C(1));
|
||||||
|
}
|
||||||
vc.finish_2_3( a.active );
|
vc.finish_2_3( a.active );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
@ -763,22 +783,32 @@ void database::update_active_sons()
|
||||||
|
|
||||||
|
|
||||||
// Compare current and to-be lists of active sons
|
// Compare current and to-be lists of active sons
|
||||||
auto cur_active_sons = gpo.active_sons;
|
const auto& cur_active_sons = gpo.active_sons;
|
||||||
vector<son_info> new_active_sons;
|
flat_map<sidechain_type, vector<son_info> > new_active_sons;
|
||||||
const auto &acc = get(gpo.parameters.son_account());
|
const auto &acc = get(gpo.parameters.son_account());
|
||||||
for( const son_object& son : sons ) {
|
for( const auto& sidechain_sons : sons ){
|
||||||
son_info swi;
|
for( const son_object& son : sidechain_sons.second ) {
|
||||||
swi.son_id = son.id;
|
son_info swi;
|
||||||
swi.weight = acc.active.account_auths.at(son.son_account);
|
swi.son_id = son.id;
|
||||||
swi.signing_key = son.signing_key;
|
swi.weight = acc.active.account_auths.at(son.son_account);
|
||||||
swi.sidechain_public_keys = son.sidechain_public_keys;
|
swi.signing_key = son.signing_key;
|
||||||
new_active_sons.push_back(swi);
|
swi.sidechain_public_keys = son.sidechain_public_keys;
|
||||||
|
new_active_sons[sidechain_sons.first].push_back(swi);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool son_sets_equal = (cur_active_sons.size() == new_active_sons.size());
|
bool son_sets_equal = (cur_active_sons.size() == new_active_sons.size());
|
||||||
if (son_sets_equal) {
|
if (son_sets_equal) {
|
||||||
for( size_t i = 0; i < cur_active_sons.size(); i++ ) {
|
for( const auto& cur_active_sidechain_sons : cur_active_sons ){
|
||||||
son_sets_equal = son_sets_equal && cur_active_sons.at(i) == new_active_sons.at(i);
|
const auto& sidechain = cur_active_sidechain_sons.first;
|
||||||
|
const auto& _cur_active_sidechain_sons = cur_active_sidechain_sons.second;
|
||||||
|
|
||||||
|
son_sets_equal = son_sets_equal && (_cur_active_sidechain_sons.size() == new_active_sons.at(sidechain).size());
|
||||||
|
if (son_sets_equal) {
|
||||||
|
for (size_t i = 0; i < _cur_active_sidechain_sons.size(); i++) {
|
||||||
|
son_sets_equal = son_sets_equal && (_cur_active_sidechain_sons.at(i) == new_active_sons.at(sidechain).at(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -797,26 +827,12 @@ void database::update_active_sons()
|
||||||
modify(gpo, [&]( global_property_object& gp ){
|
modify(gpo, [&]( global_property_object& gp ){
|
||||||
gp.active_sons.clear();
|
gp.active_sons.clear();
|
||||||
gp.active_sons.reserve(new_active_sons.size());
|
gp.active_sons.reserve(new_active_sons.size());
|
||||||
gp.active_sons.insert(gp.active_sons.end(), new_active_sons.begin(), new_active_sons.end());
|
for( const auto& new_active_sidechain_sons : new_active_sons ) {
|
||||||
});
|
const auto& sidechain = new_active_sidechain_sons.first;
|
||||||
|
const auto& _new_active_sidechain_sons = new_active_sidechain_sons.second;
|
||||||
|
|
||||||
const son_schedule_object& sso = son_schedule_id_type()(*this);
|
gp.active_sons[sidechain].reserve(_new_active_sidechain_sons.size());
|
||||||
modify(sso, [&](son_schedule_object& _sso)
|
gp.active_sons[sidechain].insert(gp.active_sons[sidechain].end(), _new_active_sidechain_sons.cbegin(), _new_active_sidechain_sons.cend());
|
||||||
{
|
|
||||||
flat_set<son_id_type> active_sons;
|
|
||||||
active_sons.reserve(gpo.active_sons.size());
|
|
||||||
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
|
|
||||||
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.size() == 0 && new_active_sons.size() > 0)
|
|
||||||
{
|
|
||||||
witness_scheduler_rng rng(_sso.rng_seed.begin(), GRAPHENE_NEAR_SCHEDULE_CTR_IV);
|
|
||||||
for( size_t i=0; i<new_active_sons.size(); ++i )
|
|
||||||
_sso.scheduler.produce_schedule(rng);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -827,8 +843,8 @@ void database::update_active_sons()
|
||||||
modify(ssohive, [&](son_schedule_object& _sso)
|
modify(ssohive, [&](son_schedule_object& _sso)
|
||||||
{
|
{
|
||||||
flat_set<son_id_type> active_sons;
|
flat_set<son_id_type> active_sons;
|
||||||
active_sons.reserve(gpo.active_sons.size());
|
active_sons.reserve(gpo.active_sons.at(sidechain_type::hive).size());
|
||||||
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
|
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()),
|
std::inserter(active_sons, active_sons.end()),
|
||||||
[](const son_info& swi) {
|
[](const son_info& swi) {
|
||||||
return swi.son_id;
|
return swi.son_id;
|
||||||
|
|
@ -850,8 +866,8 @@ void database::update_active_sons()
|
||||||
modify(ssobitcoin, [&](son_schedule_object& _sso)
|
modify(ssobitcoin, [&](son_schedule_object& _sso)
|
||||||
{
|
{
|
||||||
flat_set<son_id_type> active_sons;
|
flat_set<son_id_type> active_sons;
|
||||||
active_sons.reserve(gpo.active_sons.size());
|
active_sons.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size());
|
||||||
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
|
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()),
|
std::inserter(active_sons, active_sons.end()),
|
||||||
[](const son_info& swi) {
|
[](const son_info& swi) {
|
||||||
return swi.son_id;
|
return swi.son_id;
|
||||||
|
|
|
||||||
|
|
@ -74,49 +74,6 @@ witness_id_type database::get_scheduled_witness( uint32_t slot_num )const
|
||||||
return wid;
|
return wid;
|
||||||
}
|
}
|
||||||
|
|
||||||
son_id_type database::get_scheduled_son( uint32_t slot_num )const
|
|
||||||
{
|
|
||||||
son_id_type sid;
|
|
||||||
const global_property_object& gpo = get_global_properties();
|
|
||||||
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 = son_schedule_id_type()(*this);
|
|
||||||
uint64_t current_aslot = dpo.current_aslot + slot_num;
|
|
||||||
return sso.current_shuffled_sons[ 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 = 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)
|
|
||||||
{
|
|
||||||
// if the near scheduler doesn't know, we have to extend it to
|
|
||||||
// a far scheduler.
|
|
||||||
// n.b. instantiating it is slow, but block gaps long enough to
|
|
||||||
// need it are likely pretty rare.
|
|
||||||
|
|
||||||
witness_scheduler_rng far_rng(sso.rng_seed.begin(), GRAPHENE_FAR_SCHEDULE_CTR_IV);
|
|
||||||
|
|
||||||
far_future_son_scheduler far_scheduler =
|
|
||||||
far_future_son_scheduler(sso.scheduler, far_rng);
|
|
||||||
if(!far_scheduler.get_slot(slot_num-1, sid))
|
|
||||||
{
|
|
||||||
// no scheduled son -- somebody set up us the bomb
|
|
||||||
// n.b. this code path is impossible, the present
|
|
||||||
// implementation of far_future_son_scheduler
|
|
||||||
// returns true unconditionally
|
|
||||||
assert( false );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sid;
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is just prototype to prove that active_sons are in hive schedule_object and
|
|
||||||
// bitcoin schedule object
|
|
||||||
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;
|
||||||
|
|
@ -126,7 +83,7 @@ son_id_type database::get_scheduled_son( sidechain_type type, uint32_t slot_num
|
||||||
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 = type == sidechain_type::hive ? son_schedule_id_type(1)(*this) : son_schedule_id_type(2)(*this);
|
||||||
uint64_t current_aslot = dpo.current_aslot + slot_num;
|
uint64_t current_aslot = dpo.current_aslot + slot_num;
|
||||||
return sso.current_shuffled_sons[ 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 )
|
||||||
|
|
@ -246,24 +203,37 @@ void database::update_son_schedule()
|
||||||
_sso.current_shuffled_sons.clear();
|
_sso.current_shuffled_sons.clear();
|
||||||
_sso.current_shuffled_sons.reserve( gpo.active_sons.size() );
|
_sso.current_shuffled_sons.reserve( gpo.active_sons.size() );
|
||||||
|
|
||||||
for( const son_info& w : gpo.active_sons )
|
for(const auto& sidechain_sons : gpo.active_sons)
|
||||||
_sso.current_shuffled_sons.push_back( w.son_id );
|
{
|
||||||
|
const auto& sidechain = sidechain_sons.first;
|
||||||
|
const auto& active_sons = sidechain_sons.second;
|
||||||
|
|
||||||
|
_sso.current_shuffled_sons[sidechain].reserve( active_sons.size() );
|
||||||
|
for (const son_info &w : active_sons)
|
||||||
|
_sso.current_shuffled_sons[sidechain].push_back(w.son_id);
|
||||||
|
}
|
||||||
|
|
||||||
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32;
|
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32;
|
||||||
for( uint32_t i = 0; i < _sso.current_shuffled_sons.size(); ++i )
|
for(const auto& sidechain_current_shuffled_sons : _sso.current_shuffled_sons)
|
||||||
{
|
{
|
||||||
/// High performance random generator
|
const auto& sidechain = sidechain_current_shuffled_sons.first;
|
||||||
/// http://xorshift.di.unimi.it/
|
const auto& current_shuffled_sons = sidechain_current_shuffled_sons.second;
|
||||||
uint64_t k = now_hi + uint64_t(i)*2685821657736338717ULL;
|
|
||||||
k ^= (k >> 12);
|
|
||||||
k ^= (k << 25);
|
|
||||||
k ^= (k >> 27);
|
|
||||||
k *= 2685821657736338717ULL;
|
|
||||||
|
|
||||||
uint32_t jmax = _sso.current_shuffled_sons.size() - i;
|
for (uint32_t i = 0; i < current_shuffled_sons.size(); ++i)
|
||||||
uint32_t j = i + k%jmax;
|
{
|
||||||
std::swap( _sso.current_shuffled_sons[i],
|
/// High performance random generator
|
||||||
_sso.current_shuffled_sons[j] );
|
/// http://xorshift.di.unimi.it/
|
||||||
|
uint64_t k = now_hi + uint64_t(i) * 2685821657736338717ULL;
|
||||||
|
k ^= (k >> 12);
|
||||||
|
k ^= (k << 25);
|
||||||
|
k ^= (k >> 27);
|
||||||
|
k *= 2685821657736338717ULL;
|
||||||
|
|
||||||
|
uint32_t jmax = current_shuffled_sons.size() - i;
|
||||||
|
uint32_t j = i + k % jmax;
|
||||||
|
std::swap(_sso.current_shuffled_sons[sidechain][i],
|
||||||
|
_sso.current_shuffled_sons[sidechain][j]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -272,24 +242,36 @@ void database::update_son_schedule()
|
||||||
_sso.current_shuffled_sons.clear();
|
_sso.current_shuffled_sons.clear();
|
||||||
_sso.current_shuffled_sons.reserve( gpo.active_sons.size() );
|
_sso.current_shuffled_sons.reserve( gpo.active_sons.size() );
|
||||||
|
|
||||||
for( const son_info& w : gpo.active_sons )
|
for(const auto& sidechain_sons : gpo.active_sons)
|
||||||
_sso.current_shuffled_sons.push_back( w.son_id );
|
{
|
||||||
|
const auto& sidechain = sidechain_sons.first;
|
||||||
|
const auto& active_sons = sidechain_sons.second;
|
||||||
|
|
||||||
|
for (const son_info &w : active_sons)
|
||||||
|
_sso.current_shuffled_sons[sidechain].push_back(w.son_id);
|
||||||
|
}
|
||||||
|
|
||||||
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32;
|
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32;
|
||||||
for( uint32_t i = 0; i < _sso.current_shuffled_sons.size(); ++i )
|
for(const auto& sidechain_current_shuffled_sons : _sso.current_shuffled_sons)
|
||||||
{
|
{
|
||||||
/// High performance random generator
|
const auto& sidechain = sidechain_current_shuffled_sons.first;
|
||||||
/// http://xorshift.di.unimi.it/
|
const auto& current_shuffled_sons = sidechain_current_shuffled_sons.second;
|
||||||
uint64_t k = now_hi + uint64_t(i)*2685821657736338717ULL;
|
|
||||||
k ^= (k >> 12);
|
|
||||||
k ^= (k << 25);
|
|
||||||
k ^= (k >> 27);
|
|
||||||
k *= 2685821657736338717ULL;
|
|
||||||
|
|
||||||
uint32_t jmax = _sso.current_shuffled_sons.size() - i;
|
for (uint32_t i = 0; i < current_shuffled_sons.size(); ++i)
|
||||||
uint32_t j = i + k%jmax;
|
{
|
||||||
std::swap( _sso.current_shuffled_sons[i],
|
/// High performance random generator
|
||||||
_sso.current_shuffled_sons[j] );
|
/// http://xorshift.di.unimi.it/
|
||||||
|
uint64_t k = now_hi + uint64_t(i) * 2685821657736338717ULL;
|
||||||
|
k ^= (k >> 12);
|
||||||
|
k ^= (k << 25);
|
||||||
|
k ^= (k >> 27);
|
||||||
|
k *= 2685821657736338717ULL;
|
||||||
|
|
||||||
|
uint32_t jmax = current_shuffled_sons.size() - i;
|
||||||
|
uint32_t j = i + k % jmax;
|
||||||
|
std::swap(_sso.current_shuffled_sons[sidechain][i],
|
||||||
|
_sso.current_shuffled_sons[sidechain][j]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -298,24 +280,36 @@ void database::update_son_schedule()
|
||||||
_sso.current_shuffled_sons.clear();
|
_sso.current_shuffled_sons.clear();
|
||||||
_sso.current_shuffled_sons.reserve( gpo.active_sons.size() );
|
_sso.current_shuffled_sons.reserve( gpo.active_sons.size() );
|
||||||
|
|
||||||
for( const son_info& w : gpo.active_sons )
|
for(const auto& sidechain_sons : gpo.active_sons)
|
||||||
_sso.current_shuffled_sons.push_back( w.son_id );
|
{
|
||||||
|
const auto& sidechain = sidechain_sons.first;
|
||||||
|
const auto& active_sons = sidechain_sons.second;
|
||||||
|
|
||||||
|
for (const son_info &w : active_sons)
|
||||||
|
_sso.current_shuffled_sons[sidechain].push_back(w.son_id);
|
||||||
|
}
|
||||||
|
|
||||||
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32;
|
auto now_hi = uint64_t(head_block_time().sec_since_epoch()) << 32;
|
||||||
for( uint32_t i = 0; i < _sso.current_shuffled_sons.size(); ++i )
|
for(const auto& sidechain_current_shuffled_sons : _sso.current_shuffled_sons)
|
||||||
{
|
{
|
||||||
/// High performance random generator
|
const auto& sidechain = sidechain_current_shuffled_sons.first;
|
||||||
/// http://xorshift.di.unimi.it/
|
const auto& current_shuffled_sons = sidechain_current_shuffled_sons.second;
|
||||||
uint64_t k = now_hi + uint64_t(i)*2685821657736338717ULL;
|
|
||||||
k ^= (k >> 12);
|
|
||||||
k ^= (k << 25);
|
|
||||||
k ^= (k >> 27);
|
|
||||||
k *= 2685821657736338717ULL;
|
|
||||||
|
|
||||||
uint32_t jmax = _sso.current_shuffled_sons.size() - i;
|
for (uint32_t i = 0; i < current_shuffled_sons.size(); ++i)
|
||||||
uint32_t j = i + k%jmax;
|
{
|
||||||
std::swap( _sso.current_shuffled_sons[i],
|
/// High performance random generator
|
||||||
_sso.current_shuffled_sons[j] );
|
/// http://xorshift.di.unimi.it/
|
||||||
|
uint64_t k = now_hi + uint64_t(i) * 2685821657736338717ULL;
|
||||||
|
k ^= (k >> 12);
|
||||||
|
k ^= (k << 25);
|
||||||
|
k ^= (k >> 27);
|
||||||
|
k *= 2685821657736338717ULL;
|
||||||
|
|
||||||
|
uint32_t jmax = current_shuffled_sons.size() - i;
|
||||||
|
uint32_t j = i + k % jmax;
|
||||||
|
std::swap(_sso.current_shuffled_sons[sidechain][i],
|
||||||
|
_sso.current_shuffled_sons[sidechain][j]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -242,22 +242,6 @@ 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 the son scheduled for block production in a slot.
|
|
||||||
*
|
|
||||||
* slot_num always corresponds to a time in the future.
|
|
||||||
*
|
|
||||||
* If slot_num == 1, returns the next scheduled son.
|
|
||||||
* If slot_num == 2, returns the next scheduled son after
|
|
||||||
* 1 block gap.
|
|
||||||
*
|
|
||||||
* Use the get_slot_time() and get_slot_at_time() functions
|
|
||||||
* to convert between slot_num and timestamp.
|
|
||||||
*
|
|
||||||
* Passing slot_num == 0 returns GRAPHENE_NULL_WITNESS
|
|
||||||
*/
|
|
||||||
son_id_type get_scheduled_son(uint32_t slot_num)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.
|
||||||
*
|
*
|
||||||
|
|
@ -327,7 +311,7 @@ namespace graphene { namespace chain {
|
||||||
fc::optional<operation> create_son_deregister_proposal( son_id_type son_id, account_id_type paying_son );
|
fc::optional<operation> create_son_deregister_proposal( son_id_type son_id, account_id_type paying_son );
|
||||||
signed_transaction create_signed_transaction( const fc::ecc::private_key& signing_private_key, const operation& op );
|
signed_transaction create_signed_transaction( const fc::ecc::private_key& signing_private_key, const operation& op );
|
||||||
bool is_son_dereg_valid( son_id_type son_id );
|
bool is_son_dereg_valid( son_id_type son_id );
|
||||||
bool is_son_active( son_id_type son_id );
|
bool is_son_active( sidechain_type type, son_id_type son_id );
|
||||||
bool is_asset_creation_allowed(const string& symbol);
|
bool is_asset_creation_allowed(const string& symbol);
|
||||||
|
|
||||||
time_point_sec head_block_time()const;
|
time_point_sec head_block_time()const;
|
||||||
|
|
@ -586,13 +570,14 @@ namespace graphene { namespace chain {
|
||||||
void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props);
|
void perform_chain_maintenance(const signed_block& next_block, const global_property_object& global_props);
|
||||||
void update_active_witnesses();
|
void update_active_witnesses();
|
||||||
void update_active_committee_members();
|
void update_active_committee_members();
|
||||||
void update_son_metrics( const vector<son_info>& curr_active_sons );
|
void update_son_metrics( const flat_map<sidechain_type, vector<son_info> >& curr_active_sons );
|
||||||
void update_active_sons();
|
void update_active_sons();
|
||||||
void remove_son_proposal( const proposal_object& proposal );
|
void remove_son_proposal( const proposal_object& proposal );
|
||||||
void remove_inactive_son_down_proposals( const vector<son_id_type>& son_ids_to_remove );
|
void remove_inactive_son_down_proposals( const vector<son_id_type>& son_ids_to_remove );
|
||||||
void remove_inactive_son_proposals( const vector<son_id_type>& son_ids_to_remove );
|
void remove_inactive_son_proposals( const vector<son_id_type>& son_ids_to_remove );
|
||||||
void update_son_statuses( const vector<son_info>& cur_active_sons, const vector<son_info>& new_active_sons );
|
void update_son_statuses( const flat_map<sidechain_type, vector<son_info> >& curr_active_sons,
|
||||||
void update_son_wallet( const vector<son_info>& new_active_sons );
|
const flat_map<sidechain_type, vector<son_info> >& new_active_sons );
|
||||||
|
void update_son_wallet( const flat_map<sidechain_type, vector<son_info> >& new_active_sons );
|
||||||
void update_worker_votes();
|
void update_worker_votes();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -49,10 +49,10 @@ namespace graphene { namespace chain {
|
||||||
chain_parameters parameters;
|
chain_parameters parameters;
|
||||||
optional<chain_parameters> pending_parameters;
|
optional<chain_parameters> pending_parameters;
|
||||||
|
|
||||||
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
|
||||||
vector<son_info> active_sons; // updated once per maintenance interval
|
flat_map<sidechain_type, vector<son_info> > active_sons; // updated once per maintenance interval
|
||||||
// n.b. witness scheduling is done by witness_schedule object
|
// n.b. witness scheduling is done by witness_schedule object
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ namespace graphene { namespace chain {
|
||||||
asset fee;
|
asset fee;
|
||||||
account_id_type payer;
|
account_id_type payer;
|
||||||
|
|
||||||
vector<son_info> sons;
|
flat_map<sidechain_type, vector<son_info> > sons;
|
||||||
|
|
||||||
account_id_type fee_payer()const { return payer; }
|
account_id_type fee_payer()const { return payer; }
|
||||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ namespace graphene { namespace chain {
|
||||||
son_id_type son_id;
|
son_id_type son_id;
|
||||||
weight_type weight = 0;
|
weight_type weight = 0;
|
||||||
public_key_type signing_key;
|
public_key_type signing_key;
|
||||||
flat_map<sidechain_type, string> sidechain_public_keys;
|
flat_map<sidechain_type, string> sidechain_public_keys; //! Fixme - delete map from here
|
||||||
|
|
||||||
bool operator==(const son_info& rhs) {
|
bool operator==(const son_info& rhs) const {
|
||||||
bool son_sets_equal =
|
bool son_sets_equal =
|
||||||
(son_id == rhs.son_id) &&
|
(son_id == rhs.son_id) &&
|
||||||
(weight == rhs.weight) &&
|
(weight == rhs.weight) &&
|
||||||
|
|
|
||||||
|
|
@ -35,11 +35,11 @@ namespace graphene { namespace chain {
|
||||||
// Transactions signed since the last son payouts
|
// Transactions signed since the last son payouts
|
||||||
flat_map<sidechain_type, uint64_t> txs_signed;
|
flat_map<sidechain_type, uint64_t> txs_signed;
|
||||||
// Total Voted Active time i.e. duration selected as part of voted active SONs
|
// Total Voted Active time i.e. duration selected as part of voted active SONs
|
||||||
uint64_t total_voted_time = 0;
|
flat_map<sidechain_type, uint64_t> total_voted_time;
|
||||||
// Total Downtime barring the current down time in seconds, used for stats to present to user
|
// Total Downtime barring the current down time in seconds, used for stats to present to user
|
||||||
uint64_t total_downtime = 0;
|
flat_map<sidechain_type, uint64_t> total_downtime;
|
||||||
// Current Interval Downtime since last maintenance
|
// Current Interval Downtime since last maintenance
|
||||||
uint64_t current_interval_downtime = 0;
|
flat_map<sidechain_type, uint64_t> current_interval_downtime;
|
||||||
// Down timestamp, if son status is in_maintenance use this
|
// Down timestamp, if son status is in_maintenance use this
|
||||||
fc::time_point_sec last_down_timestamp;
|
fc::time_point_sec last_down_timestamp;
|
||||||
// Last Active heartbeat timestamp
|
// Last Active heartbeat timestamp
|
||||||
|
|
@ -71,7 +71,7 @@ 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;
|
||||||
son_status status = son_status::inactive;
|
son_status status = son_status::inactive; //! Fixme -> as map of sidechain_type
|
||||||
flat_map<sidechain_type, string> sidechain_public_keys;
|
flat_map<sidechain_type, string> sidechain_public_keys;
|
||||||
|
|
||||||
void pay_son_fee(share_type pay, database& db);
|
void pay_son_fee(share_type pay, database& db);
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace graphene { namespace chain {
|
||||||
time_point_sec expires;
|
time_point_sec expires;
|
||||||
|
|
||||||
flat_map<sidechain_type, string> addresses;
|
flat_map<sidechain_type, string> addresses;
|
||||||
vector<son_info> sons;
|
flat_map<sidechain_type, vector<son_info> > sons;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct by_valid_from;
|
struct by_valid_from;
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ class son_schedule_object : public graphene::db::abstract_object<son_schedule_ob
|
||||||
static const uint8_t space_id = implementation_ids;
|
static const uint8_t space_id = implementation_ids;
|
||||||
static const uint8_t type_id = impl_son_schedule_object_type;
|
static const uint8_t type_id = impl_son_schedule_object_type;
|
||||||
|
|
||||||
vector< son_id_type > current_shuffled_sons;
|
flat_map<sidechain_type, vector<son_id_type > > current_shuffled_sons;
|
||||||
|
|
||||||
son_scheduler scheduler;
|
son_scheduler scheduler;
|
||||||
uint32_t last_scheduling_block;
|
uint32_t last_scheduling_block;
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,7 @@ void_result update_sidechain_address_evaluator::do_evaluate(const sidechain_addr
|
||||||
{ try {
|
{ try {
|
||||||
const auto& sidx = db().get_index_type<son_index>().indices().get<by_account>();
|
const auto& sidx = db().get_index_type<son_index>().indices().get<by_account>();
|
||||||
const auto& son_obj = sidx.find(op.payer);
|
const auto& son_obj = sidx.find(op.payer);
|
||||||
FC_ASSERT( son_obj != sidx.end() && db().is_son_active(son_obj->id), "Non active SON trying to update deposit address object" );
|
FC_ASSERT( son_obj != sidx.end() && db().is_son_active(op.sidechain, son_obj->id), "Non active SON trying to update deposit address object" );
|
||||||
const auto& sdpke_idx = db().get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_deposit_public_key_and_expires>();
|
const auto& sdpke_idx = db().get_index_type<sidechain_address_index>().indices().get<by_sidechain_and_deposit_public_key_and_expires>();
|
||||||
FC_ASSERT( op.deposit_address.valid() && op.deposit_public_key.valid() && op.deposit_address_data.valid(), "Update operation by SON is not valid");
|
FC_ASSERT( op.deposit_address.valid() && op.deposit_public_key.valid() && op.deposit_address_data.valid(), "Update operation by SON is not valid");
|
||||||
FC_ASSERT( (*op.deposit_address).length() > 0 && (*op.deposit_public_key).length() > 0 && (*op.deposit_address_data).length() > 0, "SON should create a valid deposit address with valid deposit public key");
|
FC_ASSERT( (*op.deposit_address).length() > 0 && (*op.deposit_public_key).length() > 0 && (*op.deposit_address_data).length() > 0, "SON should create a valid deposit address with valid deposit public key");
|
||||||
|
|
|
||||||
|
|
@ -171,40 +171,44 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation&
|
||||||
if(itr != idx.end())
|
if(itr != idx.end())
|
||||||
{
|
{
|
||||||
const global_property_object& gpo = db().get_global_properties();
|
const global_property_object& gpo = db().get_global_properties();
|
||||||
vector<son_id_type> active_son_ids;
|
|
||||||
active_son_ids.reserve(gpo.active_sons.size());
|
|
||||||
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
|
|
||||||
std::inserter(active_son_ids, active_son_ids.end()),
|
|
||||||
[](const son_info& swi) {
|
|
||||||
return swi.son_id;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), op.son_id);
|
for(const auto& active_sidechain_sons : gpo.active_sons) {
|
||||||
bool is_son_active = true;
|
const auto& sidechain = active_sidechain_sons.first;
|
||||||
|
const auto& active_sons = active_sidechain_sons.second;
|
||||||
|
|
||||||
if(it_son == active_son_ids.end()) {
|
vector<son_id_type> active_son_ids;
|
||||||
is_son_active = false;
|
active_son_ids.reserve(active_sons.size());
|
||||||
}
|
std::transform(active_sons.cbegin(), active_sons.cend(),
|
||||||
|
std::inserter(active_son_ids, active_son_ids.end()),
|
||||||
|
[](const son_info &swi) {
|
||||||
|
return swi.son_id;
|
||||||
|
});
|
||||||
|
|
||||||
if(itr->status == son_status::in_maintenance) {
|
auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), op.son_id);
|
||||||
db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso )
|
bool is_son_active = true;
|
||||||
{
|
|
||||||
sso.current_interval_downtime += op.ts.sec_since_epoch() - sso.last_down_timestamp.sec_since_epoch();
|
|
||||||
sso.last_active_timestamp = op.ts;
|
|
||||||
} );
|
|
||||||
|
|
||||||
db().modify(*itr, [&is_son_active](son_object &so) {
|
if (it_son == active_son_ids.end()) {
|
||||||
if(is_son_active) {
|
is_son_active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (itr->status == son_status::in_maintenance) {
|
||||||
|
db().modify(itr->statistics(db()), [&](son_statistics_object &sso) {
|
||||||
|
sso.current_interval_downtime[sidechain] += op.ts.sec_since_epoch() - sso.last_down_timestamp.sec_since_epoch();
|
||||||
|
sso.last_active_timestamp = op.ts;
|
||||||
|
});
|
||||||
|
|
||||||
|
db().modify(*itr, [&is_son_active](son_object &so) {
|
||||||
|
if (is_son_active) {
|
||||||
so.status = son_status::active;
|
so.status = son_status::active;
|
||||||
} else {
|
} else {
|
||||||
so.status = son_status::inactive;
|
so.status = son_status::inactive;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if ((itr->status == son_status::active) || (itr->status == son_status::request_maintenance)) {
|
} else if ((itr->status == son_status::active) || (itr->status == son_status::request_maintenance)) {
|
||||||
db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso )
|
db().modify(itr->statistics(db()), [&](son_statistics_object &sso) {
|
||||||
{
|
sso.last_active_timestamp = op.ts;
|
||||||
sso.last_active_timestamp = op.ts;
|
});
|
||||||
} );
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return op.son_id;
|
return op.son_id;
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ void_result create_son_wallet_deposit_evaluator::do_evaluate(const son_wallet_de
|
||||||
const auto &swdo_idx = db().get_index_type<son_wallet_deposit_index>().indices().get<by_sidechain_uid>();
|
const auto &swdo_idx = db().get_index_type<son_wallet_deposit_index>().indices().get<by_sidechain_uid>();
|
||||||
const auto swdo = swdo_idx.find(op.sidechain_uid);
|
const auto swdo = swdo_idx.find(op.sidechain_uid);
|
||||||
if (swdo == swdo_idx.end()) {
|
if (swdo == swdo_idx.end()) {
|
||||||
auto &gpo = db().get_global_properties();
|
const auto &gpo = db().get_global_properties();
|
||||||
bool expected = false;
|
bool expected = false;
|
||||||
for (auto &si : gpo.active_sons) {
|
for (auto &si : gpo.active_sons.at(op.sidechain)) {
|
||||||
if (op.son_id == si.son_id) {
|
if (op.son_id == si.son_id) {
|
||||||
expected = true;
|
expected = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -78,8 +78,8 @@ object_id_type create_son_wallet_deposit_evaluator::do_apply(const son_wallet_de
|
||||||
swdo.peerplays_to = op.peerplays_to;
|
swdo.peerplays_to = op.peerplays_to;
|
||||||
swdo.peerplays_asset = op.peerplays_asset;
|
swdo.peerplays_asset = op.peerplays_asset;
|
||||||
|
|
||||||
auto &gpo = db().get_global_properties();
|
const auto &gpo = db().get_global_properties();
|
||||||
for (auto &si : gpo.active_sons) {
|
for (auto &si : gpo.active_sons.at(op.sidechain)) {
|
||||||
swdo.expected_reports.insert(std::make_pair(si.son_id, si.weight));
|
swdo.expected_reports.insert(std::make_pair(si.son_id, si.weight));
|
||||||
|
|
||||||
auto stats_itr = db().get_index_type<son_stats_index>().indices().get<by_owner>().find(si.son_id);
|
auto stats_itr = db().get_index_type<son_stats_index>().indices().get<by_owner>().find(si.son_id);
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,16 @@ void_result recreate_son_wallet_evaluator::do_evaluate(const son_wallet_recreate
|
||||||
|
|
||||||
bool son_sets_equal = (cur_wallet_sons.size() == new_wallet_sons.size());
|
bool son_sets_equal = (cur_wallet_sons.size() == new_wallet_sons.size());
|
||||||
if (son_sets_equal) {
|
if (son_sets_equal) {
|
||||||
for( size_t i = 0; i < cur_wallet_sons.size(); i++ ) {
|
for( const auto& cur_wallet_sidechain_sons : cur_wallet_sons ) {
|
||||||
son_sets_equal = son_sets_equal && cur_wallet_sons.at(i) == new_wallet_sons.at(i);
|
const auto& sidechain = cur_wallet_sidechain_sons.first;
|
||||||
|
const auto& _cur_wallet_sidechain_sons = cur_wallet_sidechain_sons.second;
|
||||||
|
|
||||||
|
son_sets_equal = son_sets_equal && (_cur_wallet_sidechain_sons.size() == new_wallet_sons.at(sidechain).size());
|
||||||
|
if (son_sets_equal) {
|
||||||
|
for (size_t i = 0; i < cur_wallet_sons.size(); i++) {
|
||||||
|
son_sets_equal = son_sets_equal && _cur_wallet_sidechain_sons.at(i) == new_wallet_sons.at(sidechain).at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ void_result create_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_w
|
||||||
const auto &swwo_idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_peerplays_uid>();
|
const auto &swwo_idx = db().get_index_type<son_wallet_withdraw_index>().indices().get<by_peerplays_uid>();
|
||||||
const auto swwo = swwo_idx.find(op.peerplays_uid);
|
const auto swwo = swwo_idx.find(op.peerplays_uid);
|
||||||
if (swwo == swwo_idx.end()) {
|
if (swwo == swwo_idx.end()) {
|
||||||
auto &gpo = db().get_global_properties();
|
const auto &gpo = db().get_global_properties();
|
||||||
bool expected = false;
|
bool expected = false;
|
||||||
for (auto &si : gpo.active_sons) {
|
for (auto &si : gpo.active_sons.at(op.sidechain)) {
|
||||||
if (op.son_id == si.son_id) {
|
if (op.son_id == si.son_id) {
|
||||||
expected = true;
|
expected = true;
|
||||||
break;
|
break;
|
||||||
|
|
@ -76,8 +76,8 @@ object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_w
|
||||||
swwo.withdraw_currency = op.withdraw_currency;
|
swwo.withdraw_currency = op.withdraw_currency;
|
||||||
swwo.withdraw_amount = op.withdraw_amount;
|
swwo.withdraw_amount = op.withdraw_amount;
|
||||||
|
|
||||||
auto &gpo = db().get_global_properties();
|
const auto &gpo = db().get_global_properties();
|
||||||
for (auto &si : gpo.active_sons) {
|
for (auto &si : gpo.active_sons.at(op.sidechain)) {
|
||||||
swwo.expected_reports.insert(std::make_pair(si.son_id, si.weight));
|
swwo.expected_reports.insert(std::make_pair(si.son_id, si.weight));
|
||||||
|
|
||||||
auto stats_itr = db().get_index_type<son_stats_index>().indices().get<by_owner>().find(si.son_id);
|
auto stats_itr = db().get_index_type<son_stats_index>().indices().get<by_owner>().find(si.son_id);
|
||||||
|
|
|
||||||
|
|
@ -316,10 +316,12 @@ bool peerplays_sidechain_plugin_impl::is_active_son(son_id_type son_id) {
|
||||||
if (son_obj == idx.end())
|
if (son_obj == idx.end())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
//! 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;
|
vector<son_id_type> active_son_ids;
|
||||||
active_son_ids.reserve(gpo.active_sons.size());
|
active_son_ids.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size());
|
||||||
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
|
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()),
|
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;
|
||||||
|
|
@ -452,19 +454,18 @@ void peerplays_sidechain_plugin_impl::son_processing() {
|
||||||
return; // Not synced
|
return; // Not synced
|
||||||
}
|
}
|
||||||
|
|
||||||
chain::son_id_type scheduled_son_id = plugin.database().get_scheduled_son(1);
|
//! Fixme - get real scheduled_son_id according to sidechain_type
|
||||||
ilog("Scheduled SON: ${scheduled_son_id} Now: ${now} ",
|
chain::son_id_type scheduled_son_id;
|
||||||
("scheduled_son_id", scheduled_son_id)("now", now));
|
|
||||||
|
|
||||||
// for the test prove that in hive scheduled son is active son
|
// for the test prove that in hive scheduled son is active son
|
||||||
chain::son_id_type scheduled_hive_son_id = plugin.database().get_scheduled_son(sidechain_type::hive ,1);
|
chain::son_id_type scheduled_hive_son_id = plugin.database().get_scheduled_son(sidechain_type::hive ,1);
|
||||||
ilog("Scheduled SON[!HIVE!]: ${scheduled_son_id} Now: ${now} ",
|
ilog("Scheduled SON[!HIVE!]: ${scheduled_hive_son_id} Now: ${now} ",
|
||||||
("scheduled_son_id", scheduled_hive_son_id)("now", now));
|
("scheduled_hive_son_id", scheduled_hive_son_id)("now", now));
|
||||||
|
|
||||||
// for the test prove that in hive scheduled son is active son
|
// for the test prove that in hive scheduled son is active son
|
||||||
chain::son_id_type scheduled_bitcoin_son_id = plugin.database().get_scheduled_son(sidechain_type::bitcoin ,1);
|
chain::son_id_type scheduled_bitcoin_son_id = plugin.database().get_scheduled_son(sidechain_type::bitcoin ,1);
|
||||||
ilog("Scheduled SON[!HIVE!]: ${scheduled_son_id} Now: ${now} ",
|
ilog("Scheduled SON[!HIVE!]: ${scheduled_bitcoin_son_id} Now: ${now} ",
|
||||||
("scheduled_son_id", scheduled_bitcoin_son_id)("now", now));
|
("scheduled_bitcoin_son_id", scheduled_bitcoin_son_id)("now", now));
|
||||||
|
|
||||||
for (son_id_type son_id : plugin.get_sons()) {
|
for (son_id_type son_id : plugin.get_sons()) {
|
||||||
if (plugin.is_son_deregistered(son_id)) {
|
if (plugin.is_son_deregistered(son_id)) {
|
||||||
|
|
@ -612,7 +613,11 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() {
|
||||||
const auto &idx = d.get_index_type<chain::son_index>().indices().get<by_id>();
|
const auto &idx = d.get_index_type<chain::son_index>().indices().get<by_id>();
|
||||||
std::set<son_id_type> sons_being_reported_down = d.get_sons_being_reported_down();
|
std::set<son_id_type> sons_being_reported_down = d.get_sons_being_reported_down();
|
||||||
chain::son_id_type my_son_id = get_current_son_id();
|
chain::son_id_type my_son_id = get_current_son_id();
|
||||||
for (auto son_inf : gpo.active_sons) {
|
|
||||||
|
//! Fixme - now set bitcoin
|
||||||
|
//! Do we need to separate create_son_down_proposals for different sidechain_types
|
||||||
|
|
||||||
|
for (auto son_inf : gpo.active_sons.at(sidechain_type::bitcoin)) {
|
||||||
if (my_son_id == son_inf.son_id || (sons_being_reported_down.find(son_inf.son_id) != sons_being_reported_down.end())) {
|
if (my_son_id == son_inf.son_id || (sons_being_reported_down.find(son_inf.son_id) != sons_being_reported_down.end())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -904,8 +904,9 @@ void zmq_listener::handle_zmq() {
|
||||||
|
|
||||||
// =============================================================================
|
// =============================================================================
|
||||||
|
|
||||||
sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
sidechain_net_handler_bitcoin::sidechain_net_handler_bitcoin(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options)
|
||||||
sidechain_net_handler(_plugin, options) {
|
: sidechain_net_handler(_plugin, options)
|
||||||
|
{
|
||||||
sidechain = sidechain_type::bitcoin;
|
sidechain = sidechain_type::bitcoin;
|
||||||
|
|
||||||
if (options.count("debug-rpc-calls")) {
|
if (options.count("debug-rpc-calls")) {
|
||||||
|
|
@ -1024,8 +1025,8 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
|
||||||
const auto swo = idx.find(swo_id);
|
const auto swo = idx.find(swo_id);
|
||||||
if (swo != idx.end()) {
|
if (swo != idx.end()) {
|
||||||
|
|
||||||
auto active_sons = gpo.active_sons;
|
const auto& active_sons = gpo.active_sons.at(sidechain);
|
||||||
vector<son_info> wallet_sons = swo->sons;
|
vector<son_info> wallet_sons = swo->sons.at(sidechain);
|
||||||
|
|
||||||
bool son_sets_equal = (active_sons.size() == wallet_sons.size());
|
bool son_sets_equal = (active_sons.size() == wallet_sons.size());
|
||||||
|
|
||||||
|
|
@ -1036,10 +1037,10 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (son_sets_equal) {
|
if (son_sets_equal) {
|
||||||
auto active_sons = gpo.active_sons;
|
const auto& active_sons = gpo.active_sons.at(sidechain);
|
||||||
vector<string> son_pubkeys_bitcoin;
|
vector<string> son_pubkeys_bitcoin;
|
||||||
for (const son_info &si : active_sons) {
|
for (const son_info &si : active_sons) {
|
||||||
son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain_type::bitcoin));
|
son_pubkeys_bitcoin.push_back(si.sidechain_public_keys.at(sidechain));
|
||||||
}
|
}
|
||||||
|
|
||||||
string reply_str = create_primary_wallet_address(active_sons);
|
string reply_str = create_primary_wallet_address(active_sons);
|
||||||
|
|
@ -1242,7 +1243,7 @@ bool sidechain_net_handler_bitcoin::process_proposal(const proposal_object &po)
|
||||||
|
|
||||||
read_transaction_data(sto->transaction, tx_hex, in_amounts, redeem_script);
|
read_transaction_data(sto->transaction, tx_hex, in_amounts, redeem_script);
|
||||||
bitcoin_transaction tx = unpack(parse_hex(tx_hex));
|
bitcoin_transaction tx = unpack(parse_hex(tx_hex));
|
||||||
bitcoin::bytes pubkey = parse_hex(son->sidechain_public_keys.at(sidechain_type::bitcoin));
|
bitcoin::bytes pubkey = parse_hex(son->sidechain_public_keys.at(sidechain));
|
||||||
vector<bitcoin::bytes> sigs = read_byte_arrays_from_string(signature);
|
vector<bitcoin::bytes> sigs = read_byte_arrays_from_string(signature);
|
||||||
for (size_t i = 0; i < tx.vin.size(); i++) {
|
for (size_t i = 0; i < tx.vin.size(); i++) {
|
||||||
const auto &sighash_str = get_signature_hash(tx, parse_hex(redeem_script), static_cast<int64_t>(in_amounts[i]), i, 1, true).str();
|
const auto &sighash_str = get_signature_hash(tx, parse_hex(redeem_script), static_cast<int64_t>(in_amounts[i]), i, 1, true).str();
|
||||||
|
|
@ -1272,8 +1273,8 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() {
|
||||||
const auto &active_sw = swi.rbegin();
|
const auto &active_sw = swi.rbegin();
|
||||||
if (active_sw != swi.rend()) {
|
if (active_sw != swi.rend()) {
|
||||||
|
|
||||||
if ((active_sw->addresses.find(sidechain_type::bitcoin) == active_sw->addresses.end()) ||
|
if ((active_sw->addresses.find(sidechain) == active_sw->addresses.end()) ||
|
||||||
(active_sw->addresses.at(sidechain_type::bitcoin).empty())) {
|
(active_sw->addresses.at(sidechain).empty())) {
|
||||||
|
|
||||||
if (proposal_exists(chain::operation::tag<chain::son_wallet_update_operation>::value, active_sw->id)) {
|
if (proposal_exists(chain::operation::tag<chain::son_wallet_update_operation>::value, active_sw->id)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -1281,7 +1282,7 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() {
|
||||||
|
|
||||||
const chain::global_property_object &gpo = database.get_global_properties();
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
|
|
||||||
auto active_sons = gpo.active_sons;
|
const auto& active_sons = gpo.active_sons.at(sidechain);
|
||||||
string reply_str = create_primary_wallet_address(active_sons);
|
string reply_str = create_primary_wallet_address(active_sons);
|
||||||
|
|
||||||
std::stringstream active_pw_ss(reply_str);
|
std::stringstream active_pw_ss(reply_str);
|
||||||
|
|
@ -1303,7 +1304,7 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() {
|
||||||
son_wallet_update_operation swu_op;
|
son_wallet_update_operation swu_op;
|
||||||
swu_op.payer = gpo.parameters.son_account();
|
swu_op.payer = gpo.parameters.son_account();
|
||||||
swu_op.son_wallet_id = active_sw->id;
|
swu_op.son_wallet_id = active_sw->id;
|
||||||
swu_op.sidechain = sidechain_type::bitcoin;
|
swu_op.sidechain = sidechain;
|
||||||
swu_op.address = res.str();
|
swu_op.address = res.str();
|
||||||
|
|
||||||
proposal_op.proposed_ops.emplace_back(swu_op);
|
proposal_op.proposed_ops.emplace_back(swu_op);
|
||||||
|
|
@ -1318,7 +1319,7 @@ void sidechain_net_handler_bitcoin::process_primary_wallet() {
|
||||||
stc_op.object_id = prev_sw->id;
|
stc_op.object_id = prev_sw->id;
|
||||||
stc_op.sidechain = sidechain;
|
stc_op.sidechain = sidechain;
|
||||||
stc_op.transaction = tx_str;
|
stc_op.transaction = tx_str;
|
||||||
stc_op.signers = prev_sw->sons;
|
stc_op.signers = prev_sw->sons.at(sidechain);
|
||||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1344,8 +1345,8 @@ void sidechain_net_handler_bitcoin::process_sidechain_addresses() {
|
||||||
|
|
||||||
const chain::global_property_object &gpo = database.get_global_properties();
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkeys;
|
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkeys;
|
||||||
for (auto &son : gpo.active_sons) {
|
for (auto &son : gpo.active_sons.at(sidechain)) {
|
||||||
std::string pub_key_str = son.sidechain_public_keys.at(sidechain_type::bitcoin);
|
std::string pub_key_str = son.sidechain_public_keys.at(sidechain);
|
||||||
auto pubkey = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str)));
|
auto pubkey = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str)));
|
||||||
pubkeys.push_back(std::make_pair(pubkey, son.weight));
|
pubkeys.push_back(std::make_pair(pubkey, son.weight));
|
||||||
}
|
}
|
||||||
|
|
@ -1422,7 +1423,7 @@ bool sidechain_net_handler_bitcoin::process_deposit(const son_wallet_deposit_obj
|
||||||
stc_op.object_id = swdo.id;
|
stc_op.object_id = swdo.id;
|
||||||
stc_op.sidechain = sidechain;
|
stc_op.sidechain = sidechain;
|
||||||
stc_op.transaction = tx_str;
|
stc_op.transaction = tx_str;
|
||||||
stc_op.signers = gpo.active_sons;
|
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||||
|
|
||||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
||||||
|
|
@ -1466,7 +1467,7 @@ bool sidechain_net_handler_bitcoin::process_withdrawal(const son_wallet_withdraw
|
||||||
stc_op.object_id = swwo.id;
|
stc_op.object_id = swwo.id;
|
||||||
stc_op.sidechain = sidechain;
|
stc_op.sidechain = sidechain;
|
||||||
stc_op.transaction = tx_str;
|
stc_op.transaction = tx_str;
|
||||||
stc_op.signers = gpo.active_sons;
|
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||||
|
|
||||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
||||||
|
|
@ -1517,7 +1518,7 @@ bool sidechain_net_handler_bitcoin::settle_sidechain_transaction(const sidechain
|
||||||
using namespace bitcoin;
|
using namespace bitcoin;
|
||||||
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkey_weights;
|
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkey_weights;
|
||||||
for (auto si : sto.signers) {
|
for (auto si : sto.signers) {
|
||||||
std::string pub_key_str = si.sidechain_public_keys.at(sidechain_type::bitcoin);
|
std::string pub_key_str = si.sidechain_public_keys.at(sidechain);
|
||||||
auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str)));
|
auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str)));
|
||||||
pubkey_weights.push_back(std::make_pair(pub_key, si.weight));
|
pubkey_weights.push_back(std::make_pair(pub_key, si.weight));
|
||||||
}
|
}
|
||||||
|
|
@ -1558,7 +1559,7 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_address(const s
|
||||||
|
|
||||||
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkey_weights;
|
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkey_weights;
|
||||||
for (auto &son : son_pubkeys) {
|
for (auto &son : son_pubkeys) {
|
||||||
std::string pub_key_str = son.sidechain_public_keys.at(sidechain_type::bitcoin);
|
std::string pub_key_str = son.sidechain_public_keys.at(sidechain);
|
||||||
auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str)));
|
auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str)));
|
||||||
pubkey_weights.push_back(std::make_pair(pub_key, son.weight));
|
pubkey_weights.push_back(std::make_pair(pub_key, son.weight));
|
||||||
}
|
}
|
||||||
|
|
@ -1576,7 +1577,7 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_address(const s
|
||||||
|
|
||||||
std::string sidechain_net_handler_bitcoin::create_primary_wallet_transaction(const son_wallet_object &prev_swo, std::string new_sw_address) {
|
std::string sidechain_net_handler_bitcoin::create_primary_wallet_transaction(const son_wallet_object &prev_swo, std::string new_sw_address) {
|
||||||
|
|
||||||
const auto &address_data = prev_swo.addresses.find(sidechain_type::bitcoin);
|
const auto &address_data = prev_swo.addresses.find(sidechain);
|
||||||
if (address_data == prev_swo.addresses.end()) {
|
if (address_data == prev_swo.addresses.end()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
@ -1627,12 +1628,12 @@ std::string sidechain_net_handler_bitcoin::create_primary_wallet_transaction(con
|
||||||
std::string sidechain_net_handler_bitcoin::create_deposit_transaction(const son_wallet_deposit_object &swdo) {
|
std::string sidechain_net_handler_bitcoin::create_deposit_transaction(const son_wallet_deposit_object &swdo) {
|
||||||
const auto &idx = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
const auto &idx = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||||
auto obj = idx.rbegin();
|
auto obj = idx.rbegin();
|
||||||
if (obj == idx.rend() || obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) {
|
if (obj == idx.rend() || obj->addresses.find(sidechain) == obj->addresses.end()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
//Get redeem script for deposit address
|
//Get redeem script for deposit address
|
||||||
std::string redeem_script = get_redeemscript_for_userdeposit(swdo.sidechain_from);
|
std::string redeem_script = get_redeemscript_for_userdeposit(swdo.sidechain_from);
|
||||||
std::string pw_address_json = obj->addresses.find(sidechain_type::bitcoin)->second;
|
std::string pw_address_json = obj->addresses.find(sidechain)->second;
|
||||||
|
|
||||||
std::stringstream ss(pw_address_json);
|
std::stringstream ss(pw_address_json);
|
||||||
boost::property_tree::ptree json;
|
boost::property_tree::ptree json;
|
||||||
|
|
@ -1668,11 +1669,11 @@ std::string sidechain_net_handler_bitcoin::create_deposit_transaction(const son_
|
||||||
std::string sidechain_net_handler_bitcoin::create_withdrawal_transaction(const son_wallet_withdraw_object &swwo) {
|
std::string sidechain_net_handler_bitcoin::create_withdrawal_transaction(const son_wallet_withdraw_object &swwo) {
|
||||||
const auto &idx = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
const auto &idx = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||||
auto obj = idx.rbegin();
|
auto obj = idx.rbegin();
|
||||||
if (obj == idx.rend() || obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) {
|
if (obj == idx.rend() || obj->addresses.find(sidechain) == obj->addresses.end()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string pw_address_json = obj->addresses.find(sidechain_type::bitcoin)->second;
|
std::string pw_address_json = obj->addresses.find(sidechain)->second;
|
||||||
|
|
||||||
std::stringstream ss(pw_address_json);
|
std::stringstream ss(pw_address_json);
|
||||||
boost::property_tree::ptree json;
|
boost::property_tree::ptree json;
|
||||||
|
|
@ -1847,13 +1848,13 @@ std::string sidechain_net_handler_bitcoin::get_redeemscript_for_userdeposit(cons
|
||||||
|
|
||||||
const auto &idx = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
const auto &idx = database.get_index_type<son_wallet_index>().indices().get<by_id>();
|
||||||
auto obj = idx.rbegin();
|
auto obj = idx.rbegin();
|
||||||
if (obj == idx.rend() || obj->addresses.find(sidechain_type::bitcoin) == obj->addresses.end()) {
|
if (obj == idx.rend() || obj->addresses.find(sidechain) == obj->addresses.end()) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkey_weights;
|
std::vector<std::pair<fc::ecc::public_key, uint16_t>> pubkey_weights;
|
||||||
for (auto &son : obj->sons) {
|
for (auto &son : obj->sons.at(sidechain)) {
|
||||||
std::string pub_key_str = son.sidechain_public_keys.at(sidechain_type::bitcoin);
|
std::string pub_key_str = son.sidechain_public_keys.at(sidechain);
|
||||||
auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str)));
|
auto pub_key = fc::ecc::public_key(create_public_key_data(parse_hex(pub_key_str)));
|
||||||
pubkey_weights.push_back(std::make_pair(pub_key, son.weight));
|
pubkey_weights.push_back(std::make_pair(pub_key, son.weight));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,9 @@ std::string hive_node_rpc_client::get_last_irreversible_block_num() {
|
||||||
return retrieve_value_from_reply(reply_str, "last_irreversible_block_num");
|
return retrieve_value_from_reply(reply_str, "last_irreversible_block_num");
|
||||||
}
|
}
|
||||||
|
|
||||||
sidechain_net_handler_hive::sidechain_net_handler_hive(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options) :
|
sidechain_net_handler_hive::sidechain_net_handler_hive(peerplays_sidechain_plugin &_plugin, const boost::program_options::variables_map &options)
|
||||||
sidechain_net_handler(_plugin, options) {
|
: sidechain_net_handler(_plugin, options)
|
||||||
|
{
|
||||||
sidechain = sidechain_type::hive;
|
sidechain = sidechain_type::hive;
|
||||||
|
|
||||||
if (options.count("debug-rpc-calls")) {
|
if (options.count("debug-rpc-calls")) {
|
||||||
|
|
@ -214,13 +215,13 @@ bool sidechain_net_handler_hive::process_proposal(const proposal_object &po) {
|
||||||
if (swo != idx.end()) {
|
if (swo != idx.end()) {
|
||||||
|
|
||||||
auto active_sons = gpo.active_sons;
|
auto active_sons = gpo.active_sons;
|
||||||
vector<son_info> wallet_sons = swo->sons;
|
vector<son_info> wallet_sons = swo->sons.at(sidechain);
|
||||||
|
|
||||||
bool son_sets_equal = (active_sons.size() == wallet_sons.size());
|
bool son_sets_equal = (active_sons.size() == wallet_sons.size());
|
||||||
|
|
||||||
if (son_sets_equal) {
|
if (son_sets_equal) {
|
||||||
for (size_t i = 0; i < active_sons.size(); i++) {
|
for (size_t i = 0; i < active_sons.size(); i++) {
|
||||||
son_sets_equal = son_sets_equal && active_sons.at(i) == wallet_sons.at(i);
|
son_sets_equal = son_sets_equal && active_sons.at(sidechain).at(i) == wallet_sons.at(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -487,7 +488,7 @@ void sidechain_net_handler_hive::process_primary_wallet() {
|
||||||
|
|
||||||
const chain::global_property_object &gpo = database.get_global_properties();
|
const chain::global_property_object &gpo = database.get_global_properties();
|
||||||
|
|
||||||
auto active_sons = gpo.active_sons;
|
const auto& active_sons = gpo.active_sons.at(sidechain);
|
||||||
fc::flat_map<std::string, uint16_t> account_auths;
|
fc::flat_map<std::string, uint16_t> account_auths;
|
||||||
uint32_t total_weight = 0;
|
uint32_t total_weight = 0;
|
||||||
for (const auto &active_son : active_sons) {
|
for (const auto &active_son : active_sons) {
|
||||||
|
|
@ -547,7 +548,7 @@ void sidechain_net_handler_hive::process_primary_wallet() {
|
||||||
stc_op.object_id = active_sw->id;
|
stc_op.object_id = active_sw->id;
|
||||||
stc_op.sidechain = sidechain;
|
stc_op.sidechain = sidechain;
|
||||||
stc_op.transaction = tx_str;
|
stc_op.transaction = tx_str;
|
||||||
stc_op.signers = gpo.active_sons;
|
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||||
|
|
||||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||||
|
|
||||||
|
|
@ -704,7 +705,7 @@ bool sidechain_net_handler_hive::process_withdrawal(const son_wallet_withdraw_ob
|
||||||
stc_op.object_id = swwo.id;
|
stc_op.object_id = swwo.id;
|
||||||
stc_op.sidechain = sidechain;
|
stc_op.sidechain = sidechain;
|
||||||
stc_op.transaction = tx_str;
|
stc_op.transaction = tx_str;
|
||||||
stc_op.signers = gpo.active_sons;
|
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||||
proposal_op.proposed_ops.emplace_back(stc_op);
|
proposal_op.proposed_ops.emplace_back(stc_op);
|
||||||
|
|
||||||
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_current_son_id()), proposal_op);
|
||||||
|
|
|
||||||
|
|
@ -197,7 +197,7 @@ bool sidechain_net_handler_peerplays::process_deposit(const son_wallet_deposit_o
|
||||||
stc_op.object_id = swdo.id;
|
stc_op.object_id = swdo.id;
|
||||||
stc_op.sidechain = sidechain;
|
stc_op.sidechain = sidechain;
|
||||||
stc_op.transaction = tx_str;
|
stc_op.transaction = tx_str;
|
||||||
stc_op.signers = gpo.active_sons;
|
stc_op.signers = gpo.active_sons.at(sidechain);
|
||||||
|
|
||||||
proposal_create_operation proposal_op;
|
proposal_create_operation proposal_op;
|
||||||
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
|
proposal_op.fee_paying_account = plugin.get_current_son_object().son_account;
|
||||||
|
|
|
||||||
|
|
@ -2232,68 +2232,80 @@ public:
|
||||||
} FC_CAPTURE_AND_RETHROW( (owner_account) ) }
|
} FC_CAPTURE_AND_RETHROW( (owner_account) ) }
|
||||||
|
|
||||||
map<string, son_id_type> list_active_sons()
|
map<string, son_id_type> list_active_sons()
|
||||||
{ try {
|
{
|
||||||
global_property_object gpo = get_global_properties();
|
try
|
||||||
vector<son_id_type> son_ids;
|
|
||||||
son_ids.reserve(gpo.active_sons.size());
|
|
||||||
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
|
|
||||||
std::inserter(son_ids, son_ids.end()),
|
|
||||||
[](const son_info& swi) {
|
|
||||||
return swi.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)
|
|
||||||
{
|
{
|
||||||
std::string acc_id = account_id_to_string(obj->son_account);
|
//! Fixme - now only bitcoin, fix according to sidechain_type
|
||||||
owners.push_back(acc_id);
|
|
||||||
|
const global_property_object& gpo = get_global_properties();
|
||||||
|
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;
|
||||||
|
});
|
||||||
|
std::vector<fc::optional<son_object>> son_objects = _remote_db->get_sons(son_ids);
|
||||||
|
vector<std::string> owners;
|
||||||
|
for(auto obj: son_objects)
|
||||||
|
{
|
||||||
|
std::string acc_id = account_id_to_string(obj->son_account);
|
||||||
|
owners.push_back(acc_id);
|
||||||
|
}
|
||||||
|
vector< optional< account_object> > accs = _remote_db->get_accounts(owners);
|
||||||
|
std::remove_if(son_objects.begin(), son_objects.end(),
|
||||||
|
[](const fc::optional<son_object>& obj) -> bool { return obj.valid(); });
|
||||||
|
map<string, son_id_type> result;
|
||||||
|
std::transform(accs.begin(), accs.end(), son_objects.begin(),
|
||||||
|
std::inserter(result, result.end()),
|
||||||
|
[](fc::optional<account_object>& acct, fc::optional<son_object> son) {
|
||||||
|
FC_ASSERT(acct, "Invalid active SONs list in global properties.");
|
||||||
|
return std::make_pair<string, son_id_type>(string(acct->name), std::move(son->id));
|
||||||
|
});
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
vector< optional< account_object> > accs = _remote_db->get_accounts(owners);
|
FC_CAPTURE_AND_RETHROW()
|
||||||
std::remove_if(son_objects.begin(), son_objects.end(),
|
}
|
||||||
[](const fc::optional<son_object>& obj) -> bool { return obj.valid(); });
|
|
||||||
map<string, son_id_type> result;
|
|
||||||
std::transform(accs.begin(), accs.end(), son_objects.begin(),
|
|
||||||
std::inserter(result, result.end()),
|
|
||||||
[](fc::optional<account_object>& acct, fc::optional<son_object> son) {
|
|
||||||
FC_ASSERT(acct, "Invalid active SONs list in global properties.");
|
|
||||||
return std::make_pair<string, son_id_type>(string(acct->name), std::move(son->id));
|
|
||||||
});
|
|
||||||
return result;
|
|
||||||
} FC_CAPTURE_AND_RETHROW() }
|
|
||||||
|
|
||||||
map<son_id_type, string> get_son_network_status()
|
map<son_id_type, string> get_son_network_status()
|
||||||
{ try {
|
{
|
||||||
global_property_object gpo = get_global_properties();
|
try
|
||||||
vector<son_id_type> son_ids;
|
{
|
||||||
son_ids.reserve(gpo.active_sons.size());
|
//! Fixme - now only bitcoin, fix according to sidechain_type
|
||||||
std::transform(gpo.active_sons.begin(), gpo.active_sons.end(),
|
|
||||||
std::inserter(son_ids, son_ids.end()),
|
|
||||||
[](const son_info& swi) {
|
|
||||||
return swi.son_id;
|
|
||||||
});
|
|
||||||
|
|
||||||
map<son_id_type, string> result;
|
const global_property_object& gpo = get_global_properties();
|
||||||
std::vector<fc::optional<son_object>> son_objects = _remote_db->get_sons(son_ids);
|
vector<son_id_type> son_ids;
|
||||||
for(auto son_obj: son_objects) {
|
son_ids.reserve(gpo.active_sons.at(sidechain_type::bitcoin).size());
|
||||||
string status;
|
std::transform(gpo.active_sons.at(sidechain_type::bitcoin).cbegin(), gpo.active_sons.at(sidechain_type::bitcoin).cend(),
|
||||||
if (son_obj) {
|
std::inserter(son_ids, son_ids.end()),
|
||||||
son_statistics_object sso = get_object(son_obj->statistics);
|
[](const son_info& swi) {
|
||||||
if (sso.last_active_timestamp + fc::seconds(gpo.parameters.son_heartbeat_frequency()) > time_point::now()) {
|
return swi.son_id;
|
||||||
status = "OK, regular SON heartbeat";
|
});
|
||||||
} else {
|
|
||||||
if (sso.last_active_timestamp + fc::seconds(gpo.parameters.son_down_time()) > time_point::now()) {
|
map<son_id_type, string> result;
|
||||||
status = "OK, irregular SON heartbeat, but not triggering SON down proposal";
|
std::vector<fc::optional<son_object>> son_objects = _remote_db->get_sons(son_ids);
|
||||||
|
for(auto son_obj: son_objects) {
|
||||||
|
string status;
|
||||||
|
if (son_obj) {
|
||||||
|
son_statistics_object sso = get_object(son_obj->statistics);
|
||||||
|
if (sso.last_active_timestamp + fc::seconds(gpo.parameters.son_heartbeat_frequency()) > time_point::now()) {
|
||||||
|
status = "OK, regular SON heartbeat";
|
||||||
} else {
|
} else {
|
||||||
status = "NOT OK, irregular SON heartbeat, triggering SON down proposal";
|
if (sso.last_active_timestamp + fc::seconds(gpo.parameters.son_down_time()) > time_point::now()) {
|
||||||
|
status = "OK, irregular SON heartbeat, but not triggering SON down proposal";
|
||||||
|
} else {
|
||||||
|
status = "NOT OK, irregular SON heartbeat, triggering SON down proposal";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
status = "NOT OK, invalid SON id";
|
||||||
}
|
}
|
||||||
} else {
|
result[son_obj->id] = status;
|
||||||
status = "NOT OK, invalid SON id";
|
|
||||||
}
|
}
|
||||||
result[son_obj->id] = status;
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
FC_CAPTURE_AND_RETHROW()
|
||||||
} FC_CAPTURE_AND_RETHROW() }
|
}
|
||||||
|
|
||||||
optional<son_wallet_object> get_active_son_wallet()
|
optional<son_wallet_object> get_active_son_wallet()
|
||||||
{ try {
|
{ try {
|
||||||
|
|
|
||||||
|
|
@ -87,7 +87,8 @@ BOOST_AUTO_TEST_CASE( sidechain_address_update_test ) {
|
||||||
{
|
{
|
||||||
son_info sinfo;
|
son_info sinfo;
|
||||||
sinfo.son_id = son.id;
|
sinfo.son_id = son.id;
|
||||||
_gpo.active_sons.push_back(sinfo);
|
_gpo.active_sons[sidechain_type::bitcoin].push_back(sinfo);
|
||||||
|
_gpo.active_sons[sidechain_type::hive].push_back(sinfo);
|
||||||
});
|
});
|
||||||
generate_block();
|
generate_block();
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -668,7 +668,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
||||||
PUSH_TX( db, trx, ~0);
|
PUSH_TX( db, trx, ~0);
|
||||||
generate_block();
|
generate_block();
|
||||||
trx.clear();
|
trx.clear();
|
||||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime, op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch());
|
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch());
|
||||||
|
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch());
|
||||||
downtime += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch();
|
downtime += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch();
|
||||||
BOOST_CHECK( obj->status == son_status::inactive);
|
BOOST_CHECK( obj->status == son_status::inactive);
|
||||||
BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts);
|
BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts);
|
||||||
|
|
@ -685,7 +686,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
||||||
{
|
{
|
||||||
son_info son_inf;
|
son_info son_inf;
|
||||||
son_inf.son_id = son_id_type(0);
|
son_inf.son_id = son_id_type(0);
|
||||||
_gpo.active_sons.push_back(son_inf);
|
_gpo.active_sons[sidechain_type::bitcoin].push_back(son_inf);
|
||||||
|
_gpo.active_sons[sidechain_type::hive].push_back(son_inf);
|
||||||
});
|
});
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -702,7 +704,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
||||||
PUSH_TX( db, trx, ~0);
|
PUSH_TX( db, trx, ~0);
|
||||||
generate_block();
|
generate_block();
|
||||||
trx.clear();
|
trx.clear();
|
||||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime, downtime + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch());
|
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), downtime + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch());
|
||||||
|
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), downtime + op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch());
|
||||||
downtime += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch();
|
downtime += op.ts.sec_since_epoch() - son_stats_obj->last_down_timestamp.sec_since_epoch();
|
||||||
BOOST_CHECK( obj->status == son_status::active);
|
BOOST_CHECK( obj->status == son_status::active);
|
||||||
BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts);
|
BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts);
|
||||||
|
|
@ -722,7 +725,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
||||||
PUSH_TX( db, trx, ~0);
|
PUSH_TX( db, trx, ~0);
|
||||||
generate_block();
|
generate_block();
|
||||||
trx.clear();
|
trx.clear();
|
||||||
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime, downtime);
|
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::bitcoin), downtime);
|
||||||
|
BOOST_REQUIRE_EQUAL(son_stats_obj->current_interval_downtime.at(sidechain_type::hive), downtime);
|
||||||
BOOST_CHECK( obj->status == son_status::active);
|
BOOST_CHECK( obj->status == son_status::active);
|
||||||
BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts);
|
BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -154,13 +154,14 @@ BOOST_AUTO_TEST_CASE( son_wallet_recreate_test ) {
|
||||||
|
|
||||||
op.payer = db.get_global_properties().parameters.son_account();
|
op.payer = db.get_global_properties().parameters.son_account();
|
||||||
|
|
||||||
|
//! Fixme - add hive tests
|
||||||
{
|
{
|
||||||
son_info si;
|
son_info si;
|
||||||
si.son_id = son_id_type(0);
|
si.son_id = son_id_type(0);
|
||||||
si.weight = 1000;
|
si.weight = 1000;
|
||||||
si.signing_key = alice_public_key;
|
si.signing_key = alice_public_key;
|
||||||
si.sidechain_public_keys[sidechain_type::bitcoin] = "";
|
si.sidechain_public_keys[sidechain_type::bitcoin] = "";
|
||||||
op.sons.push_back(si);
|
op.sons[sidechain_type::bitcoin].push_back(si);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
@ -169,7 +170,7 @@ BOOST_AUTO_TEST_CASE( son_wallet_recreate_test ) {
|
||||||
si.weight = 1000;
|
si.weight = 1000;
|
||||||
si.signing_key = bob_public_key;
|
si.signing_key = bob_public_key;
|
||||||
si.sidechain_public_keys[sidechain_type::bitcoin] = "";
|
si.sidechain_public_keys[sidechain_type::bitcoin] = "";
|
||||||
op.sons.push_back(si);
|
op.sons[sidechain_type::bitcoin].push_back(si);
|
||||||
}
|
}
|
||||||
|
|
||||||
trx.operations.push_back(op);
|
trx.operations.push_back(op);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue