diff --git a/libraries/chain/database.cpp b/libraries/chain/database.cpp index 9a5cee6efa..c4631e2664 100644 --- a/libraries/chain/database.cpp +++ b/libraries/chain/database.cpp @@ -157,16 +157,15 @@ void database::open( const open_args& args ) uint32_t database::reindex( const open_args& args ) { - bool reindex_success = false; - uint32_t last_block_number = 0; // result + reindex_notification note; - BOOST_SCOPE_EXIT(this_,&reindex_success,&last_block_number) { - STEEM_TRY_NOTIFY(this_->_on_reindex_done, reindex_success, last_block_number); + BOOST_SCOPE_EXIT(this_,¬e) { + STEEM_TRY_NOTIFY(this_->_post_reindex_signal, note); } BOOST_SCOPE_EXIT_END try { - STEEM_TRY_NOTIFY(_on_reindex_start); + STEEM_TRY_NOTIFY(_pre_reindex_signal, note); ilog( "Reindexing Blockchain" ); wipe( args.data_dir, args.shared_mem_dir, false ); @@ -215,10 +214,10 @@ uint32_t database::reindex( const open_args& args ) } apply_block( itr.first, skip_flags ); - last_block_number = itr.first.block_num(); + note.last_block_number = itr.first.block_num(); - if( (args.benchmark.first > 0) && (last_block_number % args.benchmark.first == 0) ) - args.benchmark.second( last_block_number, get_abstract_index_cntr() ); + if( (args.benchmark.first > 0) && (note.last_block_number % args.benchmark.first == 0) ) + args.benchmark.second( note.last_block_number, get_abstract_index_cntr() ); set_revision( head_block_num() ); _block_log.set_locking( true ); }); @@ -229,9 +228,9 @@ uint32_t database::reindex( const open_args& args ) auto end = fc::time_point::now(); ilog( "Done reindexing, elapsed time: ${t} sec", ("t",double((end-start).count())/1000000.0 ) ); - reindex_success = true; + note.reindex_success = true; - return last_block_number; + return note.last_block_number; } FC_CAPTURE_AND_RETHROW( (args.data_dir)(args.shared_mem_dir) ) @@ -769,9 +768,6 @@ void database::_push_transaction( const signed_transaction& trx ) notify_changed_objects(); // The transaction applied successfully. Merge its changes into the pending block session. temp_session.squash(); - - // notify anyone listening to pending transactions - notify_on_pending_transaction( trx ); } signed_block database::generate_block( @@ -958,21 +954,6 @@ void database::clear_pending() FC_CAPTURE_AND_RETHROW() } -void database::notify_pre_apply_operation( operation_notification& note ) -{ - note.trx_id = _current_trx_id; - note.block = _current_block_num; - note.trx_in_block = _current_trx_in_block; - note.op_in_trx = _current_op_in_trx; - - STEEM_TRY_NOTIFY( _pre_apply_operation, note ) -} - -void database::notify_post_apply_operation( const operation_notification& note ) -{ - STEEM_TRY_NOTIFY( _post_apply_operation, note ) -} - inline const void database::push_virtual_operation( const operation& op, bool force ) { /* @@ -990,24 +971,39 @@ inline const void database::push_virtual_operation( const operation& op, bool fo notify_post_apply_operation( note ); } -void database::notify_applied_block( const signed_block& block ) +void database::notify_pre_apply_operation( operation_notification& note ) { - STEEM_TRY_NOTIFY( _applied_block, block ) + note.trx_id = _current_trx_id; + note.block = _current_block_num; + note.trx_in_block = _current_trx_in_block; + note.op_in_trx = _current_op_in_trx; + + STEEM_TRY_NOTIFY( _pre_apply_operation_signal, note ) } -void database::notify_on_pending_transaction( const signed_transaction& tx ) +void database::notify_post_apply_operation( const operation_notification& note ) { - STEEM_TRY_NOTIFY( _on_pending_transaction, tx ) + STEEM_TRY_NOTIFY( _post_apply_operation_signal, note ) } -void database::notify_on_pre_apply_transaction( const signed_transaction& tx ) +void database::notify_pre_apply_block( const block_notification& note ) { - STEEM_TRY_NOTIFY( _on_pre_apply_transaction, tx ) + STEEM_TRY_NOTIFY( _pre_apply_block_signal, note ) } -void database::notify_on_applied_transaction( const signed_transaction& tx ) +void database::notify_post_apply_block( const block_notification& note ) { - STEEM_TRY_NOTIFY( _on_applied_transaction, tx ) + STEEM_TRY_NOTIFY( _post_apply_block_signal, note ) +} + +void database::notify_pre_apply_transaction( const transaction_notification& note ) +{ + STEEM_TRY_NOTIFY( _pre_apply_transaction_signal, note ) +} + +void database::notify_post_apply_transaction( const transaction_notification& note ) +{ + STEEM_TRY_NOTIFY( _post_apply_transaction_signal, note ) } account_name_type database::get_scheduled_witness( uint32_t slot_num )const @@ -2772,8 +2768,17 @@ void database::show_free_memory( bool force, uint32_t current_block_num ) void database::_apply_block( const signed_block& next_block ) { try { - uint32_t next_block_num = next_block.block_num(); - //block_id_type next_block_id = next_block.id(); + block_notification note( next_block ); + + notify_pre_apply_block( note ); + + const uint32_t next_block_num = note.block_num; + + BOOST_SCOPE_EXIT( this_ ) + { + this_->_currently_processing_block_id.reset(); + } BOOST_SCOPE_EXIT_END + _currently_processing_block_id = note.block_id; uint32_t skip = get_node_properties().skip_flags; @@ -2912,7 +2917,7 @@ void database::_apply_block( const signed_block& next_block ) process_hardforks(); // notify observers that the block has been applied - notify_applied_block( next_block ); + notify_post_apply_block( note ); notify_changed_objects(); } //FC_CAPTURE_AND_RETHROW( (next_block.block_num()) ) } @@ -3048,12 +3053,13 @@ try { void database::apply_transaction(const signed_transaction& trx, uint32_t skip) { detail::with_skip_flags( *this, skip, [&]() { _apply_transaction(trx); }); - notify_on_applied_transaction( trx ); } void database::_apply_transaction(const signed_transaction& trx) { try { - _current_trx_id = trx.id(); + transaction_notification note(trx); + _current_trx_id = note.transaction_id; + const transaction_id_type& trx_id = note.transaction_id; uint32_t skip = get_node_properties().skip_flags; if( !(skip&skip_validate) ) /* issue #505 explains why this skip_flag is disabled */ @@ -3061,7 +3067,6 @@ void database::_apply_transaction(const signed_transaction& trx) auto& trx_idx = get_index(); const chain_id_type& chain_id = get_chain_id(); - auto trx_id = trx.id(); // idump((trx_id)(skip&skip_transaction_dupe_check)); FC_ASSERT( (skip & skip_transaction_dupe_check) || trx_idx.indices().get().find(trx_id) == trx_idx.indices().get().end(), @@ -3116,7 +3121,7 @@ void database::_apply_transaction(const signed_transaction& trx) }); } - notify_on_pre_apply_transaction( trx ); + notify_pre_apply_transaction( note ); //Finally process the operations _current_op_in_trx = 0; @@ -3128,6 +3133,8 @@ void database::_apply_transaction(const signed_transaction& trx) } _current_trx_id = transaction_id_type(); + notify_post_apply_transaction( note ); + } FC_CAPTURE_AND_RETHROW( (trx) ) } void database::apply_operation(const operation& op) @@ -3139,7 +3146,7 @@ void database::apply_operation(const operation& op) _benchmark_dumper.begin(); _my->_evaluator_registry.get_evaluator( op ).apply( op ); - + if( _benchmark_dumper.is_enabled() ) _benchmark_dumper.end< true/*APPLY_CONTEXT*/ >( _my->_evaluator_registry.get_evaluator( op ).get_name( op ) ); @@ -3193,14 +3200,11 @@ boost::signals2::connection database::connect_impl( TSignal& signal, const TNoti { fcall fcall_wrapper(func,_benchmark_dumper,plugin,item_name); - if (group == -1) - return signal.connect(fcall_wrapper); - else - return signal.connect(group, fcall_wrapper); + return signal.connect(group, fcall_wrapper); } template< bool IS_PRE_OPERATION > -boost::signals2::connection database::any_apply_operation_proxy_impl( const operation_notification_t& func, +boost::signals2::connection database::any_apply_operation_handler_impl( const apply_operation_handler_t& func, const abstract_plugin& plugin, int32_t group ) { auto complex_func = [this, func, &plugin]( const operation_notification& o ) @@ -3224,67 +3228,57 @@ boost::signals2::connection database::any_apply_operation_proxy_impl( const oper }; if( IS_PRE_OPERATION ) - { - if (group == -1) - return _pre_apply_operation.connect(complex_func); - else - return _pre_apply_operation.connect(group, complex_func); - } + return _pre_apply_operation_signal.connect(group, complex_func); else - { - if (group == -1) - return _post_apply_operation.connect(complex_func); - else - return _post_apply_operation.connect(group, complex_func); - } + return _post_apply_operation_signal.connect(group, complex_func); } -boost::signals2::connection database::pre_apply_operation_proxy( const operation_notification_t& func, +boost::signals2::connection database::add_pre_apply_operation_handler( const apply_operation_handler_t& func, const abstract_plugin& plugin, int32_t group ) { - return any_apply_operation_proxy_impl< true/*IS_PRE_OPERATION*/ >( func, plugin, group ); + return any_apply_operation_handler_impl< true/*IS_PRE_OPERATION*/ >( func, plugin, group ); } -boost::signals2::connection database::post_apply_operation_proxy( const operation_notification_t& func, +boost::signals2::connection database::add_post_apply_operation_handler( const apply_operation_handler_t& func, const abstract_plugin& plugin, int32_t group ) { - return any_apply_operation_proxy_impl< false/*IS_PRE_OPERATION*/ >( func, plugin, group ); + return any_apply_operation_handler_impl< false/*IS_PRE_OPERATION*/ >( func, plugin, group ); } -boost::signals2::connection database::on_pending_transaction_proxy( const transaction_notification_t& func, +boost::signals2::connection database::add_pre_apply_transaction_handler( const apply_transaction_handler_t& func, const abstract_plugin& plugin, int32_t group ) { - return connect_impl(_on_pending_transaction, func, plugin, group, "@transaction"); + return connect_impl(_pre_apply_transaction_signal, func, plugin, group, "->transaction"); } -boost::signals2::connection database::on_pre_apply_transaction_proxy( const transaction_notification_t& func, +boost::signals2::connection database::add_post_apply_transaction_handler( const apply_transaction_handler_t& func, const abstract_plugin& plugin, int32_t group ) { - return connect_impl(_on_pre_apply_transaction, func, plugin, group, "->transaction"); + return connect_impl(_pre_apply_transaction_signal, func, plugin, group, "<-transaction"); } -boost::signals2::connection database::on_applied_transaction_proxy( const transaction_notification_t& func, +boost::signals2::connection database::add_pre_apply_block_handler( const apply_block_handler_t& func, const abstract_plugin& plugin, int32_t group ) { - return connect_impl(_on_pre_apply_transaction, func, plugin, group, "<-transaction"); + return connect_impl(_pre_apply_block_signal, func, plugin, group, "->block"); } -boost::signals2::connection database::applied_block_proxy( const block_notification_t& func, +boost::signals2::connection database::add_post_apply_block_handler( const apply_block_handler_t& func, const abstract_plugin& plugin, int32_t group ) { - return connect_impl(_applied_block, func, plugin, group, "<-block"); + return connect_impl(_post_apply_block_signal, func, plugin, group, "<-block"); } -boost::signals2::connection database::on_reindex_start_proxy(const on_reindex_start_notification_t& func, +boost::signals2::connection database::add_pre_reindex_handler(const reindex_handler_t& func, const abstract_plugin& plugin, int32_t group ) { - return connect_impl(_on_reindex_start, func, plugin, group, "->reindex"); + return connect_impl(_pre_reindex_signal, func, plugin, group, "->reindex"); } -boost::signals2::connection database::on_reindex_done_proxy(const on_reindex_done_notification_t& func, +boost::signals2::connection database::add_post_reindex_handler(const reindex_handler_t& func, const abstract_plugin& plugin, int32_t group ) { - return connect_impl(_on_reindex_done, func, plugin, group, "<-reindex"); + return connect_impl(_post_reindex_signal, func, plugin, group, "<-reindex"); } const witness_object& database::validate_block_header( uint32_t skip, const signed_block& next_block )const @@ -3362,7 +3356,9 @@ void database::update_global_dynamic_data( const signed_block& b ) } dgp.head_block_number = b.block_num(); - dgp.head_block_id = b.id(); + // Following FC_ASSERT should never fail, as _currently_processing_block_id is always set by caller + FC_ASSERT( _currently_processing_block_id.valid() ); + dgp.head_block_id = *_currently_processing_block_id; dgp.time = b.timestamp; dgp.current_aslot += missed_blocks+1; } ); diff --git a/libraries/chain/include/steem/chain/block_notification.hpp b/libraries/chain/include/steem/chain/block_notification.hpp new file mode 100644 index 0000000000..c715c0ac65 --- /dev/null +++ b/libraries/chain/include/steem/chain/block_notification.hpp @@ -0,0 +1,20 @@ +#pragma once + +#include + +namespace steem { namespace chain { + +struct block_notification +{ + block_notification( const steem::protocol::signed_block& b ) : block(b) + { + block_id = b.id(); + block_num = block_header::num_from_id( block_id ); + } + + steem::protocol::block_id_type block_id; + uint32_t block_num = 0; + const steem::protocol::signed_block& block; +}; + +} } diff --git a/libraries/chain/include/steem/chain/database.hpp b/libraries/chain/include/steem/chain/database.hpp index ead968fa51..36c0b40f4e 100644 --- a/libraries/chain/include/steem/chain/database.hpp +++ b/libraries/chain/include/steem/chain/database.hpp @@ -2,19 +2,21 @@ * Copyright (c) 2015 Cryptonomex, Inc., and contributors. */ #pragma once +#include +#include +#include #include #include #include -#include -#include #include +#include + +#include #include #include #include -#include - #include #include @@ -43,6 +45,13 @@ namespace steem { namespace chain { namespace util { class advanced_benchmark_dumper; } + + struct reindex_notification + { + bool reindex_success = false; + uint32_t last_block_number = 0; + }; + /** * @class database * @brief tracks the blockchain state in an extensible manner @@ -55,6 +64,8 @@ namespace steem { namespace chain { bool is_producing()const { return _is_producing; } void set_producing( bool p ) { _is_producing = p; } + bool is_processing_block()const { return _currently_processing_block_id.valid(); } + bool _is_producing = false; bool _log_hardforks = true; @@ -224,6 +235,8 @@ namespace steem { namespace chain { void pop_block(); void clear_pending(); + inline const void push_virtual_operation( const operation& op, bool force = false ); // vops are not needed for low mem. Force will push them on low mem. + /** * This method is used to track applied operations during the evaluation of a block, these * operations should include any operation actually included in a transaction as well @@ -232,18 +245,15 @@ namespace steem { namespace chain { */ void notify_pre_apply_operation( operation_notification& note ); void notify_post_apply_operation( const operation_notification& note ); - inline const void push_virtual_operation( const operation& op, bool force = false ); // vops are not needed for low mem. Force will push them on low mem. - void notify_applied_block( const signed_block& block ); - void notify_on_pending_transaction( const signed_transaction& tx ); - void notify_on_pre_apply_transaction( const signed_transaction& tx ); - void notify_on_applied_transaction( const signed_transaction& tx ); - - using operation_notification_t = std::function< void(const operation_notification&) >; - using transaction_notification_t = std::function< void(const signed_transaction&) >; - using block_notification_t = std::function< void(const signed_block&) >; - using plugin_index_signal_notification_t = std::function< void(void) >; - using on_reindex_start_notification_t = std::function< void () >; - using on_reindex_done_notification_t = std::function< void(bool,uint32_t) >; + void notify_pre_apply_block( const block_notification& note ); + void notify_post_apply_block( const block_notification& note ); + void notify_pre_apply_transaction( const transaction_notification& note ); + void notify_post_apply_transaction( const transaction_notification& note ); + + using apply_operation_handler_t = std::function< void(const operation_notification&) >; + using apply_transaction_handler_t = std::function< void(const transaction_notification&) >; + using apply_block_handler_t = std::function< void(const block_notification&) >; + using reindex_handler_t = std::function< void(const reindex_notification&) >; private: template - boost::signals2::connection any_apply_operation_proxy_impl( const operation_notification_t& func, + boost::signals2::connection any_apply_operation_handler_impl( const apply_operation_handler_t& func, const abstract_plugin& plugin, int32_t group ); public: - boost::signals2::connection pre_apply_operation_proxy( const operation_notification_t& func, const abstract_plugin& plugin, int32_t group = -1 ); - boost::signals2::connection post_apply_operation_proxy( const operation_notification_t& func, const abstract_plugin& plugin, int32_t group = -1 ); - boost::signals2::connection on_pending_transaction_proxy( const transaction_notification_t& func, const abstract_plugin& plugin, int32_t group = -1 ); - boost::signals2::connection on_pre_apply_transaction_proxy( const transaction_notification_t& func, const abstract_plugin& plugin, int32_t group = -1 ); - boost::signals2::connection on_applied_transaction_proxy( const transaction_notification_t& func, const abstract_plugin& plugin, int32_t group = -1 ); - boost::signals2::connection applied_block_proxy( const block_notification_t& func, const abstract_plugin& plugin, int32_t group = -1 ); - boost::signals2::connection on_reindex_start_proxy(const on_reindex_start_notification_t& func, const abstract_plugin& plugin, int32_t group = -1 ); - boost::signals2::connection on_reindex_done_proxy(const on_reindex_done_notification_t& func, const abstract_plugin& plugin, int32_t group = -1 ); - + boost::signals2::connection add_pre_apply_operation_handler ( const apply_operation_handler_t& func, const abstract_plugin& plugin, int32_t group = -1 ); + boost::signals2::connection add_post_apply_operation_handler ( const apply_operation_handler_t& func, const abstract_plugin& plugin, int32_t group = -1 ); + boost::signals2::connection add_pre_apply_transaction_handler ( const apply_transaction_handler_t& func, const abstract_plugin& plugin, int32_t group = -1 ); + boost::signals2::connection add_post_apply_transaction_handler( const apply_transaction_handler_t& func, const abstract_plugin& plugin, int32_t group = -1 ); + boost::signals2::connection add_pre_apply_block_handler ( const apply_block_handler_t& func, const abstract_plugin& plugin, int32_t group = -1 ); + boost::signals2::connection add_post_apply_block_handler ( const apply_block_handler_t& func, const abstract_plugin& plugin, int32_t group = -1 ); + boost::signals2::connection add_pre_reindex_handler ( const reindex_handler_t& func, const abstract_plugin& plugin, int32_t group = -1 ); + boost::signals2::connection add_post_reindex_handler ( const reindex_handler_t& func, const abstract_plugin& plugin, int32_t group = -1 ); //////////////////// db_witness_schedule.cpp //////////////////// @@ -454,13 +463,6 @@ namespace steem { namespace chain { ///@} #endif - typedef void on_reindex_start_t(); - typedef void on_reindex_done_t(bool,uint32_t); - - void on_reindex_start_connect(std::function functor) - { _on_reindex_start.connect(functor); } - void on_reindex_done_connect(std::function functor) - { _on_reindex_done.connect(functor); } protected: //Mark pop_undo() as protected -- we do not want outside calling pop_undo(); it should call pop_block() instead @@ -524,6 +526,8 @@ namespace steem { namespace chain { uint16_t _current_op_in_trx = 0; uint16_t _current_virtual_op = 0; + optional< block_id_type > _currently_processing_block_id; + flat_map _checkpoints; node_property_object _node_property_object; @@ -540,39 +544,52 @@ namespace steem { namespace chain { util::advanced_benchmark_dumper _benchmark_dumper; + fc::signal _pre_apply_operation_signal; /** * This signal is emitted for plugins to process every operation after it has been fully applied. */ - fc::signal _pre_apply_operation; - fc::signal _post_apply_operation; + fc::signal _post_apply_operation_signal; /** - * This signal is emitted after all operations and virtual operation for a - * block have been applied but before the get_applied_operations() are cleared. + * This signal is emitted when we start processing a block. * * You may not yield from this callback because the blockchain is holding * the write lock and may be in an "inconstant state" until after it is * released. */ - fc::signal _applied_block; + fc::signal _pre_apply_block_signal; /** - * This signal is emitted any time a new transaction is added to the pending - * block state. + * This signal is emitted after all operations and virtual operation for a + * block have been applied but before the get_applied_operations() are cleared. + * + * You may not yield from this callback because the blockchain is holding + * the write lock and may be in an "inconstant state" until after it is + * released. */ - fc::signal _on_pending_transaction; + fc::signal _post_apply_block_signal; /** - * This signla is emitted any time a new transaction is about to be applied + * This signal is emitted any time a new transaction is about to be applied * to the chain state. */ - fc::signal _on_pre_apply_transaction; + fc::signal _pre_apply_transaction_signal; /** * This signal is emitted any time a new transaction has been applied to the * chain state. */ - fc::signal _on_applied_transaction; + fc::signal _post_apply_transaction_signal; + + /** + * Emitted when reindexing starts + */ + fc::signal _pre_reindex_signal; + + /** + * Emitted when reindexing finishes + */ + fc::signal _post_reindex_signal; /** * Emitted After a block has been applied and committed. The callback @@ -585,10 +602,10 @@ namespace steem { namespace chain { */ //fc::signal&)> removed_objects; - fc::signal< void() > _plugin_index_signal; - - fc::signal< void() > _on_reindex_start; - fc::signal< void(bool, uint32_t) > _on_reindex_done; + /** + * Internal signal to execute deferred registration of plugin indexes. + */ + fc::signal _plugin_index_signal; }; } } diff --git a/libraries/chain/include/steem/chain/transaction_notification.hpp b/libraries/chain/include/steem/chain/transaction_notification.hpp new file mode 100644 index 0000000000..453ffc618b --- /dev/null +++ b/libraries/chain/include/steem/chain/transaction_notification.hpp @@ -0,0 +1,18 @@ +#pragma once + +#include + +namespace steem { namespace chain { + +struct transaction_notification +{ + transaction_notification( const steem::protocol::signed_transaction& tx ) : transaction(tx) + { + transaction_id = tx.id(); + } + + steem::protocol::transaction_id_type transaction_id; + const steem::protocol::signed_transaction& transaction; +}; + +} } diff --git a/libraries/plugins/account_by_key/account_by_key_plugin.cpp b/libraries/plugins/account_by_key/account_by_key_plugin.cpp index dcaf1483df..3cc29ee66e 100644 --- a/libraries/plugins/account_by_key/account_by_key_plugin.cpp +++ b/libraries/plugins/account_by_key/account_by_key_plugin.cpp @@ -17,8 +17,8 @@ class account_by_key_plugin_impl _db( appbase::app().get_plugin< steem::plugins::chain::chain_plugin >().db() ), _self( _plugin ) {} - void pre_operation( const operation_notification& op_obj ); - void post_operation( const operation_notification& op_obj ); + void on_pre_apply_operation( const operation_notification& note ); + void on_post_apply_operation( const operation_notification& note ); void clear_cache(); void cache_auths( const account_authority_object& a ); void update_key_lookup( const account_authority_object& a ); @@ -26,8 +26,8 @@ class account_by_key_plugin_impl flat_set< public_key_type > cached_keys; database& _db; account_by_key_plugin& _self; - boost::signals2::connection pre_apply_connection; - boost::signals2::connection post_apply_connection; + boost::signals2::connection _pre_apply_operation_conn; + boost::signals2::connection _post_apply_operation_conn; }; struct pre_operation_visitor @@ -224,12 +224,12 @@ void account_by_key_plugin_impl::update_key_lookup( const account_authority_obje cached_keys.clear(); } -void account_by_key_plugin_impl::pre_operation( const operation_notification& note ) +void account_by_key_plugin_impl::on_pre_apply_operation( const operation_notification& note ) { note.op.visit( pre_operation_visitor( *this ) ); } -void account_by_key_plugin_impl::post_operation( const operation_notification& note ) +void account_by_key_plugin_impl::on_post_apply_operation( const operation_notification& note ) { note.op.visit( post_operation_visitor( *this ) ); } @@ -249,8 +249,8 @@ void account_by_key_plugin::plugin_initialize( const boost::program_options::var ilog( "Initializing account_by_key plugin" ); chain::database& db = appbase::app().get_plugin< steem::plugins::chain::chain_plugin >().db(); - my->pre_apply_connection = db.pre_apply_operation_proxy( [&]( const operation_notification& o ){ my->pre_operation( o ); }, *this, 0 ); - my->post_apply_connection = db.post_apply_operation_proxy( [&]( const operation_notification& o ){ my->post_operation( o ); }, *this, 0 ); + my->_pre_apply_operation_conn = db.add_pre_apply_operation_handler( [&]( const operation_notification& note ){ my->on_pre_apply_operation( note ); }, *this, 0 ); + my->_post_apply_operation_conn = db.add_post_apply_operation_handler( [&]( const operation_notification& note ){ my->on_post_apply_operation( note ); }, *this, 0 ); add_plugin_index< key_lookup_index >(db); } @@ -261,8 +261,8 @@ void account_by_key_plugin::plugin_startup() {} void account_by_key_plugin::plugin_shutdown() { - chain::util::disconnect_signal( my->pre_apply_connection ); - chain::util::disconnect_signal( my->post_apply_connection ); + chain::util::disconnect_signal( my->_pre_apply_operation_conn ); + chain::util::disconnect_signal( my->_post_apply_operation_conn ); } } } } // steem::plugins::account_by_key diff --git a/libraries/plugins/account_history/account_history_plugin.cpp b/libraries/plugins/account_history/account_history_plugin.cpp index 17dd93fb69..940e3dbe5f 100644 --- a/libraries/plugins/account_history/account_history_plugin.cpp +++ b/libraries/plugins/account_history/account_history_plugin.cpp @@ -35,7 +35,7 @@ class account_history_plugin_impl virtual ~account_history_plugin_impl() {} - void on_operation( const operation_notification& note ); + void on_pre_apply_operation( const operation_notification& note ); flat_map< account_name_type, account_name_type > _tracked_accounts; bool _filter_content = false; @@ -43,7 +43,7 @@ class account_history_plugin_impl flat_set< string > _op_list; bool _prune = true; database& _db; - boost::signals2::connection pre_apply_connection; + boost::signals2::connection _pre_apply_operation_conn; }; struct operation_visitor @@ -146,7 +146,7 @@ struct operation_visitor_filter : operation_visitor } }; -void account_history_plugin_impl::on_operation( const operation_notification& note ) +void account_history_plugin_impl::on_pre_apply_operation( const operation_notification& note ) { flat_set impacted; @@ -220,7 +220,8 @@ void account_history_plugin::plugin_initialize( const boost::program_options::va { my = std::make_unique< detail::account_history_plugin_impl >(); - my->pre_apply_connection = my->_db.pre_apply_operation_proxy( [&]( const operation_notification& note ){ my->on_operation(note); }, *this, 0 ); + my->_pre_apply_operation_conn = my->_db.add_pre_apply_operation_handler( + [&]( const operation_notification& note ){ my->on_pre_apply_operation(note); }, *this, 0 ); typedef pair< account_name_type, account_name_type > pairstring; STEEM_LOAD_VALUE_SET(options, "account-history-track-account-range", my->_tracked_accounts, pairstring); @@ -321,7 +322,7 @@ void account_history_plugin::plugin_startup() {} void account_history_plugin::plugin_shutdown() { - chain::util::disconnect_signal( my->pre_apply_connection ); + chain::util::disconnect_signal( my->_pre_apply_operation_conn ); } flat_map< account_name_type, account_name_type > account_history_plugin::tracked_accounts() const diff --git a/libraries/plugins/account_history_rocksdb/account_history_rocksdb_plugin.cpp b/libraries/plugins/account_history_rocksdb/account_history_rocksdb_plugin.cpp index 3e5cc880f6..9320da35e1 100644 --- a/libraries/plugins/account_history_rocksdb/account_history_rocksdb_plugin.cpp +++ b/libraries/plugins/account_history_rocksdb/account_history_rocksdb_plugin.cpp @@ -324,22 +324,23 @@ class CachableWriteBatch : public WriteBatch class account_history_rocksdb_plugin::impl final { public: - impl( const bpo::variables_map& options, const bfs::path& storagePath) : + impl( account_history_rocksdb_plugin& self, const bpo::variables_map& options, const bfs::path& storagePath) : + _self(self), _mainDb(appbase::app().get_plugin().db()), _storagePath(storagePath), _writeBuffer(_storage, _columnHandles) { collectOptions(options); - _mainDb.on_reindex_start_connect([&]() -> void + _mainDb.add_pre_reindex_handler([&]( const steem::chain::reindex_notification& note ) -> void { - onReindexStart(); - }); + on_pre_reindex( note ); + }, _self, 0); - _mainDb.on_reindex_done_connect([&](bool success, uint32_t finalBlock) -> void + _mainDb.add_post_reindex_handler([&]( const steem::chain::reindex_notification& note ) -> void { - onReindexStop(finalBlock); - }); + on_post_reindex( note ); + }, _self, 0); } ~impl() @@ -372,10 +373,10 @@ class account_history_rocksdb_plugin::impl final loadSeqIdentifiers(storageDb); _storage.reset(storageDb); - _pre_apply_connection = _mainDb.pre_apply_operation_proxy( + _on_pre_apply_operation_connection = _mainDb.add_pre_apply_operation_handler( [&]( const operation_notification& note ) { - on_operation(note); + on_pre_apply_operation(note); }, appbase::app().get_plugin< account_history_rocksdb_plugin >() ); } @@ -387,8 +388,8 @@ class account_history_rocksdb_plugin::impl final } void printReport(uint32_t blockNo, const char* detailText) const; - void onReindexStart(); - void onReindexStop(uint32_t finalBlock); + void on_pre_reindex( const steem::chain::reindex_notification& note ); + void on_post_reindex( const steem::chain::reindex_notification& note ); /// Allows to start immediate data import (outside replay process). void importData(unsigned int blockLimit); @@ -405,7 +406,7 @@ class account_history_rocksdb_plugin::impl final void shutdownDb() { - chain::util::disconnect_signal(_pre_apply_connection); + chain::util::disconnect_signal(_on_pre_apply_operation_connection); flushStorage(); cleanupColumnHandles(); _storage.reset(); @@ -526,7 +527,7 @@ class account_history_rocksdb_plugin::impl final } } - void on_operation(const operation_notification& opNote); + void on_pre_apply_operation(const operation_notification& opNote); void collectOptions(const bpo::variables_map& options); @@ -571,12 +572,13 @@ class account_history_rocksdb_plugin::impl final private: typedef flat_map< account_name_type, account_name_type > account_name_range_index; + account_history_rocksdb_plugin& _self; chain::database& _mainDb; bfs::path _storagePath; std::unique_ptr _storage; std::vector _columnHandles; CachableWriteBatch _writeBuffer; - boost::signals2::connection _pre_apply_connection; + boost::signals2::connection _on_pre_apply_operation_connection; /// Helper member to be able to detect another incomming tx and increment tx-counter. transaction_id_type _lastTx; size_t _txNo = 0; @@ -635,7 +637,7 @@ inline bool account_history_rocksdb_plugin::impl::isTrackedAccount(const account if(_tracked_accounts.empty()) return true; - /// Code below is based on original contents of account_history_plugin_impl::on_operation + /// Code below is based on original contents of account_history_plugin_impl::on_pre_apply_operation auto itr = _tracked_accounts.lower_bound(name); /* @@ -1186,7 +1188,7 @@ void account_history_rocksdb_plugin::impl::prunePotentiallyTooOldItems(account_h } } -void account_history_rocksdb_plugin::impl::onReindexStart() +void account_history_rocksdb_plugin::impl::on_pre_reindex(const steem::chain::reindex_notification& note) { ilog("Received onReindexStart request, attempting to clean database storage."); @@ -1210,8 +1212,9 @@ void account_history_rocksdb_plugin::impl::onReindexStart() ilog("onReindexStart request completed successfully."); } -void account_history_rocksdb_plugin::impl::onReindexStop(uint32_t finalBlock) +void account_history_rocksdb_plugin::impl::on_post_reindex(const steem::chain::reindex_notification& note) { + const uint32_t finalBlock = note.last_block_number; ilog("Reindex completed up to block: ${b}. Setting back write limit to non-massive level.", ("b", finalBlock)); @@ -1292,7 +1295,7 @@ void account_history_rocksdb_plugin::impl::importData(unsigned int blockLimit) printReport(blockNo, "RocksDB data import finished. "); } -void account_history_rocksdb_plugin::impl::on_operation(const operation_notification& n) +void account_history_rocksdb_plugin::impl::on_pre_apply_operation(const operation_notification& n) { if(_storage != nullptr) { @@ -1349,7 +1352,7 @@ void account_history_rocksdb_plugin::plugin_initialize(const boost::program_opti dbPath = actualPath; } - _my = std::make_unique( options, dbPath ); + _my = std::make_unique( *this, options, dbPath ); _my->openDb(); } diff --git a/libraries/plugins/apis/network_broadcast_api/network_broadcast_api.cpp b/libraries/plugins/apis/network_broadcast_api/network_broadcast_api.cpp index 864f7e0c9f..fb8c0a11e6 100644 --- a/libraries/plugins/apis/network_broadcast_api/network_broadcast_api.cpp +++ b/libraries/plugins/apis/network_broadcast_api/network_broadcast_api.cpp @@ -1,8 +1,12 @@ + #include #include #include +#include +#include + #include #include @@ -17,8 +21,8 @@ namespace detail _p2p( appbase::app().get_plugin< steem::plugins::p2p::p2p_plugin >() ), _chain( appbase::app().get_plugin< steem::plugins::chain::chain_plugin >() ) { - _on_applied_block_connection = _chain.db().applied_block_proxy( - [&]( const signed_block& b ){ on_applied_block( b ); }, _chain, 0 ); + _post_apply_block_conn = _chain.db().add_post_apply_block_handler( + [&]( const steem::chain::block_notification& note ){ on_post_apply_block( note ); }, _chain, 0 ); } DECLARE_API_IMPL( @@ -29,13 +33,13 @@ namespace detail bool check_max_block_age( int32_t max_block_age ) const; - void on_applied_block( const signed_block& b ); + void on_post_apply_block( const steem::chain::block_notification& note ); steem::plugins::p2p::p2p_plugin& _p2p; steem::plugins::chain::chain_plugin& _chain; map< transaction_id_type, confirmation_callback > _callbacks; map< time_point_sec, vector< transaction_id_type > > _callback_expirations; - boost::signals2::connection _on_applied_block_connection; + boost::signals2::connection _post_apply_block_conn; boost::mutex _mtx; }; @@ -70,7 +74,7 @@ namespace detail /* It may look strange to call these without the lock and then lock again in the case of an exception, * but it is correct and avoids deadlock. accept_transaction is trained along with all other writes, including * pushing blocks. Pushing blocks do not originate from this code path and will never have this lock. - * However, it will trigger the on_applied_block callback and then attempt to acquire the lock. In this case, + * However, it will trigger the on_post_apply_block callback and then attempt to acquire the lock. In this case, * this thread will be waiting on accept_block so it can write and the block thread will be waiting on this * thread for the lock. */ @@ -85,7 +89,7 @@ namespace detail auto c_itr = _callbacks.find( txid ); if( c_itr != _callbacks.end() ) _callbacks.erase( c_itr ); - // We do not need to clean up _callback_expirations because on_applied_block handles this case. + // We do not need to clean up _callback_expirations because on_post_apply_block handles this case. throw e; } @@ -126,8 +130,9 @@ namespace detail }); } - void network_broadcast_api_impl::on_applied_block( const signed_block& b ) + void network_broadcast_api_impl::on_post_apply_block( const steem::chain::block_notification& note ) { try { + const signed_block& b = note.block; boost::lock_guard< boost::mutex > guard( _mtx ); int32_t block_num = int32_t(b.block_num()); if( _callbacks.size() ) diff --git a/libraries/plugins/block_data_export/CMakeLists.txt b/libraries/plugins/block_data_export/CMakeLists.txt new file mode 100644 index 0000000000..a802ca66a6 --- /dev/null +++ b/libraries/plugins/block_data_export/CMakeLists.txt @@ -0,0 +1,24 @@ +file(GLOB HEADERS "include/steem/plugins/block_data_export/*.hpp") + +add_library( block_data_export_plugin + block_data_export_plugin.cpp + ) + +target_link_libraries( block_data_export_plugin chain_plugin steem_chain steem_protocol ) +target_include_directories( block_data_export_plugin + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) + +if( CLANG_TIDY_EXE ) + set_target_properties( + block_data_export_plugin PROPERTIES + CXX_CLANG_TIDY "${DO_CLANG_TIDY}" + ) +endif( CLANG_TIDY_EXE ) + +install( TARGETS + block_data_export_plugin + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/libraries/plugins/block_data_export/block_data_export_plugin.cpp b/libraries/plugins/block_data_export/block_data_export_plugin.cpp new file mode 100644 index 0000000000..5acdf8d2ab --- /dev/null +++ b/libraries/plugins/block_data_export/block_data_export_plugin.cpp @@ -0,0 +1,306 @@ + +#define BOOST_THREAD_PROVIDES_EXECUTORS +#define BOOST_THREAD_PROVIDES_FUTURE + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +namespace steem { namespace plugins { namespace block_data_export { + +using steem::chain::block_notification; +using steem::chain::database; + +using steem::protocol::block_id_type; + +namespace detail { + +struct api_export_data_object +{ + block_id_type block_id; + flat_map< string, std::shared_ptr< exportable_block_data > > + export_data; + + void clear() + { + block_id = block_id_type(); + export_data.clear(); + } +}; + +} } } } + +FC_REFLECT( steem::plugins::block_data_export::detail::api_export_data_object, (block_id)(export_data) ) + +namespace steem { namespace plugins { namespace block_data_export { namespace detail { + +struct work_item +{ + std::shared_ptr< api_export_data_object > edo; + boost::promise< std::shared_ptr< std::string > > edo_json_promise; + boost::future< std::shared_ptr< std::string > > edo_json_future = edo_json_promise.get_future(); +}; + +class block_data_export_plugin_impl +{ + public: + block_data_export_plugin_impl( block_data_export_plugin& _plugin ) : + _db( appbase::app().get_plugin< steem::plugins::chain::chain_plugin >().db() ), + _self( _plugin ), + _data_queue( _max_queue_size ), + _output_queue( _max_queue_size ) {} + + void on_pre_apply_block( const block_notification& note ); + void on_post_apply_block( const block_notification& note ); + + void register_export_data_factory( const std::string& name, std::function< std::shared_ptr< exportable_block_data >() >& factory ); + void create_export_data( const block_id_type& block_id ); + void send_export_data(); + std::shared_ptr< exportable_block_data > find_abstract_export_data( const std::string& name ); + + void start_threads(); + void stop_threads(); + void convert_to_json_thread_main(); + void output_thread_main(); + + database& _db; + block_data_export_plugin& _self; + boost::signals2::connection _pre_apply_block_conn; + boost::signals2::connection _post_apply_block_conn; + std::shared_ptr< api_export_data_object > + _edo; + std::vector< std::pair< + string, + std::function< std::shared_ptr< exportable_block_data >() > + > > _factory_list; + std::string _output_name; + bool _enabled = false; + + size_t _max_queue_size = 100; + boost::concurrent::sync_bounded_queue< std::shared_ptr< work_item > > _data_queue; + boost::concurrent::sync_bounded_queue< std::shared_ptr< work_item > > _output_queue; + + size_t _thread_stack_size = 4096*1024; + std::shared_ptr< boost::thread > _output_thread; + + std::vector< boost::thread > _json_conversion_threads; +}; + +void block_data_export_plugin_impl::start_threads() +{ + boost::thread::attributes attrs; + attrs.set_stack_size( _thread_stack_size ); + + size_t num_threads = boost::thread::hardware_concurrency()+1; + for( size_t i=0; i( attrs, [this]() { output_thread_main(); } ); +} + +void block_data_export_plugin_impl::stop_threads() +{ + // + // We must close the output queue first: The output queue may be waiting on a future. + // If the conversion threads are still alive, the future will complete, + // the output thread will then wait on _output_queue and see close() has been called. + // + // (If we closed the conversion threads first, the future would never complete, + // and the output thread would wait forever.) + // + _output_queue.close(); + _output_thread->join(); + _output_thread.reset(); + + _data_queue.close(); + for( boost::thread& t : _json_conversion_threads ) + t.join(); + _json_conversion_threads.clear(); +} + +void block_data_export_plugin_impl::convert_to_json_thread_main() +{ + while( true ) + { + std::shared_ptr< work_item > work; + try + { + _data_queue.pull_front( work ); + } + catch( const boost::concurrent::sync_queue_is_closed& e ) + { + break; + } + + // TODO exception handling + std::shared_ptr< std::string > edo_json = std::make_shared< std::string >( fc::json::to_string( work->edo ) ); + work->edo_json_promise.set_value( edo_json ); + } +} + +void block_data_export_plugin_impl::output_thread_main() +{ + std::ofstream output_file( _output_name, std::ios::binary ); + while( true ) + { + std::shared_ptr< work_item > work; + try + { + _output_queue.pull_front( work ); + } + catch( const boost::concurrent::sync_queue_is_closed& e ) + { + break; + } + + std::shared_ptr< std::string > edo_json = work->edo_json_future.get(); + + output_file.write( edo_json->c_str(), edo_json->length() ); + output_file.put( '\n' ); + output_file.flush(); + } +} + +void block_data_export_plugin_impl::register_export_data_factory( + const std::string& name, + std::function< std::shared_ptr< exportable_block_data >() >& factory + ) +{ + _factory_list.emplace_back( name, factory ); +} + +void block_data_export_plugin_impl::create_export_data( const block_id_type& block_id ) +{ + _edo.reset(); + if( !_enabled ) + return; + _edo = std::make_shared< api_export_data_object >(); + + _edo->block_id = block_id; + for( const auto& fact : _factory_list ) + { + _edo->export_data.emplace( fact.first, fact.second() ); + } +} + +void block_data_export_plugin_impl::send_export_data() +{ + std::shared_ptr< work_item > work = std::make_shared< work_item >(); + work->edo = _edo; + _edo.reset(); + + try + { + _data_queue.push_back( work ); + _output_queue.push_back( work ); + } + catch( const boost::concurrent::sync_queue_is_closed& e ) + { + // We should never see this exception because we should be done handling blocks + // by the time we're closing queues + elog( "Caught unexpected sync_queue_is_closed in block_data_export_plugin_impl::push_work()" ); + } + return; +} + +std::shared_ptr< exportable_block_data > block_data_export_plugin_impl::find_abstract_export_data( const std::string& name ) +{ + std::shared_ptr< exportable_block_data > result; + if( !_edo ) + return result; + auto it = _edo->export_data.find(name); + if( it != _edo->export_data.end() ) + result = it->second; + return result; +} + +void block_data_export_plugin_impl::on_pre_apply_block( const block_notification& note ) +{ + create_export_data( note.block_id ); +} + +void block_data_export_plugin_impl::on_post_apply_block( const block_notification& note ) +{ + send_export_data(); +} + +} // detail + +block_data_export_plugin::block_data_export_plugin() {} +block_data_export_plugin::~block_data_export_plugin() {} + +void block_data_export_plugin::register_export_data_factory( + const std::string& name, + std::function< std::shared_ptr< exportable_block_data >() >& factory ) +{ + my->register_export_data_factory( name, factory ); +} + +std::shared_ptr< exportable_block_data > block_data_export_plugin::find_abstract_export_data( const std::string& name ) +{ + return my->find_abstract_export_data( name ); +} + + +void block_data_export_plugin::set_program_options( options_description& cli, options_description& cfg ) +{ + cfg.add_options() + ("block-data-export-file", boost::program_options::value< string >()->default_value("NONE"), "Where to export data (NONE to discard)") + ; +} + +void block_data_export_plugin::plugin_initialize( const boost::program_options::variables_map& options ) +{ + my = std::make_unique< detail::block_data_export_plugin_impl >( *this ); + try + { + ilog( "Initializing block_data_export plugin" ); + + my->_output_name = options.at( "block-data-export-file" ).as< string >(); + my->_enabled = (my->_output_name != "NONE"); + if( !my->_enabled ) + return; + + my->_pre_apply_block_conn = my->_db.add_pre_apply_block_handler( + [&]( const block_notification& note ){ my->on_pre_apply_block( note ); }, *this, -9300 ); + my->_post_apply_block_conn = my->_db.add_post_apply_block_handler( + [&]( const block_notification& note ){ my->on_post_apply_block( note ); }, *this, 9300 ); + + my->start_threads(); + } + FC_CAPTURE_AND_RETHROW() +} + +void block_data_export_plugin::plugin_startup() {} + +void block_data_export_plugin::plugin_shutdown() +{ + if( !my->_enabled ) + return; + + chain::util::disconnect_signal( my->_pre_apply_block_conn ); + chain::util::disconnect_signal( my->_post_apply_block_conn ); + + my->stop_threads(); +} + +exportable_block_data::exportable_block_data() {} +exportable_block_data::~exportable_block_data() {} + +} } } // steem::plugins::block_data_export diff --git a/libraries/plugins/block_data_export/include/steem/plugins/block_data_export/block_data_export_plugin.hpp b/libraries/plugins/block_data_export/include/steem/plugins/block_data_export/block_data_export_plugin.hpp new file mode 100644 index 0000000000..91508b3d8e --- /dev/null +++ b/libraries/plugins/block_data_export/include/steem/plugins/block_data_export/block_data_export_plugin.hpp @@ -0,0 +1,76 @@ +#pragma once +#include + +#include + +namespace steem { namespace plugins { namespace block_data_export { + +namespace detail { class block_data_export_plugin_impl; } + +using namespace appbase; + +#define STEEM_BLOCK_DATA_EXPORT_PLUGIN_NAME "block_data_export" + +class exportable_block_data; + +class block_data_export_plugin : public appbase::plugin< block_data_export_plugin > +{ + public: + block_data_export_plugin(); + virtual ~block_data_export_plugin(); + + APPBASE_PLUGIN_REQUIRES( (steem::plugins::chain::chain_plugin) ) + + static const std::string& name() { static std::string name = STEEM_BLOCK_DATA_EXPORT_PLUGIN_NAME; return name; } + + virtual void set_program_options( options_description& cli, options_description& cfg ) override; + virtual void plugin_initialize( const variables_map& options ) override; + virtual void plugin_startup() override; + virtual void plugin_shutdown() override; + + void register_export_data_factory( const std::string& name, std::function< std::shared_ptr< exportable_block_data >() >& factory ); + + template< typename Callable > + void register_export_data_factory( const std::string& name, Callable lamb ) + { + std::function< std::shared_ptr< exportable_block_data >() > func( lamb ); + register_export_data_factory( name, func ); + } + + void add_abstract_export_data( const std::string& name, std::shared_ptr< exportable_block_data > data ); + std::shared_ptr< exportable_block_data > find_abstract_export_data( const std::string& name ); + + template< typename T > + std::shared_ptr< T > find_export_data( const std::string& name ) + { + std::shared_ptr< exportable_block_data > adata = find_abstract_export_data( name ); + if( !adata ) + return std::shared_ptr(); + std::shared_ptr< T > result = std::dynamic_pointer_cast< T >( adata ); + FC_ASSERT( result, "Could not dynamically cast export data" ); + return result; + } + + template< typename T, typename CtorArg > + std::shared_ptr< T > get_or_create_export_data( const std::string& name, const CtorArg& arg ) + { + std::shared_ptr< T > result = find_export_data( name ); + if( !result ) + { + result = std::make_shared< T >( arg ); + add_abstract_export_data( name, result ); + } + return result; + } + + template< typename T > + void register_export_data_type( const std::string& name ) + { + register_export_data_factory( name, []() -> std::shared_ptr< exportable_block_data > { return std::make_shared(); } ); + } + + private: + std::unique_ptr< detail::block_data_export_plugin_impl > my; +}; + +} } } // steem::plugins::block_data_export diff --git a/libraries/plugins/block_data_export/include/steem/plugins/block_data_export/exportable_block_data.hpp b/libraries/plugins/block_data_export/include/steem/plugins/block_data_export/exportable_block_data.hpp new file mode 100644 index 0000000000..f03b5c0d01 --- /dev/null +++ b/libraries/plugins/block_data_export/include/steem/plugins/block_data_export/exportable_block_data.hpp @@ -0,0 +1,25 @@ +#pragma once + +#include + +namespace steem { namespace plugins { namespace block_data_export { + +class exportable_block_data +{ + public: + exportable_block_data(); + virtual ~exportable_block_data(); + + virtual void to_variant( fc::variant& v )const = 0; +}; + +} } } + +namespace fc { + +inline void to_variant( const steem::plugins::block_data_export::exportable_block_data& ebd, fc::variant& v ) +{ + ebd.to_variant( v ); +} + +} diff --git a/libraries/plugins/block_data_export/plugin.json b/libraries/plugins/block_data_export/plugin.json new file mode 100644 index 0000000000..57aa39f4b6 --- /dev/null +++ b/libraries/plugins/block_data_export/plugin.json @@ -0,0 +1,5 @@ +{ + "plugin_name": "block_data_export", + "plugin_namespace": "block_data_export", + "plugin_project": "block_data_export_plugin" +} diff --git a/libraries/plugins/block_log_info/block_log_info_plugin.cpp b/libraries/plugins/block_log_info/block_log_info_plugin.cpp index 0ea8471a35..45fe691cdb 100644 --- a/libraries/plugins/block_log_info/block_log_info_plugin.cpp +++ b/libraries/plugins/block_log_info/block_log_info_plugin.cpp @@ -22,19 +22,20 @@ class block_log_info_plugin_impl _db( appbase::app().get_plugin< steem::plugins::chain::chain_plugin >().db() ), _self( _plugin ) {} - void on_applied_block( const signed_block& b ); + void on_post_apply_block( const block_notification& note ); void print_message( const block_log_message_data& data ); database& _db; block_log_info_plugin& _self; - boost::signals2::connection on_applied_block_connection; + boost::signals2::connection _post_apply_block_conn; int32_t print_interval_seconds = 0; bool print_irreversible = true; std::string output_name; }; -void block_log_info_plugin_impl::on_applied_block( const signed_block& b ) +void block_log_info_plugin_impl::on_post_apply_block( const block_notification& note ) { + const signed_block& b = note.block; uint32_t block_num = b.block_num(); bool is_genesis = (block_num == 1); @@ -149,8 +150,8 @@ void block_log_info_plugin::plugin_initialize( const boost::program_options::var ilog( "Initializing block_log_info plugin" ); chain::database& db = appbase::app().get_plugin< steem::plugins::chain::chain_plugin >().db(); - my->on_applied_block_connection = db.applied_block_proxy( - [&]( const signed_block& b ){ my->on_applied_block( b ); }, *this ); + my->_post_apply_block_conn = db.add_post_apply_block_handler( + [&]( const block_notification& note ){ my->on_post_apply_block( note ); }, *this ); add_plugin_index< block_log_hash_state_index >(db); add_plugin_index< block_log_pending_message_index >(db); @@ -171,7 +172,7 @@ void block_log_info_plugin::plugin_startup() {} void block_log_info_plugin::plugin_shutdown() { - chain::util::disconnect_signal( my->on_applied_block_connection ); + chain::util::disconnect_signal( my->_post_apply_block_conn ); } } } } // steem::plugins::block_log_info diff --git a/libraries/plugins/debug_node/debug_node_plugin.cpp b/libraries/plugins/debug_node/debug_node_plugin.cpp index c12d7fa412..0a80dac9cc 100644 --- a/libraries/plugins/debug_node/debug_node_plugin.cpp +++ b/libraries/plugins/debug_node/debug_node_plugin.cpp @@ -25,7 +25,7 @@ class debug_node_plugin_impl virtual ~debug_node_plugin_impl(); chain::database& _db; - boost::signals2::connection applied_block_connection; + boost::signals2::connection _post_apply_block_conn; }; debug_node_plugin_impl::debug_node_plugin_impl() : @@ -67,8 +67,8 @@ void debug_node_plugin::plugin_initialize( const variables_map& options ) } // connect needed signals - my->applied_block_connection = my->_db.applied_block_proxy( - [this](const chain::signed_block& b){ on_applied_block(b); }, *this, 0 ); + my->_post_apply_block_conn = my->_db.add_post_apply_block_handler( + [this](const chain::block_notification& note){ on_post_apply_block(note); }, *this, 0 ); } void debug_node_plugin::plugin_startup() @@ -303,7 +303,7 @@ void debug_node_plugin::apply_debug_updates() update( db ); } -void debug_node_plugin::on_applied_block( const chain::signed_block& b ) +void debug_node_plugin::on_post_apply_block( const chain::block_notification& note ) { try { @@ -351,7 +351,7 @@ void debug_node_plugin::on_applied_block( const chain::signed_block& b ) void debug_node_plugin::plugin_shutdown() { - chain::util::disconnect_signal( my->applied_block_connection ); + chain::util::disconnect_signal( my->_post_apply_block_conn ); /*if( _json_object_stream ) { _json_object_stream->close(); diff --git a/libraries/plugins/debug_node/include/steem/plugins/debug_node/debug_node_plugin.hpp b/libraries/plugins/debug_node/include/steem/plugins/debug_node/debug_node_plugin.hpp index 7f7943db25..1e8f03d345 100644 --- a/libraries/plugins/debug_node/include/steem/plugins/debug_node/debug_node_plugin.hpp +++ b/libraries/plugins/debug_node/include/steem/plugins/debug_node/debug_node_plugin.hpp @@ -14,6 +14,10 @@ namespace steem { namespace protocol { struct signed_block; } } +namespace steem { namespace chain { + struct block_notification; +} } + namespace steem { namespace plugins { namespace debug_node { using namespace appbase; @@ -98,7 +102,7 @@ class debug_node_plugin : public plugin< debug_node_plugin > bool logging = true; private: - void on_applied_block( const protocol::signed_block& b ); + void on_post_apply_block( const steem::chain::block_notification& note ); void apply_debug_updates(); @@ -107,9 +111,8 @@ class debug_node_plugin : public plugin< debug_node_plugin > std::shared_ptr< detail::debug_node_plugin_impl > my; //std::shared_ptr< std::ofstream > _json_object_stream; - boost::signals2::scoped_connection _applied_block_conn; - boost::signals2::scoped_connection _changed_objects_conn; - boost::signals2::scoped_connection _removed_objects_conn; + //boost::signals2::scoped_connection _changed_objects_conn; + //boost::signals2::scoped_connection _removed_objects_conn; std::vector< std::string > _edit_scripts; //std::map< protocol::block_id_type, std::vector< fc::variant_object > > _debug_updates; diff --git a/libraries/plugins/follow/follow_plugin.cpp b/libraries/plugins/follow/follow_plugin.cpp index 3e4f3a3e81..8b4b6127d9 100644 --- a/libraries/plugins/follow/follow_plugin.cpp +++ b/libraries/plugins/follow/follow_plugin.cpp @@ -37,8 +37,8 @@ class follow_plugin_impl chain::database& _db; follow_plugin& _self; - boost::signals2::connection pre_apply_connection; - boost::signals2::connection post_apply_connection; + boost::signals2::connection _pre_apply_operation_conn; + boost::signals2::connection _post_apply_operation_conn; }; struct pre_operation_visitor @@ -349,8 +349,8 @@ void follow_plugin::plugin_initialize( const boost::program_options::variables_m // Add the registry to the database so the database can delegate custom ops to the plugin my->_db.set_custom_operation_interpreter( name(), _custom_operation_interpreter ); - my->pre_apply_connection = my->_db.pre_apply_operation_proxy( [&]( const operation_notification& o ){ my->pre_operation( o ); }, *this, 0 ); - my->post_apply_connection = my->_db.post_apply_operation_proxy( [&]( const operation_notification& o ){ my->post_operation( o ); }, *this, 0 ); + my->_pre_apply_operation_conn = my->_db.add_pre_apply_operation_handler( [&]( const operation_notification& note ){ my->pre_operation( note ); }, *this, 0 ); + my->_post_apply_operation_conn = my->_db.add_post_apply_operation_handler( [&]( const operation_notification& note ){ my->post_operation( note ); }, *this, 0 ); add_plugin_index< follow_index >( my->_db ); add_plugin_index< feed_index >( my->_db ); add_plugin_index< blog_index >( my->_db ); @@ -377,8 +377,8 @@ void follow_plugin::plugin_startup() {} void follow_plugin::plugin_shutdown() { - chain::util::disconnect_signal( my->pre_apply_connection ); - chain::util::disconnect_signal( my->post_apply_connection ); + chain::util::disconnect_signal( my->_pre_apply_operation_conn ); + chain::util::disconnect_signal( my->_post_apply_operation_conn ); } } } } // steem::plugins::follow diff --git a/libraries/plugins/market_history/market_history_plugin.cpp b/libraries/plugins/market_history/market_history_plugin.cpp index a1a0cf2601..3a93b45a15 100644 --- a/libraries/plugins/market_history/market_history_plugin.cpp +++ b/libraries/plugins/market_history/market_history_plugin.cpp @@ -23,15 +23,15 @@ class market_history_plugin_impl * This method is called as a callback after a block is applied * and will process/index all operations that were applied in the block. */ - void update_market_histories( const operation_notification& o ); + void on_post_apply_operation( const operation_notification& note ); chain::database& _db; flat_set _tracked_buckets = flat_set { 15, 60, 300, 3600, 86400 }; int32_t _maximum_history_per_bucket_size = 1000; - boost::signals2::connection post_apply_connection; + boost::signals2::connection _post_apply_operation_conn; }; -void market_history_plugin_impl::update_market_histories( const operation_notification& o ) +void market_history_plugin_impl::on_post_apply_operation( const operation_notification& o ) { if( o.op.which() == operation::tag< fill_order_operation >::value ) { @@ -165,7 +165,7 @@ void market_history_plugin::plugin_initialize( const boost::program_options::var ilog( "market_history: plugin_initialize() begin" ); my = std::make_unique< detail::market_history_plugin_impl >(); - my->post_apply_connection = my->_db.post_apply_operation_proxy( [&]( const operation_notification& o ){ my->update_market_histories( o ); }, *this, 0 ); + my->_post_apply_operation_conn = my->_db.add_post_apply_operation_handler( [&]( const operation_notification& note ){ my->on_post_apply_operation( note ); }, *this, 0 ); add_plugin_index< bucket_index >( my->_db ); add_plugin_index< order_history_index >( my->_db ); @@ -188,7 +188,7 @@ void market_history_plugin::plugin_startup() {} void market_history_plugin::plugin_shutdown() { - chain::util::disconnect_signal( my->post_apply_connection ); + chain::util::disconnect_signal( my->_post_apply_operation_conn ); } flat_set< uint32_t > market_history_plugin::get_tracked_buckets() const diff --git a/libraries/plugins/smt_test/smt_test_plugin.cpp b/libraries/plugins/smt_test/smt_test_plugin.cpp index 00d7d1c5fd..626ce2f7c7 100644 --- a/libraries/plugins/smt_test/smt_test_plugin.cpp +++ b/libraries/plugins/smt_test/smt_test_plugin.cpp @@ -19,8 +19,8 @@ class smt_test_plugin_impl _db( appbase::app().get_plugin< steem::plugins::chain::chain_plugin >().db() ), _self( _plugin ) {} - void pre_operation( const operation_notification& op_obj ); - void post_operation( const operation_notification& op_obj ); + void on_pre_apply_operation( const operation_notification& op_obj ); + void on_post_apply_operation( const operation_notification& op_obj ); void clear_cache(); void cache_auths( const account_authority_object& a ); void update_key_lookup( const account_authority_object& a ); @@ -54,12 +54,12 @@ struct post_operation_visitor void operator()( const T& )const {} }; -void smt_test_plugin_impl::pre_operation( const operation_notification& note ) +void smt_test_plugin_impl::on_pre_apply_operation( const operation_notification& note ) { note.op.visit( pre_operation_visitor( *this ) ); } -void smt_test_plugin_impl::post_operation( const operation_notification& note ) +void smt_test_plugin_impl::on_post_apply_operation( const operation_notification& note ) { note.op.visit( post_operation_visitor( *this ) ); } @@ -263,8 +263,8 @@ void smt_test_plugin::plugin_initialize( const boost::program_options::variables ilog( "Initializing smt_test plugin" ); chain::database& db = appbase::app().get_plugin< steem::plugins::chain::chain_plugin >().db(); - db.pre_apply_operation_proxy( [&]( const operation_notification& o ){ my->pre_operation( o ); }, *this, 0 ); - db.post_apply_operation_proxy( [&]( const operation_notification& o ){ my->post_operation( o ); }, *this, 0 ); + db.add_pre_apply_operation_handler( [&]( const operation_notification& note ){ my->on_pre_apply_operation( note ); }, *this, 0 ); + db.add_post_apply_operation_handler( [&]( const operation_notification& note ){ my->on_post_apply_operation( note ); }, *this, 0 ); // add_plugin_index< key_lookup_index >(db); } diff --git a/libraries/plugins/stats_export/CMakeLists.txt b/libraries/plugins/stats_export/CMakeLists.txt new file mode 100644 index 0000000000..4d86c2051c --- /dev/null +++ b/libraries/plugins/stats_export/CMakeLists.txt @@ -0,0 +1,24 @@ +file(GLOB HEADERS "include/steem/plugins/stats_export/*.hpp") + +add_library( stats_export_plugin + stats_export_plugin.cpp + ) + +target_link_libraries( stats_export_plugin block_data_export_plugin chain_plugin steem_chain steem_protocol ) +target_include_directories( stats_export_plugin + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) + +if( CLANG_TIDY_EXE ) + set_target_properties( + stats_export_plugin PROPERTIES + CXX_CLANG_TIDY "${DO_CLANG_TIDY}" + ) +endif( CLANG_TIDY_EXE ) + +install( TARGETS + stats_export_plugin + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/libraries/plugins/stats_export/include/steem/plugins/stats_export/stats_export_plugin.hpp b/libraries/plugins/stats_export/include/steem/plugins/stats_export/stats_export_plugin.hpp new file mode 100644 index 0000000000..c53ba775c8 --- /dev/null +++ b/libraries/plugins/stats_export/include/steem/plugins/stats_export/stats_export_plugin.hpp @@ -0,0 +1,37 @@ +#pragma once +#include + +#include +#include + +namespace steem { namespace plugins { namespace stats_export { + +namespace detail { class stats_export_plugin_impl; } + +using namespace appbase; + +#define STEEM_STATS_EXPORT_PLUGIN_NAME "stats_export" + +class stats_export_plugin : public appbase::plugin< stats_export_plugin > +{ + public: + stats_export_plugin(); + virtual ~stats_export_plugin(); + + APPBASE_PLUGIN_REQUIRES( + (steem::plugins::block_data_export::block_data_export_plugin) + (steem::plugins::chain::chain_plugin) + ) + + static const std::string& name() { static std::string name = STEEM_STATS_EXPORT_PLUGIN_NAME; return name; } + + virtual void set_program_options( options_description& cli, options_description& cfg ) override; + virtual void plugin_initialize( const variables_map& options ) override; + virtual void plugin_startup() override; + virtual void plugin_shutdown() override; + + private: + std::unique_ptr< detail::stats_export_plugin_impl > my; +}; + +} } } // steem::plugins::stats_export diff --git a/libraries/plugins/stats_export/plugin.json b/libraries/plugins/stats_export/plugin.json new file mode 100644 index 0000000000..03323fd50c --- /dev/null +++ b/libraries/plugins/stats_export/plugin.json @@ -0,0 +1,5 @@ +{ + "plugin_name": "stats_export", + "plugin_namespace": "stats_export", + "plugin_project": "stats_export_plugin" +} diff --git a/libraries/plugins/stats_export/stats_export_plugin.cpp b/libraries/plugins/stats_export/stats_export_plugin.cpp new file mode 100644 index 0000000000..cb1691eb03 --- /dev/null +++ b/libraries/plugins/stats_export/stats_export_plugin.cpp @@ -0,0 +1,156 @@ + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace steem { namespace plugins { namespace stats_export { + +using steem::chain::block_notification; +using steem::chain::database; +using steem::chain::dynamic_global_property_object; + +using steem::protocol::account_name_type; +using steem::protocol::authority; +using steem::protocol::signed_transaction; + +using steem::plugins::block_data_export::block_data_export_plugin; +using steem::plugins::block_data_export::exportable_block_data; + +using steem::plugins::chain::chain_plugin; + +namespace detail { + +struct api_stats_transaction_data_object +{ + account_name_type user; + uint32_t size = 0; +}; + +class api_stats_export_data_object + : public exportable_block_data +{ + public: + api_stats_export_data_object() {} + virtual ~api_stats_export_data_object() {} + + virtual void to_variant( fc::variant& v )const override + { + fc::to_variant( *this, v ); + } + + dynamic_global_property_object global_properties; + std::vector< api_stats_transaction_data_object > transaction_stats; + uint64_t free_memory = 0; +}; + +} } } } + +FC_REFLECT( steem::plugins::stats_export::detail::api_stats_transaction_data_object, (user)(size) ) +FC_REFLECT( steem::plugins::stats_export::detail::api_stats_export_data_object, (global_properties)(transaction_stats)(free_memory) ) + +namespace steem { namespace plugins { namespace stats_export { namespace detail { + +class stats_export_plugin_impl +{ + public: + stats_export_plugin_impl( stats_export_plugin& _plugin ) : + _db( appbase::app().get_plugin< chain_plugin >().db() ), + _self( _plugin ), + _export_plugin( appbase::app().get_plugin< block_data_export_plugin >() ) + {} + + void on_post_apply_block( const block_notification& note ); + + database& _db; + stats_export_plugin& _self; + boost::signals2::connection _post_apply_block_conn; + + block_data_export_plugin& _export_plugin; +}; + +account_name_type get_transaction_user( const signed_transaction& tx ) +{ + flat_set< account_name_type > active; + flat_set< account_name_type > owner; + flat_set< account_name_type > posting; + vector< authority > other; + + tx.get_required_authorities( active, owner, posting, other ); + + for( const account_name_type& name : posting ) + return name; + for( const account_name_type& name : active ) + return name; + for( const account_name_type& name : owner ) + return name; + return account_name_type(); +} + +void stats_export_plugin_impl::on_post_apply_block( const block_notification& note ) +{ + std::shared_ptr< api_stats_export_data_object > stats = _export_plugin.find_export_data< api_stats_export_data_object >( STEEM_STATS_EXPORT_PLUGIN_NAME ); + if( !stats ) + return; + + stats->global_properties = _db.get_dynamic_global_properties(); + for( const signed_transaction& tx : note.block.transactions ) + { + stats->transaction_stats.emplace_back(); + + api_stats_transaction_data_object& tx_stats = stats->transaction_stats.back(); + tx_stats.user = get_transaction_user( tx ); + tx_stats.size = fc::raw::pack_size( tx ); + } + + stats->free_memory = _db.get_free_memory(); +} + +} // detail + +stats_export_plugin::stats_export_plugin() {} +stats_export_plugin::~stats_export_plugin() {} + +void stats_export_plugin::set_program_options( options_description& cli, options_description& cfg ) +{ + /* + cfg.add_options() + ("block-log-info-print-interval-seconds", boost::program_options::value< int32_t >()->default_value(60*60*24), "How often to print out stats_export (default 1 day)") + ("block-log-info-print-irreversible", boost::program_options::value< bool >()->default_value(true), "Whether to defer printing until block is irreversible") + ("block-log-info-print-file", boost::program_options::value< string >()->default_value("ILOG"), "Where to print (filename or special sink ILOG, STDOUT, STDERR)") + ; + */ +} + +void stats_export_plugin::plugin_initialize( const boost::program_options::variables_map& options ) +{ + my = std::make_unique< detail::stats_export_plugin_impl >( *this ); + try + { + ilog( "Initializing stats_export plugin" ); + my->_post_apply_block_conn = my->_db.add_post_apply_block_handler( + [&]( const block_notification& note ){ my->on_post_apply_block( note ); }, *this ); + my->_export_plugin.register_export_data_factory( STEEM_STATS_EXPORT_PLUGIN_NAME, + []() -> std::shared_ptr< exportable_block_data > { return std::make_shared< detail::api_stats_export_data_object >(); } ); + } + FC_CAPTURE_AND_RETHROW() +} + +void stats_export_plugin::plugin_startup() {} + +void stats_export_plugin::plugin_shutdown() +{ + chain::util::disconnect_signal( my->_post_apply_block_conn ); +} + +} } } // steem::plugins::stats_export diff --git a/libraries/plugins/tags/tags_plugin.cpp b/libraries/plugins/tags/tags_plugin.cpp index 9062a23ff2..301305bd6f 100644 --- a/libraries/plugins/tags/tags_plugin.cpp +++ b/libraries/plugins/tags/tags_plugin.cpp @@ -56,14 +56,14 @@ class tags_plugin_impl tags_plugin_impl(); virtual ~tags_plugin_impl(); - void pre_operation( const operation_notification& note ); - void on_operation( const operation_notification& note ); + void on_pre_apply_operation( const operation_notification& note ); + void on_post_apply_operation( const operation_notification& note ); chain::database& _db; fc::time_point_sec _promoted_start_time; bool _started = false; - boost::signals2::connection pre_apply_connection; - boost::signals2::connection post_apply_connection; + boost::signals2::connection _pre_apply_operation_conn; + boost::signals2::connection _post_apply_operation_conn; boost::signals2::connection on_sync_connection; void remove_stats( const tag_object& tag, const tag_stats_object& stats )const; @@ -451,7 +451,7 @@ struct operation_visitor void operator()( Op&& )const{} /// ignore all other ops }; -void tags_plugin_impl::pre_operation( const operation_notification& note ) +void tags_plugin_impl::on_pre_apply_operation( const operation_notification& note ) { try { @@ -468,7 +468,7 @@ void tags_plugin_impl::pre_operation( const operation_notification& note ) } } -void tags_plugin_impl::on_operation( const operation_notification& note ) +void tags_plugin_impl::on_post_apply_operation( const operation_notification& note ) { try { @@ -506,8 +506,8 @@ void tags_plugin::plugin_initialize(const boost::program_options::variables_map& ilog("Intializing tags plugin" ); my = std::make_unique< detail::tags_plugin_impl >(); - my->pre_apply_connection = my->_db.pre_apply_operation_proxy( [&]( const operation_notification& note ){ my->pre_operation( note ); }, *this, 0 ); - my->post_apply_connection = my->_db.post_apply_operation_proxy( [&]( const operation_notification& note ){ my->on_operation( note ); }, *this, 0 ); + my->_pre_apply_operation_conn = my->_db.add_pre_apply_operation_handler( [&]( const operation_notification& note ){ my->on_pre_apply_operation( note ); }, *this, 0 ); + my->_post_apply_operation_conn = my->_db.add_post_apply_operation_handler( [&]( const operation_notification& note ){ my->on_post_apply_operation( note ); }, *this, 0 ); if( !options.at( "tags-skip-startup-update" ).as< bool >() ) { @@ -545,8 +545,8 @@ void tags_plugin::plugin_startup() void tags_plugin::plugin_shutdown() { - chain::util::disconnect_signal( my->pre_apply_connection ); - chain::util::disconnect_signal( my->post_apply_connection ); + chain::util::disconnect_signal( my->_pre_apply_operation_conn ); + chain::util::disconnect_signal( my->_post_apply_operation_conn ); } } } } /// steem::plugins::tags diff --git a/libraries/plugins/witness/witness_plugin.cpp b/libraries/plugins/witness/witness_plugin.cpp index db696df1cd..63af0c56b2 100644 --- a/libraries/plugins/witness/witness_plugin.cpp +++ b/libraries/plugins/witness/witness_plugin.cpp @@ -54,9 +54,9 @@ namespace detail { _timer(io), _db( appbase::app().get_plugin< steem::plugins::chain::chain_plugin >().db() ) {} - void pre_transaction( const steem::protocol::signed_transaction& trx ); - void pre_operation( const chain::operation_notification& note ); - void on_block( const signed_block& b ); + void on_pre_apply_transaction( const chain::transaction_notification& note ); + void on_pre_apply_operation( const chain::operation_notification& note ); + void on_post_apply_block( const block_notification& note ); void update_account_bandwidth( const chain::account_object& a, uint32_t trx_size, const bandwidth_type type ); @@ -73,9 +73,9 @@ namespace detail { boost::asio::deadline_timer _timer; chain::database& _db; - boost::signals2::connection pre_apply_connection; - boost::signals2::connection applied_block_connection; - boost::signals2::connection on_pre_apply_transaction_connection; + boost::signals2::connection _pre_apply_operation_conn; + boost::signals2::connection _post_apply_block_conn; + boost::signals2::connection _pre_apply_transaction_conn; }; struct comment_options_extension_visitor @@ -216,8 +216,9 @@ namespace detail { } }; - void witness_plugin_impl::pre_transaction( const steem::protocol::signed_transaction& trx ) + void witness_plugin_impl::on_pre_apply_transaction( const chain::transaction_notification& note ) { + const signed_transaction& trx = note.transaction; flat_set< account_name_type > required; vector other; trx.get_required_authorities( required, required, required, other ); @@ -240,7 +241,7 @@ namespace detail { } } - void witness_plugin_impl::pre_operation( const chain::operation_notification& note ) + void witness_plugin_impl::on_pre_apply_operation( const chain::operation_notification& note ) { if( _db.is_producing() ) { @@ -248,8 +249,9 @@ namespace detail { } } - void witness_plugin_impl::on_block( const signed_block& b ) + void witness_plugin_impl::on_post_apply_block( const block_notification& note ) { try { + const signed_block& b = note.block; int64_t max_block_size = _db.get_dynamic_global_properties().maximum_block_size; auto reserve_ratio_ptr = _db.find( reserve_ratio_id_type() ); @@ -581,12 +583,12 @@ void witness_plugin::plugin_initialize(const boost::program_options::variables_m my->_required_witness_participation = STEEM_1_PERCENT * options.at( "required-participation" ).as< uint32_t >(); } - my->on_pre_apply_transaction_connection = my->_db.on_pre_apply_transaction_proxy( - [&]( const signed_transaction& tx ){ my->pre_transaction( tx ); }, *this, 0 ); - my->pre_apply_connection = my->_db.pre_apply_operation_proxy( - [&]( const operation_notification& note ){ my->pre_operation( note ); }, *this, 0); - my->applied_block_connection = my->_db.applied_block_proxy( - [&]( const signed_block& b ){ my->on_block( b ); }, *this, 0 ); + my->_pre_apply_transaction_conn = my->_db.add_pre_apply_transaction_handler( + [&]( const chain::transaction_notification& note ){ my->on_pre_apply_transaction( note ); }, *this, 0 ); + my->_pre_apply_operation_conn = my->_db.add_pre_apply_operation_handler( + [&]( const chain::operation_notification& note ){ my->on_pre_apply_operation( note ); }, *this, 0); + my->_post_apply_block_conn = my->_db.add_post_apply_block_handler( + [&]( const chain::block_notification& note ){ my->on_post_apply_block( note ); }, *this, 0 ); add_plugin_index< account_bandwidth_index >( my->_db ); add_plugin_index< reserve_ratio_index >( my->_db ); @@ -618,9 +620,9 @@ void witness_plugin::plugin_shutdown() { try { - chain::util::disconnect_signal( my->pre_apply_connection ); - chain::util::disconnect_signal( my->applied_block_connection ); - chain::util::disconnect_signal( my->on_pre_apply_transaction_connection ); + chain::util::disconnect_signal( my->_pre_apply_operation_conn ); + chain::util::disconnect_signal( my->_post_apply_block_conn ); + chain::util::disconnect_signal( my->_pre_apply_transaction_conn ); my->_timer.cancel(); }