From 84c9ea1a530e6641072b94f607096fe0fdd2eb1c Mon Sep 17 00:00:00 2001 From: Srdjan Obucina Date: Fri, 20 Mar 2020 23:04:08 +0100 Subject: [PATCH] Refactor multiple SON support processing --- .../peerplays_sidechain_plugin.hpp | 5 +- .../peerplays_sidechain_plugin.cpp | 219 ++++++++++-------- .../sidechain_net_handler.cpp | 4 +- .../sidechain_net_handler_bitcoin.cpp | 6 +- 4 files changed, 133 insertions(+), 101 deletions(-) diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp index be01c33f..c69efaf4 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/peerplays_sidechain_plugin.hpp @@ -27,8 +27,9 @@ public: std::unique_ptr my; std::set &get_sons(); - son_id_type &get_current_son_id(); - son_object get_son_object(son_id_type son_id); + const son_id_type get_current_son_id(); + const son_object get_current_son_object(); + const son_object get_son_object(son_id_type son_id); bool is_active_son(son_id_type son_id); fc::ecc::private_key get_private_key(son_id_type son_id); fc::ecc::private_key get_private_key(chain::public_key_type public_key); diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 4d54eb99..c7103754 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -33,8 +33,9 @@ public: void plugin_startup(); std::set &get_sons(); - son_id_type &get_current_son_id(); - son_object get_son_object(son_id_type son_id); + const son_id_type get_current_son_id(); + const son_object get_current_son_object(); + const son_object get_son_object(son_id_type son_id); bool is_active_son(son_id_type son_id); fc::ecc::private_key get_private_key(son_id_type son_id); fc::ecc::private_key get_private_key(chain::public_key_type public_key); @@ -226,11 +227,15 @@ std::set &peerplays_sidechain_plugin_impl::get_sons() { return sons; } -son_id_type &peerplays_sidechain_plugin_impl::get_current_son_id() { +const son_id_type peerplays_sidechain_plugin_impl::get_current_son_id() { return current_son_id; } -son_object peerplays_sidechain_plugin_impl::get_son_object(son_id_type son_id) { +const son_object peerplays_sidechain_plugin_impl::get_current_son_object() { + return get_son_object(current_son_id); +} + +const son_object peerplays_sidechain_plugin_impl::get_son_object(son_id_type son_id) { const auto &idx = plugin.database().get_index_type().indices().get(); auto son_obj = idx.find(son_id); if (son_obj == idx.end()) @@ -289,7 +294,7 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() { for (son_id_type son_id : sons) { if (is_active_son(son_id) || get_son_object(son_id).status == chain::son_status::in_maintenance) { - ilog("peerplays_sidechain_plugin: sending heartbeat for SON ${son}", ("son", son_id)); + ilog("Sending heartbeat for SON ${son}", ("son", son_id)); chain::son_heartbeat_operation op; op.owner_account = get_son_object(son_id).son_account; op.son_id = son_id; @@ -302,7 +307,7 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() { plugin.app().p2p_node()->broadcast(net::trx_message(trx)); return true; } catch (fc::exception e) { - ilog("peerplays_sidechain_plugin_impl: sending heartbeat failed with exception ${e}", ("e", e.what())); + elog("Sending heartbeat failed with exception ${e}", ("e", e.what())); return false; } }); @@ -328,38 +333,63 @@ void peerplays_sidechain_plugin_impl::son_processing() { return; } - chain::son_id_type next_son_id = plugin.database().get_scheduled_son(1); - ilog("peerplays_sidechain_plugin_impl: Scheduled SON ${son}", ("son", next_son_id)); - - // Tasks that are executed by all active SONs, no matter if scheduled - // E.g. sending approvals and signing - approve_proposals(); - - // Tasks that are executed by scheduled and active SON - if (sons.find(next_son_id) != sons.end()) { - - current_son_id = next_son_id; - - create_son_down_proposals(); - - create_son_deregister_proposals(); - - recreate_primary_wallet(); - - process_deposits(); - - process_withdrawals(); - - process_sidechain_transactions(); - - send_sidechain_transactions(); + fc::time_point now_fine = fc::time_point::now(); + fc::time_point_sec now = now_fine + fc::microseconds(500000); + if (plugin.database().get_slot_time(1) < now) { + return; // Not synced } -} + + uint32_t slot = 1; //plugin.database().get_slot_at_time(now); + if (slot == 0) { + return; // Not time yet + } + + //assert(now > plugin.database().head_block_time()); + + chain::son_id_type scheduled_son_id = plugin.database().get_scheduled_son(slot); + fc::time_point_sec scheduled_time = plugin.database().get_slot_time(slot); + ilog("Slot: ${slot} Scheduled SON: ${scheduled_son_id} Scheduled time: ${scheduled_time} Now: ${now} ", + ("slot", slot)("scheduled_son_id", scheduled_son_id)("scheduled_time", scheduled_time)("now", now)); + + for (son_id_type son_id : plugin.get_sons()) { + + if (plugin.is_active_son(son_id)) { + + current_son_id = son_id; + + // Tasks that are executed by all active SONs, no matter if scheduled + // E.g. sending approvals and signing + approve_proposals(); + process_sidechain_transactions(); + + // Tasks that are executed by scheduled and active SON + if (current_son_id == scheduled_son_id) { + + create_son_down_proposals(); + + create_son_deregister_proposals(); + + recreate_primary_wallet(); + + process_deposits(); + + process_withdrawals(); + + send_sidechain_transactions(); + } + } else { + // Tasks that are executed by previously active SONs + // E.g. sending approvals and signing that SON was required to do while it was active + //approve_leftover_proposals(); ??? + //process_leftover_sidechain_transactions(); ??? + } + } +} // namespace detail void peerplays_sidechain_plugin_impl::approve_proposals() { auto approve_proposal = [&](const chain::son_id_type &son_id, const chain::proposal_id_type &proposal_id) { - ilog("peerplays_sidechain_plugin: sending approval for ${p} from ${s}", ("p", proposal_id)("s", son_id)); + ilog("Sending approval for ${p} from ${s}", ("p", proposal_id)("s", son_id)); chain::proposal_update_operation puo; puo.fee_paying_account = get_son_object(son_id).son_account; puo.proposal = proposal_id; @@ -372,7 +402,7 @@ void peerplays_sidechain_plugin_impl::approve_proposals() { plugin.app().p2p_node()->broadcast(net::trx_message(trx)); return true; } catch (fc::exception e) { - ilog("peerplays_sidechain_plugin_impl: sending approval failed with exception ${e}", ("e", e.what())); + elog("Sending approval failed with exception ${e}", ("e", e.what())); return false; } }); @@ -386,59 +416,54 @@ void peerplays_sidechain_plugin_impl::approve_proposals() { } for (const auto proposal_id : proposals) { - for (son_id_type son_id : sons) { - if (!is_active_son(son_id)) { - continue; - } - const object *obj = plugin.database().find_object(proposal_id); - const chain::proposal_object *proposal_ptr = dynamic_cast(obj); - if (proposal_ptr == nullptr) { - continue; - } - const proposal_object proposal = *proposal_ptr; - - if (proposal.available_active_approvals.find(get_son_object(son_id).son_account) != proposal.available_active_approvals.end()) { - continue; - } - - if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { - approve_proposal(son_id, proposal.id); - continue; - } - - if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { - approve_proposal(son_id, proposal.id); - continue; - } - - if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { - approve_proposal(son_id, proposal.id); - continue; - } - - if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { - approve_proposal(son_id, proposal.id); - continue; - } - - if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { - approve_proposal(son_id, proposal.id); - continue; - } - - if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { - approve_proposal(son_id, proposal.id); - continue; - } - - if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { - approve_proposal(son_id, proposal.id); - continue; - } - - approve_proposal(son_id, proposal.id); + const object *obj = plugin.database().find_object(proposal_id); + const chain::proposal_object *proposal_ptr = dynamic_cast(obj); + if (proposal_ptr == nullptr) { + continue; } + const proposal_object proposal = *proposal_ptr; + + if (proposal.available_active_approvals.find(get_current_son_object().son_account) != proposal.available_active_approvals.end()) { + continue; + } + + if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal(get_current_son_id(), proposal.id); + continue; + } + + if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal(get_current_son_id(), proposal.id); + continue; + } + + if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal(get_current_son_id(), proposal.id); + continue; + } + + if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal(get_current_son_id(), proposal.id); + continue; + } + + if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal(get_current_son_id(), proposal.id); + continue; + } + + if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal(get_current_son_id(), proposal.id); + continue; + } + + if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal(get_current_son_id(), proposal.id); + continue; + } + + approve_proposal(get_current_son_id(), proposal.id); } } @@ -477,7 +502,7 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() { 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))) { - 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)))); + 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); fc::future fut = fc::async([&]() { @@ -487,7 +512,7 @@ void peerplays_sidechain_plugin_impl::create_son_down_proposals() { plugin.app().p2p_node()->broadcast(net::trx_message(trx)); return true; } catch (fc::exception e) { - ilog("peerplays_sidechain_plugin_impl: sending son down proposal failed with exception ${e}", ("e", e.what())); + elog("Sending son down proposal failed with exception ${e}", ("e", e.what())); return false; } }); @@ -512,7 +537,7 @@ void peerplays_sidechain_plugin_impl::create_son_deregister_proposals() { auto op = d.create_son_deregister_proposal(son, get_son_object(my_son_id).son_account); if (op.valid()) { // Signing and pushing into the txs to be included in the block - ilog("peerplays_sidechain_plugin: sending son deregister proposal for ${p} from ${s}", ("p", son)("s", my_son_id)); + ilog("Sending son deregister proposal for ${p} from ${s}", ("p", son)("s", my_son_id)); chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(get_son_object(my_son_id).signing_key), *op); fc::future fut = fc::async([&]() { try { @@ -521,7 +546,7 @@ void peerplays_sidechain_plugin_impl::create_son_deregister_proposals() { plugin.app().p2p_node()->broadcast(net::trx_message(trx)); return true; } catch (fc::exception e) { - ilog("peerplays_sidechain_plugin_impl: sending son dereg proposal failed with exception ${e}", ("e", e.what())); + elog("Sending son deregister proposal failed with exception ${e}", ("e", e.what())); return false; } }); @@ -560,7 +585,7 @@ void peerplays_sidechain_plugin_impl::on_applied_block(const signed_block &b) { } } -} // end namespace detail +} // namespace detail peerplays_sidechain_plugin::peerplays_sidechain_plugin() : my(new detail::peerplays_sidechain_plugin_impl(*this)) { @@ -581,24 +606,30 @@ void peerplays_sidechain_plugin::plugin_set_program_options( } void peerplays_sidechain_plugin::plugin_initialize(const boost::program_options::variables_map &options) { - ilog("peerplays sidechain plugin: plugin_initialize()"); + ilog("peerplays sidechain plugin: plugin_initialize() begin"); my->plugin_initialize(options); + ilog("peerplays sidechain plugin: plugin_initialize() end"); } void peerplays_sidechain_plugin::plugin_startup() { - ilog("peerplays sidechain plugin: plugin_startup()"); + ilog("peerplays sidechain plugin: plugin_startup() begin"); my->plugin_startup(); + ilog("peerplays sidechain plugin: plugin_startup() end"); } std::set &peerplays_sidechain_plugin::get_sons() { return my->get_sons(); } -son_id_type &peerplays_sidechain_plugin::get_current_son_id() { +const son_id_type peerplays_sidechain_plugin::get_current_son_id() { return my->get_current_son_id(); } -son_object peerplays_sidechain_plugin::get_son_object(son_id_type son_id) { +const son_object peerplays_sidechain_plugin::get_current_son_object() { + return my->get_current_son_object(); +} + +const son_object peerplays_sidechain_plugin::get_son_object(son_id_type son_id) { return my->get_son_object(son_id); } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index 2e9eacab..a9606093 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -269,8 +269,6 @@ void sidechain_net_handler::process_sidechain_transactions() { const auto &idx_range = idx.equal_range(std::make_tuple(sidechain, false)); std::for_each(idx_range.first, idx_range.second, [&](const sidechain_transaction_object &sto) { - ilog("Sidechain transaction to process: ${sto}", ("sto", sto)); - son_id_type invalid_signer = son_id_type(0xFFFFFFFF); son_id_type next_signer = invalid_signer; for (auto &signer : sto.signers) { @@ -281,6 +279,8 @@ void sidechain_net_handler::process_sidechain_transactions() { } if ((next_signer != invalid_signer) && (next_signer == plugin.get_current_son_id())) { + ilog("Sidechain transaction to process: ${sto}", ("sto", sto)); + bool complete = false; std::string processed_sidechain_tx = process_sidechain_transaction(sto, complete); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index 1466b0ac..f8c16023 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -660,10 +660,10 @@ fc::http::reply bitcoin_rpc_client::send_post_request(std::string body, bool sho show_log = true; // Log all requests temporary if (show_log) { - ilog(" ### Request URL: ${url} ###", ("url", url)); - ilog(" ### Request: ${body} ###", ("body", body)); + ilog("### Request URL: ${url}", ("url", url)); + ilog("### Request: ${body}", ("body", body)); std::stringstream ss(std::string(reply.body.begin(), reply.body.end())); - ilog(" ### Response: ${ss} ###", ("ss", ss.str())); + ilog("### Response: ${ss}", ("ss", ss.str())); } return reply;