From 667e1f5d261cd874cbb2731d28aa34edafd84b7b Mon Sep 17 00:00:00 2001 From: AKorpusenko Date: Fri, 26 Jan 2018 13:50:40 +0300 Subject: [PATCH] Addded block_info plugin. Added plugin to contribution/config.ini. #355 --- contribution/config.ini | 4 +- libraries/plugins/block_info/CMakeLists.txt | 50 ++++++ .../golos/plugins/block_info/block_info.hpp | 39 +++++ .../golos/plugins/block_info/plugin.hpp | 103 ++++++++++++ libraries/plugins/block_info/plugin.cpp | 148 ++++++++++++++++++ programs/golosd/CMakeLists.txt | 1 + programs/golosd/main.cpp | 2 + 7 files changed, 344 insertions(+), 3 deletions(-) create mode 100644 libraries/plugins/block_info/CMakeLists.txt create mode 100644 libraries/plugins/block_info/include/golos/plugins/block_info/block_info.hpp create mode 100644 libraries/plugins/block_info/include/golos/plugins/block_info/plugin.hpp create mode 100644 libraries/plugins/block_info/plugin.cpp diff --git a/contribution/config.ini b/contribution/config.ini index bfb8848342..53b73e8e63 100644 --- a/contribution/config.ini +++ b/contribution/config.ini @@ -35,9 +35,7 @@ rpc-endpoint = 0.0.0.0:2001 shared-file-size = 64G -plugin = chain p2p json_rpc webserver network_broadcast_api witness -plugin = test_api database_api private_message -plugin = follow social_network market_history account_by_key account_history chain_stats +plugin = chain p2p json_rpc webserver network_broadcast_api witness test_api database_api private_message follow social_network market_history account_by_key account_history chain_stats block_info # JSON list of [nblocks,nseconds] pairs, see documentation/bcd-trigger.md bcd-trigger = [[0,10],[85,300]] diff --git a/libraries/plugins/block_info/CMakeLists.txt b/libraries/plugins/block_info/CMakeLists.txt new file mode 100644 index 0000000000..c2e364c512 --- /dev/null +++ b/libraries/plugins/block_info/CMakeLists.txt @@ -0,0 +1,50 @@ +set(CURRENT_TARGET block_info) + +list(APPEND CURRENT_TARGET_HEADERS + include/golos/plugins/block_info/plugin.hpp + include/golos/plugins/block_info/block_info.hpp +) + +list(APPEND CURRENT_TARGET_SOURCES + plugin.cpp +) + +if(BUILD_SHARED_LIBRARIES) + add_library(golos_${CURRENT_TARGET} SHARED + ${CURRENT_TARGET_HEADERS} + ${CURRENT_TARGET_SOURCES} + ) +else() + add_library(golos_${CURRENT_TARGET} STATIC + ${CURRENT_TARGET_HEADERS} + ${CURRENT_TARGET_SOURCES} + ) +endif() + +add_library(golos::${CURRENT_TARGET} ALIAS golos_${CURRENT_TARGET}) + +set_property(TARGET golos_${CURRENT_TARGET} PROPERTY EXPORT_NAME ${CURRENT_TARGET}) + +target_link_libraries( + golos_${CURRENT_TARGET} + golos_chain + golos_protocol + appbase + golos_chain_plugin + golos_json_rpc_plugin + fc +) + +target_include_directories( + golos_${CURRENT_TARGET} + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" + "${CMAKE_CURRENT_SOURCE_DIR}/../../" +) + +install(TARGETS + golos_${CURRENT_TARGET} + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/libraries/plugins/block_info/include/golos/plugins/block_info/block_info.hpp b/libraries/plugins/block_info/include/golos/plugins/block_info/block_info.hpp new file mode 100644 index 0000000000..eb79796b83 --- /dev/null +++ b/libraries/plugins/block_info/include/golos/plugins/block_info/block_info.hpp @@ -0,0 +1,39 @@ +#pragma once + +#include + +namespace golos { +namespace plugins { +namespace block_info { + +struct block_info { + golos::chain::block_id_type block_id; + uint32_t block_size = 0; + uint32_t average_block_size = 0; + uint64_t aslot = 0; + uint32_t last_irreversible_block_num = 0; + uint32_t num_pow_witnesses = 0; +}; + +struct block_with_info { + golos::chain::signed_block block; + block_info info; +}; + +} } } + + +FC_REFLECT( (golos::plugins::block_info::block_info), + (block_id) + (block_size) + (average_block_size) + (aslot) + (last_irreversible_block_num) + (num_pow_witnesses) +) + + +FC_REFLECT( (golos::plugins::block_info::block_with_info), + (block) + (info) +) diff --git a/libraries/plugins/block_info/include/golos/plugins/block_info/plugin.hpp b/libraries/plugins/block_info/include/golos/plugins/block_info/plugin.hpp new file mode 100644 index 0000000000..5260e9d751 --- /dev/null +++ b/libraries/plugins/block_info/include/golos/plugins/block_info/plugin.hpp @@ -0,0 +1,103 @@ +#pragma once + +#include +#include + +#include +#include +#include +#include +#include +#include + +namespace golos { +namespace protocol { + +struct signed_block; + +} } + + +namespace golos { +namespace plugins { +namespace block_info { + +using golos::plugins::json_rpc::msg_pack; + +struct get_block_info_a { + uint32_t start_block_num = 0; + uint32_t count = 1000; +}; + +struct get_blocks_with_info_a { + uint32_t start_block_num = 0; + uint32_t count = 1000; +}; + +struct get_block_info_r { + std::vector block_info_vec; +}; + +struct get_blocks_with_info_r { + std::vector block_with_info_vec; +}; + +DEFINE_API_ARGS ( get_block_info, msg_pack, get_block_info_r ) +DEFINE_API_ARGS ( get_blocks_with_info, msg_pack, get_blocks_with_info_r ) + + +using boost::program_options::options_description; + +class plugin final : public appbase::plugin { +public: + APPBASE_PLUGIN_REQUIRES((golos::plugins::chain::plugin)) + + constexpr const static char *plugin_name = "block_info"; + + static const std::string &name() { + static std::string name = plugin_name; + return name; + } + + plugin(); + + ~plugin(); + + void set_program_options(boost::program_options::options_description &cli, boost::program_options::options_description &cfg) override { + } + + void plugin_initialize(const boost::program_options::variables_map &options) override; + + void plugin_startup() override; + + void plugin_shutdown() override; + + DECLARE_API( + (get_block_info) + (get_blocks_with_info) + ) + void on_applied_block(const protocol::signed_block &b); + +private: + struct plugin_impl; + + std::unique_ptr my; +}; + +} } } + +FC_REFLECT((golos::plugins::block_info::get_block_info_a), + (start_block_num)(count) +) + +FC_REFLECT((golos::plugins::block_info::get_blocks_with_info_a), + (start_block_num)(count) +) + +FC_REFLECT((golos::plugins::block_info::get_block_info_r), + (block_info_vec) +) + +FC_REFLECT((golos::plugins::block_info::get_blocks_with_info_r), + (block_with_info_vec) +) diff --git a/libraries/plugins/block_info/plugin.cpp b/libraries/plugins/block_info/plugin.cpp new file mode 100644 index 0000000000..20d3573282 --- /dev/null +++ b/libraries/plugins/block_info/plugin.cpp @@ -0,0 +1,148 @@ +#include + +#include + +#include +#include +#include + +namespace golos { +namespace plugins { +namespace block_info { + +using namespace golos::chain; + +struct plugin::plugin_impl { +public: + plugin_impl() : db_(appbase::app().get_plugin().db()) { + } + + // API + get_block_info_r get_block_info(const get_block_info_a & args); + get_blocks_with_info_r get_blocks_with_info(const get_blocks_with_info_a & args); + + // PLUGIN_METHODS + void on_applied_block(const protocol::signed_block &b); + + // HELPING METHODS + golos::chain::database &database() { + return db_; + } +// protected: + boost::signals2::scoped_connection applied_block_conn_; +private: + std::vector block_info_; + + golos::chain::database & db_; +}; + +get_block_info_r plugin::plugin_impl::get_block_info(const get_block_info_a & args) { + get_block_info_r result; + + FC_ASSERT(args.start_block_num > 0); + FC_ASSERT(args.count <= 10000); + uint32_t n = std::min(uint32_t(block_info_.size()), + args.start_block_num + args.count); + + for (uint32_t block_num = args.start_block_num; + block_num < n; block_num++) { + result.block_info_vec.emplace_back(block_info_[block_num]); + } + + return result; +} + +get_blocks_with_info_r plugin::plugin_impl::get_blocks_with_info(const get_blocks_with_info_a & args) { + get_blocks_with_info_r result; + const auto & db = database(); + + FC_ASSERT(args.start_block_num > 0); + FC_ASSERT(args.count <= 10000); + uint32_t n = std::min( uint32_t( block_info_.size() ), args.start_block_num + args.count ); + + uint64_t total_size = 0; + for (uint32_t block_num = args.start_block_num; + block_num < n; block_num++) { + uint64_t new_size = + total_size + block_info_[block_num].block_size; + if ((new_size > 8 * 1024 * 1024) && + (block_num != args.start_block_num)) { + break; + } + total_size = new_size; + result.block_with_info_vec.emplace_back(); + result.block_with_info_vec.back().block = *db.fetch_block_by_number(block_num); + result.block_with_info_vec.back().info = block_info_[block_num]; + } + + return result; +} + +void plugin::plugin_impl::on_applied_block(const protocol::signed_block &b) { + uint32_t block_num = b.block_num(); + const auto &db = appbase::app().get_plugin().db(); + + while (block_num >= block_info_.size()) { + block_info_.emplace_back(); + } + + block_info &info = block_info_[block_num]; + const dynamic_global_property_object &dgpo = db.get_dynamic_global_properties(); + + info.block_id = b.id(); + info.block_size = fc::raw::pack_size(b); + info.average_block_size = dgpo.average_block_size; + info.aslot = dgpo.current_aslot; + info.last_irreversible_block_num = dgpo.last_irreversible_block_num; + info.num_pow_witnesses = dgpo.num_pow_witnesses; + return; +} + + +DEFINE_API ( plugin, get_block_info ) { + auto tmp = args.args->at(0).as(); + auto &db = my->database(); + return db.with_read_lock([&]() { + return my->get_block_info(tmp);; + }); +} + +DEFINE_API ( plugin, get_blocks_with_info ) { + auto tmp = args.args->at(0).as(); + auto &db = my->database(); + return db.with_read_lock([&]() { + return my->get_blocks_with_info(tmp); + }); +} + +void plugin::on_applied_block(const protocol::signed_block &b) { + return my->on_applied_block(b); +} + + +plugin::plugin() { +} + +plugin::~plugin() { +} + +void plugin::plugin_initialize(const boost::program_options::variables_map &options) { + + auto &db = appbase::app().get_plugin().db(); + + my.reset(new plugin_impl); + + my->applied_block_conn_ = db.applied_block.connect([this](const protocol::signed_block &b) { + on_applied_block(b); + }); + + JSON_RPC_REGISTER_API ( name() ) ; +} + +void plugin::plugin_startup() { +} + +void plugin::plugin_shutdown() { +} + +} } } // golos::plugin::block_info diff --git a/programs/golosd/CMakeLists.txt b/programs/golosd/CMakeLists.txt index 13fef38e3a..1dcf896766 100644 --- a/programs/golosd/CMakeLists.txt +++ b/programs/golosd/CMakeLists.txt @@ -31,6 +31,7 @@ target_link_libraries( golos::account_history golos::private_message_plugin golos::auth_util + golos::block_info golos_protocol fc ${CMAKE_DL_LIBS} diff --git a/programs/golosd/main.cpp b/programs/golosd/main.cpp index 1a84706dc8..85c5a347c2 100644 --- a/programs/golosd/main.cpp +++ b/programs/golosd/main.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -100,6 +101,7 @@ int main( int argc, char** argv ) { appbase::app().register_plugin(); appbase::app().register_plugin(); appbase::app().register_plugin(); + appbase::app().register_plugin(); ///plugins appbase::app().set_version_string( version_string() );