diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 28c9a2bd1..8d34f0e85 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -2765,7 +2765,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, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, 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, size_t max_block_count, size_t max_tx_count) const { LOG_PRINT_L3("Blockchain::" << __func__); CRITICAL_REGION_LOCAL(m_blockchain_lock); @@ -2774,7 +2774,9 @@ bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, cons if(req_start_block > 0) { // if requested height is higher than our chain, return false -- we can't help - if (req_start_block >= m_db->height()) + top_hash = m_db->top_block_hash(&total_height); + ++total_height; + if (req_start_block >= total_height) { return false; } @@ -2789,7 +2791,8 @@ bool Blockchain::find_blockchain_supplement(const uint64_t req_start_block, cons } db_rtxn_guard rtxn_guard(m_db); - total_height = get_current_blockchain_height(); + top_hash = m_db->top_block_hash(&total_height); + ++total_height; blocks.reserve(std::min(std::min(max_block_count, (size_t)10000), (size_t)(total_height - start_height))); CHECK_AND_ASSERT_MES(m_db->get_blocks_from(start_height, 3, max_block_count, max_tx_count, FIND_BLOCKCHAIN_SUPPLEMENT_MAX_SIZE, blocks, pruned, true, get_miner_tx_hash), false, "Error getting blocks"); diff --git a/src/cryptonote_core/blockchain.h b/src/cryptonote_core/blockchain.h index 8d688da6f..503ea92dd 100644 --- a/src/cryptonote_core/blockchain.h +++ b/src/cryptonote_core/blockchain.h @@ -485,6 +485,7 @@ namespace cryptonote * @param qblock_ids the foreign chain's "short history" (see get_short_chain_history) * @param blocks return-by-reference the blocks and their transactions * @param total_height return-by-reference our current blockchain height + * @param top_hash return-by-reference top block hash * @param start_height return-by-reference the height of the first block returned * @param pruned whether to return full or pruned tx blobs * @param max_block_count the max number of blocks to get @@ -492,7 +493,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, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, 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, 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 e6c65694d..08c72573b 100644 --- a/src/cryptonote_core/cryptonote_core.cpp +++ b/src/cryptonote_core/cryptonote_core.cpp @@ -1488,9 +1488,9 @@ 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, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, 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, 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, start_height, pruned, get_miner_tx_hash, max_block_count, max_tx_count); + return m_blockchain_storage.find_blockchain_supplement(req_start_block, qblock_ids, blocks, total_height, top_hash, start_height, pruned, get_miner_tx_hash, max_block_count, max_tx_count); } //----------------------------------------------------------------------------------------------- bool core::get_outs(const COMMAND_RPC_GET_OUTPUTS_BIN::request& req, COMMAND_RPC_GET_OUTPUTS_BIN::response& res) const diff --git a/src/cryptonote_core/cryptonote_core.h b/src/cryptonote_core/cryptonote_core.h index 13ee11e1c..77a5d4beb 100644 --- a/src/cryptonote_core/cryptonote_core.h +++ b/src/cryptonote_core/cryptonote_core.h @@ -597,7 +597,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, uint64_t& start_height, bool pruned, bool get_miner_tx_hash, 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, 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 e6e65889e..7fcd1e6d7 100644 --- a/src/rpc/core_rpc_server.cpp +++ b/src/rpc/core_rpc_server.cpp @@ -719,6 +719,7 @@ namespace cryptonote { res.start_height = 0; res.current_height = last_block_height + 1; + res.top_block_hash = last_block_hash; res.status = CORE_RPC_STATUS_OK; return true; } @@ -738,7 +739,7 @@ namespace cryptonote } std::vector, std::vector > > > bs; - if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, bs, res.current_height, res.start_height, req.prune, !req.no_miner_tx, max_blocks, COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT)) + 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, max_blocks, COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT)) { res.status = "Failed"; add_host_fail(ctx); diff --git a/src/rpc/core_rpc_server_commands_defs.h b/src/rpc/core_rpc_server_commands_defs.h index 6b5d08e6a..1c8525d45 100644 --- a/src/rpc/core_rpc_server_commands_defs.h +++ b/src/rpc/core_rpc_server_commands_defs.h @@ -247,6 +247,7 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st std::vector blocks; uint64_t start_height; uint64_t current_height; + crypto::hash top_block_hash; std::vector output_indices; uint64_t daemon_time; uint8_t pool_info_extent; @@ -259,6 +260,7 @@ inline const std::string get_rpc_status(const bool trusted_daemon, const std::st KV_SERIALIZE(blocks) KV_SERIALIZE(start_height) KV_SERIALIZE(current_height) + KV_SERIALIZE_VAL_POD_AS_BLOB_OPT(top_block_hash, crypto::null_hash) KV_SERIALIZE(output_indices) KV_SERIALIZE_OPT(daemon_time, (uint64_t) 0) KV_SERIALIZE_OPT(pool_info_extent, (uint8_t) 0) diff --git a/src/rpc/daemon_handler.cpp b/src/rpc/daemon_handler.cpp index 9ed2cb660..fac061cad 100644 --- a/src/rpc/daemon_handler.cpp +++ b/src/rpc/daemon_handler.cpp @@ -128,7 +128,7 @@ namespace rpc { std::vector, std::vector > > > blocks; - if(!m_core.find_blockchain_supplement(req.start_height, req.block_ids, blocks, res.current_height, res.start_height, req.prune, true, COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT, COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT)) + 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, COMMAND_RPC_GET_BLOCKS_FAST_MAX_BLOCK_COUNT, COMMAND_RPC_GET_BLOCKS_FAST_MAX_TX_COUNT)) { res.status = Message::STATUS_FAILED; res.error_details = "core::find_blockchain_supplement() returned false"; diff --git a/src/rpc/daemon_messages.h b/src/rpc/daemon_messages.h index 383665cfc..83546fce3 100644 --- a/src/rpc/daemon_messages.h +++ b/src/rpc/daemon_messages.h @@ -97,6 +97,7 @@ BEGIN_RPC_MESSAGE_CLASS(GetBlocksFast); RPC_MESSAGE_MEMBER(std::vector, blocks); RPC_MESSAGE_MEMBER(uint64_t, start_height); RPC_MESSAGE_MEMBER(uint64_t, current_height); + RPC_MESSAGE_MEMBER(crypto::hash, top_block_hash); RPC_MESSAGE_MEMBER(std::vector, output_indices); END_RPC_MESSAGE_RESPONSE; END_RPC_MESSAGE_CLASS;