diff --git a/src/ripple/app/rdb/backend/RWDBDatabase.h b/src/ripple/app/rdb/backend/RWDBDatabase.h index 8653e6cf0..2858497a8 100644 --- a/src/ripple/app/rdb/backend/RWDBDatabase.h +++ b/src/ripple/app/rdb/backend/RWDBDatabase.h @@ -51,15 +51,43 @@ private: auto const& txn = accountTx.first; auto const& meta = accountTx.second; - // Search metadata + // Search metadata, excluding RegularKey false positives Blob const metaBlob = meta->getAsObject().getSerializer().peekData(); - if (metaBlob.size() >= account.size() && - std::search( - metaBlob.begin(), - metaBlob.end(), - account.data(), - account.data() + account.size()) != metaBlob.end()) - return true; + if (metaBlob.size() >= account.size()) + { + auto it = metaBlob.begin(); + while (true) + { + // Find next occurrence of account + it = std::search( + it, + metaBlob.end(), + account.data(), + account.data() + account.size()); + + if (it == metaBlob.end()) + break; + + // Check if this is a RegularKey field (0x8814 prefix) + if (it >= metaBlob.begin() + 2) + { + auto prefix = *(it - 2); + auto prefix2 = *(it - 1); + if (prefix != 0x88 || prefix2 != 0x14) + { + // Found account not preceded by RegularKey prefix + return true; + } + } + else + { + // Too close to start to be RegularKey + return true; + } + + ++it; // Move past this occurrence + } + } // Search transaction blob Blob const txnBlob = txn->getSTransaction()->getSerializer().peekData(); diff --git a/src/ripple/app/rdb/backend/detail/impl/Node.cpp b/src/ripple/app/rdb/backend/detail/impl/Node.cpp index 63e80f498..69723c714 100644 --- a/src/ripple/app/rdb/backend/detail/impl/Node.cpp +++ b/src/ripple/app/rdb/backend/detail/impl/Node.cpp @@ -765,8 +765,18 @@ transactionsSQL( std::string sql; - std::string filterClause = options.strict ? "AND (hex(TxnMeta) LIKE '%" + - accountHex + "%' OR hex(RawTxn) LIKE '%" + accountHex + "%')" + // For metadata search: + // 1. Look for account ID not preceded by 8814 (RegularKey field) + // 2. OR look for account in raw transaction + std::string filterClause = options.strict ? "AND ((" + "hex(TxnMeta) LIKE '%" + + accountHex + + "%' AND " + "hex(TxnMeta) NOT LIKE '%8814" + + accountHex + + "%'" + ") OR hex(RawTxn) LIKE '%" + + accountHex + "%')" : ""; if (count)