BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface software
snapshot.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 Peter Conrad, and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
25 
27 
28 #include <fc/io/fstream.hpp>
29 
30 using namespace graphene::snapshot_plugin;
31 using std::string;
32 using std::vector;
33 
34 namespace bpo = boost::program_options;
35 
36 static const char* OPT_BLOCK_NUM = "snapshot-at-block";
37 static const char* OPT_BLOCK_TIME = "snapshot-at-time";
38 static const char* OPT_DEST = "snapshot-to";
39 
40 void snapshot_plugin::plugin_set_program_options(
41  boost::program_options::options_description& command_line_options,
42  boost::program_options::options_description& config_file_options)
43 {
44  command_line_options.add_options()
45  (OPT_BLOCK_NUM, bpo::value<uint32_t>(), "Block number after which to do a snapshot")
46  (OPT_BLOCK_TIME, bpo::value<string>(), "Block time (ISO format) after which to do a snapshot")
47  (OPT_DEST, bpo::value<string>(), "Pathname of JSON file where to store the snapshot")
48  ;
49  config_file_options.add(command_line_options);
50 }
51 
52 std::string snapshot_plugin::plugin_name()const
53 {
54  return "snapshot";
55 }
56 
58 {
59  return "Create snapshots at a specified time or block number.";
60 }
61 
62 void snapshot_plugin::plugin_initialize(const boost::program_options::variables_map& options)
63 { try {
64  ilog("snapshot plugin: plugin_initialize() begin");
65 
66  if( options.count(OPT_BLOCK_NUM) || options.count(OPT_BLOCK_TIME) )
67  {
68  FC_ASSERT( options.count(OPT_DEST), "Must specify snapshot-to in addition to snapshot-at-block or snapshot-at-time!" );
69  dest = options[OPT_DEST].as<std::string>();
70  if( options.count(OPT_BLOCK_NUM) )
71  snapshot_block = options[OPT_BLOCK_NUM].as<uint32_t>();
72  if( options.count(OPT_BLOCK_TIME) )
73  snapshot_time = fc::time_point_sec::from_iso_string( options[OPT_BLOCK_TIME].as<std::string>() );
74  database().applied_block.connect( [&]( const graphene::chain::signed_block& b ) {
75  check_snapshot( b );
76  });
77  }
78  else
79  FC_ASSERT( !options.count("snapshot-to"), "Must specify snapshot-at-block or snapshot-at-time in addition to snapshot-to!" );
80  ilog("snapshot plugin: plugin_initialize() end");
82 
84 
86 
87 static void create_snapshot( const graphene::chain::database& db, const fc::path& dest )
88 {
89  ilog("snapshot plugin: creating snapshot");
90  fc::ofstream out;
91  try
92  {
93  out.open( dest );
94  }
95  catch ( fc::exception& e )
96  {
97  wlog( "Failed to open snapshot destination: ${ex}", ("ex",e) );
98  return;
99  }
100  for( uint32_t space_id = 0; space_id < 256; space_id++ )
101  for( uint32_t type_id = 0; type_id < 256; type_id++ )
102  {
103  try
104  {
105  db.get_index( (uint8_t)space_id, (uint8_t)type_id );
106  }
107  catch (fc::assert_exception& e)
108  {
109  continue;
110  }
111  auto& index = db.get_index( (uint8_t)space_id, (uint8_t)type_id );
112  index.inspect_all_objects( [&out]( const graphene::db::object& o ) {
113  out << fc::json::to_string( o.to_variant() ) << '\n';
114  });
115  }
116  out.close();
117  ilog("snapshot plugin: created snapshot");
118 }
119 
120 void snapshot_plugin::check_snapshot( const graphene::chain::signed_block& b )
121 { try {
122  uint32_t current_block = b.block_num();
123  if( (last_block < snapshot_block && snapshot_block <= current_block)
124  || (last_time < snapshot_time && snapshot_time <= b.timestamp) )
125  create_snapshot( database(), dest );
126  last_block = current_block;
127  last_time = b.timestamp;
128 } FC_LOG_AND_RETHROW() }
static string to_string(const variant &v, output_formatting format=stringify_large_ints_and_doubles, uint32_t max_depth=DEFAULT_MAX_RECURSION_DEPTH)
Definition: json.cpp:638
fc::time_point_sec timestamp
Definition: block.hpp:35
virtual void plugin_shutdown() override
Cleanly shut down the plugin.
Definition: snapshot.cpp:85
static time_point_sec from_iso_string(const std::string &s)
Definition: time.cpp:35
virtual void plugin_startup() override
Begin normal runtime operations.
Definition: snapshot.cpp:83
fc::signal< void(const signed_block &)> applied_block
Definition: database.hpp:197
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
virtual void plugin_initialize(const boost::program_options::variables_map &options) override
Perform early startup routines and register plugin indexes, callbacks, etc.
Definition: snapshot.cpp:62
Used to generate a useful error report when an exception is thrown.At each level in the stack where t...
Definition: exception.hpp:56
#define wlog(FORMAT,...)
Definition: logger.hpp:123
typename impl::zip< typename impl::make_sequence< length< List >()>::type, List >::type index
Definition: typelist.hpp:225
std::string plugin_description() const override
Definition: snapshot.cpp:57
chain::database & database()
Definition: plugin.hpp:114
const index & get_index() const
#define ilog(FORMAT,...)
Definition: logger.hpp:117
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
std::string plugin_name() const override
Definition: snapshot.cpp:52
virtual variant to_variant() const =0
void open(const fc::path &file, std::ios_base::openmode m=std::ios_base::out|std::ios_base::binary)
Definition: fstream.cpp:32
uint32_t block_num() const
Definition: block.hpp:34
base for all database objects
Definition: object.hpp:62
wraps boost::filesystem::path to provide platform independent path manipulation.
Definition: filesystem.hpp:28
#define FC_LOG_AND_RETHROW()
Definition: exception.hpp:394
void close()
Definition: fstream.cpp:48