Skip to content

CCIP-9778 - Add EVM contract verification changeset hooks to the framework#899

Closed
AnieeG wants to merge 8 commits intomainfrom
pre-post-hook-verification
Closed

CCIP-9778 - Add EVM contract verification changeset hooks to the framework#899
AnieeG wants to merge 8 commits intomainfrom
pre-post-hook-verification

Conversation

@AnieeG
Copy link
Copy Markdown
Contributor

@AnieeG AnieeG commented Mar 30, 2026

  • NewVerifyDeployedEVMContractsPostHook — After a successful Apply, walks EVM address refs in the changeset output datastore and verifies them on the configured explorer (same ContractInputsProvider / metadata path as verify-env). Skips when Apply failed or when there is no output datastore. Uses Abort on failure.
  • NewRequireVerifiedEVMContractsPreHook — Before Apply, loads the environment datastore and checks that every EVM contract is already verified (IsVerified only). Uses Abort if anything is unverified or checks fail.

Related ticket - https://smartcontract-it.atlassian.net/browse/CCIP-9778

@AnieeG AnieeG requested a review from a team as a code owner March 30, 2026 20:01
Copilot AI review requested due to automatic review settings March 30, 2026 20:01
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Mar 30, 2026

⚠️ No Changeset found

Latest commit: 4e71794

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@github-actions
Copy link
Copy Markdown

👋 AnieeG, thanks for creating this pull request!

To help reviewers, please consider creating future PRs as drafts first. This allows you to self-review and make any final changes before notifying the team.

Once you're ready, you can mark it as "Ready for review" to request feedback. Thanks!

@AnieeG AnieeG changed the title Add EVM contract verification changeset hooks to the framework CCIP-9778 - Add EVM contract verification changeset hooks to the framework Mar 30, 2026
Copy link
Copy Markdown
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

Adds changeset lifecycle hooks to automatically verify EVM contracts post-apply and to enforce that environment EVM contracts are already verified pre-apply, reusing the existing EVM verification infrastructure (network config + ContractInputsProvider + explorer verifiers).

Changes:

  • Introduces a post-hook that verifies EVM contracts emitted into ChangesetOutput.DataStore after a successful Apply.
  • Introduces a pre-hook that checks IsVerified for EVM contracts in the environment datastore before Apply and aborts if any are unverified.
  • Adds unit tests covering hook definitions and iterateEVMVerifiers behavior across key skip/error cases.

Reviewed changes

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

File Description
engine/cld/verification/hooks/evm/hooks.go Adds pre/post changeset hooks and shared datastore iteration for EVM explorer verification.
engine/cld/verification/hooks/evm/hooks_test.go Adds tests for hook definitions and verifier iteration control flow (skip/error/success paths).

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

Comment thread engine/cld/verification/hooks/evm/hooks.go Outdated
Comment thread engine/cld/verification/hooks/evm/hooks.go Outdated
Comment thread engine/cld/verification/hooks/evm/hooks.go Outdated
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 30, 2026 20:10
Copy link
Copy Markdown
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

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.


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

Comment on lines +92 to +95
ds, err := dom.EnvDir(params.Env.Name).DataStore()
if err != nil {
return fmt.Errorf("require verified pre-hook: load datastore: %w", err)
}
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

requireVerifiedEnvContracts loads the environment datastore via dom.EnvDir(...).DataStore(), which only reads the local JSON files. In catalog mode (domain config datastore: catalog / all), local files may not exist or may be stale, causing this pre-hook to fail/block pipelines even though the canonical datastore is in the catalog.

Consider loading the datastore using the same logic as the contract verify-env command (i.e., respect the domain’s datastore type and load from catalog when configured), or factoring out a shared datastore loader helper so both flows stay consistent.

Copilot uses AI. Check for mistakes.
Comment on lines +88 to +117
func TestRequireVerified_PreHook_DataStoreError(t *testing.T) {
t.Parallel()

dom := domain.NewDomain(t.TempDir(), "test")
h := NewRequireVerifiedEVMContractsPreHook(dom, &mockProvider{})
err := h.Func(t.Context(), changeset.PreHookParams{
Env: changeset.HookEnv{Name: "staging", Logger: logger.Test(t)},
})
require.Error(t, err)
require.ErrorContains(t, err, "require verified pre-hook: load datastore")
}

func TestRequireVerified_PreHook_LoadNetworksError(t *testing.T) {
t.Parallel()

dom := domain.NewDomain(t.TempDir(), "test")
h := NewRequireVerifiedEVMContractsPreHook(dom, &mockProvider{})
// Minimal env layout so DataStore() succeeds: empty files skip JSON decode in loadDataStore.
envDir := dom.EnvDir("staging")
require.NoError(t, mkdirAllAndWrite(t, envDir.AddressRefsFilePath(), ""))
require.NoError(t, mkdirAllAndWrite(t, envDir.ChainMetadataFilePath(), ""))
require.NoError(t, mkdirAllAndWrite(t, envDir.ContractMetadataFilePath(), ""))
require.NoError(t, mkdirAllAndWrite(t, envDir.EnvMetadataFilePath(), ""))

err := h.Func(t.Context(), changeset.PreHookParams{
Env: changeset.HookEnv{Name: "staging", Logger: logger.Test(t)},
})
require.Error(t, err)
require.ErrorContains(t, err, "require verified pre-hook: load networks")
}
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

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

The new hooks’ core behaviors aren’t exercised in tests yet: there’s no test proving the pre-hook errors when IsVerified returns false (and succeeds when true), nor that the post-hook invokes Verify for resolvable EVM address refs.

Consider adding unit tests that stand up an httptest server for a supported strategy (e.g., Sourcify / Blockscout), point network.BlockExplorer.URL at it, and assert hook success/failure based on the mocked explorer responses.

Copilot uses AI. Check for mistakes.
AnieeG added 3 commits March 30, 2026 13:18
…kit/chainlink-deployments-framework into pre-post-hook-verification
Copilot AI review requested due to automatic review settings March 30, 2026 20:49
Copy link
Copy Markdown
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

Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.


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

Comment thread engine/cld/hooks/verification/evm/hooks.go
Comment thread engine/cld/hooks/verification/evm/hooks.go
Comment thread engine/cld/hooks/verification/evm/hooks.go
Comment thread engine/cld/hooks/verification/evm/hooks_test.go
Comment thread engine/cld/hooks/verification/evm/hooks.go
@cl-sonarqube-production
Copy link
Copy Markdown

continue
}

if err := step(ctx, v, ref, ch); err != nil {
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.

Are we verifying contracts sequentially? If so wouldn't that make the hook slow if we have to always run the verifier for all evm contracts that exist for the domain env?

if err != nil {
return fmt.Errorf("require verified pre-hook: load datastore: %w", err)
}

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.

Bot is right here we should use catalog supportive flow This loads from local files only. In environments where the catalog is the source of truth (datastore_type: all / catalog), the pre-hook won't see catalog data — it will read stale or empty local files. verify-env CLI handles this via DataStoreLoaderFunc (see deps.go); the hook should do the same or accept a loader.

continue
}

strategy := evm.GetVerificationStrategy(ch.EvmChainID)
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.

GetVerificationStrategy(chainID) was removed — this won't compile against the current evm package. Needs to be GetVerificationStrategyForNetwork(network) - hardcoded chains ids in CLDF was making it hard to add any new chains, now we just take network configuration from CLD

lggr.Debugf("%s: skipping %s (%s): %v", logPrefix, ref.Address, ref.Type, err)
continue
}

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.

VerifierConfig.HTTPClient is not set — all explorer calls go through http.DefaultClient. This makes it hard to test and impossible to inject custom transports (timeouts, retries, auth proxies) might be helpful to add it there.

@AnieeG
Copy link
Copy Markdown
Contributor Author

AnieeG commented Apr 1, 2026

Closing PR and moving hooks to chainlink-ccip smartcontractkit/chainlink-ccip#1925

@AnieeG AnieeG closed this Apr 1, 2026
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.

4 participants