aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Winget <tewinget@gmail.com>2015-03-25 11:41:30 -0400
committerThomas Winget <tewinget@gmail.com>2015-03-25 12:09:44 -0400
commit7b14d4a17f739c383322312f1a597f264c074c6e (patch)
tree3934f69a876d5f10637c93fc868d5a8f139aa164
parentupdate berkeleydb branch to blockchain branch (diff)
downloadmonero-7b14d4a17f739c383322312f1a597f264c074c6e.tar.xz
Steps toward multiple dbs available -- working
There will need to be some more refactoring for these changes to be considered complete/correct, but for now it's working. new daemon cli argument "--db-type", works for LMDB and BerkeleyDB. A good deal of refactoring is also present in this commit, namely Blockchain no longer instantiates BlockchainDB, but rather is passed a pointer to an already-instantiated BlockchainDB on init().
-rw-r--r--src/blockchain_converter/fake_core.h26
-rw-r--r--src/blockchain_db/berkeleydb/db_bdb.cpp7
-rw-r--r--src/blockchain_db/berkeleydb/db_bdb.h3
-rw-r--r--src/blockchain_db/blockchain_db.cpp5
-rw-r--r--src/blockchain_db/blockchain_db.h6
-rw-r--r--src/blockchain_db/db_types.h40
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.cpp7
-rw-r--r--src/blockchain_db/lmdb/db_lmdb.h4
-rw-r--r--src/cryptonote_core/blockchain.cpp41
-rw-r--r--src/cryptonote_core/blockchain.h4
-rw-r--r--src/cryptonote_core/cryptonote_core.cpp41
-rw-r--r--src/daemon/command_line_args.h5
-rw-r--r--src/daemon/main.cpp15
13 files changed, 146 insertions, 58 deletions
diff --git a/src/blockchain_converter/fake_core.h b/src/blockchain_converter/fake_core.h
index 175cb4660..f82b05d04 100644
--- a/src/blockchain_converter/fake_core.h
+++ b/src/blockchain_converter/fake_core.h
@@ -29,8 +29,10 @@
#pragma once
#include <boost/filesystem.hpp>
-#include "cryptonote_core/blockchain.h" // BlockchainDB and LMDB
+#include "cryptonote_core/blockchain.h" // BlockchainDB
#include "cryptonote_core/blockchain_storage.h" // in-memory DB
+#include "blockchain_db/blockchain_db.h"
+#include "blockchain_db/lmdb/db_lmdb.h"
using namespace cryptonote;
@@ -53,7 +55,27 @@ struct fake_core_lmdb
#endif
{
m_pool.init(path.string());
- m_storage.init(path.string(), use_testnet, mdb_flags);
+
+ BlockchainDB* db = new BlockchainLMDB();
+
+ boost::filesystem::path folder(path);
+
+ folder /= db->get_db_name();
+
+ LOG_PRINT_L0("Loading blockchain from folder " << folder.c_str() << " ...");
+
+ const std::string filename = folder.string();
+ try
+ {
+ db->open(filename, mdb_flags);
+ }
+ catch (const std::exception& e)
+ {
+ LOG_PRINT_L0("Error opening database: " << e.what());
+ throw;
+ }
+
+ m_storage.init(db, use_testnet);
if (do_batch)
m_storage.get_db().set_batch_transactions(do_batch);
support_batch = true;
diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp
index 786c13b0b..4b254500b 100644
--- a/src/blockchain_db/berkeleydb/db_bdb.cpp
+++ b/src/blockchain_db/berkeleydb/db_bdb.cpp
@@ -724,13 +724,6 @@ void BlockchainBDB::open(const std::string& filename, const int db_flags)
m_open = true;
}
-// unused for now, create will happen on open if doesn't exist
-void BlockchainBDB::create(const std::string& filename)
-{
- LOG_PRINT_L3("BlockchainBDB::" << __func__);
- throw DB_CREATE_FAILURE("create() is not implemented for this BlockchainDB, open() will create files if needed.");
-}
-
void BlockchainBDB::close()
{
LOG_PRINT_L3("BlockchainBDB::" << __func__);
diff --git a/src/blockchain_db/berkeleydb/db_bdb.h b/src/blockchain_db/berkeleydb/db_bdb.h
index b68ed287f..d4eb5434c 100644
--- a/src/blockchain_db/berkeleydb/db_bdb.h
+++ b/src/blockchain_db/berkeleydb/db_bdb.h
@@ -95,8 +95,6 @@ public:
virtual void open(const std::string& filename, const int db_flags);
- virtual void create(const std::string& filename);
-
virtual void close();
virtual void sync();
@@ -279,7 +277,6 @@ private:
Db* m_spent_keys;
- bool m_open;
uint64_t m_height;
uint64_t m_num_outputs;
std::string m_folder;
diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp
index 8b08d3805..d648be44e 100644
--- a/src/blockchain_db/blockchain_db.cpp
+++ b/src/blockchain_db/blockchain_db.cpp
@@ -129,6 +129,11 @@ void BlockchainDB::pop_block(block& blk, std::vector<transaction>& txs)
}
}
+bool BlockchainDB::is_open()
+{
+ return m_open;
+}
+
void BlockchainDB::remove_transaction(const crypto::hash& tx_hash)
{
transaction tx = get_tx(tx_hash);
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h
index 7b6b55a40..04d9c5384 100644
--- a/src/blockchain_db/blockchain_db.h
+++ b/src/blockchain_db/blockchain_db.h
@@ -62,6 +62,7 @@
*
* General:
* open()
+ * is_open()
* close()
* sync()
* reset()
@@ -328,8 +329,8 @@ public:
// open the db at location <filename>, or create it if there isn't one.
virtual void open(const std::string& filename, const int db_flags = 0) = 0;
- // make sure implementation has a create function as well
- virtual void create(const std::string& filename) = 0;
+ // returns true of the db is open/ready, else false
+ bool is_open();
// close and sync the db
virtual void close() = 0;
@@ -482,6 +483,7 @@ public:
// returns true if key image <img> is present in spent key images storage
virtual bool has_key_image(const crypto::key_image& img) const = 0;
+ bool m_open;
}; // class BlockchainDB
diff --git a/src/blockchain_db/db_types.h b/src/blockchain_db/db_types.h
new file mode 100644
index 000000000..b13007df4
--- /dev/null
+++ b/src/blockchain_db/db_types.h
@@ -0,0 +1,40 @@
+// Copyright (c) 2015, 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
+
+namespace cryptonote
+{
+
+ const std::unordered_set<std::string> blockchain_db_types =
+ { "lmdb"
+ , "berkeley"
+ };
+
+} // namespace cryptonote
diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp
index 524a1c269..8e09dfab2 100644
--- a/src/blockchain_db/lmdb/db_lmdb.cpp
+++ b/src/blockchain_db/lmdb/db_lmdb.cpp
@@ -733,13 +733,6 @@ void BlockchainLMDB::open(const std::string& filename, const int mdb_flags)
// from here, init should be finished
}
-// unused for now, create will happen on open if doesn't exist
-void BlockchainLMDB::create(const std::string& filename)
-{
- LOG_PRINT_L3("BlockchainLMDB::" << __func__);
- throw DB_CREATE_FAILURE("create() is not implemented for this BlockchainDB, open() will create files if needed.");
-}
-
void BlockchainLMDB::close()
{
LOG_PRINT_L3("BlockchainLMDB::" << __func__);
diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h
index c3c7ce439..8f1e07e0d 100644
--- a/src/blockchain_db/lmdb/db_lmdb.h
+++ b/src/blockchain_db/lmdb/db_lmdb.h
@@ -24,6 +24,7 @@
// 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.
+#pragma once
#include "blockchain_db/blockchain_db.h"
#include "cryptonote_protocol/blobdatatype.h" // for type blobdata
@@ -116,8 +117,6 @@ public:
virtual void open(const std::string& filename, const int mdb_flags=0);
- virtual void create(const std::string& filename);
-
virtual void close();
virtual void sync();
@@ -302,7 +301,6 @@ private:
MDB_dbi m_spent_keys;
- bool m_open;
uint64_t m_height;
uint64_t m_num_outputs;
std::string m_folder;
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 57934b3fc..0261a5614 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -39,7 +39,6 @@
#include "tx_pool.h"
#include "blockchain.h"
#include "blockchain_db/blockchain_db.h"
-#include "blockchain_db/lmdb/db_lmdb.h"
#include "cryptonote_format_utils.h"
#include "cryptonote_boost_serialization.h"
#include "cryptonote_config.h"
@@ -65,8 +64,7 @@ using epee::string_tools::pod_to_hex;
DISABLE_VS_WARNINGS(4267)
//------------------------------------------------------------------
-// TODO: initialize m_db with a concrete implementation of BlockchainDB
-Blockchain::Blockchain(tx_memory_pool& tx_pool):m_db(), m_tx_pool(tx_pool), m_current_block_cumul_sz_limit(0), m_is_in_checkpoint_zone(false), m_is_blockchain_storing(false), m_testnet(false), m_enforce_dns_checkpoints(false)
+Blockchain::Blockchain(tx_memory_pool& tx_pool):m_db(), 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)
{
LOG_PRINT_L3("Blockchain::" << __func__);
}
@@ -226,43 +224,24 @@ uint64_t Blockchain::get_current_blockchain_height() const
//------------------------------------------------------------------
//FIXME: possibly move this into the constructor, to avoid accidentally
// dereferencing a null BlockchainDB pointer
-bool Blockchain::init(const std::string& config_folder, const bool testnet, const int db_flags)
+bool Blockchain::init(BlockchainDB* db, const bool testnet)
{
LOG_PRINT_L3("Blockchain::" << __func__);
CRITICAL_REGION_LOCAL(m_blockchain_lock);
- // TODO: make this configurable
- m_db = new BlockchainLMDB();
-
- m_config_folder = config_folder;
- m_testnet = testnet;
-
- boost::filesystem::path folder(m_config_folder);
-
- folder /= m_db->get_db_name();
-
- LOG_PRINT_L0("Loading blockchain from folder " << folder.c_str() << " ...");
-
- const std::string filename = folder.string();
- try
+ if (db == nullptr)
{
- m_db->open(filename, db_flags);
+ LOG_ERROR("Attempted to init Blockchain with null DB");
+ return false;
}
- catch (const DB_OPEN_FAILURE& e)
+ if (!db->is_open())
{
- LOG_PRINT_L0("No blockchain file found, attempting to create one.");
- try
- {
- m_db->create(filename);
- }
- catch (const DB_CREATE_FAILURE& db_create_error)
- {
- LOG_PRINT_L0("Unable to create BlockchainDB! This is not good...");
- //TODO: make sure whatever calls this handles the return value properly
- return false;
- }
+ LOG_ERROR("Attempted to init Blockchain with unopened DB");
+ return false;
}
+ m_db = db;
+
// if the blockchain is new, add the genesis block
// this feels kinda kludgy to do it this way, but can be looked at later.
// TODO: add function to create and store genesis block,
diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h
index dc98a56a4..bc13901d2 100644
--- a/src/cryptonote_core/blockchain.h
+++ b/src/cryptonote_core/blockchain.h
@@ -81,7 +81,7 @@ namespace cryptonote
Blockchain(tx_memory_pool& tx_pool);
- bool init(const std::string& config_folder, const bool testnet = false, const int db_flags = 0);
+ bool init(BlockchainDB* db, const bool testnet = false);
bool deinit();
void set_checkpoints(checkpoints&& chk_pts) { m_checkpoints = chk_pts; }
@@ -180,11 +180,9 @@ namespace cryptonote
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_testnet;
bool m_enforce_dns_checkpoints;
bool switch_to_alternative_blockchain(std::list<blocks_ext_by_hash::iterator>& alt_chain, bool discard_disconnected_chain);
diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp
index f9b2b19ff..7864b55c8 100644
--- a/src/cryptonote_core/cryptonote_core.cpp
+++ b/src/cryptonote_core/cryptonote_core.cpp
@@ -44,6 +44,9 @@ using namespace epee;
#include <csignal>
#include "daemon/command_line_args.h"
#include "cryptonote_core/checkpoints_create.h"
+#include "blockchain_db/blockchain_db.h"
+#include "blockchain_db/lmdb/db_lmdb.h"
+#include "blockchain_db/berkeleydb/db_bdb.h"
DISABLE_VS_WARNINGS(4355)
@@ -194,7 +197,45 @@ namespace cryptonote
r = m_mempool.init(m_config_folder);
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, daemon_args::arg_db_type);
+
+ BlockchainDB* db = nullptr;
+ if (db_type == "lmdb")
+ {
+ db = new BlockchainLMDB();
+ }
+ else if (db_type == "berkeley")
+ {
+ db = new BlockchainBDB();
+ }
+ else
+ {
+ LOG_ERROR("Attempted to use non-existant database type");
+ return false;
+ }
+
+ boost::filesystem::path folder(m_config_folder);
+
+ folder /= db->get_db_name();
+
+ LOG_PRINT_L0("Loading blockchain from folder " << folder.c_str() << " ...");
+
+ const std::string filename = folder.string();
+ try
+ {
+ db->open(filename);
+ }
+ catch (const DB_ERROR& e)
+ {
+ LOG_PRINT_L0("Error opening database: " << e.what());
+ return false;
+ }
+
+ r = m_blockchain_storage.init(db, m_testnet);
+#else
r = m_blockchain_storage.init(m_config_folder, m_testnet);
+#endif
CHECK_AND_ASSERT_MES(r, false, "Failed to initialize blockchain storage");
// load json & DNS checkpoints, and verify them
diff --git a/src/daemon/command_line_args.h b/src/daemon/command_line_args.h
index bcf599128..2bd918478 100644
--- a/src/daemon/command_line_args.h
+++ b/src/daemon/command_line_args.h
@@ -70,6 +70,11 @@ namespace daemon_args
, "checkpoints from DNS server will be enforced"
, false
};
+ const command_line::arg_descriptor<std::string> arg_db_type = {
+ "db-type"
+ , "Specify database type"
+ , "lmdb"
+ };
} // namespace daemon_args
diff --git a/src/daemon/main.cpp b/src/daemon/main.cpp
index 5d8baf497..3bad70378 100644
--- a/src/daemon/main.cpp
+++ b/src/daemon/main.cpp
@@ -42,6 +42,7 @@
#include "rpc/core_rpc_server.h"
#include <boost/program_options.hpp>
#include "daemon/command_line_args.h"
+#include "blockchain_db/db_types.h"
namespace po = boost::program_options;
namespace bf = boost::filesystem;
@@ -78,6 +79,7 @@ int main(int argc, char const * argv[])
command_line::add_arg(core_settings, daemon_args::arg_log_level);
command_line::add_arg(core_settings, daemon_args::arg_testnet_on);
command_line::add_arg(core_settings, daemon_args::arg_dns_checkpoints);
+ command_line::add_arg(core_settings, daemon_args::arg_db_type);
daemonizer::init_options(hidden_options, visible_options);
daemonize::t_executor::init_options(core_settings);
@@ -128,6 +130,19 @@ int main(int argc, char const * argv[])
return 0;
}
+ std::string db_type = command_line::get_arg(vm, daemon_args::arg_db_type);
+
+ // verify that blockchaindb type is valid
+ if(cryptonote::blockchain_db_types.count(db_type) == 0)
+ {
+ std::cout << "Invalid database type (" << db_type << "), available types are:" << std::endl;
+ for (const auto& type : cryptonote::blockchain_db_types)
+ {
+ std::cout << "\t" << type << std::endl;
+ }
+ return 0;
+ }
+
bool testnet_mode = command_line::get_arg(vm, daemon_args::arg_testnet_on);
auto data_dir_arg = testnet_mode ? command_line::arg_testnet_data_dir : command_line::arg_data_dir;