Skip to content

fix(verifier): add adaptive log fetching and return early on no progress - #1370

Open
nvsriram wants to merge 3 commits into
mainfrom
fix/CCIP-12543-add-adaptive-range-fetch
Open

fix(verifier): add adaptive log fetching and return early on no progress#1370
nvsriram wants to merge 3 commits into
mainfrom
fix/CCIP-12543-add-adaptive-range-fetch

Conversation

@nvsriram

Copy link
Copy Markdown
Collaborator

Description

Currently, when loadEvents returns an error we simply log it and move on, even though there may be no events. For cases where the block range to large, this function would result in a death loop i.e., we fail to fetch logs for 1,000 blocks, we error, return, finalized block never updates, and we’re basically stuck.

This PR adds:

  • fetchRangeAdaptive to adaptively half the range and retry on failure
  • Early return from processEventCycle if no progress is made

Testing

  • Added TestSRS_FetchRangeAdaptive_ShrinksAndCompletesRange to ensure adaptive range logic works as intended
  • Updated latest values in test to ensure chunks are non-bisectable and tests are intact

@nvsriram
nvsriram marked this pull request as ready for review August 20, 2026 17:35
@nvsriram
nvsriram requested a review from a team as a code owner August 20, 2026 17:35
endArg,
)
if err != nil {
if ctx.Err() != nil || querySize == 1 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am wondering if we should classify this error instead of triggering the adaptive behaviour on every error? WDYT?

@nvsriram nvsriram Aug 20, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only issue with classifying errors is that I don't believe there is a universal error type across all RPCs. Ideally, this should only run for the Exceeded max range limit for eth_getLogs: 1000 errors but that type of string parsing/detection seems finicky.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's spend some time looking into classifying this, as simply doing it on every error might overload the RPC which would ensure there's going to keep being errors.

I feel like I prefer doing this only on range errors, potentially missing some others, over broadly spamming the RPC when any error occurs.

Should we stop before the query size is 1? Right now we'd be doing 10 RPC calls to go from 1k to 1, which feels excessive. Maybe if we scoped the error to exactly Exceeded max range limit it could make sense to go deeper but not for generic errors.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added error parsing logic to cover common range limit error patterns. We only go down to query size 1 if it is a range limit. Otherwise we early return.

)

querySize = nextQuerySize
adaptive = true

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For chains that truly have a limit of logs this behaviour will trigger each time we call this with a range exceeding the limit. Maybe we could persist the querySize for the lifecycle of the sourceReader?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we combine this with the error classification above this could lead to shrinking window on transient error might not be ideal but depending on the frequency we hit the max log issue might be worth doing

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, I initially had it persist but changed it since the error classification part was missing.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With error classification added now, the querySize is persisted using maxBlockRange.

@github-actions

Copy link
Copy Markdown

Code coverage report:

Package main fix/CCIP-12543-add-adaptive-range-fetch Diff
github.com/smartcontractkit/chainlink-ccv/aggregator 50.86% 50.86% +0.00%
github.com/smartcontractkit/chainlink-ccv/bootstrap 70.72% 70.72% +0.00%
github.com/smartcontractkit/chainlink-ccv/cli 59.12% 59.12% +0.00%
github.com/smartcontractkit/chainlink-ccv/cmd 35.65% 35.65% +0.00%
github.com/smartcontractkit/chainlink-ccv/common 46.46% 46.51% +0.05%
github.com/smartcontractkit/chainlink-ccv/executor 42.80% 42.80% +0.00%
github.com/smartcontractkit/chainlink-ccv/indexer 35.59% 35.54% -0.05%
github.com/smartcontractkit/chainlink-ccv/integration 55.87% 55.87% +0.00%
github.com/smartcontractkit/chainlink-ccv/internal 0.00% 0.00% +0.00%
github.com/smartcontractkit/chainlink-ccv/migration 77.66% 77.66% +0.00%
github.com/smartcontractkit/chainlink-ccv/pkg 83.33% 83.33% +0.00%
github.com/smartcontractkit/chainlink-ccv/pricer 0.00% 0.00% +0.00%
github.com/smartcontractkit/chainlink-ccv/protocol 63.06% 63.06% +0.00%
github.com/smartcontractkit/chainlink-ccv/tools 43.61% 43.61% +0.00%
github.com/smartcontractkit/chainlink-ccv/verifier 33.80% 34.59% +0.79%
Total 49.30% 49.40% +0.10%

@nvsriram
nvsriram requested review from RensR and carte7000 August 21, 2026 18:25
"range too large",
"too many blocks",
"maximum block range",
"eth_getlogs is limited to",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do we have EVM specific logic here?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, this should ideally be in the EVM source reader impl

@makramkd makramkd left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the logic makes sense, its just in the wrong place at the moment.

"range too large",
"too many blocks",
"maximum block range",
"eth_getlogs is limited to",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree, this should ideally be in the EVM source reader impl

adaptive := false
var allEvents []protocol.MessageSentEvent

for from <= to {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this kind of batching/adaptive logic be in the EVM source reader instead?

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.

5 participants