Skip to content

fix: run health check and try multiple RPCs in fork tests#708

Open
gustavogama-cll wants to merge 1 commit intomainfrom
ggama/fix/fork-tests
Open

fix: run health check and try multiple RPCs in fork tests#708
gustavogama-cll wants to merge 1 commit intomainfrom
ggama/fix/fork-tests

Conversation

@gustavogama-cll
Copy link
Contributor

@gustavogama-cll gustavogama-cll commented Feb 5, 2026

Modify the anvil provider and the fork test setup so that (1) we do a health check on public rpcs before selecting them; (2) we try different rpcs if the anvil container fails to start (using a simple round-robin algorithm).

@changeset-bot
Copy link

changeset-bot bot commented Feb 5, 2026

🦋 Changeset detected

Latest commit: d7130f1

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
chainlink-deployments-framework Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@cl-sonarqube-production
Copy link

Quality Gate failed Quality Gate failed

Failed conditions
62.5% Coverage on New Code (required ≥ 80%)

See analysis details on SonarQube

@gustavogama-cll gustavogama-cll marked this pull request as ready for review February 5, 2026 04:15
@gustavogama-cll gustavogama-cll requested a review from a team as a code owner February 5, 2026 04:15
Copilot AI review requested due to automatic review settings February 5, 2026 04:15
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

This PR enhances the fork test infrastructure to improve reliability when working with public RPCs. It implements health checking of RPCs before selection and enables retry logic with multiple RPC URLs when Anvil container startup fails.

Changes:

  • Added health check functionality to validate RPC availability before use
  • Implemented round-robin RPC selection when container startup fails
  • Removed validation requirement for pre-configured archive HTTP URLs

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
go.mod Added httpmock dependency for testing HTTP interactions
engine/cld/environment/anvil_test.go Updated tests to verify health checks and multiple RPC handling with mock HTTP responses
engine/cld/environment/anvil.go Added health check function and modified selectPublicRPC to return multiple healthy URLs
engine/cld/config/network/metadata_test.go Removed test case for archive HTTP URL validation
engine/cld/config/network/metadata.go Removed validation requiring archive HTTP URL
chain/evm/provider/ctf_anvil_provider.go Added ForkURLs field and retry logic to cycle through URLs on container startup failure
.changeset/true-lizards-search.md Added changeset entry for the fix

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.


func Test_selectPublicRPC(t *testing.T) {
t.Parallel()
httpmock.Activate(t)
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The httpmock.Activate(t) call activates mocking globally for all tests, but lacks a corresponding Deactivate call. This will cause mock responses to leak into other parallel tests. Add t.Cleanup(httpmock.DeactivateAndReset) after activation to ensure proper cleanup.

Suggested change
httpmock.Activate(t)
httpmock.Activate(t)
t.Cleanup(httpmock.DeactivateAndReset)

Copilot uses AI. Check for mistakes.
client, err := ethclient.DialContext(ctx, rpcURL)
if err != nil {
return fmt.Errorf("failed to connect to rpc %v: %w", rpcURL, err)
}
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The ethclient connection is never closed, creating a resource leak. Add defer client.Close() after successful dial to ensure proper cleanup of the connection.

Suggested change
}
}
defer client.Close()

Copilot uses AI. Check for mistakes.
Comment on lines +570 to +573
if len(p.config.ForkURLs) > 0 {
url := p.config.ForkURLs[attempt%uint(len(p.config.ForkURLs))]
p.config.DockerCmdParamsOverrides = append(p.config.DockerCmdParamsOverrides, "--fork-url", url)
}
Copy link

Copilot AI Feb 5, 2026

Choose a reason for hiding this comment

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

The DockerCmdParamsOverrides slice is being mutated on every retry attempt, causing --fork-url parameters to accumulate. Each retry will append new fork-url arguments without clearing previous ones. Store the base overrides separately and create a fresh slice for each attempt, or clear the fork-url entries before appending.

Copilot uses AI. Check for mistakes.
// gas limits, or other Anvil-specific options.
DockerCmdParamsOverrides []string

ForkURLs []string
Copy link
Collaborator

Choose a reason for hiding this comment

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

should we add some godoc for this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeah, let me add it

lggr.Infow("selected rpc for fork environment", "url", rpc.HTTPURL, "chainSelector", chainSelector)

return nil
err := runHealthCheck(ctx, rpc.HTTPURL)
Copy link
Collaborator

Choose a reason for hiding this comment

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

i wonder if it is worth parallelizing here instead of doing sequential health check?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

the health checks I ran failed fast, so I didn't bother. We can reassess once we get a bit more real world usage.


if len(p.config.ForkURLs) > 0 {
url := p.config.ForkURLs[attempt%uint(len(p.config.ForkURLs))]
p.config.DockerCmdParamsOverrides = append(p.config.DockerCmdParamsOverrides, "--fork-url", url)
Copy link
Collaborator

Choose a reason for hiding this comment

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

so everytime this runs, we will append another --fork-url into p.config.DockerCmdParamsOverrides, so then DockerCmdParamsOverrides will have more than one --fork-url ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ooops; good catch. The earlier tests didn't have the health check, so this code path wasn't re-tested

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.

2 participants