Lower bound fixes + gold lower bounds#248
Merged
Merged
Conversation
tonatoz
approved these changes
Jul 9, 2026
a10zn8
added a commit
that referenced
this pull request
Jul 10, 2026
main's lower-bound rework (#248) changed LowerBoundDetector to take the caller's context; thread it through fetchLedgerInfo instead of deriving from context.Background() Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Gold lower bounds + lower-bound detection fixes
Summary
This PR fixes several correctness bugs in EVM lower-bound detection and adds a fast
"gold lower bound" short-circuit that lets us skip the binary search entirely when a
chain ships a known-oldest data point. It also splits the monolithic EVM detector into
per-type files and hardens the retry behaviour of the shared search.
Gold lower bounds
chains.yamlnow carries an optionallower-boundssection per chain, parsed into newChainLowerBounds/GoldLowerBoundtypes (pkg/chains/chains.go) and threaded throughConfiguredChain. A gold bound is a known-oldest{block, hash}pair for a chain. Thisdata already ships in the bundled
chains.yamlsubmodule — it was simply never parsed, sothe change is purely additive (
bitcoinand other chains without the section staynil).When a chain has a gold hash for
txorreceipts, the detector issues a singleeth_getTransactionByHash/eth_getTransactionReceiptprobe for that ancient hash:resolves to
1with no binary search.search path.
This is implemented in the new
gold_bound.goand short-circuits at the top ofDetectLowerBound. EVM detectors now receive the full*chains.ConfiguredChain(insteadof just
chains.Chain) so they can read the configured bounds;LowerBoundResultswasexported so the short-circuit reuses the same per-supported-type fan-out as the search.
Lower-bound search fixes
The shared
LowerBoundSearchCalculator(lower_bound_search.go) was rewritten to fixreal detection bugs:
retained genesis but had a hole above it, it reported a bogus bound of 1. The search now
converges on the real lower boundary of the contiguous retained range regardless of
whether genesis happens to be present.
transactions, which made a naive "first tx of the middle block" probe give up too early.
A new offset variant (
detectWithOffset/shiftLeftAndSearch) scans downward up tomaxOffset(20) blocks from a no-data midpoint to tolerate sporadic empty/missing blocks;a hole wider than the offset is abandoned and the search moves higher. Tx and receipts
detectors use this variant; block/state/proof use the plain binary search.
range of upstream error messages. These are now classified (
no_data_errors.go) andtreated as "no data at this height, search higher" rather than aborting the whole
detection. Only genuinely unexpected failures propagate.
confirmed, detection now fails cleanly so the processor keeps the previously cached
bound instead of publishing a bogus
1. Tiny chains still resolve to1.before any re-search, keeping steady-state cost to one call per cycle.
(up to 30 attempts, 1s → 1m) instead of the previous fixed 3× / 100ms, so transient
upstream errors no longer poison a detection cycle.
SetSearchRetryPolicylets testsrun with negligible backoff.
Refactor: split
evm_boundsby bound typeevm_lower_bound.gowas ~470 lines mixing construction, five per-type probes, JSONhelpers, and the error-hint list. It is now split into focused files so each bound type
reads as a self-contained unit, with the shared wiring left behind:
block_bound.go,state_bound.go,tx_bound.go,receipts_bound.go,proof_bound.go— one constructor + probe per data type.
evm_util.go— block/tx envelope parsing and hex/JSON helpers.no_data_errors.go— the no-data error classification and hint list.gold_bound.go— the gold short-circuit.evm_lower_bound.go— construction, probe dispatch,fetchLatestHeight, and theJSON-RPC
callhelper.