Skip to content

fix: add EOSE timeout fallback and increase handle_missed_events default#48

Closed
dadofsambonzuki wants to merge 1 commit into
lnbits:mainfrom
dadofsambonzuki:main
Closed

fix: add EOSE timeout fallback and increase handle_missed_events default#48
dadofsambonzuki wants to merge 1 commit into
lnbits:mainfrom
dadofsambonzuki:main

Conversation

@dadofsambonzuki

Copy link
Copy Markdown

Problem

The NWC Service Provider blocks ALL request processing until it receives EOSE (End of Stored Events) for both its subscriptions (kind 23194 and 23195). If EOSE is never received — which can happen if:

  • The relay does not send EOSE
  • EOSE is lost due to race conditions in the nostrclient router shared state
  • The connection drops before EOSE arrives

...the provider silently queues incoming request events but never processes them. Client wallets see "all promises rejected" because their NWC calls time out with no response.

Additionally, handle_missed_events defaults to 0, meaning on reconnect the provider only subscribes to events created after reconnection. Any requests sent during the disconnect window are permanently lost.

Changes

1. nwcp.py — EOSE timeout fallback

  • Added _eose_timeout method: a 10-second guard that fires if both EOSEs have not arrived
  • On timeout: forces both EOSE flags to True, processes all queued stale events, and allows future events to be processed in real-time
  • If EOSE arrives normally before the timeout, its cancelled
  • Added _process_stale_events helper for reuse

2. nwcp.py — Cleanup

  • Added eose_timeout_task cancellation in cleanup() and _subscribe()

3. migrations.py

  • Changed default handle_missed_events from 0 to 120
  • On reconnect, the provider looks back 2 minutes for missed request events

4. README.md

  • Updated config table to reflect new default

Testing

Verified that:

  • The provider starts processing requests within 10s even without EOSE
  • Normal EOSE flow works as before (timeout is cancelled, no behavioral change)
  • Reconnection resets the timeout correctly
  • Python syntax and imports are valid

- Add 10s EOSE timeout guard to prevent the provider from hanging
  indefinitely if EOSE is never received or lost in transit
- Process all queued events after timeout and mark subscriptions ready
  for real-time processing
- Increase handle_missed_events default from 0 to 120s to recover
  missed requests on reconnect
@dadofsambonzuki

Copy link
Copy Markdown
Author

Running on my local instance with multiple wallets showing no connection issues now.

@dadofsambonzuki dadofsambonzuki marked this pull request as draft June 25, 2026 13:18
@dadofsambonzuki

Copy link
Copy Markdown
Author

Closing this PR — the root cause was a thread-safety race condition in the nostrclient extension router, fixed upstream in lnbits/nostrclient#71

The NWC provider was fine; the events/EOSE it needed were being silently dropped by the nostrclient relay due to unsynchronized access to shared ClassVar state between a daemon thread and asyncio tasks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant