Compare commits
7 commits
master
...
feature/SO
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0ac2272a0 | ||
|
|
3e2295bea0 | ||
|
|
8a926c29b4 | ||
|
|
1a021734af | ||
|
|
0e2d9c3310 | ||
|
|
9d8278428f | ||
|
|
d440fa98b9 |
14 changed files with 272 additions and 6 deletions
|
|
@ -310,6 +310,9 @@ struct get_impacted_account_visitor
|
||||||
void operator()( const son_heartbeat_operation& op ){
|
void operator()( const son_heartbeat_operation& op ){
|
||||||
_impacted.insert( op.owner_account );
|
_impacted.insert( op.owner_account );
|
||||||
}
|
}
|
||||||
|
void operator()( const son_maintenance_operation& op ){
|
||||||
|
_impacted.insert( op.owner_account );
|
||||||
|
}
|
||||||
void operator()( const sidechain_address_add_operation& op ){
|
void operator()( const sidechain_address_add_operation& op ){
|
||||||
_impacted.insert( op.sidechain_address_account );
|
_impacted.insert( op.sidechain_address_account );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -250,6 +250,7 @@ void database::initialize_evaluators()
|
||||||
register_evaluator<update_son_evaluator>();
|
register_evaluator<update_son_evaluator>();
|
||||||
register_evaluator<delete_son_evaluator>();
|
register_evaluator<delete_son_evaluator>();
|
||||||
register_evaluator<son_heartbeat_evaluator>();
|
register_evaluator<son_heartbeat_evaluator>();
|
||||||
|
register_evaluator<son_maintenance_evaluator>();
|
||||||
register_evaluator<add_sidechain_address_evaluator>();
|
register_evaluator<add_sidechain_address_evaluator>();
|
||||||
register_evaluator<update_sidechain_address_evaluator>();
|
register_evaluator<update_sidechain_address_evaluator>();
|
||||||
register_evaluator<delete_sidechain_address_evaluator>();
|
register_evaluator<delete_sidechain_address_evaluator>();
|
||||||
|
|
|
||||||
|
|
@ -471,6 +471,56 @@ void database::update_active_sons()
|
||||||
} else {
|
} else {
|
||||||
ilog( "Active SONs set CHANGED" );
|
ilog( "Active SONs set CHANGED" );
|
||||||
// Store new SON info, initiate wallet recreation and transfer of funds
|
// Store new SON info, initiate wallet recreation and transfer of funds
|
||||||
|
vector<son_info> sons_to_remove;
|
||||||
|
// find all cur_active_sons members that is not in new_active_sons
|
||||||
|
for_each(cur_active_sons.begin(), cur_active_sons.end(),
|
||||||
|
[&sons_to_remove, &new_active_sons](const son_info& si)
|
||||||
|
{
|
||||||
|
if(std::find(new_active_sons.begin(), new_active_sons.end(), si) ==
|
||||||
|
new_active_sons.end())
|
||||||
|
{
|
||||||
|
sons_to_remove.push_back(si);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
const auto& idx = get_index_type<son_index>().indices().get<by_id>();
|
||||||
|
for( const son_info& si : sons_to_remove )
|
||||||
|
{
|
||||||
|
auto son = idx.find( si.son_id );
|
||||||
|
if(son == idx.end()) // SON is deleted already
|
||||||
|
continue;
|
||||||
|
// keep maintenance status for nodes becoming inactive
|
||||||
|
if(son->status == son_status::active)
|
||||||
|
{
|
||||||
|
modify( *son, [&]( son_object& obj ){
|
||||||
|
obj.status = son_status::inactive;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
vector<son_info> sons_to_add;
|
||||||
|
// find all new_active_sons members that is not in cur_active_sons
|
||||||
|
for_each(new_active_sons.begin(), new_active_sons.end(),
|
||||||
|
[&sons_to_add, &cur_active_sons](const son_info& si)
|
||||||
|
{
|
||||||
|
if(std::find(cur_active_sons.begin(), cur_active_sons.end(), si) ==
|
||||||
|
cur_active_sons.end())
|
||||||
|
{
|
||||||
|
sons_to_add.push_back(si);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
for( const son_info& si : sons_to_add )
|
||||||
|
{
|
||||||
|
auto son = idx.find( si.son_id );
|
||||||
|
FC_ASSERT(son != idx.end(), "Invalid SON in active list, id={sonid}.", ("sonid", si.son_id));
|
||||||
|
// keep maintenance status for new nodes
|
||||||
|
if(son->status == son_status::inactive)
|
||||||
|
{
|
||||||
|
modify( *son, [&]( son_object& obj ){
|
||||||
|
obj.status = son_status::active;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
modify(gpo, [&]( global_property_object& gp ){
|
modify(gpo, [&]( global_property_object& gp ){
|
||||||
|
|
|
||||||
|
|
@ -297,6 +297,9 @@ struct get_impacted_account_visitor
|
||||||
void operator()( const son_heartbeat_operation& op ) {
|
void operator()( const son_heartbeat_operation& op ) {
|
||||||
_impacted.insert( op.owner_account );
|
_impacted.insert( op.owner_account );
|
||||||
}
|
}
|
||||||
|
void operator()( const son_maintenance_operation& op ) {
|
||||||
|
_impacted.insert( op.owner_account );
|
||||||
|
}
|
||||||
void operator()( const sidechain_address_add_operation& op ) {
|
void operator()( const sidechain_address_add_operation& op ) {
|
||||||
_impacted.insert( op.sidechain_address_account );
|
_impacted.insert( op.sidechain_address_account );
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,7 +145,8 @@ namespace graphene { namespace chain {
|
||||||
sidechain_address_add_operation,
|
sidechain_address_add_operation,
|
||||||
sidechain_address_update_operation,
|
sidechain_address_update_operation,
|
||||||
sidechain_address_delete_operation,
|
sidechain_address_delete_operation,
|
||||||
son_report_down_operation
|
son_report_down_operation,
|
||||||
|
son_maintenance_operation
|
||||||
> operation;
|
> operation;
|
||||||
|
|
||||||
/// @} // operations group
|
/// @} // operations group
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@ namespace graphene { namespace chain {
|
||||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct son_report_down_operation : public base_operation
|
struct son_report_down_operation : public base_operation
|
||||||
{
|
{
|
||||||
struct fee_parameters_type { uint64_t fee = 0; };
|
struct fee_parameters_type { uint64_t fee = 0; };
|
||||||
|
|
@ -76,6 +77,18 @@ namespace graphene { namespace chain {
|
||||||
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct son_maintenance_operation : public base_operation
|
||||||
|
{
|
||||||
|
struct fee_parameters_type { uint64_t fee = 0; };
|
||||||
|
|
||||||
|
asset fee;
|
||||||
|
son_id_type son_id;
|
||||||
|
account_id_type owner_account;
|
||||||
|
|
||||||
|
account_id_type fee_payer()const { return owner_account; }
|
||||||
|
share_type calculate_fee(const fee_parameters_type& k)const { return 0; }
|
||||||
|
};
|
||||||
|
|
||||||
} } // namespace graphene::chain
|
} } // namespace graphene::chain
|
||||||
|
|
||||||
FC_REFLECT(graphene::chain::son_create_operation::fee_parameters_type, (fee) )
|
FC_REFLECT(graphene::chain::son_create_operation::fee_parameters_type, (fee) )
|
||||||
|
|
@ -94,3 +107,6 @@ FC_REFLECT(graphene::chain::son_heartbeat_operation, (fee)(son_id)(owner_account
|
||||||
|
|
||||||
FC_REFLECT(graphene::chain::son_report_down_operation::fee_parameters_type, (fee) )
|
FC_REFLECT(graphene::chain::son_report_down_operation::fee_parameters_type, (fee) )
|
||||||
FC_REFLECT(graphene::chain::son_report_down_operation, (fee)(son_id)(payer)(down_ts) )
|
FC_REFLECT(graphene::chain::son_report_down_operation, (fee)(son_id)(payer)(down_ts) )
|
||||||
|
|
||||||
|
FC_REFLECT(graphene::chain::son_maintenance_operation::fee_parameters_type, (fee) )
|
||||||
|
FC_REFLECT(graphene::chain::son_maintenance_operation, (fee)(son_id)(owner_account) )
|
||||||
|
|
|
||||||
|
|
@ -49,4 +49,13 @@ public:
|
||||||
object_id_type do_apply(const son_report_down_operation& o);
|
object_id_type do_apply(const son_report_down_operation& o);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class son_maintenance_evaluator : public evaluator<son_maintenance_evaluator>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef son_maintenance_operation operation_type;
|
||||||
|
|
||||||
|
void_result do_evaluate(const son_maintenance_operation& o);
|
||||||
|
object_id_type do_apply(const son_maintenance_operation& o);
|
||||||
|
};
|
||||||
|
|
||||||
} } // namespace graphene::chain
|
} } // namespace graphene::chain
|
||||||
|
|
|
||||||
|
|
@ -97,7 +97,7 @@ namespace graphene { namespace chain {
|
||||||
FC_REFLECT_ENUM(graphene::chain::son_status, (inactive)(active)(in_maintenance)(deregistered) )
|
FC_REFLECT_ENUM(graphene::chain::son_status, (inactive)(active)(in_maintenance)(deregistered) )
|
||||||
|
|
||||||
FC_REFLECT_DERIVED( graphene::chain::son_object, (graphene::db::object),
|
FC_REFLECT_DERIVED( graphene::chain::son_object, (graphene::db::object),
|
||||||
(son_account)(vote_id)(total_votes)(url)(deposit)(signing_key)(pay_vb)(sidechain_public_keys) )
|
(son_account)(vote_id)(total_votes)(url)(deposit)(signing_key)(pay_vb)(status)(sidechain_public_keys) )
|
||||||
|
|
||||||
FC_REFLECT_DERIVED( graphene::chain::son_statistics_object,
|
FC_REFLECT_DERIVED( graphene::chain::son_statistics_object,
|
||||||
(graphene::db::object),
|
(graphene::db::object),
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,10 @@ struct proposal_operation_hardfork_visitor
|
||||||
FC_ASSERT( block_time >= HARDFORK_SON_TIME, "son_report_down_operation not allowed yet!" );
|
FC_ASSERT( block_time >= HARDFORK_SON_TIME, "son_report_down_operation not allowed yet!" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void operator()(const son_maintenance_operation &v) const {
|
||||||
|
FC_ASSERT( block_time >= HARDFORK_SON_TIME, "son_maintenance_operation not allowed yet!" );
|
||||||
|
}
|
||||||
|
|
||||||
// loop and self visit in proposals
|
// loop and self visit in proposals
|
||||||
void operator()(const proposal_create_operation &v) const {
|
void operator()(const proposal_create_operation &v) const {
|
||||||
for (const op_wrapper &op : v.proposed_ops)
|
for (const op_wrapper &op : v.proposed_ops)
|
||||||
|
|
|
||||||
|
|
@ -175,4 +175,31 @@ object_id_type son_report_down_evaluator::do_apply(const son_report_down_operati
|
||||||
return op.son_id;
|
return op.son_id;
|
||||||
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
|
void_result son_maintenance_evaluator::do_evaluate(const son_maintenance_operation& op)
|
||||||
|
{ try {
|
||||||
|
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); // can be removed after HF date pass
|
||||||
|
FC_ASSERT(db().get(op.son_id).son_account == op.owner_account);
|
||||||
|
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");
|
||||||
|
return void_result();
|
||||||
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
|
object_id_type son_maintenance_evaluator::do_apply(const son_maintenance_operation& op)
|
||||||
|
{ try {
|
||||||
|
const auto& idx = db().get_index_type<son_index>().indices().get<by_id>();
|
||||||
|
auto itr = idx.find(op.son_id);
|
||||||
|
if(itr != idx.end())
|
||||||
|
{
|
||||||
|
if(itr->status == son_status::active) {
|
||||||
|
db().modify(*itr, [](son_object &so) {
|
||||||
|
so.status = son_status::in_maintenance;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return op.son_id;
|
||||||
|
} FC_CAPTURE_AND_RETHROW( (op) ) }
|
||||||
|
|
||||||
} } // namespace graphene::chain
|
} } // namespace graphene::chain
|
||||||
|
|
|
||||||
|
|
@ -1350,6 +1350,24 @@ class wallet_api
|
||||||
signed_transaction delete_son(string owner_account,
|
signed_transaction delete_son(string owner_account,
|
||||||
bool broadcast = false);
|
bool broadcast = false);
|
||||||
|
|
||||||
|
/** Modify status of the SON owned by the given account to maintenance.
|
||||||
|
*
|
||||||
|
* @param owner_account the name or id of the account which is owning the SON
|
||||||
|
* @param broadcast true to broadcast the transaction on the network
|
||||||
|
* @returns the signed transaction
|
||||||
|
*/
|
||||||
|
signed_transaction start_son_maintenance(string owner_account,
|
||||||
|
bool broadcast = false);
|
||||||
|
|
||||||
|
/** Modify status of the SON owned by the given account back to active.
|
||||||
|
*
|
||||||
|
* @param owner_account the name or id of the account which is owning the SON
|
||||||
|
* @param broadcast true to broadcast the transaction on the network
|
||||||
|
* @returns the signed transaction
|
||||||
|
*/
|
||||||
|
signed_transaction stop_son_maintenance(string owner_account,
|
||||||
|
bool broadcast = false);
|
||||||
|
|
||||||
/** Lists all SONs in the blockchain.
|
/** Lists all SONs in the blockchain.
|
||||||
* This returns a list of all account names that own SON, and the associated SON id,
|
* This returns a list of all account names that own SON, and the associated SON id,
|
||||||
* sorted by name. This lists SONs whether they are currently voted in or not.
|
* sorted by name. This lists SONs whether they are currently voted in or not.
|
||||||
|
|
|
||||||
|
|
@ -1939,6 +1939,41 @@ public:
|
||||||
return sign_transaction( tx, broadcast );
|
return sign_transaction( tx, broadcast );
|
||||||
} FC_CAPTURE_AND_RETHROW( (owner_account)(broadcast) ) }
|
} FC_CAPTURE_AND_RETHROW( (owner_account)(broadcast) ) }
|
||||||
|
|
||||||
|
signed_transaction start_son_maintenance(string owner_account,
|
||||||
|
bool broadcast)
|
||||||
|
{ try {
|
||||||
|
son_object son = get_son(owner_account);
|
||||||
|
|
||||||
|
son_maintenance_operation op;
|
||||||
|
op.owner_account = son.son_account;
|
||||||
|
op.son_id = son.id;
|
||||||
|
|
||||||
|
signed_transaction tx;
|
||||||
|
tx.operations.push_back( op );
|
||||||
|
set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees );
|
||||||
|
tx.validate();
|
||||||
|
|
||||||
|
return sign_transaction( tx, broadcast );
|
||||||
|
} FC_CAPTURE_AND_RETHROW( (owner_account) ) }
|
||||||
|
|
||||||
|
signed_transaction stop_son_maintenance(string owner_account,
|
||||||
|
bool broadcast)
|
||||||
|
{ try {
|
||||||
|
son_object son = get_son(owner_account);
|
||||||
|
|
||||||
|
son_heartbeat_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 );
|
||||||
|
set_operation_fees( tx, _remote_db->get_global_properties().parameters.current_fees );
|
||||||
|
tx.validate();
|
||||||
|
|
||||||
|
return sign_transaction( tx, broadcast );
|
||||||
|
} FC_CAPTURE_AND_RETHROW( (owner_account) ) }
|
||||||
|
|
||||||
map<string, son_id_type> list_active_sons()
|
map<string, son_id_type> list_active_sons()
|
||||||
{ try {
|
{ try {
|
||||||
global_property_object gpo = get_global_properties();
|
global_property_object gpo = get_global_properties();
|
||||||
|
|
@ -4403,6 +4438,16 @@ signed_transaction wallet_api::delete_son(string owner_account,
|
||||||
return my->delete_son(owner_account, broadcast);
|
return my->delete_son(owner_account, broadcast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
signed_transaction wallet_api::start_son_maintenance(string owner_account, bool broadcast)
|
||||||
|
{
|
||||||
|
return my->start_son_maintenance(owner_account, broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
|
signed_transaction wallet_api::stop_son_maintenance(string owner_account, bool broadcast)
|
||||||
|
{
|
||||||
|
return my->stop_son_maintenance(owner_account, broadcast);
|
||||||
|
}
|
||||||
|
|
||||||
map<string, son_id_type> wallet_api::list_sons(const string& lowerbound, uint32_t limit)
|
map<string, son_id_type> wallet_api::list_sons(const string& lowerbound, uint32_t limit)
|
||||||
{
|
{
|
||||||
return my->_remote_db->lookup_son_accounts(lowerbound, limit);
|
return my->_remote_db->lookup_son_accounts(lowerbound, limit);
|
||||||
|
|
|
||||||
|
|
@ -658,6 +658,67 @@ BOOST_FIXTURE_TEST_CASE( cli_list_active_sons, cli_fixture )
|
||||||
BOOST_TEST_MESSAGE("SON cli wallet tests for list_active_sons end");
|
BOOST_TEST_MESSAGE("SON cli wallet tests for list_active_sons end");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE( maintenance_test )
|
||||||
|
{
|
||||||
|
BOOST_TEST_MESSAGE("SON maintenance cli wallet tests begin");
|
||||||
|
try
|
||||||
|
{
|
||||||
|
son_test_helper sth(*this);
|
||||||
|
|
||||||
|
std::string name("sonaccount1");
|
||||||
|
|
||||||
|
global_property_object gpo;
|
||||||
|
gpo = con.wallet_api_ptr->get_global_properties();
|
||||||
|
unsigned int son_number = gpo.parameters.maximum_son_count;
|
||||||
|
|
||||||
|
flat_map<graphene::peerplays_sidechain::sidechain_type, string> sidechain_public_keys;
|
||||||
|
|
||||||
|
// create son accounts
|
||||||
|
for(unsigned int i = 0; i < son_number + 1; i++)
|
||||||
|
{
|
||||||
|
sidechain_public_keys.clear();
|
||||||
|
sidechain_public_keys[graphene::peerplays_sidechain::sidechain_type::bitcoin] = "bitcoin_address " + fc::to_pretty_string(i);
|
||||||
|
sth.create_son("sonaccount" + fc::to_pretty_string(i),
|
||||||
|
"http://son" + fc::to_pretty_string(i),
|
||||||
|
sidechain_public_keys,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
BOOST_CHECK(generate_maintenance_block());
|
||||||
|
|
||||||
|
BOOST_TEST_MESSAGE("Voting for SONs");
|
||||||
|
for(unsigned int i = 1; i < son_number + 1; i++)
|
||||||
|
{
|
||||||
|
con.wallet_api_ptr->vote_for_son("sonaccount" + fc::to_pretty_string(i), name, true, true);
|
||||||
|
}
|
||||||
|
BOOST_CHECK(generate_maintenance_block());
|
||||||
|
|
||||||
|
son_object 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 maintenance
|
||||||
|
son_obj = con.wallet_api_ptr->get_son(name);
|
||||||
|
BOOST_CHECK(son_obj.status == son_status::in_maintenance);
|
||||||
|
|
||||||
|
// restore SON activity
|
||||||
|
con.wallet_api_ptr->stop_son_maintenance(name, true);
|
||||||
|
BOOST_CHECK(generate_block());
|
||||||
|
|
||||||
|
// check SON is active
|
||||||
|
son_obj = con.wallet_api_ptr->get_son(name);
|
||||||
|
BOOST_CHECK(son_obj.status == son_status::active);
|
||||||
|
|
||||||
|
} catch( fc::exception& e ) {
|
||||||
|
BOOST_TEST_MESSAGE("SON cli wallet tests exception");
|
||||||
|
edump((e.to_detail_string()));
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
BOOST_TEST_MESSAGE("SON maintenance cli wallet tests end");
|
||||||
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_SUITE_END()
|
BOOST_AUTO_TEST_SUITE_END()
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -684,6 +684,19 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
||||||
GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0), fc::exception);
|
GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0), fc::exception);
|
||||||
trx.clear();
|
trx.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
// Try to go in maintenance for an inactive SON
|
||||||
|
son_maintenance_operation op;
|
||||||
|
op.owner_account = alice_id;
|
||||||
|
op.son_id = son_id_type(0);
|
||||||
|
|
||||||
|
trx.operations.push_back(op);
|
||||||
|
sign(trx, alice_private_key);
|
||||||
|
// Expect an exception
|
||||||
|
GRAPHENE_REQUIRE_THROW(PUSH_TX( db, trx, ~0), fc::exception);
|
||||||
|
trx.clear();
|
||||||
|
}
|
||||||
generate_block();
|
generate_block();
|
||||||
|
|
||||||
const auto& idx = db.get_index_type<son_index>().indices().get<by_account>();
|
const auto& idx = db.get_index_type<son_index>().indices().get<by_account>();
|
||||||
|
|
@ -696,17 +709,32 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) {
|
||||||
auto son_stats_obj = sidx.find( obj->statistics );
|
auto son_stats_obj = sidx.find( obj->statistics );
|
||||||
BOOST_REQUIRE( son_stats_obj != sidx.end() );
|
BOOST_REQUIRE( son_stats_obj != sidx.end() );
|
||||||
|
|
||||||
// Modify SON's status to in_maintenance
|
// Modify SON's status to active
|
||||||
db.modify( *obj, [&]( son_object& _s)
|
db.modify( *obj, [&]( son_object& _s)
|
||||||
{
|
{
|
||||||
_s.status = son_status::in_maintenance;
|
_s.status = son_status::active;
|
||||||
});
|
});
|
||||||
|
|
||||||
db.modify( *son_stats_obj, [&]( son_statistics_object& _s)
|
db.modify( *son_stats_obj, [&]( son_statistics_object& _s)
|
||||||
{
|
{
|
||||||
_s.last_down_timestamp = fc::time_point_sec(db.head_block_time() - fc::hours(1));
|
_s.last_down_timestamp = fc::time_point_sec(db.head_block_time());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
{
|
||||||
|
generate_block();
|
||||||
|
// Put SON in maintenance
|
||||||
|
son_maintenance_operation op;
|
||||||
|
op.owner_account = alice_id;
|
||||||
|
op.son_id = son_id_type(0);
|
||||||
|
|
||||||
|
trx.operations.push_back(op);
|
||||||
|
sign(trx, alice_private_key);
|
||||||
|
PUSH_TX( db, trx, ~0);
|
||||||
|
generate_block();
|
||||||
|
trx.clear();
|
||||||
|
BOOST_CHECK( obj->status == son_status::in_maintenance);
|
||||||
|
}
|
||||||
|
|
||||||
uint64_t downtime = 0;
|
uint64_t downtime = 0;
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue