CCIP-9778 - Add EVM contract verification changeset hooks to the framework#899
CCIP-9778 - Add EVM contract verification changeset hooks to the framework#899
Conversation
…nts-framework into pre-post-hook-verification
|
|
👋 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! |
There was a problem hiding this comment.
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.DataStoreafter a successful Apply. - Introduces a pre-hook that checks
IsVerifiedfor EVM contracts in the environment datastore before Apply and aborts if any are unverified. - Adds unit tests covering hook definitions and
iterateEVMVerifiersbehavior 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.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
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.
| ds, err := dom.EnvDir(params.Env.Name).DataStore() | ||
| if err != nil { | ||
| return fmt.Errorf("require verified pre-hook: load datastore: %w", err) | ||
| } |
There was a problem hiding this comment.
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.
| 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") | ||
| } |
There was a problem hiding this comment.
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.
…kit/chainlink-deployments-framework into pre-post-hook-verification
There was a problem hiding this comment.
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.
|
| continue | ||
| } | ||
|
|
||
| if err := step(ctx, v, ref, ch); err != nil { |
There was a problem hiding this comment.
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) | ||
| } | ||
|
|
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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 | ||
| } | ||
|
|
There was a problem hiding this comment.
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.
|
Closing PR and moving hooks to chainlink-ccip smartcontractkit/chainlink-ccip#1925 |




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