diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp index 121183a6b..983f79157 100644 --- a/src/cryptonote_core/blockchain.cpp +++ b/src/cryptonote_core/blockchain.cpp @@ -155,6 +155,8 @@ bool Blockchain::scan_outputkeys_for_indexes(size_t tx_version, const txin_to_ke std::vector absolute_offsets = relative_output_offsets_to_absolute(tx_in_to_key.key_offsets); std::vector outputs; + // We check the m_scan_table cache, but note it may not have the entry. + // We have to read the db in that case. bool found = false; auto it = m_scan_table.find(tx_prefix_hash); if (it != m_scan_table.end()) @@ -5336,6 +5338,14 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector> tx_map; std::vector> txes(total_txs); + // We want to target max memory usage for offsets here to 100mb. We'll have output_data_t + // per offset in memory for m_scan_table and tx_map (hence the 2*sizeof(output_data_t)). + // If m_scan_table doesn't have an offset entry while handling an incoming block, that's + // ok. It should cache miss and just do the db read(s) when handling the block. + // Note: we might go over the target max offsets a little, but that's ok. + // TODO: return early once we're past the FCMP++ fork. + constexpr std::size_t TARGET_MAX_OFFSETS_FOR_SCAN_TABLE_CACHE = 100000000/*100MB*/ / (2*sizeof(output_data_t)); + #define SCAN_TABLE_QUIT(m) \ do { \ MERROR_VER(m) ;\ @@ -5345,10 +5355,13 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector= TARGET_MAX_OFFSETS_FOR_SCAN_TABLE_CACHE) + break; for (const auto &tx_blob : entry.txs) { @@ -5391,8 +5404,16 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector= TARGET_MAX_OFFSETS_FOR_SCAN_TABLE_CACHE) + { + MWARNING("Preparing large batch to sync, we exceeded our cache limit"); + break; } } ++block_index; @@ -5438,10 +5459,13 @@ bool Blockchain::prepare_handle_incoming_blocks(const std::vector