From 818acfabfafb4fc8ae6c2cf78aa87d20615d4ffd Mon Sep 17 00:00:00 2001 From: satyakoneru Date: Wed, 8 Jan 2020 13:19:14 +0000 Subject: [PATCH] SON212 - Add Sidechain Plugin Code to report SON Down --- .../peerplays_sidechain_plugin.cpp | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 0a6b4964..37458494 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -25,6 +25,8 @@ class peerplays_sidechain_plugin_impl void plugin_startup(); void schedule_heartbeat_loop(); void heartbeat_loop(); + chain::proposal_create_operation create_son_down_proposal(chain::son_id_type son_id, fc::time_point_sec last_active_ts); + void on_block_applied( const signed_block& b ); private: peerplays_sidechain_plugin& plugin; @@ -184,7 +186,7 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() const chain::global_property_object& gpo = d.get_global_properties(); auto it = std::find(gpo.active_sons.begin(), gpo.active_sons.end(), son_id); if(it != gpo.active_sons.end()) { - ilog("peerplays_sidechain_plugin: sending heartbeat"); + ilog("peerplays_sidechain_plugin_impl: sending heartbeat"); chain::son_heartbeat_operation op; const auto& idx = d.get_index_type().indices().get(); auto son_obj = idx.find( son_id ); @@ -198,7 +200,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: sending heartbeat failed with exception ${e}",("e", e.what())); + ilog("peerplays_sidechain_plugin_impl: sending heartbeat failed with exception ${e}",("e", e.what())); return false; } }); @@ -207,6 +209,64 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() schedule_heartbeat_loop(); } +chain::proposal_create_operation peerplays_sidechain_plugin_impl::create_son_down_proposal(chain::son_id_type son_id, fc::time_point_sec last_active_ts) +{ + chain::database& d = plugin.database(); + chain::son_id_type my_son_id = *(_sons.begin()); + const chain::global_property_object& gpo = d.get_global_properties(); + const auto& idx = d.get_index_type().indices().get(); + auto son_obj = idx.find( my_son_id ); + + chain::son_report_down_operation son_down_op; + son_down_op.payer = gpo.parameters.get_son_btc_account_id(); + son_down_op.son_id = son_id; + son_down_op.down_ts = last_active_ts; + + proposal_create_operation proposal_op; + proposal_op.fee_paying_account = son_obj->son_account; + proposal_op.proposed_ops.push_back( op_wrapper( son_down_op ) ); + uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; + proposal_op.expiration_time = time_point_sec( d.head_block_time().sec_since_epoch() + lifetime ); + return proposal_op; +} + +void peerplays_sidechain_plugin_impl::on_block_applied( const signed_block& b ) +{ + chain::database& d = plugin.database(); + chain::son_id_type my_son_id = *(_sons.begin()); + const chain::global_property_object& gpo = d.get_global_properties(); + // Return if there are no active SONs + if(gpo.active_sons.size() <= 0) { + return; + } + + chain::son_id_type next_son_id = d.get_scheduled_son(1); + if(next_son_id == my_son_id) { + const auto& idx = d.get_index_type().indices().get(); + for(auto son_id: gpo.active_sons) { + auto son_obj = idx.find( son_id ); + auto stats = son_obj->statistics(d); + fc::time_point_sec last_active_ts = stats.last_active_timestamp; + int64_t down_threshold = 2*180000000; + if((fc::time_point::now() - last_active_ts) > fc::microseconds(down_threshold)) { + chain::proposal_create_operation op = create_son_down_proposal(son_id, last_active_ts); + chain::signed_transaction trx = d.create_signed_transaction(_private_keys.begin()->second, op); + fc::future fut = fc::async( [&](){ + try { + d.push_transaction(trx); + 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())); + return false; + } + }); + fut.wait(fc::seconds(10)); + } + } + } +} + } // end namespace detail peerplays_sidechain_plugin::peerplays_sidechain_plugin() : @@ -236,6 +296,7 @@ void peerplays_sidechain_plugin::plugin_initialize(const boost::program_options: { ilog("peerplays sidechain plugin: plugin_initialize()"); my->plugin_initialize(options); + database().applied_block.connect( [&]( const signed_block& b){ my->on_block_applied(b); } ); } void peerplays_sidechain_plugin::plugin_startup()