From 69cad0f1bdbce31958a75a035f62d7c4667ca41d Mon Sep 17 00:00:00 2001 From: Srdjan Obucina Date: Fri, 7 Feb 2020 21:38:30 +0100 Subject: [PATCH] Add is_active_son guards, fix sending proposals and aprovals --- libraries/chain/db_init.cpp | 1 + .../chain/son_wallet_transfer_object.hpp | 3 +- .../chain/son_wallet_transfer_evaluator.cpp | 44 +++++---- .../peerplays_sidechain_plugin.hpp | 4 +- .../peerplays_sidechain_plugin.cpp | 91 +++++++++++-------- .../sidechain_net_handler.cpp | 29 +++--- .../sidechain_net_handler_bitcoin.cpp | 8 +- .../sidechain_net_manager.cpp | 3 - 8 files changed, 100 insertions(+), 83 deletions(-) diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 3d53fce0..af9929ec 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -259,6 +259,7 @@ void database::initialize_evaluators() register_evaluator(); register_evaluator(); register_evaluator(); + register_evaluator(); register_evaluator(); register_evaluator(); register_evaluator(); diff --git a/libraries/chain/include/graphene/chain/son_wallet_transfer_object.hpp b/libraries/chain/include/graphene/chain/son_wallet_transfer_object.hpp index 05497442..d5300588 100644 --- a/libraries/chain/include/graphene/chain/son_wallet_transfer_object.hpp +++ b/libraries/chain/include/graphene/chain/son_wallet_transfer_object.hpp @@ -18,6 +18,7 @@ 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; @@ -60,7 +61,7 @@ namespace graphene { namespace chain { } } // graphene::chain FC_REFLECT_DERIVED( graphene::chain::son_wallet_transfer_object, (graphene::db::object), - (timestamp) (sidechain) + (timestamp) (sidechain) (confirmations) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_amount) (peerplays_from) (peerplays_to) (processed) ) diff --git a/libraries/chain/son_wallet_transfer_evaluator.cpp b/libraries/chain/son_wallet_transfer_evaluator.cpp index 5a447569..c5e9e5a1 100644 --- a/libraries/chain/son_wallet_transfer_evaluator.cpp +++ b/libraries/chain/son_wallet_transfer_evaluator.cpp @@ -11,26 +11,36 @@ void_result create_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_t //FC_ASSERT(db().get_global_properties().parameters.get_son_btc_account_id() != GRAPHENE_NULL_ACCOUNT, "SON paying account not set."); FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id() ); - 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.sidechain_uid) == idx.end(), "Already registered " + op.sidechain_uid); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } object_id_type create_son_wallet_transfer_evaluator::do_apply(const son_wallet_transfer_create_operation& op) { try { - const auto& new_son_wallet_transfer_object = db().create( [&]( son_wallet_transfer_object& swto ){ - swto.timestamp = op.timestamp; - swto.sidechain = op.sidechain; - swto.sidechain_uid = op.sidechain_uid; - swto.sidechain_transaction_id = op.sidechain_transaction_id; - swto.sidechain_from = op.sidechain_from; - swto.sidechain_to = op.sidechain_to; - swto.sidechain_amount = op.sidechain_amount; - swto.peerplays_from = op.peerplays_from; - swto.peerplays_to = op.peerplays_to; - swto.processed = false; - }); - return new_son_wallet_transfer_object.id; + const auto& idx = db().get_index_type().indices().get(); + auto itr = idx.find(op.sidechain_uid); + if (itr == idx.end()) { + const auto& new_son_wallet_transfer_object = db().create( [&]( son_wallet_transfer_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; + swto.sidechain_to = op.sidechain_to; + swto.sidechain_amount = op.sidechain_amount; + swto.peerplays_from = op.peerplays_from; + swto.peerplays_to = op.peerplays_to; + swto.processed = false; + }); + return new_son_wallet_transfer_object.id; + } else { + db().modify(*itr, [&op](son_wallet_transfer_object &swto) { + swto.confirmations = swto.confirmations + 1; + }); + return (*itr).id; + } } FC_CAPTURE_AND_RETHROW( (op) ) } void_result process_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_transfer_process_operation& op) @@ -40,7 +50,9 @@ void_result process_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_ FC_ASSERT( op.payer == db().get_global_properties().parameters.get_son_btc_account_id() ); const auto& idx = db().get_index_type().indices().get(); - FC_ASSERT(idx.find(op.son_wallet_transfer_id) != idx.end(), "Son wallet transfer not found"); + const auto& itr = idx.find(op.son_wallet_transfer_id); + FC_ASSERT(itr != idx.end(), "Son wallet transfer not found"); + FC_ASSERT(itr->processed == false, "Son wallet transfer is already processed"); return void_result(); } FC_CAPTURE_AND_RETHROW( (op) ) } 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 594df249..e9a868f1 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,11 +27,11 @@ class peerplays_sidechain_plugin : public graphene::app::plugin std::unique_ptr my; - //son_id_type get_son_id(); + std::set& get_sons(); son_object get_son_object(son_id_type son_id); bool is_active_son(son_id_type son_id); - std::set& get_sons(); std::map& get_private_keys(); + 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 f7c24754..081d5090 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -34,11 +34,11 @@ class peerplays_sidechain_plugin_impl void plugin_initialize(const boost::program_options::variables_map& options); void plugin_startup(); - //son_id_type get_son_id(); + std::set& get_sons(); son_object get_son_object(son_id_type son_id); bool is_active_son(son_id_type son_id); - std::set& get_sons(); std::map& get_private_keys(); + 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); void schedule_heartbeat_loop(); @@ -198,10 +198,10 @@ void peerplays_sidechain_plugin_impl::plugin_startup() //} } -//son_id_type peerplays_sidechain_plugin_impl::get_son_id() -//{ -// return *(_sons.begin()); -//} +std::set& peerplays_sidechain_plugin_impl::get_sons() +{ + return _sons; +} son_object peerplays_sidechain_plugin_impl::get_son_object(son_id_type son_id) { @@ -233,16 +233,16 @@ bool peerplays_sidechain_plugin_impl::is_active_son(son_id_type son_id) return (it != active_son_ids.end()); } -std::set& peerplays_sidechain_plugin_impl::get_sons() -{ - return _sons; -} - std::map& peerplays_sidechain_plugin_impl::get_private_keys() { return _private_keys; } +fc::ecc::private_key peerplays_sidechain_plugin_impl::get_private_key(son_id_type son_id) +{ + return get_private_key(get_son_object(son_id).signing_key); +} + fc::ecc::private_key peerplays_sidechain_plugin_impl::get_private_key(chain::public_key_type public_key) { auto private_key_itr = _private_keys.find( public_key ); @@ -276,7 +276,7 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() op.owner_account = get_son_object(son_id).son_account; op.son_id = son_id; op.ts = fc::time_point::now() + fc::seconds(0); - chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(plugin.get_son_object(son_id).signing_key), op); + chain::signed_transaction trx = d.create_signed_transaction(plugin.get_private_key(son_id), op); fc::future fut = fc::async( [&](){ try { d.push_transaction(trx); @@ -372,23 +372,31 @@ void peerplays_sidechain_plugin_impl::process_deposits() { const chain::global_property_object& gpo = plugin.database().get_global_properties(); - transfer_operation op; - op.from = pay_from; - op.to = swto.peerplays_from; - op.amount = asset(swto.sidechain_amount); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market + son_wallet_transfer_process_operation p_op; + p_op.payer = gpo.parameters.get_son_btc_account_id(); + p_op.son_wallet_transfer_id = swto.id; + + //transfer_operation t_op; + //t_op.from = pay_from; + //t_op.to = swto.peerplays_from; + //t_op.amount = asset(swto.sidechain_amount); // For Bitcoin, the exchange rate is 1:1, for others, get the exchange rate from market for (son_id_type son_id : plugin.get_sons()) { - proposal_create_operation proposal_op; - proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; - proposal_op.proposed_ops.push_back( op_wrapper( op ) ); - uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; - proposal_op.expiration_time = time_point_sec( plugin.database().head_block_time().sec_since_epoch() + lifetime ); + if (plugin.is_active_son(son_id)) { + proposal_create_operation proposal_op; + proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; + proposal_op.proposed_ops.push_back( op_wrapper( p_op ) ); + //proposal_op.proposed_ops.push_back( op_wrapper( t_op ) ); + uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; + proposal_op.expiration_time = time_point_sec( plugin.database().head_block_time().sec_since_epoch() + lifetime ); - signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(plugin.get_son_object(son_id).signing_key), proposal_op); - try { - plugin.database().push_transaction(trx); - } catch(fc::exception e){ - ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what())); + ilog("sidechain_net_handler: sending proposal for transfer operation ${swto} by ${son}", ("swto", swto.id) ("son", son_id)); + signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op); + try { + plugin.database().push_transaction(trx); + } catch(fc::exception e){ + ilog("sidechain_net_handler: sending proposal for transfer operation failed with exception ${e}",("e", e.what())); + } } } }); @@ -407,6 +415,7 @@ void peerplays_sidechain_plugin_impl::on_block_applied( const signed_block& b ) } chain::son_id_type next_son_id = d.get_scheduled_son(1); + ilog("peerplays_sidechain_plugin_impl: Scheduled SON ${son}",("son", next_son_id)); // check if we control scheduled SON if( _sons.find( next_son_id ) != _sons.end() ) { @@ -427,12 +436,12 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vector fut = fc::async( [&](){ try { plugin.database().push_transaction(trx); @@ -472,7 +481,13 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vectorproposed_transaction.operations.size() == 1 - && proposal->proposed_transaction.operations[0].which() == chain::operation::tag::value) { + && proposal->proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal( son_id, proposal->id ); + } + + if(proposal->proposed_transaction.operations.size() == 1 + && proposal->proposed_transaction.operations[0].which() == chain::operation::tag::value + /*&& proposal->proposed_transaction.operations[1].which() == chain::operation::tag::value*/) { approve_proposal( son_id, proposal->id ); } } @@ -517,10 +532,10 @@ void peerplays_sidechain_plugin::plugin_startup() my->plugin_startup(); } -//son_id_type peerplays_sidechain_plugin::get_son_id() -//{ -// return my->get_son_id(); -//} +std::set& peerplays_sidechain_plugin::get_sons() +{ + return my->get_sons(); +} son_object peerplays_sidechain_plugin::get_son_object(son_id_type son_id) { @@ -532,16 +547,16 @@ bool peerplays_sidechain_plugin::is_active_son(son_id_type son_id) return my->is_active_son(son_id); } -std::set& peerplays_sidechain_plugin::get_sons() -{ - return my->get_sons(); -} - std::map& peerplays_sidechain_plugin::get_private_keys() { return my->get_private_keys(); } +fc::ecc::private_key peerplays_sidechain_plugin::get_private_key(son_id_type son_id) +{ + return my->get_private_key(son_id); +} + fc::ecc::private_key peerplays_sidechain_plugin::get_private_key(chain::public_key_type public_key) { return my->get_private_key(public_key); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index d3b3a425..16750bf4 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -42,7 +42,6 @@ std::vector sidechain_net_handler::get_sidechain_addresses() { } void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_data& sed) { - ilog( __FUNCTION__ ); ilog( "sidechain_event_data:" ); ilog( " timestamp: ${timestamp}", ( "timestamp", sed.timestamp ) ); ilog( " sidechain: ${sidechain}", ( "sidechain", sed.sidechain ) ); @@ -54,11 +53,6 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_ ilog( " peerplays_from: ${peerplays_from}", ( "peerplays_from", sed.peerplays_from ) ); ilog( " peerplays_to: ${peerplays_to}", ( "peerplays_to", sed.peerplays_to ) ); - if (!plugin.is_active_son()) { - ilog( " !!! SON is not active and not processing sidechain events..."); - return; - } - const chain::global_property_object& gpo = database.get_global_properties(); son_wallet_transfer_create_operation op; @@ -74,17 +68,20 @@ void sidechain_net_handler::sidechain_event_data_received(const sidechain_event_ op.peerplays_to = sed.peerplays_to; for (son_id_type son_id : plugin.get_sons()) { - proposal_create_operation proposal_op; - proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; - proposal_op.proposed_ops.push_back( op_wrapper( op ) ); - uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; - proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime ); + if (plugin.is_active_son(son_id)) { + proposal_create_operation proposal_op; + proposal_op.fee_paying_account = plugin.get_son_object(son_id).son_account; + proposal_op.proposed_ops.push_back( op_wrapper( op ) ); + uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; + proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime ); - signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(plugin.get_son_object(son_id).signing_key), proposal_op); - try { - database.push_transaction(trx); - } catch(fc::exception e){ - ilog("sidechain_net_handler: sending proposal for son wallet transfer create operation failed with exception ${e}",("e", e.what())); + ilog("sidechain_net_handler: sending proposal for son wallet transfer create operation by ${son}", ("son", son_id)); + signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_key(son_id), proposal_op); + try { + database.push_transaction(trx); + } catch(fc::exception e){ + ilog("sidechain_net_handler: sending proposal for son wallet transfer create operation by ${son} failed with exception ${e}", ("son", son_id) ("e", e.what())); + } } } } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index d4aa147e..0596f9fc 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -277,7 +277,6 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() { boost::property_tree::ptree pt; boost::property_tree::read_json( ss, pt ); if( pt.count( "error" ) && pt.get_child( "error" ).empty() ) { - ilog(__FUNCTION__); std::stringstream res; boost::property_tree::json_parser::write_json(res, pt.get_child("result")); @@ -295,7 +294,7 @@ void sidechain_net_handler_bitcoin::recreate_primary_wallet() { uint32_t lifetime = ( gpo.parameters.block_interval * gpo.active_witnesses.size() ) * 3; proposal_op.expiration_time = time_point_sec( database.head_block_time().sec_since_epoch() + lifetime ); - signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(plugin.get_son_object(son_id).signing_key), proposal_op); + signed_transaction trx = database.create_signed_transaction(plugin.get_private_key(son_id), proposal_op); try { database.push_transaction(trx); } catch(fc::exception e){ @@ -336,11 +335,6 @@ void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data ilog("peerplays sidechain plugin: sidechain_net_handler_bitcoin::handle_event"); ilog(" event_data: ${event_data}", ("event_data", event_data)); - if (!plugin.is_active_son()) { - ilog(" !!! SON is not active and not processing sidechain events..."); - return; - } - std::string block = bitcoin_client->receive_full_block( event_data ); if( block != "" ) { const auto& vins = extract_info_from_block( block ); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_manager.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_manager.cpp index e21af593..8b6f18c1 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_manager.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_manager.cpp @@ -10,15 +10,12 @@ sidechain_net_manager::sidechain_net_manager(peerplays_sidechain_plugin& _plugin plugin(_plugin), database(_plugin.database()) { - ilog(__FUNCTION__); } sidechain_net_manager::~sidechain_net_manager() { - ilog(__FUNCTION__); } bool sidechain_net_manager::create_handler(peerplays_sidechain::sidechain_type sidechain, const boost::program_options::variables_map& options) { - ilog(__FUNCTION__); bool ret_val = false;