From 2b2dbd887d7b57fabfe18d09e2a2bd09e2eec358 Mon Sep 17 00:00:00 2001 From: warptangent Date: Fri, 15 May 2015 17:06:59 -0700 Subject: [PATCH 1/3] Check if chunk size is zero instead of negative This corrects an unnecessary check and fixes compile error on OS X. --- src/blockchain_utilities/blockchain_import.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index 6777cc8f..84153c20 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -288,8 +288,8 @@ int import_from_file(FakeCore& simple_core, std::string& import_file_path, uint6 { LOG_PRINT_L0("NOTE: chunk_size " << chunk_size << " > 100000"); } - else if (chunk_size < 0) { - LOG_PRINT_L0("ERROR: chunk_size " << chunk_size << " < 0"); + else if (chunk_size == 0) { + LOG_PRINT_L0("ERROR: chunk_size == 0"); return 2; } import_file.read(buffer_block, chunk_size); From 73d3511412895b90117e595e031d4e57cc8de314 Mon Sep 17 00:00:00 2001 From: warptangent Date: Fri, 15 May 2015 17:14:36 -0700 Subject: [PATCH 2/3] Rename "--block-number" option to "--block-stop" Update help output for this and other options. --- .../blockchain_export.cpp | 16 +++---- .../blockchain_import.cpp | 47 +++++++++---------- src/blockchain_utilities/bootstrap_file.cpp | 28 ++++++----- 3 files changed, 45 insertions(+), 46 deletions(-) diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp index aa34ea1d..6f67c61c 100644 --- a/src/blockchain_utilities/blockchain_export.cpp +++ b/src/blockchain_utilities/blockchain_export.cpp @@ -38,7 +38,7 @@ using namespace epee; // log_space int main(int argc, char* argv[]) { uint32_t log_level = 0; - uint64_t block_height = 0; + uint64_t block_stop = 0; std::string import_filename = BLOCKCHAIN_RAW; boost::filesystem::path default_data_path {tools::get_default_data_dir()}; @@ -46,9 +46,9 @@ int main(int argc, char* argv[]) po::options_description desc_cmd_only("Command line options"); po::options_description desc_cmd_sett("Command line options and settings options"); - const command_line::arg_descriptor arg_log_level = {"log-level", "", log_level}; - const command_line::arg_descriptor arg_block_height = {"block-number", "", block_height}; - const command_line::arg_descriptor arg_testnet_on = { + const command_line::arg_descriptor arg_log_level = {"log-level", "", log_level}; + const command_line::arg_descriptor arg_block_stop = {"block-stop", "Stop at block number", block_stop}; + const command_line::arg_descriptor arg_testnet_on = { "testnet" , "Run on testnet." , false @@ -57,9 +57,9 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_cmd_sett, command_line::arg_data_dir, default_data_path.string()); command_line::add_arg(desc_cmd_sett, command_line::arg_testnet_data_dir, default_testnet_data_path.string()); - command_line::add_arg(desc_cmd_sett, arg_log_level); - command_line::add_arg(desc_cmd_sett, arg_block_height); command_line::add_arg(desc_cmd_sett, arg_testnet_on); + command_line::add_arg(desc_cmd_sett, arg_log_level); + command_line::add_arg(desc_cmd_sett, arg_block_stop); command_line::add_arg(desc_cmd_only, command_line::arg_help); @@ -84,7 +84,7 @@ int main(int argc, char* argv[]) } log_level = command_line::get_arg(vm, arg_log_level); - block_height = command_line::get_arg(vm, arg_block_height); + block_stop = command_line::get_arg(vm, arg_block_stop); log_space::get_set_log_detalisation_level(true, log_level); log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL); @@ -148,7 +148,7 @@ int main(int argc, char* argv[]) LOG_PRINT_L0("Exporting blockchain raw data..."); BootstrapFile bootstrap; - r = bootstrap.store_blockchain_raw(core_storage, NULL, output_dir, block_height); + r = bootstrap.store_blockchain_raw(core_storage, NULL, output_dir, block_stop); CHECK_AND_ASSERT_MES(r, false, "Failed to export blockchain raw data"); LOG_PRINT_L0("Blockchain raw data exported OK"); } diff --git a/src/blockchain_utilities/blockchain_import.cpp b/src/blockchain_utilities/blockchain_import.cpp index 84153c20..fc00cdcb 100644 --- a/src/blockchain_utilities/blockchain_import.cpp +++ b/src/blockchain_utilities/blockchain_import.cpp @@ -169,7 +169,7 @@ int pop_blocks(FakeCore& simple_core, int num_blocks) } template -int import_from_file(FakeCore& simple_core, std::string& import_file_path, uint64_t stop_height=0) +int import_from_file(FakeCore& simple_core, std::string& import_file_path, uint64_t block_stop=0) { #if !defined(BLOCKCHAIN_DB) static_assert(std::is_same::value || std::is_same::value, @@ -230,15 +230,15 @@ int import_from_file(FakeCore& simple_core, std::string& import_file_path, uint6 // Note that a new blockchain will start with block number 0 (total blocks: 1) // due to genesis block being added at initialization. - if (! stop_height) + if (! block_stop) { - stop_height = total_source_blocks - 1; + block_stop = total_source_blocks - 1; } // These are what we'll try to use, and they don't have to be a determination // from source and destination blockchains, but those are the defaults. LOG_PRINT_L0("start block: " << start_height << " stop block: " << - stop_height); + block_stop); bool use_batch = false; if (opt_batch) @@ -277,7 +277,7 @@ int import_from_file(FakeCore& simple_core, std::string& import_file_path, uint6 { throw std::runtime_error("Error in deserialization of chunk size"); } - LOG_PRINT_L1("chunk_size: " << chunk_size); + LOG_PRINT_L3("chunk_size: " << chunk_size); if (chunk_size > BUFFER_SIZE) { @@ -306,10 +306,10 @@ int import_from_file(FakeCore& simple_core, std::string& import_file_path, uint6 h += NUM_BLOCKS_PER_CHUNK; continue; } - if (h > stop_height) + if (h > block_stop) { std::cout << refresh_string << "block " << h-1 - << " / " << stop_height + << " / " << block_stop << std::flush; std::cout << ENDL << ENDL; LOG_PRINT_L0("Specified block number reached - stopping. block: " << h-1 << " total blocks: " << h); @@ -345,7 +345,7 @@ int import_from_file(FakeCore& simple_core, std::string& import_file_path, uint6 if ((h-1) % progress_interval == 0) { std::cout << refresh_string << "block " << h-1 - << " / " << stop_height + << " / " << block_stop << std::flush; } @@ -531,7 +531,7 @@ int main(int argc, char* argv[]) uint32_t log_level = LOG_LEVEL_0; uint64_t num_blocks = 0; - uint64_t block_height = 0; + uint64_t block_stop = 0; std::string dirname; std::string db_arg_str; @@ -540,10 +540,10 @@ int main(int argc, char* argv[]) po::options_description desc_cmd_only("Command line options"); po::options_description desc_cmd_sett("Command line options and settings options"); - const command_line::arg_descriptor arg_log_level = {"log-level", "", log_level}; - const command_line::arg_descriptor arg_block_height = {"block-number", "stop at block number", block_height}; - const command_line::arg_descriptor arg_batch_size = {"batch-size", "", db_batch_size}; - const command_line::arg_descriptor arg_pop_blocks = {"pop-blocks", "", num_blocks}; + const command_line::arg_descriptor arg_log_level = {"log-level", "", log_level}; + const command_line::arg_descriptor arg_block_stop = {"block-stop", "Stop at block number", block_stop}; + const command_line::arg_descriptor arg_batch_size = {"batch-size", "", db_batch_size}; + const command_line::arg_descriptor arg_pop_blocks = {"pop-blocks", "Remove blocks from end of blockchain", num_blocks}; const command_line::arg_descriptor arg_testnet_on = { "testnet" , "Run on testnet." @@ -567,14 +567,14 @@ int main(int argc, char* argv[]) command_line::add_arg(desc_cmd_sett, command_line::arg_data_dir, default_data_path.string()); command_line::add_arg(desc_cmd_sett, command_line::arg_testnet_data_dir, default_testnet_data_path.string()); - command_line::add_arg(desc_cmd_sett, arg_log_level); - command_line::add_arg(desc_cmd_sett, arg_block_height); - command_line::add_arg(desc_cmd_sett, arg_batch_size); - command_line::add_arg(desc_cmd_sett, arg_pop_blocks); command_line::add_arg(desc_cmd_sett, arg_testnet_on); + command_line::add_arg(desc_cmd_sett, arg_log_level); command_line::add_arg(desc_cmd_sett, arg_database); + command_line::add_arg(desc_cmd_sett, arg_batch_size); + command_line::add_arg(desc_cmd_sett, arg_block_stop); command_line::add_arg(desc_cmd_only, arg_count_blocks); + command_line::add_arg(desc_cmd_only, arg_pop_blocks); command_line::add_arg(desc_cmd_only, command_line::arg_help); // call add_options() directly for these arguments since @@ -602,7 +602,7 @@ int main(int argc, char* argv[]) opt_verify = command_line::get_arg(vm, arg_verify); opt_batch = command_line::get_arg(vm, arg_batch); opt_resume = command_line::get_arg(vm, arg_resume); - block_height = command_line::get_arg(vm, arg_block_height); + block_stop = command_line::get_arg(vm, arg_block_stop); db_batch_size = command_line::get_arg(vm, arg_batch_size); if (command_line::get_arg(vm, command_line::arg_help)) @@ -634,11 +634,6 @@ int main(int argc, char* argv[]) db_batch_size = db_batch_size_verify; } } - uint64_t stop_height = 0; - if (! vm["block-number"].defaulted()) - { - stop_height = block_height; - } std::vector db_engines {"memory", "lmdb"}; @@ -712,12 +707,12 @@ int main(int argc, char* argv[]) if (db_engine == "lmdb") { fake_core_lmdb simple_core(dirname, opt_testnet, opt_batch, mdb_flags); - import_from_file(simple_core, import_file_path, stop_height); + import_from_file(simple_core, import_file_path, block_stop); } else if (db_engine == "memory") { fake_core_memory simple_core(dirname, opt_testnet); - import_from_file(simple_core, import_file_path, stop_height); + import_from_file(simple_core, import_file_path, block_stop); } else { @@ -747,7 +742,7 @@ int main(int argc, char* argv[]) exit(0); } - import_from_file(simple_core, import_file_path, stop_height); + import_from_file(simple_core, import_file_path, block_stop); #endif } diff --git a/src/blockchain_utilities/bootstrap_file.cpp b/src/blockchain_utilities/bootstrap_file.cpp index fb67e12b..70f0b1fe 100644 --- a/src/blockchain_utilities/bootstrap_file.cpp +++ b/src/blockchain_utilities/bootstrap_file.cpp @@ -286,9 +286,9 @@ bool BootstrapFile::close() #if SOURCE_DB == DB_MEMORY -bool BootstrapFile::store_blockchain_raw(blockchain_storage* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_dir, uint64_t requested_block_height) +bool BootstrapFile::store_blockchain_raw(blockchain_storage* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_dir, uint64_t requested_block_stop) #else -bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_dir, uint64_t requested_block_height) +bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_dir, uint64_t requested_block_stop) #endif { uint64_t num_blocks_written = 0; @@ -303,20 +303,24 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem return false; } block b; - uint64_t height_start = m_height; // height_start uses 0-based height, m_height uses 1-based height. so height_start doesn't need to add 1 here, as it's already at the next height - uint64_t height_stop = 0; + + // block_start, block_stop use 0-based height. m_height uses 1-based height. So to resume export + // from last exported block, block_start doesn't need to add 1 here, as it's already at the next + // height. + uint64_t block_start = m_height; + uint64_t block_stop = 0; LOG_PRINT_L0("source blockchain height: " << m_blockchain_storage->get_current_blockchain_height()-1); - if ((requested_block_height > 0) && (requested_block_height < m_blockchain_storage->get_current_blockchain_height())) + if ((requested_block_stop > 0) && (requested_block_stop < m_blockchain_storage->get_current_blockchain_height())) { - LOG_PRINT_L0("Using requested block height: " << requested_block_height); - height_stop = requested_block_height; + LOG_PRINT_L0("Using requested block height: " << requested_block_stop); + block_stop = requested_block_stop; } else { - height_stop = m_blockchain_storage->get_current_blockchain_height() - 1; - LOG_PRINT_L0("Using block height of source blockchain: " << height_stop); + block_stop = m_blockchain_storage->get_current_blockchain_height() - 1; + LOG_PRINT_L0("Using block height of source blockchain: " << block_stop); } - for (m_cur_height = height_start; m_cur_height <= height_stop; ++m_cur_height) + for (m_cur_height = block_start; m_cur_height <= block_stop; ++m_cur_height) { // this method's height refers to 0-based height (genesis block = height 0) crypto::hash hash = m_blockchain_storage->get_block_id_by_height(m_cur_height); @@ -328,7 +332,7 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem } if (m_cur_height % progress_interval == 0) { std::cout << refresh_string; - std::cout << "block " << m_cur_height << "/" << height_stop << std::flush; + std::cout << "block " << m_cur_height << "/" << block_stop << std::flush; } } // NOTE: use of NUM_BLOCKS_PER_CHUNK is a placeholder in case multi-block chunks are later supported. @@ -338,7 +342,7 @@ bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_mem } // print message for last block, which may not have been printed yet due to progress_interval std::cout << refresh_string; - std::cout << "block " << m_cur_height-1 << "/" << height_stop << ENDL; + std::cout << "block " << m_cur_height-1 << "/" << block_stop << ENDL; LOG_PRINT_L0("Number of blocks exported: " << num_blocks_written); if (num_blocks_written > 0) From d35bffb950d7cdfc24c72ef098c3018befad14d6 Mon Sep 17 00:00:00 2001 From: warptangent Date: Sat, 16 May 2015 01:29:02 -0700 Subject: [PATCH 3/3] Allow BlockchainLMDB to be opened in read-only mode Have blockchain_export use read-only mode when source is BlockchainLMDB. --- src/blockchain_db/lmdb/db_lmdb.cpp | 8 ++++++-- src/blockchain_utilities/blockchain_export.cpp | 7 +++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 5126db40..201386e4 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -678,9 +678,13 @@ void BlockchainLMDB::open(const std::string& filename, const int mdb_flags) if (auto result = mdb_env_open(m_env, filename.c_str(), mdb_flags, 0644)) throw0(DB_ERROR(std::string("Failed to open lmdb environment: ").append(mdb_strerror(result)).c_str())); - // get a read/write MDB_txn + int txn_flags = 0; + if (mdb_flags & MDB_RDONLY) + txn_flags |= MDB_RDONLY; + + // get a read/write MDB_txn, depending on mdb_flags mdb_txn_safe txn; - if (mdb_txn_begin(m_env, NULL, 0, txn)) + if (mdb_txn_begin(m_env, NULL, txn_flags, txn)) throw0(DB_ERROR("Failed to create a transaction for the db")); // open necessary databases, and set properties as needed diff --git a/src/blockchain_utilities/blockchain_export.cpp b/src/blockchain_utilities/blockchain_export.cpp index 6f67c61c..ec885ea9 100644 --- a/src/blockchain_utilities/blockchain_export.cpp +++ b/src/blockchain_utilities/blockchain_export.cpp @@ -129,11 +129,14 @@ int main(int argc, char* argv[]) BlockchainDB* db = new BlockchainLMDB(); boost::filesystem::path folder(m_config_folder); folder /= db->get_db_name(); - LOG_PRINT_L0("Loading blockchain from folder " << folder.string() << " ..."); + int lmdb_flags = 0; + lmdb_flags |= MDB_RDONLY; const std::string filename = folder.string(); + + LOG_PRINT_L0("Loading blockchain from folder " << filename << " ..."); try { - db->open(filename); + db->open(filename, lmdb_flags); } catch (const std::exception& e) {