diff options
Diffstat (limited to 'src/blockchain_db')
-rw-r--r-- | src/blockchain_db/blockchain_db.h | 7 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.cpp | 67 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.h | 4 |
3 files changed, 58 insertions, 20 deletions
diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 838385e8a..79676b808 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -147,8 +147,9 @@ struct txpool_tx_meta_t uint8_t kept_by_block; uint8_t relayed; uint8_t do_not_relay; + uint8_t double_spend_seen: 1; - uint8_t padding[77]; // till 192 bytes + uint8_t padding[76]; // till 192 bytes }; #define DBF_SAFE 1 @@ -1314,7 +1315,7 @@ public: /** * @brief get the number of transactions in the txpool */ - virtual uint64_t get_txpool_tx_count() const = 0; + virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const = 0; /** * @brief check whether a txid is in the txpool @@ -1369,7 +1370,7 @@ public: * * @return false if the function returns false for any transaction, otherwise true */ - virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false) const = 0; + virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)>, bool include_blob = false, bool include_unrelayed_txes = true) const = 0; /** * @brief runs a function over all key images stored diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 985244f6b..6ebb35639 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -558,7 +558,7 @@ void BlockchainLMDB::check_and_resize_for_batch(uint64_t batch_num_blocks, uint6 if (batch_num_blocks > 0) { threshold_size = get_estimated_batch_size(batch_num_blocks, batch_bytes); - LOG_PRINT_L1("calculated batch size: " << threshold_size); + MDEBUG("calculated batch size: " << threshold_size); // The increased DB size could be a multiple of threshold_size, a fixed // size increase (> threshold_size), or other variations. @@ -567,7 +567,7 @@ void BlockchainLMDB::check_and_resize_for_batch(uint64_t batch_num_blocks, uint6 // minimum size increase is used to avoid frequent resizes when the batch // size is set to a very small numbers of blocks. increase_size = (threshold_size > min_increase_size) ? threshold_size : min_increase_size; - LOG_PRINT_L1("increase size: " << increase_size); + MDEBUG("increase size: " << increase_size); } // if threshold_size is 0 (i.e. number of blocks for batch not passed in), it @@ -605,7 +605,7 @@ uint64_t BlockchainLMDB::get_estimated_batch_size(uint64_t batch_num_blocks, uin block_start = block_stop - num_prev_blocks + 1; uint32_t num_blocks_used = 0; uint64_t total_block_size = 0; - LOG_PRINT_L1("[" << __func__ << "] " << "m_height: " << m_height << " block_start: " << block_start << " block_stop: " << block_stop); + MDEBUG("[" << __func__ << "] " << "m_height: " << m_height << " block_start: " << block_start << " block_stop: " << block_stop); size_t avg_block_size = 0; if (batch_bytes) { @@ -614,12 +614,12 @@ uint64_t BlockchainLMDB::get_estimated_batch_size(uint64_t batch_num_blocks, uin } if (m_height == 0) { - LOG_PRINT_L1("No existing blocks to check for average block size"); + MDEBUG("No existing blocks to check for average block size"); } else if (m_cum_count >= num_prev_blocks) { avg_block_size = m_cum_size / m_cum_count; - LOG_PRINT_L1("average block size across recent " << m_cum_count << " blocks: " << avg_block_size); + MDEBUG("average block size across recent " << m_cum_count << " blocks: " << avg_block_size); m_cum_size = 0; m_cum_count = 0; } @@ -638,12 +638,12 @@ uint64_t BlockchainLMDB::get_estimated_batch_size(uint64_t batch_num_blocks, uin } block_rtxn_stop(); avg_block_size = total_block_size / num_blocks_used; - LOG_PRINT_L1("average block size across recent " << num_blocks_used << " blocks: " << avg_block_size); + MDEBUG("average block size across recent " << num_blocks_used << " blocks: " << avg_block_size); } estim: if (avg_block_size < min_block_size) avg_block_size = min_block_size; - LOG_PRINT_L1("estimated average block size for batch: " << avg_block_size); + MDEBUG("estimated average block size for batch: " << avg_block_size); // bigger safety margin on smaller block sizes if (batch_fudge_factor < 5000.0) @@ -1123,6 +1123,12 @@ void BlockchainLMDB::open(const std::string& filename, const int db_flags) m_folder = filename; +#ifdef __OpenBSD__ + if ((mdb_flags & MDB_WRITEMAP) == 0) { + MCLOG_RED(el::Level::Info, "global", "Running on OpenBSD: forcing WRITEMAP"); + mdb_flags |= MDB_WRITEMAP; + } +#endif // set up lmdb environment if ((result = mdb_env_create(&m_env))) throw0(DB_ERROR(lmdb_error("Failed to create lmdb environment: ", result).c_str())); @@ -1516,21 +1522,49 @@ void BlockchainLMDB::update_txpool_tx(const crypto::hash &txid, const txpool_tx_ } } -uint64_t BlockchainLMDB::get_txpool_tx_count() const +uint64_t BlockchainLMDB::get_txpool_tx_count(bool include_unrelayed_txes) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); - TXN_PREFIX_RDONLY(); int result; + uint64_t num_entries = 0; - MDB_stat db_stats; - if ((result = mdb_stat(m_txn, m_txpool_meta, &db_stats))) - throw0(DB_ERROR(lmdb_error("Failed to query m_txpool_meta: ", result).c_str())); + TXN_PREFIX_RDONLY(); + + if (include_unrelayed_txes) + { + // No filtering, we can get the number of tx the "fast" way + MDB_stat db_stats; + if ((result = mdb_stat(m_txn, m_txpool_meta, &db_stats))) + throw0(DB_ERROR(lmdb_error("Failed to query m_txpool_meta: ", result).c_str())); + num_entries = db_stats.ms_entries; + } + else + { + // Filter unrelayed tx out of the result, so we need to loop over transactions and check their meta data + RCURSOR(txpool_meta); + RCURSOR(txpool_blob); + MDB_val k; + MDB_val v; + MDB_cursor_op op = MDB_FIRST; + while (1) + { + result = mdb_cursor_get(m_cur_txpool_meta, &k, &v, op); + op = MDB_NEXT; + if (result == MDB_NOTFOUND) + break; + if (result) + throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx metadata: ", result).c_str())); + const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data; + if (!meta.do_not_relay) + ++num_entries; + } + } TXN_POSTFIX_RDONLY(); - return db_stats.ms_entries; + return num_entries; } bool BlockchainLMDB::txpool_has_tx(const crypto::hash& txid) const @@ -1627,7 +1661,7 @@ cryptonote::blobdata BlockchainLMDB::get_txpool_tx_blob(const crypto::hash& txid return bd; } -bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob) const +bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob, bool include_unrelayed_txes) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -1651,6 +1685,9 @@ bool BlockchainLMDB::for_all_txpool_txes(std::function<bool(const crypto::hash&, throw0(DB_ERROR(lmdb_error("Failed to enumerate txpool tx metadata: ", result).c_str())); const crypto::hash txid = *(const crypto::hash*)k.mv_data; const txpool_tx_meta_t &meta = *(const txpool_tx_meta_t*)v.mv_data; + if (!include_unrelayed_txes && meta.do_not_relay) + // Skipping that tx + continue; const cryptonote::blobdata *passed_bd = NULL; cryptonote::blobdata bd; if (include_blob) @@ -2933,7 +2970,7 @@ void BlockchainLMDB::get_output_key(const uint64_t &amount, const std::vector<ui MDEBUG("Partial result: " << outputs.size() << "/" << offsets.size()); break; } - throw1(OUTPUT_DNE((std::string("Attempting to get output pubkey by global index (amount ") + boost::lexical_cast<std::string>(amount) + ", index " + boost::lexical_cast<std::string>(index) + ", count " + boost::lexical_cast<std::string>(get_num_outputs(amount)) + "), but key does not exist").c_str())); + throw1(OUTPUT_DNE((std::string("Attempting to get output pubkey by global index (amount ") + boost::lexical_cast<std::string>(amount) + ", index " + boost::lexical_cast<std::string>(index) + ", count " + boost::lexical_cast<std::string>(get_num_outputs(amount)) + "), but key does not exist (current height " + boost::lexical_cast<std::string>(height()) + ")").c_str())); } else if (get_result) throw0(DB_ERROR(lmdb_error("Error attempting to retrieve an output pubkey from the db", get_result).c_str())); diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 98571a7f8..fce8f29ed 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -243,13 +243,13 @@ public: virtual void add_txpool_tx(const transaction &tx, const txpool_tx_meta_t& meta); virtual void update_txpool_tx(const crypto::hash &txid, const txpool_tx_meta_t& meta); - virtual uint64_t get_txpool_tx_count() const; + virtual uint64_t get_txpool_tx_count(bool include_unrelayed_txes = true) const; virtual bool txpool_has_tx(const crypto::hash &txid) const; virtual void remove_txpool_tx(const crypto::hash& txid); virtual txpool_tx_meta_t get_txpool_tx_meta(const crypto::hash& txid) const; virtual bool get_txpool_tx_blob(const crypto::hash& txid, cryptonote::blobdata &bd) const; virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid) const; - virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob = false) const; + virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const txpool_tx_meta_t&, const cryptonote::blobdata*)> f, bool include_blob = false, bool include_unrelayed_txes = true) const; virtual bool for_all_key_images(std::function<bool(const crypto::key_image&)>) const; virtual bool for_blocks_range(const uint64_t& h1, const uint64_t& h2, std::function<bool(uint64_t, const crypto::hash&, const cryptonote::block&)>) const; |