Merge pull request #286
d35bffb
Allow BlockchainLMDB to be opened in read-only mode (warptangent)73d3511
Rename "--block-number" option to "--block-stop" (warptangent)2b2dbd8
Check if chunk size is zero instead of negative (warptangent)
This commit is contained in:
commit
2dc1cd9ae6
4 changed files with 58 additions and 52 deletions
|
@ -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
|
||||
|
|
|
@ -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<uint32_t> arg_log_level = {"log-level", "", log_level};
|
||||
const command_line::arg_descriptor<uint64_t> arg_block_height = {"block-number", "", block_height};
|
||||
const command_line::arg_descriptor<bool> arg_testnet_on = {
|
||||
const command_line::arg_descriptor<uint32_t> arg_log_level = {"log-level", "", log_level};
|
||||
const command_line::arg_descriptor<uint64_t> arg_block_stop = {"block-stop", "Stop at block number", block_stop};
|
||||
const command_line::arg_descriptor<bool> 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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -148,7 +151,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");
|
||||
}
|
||||
|
|
|
@ -169,7 +169,7 @@ int pop_blocks(FakeCore& simple_core, int num_blocks)
|
|||
}
|
||||
|
||||
template <typename FakeCore>
|
||||
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<fake_core_memory, FakeCore>::value || std::is_same<fake_core_lmdb, FakeCore>::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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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<uint32_t> arg_log_level = {"log-level", "", log_level};
|
||||
const command_line::arg_descriptor<uint64_t> arg_block_height = {"block-number", "stop at block number", block_height};
|
||||
const command_line::arg_descriptor<uint64_t> arg_batch_size = {"batch-size", "", db_batch_size};
|
||||
const command_line::arg_descriptor<uint64_t> arg_pop_blocks = {"pop-blocks", "", num_blocks};
|
||||
const command_line::arg_descriptor<uint32_t> arg_log_level = {"log-level", "", log_level};
|
||||
const command_line::arg_descriptor<uint64_t> arg_block_stop = {"block-stop", "Stop at block number", block_stop};
|
||||
const command_line::arg_descriptor<uint64_t> arg_batch_size = {"batch-size", "", db_batch_size};
|
||||
const command_line::arg_descriptor<uint64_t> arg_pop_blocks = {"pop-blocks", "Remove blocks from end of blockchain", num_blocks};
|
||||
const command_line::arg_descriptor<bool> 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<std::string> 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
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue