The current implementation in POST /lninvoice checks for hash uniqueness with a plain map lookup:
- Check if
payment_hash exists in inbound_payments.
- Create invoice.
- Persist
PaymentInfo.
Steps 1–3 are not atomic, resulting in a TOCTOU (Time Of Check To Time Of Use) race condition. Two concurrent requests with the same payment_hash can both pass step 1 before either reaches step 3.
Proposed fix
Extend UnlockedAppState with an in-memory such as:
inflight_hodl_hashes: Arc<Mutex<HashSet<PaymentHash>>>
Before the uniqueness check, insert the hash into the set using a RAII guard that removes it on Drop. Concurrent requests with the same hash fail at guard insertion before any LDK or persistence calls are made.
The current implementation in
POST /lninvoicechecks for hash uniqueness with a plain map lookup:payment_hashexists ininbound_payments.PaymentInfo.Steps 1–3 are not atomic, resulting in a TOCTOU (Time Of Check To Time Of Use) race condition. Two concurrent requests with the same
payment_hashcan both pass step 1 before either reaches step 3.Proposed fix
Extend
UnlockedAppStatewith an in-memory such as:inflight_hodl_hashes: Arc<Mutex<HashSet<PaymentHash>>>Before the uniqueness check, insert the hash into the set using a RAII guard that removes it on
Drop. Concurrent requests with the same hash fail at guard insertion before any LDK or persistence calls are made.