SON214 - Request maintenance wallet commands (#280)
This commit is contained in:
parent
a688bb93ed
commit
daf7ac5da8
8 changed files with 56 additions and 17 deletions
|
|
@ -414,10 +414,20 @@ void database::update_active_sons()
|
|||
|
||||
const auto& all_sons = get_index_type<son_index>().indices();
|
||||
|
||||
auto& local_vote_buffer_ref = _vote_tally_buffer;
|
||||
for( const son_object& son : all_sons )
|
||||
{
|
||||
modify( son, [&]( son_object& obj ){
|
||||
obj.total_votes = _vote_tally_buffer[son.vote_id];
|
||||
if(son.status == son_status::request_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 ){
|
||||
obj.total_votes = local_vote_buffer_ref[obj.vote_id];
|
||||
if(obj.status == son_status::request_maintenance)
|
||||
obj.status = son_status::in_maintenance;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ namespace graphene { namespace chain {
|
|||
{
|
||||
inactive,
|
||||
active,
|
||||
request_maintenance,
|
||||
in_maintenance,
|
||||
deregistered
|
||||
};
|
||||
|
|
@ -94,7 +95,7 @@ namespace graphene { namespace chain {
|
|||
using son_stats_index = generic_index<son_statistics_object, son_stats_multi_index_type>;
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT_ENUM(graphene::chain::son_status, (inactive)(active)(in_maintenance)(deregistered) )
|
||||
FC_REFLECT_ENUM(graphene::chain::son_status, (inactive)(active)(request_maintenance)(in_maintenance)(deregistered) )
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::son_object, (graphene::db::object),
|
||||
(son_account)(vote_id)(total_votes)(url)(deposit)(signing_key)(pay_vb)(statistics)(status)(sidechain_public_keys) )
|
||||
|
|
|
|||
|
|
@ -105,11 +105,11 @@ void_result son_heartbeat_evaluator::do_evaluate(const son_heartbeat_operation&
|
|||
auto itr = idx.find(op.son_id);
|
||||
auto stats = itr->statistics( db() );
|
||||
// Inactive SONs need not send heartbeats
|
||||
FC_ASSERT(itr->status == son_status::active || itr->status == son_status::in_maintenance, "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");
|
||||
// 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
|
||||
fc::time_point_sec max_ts = db().head_block_time() + fc::seconds(2 * db().block_interval());
|
||||
fc::time_point_sec max_ts = db().head_block_time() + fc::seconds(5 * db().block_interval());
|
||||
FC_ASSERT(op.ts > stats.last_active_timestamp, "Heartbeat sent without waiting minimum time");
|
||||
FC_ASSERT(op.ts > stats.last_down_timestamp, "Heartbeat sent is invalid can't be <= last down timestamp");
|
||||
FC_ASSERT(op.ts >= min_ts, "Heartbeat ts is behind the min threshold");
|
||||
|
|
@ -153,7 +153,7 @@ object_id_type son_heartbeat_evaluator::do_apply(const son_heartbeat_operation&
|
|||
so.status = son_status::inactive;
|
||||
}
|
||||
});
|
||||
} else if (itr->status == son_status::active) {
|
||||
} else if ((itr->status == son_status::active) || (itr->status == son_status::request_maintenance)) {
|
||||
db().modify( itr->statistics( db() ), [&]( son_statistics_object& sso )
|
||||
{
|
||||
sso.last_active_timestamp = op.ts;
|
||||
|
|
@ -171,7 +171,7 @@ void_result son_report_down_evaluator::do_evaluate(const son_report_down_operati
|
|||
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, "Inactive/Deregistered/in_maintenance SONs cannot be reported on as down");
|
||||
FC_ASSERT(itr->status == son_status::active || itr->status == son_status::request_maintenance, "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) ) }
|
||||
|
|
@ -182,7 +182,7 @@ object_id_type son_report_down_evaluator::do_apply(const son_report_down_operati
|
|||
auto itr = idx.find(op.son_id);
|
||||
if(itr != idx.end())
|
||||
{
|
||||
if (itr->status == son_status::active) {
|
||||
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;
|
||||
|
|
@ -203,8 +203,8 @@ void_result son_maintenance_evaluator::do_evaluate(const son_maintenance_operati
|
|||
const auto& idx = db().get_index_type<son_index>().indices().get<by_id>();
|
||||
auto itr = idx.find(op.son_id);
|
||||
FC_ASSERT( itr != idx.end() );
|
||||
// Inactive SONs can't go to maintenance
|
||||
FC_ASSERT(itr->status == son_status::active || itr->status == son_status::in_maintenance, "Inactive SONs can't go to maintenance");
|
||||
// Inactive SONs can't go to maintenance, toggle between active and request_maintenance states
|
||||
FC_ASSERT(itr->status == son_status::active || itr->status == son_status::request_maintenance, "Inactive SONs can't go to maintenance");
|
||||
return void_result();
|
||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||
|
||||
|
|
@ -216,7 +216,11 @@ object_id_type son_maintenance_evaluator::do_apply(const son_maintenance_operati
|
|||
{
|
||||
if(itr->status == son_status::active) {
|
||||
db().modify(*itr, [](son_object &so) {
|
||||
so.status = son_status::in_maintenance;
|
||||
so.status = son_status::request_maintenance;
|
||||
});
|
||||
} else if(itr->status == son_status::request_maintenance) {
|
||||
db().modify(*itr, [](son_object &so) {
|
||||
so.status = son_status::active;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -317,7 +317,8 @@ 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 = 2*180000000;
|
||||
if(son_obj->status == chain::son_status::active && (fc::time_point::now() - last_active_ts) > fc::microseconds(down_threshold)) {
|
||||
if(((son_obj->status == chain::son_status::active) || (son_obj->status == chain::son_status::request_maintenance)) &&
|
||||
((fc::time_point::now() - last_active_ts) > fc::microseconds(down_threshold))) {
|
||||
ilog("peerplays_sidechain_plugin: 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(_private_keys.begin()->second, op);
|
||||
|
|
|
|||
|
|
@ -2241,6 +2241,8 @@ FC_API( graphene::wallet::wallet_api,
|
|||
(delete_son)
|
||||
(list_sons)
|
||||
(list_active_sons)
|
||||
(start_son_maintenance)
|
||||
(stop_son_maintenance)
|
||||
(get_active_son_wallet)
|
||||
(get_son_wallet_by_time_point)
|
||||
(get_son_wallets)
|
||||
|
|
|
|||
|
|
@ -1964,10 +1964,9 @@ public:
|
|||
{ try {
|
||||
son_object son = get_son(owner_account);
|
||||
|
||||
son_heartbeat_operation op;
|
||||
son_maintenance_operation op;
|
||||
op.owner_account = son.son_account;
|
||||
op.son_id = son.id;
|
||||
op.ts = _remote_db->get_dynamic_global_properties().time; // or fc::time_point_sec(fc::time_point::now()) ???
|
||||
|
||||
signed_transaction tx;
|
||||
tx.operations.push_back( op );
|
||||
|
|
|
|||
|
|
@ -699,9 +699,9 @@ BOOST_AUTO_TEST_CASE( maintenance_test )
|
|||
con.wallet_api_ptr->start_son_maintenance(name, true);
|
||||
BOOST_CHECK(generate_block());
|
||||
|
||||
// check SON is in maintenance
|
||||
// check SON is in request_maintenance
|
||||
son_obj = con.wallet_api_ptr->get_son(name);
|
||||
BOOST_CHECK(son_obj.status == son_status::in_maintenance);
|
||||
BOOST_CHECK(son_obj.status == son_status::request_maintenance);
|
||||
|
||||
// restore SON activity
|
||||
con.wallet_api_ptr->stop_son_maintenance(name, true);
|
||||
|
|
@ -711,6 +711,22 @@ BOOST_AUTO_TEST_CASE( maintenance_test )
|
|||
son_obj = con.wallet_api_ptr->get_son(name);
|
||||
BOOST_CHECK(son_obj.status == son_status::active);
|
||||
|
||||
// put SON in maintenance mode
|
||||
con.wallet_api_ptr->start_son_maintenance(name, true);
|
||||
BOOST_CHECK(generate_block());
|
||||
|
||||
// check SON is in request_maintenance
|
||||
son_obj = con.wallet_api_ptr->get_son(name);
|
||||
BOOST_CHECK(son_obj.status == 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);
|
||||
|
||||
|
||||
} catch( fc::exception& e ) {
|
||||
BOOST_TEST_MESSAGE("SON cli wallet tests exception");
|
||||
edump((e.to_detail_string()));
|
||||
|
|
|
|||
|
|
@ -735,9 +735,15 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
|||
PUSH_TX( db, trx, ~0);
|
||||
generate_block();
|
||||
trx.clear();
|
||||
BOOST_CHECK( obj->status == son_status::in_maintenance);
|
||||
BOOST_CHECK( obj->status == son_status::request_maintenance);
|
||||
}
|
||||
|
||||
// Modify SON's status to in_maintenance
|
||||
db.modify( *obj, [&]( son_object& _s)
|
||||
{
|
||||
_s.status = son_status::in_maintenance;
|
||||
});
|
||||
|
||||
uint64_t downtime = 0;
|
||||
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in a new issue