From 42b7d25a990445543514467c4dc1d97c88aca018 Mon Sep 17 00:00:00 2001 From: Srdjan Obucina Date: Wed, 29 Jan 2020 17:09:37 +0100 Subject: [PATCH] SON wallet transfer object and operations, for tracking assets deposit/withdrawal --- libraries/chain/hardfork.d/SON.hf | 5 +-- .../chain/protocol/son_wallet_transfer.hpp | 11 ++++++- .../chain/son_wallet_transfer_evaluator.cpp | 17 +++++++--- .../graphene/peerplays_sidechain/defs.hpp | 3 ++ .../peerplays_sidechain_plugin.hpp | 1 + .../sidechain_net_handler.hpp | 4 +-- .../peerplays_sidechain_plugin.cpp | 31 +++++++++++++++++-- .../sidechain_net_handler.cpp | 27 ++++++++++++++++ .../sidechain_net_handler_bitcoin.cpp | 4 +++ 9 files changed, 91 insertions(+), 12 deletions(-) diff --git a/libraries/chain/hardfork.d/SON.hf b/libraries/chain/hardfork.d/SON.hf index 355c5b96..5c4e1e76 100644 --- a/libraries/chain/hardfork.d/SON.hf +++ b/libraries/chain/hardfork.d/SON.hf @@ -1,5 +1,6 @@ -// SON HARDFORK Monday, September 21, 2020 1:43:11 PM +// SON HARDFORK Wednesday, January 1, 2020 12:00:00 AM - 1577836800 +// SON HARDFORK Monday, September 21, 2020 1:43:11 PM - 1600695791 #ifndef HARDFORK_SON_TIME #include -#define HARDFORK_SON_TIME (fc::time_point_sec( time(NULL) - (60 * 60) )) +#define HARDFORK_SON_TIME (fc::time_point_sec( 1577836800 )) #endif diff --git a/libraries/chain/include/graphene/chain/protocol/son_wallet_transfer.hpp b/libraries/chain/include/graphene/chain/protocol/son_wallet_transfer.hpp index e9913d7d..1b799822 100644 --- a/libraries/chain/include/graphene/chain/protocol/son_wallet_transfer.hpp +++ b/libraries/chain/include/graphene/chain/protocol/son_wallet_transfer.hpp @@ -10,6 +10,14 @@ namespace graphene { namespace chain { asset fee; account_id_type payer; + std::string uid; + fc::time_point_sec timestamp; + peerplays_sidechain::sidechain_type sidechain; + std::string transaction_id; + std::string from; + std::string to; + int64_t amount; + account_id_type fee_payer()const { return payer; } share_type calculate_fee(const fee_parameters_type& k)const { return 0; } }; @@ -17,4 +25,5 @@ namespace graphene { namespace chain { } } // 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) ) +FC_REFLECT(graphene::chain::son_wallet_transfer_create_operation, (fee)(payer) + (uid) (timestamp) (sidechain) (transaction_id) (from) (to) (amount)) diff --git a/libraries/chain/son_wallet_transfer_evaluator.cpp b/libraries/chain/son_wallet_transfer_evaluator.cpp index d217c5bf..08b192dd 100644 --- a/libraries/chain/son_wallet_transfer_evaluator.cpp +++ b/libraries/chain/son_wallet_transfer_evaluator.cpp @@ -7,17 +7,24 @@ 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(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."); + const auto& idx = db().get_index_type().indices().get(); + FC_ASSERT(idx.find(op.uid) == idx.end(), "Already registered " + op.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& obj ){ - /*obj.valid_from = db().head_block_time(); - obj.expires = time_point_sec::maximum(); - obj.sons = db().get_global_properties().active_sons;*/ + obj.uid = op.uid; + obj.timestamp = op.timestamp; + obj.sidechain = op.sidechain; + obj.transaction_id = op.transaction_id; + obj.from = op.from; + obj.to = op.to; + obj.amount = op.amount; + obj.processed = false; }); return new_son_wallet_transfer_object.id; } FC_CAPTURE_AND_RETHROW( (op) ) } 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..6c0b69fb 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/defs.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/defs.hpp @@ -4,6 +4,7 @@ #include #include +#include #include namespace graphene { namespace peerplays_sidechain { @@ -61,6 +62,8 @@ struct info_for_vin }; struct sidechain_event_data { + std::string uid; + fc::time_point_sec timestamp; sidechain_type sidechain; std::string transaction_id; std::string from; 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 5ad7ec00..edc5c43c 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 @@ -29,6 +29,7 @@ class peerplays_sidechain_plugin : public graphene::app::plugin son_id_type get_son_id(); son_object get_son_object(); + bool is_active_son(); std::map get_private_keys(); }; diff --git a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler.hpp b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler.hpp index e39c77fc..fd632b77 100644 --- a/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler.hpp +++ b/libraries/plugins/peerplays_sidechain/include/graphene/peerplays_sidechain/sidechain_net_handler.hpp @@ -18,11 +18,11 @@ public: graphene::peerplays_sidechain::sidechain_type get_sidechain(); std::vector get_sidechain_addresses(); + void sidechain_event_data_received(const sidechain_event_data& sed); + virtual son_wallet_update_operation recreate_primary_wallet() = 0; virtual string recreate_primary_wallet(const vector& participants) = 0; - fc::signal sidechain_event_data_received; - protected: peerplays_sidechain_plugin& plugin; graphene::chain::database& database; diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index 1af9ef4a..7628f21a 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -35,6 +35,7 @@ class peerplays_sidechain_plugin_impl son_id_type get_son_id(); son_object get_son_object(); + bool is_active_son(); std::map get_private_keys(); void schedule_heartbeat_loop(); @@ -203,6 +204,27 @@ son_object peerplays_sidechain_plugin_impl::get_son_object() return *son_obj; } +bool peerplays_sidechain_plugin_impl::is_active_son() +{ + const auto& idx = plugin.database().get_index_type().indices().get(); + auto son_obj = idx.find( get_son_id() ); + if (son_obj == idx.end()) + return false; + + const chain::global_property_object& gpo = plugin.database().get_global_properties(); + vector active_son_ids; + active_son_ids.reserve(gpo.active_sons.size()); + std::transform(gpo.active_sons.begin(), gpo.active_sons.end(), + std::inserter(active_son_ids, active_son_ids.end()), + [](const son_info& swi) { + return swi.son_id; + }); + + auto it = std::find(active_son_ids.begin(), active_son_ids.end(), get_son_id()); + + return (it != active_son_ids.end()); +} + std::map peerplays_sidechain_plugin_impl::get_private_keys() { return _private_keys; @@ -325,9 +347,9 @@ void peerplays_sidechain_plugin_impl::recreate_primary_wallet() trx.sign(_private_keys.begin()->second, d.get_chain_id()); try { - d.push_transaction(trx, database::validation_steps::skip_block_size_check); + d.push_transaction(trx); } catch (fc::exception e) { - ilog("peerplays_sidechain_plugin_impl: sending son wallet update operations failed with exception ${e}",("e", e.what())); + ilog("peerplays_sidechain_plugin_impl: sending son wallet update operation failed with exception ${e}",("e", e.what())); } } @@ -467,6 +489,11 @@ son_object peerplays_sidechain_plugin::get_son_object() return my->get_son_object(); } +bool peerplays_sidechain_plugin::is_active_son() +{ + return my->is_active_son(); +} + std::map peerplays_sidechain_plugin::get_private_keys() { return my->get_private_keys(); diff --git a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp index bb036d4a..5b820081 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler.cpp @@ -44,11 +44,38 @@ 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( " uid: ${uid}", ( "uid", sed.uid ) ); + ilog( " timestamp: ${timestamp}", ( "timestamp", sed.timestamp ) ); 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 ) ); + + 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.uid = sed.uid; + op.timestamp = sed.timestamp; + op.sidechain = sed.sidechain; + op.transaction_id = sed.transaction_id; + op.from = sed.from; + op.to = sed.to; + op.amount = sed.amount; + + 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 1498f947..25f5f04e 100644 --- a/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp +++ b/libraries/plugins/peerplays_sidechain/sidechain_net_handler_bitcoin.cpp @@ -335,6 +335,10 @@ void sidechain_net_handler_bitcoin::handle_event( const std::string& event_data continue; sidechain_event_data sed; + std::stringstream ss; + ss << "bitcoin" << "-" << v.out.hash_tx << "-" << v.out.n_vout; + sed.uid = ss.str(); + sed.timestamp = plugin.database().head_block_time(); sed.sidechain = addr_itr->sidechain; sed.transaction_id = v.out.hash_tx; sed.from = "";