diff --git a/src/blockchain_db/blockchain_db.h b/src/blockchain_db/blockchain_db.h index 9abfd0816..c589ed562 100644 --- a/src/blockchain_db/blockchain_db.h +++ b/src/blockchain_db/blockchain_db.h @@ -1308,7 +1308,7 @@ public: * * @return true iff the blocks and transactions were found */ - virtual bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector, std::vector>>>& blocks, bool pruned, bool get_miner_tx_hash) const = 0; + virtual bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector, std::vector>>>& blocks, bool pruned, bool get_miner_tx_hash) const = 0; /** * @brief fetches the prunable transaction blob with the given hash diff --git a/src/blockchain_db/lmdb/db_lmdb.cpp b/src/blockchain_db/lmdb/db_lmdb.cpp index 9f4823b81..aa0eef6b4 100644 --- a/src/blockchain_db/lmdb/db_lmdb.cpp +++ b/src/blockchain_db/lmdb/db_lmdb.cpp @@ -3200,7 +3200,7 @@ std::vector BlockchainLMDB::get_txids_loose(const crypto::hash& tx return matching_hashes; } -bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector, std::vector>>>& blocks, bool pruned, bool get_miner_tx_hash) const +bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector, std::vector>>>& blocks, bool pruned, bool get_miner_tx_hash) const { LOG_PRINT_L3("BlockchainLMDB::" << __func__); check_open(); @@ -3209,7 +3209,11 @@ bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_block_cou RCURSOR(blocks); RCURSOR(tx_indices); RCURSOR(txs_pruned); - if (!pruned) + if (pruned) + { + RCURSOR(txs_prunable_hash); + } + else { RCURSOR(txs_prunable); } @@ -3281,15 +3285,31 @@ bool BlockchainLMDB::get_blocks_from(uint64_t start_height, size_t min_block_cou throw0(DB_ERROR(lmdb_error("Error attempting to retrieve transaction data from the db: ", result).c_str())); tx_blob.assign((const char*)v.mv_data, v.mv_size); - if (!pruned) + crypto::hash prunable_hash = crypto::null_hash; + if (pruned) { + MDB_val v_hash; + result = mdb_cursor_get(m_cur_txs_prunable_hash, &val_tx_id, &v_hash, MDB_SET); + if (result == 0) + { + prunable_hash = *(const crypto::hash*)v_hash.mv_data; + } + else if (result != MDB_NOTFOUND) + { + throw0(DB_ERROR(lmdb_error("Error attempting to retrieve transaction prunable hash from the db: ", result).c_str())); + } + } + else + { + // get the prunable data result = mdb_cursor_get(m_cur_txs_prunable, &val_tx_id, &v, op); if (result) throw0(DB_ERROR(lmdb_error("Error attempting to retrieve transaction data from the db: ", result).c_str())); tx_blob.append(reinterpret_cast(v.mv_data), v.mv_size); } - current_block.second.push_back(std::make_pair(tx_hash, std::move(tx_blob))); - size += current_block.second.back().second.size(); + current_block.second.emplace_back(tx_hash, prunable_hash, std::move(tx_blob)); + + size += std::get<2>(current_block.second.back()).size(); } if (blocks.size() >= min_block_count && num_txes >= max_tx_count) diff --git a/src/blockchain_db/lmdb/db_lmdb.h b/src/blockchain_db/lmdb/db_lmdb.h index 62d61e99f..74bcadeda 100644 --- a/src/blockchain_db/lmdb/db_lmdb.h +++ b/src/blockchain_db/lmdb/db_lmdb.h @@ -254,7 +254,7 @@ public: bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override; bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override; bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector &bd) const override; - bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector, std::vector>>>& blocks, bool pruned, bool get_miner_tx_hash) const override; + bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector, std::vector>>>& blocks, bool pruned, bool get_miner_tx_hash) const override; bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override; bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const override; diff --git a/src/blockchain_db/testdb.h b/src/blockchain_db/testdb.h index 43810ff97..6b110ad3a 100644 --- a/src/blockchain_db/testdb.h +++ b/src/blockchain_db/testdb.h @@ -70,7 +70,7 @@ public: virtual bool get_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; } virtual bool get_pruned_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; } virtual bool get_pruned_tx_blobs_from(const crypto::hash& h, size_t count, std::vector &bd) const override { return false; } - virtual bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector, std::vector>>>& blocks, bool pruned, bool get_miner_tx_hash) const override { return false; } + virtual bool get_blocks_from(uint64_t start_height, size_t min_block_count, size_t max_block_count, size_t max_tx_count, size_t max_size, std::vector, std::vector>>>& blocks, bool pruned, bool get_miner_tx_hash) const override { return false; } virtual std::vector get_txids_loose(const crypto::hash& h, std::uint32_t bits, relay_category category, uint64_t max_num_txs = 0) override { return {}; } virtual bool get_prunable_tx_blob(const crypto::hash& h, cryptonote::blobdata &tx) const override { return false; } virtual bool get_prunable_tx_hash(const crypto::hash& tx_hash, crypto::hash &prunable_hash) const override { return false; } diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index b8babf5a1..f2e8e230a 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -2782,7 +2782,7 @@ bool Blockchain::find_blockchain_supplement(const std::list& qbloc // find split point between ours and foreign blockchain (or start at // blockchain height ), and return up to max_count FULL // blocks by reference. -bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, const std::list& qblock_ids, std::vector, std::vector > > >& blocks, uint64_t& total_height, crypto::hash& top_hash, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, const bool qblock_ids_exclusive, size_t max_block_count, size_t max_tx_count) const +bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, const std::list& qblock_ids, std::vector, std::vector > > >& blocks, uint64_t& total_height, crypto::hash& top_hash, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, const bool qblock_ids_exclusive, size_t max_block_count, size_t max_tx_count) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index b887d7862..5062f9987 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -520,7 +520,7 @@ namespace cryptonote * * @return true if a block found in common or req_start_block specified, else false */ - bool find_blockchain_supplement(const uint64_t req_start_block, const std::list& qblock_ids, std::vector, std::vector > > >& blocks, uint64_t& total_height, crypto::hash& top_hash, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, const bool qblock_ids_exclusive, size_t max_block_count, size_t max_tx_count) const; + bool find_blockchain_supplement(const uint64_t req_start_block, const std::list& qblock_ids, std::vector, std::vector > > >& blocks, uint64_t& total_height, crypto::hash& top_hash, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, const bool qblock_ids_exclusive, size_t max_block_count, size_t max_tx_count) const; /** * @brief retrieves a set of blocks and their transactions, and possibly other transactions diff --git a/src/cryptonote_core/cryptonote_core.cpp b/src/cryptonote_core/cryptonote_core.cpp index 02d6f4525..df9a34eb4 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1245,7 +1245,7 @@ namespace cryptonote return m_blockchain_storage.find_blockchain_supplement(qblock_ids, clip_pruned, resp); } //----------------------------------------------------------------------------------------------- - bool core::find_blockchain_supplement(const uint64_t req_start_block, const std::list& qblock_ids, std::vector, std::vector > > >& blocks, uint64_t& total_height, crypto::hash& top_hash, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, const bool qblock_ids_exclusive, size_t max_block_count, size_t max_tx_count) const + bool core::find_blockchain_supplement(const uint64_t req_start_block, const std::list& qblock_ids, std::vector, std::vector > > >& blocks, uint64_t& total_height, crypto::hash& top_hash, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, const bool qblock_ids_exclusive, size_t max_block_count, size_t max_tx_count) const { return m_blockchain_storage.find_blockchain_supplement(req_start_block, qblock_ids, blocks, total_height, top_hash, start_height, pruned, get_miner_tx_hash, qblock_ids_exclusive, max_block_count, max_tx_count); } diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index bcd099955..117b8e30b 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -575,7 +575,7 @@ namespace cryptonote * * @note see Blockchain::find_blockchain_supplement(const uint64_t, const std::list&, std::vector > >&, uint64_t&, uint64_t&, size_t) const */ - bool find_blockchain_supplement(const uint64_t req_start_block, const std::list& qblock_ids, std::vector, std::vector > > >& blocks, uint64_t& total_height, crypto::hash& top_hash, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, const bool qblock_ids_exclusive, size_t max_block_count, size_t max_tx_count) const; + bool find_blockchain_supplement(const uint64_t req_start_block, const std::list& qblock_ids, std::vector, std::vector > > >& blocks, uint64_t& total_height, crypto::hash& top_hash, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, const bool qblock_ids_exclusive, size_t max_block_count, size_t max_tx_count) const; /** * @copydoc Blockchain::get_tx_outputs_gindexs diff --git a/src/rpc/core_rpc_server.cpp b/src/rpc/core_rpc_server.cpp index bd3e96e79..1348cca5b 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -595,7 +595,7 @@ namespace cryptonote ? std::min(req.max_block_count, (uint64_t)COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT) : COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT; - std::vector, std::vector > > > bs; + std::vector, std::vector > > > bs; if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.top_block_hash, res.start_height, req.prune, !req.no_miner_tx, req.block_ids_exclusive, max_blocks, COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT)) { res.status = "Failed"; @@ -618,11 +618,9 @@ namespace cryptonote if (req.no_miner_tx) res.output_indices.back().indices.push_back(COMMAND_RPC_GET_BLOCKS_FAST::tx_output_indices()); res.blocks.back().txs.reserve(bd.second.size()); - for (std::vector>::iterator i = bd.second.begin(); i != bd.second.end(); ++i) + for (auto i = bd.second.begin(); i != bd.second.end(); ++i) { - res.blocks.back().txs.push_back({std::move(i->second), crypto::null_hash}); - i->second.clear(); - i->second.shrink_to_fit(); + res.blocks.back().txs.emplace_back(std::move(std::get<2>(*i)), std::get<1>(*i)); cumul_block_data_size += res.blocks.back().txs.back().blob.size(); } @@ -630,7 +628,7 @@ namespace cryptonote if (n_txes_to_lookup > 0) { std::vector> indices; - bool r = m_core.get_tx_outputs_gindexs(req.no_miner_tx ? bd.second.front().first : bd.first.second, n_txes_to_lookup, indices); + bool r = m_core.get_tx_outputs_gindexs(req.no_miner_tx ? std::get<0>(bd.second.front()) : bd.first.second, n_txes_to_lookup, indices); if (!r) { res.status = "Failed"; diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index 087b4c48a..3a09f5b19 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -139,7 +139,7 @@ namespace rpc void DaemonHandler::handle(const GetBlocksFast::Request& req, GetBlocksFast::Response& res) { - std::vector, std::vector > > > blocks; + std::vector, std::vector > > > blocks; if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, blocks, res.current_height, res.top_block_hash, res.start_height, req.prune, true, false, COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT, COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT)) { @@ -198,8 +198,8 @@ namespace rpc bwt.transactions.back().pruned = req.prune; const bool parsed = req.prune ? - parse_and_validate_tx_base_from_blob(blob.second, bwt.transactions.back()) : - parse_and_validate_tx_from_blob(blob.second, bwt.transactions.back()); + parse_and_validate_tx_base_from_blob(std::get<2>(blob), bwt.transactions.back()) : + parse_and_validate_tx_from_blob(std::get<2>(blob), bwt.transactions.back()); if (!parsed) { res.blocks.clear();