diff options
Diffstat (limited to 'src/blockchain_db')
-rw-r--r-- | src/blockchain_db/blockchain_db.cpp | 4 | ||||
-rw-r--r-- | src/blockchain_db/blockchain_db.h | 69 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.cpp | 128 | ||||
-rw-r--r-- | src/blockchain_db/lmdb/db_lmdb.h | 14 | ||||
-rw-r--r-- | src/blockchain_db/testdb.h | 13 |
5 files changed, 170 insertions, 58 deletions
diff --git a/src/blockchain_db/blockchain_db.cpp b/src/blockchain_db/blockchain_db.cpp index d772bf4bb..2b039f557 100644 --- a/src/blockchain_db/blockchain_db.cpp +++ b/src/blockchain_db/blockchain_db.cpp @@ -211,8 +211,6 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck if (blk.tx_hashes.size() != txs.size()) throw std::runtime_error("Inconsistent tx/hashes sizes"); - block_txn_start(false); - TIME_MEASURE_START(time1); crypto::hash blk_hash = get_block_hash(blk); TIME_MEASURE_FINISH(time1); @@ -252,8 +250,6 @@ uint64_t BlockchainDB::add_block( const std::pair<block, blobdata>& blck m_hardfork->add(blk, prev_height); - block_txn_stop(); - ++num_calls; return prev_height; diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index d2fe39fc2..567be6a65 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -770,9 +770,12 @@ public: */ virtual void set_batch_transactions(bool) = 0; - virtual void block_txn_start(bool readonly=false) = 0; - virtual void block_txn_stop() = 0; - virtual void block_txn_abort() = 0; + virtual void block_wtxn_start() = 0; + virtual void block_wtxn_stop() = 0; + virtual void block_wtxn_abort() = 0; + virtual bool block_rtxn_start() const = 0; + virtual void block_rtxn_stop() const = 0; + virtual void block_rtxn_abort() const = 0; virtual void set_hard_fork(HardFork* hf); @@ -1514,6 +1517,20 @@ public: virtual bool check_pruning() = 0; /** + * @brief get the max block size + */ + virtual uint64_t get_max_block_size() = 0; + + /** + * @brief add a new max block size + * + * The max block size will be the maximum of sz and the current block size + * + * @param: sz the block size + */ + + virtual void add_max_block_size(uint64_t sz) = 0; + /** * @brief runs a function over all txpool transactions * * The subclass should run the passed function for each txpool tx it has @@ -1685,6 +1702,52 @@ public: }; // class BlockchainDB +class db_txn_guard +{ +public: + db_txn_guard(BlockchainDB *db, bool readonly): db(db), readonly(readonly), active(false) + { + if (readonly) + { + active = db->block_rtxn_start(); + } + else + { + db->block_wtxn_start(); + active = true; + } + } + virtual ~db_txn_guard() + { + if (active) + stop(); + } + void stop() + { + if (readonly) + db->block_rtxn_stop(); + else + db->block_wtxn_stop(); + active = false; + } + void abort() + { + if (readonly) + db->block_rtxn_abort(); + else + db->block_wtxn_abort(); + active = false; + } + +private: + BlockchainDB *db; + bool readonly; + bool active; +}; + +class db_rtxn_guard: public db_txn_guard { public: db_rtxn_guard(BlockchainDB *db): db_txn_guard(db, true) {} }; +class db_wtxn_guard: public db_txn_guard { public: db_wtxn_guard(BlockchainDB *db): db_txn_guard(db, false) {} }; + BlockchainDB *new_db(const std::string& db_type); } // namespace cryptonote diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 9f71fd068..340434888 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -2513,6 +2513,58 @@ std::vector<uint64_t> BlockchainLMDB::get_block_info_64bit_fields(uint64_t start return ret; } +uint64_t BlockchainLMDB::get_max_block_size() +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + + TXN_PREFIX_RDONLY(); + RCURSOR(properties) + MDB_val_str(k, "max_block_size"); + MDB_val v; + int result = mdb_cursor_get(m_cur_properties, &k, &v, MDB_SET); + if (result == MDB_NOTFOUND) + return std::numeric_limits<uint64_t>::max(); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to retrieve max block size: ", result).c_str())); + if (v.mv_size != sizeof(uint64_t)) + throw0(DB_ERROR("Failed to retrieve or create max block size: unexpected value size")); + uint64_t max_block_size; + memcpy(&max_block_size, v.mv_data, sizeof(max_block_size)); + TXN_POSTFIX_RDONLY(); + return max_block_size; +} + +void BlockchainLMDB::add_max_block_size(uint64_t sz) +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + check_open(); + mdb_txn_cursors *m_cursors = &m_wcursors; + + CURSOR(properties) + + MDB_val_str(k, "max_block_size"); + MDB_val v; + int result = mdb_cursor_get(m_cur_properties, &k, &v, MDB_SET); + if (result && result != MDB_NOTFOUND) + throw0(DB_ERROR(lmdb_error("Failed to retrieve max block size: ", result).c_str())); + uint64_t max_block_size = 0; + if (result == 0) + { + if (v.mv_size != sizeof(uint64_t)) + throw0(DB_ERROR("Failed to retrieve or create max block size: unexpected value size")); + memcpy(&max_block_size, v.mv_data, sizeof(max_block_size)); + } + if (sz > max_block_size) + max_block_size = sz; + v.mv_data = (void*)&max_block_size; + v.mv_size = sizeof(max_block_size); + result = mdb_cursor_put(m_cur_properties, &k, &v, 0); + if (result) + throw0(DB_ERROR(lmdb_error("Failed to set max_block_size: ", result).c_str())); +} + + std::vector<uint64_t> BlockchainLMDB::get_block_weights(uint64_t start_height, size_t count) const { return get_block_info_64bit_fields(start_height, count, offsetof(mdb_block_info, bi_weight)); @@ -3559,16 +3611,15 @@ void BlockchainLMDB::block_rtxn_stop() const memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags)); } -void BlockchainLMDB::block_txn_start(bool readonly) +bool BlockchainLMDB::block_rtxn_start() const { - if (readonly) - { - MDB_txn *mtxn; - mdb_txn_cursors *mcur; - block_rtxn_start(&mtxn, &mcur); - return; - } + MDB_txn *mtxn; + mdb_txn_cursors *mcur; + return block_rtxn_start(&mtxn, &mcur); +} +void BlockchainLMDB::block_wtxn_start() +{ LOG_PRINT_L3("BlockchainLMDB::" << __func__); // Distinguish the exceptions here from exceptions that would be thrown while // using the txn and committing it. @@ -3600,10 +3651,13 @@ void BlockchainLMDB::block_txn_start(bool readonly) throw0(DB_ERROR_TXN_START((std::string("Attempted to start new write txn when batch txn already exists in ")+__FUNCTION__).c_str())); } -void BlockchainLMDB::block_txn_stop() +void BlockchainLMDB::block_wtxn_stop() { LOG_PRINT_L3("BlockchainLMDB::" << __func__); - if (m_write_txn && m_writer == boost::this_thread::get_id()) + if (!m_write_txn) + throw0(DB_ERROR_TXN_START((std::string("Attempted to stop write txn when no such txn exists in ")+__FUNCTION__).c_str())); + if (m_writer != boost::this_thread::get_id()) + throw0(DB_ERROR_TXN_START((std::string("Attempted to stop write txn from the wrong thread in ")+__FUNCTION__).c_str())); { if (! m_batch_active) { @@ -3617,40 +3671,31 @@ void BlockchainLMDB::block_txn_stop() memset(&m_wcursors, 0, sizeof(m_wcursors)); } } - else if (m_tinfo->m_ti_rtxn) - { - mdb_txn_reset(m_tinfo->m_ti_rtxn); - memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags)); - } } -void BlockchainLMDB::block_txn_abort() +void BlockchainLMDB::block_wtxn_abort() { LOG_PRINT_L3("BlockchainLMDB::" << __func__); - if (m_write_txn && m_writer == boost::this_thread::get_id()) - { - if (! m_batch_active) - { - delete m_write_txn; - m_write_txn = nullptr; - memset(&m_wcursors, 0, sizeof(m_wcursors)); - } - } - else if (m_tinfo->m_ti_rtxn) - { - mdb_txn_reset(m_tinfo->m_ti_rtxn); - memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags)); - } - else + if (!m_write_txn) + throw0(DB_ERROR_TXN_START((std::string("Attempted to abort write txn when no such txn exists in ")+__FUNCTION__).c_str())); + if (m_writer != boost::this_thread::get_id()) + throw0(DB_ERROR_TXN_START((std::string("Attempted to abort write txn from the wrong thread in ")+__FUNCTION__).c_str())); + + if (! m_batch_active) { - // This would probably mean an earlier exception was caught, but then we - // proceeded further than we should have. - throw0(DB_ERROR((std::string("BlockchainLMDB::") + __func__ + - std::string(": block-level DB transaction abort called when write txn doesn't exist") - ).c_str())); + delete m_write_txn; + m_write_txn = nullptr; + memset(&m_wcursors, 0, sizeof(m_wcursors)); } } +void BlockchainLMDB::block_rtxn_abort() const +{ + LOG_PRINT_L3("BlockchainLMDB::" << __func__); + mdb_txn_reset(m_tinfo->m_ti_rtxn); + memset(&m_tinfo->m_ti_rflags, 0, sizeof(m_tinfo->m_ti_rflags)); +} + uint64_t BlockchainLMDB::add_block(const std::pair<block, blobdata>& blk, size_t block_weight, uint64_t long_term_block_weight, const difficulty_type& cumulative_difficulty, const uint64_t& coins_generated, const std::vector<std::pair<transaction, blobdata>>& txs) { @@ -3676,11 +3721,6 @@ uint64_t BlockchainLMDB::add_block(const std::pair<block, blobdata>& blk, size_t { throw; } - catch (...) - { - block_txn_abort(); - throw; - } return ++m_height; } @@ -3690,16 +3730,16 @@ void BlockchainLMDB::pop_block(block& blk, std::vector<transaction>& txs) LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); - block_txn_start(false); + block_wtxn_start(); try { BlockchainDB::pop_block(blk, txs); - block_txn_stop(); + block_wtxn_stop(); } catch (...) { - block_txn_abort(); + block_wtxn_abort(); throw; } } diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 2f89b77ac..4b46f081e 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -310,11 +310,14 @@ public: virtual void batch_stop(); virtual void batch_abort(); - virtual void block_txn_start(bool readonly); - virtual void block_txn_stop(); - virtual void block_txn_abort(); - virtual bool block_rtxn_start(MDB_txn **mtxn, mdb_txn_cursors **mcur) const; + virtual void block_wtxn_start(); + virtual void block_wtxn_stop(); + virtual void block_wtxn_abort(); + virtual bool block_rtxn_start() const; virtual void block_rtxn_stop() const; + virtual void block_rtxn_abort() const; + + bool block_rtxn_start(MDB_txn **mtxn, mdb_txn_cursors **mcur) const; virtual void pop_block(block& blk, std::vector<transaction>& txs); @@ -400,6 +403,9 @@ private: std::vector<uint64_t> get_block_info_64bit_fields(uint64_t start_height, size_t count, off_t offset) const; + uint64_t get_max_block_size(); + void add_max_block_size(uint64_t sz); + // fix up anything that may be wrong due to past bugs virtual void fixup(); diff --git a/src/blockchain_db/testdb.h b/src/blockchain_db/testdb.h index 7916364c5..1492fb2ae 100644 --- a/src/blockchain_db/testdb.h +++ b/src/blockchain_db/testdb.h @@ -55,9 +55,13 @@ public: virtual bool batch_start(uint64_t batch_num_blocks=0, uint64_t batch_bytes=0) { return true; } virtual void batch_stop() {} virtual void set_batch_transactions(bool) {} - virtual void block_txn_start(bool readonly=false) {} - virtual void block_txn_stop() {} - virtual void block_txn_abort() {} + virtual void block_wtxn_start() {} + virtual void block_wtxn_stop() {} + virtual void block_wtxn_abort() {} + virtual bool block_rtxn_start() const { return true; } + virtual void block_rtxn_stop() const {} + virtual void block_rtxn_abort() const {} + virtual void drop_hard_fork_info() {} virtual bool block_exists(const crypto::hash& h, uint64_t *height) const { return false; } virtual cryptonote::blobdata get_block_blob_from_height(const uint64_t& height) const { return cryptonote::t_serializable_object_to_blob(get_block_from_height(height)); } @@ -149,6 +153,9 @@ public: virtual bool update_pruning() { return true; } virtual bool check_pruning() { return true; } virtual void prune_outputs(uint64_t amount) {} + + virtual uint64_t get_max_block_size() { return 100000000; } + virtual void add_max_block_size(uint64_t sz) { } }; } |