Electroneum
Loading...
Searching...
No Matches
blockchain_export.cpp
Go to the documentation of this file.
1// Copyrights(c) 2017-2021, The Electroneum Project
2// Copyrights(c) 2014-2019, The Monero Project
3//
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without modification, are
7// permitted provided that the following conditions are met:
8//
9// 1. Redistributions of source code must retain the above copyright notice, this list of
10// conditions and the following disclaimer.
11//
12// 2. Redistributions in binary form must reproduce the above copyright notice, this list
13// of conditions and the following disclaimer in the documentation and/or other
14// materials provided with the distribution.
15//
16// 3. Neither the name of the copyright holder nor the names of its contributors may be
17// used to endorse or promote products derived from this software without specific
18// prior written permission.
19//
20// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
21// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
22// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
23// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
27// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
28// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30#include "bootstrap_file.h"
31#include "blocksdat_file.h"
32#include "common/command_line.h"
37#include "version.h"
38
39#undef ELECTRONEUM_DEFAULT_LOG_CATEGORY
40#define ELECTRONEUM_DEFAULT_LOG_CATEGORY "bcutil"
41
42namespace po = boost::program_options;
43using namespace epee;
44
45int main(int argc, char* argv[])
46{
47 TRY_ENTRY();
48
50
51 std::string default_db_type = "lmdb";
52
53 std::string available_dbs = cryptonote::blockchain_db_types(", ");
54 available_dbs = "available: " + available_dbs;
55
56 uint32_t log_level = 0;
57 uint64_t block_stop = 0;
58 bool blocks_dat = false;
59
61
62 boost::filesystem::path output_file_path;
63
64 po::options_description desc_cmd_only("Command line options");
65 po::options_description desc_cmd_sett("Command line options and settings options");
66 const command_line::arg_descriptor<std::string> arg_output_file = {"output-file", "Specify output file", "", true};
67 const command_line::arg_descriptor<std::string> arg_log_level = {"log-level", "0-4 or categories", ""};
68 const command_line::arg_descriptor<uint64_t> arg_block_stop = {"block-stop", "Stop at block number", block_stop};
70 "database", available_dbs.c_str(), default_db_type
71 };
72 const command_line::arg_descriptor<bool> arg_blocks_dat = {"blocksdat", "Output in blocks.dat format", blocks_dat};
73
74
76 command_line::add_arg(desc_cmd_sett, arg_output_file);
79 command_line::add_arg(desc_cmd_sett, arg_log_level);
80 command_line::add_arg(desc_cmd_sett, arg_database);
81 command_line::add_arg(desc_cmd_sett, arg_block_stop);
82 command_line::add_arg(desc_cmd_sett, arg_blocks_dat);
83
85
86 po::options_description desc_options("Allowed options");
87 desc_options.add(desc_cmd_only).add(desc_cmd_sett);
88
89 po::variables_map vm;
90 bool r = command_line::handle_error_helper(desc_options, [&]()
91 {
92 po::store(po::parse_command_line(argc, argv, desc_options), vm);
93 po::notify(vm);
94 return true;
95 });
96 if (! r)
97 return 1;
98
100 {
101 std::cout << "Electroneum '" << ELECTRONEUM_RELEASE_NAME << "' (v" << ELECTRONEUM_VERSION_FULL << ")" << ENDL << ENDL;
102 std::cout << desc_options << std::endl;
103 return 1;
104 }
105
106 mlog_configure(mlog_get_default_log_path("electroneum-blockchain-export.log"), true);
107 if (!command_line::is_arg_defaulted(vm, arg_log_level))
108 mlog_set_log(command_line::get_arg(vm, arg_log_level).c_str());
109 else
110 mlog_set_log(std::string(std::to_string(log_level) + ",bcutil:INFO").c_str());
111 block_stop = command_line::get_arg(vm, arg_block_stop);
112
113 LOG_PRINT_L0("Starting...");
114
116 bool opt_stagenet = command_line::get_arg(vm, cryptonote::arg_stagenet_on);
117 if (opt_testnet && opt_stagenet)
118 {
119 std::cerr << "Can't specify more than one of --testnet and --stagenet" << std::endl;
120 return 1;
121 }
122 bool opt_blocks_dat = command_line::get_arg(vm, arg_blocks_dat);
123
124 std::string m_config_folder;
125
126 m_config_folder = command_line::get_arg(vm, cryptonote::arg_data_dir);
127
128 std::string db_type = command_line::get_arg(vm, arg_database);
130 {
131 std::cerr << "Invalid database type: " << db_type << std::endl;
132 return 1;
133 }
134
135 if (command_line::has_arg(vm, arg_output_file))
136 output_file_path = boost::filesystem::path(command_line::get_arg(vm, arg_output_file));
137 else
138 output_file_path = boost::filesystem::path(m_config_folder) / "export" / BLOCKCHAIN_RAW;
139 LOG_PRINT_L0("Export output file: " << output_file_path.string());
140
141 // If we wanted to use the memory pool, we would set up a fake_core.
142
143 // Use Blockchain instead of lower-level BlockchainDB for two reasons:
144 // 1. Blockchain has the init() method for easy setup
145 // 2. exporter needs to use get_current_blockchain_height(), get_block_id_by_height(), get_block_by_hash()
146 //
147 // cannot match blockchain_storage setup above with just one line,
148 // e.g.
149 // Blockchain* core_storage = new Blockchain(NULL);
150 // because unlike blockchain_storage constructor, which takes a pointer to
151 // tx_memory_pool, Blockchain's constructor takes tx_memory_pool object.
152 LOG_PRINT_L0("Initializing source blockchain (BlockchainDB)");
153 Blockchain* core_storage = NULL;
154 tx_memory_pool m_mempool(*core_storage);
155 core_storage = new Blockchain(m_mempool);
156
157 BlockchainDB* db = new_db(db_type);
158 if (db == NULL)
159 {
160 LOG_ERROR("Attempted to use non-existent database type: " << db_type);
161 throw std::runtime_error("Attempting to use non-existent database type");
162 }
163 LOG_PRINT_L0("database: " << db_type);
164
165 boost::filesystem::path folder(m_config_folder);
166 folder /= db->get_db_name();
167 const std::string filename = folder.string();
168
169 LOG_PRINT_L0("Loading blockchain from folder " << filename << " ...");
170 try
171 {
172 db->open(filename, DBF_RDONLY);
173 }
174 catch (const std::exception& e)
175 {
176 LOG_PRINT_L0("Error opening database: " << e.what());
177 return 1;
178 }
179 r = core_storage->init(db, opt_testnet ? cryptonote::TESTNET : opt_stagenet ? cryptonote::STAGENET : cryptonote::MAINNET);
180
181 if (core_storage->get_blockchain_pruning_seed())
182 {
183 LOG_PRINT_L0("Blockchain is pruned, cannot export");
184 return 1;
185 }
186
187 CHECK_AND_ASSERT_MES(r, 1, "Failed to initialize source blockchain storage");
188 LOG_PRINT_L0("Source blockchain storage initialized OK");
189 LOG_PRINT_L0("Exporting blockchain raw data...");
190
191 if (opt_blocks_dat)
192 {
193 BlocksdatFile blocksdat;
194 r = blocksdat.store_blockchain_raw(core_storage, NULL, output_file_path, block_stop);
195 }
196 else
197 {
199 r = bootstrap.store_blockchain_raw(core_storage, NULL, output_file_path, block_stop);
200 }
201 CHECK_AND_ASSERT_MES(r, 1, "Failed to export blockchain raw data");
202 LOG_PRINT_L0("Blockchain raw data exported OK");
203 return 0;
204
205 CATCH_ENTRY("Export error", 1);
206}
int main()
#define DBF_RDONLY
#define BLOCKCHAIN_RAW
bool store_blockchain_raw(cryptonote::Blockchain *cs, cryptonote::tx_memory_pool *txp, boost::filesystem::path &output_file, uint64_t use_block_height=0)
The BlockchainDB backing store interface declaration/contract.
virtual std::string get_db_name() const =0
gets the name of the folder the BlockchainDB's file(s) should be in
virtual void open(const std::string &filename, const int db_flags=0)=0
open a db, or create it if necessary.
bool init(BlockchainDB *db, const network_type nettype=MAINNET, bool offline=false, const cryptonote::test_options *test_options=NULL, difficulty_type fixed_difficulty=0, const GetCheckpointsCallback &get_checkpoints=nullptr, bool ignore_bsig=false, bool fallback_to_pow=false)
Initialize the Blockchain state.
uint32_t get_blockchain_pruning_seed() const
Transaction pool, handles transactions which are not part of a block.
Definition tx_pool.h:95
void mlog_configure(const std::string &filename_base, bool console, const std::size_t max_log_file_size=MAX_LOG_FILE_SIZE, const std::size_t max_log_files=MAX_LOG_FILES)
Definition mlog.cpp:148
#define CATCH_ENTRY(location, return_val)
std::string mlog_get_default_log_path(const char *default_filename)
Definition mlog.cpp:72
void mlog_set_log(const char *log)
Definition mlog.cpp:288
#define ENDL
#define CHECK_AND_ASSERT_MES(expr, fail_ret_val, message)
#define LOG_ERROR(x)
Definition misc_log_ex.h:98
#define TRY_ENTRY()
#define LOG_PRINT_L0(x)
Definition misc_log_ex.h:99
void add_arg(boost::program_options::options_description &description, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg, bool unique=true)
const arg_descriptor< bool > arg_help
bool is_arg_defaulted(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
bool handle_error_helper(const boost::program_options::options_description &desc, F parser)
std::enable_if<!std::is_same< T, bool >::value, bool >::type has_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, required, dependent, NUM_DEPS > &arg)
T get_arg(const boost::program_options::variables_map &vm, const arg_descriptor< T, false, true > &arg)
const command_line::arg_descriptor< std::string, false, true, 2 > arg_data_dir
const command_line::arg_descriptor< bool, false > arg_testnet_on
BlockchainDB * new_db(const std::string &db_type)
bool blockchain_valid_db_type(const std::string &db_type)
const command_line::arg_descriptor< bool, false > arg_stagenet_on
std::string blockchain_db_types(const std::string &sep)
bool set_module_name_and_folder(const std::string &path_to_process_)
bool on_startup()
Definition util.cpp:778
unsigned int uint32_t
Definition stdint.h:126
unsigned __int64 uint64_t
Definition stdint.h:136
const char *const ELECTRONEUM_RELEASE_NAME
const char *const ELECTRONEUM_VERSION_FULL