diff --git a/libraries/app/impacted.cpp b/libraries/app/impacted.cpp index c8b1122e..cd92969b 100644 --- a/libraries/app/impacted.cpp +++ b/libraries/app/impacted.cpp @@ -310,6 +310,12 @@ struct get_impacted_account_visitor void operator()( const son_heartbeat_operation& op ){ _impacted.insert( op.owner_account ); } + void operator()( const son_report_down_operation& op ){ + _impacted.insert( op.payer ); + } + void operator()( const son_wallet_create_operation& op ){ + _impacted.insert( op.payer ); + } void operator()( const sidechain_address_add_operation& op ){ _impacted.insert( op.sidechain_address_account ); } @@ -319,9 +325,6 @@ struct get_impacted_account_visitor void operator()( const sidechain_address_delete_operation& op ){ _impacted.insert( op.sidechain_address_account ); } - void operator()( const son_report_down_operation& op ){ - _impacted.insert( op.payer ); - } }; void operation_get_impacted_accounts( const operation& op, flat_set& result ) diff --git a/libraries/chain/CMakeLists.txt b/libraries/chain/CMakeLists.txt index bba9e7f1..b716e974 100644 --- a/libraries/chain/CMakeLists.txt +++ b/libraries/chain/CMakeLists.txt @@ -119,6 +119,8 @@ add_library( graphene_chain sidechain_address_evaluator.cpp + son_wallet_evaluator.cpp + ${HEADERS} ${PROTOCOL_HEADERS} "${CMAKE_CURRENT_BINARY_DIR}/include/graphene/chain/hardfork.hpp" diff --git a/libraries/chain/db_init.cpp b/libraries/chain/db_init.cpp index 2aab032d..d336bd43 100644 --- a/libraries/chain/db_init.cpp +++ b/libraries/chain/db_init.cpp @@ -56,6 +56,7 @@ #include #include #include +#include #include #include @@ -79,6 +80,7 @@ #include #include #include +#include #include #include @@ -250,10 +252,11 @@ void database::initialize_evaluators() register_evaluator(); register_evaluator(); register_evaluator(); + register_evaluator(); + register_evaluator(); register_evaluator(); register_evaluator(); register_evaluator(); - register_evaluator(); } void database::initialize_indexes() @@ -298,6 +301,8 @@ void database::initialize_indexes() add_index< primary_index >(); add_index< primary_index >(); + add_index< primary_index >(); + add_index< primary_index >(); //Implementation object indexes diff --git a/libraries/chain/db_notify.cpp b/libraries/chain/db_notify.cpp index d53955a3..b3aa366e 100644 --- a/libraries/chain/db_notify.cpp +++ b/libraries/chain/db_notify.cpp @@ -297,6 +297,12 @@ struct get_impacted_account_visitor void operator()( const son_heartbeat_operation& op ) { _impacted.insert( op.owner_account ); } + void operator()( const son_report_down_operation& op ) { + _impacted.insert( op.payer ); + } + void operator()( const son_wallet_create_operation& op ) { + _impacted.insert( op.payer ); + } void operator()( const sidechain_address_add_operation& op ) { _impacted.insert( op.sidechain_address_account ); } @@ -306,9 +312,6 @@ struct get_impacted_account_visitor void operator()( const sidechain_address_delete_operation& op ) { _impacted.insert( op.sidechain_address_account ); } - void operator()( const son_report_down_operation& op ) { - _impacted.insert( op.payer ); - } }; void operation_get_impacted_accounts( const operation& op, flat_set& result ) diff --git a/libraries/chain/include/graphene/chain/protocol/operations.hpp b/libraries/chain/include/graphene/chain/protocol/operations.hpp index 646f2e69..5837c2d9 100644 --- a/libraries/chain/include/graphene/chain/protocol/operations.hpp +++ b/libraries/chain/include/graphene/chain/protocol/operations.hpp @@ -47,6 +47,7 @@ #include #include #include +#include namespace graphene { namespace chain { @@ -142,10 +143,11 @@ namespace graphene { namespace chain { son_update_operation, son_delete_operation, son_heartbeat_operation, + son_report_down_operation, + son_wallet_create_operation, sidechain_address_add_operation, sidechain_address_update_operation, - sidechain_address_delete_operation, - son_report_down_operation + sidechain_address_delete_operation > operation; /// @} // operations group diff --git a/libraries/chain/include/graphene/chain/protocol/son_wallet.hpp b/libraries/chain/include/graphene/chain/protocol/son_wallet.hpp new file mode 100644 index 00000000..386f010c --- /dev/null +++ b/libraries/chain/include/graphene/chain/protocol/son_wallet.hpp @@ -0,0 +1,20 @@ +#pragma once +#include + +namespace graphene { namespace chain { + + struct son_wallet_create_operation : public base_operation + { + struct fee_parameters_type { uint64_t fee = 0; }; + + asset fee; + account_id_type payer; + + 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_create_operation::fee_parameters_type, (fee) ) +FC_REFLECT(graphene::chain::son_wallet_create_operation, (fee)(payer) ) diff --git a/libraries/chain/include/graphene/chain/protocol/types.hpp b/libraries/chain/include/graphene/chain/protocol/types.hpp index 1d056740..abfce9c8 100644 --- a/libraries/chain/include/graphene/chain/protocol/types.hpp +++ b/libraries/chain/include/graphene/chain/protocol/types.hpp @@ -430,6 +430,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type, (bet_object_type) (son_object_type) (son_proposal_object_type) + (son_wallet_object_type) (sidechain_address_object_type) (OBJECT_TYPE_COUNT) ) @@ -504,6 +505,7 @@ FC_REFLECT_TYPENAME( graphene::chain::global_betting_statistics_id_type ) 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::sidechain_address_id_type ) diff --git a/libraries/chain/include/graphene/chain/son_wallet_evaluator.hpp b/libraries/chain/include/graphene/chain/son_wallet_evaluator.hpp new file mode 100644 index 00000000..e2689765 --- /dev/null +++ b/libraries/chain/include/graphene/chain/son_wallet_evaluator.hpp @@ -0,0 +1,16 @@ +#pragma once +#include +#include + +namespace graphene { namespace chain { + +class create_son_wallet_evaluator : public evaluator +{ +public: + typedef son_wallet_create_operation operation_type; + + void_result do_evaluate(const son_wallet_create_operation& o); + object_id_type do_apply(const son_wallet_create_operation& o); +}; + +} } // namespace graphene::chain diff --git a/libraries/chain/include/graphene/chain/son_wallet_object.hpp b/libraries/chain/include/graphene/chain/son_wallet_object.hpp index c3ea204d..3d546355 100644 --- a/libraries/chain/include/graphene/chain/son_wallet_object.hpp +++ b/libraries/chain/include/graphene/chain/son_wallet_object.hpp @@ -16,6 +16,9 @@ namespace graphene { namespace chain { static const uint8_t space_id = protocol_ids; static const uint8_t type_id = son_wallet_object_type; + time_point_sec valid_from; + time_point_sec expires; + flat_map addresses; }; @@ -33,4 +36,4 @@ namespace graphene { namespace chain { } } // graphene::chain FC_REFLECT_DERIVED( graphene::chain::son_wallet_object, (graphene::db::object), - (addresses) ) + (valid_from) (expires) (addresses) ) diff --git a/libraries/chain/son_wallet_evaluator.cpp b/libraries/chain/son_wallet_evaluator.cpp new file mode 100644 index 00000000..c64f884e --- /dev/null +++ b/libraries/chain/son_wallet_evaluator.cpp @@ -0,0 +1,24 @@ +#include + +#include +#include + +namespace graphene { namespace chain { + +void_result create_son_wallet_evaluator::do_evaluate(const son_wallet_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."); + return void_result(); +} FC_CAPTURE_AND_RETHROW( (op) ) } + +object_id_type create_son_wallet_evaluator::do_apply(const son_wallet_create_operation& op) +{ try { + const auto& new_son_wallet_object = db().create( [&]( son_wallet_object& obj ){ + obj.valid_from = db().head_block_time(); + obj.expires = time_point_sec::maximum(); + }); + return new_son_wallet_object.id; +} FC_CAPTURE_AND_RETHROW( (op) ) } + +} } // namespace graphene::chain diff --git a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp index e78c78c5..5e89674b 100644 --- a/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp +++ b/libraries/plugins/peerplays_sidechain/peerplays_sidechain_plugin.cpp @@ -27,6 +27,8 @@ class peerplays_sidechain_plugin_impl void plugin_startup(); void schedule_heartbeat_loop(); void heartbeat_loop(); + void schedule_son_event_processing_loop(); + void son_event_processing_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 ); void on_objects_new(const vector& new_object_ids); @@ -40,6 +42,7 @@ class peerplays_sidechain_plugin_impl std::map _private_keys; std::set _sons; fc::future _heartbeat_task; + fc::future _son_event_processing_task; }; peerplays_sidechain_plugin_impl::peerplays_sidechain_plugin_impl(peerplays_sidechain_plugin& _plugin) : @@ -153,19 +156,20 @@ void peerplays_sidechain_plugin_impl::plugin_startup() { if (config_ready_son) { ilog("SON running"); + + ilog("Starting heartbeats for ${n} sons.", ("n", _sons.size())); + schedule_heartbeat_loop(); + + ilog("Starting event processing for ${n} sons.", ("n", _sons.size())); + schedule_son_event_processing_loop(); + } else { + elog("No sons configured! Please add SON IDs and private keys to configuration."); } if (config_ready_bitcoin) { ilog("Bitcoin sidechain handler running"); } - if( !_sons.empty() && !_private_keys.empty() ) - { - ilog("Starting heartbeats for ${n} sons.", ("n", _sons.size())); - schedule_heartbeat_loop(); - } else - elog("No sons configured! Please add SON IDs and private keys to configuration."); - //if (config_ready_ethereum) { // ilog("Ethereum sidechain handler running"); //} @@ -220,6 +224,25 @@ void peerplays_sidechain_plugin_impl::heartbeat_loop() schedule_heartbeat_loop(); } +void peerplays_sidechain_plugin_impl::schedule_son_event_processing_loop() +{ + fc::time_point now = fc::time_point::now(); + int64_t time_to_next_second = 1000000 - (now.time_since_epoch().count() % 1000000); + if( time_to_next_second < 50000 ) // we must sleep for at least 50ms + time_to_next_second += 1000000; + + fc::time_point next_wakeup( now + fc::microseconds( time_to_next_second ) ); + + _son_event_processing_task = fc::schedule([this]{son_event_processing_loop();}, + next_wakeup, "SON Event Processing"); +} + +void peerplays_sidechain_plugin_impl::son_event_processing_loop() +{ + + schedule_son_event_processing_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();