From 9294aa04dd281d471d702d22f306b1e9b1c71524 Mon Sep 17 00:00:00 2001 From: Peter Conrad Date: Mon, 10 Sep 2018 15:55:48 +0200 Subject: [PATCH] Ported snapshot plugin from BTS --- libraries/plugins/CMakeLists.txt | 1 + libraries/plugins/snapshot/CMakeLists.txt | 17 +++ .../include/graphene/snapshot/snapshot.hpp | 56 ++++++++ libraries/plugins/snapshot/snapshot.cpp | 123 ++++++++++++++++++ programs/witness_node/CMakeLists.txt | 2 +- programs/witness_node/main.cpp | 2 + 6 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 libraries/plugins/snapshot/CMakeLists.txt create mode 100644 libraries/plugins/snapshot/include/graphene/snapshot/snapshot.hpp create mode 100644 libraries/plugins/snapshot/snapshot.cpp diff --git a/libraries/plugins/CMakeLists.txt b/libraries/plugins/CMakeLists.txt index b18415f8..f8c5f48d 100644 --- a/libraries/plugins/CMakeLists.txt +++ b/libraries/plugins/CMakeLists.txt @@ -5,3 +5,4 @@ add_subdirectory( delayed_node ) add_subdirectory( generate_genesis ) add_subdirectory( generate_uia_sharedrop_genesis ) add_subdirectory( debug_witness ) +add_subdirectory( snapshot ) diff --git a/libraries/plugins/snapshot/CMakeLists.txt b/libraries/plugins/snapshot/CMakeLists.txt new file mode 100644 index 00000000..227c3860 --- /dev/null +++ b/libraries/plugins/snapshot/CMakeLists.txt @@ -0,0 +1,17 @@ +file(GLOB HEADERS "include/graphene/snapshot/*.hpp") + +add_library( graphene_snapshot + snapshot.cpp + ) + +target_link_libraries( graphene_snapshot graphene_chain graphene_app ) +target_include_directories( graphene_snapshot + PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) + +install( TARGETS + graphene_snapshot + + RUNTIME DESTINATION bin + LIBRARY DESTINATION lib + ARCHIVE DESTINATION lib +) diff --git a/libraries/plugins/snapshot/include/graphene/snapshot/snapshot.hpp b/libraries/plugins/snapshot/include/graphene/snapshot/snapshot.hpp new file mode 100644 index 00000000..b3ee30c6 --- /dev/null +++ b/libraries/plugins/snapshot/include/graphene/snapshot/snapshot.hpp @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017 Peter Conrad, and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#pragma once + +#include +#include + +#include + +namespace graphene { namespace snapshot_plugin { + +class snapshot_plugin : public graphene::app::plugin { + public: + ~snapshot_plugin() {} + + std::string plugin_name()const override; + + virtual void plugin_set_program_options( + boost::program_options::options_description &command_line_options, + boost::program_options::options_description &config_file_options + ) override; + + virtual void plugin_initialize( const boost::program_options::variables_map& options ) override; + virtual void plugin_startup() override; + virtual void plugin_shutdown() override; + + private: + void check_snapshot( const graphene::chain::signed_block& b); + + uint32_t snapshot_block = -1, last_block = 0; + fc::time_point_sec snapshot_time = fc::time_point_sec::maximum(), last_time = fc::time_point_sec(1); + fc::path dest; +}; + +} } //graphene::snapshot_plugin diff --git a/libraries/plugins/snapshot/snapshot.cpp b/libraries/plugins/snapshot/snapshot.cpp new file mode 100644 index 00000000..fe856ecb --- /dev/null +++ b/libraries/plugins/snapshot/snapshot.cpp @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2017 Peter Conrad, and contributors. + * + * The MIT License + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include + +#include + +#include + +using namespace graphene::snapshot_plugin; +using std::string; +using std::vector; + +namespace bpo = boost::program_options; + +static const char* OPT_BLOCK_NUM = "snapshot-at-block"; +static const char* OPT_BLOCK_TIME = "snapshot-at-time"; +static const char* OPT_DEST = "snapshot-to"; + +void snapshot_plugin::plugin_set_program_options( + boost::program_options::options_description& command_line_options, + boost::program_options::options_description& config_file_options) +{ + command_line_options.add_options() + (OPT_BLOCK_NUM, bpo::value(), "Block number after which to do a snapshot") + (OPT_BLOCK_TIME, bpo::value(), "Block time (ISO format) after which to do a snapshot") + (OPT_DEST, bpo::value(), "Pathname of JSON file where to store the snapshot") + ; + config_file_options.add(command_line_options); +} + +std::string snapshot_plugin::plugin_name()const +{ + return "snapshot"; +} + +void snapshot_plugin::plugin_initialize(const boost::program_options::variables_map& options) +{ try { + ilog("snapshot plugin: plugin_initialize() begin"); + + if( options.count(OPT_BLOCK_NUM) || options.count(OPT_BLOCK_TIME) ) + { + FC_ASSERT( options.count(OPT_DEST), "Must specify snapshot-to in addition to snapshot-at-block or snapshot-at-time!" ); + dest = options[OPT_DEST].as(); + if( options.count(OPT_BLOCK_NUM) ) + snapshot_block = options[OPT_BLOCK_NUM].as(); + if( options.count(OPT_BLOCK_TIME) ) + snapshot_time = fc::time_point_sec::from_iso_string( options[OPT_BLOCK_TIME].as() ); + database().applied_block.connect( [&]( const graphene::chain::signed_block& b ) { + check_snapshot( b ); + }); + } + else + FC_ASSERT( !options.count("snapshot-to"), "Must specify snapshot-at-block or snapshot-at-time in addition to snapshot-to!" ); + ilog("snapshot plugin: plugin_initialize() end"); +} FC_LOG_AND_RETHROW() } + +void snapshot_plugin::plugin_startup() {} + +void snapshot_plugin::plugin_shutdown() {} + +static void create_snapshot( const graphene::chain::database& db, const fc::path& dest ) +{ + ilog("snapshot plugin: creating snapshot"); + fc::ofstream out; + try + { + out.open( dest ); + } + catch ( fc::exception& e ) + { + wlog( "Failed to open snapshot destination: ${ex}", ("ex",e) ); + return; + } + for( uint32_t space_id = 0; space_id < 256; space_id++ ) + for( uint32_t type_id = 0; type_id < 256; type_id++ ) + { + try + { + db.get_index( (uint8_t)space_id, (uint8_t)type_id ); + } + catch (fc::assert_exception& e) + { + continue; + } + auto& index = db.get_index( (uint8_t)space_id, (uint8_t)type_id ); + index.inspect_all_objects( [&out]( const graphene::db::object& o ) { + out << fc::json::to_string( o.to_variant() ) << '\n'; + }); + } + out.close(); + ilog("snapshot plugin: created snapshot"); +} + +void snapshot_plugin::check_snapshot( const graphene::chain::signed_block& b ) +{ try { + uint32_t current_block = b.block_num(); + if( (last_block < snapshot_block && snapshot_block <= current_block) + || (last_time < snapshot_time && snapshot_time <= b.timestamp) ) + create_snapshot( database(), dest ); + last_block = current_block; + last_time = b.timestamp; +} FC_LOG_AND_RETHROW() } diff --git a/programs/witness_node/CMakeLists.txt b/programs/witness_node/CMakeLists.txt index 7535d3ad..74327d8a 100644 --- a/programs/witness_node/CMakeLists.txt +++ b/programs/witness_node/CMakeLists.txt @@ -11,7 +11,7 @@ endif() # We have to link against graphene_debug_witness because deficiency in our API infrastructure doesn't allow plugins to be fully abstracted #246 target_link_libraries( witness_node - PRIVATE graphene_app graphene_account_history graphene_market_history graphene_witness graphene_chain graphene_debug_witness graphene_egenesis_full fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) + PRIVATE graphene_app graphene_account_history graphene_market_history graphene_witness graphene_chain graphene_debug_witness graphene_egenesis_full graphene_snapshot fc ${CMAKE_DL_LIBS} ${PLATFORM_SPECIFIC_LIBS} ) # also add dependencies to graphene_generate_genesis graphene_generate_uia_sharedrop_genesis if you want those plugins install( TARGETS diff --git a/programs/witness_node/main.cpp b/programs/witness_node/main.cpp index 2f41676c..1149ad70 100644 --- a/programs/witness_node/main.cpp +++ b/programs/witness_node/main.cpp @@ -28,6 +28,7 @@ #include //#include //#include +#include #include #include @@ -78,6 +79,7 @@ int main(int argc, char** argv) { auto market_history_plug = node->register_plugin(); //auto generate_genesis_plug = node->register_plugin(); //auto generate_uia_sharedrop_genesis_plug = node->register_plugin(); + auto snapshot_plug = node->register_plugin(); try {