Skip to content

fix(keeper): thread context into GetUpkeep and GetConfig RPC calls#21490

Open
Aboudjem wants to merge 1 commit intosmartcontractkit:developfrom
Aboudjem:fix/keeper-sync-nil-context
Open

fix(keeper): thread context into GetUpkeep and GetConfig RPC calls#21490
Aboudjem wants to merge 1 commit intosmartcontractkit:developfrom
Aboudjem:fix/keeper-sync-nil-context

Conversation

@Aboudjem
Copy link

Fixes #21489.

Noticed during a slow shutdown investigation that syncUpkeep and newRegistryFromChain both pass nil CallOpts to their on-chain calls even though they receive a context from the caller. The GetUpkeep and GetConfig RPCs end up ignoring cancellation, so they block until RPC timeout during shutdown instead of stopping when the context is done.

The fix just wires the existing ctx through bind.CallOpts on both call sites. No behavior change under normal operation - the context only matters on cancellation paths.

@Aboudjem Aboudjem requested a review from a team as a code owner March 11, 2026 03:28
Copilot AI review requested due to automatic review settings March 11, 2026 03:28
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Risk Rating: LOW (threads existing context.Context through to on-chain RPC calls; behavior change is limited to cancellation/shutdown paths).

Fixes slow shutdown/job stop behavior in the keeper registry synchronizer by ensuring GetUpkeep and GetConfig respect caller cancellation instead of waiting for RPC timeouts.

Changes:

  • Pass ctx via bind.CallOpts{Context: ctx} into GetUpkeep calls during upkeep sync.
  • Pass ctx via bind.CallOpts{Context: ctx} into GetConfig calls when building a registry from chain state.


func (rs *RegistrySynchronizer) syncUpkeep(ctx context.Context, getter upkeepGetter, registry Registry, upkeepID *sqlutil.Big) error {
upkeep, err := getter.GetUpkeep(nil, upkeepID.ToInt())
upkeep, err := getter.GetUpkeep(&bind.CallOpts{Context: ctx}, upkeepID.ToInt())
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

Add a regression unit test that asserts syncUpkeep threads the provided ctx into the *bind.CallOpts passed to GetUpkeep (e.g., a fake upkeepGetter that captures opts.Context). This prevents future regressions back to nil/background contexts which would reintroduce slow shutdown behavior.

Copilot generated this review using guidance from repository custom instructions.
contractAddress := rs.job.KeeperSpec.ContractAddress

registryConfig, err := rs.registryWrapper.GetConfig(nil)
registryConfig, err := rs.registryWrapper.GetConfig(&bind.CallOpts{Context: ctx})
Copy link

Copilot AI Mar 11, 2026

Choose a reason for hiding this comment

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

Consider adding test coverage that newRegistryFromChain passes the caller ctx into the bind.CallOpts used by GetConfig (and thus GetKeeperList). One approach is a small fake bind.ContractBackend that records the ctx it receives in CallContract, and wiring it into a generated registry wrapper in the test.

Copilot generated this review using guidance from repository custom instructions.
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.

keeper sync passes nil context to on-chain RPC calls

2 participants