remove original Cryptonote blockchain_storage blockchain format

pull/95/head
moneromooo-monero 8 years ago
parent 86b4426191
commit 9e82b694da
No known key found for this signature in database
GPG Key ID: 686F07454D6CEFC3

@ -235,10 +235,6 @@ elseif (DATABASE STREQUAL "berkeleydb")
message(STATUS "Using Berkeley DB as default DB type") message(STATUS "Using Berkeley DB as default DB type")
add_definitions("-DDEFAULT_DB_TYPE=\"berkeley\"") add_definitions("-DDEFAULT_DB_TYPE=\"berkeley\"")
elseif (DATABASE STREQUAL "memory")
set(BLOCKCHAIN_DB DB_MEMORY)
message(STATUS "Using Serialised In Memory as default DB type")
add_definitions("-DDEFAULT_DB_TYPE=\"memory\"")
else() else()
die("Invalid database type: ${DATABASE}") die("Invalid database type: ${DATABASE}")
endif() endif()

@ -26,15 +26,6 @@
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
set(blockchain_converter_sources
blockchain_converter.cpp
)
set(blockchain_converter_private_headers)
bitmonero_private_headers(blockchain_converter
${blockchain_converter_private_headers})
set(blockchain_import_sources set(blockchain_import_sources
blockchain_import.cpp blockchain_import.cpp
bootstrap_file.cpp bootstrap_file.cpp
@ -87,30 +78,6 @@ bitmonero_private_headers(cn_deserialize
${cn_deserialize_private_headers}) ${cn_deserialize_private_headers})
if (BLOCKCHAIN_DB STREQUAL DB_LMDB)
bitmonero_add_executable(blockchain_converter
${blockchain_converter_sources}
${blockchain_converter_private_headers})
target_link_libraries(blockchain_converter
LINK_PRIVATE
cryptonote_core
p2p
blockchain_db
${CMAKE_THREAD_LIBS_INIT})
if(ARCH_WIDTH)
target_compile_definitions(blockchain_converter
PUBLIC -DARCH_WIDTH=${ARCH_WIDTH})
endif()
add_dependencies(blockchain_converter
version)
set_property(TARGET blockchain_converter
PROPERTY
OUTPUT_NAME "blockchain_converter")
endif ()
bitmonero_add_executable(blockchain_import bitmonero_add_executable(blockchain_import
${blockchain_import_sources} ${blockchain_import_sources}
${blockchain_import_private_headers}) ${blockchain_import_private_headers})

@ -18,9 +18,10 @@ e.g.
This is also the default compile setting on the master branch. This is also the default compile setting on the master branch.
By default, the exporter will use the original in-memory database (blockchain.bin) as its source. The exporter will use the LMDB database as its source.
This default is to make migrating to an LMDB database easy, without having to recompile anything. If you are still using an old style in-memory database (blockchain.bin), you will
To change the source, adjust `SOURCE_DB` in `src/blockchain_utilities/bootstrap_file.h` according to the comments. have to either resync from scratch, or use an older version of the tools to export
it and import it.
## Usage: ## Usage:

@ -1,306 +0,0 @@
// Copyright (c) 2014-2016, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "include_base_utils.h"
#include "common/util.h"
#include "warnings.h"
#include "crypto/crypto.h"
#include "cryptonote_config.h"
#include "cryptonote_core/cryptonote_format_utils.h"
#include "misc_language.h"
#include "cryptonote_core/blockchain_storage.h"
#include "blockchain_db/blockchain_db.h"
#include "cryptonote_core/blockchain.h"
#include "blockchain_db/lmdb/db_lmdb.h"
#include "cryptonote_core/tx_pool.h"
#include "common/command_line.h"
#include "serialization/json_utils.h"
#include "include_base_utils.h"
#include "version.h"
#include <iostream>
namespace
{
// CONFIG
bool opt_batch = true;
bool opt_resume = true;
bool opt_testnet = false;
// number of blocks per batch transaction
// adjustable through command-line argument according to available RAM
#if ARCH_WIDTH != 32
uint64_t db_batch_size_verify = 5000;
#else
// set a lower default batch size for Windows, pending possible LMDB issue with
// large batch size.
uint64_t db_batch_size_verify = 100;
#endif
// converter only uses verify mode
uint64_t db_batch_size = db_batch_size_verify;
}
namespace po = boost::program_options;
using namespace cryptonote;
using namespace epee;
struct fake_core
{
Blockchain dummy;
tx_memory_pool m_pool;
blockchain_storage m_storage;
#if !defined(BLOCKCHAIN_DB)
// for multi_db_runtime:
fake_core(const boost::filesystem::path &path, const bool use_testnet) : dummy(m_pool), m_pool(&dummy), m_storage(m_pool)
#else
// for multi_db_compile:
fake_core(const boost::filesystem::path &path, const bool use_testnet) : dummy(m_pool), m_pool(dummy), m_storage(&m_pool)
#endif
{
m_pool.init(path.string());
m_storage.init(path.string(), use_testnet);
}
};
int main(int argc, char* argv[])
{
uint64_t height = 0;
uint64_t start_block = 0;
uint64_t end_block = 0;
uint64_t num_blocks = 0;
boost::filesystem::path default_data_path {tools::get_default_data_dir()};
boost::filesystem::path default_testnet_data_path {default_data_path / "testnet"};
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_0};
const command_line::arg_descriptor<uint64_t> arg_batch_size = {"batch-size", "", db_batch_size};
const command_line::arg_descriptor<bool> arg_testnet_on = {
"testnet"
, "Run on testnet."
, opt_testnet
};
const command_line::arg_descriptor<uint64_t> arg_block_number =
{"block-number", "Number of blocks (default: use entire source blockchain)",
0};
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_batch_size);
command_line::add_arg(desc_cmd_sett, arg_testnet_on);
command_line::add_arg(desc_cmd_sett, arg_block_number);
command_line::add_arg(desc_cmd_only, command_line::arg_help);
const command_line::arg_descriptor<bool> arg_batch = {"batch",
"Batch transactions for faster import", true};
const command_line::arg_descriptor<bool> arg_resume = {"resume",
"Resume from current height if output database already exists", true};
// call add_options() directly for these arguments since command_line helpers
// support only boolean switch, not boolean argument
desc_cmd_sett.add_options()
(arg_batch.name, make_semantic(arg_batch), arg_batch.description)
(arg_resume.name, make_semantic(arg_resume), arg_resume.description)
;
po::options_description desc_options("Allowed options");
desc_options.add(desc_cmd_only).add(desc_cmd_sett);
po::variables_map vm;
bool r = command_line::handle_error_helper(desc_options, [&]()
{
po::store(po::parse_command_line(argc, argv, desc_options), vm);
po::notify(vm);
return true;
});
if (!r)
return 1;
int log_level = command_line::get_arg(vm, arg_log_level);
opt_batch = command_line::get_arg(vm, arg_batch);
opt_resume = command_line::get_arg(vm, arg_resume);
db_batch_size = command_line::get_arg(vm, arg_batch_size);
if (command_line::get_arg(vm, command_line::arg_help))
{
std::cout << "Monero '" << MONERO_RELEASE_NAME << "' (v" << MONERO_VERSION_FULL << ")" << ENDL << ENDL;
std::cout << desc_options << std::endl;
return 1;
}
if (! opt_batch && ! vm["batch-size"].defaulted())
{
std::cerr << "Error: batch-size set, but batch option not enabled" << ENDL;
return 1;
}
if (! db_batch_size)
{
std::cerr << "Error: batch-size must be > 0" << ENDL;
return 1;
}
log_space::get_set_log_detalisation_level(true, log_level);
log_space::log_singletone::add_logger(LOGGER_CONSOLE, NULL, NULL);
LOG_PRINT_L0("Starting...");
std::string src_folder;
opt_testnet = command_line::get_arg(vm, arg_testnet_on);
auto data_dir_arg = opt_testnet ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;
src_folder = command_line::get_arg(vm, data_dir_arg);
boost::filesystem::path dest_folder(src_folder);
num_blocks = command_line::get_arg(vm, arg_block_number);
if (opt_batch)
{
LOG_PRINT_L0("batch: " << std::boolalpha << opt_batch << std::noboolalpha
<< " batch size: " << db_batch_size);
}
else
{
LOG_PRINT_L0("batch: " << std::boolalpha << opt_batch << std::noboolalpha);
}
LOG_PRINT_L0("resume: " << std::boolalpha << opt_resume << std::noboolalpha);
LOG_PRINT_L0("testnet: " << std::boolalpha << opt_testnet << std::noboolalpha);
fake_core c(src_folder, opt_testnet);
height = c.m_storage.get_current_blockchain_height();
BlockchainDB *blockchain;
blockchain = new BlockchainLMDB(opt_batch);
dest_folder /= blockchain->get_db_name();
LOG_PRINT_L0("Source blockchain: " << src_folder);
LOG_PRINT_L0("Dest blockchain: " << dest_folder.string());
LOG_PRINT_L0("Opening dest blockchain (BlockchainDB " << blockchain->get_db_name() << ")");
blockchain->open(dest_folder.string());
LOG_PRINT_L0("Source blockchain height: " << height);
LOG_PRINT_L0("Dest blockchain height: " << blockchain->height());
if (opt_resume)
// next block number to add is same as current height
start_block = blockchain->height();
if (! num_blocks || (start_block + num_blocks > height))
end_block = height - 1;
else
end_block = start_block + num_blocks - 1;
LOG_PRINT_L0("start height: " << start_block+1 << " stop height: " <<
end_block+1);
if (start_block > end_block)
{
LOG_PRINT_L0("Finished: no blocks to add");
delete blockchain;
return 0;
}
if (opt_batch)
blockchain->batch_start(db_batch_size);
uint64_t i = 0;
for (i = start_block; i < end_block + 1; ++i)
{
// block: i height: i+1 end height: end_block + 1
if ((i+1) % 10 == 0)
{
std::cout << "\r \r" << "height " << i+1 << "/" <<
end_block+1 << " (" << (i+1)*100/(end_block+1)<< "%)" << std::flush;
}
// for debugging:
// std::cout << "height " << i+1 << "/" << end_block+1
// << " ((" << i+1 << ")*100/(end_block+1))" << "%)" << ENDL;
block b = c.m_storage.get_block(i);
size_t bsize = c.m_storage.get_block_size(i);
difficulty_type bdiff = c.m_storage.get_block_cumulative_difficulty(i);
uint64_t bcoins = c.m_storage.get_block_coins_generated(i);
std::vector<transaction> txs;
std::vector<crypto::hash> missed;
c.m_storage.get_transactions(b.tx_hashes, txs, missed);
if (missed.size())
{
std::cout << ENDL;
std::cerr << "Missed transaction(s) for block at height " << i + 1 << ", exiting" << ENDL;
delete blockchain;
return 1;
}
try
{
blockchain->add_block(b, bsize, bdiff, bcoins, txs);
if (opt_batch)
{
if ((i < end_block) && ((i + 1) % db_batch_size == 0))
{
std::cout << "\r \r";
std::cout << "[- batch commit at height " << i + 1 << " -]" << ENDL;
blockchain->batch_stop();
blockchain->batch_start(db_batch_size);
std::cout << ENDL;
blockchain->show_stats();
}
}
}
catch (const std::exception& e)
{
std::cout << ENDL;
std::cerr << "Error adding block " << i << " to new blockchain: " << e.what() << ENDL;
delete blockchain;
return 2;
}
}
if (opt_batch)
{
std::cout << "\r \r" << "height " << i << "/" <<
end_block+1 << " (" << (i)*100/(end_block+1)<< "%)" << std::flush;
std::cout << ENDL;
std::cout << "[- batch commit at height " << i << " -]" << ENDL;
blockchain->batch_stop();
}
std::cout << ENDL;
blockchain->show_stats();
std::cout << "Finished at height: " << i << " block: " << i-1 << ENDL;
delete blockchain;
return 0;
}

@ -27,8 +27,8 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "cryptonote_core/cryptonote_basic.h" #include "cryptonote_core/cryptonote_basic.h"
#include "cryptonote_core/blockchain_storage.h"
#include "cryptonote_core/blockchain.h" #include "cryptonote_core/blockchain.h"
#include "cryptonote_core/tx_pool.h"
#include "blockchain_db/blockchain_db.h" #include "blockchain_db/blockchain_db.h"
#include "blockchain_db/lmdb/db_lmdb.h" #include "blockchain_db/lmdb/db_lmdb.h"
#ifdef BERKELEY_DB #ifdef BERKELEY_DB
@ -103,7 +103,6 @@ int main(int argc, char* argv[])
const command_line::arg_descriptor<std::string> arg_output_file = {"output-file", "Specify output file", "", true}; const command_line::arg_descriptor<std::string> arg_output_file = {"output-file", "Specify output file", "", true};
const command_line::arg_descriptor<uint32_t> arg_log_level = {"log-level", "", log_level}; 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_block_stop = {"block-stop", "Stop at block number", block_stop};
#if SOURCE_DB != DB_MEMORY
const command_line::arg_descriptor<std::string> arg_db_type = { const command_line::arg_descriptor<std::string> arg_db_type = {
"db-type" "db-type"
, "Specify database type" , "Specify database type"
@ -114,7 +113,6 @@ int main(int argc, char* argv[])
, "Include data that is only in a database version." , "Include data that is only in a database version."
, false , false
}; };
#endif
const command_line::arg_descriptor<bool> arg_testnet_on = { const command_line::arg_descriptor<bool> arg_testnet_on = {
"testnet" "testnet"
, "Run on testnet." , "Run on testnet."
@ -125,10 +123,8 @@ 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_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, command_line::arg_testnet_data_dir, default_testnet_data_path.string());
command_line::add_arg(desc_cmd_sett, arg_output_file); command_line::add_arg(desc_cmd_sett, arg_output_file);
#if SOURCE_DB != DB_MEMORY
command_line::add_arg(desc_cmd_sett, arg_db_type); command_line::add_arg(desc_cmd_sett, arg_db_type);
command_line::add_arg(desc_cmd_sett, arg_include_db_only_data); command_line::add_arg(desc_cmd_sett, arg_include_db_only_data);
#endif
command_line::add_arg(desc_cmd_sett, arg_testnet_on); 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_log_level);
command_line::add_arg(desc_cmd_sett, arg_block_stop); command_line::add_arg(desc_cmd_sett, arg_block_stop);
@ -164,9 +160,7 @@ int main(int argc, char* argv[])
LOG_PRINT_L0("Setting log level = " << log_level); LOG_PRINT_L0("Setting log level = " << log_level);
bool opt_testnet = command_line::get_arg(vm, arg_testnet_on); bool opt_testnet = command_line::get_arg(vm, arg_testnet_on);
#if SOURCE_DB != DB_MEMORY
bool opt_include_db_only_data = command_line::get_arg(vm, arg_include_db_only_data); bool opt_include_db_only_data = command_line::get_arg(vm, arg_include_db_only_data);
#endif
std::string m_config_folder; std::string m_config_folder;
@ -208,15 +202,6 @@ int main(int argc, char* argv[])
// If we wanted to use the memory pool, we would set up a fake_core. // If we wanted to use the memory pool, we would set up a fake_core.
#if SOURCE_DB == DB_MEMORY
// blockchain_storage* core_storage = NULL;
// tx_memory_pool m_mempool(*core_storage); // is this fake anyway? just passing in NULL! so m_mempool can't be used anyway, right?
// core_storage = new blockchain_storage(&m_mempool);
blockchain_storage* core_storage = new blockchain_storage(NULL);
LOG_PRINT_L0("Initializing source blockchain (in-memory database)");
r = core_storage->init(m_config_folder, opt_testnet);
#else
// Use Blockchain instead of lower-level BlockchainDB for two reasons: // Use Blockchain instead of lower-level BlockchainDB for two reasons:
// 1. Blockchain has the init() method for easy setup // 1. Blockchain has the init() method for easy setup
// 2. exporter needs to use get_current_blockchain_height(), get_block_id_by_height(), get_block_by_hash() // 2. exporter needs to use get_current_blockchain_height(), get_block_id_by_height(), get_block_by_hash()
@ -267,7 +252,6 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
r = core_storage->init(db, opt_testnet); r = core_storage->init(db, opt_testnet);
#endif
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize source blockchain storage"); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize source blockchain storage");
LOG_PRINT_L0("Source blockchain storage initialized OK"); LOG_PRINT_L0("Source blockchain storage initialized OK");
@ -340,7 +324,6 @@ int main(int argc, char* argv[])
write_pod(d,key_images[n]); write_pod(d,key_images[n]);
} }
end_compound(d); end_compound(d);
#if SOURCE_DB != DB_MEMORY
if (opt_include_db_only_data) if (opt_include_db_only_data)
{ {
start_struct(d, "block_timestamps", true); start_struct(d, "block_timestamps", true);
@ -420,7 +403,6 @@ int main(int argc, char* argv[])
write_pod(d, boost::lexical_cast<std::string>(h), (unsigned int)db->get_hard_fork_version(h)); write_pod(d, boost::lexical_cast<std::string>(h), (unsigned int)db->get_hard_fork_version(h));
end_compound(d); end_compound(d);
} }
#endif
end_compound(d); end_compound(d);
CHECK_AND_ASSERT_MES(r, false, "Failed to dump blockchain"); CHECK_AND_ASSERT_MES(r, false, "Failed to dump blockchain");

@ -29,6 +29,7 @@
#include "bootstrap_file.h" #include "bootstrap_file.h"
#include "blocksdat_file.h" #include "blocksdat_file.h"
#include "common/command_line.h" #include "common/command_line.h"
#include "cryptonote_core/tx_pool.h"
#include "blockchain_db/blockchain_db.h" #include "blockchain_db/blockchain_db.h"
#include "blockchain_db/lmdb/db_lmdb.h" #include "blockchain_db/lmdb/db_lmdb.h"
#if defined(BERKELEY_DB) #if defined(BERKELEY_DB)
@ -53,11 +54,7 @@ std::string join_set_strings(const std::unordered_set<std::string>& db_types_all
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
#if defined(BLOCKCHAIN_DB) && (BLOCKCHAIN_DB == DB_MEMORY)
std::string default_db_type = "memory";
#else
std::string default_db_type = "lmdb"; std::string default_db_type = "lmdb";
#endif
std::unordered_set<std::string> db_types_all = cryptonote::blockchain_db_types; std::unordered_set<std::string> db_types_all = cryptonote::blockchain_db_types;
db_types_all.insert("memory"); db_types_all.insert("memory");
@ -160,15 +157,6 @@ int main(int argc, char* argv[])
// If we wanted to use the memory pool, we would set up a fake_core. // If we wanted to use the memory pool, we would set up a fake_core.
#if SOURCE_DB == DB_MEMORY
// blockchain_storage* core_storage = NULL;
// tx_memory_pool m_mempool(*core_storage); // is this fake anyway? just passing in NULL! so m_mempool can't be used anyway, right?
// core_storage = new blockchain_storage(&m_mempool);
blockchain_storage* core_storage = new blockchain_storage(NULL);
LOG_PRINT_L0("Initializing source blockchain (in-memory database)");
r = core_storage->init(m_config_folder, opt_testnet);
#else
// Use Blockchain instead of lower-level BlockchainDB for two reasons: // Use Blockchain instead of lower-level BlockchainDB for two reasons:
// 1. Blockchain has the init() method for easy setup // 1. Blockchain has the init() method for easy setup
// 2. exporter needs to use get_current_blockchain_height(), get_block_id_by_height(), get_block_by_hash() // 2. exporter needs to use get_current_blockchain_height(), get_block_id_by_height(), get_block_by_hash()
@ -217,7 +205,6 @@ int main(int argc, char* argv[])
return 1; return 1;
} }
r = core_storage->init(db, opt_testnet); r = core_storage->init(db, opt_testnet);
#endif
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize source blockchain storage"); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize source blockchain storage");
LOG_PRINT_L0("Source blockchain storage initialized OK"); LOG_PRINT_L0("Source blockchain storage initialized OK");

@ -222,12 +222,8 @@ int pop_blocks(FakeCore& simple_core, int num_blocks)
std::vector<transaction> popped_txs; std::vector<transaction> popped_txs;
for (int i=0; i < num_blocks; ++i) for (int i=0; i < num_blocks; ++i)
{ {
#if defined(BLOCKCHAIN_DB) && (BLOCKCHAIN_DB == DB_MEMORY)
simple_core.m_storage.debug_pop_block_from_blockchain();
#else
// simple_core.m_storage.pop_block_from_blockchain() is private, so call directly through db // simple_core.m_storage.pop_block_from_blockchain() is private, so call directly through db
simple_core.m_storage.get_db().pop_block(popped_block, popped_txs); simple_core.m_storage.get_db().pop_block(popped_block, popped_txs);
#endif
quit = 1; quit = 1;
} }
@ -244,9 +240,7 @@ int pop_blocks(FakeCore& simple_core, int num_blocks)
{ {
simple_core.batch_stop(); simple_core.batch_stop();
} }
#if !defined(BLOCKCHAIN_DB) || (BLOCKCHAIN_DB == DB_LMDB)
simple_core.m_storage.get_db().show_stats(); simple_core.m_storage.get_db().show_stats();
#endif
} }
return num_blocks; return num_blocks;
@ -255,11 +249,6 @@ int pop_blocks(FakeCore& simple_core, int num_blocks)
template <typename FakeCore> template <typename FakeCore>
int import_from_file(FakeCore& simple_core, const std::string& import_file_path, uint64_t block_stop=0) int import_from_file(FakeCore& simple_core, const 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_db, FakeCore>::value,
"FakeCore constraint error");
#endif
#if !defined(BLOCKCHAIN_DB) || (BLOCKCHAIN_DB == DB_LMDB)
if (std::is_same<fake_core_db, FakeCore>::value) if (std::is_same<fake_core_db, FakeCore>::value)
{ {
// Reset stats, in case we're using newly created db, accumulating stats // Reset stats, in case we're using newly created db, accumulating stats
@ -267,7 +256,6 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path,
// This aligns internal db counts with importer counts. // This aligns internal db counts with importer counts.
simple_core.m_storage.get_db().reset_stats(); simple_core.m_storage.get_db().reset_stats();
} }
#endif
boost::filesystem::path fs_import_file_path(import_file_path); boost::filesystem::path fs_import_file_path(import_file_path);
boost::system::error_code ec; boost::system::error_code ec;
if (!boost::filesystem::exists(fs_import_file_path, ec)) if (!boost::filesystem::exists(fs_import_file_path, ec))
@ -567,9 +555,7 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path,
simple_core.batch_stop(); simple_core.batch_stop();
simple_core.batch_start(db_batch_size); simple_core.batch_start(db_batch_size);
std::cout << ENDL; std::cout << ENDL;
#if !defined(BLOCKCHAIN_DB) || (BLOCKCHAIN_DB == DB_LMDB)
simple_core.m_storage.get_db().show_stats(); simple_core.m_storage.get_db().show_stats();
#endif
} }
} }
} }
@ -595,9 +581,7 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path,
{ {
simple_core.batch_stop(); simple_core.batch_stop();
} }
#if !defined(BLOCKCHAIN_DB) || (BLOCKCHAIN_DB == DB_LMDB)
simple_core.m_storage.get_db().show_stats(); simple_core.m_storage.get_db().show_stats();
#endif
LOG_PRINT_L0("Number of blocks imported: " << num_imported); LOG_PRINT_L0("Number of blocks imported: " << num_imported);
if (h > 0) if (h > 0)
// TODO: if there was an error, the last added block is probably at zero-based height h-2 // TODO: if there was an error, the last added block is probably at zero-based height h-2
@ -609,13 +593,8 @@ int import_from_file(FakeCore& simple_core, const std::string& import_file_path,
int main(int argc, char* argv[]) int main(int argc, char* argv[])
{ {
#if defined(BLOCKCHAIN_DB) && (BLOCKCHAIN_DB == DB_MEMORY)
std::string default_db_type = "memory";
std::string default_db_engine_compiled = "memory";
#else
std::string default_db_type = "lmdb"; std::string default_db_type = "lmdb";
std::string default_db_engine_compiled = "blockchain_db"; std::string default_db_engine_compiled = "blockchain_db";
#endif
std::unordered_set<std::string> db_types_all = cryptonote::blockchain_db_types; std::unordered_set<std::string> db_types_all = cryptonote::blockchain_db_types;
db_types_all.insert("memory"); db_types_all.insert("memory");
@ -817,17 +796,11 @@ int main(int argc, char* argv[])
// circumstance. // circumstance.
// for multi_db_runtime: // for multi_db_runtime:
#if !defined(BLOCKCHAIN_DB)
if (db_type == "lmdb" || db_type == "berkeley") if (db_type == "lmdb" || db_type == "berkeley")
{ {
fake_core_db simple_core(m_config_folder, opt_testnet, opt_batch, db_type, db_flags); fake_core_db simple_core(m_config_folder, opt_testnet, opt_batch, db_type, db_flags);
import_from_file(simple_core, import_file_path, block_stop); import_from_file(simple_core, import_file_path, block_stop);
} }
else if (db_type == "memory")
{
fake_core_memory simple_core(m_config_folder, opt_testnet);
import_from_file(simple_core, import_file_path, block_stop);
}
else else
{ {
std::cerr << "database type unrecognized" << ENDL; std::cerr << "database type unrecognized" << ENDL;
@ -835,17 +808,7 @@ int main(int argc, char* argv[])
} }
// for multi_db_compile: // for multi_db_compile:
#else
if (db_engine_compiled != default_db_engine_compiled)
{
std::cerr << "Invalid database type for compiled version: " << db_type << std::endl;
return 1;
}
#if BLOCKCHAIN_DB == DB_LMDB
fake_core_db simple_core(m_config_folder, opt_testnet, opt_batch, db_type, db_flags); fake_core_db simple_core(m_config_folder, opt_testnet, opt_batch, db_type, db_flags);
#else
fake_core_memory simple_core(m_config_folder, opt_testnet);
#endif
if (! vm["pop-blocks"].defaulted()) if (! vm["pop-blocks"].defaulted())
{ {
@ -856,17 +819,14 @@ int main(int argc, char* argv[])
return 0; return 0;
} }
#if !defined(BLOCKCHAIN_DB) || (BLOCKCHAIN_DB == DB_LMDB)
if (! vm["drop-hard-fork"].defaulted()) if (! vm["drop-hard-fork"].defaulted())
{ {
LOG_PRINT_L0("Dropping hard fork tables..."); LOG_PRINT_L0("Dropping hard fork tables...");
simple_core.m_storage.get_db().drop_hard_fork_info(); simple_core.m_storage.get_db().drop_hard_fork_info();
return 0; return 0;
} }
#endif
import_from_file(simple_core, import_file_path, block_stop); import_from_file(simple_core, import_file_path, block_stop);
#endif
} }
catch (const DB_ERROR& e) catch (const DB_ERROR& e)

@ -31,21 +31,6 @@
#include "version.h" #include "version.h"
// CONFIG: choose one of the three #define's
//
// DB_MEMORY was a sensible default for users migrating to LMDB, as it allowed
// the exporter to use the in-memory blockchain while the other binaries
// work with LMDB, without recompiling anything.
//
// Now that the majority of users are on 0.9.2, and the converter has largely
// become a generalised database tool, the default has changed to DB_LMDB.
//
// #define SOURCE_DB DB_MEMORY
#define SOURCE_DB DB_LMDB
// to use global compile-time setting (DB_MEMORY or DB_LMDB):
// #define SOURCE_DB BLOCKCHAIN_DB
// bounds checking is done before writing to buffer, but buffer size // bounds checking is done before writing to buffer, but buffer size
// should be a sensible maximum // should be a sensible maximum
#define BUFFER_SIZE 1000000 #define BUFFER_SIZE 1000000

@ -114,11 +114,7 @@ bool BlocksdatFile::close()
} }
#if SOURCE_DB == DB_MEMORY
bool BlocksdatFile::store_blockchain_raw(blockchain_storage* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop)
#else
bool BlocksdatFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop) bool BlocksdatFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop)
#endif
{ {
uint64_t num_blocks_written = 0; uint64_t num_blocks_written = 0;
m_blockchain_storage = _blockchain_storage; m_blockchain_storage = _blockchain_storage;

@ -36,7 +36,6 @@
#include "cryptonote_core/cryptonote_basic.h" #include "cryptonote_core/cryptonote_basic.h"
#include "cryptonote_core/cryptonote_boost_serialization.h" #include "cryptonote_core/cryptonote_boost_serialization.h"
#include "cryptonote_core/blockchain_storage.h"
#include "cryptonote_core/blockchain.h" #include "cryptonote_core/blockchain.h"
#include "blockchain_db/blockchain_db.h" #include "blockchain_db/blockchain_db.h"
#include "blockchain_db/lmdb/db_lmdb.h" #include "blockchain_db/lmdb/db_lmdb.h"
@ -60,21 +59,12 @@ class BlocksdatFile
{ {
public: public:
#if SOURCE_DB == DB_MEMORY
bool store_blockchain_raw(cryptonote::blockchain_storage* cs, cryptonote::tx_memory_pool* txp,
boost::filesystem::path& output_file, uint64_t use_block_height=0);
#else
bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp, bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp,
boost::filesystem::path& output_file, uint64_t use_block_height=0); boost::filesystem::path& output_file, uint64_t use_block_height=0);
#endif
protected: protected:
#if SOURCE_DB == DB_MEMORY
blockchain_storage* m_blockchain_storage;
#else
Blockchain* m_blockchain_storage; Blockchain* m_blockchain_storage;
#endif
std::ofstream * m_raw_data_file; std::ofstream * m_raw_data_file;

@ -223,31 +223,9 @@ void BootstrapFile::write_block(block& block)
{ {
throw std::runtime_error("Aborting: tx == null_hash"); throw std::runtime_error("Aborting: tx == null_hash");
} }
#if SOURCE_DB == DB_MEMORY
const transaction* tx = m_blockchain_storage->get_tx(tx_id);
#else
transaction tx = m_blockchain_storage->get_db().get_tx(tx_id); transaction tx = m_blockchain_storage->get_db().get_tx(tx_id);
#endif
#if SOURCE_DB == DB_MEMORY
if(tx == NULL)
{
if (! m_tx_pool)
throw std::runtime_error("Aborting: tx == NULL, so memory pool required to get tx, but memory pool isn't enabled");
else
{
transaction tx;
if(m_tx_pool->get_transaction(tx_id, tx))
txs.push_back(tx);
else
throw std::runtime_error("Aborting: tx not found in pool");
}
}
else
txs.push_back(*tx);
#else
txs.push_back(tx); txs.push_back(tx);
#endif
} }
// these non-coinbase txs will be serialized using this structure // these non-coinbase txs will be serialized using this structure
@ -257,15 +235,9 @@ void BootstrapFile::write_block(block& block)
bool include_extra_block_data = true; bool include_extra_block_data = true;
if (include_extra_block_data) if (include_extra_block_data)
{ {
#if SOURCE_DB == DB_MEMORY
size_t block_size = m_blockchain_storage->get_block_size(block_height);
difficulty_type cumulative_difficulty = m_blockchain_storage->get_block_cumulative_difficulty(block_height);
uint64_t coins_generated = m_blockchain_storage->get_block_coins_generated(block_height);
#else
size_t block_size = m_blockchain_storage->get_db().get_block_size(block_height); size_t block_size = m_blockchain_storage->get_db().get_block_size(block_height);
difficulty_type cumulative_difficulty = m_blockchain_storage->get_db().get_block_cumulative_difficulty(block_height); difficulty_type cumulative_difficulty = m_blockchain_storage->get_db().get_block_cumulative_difficulty(block_height);
uint64_t coins_generated = m_blockchain_storage->get_db().get_block_already_generated_coins(block_height); uint64_t coins_generated = m_blockchain_storage->get_db().get_block_already_generated_coins(block_height);
#endif
bp.block_size = block_size; bp.block_size = block_size;
bp.cumulative_difficulty = cumulative_difficulty; bp.cumulative_difficulty = cumulative_difficulty;
@ -288,11 +260,7 @@ 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_file, uint64_t requested_block_stop)
#else
bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop) bool BootstrapFile::store_blockchain_raw(Blockchain* _blockchain_storage, tx_memory_pool* _tx_pool, boost::filesystem::path& output_file, uint64_t requested_block_stop)
#endif
{ {
uint64_t num_blocks_written = 0; uint64_t num_blocks_written = 0;
m_max_chunk = 0; m_max_chunk = 0;

@ -35,7 +35,6 @@
#include <boost/iostreams/filtering_streambuf.hpp> #include <boost/iostreams/filtering_streambuf.hpp>
#include "cryptonote_core/cryptonote_basic.h" #include "cryptonote_core/cryptonote_basic.h"
#include "cryptonote_core/blockchain_storage.h"
#include "cryptonote_core/blockchain.h" #include "cryptonote_core/blockchain.h"
#include <algorithm> #include <algorithm>
@ -60,21 +59,12 @@ public:
uint64_t count_blocks(const std::string& dir_path); uint64_t count_blocks(const std::string& dir_path);
uint64_t seek_to_first_chunk(std::ifstream& import_file); uint64_t seek_to_first_chunk(std::ifstream& import_file);
#if SOURCE_DB == DB_MEMORY
bool store_blockchain_raw(cryptonote::blockchain_storage* cs, cryptonote::tx_memory_pool* txp,
boost::filesystem::path& output_file, uint64_t use_block_height=0);
#else
bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp, bool store_blockchain_raw(cryptonote::Blockchain* cs, cryptonote::tx_memory_pool* txp,
boost::filesystem::path& output_file, uint64_t use_block_height=0); boost::filesystem::path& output_file, uint64_t use_block_height=0);
#endif
protected: protected:
#if SOURCE_DB == DB_MEMORY
blockchain_storage* m_blockchain_storage;
#else
Blockchain* m_blockchain_storage; Blockchain* m_blockchain_storage;
#endif
tx_memory_pool* m_tx_pool; tx_memory_pool* m_tx_pool;
typedef std::vector<char> buffer_type; typedef std::vector<char> buffer_type;

@ -30,7 +30,7 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include "cryptonote_core/blockchain.h" // BlockchainDB #include "cryptonote_core/blockchain.h" // BlockchainDB
#include "cryptonote_core/blockchain_storage.h" // in-memory DB #include "cryptonote_core/tx_pool.h"
#include "blockchain_db/blockchain_db.h" #include "blockchain_db/blockchain_db.h"
#include "blockchain_db/lmdb/db_lmdb.h" #include "blockchain_db/lmdb/db_lmdb.h"
#if defined(BERKELEY_DB) #if defined(BERKELEY_DB)
@ -48,8 +48,6 @@ namespace
} }
#if !defined(BLOCKCHAIN_DB) || BLOCKCHAIN_DB == DB_LMDB
struct fake_core_db struct fake_core_db
{ {
Blockchain m_storage; Blockchain m_storage;
@ -59,12 +57,7 @@ struct fake_core_db
bool support_add_block; bool support_add_block;
// for multi_db_runtime: // for multi_db_runtime:
#if !defined(BLOCKCHAIN_DB)
fake_core_db(const boost::filesystem::path &path, const bool use_testnet=false, const bool do_batch=true, const std::string& db_type="lmdb", const int db_flags=0) : m_pool(&m_storage), m_storage(m_pool)
// for multi_db_compile:
#else
fake_core_db(const boost::filesystem::path &path, const bool use_testnet=false, const bool do_batch=true, const std::string& db_type="lmdb", const int db_flags=0) : m_pool(m_storage), m_storage(m_pool) fake_core_db(const boost::filesystem::path &path, const bool use_testnet=false, const bool do_batch=true, const std::string& db_type="lmdb", const int db_flags=0) : m_pool(m_storage), m_storage(m_pool)
#endif
{ {
m_pool.init(path.string()); m_pool.init(path.string());
@ -136,60 +129,5 @@ struct fake_core_db
m_storage.get_db().batch_stop(); m_storage.get_db().batch_stop();
} }
};
#endif
#if !defined(BLOCKCHAIN_DB) || BLOCKCHAIN_DB == DB_MEMORY
struct fake_core_memory
{
blockchain_storage m_storage;
tx_memory_pool m_pool;
bool support_batch;
bool support_add_block;
// for multi_db_runtime:
#if !defined(BLOCKCHAIN_DB)
fake_core_memory(const boost::filesystem::path &path, const bool use_testnet=false) : m_pool(&m_storage), m_storage(m_pool)
#else
// for multi_db_compile:
fake_core_memory(const boost::filesystem::path &path, const bool use_testnet=false) : m_pool(m_storage), m_storage(&m_pool)
#endif
{
m_pool.init(path.string());
m_storage.init(path.string(), use_testnet);
support_batch = false;
support_add_block = false;
}
~fake_core_memory()
{
LOG_PRINT_L3("fake_core_memory() destructor called - want to see it ripple down");
m_storage.deinit();
}
uint64_t add_block(const block& blk
, const size_t& block_size
, const difficulty_type& cumulative_difficulty
, const uint64_t& coins_generated
, const std::vector<transaction>& txs
)
{
// TODO:
// would need to refactor handle_block_to_main_chain() to have a direct add_block() method like Blockchain class
throw std::runtime_error("direct add_block() method not implemented for in-memory db");
return 2;
}
void batch_start(uint64_t batch_num_blocks = 0)
{
LOG_PRINT_L0("WARNING: [batch_start] opt_batch set, but this database doesn't support/need transactions - ignoring");
}
void batch_stop()
{
LOG_PRINT_L0("WARNING: [batch_stop] opt_batch set, but this database doesn't support/need transactions - ignoring");
}
}; };
#endif

@ -28,7 +28,6 @@
set(cryptonote_core_sources set(cryptonote_core_sources
account.cpp account.cpp
blockchain_storage.cpp
blockchain.cpp blockchain.cpp
checkpoints.cpp checkpoints.cpp
cryptonote_basic_impl.cpp cryptonote_basic_impl.cpp
@ -44,7 +43,6 @@ set(cryptonote_core_headers)
set(cryptonote_core_private_headers set(cryptonote_core_private_headers
account.h account.h
account_boost_serialization.h account_boost_serialization.h
blockchain_storage.h
blockchain_storage_boost_serialization.h blockchain_storage_boost_serialization.h
blockchain.h blockchain.h
checkpoints.h checkpoints.h

File diff suppressed because it is too large Load Diff

@ -1,377 +0,0 @@
// Copyright (c) 2014-2016, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright notice, this list
// of conditions and the following disclaimer in the documentation and/or other
// materials provided with the distribution.
//
// 3. Neither the name of the copyright holder nor the names of its contributors may be
// used to endorse or promote products derived from this software without specific
// prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Parts of this file are originally copyright (c) 2012-2013 The Cryptonote developers
#pragma once
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/version.hpp>
#include <boost/serialization/list.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/global_fun.hpp>
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/foreach.hpp>
#include <atomic>
#include "syncobj.h"
#include "string_tools.h"
#include "tx_pool.h"
#include "cryptonote_basic.h"
#include "common/util.h"
#include "cryptonote_protocol/cryptonote_protocol_defs.h"
#include "rpc/core_rpc_server_commands_defs.h"
#include "difficulty.h"
#include "cryptonote_core/cryptonote_format_utils.h"
#include "verification_context.h"
#include "crypto/hash.h"
#include "checkpoints.h"
namespace cryptonote
{
/************************************************************************/
/* */
/************************************************************************/
class blockchain_storage
{
public:
struct transaction_chain_entry
{
transaction tx;
uint64_t m_keeper_block_height;
size_t m_blob_size;
std::vector<uint64_t> m_global_output_indexes;
};
struct block_extended_info
{
block bl;
uint64_t height;
size_t block_cumulative_size;
difficulty_type cumulative_difficulty;
uint64_t already_generated_coins;
};
blockchain_storage(tx_memory_pool* tx_pool):m_tx_pool(tx_pool), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false), m_is_blockchain_storing(false), m_enforce_dns_checkpoints(false)
{};
bool init() { return init(tools::get_default_data_dir(), true); }
bool init(const std::string& config_folder, bool testnet = false);
bool deinit();
void set_checkpoints(checkpoints&& chk_pts) { m_checkpoints = chk_pts; }
//bool push_new_block();
bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks, std::list<transaction>& txs) const;
bool get_blocks(uint64_t start_offset, size_t count, std::list<block>& blocks) const;
bool get_alternative_blocks(std::list<block>& blocks) const;
size_t get_alternative_blocks_count() const;
crypto::hash get_block_id_by_height(uint64_t height) const;
bool get_block_by_hash(const crypto::hash &h, block &blk) const;
void get_all_known_block_ids(std::list<crypto::hash> &main, std::list<crypto::hash> &alt, std::list<crypto::hash> &invalid) const;
template<class archive_t>
void serialize(archive_t & ar, const unsigned int version);
bool have_tx(const crypto::hash &id) const;
bool have_tx_keyimges_as_spent(const transaction &tx) const;
bool have_tx_keyimg_as_spent(const crypto::key_image &key_im) const;
const transaction *get_tx(const crypto::hash &id) const;
uint64_t get_current_blockchain_height() const;
crypto::hash get_tail_id() const;
crypto::hash get_tail_id(uint64_t& height) const;
difficulty_type get_difficulty_for_next_block() const;
bool add_new_block(const block& bl_, block_verification_context& bvc);
bool reset_and_set_genesis_block(const block& b);
bool create_block_template(block& b, const account_public_address& miner_address, difficulty_type& di, uint64_t& height, const blobdata& ex_nonce) const;
bool have_block(const crypto::hash& id) const;
size_t get_total_transactions() const;
bool get_outs(uint64_t amount, std::list<crypto::public_key>& pkeys) const;
bool get_short_chain_history(std::list<crypto::hash>& ids) const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp) const;
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, uint64_t& starter_offset) const;
bool find_blockchain_supplement(const uint64_t req_start_block, const std::list<crypto::hash>& qblock_ids, std::list<std::pair<block, std::list<transaction> > >& blocks, uint64_t& total_height, uint64_t& start_height, size_t max_count) const;
bool handle_get_objects(NOTIFY_REQUEST_GET_OBJECTS::request& arg, NOTIFY_RESPONSE_GET_OBJECTS::request& rsp);
bool handle_get_objects(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res);
bool get_random_outs_for_amounts(const COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::request& req, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::response& res) const;
bool get_backward_blocks_sizes(size_t from_height, std::vector<size_t>& sz, size_t count) const;
bool get_tx_outputs_gindexs(const crypto::hash& tx_id, std::vector<uint64_t>& indexs) const;
bool store_blockchain();
bool check_tx_inputs(const transaction& tx, uint64_t& pmax_used_block_height, crypto::hash& max_used_block_id) const;
uint64_t get_current_cumulative_blocksize_limit() const;
bool is_storing_blockchain()const{return m_is_blockchain_storing;}
uint64_t block_difficulty(size_t i) const;
double get_avg_block_size( size_t count) const;
bool flush_txes_from_pool(const std::list<crypto::hash> &txids);
template<class t_ids_container, class t_blocks_container, class t_missed_container>
bool get_blocks(const t_ids_container& block_ids, t_blocks_container& blocks, t_missed_container& missed_bs) const
{
CRITICAL_REGION_LOCAL(m_blockchain_lock);
BOOST_FOREACH(const auto& bl_id, block_ids)
{
auto it = m_blocks_index.find(bl_id);
if(it == m_blocks_index.end())
missed_bs.push_back(bl_id);
else
{
CHECK_AND_ASSERT_MES(it->second < m_blocks.size(), false, "Internal error: bl_id=" << epee::string_tools::pod_to_hex(bl_id)
<< " have index record with offset="<<it->second<< ", bigger then m_blocks.size()=" << m_blocks.size());
blocks.push_back(m_blocks[it->second].bl);
}
}
return true;
}
template<class t_ids_container, class t_tx_container, class t_missed_container>
bool get_transactions(const t_ids_container& txs_ids, t_tx_container& txs, t_missed_container& missed_txs) const
{
CRITICAL_REGION_LOCAL(m_blockchain_lock);
BOOST_FOREACH(const auto& tx_id, txs_ids)
{
auto it = m_transactions.find(tx_id);
if(it == m_transactions.end())
{
transaction tx;
if(!m_tx_pool->get_transaction(tx_id, tx))
missed_txs.push_back(tx_id);
else
txs.push_back(tx);
}
else
txs.push_back(it->second.tx);
}
return true;
}
//debug functions
void print_blockchain(uint64_t start_index, uint64_t end_index) const;
void print_blockchain_index() const;
void print_blockchain_outs(const std::string& file) const;
void check_against_checkpoints(const checkpoints& points, bool enforce);
bool update_checkpoints(const std::string& file_path, bool check_dns);
void set_enforce_dns_checkpoints(bool enforce_checkpoints);
block get_block(uint64_t height) const { return m_blocks[height].bl; }
size_t get_block_size(uint64_t height) const { return m_blocks[height].block_cumulative_size; }
difficulty_type get_block_cumulative_difficulty(uint64_t height) const { return m_blocks[height].cumulative_difficulty; }
uint64_t get_block_coins_generated(uint64_t height) const { return m_blocks[height].already_generated_coins; }
bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const;
bool for_all_blocks(std::function<bool(uint64_t height, const crypto::hash&, const block&)>) const;
bool for_all_transactions(std::function<bool(const crypto::hash&, const transaction&)>) const;
bool for_all_outputs(std::function<bool(uint64_t amount, const crypto::hash &tx_hash, size_t tx_idx)>) const;
// use for testing only
bool debug_pop_block_from_blockchain() { return pop_block_from_blockchain(); }
private:
typedef std::unordered_map<crypto::hash, size_t> blocks_by_id_index;
typedef std::unordered_map<crypto::hash, transaction_chain_entry> transactions_container;
typedef std::unordered_set<crypto::key_image> key_images_container;
typedef std::vector<block_extended_info> blocks_container;
typedef std::unordered_map<crypto::hash, block_extended_info> blocks_ext_by_hash;
typedef std::unordered_map<crypto::hash, block> blocks_by_hash;
typedef std::map<uint64_t, std::vector<std::pair<crypto::hash, size_t>>> outputs_container; //crypto::hash - tx hash, size_t - index of out in transaction
tx_memory_pool* m_tx_pool;
mutable epee::critical_section m_blockchain_lock; // TODO: add here reader/writer lock
// main chain
blocks_container m_blocks; // height -> block_extended_info
blocks_by_id_index m_blocks_index; // crypto::hash -> height
transactions_container m_transactions;
key_images_container m_spent_keys;
size_t m_current_block_cumul_sz_limit;
// all alternative chains
blocks_ext_by_hash m_alternative_chains; // crypto::hash -> block_extended_info
// some invalid blocks
blocks_ext_by_hash m_invalid_blocks; // crypto::hash -> block_extended_info
outputs_container m_outputs;
std::string m_config_folder;
checkpoints m_checkpoints;
std::atomic<bool> m_is_in_checkpoint_zone;
std::atomic<bool> m_is_blockchain_storing;
bool m_enforce_dns_checkpoints;
bool m_testnet;
// made private for consistency with blockchain.h
template<class visitor_t>
bool scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height = NULL) const;
bool check_tx_input(const txin_to_key& txin, const crypto::hash& tx_prefix_hash, const std::vector<crypto::signature>& sig, uint64_t* pmax_related_block_height = NULL) const;
bool check_tx_inputs(const transaction& tx, const crypto::hash& tx_prefix_hash, uint64_t* pmax_used_block_height = NULL) const;
bool check_tx_inputs(const transaction& tx, uint64_t* pmax_used_block_height = NULL) const;
bool switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain, bool discard_disconnected_chain);
bool pop_block_from_blockchain();
bool purge_block_data_from_blockchain(const block& b, size_t processed_tx_count);
bool purge_transaction_from_blockchain(const crypto::hash& tx_id);
bool purge_transaction_keyimages_from_blockchain(const transaction& tx, bool strict_check);
bool handle_block_to_main_chain(const block& bl, block_verification_context& bvc);
bool handle_block_to_main_chain(const block& bl, const crypto::hash& id, block_verification_context& bvc);
bool handle_alternative_block(const block& b, const crypto::hash& id, block_verification_context& bvc);
difficulty_type get_next_difficulty_for_alternative_chain(const std::list<blocks_ext_by_hash::iterator>& alt_chain, block_extended_info& bei) const;
bool prevalidate_miner_transaction(const block& b, uint64_t height) const;
bool validate_miner_transaction(const block& b, size_t cumulative_block_size, uint64_t fee, uint64_t& base_reward, uint64_t already_generated_coins) const;
bool validate_transaction(const block& b, uint64_t height, const transaction& tx) const;
bool rollback_blockchain_switching(std::list<block>& original_chain, size_t rollback_height);
bool add_transaction_from_block(const transaction& tx, const crypto::hash& tx_id, const crypto::hash& bl_id, uint64_t bl_height, size_t blob_size);
bool push_transaction_to_global_outs_index(const transaction& tx, const crypto::hash& tx_id, std::vector<uint64_t>& global_indexes);
bool pop_transaction_from_global_index(const transaction& tx, const crypto::hash& tx_id);
bool get_last_n_blocks_sizes(std::vector<size_t>& sz, size_t count) const;
bool add_out_to_get_random_outs(const std::vector<std::pair<crypto::hash, size_t> >& amount_outs, COMMAND_RPC_GET_RANDOM_OUTPUTS_FOR_AMOUNTS::outs_for_amount& result_outs, uint64_t amount, size_t i) const;
bool is_tx_spendtime_unlocked(uint64_t unlock_time) const;
bool add_block_as_invalid(const block& bl, const crypto::hash& h);
bool add_block_as_invalid(const block_extended_info& bei, const crypto::hash& h);
size_t find_end_of_allowed_index(const std::vector<std::pair<crypto::hash, size_t> >& amount_outs) const;
bool check_block_timestamp_main(const block& b) const;
bool check_block_timestamp(std::vector<uint64_t> timestamps, const block& b) const;
uint64_t get_adjusted_time() const;
bool complete_timestamps_vector(uint64_t start_height, std::vector<uint64_t>& timestamps) const;
bool update_next_comulative_size_limit();
bool store_genesis_block(bool testnet, bool check_added = false);
};
/************************************************************************/
/* */
/************************************************************************/
#define CURRENT_BLOCKCHAIN_STORAGE_ARCHIVE_VER 12
template<class archive_t>
void blockchain_storage::serialize(archive_t & ar, const unsigned int version)
{
if(version < 11)
return;
CRITICAL_REGION_LOCAL(m_blockchain_lock);
ar & m_blocks;
ar & m_blocks_index;
ar & m_transactions;
ar & m_spent_keys;
ar & m_alternative_chains;
ar & m_outputs;
ar & m_invalid_blocks;
ar & m_current_block_cumul_sz_limit;
/*serialization bug workaround*/
if(version > 11)
{
uint64_t total_check_count = m_blocks.size() + m_blocks_index.size() + m_transactions.size() + m_spent_keys.size() + m_alternative_chains.size() + m_outputs.size() + m_invalid_blocks.size() + m_current_block_cumul_sz_limit;
if(archive_t::is_saving::value)
{
ar & total_check_count;
}else
{
uint64_t total_check_count_loaded = 0;
ar & total_check_count_loaded;
if(total_check_count != total_check_count_loaded)
{
LOG_ERROR("Blockchain storage data corruption detected. total_count loaded from file = " << total_check_count_loaded << ", expected = " << total_check_count);
LOG_PRINT_L0("Blockchain storage:" << ENDL <<
"m_blocks: " << m_blocks.size() << ENDL <<
"m_blocks_index: " << m_blocks_index.size() << ENDL <<
"m_transactions: " << m_transactions.size() << ENDL <<
"m_spent_keys: " << m_spent_keys.size() << ENDL <<
"m_alternative_chains: " << m_alternative_chains.size() << ENDL <<
"m_outputs: " << m_outputs.size() << ENDL <<
"m_invalid_blocks: " << m_invalid_blocks.size() << ENDL <<
"m_current_block_cumul_sz_limit: " << m_current_block_cumul_sz_limit);
throw std::runtime_error("Blockchain data corruption");
}
}
}
LOG_PRINT_L2("Blockchain storage:" << ENDL <<
"m_blocks: " << m_blocks.size() << ENDL <<
"m_blocks_index: " << m_blocks_index.size() << ENDL <<
"m_transactions: " << m_transactions.size() << ENDL <<
"m_spent_keys: " << m_spent_keys.size() << ENDL <<
"m_alternative_chains: " << m_alternative_chains.size() << ENDL <<
"m_outputs: " << m_outputs.size() << ENDL <<
"m_invalid_blocks: " << m_invalid_blocks.size() << ENDL <<
"m_current_block_cumul_sz_limit: " << m_current_block_cumul_sz_limit);
}
//------------------------------------------------------------------
template<class visitor_t>
bool blockchain_storage::scan_outputkeys_for_indexes(const txin_to_key& tx_in_to_key, visitor_t& vis, uint64_t* pmax_related_block_height) const
{
CRITICAL_REGION_LOCAL(m_blockchain_lock);
auto it = m_outputs.find(tx_in_to_key.amount);
if(it == m_outputs.end() || !tx_in_to_key.key_offsets.size())
return false;
std::vector<uint64_t> absolute_offsets = relative_output_offsets_to_absolute(tx_in_to_key.key_offsets);
const std::vector<std::pair<crypto::hash, size_t> >& amount_outs_vec = it->second;
size_t count = 0;
BOOST_FOREACH(uint64_t i, absolute_offsets)
{
if(i >= amount_outs_vec.size() )
{
LOG_PRINT_L0("Wrong index in transaction inputs: " << i << ", expected maximum " << amount_outs_vec.size() - 1);
return false;
}
transactions_container::const_iterator tx_it = m_transactions.find(amount_outs_vec[i].first);
CHECK_AND_ASSERT_MES(tx_it != m_transactions.end(), false, "Wrong transaction id in output indexes: " << epee::string_tools::pod_to_hex(amount_outs_vec[i].first));
CHECK_AND_ASSERT_MES(amount_outs_vec[i].second < tx_it->second.tx.vout.size(), false,
"Wrong index in transaction outputs: " << amount_outs_vec[i].second << ", expected less then " << tx_it->second.tx.vout.size());
if(!vis.handle_output(tx_it->second.tx, tx_it->second.tx.vout[amount_outs_vec[i].second]))
{
LOG_PRINT_L0("Failed to handle_output for output no = " << count << ", with absolute offset " << i);
return false;
}
if(count++ == absolute_offsets.size()-1 && pmax_related_block_height)
{
if(*pmax_related_block_height < tx_it->second.m_keeper_block_height)
*pmax_related_block_height = tx_it->second.m_keeper_block_height;
}
}
return true;
}
}
BOOST_CLASS_VERSION(cryptonote::blockchain_storage, CURRENT_BLOCKCHAIN_STORAGE_ARCHIVE_VER)

@ -50,9 +50,6 @@
#include "misc_language.h" #include "misc_language.h"
#include "tx_extra.h" #include "tx_extra.h"
#define DB_MEMORY 1
#define DB_LMDB 2
namespace cryptonote namespace cryptonote
{ {

@ -57,11 +57,7 @@ namespace cryptonote
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
core::core(i_cryptonote_protocol* pprotocol): core::core(i_cryptonote_protocol* pprotocol):
m_mempool(m_blockchain_storage), m_mempool(m_blockchain_storage),
#if BLOCKCHAIN_DB == DB_LMDB
m_blockchain_storage(m_mempool), m_blockchain_storage(m_mempool),
#else
m_blockchain_storage(&m_mempool),
#endif
m_miner(this), m_miner(this),
m_miner_address(boost::value_initialized<account_public_address>()), m_miner_address(boost::value_initialized<account_public_address>()),
m_starter_message_showed(false), m_starter_message_showed(false),
@ -257,7 +253,6 @@ namespace cryptonote
r = m_mempool.init(m_fakechain ? std::string() : m_config_folder); r = m_mempool.init(m_fakechain ? std::string() : m_config_folder);
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool"); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize memory pool");
#if BLOCKCHAIN_DB == DB_LMDB
std::string db_type = command_line::get_arg(vm, command_line::arg_db_type); std::string db_type = command_line::get_arg(vm, command_line::arg_db_type);
std::string db_sync_mode = command_line::get_arg(vm, command_line::arg_db_sync_mode); std::string db_sync_mode = command_line::get_arg(vm, command_line::arg_db_sync_mode);
bool fast_sync = command_line::get_arg(vm, command_line::arg_fast_block_sync) != 0; bool fast_sync = command_line::get_arg(vm, command_line::arg_fast_block_sync) != 0;
@ -405,9 +400,6 @@ namespace cryptonote
bool show_time_stats = command_line::get_arg(vm, command_line::arg_show_time_stats) != 0; bool show_time_stats = command_line::get_arg(vm, command_line::arg_show_time_stats) != 0;
m_blockchain_storage.set_show_time_stats(show_time_stats); m_blockchain_storage.set_show_time_stats(show_time_stats);
#else
r = m_blockchain_storage.init(m_config_folder, m_testnet);
#endif
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage"); CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
// load json & DNS checkpoints, and verify them // load json & DNS checkpoints, and verify them
@ -780,18 +772,14 @@ namespace cryptonote
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
bool core::prepare_handle_incoming_blocks(const std::list<block_complete_entry> &blocks) bool core::prepare_handle_incoming_blocks(const std::list<block_complete_entry> &blocks)
{ {
#if BLOCKCHAIN_DB == DB_LMDB
m_blockchain_storage.prepare_handle_incoming_blocks(blocks); m_blockchain_storage.prepare_handle_incoming_blocks(blocks);
#endif
return true; return true;
} }
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
bool core::cleanup_handle_incoming_blocks(bool force_sync) bool core::cleanup_handle_incoming_blocks(bool force_sync)
{ {
#if BLOCKCHAIN_DB == DB_LMDB
m_blockchain_storage.cleanup_handle_incoming_blocks(force_sync); m_blockchain_storage.cleanup_handle_incoming_blocks(force_sync);
#endif
return true; return true;
} }
@ -918,11 +906,6 @@ namespace cryptonote
m_starter_message_showed = true; m_starter_message_showed = true;
} }
#if BLOCKCHAIN_DB == DB_LMDB
// m_store_blockchain_interval.do_call(boost::bind(&Blockchain::store_blockchain, &m_blockchain_storage));
#else
m_store_blockchain_interval.do_call(boost::bind(&blockchain_storage::store_blockchain, &m_blockchain_storage));
#endif
m_fork_moaner.do_call(boost::bind(&core::check_fork_time, this)); m_fork_moaner.do_call(boost::bind(&core::check_fork_time, this));
m_txpool_auto_relayer.do_call(boost::bind(&core::relay_txpool_transactions, this)); m_txpool_auto_relayer.do_call(boost::bind(&core::relay_txpool_transactions, this));
m_miner.on_idle(); m_miner.on_idle();
@ -932,7 +915,6 @@ namespace cryptonote
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------
bool core::check_fork_time() bool core::check_fork_time()
{ {
#if BLOCKCHAIN_DB == DB_LMDB
HardFork::State state = m_blockchain_storage.get_hard_fork_state(); HardFork::State state = m_blockchain_storage.get_hard_fork_state();
switch (state) { switch (state) {
case HardFork::LikelyForked: case HardFork::LikelyForked:
@ -951,7 +933,6 @@ namespace cryptonote
default: default:
break; break;
} }
#endif
return true; return true;
} }
//----------------------------------------------------------------------------------------------- //-----------------------------------------------------------------------------------------------

@ -40,11 +40,7 @@
#include "cryptonote_protocol/cryptonote_protocol_handler_common.h" #include "cryptonote_protocol/cryptonote_protocol_handler_common.h"
#include "storages/portable_storage_template_helper.h" #include "storages/portable_storage_template_helper.h"
#include "tx_pool.h" #include "tx_pool.h"
#if BLOCKCHAIN_DB == DB_LMDB
#include "blockchain.h" #include "blockchain.h"
#else
#include "blockchain_storage.h"
#endif
#include "miner.h" #include "miner.h"
#include "connection_context.h" #include "connection_context.h"
#include "cryptonote_core/cryptonote_stat_info.h" #include "cryptonote_core/cryptonote_stat_info.h"
@ -498,7 +494,6 @@ namespace cryptonote
*/ */
void resume_mine(); void resume_mine();
#if BLOCKCHAIN_DB == DB_LMDB
/** /**
* @brief gets the Blockchain instance * @brief gets the Blockchain instance
* *
@ -512,10 +507,6 @@ namespace cryptonote
* @return a const reference to the Blockchain instance * @return a const reference to the Blockchain instance
*/ */
const Blockchain& get_blockchain_storage()const{return m_blockchain_storage;} const Blockchain& get_blockchain_storage()const{return m_blockchain_storage;}
#else
blockchain_storage& get_blockchain_storage(){return m_blockchain_storage;}
const blockchain_storage& get_blockchain_storage()const{return m_blockchain_storage;}
#endif
/** /**
* @copydoc Blockchain::print_blockchain * @copydoc Blockchain::print_blockchain
@ -765,11 +756,7 @@ namespace cryptonote
uint64_t m_test_drop_download_height = 0; //!< height under which to drop incoming blocks, if doing so uint64_t m_test_drop_download_height = 0; //!< height under which to drop incoming blocks, if doing so
tx_memory_pool m_mempool; //!< transaction pool instance tx_memory_pool m_mempool; //!< transaction pool instance
#if BLOCKCHAIN_DB == DB_LMDB
Blockchain m_blockchain_storage; //!< Blockchain instance Blockchain m_blockchain_storage; //!< Blockchain instance
#else
blockchain_storage m_blockchain_storage;
#endif
i_cryptonote_protocol* m_pprotocol; //!< cryptonote protocol instance i_cryptonote_protocol* m_pprotocol; //!< cryptonote protocol instance

@ -37,11 +37,7 @@
#include "cryptonote_format_utils.h" #include "cryptonote_format_utils.h"
#include "cryptonote_boost_serialization.h" #include "cryptonote_boost_serialization.h"
#include "cryptonote_config.h" #include "cryptonote_config.h"
#if BLOCKCHAIN_DB == DB_LMDB
#include "blockchain.h" #include "blockchain.h"
#else
#include "blockchain_storage.h"
#endif
#include "common/boost_serialization_helper.h" #include "common/boost_serialization_helper.h"
#include "common/int-util.h" #include "common/int-util.h"
#include "misc_language.h" #include "misc_language.h"
@ -74,18 +70,11 @@ namespace cryptonote
} }
} }
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
#if BLOCKCHAIN_DB == DB_LMDB
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
tx_memory_pool::tx_memory_pool(Blockchain& bchs): m_blockchain(bchs) tx_memory_pool::tx_memory_pool(Blockchain& bchs): m_blockchain(bchs)
{ {
} }
#else
tx_memory_pool::tx_memory_pool(blockchain_storage& bchs): m_blockchain(bchs)
{
}
#endif
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
bool tx_memory_pool::add_tx(const transaction &tx, /*const crypto::hash& tx_prefix_hash,*/ const crypto::hash &id, size_t blob_size, tx_verification_context& tvc, bool kept_by_block, bool relayed, uint8_t version) bool tx_memory_pool::add_tx(const transaction &tx, /*const crypto::hash& tx_prefix_hash,*/ const crypto::hash &id, size_t blob_size, tx_verification_context& tvc, bool kept_by_block, bool relayed, uint8_t version)
{ {
@ -169,11 +158,7 @@ namespace cryptonote
crypto::hash max_used_block_id = null_hash; crypto::hash max_used_block_id = null_hash;
uint64_t max_used_block_height = 0; uint64_t max_used_block_height = 0;
#if BLOCKCHAIN_DB == DB_LMDB
bool ch_inp_res = m_blockchain.check_tx_inputs(tx, max_used_block_height, max_used_block_id, tvc, kept_by_block); bool ch_inp_res = m_blockchain.check_tx_inputs(tx, max_used_block_height, max_used_block_id, tvc, kept_by_block);
#else
bool ch_inp_res = m_blockchain.check_tx_inputs(tx, max_used_block_height, max_used_block_id);
#endif
CRITICAL_REGION_LOCAL(m_transactions_lock); CRITICAL_REGION_LOCAL(m_transactions_lock);
if(!ch_inp_res) if(!ch_inp_res)
{ {
@ -518,12 +503,8 @@ namespace cryptonote
if(txd.last_failed_id == m_blockchain.get_block_id_by_height(txd.last_failed_height)) if(txd.last_failed_id == m_blockchain.get_block_id_by_height(txd.last_failed_height))
return false; return false;
//check ring signature again, it is possible (with very small chance) that this transaction become again valid //check ring signature again, it is possible (with very small chance) that this transaction become again valid
#if BLOCKCHAIN_DB == DB_LMDB
tx_verification_context tvc; tx_verification_context tvc;
if(!m_blockchain.check_tx_inputs(txd.tx, txd.max_used_block_height, txd.max_used_block_id, tvc)) if(!m_blockchain.check_tx_inputs(txd.tx, txd.max_used_block_height, txd.max_used_block_id, tvc))
#else
if(!m_blockchain.check_tx_inputs(txd.tx, txd.max_used_block_height, txd.max_used_block_id))
#endif
{ {
txd.last_failed_height = m_blockchain.get_current_blockchain_height()-1; txd.last_failed_height = m_blockchain.get_current_blockchain_height()-1;
txd.last_failed_id = m_blockchain.get_block_id_by_height(txd.last_failed_height); txd.last_failed_id = m_blockchain.get_block_id_by_height(txd.last_failed_height);

@ -48,11 +48,7 @@
namespace cryptonote namespace cryptonote
{ {
#if BLOCKCHAIN_DB == DB_LMDB
class Blockchain; class Blockchain;
#else
class blockchain_storage;
#endif
/************************************************************************/ /************************************************************************/
/* */ /* */
/************************************************************************/ /************************************************************************/
@ -93,16 +89,12 @@ namespace cryptonote
class tx_memory_pool: boost::noncopyable class tx_memory_pool: boost::noncopyable
{ {
public: public:
#if BLOCKCHAIN_DB == DB_LMDB
/** /**
* @brief Constructor * @brief Constructor
* *
* @param bchs a Blockchain class instance, for getting chain info * @param bchs a Blockchain class instance, for getting chain info
*/ */
tx_memory_pool(Blockchain& bchs); tx_memory_pool(Blockchain& bchs);
#else
tx_memory_pool(blockchain_storage& bchs);
#endif
/** /**
@ -492,18 +484,7 @@ namespace cryptonote
std::unordered_set<crypto::hash> m_timed_out_transactions; std::unordered_set<crypto::hash> m_timed_out_transactions;
std::string m_config_folder; //!< the folder to save state to std::string m_config_folder; //!< the folder to save state to
#if BLOCKCHAIN_DB == DB_LMDB
Blockchain& m_blockchain; //!< reference to the Blockchain object Blockchain& m_blockchain; //!< reference to the Blockchain object
#else
blockchain_storage& m_blockchain;
#endif
#if BLOCKCHAIN_DB == DB_LMDB
#else
#if defined(DEBUG_CREATE_BLOCK_TEMPLATE)
friend class blockchain_storage;
#endif
#endif
}; };
} }

@ -1023,7 +1023,6 @@ namespace cryptonote
return false; return false;
} }
#if BLOCKCHAIN_DB == DB_LMDB
const Blockchain &blockchain = m_core.get_blockchain_storage(); const Blockchain &blockchain = m_core.get_blockchain_storage();
uint8_t version = req.version > 0 ? req.version : blockchain.get_next_hard_fork_version(); uint8_t version = req.version > 0 ? req.version : blockchain.get_next_hard_fork_version();
res.version = blockchain.get_current_hard_fork_version(); res.version = blockchain.get_current_hard_fork_version();
@ -1031,11 +1030,6 @@ namespace cryptonote
res.state = blockchain.get_hard_fork_state(); res.state = blockchain.get_hard_fork_state();
res.status = CORE_RPC_STATUS_OK; res.status = CORE_RPC_STATUS_OK;
return true; return true;
#else
error_resp.code = CORE_RPC_ERROR_CODE_UNSUPPORTED_RPC;
error_resp.message = "Hard fork inoperative in memory mode.";
return false;
#endif
} }
//------------------------------------------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------------------------------------------
bool core_rpc_server::on_get_bans(const COMMAND_RPC_GETBANS::request& req, COMMAND_RPC_GETBANS::response& res, epee::json_rpc::error& error_resp) bool core_rpc_server::on_get_bans(const COMMAND_RPC_GETBANS::request& req, COMMAND_RPC_GETBANS::response& res, epee::json_rpc::error& error_resp)

@ -34,7 +34,6 @@
#include "cryptonote_core/cryptonote_basic_impl.h" #include "cryptonote_core/cryptonote_basic_impl.h"
#include "cryptonote_core/verification_context.h" #include "cryptonote_core/verification_context.h"
#include "cryptonote_core/blockchain_storage.h"
#include <unordered_map> #include <unordered_map>
namespace tests namespace tests
@ -82,7 +81,7 @@ namespace tests
bool on_idle(){return true;} bool on_idle(){return true;}
bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp){return true;} bool find_blockchain_supplement(const std::list<crypto::hash>& qblock_ids, cryptonote::NOTIFY_RESPONSE_CHAIN_ENTRY::request& resp){return true;}
bool handle_get_objects(cryptonote::NOTIFY_REQUEST_GET_OBJECTS::request& arg, cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote::cryptonote_connection_context& context){return true;} bool handle_get_objects(cryptonote::NOTIFY_REQUEST_GET_OBJECTS::request& arg, cryptonote::NOTIFY_RESPONSE_GET_OBJECTS::request& rsp, cryptonote::cryptonote_connection_context& context){return true;}
cryptonote::blockchain_storage &get_blockchain_storage() { throw std::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class proxy_core."); } cryptonote::Blockchain &get_blockchain_storage() { throw std::runtime_error("Called invalid member function: please never call get_blockchain_storage on the TESTING class proxy_core."); }
bool get_test_drop_download() {return true;} bool get_test_drop_download() {return true;}
bool get_test_drop_download_height() {return true;} bool get_test_drop_download_height() {return true;}
bool prepare_handle_incoming_blocks(const std::list<cryptonote::block_complete_entry> &blocks) { return true; } bool prepare_handle_incoming_blocks(const std::list<cryptonote::block_complete_entry> &blocks) { return true; }

@ -31,7 +31,6 @@
#include "include_base_utils.h" #include "include_base_utils.h"
using namespace epee; using namespace epee;
#include "wallet/wallet2.h" #include "wallet/wallet2.h"
#include "cryptonote_core/blockchain_storage.h"
using namespace cryptonote; using namespace cryptonote;

Loading…
Cancel
Save