From 9d09c561d3ee094d7286330fb6dbe438e98b3029 Mon Sep 17 00:00:00 2001 From: Lee *!* Clagett Date: Tue, 15 Oct 2024 21:45:52 -0400 Subject: [PATCH] Fix LMDB double-reader bug with subaddresses+mempool (#140) --- src/scanner.cpp | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/scanner.cpp b/src/scanner.cpp index ae1100c..066c4e4 100644 --- a/src/scanner.cpp +++ b/src/scanner.cpp @@ -205,7 +205,7 @@ namespace lws }; struct add_output { - bool operator()(lws::account& user, const db::output& out) const + bool operator()(expect&, lws::account& user, const db::output& out) const { return user.add_out(out); } }; @@ -221,7 +221,7 @@ namespace lws net::ssl_verification_t verify_mode_; std::unordered_map txpool_; - bool operator()(lws::account& user, const db::output& out) + bool operator()(expect& reader, lws::account& user, const db::output& out) { /* Upstream monerod does not send all fields for a transaction, so mempool notifications cannot compute tx_hash correctly (it is not @@ -230,14 +230,23 @@ namespace lws then use corresponding tx_hash. */ const db::webhook_key key{user.id(), db::webhook_type::tx_confirmation}; std::vector hooks{}; + { - auto reader = disk_.start_read(); - if (!reader) + db::storage_reader* active_reader = reader ? + std::addressof(*reader) : nullptr; + + expect temp_reader{common_error::kInvalidArgument}; + if (!active_reader) { - MERROR("Unable to lookup webhook on tx in pool: " << reader.error().message()); - return false; + temp_reader = disk_.start_read(); + if (!temp_reader) + { + MERROR("Unable to lookup webhook on tx in pool: " << reader.error().message()); + return false; + } + active_reader = std::addressof(*temp_reader); } - auto found = reader->find_webhook(key, out.payment_id.short_); + auto found = active_reader->find_webhook(key, out.payment_id.short_); if (!found) { MERROR("Failed db lookup for webhooks: " << found.error().message()); @@ -311,7 +320,7 @@ namespace lws std::vector const& out_ids, subaddress_reader& reader, std::function spend_action, - std::function output_action) + std::function&, lws::account&, const db::output&)> output_action) { if (2 < tx.version) throw std::runtime_error{"Unsupported tx version"}; @@ -515,6 +524,7 @@ namespace lws } } const bool added = output_action( + reader.reader, user, db::output{ db::transaction_link{height, tx_hash},