From 7702f060a7bc8537a4e7674de7f38df155b0df4d Mon Sep 17 00:00:00 2001 From: Dario Gabriel Lipicar Date: Fri, 21 Aug 2026 09:50:14 -0300 Subject: [PATCH] docs: stop() is not bounded by drainTimeoutMs, in the places callers read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit corrected the internal comments but left the overstatement in the two spots that actually reach a consumer: the `stop()` doc comment — which the generator copies verbatim into the LIDL contract and `lm methods` shows — and the README's API table. Both still said stop() "blocks up to drainTimeoutMs". It does not. The drain loop checks its deadline BETWEEN calls into the library, and a single processVerifProxyTasks was measured blocking up to 3.3s, so the real budget is drainTimeoutMs plus up to one pump duration. Bounded, which is what keeps the unconditional destructor join safe, but not the tight bound the name implies. Also documents that callers blocked in an RPC call are released with "proxy shutting down" rather than waiting out their own timeout, since that is the other thing someone reading stop() wants to know. Co-Authored-By: Claude Opus 5 --- README.md | 6 ++++-- src/verified_proxy_impl.h | 12 +++++++++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index c801da8..448c4a1 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,8 @@ impossible without it. (Infura notably does not.) |---|---| | `configure(config)` | Validate and store config. Synchronous; starts nothing. | | `getConfig()` | Effective config, credentials redacted. | -| `start()` / `stop()` | Blocking, bounded by `startTimeoutMs` / `drainTimeoutMs`. | +| `start()` | Blocks until the light client initialises, bounded by `startTimeoutMs`. | +| `stop()` | Drains, then releases. See the note on `drainTimeoutMs` below — it is not a tight bound. | | `ok()` / `status()` | Health probe and full state. `status()` never blocks on the proxy thread. | | `rpc(method, params)` | Any method the proxy supports. `params` is a JSON-RPC array. | | `ethBlockNumber()`, `ethGetBalance(...)`, `ethCall(...)`, … | Typed wrappers over the same path. | @@ -87,7 +88,8 @@ is enabled by setting `opExecutionApiUrls` (there is no `op-*` network name in the library's JSON config — that is a CLI-only option on the standalone binary). Module-side knobs: `callTimeoutMs` (30000), `startTimeoutMs` (120000), -`drainTimeoutMs` (2000), `pumpIntervalMs` (50), `maxInFlight` (64), +`drainTimeoutMs` (2000 — a polling bound, see below), `pumpIntervalMs` (50), +`maxInFlight` (64), `keepAlive` (`off` | `interval` | `continuous`), `keepAliveIntervalMs` (1000), `autoStart` (false). Upstream tuning lives under `tuning`. diff --git a/src/verified_proxy_impl.h b/src/verified_proxy_impl.h index a4e75b0..06142b1 100644 --- a/src/verified_proxy_impl.h +++ b/src/verified_proxy_impl.h @@ -74,7 +74,17 @@ public: StdLogosResult start(); /// Stop the proxy: drain in-flight calls, then release the context. - /// Blocks up to `drainTimeoutMs`. Also emits `proxyStopped`. + /// + /// `drainTimeoutMs` (default 2000) bounds when the drain stops STARTING new + /// turns of the library's task pump — not when this returns. The deadline is + /// checked between calls into the library, and one such call was measured + /// blocking for up to 3.3s, so budget `drainTimeoutMs` plus up to one pump + /// duration. Bounded, but not tight: a measured stop() took 1102ms. + /// + /// Callers still blocked in an RPC call are released with + /// "proxy shutting down" rather than waiting out their own timeout. + /// + /// Also emits `proxyStopped`. StdLogosResult stop(); /// True when the proxy is running and its last heartbeat succeeded.