#308 - son_status as map
This commit is contained in:
parent
32d67b2c30
commit
467522f7d8
8 changed files with 200 additions and 82 deletions
|
|
@ -222,11 +222,18 @@ std::set<son_id_type> database::get_sons_to_be_deregistered()
|
|||
|
||||
for( auto& son : son_idx )
|
||||
{
|
||||
if(son.status == son_status::in_maintenance)
|
||||
bool need_to_be_deregistered = true;
|
||||
for(const auto& status : son.statuses)
|
||||
{
|
||||
if(status.second != son_status::in_maintenance)
|
||||
need_to_be_deregistered = false;
|
||||
}
|
||||
|
||||
if(need_to_be_deregistered)
|
||||
{
|
||||
auto stats = son.statistics(*this);
|
||||
// TODO : We need to add a function that returns if we can deregister SON
|
||||
// i.e. with introduction of PW code, we have to make a decision if the SON
|
||||
// TODO : We need to add a function that returns if we can deregister SON
|
||||
// i.e. with introduction of PW code, we have to make a decision if the SON
|
||||
// is needed for release of funds from the PW
|
||||
if(head_block_time() - stats.last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time()))
|
||||
{
|
||||
|
|
@ -289,7 +296,14 @@ bool database::is_son_dereg_valid( son_id_type son_id )
|
|||
return false;
|
||||
}
|
||||
|
||||
return (son->status == son_status::in_maintenance &&
|
||||
bool status_in_maintenance = true;
|
||||
for(const auto& status : son->statuses)
|
||||
{
|
||||
if(status.second != son_status::in_maintenance)
|
||||
status_in_maintenance = false;
|
||||
}
|
||||
|
||||
return (status_in_maintenance &&
|
||||
(head_block_time() - son->statistics(*this).last_down_timestamp >= fc::seconds(get_global_properties().parameters.son_deregister_time())));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ vector<std::reference_wrapper<const son_object>> database::sort_votable_objects<
|
|||
std::vector<std::reference_wrapper<const son_object>> refs;
|
||||
for( auto& son : all_sons )
|
||||
{
|
||||
if(son.has_valid_config(head_block_time()) && son.status != son_status::deregistered)
|
||||
if(son.has_valid_config(head_block_time()) && son.statuses.at(sidechain) != son_status::deregistered)
|
||||
{
|
||||
refs.push_back(std::cref(son));
|
||||
}
|
||||
|
|
@ -186,6 +186,7 @@ void database::pay_sons()
|
|||
const dynamic_global_property_object& dpo = get_dynamic_global_properties();
|
||||
// Current requirement is that we have to pay every 24 hours, so the following check
|
||||
if( dpo.son_budget.value > 0 && ((now - dpo.last_son_payout_time) >= fc::seconds(get_global_properties().parameters.son_pay_time()))) {
|
||||
//! Fixme - sort_votable_objects only for bitcoin
|
||||
auto sons = sort_votable_objects<son_index>(sidechain_type::bitcoin, get_global_properties().parameters.maximum_son_count());
|
||||
// After SON2 HF
|
||||
uint64_t total_votes = 0;
|
||||
|
|
@ -353,9 +354,9 @@ void database::update_son_statuses( const flat_map<sidechain_type, vector<son_in
|
|||
if (son == idx.end()) // SON is deleted already
|
||||
continue;
|
||||
// keep maintenance status for nodes becoming inactive
|
||||
if (son->status == son_status::active) {
|
||||
if (son->statuses.at(sidechain) == son_status::active) {
|
||||
modify(*son, [&](son_object &obj) {
|
||||
obj.status = son_status::inactive;
|
||||
obj.statuses.at(sidechain) = son_status::inactive;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -373,9 +374,9 @@ void database::update_son_statuses( const flat_map<sidechain_type, vector<son_in
|
|||
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) {
|
||||
if (son->statuses.at(sidechain) == son_status::inactive) {
|
||||
modify(*son, [&](son_object &obj) {
|
||||
obj.status = son_status::active;
|
||||
obj.statuses.at(sidechain) = son_status::active;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -385,7 +386,7 @@ void database::update_son_statuses( const flat_map<sidechain_type, vector<son_in
|
|||
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));
|
||||
ilog("${s}, status = ${ss}, total_votes = ${sv}", ("s", new_sons[i])("ss", son->statuses.at(sidechain))("sv", son->total_votes));
|
||||
}
|
||||
|
||||
if (sons_to_remove.size() > 0) {
|
||||
|
|
@ -723,19 +724,29 @@ void database::update_active_sons()
|
|||
auto& local_vote_buffer_ref = _vote_tally_buffer;
|
||||
for( const son_object& son : all_sons )
|
||||
{
|
||||
if(son.status == son_status::request_maintenance)
|
||||
bool status_in_maintenance = true;
|
||||
for(const auto& status: son.statuses)
|
||||
{
|
||||
auto& stats = son.statistics(*this);
|
||||
modify( stats, [&]( son_statistics_object& _s){
|
||||
_s.last_down_timestamp = head_block_time();
|
||||
});
|
||||
if(status.second != son_status::in_maintenance)
|
||||
status_in_maintenance = false;
|
||||
}
|
||||
if(status_in_maintenance)
|
||||
{
|
||||
auto &stats = son.statistics(*this);
|
||||
modify(stats, [&](son_statistics_object &_s) {
|
||||
_s.last_down_timestamp = head_block_time();
|
||||
});
|
||||
}
|
||||
|
||||
modify( son, [local_vote_buffer_ref]( son_object& obj ){
|
||||
for(const auto& sidechain_vote_id : obj.sidechain_vote_ids ){
|
||||
obj.total_votes[sidechain_vote_id.first] = local_vote_buffer_ref[sidechain_vote_id.second];
|
||||
}
|
||||
if(obj.status == son_status::request_maintenance)
|
||||
obj.status = son_status::in_maintenance;
|
||||
for(auto& status: obj.statuses)
|
||||
{
|
||||
if (status.second == son_status::request_maintenance)
|
||||
status.second = son_status::in_maintenance;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -513,6 +513,7 @@ namespace graphene { namespace chain {
|
|||
template<class Index>
|
||||
vector<std::reference_wrapper<const typename Index::object_type>> sort_votable_objects(size_t count)const;
|
||||
|
||||
//! Fixme return map here
|
||||
template<class Index>
|
||||
vector<std::reference_wrapper<const typename Index::object_type>> sort_votable_objects(sidechain_type sidechain, size_t count)const;
|
||||
|
||||
|
|
|
|||
|
|
@ -35,11 +35,11 @@ namespace graphene { namespace chain {
|
|||
// Transactions signed since the last son payouts
|
||||
flat_map<sidechain_type, uint64_t> txs_signed;
|
||||
// Total Voted Active time i.e. duration selected as part of voted active SONs
|
||||
flat_map<sidechain_type, uint64_t> total_voted_time;
|
||||
flat_map<sidechain_type, uint64_t> total_voted_time; //! Fixme - check if we need map of sidechain_type here
|
||||
// Total Downtime barring the current down time in seconds, used for stats to present to user
|
||||
flat_map<sidechain_type, uint64_t> total_downtime;
|
||||
flat_map<sidechain_type, uint64_t> total_downtime; //! Fixme - check if we need map of sidechain_type here
|
||||
// Current Interval Downtime since last maintenance
|
||||
flat_map<sidechain_type, uint64_t> current_interval_downtime;
|
||||
flat_map<sidechain_type, uint64_t> current_interval_downtime; //! Fixme - check if we need map of sidechain_type here
|
||||
// Down timestamp, if son status is in_maintenance use this
|
||||
fc::time_point_sec last_down_timestamp;
|
||||
// Last Active heartbeat timestamp
|
||||
|
|
@ -71,7 +71,7 @@ namespace graphene { namespace chain {
|
|||
public_key_type signing_key;
|
||||
vesting_balance_id_type pay_vb;
|
||||
son_statistics_id_type statistics;
|
||||
son_status status = son_status::inactive; //! Fixme -> as map of sidechain_type
|
||||
flat_map<sidechain_type, son_status> statuses;
|
||||
flat_map<sidechain_type, string> sidechain_public_keys;
|
||||
|
||||
void pay_son_fee(share_type pay, database& db);
|
||||
|
|
@ -132,7 +132,7 @@ FC_REFLECT_DERIVED( graphene::chain::son_object, (graphene::db::object),
|
|||
(signing_key)
|
||||
(pay_vb)
|
||||
(statistics)
|
||||
(status)
|
||||
(statuses)
|
||||
(sidechain_public_keys)
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -97,7 +97,8 @@ object_id_type update_son_evaluator::do_apply(const son_update_operation& op)
|
|||
if(op.new_signing_key.valid()) so.signing_key = *op.new_signing_key;
|
||||
if(op.new_sidechain_public_keys.valid()) so.sidechain_public_keys = *op.new_sidechain_public_keys;
|
||||
if(op.new_pay_vb.valid()) so.pay_vb = *op.new_pay_vb;
|
||||
if(so.status == son_status::deregistered) so.status = son_status::inactive;
|
||||
for(auto& status : so.statuses)
|
||||
if(status.second == son_status::deregistered) status.second = son_status::inactive;
|
||||
});
|
||||
}
|
||||
return op.son_id;
|
||||
|
|
@ -130,7 +131,8 @@ void_result deregister_son_evaluator::do_apply(const son_deregister_operation& o
|
|||
});
|
||||
|
||||
db().modify(*son, [&op](son_object &so) {
|
||||
so.status = son_status::deregistered;
|
||||
for(auto& status : so.statuses)
|
||||
status.second = son_status::deregistered;
|
||||
});
|
||||
|
||||
auto stats_obj = ss_idx.find(son->statistics);
|
||||
|
|
@ -147,12 +149,18 @@ void_result son_heartbeat_evaluator::do_evaluate(const son_heartbeat_operation&
|
|||
{ try {
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); // can be removed after HF date pass
|
||||
const auto& idx = db().get_index_type<son_index>().indices().get<by_id>();
|
||||
auto itr = idx.find(op.son_id);
|
||||
const auto itr = idx.find(op.son_id);
|
||||
FC_ASSERT( itr != idx.end() );
|
||||
FC_ASSERT(itr->son_account == op.owner_account);
|
||||
auto stats = itr->statistics( db() );
|
||||
// Inactive SONs need not send heartbeats
|
||||
FC_ASSERT((itr->status == son_status::active) || (itr->status == son_status::in_maintenance) || (itr->status == son_status::request_maintenance), "Inactive SONs need not send heartbeats");
|
||||
bool status_need_to_send_heartbeats = false;
|
||||
for(const auto& status : itr->statuses)
|
||||
{
|
||||
if( (status.second == son_status::active) || (status.second == son_status::in_maintenance) || (status.second == son_status::request_maintenance) )
|
||||
status_need_to_send_heartbeats = true;
|
||||
}
|
||||
FC_ASSERT(status_need_to_send_heartbeats, "Inactive SONs need not send heartbeats");
|
||||
// Account for network delays
|
||||
fc::time_point_sec min_ts = db().head_block_time() - fc::seconds(5 * db().block_interval());
|
||||
// Account for server ntp sync difference
|
||||
|
|
@ -167,7 +175,7 @@ void_result son_heartbeat_evaluator::do_evaluate(const son_heartbeat_operation&
|
|||
object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation& op)
|
||||
{ try {
|
||||
const auto& idx = db().get_index_type<son_index>().indices().get<by_id>();
|
||||
auto itr = idx.find(op.son_id);
|
||||
const auto itr = idx.find(op.son_id);
|
||||
if(itr != idx.end())
|
||||
{
|
||||
const global_property_object& gpo = db().get_global_properties();
|
||||
|
|
@ -184,27 +192,27 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation&
|
|||
return swi.son_id;
|
||||
});
|
||||
|
||||
auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), op.son_id);
|
||||
const auto it_son = std::find(active_son_ids.begin(), active_son_ids.end(), op.son_id);
|
||||
bool is_son_active = true;
|
||||
|
||||
if (it_son == active_son_ids.end()) {
|
||||
is_son_active = false;
|
||||
}
|
||||
|
||||
if (itr->status == son_status::in_maintenance) {
|
||||
if (itr->statuses.at(sidechain) == 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) {
|
||||
db().modify(*itr, [&is_son_active, &sidechain](son_object &so) {
|
||||
if (is_son_active) {
|
||||
so.status = son_status::active;
|
||||
so.statuses[sidechain] = son_status::active;
|
||||
} else {
|
||||
so.status = son_status::inactive;
|
||||
so.statuses[sidechain] = son_status::inactive;
|
||||
}
|
||||
});
|
||||
} else if ((itr->status == son_status::active) || (itr->status == son_status::request_maintenance)) {
|
||||
} else if ((itr->statuses.at(sidechain) == son_status::active) || (itr->statuses.at(sidechain) == son_status::request_maintenance)) {
|
||||
db().modify(itr->statistics(db()), [&](son_statistics_object &sso) {
|
||||
sso.last_active_timestamp = op.ts;
|
||||
});
|
||||
|
|
@ -220,9 +228,15 @@ void_result son_report_down_evaluator::do_evaluate(const son_report_down_operati
|
|||
FC_ASSERT(op.payer == db().get_global_properties().parameters.son_account(), "SON paying account must be set as payer.");
|
||||
const auto& idx = db().get_index_type<son_index>().indices().get<by_id>();
|
||||
FC_ASSERT( idx.find(op.son_id) != idx.end() );
|
||||
auto itr = idx.find(op.son_id);
|
||||
auto stats = itr->statistics( db() );
|
||||
FC_ASSERT(itr->status == son_status::active || itr->status == son_status::request_maintenance, "Inactive/Deregistered/in_maintenance SONs cannot be reported on as down");
|
||||
const auto itr = idx.find(op.son_id);
|
||||
const auto stats = itr->statistics( db() );
|
||||
bool status_need_to_report_down = false;
|
||||
for(const auto& status : itr->statuses)
|
||||
{
|
||||
if( (status.second == son_status::active) || (status.second == son_status::request_maintenance) )
|
||||
status_need_to_report_down = true;
|
||||
}
|
||||
FC_ASSERT(status_need_to_report_down, "Inactive/Deregistered/in_maintenance SONs cannot be reported on as down");
|
||||
FC_ASSERT(op.down_ts >= stats.last_active_timestamp, "down_ts should be greater than last_active_timestamp");
|
||||
return void_result();
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
|
@ -230,19 +244,28 @@ void_result son_report_down_evaluator::do_evaluate(const son_report_down_operati
|
|||
object_id_type son_report_down_evaluator::do_apply(const son_report_down_operation& op)
|
||||
{ try {
|
||||
const auto& idx = db().get_index_type<son_index>().indices().get<by_id>();
|
||||
auto itr = idx.find(op.son_id);
|
||||
const auto itr = idx.find(op.son_id);
|
||||
if(itr != idx.end())
|
||||
{
|
||||
if ((itr->status == son_status::active) || (itr->status == son_status::request_maintenance)) {
|
||||
db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso )
|
||||
{
|
||||
sso.last_down_timestamp = op.down_ts;
|
||||
});
|
||||
bool status_report_down = true;
|
||||
|
||||
db().modify(*itr, [&op](son_object &so) {
|
||||
so.status = son_status::in_maintenance;
|
||||
});
|
||||
}
|
||||
for( const auto& status : itr->statuses ) {
|
||||
const auto& sidechain = status.first;
|
||||
|
||||
if ((status.second == son_status::active) || (status.second == son_status::request_maintenance)) {
|
||||
db().modify(*itr, [&sidechain](son_object &so) {
|
||||
so.statuses[sidechain] = son_status::in_maintenance;
|
||||
});
|
||||
}
|
||||
else
|
||||
status_report_down = false;
|
||||
}
|
||||
|
||||
if(status_report_down) {
|
||||
db().modify(itr->statistics(db()), [&](son_statistics_object &sso) {
|
||||
sso.last_down_timestamp = op.down_ts;
|
||||
});
|
||||
}
|
||||
}
|
||||
return op.son_id;
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
|
@ -256,9 +279,19 @@ void_result son_maintenance_evaluator::do_evaluate(const son_maintenance_operati
|
|||
FC_ASSERT( itr != idx.end() );
|
||||
// Inactive SONs can't go to maintenance, toggle between active and request_maintenance states
|
||||
if(op.request_type == son_maintenance_request_type::request_maintenance) {
|
||||
FC_ASSERT(itr->status == son_status::active, "Inactive SONs can't request for maintenance");
|
||||
} else if(op.request_type == son_maintenance_request_type::cancel_request_maintenance) {
|
||||
FC_ASSERT(itr->status == son_status::request_maintenance, "Only maintenance requested SONs can cancel the request");
|
||||
bool status_active = false;
|
||||
for(const auto& status : itr->statuses) {
|
||||
if( (status.second == son_status::active) )
|
||||
status_active = true;
|
||||
}
|
||||
FC_ASSERT(status_active, "Inactive SONs can't request for maintenance");
|
||||
} else if(op.request_type == son_maintenance_request_type::cancel_request_maintenance) {
|
||||
bool status_request_maintenance = false;
|
||||
for(const auto& status : itr->statuses) {
|
||||
if( (status.second == son_status::request_maintenance) )
|
||||
status_request_maintenance = true;
|
||||
}
|
||||
FC_ASSERT(status_request_maintenance, "Only maintenance requested SONs can cancel the request");
|
||||
} else {
|
||||
FC_ASSERT(false, "Invalid maintenance operation");
|
||||
}
|
||||
|
|
@ -271,15 +304,33 @@ object_id_type son_maintenance_evaluator::do_apply(const son_maintenance_operati
|
|||
auto itr = idx.find(op.son_id);
|
||||
if(itr != idx.end())
|
||||
{
|
||||
if(itr->status == son_status::active && op.request_type == son_maintenance_request_type::request_maintenance) {
|
||||
db().modify(*itr, [](son_object &so) {
|
||||
so.status = son_status::request_maintenance;
|
||||
});
|
||||
} else if(itr->status == son_status::request_maintenance && op.request_type == son_maintenance_request_type::cancel_request_maintenance) {
|
||||
db().modify(*itr, [](son_object &so) {
|
||||
so.status = son_status::active;
|
||||
});
|
||||
}
|
||||
bool status_active = false;
|
||||
for(const auto& status : itr->statuses) {
|
||||
if( (status.second == son_status::active) )
|
||||
status_active = true;
|
||||
}
|
||||
if(status_active && op.request_type == son_maintenance_request_type::request_maintenance) {
|
||||
db().modify(*itr, [](son_object &so) {
|
||||
for(auto& status : so.statuses) {
|
||||
status.second = son_status::request_maintenance;
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
bool status_request_maintenance = false;
|
||||
for(const auto& status : itr->statuses) {
|
||||
if( (status.second == son_status::request_maintenance) )
|
||||
status_request_maintenance = true;
|
||||
}
|
||||
if(status_request_maintenance && op.request_type == son_maintenance_request_type::cancel_request_maintenance) {
|
||||
db().modify(*itr, [](son_object &so) {
|
||||
for(auto& status : so.statuses) {
|
||||
status.second = son_status::active;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return op.son_id;
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
|
|
|||
|
|
@ -338,7 +338,13 @@ bool peerplays_sidechain_plugin_impl::is_son_deregistered(son_id_type son_id) {
|
|||
if (son_obj == idx.end())
|
||||
return true;
|
||||
|
||||
if (son_obj->status == chain::son_status::deregistered) {
|
||||
bool status_deregistered = true;
|
||||
for(const auto& status : son_obj->statuses) {
|
||||
if( (status.second != son_status::deregistered) )
|
||||
status_deregistered = false;
|
||||
}
|
||||
|
||||
if (status_deregistered) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -364,8 +370,13 @@ bool peerplays_sidechain_plugin_impl::is_son_down_op_valid(const chain::operatio
|
|||
fc::time_point_sec last_maintenance_time = dgpo.next_maintenance_time - gpo.parameters.maintenance_interval;
|
||||
fc::time_point_sec last_active_ts = ((stats.last_active_timestamp > last_maintenance_time) ? stats.last_active_timestamp : last_maintenance_time);
|
||||
int64_t down_threshold = gpo.parameters.son_down_time();
|
||||
if (((son_obj->status == chain::son_status::active) || (son_obj->status == chain::son_status::request_maintenance)) &&
|
||||
((fc::time_point::now() - last_active_ts) > fc::seconds(down_threshold))) {
|
||||
|
||||
bool status_son_down_op_valid = true;
|
||||
for(const auto& status : son_obj->statuses) {
|
||||
if( (status.second != son_status::active) && (status.second != son_status::request_maintenance) )
|
||||
status_son_down_op_valid = false;
|
||||
}
|
||||
if ((status_son_down_op_valid) && ((fc::time_point::now() - last_active_ts) > fc::seconds(down_threshold))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
|
@ -400,7 +411,14 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() {
|
|||
chain::database &d = plugin.database();
|
||||
|
||||
for (son_id_type son_id : sons) {
|
||||
if (is_active_son(son_id) || get_son_object(son_id).status == chain::son_status::in_maintenance) {
|
||||
const auto& son_obj = get_son_object(son_id);
|
||||
bool status_in_maintenance= false;
|
||||
for(const auto& status : son_obj.statuses) {
|
||||
if( (status.second == son_status::in_maintenance) )
|
||||
status_in_maintenance = true;
|
||||
}
|
||||
|
||||
if (is_active_son(son_id) || status_in_maintenance) {
|
||||
|
||||
ilog("Sending heartbeat for SON ${son}", ("son", son_id));
|
||||
chain::son_heartbeat_operation op;
|
||||
|
|
@ -626,8 +644,13 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() {
|
|||
fc::time_point_sec last_maintenance_time = dgpo.next_maintenance_time - gpo.parameters.maintenance_interval;
|
||||
fc::time_point_sec last_active_ts = ((stats.last_active_timestamp > last_maintenance_time) ? stats.last_active_timestamp : last_maintenance_time);
|
||||
int64_t down_threshold = gpo.parameters.son_down_time();
|
||||
if (((son_obj->status == chain::son_status::active) || (son_obj->status == chain::son_status::request_maintenance)) &&
|
||||
((fc::time_point::now() - last_active_ts) > fc::seconds(down_threshold))) {
|
||||
|
||||
bool status_son_down_valid = true;
|
||||
for(const auto& status : son_obj->statuses) {
|
||||
if( (status.second != son_status::active) && (status.second != son_status::request_maintenance) )
|
||||
status_son_down_valid = false;
|
||||
}
|
||||
if ((status_son_down_valid) && ((fc::time_point::now() - last_active_ts) > fc::seconds(down_threshold))) {
|
||||
ilog("Sending son down proposal for ${t} from ${s}", ("t", std::string(object_id_type(son_obj->id)))("s", std::string(object_id_type(my_son_id))));
|
||||
chain::proposal_create_operation op = create_son_down_proposal(son_inf.son_id, last_active_ts);
|
||||
chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(get_son_object(my_son_id).signing_key), op);
|
||||
|
|
|
|||
|
|
@ -858,7 +858,8 @@ BOOST_AUTO_TEST_CASE( maintenance_test )
|
|||
BOOST_CHECK(generate_maintenance_block());
|
||||
|
||||
son_object son_obj = con.wallet_api_ptr->get_son(name);
|
||||
BOOST_CHECK(son_obj.status == son_status::active);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::active);
|
||||
|
||||
// put SON in maintenance mode
|
||||
con.wallet_api_ptr->request_son_maintenance(name, true);
|
||||
|
|
@ -866,7 +867,8 @@ BOOST_AUTO_TEST_CASE( maintenance_test )
|
|||
|
||||
// check SON is in request_maintenance
|
||||
son_obj = con.wallet_api_ptr->get_son(name);
|
||||
BOOST_CHECK(son_obj.status == son_status::request_maintenance);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::request_maintenance);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::request_maintenance);
|
||||
|
||||
// restore SON activity
|
||||
con.wallet_api_ptr->cancel_request_son_maintenance(name, true);
|
||||
|
|
@ -874,7 +876,8 @@ BOOST_AUTO_TEST_CASE( maintenance_test )
|
|||
|
||||
// check SON is active
|
||||
son_obj = con.wallet_api_ptr->get_son(name);
|
||||
BOOST_CHECK(son_obj.status == son_status::active);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::active);
|
||||
|
||||
// put SON in maintenance mode
|
||||
con.wallet_api_ptr->request_son_maintenance(name, true);
|
||||
|
|
@ -882,14 +885,16 @@ BOOST_AUTO_TEST_CASE( maintenance_test )
|
|||
|
||||
// check SON is in request_maintenance
|
||||
son_obj = con.wallet_api_ptr->get_son(name);
|
||||
BOOST_CHECK(son_obj.status == son_status::request_maintenance);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::request_maintenance);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::request_maintenance);
|
||||
|
||||
// process maintenance
|
||||
BOOST_CHECK(generate_maintenance_block());
|
||||
|
||||
// check SON is in maintenance
|
||||
son_obj = con.wallet_api_ptr->get_son(name);
|
||||
BOOST_CHECK(son_obj.status == son_status::in_maintenance);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::in_maintenance);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::in_maintenance);
|
||||
|
||||
|
||||
} catch( fc::exception& e ) {
|
||||
|
|
@ -1006,7 +1011,8 @@ BOOST_AUTO_TEST_CASE( sidechain_withdraw_transaction_test )
|
|||
BOOST_CHECK(generate_maintenance_block());
|
||||
|
||||
son_object son_obj = con.wallet_api_ptr->get_son(name);
|
||||
BOOST_CHECK(son_obj.status == son_status::active);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK(son_obj.statuses.at(sidechain_type::hive) == son_status::active);
|
||||
|
||||
// create son account
|
||||
std::string account_name("peerplaystest");
|
||||
|
|
|
|||
|
|
@ -193,7 +193,8 @@ try {
|
|||
// Modify SON's status to active
|
||||
db.modify( *obj, [&]( son_object& _s)
|
||||
{
|
||||
_s.status = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::hive] = son_status::in_maintenance;
|
||||
});
|
||||
|
||||
db.modify( *son_stats_obj, [&]( son_statistics_object& _s)
|
||||
|
|
@ -218,7 +219,8 @@ try {
|
|||
generate_block();
|
||||
|
||||
BOOST_REQUIRE( idx.size() == 1 );
|
||||
BOOST_REQUIRE( obj->status == son_status::deregistered );
|
||||
BOOST_REQUIRE( obj->statuses.at(sidechain_type::bitcoin) == son_status::deregistered );
|
||||
BOOST_REQUIRE( obj->statuses.at(sidechain_type::hive) == son_status::deregistered );
|
||||
BOOST_REQUIRE( son_stats_obj->deregistered_timestamp == now );
|
||||
|
||||
deposit_vesting = db.get<vesting_balance_object>(vesting_balance_id_type(0));
|
||||
|
|
@ -604,7 +606,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
// Modify SON's status to active
|
||||
db.modify( *obj, [&]( son_object& _s)
|
||||
{
|
||||
_s.status = son_status::active;
|
||||
_s.statuses[sidechain_type::bitcoin] = son_status::active;
|
||||
_s.statuses[sidechain_type::hive] = son_status::active;
|
||||
});
|
||||
|
||||
db.modify( *son_stats_obj, [&]( son_statistics_object& _s)
|
||||
|
|
@ -626,7 +629,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
PUSH_TX( db, trx, ~0);
|
||||
generate_block();
|
||||
trx.clear();
|
||||
BOOST_CHECK( obj->status == son_status::request_maintenance);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::request_maintenance);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::request_maintenance);
|
||||
}
|
||||
|
||||
{
|
||||
|
|
@ -643,13 +647,15 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
PUSH_TX( db, trx, ~0);
|
||||
generate_block();
|
||||
trx.clear();
|
||||
BOOST_CHECK( obj->status == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active);
|
||||
}
|
||||
|
||||
// Modify SON's status to in_maintenance
|
||||
db.modify( *obj, [&]( son_object& _s)
|
||||
{
|
||||
_s.status = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::hive] = son_status::in_maintenance;
|
||||
});
|
||||
|
||||
uint64_t downtime = 0;
|
||||
|
|
@ -671,14 +677,16 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
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();
|
||||
BOOST_CHECK( obj->status == son_status::inactive);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::inactive);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::inactive);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts);
|
||||
}
|
||||
|
||||
// Modify SON's status to in_maintenance
|
||||
db.modify( *obj, [&]( son_object& _s)
|
||||
{
|
||||
_s.status = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance;
|
||||
_s.statuses[sidechain_type::bitcoin] = son_status::in_maintenance;
|
||||
});
|
||||
|
||||
// SON is selected as one of the active SONs
|
||||
|
|
@ -707,7 +715,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
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();
|
||||
BOOST_CHECK( obj->status == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts);
|
||||
}
|
||||
|
||||
|
|
@ -727,7 +736,8 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
trx.clear();
|
||||
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->statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active);
|
||||
BOOST_CHECK( son_stats_obj->last_active_timestamp == op.ts);
|
||||
}
|
||||
} FC_LOG_AND_RETHROW()
|
||||
|
|
@ -753,7 +763,8 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) {
|
|||
auto son_stats_obj = sidx.find( obj->statistics );
|
||||
BOOST_REQUIRE( son_stats_obj != sidx.end() );
|
||||
|
||||
BOOST_CHECK( obj->status == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::active);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::active);
|
||||
|
||||
{
|
||||
// Check that transaction fails if down_ts < last_active_timestamp
|
||||
|
|
@ -805,7 +816,8 @@ BOOST_AUTO_TEST_CASE( son_report_down_test ) {
|
|||
generate_block();
|
||||
trx.clear();
|
||||
|
||||
BOOST_CHECK( obj->status == son_status::in_maintenance);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::bitcoin) == son_status::in_maintenance);
|
||||
BOOST_CHECK( obj->statuses.at(sidechain_type::hive) == son_status::in_maintenance);
|
||||
BOOST_CHECK( son_stats_obj->last_down_timestamp == op.down_ts);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue