From 2e8c07465551ab9c7cba880696fce90a5f01c13f Mon Sep 17 00:00:00 2001 From: satyakoneru Date: Fri, 6 Mar 2020 22:49:26 +1100 Subject: [PATCH] SON202 - Maintenance improvements (#303) --- .../include/graphene/chain/protocol/son.hpp | 10 ++++++++- libraries/chain/son_evaluator.cpp | 15 +++++++------ .../wallet/include/graphene/wallet/wallet.hpp | 8 +++---- libraries/wallet/wallet.cpp | 14 +++++++------ tests/cli/son.cpp | 6 +++--- tests/tests/son_operations_tests.cpp | 21 ++++++++++++++++++- 6 files changed, 53 insertions(+), 21 deletions(-) diff --git a/libraries/chain/include/graphene/chain/protocol/son.hpp b/libraries/chain/include/graphene/chain/protocol/son.hpp index dc11d5be..20353b91 100644 --- a/libraries/chain/include/graphene/chain/protocol/son.hpp +++ b/libraries/chain/include/graphene/chain/protocol/son.hpp @@ -77,6 +77,12 @@ namespace graphene { namespace chain { share_type calculate_fee(const fee_parameters_type& k)const { return 0; } }; + enum class son_maintenance_request_type + { + request_maintenance, + cancel_request_maintenance + }; + struct son_maintenance_operation : public base_operation { struct fee_parameters_type { uint64_t fee = 0; }; @@ -84,6 +90,7 @@ namespace graphene { namespace chain { asset fee; son_id_type son_id; account_id_type owner_account; + son_maintenance_request_type request_type = son_maintenance_request_type::request_maintenance; account_id_type fee_payer()const { return owner_account; } share_type calculate_fee(const fee_parameters_type& k)const { return 0; } @@ -108,5 +115,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)(son_id)(payer)(down_ts) ) +FC_REFLECT_ENUM( graphene::chain::son_maintenance_request_type, (request_maintenance)(cancel_request_maintenance) ) FC_REFLECT(graphene::chain::son_maintenance_operation::fee_parameters_type, (fee) ) -FC_REFLECT(graphene::chain::son_maintenance_operation, (fee)(son_id)(owner_account) ) +FC_REFLECT(graphene::chain::son_maintenance_operation, (fee)(son_id)(owner_account)(request_type) ) diff --git a/libraries/chain/son_evaluator.cpp b/libraries/chain/son_evaluator.cpp index f4a7548a..908c40d5 100644 --- a/libraries/chain/son_evaluator.cpp +++ b/libraries/chain/son_evaluator.cpp @@ -66,9 +66,6 @@ object_id_type update_son_evaluator::do_apply(const son_update_operation& op) void_result delete_son_evaluator::do_evaluate(const son_delete_operation& op) { try { FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON_HARDFORK"); // can be removed after HF date pass - // Get the current block witness signatory - witness_id_type wit_id = db().get_scheduled_witness(1); - const witness_object& current_witness = wit_id(db()); // Either owner can remove or consensus son account FC_ASSERT(op.payer == db().get(op.son_id).son_account || (db().is_son_dereg_valid(op.son_id) && op.payer == GRAPHENE_SON_ACCOUNT)); const auto& idx = db().get_index_type().indices().get(); @@ -204,7 +201,13 @@ void_result son_maintenance_evaluator::do_evaluate(const son_maintenance_operati auto itr = idx.find(op.son_id); FC_ASSERT( itr != idx.end() ); // 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"); + 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"); + } else { + FC_ASSERT(false, "Invalid maintenance operation"); + } return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -214,11 +217,11 @@ 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) { + 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) { + } 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; }); diff --git a/libraries/wallet/include/graphene/wallet/wallet.hpp b/libraries/wallet/include/graphene/wallet/wallet.hpp index 34fc1885..364fb20b 100644 --- a/libraries/wallet/include/graphene/wallet/wallet.hpp +++ b/libraries/wallet/include/graphene/wallet/wallet.hpp @@ -1356,7 +1356,7 @@ class wallet_api * @param broadcast true to broadcast the transaction on the network * @returns the signed transaction */ - signed_transaction start_son_maintenance(string owner_account, + signed_transaction request_son_maintenance(string owner_account, bool broadcast = false); /** Modify status of the SON owned by the given account back to active. @@ -1365,7 +1365,7 @@ class wallet_api * @param broadcast true to broadcast the transaction on the network * @returns the signed transaction */ - signed_transaction stop_son_maintenance(string owner_account, + signed_transaction cancel_request_son_maintenance(string owner_account, bool broadcast = false); /** Lists all SONs in the blockchain. @@ -2237,8 +2237,8 @@ FC_API( graphene::wallet::wallet_api, (delete_son) (list_sons) (list_active_sons) - (start_son_maintenance) - (stop_son_maintenance) + (request_son_maintenance) + (cancel_request_son_maintenance) (get_active_son_wallet) (get_son_wallet_by_time_point) (get_son_wallets) diff --git a/libraries/wallet/wallet.cpp b/libraries/wallet/wallet.cpp index 8af353e2..aca8c04f 100644 --- a/libraries/wallet/wallet.cpp +++ b/libraries/wallet/wallet.cpp @@ -1942,7 +1942,7 @@ public: return sign_transaction( tx, broadcast ); } FC_CAPTURE_AND_RETHROW( (owner_account)(broadcast) ) } - signed_transaction start_son_maintenance(string owner_account, + signed_transaction request_son_maintenance(string owner_account, bool broadcast) { try { son_object son = get_son(owner_account); @@ -1950,6 +1950,7 @@ public: son_maintenance_operation op; op.owner_account = son.son_account; op.son_id = son.id; + op.request_type = son_maintenance_request_type::request_maintenance; signed_transaction tx; tx.operations.push_back( op ); @@ -1959,7 +1960,7 @@ public: return sign_transaction( tx, broadcast ); } FC_CAPTURE_AND_RETHROW( (owner_account) ) } - signed_transaction stop_son_maintenance(string owner_account, + signed_transaction cancel_request_son_maintenance(string owner_account, bool broadcast) { try { son_object son = get_son(owner_account); @@ -1967,6 +1968,7 @@ public: son_maintenance_operation op; op.owner_account = son.son_account; op.son_id = son.id; + op.request_type = son_maintenance_request_type::cancel_request_maintenance; signed_transaction tx; tx.operations.push_back( op ); @@ -4463,14 +4465,14 @@ signed_transaction wallet_api::delete_son(string owner_account, return my->delete_son(owner_account, broadcast); } -signed_transaction wallet_api::start_son_maintenance(string owner_account, bool broadcast) +signed_transaction wallet_api::request_son_maintenance(string owner_account, bool broadcast) { - return my->start_son_maintenance(owner_account, broadcast); + return my->request_son_maintenance(owner_account, broadcast); } -signed_transaction wallet_api::stop_son_maintenance(string owner_account, bool broadcast) +signed_transaction wallet_api::cancel_request_son_maintenance(string owner_account, bool broadcast) { - return my->stop_son_maintenance(owner_account, broadcast); + return my->cancel_request_son_maintenance(owner_account, broadcast); } map wallet_api::list_sons(const string& lowerbound, uint32_t limit) diff --git a/tests/cli/son.cpp b/tests/cli/son.cpp index 7915c71e..3630000c 100644 --- a/tests/cli/son.cpp +++ b/tests/cli/son.cpp @@ -699,7 +699,7 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) BOOST_CHECK(son_obj.status == son_status::active); // put SON in maintenance mode - con.wallet_api_ptr->start_son_maintenance(name, true); + con.wallet_api_ptr->request_son_maintenance(name, true); BOOST_CHECK(generate_block()); // check SON is in request_maintenance @@ -707,7 +707,7 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) BOOST_CHECK(son_obj.status == son_status::request_maintenance); // restore SON activity - con.wallet_api_ptr->stop_son_maintenance(name, true); + con.wallet_api_ptr->cancel_request_son_maintenance(name, true); BOOST_CHECK(generate_block()); // check SON is active @@ -715,7 +715,7 @@ BOOST_AUTO_TEST_CASE( maintenance_test ) BOOST_CHECK(son_obj.status == son_status::active); // put SON in maintenance mode - con.wallet_api_ptr->start_son_maintenance(name, true); + con.wallet_api_ptr->request_son_maintenance(name, true); BOOST_CHECK(generate_block()); // check SON is in request_maintenance diff --git a/tests/tests/son_operations_tests.cpp b/tests/tests/son_operations_tests.cpp index 9f3c0937..48c52feb 100644 --- a/tests/tests/son_operations_tests.cpp +++ b/tests/tests/son_operations_tests.cpp @@ -553,6 +553,7 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { son_maintenance_operation op; op.owner_account = alice_id; op.son_id = son_id_type(0); + op.request_type = son_maintenance_request_type::request_maintenance; trx.operations.push_back(op); set_expiration(db, trx); @@ -586,10 +587,11 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { { generate_block(); - // Put SON in maintenance + // Request SON Maintenance son_maintenance_operation op; op.owner_account = alice_id; op.son_id = son_id_type(0); + op.request_type = son_maintenance_request_type::request_maintenance; trx.operations.push_back(op); set_expiration(db, trx); @@ -600,6 +602,23 @@ BOOST_AUTO_TEST_CASE( son_heartbeat_test ) { BOOST_CHECK( obj->status == son_status::request_maintenance); } + { + generate_block(); + // Cancel SON Maintenance request + son_maintenance_operation op; + op.owner_account = alice_id; + op.son_id = son_id_type(0); + op.request_type = son_maintenance_request_type::cancel_request_maintenance; + + trx.operations.push_back(op); + set_expiration(db, trx); + sign(trx, alice_private_key); + PUSH_TX( db, trx, ~0); + generate_block(); + trx.clear(); + BOOST_CHECK( obj->status == son_status::active); + } + // Modify SON's status to in_maintenance db.modify( *obj, [&]( son_object& _s) {