v2.6.3
The first run stops stalling. If you tried nuthatch on Ethereum mainnet and concluded it was broken,
it was, and this is the release that fixes it.
Drop-in. Swap the binary and restart; no config changes, no data migration.
A first run on mainnet no longer stalls
Point nuthatch init at a contract, run nuthatch dev, and on 2.6.2 you would get 15 events in 90
seconds - or, behind a provider that refuses without explaining itself, no progress at all, forever.
The window controller grows fourfold on an empty range. An empty range says nothing about capacity,
so from a 1,000-block start it reached 100,000 blocks in four steps having never been served
anything near that. Every mainnet provider refuses a range that wide - Alchemy caps eth_getLogs at
10,000 - and discovering the real cap from there costs a binary search down: refused at 100k, 50k,
25k, 12,500 before anything succeeds. Fifteen round trips that returned nothing, each carrying a
backoff.
What hid it is that the recovery was invisible to the controller. The splitter halves a refused range
until the pieces succeed and returns the merged result, so the caller saw success and grew fourfold
again - on the strength of a success that never happened at that width.
Growth is now bounded by what a provider has actually served whole. One step past proven capacity is
exploration; four steps past it is guessing.
| crossing a 200,000-block prefix behind a 10,000-block cap | 2.6.2 | 2.6.3 |
|---|---|---|
| requests refused | 24 | 4 |
| widest range attempted | 100,000 | 16,000 |
| terminates | no | 0.04s |
This took five attempts, and two existing tests killed three of them - one defending cheap traversal
of the empty blocks in front of a late-deployed contract, one defending against an exponential
fan-out that turned 3 requests into 2,047 against a dead endpoint. Both requirements are real and both
still hold.
The front door, finished
- A bare
nuthatchprints the same grouped listing--helpdoes. It was gated on argument
count, so the grouping added in 2.6.2 was missing from the shortest way to ask for it. Still exits
2 on stderr: a missing subcommand is a usage error, and prettier output must not make a script that
runsnuthatchby mistake see success. initprints prose, all the way through. Warnings from the RPC layer used to arrive mid-block
with a timestamp, a level and ANSI colouring. They arrive as· messagenow, in the same idiom
as the ticks around them. Reformatted rather than suppressed: they are the only signal that a probe
is struggling whileinitappears to hang.
For operators and contributors
live-endpointsretries each endpoint three times before calling it dead. Two shipped defaults
once failed a scheduled run and answered fine two days later, and the job sat red throughout. A red
nobody trusts is a red nobody reads.- The review-signature gate is real. It checked that a signature was non-blank, which the literal
stringpendingsatisfies; it could not detect a self-signature; and it was required on no
branch, so even a red changed nothing. All three are fixed: a committed roster of who may sign, and
the context is now enforced. - The config drift gate reads
queries.toml's structs. A key added toCeilingorNamedQuery
used to ship undocumented, invisible to the agent skill that is supposed to describe it. - The stranded-work check no longer fails open. It reported "Nothing. Every PR is reachable from
main" when its query failed - a clean bill of health from a check that never ran.