From 116be75c32a908f980bb27c29c02585c900c0d67 Mon Sep 17 00:00:00 2001 From: obucinac Date: Tue, 11 Feb 2020 14:46:35 +0100 Subject: [PATCH] SON wallet transfer object and operations (#279) * Extend GPO.active_sons to contain votes and all public keys * Introduce son_wallet_object * son_wallet_object operations * son_wallet_object operations * son_wallet_object operations completed, basic tests added * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation * son_wallet_object API and cli wallet commands * Send RPC command to bitcoin node to recreate multisig wallet * Send RPC command to bitcoin node to recreate multisig wallet * Send RPC command to bitcoin node to recreate multisig wallet * Wallet recreation by scheduled SON only, some cosmetic refactoring * Wallet recreation by scheduled SON only, some cosmetic refactoring * Updating wallet info through operation instead through database.modify() for persistance * SON wallet transfer object and operations, for tracking assets deposit/withdrawal * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp Co-Authored-By: gladcow * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp Co-Authored-By: gladcow * Fix #include * SON wallet transfer object and operations, for tracking assets deposit/withdrawal * SON wallet transfer object and operations, for tracking assets deposit/withdrawal * Refactor primary wallet recreation * Refactor primary wallet recreation * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal * Quickfix for checking payer in evaluator * Quickfix for checking payer in evaluator * Fix failing son_wallet_tests - Check for son_btc_account is temporarely disabled * Remove redundant file * Squashed commit of the following: commit a688bb93ed4e16232a907aa8c76e240c83c771bf Author: obucinac Date: Tue Feb 4 19:31:45 2020 +0100 son_wallet_object operations and multisig wallet recreation by RPC (#263) * Extend GPO.active_sons to contain votes and all public keys * Introduce son_wallet_object * son_wallet_object operations * Create son_wallet_object on new set of SONs, to initiate primary wallet recreation * son_wallet_object API and cli wallet commands * Send RPC command to bitcoin node to recreate multisig wallet * Updating wallet info through operation instead through database.modify() for persistance * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp * Update libraries/chain/include/graphene/chain/protocol/son_wallet.hpp * Fix #include * Refactor primary wallet recreation * PW recreation refactoring, prevent duplicated recreations, update wallet address through proposal * Quickfix for checking payer in evaluator * Fix failing son_wallet_tests - Check for son_btc_account is temporarely disabled * Remove redundant file Co-authored-by: gladcow commit 6e61d6b055eb276757e426245a3a7c23a61b3854 Author: satyakoneru Date: Tue Feb 4 00:14:39 2020 +1100 SON233 - Provide correct downtime metrics to user (#278) * Remove duplicated item in CMakeLists.txt * Issue tokens to the user who deposited Bitcoin, WIP... * Add son_wallet_transfer_process_operation * Issue tokens to the user who deposited Bitcoin, WIP... * Add is_active_son guards for sidechain events processing Co-authored-by: gladcow --- libraries/app/impacted.cpp | 6 ++ libraries/chain/CMakeLists.txt | 1 + libraries/chain/db_init.cpp | 4 ++ libraries/chain/db_notify.cpp | 6 ++ .../graphene/chain/protocol/operations.hpp | 3 + .../chain/protocol/son_wallet_transfer.hpp | 47 +++++++++++++ .../include/graphene/chain/protocol/types.hpp | 5 ++ .../chain/son_wallet_transfer_evaluator.hpp | 24 +++++++ .../chain/son_wallet_transfer_object.hpp | 66 +++++++++++++++++++ .../chain/son_wallet_transfer_evaluator.cpp | 60 +++++++++++++++++ .../graphene/peerplays_sidechain/defs.hpp | 15 +++-- .../peerplays_sidechain_plugin.cpp | 43 +++++++++++- .../sidechain_net_handler.cpp | 46 +++++++++++-- .../sidechain_net_handler_bitcoin.cpp | 22 +++++-- programs/js_operation_serializer/main.cpp | 1 + 15 files changed, 335 insertions(+), 14 deletions(-) create mode 100644 libraries/chain/include/graphene/chain/protocol/son_wallet_transfer.hpp create mode 100644 libraries/chain/include/graphene/chain/son_wallet_transfer_evaluator.hpp create mode 100644 libraries/chain/include/graphene/chain/son_wallet_transfer_object.hpp create mode 100644 libraries/chain/son_wallet_transfer_evaluator.cpp diff --git a/libraries/app/impacted.cpp b/libraries/app/impacted.cpp index 6834fa51..d3e8eb8c 100644 --- a/libraries/app/impacted.cpp +++ b/libraries/app/impacted.cpp @@ -322,6 +322,12 @@ struct get_impacted_account_visitor void operator()( const son_wallet_update_operation& op ){ _impacted.insert( op.payer ); } + void operator()( const son_wallet_transfer_create_operation& op ){ + _impacted.insert( op.payer ); + } + void operator()( const son_wallet_transfer_process_operation& op ){ + _impacted.insert( op.payer ); + } void operator()( const sidechain_address_add_operation& op ){ _impacted.insert( op.sidechain_address_account ); } diff --git a/libraries/chain/CMakeLists.txt b/libraries/chain/CMakeLists.txt index b392bc5e..c7dd5375 100644 --- a/libraries/chain/CMakeLists.txt +++ b/libraries/chain/CMakeLists.txt @@ -118,6 +118,7 @@ add_library( graphene_chain son_object.cpp son_wallet_evaluator.cpp + son_wallet_transfer_evaluator.cpp sidechain_address_evaluator.cpp diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index c41aad87..3d53fce0 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -57,6 +57,7 @@ #include #include #include +#include #include #include @@ -81,6 +82,7 @@ #include #include #include +#include #include #include @@ -256,6 +258,7 @@ void database::initialize_evaluators() register_evaluator(); register_evaluator(); register_evaluator(); + register_evaluator(); register_evaluator(); register_evaluator(); register_evaluator(); @@ -304,6 +307,7 @@ void database::initialize_indexes() add_index< primary_index >(); add_index< primary_index >(); + add_index< primary_index >(); add_index< primary_index >(); diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index fbd3888d..299cd9d0 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -309,6 +309,12 @@ struct get_impacted_account_visitor void operator()( const son_wallet_update_operation& op ) { _impacted.insert( op.payer ); } + void operator()( const son_wallet_transfer_create_operation& op ) { + _impacted.insert( op.payer ); + } + void operator()( const son_wallet_transfer_process_operation& op ) { + _impacted.insert( op.payer ); + } void operator()( const sidechain_address_add_operation& op ) { _impacted.insert( op.sidechain_address_account ); } diff --git a/libraries/chain/include/graphene/chain/protocol/operations.hpp b/libraries/chain/include/graphene/chain/protocol/operations.hpp index 74fd532c..27980ae2 100644 --- a/libraries/chain/include/graphene/chain/protocol/operations.hpp +++ b/libraries/chain/include/graphene/chain/protocol/operations.hpp @@ -48,6 +48,7 @@ #include #include #include +#include namespace graphene { namespace chain { @@ -147,6 +148,8 @@ namespace graphene { namespace chain { son_maintenance_operation, son_wallet_recreate_operation, son_wallet_update_operation, + son_wallet_transfer_create_operation, + son_wallet_transfer_process_operation, sidechain_address_add_operation, sidechain_address_update_operation, sidechain_address_delete_operation diff --git a/libraries/chain/include/graphene/chain/protocol/son_wallet_transfer.hpp b/libraries/chain/include/graphene/chain/protocol/son_wallet_transfer.hpp new file mode 100644 index 00000000..f32eb2a5 --- /dev/null +++ b/libraries/chain/include/graphene/chain/protocol/son_wallet_transfer.hpp @@ -0,0 +1,47 @@ +#pragma once +#include + +namespace graphene { namespace chain { + + struct son_wallet_transfer_create_operation : public base_operation + { + struct fee_parameters_type { uint64_t fee = 0; }; + + asset fee; + account_id_type payer; + + fc::time_point_sec timestamp; + peerplays_sidechain::sidechain_type sidechain; + std::string sidechain_uid; + std::string sidechain_transaction_id; + std::string sidechain_from; + std::string sidechain_to; + int64_t sidechain_amount; + chain::account_id_type peerplays_from; + chain::account_id_type peerplays_to; + + account_id_type fee_payer()const { return payer; } + share_type calculate_fee(const fee_parameters_type& k)const { return 0; } + }; + + struct son_wallet_transfer_process_operation : public base_operation + { + struct fee_parameters_type { uint64_t fee = 0; }; + + asset fee; + account_id_type payer; + + son_wallet_transfer_id_type son_wallet_transfer_id; + + account_id_type fee_payer()const { return payer; } + share_type calculate_fee(const fee_parameters_type& k)const { return 0; } + }; + +} } // namespace graphene::chain + +FC_REFLECT(graphene::chain::son_wallet_transfer_create_operation::fee_parameters_type, (fee) ) +FC_REFLECT(graphene::chain::son_wallet_transfer_create_operation, (fee)(payer) + (timestamp) (sidechain) (sidechain_uid) (sidechain_transaction_id) (sidechain_from) (sidechain_to) (sidechain_amount) (peerplays_from) (peerplays_to)) +FC_REFLECT(graphene::chain::son_wallet_transfer_process_operation::fee_parameters_type, (fee) ) +FC_REFLECT(graphene::chain::son_wallet_transfer_process_operation, (fee)(payer) + (son_wallet_transfer_id)) diff --git a/libraries/chain/include/graphene/chain/protocol/types.hpp b/libraries/chain/include/graphene/chain/protocol/types.hpp index abfce9c8..c25c465c 100644 --- a/libraries/chain/include/graphene/chain/protocol/types.hpp +++ b/libraries/chain/include/graphene/chain/protocol/types.hpp @@ -148,6 +148,7 @@ namespace graphene { namespace chain { son_object_type, son_proposal_object_type, son_wallet_object_type, + son_wallet_transfer_object_type, sidechain_address_object_type, OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types }; @@ -213,6 +214,7 @@ namespace graphene { namespace chain { class son_object; class son_proposal_object; class son_wallet_object; + class son_wallet_transfer_object; class sidechain_address_object; typedef object_id< protocol_ids, account_object_type, account_object> account_id_type; @@ -243,6 +245,7 @@ namespace graphene { namespace chain { typedef object_id< protocol_ids, son_object_type, son_object> son_id_type; typedef object_id< protocol_ids, son_proposal_object_type, son_proposal_object> son_proposal_id_type; typedef object_id< protocol_ids, son_wallet_object_type, son_wallet_object> son_wallet_id_type; + typedef object_id< protocol_ids, son_wallet_transfer_object_type, son_wallet_transfer_object> son_wallet_transfer_id_type; typedef object_id< protocol_ids, sidechain_address_object_type, sidechain_address_object> sidechain_address_id_type; // implementation types @@ -431,6 +434,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type, (son_object_type) (son_proposal_object_type) (son_wallet_object_type) + (son_wallet_transfer_object_type) (sidechain_address_object_type) (OBJECT_TYPE_COUNT) ) @@ -506,6 +510,7 @@ FC_REFLECT_TYPENAME( graphene::chain::tournament_details_id_type ) FC_REFLECT_TYPENAME( graphene::chain::son_id_type ) FC_REFLECT_TYPENAME( graphene::chain::son_proposal_id_type ) FC_REFLECT_TYPENAME( graphene::chain::son_wallet_id_type ) +FC_REFLECT_TYPENAME( graphene::chain::son_wallet_transfer_id_type ) FC_REFLECT_TYPENAME( graphene::chain::sidechain_address_id_type ) diff --git a/libraries/chain/include/graphene/chain/son_wallet_transfer_evaluator.hpp b/libraries/chain/include/graphene/chain/son_wallet_transfer_evaluator.hpp new file mode 100644 index 00000000..68fd0ad5 --- /dev/null +++ b/libraries/chain/include/graphene/chain/son_wallet_transfer_evaluator.hpp @@ -0,0 +1,24 @@ +#pragma once +#include + +namespace graphene { namespace chain { + +class create_son_wallet_transfer_evaluator : public evaluator +{ +public: + typedef son_wallet_transfer_create_operation operation_type; + + void_result do_evaluate(const son_wallet_transfer_create_operation& o); + object_id_type do_apply(const son_wallet_transfer_create_operation& o); +}; + +class process_son_wallet_transfer_evaluator : public evaluator +{ +public: + typedef son_wallet_transfer_process_operation operation_type; + + void_result do_evaluate(const son_wallet_transfer_process_operation& o); + object_id_type do_apply(const son_wallet_transfer_process_operation& o); +}; + +} } // namespace graphene::chain diff --git a/libraries/chain/include/graphene/chain/son_wallet_transfer_object.hpp b/libraries/chain/include/graphene/chain/son_wallet_transfer_object.hpp new file mode 100644 index 00000000..05497442 --- /dev/null +++ b/libraries/chain/include/graphene/chain/son_wallet_transfer_object.hpp @@ -0,0 +1,66 @@ +#pragma once +#include +#include + +namespace graphene { namespace chain { + using namespace graphene::db; + + /** + * @class son_wallet_transfer_object + * @brief tracks information about a SON wallet transfer. + * @ingroup object + */ + class son_wallet_transfer_object : public abstract_object + { + public: + static const uint8_t space_id = protocol_ids; + static const uint8_t type_id = son_wallet_transfer_object_type; + + time_point_sec timestamp; + peerplays_sidechain::sidechain_type sidechain; + std::string sidechain_uid; + std::string sidechain_transaction_id; + std::string sidechain_from; + std::string sidechain_to; + int64_t sidechain_amount; + chain::account_id_type peerplays_from; + chain::account_id_type peerplays_to; + + bool processed; + }; + + struct by_sidechain; + struct by_sidechain_uid; + struct by_processed; + struct by_sidechain_and_processed; + using son_wallet_transfer_multi_index_type = multi_index_container< + son_wallet_transfer_object, + indexed_by< + ordered_unique< tag, + member + >, + ordered_non_unique< tag, + member + >, + ordered_unique< tag, + member + >, + ordered_non_unique< tag, + member + >, + ordered_non_unique< tag, + composite_key, + member + > + > + > + >; + using son_wallet_transfer_index = generic_index; +} } // graphene::chain + +FC_REFLECT_DERIVED( graphene::chain::son_wallet_transfer_object, (graphene::db::object), + (timestamp) (sidechain) + (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 new file mode 100644 index 00000000..5a447569 --- /dev/null +++ b/libraries/chain/son_wallet_transfer_evaluator.cpp @@ -0,0 +1,60 @@ +#include + +#include +#include + +namespace graphene { namespace chain { + +void_result create_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_transfer_create_operation& op) +{ try{ + FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); + //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); + 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; +} FC_CAPTURE_AND_RETHROW( (op) ) } + +void_result process_son_wallet_transfer_evaluator::do_evaluate(const son_wallet_transfer_process_operation& op) +{ try{ + FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); + //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.son_wallet_transfer_id) != idx.end(), "Son wallet transfer not found"); + return void_result(); +} FC_CAPTURE_AND_RETHROW( (op) ) } + +object_id_type process_son_wallet_transfer_evaluator::do_apply(const son_wallet_transfer_process_operation& op) +{ try { + const auto& idx = db().get_index_type().indices().get(); + auto itr = idx.find(op.son_wallet_transfer_id); + if(itr != idx.end()) + { + db().modify(*itr, [&op](son_wallet_transfer_object &swto) { + swto.processed = true; + }); + } + return op.son_wallet_transfer_id; +} FC_CAPTURE_AND_RETHROW( (op) ) } + +} } // namespace graphene::chain diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/defs.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/defs.hpp index 836cecb7..3bd94a49 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/defs.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/defs.hpp @@ -4,8 +4,11 @@ #include #include +#include #include +#include + namespace graphene { namespace peerplays_sidechain { enum class sidechain_type { @@ -61,11 +64,15 @@ struct info_for_vin }; struct sidechain_event_data { + fc::time_point_sec timestamp; sidechain_type sidechain; - std::string transaction_id; - std::string from; - std::string to; - int64_t amount; + std::string sidechain_uid; + std::string sidechain_transaction_id; + std::string sidechain_from; + std::string sidechain_to; + int64_t sidechain_amount; + chain::account_id_type peerplays_from; + chain::account_id_type peerplays_to; }; } } // graphene::peerplays_sidechain diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 0c05756a..ad1bb36c 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -9,6 +9,8 @@ #include #include #include +#include +#include #include #include @@ -59,7 +61,7 @@ class peerplays_sidechain_plugin_impl }; peerplays_sidechain_plugin_impl::peerplays_sidechain_plugin_impl(peerplays_sidechain_plugin& _plugin) : - plugin( _plugin ), + plugin(_plugin), config_ready_son(false), config_ready_bitcoin(false), net_manager(nullptr) @@ -344,6 +346,40 @@ void peerplays_sidechain_plugin_impl::recreate_primary_wallet() } void peerplays_sidechain_plugin_impl::process_deposits() { + + // Account who issues tokens to the user who made deposit + account_id_type pay_from = GRAPHENE_NULL_ACCOUNT; + const auto& account_idx = plugin.database().get_index_type().indices().get(); + const auto& account_itr = account_idx.find("nathan"); + if (account_itr != account_idx.end()) + pay_from = (*account_itr).id; + + const auto& idx = plugin.database().get_index_type().indices().get(); + const auto& idx_range = idx.equal_range(false); + + std::for_each(idx_range.first, idx_range.second, + [&] (const son_wallet_transfer_object& swto) { + + 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 + + proposal_create_operation proposal_op; + proposal_op.fee_paying_account = plugin.get_son_object().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 ); + + signed_transaction trx = plugin.database().create_signed_transaction(plugin.get_private_keys().begin()->second, 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())); + } + }); } //void peerplays_sidechain_plugin_impl::process_withdrawals() { @@ -433,6 +469,11 @@ void peerplays_sidechain_plugin_impl::on_objects_new(const vectorproposed_transaction.operations[0].which() == chain::operation::tag::value) { approve_proposal( proposal->id ); } + + if(proposal->proposed_transaction.operations.size() == 1 + && proposal->proposed_transaction.operations[0].which() == chain::operation::tag::value) { + approve_proposal( proposal->id ); + } } } } diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index bb036d4a..3a610dca 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -44,11 +44,47 @@ 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( " sidechain: ${sidechain}", ( "sidechain", sed.sidechain ) ); - ilog( " transaction_id: ${transaction_id}", ( "transaction_id", sed.transaction_id ) ); - ilog( " from: ${from}", ( "from", sed.from ) ); - ilog( " to: ${to}", ( "to", sed.to ) ); - ilog( " amount: ${amount}", ( "amount", sed.amount ) ); + ilog( " timestamp: ${timestamp}", ( "timestamp", sed.timestamp ) ); + ilog( " sidechain: ${sidechain}", ( "sidechain", sed.sidechain ) ); + ilog( " sidechain_uid: ${uid}", ( "uid", sed.sidechain_uid ) ); + ilog( " sidechain_transaction_id: ${transaction_id}", ( "transaction_id", sed.sidechain_transaction_id ) ); + ilog( " sidechain_from: ${from}", ( "from", sed.sidechain_from ) ); + ilog( " sidechain_to: ${to}", ( "to", sed.sidechain_to ) ); + ilog( " sidechain_amount: ${amount}", ( "amount", sed.sidechain_amount ) ); + 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; + op.payer = gpo.parameters.get_son_btc_account_id(); + op.timestamp = sed.timestamp; + op.sidechain = sed.sidechain; + op.sidechain_uid = sed.sidechain_uid; + op.sidechain_transaction_id = sed.sidechain_transaction_id; + op.sidechain_from = sed.sidechain_from; + op.sidechain_to = sed.sidechain_to; + op.sidechain_amount = sed.sidechain_amount; + op.peerplays_from = sed.peerplays_from; + op.peerplays_to = sed.peerplays_to; + + proposal_create_operation proposal_op; + proposal_op.fee_paying_account = plugin.get_son_object().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_keys().begin()->second, 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())); + } } } } // graphene::peerplays_sidechain diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp index e6bda28e..3d89938f 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -333,6 +334,11 @@ 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 ); @@ -344,12 +350,20 @@ void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data if ( addr_itr == sidechain_addresses_idx.end() ) continue; + std::stringstream ss; + ss << "bitcoin" << "-" << v.out.hash_tx << "-" << v.out.n_vout; + std::string sidechain_uid = ss.str(); + sidechain_event_data sed; + sed.timestamp = plugin.database().head_block_time(); sed.sidechain = addr_itr->sidechain; - sed.transaction_id = v.out.hash_tx; - sed.from = ""; - sed.to = v.address; - sed.amount = v.out.amount; + sed.sidechain_uid = sidechain_uid; + sed.sidechain_transaction_id = v.out.hash_tx; + sed.sidechain_from = ""; + sed.sidechain_to = v.address; + sed.sidechain_amount = v.out.amount; + sed.peerplays_from = addr_itr->sidechain_address_account; + sed.peerplays_to = GRAPHENE_SON_ACCOUNT_ID; sidechain_event_data_received(sed); } } diff --git a/programs/js_operation_serializer/main.cpp b/programs/js_operation_serializer/main.cpp index f9056a55..04a94827 100644 --- a/programs/js_operation_serializer/main.cpp +++ b/programs/js_operation_serializer/main.cpp @@ -45,6 +45,7 @@ #include #include #include +#include #include #include