From 3bf35e14e3b9a21e4a2b5fbb1dd27ca5b6b8a6f1 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Fri, 4 Dec 2015 22:25:00 +0000 Subject: [PATCH 1/3] db_bdb: read 32 bit heights from keys Keys in Berkeley DB are 32 bits. We don't want to read random bits in the high part. --- src/blockchain_db/berkeleydb/db_bdb.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/blockchain_db/berkeleydb/db_bdb.cpp b/src/blockchain_db/berkeleydb/db_bdb.cpp index da68ff40..486b63a3 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.cpp +++ b/src/blockchain_db/berkeleydb/db_bdb.cpp @@ -588,7 +588,7 @@ bool BlockchainBDB::for_all_blocks(std::function k; + Dbt_copy k; Dbt_safe v; bool ret = true; int result; From a70211842693f00f81c2374b7999eda9e184efce Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 5 Dec 2015 12:40:01 +0000 Subject: [PATCH 2/3] blockchain_dump: fix output key dump for BDB 1-based indices Berkeley DB uses 1 based indices for RECNO databases, and the implementation of BlockchainDB for Berkeley DB assumes 1 based indices are passed to the API, whereas the LMDB one assumes 0 based indices. This is all internally consisteny, but since the BDB code stores 1 based indices in the database, external users have to be aware of this, as the indices will be off by one depending on which DB is used. --- src/blockchain_utilities/blockchain_dump.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/blockchain_utilities/blockchain_dump.cpp b/src/blockchain_utilities/blockchain_dump.cpp index f3666c72..6c61cb90 100644 --- a/src/blockchain_utilities/blockchain_dump.cpp +++ b/src/blockchain_utilities/blockchain_dump.cpp @@ -236,16 +236,19 @@ int main(int argc, char* argv[]) BlockchainDB* db; int mdb_flags = 0; std::string db_type = command_line::get_arg(vm, arg_db_type); + size_t base_idx = 0; if (db_type.empty() || db_type == "lmdb") { db = new BlockchainLMDB(); mdb_flags |= MDB_RDONLY; + base_idx = 0; } #ifdef BERKELEY_DB else if (db_type == "berkeley") { db = new BlockchainBDB(); // can't open readonly due to the way flags are split in db_bdb.cpp + base_idx = 1; } #endif else @@ -386,7 +389,7 @@ int main(int argc, char* argv[]) { try { - tx_out_index toi = db->get_output_tx_and_index_from_global(idx); + tx_out_index toi = db->get_output_tx_and_index_from_global(idx + base_idx); start_struct(d, boost::lexical_cast(idx)); write_pod(d, "tx_hash", string_tools::pod_to_hex(toi.first)); write_pod(d, "tx_index", string_tools::pod_to_hex(toi.second)); @@ -406,7 +409,7 @@ int main(int argc, char* argv[]) { try { - output_data_t od = db->get_output_key(idx); + output_data_t od = db->get_output_key(idx + base_idx); start_struct(d, boost::lexical_cast(idx)); write_pod(d, "pubkey", string_tools::pod_to_hex(od.pubkey)); write_pod(d, "unlock_time", od.unlock_time); From a3c5ca077c27b7a8fe5ee0a7afdc1d30b6f8ffe8 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Sat, 5 Dec 2015 18:41:29 +0000 Subject: [PATCH 3/3] blockchain_db: make the indexing base a BlockchainDB virtual function --- src/blockchain_db/berkeleydb/db_bdb.h | 2 ++ src/blockchain_db/blockchain_db.h | 3 +++ src/blockchain_utilities/blockchain_dump.cpp | 4 +--- tests/unit_tests/hardfork.cpp | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/blockchain_db/berkeleydb/db_bdb.h b/src/blockchain_db/berkeleydb/db_bdb.h index 6bc9cb4f..d05abea2 100644 --- a/src/blockchain_db/berkeleydb/db_bdb.h +++ b/src/blockchain_db/berkeleydb/db_bdb.h @@ -297,6 +297,8 @@ public: virtual uint64_t get_num_outputs(const uint64_t& amount) const; + virtual uint64_t get_indexing_base() const { return 1; } + virtual output_data_t get_output_key(const uint64_t& amount, const uint64_t& index); virtual output_data_t get_output_key(const uint64_t& global_index) const; virtual void get_output_key(const uint64_t &amount, const std::vector &offsets, std::vector &outputs); diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 85144f04..152f29b3 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -464,6 +464,9 @@ public: // returns the total number of outputs of amount virtual uint64_t get_num_outputs(const uint64_t& amount) const = 0; + // return index of the first element (should be hidden, but isn't) + virtual uint64_t get_indexing_base() const { return 0; } + // return public key for output with global output amount and index virtual output_data_t get_output_key(const uint64_t& amount, const uint64_t& index) = 0; virtual output_data_t get_output_key(const uint64_t& global_index) const = 0; diff --git a/src/blockchain_utilities/blockchain_dump.cpp b/src/blockchain_utilities/blockchain_dump.cpp index 6c61cb90..f5f0986e 100644 --- a/src/blockchain_utilities/blockchain_dump.cpp +++ b/src/blockchain_utilities/blockchain_dump.cpp @@ -236,19 +236,16 @@ int main(int argc, char* argv[]) BlockchainDB* db; int mdb_flags = 0; std::string db_type = command_line::get_arg(vm, arg_db_type); - size_t base_idx = 0; if (db_type.empty() || db_type == "lmdb") { db = new BlockchainLMDB(); mdb_flags |= MDB_RDONLY; - base_idx = 0; } #ifdef BERKELEY_DB else if (db_type == "berkeley") { db = new BlockchainBDB(); // can't open readonly due to the way flags are split in db_bdb.cpp - base_idx = 1; } #endif else @@ -259,6 +256,7 @@ int main(int argc, char* argv[]) boost::filesystem::path folder(m_config_folder); folder /= db->get_db_name(); const std::string filename = folder.string(); + uint64_t base_idx = db->get_indexing_base(); LOG_PRINT_L0("Loading blockchain from folder " << filename << " ..."); try diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp index 254dece5..e59d4c59 100644 --- a/tests/unit_tests/hardfork.cpp +++ b/tests/unit_tests/hardfork.cpp @@ -79,6 +79,7 @@ public: virtual std::vector get_tx_list(const std::vector& hlist) const { return std::vector(); } virtual uint64_t get_tx_block_height(const crypto::hash& h) const { return 0; } virtual uint64_t get_num_outputs(const uint64_t& amount) const { return 1; } + virtual uint64_t get_indexing_base() const { return 0; } virtual output_data_t get_output_key(const uint64_t& amount, const uint64_t& index) { return output_data_t(); } virtual output_data_t get_output_key(const uint64_t& global_index) const { return output_data_t(); } virtual tx_out_index get_output_tx_and_index_from_global(const uint64_t& index) const { return tx_out_index(); }