From c634c261c216851b27d5c06140974efcda5ed5e2 Mon Sep 17 00:00:00 2001 From: Oscar Mira Date: Thu, 4 Jul 2024 12:46:19 +0200 Subject: [PATCH 1/2] wallet2: use start_height consistently as const in process_parsed_blocks --- src/wallet/wallet2.cpp | 6 +++--- src/wallet/wallet2.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 9b09d0920..5e7e26657 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -3108,13 +3108,12 @@ void wallet2::pull_hashes(uint64_t start_height, uint64_t &blocks_start_height, hashes = std::move(res.m_block_ids); } //---------------------------------------------------------------------------------------------------- -void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added, std::map, size_t> *output_tracker_cache) +void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added, std::map, size_t> *output_tracker_cache) { - size_t current_index = start_height; blocks_added = 0; THROW_WALLET_EXCEPTION_IF(blocks.size() != parsed_blocks.size(), error::wallet_internal_error, "size mismatch"); - THROW_WALLET_EXCEPTION_IF(!m_blockchain.is_in_bounds(current_index), error::out_of_hashchain_bounds_error); + THROW_WALLET_EXCEPTION_IF(!m_blockchain.is_in_bounds(start_height), error::out_of_hashchain_bounds_error); tools::threadpool& tpool = tools::threadpool::getInstanceForCompute(); tools::threadpool::waiter waiter(tpool); @@ -3266,6 +3265,7 @@ void wallet2::process_parsed_blocks(uint64_t start_height, const std::vector &short_chain_history, std::vector &hashes); void fast_refresh(uint64_t stop_height, uint64_t &blocks_start_height, std::list &short_chain_history, bool force = false); void pull_and_parse_next_blocks(bool first, bool try_incremental, uint64_t start_height, uint64_t &blocks_start_height, std::list &short_chain_history, const std::vector &prev_blocks, const std::vector &prev_parsed_blocks, std::vector &blocks, std::vector &parsed_blocks, std::vector>& process_pool_txs, bool &last, bool &error, std::exception_ptr &exception); - void process_parsed_blocks(uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added, std::map, size_t> *output_tracker_cache = NULL); + void process_parsed_blocks(const uint64_t start_height, const std::vector &blocks, const std::vector &parsed_blocks, uint64_t& blocks_added, std::map, size_t> *output_tracker_cache = NULL); bool accept_pool_tx_for_processing(const crypto::hash &txid); void process_unconfirmed_transfer(bool incremental, const crypto::hash &txid, wallet2::unconfirmed_transfer_details &tx_details, bool seen_in_pool, std::chrono::system_clock::time_point now, bool refreshed); void process_pool_info_extent(const cryptonote::COMMAND_RPC_GET_BLOCKS_FAST::response &res, std::vector> &process_txs, bool refreshed); From a026d5ac44d936a4f89a144beb1af350eb149cb3 Mon Sep 17 00:00:00 2001 From: Oscar Mira Date: Mon, 27 May 2024 17:17:17 +0200 Subject: [PATCH 2/2] wallet2: validate fetched block height and parent hash --- src/wallet/wallet2.cpp | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp index 5e7e26657..36e18382a 100644 --- a/src/wallet/wallet2.cpp +++ b/src/wallet/wallet2.cpp @@ -2891,6 +2891,10 @@ void wallet2::process_new_blockchain_entry(const cryptonote::block& b, const cry "block transactions=" + std::to_string(bche.txs.size()) + " not match with daemon response size=" + std::to_string(parsed_block.o_indices.indices.size())); + THROW_WALLET_EXCEPTION_IF(height != m_blockchain.size(), error::wallet_internal_error, + "New blockchain entry mismatch: block height " + std::to_string(height) + + " is not the expected next height " + std::to_string(m_blockchain.size())); + //handle transactions from new block //optimization: seeking only for blocks that are not older then the wallet creation time plus 1 day. 1 day is for possible user incorrect time setup @@ -3124,8 +3128,22 @@ void wallet2::process_parsed_blocks(const uint64_t start_height, const std::vect num_txes += 1 + parsed_blocks[i].txes.size(); tx_cache_data.resize(num_txes); size_t txidx = 0; + crypto::hash prev_block_id; + bool has_prev_block = m_blockchain.is_in_bounds(start_height - 1); + if (has_prev_block) { + prev_block_id = m_blockchain[start_height - 1]; + } for (size_t i = 0; i < blocks.size(); ++i) { + if (has_prev_block) { + THROW_WALLET_EXCEPTION_IF(prev_block_id != parsed_blocks[i].block.prev_id, error::wallet_internal_error, + "Parent block hash mismatch at height " + std::to_string(start_height + i) + + ": expected " + string_tools::pod_to_hex(prev_block_id) + + ", but received a new block with prev_id " + string_tools::pod_to_hex(parsed_blocks[i].block.prev_id)); + } + prev_block_id = parsed_blocks[i].hash; + has_prev_block = true; + THROW_WALLET_EXCEPTION_IF(parsed_blocks[i].txes.size() != parsed_blocks[i].block.tx_hashes.size(), error::wallet_internal_error, "Mismatched parsed_blocks[i].txes.size() and parsed_blocks[i].block.tx_hashes.size()"); if (should_skip_block(parsed_blocks[i].block, start_height + i))