From cc7b47cf0f460f12dc34321910220fd068c89467 Mon Sep 17 00:00:00 2001 From: sierra19XX <15652887+sierra19XX@users.noreply.github.com> Date: Sat, 14 Mar 2020 11:08:45 +1100 Subject: [PATCH 1/2] SON276 - Fix SON proposal exceptions - I (#307) Co-authored-by: satyakoneru <15652887+satyakoneru@users.noreply.github.com> --- libraries/chain/db_getter.cpp | 15 -- libraries/chain/db_maint.cpp | 208 +++++++++++------- libraries/chain/db_update.cpp | 46 ++++ .../chain/include/graphene/chain/database.hpp | 6 +- libraries/chain/son_evaluator.cpp | 4 +- 5 files changed, 177 insertions(+), 102 deletions(-) diff --git a/libraries/chain/db_getter.cpp b/libraries/chain/db_getter.cpp index 72e0327f..dfd59567 100644 --- a/libraries/chain/db_getter.cpp +++ b/libraries/chain/db_getter.cpp @@ -222,21 +222,6 @@ signed_transaction database::create_signed_transaction( const fc::ecc::private_k return processed_trx; } -void database::remove_son_proposal( const proposal_object& proposal ) -{ try { - if( proposal.proposed_transaction.operations.size() == 1 && - ( proposal.proposed_transaction.operations.back().which() == operation::tag::value || - proposal.proposed_transaction.operations.back().which() == operation::tag::value) ) - { - const auto& son_proposal_idx = get_index_type().indices().get(); - auto son_proposal_itr = son_proposal_idx.find( proposal.id ); - if( son_proposal_itr == son_proposal_idx.end() ) { - return; - } - remove( *son_proposal_itr ); - } -} FC_CAPTURE_AND_RETHROW( (proposal) ) } - bool database::is_son_dereg_valid( son_id_type son_id ) { const auto& son_idx = get_index_type().indices().get< by_id >(); diff --git a/libraries/chain/db_maint.cpp b/libraries/chain/db_maint.cpp index def394a8..96ef6853 100644 --- a/libraries/chain/db_maint.cpp +++ b/libraries/chain/db_maint.cpp @@ -180,6 +180,128 @@ void database::update_son_metrics() } } +void database::update_son_statuses(const vector& curr_active_sons, const vector& new_active_sons) +{ + vector current_sons, new_sons; + vector sons_to_remove, sons_to_add; + const auto& idx = get_index_type().indices().get(); + + current_sons.reserve(curr_active_sons.size()); + 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; + }); + + new_sons.reserve(new_active_sons.size()); + std::transform(new_active_sons.begin(), new_active_sons.end(), + std::inserter(new_sons, new_sons.end()), + [](const son_info &swi) { + return swi.son_id; + }); + + // find all cur_active_sons members that is not in new_active_sons + for_each(current_sons.begin(), current_sons.end(), + [&sons_to_remove, &new_sons](const son_id_type& si) + { + if(std::find(new_sons.begin(), new_sons.end(), si) == + new_sons.end()) + { + sons_to_remove.push_back(si); + } + } + ); + + for( const auto& sid : sons_to_remove ) + { + auto son = idx.find( sid ); + 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; + }); + } + } + + // find all new_active_sons members that is not in cur_active_sons + for_each(new_sons.begin(), new_sons.end(), + [&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(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& new_active_sons) +{ + bool should_recreate_pw = true; + + // Expire for current son_wallet_object wallet, if exists + const auto& idx_swi = get_index_type().indices().get(); + auto obj = idx_swi.rbegin(); + if (obj != idx_swi.rend()) { + // Compare current wallet SONs and to-be lists of active sons + auto cur_wallet_sons = (*obj).sons; + + bool wallet_son_sets_equal = (cur_wallet_sons.size() == new_active_sons.size()); + if (wallet_son_sets_equal) { + for( size_t i = 0; i < cur_wallet_sons.size(); i++ ) { + wallet_son_sets_equal = wallet_son_sets_equal && cur_wallet_sons.at(i) == new_active_sons.at(i); + } + } + + should_recreate_pw = !wallet_son_sets_equal; + + if (should_recreate_pw) { + modify(*obj, [&, obj](son_wallet_object &swo) { + swo.expires = head_block_time(); + }); + } + } + + if (should_recreate_pw) { + // Create new son_wallet_object, to initiate wallet recreation + create( [&]( son_wallet_object& obj ) { + obj.valid_from = head_block_time(); + obj.expires = time_point_sec::maximum(); + obj.sons.insert(obj.sons.end(), new_active_sons.begin(), new_active_sons.end()); + }); + } +} + void database::pay_workers( share_type& budget ) { // ilog("Processing payroll! Available budget is ${b}", ("b", budget)); @@ -496,90 +618,8 @@ void database::update_active_sons() } else { ilog( "Active SONs set CHANGED" ); - bool should_recreate_pw = true; - - // Expire for current son_wallet_object wallet, if exists - const auto& idx_swi = get_index_type().indices().get(); - auto obj = idx_swi.rbegin(); - if (obj != idx_swi.rend()) { - // Compare current wallet SONs and to-be lists of active sons - auto cur_wallet_sons = (*obj).sons; - - bool wallet_son_sets_equal = (cur_wallet_sons.size() == new_active_sons.size()); - if (wallet_son_sets_equal) { - for( size_t i = 0; i < cur_wallet_sons.size(); i++ ) { - wallet_son_sets_equal = wallet_son_sets_equal && cur_wallet_sons.at(i) == new_active_sons.at(i); - } - } - - should_recreate_pw = !wallet_son_sets_equal; - - if (should_recreate_pw) { - modify(*obj, [&, obj](son_wallet_object &swo) { - swo.expires = head_block_time(); - }); - } - } - - if (should_recreate_pw) { - // Create new son_wallet_object, to initiate wallet recreation - create( [&]( son_wallet_object& obj ) { - obj.valid_from = head_block_time(); - obj.expires = time_point_sec::maximum(); - obj.sons.insert(obj.sons.end(), new_active_sons.begin(), new_active_sons.end()); - }); - } - - vector 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().indices().get(); - 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 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; - }); - } - } + update_son_wallet(new_active_sons); + update_son_statuses(cur_active_sons, new_active_sons); } modify(gpo, [&]( global_property_object& gp ){ diff --git a/libraries/chain/db_update.cpp b/libraries/chain/db_update.cpp index b33e3819..ed440d82 100644 --- a/libraries/chain/db_update.cpp +++ b/libraries/chain/db_update.cpp @@ -652,4 +652,50 @@ void database::update_betting_markets(fc::time_point_sec current_block_time) remove_completed_events(); } +void database::remove_son_proposal( const proposal_object& proposal ) +{ try { + if( proposal.proposed_transaction.operations.size() == 1 && + ( proposal.proposed_transaction.operations.back().which() == operation::tag::value || + proposal.proposed_transaction.operations.back().which() == operation::tag::value) ) + { + const auto& son_proposal_idx = get_index_type().indices().get(); + auto son_proposal_itr = son_proposal_idx.find( proposal.id ); + if( son_proposal_itr == son_proposal_idx.end() ) { + return; + } + remove( *son_proposal_itr ); + } +} FC_CAPTURE_AND_RETHROW( (proposal) ) } + +void database::remove_inactive_son_down_proposals( const vector& son_ids_to_remove ) +{ + const auto& son_proposal_idx = get_index_type().indices().get< by_id >(); + std::vector proposals_to_remove; + + for( auto& son_proposal : son_proposal_idx ) + { + if(son_proposal.proposal_type == son_proposal_type::son_report_down_proposal) + { + auto it = std::find(son_ids_to_remove.begin(), son_ids_to_remove.end(), son_proposal.son_id); + if (it != son_ids_to_remove.end()) + { + ilog( "Removing inactive proposal ${p} for son ${s}", ("p", son_proposal.proposal_id) ("s",son_proposal.son_id)); + proposals_to_remove.push_back(son_proposal.proposal_id); + } + } + } + + for( auto& proposal_id : proposals_to_remove ) + { + const auto& proposal_obj = proposal_id(*this); + remove_son_proposal(proposal_obj); + remove(proposal_obj); + } +} + +void database::remove_inactive_son_proposals( const vector& son_ids_to_remove ) +{ + remove_inactive_son_down_proposals( son_ids_to_remove ); +} + } } diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index 5b8952df..4727bc1d 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -304,7 +304,6 @@ namespace graphene { namespace chain { std::set get_sons_to_be_deregistered(); fc::optional 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 ); - void remove_son_proposal( const proposal_object& proposal ); bool is_son_dereg_valid( son_id_type son_id ); time_point_sec head_block_time()const; @@ -549,6 +548,11 @@ namespace graphene { namespace chain { void update_active_committee_members(); void update_son_metrics(); void update_active_sons(); + void remove_son_proposal( const proposal_object& proposal ); + void remove_inactive_son_down_proposals( const vector& son_ids_to_remove ); + void remove_inactive_son_proposals( const vector& son_ids_to_remove ); + void update_son_statuses( const vector& cur_active_sons, const vector& new_active_sons ); + void update_son_wallet( const vector& new_active_sons ); void update_worker_votes(); template diff --git a/libraries/chain/son_evaluator.cpp b/libraries/chain/son_evaluator.cpp index 908c40d5..c95c717f 100644 --- a/libraries/chain/son_evaluator.cpp +++ b/libraries/chain/son_evaluator.cpp @@ -96,10 +96,10 @@ void_result delete_son_evaluator::do_apply(const son_delete_operation& op) void_result son_heartbeat_evaluator::do_evaluate(const son_heartbeat_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().indices().get(); - FC_ASSERT( idx.find(op.son_id) != idx.end() ); 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"); From ff7e1baaf130f08eaf1153aa4102dece7f9bea3e Mon Sep 17 00:00:00 2001 From: obucina <11353193+obucina@users.noreply.github.com> Date: Sat, 14 Mar 2020 11:44:39 +0100 Subject: [PATCH 2/2] Add SON statistic for tracking reported sidechain transactions (#308) - Deposit and Withdrawal object extended to contain expected and received transaction reports from SON network - SON statistic object extended to contain total number of sidechain transactions reported by SON network when SON was active and number of transactions reported by single SON when he was active - Code formatting --- .../chain/protocol/son_wallet_deposit.hpp | 3 +- .../chain/protocol/son_wallet_withdraw.hpp | 3 +- .../include/graphene/chain/son_object.hpp | 16 ++++++++-- .../chain/son_wallet_deposit_object.hpp | 7 +++-- .../chain/son_wallet_withdraw_object.hpp | 8 +++-- .../chain/son_wallet_deposit_evaluator.cpp | 31 ++++++++++++++++--- .../chain/son_wallet_withdraw_evaluator.cpp | 29 +++++++++++++++-- .../sidechain_net_handler.cpp | 8 +++++ .../sidechain_net_handler_bitcoin.cpp | 2 +- 9 files changed, 90 insertions(+), 17 deletions(-) diff --git a/libraries/chain/include/graphene/chain/protocol/son_wallet_deposit.hpp b/libraries/chain/include/graphene/chain/protocol/son_wallet_deposit.hpp index abcc4384..ddc1ff53 100644 --- a/libraries/chain/include/graphene/chain/protocol/son_wallet_deposit.hpp +++ b/libraries/chain/include/graphene/chain/protocol/son_wallet_deposit.hpp @@ -12,6 +12,7 @@ namespace graphene { namespace chain { asset fee; account_id_type payer; + son_id_type son_id; fc::time_point_sec timestamp; peerplays_sidechain::sidechain_type sidechain; std::string sidechain_uid; @@ -45,7 +46,7 @@ namespace graphene { namespace chain { FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation::fee_parameters_type, (fee) ) FC_REFLECT(graphene::chain::son_wallet_deposit_create_operation, (fee)(payer) - (timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount) (peerplays_from) (peerplays_to) (peerplays_asset)) + (son_id) (timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount) (peerplays_from) (peerplays_to) (peerplays_asset)) FC_REFLECT(graphene::chain::son_wallet_deposit_process_operation::fee_parameters_type, (fee) ) FC_REFLECT(graphene::chain::son_wallet_deposit_process_operation, (fee)(payer) (son_wallet_deposit_id)) diff --git a/libraries/chain/include/graphene/chain/protocol/son_wallet_withdraw.hpp b/libraries/chain/include/graphene/chain/protocol/son_wallet_withdraw.hpp index 99c263be..4e9d4971 100644 --- a/libraries/chain/include/graphene/chain/protocol/son_wallet_withdraw.hpp +++ b/libraries/chain/include/graphene/chain/protocol/son_wallet_withdraw.hpp @@ -12,6 +12,7 @@ namespace graphene { namespace chain { asset fee; account_id_type payer; + son_id_type son_id; fc::time_point_sec timestamp; peerplays_sidechain::sidechain_type sidechain; std::string peerplays_uid; @@ -44,7 +45,7 @@ namespace graphene { namespace chain { FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation::fee_parameters_type, (fee) ) FC_REFLECT(graphene::chain::son_wallet_withdraw_create_operation, (fee)(payer) - (timestamp) (sidechain) (peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset) (withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount) ) + (son_id) (timestamp) (sidechain) (peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset) (withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount) ) FC_REFLECT(graphene::chain::son_wallet_withdraw_process_operation::fee_parameters_type, (fee) ) FC_REFLECT(graphene::chain::son_wallet_withdraw_process_operation, (fee)(payer) (son_wallet_withdraw_id)) diff --git a/libraries/chain/include/graphene/chain/son_object.hpp b/libraries/chain/include/graphene/chain/son_object.hpp index 0d4a7317..ef479962 100644 --- a/libraries/chain/include/graphene/chain/son_object.hpp +++ b/libraries/chain/include/graphene/chain/son_object.hpp @@ -42,6 +42,10 @@ namespace graphene { namespace chain { fc::time_point_sec last_down_timestamp; // Last Active heartbeat timestamp fc::time_point_sec last_active_timestamp; + // Total sidechain transactions reported by SON network while SON was active + uint64_t total_sidechain_txs_reported = 0; + // Sidechain transactions reported by this SON + uint64_t sidechain_txs_reported = 0; }; /** @@ -87,14 +91,20 @@ namespace graphene { namespace chain { >; using son_index = generic_index; + struct by_owner; using son_stats_multi_index_type = multi_index_container< son_statistics_object, indexed_by< - ordered_unique< tag, member< object, object_id_type, &object::id > > + ordered_unique< tag, + member + >, + ordered_unique< tag, + member + > > >; - using son_stats_index = generic_index; + } } // graphene::chain FC_REFLECT_ENUM(graphene::chain::son_status, (inactive)(active)(request_maintenance)(in_maintenance)(deregistered) ) @@ -111,4 +121,6 @@ FC_REFLECT_DERIVED( graphene::chain::son_statistics_object, (current_interval_downtime) (last_down_timestamp) (last_active_timestamp) + (total_sidechain_txs_reported) + (sidechain_txs_reported) ) diff --git a/libraries/chain/include/graphene/chain/son_wallet_deposit_object.hpp b/libraries/chain/include/graphene/chain/son_wallet_deposit_object.hpp index 668af1d1..4c30cc49 100644 --- a/libraries/chain/include/graphene/chain/son_wallet_deposit_object.hpp +++ b/libraries/chain/include/graphene/chain/son_wallet_deposit_object.hpp @@ -18,7 +18,6 @@ namespace graphene { namespace chain { time_point_sec timestamp; peerplays_sidechain::sidechain_type sidechain; - int64_t confirmations; std::string sidechain_uid; std::string sidechain_transaction_id; std::string sidechain_from; @@ -29,6 +28,9 @@ namespace graphene { namespace chain { chain::account_id_type peerplays_to; chain::asset peerplays_asset; + std::set expected_reports; + std::set received_reports; + bool processed; }; @@ -63,7 +65,8 @@ namespace graphene { namespace chain { } } // graphene::chain FC_REFLECT_DERIVED( graphene::chain::son_wallet_deposit_object, (graphene::db::object), - (timestamp) (sidechain) (confirmations) + (timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_currency) (sidechain_amount) (peerplays_from) (peerplays_to) (peerplays_asset) + (expected_reports) (received_reports) (processed) ) diff --git a/libraries/chain/include/graphene/chain/son_wallet_withdraw_object.hpp b/libraries/chain/include/graphene/chain/son_wallet_withdraw_object.hpp index 68e870e0..71245ba7 100644 --- a/libraries/chain/include/graphene/chain/son_wallet_withdraw_object.hpp +++ b/libraries/chain/include/graphene/chain/son_wallet_withdraw_object.hpp @@ -18,7 +18,6 @@ namespace graphene { namespace chain { time_point_sec timestamp; peerplays_sidechain::sidechain_type sidechain; - int64_t confirmations; std::string peerplays_uid; std::string peerplays_transaction_id; chain::account_id_type peerplays_from; @@ -27,6 +26,10 @@ namespace graphene { namespace chain { std::string withdraw_address; std::string withdraw_currency; safe withdraw_amount; + + std::set expected_reports; + std::set received_reports; + bool processed; }; @@ -61,7 +64,8 @@ namespace graphene { namespace chain { } } // graphene::chain FC_REFLECT_DERIVED( graphene::chain::son_wallet_withdraw_object, (graphene::db::object), - (timestamp) (sidechain) (confirmations) + (timestamp) (sidechain) (peerplays_uid) (peerplays_transaction_id) (peerplays_from) (peerplays_asset) (withdraw_sidechain) (withdraw_address) (withdraw_currency) (withdraw_amount) + (expected_reports) (received_reports) (processed) ) diff --git a/libraries/chain/son_wallet_deposit_evaluator.cpp b/libraries/chain/son_wallet_deposit_evaluator.cpp index 839c5183..764f2c29 100644 --- a/libraries/chain/son_wallet_deposit_evaluator.cpp +++ b/libraries/chain/son_wallet_deposit_evaluator.cpp @@ -2,6 +2,7 @@ #include #include +#include #include namespace graphene { namespace chain { @@ -11,8 +12,9 @@ void_result create_son_wallet_deposit_evaluator::do_evaluate(const son_wallet_de FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); FC_ASSERT( op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer." ); - //const auto& idx = db().get_index_type().indices().get(); - //FC_ASSERT(idx.find(op.sidechain_uid) == idx.end(), "Already registered " + op.sidechain_uid); + const auto &idx = db().get_index_type().indices().get(); + FC_ASSERT(idx.find(op.son_id) != idx.end(), "Statistic object for a given SON ID does not exists"); + return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -24,7 +26,6 @@ object_id_type create_son_wallet_deposit_evaluator::do_apply(const son_wallet_de const auto& new_son_wallet_deposit_object = db().create( [&]( son_wallet_deposit_object& swto ){ swto.timestamp = op.timestamp; swto.sidechain = op.sidechain; - swto.confirmations = 1; swto.sidechain_uid = op.sidechain_uid; swto.sidechain_transaction_id = op.sidechain_transaction_id; swto.sidechain_from = op.sidechain_from; @@ -33,12 +34,32 @@ object_id_type create_son_wallet_deposit_evaluator::do_apply(const son_wallet_de swto.peerplays_from = op.peerplays_from; swto.peerplays_to = op.peerplays_to; swto.peerplays_asset = op.peerplays_asset; + + auto &gpo = db().get_global_properties(); + for (auto &si : gpo.active_sons) { + swto.expected_reports.insert(si.son_id); + + auto stats_itr = db().get_index_type().indices().get().find(si.son_id); + db().modify(*stats_itr, [&op, &si](son_statistics_object &sso) { + sso.total_sidechain_txs_reported = sso.total_sidechain_txs_reported + 1; + if (si.son_id == op.son_id) { + sso.sidechain_txs_reported = sso.sidechain_txs_reported + 1; + } + }); + } + + swto.received_reports.insert(op.son_id); + swto.processed = false; }); return new_son_wallet_deposit_object.id; } else { db().modify(*itr, [&op](son_wallet_deposit_object &swto) { - swto.confirmations = swto.confirmations + 1; + swto.received_reports.insert(op.son_id); + }); + auto stats_itr = db().get_index_type().indices().get().find(op.son_id); + db().modify(*stats_itr, [&op](son_statistics_object &sso) { + sso.sidechain_txs_reported = sso.sidechain_txs_reported + 1; }); return (*itr).id; } @@ -51,7 +72,7 @@ void_result process_son_wallet_deposit_evaluator::do_evaluate(const son_wallet_d const auto& idx = db().get_index_type().indices().get(); const auto& itr = idx.find(op.son_wallet_deposit_id); - FC_ASSERT(itr != idx.end(), "Son wallet transfer not found"); + FC_ASSERT(itr != idx.end(), "Son wallet deposit not found"); const database& d = db(); diff --git a/libraries/chain/son_wallet_withdraw_evaluator.cpp b/libraries/chain/son_wallet_withdraw_evaluator.cpp index baf9b06a..2185e808 100644 --- a/libraries/chain/son_wallet_withdraw_evaluator.cpp +++ b/libraries/chain/son_wallet_withdraw_evaluator.cpp @@ -2,6 +2,7 @@ #include #include +#include #include namespace graphene { namespace chain { @@ -11,6 +12,9 @@ void_result create_son_wallet_withdraw_evaluator::do_evaluate(const son_wallet_w FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); FC_ASSERT( op.payer == GRAPHENE_SON_ACCOUNT, "SON paying account must be set as payer." ); + const auto &idx = db().get_index_type().indices().get(); + FC_ASSERT(idx.find(op.son_id) != idx.end(), "Statistic object for a given SON ID does not exists"); + return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } @@ -22,7 +26,6 @@ object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_w const auto& new_son_wallet_withdraw_object = db().create( [&]( son_wallet_withdraw_object& swwo ){ swwo.timestamp = op.timestamp; swwo.sidechain = op.sidechain; - swwo.confirmations = 1; swwo.peerplays_uid = op.peerplays_uid; swwo.peerplays_transaction_id = op.peerplays_transaction_id; swwo.peerplays_from = op.peerplays_from; @@ -31,12 +34,32 @@ object_id_type create_son_wallet_withdraw_evaluator::do_apply(const son_wallet_w swwo.withdraw_address = op.withdraw_address; swwo.withdraw_currency = op.withdraw_currency; swwo.withdraw_amount = op.withdraw_amount; + + auto &gpo = db().get_global_properties(); + for (auto &si : gpo.active_sons) { + swwo.expected_reports.insert(si.son_id); + + auto stats_itr = db().get_index_type().indices().get().find(si.son_id); + db().modify(*stats_itr, [&op, &si](son_statistics_object &sso) { + sso.total_sidechain_txs_reported = sso.total_sidechain_txs_reported + 1; + if (si.son_id == op.son_id) { + sso.sidechain_txs_reported = sso.sidechain_txs_reported + 1; + } + }); + } + + swwo.received_reports.insert(op.son_id); + swwo.processed = false; }); return new_son_wallet_withdraw_object.id; } else { - db().modify(*itr, [&op](son_wallet_withdraw_object &swto) { - swto.confirmations = swto.confirmations + 1; + db().modify(*itr, [&op](son_wallet_withdraw_object &swwo) { + swwo.received_reports.insert(op.son_id); + }); + auto stats_itr = db().get_index_type().indices().get().find(op.son_id); + db().modify(*stats_itr, [&op](son_statistics_object &sso) { + sso.sidechain_txs_reported = sso.sidechain_txs_reported + 1; }); return (*itr).id; } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index 19188440..38dbf4f3 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -74,6 +74,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_ if ((sed.peerplays_to == GRAPHENE_SON_ACCOUNT) && (sed.sidechain_currency.compare("1.3.0") != 0)) { son_wallet_deposit_create_operation op; op.payer = GRAPHENE_SON_ACCOUNT; + //op.son_id = ; // to be filled for each son op.timestamp = sed.timestamp; op.sidechain = sed.sidechain; op.sidechain_uid = sed.sidechain_uid; @@ -88,6 +89,9 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_ for (son_id_type son_id : plugin.get_sons()) { if (plugin.is_active_son(son_id)) { + + op.son_id = son_id; + proposal_create_operation proposal_op; proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; proposal_op.proposed_ops.emplace_back(op_wrapper(op)); @@ -117,6 +121,7 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_ son_wallet_withdraw_create_operation op; op.payer = GRAPHENE_SON_ACCOUNT; + //op.son_id = ; // to be filled for each son op.timestamp = sed.timestamp; op.sidechain = sed.sidechain; op.peerplays_uid = sed.sidechain_uid; @@ -130,6 +135,9 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_ for (son_id_type son_id : plugin.get_sons()) { if (plugin.is_active_son(son_id)) { + + op.son_id = son_id; + proposal_create_operation proposal_op; proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; proposal_op.proposed_ops.emplace_back(op_wrapper(op)); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 1b1889bc..fc891054 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -549,7 +549,7 @@ void zmq_listener::handle_zmq() { const auto header = std::string(static_cast(msg[0].data()), msg[0].size()); const auto block_hash = boost::algorithm::hex(std::string(static_cast(msg[1].data()), msg[1].size())); event_received(block_hash); - } catch (zmq::error_t& e) { + } catch (zmq::error_t &e) { } } }