From 28e7821261bea880830e4f9472b822ef545bc40b Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Fri, 17 Apr 2026 05:26:58 -0700 Subject: [PATCH 01/17] offchain tooling api --- build/devenv/environment.go | 75 +- build/devenv/go.mod | 8 +- build/devenv/implcommon.go | 30 +- build/devenv/jobs/jd.go | 16 +- build/devenv/offchainloader/loader.go | 26 +- build/devenv/topology_compat.go | 29 + deployment/adapters/aggregator_config.go | 89 ++ deployment/adapters/executor_config.go | 79 ++ deployment/adapters/indexer_config.go | 98 ++ deployment/adapters/token_verifier_config.go | 79 ++ deployment/adapters/verifier_config.go | 79 ++ deployment/aggregator.go | 20 + .../changesets/apply_executor_config.go | 419 ++++++ .../changesets/apply_verifier_config.go | 627 +++++++++ .../changesets/generate_aggregator_config.go | 258 ++++ .../changesets/generate_indexer_config.go | 164 +++ .../generate_token_verifier_config.go | 250 ++++ deployment/changesets/sync_job_proposals.go | 60 + deployment/env_metadata_util.go | 408 ++++++ deployment/go.mod | 219 ++++ deployment/go.sum | 1160 +++++++++++++++++ deployment/indexer.go | 10 + .../fetch_node_chain_support.go | 114 ++ .../fetch_signing_keys/fetch_signing_keys.go | 118 ++ .../operations/propose_jobs/propose_jobs.go | 128 ++ .../operations/revoke_jobs/revoke_jobs.go | 112 ++ .../sync_job_proposals/sync_job_proposals.go | 278 ++++ deployment/sequences/manage_job_proposals.go | 381 ++++++ deployment/shared/chain_type_registry.go | 54 + deployment/shared/chain_validation.go | 83 ++ deployment/shared/jd_client.go | 21 + deployment/shared/nodes.go | 66 + deployment/shared/types.go | 215 +++ deployment/token_verifier.go | 55 + deployment/topology.go | 381 ++++++ evm/aggregator_config.go | 29 + evm/executor_config.go | 26 + evm/go.mod | 220 ++++ evm/go.sum | 1156 ++++++++++++++++ evm/indexer_config.go | 21 + evm/register.go | 36 + evm/token_verifier_config.go | 24 + evm/verifier_config.go | 31 + 43 files changed, 7679 insertions(+), 73 deletions(-) create mode 100644 build/devenv/topology_compat.go create mode 100644 deployment/adapters/aggregator_config.go create mode 100644 deployment/adapters/executor_config.go create mode 100644 deployment/adapters/indexer_config.go create mode 100644 deployment/adapters/token_verifier_config.go create mode 100644 deployment/adapters/verifier_config.go create mode 100644 deployment/aggregator.go create mode 100644 deployment/changesets/apply_executor_config.go create mode 100644 deployment/changesets/apply_verifier_config.go create mode 100644 deployment/changesets/generate_aggregator_config.go create mode 100644 deployment/changesets/generate_indexer_config.go create mode 100644 deployment/changesets/generate_token_verifier_config.go create mode 100644 deployment/changesets/sync_job_proposals.go create mode 100644 deployment/env_metadata_util.go create mode 100644 deployment/go.mod create mode 100644 deployment/go.sum create mode 100644 deployment/indexer.go create mode 100644 deployment/operations/fetch_node_chain_support/fetch_node_chain_support.go create mode 100644 deployment/operations/fetch_signing_keys/fetch_signing_keys.go create mode 100644 deployment/operations/propose_jobs/propose_jobs.go create mode 100644 deployment/operations/revoke_jobs/revoke_jobs.go create mode 100644 deployment/operations/sync_job_proposals/sync_job_proposals.go create mode 100644 deployment/sequences/manage_job_proposals.go create mode 100644 deployment/shared/chain_type_registry.go create mode 100644 deployment/shared/chain_validation.go create mode 100644 deployment/shared/jd_client.go create mode 100644 deployment/shared/nodes.go create mode 100644 deployment/shared/types.go create mode 100644 deployment/token_verifier.go create mode 100644 deployment/topology.go create mode 100644 evm/aggregator_config.go create mode 100644 evm/executor_config.go create mode 100644 evm/go.mod create mode 100644 evm/go.sum create mode 100644 evm/indexer_config.go create mode 100644 evm/register.go create mode 100644 evm/token_verifier_config.go create mode 100644 evm/verifier_config.go diff --git a/build/devenv/environment.go b/build/devenv/environment.go index 174fc8d88..957eb4764 100644 --- a/build/devenv/environment.go +++ b/build/devenv/environment.go @@ -23,10 +23,11 @@ import ( chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-ccv/bootstrap" - ccipAdapters "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/adapters" - ccipChangesets "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/changesets" - ccipOffchain "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain" - "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain/shared" + _ "github.com/smartcontractkit/chainlink-ccv/evm" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + ccvadapters "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" + ccvchangesets "github.com/smartcontractkit/chainlink-ccv/deployment/changesets" + ccvshared "github.com/smartcontractkit/chainlink-ccv/deployment/shared" "github.com/smartcontractkit/chainlink-ccv/build/devenv/cciptestinterfaces" devenvcommon "github.com/smartcontractkit/chainlink-ccv/build/devenv/common" "github.com/smartcontractkit/chainlink-ccv/build/devenv/jobs" @@ -120,7 +121,7 @@ type Cfg struct { // IndexerInternalEndpoints holds internal Docker network URLs for all indexers. IndexerInternalEndpoints []string `toml:"indexer_internal_endpoints"` // EnvironmentTopology is the shared environment configuration for NOPs, committees, and executor pools. - EnvironmentTopology *ccipOffchain.EnvironmentTopology `toml:"environment_topology" validate:"required"` + EnvironmentTopology *ccvdeployment.EnvironmentTopology `toml:"environment_topology" validate:"required"` // JDInfra holds the runtime JD infrastructure (not from config, populated at runtime). JDInfra *jobs.JDInfrastructure `toml:"-"` // ClientLookup provides ChainlinkClient lookup by NOP alias (populated at runtime). @@ -235,7 +236,7 @@ func (c *Cfg) expandAggregators() error { aggContainerName := fmt.Sprintf("%s-%s", cloneName, services.AggregatorContainerNameSuffix) cloneAddr := fmt.Sprintf("%s:%d", aggContainerName, services.DefaultAggregatorGRPCPort) - committee.Aggregators = append(committee.Aggregators, ccipOffchain.AggregatorConfig{ + committee.Aggregators = append(committee.Aggregators, ccvdeployment.AggregatorConfig{ Name: cloneName, Address: cloneAddr, InsecureAggregatorConnection: insecure, @@ -460,7 +461,7 @@ func NewProductConfigurationFromNetwork(typ string) (cciptestinterfaces.CCIP17Co // // Signer key selection is delegated to each registered ImplFactory via DefaultSignerKey, // so adding a new chain family requires no changes here. -func enrichEnvironmentTopology(cfg *ccipOffchain.EnvironmentTopology, verifiers []*committeeverifier.Input) { +func enrichEnvironmentTopology(cfg *ccvdeployment.EnvironmentTopology, verifiers []*committeeverifier.Input) { factories := GetAllImplFactories() seenAliases := make(map[string]struct{}) @@ -469,7 +470,7 @@ func enrichEnvironmentTopology(cfg *ccipOffchain.EnvironmentTopology, verifiers continue } nop, ok := cfg.NOPTopology.GetNOP(ver.NOPAlias) - if !ok || nop.GetMode() == shared.NOPModeCL { + if !ok || nop.GetMode() == ccvshared.NOPModeCL { continue } @@ -492,7 +493,7 @@ func enrichEnvironmentTopology(cfg *ccipOffchain.EnvironmentTopology, verifiers // and verifier changesets as the single source of truth. // For each chain_config entry that lacks a FeeAggregator, the corresponding // chain's deployer key is used as a fallback via the registered ImplFactory. -func buildEnvironmentTopology(in *Cfg, e *deployment.Environment) *ccipOffchain.EnvironmentTopology { +func buildEnvironmentTopology(in *Cfg, e *deployment.Environment) *ccvdeployment.EnvironmentTopology { if in.EnvironmentTopology == nil { return nil } @@ -543,7 +544,7 @@ func generateExecutorJobSpecs( in *Cfg, selectors []uint64, impls []cciptestinterfaces.CCIP17Configuration, - topology *ccipOffchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, ds datastore.MutableDataStore, ) (map[string]bootstrap.JobSpec, error) { executorJobSpecs := make(map[string]bootstrap.JobSpec) @@ -569,11 +570,11 @@ func generateExecutorJobSpecs( execNOPAliases = append(execNOPAliases, exec.NOPAlias) } - cs := ccipChangesets.ApplyExecutorConfig(ccipAdapters.GetExecutorConfigRegistry()) - output, err := cs.Apply(*e, ccipChangesets.ApplyExecutorConfigInput{ + cs := ccvchangesets.ApplyExecutorConfig(ccvadapters.GetExecutorConfigRegistry()) + output, err := cs.Apply(*e, ccvchangesets.ApplyExecutorConfigInput{ Topology: topology, ExecutorQualifier: qualifier, - TargetNOPs: shared.ConvertStringToNopAliases(execNOPAliases), + TargetNOPs: ccvshared.ConvertStringToNopAliases(execNOPAliases), }) if err != nil { return nil, fmt.Errorf("failed to generate executor configs for qualifier %s: %w", qualifier, err) @@ -584,8 +585,8 @@ func generateExecutorJobSpecs( } for _, exec := range qualifierExecutors { - jobSpecID := shared.NewExecutorJobID(shared.NOPAlias(exec.NOPAlias), shared.ExecutorJobScope{ExecutorQualifier: qualifier}) - job, err := ccipOffchain.GetJob(output.DataStore.Seal(), shared.NOPAlias(exec.NOPAlias), jobSpecID.ToJobID()) + jobSpecID := ccvshared.NewExecutorJobID(ccvshared.NOPAlias(exec.NOPAlias), ccvshared.ExecutorJobScope{ExecutorQualifier: qualifier}) + job, err := ccvdeployment.GetJob(output.DataStore.Seal(), ccvshared.NOPAlias(exec.NOPAlias), jobSpecID.ToJobID()) if err != nil { return nil, fmt.Errorf("failed to get executor job spec for %s: %w", exec.ContainerName, err) } @@ -691,7 +692,7 @@ func generateVerifierJobSpecs( e *deployment.Environment, in *Cfg, selectors []uint64, - topology *ccipOffchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, sharedTLSCerts *services.TLSCertPaths, ds datastore.MutableDataStore, ) (map[string][]bootstrap.JobSpec, error) { @@ -722,16 +723,16 @@ func generateVerifierJobSpecs( } for family := range families { - verNOPAliases := make([]shared.NOPAlias, 0, len(committeeVerifiers)) + verNOPAliases := make([]ccvshared.NOPAlias, 0, len(committeeVerifiers)) for _, ver := range committeeVerifiers { if ver.ChainFamily == family { - verNOPAliases = append(verNOPAliases, shared.NOPAlias(ver.NOPAlias)) + verNOPAliases = append(verNOPAliases, ccvshared.NOPAlias(ver.NOPAlias)) } } disableFinalityCheckers := disableFinalityCheckersPerFamily[family] - cs := ccipChangesets.ApplyVerifierConfig(ccipAdapters.GetVerifierJobConfigRegistry()) - output, err := cs.Apply(*e, ccipChangesets.ApplyVerifierConfigInput{ + cs := ccvchangesets.ApplyVerifierConfig(ccvadapters.GetVerifierJobConfigRegistry()) + output, err := cs.Apply(*e, ccvchangesets.ApplyVerifierConfigInput{ Topology: topology, CommitteeQualifier: committeeName, DefaultExecutorQualifier: devenvcommon.DefaultExecutorQualifier, @@ -767,8 +768,8 @@ func generateVerifierJobSpecs( allJobSpecs := make([]bootstrap.JobSpec, 0, len(aggNames)) for _, aggName := range aggNames { - jobSpecID := shared.NewVerifierJobID(shared.NOPAlias(ver.NOPAlias), aggName, shared.VerifierJobScope{CommitteeQualifier: committeeName}) - job, err := ccipOffchain.GetJob(output.DataStore.Seal(), shared.NOPAlias(ver.NOPAlias), jobSpecID.ToJobID()) + jobSpecID := ccvshared.NewVerifierJobID(ccvshared.NOPAlias(ver.NOPAlias), aggName, ccvshared.VerifierJobScope{CommitteeQualifier: committeeName}) + job, err := ccvdeployment.GetJob(output.DataStore.Seal(), ccvshared.NOPAlias(ver.NOPAlias), jobSpecID.ToJobID()) if err != nil { return nil, fmt.Errorf("failed to get verifier job spec for %s aggregator %s: %w", ver.ContainerName, aggName, err) } @@ -994,7 +995,7 @@ func NewEnvironment() (in *Cfg, err error) { clModeNopAliases := make([]string, 0) if in.EnvironmentTopology != nil && in.EnvironmentTopology.NOPTopology != nil { for _, nop := range in.EnvironmentTopology.NOPTopology.NOPs { - if nop.GetMode() == shared.NOPModeCL { + if nop.GetMode() == ccvshared.NOPModeCL { clModeNopAliases = append(clModeNopAliases, nop.Alias) } } @@ -1108,7 +1109,7 @@ func NewEnvironment() (in *Cfg, err error) { capsBySelector[networkInfo.ChainSelector] = nil } } - combos := devenvcommon.ComputeTokenCombinations(capsBySelector, topology) + combos := devenvcommon.ComputeTokenCombinations(capsBySelector, convertTopologyToCCIP(topology)) ds := datastore.NewMemoryDataStore() for i, impl := range impls { @@ -1244,8 +1245,8 @@ func NewEnvironment() (in *Cfg, err error) { // Use changeset to generate committee config from on-chain state instanceName := aggregatorInput.InstanceName() - cs := ccipChangesets.GenerateAggregatorConfig(ccipAdapters.GetAggregatorConfigRegistry()) - output, err := cs.Apply(*e, ccipChangesets.GenerateAggregatorConfigInput{ + cs := ccvchangesets.GenerateAggregatorConfig(ccvadapters.GetAggregatorConfigRegistry()) + output, err := cs.Apply(*e, ccvchangesets.GenerateAggregatorConfigInput{ Topology: topology, ServiceIdentifier: instanceName + "-aggregator", CommitteeQualifier: aggregatorInput.CommitteeName, @@ -1285,8 +1286,8 @@ func NewEnvironment() (in *Cfg, err error) { // One shared config is generated; all indexers use the same config and duplicated secrets/auth. if len(in.Aggregator) > 0 && len(in.Indexer) > 0 { firstIdx := in.Indexer[0] - cs := ccipChangesets.GenerateIndexerConfig(ccipAdapters.GetIndexerConfigRegistry()) - output, err := cs.Apply(*e, ccipChangesets.GenerateIndexerConfigInput{ + cs := ccvchangesets.GenerateIndexerConfig(ccvadapters.GetIndexerConfigRegistry()) + output, err := cs.Apply(*e, ccvchangesets.GenerateIndexerConfigInput{ ServiceIdentifier: "indexer", CommitteeVerifierNameToQualifier: firstIdx.CommitteeVerifierNameToQualifier, CCTPVerifierNameToQualifier: firstIdx.CCTPVerifierNameToQualifier, @@ -1502,15 +1503,15 @@ func NewEnvironment() (in *Cfg, err error) { } // Use changeset to generate token verifier config from on-chain state - cs := ccipChangesets.GenerateTokenVerifierConfig(ccipAdapters.GetTokenVerifierConfigRegistry()) - output, err := cs.Apply(*e, ccipChangesets.GenerateTokenVerifierConfigInput{ + cs := ccvchangesets.GenerateTokenVerifierConfig(ccvadapters.GetTokenVerifierConfigRegistry()) + output, err := cs.Apply(*e, ccvchangesets.GenerateTokenVerifierConfigInput{ ServiceIdentifier: "TokenVerifier", ChainSelectors: selectors, PyroscopeURL: template.PyroscopeURL, - Monitoring: shared.MonitoringInput{ + Monitoring: ccvshared.MonitoringInput{ Enabled: template.Monitoring.Enabled, Type: template.Monitoring.Type, - Beholder: shared.BeholderInput{ + Beholder: ccvshared.BeholderInput{ InsecureConnection: template.Monitoring.Beholder.InsecureConnection, CACertFile: template.Monitoring.Beholder.CACertFile, OtelExporterGRPCEndpoint: template.Monitoring.Beholder.OtelExporterGRPCEndpoint, @@ -1521,12 +1522,12 @@ func NewEnvironment() (in *Cfg, err error) { TraceBatchTimeout: template.Monitoring.Beholder.TraceBatchTimeout, }, }, - Lombard: ccipChangesets.LombardConfigInput{ + Lombard: ccvchangesets.LombardConfigInput{ VerifierID: "LombardVerifier", Qualifier: devenvcommon.LombardContractsQualifier, AttestationAPI: fakeOut.InternalHTTPURL + "/lombard", }, - CCTP: ccipChangesets.CCTPConfigInput{ + CCTP: ccvchangesets.CCTPConfigInput{ VerifierID: "CCTPVerifier", AttestationAPI: fakeOut.InternalHTTPURL + "/cctp", }, @@ -1702,10 +1703,10 @@ func launchCLNodes( return nil, fmt.Errorf("no API key pairs found for client %s on aggregator %s", apiClient.ClientID, agg.InstanceName()) } apiKeyPair := apiClient.APIKeyPairs[0] - verifierID := shared.NewVerifierJobID( - shared.NOPAlias(ver.NOPAlias), + verifierID := ccvshared.NewVerifierJobID( + ccvshared.NOPAlias(ver.NOPAlias), aggName, - shared.VerifierJobScope{CommitteeQualifier: ver.CommitteeName}, + ccvshared.VerifierJobScope{CommitteeQualifier: ver.CommitteeName}, ).GetVerifierID() Plog.Debug(). Int("nodeIndex", index). diff --git a/build/devenv/go.mod b/build/devenv/go.mod index 8588beb4b..6819f0f00 100644 --- a/build/devenv/go.mod +++ b/build/devenv/go.mod @@ -4,6 +4,10 @@ go 1.25.7 replace github.com/smartcontractkit/chainlink-ccv => ../.. +replace github.com/smartcontractkit/chainlink-ccv/deployment => ../../deployment + +replace github.com/smartcontractkit/chainlink-ccv/evm => ../../evm + require ( github.com/BurntSushi/toml v1.6.0 github.com/Masterminds/semver/v3 v3.4.0 @@ -35,7 +39,9 @@ require ( github.com/jmoiron/sqlx v1.4.0 github.com/lib/pq v1.11.1 github.com/sethvargo/go-retry v0.3.0 - github.com/smartcontractkit/chainlink-ccv v0.0.0-20260218133052-8e7fe2f457f9 + github.com/smartcontractkit/chainlink-ccv v0.0.0 + github.com/smartcontractkit/chainlink-ccv/deployment v0.0.0 + github.com/smartcontractkit/chainlink-ccv/evm v0.0.0 github.com/smartcontractkit/chainlink-common/keystore v1.0.2 github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20260119171452-39c98c3b33cd github.com/smartcontractkit/chainlink-protos/chainlink-ccv/committee-verifier v0.0.0-20251211142334-5c3421fe2c8d diff --git a/build/devenv/implcommon.go b/build/devenv/implcommon.go index c84e6f616..7a471e893 100644 --- a/build/devenv/implcommon.go +++ b/build/devenv/implcommon.go @@ -16,7 +16,7 @@ import ( devenvmcms "github.com/smartcontractkit/chainlink-ccip/deployment/utils/mcms" ccipAdapters "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/adapters" ccipChangesets "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/changesets" - ccipOffchain "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/build/devenv/cciptestinterfaces" devenvcommon "github.com/smartcontractkit/chainlink-ccv/build/devenv/common" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" @@ -50,7 +50,7 @@ func DeployContractsForSelector( env *deployment.Environment, impl cciptestinterfaces.OnChainConfigurable, selector uint64, - topology *ccipOffchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, ) (datastore.DataStore, error) { runningDS := datastore.NewMemoryDataStore() @@ -60,8 +60,10 @@ func DeployContractsForSelector( operations.NewMemoryReporter(), ) + ccipTopology := convertTopologyToCCIP(topology) + // 1. Pre-hook (e.g. EVM deploys CREATE2 factory here). - preDS, err := impl.PreDeployContractsForSelector(ctx, env, selector, topology) + preDS, err := impl.PreDeployContractsForSelector(ctx, env, selector, ccipTopology) if err != nil { return nil, fmt.Errorf("pre-deploy for selector %d: %w", selector, err) } @@ -77,7 +79,7 @@ func DeployContractsForSelector( } // 2. Get chain-specific config (reads pre-deployed addresses from env.DataStore). - cfg, err := impl.GetDeployChainContractsCfg(env, selector, topology) + cfg, err := impl.GetDeployChainContractsCfg(env, selector, ccipTopology) if err != nil { return nil, fmt.Errorf("get deploy config for selector %d: %w", selector, err) } @@ -86,7 +88,7 @@ func DeployContractsForSelector( registry := ccipAdapters.GetDeployChainContractsRegistry() out, err := ccipChangesets.DeployChainContracts(registry).Apply(*env, changesetscore.WithMCMS[ccipChangesets.DeployChainContractsCfg]{ Cfg: ccipChangesets.DeployChainContractsCfg{ - Topology: topology, + Topology: ccipTopology, ChainSelectors: []uint64{selector}, IgnoreImportedConfigFromPreviousVersion: true, DefaultCfg: cfg, @@ -105,7 +107,7 @@ func DeployContractsForSelector( env.DataStore = merged // 4. Post-hook (e.g. EVM deploys USDC/Lombard pools here). - postDS, err := impl.PostDeployContractsForSelector(ctx, env, selector, topology) + postDS, err := impl.PostDeployContractsForSelector(ctx, env, selector, ccipTopology) if err != nil { return nil, fmt.Errorf("post-deploy for selector %d: %w", selector, err) } @@ -142,7 +144,7 @@ func connectAllChainsCanonical( blockchains []*blockchain.Input, selectors []uint64, e *deployment.Environment, - topology *ccipOffchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, ) error { if len(blockchains) != len(impls) { return fmt.Errorf("connectAllChains: mismatched lengths: %d impls and %d blockchains", len(impls), len(blockchains)) @@ -210,7 +212,7 @@ func connectAllChainsCanonical( } cfg := ccipChangesets.ConfigureChainsForLanesFromTopologyConfig{ - Topology: topology, + Topology: convertTopologyToCCIP(topology), Chains: configs, } if err := cs.VerifyPreconditions(*e, cfg); err != nil { @@ -235,7 +237,7 @@ func buildPartialChainConfig( localSel uint64, remoteSels []uint64, profiles map[uint64]chainProfile, - topology *ccipOffchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, ) (ccipChangesets.PartialChainConfig, error) { localEntry, ok := profiles[localSel] if !ok { @@ -306,7 +308,7 @@ func connectAllChainsLegacy( blockchains []*blockchain.Input, selectors []uint64, e *deployment.Environment, - topology *ccipOffchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, ) error { if len(blockchains) != len(impls) { return fmt.Errorf("connectAllChainsLegacy: mismatched lengths: %d impls and %d blockchains", len(impls), len(blockchains)) @@ -374,7 +376,7 @@ func connectAllChainsLegacy( populator := ccipChangesets.NewTopologyCommitteePopulator( ccipAdapters.GetCommitteeVerifierContractRegistry(), - topology, + convertTopologyToCCIP(topology), ) laneAdapterRegistry := lanes.GetLaneAdapterRegistry() @@ -403,7 +405,7 @@ func connectAllChainsLegacy( } func buildCommitteeVerifierInputs( - topology *ccipOffchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, remoteSelectors []uint64, entries map[uint64]chainEntry, ) []lanes.CommitteeVerifierInput { @@ -522,7 +524,7 @@ func ConfigureAllTokenTransfers( impls []cciptestinterfaces.CCIP17Configuration, selectors []uint64, env *deployment.Environment, - topology *ccipOffchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, ) error { refKey := func(ref datastore.AddressRef) string { v := "" @@ -554,7 +556,7 @@ func ConfigureAllTokenTransfers( } } - cfgs, err := tcp.GetTokenTransferConfigs(env, selectors[i], remoteSelectors, topology) + cfgs, err := tcp.GetTokenTransferConfigs(env, selectors[i], remoteSelectors, convertTopologyToCCIP(topology)) if err != nil { return fmt.Errorf("get token transfer configs for selector %d: %w", selectors[i], err) } diff --git a/build/devenv/jobs/jd.go b/build/devenv/jobs/jd.go index e23c2dbf5..430ad4745 100644 --- a/build/devenv/jobs/jd.go +++ b/build/devenv/jobs/jd.go @@ -22,9 +22,9 @@ import ( ns "github.com/smartcontractkit/chainlink-testing-framework/framework/components/simple_node_set" sdkclient "github.com/smartcontractkit/chainlink/deployment/environment/web/sdk/client" - ccipChangesets "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/changesets" - ccipOffchain "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain" - "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain/shared" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + ccvchangesets "github.com/smartcontractkit/chainlink-ccv/deployment/changesets" + ccvshared "github.com/smartcontractkit/chainlink-ccv/deployment/shared" ) type JDInfrastructure struct { @@ -415,7 +415,7 @@ func SyncAndVerifyJobProposals(e *deployment.Environment) error { return fmt.Errorf("datastore is required for job proposal verification") } - allJobs, err := ccipOffchain.GetAllJobs(e.DataStore) + allJobs, err := ccvdeployment.GetAllJobs(e.DataStore) if err != nil { return fmt.Errorf("failed to get all jobs: %w", err) } @@ -423,7 +423,7 @@ func SyncAndVerifyJobProposals(e *deployment.Environment) error { clJobCount := 0 for _, nopJobs := range allJobs { for _, job := range nopJobs { - if job.Mode == shared.NOPModeCL { + if job.Mode == ccvshared.NOPModeCL { clJobCount++ } } @@ -434,12 +434,12 @@ func SyncAndVerifyJobProposals(e *deployment.Environment) error { return nil } - output, err := ccipChangesets.SyncJobProposals().Apply(*e, ccipChangesets.SyncJobProposalsInput{}) + output, err := ccvchangesets.SyncJobProposals().Apply(*e, ccvchangesets.SyncJobProposalsInput{}) if err != nil { return fmt.Errorf("failed to sync job proposals: %w", err) } - updatedJobs, err := ccipOffchain.GetAllJobs(output.DataStore.Seal()) + updatedJobs, err := ccvdeployment.GetAllJobs(output.DataStore.Seal()) if err != nil { return fmt.Errorf("failed to get updated jobs: %w", err) } @@ -447,7 +447,7 @@ func SyncAndVerifyJobProposals(e *deployment.Environment) error { pendingCLJobs := make([]string, 0) for nopAlias, nopJobs := range updatedJobs { for jobID, job := range nopJobs { - if job.Mode == shared.NOPModeCL && job.LatestStatus() != shared.JobProposalStatusApproved { + if job.Mode == ccvshared.NOPModeCL && job.LatestStatus() != ccvshared.JobProposalStatusApproved { pendingCLJobs = append(pendingCLJobs, fmt.Sprintf("%s/%s: %s", nopAlias, jobID, job.LatestStatus())) } diff --git a/build/devenv/offchainloader/loader.go b/build/devenv/offchainloader/loader.go index 7e84bd61a..f05818ab7 100644 --- a/build/devenv/offchainloader/loader.go +++ b/build/devenv/offchainloader/loader.go @@ -1,7 +1,7 @@ package offchainloader import ( - "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/model" "github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config" "github.com/smartcontractkit/chainlink-ccv/pkg/chainaccess" @@ -14,30 +14,30 @@ import ( ) func GetAggregatorConfig(ds datastore.DataStore, id string) (*model.Committee, error) { - ccipCfg, err := offchain.GetAggregatorConfig(ds, id) + ccvCfg, err := ccvdeployment.GetAggregatorConfig(ds, id) if err != nil { return nil, err } - return convertCommittee(ccipCfg), nil + return convertCommittee(ccvCfg), nil } func GetIndexerConfig(ds datastore.DataStore, id string) (*config.GeneratedConfig, error) { - ccipCfg, err := offchain.GetIndexerConfig(ds, id) + ccvCfg, err := ccvdeployment.GetIndexerConfig(ds, id) if err != nil { return nil, err } - return convertIndexerConfig(ccipCfg), nil + return convertIndexerConfig(ccvCfg), nil } func GetTokenVerifierConfig(ds datastore.DataStore, id string) (*token.Config, error) { - ccipCfg, err := offchain.GetTokenVerifierConfig(ds, id) + ccvCfg, err := ccvdeployment.GetTokenVerifierConfig(ds, id) if err != nil { return nil, err } - return convertTokenVerifierConfig(ccipCfg), nil + return convertTokenVerifierConfig(ccvCfg), nil } -func convertCommittee(src *offchain.Committee) *model.Committee { +func convertCommittee(src *ccvdeployment.Committee) *model.Committee { if src == nil { return nil } @@ -53,7 +53,7 @@ func convertCommittee(src *offchain.Committee) *model.Committee { return dst } -func convertQuorumConfig(src *offchain.QuorumConfig) *model.QuorumConfig { +func convertQuorumConfig(src *ccvdeployment.QuorumConfig) *model.QuorumConfig { if src == nil { return nil } @@ -68,7 +68,7 @@ func convertQuorumConfig(src *offchain.QuorumConfig) *model.QuorumConfig { } } -func convertIndexerConfig(src *offchain.IndexerGeneratedConfig) *config.GeneratedConfig { +func convertIndexerConfig(src *ccvdeployment.IndexerGeneratedConfig) *config.GeneratedConfig { if src == nil { return nil } @@ -82,7 +82,7 @@ func convertIndexerConfig(src *offchain.IndexerGeneratedConfig) *config.Generate return &config.GeneratedConfig{Verifier: verifiers} } -func convertTokenVerifierConfig(src *offchain.TokenVerifierGeneratedConfig) *token.Config { +func convertTokenVerifierConfig(src *ccvdeployment.TokenVerifierGeneratedConfig) *token.Config { if src == nil { return nil } @@ -125,7 +125,7 @@ func convertTokenVerifierConfig(src *offchain.TokenVerifierGeneratedConfig) *tok return dst } -func convertCCTPConfig(src *offchain.CCTPVerifierConfig) *cctp.CCTPConfig { +func convertCCTPConfig(src *ccvdeployment.CCTPVerifierConfig) *cctp.CCTPConfig { if src == nil { return nil } @@ -145,7 +145,7 @@ func convertCCTPConfig(src *offchain.CCTPVerifierConfig) *cctp.CCTPConfig { return dst } -func convertLombardConfig(src *offchain.LombardVerifierConfig) *lombard.LombardConfig { +func convertLombardConfig(src *ccvdeployment.LombardVerifierConfig) *lombard.LombardConfig { if src == nil { return nil } diff --git a/build/devenv/topology_compat.go b/build/devenv/topology_compat.go new file mode 100644 index 000000000..69fcc142a --- /dev/null +++ b/build/devenv/topology_compat.go @@ -0,0 +1,29 @@ +package ccv + +import ( + "bytes" + "fmt" + + "github.com/BurntSushi/toml" + + ccipOffchain "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" +) + +// convertTopologyToCCIP converts ccvdeployment.EnvironmentTopology to the +// ccipOffchain.EnvironmentTopology required by onchain changesets in chainlink-ccip +// that have not yet migrated to the ccv deployment package. Phase 2 bridge shim. +func convertTopologyToCCIP(src *ccvdeployment.EnvironmentTopology) *ccipOffchain.EnvironmentTopology { + if src == nil { + return nil + } + var buf bytes.Buffer + if err := toml.NewEncoder(&buf).Encode(src); err != nil { + panic(fmt.Sprintf("convertTopologyToCCIP encode: %v", err)) + } + var dst ccipOffchain.EnvironmentTopology + if _, err := toml.Decode(buf.String(), &dst); err != nil { + panic(fmt.Sprintf("convertTopologyToCCIP decode: %v", err)) + } + return &dst +} diff --git a/deployment/adapters/aggregator_config.go b/deployment/adapters/aggregator_config.go new file mode 100644 index 000000000..b6d566302 --- /dev/null +++ b/deployment/adapters/aggregator_config.go @@ -0,0 +1,89 @@ +package adapters + +import ( + "context" + "fmt" + "sync" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" +) + +type CommitteeState struct { + Qualifier string + ChainSelector uint64 + Address string + SignatureConfigs []SignatureConfig +} + +type SignatureConfig struct { + SourceChainSelector uint64 + Signers []string + Threshold uint8 +} + +// AggregatorConfigAdapter provides chain-family-specific logic to discover committee state +// and resolve verifier addresses for aggregator offchain config. +type AggregatorConfigAdapter interface { + // ScanCommitteeStates returns committee states for the given chain from the deployment env. + ScanCommitteeStates(ctx context.Context, env deployment.Environment, chainSelector uint64) ([]*CommitteeState, error) + // ResolveVerifierAddress returns the verifier contract address for the given chain and qualifier using the datastore. + ResolveVerifierAddress(ds datastore.DataStore, chainSelector uint64, qualifier string) (string, error) +} + +type AggregatorConfigRegistry struct { + mu sync.Mutex + adapters map[string]AggregatorConfigAdapter +} + +var ( + singletonOffchainConfigRegistry *AggregatorConfigRegistry + aggregatorConfigRegistryOnce sync.Once +) + +func newOffchainConfigRegistry() *AggregatorConfigRegistry { + return &AggregatorConfigRegistry{ + adapters: make(map[string]AggregatorConfigAdapter), + } +} + +func GetAggregatorConfigRegistry() *AggregatorConfigRegistry { + aggregatorConfigRegistryOnce.Do(func() { + singletonOffchainConfigRegistry = newOffchainConfigRegistry() + }) + return singletonOffchainConfigRegistry +} + +func (r *AggregatorConfigRegistry) Register(family string, a AggregatorConfigAdapter) { + r.mu.Lock() + defer r.mu.Unlock() + if r.adapters == nil { + r.adapters = make(map[string]AggregatorConfigAdapter) + } + if _, exists := r.adapters[family]; !exists { + r.adapters[family] = a + } +} + +func (r *AggregatorConfigRegistry) Get(family string) (AggregatorConfigAdapter, bool) { + r.mu.Lock() + defer r.mu.Unlock() + if r.adapters == nil { + return nil, false + } + a, ok := r.adapters[family] + return a, ok +} + +func (r *AggregatorConfigRegistry) GetByChain(chainSelector uint64) (AggregatorConfigAdapter, error) { + family, err := chainsel.GetSelectorFamily(chainSelector) + if err != nil { + return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) + } + adapter, ok := r.Get(family) + if !ok { + return nil, fmt.Errorf("no offchain config adapter registered for chain family %q", family) + } + return adapter, nil +} diff --git a/deployment/adapters/executor_config.go b/deployment/adapters/executor_config.go new file mode 100644 index 000000000..5d169c53d --- /dev/null +++ b/deployment/adapters/executor_config.go @@ -0,0 +1,79 @@ +package adapters + +import ( + "fmt" + "sync" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + + "github.com/smartcontractkit/chainlink-ccv/executor" +) + +// ExecutorConfigAdapter resolves per-chain executor configuration from the datastore. +// BuildChainConfig returns executor.ChainConfiguration directly — no intermediate copy type needed. +type ExecutorConfigAdapter interface { + GetDeployedChains(ds datastore.DataStore, qualifier string) []uint64 + BuildChainConfig(ds datastore.DataStore, chainSelector uint64, qualifier string) (executor.ChainConfiguration, error) +} + +type ExecutorConfigRegistry struct { + mu sync.Mutex + adapters map[string]ExecutorConfigAdapter +} + +var ( + singletonExecutorConfigRegistry *ExecutorConfigRegistry + executorConfigRegistryOnce sync.Once +) + +func NewExecutorConfigRegistry() *ExecutorConfigRegistry { + return &ExecutorConfigRegistry{ + adapters: make(map[string]ExecutorConfigAdapter), + } +} + +func GetExecutorConfigRegistry() *ExecutorConfigRegistry { + executorConfigRegistryOnce.Do(func() { + singletonExecutorConfigRegistry = NewExecutorConfigRegistry() + }) + return singletonExecutorConfigRegistry +} + +func (r *ExecutorConfigRegistry) Register(family string, a ExecutorConfigAdapter) { + r.mu.Lock() + defer r.mu.Unlock() + if _, exists := r.adapters[family]; !exists { + r.adapters[family] = a + } +} + +func (r *ExecutorConfigRegistry) Get(family string) (ExecutorConfigAdapter, bool) { + r.mu.Lock() + defer r.mu.Unlock() + a, ok := r.adapters[family] + return a, ok +} + +func (r *ExecutorConfigRegistry) GetByChain(chainSelector uint64) (ExecutorConfigAdapter, error) { + family, err := chainsel.GetSelectorFamily(chainSelector) + if err != nil { + return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) + } + adapter, ok := r.Get(family) + if !ok { + return nil, fmt.Errorf("no executor config adapter registered for chain family %q", family) + } + return adapter, nil +} + +// AllDeployedChains collects deployed chains across all registered adapters. +func (r *ExecutorConfigRegistry) AllDeployedChains(ds datastore.DataStore, qualifier string) []uint64 { + r.mu.Lock() + defer r.mu.Unlock() + var chains []uint64 + for _, adapter := range r.adapters { + chains = append(chains, adapter.GetDeployedChains(ds, qualifier)...) + } + return chains +} diff --git a/deployment/adapters/indexer_config.go b/deployment/adapters/indexer_config.go new file mode 100644 index 000000000..3e9e9c625 --- /dev/null +++ b/deployment/adapters/indexer_config.go @@ -0,0 +1,98 @@ +package adapters + +import ( + "fmt" + "sync" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" +) + +type VerifierKind string + +const ( + CommitteeVerifierKind VerifierKind = "committee" + CCTPVerifierKind VerifierKind = "cctp" + LombardVerifierKind VerifierKind = "lombard" +) + +type MissingIndexerVerifierAddressesError struct { + Kind VerifierKind + ChainSelector uint64 + Qualifier string +} + +func (e *MissingIndexerVerifierAddressesError) Error() string { + return fmt.Sprintf( + "no %s verifier addresses found for chain %d with qualifier %q", + e.Kind, + e.ChainSelector, + e.Qualifier, + ) +} + +type IndexerConfigAdapter interface { + ResolveVerifierAddresses(ds datastore.DataStore, chainSelector uint64, qualifier string, kind VerifierKind) ([]string, error) +} + +type IndexerConfigRegistry struct { + mu sync.Mutex + adapters map[string]IndexerConfigAdapter +} + +var ( + singletonIndexerConfigRegistry *IndexerConfigRegistry + indexerConfigRegistryOnce sync.Once +) + +func newIndexerConfigRegistry() *IndexerConfigRegistry { + return &IndexerConfigRegistry{ + adapters: make(map[string]IndexerConfigAdapter), + } +} + +func GetIndexerConfigRegistry() *IndexerConfigRegistry { + indexerConfigRegistryOnce.Do(func() { + singletonIndexerConfigRegistry = newIndexerConfigRegistry() + }) + return singletonIndexerConfigRegistry +} + +func (r *IndexerConfigRegistry) Register(family string, a IndexerConfigAdapter) { + r.mu.Lock() + defer r.mu.Unlock() + if r.adapters == nil { + r.adapters = make(map[string]IndexerConfigAdapter) + } + if _, exists := r.adapters[family]; !exists { + r.adapters[family] = a + } +} + +func (r *IndexerConfigRegistry) Get(family string) (IndexerConfigAdapter, bool) { + r.mu.Lock() + defer r.mu.Unlock() + if r.adapters == nil { + return nil, false + } + a, ok := r.adapters[family] + return a, ok +} + +func (r *IndexerConfigRegistry) GetByChain(chainSelector uint64) (IndexerConfigAdapter, error) { + family, err := chainsel.GetSelectorFamily(chainSelector) + if err != nil { + return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) + } + adapter, ok := r.Get(family) + if !ok { + return nil, fmt.Errorf("no indexer config adapter registered for chain family %q", family) + } + return adapter, nil +} + +func (r *IndexerConfigRegistry) HasAdapters() bool { + r.mu.Lock() + defer r.mu.Unlock() + return len(r.adapters) > 0 +} diff --git a/deployment/adapters/token_verifier_config.go b/deployment/adapters/token_verifier_config.go new file mode 100644 index 000000000..4dc496970 --- /dev/null +++ b/deployment/adapters/token_verifier_config.go @@ -0,0 +1,79 @@ +package adapters + +import ( + "fmt" + "sync" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" +) + +type TokenVerifierChainAddresses struct { + OnRampAddress string + RMNRemoteAddress string + CCTPVerifierAddress string + CCTPVerifierResolverAddress string + LombardVerifierResolverAddress string +} + +type TokenVerifierConfigAdapter interface { + ResolveTokenVerifierAddresses( + ds datastore.DataStore, + chainSelector uint64, + cctpQualifier string, + lombardQualifier string, + ) (*TokenVerifierChainAddresses, error) +} + +type TokenVerifierConfigRegistry struct { + mu sync.Mutex + adapters map[string]TokenVerifierConfigAdapter +} + +var ( + singletonTokenVerifierConfigRegistry *TokenVerifierConfigRegistry + tokenVerifierConfigRegistryOnce sync.Once +) + +func NewTokenVerifierConfigRegistry() *TokenVerifierConfigRegistry { + return &TokenVerifierConfigRegistry{ + adapters: make(map[string]TokenVerifierConfigAdapter), + } +} + +func GetTokenVerifierConfigRegistry() *TokenVerifierConfigRegistry { + tokenVerifierConfigRegistryOnce.Do(func() { + singletonTokenVerifierConfigRegistry = NewTokenVerifierConfigRegistry() + }) + return singletonTokenVerifierConfigRegistry +} + +func (r *TokenVerifierConfigRegistry) Register(family string, a TokenVerifierConfigAdapter) { + if a == nil { + return + } + r.mu.Lock() + defer r.mu.Unlock() + if _, exists := r.adapters[family]; !exists { + r.adapters[family] = a + } +} + +func (r *TokenVerifierConfigRegistry) Get(family string) (TokenVerifierConfigAdapter, bool) { + r.mu.Lock() + defer r.mu.Unlock() + a, ok := r.adapters[family] + return a, ok +} + +func (r *TokenVerifierConfigRegistry) GetByChain(chainSelector uint64) (TokenVerifierConfigAdapter, error) { + family, err := chainsel.GetSelectorFamily(chainSelector) + if err != nil { + return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) + } + adapter, ok := r.Get(family) + if !ok { + return nil, fmt.Errorf("no token verifier config adapter registered for chain family %q", family) + } + return adapter, nil +} diff --git a/deployment/adapters/verifier_config.go b/deployment/adapters/verifier_config.go new file mode 100644 index 000000000..dd60bf9f7 --- /dev/null +++ b/deployment/adapters/verifier_config.go @@ -0,0 +1,79 @@ +package adapters + +import ( + "fmt" + "sync" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" +) + +type VerifierContractAddresses struct { + CommitteeVerifierAddress string + OnRampAddress string + ExecutorProxyAddress string + RMNRemoteAddress string +} + +type VerifierConfigAdapter interface { + ResolveVerifierContractAddresses( + ds datastore.DataStore, + chainSelector uint64, + committeeQualifier string, + executorQualifier string, + ) (*VerifierContractAddresses, error) + // GetSignerAddressFamily returns the chain-selectors family string whose signing key + // verifier jobs must use (e.g. chainsel.FamilyEVM for EVM committee verifiers). + // This allows the changeset layer to stay chain-agnostic. + GetSignerAddressFamily() string +} + +type VerifierConfigRegistry struct { + mu sync.Mutex + adapters map[string]VerifierConfigAdapter +} + +var ( + singletonVerifierJobConfigRegistry *VerifierConfigRegistry + verifierJobConfigRegistryOnce sync.Once +) + +func NewVerifierConfigRegistry() *VerifierConfigRegistry { + return &VerifierConfigRegistry{ + adapters: make(map[string]VerifierConfigAdapter), + } +} + +func GetVerifierJobConfigRegistry() *VerifierConfigRegistry { + verifierJobConfigRegistryOnce.Do(func() { + singletonVerifierJobConfigRegistry = NewVerifierConfigRegistry() + }) + return singletonVerifierJobConfigRegistry +} + +func (r *VerifierConfigRegistry) Register(family string, a VerifierConfigAdapter) { + r.mu.Lock() + defer r.mu.Unlock() + if _, exists := r.adapters[family]; !exists { + r.adapters[family] = a + } +} + +func (r *VerifierConfigRegistry) Get(family string) (VerifierConfigAdapter, bool) { + r.mu.Lock() + defer r.mu.Unlock() + a, ok := r.adapters[family] + return a, ok +} + +func (r *VerifierConfigRegistry) GetByChain(chainSelector uint64) (VerifierConfigAdapter, error) { + family, err := chainsel.GetSelectorFamily(chainSelector) + if err != nil { + return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) + } + adapter, ok := r.Get(family) + if !ok { + return nil, fmt.Errorf("no verifier job config adapter registered for chain family %q", family) + } + return adapter, nil +} diff --git a/deployment/aggregator.go b/deployment/aggregator.go new file mode 100644 index 000000000..d6701d92f --- /dev/null +++ b/deployment/aggregator.go @@ -0,0 +1,20 @@ +package deployment + +type SourceSelector = string + +type DestinationSelector = string + +type Signer struct { + Address string `json:"address"` +} + +type QuorumConfig struct { + SourceVerifierAddress string `json:"sourceVerifierAddress"` + Signers []Signer `json:"signers"` + Threshold uint8 `json:"threshold"` +} + +type Committee struct { + QuorumConfigs map[SourceSelector]*QuorumConfig `json:"quorumConfigs"` + DestinationVerifiers map[DestinationSelector]string `json:"destinationVerifiers"` +} diff --git a/deployment/changesets/apply_executor_config.go b/deployment/changesets/apply_executor_config.go new file mode 100644 index 000000000..6a6e62a1d --- /dev/null +++ b/deployment/changesets/apply_executor_config.go @@ -0,0 +1,419 @@ +package changesets + +import ( + "fmt" + "slices" + "strconv" + + "github.com/BurntSushi/toml" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-deployments-framework/operations" + + "github.com/smartcontractkit/chainlink-ccv/executor" + + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" + "github.com/smartcontractkit/chainlink-ccv/deployment/operations/fetch_node_chain_support" + "github.com/smartcontractkit/chainlink-ccv/deployment/sequences" + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +type ApplyExecutorConfigInput struct { + Topology *ccvdeployment.EnvironmentTopology + ExecutorQualifier string + TargetNOPs []shared.NOPAlias + // RevokeOrphanedJobs when true revokes and cleans up orphaned jobs; default false. + RevokeOrphanedJobs bool +} + +func ApplyExecutorConfig(registry *adapters.ExecutorConfigRegistry) deployment.ChangeSetV2[ApplyExecutorConfigInput] { + validate := func(e deployment.Environment, cfg ApplyExecutorConfigInput) error { + if cfg.Topology == nil { + return fmt.Errorf("topology is required") + } + + if cfg.ExecutorQualifier == "" { + return fmt.Errorf("executor qualifier is required") + } + + if cfg.Topology.NOPTopology == nil || len(cfg.Topology.NOPTopology.NOPs) == 0 { + return fmt.Errorf("NOP topology with at least one NOP is required") + } + + if len(cfg.Topology.IndexerAddress) == 0 { + return fmt.Errorf("indexer address is required in topology") + } + + pool, ok := cfg.Topology.ExecutorPools[cfg.ExecutorQualifier] + if !ok { + return fmt.Errorf("executor pool %q not found in topology", cfg.ExecutorQualifier) + } + + if len(pool.ChainConfigs) == 0 { + return fmt.Errorf("executor pool %q requires non-empty chain_configs", cfg.ExecutorQualifier) + } + + poolNOPs := getExecutorPoolNOPAliases(pool) + if len(poolNOPs) == 0 { + return fmt.Errorf("executor pool %q has no NOPs", cfg.ExecutorQualifier) + } + for _, alias := range cfg.TargetNOPs { + if !slices.Contains(poolNOPs, alias) { + return fmt.Errorf("NOP alias %q not found in executor pool %q", alias, cfg.ExecutorQualifier) + } + } + + if shared.IsProductionEnvironment(e.Name) { + if cfg.Topology.PyroscopeURL != "" { + return fmt.Errorf("pyroscope URL is not supported for production environments") + } + } + return nil + } + + apply := func(e deployment.Environment, cfg ApplyExecutorConfigInput) (deployment.ChangesetOutput, error) { + selectors := registry.AllDeployedChains(e.DataStore, cfg.ExecutorQualifier) + pool := cfg.Topology.ExecutorPools[cfg.ExecutorQualifier] + + if len(selectors) == 0 { + if !cfg.RevokeOrphanedJobs { + e.Logger.Infow("No deployed chains found for executor pool, nothing to do", + "qualifier", cfg.ExecutorQualifier) + ds := datastore.NewMemoryDataStore() + if e.DataStore != nil { + if err := ds.Merge(e.DataStore); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to merge datastore: %w", err) + } + } + return deployment.ChangesetOutput{DataStore: ds}, nil + } + e.Logger.Infow("No deployed chains for executor pool, running orphan cleanup only", + "qualifier", cfg.ExecutorQualifier) + nopModes := buildNOPModes(cfg.Topology.NOPTopology.NOPs) + scope := shared.ExecutorJobScope{ExecutorQualifier: cfg.ExecutorQualifier} + manageReport, err := operations.ExecuteSequence( + e.OperationsBundle, + sequences.ManageJobProposals, + sequences.ManageJobProposalsDeps{Env: e}, + sequences.ManageJobProposalsInput{ + JobSpecs: nil, + AffectedScope: scope, + Labels: map[string]string{"job_type": "executor", "executor": cfg.ExecutorQualifier}, + NOPs: sequences.NOPContext{Modes: nopModes, TargetNOPs: cfg.TargetNOPs, AllNOPs: getAllNOPAliases(cfg.Topology.NOPTopology.NOPs)}, + RevokeOrphanedJobs: true, + }, + ) + if err != nil { + return deployment.ChangesetOutput{Reports: manageReport.ExecutionReports}, fmt.Errorf("failed to manage job proposals (orphan cleanup): %w", err) + } + return deployment.ChangesetOutput{Reports: manageReport.ExecutionReports, DataStore: manageReport.Output.DataStore}, nil + } + + nopsToValidate := cfg.TargetNOPs + if len(nopsToValidate) == 0 { + nopsToValidate = getExecutorPoolNOPAliases(pool) + } + + clNOPs := filterCLModeNOPs(nopsToValidate, cfg.Topology.NOPTopology.NOPs) + if err := validateExecutorChainSupport(e, pool, clNOPs, selectors); err != nil { + return deployment.ChangesetOutput{}, err + } + + chainConfigs, err := buildExecutorChainConfigs(registry, e.DataStore, selectors, cfg.ExecutorQualifier) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + nopModes := buildNOPModes(cfg.Topology.NOPTopology.NOPs) + + jobSpecs, scope, err := buildExecutorJobSpecs( + chainConfigs, + cfg.ExecutorQualifier, + cfg.TargetNOPs, + pool, + cfg.Topology.IndexerAddress, + cfg.Topology.PyroscopeURL, + cfg.Topology.Monitoring, + ) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + manageReport, err := operations.ExecuteSequence( + e.OperationsBundle, + sequences.ManageJobProposals, + sequences.ManageJobProposalsDeps{Env: e}, + sequences.ManageJobProposalsInput{ + JobSpecs: jobSpecs, + AffectedScope: scope, + Labels: map[string]string{ + "job_type": "executor", + "executor": cfg.ExecutorQualifier, + }, + NOPs: sequences.NOPContext{ + Modes: nopModes, + TargetNOPs: cfg.TargetNOPs, + AllNOPs: getAllNOPAliases(cfg.Topology.NOPTopology.NOPs), + }, + RevokeOrphanedJobs: cfg.RevokeOrphanedJobs, + }, + ) + if err != nil { + return deployment.ChangesetOutput{ + Reports: manageReport.ExecutionReports, + }, fmt.Errorf("failed to manage job proposals: %w", err) + } + + e.Logger.Infow("Executor config applied", + "jobsCount", len(manageReport.Output.Jobs), + "revokedCount", len(manageReport.Output.RevokedJobs)) + + return deployment.ChangesetOutput{ + Reports: manageReport.ExecutionReports, + DataStore: manageReport.Output.DataStore, + }, nil + } + + return deployment.CreateChangeSet(apply, validate) +} + +func buildExecutorChainConfigs( + registry *adapters.ExecutorConfigRegistry, + ds datastore.DataStore, + selectors []uint64, + qualifier string, +) (map[string]executor.ChainConfiguration, error) { + chainConfigs := make(map[string]executor.ChainConfiguration, len(selectors)) + for _, sel := range selectors { + adapter, err := registry.GetByChain(sel) + if err != nil { + return nil, fmt.Errorf("no adapter for chain %d: %w", sel, err) + } + cfg, err := adapter.BuildChainConfig(ds, sel, qualifier) + if err != nil { + return nil, fmt.Errorf("failed to build config for chain %d: %w", sel, err) + } + chainConfigs[strconv.FormatUint(sel, 10)] = cfg + } + return chainConfigs, nil +} + +func getExecutorPoolNOPAliases(pool ccvdeployment.ExecutorPoolConfig) []shared.NOPAlias { + aliasSet := make(map[string]struct{}) + for _, chainCfg := range pool.ChainConfigs { + for _, alias := range chainCfg.NOPAliases { + aliasSet[alias] = struct{}{} + } + } + aliases := make([]string, 0, len(aliasSet)) + for a := range aliasSet { + aliases = append(aliases, a) + } + slices.Sort(aliases) + return shared.ConvertStringToNopAliases(aliases) +} + +func validateExecutorChainSupport( + e deployment.Environment, + pool ccvdeployment.ExecutorPoolConfig, + nopsToValidate []shared.NOPAlias, + deployedChains []uint64, +) error { + if e.Offchain == nil { + e.Logger.Debugw("Offchain client not available, skipping chain support validation") + return nil + } + + nopAliasStrings := shared.ConvertNopAliasToString(nopsToValidate) + + supportedChains, err := fetchNodeChainSupport(e, nopAliasStrings) + if err != nil { + return fmt.Errorf("failed to fetch node chain support: %w", err) + } + if supportedChains == nil { + return nil + } + + var validationResults []shared.ChainValidationResult + for _, nopAlias := range nopsToValidate { + requiredChains, err := getRequiredChainsForExecutorNOP(string(nopAlias), pool, deployedChains) + if err != nil { + return err + } + result := shared.ValidateNOPChainSupport( + string(nopAlias), + requiredChains, + supportedChains[string(nopAlias)], + ) + if result != nil { + validationResults = append(validationResults, *result) + } + } + + return shared.FormatChainValidationError(validationResults) +} + +func getRequiredChainsForExecutorNOP(nopAlias string, pool ccvdeployment.ExecutorPoolConfig, _ []uint64) ([]uint64, error) { + var requiredChains []uint64 + for chainSelectorStr, chainCfg := range pool.ChainConfigs { + if !slices.Contains(chainCfg.NOPAliases, nopAlias) { + continue + } + sel, err := strconv.ParseUint(chainSelectorStr, 10, 64) + if err != nil { + return nil, fmt.Errorf("executor pool chain_configs key %q is not a valid chain selector: %w", chainSelectorStr, err) + } + requiredChains = append(requiredChains, sel) + } + return requiredChains, nil +} + +func fetchNodeChainSupport(e deployment.Environment, nopAliases []string) (shared.ChainSupportByNOP, error) { + if len(nopAliases) == 0 { + return nil, nil + } + + report, err := operations.ExecuteOperation( + e.OperationsBundle, + fetch_node_chain_support.FetchNodeChainSupport, + fetch_node_chain_support.FetchNodeChainSupportDeps{ + JDClient: e.Offchain, + Logger: e.Logger, + NodeIDs: e.NodeIDs, + }, + fetch_node_chain_support.FetchNodeChainSupportInput{ + NOPAliases: nopAliases, + }, + ) + if err != nil { + return nil, fmt.Errorf("failed to fetch node chain support from JD: %w", err) + } + + return report.Output.SupportedChains, nil +} + +func buildExecutorJobSpecs( + adapterChainConfigs map[string]executor.ChainConfiguration, + executorQualifier string, + targetNOPs []shared.NOPAlias, + pool ccvdeployment.ExecutorPoolConfig, + indexerAddress []string, + pyroscopeURL string, + monitoring ccvdeployment.MonitoringConfig, +) (shared.NOPJobSpecs, shared.ExecutorJobScope, error) { + scope := shared.ExecutorJobScope{ + ExecutorQualifier: executorQualifier, + } + + poolNOPs := getExecutorPoolNOPAliases(pool) + nopAliases := targetNOPs + if len(nopAliases) == 0 { + nopAliases = poolNOPs + } + + jobSpecs := make(shared.NOPJobSpecs) + + for _, nopAlias := range nopAliases { + chainCfgs := make(map[string]executor.ChainConfiguration) + for chainSelectorStr, adapterCfg := range adapterChainConfigs { + chainCfg, ok := pool.ChainConfigs[chainSelectorStr] + if !ok { + continue + } + sortedPool := slices.Clone(chainCfg.NOPAliases) + slices.Sort(sortedPool) + chainCfgs[chainSelectorStr] = executor.ChainConfiguration{ + OffRampAddress: adapterCfg.OffRampAddress, + RmnAddress: adapterCfg.RmnAddress, + DefaultExecutorAddress: adapterCfg.DefaultExecutorAddress, + ExecutorPool: sortedPool, + ExecutionInterval: chainCfg.ExecutionInterval, + } + } + + jobSpecID := shared.NewExecutorJobID(nopAlias, scope) + + executorCfg := executor.Configuration{ + IndexerAddress: indexerAddress, + ExecutorID: jobSpecID.GetExecutorID(), + PyroscopeURL: pyroscopeURL, + NtpServer: pool.NtpServer, + IndexerQueryLimit: pool.IndexerQueryLimit, + BackoffDuration: pool.BackoffDuration, + LookbackWindow: pool.LookbackWindow, + ReaderCacheExpiry: pool.ReaderCacheExpiry, + MaxRetryDuration: pool.MaxRetryDuration, + WorkerCount: pool.WorkerCount, + Monitoring: toExecutorMonitoring(monitoring), + ChainConfiguration: chainCfgs, + } + + configBytes, err := toml.Marshal(executorCfg) + if err != nil { + return nil, scope, fmt.Errorf("failed to marshal executor config for NOP %q: %w", nopAlias, err) + } + + jobID := jobSpecID.ToJobID() + jobSpec := fmt.Sprintf(`schemaVersion = 1 +type = "ccvexecutor" +name = "%s" +externalJobID = "%s" +executorConfig = ''' +%s''' +`, string(jobID), jobID.ToExternalJobID(), string(configBytes)) + + if jobSpecs[nopAlias] == nil { + jobSpecs[nopAlias] = make(map[shared.JobID]string) + } + jobSpecs[nopAlias][jobID] = jobSpec + } + + return jobSpecs, scope, nil +} + +func toExecutorMonitoring(m ccvdeployment.MonitoringConfig) executor.MonitoringConfig { + return executor.MonitoringConfig{ + Enabled: m.Enabled, + Type: m.Type, + Beholder: executor.BeholderConfig{ + InsecureConnection: m.Beholder.InsecureConnection, + CACertFile: m.Beholder.CACertFile, + OtelExporterGRPCEndpoint: m.Beholder.OtelExporterGRPCEndpoint, + OtelExporterHTTPEndpoint: m.Beholder.OtelExporterHTTPEndpoint, + LogStreamingEnabled: m.Beholder.LogStreamingEnabled, + MetricReaderInterval: m.Beholder.MetricReaderInterval, + TraceSampleRatio: m.Beholder.TraceSampleRatio, + TraceBatchTimeout: m.Beholder.TraceBatchTimeout, + }, + } +} + +func buildNOPModes(nops []ccvdeployment.NOPConfig) map[shared.NOPAlias]shared.NOPMode { + nopModes := make(map[shared.NOPAlias]shared.NOPMode) + for _, nop := range nops { + mode := nop.GetMode() + nopModes[shared.NOPAlias(nop.Alias)] = mode + } + return nopModes +} + +func filterCLModeNOPs(aliases []shared.NOPAlias, nops []ccvdeployment.NOPConfig) []shared.NOPAlias { + modeByAlias := buildNOPModes(nops) + filtered := make([]shared.NOPAlias, 0, len(aliases)) + for _, alias := range aliases { + if mode, ok := modeByAlias[alias]; ok && mode == shared.NOPModeCL { + filtered = append(filtered, alias) + } + } + return filtered +} + +func getAllNOPAliases(nops []ccvdeployment.NOPConfig) []shared.NOPAlias { + aliases := make([]shared.NOPAlias, len(nops)) + for i, nop := range nops { + aliases[i] = shared.NOPAlias(nop.Alias) + } + return aliases +} diff --git a/deployment/changesets/apply_verifier_config.go b/deployment/changesets/apply_verifier_config.go new file mode 100644 index 000000000..6def6a5e1 --- /dev/null +++ b/deployment/changesets/apply_verifier_config.go @@ -0,0 +1,627 @@ +package changesets + +import ( + "fmt" + "slices" + "strconv" + + "github.com/BurntSushi/toml" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-deployments-framework/operations" + + "github.com/smartcontractkit/chainlink-ccv/pkg/chainaccess" + "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/commit" + vtypes "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/vtypes" + + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" + "github.com/smartcontractkit/chainlink-ccv/deployment/operations/fetch_signing_keys" + "github.com/smartcontractkit/chainlink-ccv/deployment/sequences" + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +type ApplyVerifierConfigInput struct { + Topology *ccvdeployment.EnvironmentTopology + CommitteeQualifier string + DefaultExecutorQualifier string + TargetNOPs []shared.NOPAlias + DisableFinalityCheckers []string + // RevokeOrphanedJobs when true revokes and cleans up orphaned jobs; default false. + RevokeOrphanedJobs bool +} + +func ApplyVerifierConfig(registry *adapters.VerifierConfigRegistry) deployment.ChangeSetV2[ApplyVerifierConfigInput] { + validate := func(e deployment.Environment, cfg ApplyVerifierConfigInput) error { + if cfg.Topology == nil { + return fmt.Errorf("topology is required") + } + + if cfg.Topology.NOPTopology == nil || len(cfg.Topology.NOPTopology.NOPs) == 0 { + return fmt.Errorf("NOP topology with at least one NOP is required") + } + + if cfg.CommitteeQualifier == "" { + return fmt.Errorf("committee qualifier is required") + } + + if cfg.DefaultExecutorQualifier == "" { + return fmt.Errorf("default executor qualifier is required") + } + + committee, ok := cfg.Topology.NOPTopology.Committees[cfg.CommitteeQualifier] + if !ok { + return fmt.Errorf("committee %q not found in topology", cfg.CommitteeQualifier) + } + + if len(committee.Aggregators) == 0 { + return fmt.Errorf("at least one aggregator is required for committee %q", cfg.CommitteeQualifier) + } + + nopSet := make(map[string]bool) + for _, nop := range cfg.Topology.NOPTopology.NOPs { + nopSet[nop.Alias] = true + } + + nopAliases := cfg.TargetNOPs + if len(nopAliases) == 0 { + nopAliases = shared.ConvertStringToNopAliases(getCommitteeNOPAliases(committee)) + } + + for _, alias := range nopAliases { + if !nopSet[string(alias)] { + return fmt.Errorf("NOP alias %q not found in topology", alias) + } + } + + if shared.IsProductionEnvironment(e.Name) { + if cfg.Topology.PyroscopeURL != "" { + return fmt.Errorf("pyroscope URL is not supported for production environments") + } + } + + return nil + } + + apply := func(e deployment.Environment, cfg ApplyVerifierConfigInput) (deployment.ChangesetOutput, error) { + committee := cfg.Topology.NOPTopology.Committees[cfg.CommitteeQualifier] + selectors, err := getCommitteeChainSelectors(committee) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + if len(selectors) == 0 { + if !cfg.RevokeOrphanedJobs { + e.Logger.Infow("No chain configs found for committee, nothing to do", + "committee", cfg.CommitteeQualifier) + ds := datastore.NewMemoryDataStore() + if e.DataStore != nil { + if err := ds.Merge(e.DataStore); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to merge datastore: %w", err) + } + } + return deployment.ChangesetOutput{DataStore: ds}, nil + } + e.Logger.Infow("No chain configs for committee, running orphan cleanup only", + "committee", cfg.CommitteeQualifier) + nopModes := buildNOPModes(cfg.Topology.NOPTopology.NOPs) + scope := shared.VerifierJobScope{CommitteeQualifier: cfg.CommitteeQualifier} + manageReport, err := operations.ExecuteSequence( + e.OperationsBundle, + sequences.ManageJobProposals, + sequences.ManageJobProposalsDeps{Env: e}, + sequences.ManageJobProposalsInput{ + JobSpecs: nil, + AffectedScope: scope, + Labels: map[string]string{"job_type": "verifier", "committee": cfg.CommitteeQualifier}, + NOPs: sequences.NOPContext{Modes: nopModes, TargetNOPs: cfg.TargetNOPs, AllNOPs: getAllNOPAliases(cfg.Topology.NOPTopology.NOPs)}, + RevokeOrphanedJobs: true, + }, + ) + if err != nil { + return deployment.ChangesetOutput{Reports: manageReport.ExecutionReports}, + fmt.Errorf("failed to manage job proposals (orphan cleanup): %w", err) + } + return deployment.ChangesetOutput{Reports: manageReport.ExecutionReports, DataStore: manageReport.Output.DataStore}, nil + } + + // Derive the signing key family from the registered adapter — no hardcoded chain family. + signerFamily, err := getSignerFamilyFromRegistry(registry, selectors) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to determine signer address family: %w", err) + } + + nopsToValidate := cfg.TargetNOPs + if len(nopsToValidate) == 0 { + nopsToValidate = shared.ConvertStringToNopAliases(getCommitteeNOPAliases(committee)) + } + + targetedNOPs := filterNOPsByAliases(cfg.Topology.NOPTopology.NOPs, shared.ConvertNopAliasToString(nopsToValidate)) + signingKeysByNOP, err := fetchSigningKeysForNOPs(e, targetedNOPs, signerFamily) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to fetch signing keys: %w", err) + } + + clNOPs := filterCLModeNOPs(nopsToValidate, cfg.Topology.NOPTopology.NOPs) + if err := validateVerifierChainSupport(e, clNOPs, committee); err != nil { + return deployment.ChangesetOutput{}, err + } + + contractAddresses, err := buildVerifierContractConfigs(registry, e, selectors, cfg.CommitteeQualifier, cfg.DefaultExecutorQualifier) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + nopInputs := convertNOPsToVerifierInput(cfg.Topology.NOPTopology.NOPs, signingKeysByNOP, signerFamily) + committeeInput := convertTopologyCommittee(committee) + + jobSpecs, scope, err := buildVerifierJobSpecs( + contractAddresses, + cfg.TargetNOPs, + nopInputs, + committeeInput, + cfg.Topology.PyroscopeURL, + cfg.Topology.Monitoring, + cfg.DisableFinalityCheckers, + signerFamily, + ) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + nopModes := buildNOPModes(cfg.Topology.NOPTopology.NOPs) + + manageReport, err := operations.ExecuteSequence( + e.OperationsBundle, + sequences.ManageJobProposals, + sequences.ManageJobProposalsDeps{Env: e}, + sequences.ManageJobProposalsInput{ + JobSpecs: jobSpecs, + AffectedScope: scope, + Labels: map[string]string{ + "job_type": "verifier", + "committee": cfg.CommitteeQualifier, + }, + NOPs: sequences.NOPContext{ + Modes: nopModes, + TargetNOPs: cfg.TargetNOPs, + AllNOPs: getAllNOPAliases(cfg.Topology.NOPTopology.NOPs), + }, + RevokeOrphanedJobs: cfg.RevokeOrphanedJobs, + }, + ) + if err != nil { + return deployment.ChangesetOutput{ + Reports: manageReport.ExecutionReports, + }, fmt.Errorf("failed to manage job proposals: %w", err) + } + + e.Logger.Infow("Verifier config applied", + "jobsCount", len(manageReport.Output.Jobs), + "revokedCount", len(manageReport.Output.RevokedJobs)) + + return deployment.ChangesetOutput{ + Reports: manageReport.ExecutionReports, + DataStore: manageReport.Output.DataStore, + }, nil + } + + return deployment.CreateChangeSet(apply, validate) +} + +// getSignerFamilyFromRegistry returns the signing key family by querying the registered +// adapter for any of the given chain selectors. All adapters in a committee are expected +// to agree on the signer family (e.g. every EVM adapter returns chainsel.FamilyEVM). +func getSignerFamilyFromRegistry(registry *adapters.VerifierConfigRegistry, selectors []uint64) (string, error) { + for _, sel := range selectors { + adapter, err := registry.GetByChain(sel) + if err != nil { + continue + } + return adapter.GetSignerAddressFamily(), nil + } + return "", fmt.Errorf("no registered verifier adapter found for any committee chain selector") +} + +func buildVerifierContractConfigs( + registry *adapters.VerifierConfigRegistry, + e deployment.Environment, + selectors []uint64, + committeeQualifier string, + executorQualifier string, +) (map[string]*adapters.VerifierContractAddresses, error) { + configs := make(map[string]*adapters.VerifierContractAddresses, len(selectors)) + for _, sel := range selectors { + adapter, err := registry.GetByChain(sel) + if err != nil { + return nil, fmt.Errorf("no adapter for chain %d: %w", sel, err) + } + addrs, err := adapter.ResolveVerifierContractAddresses(e.DataStore, sel, committeeQualifier, executorQualifier) + if err != nil { + return nil, fmt.Errorf("failed to resolve contract addresses for chain %d: %w", sel, err) + } + configs[strconv.FormatUint(sel, 10)] = addrs + } + return configs, nil +} + +type verifierNOPInput struct { + Alias shared.NOPAlias + SignerAddressByFamily map[string]string + Mode shared.NOPMode +} + +type verifierAggregatorInput struct { + Name string + Address string + InsecureAggregatorConnection bool +} + +type verifierCommitteeInput struct { + Qualifier string + Aggregators []verifierAggregatorInput + NOPAliases []shared.NOPAlias + ChainNOPAliases map[string][]shared.NOPAlias +} + +func buildVerifierJobSpecs( + contractAddresses map[string]*adapters.VerifierContractAddresses, + targetNOPs []shared.NOPAlias, + environmentNOPs []verifierNOPInput, + committee verifierCommitteeInput, + pyroscopeURL string, + monitoring ccvdeployment.MonitoringConfig, + disableFinalityCheckers []string, + signerFamily string, +) (shared.NOPJobSpecs, shared.VerifierJobScope, error) { + scope := shared.VerifierJobScope{ + CommitteeQualifier: committee.Qualifier, + } + + nopByAlias := make(map[shared.NOPAlias]verifierNOPInput, len(environmentNOPs)) + for _, nop := range environmentNOPs { + nopByAlias[nop.Alias] = nop + } + + nopAliases := targetNOPs + if len(nopAliases) == 0 { + nopAliases = committee.NOPAliases + } + + committeeVerifierAddrs := make(map[string]string, len(contractAddresses)) + onRampAddrs := make(map[string]string, len(contractAddresses)) + executorOnRampAddrs := make(map[string]string, len(contractAddresses)) + rmnRemoteAddrs := make(map[string]string, len(contractAddresses)) + + for chainSel, addrs := range contractAddresses { + committeeVerifierAddrs[chainSel] = addrs.CommitteeVerifierAddress + onRampAddrs[chainSel] = addrs.OnRampAddress + executorOnRampAddrs[chainSel] = addrs.ExecutorProxyAddress + rmnRemoteAddrs[chainSel] = addrs.RMNRemoteAddress + } + + jobSpecs := make(shared.NOPJobSpecs) + + for _, nopAlias := range nopAliases { + nop, ok := nopByAlias[nopAlias] + if !ok { + return nil, scope, fmt.Errorf("NOP %q not found in input", nopAlias) + } + + nopChains := getNOPChainMembership(nopAlias, committee.ChainNOPAliases) + + if len(committee.ChainNOPAliases) > 0 && len(nopChains) == 0 { + continue + } + + for _, agg := range committee.Aggregators { + verifierJobID := shared.NewVerifierJobID(nopAlias, agg.Name, scope) + + signerAddress := nop.SignerAddressByFamily[signerFamily] + if signerAddress == "" { + return nil, scope, fmt.Errorf("NOP %q missing signer address for family %s", nop.Alias, signerFamily) + } + + sortedFinalityCheckers := slices.Clone(disableFinalityCheckers) + slices.Sort(sortedFinalityCheckers) + + verifierCfg := commit.Config{ + VerifierID: verifierJobID.GetVerifierID(), + AggregatorAddress: agg.Address, + InsecureAggregatorConnection: agg.InsecureAggregatorConnection, + SignerAddress: signerAddress, + PyroscopeURL: pyroscopeURL, + CommitteeVerifierAddresses: filterAddressesByChains(committeeVerifierAddrs, nopChains), + DefaultExecutorOnRampAddresses: filterAddressesByChains(executorOnRampAddrs, nopChains), + DisableFinalityCheckers: sortedFinalityCheckers, + Monitoring: toVerifierMonitoring(monitoring), + CommitteeConfig: chainaccess.CommitteeConfig{ + OnRampAddresses: filterAddressesByChains(onRampAddrs, nopChains), + RMNRemoteAddresses: filterAddressesByChains(rmnRemoteAddrs, nopChains), + }, + } + + configBytes, err := toml.Marshal(verifierCfg) + if err != nil { + return nil, scope, fmt.Errorf("failed to marshal verifier config for NOP %q aggregator %q: %w", nopAlias, agg.Name, err) + } + + jobID := verifierJobID.ToJobID() + jobSpec := fmt.Sprintf(`schemaVersion = 1 +type = "ccvcommitteeverifier" +name = "%s" +externalJobID = "%s" +committeeVerifierConfig = ''' +%s''' +`, string(jobID), jobID.ToExternalJobID(), string(configBytes)) + + if jobSpecs[nopAlias] == nil { + jobSpecs[nopAlias] = make(map[shared.JobID]string) + } + jobSpecs[nopAlias][jobID] = jobSpec + } + } + + return jobSpecs, scope, nil +} + +func toVerifierMonitoring(m ccvdeployment.MonitoringConfig) vtypes.MonitoringConfig { + return vtypes.MonitoringConfig{ + Enabled: m.Enabled, + Type: m.Type, + Beholder: vtypes.BeholderConfig{ + InsecureConnection: m.Beholder.InsecureConnection, + CACertFile: m.Beholder.CACertFile, + OtelExporterGRPCEndpoint: m.Beholder.OtelExporterGRPCEndpoint, + OtelExporterHTTPEndpoint: m.Beholder.OtelExporterHTTPEndpoint, + LogStreamingEnabled: m.Beholder.LogStreamingEnabled, + MetricReaderInterval: m.Beholder.MetricReaderInterval, + TraceSampleRatio: m.Beholder.TraceSampleRatio, + TraceBatchTimeout: m.Beholder.TraceBatchTimeout, + }, + } +} + +// fetchSigningKeysForNOPs fetches signing keys from JD for NOPs that are missing a signer +// address for the given signerFamily. +func fetchSigningKeysForNOPs( + e deployment.Environment, + nops []ccvdeployment.NOPConfig, + signerFamily string, +) (fetch_signing_keys.SigningKeysByNOP, error) { + return fetchSigningKeysForNOPsFiltered(e, nops, func(nop ccvdeployment.NOPConfig) bool { + return nop.SignerAddressByFamily == nil || nop.SignerAddressByFamily[signerFamily] == "" + }) +} + +func fetchSigningKeysForNOPsFiltered( + e deployment.Environment, + nops []ccvdeployment.NOPConfig, + include func(ccvdeployment.NOPConfig) bool, +) (fetch_signing_keys.SigningKeysByNOP, error) { + if e.Offchain == nil { + return nil, nil + } + + aliases := make([]string, 0, len(nops)) + for _, nop := range nops { + if include(nop) { + aliases = append(aliases, nop.Alias) + } + } + + if len(aliases) == 0 { + return nil, nil + } + + report, err := operations.ExecuteOperation( + e.OperationsBundle, + fetch_signing_keys.FetchNOPSigningKeys, + fetch_signing_keys.FetchSigningKeysDeps{ + JDClient: e.Offchain, + Logger: e.Logger, + NodeIDs: e.NodeIDs, + }, + fetch_signing_keys.FetchSigningKeysInput{ + NOPAliases: aliases, + }, + ) + if err != nil { + return nil, fmt.Errorf("failed to fetch signing keys from JD for NOPs %v: %w", aliases, err) + } + + return report.Output.SigningKeysByNOP, nil +} + +func convertNOPsToVerifierInput( + nops []ccvdeployment.NOPConfig, + signingKeysByNOP fetch_signing_keys.SigningKeysByNOP, + signerFamily string, +) []verifierNOPInput { + result := make([]verifierNOPInput, len(nops)) + + for i, nop := range nops { + signerAddresses := nop.SignerAddressByFamily + + if signer, ok := signerFromJDIfMissing(signerAddresses, nop.Alias, signerFamily, signingKeysByNOP); ok { + if signerAddresses == nil { + signerAddresses = make(map[string]string) + } + signerAddresses[signerFamily] = signer + } + + result[i] = verifierNOPInput{ + Alias: shared.NOPAlias(nop.Alias), + SignerAddressByFamily: signerAddresses, + Mode: nop.GetMode(), + } + } + + return result +} + +func convertTopologyCommittee(committee ccvdeployment.CommitteeConfig) verifierCommitteeInput { + aggregators := make([]verifierAggregatorInput, len(committee.Aggregators)) + for i, agg := range committee.Aggregators { + aggregators[i] = verifierAggregatorInput{ + Name: agg.Name, + Address: agg.Address, + InsecureAggregatorConnection: agg.InsecureAggregatorConnection, + } + } + + chainNOPAliases := make(map[string][]shared.NOPAlias, len(committee.ChainConfigs)) + for chainSelector, chainConfig := range committee.ChainConfigs { + chainNOPAliases[chainSelector] = shared.ConvertStringToNopAliases(chainConfig.NOPAliases) + } + + return verifierCommitteeInput{ + Qualifier: committee.Qualifier, + Aggregators: aggregators, + NOPAliases: shared.ConvertStringToNopAliases(getCommitteeNOPAliases(committee)), + ChainNOPAliases: chainNOPAliases, + } +} + +func filterNOPsByAliases(nops []ccvdeployment.NOPConfig, aliases []string) []ccvdeployment.NOPConfig { + aliasSet := make(map[string]struct{}, len(aliases)) + for _, a := range aliases { + aliasSet[a] = struct{}{} + } + filtered := make([]ccvdeployment.NOPConfig, 0, len(aliases)) + for _, nop := range nops { + if _, ok := aliasSet[nop.Alias]; ok { + filtered = append(filtered, nop) + } + } + return filtered +} + +func getCommitteeNOPAliases(committee ccvdeployment.CommitteeConfig) []string { + aliasSet := make(map[string]struct{}) + for _, chainConfig := range committee.ChainConfigs { + for _, alias := range chainConfig.NOPAliases { + aliasSet[alias] = struct{}{} + } + } + aliases := make([]string, 0, len(aliasSet)) + for alias := range aliasSet { + aliases = append(aliases, alias) + } + slices.Sort(aliases) + return aliases +} + +func getCommitteeChainSelectors(committee ccvdeployment.CommitteeConfig) ([]uint64, error) { + selectors := make([]uint64, 0, len(committee.ChainConfigs)) + for chainStr := range committee.ChainConfigs { + sel, err := strconv.ParseUint(chainStr, 10, 64) + if err != nil { + return nil, fmt.Errorf("committee chain_configs key %q is not a valid chain selector: %w", chainStr, err) + } + selectors = append(selectors, sel) + } + slices.Sort(selectors) + return selectors, nil +} + +func validateVerifierChainSupport( + e deployment.Environment, + nopsToValidate []shared.NOPAlias, + committee ccvdeployment.CommitteeConfig, +) error { + if e.Offchain == nil { + e.Logger.Debugw("Offchain client not available, skipping chain support validation") + return nil + } + + nopAliasStrings := shared.ConvertNopAliasToString(nopsToValidate) + + supportedChains, err := fetchNodeChainSupport(e, nopAliasStrings) + if err != nil { + return fmt.Errorf("failed to fetch node chain support: %w", err) + } + if supportedChains == nil { + return nil + } + + var validationResults []shared.ChainValidationResult + for _, nopAlias := range nopsToValidate { + requiredChains, err := getRequiredChainsForNOP(string(nopAlias), committee) + if err != nil { + return err + } + result := shared.ValidateNOPChainSupport( + string(nopAlias), + requiredChains, + supportedChains[string(nopAlias)], + ) + if result != nil { + validationResults = append(validationResults, *result) + } + } + + return shared.FormatChainValidationError(validationResults) +} + +func getRequiredChainsForNOP(nopAlias string, committee ccvdeployment.CommitteeConfig) ([]uint64, error) { + var requiredChains []uint64 + for chainSelectorStr, chainConfig := range committee.ChainConfigs { + if slices.Contains(chainConfig.NOPAliases, nopAlias) { + sel, err := strconv.ParseUint(chainSelectorStr, 10, 64) + if err != nil { + return nil, fmt.Errorf("committee chain_configs key %q is not a valid chain selector: %w", chainSelectorStr, err) + } + requiredChains = append(requiredChains, sel) + } + } + return requiredChains, nil +} + +func signerFromJDIfMissing( + signerAddresses map[string]string, + nopAlias string, + family string, + signingKeysByNOP fetch_signing_keys.SigningKeysByNOP, +) (string, bool) { + if signerAddresses != nil && signerAddresses[family] != "" { + return "", false + } + + if signingKeysByNOP == nil { + return "", false + } + + if signer := signingKeysByNOP[nopAlias][family]; signer != "" { + return signer, true + } + + return "", false +} + +func getNOPChainMembership(nopAlias shared.NOPAlias, chainNOPAliases map[string][]shared.NOPAlias) map[string]bool { + chains := make(map[string]bool) + if chainNOPAliases == nil { + return chains + } + for chainSelector, nops := range chainNOPAliases { + if slices.Contains(nops, nopAlias) { + chains[chainSelector] = true + } + } + return chains +} + +func filterAddressesByChains(addresses map[string]string, nopChains map[string]bool) map[string]string { + if len(nopChains) == 0 { + return addresses + } + filtered := make(map[string]string, len(nopChains)) + for chainSelector, addr := range addresses { + if nopChains[chainSelector] { + filtered[chainSelector] = addr + } + } + return filtered +} diff --git a/deployment/changesets/generate_aggregator_config.go b/deployment/changesets/generate_aggregator_config.go new file mode 100644 index 000000000..cf22bb17d --- /dev/null +++ b/deployment/changesets/generate_aggregator_config.go @@ -0,0 +1,258 @@ +package changesets + +import ( + "context" + "fmt" + "slices" + "strconv" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" +) + +type GenerateAggregatorConfigInput struct { + ServiceIdentifier string + CommitteeQualifier string + Topology *ccvdeployment.EnvironmentTopology +} + +func GenerateAggregatorConfig(registry *adapters.AggregatorConfigRegistry) deployment.ChangeSetV2[GenerateAggregatorConfigInput] { + validate := func(e deployment.Environment, cfg GenerateAggregatorConfigInput) error { + if cfg.ServiceIdentifier == "" { + return fmt.Errorf("service identifier is required") + } + if cfg.CommitteeQualifier == "" { + return fmt.Errorf("committee qualifier is required") + } + _, err := resolveAggregatorChainSelectors(e, cfg) + return err + } + + apply := func(e deployment.Environment, cfg GenerateAggregatorConfigInput) (deployment.ChangesetOutput, error) { + chainSelectors, err := resolveAggregatorChainSelectors(e, cfg) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + committee, err := buildAggregatorCommittee(e, registry, cfg.CommitteeQualifier, chainSelectors) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to build aggregator config: %w", err) + } + + outputDS := datastore.NewMemoryDataStore() + if e.DataStore != nil { + if err := outputDS.Merge(e.DataStore); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to merge existing datastore: %w", err) + } + } + + if err := ccvdeployment.SaveAggregatorConfig(outputDS, cfg.ServiceIdentifier, committee); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to save aggregator config: %w", err) + } + + return deployment.ChangesetOutput{ + DataStore: outputDS, + }, nil + } + + return deployment.CreateChangeSet(apply, validate) +} + +func resolveAggregatorChainSelectors(e deployment.Environment, cfg GenerateAggregatorConfigInput) ([]uint64, error) { + if cfg.Topology == nil { + return nil, fmt.Errorf("topology is required") + } + if cfg.Topology.NOPTopology == nil { + return nil, fmt.Errorf("NOP topology is required") + } + + committee, ok := cfg.Topology.NOPTopology.Committees[cfg.CommitteeQualifier] + if !ok { + return nil, fmt.Errorf("committee %q not found in topology", cfg.CommitteeQualifier) + } + + chainSelectors, err := getCommitteeChainSelectors(committee) + if err != nil { + return nil, err + } + + envSelectors := e.BlockChains.ListChainSelectors() + for _, s := range chainSelectors { + if !slices.Contains(envSelectors, s) { + return nil, fmt.Errorf("committee %q references chain selector %d which is not available in environment", cfg.CommitteeQualifier, s) + } + } + + return chainSelectors, nil +} + +func buildAggregatorCommittee( + e deployment.Environment, + registry *adapters.AggregatorConfigRegistry, + committeeQualifier string, + chainSelectors []uint64, +) (*ccvdeployment.Committee, error) { + ctx := context.Background() + + type chainQualifier struct { + chainSelector uint64 + qualifier string + } + seen := make(map[chainQualifier]bool) + allCommittees := make(map[string][]*adapters.CommitteeState) + for _, sel := range chainSelectors { + adapter, err := registry.GetByChain(sel) + if err != nil { + return nil, err + } + + states, err := adapter.ScanCommitteeStates(ctx, e, sel) + if err != nil { + return nil, fmt.Errorf("failed to scan committee states on chain %d: %w", sel, err) + } + for _, state := range states { + key := chainQualifier{chainSelector: sel, qualifier: state.Qualifier} + if seen[key] { + return nil, fmt.Errorf( + "chain %d has multiple committee verifiers with qualifier %q", + sel, state.Qualifier, + ) + } + seen[key] = true + allCommittees[state.Qualifier] = append(allCommittees[state.Qualifier], state) + } + } + + committeeStates, ok := allCommittees[committeeQualifier] + if !ok || len(committeeStates) == 0 { + return nil, fmt.Errorf("committee %q not found in deployed verifier state", committeeQualifier) + } + + quorumConfigs, err := buildQuorumConfigs(e.DataStore, registry, committeeStates, committeeQualifier, chainSelectors) + if err != nil { + return nil, fmt.Errorf("failed to build quorum configs: %w", err) + } + + destVerifiers, err := buildDestinationVerifiers(e.DataStore, registry, committeeQualifier, chainSelectors) + if err != nil { + return nil, fmt.Errorf("failed to build destination verifiers: %w", err) + } + + return &ccvdeployment.Committee{ + QuorumConfigs: quorumConfigs, + DestinationVerifiers: destVerifiers, + }, nil +} + +func buildQuorumConfigs( + ds datastore.DataStore, + registry *adapters.AggregatorConfigRegistry, + committeeStates []*adapters.CommitteeState, + committeeQualifier string, + chainSelectors []uint64, +) (map[string]*ccvdeployment.QuorumConfig, error) { + supportedChains := make(map[uint64]bool, len(chainSelectors)) + for _, sel := range chainSelectors { + supportedChains[sel] = true + } + + quorumConfigs := make(map[string]*ccvdeployment.QuorumConfig) + + for _, state := range committeeStates { + for _, sigConfig := range state.SignatureConfigs { + if !supportedChains[sigConfig.SourceChainSelector] { + continue + } + + chainSelectorStr := strconv.FormatUint(sigConfig.SourceChainSelector, 10) + if existing, exists := quorumConfigs[chainSelectorStr]; exists { + if err := validateSignatureConfigConsistency(existing, sigConfig, chainSelectorStr, committeeQualifier); err != nil { + return nil, err + } + continue + } + + adapter, err := registry.GetByChain(sigConfig.SourceChainSelector) + if err != nil { + return nil, err + } + + sourceVerifierAddr, err := adapter.ResolveVerifierAddress(ds, sigConfig.SourceChainSelector, committeeQualifier) + if err != nil { + return nil, fmt.Errorf("failed to resolve source verifier for chain %d: %w", sigConfig.SourceChainSelector, err) + } + + signers := make([]ccvdeployment.Signer, 0, len(sigConfig.Signers)) + for _, addr := range sigConfig.Signers { + signers = append(signers, ccvdeployment.Signer{Address: addr}) + } + + quorumConfigs[chainSelectorStr] = &ccvdeployment.QuorumConfig{ + SourceVerifierAddress: sourceVerifierAddr, + Signers: signers, + Threshold: sigConfig.Threshold, + } + } + } + + return quorumConfigs, nil +} + +func validateSignatureConfigConsistency( + existing *ccvdeployment.QuorumConfig, + newSig adapters.SignatureConfig, + chainSelectorStr string, + committeeQualifier string, +) error { + if existing.Threshold != newSig.Threshold { + return fmt.Errorf( + "committee %q chain %s: conflicting signature config threshold %d vs %d", + committeeQualifier, chainSelectorStr, existing.Threshold, newSig.Threshold, + ) + } + + existingAddrs := make([]string, len(existing.Signers)) + for i, s := range existing.Signers { + existingAddrs[i] = s.Address + } + slices.Sort(existingAddrs) + + newAddrs := slices.Clone(newSig.Signers) + slices.Sort(newAddrs) + + if !slices.Equal(existingAddrs, newAddrs) { + return fmt.Errorf( + "committee %q chain %s: conflicting signers (count %d vs %d)", + committeeQualifier, chainSelectorStr, len(existingAddrs), len(newAddrs), + ) + } + + return nil +} + +func buildDestinationVerifiers( + ds datastore.DataStore, + registry *adapters.AggregatorConfigRegistry, + committeeQualifier string, + destChainSelectors []uint64, +) (map[string]string, error) { + destVerifiers := make(map[string]string, len(destChainSelectors)) + + for _, chainSelector := range destChainSelectors { + adapter, err := registry.GetByChain(chainSelector) + if err != nil { + return nil, err + } + + addr, err := adapter.ResolveVerifierAddress(ds, chainSelector, committeeQualifier) + if err != nil { + return nil, fmt.Errorf("failed to resolve destination verifier for chain %d: %w", chainSelector, err) + } + destVerifiers[strconv.FormatUint(chainSelector, 10)] = addr + } + + return destVerifiers, nil +} diff --git a/deployment/changesets/generate_indexer_config.go b/deployment/changesets/generate_indexer_config.go new file mode 100644 index 000000000..3a1c9326e --- /dev/null +++ b/deployment/changesets/generate_indexer_config.go @@ -0,0 +1,164 @@ +package changesets + +import ( + "errors" + "fmt" + "sort" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" +) + +type GenerateIndexerConfigInput struct { + ServiceIdentifier string + CommitteeVerifierNameToQualifier map[string]string + CCTPVerifierNameToQualifier map[string]string + LombardVerifierNameToQualifier map[string]string +} + +func GenerateIndexerConfig(registry *adapters.IndexerConfigRegistry) deployment.ChangeSetV2[GenerateIndexerConfigInput] { + validate := func(e deployment.Environment, cfg GenerateIndexerConfigInput) error { + if cfg.ServiceIdentifier == "" { + return fmt.Errorf("service identifier is required") + } + if len(cfg.CommitteeVerifierNameToQualifier) == 0 && + len(cfg.CCTPVerifierNameToQualifier) == 0 && + len(cfg.LombardVerifierNameToQualifier) == 0 { + return fmt.Errorf("at least one verifier name to qualifier mapping is required") + } + return nil + } + + apply := func(e deployment.Environment, cfg GenerateIndexerConfigInput) (deployment.ChangesetOutput, error) { + verifierMap, err := buildIndexerVerifierMap(e.DataStore, registry, e.BlockChains.ListChainSelectors(), cfg) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + idxCfg := toIndexerGeneratedConfig(verifierMap) + + outputDS := datastore.NewMemoryDataStore() + if e.DataStore != nil { + if err := outputDS.Merge(e.DataStore); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to merge existing datastore: %w", err) + } + } + + if err := ccvdeployment.SaveIndexerConfig(outputDS, cfg.ServiceIdentifier, idxCfg); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to save indexer config: %w", err) + } + + return deployment.ChangesetOutput{ + DataStore: outputDS, + }, nil + } + + return deployment.CreateChangeSet(apply, validate) +} + +func buildIndexerVerifierMap( + ds datastore.DataStore, + registry *adapters.IndexerConfigRegistry, + selectors []uint64, + cfg GenerateIndexerConfigInput, +) (map[string][]string, error) { + verifierMap := make(map[string][]string) + + kindMappings := []struct { + kind adapters.VerifierKind + nameToQualifier map[string]string + }{ + {adapters.CommitteeVerifierKind, cfg.CommitteeVerifierNameToQualifier}, + {adapters.CCTPVerifierKind, cfg.CCTPVerifierNameToQualifier}, + {adapters.LombardVerifierKind, cfg.LombardVerifierNameToQualifier}, + } + + for _, km := range kindMappings { + for name, qualifier := range km.nameToQualifier { + addresses, err := collectVerifierAddresses(ds, registry, selectors, qualifier, km.kind) + if err != nil { + return nil, fmt.Errorf("failed to resolve addresses for verifier %q (qualifier %q): %w", name, qualifier, err) + } + verifierMap[name] = append(verifierMap[name], addresses...) + } + } + + return verifierMap, nil +} + +func collectVerifierAddresses( + ds datastore.DataStore, + registry *adapters.IndexerConfigRegistry, + selectors []uint64, + qualifier string, + kind adapters.VerifierKind, +) ([]string, error) { + if !registry.HasAdapters() { + return nil, fmt.Errorf("no indexer config adapter registered") + } + + seen := make(map[string]bool) + var addresses []string + + for _, sel := range selectors { + adapter, err := registry.GetByChain(sel) + if err != nil { + return nil, err + } + + addrs, err := adapter.ResolveVerifierAddresses(ds, sel, qualifier, kind) + if err != nil { + var missingErr *adapters.MissingIndexerVerifierAddressesError + if errors.As(err, &missingErr) { + continue + } + return nil, fmt.Errorf("chain %d: %w", sel, err) + } + + for _, addr := range addrs { + if !seen[addr] { + seen[addr] = true + addresses = append(addresses, addr) + } + } + } + + if len(addresses) == 0 { + return nil, fmt.Errorf("no deployed %s verifier addresses found for qualifier %q", kind, qualifier) + } + + return addresses, nil +} + +func toIndexerGeneratedConfig(verifierMap map[string][]string) *ccvdeployment.IndexerGeneratedConfig { + verifiers := make([]ccvdeployment.IndexerVerifierConfig, 0, len(verifierMap)) + + names := make([]string, 0, len(verifierMap)) + for name := range verifierMap { + names = append(names, name) + } + sort.Strings(names) + + for _, name := range names { + addresses := verifierMap[name] + seen := make(map[string]bool) + unique := make([]string, 0, len(addresses)) + for _, addr := range addresses { + if !seen[addr] { + seen[addr] = true + unique = append(unique, addr) + } + } + verifiers = append(verifiers, ccvdeployment.IndexerVerifierConfig{ + Name: name, + IssuerAddresses: unique, + }) + } + + return &ccvdeployment.IndexerGeneratedConfig{ + Verifiers: verifiers, + } +} diff --git a/deployment/changesets/generate_token_verifier_config.go b/deployment/changesets/generate_token_verifier_config.go new file mode 100644 index 000000000..e41835b6c --- /dev/null +++ b/deployment/changesets/generate_token_verifier_config.go @@ -0,0 +1,250 @@ +package changesets + +import ( + "encoding/hex" + "fmt" + "slices" + "strconv" + "time" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +const ( + TestnetCCTPAttestationAPI = "https://iris-api-sandbox.circle.com" + TestnetLombardAttestationAPI = "https://gastald-testnet.prod.lombard.finance/api/" + MainnetCCTPAttestationAPI = "https://iris-api.circle.com" + MainnetLombardAttestationAPI = "https://mainnet.prod.lombard.finance/api/" +) + +var ( + // bytes4(keccak256("CCTPVerifier 2.0.0")) = 0x35a25838 + DefaultCCTPVerifierVersion = mustDecodeHex("35a25838") + // bytes4(keccak256("LombardVerifier 2.0.0")) = 0xeba55588 + DefaultLombardVerifierVersion = mustDecodeHex("eba55588") +) + +func mustDecodeHex(s string) []byte { + b, err := hex.DecodeString(s) + if err != nil { + panic(fmt.Sprintf("failed to decode hex %q: %v", s, err)) + } + return b +} + +type LombardConfigInput struct { + Qualifier string + VerifierID string + VerifierVersion []byte + AttestationAPI string + AttestationAPITimeout time.Duration + AttestationAPIInterval time.Duration + AttestationAPIBatchSize int +} + +type CCTPConfigInput struct { + Qualifier string + VerifierID string + VerifierVersion []byte + AttestationAPI string + AttestationAPITimeout time.Duration + AttestationAPIInterval time.Duration + AttestationAPICooldown time.Duration +} + +type GenerateTokenVerifierConfigInput struct { + ServiceIdentifier string + ChainSelectors []uint64 + PyroscopeURL string + Monitoring shared.MonitoringInput + Lombard LombardConfigInput + CCTP CCTPConfigInput +} + +func GenerateTokenVerifierConfig(registry *adapters.TokenVerifierConfigRegistry) deployment.ChangeSetV2[GenerateTokenVerifierConfigInput] { + validate := func(e deployment.Environment, cfg GenerateTokenVerifierConfigInput) error { + if cfg.ServiceIdentifier == "" { + return fmt.Errorf("service identifier is required") + } + envSelectors := e.BlockChains.ListChainSelectors() + for _, s := range cfg.ChainSelectors { + if !slices.Contains(envSelectors, s) { + return fmt.Errorf("selector %d is not available in environment", s) + } + } + return nil + } + + apply := func(e deployment.Environment, cfg GenerateTokenVerifierConfigInput) (deployment.ChangesetOutput, error) { + selectors := cfg.ChainSelectors + if len(selectors) == 0 { + selectors = e.BlockChains.ListChainSelectors() + } + + isProd := shared.IsProductionEnvironment(e.Name) + lombardCfg := applyLombardDefaults(cfg.Lombard, isProd) + cctpCfg := applyCCTPDefaults(cfg.CCTP, isProd) + + onRampAddresses := make(map[string]string) + rmnRemoteAddresses := make(map[string]string) + cctpVerifierAddresses := make(map[string]string) + cctpVerifierResolverAddresses := make(map[string]string) + lombardVerifierResolverAddresses := make(map[string]string) + + for _, sel := range selectors { + adapter, err := registry.GetByChain(sel) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + addrs, err := adapter.ResolveTokenVerifierAddresses( + e.DataStore, sel, cctpCfg.Qualifier, lombardCfg.Qualifier, + ) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to resolve token verifier addresses for chain %d: %w", sel, err) + } + + chainSelectorStr := strconv.FormatUint(sel, 10) + onRampAddresses[chainSelectorStr] = addrs.OnRampAddress + rmnRemoteAddresses[chainSelectorStr] = addrs.RMNRemoteAddress + + if addrs.CCTPVerifierAddress != "" { + cctpVerifierAddresses[chainSelectorStr] = addrs.CCTPVerifierAddress + cctpVerifierResolverAddresses[chainSelectorStr] = addrs.CCTPVerifierResolverAddress + } + if addrs.LombardVerifierResolverAddress != "" { + lombardVerifierResolverAddresses[chainSelectorStr] = addrs.LombardVerifierResolverAddress + } + } + + config := &ccvdeployment.TokenVerifierGeneratedConfig{ + PyroscopeURL: cfg.PyroscopeURL, + OnRampAddresses: onRampAddresses, + RMNRemoteAddresses: rmnRemoteAddresses, + TokenVerifiers: []ccvdeployment.TokenVerifierEntry{}, + Monitoring: ccvdeployment.TokenVerifierMonitoringConfig{ + Enabled: cfg.Monitoring.Enabled, + Type: cfg.Monitoring.Type, + Beholder: ccvdeployment.TokenVerifierBeholderConfig{ + InsecureConnection: cfg.Monitoring.Beholder.InsecureConnection, + CACertFile: cfg.Monitoring.Beholder.CACertFile, + OtelExporterGRPCEndpoint: cfg.Monitoring.Beholder.OtelExporterGRPCEndpoint, + OtelExporterHTTPEndpoint: cfg.Monitoring.Beholder.OtelExporterHTTPEndpoint, + LogStreamingEnabled: cfg.Monitoring.Beholder.LogStreamingEnabled, + MetricReaderInterval: cfg.Monitoring.Beholder.MetricReaderInterval, + TraceSampleRatio: cfg.Monitoring.Beholder.TraceSampleRatio, + TraceBatchTimeout: cfg.Monitoring.Beholder.TraceBatchTimeout, + }, + }, + } + + if len(cctpVerifierAddresses) > 0 { + cctpVerifierID := cctpCfg.VerifierID + if cctpVerifierID == "" { + cctpVerifierID = fmt.Sprintf("cctp-%s", cctpCfg.Qualifier) + } + config.TokenVerifiers = append(config.TokenVerifiers, ccvdeployment.TokenVerifierEntry{ + VerifierID: cctpVerifierID, + Type: "cctp", + Version: "2.0", + CCTP: &ccvdeployment.CCTPVerifierConfig{ + AttestationAPI: cctpCfg.AttestationAPI, + AttestationAPITimeout: cctpCfg.AttestationAPITimeout, + AttestationAPIInterval: cctpCfg.AttestationAPIInterval, + AttestationAPICooldown: cctpCfg.AttestationAPICooldown, + VerifierVersion: cctpCfg.VerifierVersion, + Verifiers: cctpVerifierAddresses, + VerifierResolvers: cctpVerifierResolverAddresses, + }, + }) + } + + if len(lombardVerifierResolverAddresses) > 0 { + lombardVerifierID := lombardCfg.VerifierID + if lombardVerifierID == "" { + lombardVerifierID = fmt.Sprintf("lombard-%s", lombardCfg.Qualifier) + } + config.TokenVerifiers = append(config.TokenVerifiers, ccvdeployment.TokenVerifierEntry{ + VerifierID: lombardVerifierID, + Type: "lombard", + Version: "1.0", + Lombard: &ccvdeployment.LombardVerifierConfig{ + AttestationAPI: lombardCfg.AttestationAPI, + AttestationAPITimeout: lombardCfg.AttestationAPITimeout, + AttestationAPIInterval: lombardCfg.AttestationAPIInterval, + AttestationAPIBatchSize: lombardCfg.AttestationAPIBatchSize, + VerifierVersion: lombardCfg.VerifierVersion, + VerifierResolvers: lombardVerifierResolverAddresses, + }, + }) + } + + outputDS := datastore.NewMemoryDataStore() + if e.DataStore != nil { + if err := outputDS.Merge(e.DataStore); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to merge existing datastore: %w", err) + } + } + + if err := ccvdeployment.SaveTokenVerifierConfig(outputDS, cfg.ServiceIdentifier, config); err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to save token verifier config: %w", err) + } + + return deployment.ChangesetOutput{ + DataStore: outputDS, + }, nil + } + + return deployment.CreateChangeSet(apply, validate) +} + +func applyLombardDefaults(cfg LombardConfigInput, isProd bool) LombardConfigInput { + if cfg.AttestationAPI == "" { + if isProd { + cfg.AttestationAPI = MainnetLombardAttestationAPI + } else { + cfg.AttestationAPI = TestnetLombardAttestationAPI + } + } + if cfg.AttestationAPITimeout == 0 { + cfg.AttestationAPITimeout = 1 * time.Second + } + if cfg.AttestationAPIInterval == 0 { + cfg.AttestationAPIInterval = 100 * time.Millisecond + } + if cfg.AttestationAPIBatchSize == 0 { + cfg.AttestationAPIBatchSize = 20 + } + if len(cfg.VerifierVersion) == 0 { + cfg.VerifierVersion = DefaultLombardVerifierVersion + } + return cfg +} + +func applyCCTPDefaults(cfg CCTPConfigInput, isProd bool) CCTPConfigInput { + if cfg.AttestationAPI == "" { + if isProd { + cfg.AttestationAPI = MainnetCCTPAttestationAPI + } else { + cfg.AttestationAPI = TestnetCCTPAttestationAPI + } + } + if cfg.AttestationAPITimeout == 0 { + cfg.AttestationAPITimeout = 1 * time.Second + } + if cfg.AttestationAPIInterval == 0 { + cfg.AttestationAPIInterval = 100 * time.Millisecond + } + if cfg.AttestationAPICooldown == 0 { + cfg.AttestationAPICooldown = 5 * time.Minute + } + if len(cfg.VerifierVersion) == 0 { + cfg.VerifierVersion = DefaultCCTPVerifierVersion + } + return cfg +} diff --git a/deployment/changesets/sync_job_proposals.go b/deployment/changesets/sync_job_proposals.go new file mode 100644 index 000000000..177ce0db9 --- /dev/null +++ b/deployment/changesets/sync_job_proposals.go @@ -0,0 +1,60 @@ +package changesets + +import ( + "fmt" + + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-deployments-framework/operations" + + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" + syncjobproposals "github.com/smartcontractkit/chainlink-ccv/deployment/operations/sync_job_proposals" +) + +type SyncJobProposalsInput struct { + NOPAliases []shared.NOPAlias +} + +func SyncJobProposals() deployment.ChangeSetV2[SyncJobProposalsInput] { + validate := func(e deployment.Environment, cfg SyncJobProposalsInput) error { + if e.Offchain == nil { + return fmt.Errorf("offchain client (JD) is required for syncing job proposals") + } + return nil + } + + apply := func(e deployment.Environment, cfg SyncJobProposalsInput) (deployment.ChangesetOutput, error) { + report, err := operations.ExecuteOperation( + e.OperationsBundle, + syncjobproposals.SyncJobProposals, + syncjobproposals.SyncJobProposalsDeps{Env: e}, + syncjobproposals.SyncJobProposalsInput{NOPAliases: cfg.NOPAliases}, + ) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to sync job proposals: %w", err) + } + + e.Logger.Infow("Job proposals synced", + "statusChanges", len(report.Output.StatusChanges), + "specDrifts", len(report.Output.SpecDrifts), + "errors", len(report.Output.Errors)) + + if len(report.Output.SpecDrifts) > 0 { + e.Logger.Warnw("Spec drift detected between local and JD", + "driftCount", len(report.Output.SpecDrifts)) + for _, drift := range report.Output.SpecDrifts { + e.Logger.Warnw("Spec drift detail", + "nopAlias", drift.NOPAlias, + "jobId", drift.JobID, + "localSpec", drift.LocalSpec, + "jdSpec", drift.JDSpec, + ) + } + } + + return deployment.ChangesetOutput{ + DataStore: report.Output.DataStore, + }, nil + } + + return deployment.CreateChangeSet(apply, validate) +} diff --git a/deployment/env_metadata_util.go b/deployment/env_metadata_util.go new file mode 100644 index 000000000..0fb425161 --- /dev/null +++ b/deployment/env_metadata_util.go @@ -0,0 +1,408 @@ +package deployment + +import ( + "encoding/json" + "errors" + "fmt" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +type OffchainConfigs struct { + Aggregators map[string]*Committee `json:"aggregators,omitempty"` + Indexers map[string]*IndexerGeneratedConfig `json:"indexers,omitempty"` + TokenVerifiers map[string]*TokenVerifierGeneratedConfig `json:"tokenVerifiers,omitempty"` + NOPJobs shared.NOPJobs `json:"nopJobs,omitempty"` +} + +type CCVEnvMetadata struct { + OffchainConfigs *OffchainConfigs `json:"offchainConfigs,omitempty"` +} + +func SaveAggregatorConfig(ds datastore.MutableDataStore, serviceIdentifier string, cfg *Committee) error { + ccvMeta, err := loadOrCreateCCVEnvMetadata(ds) + if err != nil { + return err + } + + if ccvMeta.OffchainConfigs == nil { + ccvMeta.OffchainConfigs = &OffchainConfigs{} + } + if ccvMeta.OffchainConfigs.Aggregators == nil { + ccvMeta.OffchainConfigs.Aggregators = make(map[string]*Committee) + } + + ccvMeta.OffchainConfigs.Aggregators[serviceIdentifier] = cfg + + return persistCCVEnvMetadata(ds, ccvMeta) +} + +func GetAggregatorConfig(ds datastore.DataStore, serviceIdentifier string) (*Committee, error) { + ccvMeta, err := loadCCVEnvMetadata(ds) + if err != nil { + return nil, err + } + + if ccvMeta.OffchainConfigs == nil || ccvMeta.OffchainConfigs.Aggregators == nil { + return nil, fmt.Errorf("no aggregator configs found") + } + + cfg, ok := ccvMeta.OffchainConfigs.Aggregators[serviceIdentifier] + if !ok { + return nil, fmt.Errorf("aggregator config %q not found", serviceIdentifier) + } + + return cfg, nil +} + +func SaveIndexerConfig(ds datastore.MutableDataStore, serviceIdentifier string, cfg *IndexerGeneratedConfig) error { + ccvMeta, err := loadOrCreateCCVEnvMetadata(ds) + if err != nil { + return err + } + + if ccvMeta.OffchainConfigs == nil { + ccvMeta.OffchainConfigs = &OffchainConfigs{} + } + if ccvMeta.OffchainConfigs.Indexers == nil { + ccvMeta.OffchainConfigs.Indexers = make(map[string]*IndexerGeneratedConfig) + } + + ccvMeta.OffchainConfigs.Indexers[serviceIdentifier] = cfg + + return persistCCVEnvMetadata(ds, ccvMeta) +} + +func GetIndexerConfig(ds datastore.DataStore, serviceIdentifier string) (*IndexerGeneratedConfig, error) { + ccvMeta, err := loadCCVEnvMetadata(ds) + if err != nil { + return nil, err + } + + if ccvMeta.OffchainConfigs == nil || ccvMeta.OffchainConfigs.Indexers == nil { + return nil, fmt.Errorf("no indexer configs found") + } + + cfg, ok := ccvMeta.OffchainConfigs.Indexers[serviceIdentifier] + if !ok { + return nil, fmt.Errorf("indexer config %q not found", serviceIdentifier) + } + + return cfg, nil +} + +func SaveTokenVerifierConfig(ds datastore.MutableDataStore, serviceIdentifier string, cfg *TokenVerifierGeneratedConfig) error { + ccvMeta, err := loadOrCreateCCVEnvMetadata(ds) + if err != nil { + return err + } + + if ccvMeta.OffchainConfigs == nil { + ccvMeta.OffchainConfigs = &OffchainConfigs{} + } + if ccvMeta.OffchainConfigs.TokenVerifiers == nil { + ccvMeta.OffchainConfigs.TokenVerifiers = make(map[string]*TokenVerifierGeneratedConfig) + } + + ccvMeta.OffchainConfigs.TokenVerifiers[serviceIdentifier] = cfg + + return persistCCVEnvMetadata(ds, ccvMeta) +} + +func GetTokenVerifierConfig(ds datastore.DataStore, serviceIdentifier string) (*TokenVerifierGeneratedConfig, error) { + ccvMeta, err := loadCCVEnvMetadata(ds) + if err != nil { + return nil, err + } + + if ccvMeta.OffchainConfigs == nil || ccvMeta.OffchainConfigs.TokenVerifiers == nil { + return nil, fmt.Errorf("no token verifier configs found") + } + + cfg, ok := ccvMeta.OffchainConfigs.TokenVerifiers[serviceIdentifier] + if !ok { + return nil, fmt.Errorf("token verifier config %q not found", serviceIdentifier) + } + + return cfg, nil +} + +func loadCCVEnvMetadata(ds datastore.DataStore) (*CCVEnvMetadata, error) { + envMeta, err := ds.EnvMetadata().Get() + if err != nil { + return nil, fmt.Errorf("failed to get env metadata: %w", err) + } + return parseCCVEnvMetadata(envMeta.Metadata) +} + +func loadOrCreateCCVEnvMetadata(ds datastore.MutableDataStore) (*CCVEnvMetadata, error) { + envMeta, err := ds.EnvMetadata().Get() + if err != nil { + if errors.Is(err, datastore.ErrEnvMetadataNotSet) { + return &CCVEnvMetadata{}, nil + } + return nil, fmt.Errorf("failed to get env metadata: %w", err) + } + return parseCCVEnvMetadata(envMeta.Metadata) +} + +func parseCCVEnvMetadata(metadata any) (*CCVEnvMetadata, error) { + if metadata == nil { + return &CCVEnvMetadata{}, nil + } + + data, err := json.Marshal(metadata) + if err != nil { + return nil, fmt.Errorf("failed to marshal env metadata: %w", err) + } + + var ccvMeta CCVEnvMetadata + if err := json.Unmarshal(data, &ccvMeta); err != nil { + return nil, fmt.Errorf("failed to unmarshal CCV env metadata: %w", err) + } + + return &ccvMeta, nil +} + +// persistCCVEnvMetadata persists CCV metadata using shallow merge at the +// offchainConfigs level. Known offchainConfigs keys (aggregators, indexers, +// tokenVerifiers, nopJobs) are replaced fully — removing stale nested entries +// when chains or jobs are removed. Unknown sibling keys under offchainConfigs +// and non-CCV top-level keys are preserved. +func persistCCVEnvMetadata(ds datastore.MutableDataStore, ccvMeta *CCVEnvMetadata) error { + var existingMeta map[string]any + envMeta, err := ds.EnvMetadata().Get() + if err != nil { + if !errors.Is(err, datastore.ErrEnvMetadataNotSet) { + return fmt.Errorf("failed to get env metadata: %w", err) + } + existingMeta = make(map[string]any) + } else if envMeta.Metadata != nil { + data, err := json.Marshal(envMeta.Metadata) + if err != nil { + return fmt.Errorf("failed to marshal existing env metadata: %w", err) + } + if err := json.Unmarshal(data, &existingMeta); err != nil { + return fmt.Errorf("failed to unmarshal existing env metadata: %w", err) + } + } else { + existingMeta = make(map[string]any) + } + + if ccvMeta.OffchainConfigs != nil { + existingOC, ok := existingMeta["offchainConfigs"].(map[string]any) + if !ok { + existingOC = make(map[string]any) + } + + oc := ccvMeta.OffchainConfigs + if oc.Aggregators != nil { + v, err := marshalToAny(oc.Aggregators) + if err != nil { + return fmt.Errorf("failed to convert aggregators: %w", err) + } + existingOC["aggregators"] = v + } + if oc.Indexers != nil { + v, err := marshalToAny(oc.Indexers) + if err != nil { + return fmt.Errorf("failed to convert indexers: %w", err) + } + existingOC["indexers"] = v + } + if oc.TokenVerifiers != nil { + v, err := marshalToAny(oc.TokenVerifiers) + if err != nil { + return fmt.Errorf("failed to convert token verifiers: %w", err) + } + existingOC["tokenVerifiers"] = v + } + if oc.NOPJobs != nil { + v, err := marshalToAny(oc.NOPJobs) + if err != nil { + return fmt.Errorf("failed to convert NOP jobs: %w", err) + } + existingOC["nopJobs"] = v + } + + existingMeta["offchainConfigs"] = existingOC + } + + return ds.EnvMetadata().Set(datastore.EnvMetadata{Metadata: existingMeta}) +} + +func marshalToAny(v any) (any, error) { + data, err := json.Marshal(v) + if err != nil { + return nil, fmt.Errorf("failed to marshal value: %w", err) + } + var result any + if err := json.Unmarshal(data, &result); err != nil { + return nil, fmt.Errorf("failed to unmarshal value: %w", err) + } + return result, nil +} + +func SaveJob(ds datastore.MutableDataStore, job shared.JobInfo) error { + ccvMeta, err := loadOrCreateCCVEnvMetadata(ds) + if err != nil { + return err + } + + if ccvMeta.OffchainConfigs == nil { + ccvMeta.OffchainConfigs = &OffchainConfigs{} + } + if ccvMeta.OffchainConfigs.NOPJobs == nil { + ccvMeta.OffchainConfigs.NOPJobs = make(shared.NOPJobs) + } + if ccvMeta.OffchainConfigs.NOPJobs[job.NOPAlias] == nil { + ccvMeta.OffchainConfigs.NOPJobs[job.NOPAlias] = make(map[shared.JobID]shared.JobInfo) + } + + ccvMeta.OffchainConfigs.NOPJobs[job.NOPAlias][job.JobID] = job + + return persistCCVEnvMetadata(ds, ccvMeta) +} + +func SaveJobs(ds datastore.MutableDataStore, jobs []shared.JobInfo) error { + if len(jobs) == 0 { + return nil + } + + ccvMeta, err := loadOrCreateCCVEnvMetadata(ds) + if err != nil { + return err + } + + if ccvMeta.OffchainConfigs == nil { + ccvMeta.OffchainConfigs = &OffchainConfigs{} + } + if ccvMeta.OffchainConfigs.NOPJobs == nil { + ccvMeta.OffchainConfigs.NOPJobs = make(shared.NOPJobs) + } + + for _, job := range jobs { + if ccvMeta.OffchainConfigs.NOPJobs[job.NOPAlias] == nil { + ccvMeta.OffchainConfigs.NOPJobs[job.NOPAlias] = make(map[shared.JobID]shared.JobInfo) + } + ccvMeta.OffchainConfigs.NOPJobs[job.NOPAlias][job.JobID] = job + } + + return persistCCVEnvMetadata(ds, ccvMeta) +} + +func GetAllJobs(ds datastore.DataStore) (shared.NOPJobs, error) { + ccvMeta, err := loadCCVEnvMetadata(ds) + if err != nil { + return nil, err + } + + if ccvMeta.OffchainConfigs == nil || ccvMeta.OffchainConfigs.NOPJobs == nil { + return make(shared.NOPJobs), nil + } + + return ccvMeta.OffchainConfigs.NOPJobs, nil +} + +func GetJob(ds datastore.DataStore, nopAlias shared.NOPAlias, jobID shared.JobID) (*shared.JobInfo, error) { + ccvMeta, err := loadCCVEnvMetadata(ds) + if err != nil { + return nil, err + } + + if ccvMeta.OffchainConfigs == nil || ccvMeta.OffchainConfigs.NOPJobs == nil { + return nil, fmt.Errorf("no jobs found") + } + + nopJobs, ok := ccvMeta.OffchainConfigs.NOPJobs[nopAlias] + if !ok { + return nil, fmt.Errorf("no jobs found for NOP %q", nopAlias) + } + + job, ok := nopJobs[jobID] + if !ok { + return nil, fmt.Errorf("job %q not found for NOP %q", jobID, nopAlias) + } + + return &job, nil +} + +func DeleteJob(ds datastore.MutableDataStore, nopAlias shared.NOPAlias, jobID shared.JobID) error { + ccvMeta, err := loadOrCreateCCVEnvMetadata(ds) + if err != nil { + return err + } + + if ccvMeta.OffchainConfigs == nil || ccvMeta.OffchainConfigs.NOPJobs == nil { + return nil + } + + nopJobs, ok := ccvMeta.OffchainConfigs.NOPJobs[nopAlias] + if !ok { + return nil + } + + if _, ok := nopJobs[jobID]; !ok { + return nil + } + + delete(ccvMeta.OffchainConfigs.NOPJobs[nopAlias], jobID) + + if len(ccvMeta.OffchainConfigs.NOPJobs[nopAlias]) == 0 { + delete(ccvMeta.OffchainConfigs.NOPJobs, nopAlias) + } + + return persistCCVEnvMetadata(ds, ccvMeta) +} + +func CollectOrphanedJobs( + ds datastore.DataStore, + scope shared.JobScope, + expectedJobsByNOP map[shared.NOPAlias]map[shared.JobID]bool, + scopedNOPs map[shared.NOPAlias]bool, + environmentNOPs map[shared.NOPAlias]bool, +) ([]shared.JobInfo, error) { + allJobs, err := GetAllJobs(ds) + if err != nil { + return nil, fmt.Errorf("failed to get all jobs for cleanup: %w", err) + } + + orphaned := make([]shared.JobInfo, 0) + for nopAlias, nopJobs := range allJobs { + if scopedNOPs != nil && !scopedNOPs[nopAlias] { + continue + } + + for jobID, job := range nopJobs { + if !scope.IsJobInScope(jobID) { + continue + } + + nopExpectedJobs := expectedJobsByNOP[nopAlias] + shouldRevoke := nopExpectedJobs == nil || !nopExpectedJobs[jobID] + if environmentNOPs != nil && !environmentNOPs[nopAlias] { + shouldRevoke = true + } + + if shouldRevoke { + orphaned = append(orphaned, job) + } + } + } + + return orphaned, nil +} + +func CleanupOrphanedJobs( + ds datastore.MutableDataStore, + jobs []shared.JobInfo, +) error { + for _, job := range jobs { + if err := DeleteJob(ds, job.NOPAlias, job.JobID); err != nil { + return fmt.Errorf("failed to delete job %q for NOP %q: %w", job.JobID, job.NOPAlias, err) + } + } + return nil +} diff --git a/deployment/go.mod b/deployment/go.mod new file mode 100644 index 000000000..dea1e8731 --- /dev/null +++ b/deployment/go.mod @@ -0,0 +1,219 @@ +module github.com/smartcontractkit/chainlink-ccv/deployment + +go 1.25.7 + +replace ( + github.com/fbsobreira/gotron-sdk => github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.4 + github.com/smartcontractkit/chainlink-ccv => .. +) + +require ( + github.com/BurntSushi/toml v1.5.0 + github.com/Masterminds/semver/v3 v3.4.0 + github.com/google/uuid v1.6.0 + github.com/smartcontractkit/chain-selectors v1.0.98 + github.com/smartcontractkit/chainlink-ccv v0.0.0 + github.com/smartcontractkit/chainlink-common v0.11.2-0.20260407150650-8115835abd6e + github.com/smartcontractkit/chainlink-deployments-framework v0.94.1 + github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 + google.golang.org/grpc v1.80.0 +) + +require ( + filippo.io/edwards25519 v1.1.1 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect + github.com/XSAM/otelsql v0.37.0 // indirect + github.com/aptos-labs/aptos-go-sdk v1.12.0 // indirect + github.com/avast/retry-go/v4 v4.7.0 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bits-and-blooms/bitset v1.24.0 // indirect + github.com/blendle/zapdriver v1.3.1 // indirect + github.com/block-vision/sui-go-sdk v1.1.4 // indirect + github.com/btcsuite/btcd v0.24.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/btcsuite/btcd/btcutil v1.1.6 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/btcsuite/btcutil v1.0.2 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.2 // indirect + github.com/cloudevents/sdk-go/v2 v2.16.2 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/coder/websocket v1.8.14 // indirect + github.com/consensys/gnark-crypto v0.19.2 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect + github.com/creachadair/jrpc2 v1.2.0 // indirect + github.com/creachadair/mds v0.13.4 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deckarep/golang-set/v2 v2.8.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect + github.com/digital-asset/dazl-client/v8 v8.9.0 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.6 // indirect + github.com/ethereum/go-ethereum v1.17.1 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/fbsobreira/gotron-sdk v0.0.0-20250403083053-2943ce8c759b // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.13 // indirect + github.com/gagliardetto/binary v0.8.0 // indirect + github.com/gagliardetto/solana-go v1.13.0 // indirect + github.com/gagliardetto/treeout v0.1.4 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.10.1 // indirect + github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.30.1 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/grafana/otel-profiling-go v0.5.1 // indirect + github.com/grafana/pyroscope-go v1.2.8 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect + github.com/hashicorp/go-plugin v1.7.0 // indirect + github.com/hashicorp/yamux v0.1.2 // indirect + github.com/hasura/go-graphql-client v0.15.1 // indirect + github.com/hdevalence/ed25519consensus v0.2.0 // indirect + github.com/holiman/uint256 v1.3.2 // indirect + github.com/invopop/jsonschema v0.13.0 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgconn v1.14.3 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.3.3 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgtype v1.14.4 // indirect + github.com/jackc/pgx/v4 v4.18.3 // indirect + github.com/jinzhu/copier v0.4.0 // indirect + github.com/jmoiron/sqlx v1.4.0 // indirect + github.com/jpillora/backoff v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 // indirect + github.com/klauspost/compress v1.18.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/lib/pq v1.11.1 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/mailru/easyjson v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mfridman/interpolate v0.0.2 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oklog/run v1.2.0 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/pressly/goose/v3 v3.26.0 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/samber/lo v1.52.0 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect + github.com/scylladb/go-reflectx v1.0.1 // indirect + github.com/sethvargo/go-retry v0.3.0 // indirect + github.com/shirou/gopsutil v3.21.11+incompatible // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 // indirect + github.com/smartcontractkit/chainlink-aptos v0.0.0-20260306142855-8d629e752265 // indirect + github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d // indirect + github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 // indirect + github.com/smartcontractkit/chainlink-common/keystore v1.0.2 // indirect + github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect + github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d // indirect + github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f // indirect + github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b // indirect + github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260211172625-dff40e83b3c9 // indirect + github.com/smartcontractkit/chainlink-sui v0.0.0-20260205175622-33e65031f9a9 // indirect + github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 // indirect + github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250908203554-5bd9d2fe9513 // indirect + github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad // indirect + github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect + github.com/smartcontractkit/libocr v0.0.0-20260304194147-a03701e2c02e // indirect + github.com/smartcontractkit/mcms v0.40.1 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/stellar/go-stellar-sdk v0.1.0 // indirect + github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2 // indirect + github.com/stephenlacy/go-ethereum-hdwallet v0.0.0-20230913225845-a4fa94429863 // indirect + github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/testify v1.11.1 // indirect + github.com/supranational/blst v0.3.16 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/valyala/fastjson v1.6.10 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect + github.com/x448/float16 v0.8.4 // indirect + github.com/xssnick/tonutils-go v1.14.1 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect + github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6 // indirect + go.mongodb.org/mongo-driver v1.17.2 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 // indirect + go.opentelemetry.io/otel/log v0.15.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/sdk v1.43.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/ratelimit v0.3.1 // indirect + go.uber.org/zap v1.27.1 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect + golang.org/x/net v0.50.0 // indirect + golang.org/x/oauth2 v0.35.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/time v0.14.0 // indirect + golang.org/x/tools v0.42.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/deployment/go.sum b/deployment/go.sum new file mode 100644 index 000000000..52cb59c46 --- /dev/null +++ b/deployment/go.sum @@ -0,0 +1,1160 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= +dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= +github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/DataDog/zstd v1.5.6 h1:LbEglqepa/ipmmQJUDnSsfvA8e8IStVcGaFWDuxvGOY= +github.com/DataDog/zstd v1.5.6/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI= +github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0= +github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU= +github.com/XSAM/otelsql v0.37.0 h1:ya5RNw028JW0eJW8Ma4AmoKxAYsJSGuNVbC7F1J457A= +github.com/XSAM/otelsql v0.37.0/go.mod h1:LHbCu49iU8p255nCn1oi04oX2UjSoRcUMiKEHo2a5qM= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/apache/arrow-go/v18 v18.3.1 h1:oYZT8FqONiK74JhlH3WKVv+2NKYoyZ7C2ioD4Dj3ixk= +github.com/apache/arrow-go/v18 v18.3.1/go.mod h1:12QBya5JZT6PnBihi5NJTzbACrDGXYkrgjujz3MRQXU= +github.com/aptos-labs/aptos-go-sdk v1.12.0 h1:deHZ7NJlFhHm2i+eaPHt6EPa3BuXXnIYx2X5J3/U0Es= +github.com/aptos-labs/aptos-go-sdk v1.12.0/go.mod h1:FTgKp0RLfEefllCdkCj0jPU14xWk11yA7SFVfCDLUj8= +github.com/avast/retry-go/v4 v4.7.0 h1:yjDs35SlGvKwRNSykujfjdMxMhMQQM0TnIjJaHB+Zio= +github.com/avast/retry-go/v4 v4.7.0/go.mod h1:ZMPDa3sY2bKgpLtap9JRUgk2yTAba7cgiFhqxY2Sg6Q= +github.com/aws/aws-sdk-go-v2 v1.41.4 h1:10f50G7WyU02T56ox1wWXq+zTX9I1zxG46HYuG1hH/k= +github.com/aws/aws-sdk-go-v2 v1.41.4/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= +github.com/aws/aws-sdk-go-v2/config v1.32.12 h1:O3csC7HUGn2895eNrLytOJQdoL2xyJy0iYXhoZ1OmP0= +github.com/aws/aws-sdk-go-v2/config v1.32.12/go.mod h1:96zTvoOFR4FURjI+/5wY1vc1ABceROO4lWgWJuxgy0g= +github.com/aws/aws-sdk-go-v2/credentials v1.19.12 h1:oqtA6v+y5fZg//tcTWahyN9PEn5eDU/Wpvc2+kJ4aY8= +github.com/aws/aws-sdk-go-v2/credentials v1.19.12/go.mod h1:U3R1RtSHx6NB0DvEQFGyf/0sbrpJrluENHdPy1j/3TE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 h1:zOgq3uezl5nznfoK3ODuqbhVg1JzAGDUhXOsU0IDCAo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20/go.mod h1:z/MVwUARehy6GAg/yQ1GO2IMl0k++cu1ohP9zo887wE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 h1:CNXO7mvgThFGqOFgbNAP2nol2qAWBOGfqR/7tQlvLmc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20/go.mod h1:oydPDJKcfMhgfcgBUZaG+toBbwy8yPWubJXBVERtI4o= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 h1:tN6W/hg+pkM+tf9XDkWUbDEjGLb+raoBMFsTodcoYKw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20/go.mod h1:YJ898MhD067hSHA6xYCx5ts/jEd8BSOLtQDL3iZsvbc= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 h1:2HvVAIq+YqgGotK6EkMf+KIEqTISmTYh5zLpYyeTo1Y= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20/go.mod h1:V4X406Y666khGa8ghKmphma/7C0DAtEQYhkq9z4vpbk= +github.com/aws/aws-sdk-go-v2/service/kms v1.50.1 h1:wb/PYYm3wlcqGzw7Ls4GD3X5+seDDoNdVYIB6I/V87E= +github.com/aws/aws-sdk-go-v2/service/kms v1.50.1/go.mod h1:xvHowJ6J9CuaFE04S8fitWQXytf4sHz3DTPGhw9FtmU= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.8 h1:0GFOLzEbOyZABS3PhYfBIx2rNBACYcKty+XGkTgw1ow= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.8/go.mod h1:LXypKvk85AROkKhOG6/YEcHFPoX+prKTowKnVdcaIxE= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.13 h1:kiIDLZ005EcKomYYITtfsjn7dtOwHDOFy7IbPXKek2o= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.13/go.mod h1:2h/xGEowcW/g38g06g3KpRWDlT+OTfxxI0o1KqayAB8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 h1:jzKAXIlhZhJbnYwHbvUQZEB8KfgAEuG0dc08Bkda7NU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17/go.mod h1:Al9fFsXjv4KfbzQHGe6V4NZSZQXecFcvaIF4e70FoRA= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 h1:Cng+OOwCHmFljXIxpEVXAGMnBia8MSU6Ch5i9PgBkcU= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.9/go.mod h1:LrlIndBDdjA/EeXeyNBle+gyCwTlizzW5ycgWnvIxkk= +github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= +github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.24.0 h1:H4x4TuulnokZKvHLfzVRTHJfFfnHEeSYJizujEZvmAM= +github.com/bits-and-blooms/bitset v1.24.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= +github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/block-vision/sui-go-sdk v1.1.4 h1:1PPgYxQjo1P9UCgFOPTvDCuGEglRL32NwjKPulR4FQk= +github.com/block-vision/sui-go-sdk v1.1.4/go.mod h1:t8mWASwfyv+EyqHGO9ZrcDiCJWGOFEXqq50TMJ8GQco= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= +github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= +github.com/btcsuite/btcd v0.24.2 h1:aLmxPguqxza+4ag8R1I2nnJjSu2iFn/kqtHTIImswcY= +github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg= +github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= +github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= +github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= +github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.2 h1:ydUjnKn4RoCeN8rge3F/deT52w2WJMmIC5mHNUq+Ut8= +github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.2/go.mod h1:Bny999RuVUtNjzTGa9HCHpXjrLGMipJVq5kqVpudBl0= +github.com/cloudevents/sdk-go/v2 v2.16.2 h1:ZYDFrYke4FD+jM8TZTJJO6JhKHzOQl2oqpFK1D+NnQM= +github.com/cloudevents/sdk-go/v2 v2.16.2/go.mod h1:laOcGImm4nVJEU+PHnUrKL56CKmRL65RlQF0kRmW/kg= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 h1:pU88SPhIFid6/k0egdR5V6eALQYq2qbSmukrkgIh/0A= +github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= +github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= +github.com/consensys/gnark-crypto v0.19.2 h1:qrEAIXq3T4egxqiliFFoNrepkIWVEeIYwt3UL0fvS80= +github.com/consensys/gnark-crypto v0.19.2/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0= +github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= +github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6acgLGv/QzE4= +github.com/containerd/platforms v1.0.0-rc.2/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= +github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= +github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg= +github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/creachadair/jrpc2 v1.2.0 h1:SXr0OgnwM0X18P+HccJP0uT3KGSDk/BCSRlJBvE2bMY= +github.com/creachadair/jrpc2 v1.2.0/go.mod h1:66uKSdr6tR5ZeNvkIjDSbbVUtOv0UhjS/vcd8ECP7Iw= +github.com/creachadair/mds v0.13.4 h1:RgU0MhiVqkzp6/xtNWhK6Pw7tDeaVuGFtA0UA2RBYvY= +github.com/creachadair/mds v0.13.4/go.mod h1:4vrFYUzTXMJpMBU+OA292I6IUxKWCCfZkgXg+/kBZMo= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= +github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= +github.com/cucumber/godog v0.15.1 h1:rb/6oHDdvVZKS66hrhpjFQFHjthFSrQBCOI1LwshNTI= +github.com/cucumber/godog v0.15.1/go.mod h1:qju+SQDewOljHuq9NSM66s0xEhogx0q30flfxL4WUk8= +github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= +github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA= +github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc= +github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ= +github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= +github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/digital-asset/dazl-client/v8 v8.9.0 h1:F2qTUWtHAjhGyRGV+xTim+VAFwM99FpcOx4+wowvPnY= +github.com/digital-asset/dazl-client/v8 v8.9.0/go.mod h1:q1KevCJ8FpH8je2MnnjN8/QUfhstB4fKpyKyqDtqFh0= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= +github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= +github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ethereum/c-kzg-4844/v2 v2.1.6 h1:xQymkKCT5E2Jiaoqf3v4wsNgjZLY0lRSkZn27fRjSls= +github.com/ethereum/c-kzg-4844/v2 v2.1.6/go.mod h1:8HMkUZ5JRv4hpw/XUrYWSQNAUzhHMg2UDb/U+5m+XNw= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8= +github.com/ethereum/go-ethereum v1.17.1 h1:IjlQDjgxg2uL+GzPRkygGULPMLzcYWncEI7wbaizvho= +github.com/ethereum/go-ethereum v1.17.1/go.mod h1:7UWOVHL7K3b8RfVRea022btnzLCaanwHtBuH1jUCH/I= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= +github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM= +github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= +github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= +github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= +github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= +github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= +github.com/gagliardetto/solana-go v1.13.0 h1:uNzhjwdAdbq9xMaX2DF0MwXNMw6f8zdZ7JPBtkJG7Ig= +github.com/gagliardetto/solana-go v1.13.0/go.mod h1:l/qqqIN6qJJPtxW/G1PF4JtcE3Zg2vD2EliZrr9Gn5k= +github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= +github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= +github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w= +github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= +github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= +github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= +github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8= +github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls= +github.com/grafana/pyroscope-go v1.2.8 h1:UvCwIhlx9DeV7F6TW/z8q1Mi4PIm3vuUJ2ZlCEvmA4M= +github.com/grafana/pyroscope-go v1.2.8/go.mod h1:SSi59eQ1/zmKoY/BKwa5rSFsJaq+242Bcrr4wPix1g8= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= +github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMNMPSVXA1yc= +github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.5 h1:b3taDMxCBCBVgyRrS1AZVHO14ubMYZB++QpNhBg+Nyo= +github.com/hashicorp/go-memdb v1.3.5/go.mod h1:8IVKKBkVe+fxFgdFOYxzQQNjz+sWCyHCdIC/+5+Vy1Y= +github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= +github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= +github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= +github.com/hasura/go-graphql-client v0.15.1 h1:mCb5I+8Bk3FU3GKWvf/zDXkTh7FbGlqJmP3oisBdnN8= +github.com/hasura/go-graphql-client v0.15.1/go.mod h1:jfSZtBER3or+88Q9vFhWHiFMPppfYILRyl+0zsgPIIw= +github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= +github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= +github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSHzRbhzK8RdXOsAdfDgO49TtqC1oZ+acxPrkfTxcCs= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsDSy7TDxedi9gyBkMvAirat/oRcL0lFdJBf6tdM= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= +github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= +github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.14.4 h1:fKuNiCumbKTAIxQwXfB/nsrnkEI6bPJrrSiMKgbJ2j8= +github.com/jackc/pgtype v1.14.4/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= +github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA= +github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 h1:msKODTL1m0wigztaqILOtla9HeW1ciscYG4xjLtvk5I= +github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52/go.mod h1:qk1sX/IBgppQNcGCRoj90u6EGC056EBoIc1oEjCWla8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.11.1 h1:wuChtj2hfsGmmx3nf1m7xC2XpK6OtelS2shMY+bGMtI= +github.com/lib/pq v1.11.1/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88 h1:PTw+yKnXcOFCR6+8hHTyWBeQ/P4Nb7dd4/0ohEcWQuM= +github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= +github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= +github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739 h1:ykXz+pRRTibcSjG1yRhpdSHInF8yZY/mfn+Rz2Nd1rE= +github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739/go.mod h1:zUx1mhth20V3VKgL5jbd1BSQcW4Fy6Qs4PZvQwRFwzM= +github.com/marcboeker/go-duckdb v1.8.5 h1:tkYp+TANippy0DaIOP5OEfBEwbUINqiFqgwMQ44jME0= +github.com/marcboeker/go-duckdb v1.8.5/go.mod h1:6mK7+WQE4P4u5AFLvVBmhFxY5fvhymFptghgJX6B+/8= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= +github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= +github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmLKZf+SjVanKKhCgf3bg+511DmU9eDQTen7LLbY= +github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8= +github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= +github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= +github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/morikuni/aec v1.1.0 h1:vBBl0pUnvi/Je71dsRrhMBtreIqNMYErSAbEeb8jrXQ= +github.com/morikuni/aec v1.1.0/go.mod h1:xDRgiq/iw5l+zkao76YTKzKttOp2cwPEne25HDkJnBw= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E= +github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= +github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/pressly/goose/v3 v3.26.0 h1:KJakav68jdH0WDvoAcj8+n61WqOIaPGgH0bJWS6jpmM= +github.com/pressly/goose/v3 v3.26.0/go.mod h1:4hC1KrritdCxtuFsqgs1R4AU5bWtTAf+cnWvfhf2DNY= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= +github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= +github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= +github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2 h1:S4OC0+OBKz6mJnzuHioeEat74PuQ4Sgvbf8eus695sc= +github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2/go.mod h1:8zLRYR5npGjaOXgPSKat5+oOh+UHd8OdbS18iqX9F6Y= +github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE= +github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs= +github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/smartcontractkit/chain-selectors v1.0.98 h1:fuI7CQ1o5cX64eO4/LvwtfhdpGFH5vnsM/bFHRwEiww= +github.com/smartcontractkit/chain-selectors v1.0.98/go.mod h1:qy7whtgG5g+7z0jt0nRyii9bLND9m15NZTzuQPkMZ5w= +github.com/smartcontractkit/chainlink-aptos v0.0.0-20260306142855-8d629e752265 h1:Q/sYLdOefZUKc/Bxssq1mg8ptQE/AOot2WI+QcLoiVA= +github.com/smartcontractkit/chainlink-aptos v0.0.0-20260306142855-8d629e752265/go.mod h1:CQGkKp3YDsUuxixxmmngmRKfh6yIcftGEZsQrsSIIM8= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d h1:xdFpzbApEMz4Rojg2Y2OjFlrh0wu7eB10V2tSZGW5y8= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d/go.mod h1:bgmqE7x9xwmIVr8PqLbC0M5iPm4AV2DBl596lO6S5Sw= +github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= +github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260407150650-8115835abd6e h1:SLnJ0/55Rcn9/9OWrjhvhOTDW9+Bhd63v1tY4dvqtQM= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260407150650-8115835abd6e/go.mod h1:Ob7ZRLEvPkDwGUjKdDIiHy0Mxu4+UG6oMBkR7Jv/U6o= +github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= +github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= +github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= +github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= +github.com/smartcontractkit/chainlink-deployments-framework v0.94.1 h1:eQ9hEHG6s0BRZ3tfGytPnBDtde6035HZve5eyCRhYs0= +github.com/smartcontractkit/chainlink-deployments-framework v0.94.1/go.mod h1:pTA1JrdlMSfb9WkrIfphq2KV/+paW7GHf15Oc/uJBxs= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/committee-verifier v0.0.0-20251211142334-5c3421fe2c8d h1:VYoBBNnQpZ5p+enPTl8SkKBRaubqyGpO0ul3B1np++I= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/committee-verifier v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:oNFoKHRIerxuaANa8ASNejtHrdsG26LqGtQ2XhSac2g= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/message-discovery v0.0.0-20251211142334-5c3421fe2c8d h1:pKCyW7BYzO5GThFNlXZY0Azx/yOnI4b5GeuLeU23ie0= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/message-discovery v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:ATjAPIVJibHRcIfiG47rEQkUIOoYa6KDvWj3zwCAw6g= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d h1:AJy55QJ/pBhXkZjc7N+ATnWfxrcjq9BI9DmdtdjwDUQ= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:5JdppgngCOUS76p61zCinSCgOhPeYQ+OcDUuome5THQ= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f h1:8p3vE987AHM3Of1JvnNJXNE/AtWtfNvJhk3TeeAG3Qw= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= +github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 h1:q+VDPcxWrj5k9QizSYfUOSMnDH3Sd5HvbPguZOgfXTY= +github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= +github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b h1:QuI6SmQFK/zyUlVWEf0GMkiUYBPY4lssn26nKSd/bOM= +github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b/go.mod h1:qSTSwX3cBP3FKQwQacdjArqv0g6QnukjV4XuzO6UyoY= +github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260211172625-dff40e83b3c9 h1:hhevsu8k7tlDRrYZmgAh7V4avGQDMvus1bwIlial3Ps= +github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260211172625-dff40e83b3c9/go.mod h1:dkR2uYg9XYJuT1JASkPzWE51jjFkVb86P7a/yXe5/GM= +github.com/smartcontractkit/chainlink-protos/op-catalog v0.0.4 h1:AEnxv4HM3WD1RbQkRiFyb9cJ6YKAcqBp1CpIcFdZfuo= +github.com/smartcontractkit/chainlink-protos/op-catalog v0.0.4/go.mod h1:PjZD54vr6rIKEKQj6HNA4hllvYI/QpT+Zefj3tqkFAs= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.10.0 h1:0eroOyBwmdoGUwUdvMI0/J7m5wuzNnJDMglSOK1sfNY= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.10.0/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= +github.com/smartcontractkit/chainlink-sui v0.0.0-20260205175622-33e65031f9a9 h1:KyPROV+v7P8VdiU7JhVuGLcDlEBsURSpQmSCgNBTY+s= +github.com/smartcontractkit/chainlink-sui v0.0.0-20260205175622-33e65031f9a9/go.mod h1:KpEWZJMLwbdMHeHQz9rbkES0vRrx4nk6OQXyhlHb9/8= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.13 h1:quHuZ/2I7XZ8pdRw5UAwKW/idsPchHN7KnQ69YWzxS4= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.13/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= +github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 h1:7f92q/Tz/Ns+gjChmWg5mEonrYutZV33k/1x+Xxsb4I= +github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418/go.mod h1:FDDjLuc4vrfclu3JHkMaREg0XZz7Lw1MK47Z4jJ4U5Q= +github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250908203554-5bd9d2fe9513 h1:XRNxgcNqagXu6e4smJuS1crRK5cUAcCVd7u+iLduHDM= +github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250908203554-5bd9d2fe9513/go.mod h1:ccjEgNeqOO+bjPddnL4lUrNLzyCvGCxgBjJdhFX3wa8= +github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.4 h1:J4qtAo0ZmgX5pIr8Y5mdC+J2rj2e/6CTUC263t6mGOM= +github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.4/go.mod h1:4WhGgCA0smBbBud5mK+jnDb2wwndMvoqaWBJ3OV/7Bw= +github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad h1:lgHxTHuzJIF3Vj6LSMOnjhqKgRqYW+0MV2SExtCYL1Q= +github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad/go.mod h1:T4zH9R8R8lVWKfU7tUvYz2o2jMv1OpGCdpY2j2QZXzU= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= +github.com/smartcontractkit/libocr v0.0.0-20260304194147-a03701e2c02e h1:poXTj5cFVM6XfC4HICIDYkDVc/A6OYB0eeID0wU2JQE= +github.com/smartcontractkit/libocr v0.0.0-20260304194147-a03701e2c02e/go.mod h1:PLdNK6GlqfxIWXzziPkU7dCAVlVFeYkyyW7AQY0R+4Q= +github.com/smartcontractkit/mcms v0.40.1 h1:r9bU/2GfIf6mHHM4PklSBkfi2Lq4+EGILC81e4IqKz0= +github.com/smartcontractkit/mcms v0.40.1/go.mod h1:7YqJPR8w9GiO1L/JjjTrwlSwAZ7i3J7cgOcu88PqtvU= +github.com/smartcontractkit/wsrpc v0.8.5-0.20250502134807-c57d3d995945 h1:zxcODLrFytOKmAd8ty8S/XK6WcIEJEgRBaL7sY/7l4Y= +github.com/smartcontractkit/wsrpc v0.8.5-0.20250502134807-c57d3d995945/go.mod h1:m3pdp17i4bD50XgktkzWetcV5yaLsi7Gunbv4ZgN6qg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stellar/go-stellar-sdk v0.1.0 h1:MfV7dv4k6xQQrWeKT7npWyKhjoayphLVGwXKtTLNeH8= +github.com/stellar/go-stellar-sdk v0.1.0/go.mod h1:fZPcxQZw1I0zZ+X76uFcVPqmQCaYbWc87lDFW/kQJaY= +github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2 h1:OzCVd0SV5qE3ZcDeSFCmOWLZfEWZ3Oe8KtmSOYKEVWE= +github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2/go.mod h1:yoxyU/M8nl9LKeWIoBrbDPQ7Cy+4jxRcWcOayZ4BMps= +github.com/stephenlacy/go-ethereum-hdwallet v0.0.0-20230913225845-a4fa94429863 h1:ba4VRWSkRzgdP5hB5OxexIzBXZbSwgcw8bEu06ivGQI= +github.com/stephenlacy/go-ethereum-hdwallet v0.0.0-20230913225845-a4fa94429863/go.mod h1:oPTjPNrRucLv9mU27iNPj6n0CWWcNFhoXFOLVGJwHCA= +github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 h1:RN5mrigyirb8anBEtdjtHFIufXdacyTi6i4KBfeNXeo= +github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jqwYhE= +github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= +github.com/testcontainers/testcontainers-go v0.41.0 h1:mfpsD0D36YgkxGj2LrIyxuwQ9i2wCKAD+ESsYM1wais= +github.com/testcontainers/testcontainers-go v0.41.0/go.mod h1:pdFrEIfaPl24zmBjerWTTYaY0M6UHsqA1YSvsoU40MI= +github.com/testcontainers/testcontainers-go/modules/postgres v0.41.0 h1:AOtFXssrDlLm84A2sTTR/AhvJiYbrIuCO59d+Ro9Tb0= +github.com/testcontainers/testcontainers-go/modules/postgres v0.41.0/go.mod h1:k2a09UKhgSp6vNpliIY0QSgm4Hi7GXVTzWvWgUemu/8= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= +github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= +github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADTh4= +github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xdrpp/goxdr v0.1.1 h1:E1B2c6E8eYhOVyd7yEpOyopzTPirUeF6mVOfXfGyJyc= +github.com/xdrpp/goxdr v0.1.1/go.mod h1:dXo1scL/l6s7iME1gxHWo2XCppbHEKZS7m/KyYWkNzA= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/xssnick/tonutils-go v1.14.1 h1:zV/iVYl/h3hArS+tPsd9XrSFfGert3r21caMltPSeHg= +github.com/xssnick/tonutils-go v1.14.1/go.mod h1:68xwWjpoGGqiTbLJ0gT63sKu1Z1moCnDLLzA+DKanIg= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6 h1:VRdX3Gn/I7ITbzUY4ZNfgn65tdQM9Zhf2b7KP0HZllk= +github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6/go.mod h1:NWNlQS21isOsSsn+hLRAPpiuv+3P+LcdaZNuRt2T5Yo= +go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM= +go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 h1:gAU726w9J8fwr4qRDqu1GYMNNs4gXrU+Pv20/N1UpB4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0/go.mod h1:RboSDkp7N292rgu+T0MgVt2qgFGu6qa1RpZDOtpL76w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0/go.mod h1:Izur+Wt8gClgMJqO/cZ8wdeeMryJ/xxiOVgFSSfpDTY= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKECHbOlr5GLwH6KTjLJ1sBSkkxkc= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0/go.mod h1:/GXR0tBmmkxDaCUGahvksvp66mx4yh5+cFXgSlhg0vQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 h1:G8Xec/SgZQricwWBJF/mHZc7A02YHedfFDENwJEdRA0= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0/go.mod h1:PD57idA/AiFD5aqoxGxCvT/ILJPeHy3MjqU/NS7KogY= +go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY= +go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= +go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= +go.opentelemetry.io/otel/sdk/log/logtest v0.13.0 h1:9yio6AFZ3QD9j9oqshV1Ibm9gPLlHNxurno5BreMtIA= +go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0= +go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= +golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0= +golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls= +k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k= +k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U= +k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU= +k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= +k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 h1:jGnCPejIetjiy2gqaJ5V0NLwTpF4wbQ6cZIItJCSHno= +k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +modernc.org/libc v1.66.3 h1:cfCbjTUcdsKyyZZfEUKfoHcP3S0Wkvz3jgSzByEWVCQ= +modernc.org/libc v1.66.3/go.mod h1:XD9zO8kt59cANKvHPXpx7yS2ELPheAey0vjIuZOhOU8= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/sqlite v1.39.0 h1:6bwu9Ooim0yVYA7IZn9demiQk/Ejp0BtTjBWFLymSeY= +modernc.org/sqlite v1.39.0/go.mod h1:cPTJYSlgg3Sfg046yBShXENNtPrWrDX8bsbAQBzgQ5E= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/deployment/indexer.go b/deployment/indexer.go new file mode 100644 index 000000000..462c442df --- /dev/null +++ b/deployment/indexer.go @@ -0,0 +1,10 @@ +package deployment + +type IndexerVerifierConfig struct { + Name string `json:"name"` + IssuerAddresses []string `json:"issuerAddresses"` +} + +type IndexerGeneratedConfig struct { + Verifiers []IndexerVerifierConfig `json:"verifiers"` +} diff --git a/deployment/operations/fetch_node_chain_support/fetch_node_chain_support.go b/deployment/operations/fetch_node_chain_support/fetch_node_chain_support.go new file mode 100644 index 000000000..c3be15f82 --- /dev/null +++ b/deployment/operations/fetch_node_chain_support/fetch_node_chain_support.go @@ -0,0 +1,114 @@ +package fetch_node_chain_support + +import ( + "fmt" + + "github.com/Masterminds/semver/v3" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-deployments-framework/operations" + nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" + + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +type FetchNodeChainSupportInput struct { + NOPAliases []string +} + +type FetchNodeChainSupportOutput struct { + SupportedChains shared.ChainSupportByNOP +} + +type FetchNodeChainSupportDeps struct { + JDClient shared.JDClient + Logger logger.Logger + NodeIDs []string +} + +var FetchNodeChainSupport = operations.NewOperation( + "fetch-node-chain-support", + semver.MustParse("1.0.0"), + "Fetches supported chain selectors for specified NOPs from the job distributor", + func(b operations.Bundle, deps FetchNodeChainSupportDeps, input FetchNodeChainSupportInput) (FetchNodeChainSupportOutput, error) { + ctx := b.GetContext() + lggr := deps.Logger + + output := FetchNodeChainSupportOutput{ + SupportedChains: make(shared.ChainSupportByNOP), + } + + if len(input.NOPAliases) == 0 { + return output, nil + } + + lookup, err := shared.FetchNodeLookup(ctx, deps.JDClient, deps.NodeIDs) + if err != nil { + return output, err + } + + nodeIDs := make([]string, 0, len(input.NOPAliases)) + nodeIDToAlias := make(map[string]string) + seenNodeIDs := make(map[string]string) + for _, nopAlias := range input.NOPAliases { + node, ok := lookup.FindByName(nopAlias) + if !ok { + return output, fmt.Errorf("NOP alias %q not found in node lookup (node IDs: %v)", nopAlias, deps.NodeIDs) + } + if existing, ok := seenNodeIDs[node.Id]; ok && existing != nopAlias { + return output, fmt.Errorf("duplicate node ID %q: NOP aliases %q and %q both resolve to the same node", node.Id, existing, nopAlias) + } + seenNodeIDs[node.Id] = nopAlias + nodeIDs = append(nodeIDs, node.Id) + nodeIDToAlias[node.Id] = nopAlias + } + + chainConfigsResp, err := deps.JDClient.ListNodeChainConfigs(ctx, &nodev1.ListNodeChainConfigsRequest{ + Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ + NodeIds: nodeIDs, + }, + }) + if err != nil { + return output, fmt.Errorf("failed to list chain configs: %w", err) + } + + for _, chainConfig := range chainConfigsResp.ChainConfigs { + nopAlias, ok := nodeIDToAlias[chainConfig.NodeId] + if !ok { + continue + } + + chainFamily, ok := shared.GetChainTypeFamily(chainConfig.Chain.Type) + if !ok { + lggr.Debugw("Skipping unsupported chain type", + "chainType", chainConfig.Chain.Type.String()) + continue + } + + chainDetails, err := chainsel.GetChainDetailsByChainIDAndFamily(chainConfig.Chain.Id, chainFamily) + if err != nil { + lggr.Warnw("Failed to get chain details from chain ID", + "chainId", chainConfig.Chain.Id, + "chainFamily", chainFamily, + "error", err) + continue + } + chainSelector := chainDetails.ChainSelector + + if output.SupportedChains[nopAlias] == nil { + output.SupportedChains[nopAlias] = make([]uint64, 0) + } + output.SupportedChains[nopAlias] = append(output.SupportedChains[nopAlias], chainSelector) + + lggr.Debugw("Found supported chain", + "nopAlias", nopAlias, + "nodeId", chainConfig.NodeId, + "chainId", chainConfig.Chain.Id, + "chainFamily", chainFamily, + "chainSelector", chainSelector) + } + + return output, nil + }, +) diff --git a/deployment/operations/fetch_signing_keys/fetch_signing_keys.go b/deployment/operations/fetch_signing_keys/fetch_signing_keys.go new file mode 100644 index 000000000..d6b0da56e --- /dev/null +++ b/deployment/operations/fetch_signing_keys/fetch_signing_keys.go @@ -0,0 +1,118 @@ +package fetch_signing_keys + +import ( + "fmt" + + "github.com/Masterminds/semver/v3" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-deployments-framework/operations" + nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" + + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +// SigningKeysByNOP maps NOP alias -> chain family -> signer address. +type SigningKeysByNOP map[string]map[string]string + +type FetchSigningKeysInput struct { + NOPAliases []string +} + +type FetchSigningKeysOutput struct { + SigningKeysByNOP SigningKeysByNOP +} + +type FetchSigningKeysDeps struct { + JDClient shared.JDClient + Logger logger.Logger + NodeIDs []string +} + +var FetchNOPSigningKeys = operations.NewOperation( + "fetch-nop-signing-keys", + semver.MustParse("1.0.0"), + "Fetches signing keys for all specified NOPs from the job distributor in a single batch", + func(b operations.Bundle, deps FetchSigningKeysDeps, input FetchSigningKeysInput) (FetchSigningKeysOutput, error) { + ctx := b.GetContext() + lggr := deps.Logger + + output := FetchSigningKeysOutput{ + SigningKeysByNOP: make(SigningKeysByNOP), + } + + if len(input.NOPAliases) == 0 { + return output, nil + } + + lookup, err := shared.FetchNodeLookup(ctx, deps.JDClient, deps.NodeIDs) + if err != nil { + return output, err + } + + nodeIDs := make([]string, 0, len(input.NOPAliases)) + nodeIDToAlias := make(map[string]string) + seenNodeIDs := make(map[string]string) + for _, nopAlias := range input.NOPAliases { + node, ok := lookup.FindByName(nopAlias) + if !ok { + return output, fmt.Errorf("NOP alias %q not found in node lookup (node IDs: %v)", nopAlias, deps.NodeIDs) + } + if existing, ok := seenNodeIDs[node.Id]; ok && existing != nopAlias { + return output, fmt.Errorf("duplicate node ID %q: NOP aliases %q and %q both resolve to the same node", node.Id, existing, nopAlias) + } + seenNodeIDs[node.Id] = nopAlias + nodeIDs = append(nodeIDs, node.Id) + nodeIDToAlias[node.Id] = nopAlias + } + + chainConfigsResp, err := deps.JDClient.ListNodeChainConfigs(ctx, &nodev1.ListNodeChainConfigsRequest{ + Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ + NodeIds: nodeIDs, + }, + }) + if err != nil { + return output, fmt.Errorf("failed to list chain configs: %w", err) + } + + for _, chainConfig := range chainConfigsResp.ChainConfigs { + if chainConfig.Ocr2Config == nil || chainConfig.Ocr2Config.OcrKeyBundle == nil { + continue + } + + nopAlias, ok := nodeIDToAlias[chainConfig.NodeId] + if !ok { + continue + } + + signerAddress := chainConfig.Ocr2Config.OcrKeyBundle.OnchainSigningAddress + if signerAddress == "" { + continue + } + + chainFamily, ok := shared.GetChainTypeFamily(chainConfig.Chain.Type) + if !ok { + lggr.Debugw("Skipping unsupported chain type", + "chainType", chainConfig.Chain.Type.String()) + continue + } + + if output.SigningKeysByNOP[nopAlias] == nil { + output.SigningKeysByNOP[nopAlias] = make(map[string]string) + } + addr := shared.NormalizeAddress(chainFamily, signerAddress) + if existing, ok := output.SigningKeysByNOP[nopAlias][chainFamily]; ok && existing != addr { + return output, fmt.Errorf("NOP %q has conflicting OCR key bundles for family %s: address %s vs %s — the job spec requires a single signing address (per-chain scoping not supported yet)", nopAlias, chainFamily, existing, addr) + } + output.SigningKeysByNOP[nopAlias][chainFamily] = addr + + lggr.Debugw("Found signing address", + "nopAlias", nopAlias, + "nodeId", chainConfig.NodeId, + "chainFamily", chainFamily, + "signerAddress", signerAddress) + } + + return output, nil + }, +) diff --git a/deployment/operations/propose_jobs/propose_jobs.go b/deployment/operations/propose_jobs/propose_jobs.go new file mode 100644 index 000000000..d12e6c110 --- /dev/null +++ b/deployment/operations/propose_jobs/propose_jobs.go @@ -0,0 +1,128 @@ +package propose_jobs + +import ( + "fmt" + + "github.com/Masterminds/semver/v3" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-deployments-framework/operations" + jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" + "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/shared/ptypes" + + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +type JobSpecInput struct { + NOPAlias shared.NOPAlias + InternalJobID shared.JobID + Spec string +} + +type ProposeJobsInput struct { + JobSpecs []JobSpecInput + Labels map[string]string +} + +type ProposeJobsOutput struct { + ProposedJobs []ProposedJob +} + +type ProposedJob struct { + NodeID string + NodeName string + ProposalID string + JobID string + InternalJobID shared.JobID + Spec string + NOPAlias shared.NOPAlias + Revision int64 +} + +type ProposeJobsDeps struct { + JDClient shared.JDClient + Logger logger.Logger + NodeIDs []string +} + +var ProposeJobs = operations.NewOperation( + "propose-jobs", + semver.MustParse("1.0.0"), + "Proposes jobs to nodes via the job distributor", + func(b operations.Bundle, deps ProposeJobsDeps, input ProposeJobsInput) (ProposeJobsOutput, error) { + ctx := b.GetContext() + lggr := deps.Logger + + output := ProposeJobsOutput{ + ProposedJobs: make([]ProposedJob, 0, len(input.JobSpecs)), + } + + if len(input.JobSpecs) == 0 { + return output, nil + } + + lookup, err := shared.FetchNodeLookup(ctx, deps.JDClient, deps.NodeIDs) + if err != nil { + return output, err + } + + for _, jobSpecInput := range input.JobSpecs { + nopAlias := string(jobSpecInput.NOPAlias) + node, ok := lookup.FindByName(nopAlias) + if !ok { + lggr.Warnw("Node not found for job spec", + "nopAlias", nopAlias, + "internalJobId", jobSpecInput.InternalJobID) + return output, fmt.Errorf("node not found for job spec: %s", nopAlias) + } + + var jobLabels []*ptypes.Label + for k, v := range input.Labels { + jobLabels = append(jobLabels, &ptypes.Label{ + Key: k, + Value: &v, + }) + } + + lggr.Debugw("Proposing job", + "nodeId", node.Id, + "nodeName", node.Name, + "nopAlias", nopAlias, + "internalJobId", jobSpecInput.InternalJobID) + + resp, err := deps.JDClient.ProposeJob(ctx, &jobv1.ProposeJobRequest{ + NodeId: node.Id, + Spec: jobSpecInput.Spec, + Labels: jobLabels, + }) + if err != nil { + lggr.Errorw("Failed to propose job", + "nodeId", node.Id, + "nodeName", node.Name, + "internalJobId", jobSpecInput.InternalJobID, + "error", err) + return output, fmt.Errorf("failed to propose job %s for node %s: %w", jobSpecInput.InternalJobID, node.Name, err) + } + + lggr.Infow("Job proposed successfully", + "nodeId", node.Id, + "nodeName", node.Name, + "proposalId", resp.Proposal.Id, + "jdJobId", resp.Proposal.JobId, + "internalJobId", jobSpecInput.InternalJobID) + + output.ProposedJobs = append(output.ProposedJobs, ProposedJob{ + NodeID: node.Id, + NodeName: node.Name, + ProposalID: resp.Proposal.Id, + JobID: resp.Proposal.JobId, + InternalJobID: jobSpecInput.InternalJobID, + Spec: resp.Proposal.Spec, + NOPAlias: jobSpecInput.NOPAlias, + Revision: resp.Proposal.Revision, + }) + } + + return output, nil + }, +) diff --git a/deployment/operations/revoke_jobs/revoke_jobs.go b/deployment/operations/revoke_jobs/revoke_jobs.go new file mode 100644 index 000000000..f6bd7b441 --- /dev/null +++ b/deployment/operations/revoke_jobs/revoke_jobs.go @@ -0,0 +1,112 @@ +package revoke_jobs + +import ( + "fmt" + + "github.com/Masterminds/semver/v3" + + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-deployments-framework/operations" + jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" + + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +type RevokeJobsInput struct { + Jobs []shared.JobInfo +} + +type RevokeJobsOutput struct { + RevokedJobs []RevokedJob + Errors []RevokeError +} + +type RevokedJob struct { + JobID shared.JobID + NOPAlias shared.NOPAlias +} + +type RevokeError struct { + JobID shared.JobID + NOPAlias shared.NOPAlias + Error string +} + +type RevokeJobsDeps struct { + JDClient shared.JDClient + Logger logger.Logger + NodeIDs []string +} + +var RevokeJobs = operations.NewOperation( + "revoke-jobs", + semver.MustParse("1.0.0"), + "Revokes job proposals from nodes via the job distributor", + func(b operations.Bundle, deps RevokeJobsDeps, input RevokeJobsInput) (RevokeJobsOutput, error) { + ctx := b.GetContext() + lggr := deps.Logger + + output := RevokeJobsOutput{ + RevokedJobs: make([]RevokedJob, 0), + Errors: make([]RevokeError, 0), + } + + if len(input.Jobs) == 0 { + return output, nil + } + + allowedNodeIDs := shared.NodeIDsToSet(deps.NodeIDs) + if allowedNodeIDs == nil { + return output, fmt.Errorf("NodeIDs must be specified") + } + + for _, job := range input.Jobs { + if job.NodeID == "" { + return output, fmt.Errorf("job %s has no NodeID - cannot validate node ownership", job.JobID) + } + if !allowedNodeIDs[job.NodeID] { + return output, fmt.Errorf("job %s has NodeID %s which is not in the allowed node list", job.JobID, job.NodeID) + } + } + + for _, job := range input.Jobs { + if job.JDJobID == "" { + lggr.Warnw("Skipping job with no JD job ID", + "jobId", job.JobID, + "nopAlias", job.NOPAlias) + output.Errors = append(output.Errors, RevokeError{ + JobID: job.JobID, + NOPAlias: job.NOPAlias, + Error: "no JD job ID", + }) + continue + } + + _, err := deps.JDClient.RevokeJob(ctx, &jobv1.RevokeJobRequest{ + IdOneof: &jobv1.RevokeJobRequest_Id{Id: job.JDJobID}, + }) + if err != nil { + lggr.Errorw("Failed to revoke job", + "jobId", job.JobID, + "error", err) + output.Errors = append(output.Errors, RevokeError{ + JobID: job.JobID, + NOPAlias: job.NOPAlias, + Error: err.Error(), + }) + continue + } + + lggr.Infow("Job proposal revoked successfully", + "jobId", job.JobID, + "nopAlias", job.NOPAlias) + + output.RevokedJobs = append(output.RevokedJobs, RevokedJob{ + JobID: job.JobID, + NOPAlias: job.NOPAlias, + }) + } + + return output, nil + }, +) diff --git a/deployment/operations/sync_job_proposals/sync_job_proposals.go b/deployment/operations/sync_job_proposals/sync_job_proposals.go new file mode 100644 index 000000000..b0a4b8a1d --- /dev/null +++ b/deployment/operations/sync_job_proposals/sync_job_proposals.go @@ -0,0 +1,278 @@ +package sync_job_proposals + +import ( + "fmt" + + "github.com/Masterminds/semver/v3" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-deployments-framework/operations" + jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" + + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +type SyncJobProposalsInput struct { + NOPAliases []shared.NOPAlias +} + +type SyncJobProposalsOutput struct { + StatusChanges []ProposalStatusChange + SpecDrifts []ProposalSpecDrift + OrphanedJobs []OrphanedJob + Errors []SyncError + DataStore datastore.MutableDataStore +} + +type OrphanedJob struct { + NOPAlias shared.NOPAlias + JobID shared.JobID + JDJobID string + Reason string +} + +type ProposalStatusChange struct { + NOPAlias shared.NOPAlias + JobID shared.JobID + OldStatus shared.JobProposalStatus + NewStatus shared.JobProposalStatus +} + +type ProposalSpecDrift struct { + NOPAlias shared.NOPAlias + JobID shared.JobID + LocalSpec string + JDSpec string +} + +type SyncError struct { + ProposalID string + NOPAlias shared.NOPAlias + JobID shared.JobID + Error string +} + +type SyncJobProposalsDeps struct { + Env deployment.Environment + JDClient shared.JDClient +} + +var SyncJobProposals = operations.NewOperation( + "sync-job-proposals", + semver.MustParse("1.0.0"), + "Syncs job proposal statuses from JD and detects spec drift", + func(b operations.Bundle, deps SyncJobProposalsDeps, input SyncJobProposalsInput) (SyncJobProposalsOutput, error) { + ctx := b.GetContext() + e := deps.Env + + ds := datastore.NewMemoryDataStore() + if e.DataStore != nil { + if err := ds.Merge(e.DataStore); err != nil { + return SyncJobProposalsOutput{}, fmt.Errorf("failed to merge datastore: %w", err) + } + } + + output := SyncJobProposalsOutput{ + StatusChanges: make([]ProposalStatusChange, 0), + SpecDrifts: make([]ProposalSpecDrift, 0), + OrphanedJobs: make([]OrphanedJob, 0), + Errors: make([]SyncError, 0), + DataStore: ds, + } + + jdClient := deps.JDClient + if jdClient == nil { + if e.Offchain == nil { + return output, fmt.Errorf("offchain client not available") + } + jdClient = e.Offchain + } + + allJobs, err := ccvdeployment.GetAllJobs(ds.Seal()) + if err != nil { + e.Logger.Debugw("No jobs found in datastore, nothing to sync", "error", err) + return output, nil + } + + nopFilter := shared.NOPAliasSliceToSet(input.NOPAliases) + + allowedNodeIDs := shared.NodeIDsToSet(e.NodeIDs) + if allowedNodeIDs == nil { + return SyncJobProposalsOutput{}, fmt.Errorf("NodeIDs must be specified") + } + + for nopAlias, nopJobs := range allJobs { + if len(nopFilter) > 0 && !nopFilter[nopAlias] { + continue + } + for jobID, localJob := range nopJobs { + if localJob.Mode != shared.NOPModeCL { + continue + } + if localJob.JDJobID == "" { + continue + } + if localJob.NodeID == "" { + return SyncJobProposalsOutput{}, fmt.Errorf("job %s has no NodeID", jobID) + } + if !allowedNodeIDs[localJob.NodeID] { + return SyncJobProposalsOutput{}, fmt.Errorf("job %s has NodeID %s which is not in the allowed node list", jobID, localJob.NodeID) + } + } + } + + for nopAlias, nopJobs := range allJobs { + if len(nopFilter) > 0 && !nopFilter[nopAlias] { + continue + } + + for jobID, localJob := range nopJobs { + if localJob.Mode != shared.NOPModeCL { + continue + } + + if localJob.JDJobID == "" { + e.Logger.Debugw("Skipping job without JD job ID", + "nopAlias", nopAlias, + "jobId", jobID) + continue + } + + e.Logger.Debugw("Fetching proposals from JD", + "jdJobId", localJob.JDJobID, + "nopAlias", nopAlias, + "jobId", jobID) + + listResp, err := jdClient.ListProposals(ctx, &jobv1.ListProposalsRequest{ + Filter: &jobv1.ListProposalsRequest_Filter{ + JobIds: []string{localJob.JDJobID}, + }, + }) + if err != nil { + e.Logger.Warnw("Failed to list proposals from JD", + "jdJobId", localJob.JDJobID, + "error", err) + output.Errors = append(output.Errors, SyncError{ + NOPAlias: nopAlias, + JobID: jobID, + Error: err.Error(), + }) + continue + } + + if listResp == nil || len(listResp.Proposals) == 0 { + e.Logger.Infow("Job no longer exists in JD, marking as orphaned", + "jdJobId", localJob.JDJobID, + "nopAlias", nopAlias, + "jobId", jobID) + + output.OrphanedJobs = append(output.OrphanedJobs, OrphanedJob{ + NOPAlias: nopAlias, + JobID: jobID, + JDJobID: localJob.JDJobID, + Reason: "no proposals found in JD", + }) + + if err := ccvdeployment.DeleteJob(ds, nopAlias, jobID); err != nil { + e.Logger.Errorw("Failed to delete orphaned job", + "jdJobId", localJob.JDJobID, + "error", err) + output.Errors = append(output.Errors, SyncError{ + NOPAlias: nopAlias, + JobID: jobID, + Error: fmt.Sprintf("failed to delete orphaned job: %s", err.Error()), + }) + } + continue + } + + oldStatus := localJob.LatestStatus() + + for _, jdProposal := range listResp.Proposals { + localJob.AddProposal(shared.ProposalRevision{ + ProposalID: jdProposal.Id, + Revision: jdProposal.Revision, + Status: mapJDStatusToLocal(jdProposal.Status), + Spec: jdProposal.Spec, + }) + + if jdProposal.Status == jobv1.ProposalStatus_PROPOSAL_STATUS_APPROVED { + localJob.SetActiveProposal(jdProposal.Id) + } + } + + newStatus := localJob.LatestStatus() + if newStatus != oldStatus { + e.Logger.Infow("Status change detected", + "jdJobId", localJob.JDJobID, + "nopAlias", nopAlias, + "jobId", jobID, + "oldStatus", oldStatus, + "newStatus", newStatus) + + output.StatusChanges = append(output.StatusChanges, ProposalStatusChange{ + NOPAlias: nopAlias, + JobID: jobID, + OldStatus: oldStatus, + NewStatus: newStatus, + }) + } + + latestProposal := localJob.LatestProposal() + if latestProposal != nil && latestProposal.Spec != localJob.Spec { + e.Logger.Warnw("Spec drift detected", + "jdJobId", localJob.JDJobID, + "nopAlias", nopAlias, + "jobId", jobID) + + output.SpecDrifts = append(output.SpecDrifts, ProposalSpecDrift{ + NOPAlias: nopAlias, + JobID: jobID, + LocalSpec: localJob.Spec, + JDSpec: latestProposal.Spec, + }) + } + + if err := ccvdeployment.SaveJob(ds, localJob); err != nil { + e.Logger.Errorw("Failed to save job", + "jdJobId", localJob.JDJobID, + "error", err) + output.Errors = append(output.Errors, SyncError{ + NOPAlias: nopAlias, + JobID: jobID, + Error: fmt.Sprintf("failed to save job: %s", err.Error()), + }) + } + } + } + + e.Logger.Infow("Job proposals sync completed", + "statusChanges", len(output.StatusChanges), + "specDrifts", len(output.SpecDrifts), + "orphanedJobs", len(output.OrphanedJobs), + "errors", len(output.Errors)) + + return output, nil + }, +) + +func mapJDStatusToLocal(jdStatus jobv1.ProposalStatus) shared.JobProposalStatus { + switch jdStatus { + case jobv1.ProposalStatus_PROPOSAL_STATUS_PENDING: + return shared.JobProposalStatusPending + case jobv1.ProposalStatus_PROPOSAL_STATUS_PROPOSED: + return shared.JobProposalStatusPending + case jobv1.ProposalStatus_PROPOSAL_STATUS_APPROVED: + return shared.JobProposalStatusApproved + case jobv1.ProposalStatus_PROPOSAL_STATUS_REJECTED: + return shared.JobProposalStatusRejected + case jobv1.ProposalStatus_PROPOSAL_STATUS_REVOKED: + return shared.JobProposalStatusRevoked + case jobv1.ProposalStatus_PROPOSAL_STATUS_CANCELLED: + return shared.JobProposalStatusRevoked + default: + return shared.JobProposalStatusPending + } +} diff --git a/deployment/sequences/manage_job_proposals.go b/deployment/sequences/manage_job_proposals.go new file mode 100644 index 000000000..888eee44e --- /dev/null +++ b/deployment/sequences/manage_job_proposals.go @@ -0,0 +1,381 @@ +package sequences + +import ( + "fmt" + + "github.com/Masterminds/semver/v3" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-deployments-framework/operations" + + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + "github.com/smartcontractkit/chainlink-ccv/deployment/operations/propose_jobs" + "github.com/smartcontractkit/chainlink-ccv/deployment/operations/revoke_jobs" + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +type NOPContext struct { + Modes map[shared.NOPAlias]shared.NOPMode + TargetNOPs []shared.NOPAlias + AllNOPs []shared.NOPAlias +} + +type ManageJobProposalsInput struct { + JobSpecs shared.NOPJobSpecs + AffectedScope shared.JobScope + Labels map[string]string + NOPs NOPContext + // RevokeOrphanedJobs when true runs orphan collection, JD revoke, and datastore cleanup; default false. + RevokeOrphanedJobs bool +} + +type ManageJobProposalsOutput struct { + Jobs []shared.JobInfo + RevokedJobs []shared.JobInfo + DataStore datastore.MutableDataStore +} + +type ManageJobProposalsDeps struct { + Env deployment.Environment +} + +var ManageJobProposals = operations.NewSequence( + "manage-job-proposals", + semver.MustParse("1.0.0"), + "Manages job proposals by proposing new jobs and optionally revoking orphaned ones via JD when RevokeOrphanedJobs is enabled", + func(b operations.Bundle, deps ManageJobProposalsDeps, input ManageJobProposalsInput) (ManageJobProposalsOutput, error) { + e := deps.Env + + ds := datastore.NewMemoryDataStore() + if e.DataStore != nil { + if err := ds.Merge(e.DataStore); err != nil { + return ManageJobProposalsOutput{}, fmt.Errorf("failed to merge datastore: %w", err) + } + } + + existingJobs, err := ccvdeployment.GetAllJobs(ds.Seal()) + if err != nil { + e.Logger.Warnw("Failed to load existing jobs, will propose all jobs", "error", err) + existingJobs = nil + } + + jobs := buildJobsFromJobSpecs(input.JobSpecs, input.NOPs.Modes) + carryForwardExistingJobMetadata(jobs, existingJobs) + + changedJobs := filterChangedJobs(jobs, existingJobs) + + transitioned := detectCLToStandaloneTransitions(jobs, existingJobs) + if len(transitioned) > 0 { + if input.RevokeOrphanedJobs { + if e.Offchain == nil { + return ManageJobProposalsOutput{}, fmt.Errorf("CL-to-standalone transition requires JD for revocation but e.Offchain is nil") + } + revokeReport, revokeErr := operations.ExecuteOperation( + b, + revoke_jobs.RevokeJobs, + revoke_jobs.RevokeJobsDeps{ + JDClient: e.Offchain, + Logger: e.Logger, + NodeIDs: e.NodeIDs, + }, + revoke_jobs.RevokeJobsInput{ + Jobs: transitioned, + }, + ) + if revokeErr != nil { + return ManageJobProposalsOutput{DataStore: ds}, + fmt.Errorf("failed to revoke CL-to-standalone transitioned jobs: %w", revokeErr) + } + e.Logger.Infow("Revoked CL-to-standalone transitioned jobs", "count", len(revokeReport.Output.RevokedJobs)) + } else { + e.Logger.Warnw("CL-to-standalone transitions detected but RevokeOrphanedJobs is false; skipping JD revocation. Re-run with RevokeOrphanedJobs=true or revoke manually.", + "count", len(transitioned)) + } + clearJDMetadata(jobs, transitioned) + } + + clModeSpecs := extractCLModeSpecs(changedJobs) + + if len(changedJobs) < len(jobs) { + e.Logger.Infow("Skipping unchanged jobs", "total", len(jobs), "changed", len(changedJobs), "skipped", len(jobs)-len(changedJobs)) + } + + if len(clModeSpecs) > 0 { + if e.Offchain == nil { + return ManageJobProposalsOutput{}, fmt.Errorf("CL mode NOPs require JD but e.Offchain is nil") + } + + proposeReport, err := operations.ExecuteOperation( + b, + propose_jobs.ProposeJobs, + propose_jobs.ProposeJobsDeps{ + JDClient: e.Offchain, + Logger: e.Logger, + NodeIDs: e.NodeIDs, + }, + propose_jobs.ProposeJobsInput{ + JobSpecs: clModeSpecs, + Labels: input.Labels, + }, + ) + if err != nil { + return ManageJobProposalsOutput{}, fmt.Errorf("failed to propose CL mode jobs: %w", err) + } + + updateJobsWithJDResponse(jobs, proposeReport.Output.ProposedJobs) + } + + if err := ccvdeployment.SaveJobs(ds, jobs); err != nil { + return ManageJobProposalsOutput{}, fmt.Errorf("failed to save jobs: %w", err) + } + + var revokedJobs []shared.JobInfo + + if !input.RevokeOrphanedJobs { + e.Logger.Debugw("Skipping orphan job revocation (RevokeOrphanedJobs=false)") + } else { + expectedJobsByNOP := extractExpectedJobsByNOP(jobs) + + orphanedJobs, err := ccvdeployment.CollectOrphanedJobs( + ds.Seal(), + input.AffectedScope, + expectedJobsByNOP, + shared.NOPAliasSliceToSet(input.NOPs.TargetNOPs), + shared.NOPAliasSliceToSet(input.NOPs.AllNOPs), + ) + if err != nil { + e.Logger.Warnw("Failed to collect orphaned jobs", "error", err) + orphanedJobs = nil + } + + if len(orphanedJobs) > 0 { + clOrphanedJobs := filterCLModeJobs(orphanedJobs) + clJobsNeedingRevoke := filterNonRevokedJobs(clOrphanedJobs) + if len(clJobsNeedingRevoke) > 0 && e.Offchain != nil { + revokeReport, revokeErr := operations.ExecuteOperation( + b, + revoke_jobs.RevokeJobs, + revoke_jobs.RevokeJobsDeps{ + JDClient: e.Offchain, + Logger: e.Logger, + NodeIDs: e.NodeIDs, + }, + revoke_jobs.RevokeJobsInput{ + Jobs: clJobsNeedingRevoke, + }, + ) + if revokeErr != nil { + return ManageJobProposalsOutput{ + Jobs: jobs, + DataStore: ds, + }, fmt.Errorf("failed to revoke orphaned CL mode jobs: %w", revokeErr) + } + e.Logger.Infow("Revoked orphaned jobs", "count", len(revokeReport.Output.RevokedJobs)) + } + + if cleanupErr := ccvdeployment.CleanupOrphanedJobs(ds, orphanedJobs); cleanupErr != nil { + return ManageJobProposalsOutput{ + Jobs: jobs, + DataStore: ds, + }, fmt.Errorf("failed to cleanup orphaned jobs: %w", cleanupErr) + } + revokedJobs = orphanedJobs + } + } + + return ManageJobProposalsOutput{ + Jobs: jobs, + RevokedJobs: revokedJobs, + DataStore: ds, + }, nil + }, +) + +func buildJobsFromJobSpecs(jobSpecs shared.NOPJobSpecs, nopModes map[shared.NOPAlias]shared.NOPMode) []shared.JobInfo { + totalJobs := 0 + for _, jobSpecsByID := range jobSpecs { + totalJobs += len(jobSpecsByID) + } + jobs := make([]shared.JobInfo, 0, totalJobs) + + for nopAlias, jobSpecsByID := range jobSpecs { + mode := nopModes[nopAlias] + if mode == "" { + mode = shared.NOPModeCL + } + + for jobID, spec := range jobSpecsByID { + job := shared.JobInfo{ + Spec: spec, + ExternalJobID: jobID.ToExternalJobID(), + JobID: jobID, + NOPAlias: nopAlias, + Mode: mode, + Proposals: make(map[string]shared.ProposalRevision), + } + jobs = append(jobs, job) + } + } + + return jobs +} + +func extractCLModeSpecs(jobs []shared.JobInfo) []propose_jobs.JobSpecInput { + clModeSpecs := make([]propose_jobs.JobSpecInput, 0) + for _, job := range jobs { + if job.Mode == shared.NOPModeCL { + clModeSpecs = append(clModeSpecs, propose_jobs.JobSpecInput{ + NOPAlias: job.NOPAlias, + InternalJobID: job.JobID, + Spec: job.Spec, + }) + } + } + return clModeSpecs +} + +func updateJobsWithJDResponse(jobs []shared.JobInfo, proposedJobs []propose_jobs.ProposedJob) { + proposedJobMap := make(map[shared.JobID]propose_jobs.ProposedJob, len(proposedJobs)) + for _, pj := range proposedJobs { + proposedJobMap[pj.InternalJobID] = pj + } + + for i := range jobs { + if jobs[i].Mode != shared.NOPModeCL { + continue + } + if pj, ok := proposedJobMap[jobs[i].JobID]; ok { + jobs[i].JDJobID = pj.JobID + jobs[i].NodeID = pj.NodeID + jobs[i].AddProposal(shared.ProposalRevision{ + ProposalID: pj.ProposalID, + Revision: pj.Revision, + Status: shared.JobProposalStatusPending, + Spec: pj.Spec, + }) + } + } +} + +func extractExpectedJobsByNOP(jobs []shared.JobInfo) map[shared.NOPAlias]map[shared.JobID]bool { + result := make(map[shared.NOPAlias]map[shared.JobID]bool) + for _, job := range jobs { + if result[job.NOPAlias] == nil { + result[job.NOPAlias] = make(map[shared.JobID]bool) + } + result[job.NOPAlias][job.JobID] = true + } + return result +} + +func filterCLModeJobs(jobs []shared.JobInfo) []shared.JobInfo { + result := make([]shared.JobInfo, 0) + for _, j := range jobs { + if j.Mode == shared.NOPModeCL { + result = append(result, j) + } + } + return result +} + +func carryForwardExistingJobMetadata(jobs []shared.JobInfo, existingJobs shared.NOPJobs) { + if existingJobs == nil { + return + } + for i := range jobs { + nopJobs, ok := existingJobs[jobs[i].NOPAlias] + if !ok { + continue + } + existing, ok := nopJobs[jobs[i].JobID] + if !ok { + continue + } + jobs[i].JDJobID = existing.JDJobID + jobs[i].NodeID = existing.NodeID + jobs[i].ActiveProposalID = existing.ActiveProposalID + jobs[i].Proposals = existing.Proposals + } +} + +func filterNonRevokedJobs(jobs []shared.JobInfo) []shared.JobInfo { + result := make([]shared.JobInfo, 0, len(jobs)) + for _, j := range jobs { + if j.LatestStatus() != shared.JobProposalStatusRevoked { + result = append(result, j) + } + } + return result +} + +func detectCLToStandaloneTransitions(newJobs []shared.JobInfo, existingJobs shared.NOPJobs) []shared.JobInfo { + if existingJobs == nil { + return nil + } + var transitioned []shared.JobInfo + for _, newJob := range newJobs { + if newJob.Mode != shared.NOPModeStandalone { + continue + } + nopJobs, ok := existingJobs[newJob.NOPAlias] + if !ok { + continue + } + existing, ok := nopJobs[newJob.JobID] + if !ok { + continue + } + if existing.Mode == shared.NOPModeCL && existing.JDJobID != "" { + transitioned = append(transitioned, existing) + } + } + return transitioned +} + +func clearJDMetadata(jobs []shared.JobInfo, transitioned []shared.JobInfo) { + transitionedSet := make(map[shared.JobID]bool, len(transitioned)) + for _, t := range transitioned { + transitionedSet[t.JobID] = true + } + for i := range jobs { + if transitionedSet[jobs[i].JobID] { + jobs[i].JDJobID = "" + jobs[i].NodeID = "" + jobs[i].ActiveProposalID = "" + jobs[i].Proposals = nil + } + } +} + +func filterChangedJobs(newJobs []shared.JobInfo, existingJobs shared.NOPJobs) []shared.JobInfo { + if existingJobs == nil { + return newJobs + } + + changed := make([]shared.JobInfo, 0, len(newJobs)) + for _, job := range newJobs { + nopJobs, nopExists := existingJobs[job.NOPAlias] + if !nopExists { + changed = append(changed, job) + continue + } + + existing, jobExists := nopJobs[job.JobID] + if !jobExists { + changed = append(changed, job) + continue + } + + if existing.Mode != job.Mode { + changed = append(changed, job) + continue + } + + latestProposal := existing.LatestProposal() + if latestProposal == nil || latestProposal.Spec != job.Spec { + changed = append(changed, job) + } + } + return changed +} diff --git a/deployment/shared/chain_type_registry.go b/deployment/shared/chain_type_registry.go new file mode 100644 index 000000000..d94ae5a14 --- /dev/null +++ b/deployment/shared/chain_type_registry.go @@ -0,0 +1,54 @@ +package shared + +import ( + "sync" + + nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" +) + +var ( + chainTypeMu sync.RWMutex + chainTypeRegistry = make(map[nodev1.ChainType]string) + + normalizerMu sync.RWMutex + normalizerRegistry = make(map[string]func(string) string) +) + +// RegisterChainTypeFamily maps a JD proto ChainType to its chain-selectors family string. +// Chain-specific packages (e.g. evm) call this from their init() function so that JD +// operations can filter chain configs without hardcoding known families in the core. +func RegisterChainTypeFamily(protoType nodev1.ChainType, family string) { + chainTypeMu.Lock() + defer chainTypeMu.Unlock() + chainTypeRegistry[protoType] = family +} + +// GetChainTypeFamily returns the chain-selectors family string for the given JD proto ChainType. +// Returns false if no chain-specific package has registered a mapping for this type. +func GetChainTypeFamily(protoType nodev1.ChainType) (string, bool) { + chainTypeMu.RLock() + defer chainTypeMu.RUnlock() + f, ok := chainTypeRegistry[protoType] + return f, ok +} + +// RegisterAddressNormalizer registers a chain-family-specific function that canonicalises +// raw signing addresses returned by JD (e.g. lowercase + "0x" prefix for EVM). +// If no normalizer is registered for a family the address is used as-is. +func RegisterAddressNormalizer(family string, fn func(string) string) { + normalizerMu.Lock() + defer normalizerMu.Unlock() + normalizerRegistry[family] = fn +} + +// NormalizeAddress returns the canonical form of addr for the given chain family. +// Falls back to the identity function when no normalizer has been registered. +func NormalizeAddress(family, addr string) string { + normalizerMu.RLock() + fn, ok := normalizerRegistry[family] + normalizerMu.RUnlock() + if !ok { + return addr + } + return fn(addr) +} diff --git a/deployment/shared/chain_validation.go b/deployment/shared/chain_validation.go new file mode 100644 index 000000000..1b1920112 --- /dev/null +++ b/deployment/shared/chain_validation.go @@ -0,0 +1,83 @@ +package shared + +import ( + "fmt" + "strings" + + chainsel "github.com/smartcontractkit/chain-selectors" +) + +const unknownChainName = "unknown" + +type ChainValidationResult struct { + NOPAlias string + MissingChains []uint64 +} + +func ValidateNOPChainSupport( + nopAlias string, + requiredChains []uint64, + supportedChains []uint64, +) *ChainValidationResult { + if len(requiredChains) == 0 { + return nil + } + + supportedSet := make(map[uint64]bool, len(supportedChains)) + for _, s := range supportedChains { + supportedSet[s] = true + } + + var missing []uint64 + for _, required := range requiredChains { + if !supportedSet[required] { + missing = append(missing, required) + } + } + + if len(missing) == 0 { + return nil + } + + return &ChainValidationResult{ + NOPAlias: nopAlias, + MissingChains: missing, + } +} + +func FormatChainValidationError(results []ChainValidationResult) error { + if len(results) == 0 { + return nil + } + + var sb strings.Builder + sb.WriteString("chain support validation failed:\n") + + for _, result := range results { + sb.WriteString(fmt.Sprintf(" NOP %q missing chain configs for:\n", result.NOPAlias)) + for _, chainSelector := range result.MissingChains { + chainName := formatChainName(chainSelector) + sb.WriteString(fmt.Sprintf(" - %d (%s)\n", chainSelector, chainName)) + } + } + + sb.WriteString(" action: ensure configs are created for the missing chains on the node") + + return fmt.Errorf("%s", sb.String()) +} + +func formatChainName(chainSelector uint64) string { + family, err := chainsel.GetSelectorFamily(chainSelector) + if err != nil { + return unknownChainName + } + chainID, err := chainsel.GetChainIDFromSelector(chainSelector) + if err != nil { + return unknownChainName + } + details, err := chainsel.GetChainDetailsByChainIDAndFamily(chainID, family) + if err != nil { + return unknownChainName + } + return details.ChainName +} diff --git a/deployment/shared/jd_client.go b/deployment/shared/jd_client.go new file mode 100644 index 000000000..79a1ee593 --- /dev/null +++ b/deployment/shared/jd_client.go @@ -0,0 +1,21 @@ +package shared + +import ( + "context" + + "google.golang.org/grpc" + + jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" + nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" +) + +// JDClient defines the Job Distributor client methods used by CCV deployment operations. +// This interface is a subset of offchain.Client, containing only the methods required for CCV. +// The framework's offchain.Client satisfies this interface automatically. +type JDClient interface { + ListNodes(ctx context.Context, in *nodev1.ListNodesRequest, opts ...grpc.CallOption) (*nodev1.ListNodesResponse, error) + ListNodeChainConfigs(ctx context.Context, in *nodev1.ListNodeChainConfigsRequest, opts ...grpc.CallOption) (*nodev1.ListNodeChainConfigsResponse, error) + ProposeJob(ctx context.Context, in *jobv1.ProposeJobRequest, opts ...grpc.CallOption) (*jobv1.ProposeJobResponse, error) + RevokeJob(ctx context.Context, in *jobv1.RevokeJobRequest, opts ...grpc.CallOption) (*jobv1.RevokeJobResponse, error) + ListProposals(ctx context.Context, in *jobv1.ListProposalsRequest, opts ...grpc.CallOption) (*jobv1.ListProposalsResponse, error) +} diff --git a/deployment/shared/nodes.go b/deployment/shared/nodes.go new file mode 100644 index 000000000..48da7b0da --- /dev/null +++ b/deployment/shared/nodes.go @@ -0,0 +1,66 @@ +package shared + +import ( + "context" + "fmt" + "strings" + + nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" +) + +type NodeLookup struct { + nodesByName map[string]*nodev1.Node +} + +func NewNodeLookup(nodes []*nodev1.Node) (*NodeLookup, error) { + lookup := &NodeLookup{ + nodesByName: make(map[string]*nodev1.Node), + } + for _, node := range nodes { + key := strings.ToLower(node.Name) + if existing, ok := lookup.nodesByName[key]; ok && existing.Id != node.Id { + return nil, fmt.Errorf("duplicate node name %q: node IDs %s and %s both claim this name", node.Name, existing.Id, node.Id) + } + lookup.nodesByName[key] = node + } + return lookup, nil +} + +func (l *NodeLookup) FindByName(name string) (*nodev1.Node, bool) { + node, ok := l.nodesByName[strings.ToLower(name)] + return node, ok +} + +func NodeIDsToSet(nodeIDs []string) map[string]bool { + if len(nodeIDs) == 0 { + return nil + } + set := make(map[string]bool, len(nodeIDs)) + for _, id := range nodeIDs { + set[id] = true + } + return set +} + +func FetchNodeLookup(ctx context.Context, jdClient JDClient, nodeIDs []string) (*NodeLookup, error) { + if len(nodeIDs) == 0 { + return nil, fmt.Errorf("nodeIDs must be specified - refusing to fetch all nodes for security reasons") + } + + filter := &nodev1.ListNodesRequest_Filter{ + Ids: nodeIDs, + } + + nodesResp, err := jdClient.ListNodes(ctx, &nodev1.ListNodesRequest{ + Filter: filter, + }) + if err != nil { + return nil, fmt.Errorf("failed to list nodes: %w", err) + } + + lookup, err := NewNodeLookup(nodesResp.Nodes) + if err != nil { + return nil, fmt.Errorf("failed to build node lookup: %w", err) + } + return lookup, nil +} diff --git a/deployment/shared/types.go b/deployment/shared/types.go new file mode 100644 index 000000000..217a41a79 --- /dev/null +++ b/deployment/shared/types.go @@ -0,0 +1,215 @@ +package shared + +import ( + "fmt" + "strings" + + "github.com/google/uuid" +) + +type NOPAlias string + +// ChainSupportByNOP maps NOP alias to the chain selectors that node supports. +type ChainSupportByNOP map[string][]uint64 + +// NOPJobSpecs maps NOP alias -> job ID -> job spec TOML. +type NOPJobSpecs map[NOPAlias]map[JobID]string + +// JobProposalStatus represents the state of a job proposal. +type JobProposalStatus string + +const ( + JobProposalStatusPending JobProposalStatus = "pending" + JobProposalStatusApproved JobProposalStatus = "approved" + JobProposalStatusRevoked JobProposalStatus = "revoked" + JobProposalStatusRejected JobProposalStatus = "rejected" +) + +// NOPMode defines how a Node Operator runs its jobs. +type NOPMode string + +const ( + NOPModeCL NOPMode = "cl" + NOPModeStandalone NOPMode = "standalone" +) + +// ProposalRevision tracks a single proposal revision from JD. +type ProposalRevision struct { + ProposalID string `json:"proposalId"` + Revision int64 `json:"revision"` + Status JobProposalStatus `json:"status"` + Spec string `json:"spec"` +} + +// JobInfo contains all metadata about a job and its proposal history. +type JobInfo struct { + JobID JobID `json:"jobId"` + JDJobID string `json:"jdJobId,omitempty"` + ExternalJobID string `json:"externalJobId"` + NOPAlias NOPAlias `json:"nopAlias"` + NodeID string `json:"nodeId,omitempty"` + Mode NOPMode `json:"mode,omitempty"` + + Spec string `json:"spec"` + ActiveProposalID string `json:"activeProposalId,omitempty"` + + Proposals map[string]ProposalRevision `json:"proposals,omitempty"` +} + +func (j *JobInfo) LatestProposal() *ProposalRevision { + if len(j.Proposals) == 0 { + return nil + } + var latest *ProposalRevision + for _, p := range j.Proposals { + if latest == nil || p.Revision > latest.Revision { + latest = &p + } + } + return latest +} + +func (j *JobInfo) IsRunning() bool { + return j.ActiveProposalID != "" +} + +func (j *JobInfo) LatestStatus() JobProposalStatus { + latest := j.LatestProposal() + if latest == nil { + return "" + } + return latest.Status +} + +// NOPJobs maps NOP alias -> job ID -> job info. +type NOPJobs map[NOPAlias]map[JobID]JobInfo + +type MonitoringInput struct { + Enabled bool + Type string + Beholder BeholderInput +} + +type BeholderInput struct { + InsecureConnection bool + CACertFile string + OtelExporterGRPCEndpoint string + OtelExporterHTTPEndpoint string + LogStreamingEnabled bool + MetricReaderInterval int64 + TraceSampleRatio float64 + TraceBatchTimeout int64 +} + +type JobID string + +// CCVJobNamespace is a UUID v5 namespace for generating deterministic external job IDs. +var CCVJobNamespace = uuid.MustParse("a1b2c3d4-e5f6-4a5b-8c9d-0e1f2a3b4c5d") + +func (id JobID) ToExternalJobID() string { + return uuid.NewSHA1(CCVJobNamespace, []byte(id)).String() +} + +type JobScope interface { + IsJobInScope(jobID JobID) bool +} + +type ExecutorJobID struct { + NOPAlias NOPAlias + Scope ExecutorJobScope +} + +type ExecutorJobScope struct { + ExecutorQualifier string +} + +func NewExecutorJobID(nopAlias NOPAlias, scope ExecutorJobScope) ExecutorJobID { + return ExecutorJobID{ + NOPAlias: nopAlias, + Scope: scope, + } +} + +func (id ExecutorJobID) ToJobID() JobID { + return JobID(fmt.Sprintf("%s-%s-executor", string(id.NOPAlias), id.Scope.ExecutorQualifier)) +} + +func (id ExecutorJobID) GetExecutorID() string { + return string(id.NOPAlias) +} + +func (scope ExecutorJobScope) IsJobInScope(jobID JobID) bool { + return strings.HasSuffix(string(jobID), fmt.Sprintf("-%s-executor", scope.ExecutorQualifier)) +} + +type VerifierJobScope struct { + CommitteeQualifier string +} + +type VerifierJobID struct { + NOPAlias NOPAlias + CommitteeQualifier string + AggregatorName string +} + +func NewVerifierJobID(nopAlias NOPAlias, aggregatorName string, scope VerifierJobScope) VerifierJobID { + return VerifierJobID{ + NOPAlias: nopAlias, + CommitteeQualifier: scope.CommitteeQualifier, + AggregatorName: aggregatorName, + } +} + +func (id VerifierJobID) GetVerifierID() string { + return fmt.Sprintf("%s-%s-verifier", id.AggregatorName, id.CommitteeQualifier) +} + +func (id VerifierJobID) ToJobID() JobID { + return JobID(fmt.Sprintf("%s-%s-%s-verifier", string(id.NOPAlias), id.AggregatorName, id.CommitteeQualifier)) +} + +func (scope VerifierJobScope) IsJobInScope(jobID JobID) bool { + return strings.HasSuffix(string(jobID), fmt.Sprintf("-%s-verifier", scope.CommitteeQualifier)) +} + +func ConvertNopAliasToString(aliases []NOPAlias) []string { + str := make([]string, len(aliases)) + for i, alias := range aliases { + str[i] = string(alias) + } + return str +} + +func ConvertStringToNopAliases(strs []string) []NOPAlias { + aliases := make([]NOPAlias, len(strs)) + for i, alias := range strs { + aliases[i] = NOPAlias(alias) + } + return aliases +} + +func IsProductionEnvironment(env string) bool { + return env == "mainnet" +} + +func NOPAliasSliceToSet(slice []NOPAlias) map[NOPAlias]bool { + if len(slice) == 0 { + return nil + } + set := make(map[NOPAlias]bool, len(slice)) + for _, v := range slice { + set[v] = true + } + return set +} + +func (j *JobInfo) AddProposal(p ProposalRevision) { + if j.Proposals == nil { + j.Proposals = make(map[string]ProposalRevision) + } + j.Proposals[p.ProposalID] = p +} + +func (j *JobInfo) SetActiveProposal(proposalID string) { + j.ActiveProposalID = proposalID +} diff --git a/deployment/token_verifier.go b/deployment/token_verifier.go new file mode 100644 index 000000000..1eb6b201d --- /dev/null +++ b/deployment/token_verifier.go @@ -0,0 +1,55 @@ +package deployment + +import "time" + +type TokenVerifierGeneratedConfig struct { + PyroscopeURL string `json:"pyroscope_url"` + OnRampAddresses map[string]string `json:"on_ramp_addresses"` + RMNRemoteAddresses map[string]string `json:"rmn_remote_addresses"` + TokenVerifiers []TokenVerifierEntry `json:"token_verifiers"` + Monitoring TokenVerifierMonitoringConfig `json:"monitoring"` +} + +type TokenVerifierEntry struct { + VerifierID string `json:"verifier_id"` + Type string `json:"type"` + Version string `json:"version"` + CCTP *CCTPVerifierConfig `json:"cctp,omitempty"` + Lombard *LombardVerifierConfig `json:"lombard,omitempty"` +} + +type CCTPVerifierConfig struct { + AttestationAPI string `json:"attestation_api"` + AttestationAPITimeout time.Duration `json:"attestation_api_timeout"` + AttestationAPIInterval time.Duration `json:"attestation_api_interval"` + AttestationAPICooldown time.Duration `json:"attestation_api_cooldown"` + VerifierVersion []byte `json:"verifier_version"` + Verifiers map[string]string `json:"verifiers"` + VerifierResolvers map[string]string `json:"verifier_resolvers"` +} + +type LombardVerifierConfig struct { + AttestationAPI string `json:"attestation_api"` + AttestationAPITimeout time.Duration `json:"attestation_api_timeout"` + AttestationAPIInterval time.Duration `json:"attestation_api_interval"` + AttestationAPIBatchSize int `json:"attestation_api_batch_size"` + VerifierVersion []byte `json:"verifier_version"` + VerifierResolvers map[string]string `json:"verifier_resolvers"` +} + +type TokenVerifierMonitoringConfig struct { + Enabled bool `json:"enabled"` + Type string `json:"type"` + Beholder TokenVerifierBeholderConfig `json:"beholder"` +} + +type TokenVerifierBeholderConfig struct { + InsecureConnection bool `json:"insecure_connection"` + CACertFile string `json:"ca_cert_file"` + OtelExporterGRPCEndpoint string `json:"otel_exporter_grpc_endpoint"` + OtelExporterHTTPEndpoint string `json:"otel_exporter_http_endpoint"` + LogStreamingEnabled bool `json:"log_streaming_enabled"` + MetricReaderInterval int64 `json:"metric_reader_interval"` + TraceSampleRatio float64 `json:"trace_sample_ratio"` + TraceBatchTimeout int64 `json:"trace_batch_timeout"` +} diff --git a/deployment/topology.go b/deployment/topology.go new file mode 100644 index 000000000..1d889cf3d --- /dev/null +++ b/deployment/topology.go @@ -0,0 +1,381 @@ +package deployment + +import ( + "fmt" + "os" + "slices" + "strconv" + "strings" + "time" + + "github.com/BurntSushi/toml" + "github.com/Masterminds/semver/v3" + + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +// EnvironmentTopology holds all environment-specific configuration that cannot be inferred +// from the datastore. This serves as the single source of truth for the desired state of both off-chain +// (job specs) and on-chain (committee contracts) configuration. +type EnvironmentTopology struct { + IndexerAddress []string `toml:"indexer_address"` + PyroscopeURL string `toml:"pyroscope_url"` + Monitoring MonitoringConfig `toml:"monitoring"` + NOPTopology *NOPTopology `toml:"nop_topology"` + ExecutorPools map[string]ExecutorPoolConfig `toml:"executor_pools"` +} + +// NOPTopology defines the node operator structure and committee membership. +type NOPTopology struct { + NOPs []NOPConfig `toml:"nops"` + Committees map[string]CommitteeConfig `toml:"committees"` + + nopIndex map[string]int +} + +func (t *NOPTopology) GetNOP(alias string) (NOPConfig, bool) { + t.ensureIndex() + idx, ok := t.nopIndex[alias] + if !ok { + return NOPConfig{}, false + } + return t.NOPs[idx], true +} + +func (t *NOPTopology) GetNOPIndex(alias string) (int, bool) { + t.ensureIndex() + idx, ok := t.nopIndex[alias] + return idx, ok +} + +func (t *NOPTopology) SetNOPSignerAddress(alias, family, addr string) bool { + t.ensureIndex() + idx, ok := t.nopIndex[alias] + if !ok { + return false + } + + if t.NOPs[idx].SignerAddressByFamily == nil { + t.NOPs[idx].SignerAddressByFamily = make(map[string]string) + } + + t.NOPs[idx].SignerAddressByFamily[family] = addr + return true +} + +func (t *NOPTopology) HasNOP(alias string) bool { + t.ensureIndex() + _, ok := t.nopIndex[alias] + return ok +} + +func (t *NOPTopology) ensureIndex() { + if t.nopIndex != nil { + return + } + t.nopIndex = make(map[string]int, len(t.NOPs)) + for i, nop := range t.NOPs { + t.nopIndex[nop.Alias] = i + } +} + +// NOPConfig defines a Node Operator. +type NOPConfig struct { + Alias string `toml:"alias"` + Name string `toml:"name"` + SignerAddressByFamily map[string]string `toml:"signer_address_by_family,omitempty"` + Mode shared.NOPMode `toml:"mode,omitempty"` +} + +func (n *NOPConfig) GetMode() shared.NOPMode { + if n.Mode == "" { + return shared.NOPModeCL + } + return n.Mode +} + +// CommitteeConfig defines a committee and its per-chain membership. +type CommitteeConfig struct { + Qualifier string `toml:"qualifier"` + VerifierVersion *semver.Version `toml:"verifier_version"` + StorageLocations []string `toml:"storage_locations,omitempty"` + ChainConfigs map[string]ChainCommitteeConfig `toml:"chain_configs"` + Aggregators []AggregatorConfig `toml:"aggregators"` +} + +// ChainCommitteeConfig defines committee membership and on-chain parameters for a specific chain. +type ChainCommitteeConfig struct { + NOPAliases []string `toml:"nop_aliases"` + Threshold uint8 `toml:"threshold"` + FeeAggregator string `toml:"fee_aggregator,omitempty"` + AllowlistAdmin string `toml:"allowlist_admin,omitempty"` +} + +type AggregatorConfig struct { + Name string `toml:"name"` + Address string `toml:"address"` + InsecureAggregatorConnection bool `toml:"insecure_connection"` +} + +// ExecutorPoolConfig defines executor pool membership and configuration. +type ExecutorPoolConfig struct { + ChainConfigs map[string]ChainExecutorPoolConfig `toml:"chain_configs"` + IndexerQueryLimit uint64 `toml:"indexer_query_limit"` + BackoffDuration time.Duration `toml:"backoff_duration"` + LookbackWindow time.Duration `toml:"lookback_window"` + ReaderCacheExpiry time.Duration `toml:"reader_cache_expiry"` + MaxRetryDuration time.Duration `toml:"max_retry_duration"` + WorkerCount int `toml:"worker_count"` + NtpServer string `toml:"ntp_server"` +} + +// ChainExecutorPoolConfig defines executor pool membership and execution interval for a single chain. +type ChainExecutorPoolConfig struct { + NOPAliases []string `toml:"nop_aliases"` + ExecutionInterval time.Duration `toml:"execution_interval"` +} + +type MonitoringConfig struct { + Enabled bool `toml:"Enabled"` + Type string `toml:"Type"` + Beholder BeholderConfig `toml:"Beholder"` +} + +type BeholderConfig struct { + InsecureConnection bool `toml:"InsecureConnection"` + CACertFile string `toml:"CACertFile"` + OtelExporterGRPCEndpoint string `toml:"OtelExporterGRPCEndpoint"` + OtelExporterHTTPEndpoint string `toml:"OtelExporterHTTPEndpoint"` + LogStreamingEnabled bool `toml:"LogStreamingEnabled"` + MetricReaderInterval int64 `toml:"MetricReaderInterval"` + TraceSampleRatio float64 `toml:"TraceSampleRatio"` + TraceBatchTimeout int64 `toml:"TraceBatchTimeout"` +} + +func LoadEnvironmentTopology(path string) (*EnvironmentTopology, error) { + data, err := os.ReadFile(path) //nolint:gosec // G304: path is provided by trusted caller + if err != nil { + return nil, fmt.Errorf("failed to read environment topology file: %w", err) + } + + var cfg EnvironmentTopology + if err := toml.Unmarshal(data, &cfg); err != nil { + return nil, fmt.Errorf("failed to parse environment topology TOML: %w", err) + } + + if err := cfg.Validate(); err != nil { + return nil, fmt.Errorf("environment topology validation failed: %w", err) + } + + return &cfg, nil +} + +func WriteEnvironmentTopology(path string, cfg EnvironmentTopology) error { + if err := cfg.Validate(); err != nil { + return fmt.Errorf("environment topology validation failed: %w", err) + } + + data, err := toml.Marshal(cfg) + if err != nil { + return fmt.Errorf("failed to marshal environment topology to TOML: %w", err) + } + + if err := os.WriteFile(path, data, 0o600); err != nil { + return fmt.Errorf("failed to write environment topology file: %w", err) + } + + return nil +} + +func (c *EnvironmentTopology) Validate() error { + if len(c.IndexerAddress) == 0 { + return fmt.Errorf("indexer_address is required") + } + + addressSet := make(map[string]struct{}, len(c.IndexerAddress)) + for _, addr := range c.IndexerAddress { + if addr == "" { + return fmt.Errorf("indexer_address is required") + } + if _, exists := addressSet[addr]; exists { + return fmt.Errorf("duplicate indexer_address found: %q", addr) + } + addressSet[addr] = struct{}{} + } + + if err := c.NOPTopology.Validate(); err != nil { + return fmt.Errorf("nop_topology validation failed: %w", err) + } + + for poolName, pool := range c.ExecutorPools { + if err := pool.Validate(poolName, c.NOPTopology); err != nil { + return fmt.Errorf("executor_pool %q validation failed: %w", poolName, err) + } + } + + return nil +} + +func (t *NOPTopology) Validate() error { + seen := make(map[string]struct{}, len(t.NOPs)) + for _, nop := range t.NOPs { + if nop.Alias == "" { + return fmt.Errorf("NOP alias is required") + } + if _, exists := seen[nop.Alias]; exists { + return fmt.Errorf("duplicate NOP alias %q", nop.Alias) + } + seen[nop.Alias] = struct{}{} + if nop.Name == "" { + return fmt.Errorf("NOP %q name is required", nop.Alias) + } + } + + for qualifier, committee := range t.Committees { + if committee.Qualifier != qualifier { + return fmt.Errorf("committee qualifier mismatch: key %q != qualifier %q", qualifier, committee.Qualifier) + } + if err := committee.Validate(t); err != nil { + return fmt.Errorf("committee %q validation failed: %w", qualifier, err) + } + } + + return nil +} + +func (c *CommitteeConfig) Validate(topology *NOPTopology) error { + if len(c.Aggregators) == 0 { + return fmt.Errorf("at least one aggregator is required") + } + + for _, agg := range c.Aggregators { + if agg.Name == "" { + return fmt.Errorf("aggregator name is required") + } + if agg.Address == "" { + return fmt.Errorf("aggregator %q address is required", agg.Name) + } + } + + for chainSelector, chainCfg := range c.ChainConfigs { + if _, err := strconv.ParseUint(chainSelector, 10, 64); err != nil { + return fmt.Errorf("committee chain_configs has invalid chain selector key %q: %w", chainSelector, err) + } + if len(chainCfg.NOPAliases) == 0 { + return fmt.Errorf("chain %q requires at least one NOP", chainSelector) + } + for _, alias := range chainCfg.NOPAliases { + if !topology.HasNOP(alias) { + return fmt.Errorf("chain %q references unknown NOP alias %q", chainSelector, alias) + } + } + if chainCfg.Threshold == 0 { + return fmt.Errorf("chain %q threshold must be greater than 0", chainSelector) + } + if int(chainCfg.Threshold) > len(chainCfg.NOPAliases) { + return fmt.Errorf("chain %q threshold %d exceeds NOP count %d", chainSelector, chainCfg.Threshold, len(chainCfg.NOPAliases)) + } + } + + return nil +} + +func (p *ExecutorPoolConfig) Validate(poolName string, topology *NOPTopology) error { + if len(p.ChainConfigs) == 0 { + return fmt.Errorf("executor pool %q requires non-empty chain_configs", poolName) + } + for chainSelector, chainCfg := range p.ChainConfigs { + if _, err := strconv.ParseUint(chainSelector, 10, 64); err != nil { + return fmt.Errorf("executor pool %q has invalid chain selector key %q: %w", poolName, chainSelector, err) + } + if len(chainCfg.NOPAliases) == 0 { + return fmt.Errorf("executor pool %q chain %q requires at least one NOP", poolName, chainSelector) + } + for _, alias := range chainCfg.NOPAliases { + if !topology.HasNOP(alias) { + return fmt.Errorf("executor pool %q chain %q references unknown NOP alias %q", poolName, chainSelector, alias) + } + } + } + return nil +} + +func (c *EnvironmentTopology) GetNOPsForPool(poolName string) ([]string, error) { + pool, ok := c.ExecutorPools[poolName] + if !ok { + return nil, fmt.Errorf("executor pool %q not found", poolName) + } + nopSet := make(map[string]struct{}) + for _, chainCfg := range pool.ChainConfigs { + for _, alias := range chainCfg.NOPAliases { + nopSet[alias] = struct{}{} + } + } + nops := make([]string, 0, len(nopSet)) + for alias := range nopSet { + nops = append(nops, alias) + } + slices.Sort(nops) + return nops, nil +} + +func (c *EnvironmentTopology) GetNOPsForCommittee(committeeQualifier string) ([]string, error) { + committee, ok := c.NOPTopology.Committees[committeeQualifier] + if !ok { + return nil, fmt.Errorf("committee %q not found", committeeQualifier) + } + + nopSet := make(map[string]struct{}) + for _, chainCfg := range committee.ChainConfigs { + for _, alias := range chainCfg.NOPAliases { + nopSet[alias] = struct{}{} + } + } + + nops := make([]string, 0, len(nopSet)) + for alias := range nopSet { + nops = append(nops, alias) + } + slices.Sort(nops) + + return nops, nil +} + +func (c *EnvironmentTopology) GetCommitteesForNOP(nopAlias string) []string { + var committees []string + for qualifier, committee := range c.NOPTopology.Committees { + for _, chainCfg := range committee.ChainConfigs { + if slices.Contains(chainCfg.NOPAliases, nopAlias) { + committees = append(committees, qualifier) + break + } + } + } + return committees +} + +func (c *EnvironmentTopology) GetPoolsForNOP(nopAlias string) []string { + var pools []string + for poolName, pool := range c.ExecutorPools { + for _, chainCfg := range pool.ChainConfigs { + if slices.Contains(chainCfg.NOPAliases, nopAlias) { + pools = append(pools, poolName) + break + } + } + } + return pools +} + +func (c *EnvironmentTopology) GetAggregatorNamesForCommittee(name string) ([]string, error) { + for _, committee := range c.NOPTopology.Committees { + if strings.EqualFold(committee.Qualifier, name) { + names := make([]string, len(committee.Aggregators)) + for i, agg := range committee.Aggregators { + names[i] = agg.Name + } + return names, nil + } + } + return nil, fmt.Errorf("no aggregators found for committee: %s", name) +} diff --git a/evm/aggregator_config.go b/evm/aggregator_config.go new file mode 100644 index 000000000..af2f5c1ea --- /dev/null +++ b/evm/aggregator_config.go @@ -0,0 +1,29 @@ +package evm + +import ( + "context" + "fmt" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" +) + +type evmAggregatorConfigAdapter struct{} + +// ScanCommitteeStates queries the EVM chain for all deployed committee verifier contracts +// and returns their on-chain state (signers, thresholds, etc.) for the aggregator config. +func (a *evmAggregatorConfigAdapter) ScanCommitteeStates(ctx context.Context, env deployment.Environment, chainSelector uint64) ([]*adapters.CommitteeState, error) { + // TODO: call EVM committee verifier contracts on the given chain to enumerate + // deployed committee states and return their signer/threshold configs. + return nil, fmt.Errorf("EVM aggregator config adapter not yet implemented for chain %d", chainSelector) +} + +// ResolveVerifierAddress returns the committee verifier contract address stored in the +// EVM-specific datastore entry for the given chain and qualifier. +func (a *evmAggregatorConfigAdapter) ResolveVerifierAddress(ds datastore.DataStore, chainSelector uint64, qualifier string) (string, error) { + // TODO: read the verifier address from the EVM datastore entry for this + // chainSelector and qualifier. + return "", fmt.Errorf("EVM aggregator config adapter not yet implemented for chain %d", chainSelector) +} diff --git a/evm/executor_config.go b/evm/executor_config.go new file mode 100644 index 000000000..90144d56b --- /dev/null +++ b/evm/executor_config.go @@ -0,0 +1,26 @@ +package evm + +import ( + "fmt" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + + "github.com/smartcontractkit/chainlink-ccv/executor" +) + +type evmExecutorConfigAdapter struct{} + +// GetDeployedChains returns EVM chain selectors that have executor contracts deployed +// for the given qualifier, as recorded in the datastore. +func (a *evmExecutorConfigAdapter) GetDeployedChains(ds datastore.DataStore, qualifier string) []uint64 { + // TODO: query EVM contract addresses from the datastore keyed by qualifier. + return nil +} + +// BuildChainConfig reads EVM-specific contract addresses from the datastore and returns +// the executor chain configuration for the given chain selector and qualifier. +func (a *evmExecutorConfigAdapter) BuildChainConfig(ds datastore.DataStore, chainSelector uint64, qualifier string) (executor.ChainConfiguration, error) { + // TODO: resolve OffRampAddress, RmnAddress, DefaultExecutorAddress from the + // EVM-specific datastore entries for this chainSelector and qualifier. + return executor.ChainConfiguration{}, fmt.Errorf("EVM executor config adapter not yet implemented for chain %d", chainSelector) +} diff --git a/evm/go.mod b/evm/go.mod new file mode 100644 index 000000000..96fd6cea5 --- /dev/null +++ b/evm/go.mod @@ -0,0 +1,220 @@ +module github.com/smartcontractkit/chainlink-ccv/evm + +go 1.25.7 + +replace ( + github.com/fbsobreira/gotron-sdk => github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.4 + github.com/smartcontractkit/chainlink-ccv => .. + github.com/smartcontractkit/chainlink-ccv/deployment => ../deployment +) + +require ( + github.com/smartcontractkit/chain-selectors v1.0.98 + github.com/smartcontractkit/chainlink-ccv v0.0.0 + github.com/smartcontractkit/chainlink-ccv/deployment v0.0.0 + github.com/smartcontractkit/chainlink-deployments-framework v0.94.1 + github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 +) + +require ( + filippo.io/edwards25519 v1.1.1 // indirect + github.com/BurntSushi/toml v1.5.0 // indirect + github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/Microsoft/go-winio v0.6.2 // indirect + github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect + github.com/XSAM/otelsql v0.37.0 // indirect + github.com/aptos-labs/aptos-go-sdk v1.12.0 // indirect + github.com/avast/retry-go/v4 v4.7.0 // indirect + github.com/bahlo/generic-list-go v0.2.0 // indirect + github.com/benbjohnson/clock v1.3.5 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bits-and-blooms/bitset v1.24.0 // indirect + github.com/blendle/zapdriver v1.3.1 // indirect + github.com/block-vision/sui-go-sdk v1.1.4 // indirect + github.com/btcsuite/btcd v0.24.2 // indirect + github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect + github.com/btcsuite/btcd/btcutil v1.1.6 // indirect + github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect + github.com/btcsuite/btcutil v1.0.2 // indirect + github.com/buger/jsonparser v1.1.1 // indirect + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect + github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.2 // indirect + github.com/cloudevents/sdk-go/v2 v2.16.2 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/coder/websocket v1.8.14 // indirect + github.com/consensys/gnark-crypto v0.19.2 // indirect + github.com/cosmos/go-bip39 v1.0.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect + github.com/creachadair/jrpc2 v1.2.0 // indirect + github.com/creachadair/mds v0.13.4 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/deckarep/golang-set/v2 v2.8.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect + github.com/digital-asset/dazl-client/v8 v8.9.0 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.6 // indirect + github.com/ethereum/go-ethereum v1.17.1 // indirect + github.com/fatih/color v1.18.0 // indirect + github.com/fbsobreira/gotron-sdk v0.0.0-20250403083053-2943ce8c759b // indirect + github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/gabriel-vasile/mimetype v1.4.13 // indirect + github.com/gagliardetto/binary v0.8.0 // indirect + github.com/gagliardetto/solana-go v1.13.0 // indirect + github.com/gagliardetto/treeout v0.1.4 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/gin-gonic/gin v1.10.1 // indirect + github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 // indirect + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-playground/validator/v10 v10.30.1 // indirect + github.com/go-viper/mapstructure/v2 v2.5.0 // indirect + github.com/goccy/go-json v0.10.5 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gorilla/websocket v1.5.3 // indirect + github.com/grafana/otel-profiling-go v0.5.1 // indirect + github.com/grafana/pyroscope-go v1.2.8 // indirect + github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 // indirect + github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect + github.com/hashicorp/go-plugin v1.7.0 // indirect + github.com/hashicorp/yamux v0.1.2 // indirect + github.com/hasura/go-graphql-client v0.15.1 // indirect + github.com/hdevalence/ed25519consensus v0.2.0 // indirect + github.com/holiman/uint256 v1.3.2 // indirect + github.com/invopop/jsonschema v0.13.0 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgconn v1.14.3 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.3.3 // indirect + github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect + github.com/jackc/pgtype v1.14.4 // indirect + github.com/jackc/pgx/v4 v4.18.3 // indirect + github.com/jinzhu/copier v0.4.0 // indirect + github.com/jmoiron/sqlx v1.4.0 // indirect + github.com/jpillora/backoff v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 // indirect + github.com/klauspost/compress v1.18.4 // indirect + github.com/klauspost/cpuid/v2 v2.2.10 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/lib/pq v1.11.1 // indirect + github.com/logrusorgru/aurora v2.0.3+incompatible // indirect + github.com/mailru/easyjson v0.9.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mfridman/interpolate v0.0.2 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oklog/run v1.2.0 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.2.4 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/pressly/goose/v3 v3.26.0 // indirect + github.com/prometheus/client_golang v1.23.2 // indirect + github.com/prometheus/client_model v0.6.2 // indirect + github.com/prometheus/common v0.66.1 // indirect + github.com/prometheus/procfs v0.16.1 // indirect + github.com/samber/lo v1.52.0 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect + github.com/scylladb/go-reflectx v1.0.1 // indirect + github.com/sethvargo/go-retry v0.3.0 // indirect + github.com/shirou/gopsutil v3.21.11+incompatible // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 // indirect + github.com/smartcontractkit/chainlink-aptos v0.0.0-20260306142855-8d629e752265 // indirect + github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d // indirect + github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 // indirect + github.com/smartcontractkit/chainlink-common v0.11.2-0.20260407150650-8115835abd6e // indirect + github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect + github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d // indirect + github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f // indirect + github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b // indirect + github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260211172625-dff40e83b3c9 // indirect + github.com/smartcontractkit/chainlink-sui v0.0.0-20260205175622-33e65031f9a9 // indirect + github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 // indirect + github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250908203554-5bd9d2fe9513 // indirect + github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad // indirect + github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect + github.com/smartcontractkit/libocr v0.0.0-20260304194147-a03701e2c02e // indirect + github.com/smartcontractkit/mcms v0.40.1 // indirect + github.com/spf13/cast v1.10.0 // indirect + github.com/stellar/go-stellar-sdk v0.1.0 // indirect + github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2 // indirect + github.com/stephenlacy/go-ethereum-hdwallet v0.0.0-20230913225845-a4fa94429863 // indirect + github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/testify v1.11.1 // indirect + github.com/supranational/blst v0.3.16 // indirect + github.com/tidwall/gjson v1.18.0 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/tklauser/go-sysconf v0.3.16 // indirect + github.com/tklauser/numcpus v0.11.0 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/tyler-smith/go-bip39 v1.1.0 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/valyala/fastjson v1.6.10 // indirect + github.com/wk8/go-ordered-map/v2 v2.1.8 // indirect + github.com/x448/float16 v0.8.4 // indirect + github.com/xssnick/tonutils-go v1.14.1 // indirect + github.com/yusufpapurcu/wmi v1.2.4 // indirect + github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6 // indirect + go.mongodb.org/mongo-driver v1.17.2 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect + go.opentelemetry.io/otel v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 // indirect + go.opentelemetry.io/otel/log v0.15.0 // indirect + go.opentelemetry.io/otel/metric v1.43.0 // indirect + go.opentelemetry.io/otel/sdk v1.43.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect + go.opentelemetry.io/otel/trace v1.43.0 // indirect + go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/ratelimit v0.3.1 // indirect + go.uber.org/zap v1.27.1 // indirect + go.yaml.in/yaml/v2 v2.4.2 // indirect + golang.org/x/arch v0.8.0 // indirect + golang.org/x/crypto v0.48.0 // indirect + golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect + golang.org/x/net v0.50.0 // indirect + golang.org/x/oauth2 v0.35.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/sys v0.42.0 // indirect + golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect + golang.org/x/time v0.14.0 // indirect + golang.org/x/tools v0.42.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/grpc v1.80.0 // indirect + google.golang.org/protobuf v1.36.11 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/evm/go.sum b/evm/go.sum new file mode 100644 index 000000000..5ce7cbdc3 --- /dev/null +++ b/evm/go.sum @@ -0,0 +1,1156 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dario.cat/mergo v1.0.2 h1:85+piFYR1tMbRrLcDwR18y4UKJ3aH1Tbzi24VRW1TK8= +dario.cat/mergo v1.0.2/go.mod h1:E/hbnu0NxMFBjpMIE34DRGLWqDy0g5FuKDhCb31ngxA= +filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +filippo.io/edwards25519 v1.1.1 h1:YpjwWWlNmGIDyXOn8zLzqiD+9TyIlPhGFG96P39uBpw= +filippo.io/edwards25519 v1.1.1/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= +github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI= +github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= +github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= +github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/DataDog/zstd v1.5.6 h1:LbEglqepa/ipmmQJUDnSsfvA8e8IStVcGaFWDuxvGOY= +github.com/DataDog/zstd v1.5.6/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= +github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI= +github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0= +github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU= +github.com/XSAM/otelsql v0.37.0 h1:ya5RNw028JW0eJW8Ma4AmoKxAYsJSGuNVbC7F1J457A= +github.com/XSAM/otelsql v0.37.0/go.mod h1:LHbCu49iU8p255nCn1oi04oX2UjSoRcUMiKEHo2a5qM= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/apache/arrow-go/v18 v18.3.1 h1:oYZT8FqONiK74JhlH3WKVv+2NKYoyZ7C2ioD4Dj3ixk= +github.com/apache/arrow-go/v18 v18.3.1/go.mod h1:12QBya5JZT6PnBihi5NJTzbACrDGXYkrgjujz3MRQXU= +github.com/aptos-labs/aptos-go-sdk v1.12.0 h1:deHZ7NJlFhHm2i+eaPHt6EPa3BuXXnIYx2X5J3/U0Es= +github.com/aptos-labs/aptos-go-sdk v1.12.0/go.mod h1:FTgKp0RLfEefllCdkCj0jPU14xWk11yA7SFVfCDLUj8= +github.com/avast/retry-go/v4 v4.7.0 h1:yjDs35SlGvKwRNSykujfjdMxMhMQQM0TnIjJaHB+Zio= +github.com/avast/retry-go/v4 v4.7.0/go.mod h1:ZMPDa3sY2bKgpLtap9JRUgk2yTAba7cgiFhqxY2Sg6Q= +github.com/aws/aws-sdk-go-v2 v1.41.4 h1:10f50G7WyU02T56ox1wWXq+zTX9I1zxG46HYuG1hH/k= +github.com/aws/aws-sdk-go-v2 v1.41.4/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= +github.com/aws/aws-sdk-go-v2/config v1.32.12 h1:O3csC7HUGn2895eNrLytOJQdoL2xyJy0iYXhoZ1OmP0= +github.com/aws/aws-sdk-go-v2/config v1.32.12/go.mod h1:96zTvoOFR4FURjI+/5wY1vc1ABceROO4lWgWJuxgy0g= +github.com/aws/aws-sdk-go-v2/credentials v1.19.12 h1:oqtA6v+y5fZg//tcTWahyN9PEn5eDU/Wpvc2+kJ4aY8= +github.com/aws/aws-sdk-go-v2/credentials v1.19.12/go.mod h1:U3R1RtSHx6NB0DvEQFGyf/0sbrpJrluENHdPy1j/3TE= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20 h1:zOgq3uezl5nznfoK3ODuqbhVg1JzAGDUhXOsU0IDCAo= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.20/go.mod h1:z/MVwUARehy6GAg/yQ1GO2IMl0k++cu1ohP9zo887wE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20 h1:CNXO7mvgThFGqOFgbNAP2nol2qAWBOGfqR/7tQlvLmc= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.20/go.mod h1:oydPDJKcfMhgfcgBUZaG+toBbwy8yPWubJXBVERtI4o= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 h1:tN6W/hg+pkM+tf9XDkWUbDEjGLb+raoBMFsTodcoYKw= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20/go.mod h1:YJ898MhD067hSHA6xYCx5ts/jEd8BSOLtQDL3iZsvbc= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 h1:2HvVAIq+YqgGotK6EkMf+KIEqTISmTYh5zLpYyeTo1Y= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20/go.mod h1:V4X406Y666khGa8ghKmphma/7C0DAtEQYhkq9z4vpbk= +github.com/aws/aws-sdk-go-v2/service/kms v1.50.1 h1:wb/PYYm3wlcqGzw7Ls4GD3X5+seDDoNdVYIB6I/V87E= +github.com/aws/aws-sdk-go-v2/service/kms v1.50.1/go.mod h1:xvHowJ6J9CuaFE04S8fitWQXytf4sHz3DTPGhw9FtmU= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.8 h1:0GFOLzEbOyZABS3PhYfBIx2rNBACYcKty+XGkTgw1ow= +github.com/aws/aws-sdk-go-v2/service/signin v1.0.8/go.mod h1:LXypKvk85AROkKhOG6/YEcHFPoX+prKTowKnVdcaIxE= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.13 h1:kiIDLZ005EcKomYYITtfsjn7dtOwHDOFy7IbPXKek2o= +github.com/aws/aws-sdk-go-v2/service/sso v1.30.13/go.mod h1:2h/xGEowcW/g38g06g3KpRWDlT+OTfxxI0o1KqayAB8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17 h1:jzKAXIlhZhJbnYwHbvUQZEB8KfgAEuG0dc08Bkda7NU= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.17/go.mod h1:Al9fFsXjv4KfbzQHGe6V4NZSZQXecFcvaIF4e70FoRA= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.9 h1:Cng+OOwCHmFljXIxpEVXAGMnBia8MSU6Ch5i9PgBkcU= +github.com/aws/aws-sdk-go-v2/service/sts v1.41.9/go.mod h1:LrlIndBDdjA/EeXeyNBle+gyCwTlizzW5ycgWnvIxkk= +github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng= +github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc= +github.com/bahlo/generic-list-go v0.2.0 h1:5sz/EEAK+ls5wF+NeqDpk5+iNdMDXrh3z3nPnH1Wvgk= +github.com/bahlo/generic-list-go v0.2.0/go.mod h1:2KvAjgMlE5NNynlg/5iLrrCCZ2+5xWbdbCW3pNTGyYg= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.24.0 h1:H4x4TuulnokZKvHLfzVRTHJfFfnHEeSYJizujEZvmAM= +github.com/bits-and-blooms/bitset v1.24.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= +github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/block-vision/sui-go-sdk v1.1.4 h1:1PPgYxQjo1P9UCgFOPTvDCuGEglRL32NwjKPulR4FQk= +github.com/block-vision/sui-go-sdk v1.1.4/go.mod h1:t8mWASwfyv+EyqHGO9ZrcDiCJWGOFEXqq50TMJ8GQco= +github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= +github.com/btcsuite/btcd v0.22.0-beta.0.20220111032746-97732e52810c/go.mod h1:tjmYdS6MLJ5/s0Fj4DbLgSbDHbEqLJrtnHecBFkdz5M= +github.com/btcsuite/btcd v0.23.5-0.20231215221805-96c9fd8078fd/go.mod h1:nm3Bko6zh6bWP60UxwoT5LzdGJsQJaPo6HjduXq9p6A= +github.com/btcsuite/btcd v0.24.2 h1:aLmxPguqxza+4ag8R1I2nnJjSu2iFn/kqtHTIImswcY= +github.com/btcsuite/btcd v0.24.2/go.mod h1:5C8ChTkl5ejr3WHj8tkQSCmydiMEPB0ZhQhehpq7Dgg= +github.com/btcsuite/btcd/btcec/v2 v2.1.0/go.mod h1:2VzYrv4Gm4apmbVVsSq5bqf1Ec8v56E48Vt0Y/umPgA= +github.com/btcsuite/btcd/btcec/v2 v2.1.3/go.mod h1:ctjw4H1kknNJmRN4iP1R7bTQ+v3GJkZBd6mui8ZsAZE= +github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= +github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= +github.com/btcsuite/btcd/btcutil v1.0.0/go.mod h1:Uoxwv0pqYWhD//tfTiipkxNfdhG9UrLwaeswfjfdF0A= +github.com/btcsuite/btcd/btcutil v1.1.0/go.mod h1:5OapHB7A2hBBWLm48mmw4MOHNJCcUBTwmWH/0Jn8VHE= +github.com/btcsuite/btcd/btcutil v1.1.5/go.mod h1:PSZZ4UitpLBWzxGd5VGOrLnmOjtPP/a6HaFo12zMs00= +github.com/btcsuite/btcd/btcutil v1.1.6 h1:zFL2+c3Lb9gEgqKNzowKUPQNb8jV7v5Oaodi/AYFd6c= +github.com/btcsuite/btcd/btcutil v1.1.6/go.mod h1:9dFymx8HpuLqBnsPELrImQeTQfKBQqzqGbbV3jK55aE= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 h1:59Kx4K6lzOW5w6nFlA0v5+lk/6sjybR934QNHSJZPTQ= +github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts= +github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/goleveldb v1.0.0/go.mod h1:QiK9vBlgftBg6rWQIj6wFzbPfRjiykIEhBH4obrXJ/I= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/snappy-go v1.0.0/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= +github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= +github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1xcsSM= +github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/cp v1.1.1 h1:nCb6ZLdB7NRaqsm91JtQTAme2SKJzXVsdPIPkyJr1MU= +github.com/cespare/cp v1.1.1/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.2 h1:ydUjnKn4RoCeN8rge3F/deT52w2WJMmIC5mHNUq+Ut8= +github.com/cloudevents/sdk-go/binding/format/protobuf/v2 v2.16.2/go.mod h1:Bny999RuVUtNjzTGa9HCHpXjrLGMipJVq5kqVpudBl0= +github.com/cloudevents/sdk-go/v2 v2.16.2 h1:ZYDFrYke4FD+jM8TZTJJO6JhKHzOQl2oqpFK1D+NnQM= +github.com/cloudevents/sdk-go/v2 v2.16.2/go.mod h1:laOcGImm4nVJEU+PHnUrKL56CKmRL65RlQF0kRmW/kg= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0 h1:pU88SPhIFid6/k0egdR5V6eALQYq2qbSmukrkgIh/0A= +github.com/cockroachdb/fifo v0.0.0-20240816210425-c5d0cb0b6fc0/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/coder/websocket v1.8.14 h1:9L0p0iKiNOibykf283eHkKUHHrpG7f65OE3BhhO7v9g= +github.com/coder/websocket v1.8.14/go.mod h1:NX3SzP+inril6yawo5CQXx8+fk145lPDC6pumgx0mVg= +github.com/consensys/gnark-crypto v0.19.2 h1:qrEAIXq3T4egxqiliFFoNrepkIWVEeIYwt3UL0fvS80= +github.com/consensys/gnark-crypto v0.19.2/go.mod h1:rT23F0XSZqE0mUA0+pRtnL56IbPxs6gp4CeRsBk4XS0= +github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE= +github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6acgLGv/QzE4= +github.com/containerd/platforms v1.0.0-rc.2/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/cosmos/go-bip39 v1.0.0 h1:pcomnQdrdH22njcAatO0yWojsUnCO3y2tNoV1cb6hHY= +github.com/cosmos/go-bip39 v1.0.0/go.mod h1:RNJv0H/pOIVgxw6KS7QeX2a0Uo0aKUlfhZ4xuwvCdJw= +github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GKorA= +github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= +github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= +github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg= +github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/creachadair/jrpc2 v1.2.0 h1:SXr0OgnwM0X18P+HccJP0uT3KGSDk/BCSRlJBvE2bMY= +github.com/creachadair/jrpc2 v1.2.0/go.mod h1:66uKSdr6tR5ZeNvkIjDSbbVUtOv0UhjS/vcd8ECP7Iw= +github.com/creachadair/mds v0.13.4 h1:RgU0MhiVqkzp6/xtNWhK6Pw7tDeaVuGFtA0UA2RBYvY= +github.com/creachadair/mds v0.13.4/go.mod h1:4vrFYUzTXMJpMBU+OA292I6IUxKWCCfZkgXg+/kBZMo= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= +github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= +github.com/cucumber/godog v0.15.1 h1:rb/6oHDdvVZKS66hrhpjFQFHjthFSrQBCOI1LwshNTI= +github.com/cucumber/godog v0.15.1/go.mod h1:qju+SQDewOljHuq9NSM66s0xEhogx0q30flfxL4WUk8= +github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= +github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA= +github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc= +github.com/deckarep/golang-set/v2 v2.8.0 h1:swm0rlPCmdWn9mESxKOjWk8hXSqoxOp+ZlfuyaAdFlQ= +github.com/deckarep/golang-set/v2 v2.8.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/crypto/blake256 v1.1.0 h1:zPMNGQCm0g4QTY27fOCorQW7EryeQ/U0x++OzVrdms8= +github.com/decred/dcrd/crypto/blake256 v1.1.0/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 h1:NMZiJj8QnKe1LgsbDayM4UoHwbvwDRwnI3hwNaAHRnc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0/go.mod h1:ZXNYxsqcloTdSy/rNShjYzMhyjf0LaoftYK0p+A3h40= +github.com/decred/dcrd/lru v1.0.0/go.mod h1:mxKOwFd7lFjN2GZYsiz/ecgqR6kkYAl+0pz0tEMk218= +github.com/deepmap/oapi-codegen v1.8.2 h1:SegyeYGcdi0jLLrpbCMoJxnUUn8GBXHsvr4rbzjuhfU= +github.com/deepmap/oapi-codegen v1.8.2/go.mod h1:YLgSKSDv/bZQB7N4ws6luhozi3cEdRktEqrX88CvjIw= +github.com/digital-asset/dazl-client/v8 v8.9.0 h1:F2qTUWtHAjhGyRGV+xTim+VAFwM99FpcOx4+wowvPnY= +github.com/digital-asset/dazl-client/v8 v8.9.0/go.mod h1:q1KevCJ8FpH8je2MnnjN8/QUfhstB4fKpyKyqDtqFh0= +github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= +github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= +github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= +github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= +github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= +github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= +github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= +github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ethereum/c-kzg-4844/v2 v2.1.6 h1:xQymkKCT5E2Jiaoqf3v4wsNgjZLY0lRSkZn27fRjSls= +github.com/ethereum/c-kzg-4844/v2 v2.1.6/go.mod h1:8HMkUZ5JRv4hpw/XUrYWSQNAUzhHMg2UDb/U+5m+XNw= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8= +github.com/ethereum/go-ethereum v1.17.1 h1:IjlQDjgxg2uL+GzPRkygGULPMLzcYWncEI7wbaizvho= +github.com/ethereum/go-ethereum v1.17.1/go.mod h1:7UWOVHL7K3b8RfVRea022btnzLCaanwHtBuH1jUCH/I= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= +github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= +github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= +github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM= +github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s= +github.com/gagliardetto/binary v0.8.0 h1:U9ahc45v9HW0d15LoN++vIXSJyqR/pWw8DDlhd7zvxg= +github.com/gagliardetto/binary v0.8.0/go.mod h1:2tfj51g5o9dnvsc+fL3Jxr22MuWzYXwx9wEoN0XQ7/c= +github.com/gagliardetto/gofuzz v1.2.2 h1:XL/8qDMzcgvR4+CyRQW9UGdwPRPMHVJfqQ/uMvSUuQw= +github.com/gagliardetto/gofuzz v1.2.2/go.mod h1:bkH/3hYLZrMLbfYWA0pWzXmi5TTRZnu4pMGZBkqMKvY= +github.com/gagliardetto/solana-go v1.13.0 h1:uNzhjwdAdbq9xMaX2DF0MwXNMw6f8zdZ7JPBtkJG7Ig= +github.com/gagliardetto/solana-go v1.13.0/go.mod h1:l/qqqIN6qJJPtxW/G1PF4JtcE3Zg2vD2EliZrr9Gn5k= +github.com/gagliardetto/treeout v0.1.4 h1:ozeYerrLCmCubo1TcIjFiOWTTGteOOHND1twdFpgwaw= +github.com/gagliardetto/treeout v0.1.4/go.mod h1:loUefvXTrlRG5rYmJmExNryyBRh8f89VZhmMOyCyqok= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= +github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.1 h1:T0ujvqyCSqRopADpgPgiTT63DUQVSfojyME59Ei63pQ= +github.com/gin-gonic/gin v1.10.1/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-chi/chi v4.1.2+incompatible h1:fGFk2Gmi/YKXk0OmGfBh0WgmN3XB8lVnEyNz34tQRec= +github.com/go-chi/chi v4.1.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ= +github.com/go-errors/errors v1.5.1 h1:ZwEMSLRCapFLflTpT7NKaAc7ukJ8ZPEjzlxt8rPN8bk= +github.com/go-errors/errors v1.5.1/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874 h1:F8d1AJ6M9UQCavhwmO6ZsrYLfG8zVFWfEfMS2MXPkSY= +github.com/go-json-experiment/json v0.0.0-20250223041408-d3c622f1b874/go.mod h1:TiCD2a1pcmjd7YnhGH0f/zKNcCD06B029pHhzV23c2M= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= +github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDslNPMo06cago5JNLkm4= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w= +github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM= +github.com/go-resty/resty/v2 v2.17.2 h1:FQW5oHYcIlkCNrMD2lloGScxcHJ0gkjshV3qcQAyHQk= +github.com/go-resty/resty/v2 v2.17.2/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA= +github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= +github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo= +github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-viper/mapstructure/v2 v2.5.0 h1:vM5IJoUAy3d7zRSVtIwQgBj7BiWtMPfmPEgAXnvj1Ro= +github.com/go-viper/mapstructure/v2 v2.5.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4= +github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= +github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXeUI= +github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= +github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= +github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= +github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/otel-profiling-go v0.5.1 h1:stVPKAFZSa7eGiqbYuG25VcqYksR6iWvF3YH66t4qL8= +github.com/grafana/otel-profiling-go v0.5.1/go.mod h1:ftN/t5A/4gQI19/8MoWurBEtC6gFw8Dns1sJZ9W4Tls= +github.com/grafana/pyroscope-go v1.2.8 h1:UvCwIhlx9DeV7F6TW/z8q1Mi4PIm3vuUJ2ZlCEvmA4M= +github.com/grafana/pyroscope-go v1.2.8/go.mod h1:SSi59eQ1/zmKoY/BKwa5rSFsJaq+242Bcrr4wPix1g8= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= +github.com/graph-gophers/graphql-go v1.5.0 h1:fDqblo50TEpD0LY7RXk/LFVYEVqo3+tXMNMPSVXA1yc= +github.com/graph-gophers/graphql-go v1.5.0/go.mod h1:YtmJZDLbF1YYNrlNAuiO5zAStUWc3XZT07iGsVqe1Os= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2 h1:sGm2vDRFUrQJO/Veii4h4zG2vvqG6uWNkBHSTqXOZk0= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.2/go.mod h1:wd1YpapPLivG6nQgbf7ZkG1hhSOXDhhn4MLTknx2aAc= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c= +github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= +github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.5 h1:b3taDMxCBCBVgyRrS1AZVHO14ubMYZB++QpNhBg+Nyo= +github.com/hashicorp/go-memdb v1.3.5/go.mod h1:8IVKKBkVe+fxFgdFOYxzQQNjz+sWCyHCdIC/+5+Vy1Y= +github.com/hashicorp/go-plugin v1.7.0 h1:YghfQH/0QmPNc/AZMTFE3ac8fipZyZECHdDPshfk+mA= +github.com/hashicorp/go-plugin v1.7.0/go.mod h1:BExt6KEaIYx804z8k4gRzRLEvxKVb+kn0NMcihqOqb8= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= +github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= +github.com/hasura/go-graphql-client v0.15.1 h1:mCb5I+8Bk3FU3GKWvf/zDXkTh7FbGlqJmP3oisBdnN8= +github.com/hasura/go-graphql-client v0.15.1/go.mod h1:jfSZtBER3or+88Q9vFhWHiFMPppfYILRyl+0zsgPIIw= +github.com/hdevalence/ed25519consensus v0.2.0 h1:37ICyZqdyj0lAZ8P4D1d1id3HqbbG1N3iBb1Tb4rdcU= +github.com/hdevalence/ed25519consensus v0.2.0/go.mod h1:w3BHWjwJbFU29IRHL1Iqkw3sus+7FctEyM4RqDxYNzo= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= +github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= +github.com/influxdata/influxdb-client-go/v2 v2.4.0 h1:HGBfZYStlx3Kqvsv1h2pJixbCl/jhnFtxpKFAv9Tu5k= +github.com/influxdata/influxdb-client-go/v2 v2.4.0/go.mod h1:vLNHdxTJkIf2mSLvGrpj8TCcISApPoXkaxP8g9uRlW8= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c h1:qSHzRbhzK8RdXOsAdfDgO49TtqC1oZ+acxPrkfTxcCs= +github.com/influxdata/influxdb1-client v0.0.0-20220302092344-a9ab5670611c/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 h1:vilfsDSy7TDxedi9gyBkMvAirat/oRcL0lFdJBf6tdM= +github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097/go.mod h1:xaLFMmpvUxqXtVkUJfg9QmT88cDaCJ3ZKgdZ78oO8Qo= +github.com/invopop/jsonschema v0.13.0 h1:KvpoAJWEjR3uD9Kbm2HWJmqsEaHt8lBUpd0qHcIi21E= +github.com/invopop/jsonschema v0.13.0/go.mod h1:ffZ5Km5SWWRAIN6wbDXItl95euhFz2uON45H2qjYt+0= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.14.3 h1:bVoTr12EGANZz66nZPkMInAV/KHD2TxH9npjXXgiB3w= +github.com/jackc/pgconn v1.14.3/go.mod h1:RZbme4uasqzybK2RK5c65VsHxoyaml09lx3tXOcO/VM= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.3 h1:1HLSx5H+tXR9pW3in3zaztoEwQYRC9SQaYUHjTSUOag= +github.com/jackc/pgproto3/v2 v2.3.3/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= +github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.14.4 h1:fKuNiCumbKTAIxQwXfB/nsrnkEI6bPJrrSiMKgbJ2j8= +github.com/jackc/pgtype v1.14.4/go.mod h1:aKeozOde08iifGosdJpz9MBZonJOUJxqNpPBcMJTlVA= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.18.2/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= +github.com/jackc/pgx/v4 v4.18.3 h1:dE2/TrEsGX3RBprb3qryqSV9Y60iZN1C6i8IrmW9/BA= +github.com/jackc/pgx/v4 v4.18.3/go.mod h1:Ey4Oru5tH5sB6tV7hDmfWFahwF15Eb7DNXlRKx2CkVw= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.3.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= +github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= +github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= +github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= +github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= +github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 h1:msKODTL1m0wigztaqILOtla9HeW1ciscYG4xjLtvk5I= +github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52/go.mod h1:qk1sX/IBgppQNcGCRoj90u6EGC056EBoIc1oEjCWla8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= +github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.18.4 h1:RPhnKRAQ4Fh8zU2FY/6ZFDwTVTxgJ/EMydqSTzE9a2c= +github.com/klauspost/compress v1.18.4/go.mod h1:R0h/fSBs8DE4ENlcrlib3PsXS61voFxhIs2DeRhCvJ4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE= +github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.11.1 h1:wuChtj2hfsGmmx3nf1m7xC2XpK6OtelS2shMY+bGMtI= +github.com/lib/pq v1.11.1/go.mod h1:/p+8NSbOcwzAEI7wiMXFlgydTwcgTr3OSKMsD2BitpA= +github.com/logrusorgru/aurora v2.0.3+incompatible h1:tOpm7WcpBTn4fjmVfgpQq0EfczGlG91VSDkswnjF5A8= +github.com/logrusorgru/aurora v2.0.3+incompatible/go.mod h1:7rIyQOR62GCctdiQpZ/zOJlFyk6y+94wXzv6RNZgaR4= +github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88 h1:PTw+yKnXcOFCR6+8hHTyWBeQ/P4Nb7dd4/0ohEcWQuM= +github.com/lufia/plan9stats v0.0.0-20260216142805-b3301c5f2a88/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg= +github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= +github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4= +github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU= +github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739 h1:ykXz+pRRTibcSjG1yRhpdSHInF8yZY/mfn+Rz2Nd1rE= +github.com/manucorporat/sse v0.0.0-20160126180136-ee05b128a739/go.mod h1:zUx1mhth20V3VKgL5jbd1BSQcW4Fy6Qs4PZvQwRFwzM= +github.com/marcboeker/go-duckdb v1.8.5 h1:tkYp+TANippy0DaIOP5OEfBEwbUINqiFqgwMQ44jME0= +github.com/marcboeker/go-duckdb v1.8.5/go.mod h1:6mK7+WQE4P4u5AFLvVBmhFxY5fvhymFptghgJX6B+/8= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= +github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U= +github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= +github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= +github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= +github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 h1:BpfhmLKZf+SjVanKKhCgf3bg+511DmU9eDQTen7LLbY= +github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/pointerstructure v1.2.0 h1:O+i9nHnXS3l/9Wu7r4NrEdwA2VFTicjUEN1uBnDo34A= +github.com/mitchellh/pointerstructure v1.2.0/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4= +github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3Nl2EsFP0= +github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo= +github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8= +github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU= +github.com/moby/patternmatcher v0.6.0 h1:GmP9lR19aU5GqSSFko+5pRqHi+Ohk1O69aFiKkVGiPk= +github.com/moby/patternmatcher v0.6.0/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc= +github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU= +github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko= +github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs= +github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs= +github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ= +github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/morikuni/aec v1.1.0 h1:vBBl0pUnvi/Je71dsRrhMBtreIqNMYErSAbEeb8jrXQ= +github.com/morikuni/aec v1.1.0/go.mod h1:xDRgiq/iw5l+zkao76YTKzKttOp2cwPEne25HDkJnBw= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= +github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1/go.mod h1:ye2e/VUEtE2BHE+G/QcKkcLQVAEJoYRFj5VUOQatCRE= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= +github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/run v1.2.0 h1:O8x3yXwah4A73hJdlrwo/2X6J62gE5qTMusH0dvz60E= +github.com/oklog/run v1.2.0/go.mod h1:mgDbKRSwPhJfesJ4PntqFUbKQRZ50NgmZTSPlFA0YFk= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= +github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= +github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= +github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= +github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU= +github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/stun/v2 v2.0.0 h1:A5+wXKLAypxQri59+tmQKVs7+l6mMM+3d+eER9ifRU0= +github.com/pion/stun/v2 v2.0.0/go.mod h1:22qRSh08fSEttYUmJZGlriq9+03jtVmXNODgLccj8GQ= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/transport/v3 v3.0.1 h1:gDTlPJwROfSfz6QfSi0ZmeCSkFcnWWiiR9ES0ouANiM= +github.com/pion/transport/v3 v3.0.1/go.mod h1:UY7kiITrlMv7/IKgd5eTUcaahZx5oUN3l9SzK5f5xE0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU= +github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= +github.com/pressly/goose/v3 v3.26.0 h1:KJakav68jdH0WDvoAcj8+n61WqOIaPGgH0bJWS6jpmM= +github.com/pressly/goose/v3 v3.26.0/go.mod h1:4hC1KrritdCxtuFsqgs1R4AU5bWtTAf+cnWvfhf2DNY= +github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= +github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk= +github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE= +github.com/prometheus/common v0.66.1 h1:h5E0h5/Y8niHc5DlaLlWLArTQI7tMrsfQjHV+d9ZoGs= +github.com/prometheus/common v0.66.1/go.mod h1:gcaUsgf3KfRSwHY4dIMXLPV0K/Wg1oZ8+SbZk/HH/dA= +github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg= +github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= +github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA= +github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= +github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= +github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cjj1iZQ= +github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= +github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2 h1:S4OC0+OBKz6mJnzuHioeEat74PuQ4Sgvbf8eus695sc= +github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2/go.mod h1:8zLRYR5npGjaOXgPSKat5+oOh+UHd8OdbS18iqX9F6Y= +github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE= +github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= +github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= +github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil/v4 v4.26.2 h1:X8i6sicvUFih4BmYIGT1m2wwgw2VG9YgrDTi7cIRGUI= +github.com/shirou/gopsutil/v4 v4.26.2/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 h1:aQKxg3+2p+IFXXg97McgDGT5zcMrQoi0EICZs8Pgchs= +github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3/go.mod h1:9/etS5gpQq9BJsJMWg1wpLbfuSnkm8dPF6FdW2JXVhA= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= +github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/smartcontractkit/chain-selectors v1.0.98 h1:fuI7CQ1o5cX64eO4/LvwtfhdpGFH5vnsM/bFHRwEiww= +github.com/smartcontractkit/chain-selectors v1.0.98/go.mod h1:qy7whtgG5g+7z0jt0nRyii9bLND9m15NZTzuQPkMZ5w= +github.com/smartcontractkit/chainlink-aptos v0.0.0-20260306142855-8d629e752265 h1:Q/sYLdOefZUKc/Bxssq1mg8ptQE/AOot2WI+QcLoiVA= +github.com/smartcontractkit/chainlink-aptos v0.0.0-20260306142855-8d629e752265/go.mod h1:CQGkKp3YDsUuxixxmmngmRKfh6yIcftGEZsQrsSIIM8= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d h1:xdFpzbApEMz4Rojg2Y2OjFlrh0wu7eB10V2tSZGW5y8= +github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d/go.mod h1:bgmqE7x9xwmIVr8PqLbC0M5iPm4AV2DBl596lO6S5Sw= +github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= +github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260407150650-8115835abd6e h1:SLnJ0/55Rcn9/9OWrjhvhOTDW9+Bhd63v1tY4dvqtQM= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260407150650-8115835abd6e/go.mod h1:Ob7ZRLEvPkDwGUjKdDIiHy0Mxu4+UG6oMBkR7Jv/U6o= +github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= +github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= +github.com/smartcontractkit/chainlink-deployments-framework v0.94.1 h1:eQ9hEHG6s0BRZ3tfGytPnBDtde6035HZve5eyCRhYs0= +github.com/smartcontractkit/chainlink-deployments-framework v0.94.1/go.mod h1:pTA1JrdlMSfb9WkrIfphq2KV/+paW7GHf15Oc/uJBxs= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/committee-verifier v0.0.0-20251211142334-5c3421fe2c8d h1:VYoBBNnQpZ5p+enPTl8SkKBRaubqyGpO0ul3B1np++I= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/committee-verifier v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:oNFoKHRIerxuaANa8ASNejtHrdsG26LqGtQ2XhSac2g= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/message-discovery v0.0.0-20251211142334-5c3421fe2c8d h1:pKCyW7BYzO5GThFNlXZY0Azx/yOnI4b5GeuLeU23ie0= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/message-discovery v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:ATjAPIVJibHRcIfiG47rEQkUIOoYa6KDvWj3zwCAw6g= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d h1:AJy55QJ/pBhXkZjc7N+ATnWfxrcjq9BI9DmdtdjwDUQ= +github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:5JdppgngCOUS76p61zCinSCgOhPeYQ+OcDUuome5THQ= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f h1:8p3vE987AHM3Of1JvnNJXNE/AtWtfNvJhk3TeeAG3Qw= +github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f/go.mod h1:Jqt53s27Tr0jDl8mdBXg1xhu6F8Fci8JOuq43tgHOM8= +github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0 h1:q+VDPcxWrj5k9QizSYfUOSMnDH3Sd5HvbPguZOgfXTY= +github.com/smartcontractkit/chainlink-protos/job-distributor v0.18.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= +github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b h1:QuI6SmQFK/zyUlVWEf0GMkiUYBPY4lssn26nKSd/bOM= +github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b/go.mod h1:qSTSwX3cBP3FKQwQacdjArqv0g6QnukjV4XuzO6UyoY= +github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260211172625-dff40e83b3c9 h1:hhevsu8k7tlDRrYZmgAh7V4avGQDMvus1bwIlial3Ps= +github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260211172625-dff40e83b3c9/go.mod h1:dkR2uYg9XYJuT1JASkPzWE51jjFkVb86P7a/yXe5/GM= +github.com/smartcontractkit/chainlink-protos/op-catalog v0.0.4 h1:AEnxv4HM3WD1RbQkRiFyb9cJ6YKAcqBp1CpIcFdZfuo= +github.com/smartcontractkit/chainlink-protos/op-catalog v0.0.4/go.mod h1:PjZD54vr6rIKEKQj6HNA4hllvYI/QpT+Zefj3tqkFAs= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.10.0 h1:0eroOyBwmdoGUwUdvMI0/J7m5wuzNnJDMglSOK1sfNY= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.10.0/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= +github.com/smartcontractkit/chainlink-sui v0.0.0-20260205175622-33e65031f9a9 h1:KyPROV+v7P8VdiU7JhVuGLcDlEBsURSpQmSCgNBTY+s= +github.com/smartcontractkit/chainlink-sui v0.0.0-20260205175622-33e65031f9a9/go.mod h1:KpEWZJMLwbdMHeHQz9rbkES0vRrx4nk6OQXyhlHb9/8= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.13 h1:quHuZ/2I7XZ8pdRw5UAwKW/idsPchHN7KnQ69YWzxS4= +github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.13/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= +github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 h1:7f92q/Tz/Ns+gjChmWg5mEonrYutZV33k/1x+Xxsb4I= +github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418/go.mod h1:FDDjLuc4vrfclu3JHkMaREg0XZz7Lw1MK47Z4jJ4U5Q= +github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250908203554-5bd9d2fe9513 h1:XRNxgcNqagXu6e4smJuS1crRK5cUAcCVd7u+iLduHDM= +github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250908203554-5bd9d2fe9513/go.mod h1:ccjEgNeqOO+bjPddnL4lUrNLzyCvGCxgBjJdhFX3wa8= +github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.4 h1:J4qtAo0ZmgX5pIr8Y5mdC+J2rj2e/6CTUC263t6mGOM= +github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.4/go.mod h1:4WhGgCA0smBbBud5mK+jnDb2wwndMvoqaWBJ3OV/7Bw= +github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad h1:lgHxTHuzJIF3Vj6LSMOnjhqKgRqYW+0MV2SExtCYL1Q= +github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad/go.mod h1:T4zH9R8R8lVWKfU7tUvYz2o2jMv1OpGCdpY2j2QZXzU= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 h1:12ijqMM9tvYVEm+nR826WsrNi6zCKpwBhuApq127wHs= +github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7/go.mod h1:FX7/bVdoep147QQhsOPkYsPEXhGZjeYx6lBSaSXtZOA= +github.com/smartcontractkit/libocr v0.0.0-20260304194147-a03701e2c02e h1:poXTj5cFVM6XfC4HICIDYkDVc/A6OYB0eeID0wU2JQE= +github.com/smartcontractkit/libocr v0.0.0-20260304194147-a03701e2c02e/go.mod h1:PLdNK6GlqfxIWXzziPkU7dCAVlVFeYkyyW7AQY0R+4Q= +github.com/smartcontractkit/mcms v0.40.1 h1:r9bU/2GfIf6mHHM4PklSBkfi2Lq4+EGILC81e4IqKz0= +github.com/smartcontractkit/mcms v0.40.1/go.mod h1:7YqJPR8w9GiO1L/JjjTrwlSwAZ7i3J7cgOcu88PqtvU= +github.com/smartcontractkit/wsrpc v0.8.5-0.20250502134807-c57d3d995945 h1:zxcODLrFytOKmAd8ty8S/XK6WcIEJEgRBaL7sY/7l4Y= +github.com/smartcontractkit/wsrpc v0.8.5-0.20250502134807-c57d3d995945/go.mod h1:m3pdp17i4bD50XgktkzWetcV5yaLsi7Gunbv4ZgN6qg= +github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= +github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= +github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= +github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stellar/go-stellar-sdk v0.1.0 h1:MfV7dv4k6xQQrWeKT7npWyKhjoayphLVGwXKtTLNeH8= +github.com/stellar/go-stellar-sdk v0.1.0/go.mod h1:fZPcxQZw1I0zZ+X76uFcVPqmQCaYbWc87lDFW/kQJaY= +github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2 h1:OzCVd0SV5qE3ZcDeSFCmOWLZfEWZ3Oe8KtmSOYKEVWE= +github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2/go.mod h1:yoxyU/M8nl9LKeWIoBrbDPQ7Cy+4jxRcWcOayZ4BMps= +github.com/stephenlacy/go-ethereum-hdwallet v0.0.0-20230913225845-a4fa94429863 h1:ba4VRWSkRzgdP5hB5OxexIzBXZbSwgcw8bEu06ivGQI= +github.com/stephenlacy/go-ethereum-hdwallet v0.0.0-20230913225845-a4fa94429863/go.mod h1:oPTjPNrRucLv9mU27iNPj6n0CWWcNFhoXFOLVGJwHCA= +github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091 h1:RN5mrigyirb8anBEtdjtHFIufXdacyTi6i4KBfeNXeo= +github.com/streamingfast/logging v0.0.0-20230608130331-f22c91403091/go.mod h1:VlduQ80JcGJSargkRU4Sg9Xo63wZD/l8A5NC/Uo1/uU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jqwYhE= +github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d h1:vfofYNRScrDdvS342BElfbETmL1Aiz3i2t0zfRj16Hs= +github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d/go.mod h1:RRCYJbIwD5jmqPI9XoAFR0OcDxqUctll6zUj/+B4S48= +github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE= +github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU= +github.com/testcontainers/testcontainers-go v0.41.0 h1:mfpsD0D36YgkxGj2LrIyxuwQ9i2wCKAD+ESsYM1wais= +github.com/testcontainers/testcontainers-go v0.41.0/go.mod h1:pdFrEIfaPl24zmBjerWTTYaY0M6UHsqA1YSvsoU40MI= +github.com/testcontainers/testcontainers-go/modules/postgres v0.41.0 h1:AOtFXssrDlLm84A2sTTR/AhvJiYbrIuCO59d+Ro9Tb0= +github.com/testcontainers/testcontainers-go/modules/postgres v0.41.0/go.mod h1:k2a09UKhgSp6vNpliIY0QSgm4Hi7GXVTzWvWgUemu/8= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= +github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA= +github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= +github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= +github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= +github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk= +github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= +github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADTh4= +github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE= +github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc= +github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/xdrpp/goxdr v0.1.1 h1:E1B2c6E8eYhOVyd7yEpOyopzTPirUeF6mVOfXfGyJyc= +github.com/xdrpp/goxdr v0.1.1/go.mod h1:dXo1scL/l6s7iME1gxHWo2XCppbHEKZS7m/KyYWkNzA= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= +github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/xssnick/tonutils-go v1.14.1 h1:zV/iVYl/h3hArS+tPsd9XrSFfGert3r21caMltPSeHg= +github.com/xssnick/tonutils-go v1.14.1/go.mod h1:68xwWjpoGGqiTbLJ0gT63sKu1Z1moCnDLLzA+DKanIg= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= +github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6 h1:VRdX3Gn/I7ITbzUY4ZNfgn65tdQM9Zhf2b7KP0HZllk= +github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6/go.mod h1:NWNlQS21isOsSsn+hLRAPpiuv+3P+LcdaZNuRt2T5Yo= +go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM= +go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 h1:YH4g8lQroajqUwWbq/tr2QX1JFmEXaDLgG+ew9bLMWo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0/go.mod h1:fvPi2qXDqFs8M4B4fmJhE92TyQs9Ydjlg3RvfUp+NbQ= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0 h1:7iP2uCb7sGddAr30RRS6xjKy7AZ2JtTOPA3oolgVSw8= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1:c7hN3ddxs/z6q9xwvfLPk+UHlWRQyaeR1LdgfL/66l0= +go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= +go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 h1:gAU726w9J8fwr4qRDqu1GYMNNs4gXrU+Pv20/N1UpB4= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0/go.mod h1:RboSDkp7N292rgu+T0MgVt2qgFGu6qa1RpZDOtpL76w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0/go.mod h1:Izur+Wt8gClgMJqO/cZ8wdeeMryJ/xxiOVgFSSfpDTY= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKECHbOlr5GLwH6KTjLJ1sBSkkxkc= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0/go.mod h1:/GXR0tBmmkxDaCUGahvksvp66mx4yh5+cFXgSlhg0vQ= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 h1:G8Xec/SgZQricwWBJF/mHZc7A02YHedfFDENwJEdRA0= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0/go.mod h1:PD57idA/AiFD5aqoxGxCvT/ILJPeHy3MjqU/NS7KogY= +go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY= +go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4= +go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= +go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= +go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= +go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= +go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= +go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= +go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= +go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= +go.opentelemetry.io/otel/sdk/log/logtest v0.13.0 h1:9yio6AFZ3QD9j9oqshV1Ibm9gPLlHNxurno5BreMtIA= +go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168= +go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= +go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= +go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= +go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= +go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= +go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= +go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/ratelimit v0.3.1 h1:K4qVE+byfv/B3tC+4nYWP7v/6SimcO7HzHekoMNBma0= +go.uber.org/ratelimit v0.3.1/go.mod h1:6euWsTB6U/Nb3X++xEUXA8ciPJvr19Q/0h1+oDcJhRk= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= +go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= +go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= +golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= +golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= +golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= +golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= +golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8= +golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w= +golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= +golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= +golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.42.0 h1:omrd2nAlyT5ESRdCLYdm3+fMfNFE/+Rf4bDIQImRJeo= +golang.org/x/sys v0.42.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= +golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4 h1:bTLqdHv7xrGlFbvf5/TXNxy/iUwwdkjhqQTJDjW7aj0= +golang.org/x/telemetry v0.0.0-20260209163413-e7419c687ee4/go.mod h1:g5NllXBEermZrmR51cJDQxmJUHUOfRAaNyWBM+R+548= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= +golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= +golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= +golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= +golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k= +golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= +gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= +google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= +google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc= +gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= +gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= +k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls= +k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k= +k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U= +k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU= +k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg= +k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= +k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078 h1:jGnCPejIetjiy2gqaJ5V0NLwTpF4wbQ6cZIItJCSHno= +k8s.io/utils v0.0.0-20241104163129-6fe5fd82f078/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +modernc.org/libc v1.66.3 h1:cfCbjTUcdsKyyZZfEUKfoHcP3S0Wkvz3jgSzByEWVCQ= +modernc.org/libc v1.66.3/go.mod h1:XD9zO8kt59cANKvHPXpx7yS2ELPheAey0vjIuZOhOU8= +modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= +modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= +modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= +modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= +modernc.org/sqlite v1.39.0 h1:6bwu9Ooim0yVYA7IZn9demiQk/Ejp0BtTjBWFLymSeY= +modernc.org/sqlite v1.39.0/go.mod h1:cPTJYSlgg3Sfg046yBShXENNtPrWrDX8bsbAQBzgQ5E= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2 h1:MdmvkGuXi/8io6ixD5wud3vOLwc1rj0aNqRlpuvjmwA= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/evm/indexer_config.go b/evm/indexer_config.go new file mode 100644 index 000000000..8924b4bca --- /dev/null +++ b/evm/indexer_config.go @@ -0,0 +1,21 @@ +package evm + +import ( + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" +) + +type evmIndexerConfigAdapter struct{} + +// ResolveVerifierAddresses returns the EVM verifier contract addresses of the given kind +// (committee, cctp, lombard) for the given chain and qualifier from the datastore. +func (a *evmIndexerConfigAdapter) ResolveVerifierAddresses(ds datastore.DataStore, chainSelector uint64, qualifier string, kind adapters.VerifierKind) ([]string, error) { + // TODO: read verifier addresses from EVM datastore entries for this + // chainSelector, qualifier, and verifier kind. + return nil, &adapters.MissingIndexerVerifierAddressesError{ + Kind: kind, + ChainSelector: chainSelector, + Qualifier: qualifier, + } +} diff --git a/evm/register.go b/evm/register.go new file mode 100644 index 000000000..d973f36ea --- /dev/null +++ b/evm/register.go @@ -0,0 +1,36 @@ +// Package evm provides EVM-specific adapter implementations for the chainlink-ccv +// deployment tooling. Import this package with a blank identifier to self-register: +// +// import _ "github.com/smartcontractkit/chainlink-ccv/evm" +package evm + +import ( + "strings" + + chainsel "github.com/smartcontractkit/chain-selectors" + nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" + + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" + "github.com/smartcontractkit/chainlink-ccv/deployment/shared" +) + +func init() { + // Register EVM chain type so JD operations can map proto ChainType → family. + shared.RegisterChainTypeFamily(nodev1.ChainType_CHAIN_TYPE_EVM, chainsel.FamilyEVM) + + // EVM signing addresses are hex strings: normalise to lowercase with 0x prefix. + shared.RegisterAddressNormalizer(chainsel.FamilyEVM, func(addr string) string { + lower := strings.ToLower(addr) + if !strings.HasPrefix(lower, "0x") { + return "0x" + lower + } + return lower + }) + + // Register EVM adapter implementations in the deployment registries. + adapters.GetExecutorConfigRegistry().Register(chainsel.FamilyEVM, &evmExecutorConfigAdapter{}) + adapters.GetVerifierJobConfigRegistry().Register(chainsel.FamilyEVM, &evmVerifierConfigAdapter{}) + adapters.GetAggregatorConfigRegistry().Register(chainsel.FamilyEVM, &evmAggregatorConfigAdapter{}) + adapters.GetIndexerConfigRegistry().Register(chainsel.FamilyEVM, &evmIndexerConfigAdapter{}) + adapters.GetTokenVerifierConfigRegistry().Register(chainsel.FamilyEVM, &evmTokenVerifierConfigAdapter{}) +} diff --git a/evm/token_verifier_config.go b/evm/token_verifier_config.go new file mode 100644 index 000000000..005488540 --- /dev/null +++ b/evm/token_verifier_config.go @@ -0,0 +1,24 @@ +package evm + +import ( + "fmt" + + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" +) + +type evmTokenVerifierConfigAdapter struct{} + +// ResolveTokenVerifierAddresses returns the EVM-specific contract addresses needed to +// build the token verifier config (OnRamp, RMNRemote, CCTP/Lombard verifiers and resolvers). +func (a *evmTokenVerifierConfigAdapter) ResolveTokenVerifierAddresses( + ds datastore.DataStore, + chainSelector uint64, + cctpQualifier string, + lombardQualifier string, +) (*adapters.TokenVerifierChainAddresses, error) { + // TODO: read OnRamp, RMNRemote, CCTPVerifier, CCTPVerifierResolver, + // and LombardVerifierResolver addresses from EVM datastore entries. + return nil, fmt.Errorf("EVM token verifier config adapter not yet implemented for chain %d", chainSelector) +} diff --git a/evm/verifier_config.go b/evm/verifier_config.go new file mode 100644 index 000000000..50fd6a267 --- /dev/null +++ b/evm/verifier_config.go @@ -0,0 +1,31 @@ +package evm + +import ( + "fmt" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + + "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" +) + +type evmVerifierConfigAdapter struct{} + +// GetSignerAddressFamily returns the chain-selectors family whose OCR2 signing key +// EVM committee verifier jobs must use. +func (a *evmVerifierConfigAdapter) GetSignerAddressFamily() string { + return chainsel.FamilyEVM +} + +// ResolveVerifierContractAddresses reads EVM committee verifier contract addresses +// (CommitteeVerifier, OnRamp, ExecutorProxy, RMNRemote) from the datastore. +func (a *evmVerifierConfigAdapter) ResolveVerifierContractAddresses( + ds datastore.DataStore, + chainSelector uint64, + committeeQualifier string, + executorQualifier string, +) (*adapters.VerifierContractAddresses, error) { + // TODO: resolve addresses from EVM-specific datastore entries for this + // chainSelector, committeeQualifier, and executorQualifier. + return nil, fmt.Errorf("EVM verifier config adapter not yet implemented for chain %d", chainSelector) +} From 298b021d98b34e60c9ad75c1a646a79bc57c0d8e Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Fri, 17 Apr 2026 06:09:38 -0700 Subject: [PATCH 02/17] evm impl --- evm/aggregator_config.go | 82 ++++++++++++++--- evm/executor_config.go | 68 +++++++++++++-- evm/go.mod | 61 +++++++------ evm/go.sum | 165 +++++++++++++++++++++++------------ evm/indexer_config.go | 60 +++++++++++-- evm/token_verifier_config.go | 63 +++++++++++-- evm/verifier_config.go | 60 +++++++++++-- 7 files changed, 437 insertions(+), 122 deletions(-) diff --git a/evm/aggregator_config.go b/evm/aggregator_config.go index af2f5c1ea..a55bcb995 100644 --- a/evm/aggregator_config.go +++ b/evm/aggregator_config.go @@ -4,6 +4,13 @@ import ( "context" "fmt" + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + dsutils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore" + "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/operations/committee_verifier" + "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/versioned_verifier_resolver" + cv "github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v2_0_0/committee_verifier" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-deployments-framework/deployment" @@ -12,18 +19,73 @@ import ( type evmAggregatorConfigAdapter struct{} -// ScanCommitteeStates queries the EVM chain for all deployed committee verifier contracts -// and returns their on-chain state (signers, thresholds, etc.) for the aggregator config. func (a *evmAggregatorConfigAdapter) ScanCommitteeStates(ctx context.Context, env deployment.Environment, chainSelector uint64) ([]*adapters.CommitteeState, error) { - // TODO: call EVM committee verifier contracts on the given chain to enumerate - // deployed committee states and return their signer/threshold configs. - return nil, fmt.Errorf("EVM aggregator config adapter not yet implemented for chain %d", chainSelector) + refs := env.DataStore.Addresses().Filter( + datastore.AddressRefByType(datastore.ContractType(committee_verifier.ContractType)), + datastore.AddressRefByChainSelector(chainSelector), + ) + + if len(refs) == 0 { + return nil, nil + } + + evmChains := env.BlockChains.EVMChains() + if evmChains == nil { + return nil, fmt.Errorf("no EVM chains found in environment") + } + + chain, ok := evmChains[chainSelector] + if !ok { + return nil, fmt.Errorf("EVM chain %d not found in environment", chainSelector) + } + + states := make([]*adapters.CommitteeState, 0, len(refs)) + for _, ref := range refs { + addr := common.HexToAddress(ref.Address) + contract, err := cv.NewCommitteeVerifier(addr, chain.Client) + if err != nil { + return nil, fmt.Errorf("failed to bind CommitteeVerifier %s on chain %d: %w", ref.Address, chainSelector, err) + } + + allConfigs, err := contract.GetAllSignatureConfigs(&bind.CallOpts{Context: ctx}) + if err != nil { + return nil, fmt.Errorf("failed to get signature configs from %s on chain %d: %w", ref.Address, chainSelector, err) + } + + sigConfigs := make([]adapters.SignatureConfig, 0, len(allConfigs)) + for _, cfg := range allConfigs { + signers := make([]string, 0, len(cfg.Signers)) + for _, signer := range cfg.Signers { + signers = append(signers, signer.Hex()) + } + sigConfigs = append(sigConfigs, adapters.SignatureConfig{ + SourceChainSelector: cfg.SourceChainSelector, + Signers: signers, + Threshold: cfg.Threshold, + }) + } + + states = append(states, &adapters.CommitteeState{ + Qualifier: ref.Qualifier, + ChainSelector: chainSelector, + Address: ref.Address, + SignatureConfigs: sigConfigs, + }) + } + + return states, nil } -// ResolveVerifierAddress returns the committee verifier contract address stored in the -// EVM-specific datastore entry for the given chain and qualifier. func (a *evmAggregatorConfigAdapter) ResolveVerifierAddress(ds datastore.DataStore, chainSelector uint64, qualifier string) (string, error) { - // TODO: read the verifier address from the EVM datastore entry for this - // chainSelector and qualifier. - return "", fmt.Errorf("EVM aggregator config adapter not yet implemented for chain %d", chainSelector) + return dsutils.FindAndFormatFirstRef(ds, chainSelector, + func(r datastore.AddressRef) (string, error) { return r.Address, nil }, + datastore.AddressRef{ + Type: datastore.ContractType(versioned_verifier_resolver.CommitteeVerifierResolverType), + Qualifier: qualifier, + }, + datastore.AddressRef{ + Type: datastore.ContractType(committee_verifier.ContractType), + Qualifier: qualifier, + }, + ) } diff --git a/evm/executor_config.go b/evm/executor_config.go index 90144d56b..6fbe981cb 100644 --- a/evm/executor_config.go +++ b/evm/executor_config.go @@ -3,6 +3,12 @@ package evm import ( "fmt" + chainsel "github.com/smartcontractkit/chain-selectors" + dsutils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore" + execop "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/operations/executor" + offrampop "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/operations/offramp" + rmnremote "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/operations/rmn_remote" + "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/sequences" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-ccv/executor" @@ -10,17 +16,61 @@ import ( type evmExecutorConfigAdapter struct{} -// GetDeployedChains returns EVM chain selectors that have executor contracts deployed -// for the given qualifier, as recorded in the datastore. func (a *evmExecutorConfigAdapter) GetDeployedChains(ds datastore.DataStore, qualifier string) []uint64 { - // TODO: query EVM contract addresses from the datastore keyed by qualifier. - return nil + if ds == nil { + return nil + } + refs := ds.Addresses().Filter( + datastore.AddressRefByQualifier(qualifier), + datastore.AddressRefByType(datastore.ContractType(sequences.ExecutorProxyType)), + ) + seen := make(map[uint64]struct{}, len(refs)) + chains := make([]uint64, 0, len(refs)) + for _, ref := range refs { + if _, exists := seen[ref.ChainSelector]; exists { + continue + } + family, err := chainsel.GetSelectorFamily(ref.ChainSelector) + if err != nil || family != chainsel.FamilyEVM { + continue + } + seen[ref.ChainSelector] = struct{}{} + chains = append(chains, ref.ChainSelector) + } + return chains } -// BuildChainConfig reads EVM-specific contract addresses from the datastore and returns -// the executor chain configuration for the given chain selector and qualifier. func (a *evmExecutorConfigAdapter) BuildChainConfig(ds datastore.DataStore, chainSelector uint64, qualifier string) (executor.ChainConfiguration, error) { - // TODO: resolve OffRampAddress, RmnAddress, DefaultExecutorAddress from the - // EVM-specific datastore entries for this chainSelector and qualifier. - return executor.ChainConfiguration{}, fmt.Errorf("EVM executor config adapter not yet implemented for chain %d", chainSelector) + toAddress := func(ref datastore.AddressRef) (string, error) { return ref.Address, nil } + + offRampAddr, err := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(offrampop.ContractType), + Version: offrampop.Version, + }, chainSelector, toAddress) + if err != nil { + return executor.ChainConfiguration{}, fmt.Errorf("failed to get off ramp address for chain %d: %w", chainSelector, err) + } + + rmnRemoteAddr, err := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(rmnremote.ContractType), + Version: rmnremote.Version, + }, chainSelector, toAddress) + if err != nil { + return executor.ChainConfiguration{}, fmt.Errorf("failed to get rmn remote address for chain %d: %w", chainSelector, err) + } + + executorAddr, err := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(sequences.ExecutorProxyType), + Qualifier: qualifier, + Version: execop.Version, + }, chainSelector, toAddress) + if err != nil { + return executor.ChainConfiguration{}, fmt.Errorf("failed to get executor proxy address for chain %d: %w", chainSelector, err) + } + + return executor.ChainConfiguration{ + OffRampAddress: offRampAddr, + RmnAddress: rmnRemoteAddr, + DefaultExecutorAddress: executorAddr, + }, nil } diff --git a/evm/go.mod b/evm/go.mod index 96fd6cea5..f2fec9542 100644 --- a/evm/go.mod +++ b/evm/go.mod @@ -9,7 +9,11 @@ replace ( ) require ( + github.com/Masterminds/semver/v3 v3.4.0 + github.com/ethereum/go-ethereum v1.17.2 github.com/smartcontractkit/chain-selectors v1.0.98 + github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260416055149-75c017f534ca + github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260416055149-75c017f534ca github.com/smartcontractkit/chainlink-ccv v0.0.0 github.com/smartcontractkit/chainlink-ccv/deployment v0.0.0 github.com/smartcontractkit/chainlink-deployments-framework v0.94.1 @@ -17,9 +21,9 @@ require ( ) require ( + dario.cat/mergo v1.0.2 // indirect filippo.io/edwards25519 v1.1.1 // indirect github.com/BurntSushi/toml v1.5.0 // indirect - github.com/Masterminds/semver/v3 v3.4.0 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 // indirect github.com/XSAM/otelsql v0.37.0 // indirect @@ -36,7 +40,7 @@ require ( github.com/btcsuite/btcd/btcutil v1.1.6 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/btcsuite/btcutil v1.0.2 // indirect - github.com/buger/jsonparser v1.1.1 // indirect + github.com/buger/jsonparser v1.1.2 // indirect github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect @@ -48,7 +52,7 @@ require ( github.com/coder/websocket v1.8.14 // indirect github.com/consensys/gnark-crypto v0.19.2 // indirect github.com/cosmos/go-bip39 v1.0.0 // indirect - github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect + github.com/crate-crypto/go-eth-kzg v1.5.0 // indirect github.com/creachadair/jrpc2 v1.2.0 // indirect github.com/creachadair/mds v0.13.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -56,7 +60,6 @@ require ( github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.0 // indirect github.com/digital-asset/dazl-client/v8 v8.9.0 // indirect github.com/ethereum/c-kzg-4844/v2 v2.1.6 // indirect - github.com/ethereum/go-ethereum v1.17.1 // indirect github.com/fatih/color v1.18.0 // indirect github.com/fbsobreira/gotron-sdk v0.0.0-20250403083053-2943ce8c759b // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect @@ -105,7 +108,7 @@ require ( github.com/jmoiron/sqlx v1.4.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 // indirect + github.com/karalabe/hid v1.0.1-0.20260315100226-f5d04adeffeb // indirect github.com/klauspost/compress v1.18.4 // indirect github.com/klauspost/cpuid/v2 v2.2.10 // indirect github.com/leodido/go-urn v1.4.0 // indirect @@ -138,17 +141,21 @@ require ( github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shopspring/decimal v1.4.0 // indirect github.com/sigurn/crc16 v0.0.0-20211026045750-20ab5afb07e3 // indirect + github.com/smartcontractkit/ccip-contract-examples/chains/evm v0.0.0-20250826190403-aed7f5f33cde // indirect github.com/smartcontractkit/chainlink-aptos v0.0.0-20260306142855-8d629e752265 // indirect github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d // indirect github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 // indirect github.com/smartcontractkit/chainlink-common v0.11.2-0.20260407150650-8115835abd6e // indirect + github.com/smartcontractkit/chainlink-common/keystore v1.0.2 // indirect github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect + github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260410162948-2dca02f24e98 // indirect + github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20260119171452-39c98c3b33cd // indirect github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d // indirect github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f // indirect github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b // indirect github.com/smartcontractkit/chainlink-protos/node-platform v0.0.0-20260211172625-dff40e83b3c9 // indirect github.com/smartcontractkit/chainlink-sui v0.0.0-20260205175622-33e65031f9a9 // indirect - github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 // indirect + github.com/smartcontractkit/chainlink-ton v0.0.0-20260415120434-cecc380f8d87 // indirect github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250908203554-5bd9d2fe9513 // indirect github.com/smartcontractkit/freeport v0.1.3-0.20250828155247-add56fa28aad // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect @@ -176,44 +183,46 @@ require ( github.com/xssnick/tonutils-go v1.14.1 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6 // indirect + go.dedis.ch/fixbuf v1.0.3 // indirect + go.dedis.ch/kyber/v3 v3.1.0 // indirect go.mongodb.org/mongo-driver v1.17.2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.63.0 // indirect go.opentelemetry.io/otel v1.43.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 // indirect - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 // indirect - go.opentelemetry.io/otel/log v0.15.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.19.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0 // indirect + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0 // indirect + go.opentelemetry.io/otel/log v0.19.0 // indirect go.opentelemetry.io/otel/metric v1.43.0 // indirect go.opentelemetry.io/otel/sdk v1.43.0 // indirect - go.opentelemetry.io/otel/sdk/log v0.15.0 // indirect + go.opentelemetry.io/otel/sdk/log v0.19.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.43.0 // indirect go.opentelemetry.io/otel/trace v1.43.0 // indirect - go.opentelemetry.io/proto/otlp v1.9.0 // indirect + go.opentelemetry.io/proto/otlp v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/ratelimit v0.3.1 // indirect go.uber.org/zap v1.27.1 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect golang.org/x/arch v0.8.0 // indirect - golang.org/x/crypto v0.48.0 // indirect + golang.org/x/crypto v0.49.0 // indirect golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect - golang.org/x/net v0.50.0 // indirect + golang.org/x/net v0.52.0 // indirect golang.org/x/oauth2 v0.35.0 // indirect golang.org/x/sync v0.20.0 // indirect golang.org/x/sys v0.42.0 // indirect - golang.org/x/term v0.40.0 // indirect - golang.org/x/text v0.34.0 // indirect - golang.org/x/time v0.14.0 // indirect + golang.org/x/term v0.41.0 // indirect + golang.org/x/text v0.35.0 // indirect + golang.org/x/time v0.15.0 // indirect golang.org/x/tools v0.42.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 // indirect google.golang.org/grpc v1.80.0 // indirect google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/evm/go.sum b/evm/go.sum index 5ce7cbdc3..ea740f23b 100644 --- a/evm/go.sum +++ b/evm/go.sum @@ -29,8 +29,14 @@ github.com/apache/arrow-go/v18 v18.3.1 h1:oYZT8FqONiK74JhlH3WKVv+2NKYoyZ7C2ioD4D github.com/apache/arrow-go/v18 v18.3.1/go.mod h1:12QBya5JZT6PnBihi5NJTzbACrDGXYkrgjujz3MRQXU= github.com/aptos-labs/aptos-go-sdk v1.12.0 h1:deHZ7NJlFhHm2i+eaPHt6EPa3BuXXnIYx2X5J3/U0Es= github.com/aptos-labs/aptos-go-sdk v1.12.0/go.mod h1:FTgKp0RLfEefllCdkCj0jPU14xWk11yA7SFVfCDLUj8= +github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= +github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= github.com/avast/retry-go/v4 v4.7.0 h1:yjDs35SlGvKwRNSykujfjdMxMhMQQM0TnIjJaHB+Zio= github.com/avast/retry-go/v4 v4.7.0/go.mod h1:ZMPDa3sY2bKgpLtap9JRUgk2yTAba7cgiFhqxY2Sg6Q= +github.com/awalterschulze/gographviz v2.0.3+incompatible h1:9sVEXJBJLwGX7EQVhLm2elIKCm7P2YHFC8v6096G09E= +github.com/awalterschulze/gographviz v2.0.3+incompatible/go.mod h1:GEV5wmg4YquNw7v1kkyoX9etIk8yVmXj+AkDHuuETHs= +github.com/aws/aws-sdk-go v1.55.8 h1:JRmEUbU52aJQZ2AjX4q4Wu7t4uZjOu71uyNmaWlUkJQ= +github.com/aws/aws-sdk-go v1.55.8/go.mod h1:ZkViS9AqA6otK+JBBNH2++sx1sgxrPKcSzPPvQkUtXk= github.com/aws/aws-sdk-go-v2 v1.41.4 h1:10f50G7WyU02T56ox1wWXq+zTX9I1zxG46HYuG1hH/k= github.com/aws/aws-sdk-go-v2 v1.41.4/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o= github.com/aws/aws-sdk-go-v2/config v1.32.12 h1:O3csC7HUGn2895eNrLytOJQdoL2xyJy0iYXhoZ1OmP0= @@ -45,6 +51,8 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20 h1:tN6W/hg+pkM+tf9XDk github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.20/go.mod h1:YJ898MhD067hSHA6xYCx5ts/jEd8BSOLtQDL3iZsvbc= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6 h1:qYQ4pzQ2Oz6WpQ8T3HvGHnZydA72MnLuFK9tJwmrbHw= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.6/go.mod h1:O3h0IK87yXci+kg6flUKzJnWeziQUKciKrLjcatSNcY= +github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.59.2 h1:I1oExVl2b6nJGv//TcU78k9Covm/htQ5gwPIcDlM2PI= +github.com/aws/aws-sdk-go-v2/service/cognitoidentityprovider v1.59.2/go.mod h1:sxvHFUS0fM9Y3BpmDvwrO9fnQC0CrFSG8KD9THjv6k4= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.20 h1:2HvVAIq+YqgGotK6EkMf+KIEqTISmTYh5zLpYyeTo1Y= @@ -105,8 +113,8 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= -github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk= +github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= @@ -166,8 +174,8 @@ github.com/cpuguy83/dockercfg v0.3.2 h1:DlJTyZGBDlXqUZ2Dk2Q3xHs/FtnooJJVaad2S9GK github.com/cpuguy83/dockercfg v0.3.2/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.7 h1:zbFlGlXEAKlwXpmvle3d8Oe3YnkKIK4xSRTd3sHPnBo= github.com/cpuguy83/go-md2man/v2 v2.0.7/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= -github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg= -github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/crate-crypto/go-eth-kzg v1.5.0 h1:FYRiJMJG2iv+2Dy3fi14SVGjcPteZ5HAAUe4YWlJygc= +github.com/crate-crypto/go-eth-kzg v1.5.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/creachadair/jrpc2 v1.2.0 h1:SXr0OgnwM0X18P+HccJP0uT3KGSDk/BCSRlJBvE2bMY= github.com/creachadair/jrpc2 v1.2.0/go.mod h1:66uKSdr6tR5ZeNvkIjDSbbVUtOv0UhjS/vcd8ECP7Iw= github.com/creachadair/mds v0.13.4 h1:RgU0MhiVqkzp6/xtNWhK6Pw7tDeaVuGFtA0UA2RBYvY= @@ -201,8 +209,8 @@ github.com/digital-asset/dazl-client/v8 v8.9.0 h1:F2qTUWtHAjhGyRGV+xTim+VAFwM99F github.com/digital-asset/dazl-client/v8 v8.9.0/go.mod h1:q1KevCJ8FpH8je2MnnjN8/QUfhstB4fKpyKyqDtqFh0= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= -github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v28.5.3-0.20260325154711-31a1689cb0a1+incompatible h1:f51eIlZsZqGKXyNeCHs5oVo/xQiR9zh+pDYMfnu3VPQ= +github.com/docker/docker v28.5.3-0.20260325154711-31a1689cb0a1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -223,8 +231,8 @@ github.com/ethereum/c-kzg-4844/v2 v2.1.6 h1:xQymkKCT5E2Jiaoqf3v4wsNgjZLY0lRSkZn2 github.com/ethereum/c-kzg-4844/v2 v2.1.6/go.mod h1:8HMkUZ5JRv4hpw/XUrYWSQNAUzhHMg2UDb/U+5m+XNw= github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk= github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8= -github.com/ethereum/go-ethereum v1.17.1 h1:IjlQDjgxg2uL+GzPRkygGULPMLzcYWncEI7wbaizvho= -github.com/ethereum/go-ethereum v1.17.1/go.mod h1:7UWOVHL7K3b8RfVRea022btnzLCaanwHtBuH1jUCH/I= +github.com/ethereum/go-ethereum v1.17.2 h1:ag6geu0kn8Hv5FLKTpH+Hm2DHD+iuFtuqKxEuwUsDOI= +github.com/ethereum/go-ethereum v1.17.2/go.mod h1:KHcRXfGOUfUmKg51IhQ0IowiqZ6PqZf08CMtk0g5K1o= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= @@ -466,6 +474,8 @@ github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5Xum github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= github.com/jinzhu/copier v0.4.0 h1:w3ciUoD19shMCRargcpm0cm91ytaBhDvuRpz1ODO/U8= github.com/jinzhu/copier v0.4.0/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= @@ -475,8 +485,8 @@ github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52 h1:msKODTL1m0wigztaqILOtla9HeW1ciscYG4xjLtvk5I= -github.com/karalabe/hid v1.0.1-0.20240306101548-573246063e52/go.mod h1:qk1sX/IBgppQNcGCRoj90u6EGC056EBoIc1oEjCWla8= +github.com/karalabe/hid v1.0.1-0.20260315100226-f5d04adeffeb h1:Ag83At00qa4FLkcdMgrwHVSakqky/eZczOlxd4q336E= +github.com/karalabe/hid v1.0.1-0.20260315100226-f5d04adeffeb/go.mod h1:qk1sX/IBgppQNcGCRoj90u6EGC056EBoIc1oEjCWla8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= @@ -570,6 +580,8 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= +github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/morikuni/aec v1.1.0 h1:vBBl0pUnvi/Je71dsRrhMBtreIqNMYErSAbEeb8jrXQ= github.com/morikuni/aec v1.1.0/go.mod h1:xDRgiq/iw5l+zkao76YTKzKttOp2cwPEne25HDkJnBw= github.com/mostynb/zstdpool-freelist v0.0.0-20201229113212-927304c0c3b1 h1:mPMvm6X6tf4w8y7j9YIt6V9jfWhL6QlbEc7CCmeQlWk= @@ -597,8 +609,8 @@ github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5 github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.34.2 h1:pNCwDkzrsv7MS9kpaQvVb1aVLahQXyJ/Tv5oAZMI3i8= -github.com/onsi/gomega v1.34.2/go.mod h1:v1xfxRgk0KIsG+QOdm7p8UosrOzPYRo60fd3B/1Dukc= +github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8= +github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -656,6 +668,8 @@ github.com/rs/zerolog v1.34.0 h1:k43nTLIwcTVQAncfCw4KZ2VY6ukYoZaBPNOE8txlOeY= github.com/rs/zerolog v1.34.0/go.mod h1:bJsvje4Z08ROH4Nhs5iH600c3IkWhwp44iRc54W6wYQ= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc= +github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik= github.com/samber/lo v1.52.0 h1:Rvi+3BFHES3A8meP33VPAxiBZX/Aws5RxrschYGjomw= github.com/samber/lo v1.52.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= @@ -665,6 +679,8 @@ github.com/scylladb/go-reflectx v1.0.1 h1:b917wZM7189pZdlND9PbIJ6NQxfDPfBvUaQ7cj github.com/scylladb/go-reflectx v1.0.1/go.mod h1:rWnOfDIRWBGN0miMLIcoPt/Dhi2doCMZqwMCJ3KupFc= github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2 h1:S4OC0+OBKz6mJnzuHioeEat74PuQ4Sgvbf8eus695sc= github.com/segmentio/go-loggly v0.5.1-0.20171222203950-eb91657e62b2/go.mod h1:8zLRYR5npGjaOXgPSKat5+oOh+UHd8OdbS18iqX9F6Y= +github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= +github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE= github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE= github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -682,20 +698,34 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/smartcontractkit/ccip-contract-examples/chains/evm v0.0.0-20250826190403-aed7f5f33cde h1:dMUf1YOX5hdUkQDgnA/A/sWVoMaQWGB+EYBPuYffYIA= +github.com/smartcontractkit/ccip-contract-examples/chains/evm v0.0.0-20250826190403-aed7f5f33cde/go.mod h1:SYc+BvAALmwsx2zMJIAczIyVNwsiXRIBXmejcTORxGE= +github.com/smartcontractkit/ccip-owner-contracts v0.1.0 h1:GiBDtlx7539o7AKlDV+9LsA7vTMPv+0n7ClhSFnZFAk= +github.com/smartcontractkit/ccip-owner-contracts v0.1.0/go.mod h1:NnT6w4Kj42OFFXhSx99LvJZWPpMjmo4+CpDEWfw61xY= github.com/smartcontractkit/chain-selectors v1.0.98 h1:fuI7CQ1o5cX64eO4/LvwtfhdpGFH5vnsM/bFHRwEiww= github.com/smartcontractkit/chain-selectors v1.0.98/go.mod h1:qy7whtgG5g+7z0jt0nRyii9bLND9m15NZTzuQPkMZ5w= github.com/smartcontractkit/chainlink-aptos v0.0.0-20260306142855-8d629e752265 h1:Q/sYLdOefZUKc/Bxssq1mg8ptQE/AOot2WI+QcLoiVA= github.com/smartcontractkit/chainlink-aptos v0.0.0-20260306142855-8d629e752265/go.mod h1:CQGkKp3YDsUuxixxmmngmRKfh6yIcftGEZsQrsSIIM8= +github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260416055149-75c017f534ca h1:rfY6ufm3HoQ+hAZ+9eJOb1UBVH8eE012Cn+eR/NRqK8= +github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260416055149-75c017f534ca/go.mod h1:7XR5wfgT8hjSsiV+t0EAWvna+rYQeMPaoZf/0g+dios= github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d h1:xdFpzbApEMz4Rojg2Y2OjFlrh0wu7eB10V2tSZGW5y8= github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260121163256-85accaf3d28d/go.mod h1:bgmqE7x9xwmIVr8PqLbC0M5iPm4AV2DBl596lO6S5Sw= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 h1:Z4t2ZY+ZyGWxtcXvPr11y4o3CGqhg3frJB5jXkCSvWA= github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5/go.mod h1:xtZNi6pOKdC3sLvokDvXOhgHzT+cyBqH/gWwvxTxqrg= +github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260416055149-75c017f534ca h1:Suhepa3nU9GhWcq9z8zI2FfOnZfAN5GsuTKoQcb6Kx8= +github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260416055149-75c017f534ca/go.mod h1:Ex2OUp35VJuCcRAjuBKwP+cevEPOSjy1pZXm3ncV4kQ= github.com/smartcontractkit/chainlink-common v0.11.2-0.20260407150650-8115835abd6e h1:SLnJ0/55Rcn9/9OWrjhvhOTDW9+Bhd63v1tY4dvqtQM= github.com/smartcontractkit/chainlink-common v0.11.2-0.20260407150650-8115835abd6e/go.mod h1:Ob7ZRLEvPkDwGUjKdDIiHy0Mxu4+UG6oMBkR7Jv/U6o= +github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= +github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-deployments-framework v0.94.1 h1:eQ9hEHG6s0BRZ3tfGytPnBDtde6035HZve5eyCRhYs0= github.com/smartcontractkit/chainlink-deployments-framework v0.94.1/go.mod h1:pTA1JrdlMSfb9WkrIfphq2KV/+paW7GHf15Oc/uJBxs= +github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260410162948-2dca02f24e98 h1:h/L6wrXYLQalI/vHm6qg/KBv6d7kMb3geMHV5hCM1t4= +github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260410162948-2dca02f24e98/go.mod h1:6vCMfxz7cMW0wWseNKtct+b1JJbbRVJJhh/t6pQWN3M= +github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20260119171452-39c98c3b33cd h1:sK+pK4epQp20yQ7XztwrVgkTkRAr4FY+TvEegW8RuQk= +github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20260119171452-39c98c3b33cd/go.mod h1:7Jlt72+V9891y3LnGwHzmQwt9tfEGYryRKiGlQHo/o8= github.com/smartcontractkit/chainlink-protos/chainlink-ccv/committee-verifier v0.0.0-20251211142334-5c3421fe2c8d h1:VYoBBNnQpZ5p+enPTl8SkKBRaubqyGpO0ul3B1np++I= github.com/smartcontractkit/chainlink-protos/chainlink-ccv/committee-verifier v0.0.0-20251211142334-5c3421fe2c8d/go.mod h1:oNFoKHRIerxuaANa8ASNejtHrdsG26LqGtQ2XhSac2g= github.com/smartcontractkit/chainlink-protos/chainlink-ccv/message-discovery v0.0.0-20251211142334-5c3421fe2c8d h1:pKCyW7BYzO5GThFNlXZY0Azx/yOnI4b5GeuLeU23ie0= @@ -718,8 +748,10 @@ github.com/smartcontractkit/chainlink-sui v0.0.0-20260205175622-33e65031f9a9 h1: github.com/smartcontractkit/chainlink-sui v0.0.0-20260205175622-33e65031f9a9/go.mod h1:KpEWZJMLwbdMHeHQz9rbkES0vRrx4nk6OQXyhlHb9/8= github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.13 h1:quHuZ/2I7XZ8pdRw5UAwKW/idsPchHN7KnQ69YWzxS4= github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.13/go.mod h1:BALK9cj8sk12e15UF6uDhifHgIApa+6N11TcQfInEro= -github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418 h1:7f92q/Tz/Ns+gjChmWg5mEonrYutZV33k/1x+Xxsb4I= -github.com/smartcontractkit/chainlink-ton v0.0.0-20260219201907-054376f21418/go.mod h1:FDDjLuc4vrfclu3JHkMaREg0XZz7Lw1MK47Z4jJ4U5Q= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.51.5 h1:RwZXxdIAOyjp6cwc9Quxgr38k8r7ACz+Lxh9o/A6oH0= +github.com/smartcontractkit/chainlink-testing-framework/seth v1.51.5/go.mod h1:kHYJnZUqiPF7/xN5273prV+srrLJkS77GbBXHLKQpx0= +github.com/smartcontractkit/chainlink-ton v0.0.0-20260415120434-cecc380f8d87 h1:NgA2+Q0wfHicP/QeY1hgULQ1ZBk1sgBpOJi3GpxfjE8= +github.com/smartcontractkit/chainlink-ton v0.0.0-20260415120434-cecc380f8d87/go.mod h1:UmQdvE8BtbLdoOFY0+Adqoc7HT1Hd1bbFY/yymuM0NU= github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250908203554-5bd9d2fe9513 h1:XRNxgcNqagXu6e4smJuS1crRK5cUAcCVd7u+iLduHDM= github.com/smartcontractkit/chainlink-tron/relayer v0.0.11-0.20250908203554-5bd9d2fe9513/go.mod h1:ccjEgNeqOO+bjPddnL4lUrNLzyCvGCxgBjJdhFX3wa8= github.com/smartcontractkit/chainlink-tron/relayer/gotron-sdk v0.0.4 h1:J4qtAo0ZmgX5pIr8Y5mdC+J2rj2e/6CTUC263t6mGOM= @@ -734,10 +766,16 @@ github.com/smartcontractkit/mcms v0.40.1 h1:r9bU/2GfIf6mHHM4PklSBkfi2Lq4+EGILC81 github.com/smartcontractkit/mcms v0.40.1/go.mod h1:7YqJPR8w9GiO1L/JjjTrwlSwAZ7i3J7cgOcu88PqtvU= github.com/smartcontractkit/wsrpc v0.8.5-0.20250502134807-c57d3d995945 h1:zxcODLrFytOKmAd8ty8S/XK6WcIEJEgRBaL7sY/7l4Y= github.com/smartcontractkit/wsrpc v0.8.5-0.20250502134807-c57d3d995945/go.mod h1:m3pdp17i4bD50XgktkzWetcV5yaLsi7Gunbv4ZgN6qg= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw= +github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U= +github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I= +github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg= github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY= github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk= github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU= +github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY= github.com/stellar/go-stellar-sdk v0.1.0 h1:MfV7dv4k6xQQrWeKT7npWyKhjoayphLVGwXKtTLNeH8= github.com/stellar/go-stellar-sdk v0.1.0/go.mod h1:fZPcxQZw1I0zZ+X76uFcVPqmQCaYbWc87lDFW/kQJaY= github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2 h1:OzCVd0SV5qE3ZcDeSFCmOWLZfEWZ3Oe8KtmSOYKEVWE= @@ -766,6 +804,8 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= +github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= github.com/supranational/blst v0.3.16 h1:bTDadT+3fK497EvLdWRQEjiGnUtzJ7jjIUMF0jqwYhE= github.com/supranational/blst v0.3.16/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= @@ -821,6 +861,15 @@ github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaD github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6 h1:VRdX3Gn/I7ITbzUY4ZNfgn65tdQM9Zhf2b7KP0HZllk= github.com/zksync-sdk/zksync2-go v1.1.1-0.20250620124214-2c742ee399c6/go.mod h1:NWNlQS21isOsSsn+hLRAPpiuv+3P+LcdaZNuRt2T5Yo= +go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= +go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= +go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= +go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg= +go.dedis.ch/kyber/v3 v3.1.0 h1:ghu+kiRgM5JyD9TJ0hTIxTLQlJBR/ehjWvWwYW3XsC0= +go.dedis.ch/kyber/v3 v3.1.0/go.mod h1:kXy7p3STAurkADD+/aZcsznZGKVHEqbtmdIzvPfrs1U= +go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= +go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= +go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= go.mongodb.org/mongo-driver v1.17.2 h1:gvZyk8352qSfzyZ2UMWcpDpMSGEr1eqE4T793SqyhzM= go.mongodb.org/mongo-driver v1.17.2/go.mod h1:Hy04i7O2kC4RS06ZrhPRqj/u4DTYkFDAAccj+rVKqgQ= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= @@ -832,45 +881,45 @@ go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.65.0/go.mod h1: go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= go.opentelemetry.io/otel v1.43.0 h1:mYIM03dnh5zfN7HautFE4ieIig9amkNANT+xcVxAj9I= go.opentelemetry.io/otel v1.43.0/go.mod h1:JuG+u74mvjvcm8vj8pI5XiHy1zDeoCS2LB1spIq7Ay0= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2 h1:06ZeJRe5BnYXceSM9Vya83XXVaNGe3H1QqsvqRANQq8= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.12.2/go.mod h1:DvPtKE63knkDVP88qpatBj81JxN+w1bqfVbsbCbj1WY= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2 h1:tPLwQlXbJ8NSOfZc4OkgU5h2A38M4c9kfHSVc4PFQGs= -go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.12.2/go.mod h1:QTnxBwT/1rBIgAG1goq6xMydfYOBKU6KTiYF4fp5zL8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0 h1:vl9obrcoWVKp/lwl8tRE33853I8Xru9HFbw/skNeLs8= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.38.0/go.mod h1:GAXRxmLJcVM3u22IjTg74zWBrRCKq8BnOqUVLodpcpw= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0 h1:gAU726w9J8fwr4qRDqu1GYMNNs4gXrU+Pv20/N1UpB4= -go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.36.0/go.mod h1:RboSDkp7N292rgu+T0MgVt2qgFGu6qa1RpZDOtpL76w= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0 h1:ao6Oe+wSebTlQ1OEht7jlYTzQKE+pnx/iNywFvTbuuI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.41.0/go.mod h1:u3T6vz0gh/NVzgDgiwkgLxpsSF6PaPmo2il0apGJbls= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0 h1:EtFWSnwW9hGObjkIdmlnWSydO+Qs8OwzfzXLUPg4xOc= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.37.0/go.mod h1:QjUEoiGCPkvFZ/MjK6ZZfNOS6mfVEVKYE99dFhuN2LI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0 h1:inYW9ZhgqiDqh6BioM7DVHHzEGVq76Db5897WLGZ5Go= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.41.0/go.mod h1:Izur+Wt8gClgMJqO/cZ8wdeeMryJ/xxiOVgFSSfpDTY= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0 h1:yEX3aC9KDgvYPhuKECHbOlr5GLwH6KTjLJ1sBSkkxkc= -go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.13.0/go.mod h1:/GXR0tBmmkxDaCUGahvksvp66mx4yh5+cFXgSlhg0vQ= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0 h1:rixTyDGXFxRy1xzhKrotaHy3/KXdPhlWARrCgK+eqUY= -go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.36.0/go.mod h1:dowW6UsM9MKbJq5JTz2AMVp3/5iW5I/TStsk8S+CfHw= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0 h1:G8Xec/SgZQricwWBJF/mHZc7A02YHedfFDENwJEdRA0= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.36.0/go.mod h1:PD57idA/AiFD5aqoxGxCvT/ILJPeHy3MjqU/NS7KogY= -go.opentelemetry.io/otel/log v0.15.0 h1:0VqVnc3MgyYd7QqNVIldC3dsLFKgazR6P3P3+ypkyDY= -go.opentelemetry.io/otel/log v0.15.0/go.mod h1:9c/G1zbyZfgu1HmQD7Qj84QMmwTp2QCQsZH1aeoWDE4= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0 h1:Dn8rkudDzY6KV9dr/D/bTUuWgqDf9xe0rr4G2elrn0Y= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploggrpc v0.19.0/go.mod h1:gMk9F0xDgyN9M/3Ed5Y1wKcx/9mlU91NXY2SNq7RQuU= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0 h1:HIBTQ3VO5aupLKjC90JgMqpezVXwFuq6Ryjn0/izoag= +go.opentelemetry.io/otel/exporters/otlp/otlplog/otlploghttp v0.19.0/go.mod h1:ji9vId85hMxqfvICA0Jt8JqEdrXaAkcpkI9HPXya0ro= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0 h1:8UQVDcZxOJLtX6gxtDt3vY2WTgvZqMQRzjsqiIHQdkc= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc v1.43.0/go.mod h1:2lmweYCiHYpEjQ/lSJBYhj9jP1zvCvQW4BqL9dnT7FQ= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0 h1:w1K+pCJoPpQifuVpsKamUdn9U0zM3xUziVOqsGksUrY= +go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.43.0/go.mod h1:HBy4BjzgVE8139ieRI75oXm3EcDN+6GhD88JT1Kjvxg= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 h1:88Y4s2C8oTui1LGM6bTWkw0ICGcOLCAI5l6zsD1j20k= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0/go.mod h1:Vl1/iaggsuRlrHf/hfPJPvVag77kKyvrLeD10kpMl+A= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0 h1:RAE+JPfvEmvy+0LzyUA25/SGawPwIUbZ6u0Wug54sLc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.43.0/go.mod h1:AGmbycVGEsRx9mXMZ75CsOyhSP6MFIcj/6dnG+vhVjk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 h1:3iZJKlCZufyRzPzlQhUIWVmfltrXuGyfjREgGP3UUjc= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0/go.mod h1:/G+nUPfhq2e+qiXMGxMwumDrP5jtzU+mWN7/sjT2rak= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.19.0 h1:GJkybS+crDMdExT/BUNCEgfrmfboztcS6PhvSo88HKM= +go.opentelemetry.io/otel/exporters/stdout/stdoutlog v0.19.0/go.mod h1:NuAyxRYIG2lKX3YQkB+83StTxM7s52PUUkRRiC0wnYI= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0 h1:TC+BewnDpeiAmcscXbGMfxkO+mwYUwE/VySwvw88PfA= +go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.43.0/go.mod h1:J/ZyF4vfPwsSr9xJSPyQ4LqtcTPULFR64KwTikGLe+A= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0 h1:mS47AX77OtFfKG4vtp+84kuGSFZHTyxtXIN269vChY0= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.43.0/go.mod h1:PJnsC41lAGncJlPUniSwM81gc80GkgWJWr3cu2nKEtU= +go.opentelemetry.io/otel/log v0.19.0 h1:KUZs/GOsw79TBBMfDWsXS+KZ4g2Ckzksd1ymzsIEbo4= +go.opentelemetry.io/otel/log v0.19.0/go.mod h1:5DQYeGmxVIr4n0/BcJvF4upsraHjg6vudJJpnkL6Ipk= go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= go.opentelemetry.io/otel/metric v1.43.0 h1:d7638QeInOnuwOONPp4JAOGfbCEpYb+K6DVWvdxGzgM= go.opentelemetry.io/otel/metric v1.43.0/go.mod h1:RDnPtIxvqlgO8GRW18W6Z/4P462ldprJtfxHxyKd2PY= go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= go.opentelemetry.io/otel/sdk v1.43.0 h1:pi5mE86i5rTeLXqoF/hhiBtUNcrAGHLKQdhg4h4V9Dg= go.opentelemetry.io/otel/sdk v1.43.0/go.mod h1:P+IkVU3iWukmiit/Yf9AWvpyRDlUeBaRg6Y+C58QHzg= -go.opentelemetry.io/otel/sdk/log v0.15.0 h1:WgMEHOUt5gjJE93yqfqJOkRflApNif84kxoHWS9VVHE= -go.opentelemetry.io/otel/sdk/log v0.15.0/go.mod h1:qDC/FlKQCXfH5hokGsNg9aUBGMJQsrUyeOiW5u+dKBQ= -go.opentelemetry.io/otel/sdk/log/logtest v0.13.0 h1:9yio6AFZ3QD9j9oqshV1Ibm9gPLlHNxurno5BreMtIA= -go.opentelemetry.io/otel/sdk/log/logtest v0.13.0/go.mod h1:QOGiAJHl+fob8Nu85ifXfuQYmJTFAvcrxL6w5/tu168= +go.opentelemetry.io/otel/sdk/log v0.19.0 h1:scYVLqT22D2gqXItnWiocLUKGH9yvkkeql5dBDiXyko= +go.opentelemetry.io/otel/sdk/log v0.19.0/go.mod h1:vFBowwXGLlW9AvpuF7bMgnNI95LiW10szrOdvzBHlAg= +go.opentelemetry.io/otel/sdk/log/logtest v0.19.0 h1:BEbF7ZBB6qQloV/Ub1+3NQoOUnVtcGkU3XX4Ws3GQfk= +go.opentelemetry.io/otel/sdk/log/logtest v0.19.0/go.mod h1:Lua81/3yM0wOmoHTokLj9y9ADeA02v1naRrVrkAZuKk= go.opentelemetry.io/otel/sdk/metric v1.43.0 h1:S88dyqXjJkuBNLeMcVPRFXpRw2fuwdvfCGLEo89fDkw= go.opentelemetry.io/otel/sdk/metric v1.43.0/go.mod h1:C/RJtwSEJ5hzTiUz5pXF1kILHStzb9zFlIEe85bhj6A= go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= go.opentelemetry.io/otel/trace v1.43.0 h1:BkNrHpup+4k4w+ZZ86CZoHHEkohws8AY+WTX09nk+3A= go.opentelemetry.io/otel/trace v1.43.0/go.mod h1:/QJhyVBUUswCphDVxq+8mld+AvhXZLhe+8WVFxiFff0= -go.opentelemetry.io/proto/otlp v1.9.0 h1:l706jCMITVouPOqEnii2fIAuO3IVGBRPV5ICjceRb/A= -go.opentelemetry.io/proto/otlp v1.9.0/go.mod h1:xE+Cx5E/eEHw+ISFkwPLwCZefwVjY+pqKg1qcK03+/4= +go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g= +go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -897,10 +946,13 @@ go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI= go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= +go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= +go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.8.0 h1:3wRIsP3pM4yUptoR96otTUOXI367OS0+c9eeRi9doIc= golang.org/x/arch v0.8.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -916,8 +968,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.20.0/go.mod h1:Xwo95rrVNIoSMx9wa1JroENMToLWn3RNVrTBpLHgZPQ= -golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts= -golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos= +golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4= +golang.org/x/crypto v0.49.0/go.mod h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= @@ -955,8 +1007,8 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60= -golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM= +golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0= +golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ= golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= @@ -972,6 +1024,7 @@ golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190124100055-b90733256f2e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1019,8 +1072,8 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.40.0 h1:36e4zGLqU4yhjlmxEaagx2KuYbJq3EwY8K943ZsHcvg= -golang.org/x/term v0.40.0/go.mod h1:w2P8uVp06p2iyKKuvXIm7N/y0UCRt3UfJTfZ7oOpglM= +golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU= +golang.org/x/term v0.41.0/go.mod h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= @@ -1031,10 +1084,10 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk= -golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA= -golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI= -golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4= +golang.org/x/text v0.35.0 h1:JOVx6vVDFokkpaq1AEptVzLTpDe9KGpj5tR4/X+ybL8= +golang.org/x/text v0.35.0/go.mod h1:khi/HExzZJ2pGnjenulevKNX1W67CUy0AsXcNubPGCA= +golang.org/x/time v0.15.0 h1:bbrp8t3bGUeFOx08pvsMYRTCVSMk89u4tKbNOZbp88U= +golang.org/x/time v0.15.0/go.mod h1:Y4YMaQmXwGQZoFaVFk4YpCt4FLQMYKZe9oeV/f4MSno= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= @@ -1070,10 +1123,10 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20210401141331-865547bb08e2/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0= -google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9 h1:VPWxll4HlMw1Vs/qXtN7BvhZqsS9cdAittCNvVENElA= +google.golang.org/genproto/googleapis/api v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:7QBABkRtR8z+TEnmXTqIqwJLlzrZKVfAUm7tY3yGv0M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9 h1:m8qni9SQFH0tJc1X0vmnpw/0t+AImlSvp30sEupozUg= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260401024825-9d38bb4040a9/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= diff --git a/evm/indexer_config.go b/evm/indexer_config.go index 8924b4bca..437d89830 100644 --- a/evm/indexer_config.go +++ b/evm/indexer_config.go @@ -1,21 +1,63 @@ package evm import ( + "fmt" + + "github.com/Masterminds/semver/v3" + cctpverifier "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/operations/cctp_verifier" + lombardverifier "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/operations/lombard_verifier" + "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/versioned_verifier_resolver" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + cldfdeployment "github.com/smartcontractkit/chainlink-deployments-framework/deployment" "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" ) type evmIndexerConfigAdapter struct{} -// ResolveVerifierAddresses returns the EVM verifier contract addresses of the given kind -// (committee, cctp, lombard) for the given chain and qualifier from the datastore. -func (a *evmIndexerConfigAdapter) ResolveVerifierAddresses(ds datastore.DataStore, chainSelector uint64, qualifier string, kind adapters.VerifierKind) ([]string, error) { - // TODO: read verifier addresses from EVM datastore entries for this - // chainSelector, qualifier, and verifier kind. - return nil, &adapters.MissingIndexerVerifierAddressesError{ - Kind: kind, - ChainSelector: chainSelector, - Qualifier: qualifier, +func (a *evmIndexerConfigAdapter) ResolveVerifierAddresses( + ds datastore.DataStore, + chainSelector uint64, + qualifier string, + kind adapters.VerifierKind, +) ([]string, error) { + resolverType, version, err := resolveIndexerContractMeta(kind) + if err != nil { + return nil, err + } + + refs := ds.Addresses().Filter( + datastore.AddressRefByChainSelector(chainSelector), + datastore.AddressRefByQualifier(qualifier), + datastore.AddressRefByType(datastore.ContractType(resolverType)), + datastore.AddressRefByVersion(version), + ) + + if len(refs) == 0 { + return nil, &adapters.MissingIndexerVerifierAddressesError{ + Kind: kind, + ChainSelector: chainSelector, + Qualifier: qualifier, + } + } + + addresses := make([]string, 0, len(refs)) + for _, r := range refs { + addresses = append(addresses, r.Address) + } + + return addresses, nil +} + +func resolveIndexerContractMeta(kind adapters.VerifierKind) (cldfdeployment.ContractType, *semver.Version, error) { + switch kind { + case adapters.CommitteeVerifierKind: + return versioned_verifier_resolver.CommitteeVerifierResolverType, versioned_verifier_resolver.Version, nil + case adapters.CCTPVerifierKind: + return versioned_verifier_resolver.CCTPVerifierResolverType, cctpverifier.Version, nil + case adapters.LombardVerifierKind: + return versioned_verifier_resolver.LombardVerifierResolverType, lombardverifier.Version, nil + default: + return "", nil, fmt.Errorf("unknown verifier kind %q", kind) } } diff --git a/evm/token_verifier_config.go b/evm/token_verifier_config.go index 005488540..309fe4af5 100644 --- a/evm/token_verifier_config.go +++ b/evm/token_verifier_config.go @@ -3,6 +3,11 @@ package evm import ( "fmt" + dsutils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore" + cctpverifier "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/operations/cctp_verifier" + onrampop "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/operations/onramp" + rmnremote "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/operations/rmn_remote" + "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/versioned_verifier_resolver" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" @@ -10,15 +15,63 @@ import ( type evmTokenVerifierConfigAdapter struct{} -// ResolveTokenVerifierAddresses returns the EVM-specific contract addresses needed to -// build the token verifier config (OnRamp, RMNRemote, CCTP/Lombard verifiers and resolvers). func (a *evmTokenVerifierConfigAdapter) ResolveTokenVerifierAddresses( ds datastore.DataStore, chainSelector uint64, cctpQualifier string, lombardQualifier string, ) (*adapters.TokenVerifierChainAddresses, error) { - // TODO: read OnRamp, RMNRemote, CCTPVerifier, CCTPVerifierResolver, - // and LombardVerifierResolver addresses from EVM datastore entries. - return nil, fmt.Errorf("EVM token verifier config adapter not yet implemented for chain %d", chainSelector) + toAddress := func(ref datastore.AddressRef) (string, error) { return ref.Address, nil } + + onRampAddr, err := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(onrampop.ContractType), + }, chainSelector, toAddress) + if err != nil { + return nil, fmt.Errorf("failed to get on ramp address for chain %d: %w", chainSelector, err) + } + + rmnRemoteAddr, err := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(rmnremote.ContractType), + }, chainSelector, toAddress) + if err != nil { + return nil, fmt.Errorf("failed to get rmn remote address for chain %d: %w", chainSelector, err) + } + + result := &adapters.TokenVerifierChainAddresses{ + OnRampAddress: onRampAddr, + RMNRemoteAddress: rmnRemoteAddr, + } + + cctpVerifierAddr, cctpVerifierErr := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(cctpverifier.ContractType), + Qualifier: cctpQualifier, + }, chainSelector, toAddress) + + cctpResolverAddr, cctpResolverErr := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(versioned_verifier_resolver.CCTPVerifierResolverType), + Qualifier: cctpQualifier, + }, chainSelector, toAddress) + + if (cctpVerifierErr == nil) != (cctpResolverErr == nil) { + return nil, fmt.Errorf( + "chain %d: cctp verifier and resolver must both exist or both be absent (verifier error: %v, resolver error: %v)", + chainSelector, cctpVerifierErr, cctpResolverErr, + ) + } + + if cctpVerifierErr == nil { + result.CCTPVerifierAddress = cctpVerifierAddr + result.CCTPVerifierResolverAddress = cctpResolverAddr + } + + lombardResolverAddr, lombardResolverErr := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(versioned_verifier_resolver.LombardVerifierResolverType), + Qualifier: lombardQualifier, + }, chainSelector, toAddress) + + if lombardResolverErr == nil { + result.LombardVerifierResolverAddress = lombardResolverAddr + } + + return result, nil } diff --git a/evm/verifier_config.go b/evm/verifier_config.go index 50fd6a267..ca9a09cab 100644 --- a/evm/verifier_config.go +++ b/evm/verifier_config.go @@ -4,6 +4,12 @@ import ( "fmt" chainsel "github.com/smartcontractkit/chain-selectors" + dsutils "github.com/smartcontractkit/chainlink-ccip/deployment/utils/datastore" + execop "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/operations/executor" + onrampop "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/operations/onramp" + rmnremote "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/operations/rmn_remote" + "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/sequences" + "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v2_0_0/versioned_verifier_resolver" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" @@ -11,21 +17,61 @@ import ( type evmVerifierConfigAdapter struct{} -// GetSignerAddressFamily returns the chain-selectors family whose OCR2 signing key -// EVM committee verifier jobs must use. func (a *evmVerifierConfigAdapter) GetSignerAddressFamily() string { return chainsel.FamilyEVM } -// ResolveVerifierContractAddresses reads EVM committee verifier contract addresses -// (CommitteeVerifier, OnRamp, ExecutorProxy, RMNRemote) from the datastore. func (a *evmVerifierConfigAdapter) ResolveVerifierContractAddresses( ds datastore.DataStore, chainSelector uint64, committeeQualifier string, executorQualifier string, ) (*adapters.VerifierContractAddresses, error) { - // TODO: resolve addresses from EVM-specific datastore entries for this - // chainSelector, committeeQualifier, and executorQualifier. - return nil, fmt.Errorf("EVM verifier config adapter not yet implemented for chain %d", chainSelector) + toAddress := func(ref datastore.AddressRef) (string, error) { return ref.Address, nil } + + committeeVerifierAddr, err := dsutils.FindAndFormatFirstRef(ds, chainSelector, toAddress, + datastore.AddressRef{ + Type: datastore.ContractType(versioned_verifier_resolver.CommitteeVerifierResolverType), + Qualifier: committeeQualifier, + }, + datastore.AddressRef{ + Type: datastore.ContractType(versioned_verifier_resolver.CommitteeVerifierContractType), + Qualifier: committeeQualifier, + }, + ) + if err != nil { + return nil, fmt.Errorf("failed to get committee verifier address for chain %d: %w", chainSelector, err) + } + + onRampAddr, err := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(onrampop.ContractType), + Version: onrampop.Version, + }, chainSelector, toAddress) + if err != nil { + return nil, fmt.Errorf("failed to get on ramp address for chain %d: %w", chainSelector, err) + } + + executorAddr, err := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(sequences.ExecutorProxyType), + Qualifier: executorQualifier, + Version: execop.Version, + }, chainSelector, toAddress) + if err != nil { + return nil, fmt.Errorf("failed to get executor proxy address for chain %d: %w", chainSelector, err) + } + + rmnRemoteAddr, err := dsutils.FindAndFormatRef(ds, datastore.AddressRef{ + Type: datastore.ContractType(rmnremote.ContractType), + Version: rmnremote.Version, + }, chainSelector, toAddress) + if err != nil { + return nil, fmt.Errorf("failed to get rmn remote address for chain %d: %w", chainSelector, err) + } + + return &adapters.VerifierContractAddresses{ + CommitteeVerifierAddress: committeeVerifierAddr, + OnRampAddress: onRampAddr, + ExecutorProxyAddress: executorAddr, + RMNRemoteAddress: rmnRemoteAddr, + }, nil } From 0d256ff6d4617d0e6f1afc0f67be641c0f05c59c Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Fri, 17 Apr 2026 11:34:46 -0700 Subject: [PATCH 03/17] deps --- build/devenv/expand_ha_test.go | 16 ++++++++-------- deployment/go.mod | 2 +- deployment/go.sum | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/build/devenv/expand_ha_test.go b/build/devenv/expand_ha_test.go index b719b0250..66c58700a 100644 --- a/build/devenv/expand_ha_test.go +++ b/build/devenv/expand_ha_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/build/devenv/services" "github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config" ) @@ -387,12 +387,12 @@ type cfgOption func(*Cfg) func buildCfgPtr(opts ...cfgOption) *Cfg { c := &Cfg{ HighAvailability: true, - EnvironmentTopology: &offchain.EnvironmentTopology{ - NOPTopology: &offchain.NOPTopology{ - NOPs: []offchain.NOPConfig{ + EnvironmentTopology: &ccvdeployment.EnvironmentTopology{ + NOPTopology: &ccvdeployment.NOPTopology{ + NOPs: []ccvdeployment.NOPConfig{ {Alias: "nop-1", Name: "nop-1"}, }, - Committees: make(map[string]offchain.CommitteeConfig), + Committees: make(map[string]ccvdeployment.CommitteeConfig), }, }, } @@ -437,17 +437,17 @@ func withAggregatorWithClients(committee string, hostPort, dbPort, redisPort, re func withTopologyCommittee(name, qualifier string, insecure bool) cfgOption { return func(c *Cfg) { - c.EnvironmentTopology.NOPTopology.Committees[name] = offchain.CommitteeConfig{ + c.EnvironmentTopology.NOPTopology.Committees[name] = ccvdeployment.CommitteeConfig{ Qualifier: qualifier, VerifierVersion: semver.MustParse("2.0.0"), - Aggregators: []offchain.AggregatorConfig{ + Aggregators: []ccvdeployment.AggregatorConfig{ { Name: "default", Address: fmt.Sprintf("%s-aggregator:50051", name), InsecureAggregatorConnection: insecure, }, }, - ChainConfigs: map[string]offchain.ChainCommitteeConfig{ + ChainConfigs: map[string]ccvdeployment.ChainCommitteeConfig{ "3379446385462418246": { NOPAliases: []string{"nop-1"}, Threshold: 1, diff --git a/deployment/go.mod b/deployment/go.mod index dea1e8731..f267503b0 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -37,7 +37,7 @@ require ( github.com/btcsuite/btcd/btcutil v1.1.6 // indirect github.com/btcsuite/btcd/chaincfg/chainhash v1.1.0 // indirect github.com/btcsuite/btcutil v1.0.2 // indirect - github.com/buger/jsonparser v1.1.1 // indirect + github.com/buger/jsonparser v1.1.2 // indirect github.com/bytedance/sonic v1.11.6 // indirect github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect diff --git a/deployment/go.sum b/deployment/go.sum index 52cb59c46..0f328db5b 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -105,8 +105,8 @@ github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtE github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/FBatYVw= github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c= -github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/buger/jsonparser v1.1.2 h1:frqHqw7otoVbk5M8LlE/L7HTnIq2v9RX6EJ48i9AxJk= +github.com/buger/jsonparser v1.1.2/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= From d4820eb708c33929365892c87672851f3acc3b31 Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Fri, 17 Apr 2026 11:53:08 -0700 Subject: [PATCH 04/17] lint --- build/devenv/environment.go | 10 +++++----- build/devenv/expand_ha_test.go | 2 +- build/devenv/implcommon.go | 2 +- build/devenv/offchainloader/loader.go | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/devenv/environment.go b/build/devenv/environment.go index 957eb4764..9e7156cea 100644 --- a/build/devenv/environment.go +++ b/build/devenv/environment.go @@ -23,11 +23,6 @@ import ( chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-ccv/bootstrap" - _ "github.com/smartcontractkit/chainlink-ccv/evm" - ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" - ccvadapters "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" - ccvchangesets "github.com/smartcontractkit/chainlink-ccv/deployment/changesets" - ccvshared "github.com/smartcontractkit/chainlink-ccv/deployment/shared" "github.com/smartcontractkit/chainlink-ccv/build/devenv/cciptestinterfaces" devenvcommon "github.com/smartcontractkit/chainlink-ccv/build/devenv/common" "github.com/smartcontractkit/chainlink-ccv/build/devenv/jobs" @@ -37,6 +32,11 @@ import ( "github.com/smartcontractkit/chainlink-ccv/build/devenv/services/committeeverifier" executorsvc "github.com/smartcontractkit/chainlink-ccv/build/devenv/services/executor" "github.com/smartcontractkit/chainlink-ccv/build/devenv/util" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" + ccvadapters "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" + ccvchangesets "github.com/smartcontractkit/chainlink-ccv/deployment/changesets" + ccvshared "github.com/smartcontractkit/chainlink-ccv/deployment/shared" + _ "github.com/smartcontractkit/chainlink-ccv/evm" "github.com/smartcontractkit/chainlink-ccv/executor" "github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config" "github.com/smartcontractkit/chainlink-ccv/protocol" diff --git a/build/devenv/expand_ha_test.go b/build/devenv/expand_ha_test.go index 66c58700a..0da7f0ab9 100644 --- a/build/devenv/expand_ha_test.go +++ b/build/devenv/expand_ha_test.go @@ -8,8 +8,8 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/build/devenv/services" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config" ) diff --git a/build/devenv/implcommon.go b/build/devenv/implcommon.go index 7a471e893..39052be85 100644 --- a/build/devenv/implcommon.go +++ b/build/devenv/implcommon.go @@ -16,9 +16,9 @@ import ( devenvmcms "github.com/smartcontractkit/chainlink-ccip/deployment/utils/mcms" ccipAdapters "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/adapters" ccipChangesets "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/changesets" - ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/build/devenv/cciptestinterfaces" devenvcommon "github.com/smartcontractkit/chainlink-ccv/build/devenv/common" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-deployments-framework/deployment" "github.com/smartcontractkit/chainlink-deployments-framework/operations" diff --git a/build/devenv/offchainloader/loader.go b/build/devenv/offchainloader/loader.go index f05818ab7..e97e79a84 100644 --- a/build/devenv/offchainloader/loader.go +++ b/build/devenv/offchainloader/loader.go @@ -1,8 +1,8 @@ package offchainloader import ( - ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/model" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config" "github.com/smartcontractkit/chainlink-ccv/pkg/chainaccess" "github.com/smartcontractkit/chainlink-ccv/protocol" From 085723b8cd6dad9f0ca7decfed357b9d7e93feaa Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Mon, 20 Apr 2026 05:31:57 -0700 Subject: [PATCH 05/17] cr comments --- build/devenv/environment.go | 14 ++-- deployment/adapters/aggregator_config.go | 59 ----------------- deployment/adapters/executor_config.go | 65 ------------------- deployment/adapters/indexer_config.go | 64 ------------------ deployment/adapters/token_verifier_config.go | 57 ---------------- deployment/adapters/verifier_config.go | 55 ---------------- .../changesets/apply_executor_config.go | 13 ++-- .../changesets/apply_verifier_config.go | 19 +++--- .../changesets/generate_aggregator_config.go | 29 ++++++--- .../changesets/generate_indexer_config.go | 13 ++-- .../generate_token_verifier_config.go | 11 ++-- deployment/shared/types.go | 16 ----- deployment/topology.go | 3 + evm/register.go | 14 ++-- 14 files changed, 71 insertions(+), 361 deletions(-) diff --git a/build/devenv/environment.go b/build/devenv/environment.go index 9e7156cea..932a36e09 100644 --- a/build/devenv/environment.go +++ b/build/devenv/environment.go @@ -570,7 +570,7 @@ func generateExecutorJobSpecs( execNOPAliases = append(execNOPAliases, exec.NOPAlias) } - cs := ccvchangesets.ApplyExecutorConfig(ccvadapters.GetExecutorConfigRegistry()) + cs := ccvchangesets.ApplyExecutorConfig(ccvadapters.GetRegistry()) output, err := cs.Apply(*e, ccvchangesets.ApplyExecutorConfigInput{ Topology: topology, ExecutorQualifier: qualifier, @@ -731,7 +731,7 @@ func generateVerifierJobSpecs( } disableFinalityCheckers := disableFinalityCheckersPerFamily[family] - cs := ccvchangesets.ApplyVerifierConfig(ccvadapters.GetVerifierJobConfigRegistry()) + cs := ccvchangesets.ApplyVerifierConfig(ccvadapters.GetRegistry()) output, err := cs.Apply(*e, ccvchangesets.ApplyVerifierConfigInput{ Topology: topology, CommitteeQualifier: committeeName, @@ -1245,7 +1245,7 @@ func NewEnvironment() (in *Cfg, err error) { // Use changeset to generate committee config from on-chain state instanceName := aggregatorInput.InstanceName() - cs := ccvchangesets.GenerateAggregatorConfig(ccvadapters.GetAggregatorConfigRegistry()) + cs := ccvchangesets.GenerateAggregatorConfig(ccvadapters.GetRegistry()) output, err := cs.Apply(*e, ccvchangesets.GenerateAggregatorConfigInput{ Topology: topology, ServiceIdentifier: instanceName + "-aggregator", @@ -1286,7 +1286,7 @@ func NewEnvironment() (in *Cfg, err error) { // One shared config is generated; all indexers use the same config and duplicated secrets/auth. if len(in.Aggregator) > 0 && len(in.Indexer) > 0 { firstIdx := in.Indexer[0] - cs := ccvchangesets.GenerateIndexerConfig(ccvadapters.GetIndexerConfigRegistry()) + cs := ccvchangesets.GenerateIndexerConfig(ccvadapters.GetRegistry()) output, err := cs.Apply(*e, ccvchangesets.GenerateIndexerConfigInput{ ServiceIdentifier: "indexer", CommitteeVerifierNameToQualifier: firstIdx.CommitteeVerifierNameToQualifier, @@ -1503,15 +1503,15 @@ func NewEnvironment() (in *Cfg, err error) { } // Use changeset to generate token verifier config from on-chain state - cs := ccvchangesets.GenerateTokenVerifierConfig(ccvadapters.GetTokenVerifierConfigRegistry()) + cs := ccvchangesets.GenerateTokenVerifierConfig(ccvadapters.GetRegistry()) output, err := cs.Apply(*e, ccvchangesets.GenerateTokenVerifierConfigInput{ ServiceIdentifier: "TokenVerifier", ChainSelectors: selectors, PyroscopeURL: template.PyroscopeURL, - Monitoring: ccvshared.MonitoringInput{ + Monitoring: ccvdeployment.MonitoringConfig{ Enabled: template.Monitoring.Enabled, Type: template.Monitoring.Type, - Beholder: ccvshared.BeholderInput{ + Beholder: ccvdeployment.BeholderConfig{ InsecureConnection: template.Monitoring.Beholder.InsecureConnection, CACertFile: template.Monitoring.Beholder.CACertFile, OtelExporterGRPCEndpoint: template.Monitoring.Beholder.OtelExporterGRPCEndpoint, diff --git a/deployment/adapters/aggregator_config.go b/deployment/adapters/aggregator_config.go index b6d566302..f4f0bb093 100644 --- a/deployment/adapters/aggregator_config.go +++ b/deployment/adapters/aggregator_config.go @@ -2,10 +2,7 @@ package adapters import ( "context" - "fmt" - "sync" - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-deployments-framework/deployment" ) @@ -31,59 +28,3 @@ type AggregatorConfigAdapter interface { // ResolveVerifierAddress returns the verifier contract address for the given chain and qualifier using the datastore. ResolveVerifierAddress(ds datastore.DataStore, chainSelector uint64, qualifier string) (string, error) } - -type AggregatorConfigRegistry struct { - mu sync.Mutex - adapters map[string]AggregatorConfigAdapter -} - -var ( - singletonOffchainConfigRegistry *AggregatorConfigRegistry - aggregatorConfigRegistryOnce sync.Once -) - -func newOffchainConfigRegistry() *AggregatorConfigRegistry { - return &AggregatorConfigRegistry{ - adapters: make(map[string]AggregatorConfigAdapter), - } -} - -func GetAggregatorConfigRegistry() *AggregatorConfigRegistry { - aggregatorConfigRegistryOnce.Do(func() { - singletonOffchainConfigRegistry = newOffchainConfigRegistry() - }) - return singletonOffchainConfigRegistry -} - -func (r *AggregatorConfigRegistry) Register(family string, a AggregatorConfigAdapter) { - r.mu.Lock() - defer r.mu.Unlock() - if r.adapters == nil { - r.adapters = make(map[string]AggregatorConfigAdapter) - } - if _, exists := r.adapters[family]; !exists { - r.adapters[family] = a - } -} - -func (r *AggregatorConfigRegistry) Get(family string) (AggregatorConfigAdapter, bool) { - r.mu.Lock() - defer r.mu.Unlock() - if r.adapters == nil { - return nil, false - } - a, ok := r.adapters[family] - return a, ok -} - -func (r *AggregatorConfigRegistry) GetByChain(chainSelector uint64) (AggregatorConfigAdapter, error) { - family, err := chainsel.GetSelectorFamily(chainSelector) - if err != nil { - return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) - } - adapter, ok := r.Get(family) - if !ok { - return nil, fmt.Errorf("no offchain config adapter registered for chain family %q", family) - } - return adapter, nil -} diff --git a/deployment/adapters/executor_config.go b/deployment/adapters/executor_config.go index 5d169c53d..5e0b9a5b9 100644 --- a/deployment/adapters/executor_config.go +++ b/deployment/adapters/executor_config.go @@ -1,10 +1,6 @@ package adapters import ( - "fmt" - "sync" - - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-ccv/executor" @@ -16,64 +12,3 @@ type ExecutorConfigAdapter interface { GetDeployedChains(ds datastore.DataStore, qualifier string) []uint64 BuildChainConfig(ds datastore.DataStore, chainSelector uint64, qualifier string) (executor.ChainConfiguration, error) } - -type ExecutorConfigRegistry struct { - mu sync.Mutex - adapters map[string]ExecutorConfigAdapter -} - -var ( - singletonExecutorConfigRegistry *ExecutorConfigRegistry - executorConfigRegistryOnce sync.Once -) - -func NewExecutorConfigRegistry() *ExecutorConfigRegistry { - return &ExecutorConfigRegistry{ - adapters: make(map[string]ExecutorConfigAdapter), - } -} - -func GetExecutorConfigRegistry() *ExecutorConfigRegistry { - executorConfigRegistryOnce.Do(func() { - singletonExecutorConfigRegistry = NewExecutorConfigRegistry() - }) - return singletonExecutorConfigRegistry -} - -func (r *ExecutorConfigRegistry) Register(family string, a ExecutorConfigAdapter) { - r.mu.Lock() - defer r.mu.Unlock() - if _, exists := r.adapters[family]; !exists { - r.adapters[family] = a - } -} - -func (r *ExecutorConfigRegistry) Get(family string) (ExecutorConfigAdapter, bool) { - r.mu.Lock() - defer r.mu.Unlock() - a, ok := r.adapters[family] - return a, ok -} - -func (r *ExecutorConfigRegistry) GetByChain(chainSelector uint64) (ExecutorConfigAdapter, error) { - family, err := chainsel.GetSelectorFamily(chainSelector) - if err != nil { - return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) - } - adapter, ok := r.Get(family) - if !ok { - return nil, fmt.Errorf("no executor config adapter registered for chain family %q", family) - } - return adapter, nil -} - -// AllDeployedChains collects deployed chains across all registered adapters. -func (r *ExecutorConfigRegistry) AllDeployedChains(ds datastore.DataStore, qualifier string) []uint64 { - r.mu.Lock() - defer r.mu.Unlock() - var chains []uint64 - for _, adapter := range r.adapters { - chains = append(chains, adapter.GetDeployedChains(ds, qualifier)...) - } - return chains -} diff --git a/deployment/adapters/indexer_config.go b/deployment/adapters/indexer_config.go index 3e9e9c625..72b6cdf4c 100644 --- a/deployment/adapters/indexer_config.go +++ b/deployment/adapters/indexer_config.go @@ -2,9 +2,7 @@ package adapters import ( "fmt" - "sync" - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" ) @@ -34,65 +32,3 @@ func (e *MissingIndexerVerifierAddressesError) Error() string { type IndexerConfigAdapter interface { ResolveVerifierAddresses(ds datastore.DataStore, chainSelector uint64, qualifier string, kind VerifierKind) ([]string, error) } - -type IndexerConfigRegistry struct { - mu sync.Mutex - adapters map[string]IndexerConfigAdapter -} - -var ( - singletonIndexerConfigRegistry *IndexerConfigRegistry - indexerConfigRegistryOnce sync.Once -) - -func newIndexerConfigRegistry() *IndexerConfigRegistry { - return &IndexerConfigRegistry{ - adapters: make(map[string]IndexerConfigAdapter), - } -} - -func GetIndexerConfigRegistry() *IndexerConfigRegistry { - indexerConfigRegistryOnce.Do(func() { - singletonIndexerConfigRegistry = newIndexerConfigRegistry() - }) - return singletonIndexerConfigRegistry -} - -func (r *IndexerConfigRegistry) Register(family string, a IndexerConfigAdapter) { - r.mu.Lock() - defer r.mu.Unlock() - if r.adapters == nil { - r.adapters = make(map[string]IndexerConfigAdapter) - } - if _, exists := r.adapters[family]; !exists { - r.adapters[family] = a - } -} - -func (r *IndexerConfigRegistry) Get(family string) (IndexerConfigAdapter, bool) { - r.mu.Lock() - defer r.mu.Unlock() - if r.adapters == nil { - return nil, false - } - a, ok := r.adapters[family] - return a, ok -} - -func (r *IndexerConfigRegistry) GetByChain(chainSelector uint64) (IndexerConfigAdapter, error) { - family, err := chainsel.GetSelectorFamily(chainSelector) - if err != nil { - return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) - } - adapter, ok := r.Get(family) - if !ok { - return nil, fmt.Errorf("no indexer config adapter registered for chain family %q", family) - } - return adapter, nil -} - -func (r *IndexerConfigRegistry) HasAdapters() bool { - r.mu.Lock() - defer r.mu.Unlock() - return len(r.adapters) > 0 -} diff --git a/deployment/adapters/token_verifier_config.go b/deployment/adapters/token_verifier_config.go index 4dc496970..f7539252d 100644 --- a/deployment/adapters/token_verifier_config.go +++ b/deployment/adapters/token_verifier_config.go @@ -1,10 +1,6 @@ package adapters import ( - "fmt" - "sync" - - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" ) @@ -24,56 +20,3 @@ type TokenVerifierConfigAdapter interface { lombardQualifier string, ) (*TokenVerifierChainAddresses, error) } - -type TokenVerifierConfigRegistry struct { - mu sync.Mutex - adapters map[string]TokenVerifierConfigAdapter -} - -var ( - singletonTokenVerifierConfigRegistry *TokenVerifierConfigRegistry - tokenVerifierConfigRegistryOnce sync.Once -) - -func NewTokenVerifierConfigRegistry() *TokenVerifierConfigRegistry { - return &TokenVerifierConfigRegistry{ - adapters: make(map[string]TokenVerifierConfigAdapter), - } -} - -func GetTokenVerifierConfigRegistry() *TokenVerifierConfigRegistry { - tokenVerifierConfigRegistryOnce.Do(func() { - singletonTokenVerifierConfigRegistry = NewTokenVerifierConfigRegistry() - }) - return singletonTokenVerifierConfigRegistry -} - -func (r *TokenVerifierConfigRegistry) Register(family string, a TokenVerifierConfigAdapter) { - if a == nil { - return - } - r.mu.Lock() - defer r.mu.Unlock() - if _, exists := r.adapters[family]; !exists { - r.adapters[family] = a - } -} - -func (r *TokenVerifierConfigRegistry) Get(family string) (TokenVerifierConfigAdapter, bool) { - r.mu.Lock() - defer r.mu.Unlock() - a, ok := r.adapters[family] - return a, ok -} - -func (r *TokenVerifierConfigRegistry) GetByChain(chainSelector uint64) (TokenVerifierConfigAdapter, error) { - family, err := chainsel.GetSelectorFamily(chainSelector) - if err != nil { - return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) - } - adapter, ok := r.Get(family) - if !ok { - return nil, fmt.Errorf("no token verifier config adapter registered for chain family %q", family) - } - return adapter, nil -} diff --git a/deployment/adapters/verifier_config.go b/deployment/adapters/verifier_config.go index dd60bf9f7..3dbb8f137 100644 --- a/deployment/adapters/verifier_config.go +++ b/deployment/adapters/verifier_config.go @@ -1,10 +1,6 @@ package adapters import ( - "fmt" - "sync" - - chainsel "github.com/smartcontractkit/chain-selectors" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" ) @@ -24,56 +20,5 @@ type VerifierConfigAdapter interface { ) (*VerifierContractAddresses, error) // GetSignerAddressFamily returns the chain-selectors family string whose signing key // verifier jobs must use (e.g. chainsel.FamilyEVM for EVM committee verifiers). - // This allows the changeset layer to stay chain-agnostic. GetSignerAddressFamily() string } - -type VerifierConfigRegistry struct { - mu sync.Mutex - adapters map[string]VerifierConfigAdapter -} - -var ( - singletonVerifierJobConfigRegistry *VerifierConfigRegistry - verifierJobConfigRegistryOnce sync.Once -) - -func NewVerifierConfigRegistry() *VerifierConfigRegistry { - return &VerifierConfigRegistry{ - adapters: make(map[string]VerifierConfigAdapter), - } -} - -func GetVerifierJobConfigRegistry() *VerifierConfigRegistry { - verifierJobConfigRegistryOnce.Do(func() { - singletonVerifierJobConfigRegistry = NewVerifierConfigRegistry() - }) - return singletonVerifierJobConfigRegistry -} - -func (r *VerifierConfigRegistry) Register(family string, a VerifierConfigAdapter) { - r.mu.Lock() - defer r.mu.Unlock() - if _, exists := r.adapters[family]; !exists { - r.adapters[family] = a - } -} - -func (r *VerifierConfigRegistry) Get(family string) (VerifierConfigAdapter, bool) { - r.mu.Lock() - defer r.mu.Unlock() - a, ok := r.adapters[family] - return a, ok -} - -func (r *VerifierConfigRegistry) GetByChain(chainSelector uint64) (VerifierConfigAdapter, error) { - family, err := chainsel.GetSelectorFamily(chainSelector) - if err != nil { - return nil, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) - } - adapter, ok := r.Get(family) - if !ok { - return nil, fmt.Errorf("no verifier job config adapter registered for chain family %q", family) - } - return adapter, nil -} diff --git a/deployment/changesets/apply_executor_config.go b/deployment/changesets/apply_executor_config.go index 6a6e62a1d..fff126381 100644 --- a/deployment/changesets/apply_executor_config.go +++ b/deployment/changesets/apply_executor_config.go @@ -28,7 +28,7 @@ type ApplyExecutorConfigInput struct { RevokeOrphanedJobs bool } -func ApplyExecutorConfig(registry *adapters.ExecutorConfigRegistry) deployment.ChangeSetV2[ApplyExecutorConfigInput] { +func ApplyExecutorConfig(registry *adapters.Registry) deployment.ChangeSetV2[ApplyExecutorConfigInput] { validate := func(e deployment.Environment, cfg ApplyExecutorConfigInput) error { if cfg.Topology == nil { return fmt.Errorf("topology is required") @@ -74,7 +74,7 @@ func ApplyExecutorConfig(registry *adapters.ExecutorConfigRegistry) deployment.C } apply := func(e deployment.Environment, cfg ApplyExecutorConfigInput) (deployment.ChangesetOutput, error) { - selectors := registry.AllDeployedChains(e.DataStore, cfg.ExecutorQualifier) + selectors := registry.AllDeployedExecutorChains(e.DataStore, cfg.ExecutorQualifier) pool := cfg.Topology.ExecutorPools[cfg.ExecutorQualifier] if len(selectors) == 0 { @@ -180,18 +180,21 @@ func ApplyExecutorConfig(registry *adapters.ExecutorConfigRegistry) deployment.C } func buildExecutorChainConfigs( - registry *adapters.ExecutorConfigRegistry, + registry *adapters.Registry, ds datastore.DataStore, selectors []uint64, qualifier string, ) (map[string]executor.ChainConfiguration, error) { chainConfigs := make(map[string]executor.ChainConfiguration, len(selectors)) for _, sel := range selectors { - adapter, err := registry.GetByChain(sel) + a, err := registry.GetByChain(sel) if err != nil { return nil, fmt.Errorf("no adapter for chain %d: %w", sel, err) } - cfg, err := adapter.BuildChainConfig(ds, sel, qualifier) + if a.Executor == nil { + return nil, fmt.Errorf("no executor config adapter registered for chain %d", sel) + } + cfg, err := a.Executor.BuildChainConfig(ds, sel, qualifier) if err != nil { return nil, fmt.Errorf("failed to build config for chain %d: %w", sel, err) } diff --git a/deployment/changesets/apply_verifier_config.go b/deployment/changesets/apply_verifier_config.go index 6def6a5e1..d7886e060 100644 --- a/deployment/changesets/apply_verifier_config.go +++ b/deployment/changesets/apply_verifier_config.go @@ -32,7 +32,7 @@ type ApplyVerifierConfigInput struct { RevokeOrphanedJobs bool } -func ApplyVerifierConfig(registry *adapters.VerifierConfigRegistry) deployment.ChangeSetV2[ApplyVerifierConfigInput] { +func ApplyVerifierConfig(registry *adapters.Registry) deployment.ChangeSetV2[ApplyVerifierConfigInput] { validate := func(e deployment.Environment, cfg ApplyVerifierConfigInput) error { if cfg.Topology == nil { return fmt.Errorf("topology is required") @@ -213,19 +213,19 @@ func ApplyVerifierConfig(registry *adapters.VerifierConfigRegistry) deployment.C // getSignerFamilyFromRegistry returns the signing key family by querying the registered // adapter for any of the given chain selectors. All adapters in a committee are expected // to agree on the signer family (e.g. every EVM adapter returns chainsel.FamilyEVM). -func getSignerFamilyFromRegistry(registry *adapters.VerifierConfigRegistry, selectors []uint64) (string, error) { +func getSignerFamilyFromRegistry(registry *adapters.Registry, selectors []uint64) (string, error) { for _, sel := range selectors { - adapter, err := registry.GetByChain(sel) - if err != nil { + a, err := registry.GetByChain(sel) + if err != nil || a.Verifier == nil { continue } - return adapter.GetSignerAddressFamily(), nil + return a.Verifier.GetSignerAddressFamily(), nil } return "", fmt.Errorf("no registered verifier adapter found for any committee chain selector") } func buildVerifierContractConfigs( - registry *adapters.VerifierConfigRegistry, + registry *adapters.Registry, e deployment.Environment, selectors []uint64, committeeQualifier string, @@ -233,11 +233,14 @@ func buildVerifierContractConfigs( ) (map[string]*adapters.VerifierContractAddresses, error) { configs := make(map[string]*adapters.VerifierContractAddresses, len(selectors)) for _, sel := range selectors { - adapter, err := registry.GetByChain(sel) + a, err := registry.GetByChain(sel) if err != nil { return nil, fmt.Errorf("no adapter for chain %d: %w", sel, err) } - addrs, err := adapter.ResolveVerifierContractAddresses(e.DataStore, sel, committeeQualifier, executorQualifier) + if a.Verifier == nil { + return nil, fmt.Errorf("no verifier config adapter registered for chain %d", sel) + } + addrs, err := a.Verifier.ResolveVerifierContractAddresses(e.DataStore, sel, committeeQualifier, executorQualifier) if err != nil { return nil, fmt.Errorf("failed to resolve contract addresses for chain %d: %w", sel, err) } diff --git a/deployment/changesets/generate_aggregator_config.go b/deployment/changesets/generate_aggregator_config.go index cf22bb17d..d26432e24 100644 --- a/deployment/changesets/generate_aggregator_config.go +++ b/deployment/changesets/generate_aggregator_config.go @@ -19,7 +19,7 @@ type GenerateAggregatorConfigInput struct { Topology *ccvdeployment.EnvironmentTopology } -func GenerateAggregatorConfig(registry *adapters.AggregatorConfigRegistry) deployment.ChangeSetV2[GenerateAggregatorConfigInput] { +func GenerateAggregatorConfig(registry *adapters.Registry) deployment.ChangeSetV2[GenerateAggregatorConfigInput] { validate := func(e deployment.Environment, cfg GenerateAggregatorConfigInput) error { if cfg.ServiceIdentifier == "" { return fmt.Errorf("service identifier is required") @@ -91,7 +91,7 @@ func resolveAggregatorChainSelectors(e deployment.Environment, cfg GenerateAggre func buildAggregatorCommittee( e deployment.Environment, - registry *adapters.AggregatorConfigRegistry, + registry *adapters.Registry, committeeQualifier string, chainSelectors []uint64, ) (*ccvdeployment.Committee, error) { @@ -104,12 +104,15 @@ func buildAggregatorCommittee( seen := make(map[chainQualifier]bool) allCommittees := make(map[string][]*adapters.CommitteeState) for _, sel := range chainSelectors { - adapter, err := registry.GetByChain(sel) + a, err := registry.GetByChain(sel) if err != nil { return nil, err } + if a.Aggregator == nil { + return nil, fmt.Errorf("no aggregator config adapter registered for chain %d", sel) + } - states, err := adapter.ScanCommitteeStates(ctx, e, sel) + states, err := a.Aggregator.ScanCommitteeStates(ctx, e, sel) if err != nil { return nil, fmt.Errorf("failed to scan committee states on chain %d: %w", sel, err) } @@ -149,7 +152,7 @@ func buildAggregatorCommittee( func buildQuorumConfigs( ds datastore.DataStore, - registry *adapters.AggregatorConfigRegistry, + registry *adapters.Registry, committeeStates []*adapters.CommitteeState, committeeQualifier string, chainSelectors []uint64, @@ -175,12 +178,15 @@ func buildQuorumConfigs( continue } - adapter, err := registry.GetByChain(sigConfig.SourceChainSelector) + a, err := registry.GetByChain(sigConfig.SourceChainSelector) if err != nil { return nil, err } + if a.Aggregator == nil { + return nil, fmt.Errorf("no aggregator config adapter registered for chain %d", sigConfig.SourceChainSelector) + } - sourceVerifierAddr, err := adapter.ResolveVerifierAddress(ds, sigConfig.SourceChainSelector, committeeQualifier) + sourceVerifierAddr, err := a.Aggregator.ResolveVerifierAddress(ds, sigConfig.SourceChainSelector, committeeQualifier) if err != nil { return nil, fmt.Errorf("failed to resolve source verifier for chain %d: %w", sigConfig.SourceChainSelector, err) } @@ -235,19 +241,22 @@ func validateSignatureConfigConsistency( func buildDestinationVerifiers( ds datastore.DataStore, - registry *adapters.AggregatorConfigRegistry, + registry *adapters.Registry, committeeQualifier string, destChainSelectors []uint64, ) (map[string]string, error) { destVerifiers := make(map[string]string, len(destChainSelectors)) for _, chainSelector := range destChainSelectors { - adapter, err := registry.GetByChain(chainSelector) + a, err := registry.GetByChain(chainSelector) if err != nil { return nil, err } + if a.Aggregator == nil { + return nil, fmt.Errorf("no aggregator config adapter registered for chain %d", chainSelector) + } - addr, err := adapter.ResolveVerifierAddress(ds, chainSelector, committeeQualifier) + addr, err := a.Aggregator.ResolveVerifierAddress(ds, chainSelector, committeeQualifier) if err != nil { return nil, fmt.Errorf("failed to resolve destination verifier for chain %d: %w", chainSelector, err) } diff --git a/deployment/changesets/generate_indexer_config.go b/deployment/changesets/generate_indexer_config.go index 3a1c9326e..4a272bcfd 100644 --- a/deployment/changesets/generate_indexer_config.go +++ b/deployment/changesets/generate_indexer_config.go @@ -19,7 +19,7 @@ type GenerateIndexerConfigInput struct { LombardVerifierNameToQualifier map[string]string } -func GenerateIndexerConfig(registry *adapters.IndexerConfigRegistry) deployment.ChangeSetV2[GenerateIndexerConfigInput] { +func GenerateIndexerConfig(registry *adapters.Registry) deployment.ChangeSetV2[GenerateIndexerConfigInput] { validate := func(e deployment.Environment, cfg GenerateIndexerConfigInput) error { if cfg.ServiceIdentifier == "" { return fmt.Errorf("service identifier is required") @@ -61,7 +61,7 @@ func GenerateIndexerConfig(registry *adapters.IndexerConfigRegistry) deployment. func buildIndexerVerifierMap( ds datastore.DataStore, - registry *adapters.IndexerConfigRegistry, + registry *adapters.Registry, selectors []uint64, cfg GenerateIndexerConfigInput, ) (map[string][]string, error) { @@ -91,7 +91,7 @@ func buildIndexerVerifierMap( func collectVerifierAddresses( ds datastore.DataStore, - registry *adapters.IndexerConfigRegistry, + registry *adapters.Registry, selectors []uint64, qualifier string, kind adapters.VerifierKind, @@ -104,12 +104,15 @@ func collectVerifierAddresses( var addresses []string for _, sel := range selectors { - adapter, err := registry.GetByChain(sel) + a, err := registry.GetByChain(sel) if err != nil { return nil, err } + if a.Indexer == nil { + return nil, fmt.Errorf("no indexer config adapter registered for chain %d", sel) + } - addrs, err := adapter.ResolveVerifierAddresses(ds, sel, qualifier, kind) + addrs, err := a.Indexer.ResolveVerifierAddresses(ds, sel, qualifier, kind) if err != nil { var missingErr *adapters.MissingIndexerVerifierAddressesError if errors.As(err, &missingErr) { diff --git a/deployment/changesets/generate_token_verifier_config.go b/deployment/changesets/generate_token_verifier_config.go index e41835b6c..971faa883 100644 --- a/deployment/changesets/generate_token_verifier_config.go +++ b/deployment/changesets/generate_token_verifier_config.go @@ -61,12 +61,12 @@ type GenerateTokenVerifierConfigInput struct { ServiceIdentifier string ChainSelectors []uint64 PyroscopeURL string - Monitoring shared.MonitoringInput + Monitoring ccvdeployment.MonitoringConfig Lombard LombardConfigInput CCTP CCTPConfigInput } -func GenerateTokenVerifierConfig(registry *adapters.TokenVerifierConfigRegistry) deployment.ChangeSetV2[GenerateTokenVerifierConfigInput] { +func GenerateTokenVerifierConfig(registry *adapters.Registry) deployment.ChangeSetV2[GenerateTokenVerifierConfigInput] { validate := func(e deployment.Environment, cfg GenerateTokenVerifierConfigInput) error { if cfg.ServiceIdentifier == "" { return fmt.Errorf("service identifier is required") @@ -97,12 +97,15 @@ func GenerateTokenVerifierConfig(registry *adapters.TokenVerifierConfigRegistry) lombardVerifierResolverAddresses := make(map[string]string) for _, sel := range selectors { - adapter, err := registry.GetByChain(sel) + a, err := registry.GetByChain(sel) if err != nil { return deployment.ChangesetOutput{}, err } + if a.TokenVerifier == nil { + return deployment.ChangesetOutput{}, fmt.Errorf("no token verifier config adapter registered for chain %d", sel) + } - addrs, err := adapter.ResolveTokenVerifierAddresses( + addrs, err := a.TokenVerifier.ResolveTokenVerifierAddresses( e.DataStore, sel, cctpCfg.Qualifier, lombardCfg.Qualifier, ) if err != nil { diff --git a/deployment/shared/types.go b/deployment/shared/types.go index 217a41a79..38c44cc62 100644 --- a/deployment/shared/types.go +++ b/deployment/shared/types.go @@ -84,22 +84,6 @@ func (j *JobInfo) LatestStatus() JobProposalStatus { // NOPJobs maps NOP alias -> job ID -> job info. type NOPJobs map[NOPAlias]map[JobID]JobInfo -type MonitoringInput struct { - Enabled bool - Type string - Beholder BeholderInput -} - -type BeholderInput struct { - InsecureConnection bool - CACertFile string - OtelExporterGRPCEndpoint string - OtelExporterHTTPEndpoint string - LogStreamingEnabled bool - MetricReaderInterval int64 - TraceSampleRatio float64 - TraceBatchTimeout int64 -} type JobID string diff --git a/deployment/topology.go b/deployment/topology.go index 1d889cf3d..a7db0134c 100644 --- a/deployment/topology.go +++ b/deployment/topology.go @@ -203,6 +203,9 @@ func (c *EnvironmentTopology) Validate() error { addressSet[addr] = struct{}{} } + if c.NOPTopology == nil { + return fmt.Errorf("nop_topology is required") + } if err := c.NOPTopology.Validate(); err != nil { return fmt.Errorf("nop_topology validation failed: %w", err) } diff --git a/evm/register.go b/evm/register.go index d973f36ea..7b59b00c2 100644 --- a/evm/register.go +++ b/evm/register.go @@ -27,10 +27,12 @@ func init() { return lower }) - // Register EVM adapter implementations in the deployment registries. - adapters.GetExecutorConfigRegistry().Register(chainsel.FamilyEVM, &evmExecutorConfigAdapter{}) - adapters.GetVerifierJobConfigRegistry().Register(chainsel.FamilyEVM, &evmVerifierConfigAdapter{}) - adapters.GetAggregatorConfigRegistry().Register(chainsel.FamilyEVM, &evmAggregatorConfigAdapter{}) - adapters.GetIndexerConfigRegistry().Register(chainsel.FamilyEVM, &evmIndexerConfigAdapter{}) - adapters.GetTokenVerifierConfigRegistry().Register(chainsel.FamilyEVM, &evmTokenVerifierConfigAdapter{}) + // Register all EVM adapter implementations in the combined registry. + adapters.GetRegistry().Register(chainsel.FamilyEVM, adapters.ChainAdapters{ + Aggregator: &evmAggregatorConfigAdapter{}, + Executor: &evmExecutorConfigAdapter{}, + Verifier: &evmVerifierConfigAdapter{}, + Indexer: &evmIndexerConfigAdapter{}, + TokenVerifier: &evmTokenVerifierConfigAdapter{}, + }) } From 243467713e3a40a8e9691e8b6e4c433c54723130 Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Mon, 20 Apr 2026 05:53:22 -0700 Subject: [PATCH 06/17] add missing file --- deployment/adapters/registry.go | 88 +++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 deployment/adapters/registry.go diff --git a/deployment/adapters/registry.go b/deployment/adapters/registry.go new file mode 100644 index 000000000..bd5d6de14 --- /dev/null +++ b/deployment/adapters/registry.go @@ -0,0 +1,88 @@ +package adapters + +import ( + "fmt" + "sync" + + chainsel "github.com/smartcontractkit/chain-selectors" + "github.com/smartcontractkit/chainlink-deployments-framework/datastore" +) + +// ChainAdapters bundles all chain-family-specific adapter implementations. +// A nil field means the adapter is not supported for that family. +type ChainAdapters struct { + Aggregator AggregatorConfigAdapter + Executor ExecutorConfigAdapter + Verifier VerifierConfigAdapter + Indexer IndexerConfigAdapter + TokenVerifier TokenVerifierConfigAdapter +} + +// Registry is a single registry mapping chain family → ChainAdapters. +// Use GetRegistry() to obtain the process-wide singleton. +type Registry struct { + mu sync.Mutex + adapters map[string]ChainAdapters +} + +var ( + singletonRegistry *Registry + registryOnce sync.Once +) + +func GetRegistry() *Registry { + registryOnce.Do(func() { + singletonRegistry = &Registry{ + adapters: make(map[string]ChainAdapters), + } + }) + return singletonRegistry +} + +func (r *Registry) Register(family string, a ChainAdapters) { + r.mu.Lock() + defer r.mu.Unlock() + if _, exists := r.adapters[family]; !exists { + r.adapters[family] = a + } +} + +func (r *Registry) Get(family string) (ChainAdapters, bool) { + r.mu.Lock() + defer r.mu.Unlock() + a, ok := r.adapters[family] + return a, ok +} + +func (r *Registry) GetByChain(chainSelector uint64) (ChainAdapters, error) { + family, err := chainsel.GetSelectorFamily(chainSelector) + if err != nil { + return ChainAdapters{}, fmt.Errorf("failed to get chain family for selector %d: %w", chainSelector, err) + } + a, ok := r.Get(family) + if !ok { + return ChainAdapters{}, fmt.Errorf("no adapters registered for chain family %q", family) + } + return a, nil +} + +// AllDeployedExecutorChains collects all chain selectors with executor proxies deployed, +// across all registered families. +func (r *Registry) AllDeployedExecutorChains(ds datastore.DataStore, qualifier string) []uint64 { + r.mu.Lock() + defer r.mu.Unlock() + var chains []uint64 + for _, a := range r.adapters { + if a.Executor != nil { + chains = append(chains, a.Executor.GetDeployedChains(ds, qualifier)...) + } + } + return chains +} + +// HasAdapters reports whether any chain family has been registered. +func (r *Registry) HasAdapters() bool { + r.mu.Lock() + defer r.mu.Unlock() + return len(r.adapters) > 0 +} From 9e031418afcfd6d0f38b81e9fe5eec2ffa3479bc Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Tue, 21 Apr 2026 16:24:31 -0700 Subject: [PATCH 07/17] delete custom types --- aggregator/pkg/model/config.go | 47 ++--- build/devenv/cciptestinterfaces/interface.go | 10 +- build/devenv/common/common.go | 11 +- build/devenv/environment.go | 9 +- build/devenv/evm/impl.go | 12 +- build/devenv/implcommon.go | 11 +- build/devenv/offchainloader/loader.go | 174 ------------------ deployment/aggregator.go | 20 -- .../changesets/apply_executor_config.go | 19 +- .../changesets/apply_verifier_config.go | 20 +- .../changesets/generate_aggregator_config.go | 17 +- .../changesets/generate_indexer_config.go | 11 +- .../generate_token_verifier_config.go | 62 ++++--- deployment/env_metadata_util.go | 27 +-- deployment/go.mod | 1 + deployment/indexer.go | 10 - deployment/token_verifier.go | 55 ------ deployment/topology.go | 22 +-- executor/config.go | 67 +------ indexer/pkg/config/config.go | 6 +- indexer/pkg/config/monitoring.go | 70 +------ pkg/monitoring/config.go | 65 +++++++ verifier/pkg/vtypes/config.go | 70 +------ 23 files changed, 196 insertions(+), 620 deletions(-) delete mode 100644 build/devenv/offchainloader/loader.go delete mode 100644 deployment/aggregator.go delete mode 100644 deployment/indexer.go delete mode 100644 deployment/token_verifier.go create mode 100644 pkg/monitoring/config.go diff --git a/aggregator/pkg/model/config.go b/aggregator/pkg/model/config.go index 732632d49..5f8c20b31 100644 --- a/aggregator/pkg/model/config.go +++ b/aggregator/pkg/model/config.go @@ -11,13 +11,14 @@ import ( "time" "github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/auth" + "github.com/smartcontractkit/chainlink-ccv/pkg/monitoring" "github.com/smartcontractkit/chainlink-ccv/protocol" hmacutil "github.com/smartcontractkit/chainlink-ccv/protocol/common/hmac" ) // Signer represents a participant in the commit verification process. type Signer struct { - Address string `toml:"address"` + Address string `toml:"address" json:"address"` } // SignerIdentifier holds the chain-native signer identifier. @@ -44,9 +45,9 @@ type Committee struct { // The aggregator uses this to verify signatures from each chain's // commit verifier set. // Map structure: source selector -> QuorumConfig - QuorumConfigs map[SourceSelector]*QuorumConfig `toml:"quorumConfigs"` + QuorumConfigs map[SourceSelector]*QuorumConfig `toml:"quorumConfigs" json:"quorumConfigs"` // DestinationVerifiers maps destination chain selectors to their verifier contract addresses. - DestinationVerifiers map[DestinationSelector]string `toml:"destinationVerifiers"` + DestinationVerifiers map[DestinationSelector]string `toml:"destinationVerifiers" json:"destinationVerifiers"` // destinationVerifiersParsed holds the parsed addresses, populated during validation. destinationVerifiersParsed map[DestinationSelector]protocol.UnknownAddress } @@ -87,9 +88,9 @@ func (c *Committee) SetQuorumConfig(sourceSelector SourceSelector, quorumConfig // QuorumConfig represents the configuration for a quorum of signers. type QuorumConfig struct { - SourceVerifierAddress string `toml:"sourceVerifierAddress"` - Signers []Signer `toml:"signers"` - Threshold uint8 `toml:"threshold"` + SourceVerifierAddress string `toml:"sourceVerifierAddress" json:"sourceVerifierAddress"` + Signers []Signer `toml:"signers" json:"signers"` + Threshold uint8 `toml:"threshold" json:"threshold"` // sourceVerifierAddressParsed holds the parsed address, populated during validation. sourceVerifierAddressParsed protocol.UnknownAddress } @@ -361,35 +362,11 @@ func (c *RateLimitingConfig) getMostRestrictiveGroupLimit(client auth.ClientConf return mostRestrictive } -// MonitoringConfig provides monitoring configuration for aggregator. -type MonitoringConfig struct { - // Enabled enables the monitoring system. - Enabled bool `toml:"Enabled"` - // Type is the type of monitoring system to use (beholder, noop). - Type string `toml:"Type"` - // Beholder is the configuration for the beholder client (Not required if type is noop). - Beholder BeholderConfig `toml:"Beholder"` -} - -// BeholderConfig wraps OpenTelemetry configuration for the beholder client. -type BeholderConfig struct { - // InsecureConnection disables TLS for the beholder client. - InsecureConnection bool `toml:"InsecureConnection"` - // CACertFile is the path to the CA certificate file for the beholder client. - CACertFile string `toml:"CACertFile"` - // OtelExporterGRPCEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterGRPCEndpoint string `toml:"OtelExporterGRPCEndpoint"` - // OtelExporterHTTPEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterHTTPEndpoint string `toml:"OtelExporterHTTPEndpoint"` - // LogStreamingEnabled enables log streaming to the collector. - LogStreamingEnabled bool `toml:"LogStreamingEnabled"` - // MetricReaderInterval is the interval to scrape metrics (in seconds). - MetricReaderInterval int64 `toml:"MetricReaderInterval"` - // TraceSampleRatio is the ratio of traces to sample. - TraceSampleRatio float64 `toml:"TraceSampleRatio"` - // TraceBatchTimeout is the timeout for a batch of traces. - TraceBatchTimeout int64 `toml:"TraceBatchTimeout"` -} +// Type aliases — canonical definitions live in pkg/monitoring. +type ( + MonitoringConfig = monitoring.MonitoringConfig + BeholderConfig = monitoring.BeholderConfig +) // AggregatorConfig is the root configuration for the pb. type AggregatorConfig struct { diff --git a/build/devenv/cciptestinterfaces/interface.go b/build/devenv/cciptestinterfaces/interface.go index b1f928bcc..ac1e9cf3e 100644 --- a/build/devenv/cciptestinterfaces/interface.go +++ b/build/devenv/cciptestinterfaces/interface.go @@ -16,8 +16,8 @@ import ( tokensapi "github.com/smartcontractkit/chainlink-ccip/deployment/tokens" "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/adapters" ccipChangesets "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/changesets" - "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain" devenvcommon "github.com/smartcontractkit/chainlink-ccv/build/devenv/common" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/protocol" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-deployments-framework/deployment" @@ -260,7 +260,7 @@ type TokenConfigProvider interface { env *deployment.Environment, selector uint64, remoteSelectors []uint64, - topology *offchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, ) ([]tokensapi.TokenTransferConfig, error) } @@ -277,15 +277,15 @@ type OnChainConfigurable interface { // DeployChainContracts call (e.g. deploying CREATE2 factory on EVM). // The returned DataStore is merged into env.DataStore before // GetDeployChainContractsCfg is called. - PreDeployContractsForSelector(ctx context.Context, env *deployment.Environment, selector uint64, topology *offchain.EnvironmentTopology) (datastore.DataStore, error) + PreDeployContractsForSelector(ctx context.Context, env *deployment.Environment, selector uint64, topology *ccvdeployment.EnvironmentTopology) (datastore.DataStore, error) // GetDeployChainContractsCfg returns the per-chain configuration for the // common DeployChainContracts changeset. Called after Pre, so env.DataStore // includes pre-deployed addresses (e.g. CREATE2 factory). - GetDeployChainContractsCfg(env *deployment.Environment, selector uint64, topology *offchain.EnvironmentTopology) (ccipChangesets.DeployChainContractsPerChainCfg, error) + GetDeployChainContractsCfg(env *deployment.Environment, selector uint64, topology *ccvdeployment.EnvironmentTopology) (ccipChangesets.DeployChainContractsPerChainCfg, error) // PostDeployContractsForSelector runs chain-specific setup after the common // DeployChainContracts call (e.g. deploying USDC/Lombard token pools on EVM). // The returned DataStore is merged into the final result. - PostDeployContractsForSelector(ctx context.Context, env *deployment.Environment, selector uint64, topology *offchain.EnvironmentTopology) (datastore.DataStore, error) + PostDeployContractsForSelector(ctx context.Context, env *deployment.Environment, selector uint64, topology *ccvdeployment.EnvironmentTopology) (datastore.DataStore, error) // GetConnectionProfile returns a ChainDefinition describing this chain as a // lane destination, plus the default committee verifier config to apply for // each remote chain. The environment uses profiles from all chains to diff --git a/build/devenv/common/common.go b/build/devenv/common/common.go index b38df125f..9dec7bf0f 100644 --- a/build/devenv/common/common.go +++ b/build/devenv/common/common.go @@ -8,8 +8,7 @@ import ( "github.com/smartcontractkit/chainlink-deployments-framework/datastore" - "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain" - + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/protocol" ) @@ -237,7 +236,7 @@ func All17TokenCombinations() []TokenCombination { // - LockRelease pairs with BurnMint (in both directions) func ComputeTokenCombinations( capabilities map[uint64][]PoolCapability, - topology *offchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, ) []TokenCombination { // Collect the set of distinct pool capabilities across all chains. type capKey struct { @@ -357,7 +356,7 @@ func newTokenCombination(localType, localVersion string, localCCVs []string, rem // ccvQualifierPermutations returns the set of CCV qualifier slices to exercise, // derived from the topology's available committees. It always includes the // empty-qualifier case (no explicit CCVs) for pools that support it. -func ccvQualifierPermutations(topology *offchain.EnvironmentTopology) [][]string { +func ccvQualifierPermutations(topology *ccvdeployment.EnvironmentTopology) [][]string { result := [][]string{ {}, // no explicit CCVs } @@ -384,7 +383,7 @@ func ccvQualifierPermutations(topology *offchain.EnvironmentTopology) [][]string } // qualifiersAvailable returns true if all qualifiers exist as committees in the topology. -func qualifiersAvailable(qualifiers []string, topology *offchain.EnvironmentTopology) bool { +func qualifiersAvailable(qualifiers []string, topology *ccvdeployment.EnvironmentTopology) bool { if topology == nil || topology.NOPTopology == nil { return len(qualifiers) == 0 } @@ -401,7 +400,7 @@ func qualifiersAvailable(qualifiers []string, topology *offchain.EnvironmentTopo // as the local chain and selectors[1:] as candidate remotes, and the filter keeps only // combinations whose declared local->remote orientation exists in the datastore. // Pass ds nil to skip the datastore check. -func FilterTokenCombinations(combos []TokenCombination, topology *offchain.EnvironmentTopology, ds datastore.DataStore, selectors []uint64) []TokenCombination { +func FilterTokenCombinations(combos []TokenCombination, topology *ccvdeployment.EnvironmentTopology, ds datastore.DataStore, selectors []uint64) []TokenCombination { filtered := make([]TokenCombination, 0, len(combos)) for _, combo := range combos { if !qualifiersAvailable(combo.LocalPoolCCVQualifiers(), topology) || diff --git a/build/devenv/environment.go b/build/devenv/environment.go index 932a36e09..0b1f5538b 100644 --- a/build/devenv/environment.go +++ b/build/devenv/environment.go @@ -26,7 +26,6 @@ import ( "github.com/smartcontractkit/chainlink-ccv/build/devenv/cciptestinterfaces" devenvcommon "github.com/smartcontractkit/chainlink-ccv/build/devenv/common" "github.com/smartcontractkit/chainlink-ccv/build/devenv/jobs" - "github.com/smartcontractkit/chainlink-ccv/build/devenv/offchainloader" "github.com/smartcontractkit/chainlink-ccv/build/devenv/services" "github.com/smartcontractkit/chainlink-ccv/build/devenv/services/chainconfig" "github.com/smartcontractkit/chainlink-ccv/build/devenv/services/committeeverifier" @@ -1109,7 +1108,7 @@ func NewEnvironment() (in *Cfg, err error) { capsBySelector[networkInfo.ChainSelector] = nil } } - combos := devenvcommon.ComputeTokenCombinations(capsBySelector, convertTopologyToCCIP(topology)) + combos := devenvcommon.ComputeTokenCombinations(capsBySelector, topology) ds := datastore.NewMemoryDataStore() for i, impl := range impls { @@ -1256,7 +1255,7 @@ func NewEnvironment() (in *Cfg, err error) { } // Get generated config from output datastore - aggCfg, err := offchainloader.GetAggregatorConfig(output.DataStore.Seal(), instanceName+"-aggregator") + aggCfg, err := ccvdeployment.GetAggregatorConfig(output.DataStore.Seal(), instanceName+"-aggregator") if err != nil { return nil, fmt.Errorf("failed to get aggregator config from output: %w", err) } @@ -1297,7 +1296,7 @@ func NewEnvironment() (in *Cfg, err error) { return nil, fmt.Errorf("failed to generate indexer config: %w", err) } - idxCfg, err := offchainloader.GetIndexerConfig(output.DataStore.Seal(), "indexer") + idxCfg, err := ccvdeployment.GetIndexerConfig(output.DataStore.Seal(), "indexer") if err != nil { return nil, fmt.Errorf("failed to get indexer config from output: %w", err) } @@ -1537,7 +1536,7 @@ func NewEnvironment() (in *Cfg, err error) { } // Get generated config from output datastore - tokenVerifierCfg, err := offchainloader.GetTokenVerifierConfig( + tokenVerifierCfg, err := ccvdeployment.GetTokenVerifierConfig( output.DataStore.Seal(), "TokenVerifier", ) if err != nil { diff --git a/build/devenv/evm/impl.go b/build/devenv/evm/impl.go index 49634a389..d57b48db0 100644 --- a/build/devenv/evm/impl.go +++ b/build/devenv/evm/impl.go @@ -56,7 +56,7 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/operations/rmn_remote" "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/adapters" ccipChangesets "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/changesets" - ccipOffchain "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/offchain" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/build/devenv/cciptestinterfaces" devenvcommon "github.com/smartcontractkit/chainlink-ccv/build/devenv/common" "github.com/smartcontractkit/chainlink-ccv/protocol" @@ -1001,7 +1001,7 @@ func (m *CCIP17EVMConfig) ConfigureNodes(ctx context.Context, bc *blockchain.Inp // For each committee qualifier in the topology, a receiver requiring that committee's // verifier is created. Multi-committee receivers (requiring one committee with optional // verifiers from others) are only created when all referenced committees exist. -func buildMockReceivers(topology *ccipOffchain.EnvironmentTopology, selector uint64) []adapters.MockReceiverDeployParams { +func buildMockReceivers(topology *ccvdeployment.EnvironmentTopology, selector uint64) []adapters.MockReceiverDeployParams { has := func(q string) bool { _, ok := topology.NOPTopology.Committees[q] return ok @@ -1065,7 +1065,7 @@ func buildMockReceivers(topology *ccipOffchain.EnvironmentTopology, selector uin return receivers } -func (m *CCIP17EVMConfig) PreDeployContractsForSelector(_ context.Context, env *deployment.Environment, selector uint64, _ *ccipOffchain.EnvironmentTopology) (datastore.DataStore, error) { +func (m *CCIP17EVMConfig) PreDeployContractsForSelector(_ context.Context, env *deployment.Environment, selector uint64, _ *ccvdeployment.EnvironmentTopology) (datastore.DataStore, error) { m.logger.Info().Uint64("Selector", selector).Msg("EVM pre-deploy: deploying CREATE2 factory") create2FactoryRep, err := operations.ExecuteOperation(env.OperationsBundle, create2_factory.Deploy, env.BlockChains.EVMChains()[selector], @@ -1087,7 +1087,7 @@ func (m *CCIP17EVMConfig) PreDeployContractsForSelector(_ context.Context, env * return ds.Seal(), nil } -func (m *CCIP17EVMConfig) GetDeployChainContractsCfg(env *deployment.Environment, selector uint64, topology *ccipOffchain.EnvironmentTopology) (ccipChangesets.DeployChainContractsPerChainCfg, error) { +func (m *CCIP17EVMConfig) GetDeployChainContractsCfg(env *deployment.Environment, selector uint64, topology *ccvdeployment.EnvironmentTopology) (ccipChangesets.DeployChainContractsPerChainCfg, error) { create2Ref, err := env.DataStore.Addresses().Get( datastore.NewAddressRefKey(selector, datastore.ContractType(create2_factory.ContractType), create2_factory.Version, ""), ) @@ -1154,7 +1154,7 @@ func (m *CCIP17EVMConfig) GetDeployChainContractsCfg(env *deployment.Environment }, nil } -func (m *CCIP17EVMConfig) PostDeployContractsForSelector(_ context.Context, env *deployment.Environment, selector uint64, _ *ccipOffchain.EnvironmentTopology) (datastore.DataStore, error) { +func (m *CCIP17EVMConfig) PostDeployContractsForSelector(_ context.Context, env *deployment.Environment, selector uint64, _ *ccvdeployment.EnvironmentTopology) (datastore.DataStore, error) { m.logger.Info().Uint64("Selector", selector).Msg("EVM post-deploy: deploying USDC and Lombard token pools") create2Ref, err := env.DataStore.Addresses().Get( @@ -1305,7 +1305,7 @@ func (m *CCIP17EVMConfig) GetTokenTransferConfigs( env *deployment.Environment, selector uint64, remoteSelectors []uint64, - topology *ccipOffchain.EnvironmentTopology, + topology *ccvdeployment.EnvironmentTopology, ) ([]tokenscore.TokenTransferConfig, error) { applicableCombos := devenvcommon.FilterTokenCombinations( devenvcommon.AllTokenCombinations(), topology, env.DataStore, append([]uint64{selector}, remoteSelectors...), diff --git a/build/devenv/implcommon.go b/build/devenv/implcommon.go index 39052be85..62632f419 100644 --- a/build/devenv/implcommon.go +++ b/build/devenv/implcommon.go @@ -60,10 +60,8 @@ func DeployContractsForSelector( operations.NewMemoryReporter(), ) - ccipTopology := convertTopologyToCCIP(topology) - // 1. Pre-hook (e.g. EVM deploys CREATE2 factory here). - preDS, err := impl.PreDeployContractsForSelector(ctx, env, selector, ccipTopology) + preDS, err := impl.PreDeployContractsForSelector(ctx, env, selector, topology) if err != nil { return nil, fmt.Errorf("pre-deploy for selector %d: %w", selector, err) } @@ -79,12 +77,13 @@ func DeployContractsForSelector( } // 2. Get chain-specific config (reads pre-deployed addresses from env.DataStore). - cfg, err := impl.GetDeployChainContractsCfg(env, selector, ccipTopology) + cfg, err := impl.GetDeployChainContractsCfg(env, selector, topology) if err != nil { return nil, fmt.Errorf("get deploy config for selector %d: %w", selector, err) } // 3. Call the tooling API changeset. + ccipTopology := convertTopologyToCCIP(topology) registry := ccipAdapters.GetDeployChainContractsRegistry() out, err := ccipChangesets.DeployChainContracts(registry).Apply(*env, changesetscore.WithMCMS[ccipChangesets.DeployChainContractsCfg]{ Cfg: ccipChangesets.DeployChainContractsCfg{ @@ -107,7 +106,7 @@ func DeployContractsForSelector( env.DataStore = merged // 4. Post-hook (e.g. EVM deploys USDC/Lombard pools here). - postDS, err := impl.PostDeployContractsForSelector(ctx, env, selector, ccipTopology) + postDS, err := impl.PostDeployContractsForSelector(ctx, env, selector, topology) if err != nil { return nil, fmt.Errorf("post-deploy for selector %d: %w", selector, err) } @@ -556,7 +555,7 @@ func ConfigureAllTokenTransfers( } } - cfgs, err := tcp.GetTokenTransferConfigs(env, selectors[i], remoteSelectors, convertTopologyToCCIP(topology)) + cfgs, err := tcp.GetTokenTransferConfigs(env, selectors[i], remoteSelectors, topology) if err != nil { return fmt.Errorf("get token transfer configs for selector %d: %w", selectors[i], err) } diff --git a/build/devenv/offchainloader/loader.go b/build/devenv/offchainloader/loader.go deleted file mode 100644 index e97e79a84..000000000 --- a/build/devenv/offchainloader/loader.go +++ /dev/null @@ -1,174 +0,0 @@ -package offchainloader - -import ( - "github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/model" - ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" - "github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config" - "github.com/smartcontractkit/chainlink-ccv/pkg/chainaccess" - "github.com/smartcontractkit/chainlink-ccv/protocol" - verifier "github.com/smartcontractkit/chainlink-ccv/verifier/pkg" - "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token" - "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token/cctp" - "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token/lombard" - "github.com/smartcontractkit/chainlink-deployments-framework/datastore" -) - -func GetAggregatorConfig(ds datastore.DataStore, id string) (*model.Committee, error) { - ccvCfg, err := ccvdeployment.GetAggregatorConfig(ds, id) - if err != nil { - return nil, err - } - return convertCommittee(ccvCfg), nil -} - -func GetIndexerConfig(ds datastore.DataStore, id string) (*config.GeneratedConfig, error) { - ccvCfg, err := ccvdeployment.GetIndexerConfig(ds, id) - if err != nil { - return nil, err - } - return convertIndexerConfig(ccvCfg), nil -} - -func GetTokenVerifierConfig(ds datastore.DataStore, id string) (*token.Config, error) { - ccvCfg, err := ccvdeployment.GetTokenVerifierConfig(ds, id) - if err != nil { - return nil, err - } - return convertTokenVerifierConfig(ccvCfg), nil -} - -func convertCommittee(src *ccvdeployment.Committee) *model.Committee { - if src == nil { - return nil - } - dst := &model.Committee{ - DestinationVerifiers: src.DestinationVerifiers, - } - if src.QuorumConfigs != nil { - dst.QuorumConfigs = make(map[model.SourceSelector]*model.QuorumConfig, len(src.QuorumConfigs)) - for k, qc := range src.QuorumConfigs { - dst.QuorumConfigs[k] = convertQuorumConfig(qc) - } - } - return dst -} - -func convertQuorumConfig(src *ccvdeployment.QuorumConfig) *model.QuorumConfig { - if src == nil { - return nil - } - signers := make([]model.Signer, len(src.Signers)) - for i, s := range src.Signers { - signers[i] = model.Signer{Address: s.Address} - } - return &model.QuorumConfig{ - SourceVerifierAddress: src.SourceVerifierAddress, - Signers: signers, - Threshold: src.Threshold, - } -} - -func convertIndexerConfig(src *ccvdeployment.IndexerGeneratedConfig) *config.GeneratedConfig { - if src == nil { - return nil - } - verifiers := make([]config.GeneratedVerifierConfig, len(src.Verifiers)) - for i, v := range src.Verifiers { - verifiers[i] = config.GeneratedVerifierConfig{ - Name: v.Name, - IssuerAddresses: v.IssuerAddresses, - } - } - return &config.GeneratedConfig{Verifier: verifiers} -} - -func convertTokenVerifierConfig(src *ccvdeployment.TokenVerifierGeneratedConfig) *token.Config { - if src == nil { - return nil - } - dst := &token.Config{ - PyroscopeURL: src.PyroscopeURL, - CommitteeConfig: chainaccess.CommitteeConfig{ - OnRampAddresses: src.OnRampAddresses, - RMNRemoteAddresses: src.RMNRemoteAddresses, - }, - Monitoring: verifier.MonitoringConfig{ - Enabled: src.Monitoring.Enabled, - Type: src.Monitoring.Type, - Beholder: verifier.BeholderConfig{ - InsecureConnection: src.Monitoring.Beholder.InsecureConnection, - CACertFile: src.Monitoring.Beholder.CACertFile, - OtelExporterGRPCEndpoint: src.Monitoring.Beholder.OtelExporterGRPCEndpoint, - OtelExporterHTTPEndpoint: src.Monitoring.Beholder.OtelExporterHTTPEndpoint, - LogStreamingEnabled: src.Monitoring.Beholder.LogStreamingEnabled, - MetricReaderInterval: src.Monitoring.Beholder.MetricReaderInterval, - TraceSampleRatio: src.Monitoring.Beholder.TraceSampleRatio, - TraceBatchTimeout: src.Monitoring.Beholder.TraceBatchTimeout, - }, - }, - } - dst.TokenVerifiers = make([]token.VerifierConfig, len(src.TokenVerifiers)) - for i, tv := range src.TokenVerifiers { - vc := token.VerifierConfig{ - VerifierID: tv.VerifierID, - Type: tv.Type, - Version: tv.Version, - } - if tv.CCTP != nil { - vc.CCTPConfig = convertCCTPConfig(tv.CCTP) - } - if tv.Lombard != nil { - vc.LombardConfig = convertLombardConfig(tv.Lombard) - } - dst.TokenVerifiers[i] = vc - } - return dst -} - -func convertCCTPConfig(src *ccvdeployment.CCTPVerifierConfig) *cctp.CCTPConfig { - if src == nil { - return nil - } - dst := &cctp.CCTPConfig{ - AttestationAPI: src.AttestationAPI, - AttestationAPITimeout: src.AttestationAPITimeout, - AttestationAPIInterval: src.AttestationAPIInterval, - AttestationAPICooldown: src.AttestationAPICooldown, - VerifierVersion: protocol.ByteSlice(src.VerifierVersion), - } - if src.Verifiers != nil { - dst.Verifiers = toAnyMap(src.Verifiers) - } - if src.VerifierResolvers != nil { - dst.VerifierResolvers = toAnyMap(src.VerifierResolvers) - } - return dst -} - -func convertLombardConfig(src *ccvdeployment.LombardVerifierConfig) *lombard.LombardConfig { - if src == nil { - return nil - } - dst := &lombard.LombardConfig{ - AttestationAPI: src.AttestationAPI, - AttestationAPITimeout: src.AttestationAPITimeout, - AttestationAPIInterval: src.AttestationAPIInterval, - AttestationAPIBatchSize: src.AttestationAPIBatchSize, - VerifierVersion: protocol.ByteSlice(src.VerifierVersion), - } - if src.VerifierResolvers != nil { - dst.VerifierResolvers = toAnyMap(src.VerifierResolvers) - } - return dst -} - -func toAnyMap(src map[string]string) map[string]any { - if src == nil { - return nil - } - dst := make(map[string]any, len(src)) - for k, v := range src { - dst[k] = v - } - return dst -} diff --git a/deployment/aggregator.go b/deployment/aggregator.go deleted file mode 100644 index d6701d92f..000000000 --- a/deployment/aggregator.go +++ /dev/null @@ -1,20 +0,0 @@ -package deployment - -type SourceSelector = string - -type DestinationSelector = string - -type Signer struct { - Address string `json:"address"` -} - -type QuorumConfig struct { - SourceVerifierAddress string `json:"sourceVerifierAddress"` - Signers []Signer `json:"signers"` - Threshold uint8 `json:"threshold"` -} - -type Committee struct { - QuorumConfigs map[SourceSelector]*QuorumConfig `json:"quorumConfigs"` - DestinationVerifiers map[DestinationSelector]string `json:"destinationVerifiers"` -} diff --git a/deployment/changesets/apply_executor_config.go b/deployment/changesets/apply_executor_config.go index fff126381..d364f8bab 100644 --- a/deployment/changesets/apply_executor_config.go +++ b/deployment/changesets/apply_executor_config.go @@ -349,7 +349,7 @@ func buildExecutorJobSpecs( ReaderCacheExpiry: pool.ReaderCacheExpiry, MaxRetryDuration: pool.MaxRetryDuration, WorkerCount: pool.WorkerCount, - Monitoring: toExecutorMonitoring(monitoring), + Monitoring: monitoring, ChainConfiguration: chainCfgs, } @@ -376,23 +376,6 @@ executorConfig = ''' return jobSpecs, scope, nil } -func toExecutorMonitoring(m ccvdeployment.MonitoringConfig) executor.MonitoringConfig { - return executor.MonitoringConfig{ - Enabled: m.Enabled, - Type: m.Type, - Beholder: executor.BeholderConfig{ - InsecureConnection: m.Beholder.InsecureConnection, - CACertFile: m.Beholder.CACertFile, - OtelExporterGRPCEndpoint: m.Beholder.OtelExporterGRPCEndpoint, - OtelExporterHTTPEndpoint: m.Beholder.OtelExporterHTTPEndpoint, - LogStreamingEnabled: m.Beholder.LogStreamingEnabled, - MetricReaderInterval: m.Beholder.MetricReaderInterval, - TraceSampleRatio: m.Beholder.TraceSampleRatio, - TraceBatchTimeout: m.Beholder.TraceBatchTimeout, - }, - } -} - func buildNOPModes(nops []ccvdeployment.NOPConfig) map[shared.NOPAlias]shared.NOPMode { nopModes := make(map[shared.NOPAlias]shared.NOPMode) for _, nop := range nops { diff --git a/deployment/changesets/apply_verifier_config.go b/deployment/changesets/apply_verifier_config.go index d7886e060..c846496fa 100644 --- a/deployment/changesets/apply_verifier_config.go +++ b/deployment/changesets/apply_verifier_config.go @@ -13,7 +13,6 @@ import ( "github.com/smartcontractkit/chainlink-ccv/pkg/chainaccess" "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/commit" - vtypes "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/vtypes" ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" @@ -338,7 +337,7 @@ func buildVerifierJobSpecs( CommitteeVerifierAddresses: filterAddressesByChains(committeeVerifierAddrs, nopChains), DefaultExecutorOnRampAddresses: filterAddressesByChains(executorOnRampAddrs, nopChains), DisableFinalityCheckers: sortedFinalityCheckers, - Monitoring: toVerifierMonitoring(monitoring), + Monitoring: monitoring, CommitteeConfig: chainaccess.CommitteeConfig{ OnRampAddresses: filterAddressesByChains(onRampAddrs, nopChains), RMNRemoteAddresses: filterAddressesByChains(rmnRemoteAddrs, nopChains), @@ -369,23 +368,6 @@ committeeVerifierConfig = ''' return jobSpecs, scope, nil } -func toVerifierMonitoring(m ccvdeployment.MonitoringConfig) vtypes.MonitoringConfig { - return vtypes.MonitoringConfig{ - Enabled: m.Enabled, - Type: m.Type, - Beholder: vtypes.BeholderConfig{ - InsecureConnection: m.Beholder.InsecureConnection, - CACertFile: m.Beholder.CACertFile, - OtelExporterGRPCEndpoint: m.Beholder.OtelExporterGRPCEndpoint, - OtelExporterHTTPEndpoint: m.Beholder.OtelExporterHTTPEndpoint, - LogStreamingEnabled: m.Beholder.LogStreamingEnabled, - MetricReaderInterval: m.Beholder.MetricReaderInterval, - TraceSampleRatio: m.Beholder.TraceSampleRatio, - TraceBatchTimeout: m.Beholder.TraceBatchTimeout, - }, - } -} - // fetchSigningKeysForNOPs fetches signing keys from JD for NOPs that are missing a signer // address for the given signerFamily. func fetchSigningKeysForNOPs( diff --git a/deployment/changesets/generate_aggregator_config.go b/deployment/changesets/generate_aggregator_config.go index d26432e24..d3f7c02c7 100644 --- a/deployment/changesets/generate_aggregator_config.go +++ b/deployment/changesets/generate_aggregator_config.go @@ -9,6 +9,7 @@ import ( "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/model" ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" ) @@ -94,7 +95,7 @@ func buildAggregatorCommittee( registry *adapters.Registry, committeeQualifier string, chainSelectors []uint64, -) (*ccvdeployment.Committee, error) { +) (*model.Committee, error) { ctx := context.Background() type chainQualifier struct { @@ -144,7 +145,7 @@ func buildAggregatorCommittee( return nil, fmt.Errorf("failed to build destination verifiers: %w", err) } - return &ccvdeployment.Committee{ + return &model.Committee{ QuorumConfigs: quorumConfigs, DestinationVerifiers: destVerifiers, }, nil @@ -156,13 +157,13 @@ func buildQuorumConfigs( committeeStates []*adapters.CommitteeState, committeeQualifier string, chainSelectors []uint64, -) (map[string]*ccvdeployment.QuorumConfig, error) { +) (map[string]*model.QuorumConfig, error) { supportedChains := make(map[uint64]bool, len(chainSelectors)) for _, sel := range chainSelectors { supportedChains[sel] = true } - quorumConfigs := make(map[string]*ccvdeployment.QuorumConfig) + quorumConfigs := make(map[string]*model.QuorumConfig) for _, state := range committeeStates { for _, sigConfig := range state.SignatureConfigs { @@ -191,12 +192,12 @@ func buildQuorumConfigs( return nil, fmt.Errorf("failed to resolve source verifier for chain %d: %w", sigConfig.SourceChainSelector, err) } - signers := make([]ccvdeployment.Signer, 0, len(sigConfig.Signers)) + signers := make([]model.Signer, 0, len(sigConfig.Signers)) for _, addr := range sigConfig.Signers { - signers = append(signers, ccvdeployment.Signer{Address: addr}) + signers = append(signers, model.Signer{Address: addr}) } - quorumConfigs[chainSelectorStr] = &ccvdeployment.QuorumConfig{ + quorumConfigs[chainSelectorStr] = &model.QuorumConfig{ SourceVerifierAddress: sourceVerifierAddr, Signers: signers, Threshold: sigConfig.Threshold, @@ -208,7 +209,7 @@ func buildQuorumConfigs( } func validateSignatureConfigConsistency( - existing *ccvdeployment.QuorumConfig, + existing *model.QuorumConfig, newSig adapters.SignatureConfig, chainSelectorStr string, committeeQualifier string, diff --git a/deployment/changesets/generate_indexer_config.go b/deployment/changesets/generate_indexer_config.go index 4a272bcfd..0907c0b93 100644 --- a/deployment/changesets/generate_indexer_config.go +++ b/deployment/changesets/generate_indexer_config.go @@ -10,6 +10,7 @@ import ( ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" + indexerconfig "github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config" ) type GenerateIndexerConfigInput struct { @@ -136,8 +137,8 @@ func collectVerifierAddresses( return addresses, nil } -func toIndexerGeneratedConfig(verifierMap map[string][]string) *ccvdeployment.IndexerGeneratedConfig { - verifiers := make([]ccvdeployment.IndexerVerifierConfig, 0, len(verifierMap)) +func toIndexerGeneratedConfig(verifierMap map[string][]string) *indexerconfig.GeneratedConfig { + verifiers := make([]indexerconfig.GeneratedVerifierConfig, 0, len(verifierMap)) names := make([]string, 0, len(verifierMap)) for name := range verifierMap { @@ -155,13 +156,13 @@ func toIndexerGeneratedConfig(verifierMap map[string][]string) *ccvdeployment.In unique = append(unique, addr) } } - verifiers = append(verifiers, ccvdeployment.IndexerVerifierConfig{ + verifiers = append(verifiers, indexerconfig.GeneratedVerifierConfig{ Name: name, IssuerAddresses: unique, }) } - return &ccvdeployment.IndexerGeneratedConfig{ - Verifiers: verifiers, + return &indexerconfig.GeneratedConfig{ + Verifier: verifiers, } } diff --git a/deployment/changesets/generate_token_verifier_config.go b/deployment/changesets/generate_token_verifier_config.go index 971faa883..3b42a4856 100644 --- a/deployment/changesets/generate_token_verifier_config.go +++ b/deployment/changesets/generate_token_verifier_config.go @@ -10,6 +10,12 @@ import ( "github.com/smartcontractkit/chainlink-deployments-framework/datastore" "github.com/smartcontractkit/chainlink-deployments-framework/deployment" + "github.com/smartcontractkit/chainlink-ccv/pkg/chainaccess" + "github.com/smartcontractkit/chainlink-ccv/protocol" + "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token" + "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token/cctp" + "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token/lombard" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/deployment/adapters" "github.com/smartcontractkit/chainlink-ccv/deployment/shared" @@ -125,25 +131,14 @@ func GenerateTokenVerifierConfig(registry *adapters.Registry) deployment.ChangeS } } - config := &ccvdeployment.TokenVerifierGeneratedConfig{ - PyroscopeURL: cfg.PyroscopeURL, - OnRampAddresses: onRampAddresses, - RMNRemoteAddresses: rmnRemoteAddresses, - TokenVerifiers: []ccvdeployment.TokenVerifierEntry{}, - Monitoring: ccvdeployment.TokenVerifierMonitoringConfig{ - Enabled: cfg.Monitoring.Enabled, - Type: cfg.Monitoring.Type, - Beholder: ccvdeployment.TokenVerifierBeholderConfig{ - InsecureConnection: cfg.Monitoring.Beholder.InsecureConnection, - CACertFile: cfg.Monitoring.Beholder.CACertFile, - OtelExporterGRPCEndpoint: cfg.Monitoring.Beholder.OtelExporterGRPCEndpoint, - OtelExporterHTTPEndpoint: cfg.Monitoring.Beholder.OtelExporterHTTPEndpoint, - LogStreamingEnabled: cfg.Monitoring.Beholder.LogStreamingEnabled, - MetricReaderInterval: cfg.Monitoring.Beholder.MetricReaderInterval, - TraceSampleRatio: cfg.Monitoring.Beholder.TraceSampleRatio, - TraceBatchTimeout: cfg.Monitoring.Beholder.TraceBatchTimeout, - }, + tvConfig := &token.Config{ + PyroscopeURL: cfg.PyroscopeURL, + CommitteeConfig: chainaccess.CommitteeConfig{ + OnRampAddresses: onRampAddresses, + RMNRemoteAddresses: rmnRemoteAddresses, }, + TokenVerifiers: []token.VerifierConfig{}, + Monitoring: cfg.Monitoring, } if len(cctpVerifierAddresses) > 0 { @@ -151,18 +146,18 @@ func GenerateTokenVerifierConfig(registry *adapters.Registry) deployment.ChangeS if cctpVerifierID == "" { cctpVerifierID = fmt.Sprintf("cctp-%s", cctpCfg.Qualifier) } - config.TokenVerifiers = append(config.TokenVerifiers, ccvdeployment.TokenVerifierEntry{ + tvConfig.TokenVerifiers = append(tvConfig.TokenVerifiers, token.VerifierConfig{ VerifierID: cctpVerifierID, Type: "cctp", Version: "2.0", - CCTP: &ccvdeployment.CCTPVerifierConfig{ + CCTPConfig: &cctp.CCTPConfig{ AttestationAPI: cctpCfg.AttestationAPI, AttestationAPITimeout: cctpCfg.AttestationAPITimeout, AttestationAPIInterval: cctpCfg.AttestationAPIInterval, AttestationAPICooldown: cctpCfg.AttestationAPICooldown, - VerifierVersion: cctpCfg.VerifierVersion, - Verifiers: cctpVerifierAddresses, - VerifierResolvers: cctpVerifierResolverAddresses, + VerifierVersion: protocol.ByteSlice(cctpCfg.VerifierVersion), + Verifiers: stringsToAnyMap(cctpVerifierAddresses), + VerifierResolvers: stringsToAnyMap(cctpVerifierResolverAddresses), }, }) } @@ -172,17 +167,17 @@ func GenerateTokenVerifierConfig(registry *adapters.Registry) deployment.ChangeS if lombardVerifierID == "" { lombardVerifierID = fmt.Sprintf("lombard-%s", lombardCfg.Qualifier) } - config.TokenVerifiers = append(config.TokenVerifiers, ccvdeployment.TokenVerifierEntry{ + tvConfig.TokenVerifiers = append(tvConfig.TokenVerifiers, token.VerifierConfig{ VerifierID: lombardVerifierID, Type: "lombard", Version: "1.0", - Lombard: &ccvdeployment.LombardVerifierConfig{ + LombardConfig: &lombard.LombardConfig{ AttestationAPI: lombardCfg.AttestationAPI, AttestationAPITimeout: lombardCfg.AttestationAPITimeout, AttestationAPIInterval: lombardCfg.AttestationAPIInterval, AttestationAPIBatchSize: lombardCfg.AttestationAPIBatchSize, - VerifierVersion: lombardCfg.VerifierVersion, - VerifierResolvers: lombardVerifierResolverAddresses, + VerifierVersion: protocol.ByteSlice(lombardCfg.VerifierVersion), + VerifierResolvers: stringsToAnyMap(lombardVerifierResolverAddresses), }, }) } @@ -194,7 +189,7 @@ func GenerateTokenVerifierConfig(registry *adapters.Registry) deployment.ChangeS } } - if err := ccvdeployment.SaveTokenVerifierConfig(outputDS, cfg.ServiceIdentifier, config); err != nil { + if err := ccvdeployment.SaveTokenVerifierConfig(outputDS, cfg.ServiceIdentifier, tvConfig); err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("failed to save token verifier config: %w", err) } @@ -206,6 +201,17 @@ func GenerateTokenVerifierConfig(registry *adapters.Registry) deployment.ChangeS return deployment.CreateChangeSet(apply, validate) } +func stringsToAnyMap(src map[string]string) map[string]any { + if src == nil { + return nil + } + dst := make(map[string]any, len(src)) + for k, v := range src { + dst[k] = v + } + return dst +} + func applyLombardDefaults(cfg LombardConfigInput, isProd bool) LombardConfigInput { if cfg.AttestationAPI == "" { if isProd { diff --git a/deployment/env_metadata_util.go b/deployment/env_metadata_util.go index 0fb425161..2c6601406 100644 --- a/deployment/env_metadata_util.go +++ b/deployment/env_metadata_util.go @@ -7,13 +7,16 @@ import ( "github.com/smartcontractkit/chainlink-deployments-framework/datastore" + "github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/model" + indexerconfig "github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config" "github.com/smartcontractkit/chainlink-ccv/deployment/shared" + "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token" ) type OffchainConfigs struct { - Aggregators map[string]*Committee `json:"aggregators,omitempty"` - Indexers map[string]*IndexerGeneratedConfig `json:"indexers,omitempty"` - TokenVerifiers map[string]*TokenVerifierGeneratedConfig `json:"tokenVerifiers,omitempty"` + Aggregators map[string]*model.Committee `json:"aggregators,omitempty"` + Indexers map[string]*indexerconfig.GeneratedConfig `json:"indexers,omitempty"` + TokenVerifiers map[string]*token.Config `json:"tokenVerifiers,omitempty"` NOPJobs shared.NOPJobs `json:"nopJobs,omitempty"` } @@ -21,7 +24,7 @@ type CCVEnvMetadata struct { OffchainConfigs *OffchainConfigs `json:"offchainConfigs,omitempty"` } -func SaveAggregatorConfig(ds datastore.MutableDataStore, serviceIdentifier string, cfg *Committee) error { +func SaveAggregatorConfig(ds datastore.MutableDataStore, serviceIdentifier string, cfg *model.Committee) error { ccvMeta, err := loadOrCreateCCVEnvMetadata(ds) if err != nil { return err @@ -31,7 +34,7 @@ func SaveAggregatorConfig(ds datastore.MutableDataStore, serviceIdentifier strin ccvMeta.OffchainConfigs = &OffchainConfigs{} } if ccvMeta.OffchainConfigs.Aggregators == nil { - ccvMeta.OffchainConfigs.Aggregators = make(map[string]*Committee) + ccvMeta.OffchainConfigs.Aggregators = make(map[string]*model.Committee) } ccvMeta.OffchainConfigs.Aggregators[serviceIdentifier] = cfg @@ -39,7 +42,7 @@ func SaveAggregatorConfig(ds datastore.MutableDataStore, serviceIdentifier strin return persistCCVEnvMetadata(ds, ccvMeta) } -func GetAggregatorConfig(ds datastore.DataStore, serviceIdentifier string) (*Committee, error) { +func GetAggregatorConfig(ds datastore.DataStore, serviceIdentifier string) (*model.Committee, error) { ccvMeta, err := loadCCVEnvMetadata(ds) if err != nil { return nil, err @@ -57,7 +60,7 @@ func GetAggregatorConfig(ds datastore.DataStore, serviceIdentifier string) (*Com return cfg, nil } -func SaveIndexerConfig(ds datastore.MutableDataStore, serviceIdentifier string, cfg *IndexerGeneratedConfig) error { +func SaveIndexerConfig(ds datastore.MutableDataStore, serviceIdentifier string, cfg *indexerconfig.GeneratedConfig) error { ccvMeta, err := loadOrCreateCCVEnvMetadata(ds) if err != nil { return err @@ -67,7 +70,7 @@ func SaveIndexerConfig(ds datastore.MutableDataStore, serviceIdentifier string, ccvMeta.OffchainConfigs = &OffchainConfigs{} } if ccvMeta.OffchainConfigs.Indexers == nil { - ccvMeta.OffchainConfigs.Indexers = make(map[string]*IndexerGeneratedConfig) + ccvMeta.OffchainConfigs.Indexers = make(map[string]*indexerconfig.GeneratedConfig) } ccvMeta.OffchainConfigs.Indexers[serviceIdentifier] = cfg @@ -75,7 +78,7 @@ func SaveIndexerConfig(ds datastore.MutableDataStore, serviceIdentifier string, return persistCCVEnvMetadata(ds, ccvMeta) } -func GetIndexerConfig(ds datastore.DataStore, serviceIdentifier string) (*IndexerGeneratedConfig, error) { +func GetIndexerConfig(ds datastore.DataStore, serviceIdentifier string) (*indexerconfig.GeneratedConfig, error) { ccvMeta, err := loadCCVEnvMetadata(ds) if err != nil { return nil, err @@ -93,7 +96,7 @@ func GetIndexerConfig(ds datastore.DataStore, serviceIdentifier string) (*Indexe return cfg, nil } -func SaveTokenVerifierConfig(ds datastore.MutableDataStore, serviceIdentifier string, cfg *TokenVerifierGeneratedConfig) error { +func SaveTokenVerifierConfig(ds datastore.MutableDataStore, serviceIdentifier string, cfg *token.Config) error { ccvMeta, err := loadOrCreateCCVEnvMetadata(ds) if err != nil { return err @@ -103,7 +106,7 @@ func SaveTokenVerifierConfig(ds datastore.MutableDataStore, serviceIdentifier st ccvMeta.OffchainConfigs = &OffchainConfigs{} } if ccvMeta.OffchainConfigs.TokenVerifiers == nil { - ccvMeta.OffchainConfigs.TokenVerifiers = make(map[string]*TokenVerifierGeneratedConfig) + ccvMeta.OffchainConfigs.TokenVerifiers = make(map[string]*token.Config) } ccvMeta.OffchainConfigs.TokenVerifiers[serviceIdentifier] = cfg @@ -111,7 +114,7 @@ func SaveTokenVerifierConfig(ds datastore.MutableDataStore, serviceIdentifier st return persistCCVEnvMetadata(ds, ccvMeta) } -func GetTokenVerifierConfig(ds datastore.DataStore, serviceIdentifier string) (*TokenVerifierGeneratedConfig, error) { +func GetTokenVerifierConfig(ds datastore.DataStore, serviceIdentifier string) (*token.Config, error) { ccvMeta, err := loadCCVEnvMetadata(ds) if err != nil { return nil, err diff --git a/deployment/go.mod b/deployment/go.mod index f267503b0..8047bfabc 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -143,6 +143,7 @@ require ( github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20250912190424-fd2e35d7deb5 // indirect github.com/smartcontractkit/chainlink-common/keystore v1.0.2 // indirect github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect + github.com/smartcontractkit/chainlink-protos/chainlink-ccv/committee-verifier v0.0.0-20251211142334-5c3421fe2c8d // indirect github.com/smartcontractkit/chainlink-protos/chainlink-ccv/verifier v0.0.0-20251211142334-5c3421fe2c8d // indirect github.com/smartcontractkit/chainlink-protos/cre/go v0.0.0-20260326111235-8c09d1a4491f // indirect github.com/smartcontractkit/chainlink-protos/linking-service/go v0.0.0-20251002192024-d2ad9222409b // indirect diff --git a/deployment/indexer.go b/deployment/indexer.go deleted file mode 100644 index 462c442df..000000000 --- a/deployment/indexer.go +++ /dev/null @@ -1,10 +0,0 @@ -package deployment - -type IndexerVerifierConfig struct { - Name string `json:"name"` - IssuerAddresses []string `json:"issuerAddresses"` -} - -type IndexerGeneratedConfig struct { - Verifiers []IndexerVerifierConfig `json:"verifiers"` -} diff --git a/deployment/token_verifier.go b/deployment/token_verifier.go deleted file mode 100644 index 1eb6b201d..000000000 --- a/deployment/token_verifier.go +++ /dev/null @@ -1,55 +0,0 @@ -package deployment - -import "time" - -type TokenVerifierGeneratedConfig struct { - PyroscopeURL string `json:"pyroscope_url"` - OnRampAddresses map[string]string `json:"on_ramp_addresses"` - RMNRemoteAddresses map[string]string `json:"rmn_remote_addresses"` - TokenVerifiers []TokenVerifierEntry `json:"token_verifiers"` - Monitoring TokenVerifierMonitoringConfig `json:"monitoring"` -} - -type TokenVerifierEntry struct { - VerifierID string `json:"verifier_id"` - Type string `json:"type"` - Version string `json:"version"` - CCTP *CCTPVerifierConfig `json:"cctp,omitempty"` - Lombard *LombardVerifierConfig `json:"lombard,omitempty"` -} - -type CCTPVerifierConfig struct { - AttestationAPI string `json:"attestation_api"` - AttestationAPITimeout time.Duration `json:"attestation_api_timeout"` - AttestationAPIInterval time.Duration `json:"attestation_api_interval"` - AttestationAPICooldown time.Duration `json:"attestation_api_cooldown"` - VerifierVersion []byte `json:"verifier_version"` - Verifiers map[string]string `json:"verifiers"` - VerifierResolvers map[string]string `json:"verifier_resolvers"` -} - -type LombardVerifierConfig struct { - AttestationAPI string `json:"attestation_api"` - AttestationAPITimeout time.Duration `json:"attestation_api_timeout"` - AttestationAPIInterval time.Duration `json:"attestation_api_interval"` - AttestationAPIBatchSize int `json:"attestation_api_batch_size"` - VerifierVersion []byte `json:"verifier_version"` - VerifierResolvers map[string]string `json:"verifier_resolvers"` -} - -type TokenVerifierMonitoringConfig struct { - Enabled bool `json:"enabled"` - Type string `json:"type"` - Beholder TokenVerifierBeholderConfig `json:"beholder"` -} - -type TokenVerifierBeholderConfig struct { - InsecureConnection bool `json:"insecure_connection"` - CACertFile string `json:"ca_cert_file"` - OtelExporterGRPCEndpoint string `json:"otel_exporter_grpc_endpoint"` - OtelExporterHTTPEndpoint string `json:"otel_exporter_http_endpoint"` - LogStreamingEnabled bool `json:"log_streaming_enabled"` - MetricReaderInterval int64 `json:"metric_reader_interval"` - TraceSampleRatio float64 `json:"trace_sample_ratio"` - TraceBatchTimeout int64 `json:"trace_batch_timeout"` -} diff --git a/deployment/topology.go b/deployment/topology.go index a7db0134c..cfae5f9e9 100644 --- a/deployment/topology.go +++ b/deployment/topology.go @@ -12,6 +12,7 @@ import ( "github.com/Masterminds/semver/v3" "github.com/smartcontractkit/chainlink-ccv/deployment/shared" + "github.com/smartcontractkit/chainlink-ccv/pkg/monitoring" ) // EnvironmentTopology holds all environment-specific configuration that cannot be inferred @@ -135,22 +136,11 @@ type ChainExecutorPoolConfig struct { ExecutionInterval time.Duration `toml:"execution_interval"` } -type MonitoringConfig struct { - Enabled bool `toml:"Enabled"` - Type string `toml:"Type"` - Beholder BeholderConfig `toml:"Beholder"` -} - -type BeholderConfig struct { - InsecureConnection bool `toml:"InsecureConnection"` - CACertFile string `toml:"CACertFile"` - OtelExporterGRPCEndpoint string `toml:"OtelExporterGRPCEndpoint"` - OtelExporterHTTPEndpoint string `toml:"OtelExporterHTTPEndpoint"` - LogStreamingEnabled bool `toml:"LogStreamingEnabled"` - MetricReaderInterval int64 `toml:"MetricReaderInterval"` - TraceSampleRatio float64 `toml:"TraceSampleRatio"` - TraceBatchTimeout int64 `toml:"TraceBatchTimeout"` -} +// Type aliases — canonical definitions live in pkg/monitoring. +type ( + MonitoringConfig = monitoring.MonitoringConfig + BeholderConfig = monitoring.BeholderConfig +) func LoadEnvironmentTopology(path string) (*EnvironmentTopology, error) { data, err := os.ReadFile(path) //nolint:gosec // G304: path is provided by trusted caller diff --git a/executor/config.go b/executor/config.go index 0a8f95338..3dd6ee17c 100644 --- a/executor/config.go +++ b/executor/config.go @@ -6,6 +6,7 @@ import ( "time" "github.com/smartcontractkit/chainlink-ccv/pkg/chainaccess" + "github.com/smartcontractkit/chainlink-ccv/pkg/monitoring" ) const ( @@ -192,64 +193,8 @@ func (c *Configuration) GetNormalizedConfig() (*Configuration, error) { return &normalized, nil } -// MonitoringConfig provides monitoring configuration for executor. -type MonitoringConfig struct { - // Enabled enables the monitoring system. - Enabled bool `toml:"Enabled"` - // Type is the type of monitoring system to use (beholder, noop). - Type string `toml:"Type"` - // Beholder is the configuration for the beholder client (Not required if type is noop). - Beholder BeholderConfig `toml:"Beholder"` -} - -// BeholderConfig wraps OpenTelemetry configuration for the beholder client. -type BeholderConfig struct { - // InsecureConnection disables TLS for the beholder client. - InsecureConnection bool `toml:"InsecureConnection"` - // CACertFile is the path to the CA certificate file for the beholder client. - CACertFile string `toml:"CACertFile"` - // OtelExporterGRPCEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterGRPCEndpoint string `toml:"OtelExporterGRPCEndpoint"` - // OtelExporterHTTPEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterHTTPEndpoint string `toml:"OtelExporterHTTPEndpoint"` - // LogStreamingEnabled enables log streaming to the collector. - LogStreamingEnabled bool `toml:"LogStreamingEnabled"` - // MetricReaderInterval is the interval to scrape metrics (in seconds). - MetricReaderInterval int64 `toml:"MetricReaderInterval"` - // TraceSampleRatio is the ratio of traces to sample. - TraceSampleRatio float64 `toml:"TraceSampleRatio"` - // TraceBatchTimeout is the timeout for a batch of traces. - TraceBatchTimeout int64 `toml:"TraceBatchTimeout"` -} - -// Validate performs validation on the monitoring configuration. -func (m *MonitoringConfig) Validate() error { - if m.Enabled && m.Type == "" { - return fmt.Errorf("monitoring type is required when monitoring is enabled") - } - - if m.Enabled && m.Type == "beholder" { - if err := m.Beholder.Validate(); err != nil { - return fmt.Errorf("beholder config validation failed: %w", err) - } - } - - return nil -} - -// Validate performs validation on the beholder configuration. -func (b *BeholderConfig) Validate() error { - if b.MetricReaderInterval <= 0 { - return fmt.Errorf("metric_reader_interval must be positive, got %d", b.MetricReaderInterval) - } - - if b.TraceSampleRatio < 0 || b.TraceSampleRatio > 1 { - return fmt.Errorf("trace_sample_ratio must be between 0 and 1, got %f", b.TraceSampleRatio) - } - - if b.TraceBatchTimeout <= 0 { - return fmt.Errorf("trace_batch_timeout must be positive, got %d", b.TraceBatchTimeout) - } - - return nil -} +// Type aliases — canonical definitions live in pkg/monitoring. +type ( + MonitoringConfig = monitoring.MonitoringConfig + BeholderConfig = monitoring.BeholderConfig +) diff --git a/indexer/pkg/config/config.go b/indexer/pkg/config/config.go index 6ce443bdb..86fd3f53f 100644 --- a/indexer/pkg/config/config.go +++ b/indexer/pkg/config/config.go @@ -12,14 +12,14 @@ import ( // GeneratedVerifierConfig contains auto-generated verifier configuration. type GeneratedVerifierConfig struct { - Name string `toml:"Name"` - IssuerAddresses []string `toml:"IssuerAddresses"` + Name string `toml:"Name" json:"name"` + IssuerAddresses []string `toml:"IssuerAddresses" json:"issuerAddresses"` } // GeneratedConfig contains auto-generated deployment configuration. // This is typically generated by tooling and loaded from a separate file. type GeneratedConfig struct { - Verifier []GeneratedVerifierConfig `toml:"Verifier"` + Verifier []GeneratedVerifierConfig `toml:"Verifier" json:"verifiers"` } // Config provides all configuration for the indexer. diff --git a/indexer/pkg/config/monitoring.go b/indexer/pkg/config/monitoring.go index d9cbca55f..b07a94600 100644 --- a/indexer/pkg/config/monitoring.go +++ b/indexer/pkg/config/monitoring.go @@ -1,67 +1,9 @@ package config -import ( - "fmt" -) - -// Config provides monitoring configuration for CCV services (verifier, executor, indexer, aggregator). -type MonitoringConfig struct { - // Enabled enables the monitoring system. - Enabled bool `toml:"Enabled"` - // Type is the type of monitoring system to use (beholder, noop). - Type string `toml:"Type"` - // Beholder is the configuration for the beholder client (Not required if type is noop). - Beholder BeholderConfig `toml:"Beholder"` -} - -// BeholderConfig wraps OpenTelemetry configuration for the beholder client. -type BeholderConfig struct { - // InsecureConnection disables TLS for the beholder client. - InsecureConnection bool `toml:"InsecureConnection"` - // CACertFile is the path to the CA certificate file for the beholder client. - CACertFile string `toml:"CACertFile"` - // OtelExporterGRPCEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterGRPCEndpoint string `toml:"OtelExporterGRPCEndpoint"` - // OtelExporterHTTPEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterHTTPEndpoint string `toml:"OtelExporterHTTPEndpoint"` - // LogStreamingEnabled enables log streaming to the collector. - LogStreamingEnabled bool `toml:"LogStreamingEnabled"` - // MetricReaderInterval is the interval to scrape metrics (in seconds). - MetricReaderInterval int64 `toml:"MetricReaderInterval"` - // TraceSampleRatio is the ratio of traces to sample. - TraceSampleRatio float64 `toml:"TraceSampleRatio"` - // TraceBatchTimeout is the timeout for a batch of traces. - TraceBatchTimeout int64 `toml:"TraceBatchTimeout"` -} - -// Validate performs validation on the monitoring configuration. -func (m *MonitoringConfig) Validate() error { - if m.Enabled && m.Type == "" { - return fmt.Errorf("monitoring type is required when monitoring is enabled") - } - - if m.Enabled && m.Type == "beholder" { - if err := m.Beholder.Validate(); err != nil { - return fmt.Errorf("beholder config validation failed: %w", err) - } - } +import "github.com/smartcontractkit/chainlink-ccv/pkg/monitoring" - return nil -} - -// Validate performs validation on the beholder configuration. -func (b *BeholderConfig) Validate() error { - if b.MetricReaderInterval <= 0 { - return fmt.Errorf("metric_reader_interval must be positive, got %d", b.MetricReaderInterval) - } - - if b.TraceSampleRatio < 0 || b.TraceSampleRatio > 1 { - return fmt.Errorf("trace_sample_ratio must be between 0 and 1, got %f", b.TraceSampleRatio) - } - - if b.TraceBatchTimeout <= 0 { - return fmt.Errorf("trace_batch_timeout must be positive, got %d", b.TraceBatchTimeout) - } - - return nil -} +// Type aliases — canonical definitions live in pkg/monitoring. +type ( + MonitoringConfig = monitoring.MonitoringConfig + BeholderConfig = monitoring.BeholderConfig +) diff --git a/pkg/monitoring/config.go b/pkg/monitoring/config.go new file mode 100644 index 000000000..5e9735cb0 --- /dev/null +++ b/pkg/monitoring/config.go @@ -0,0 +1,65 @@ +package monitoring + +import "fmt" + +// MonitoringConfig provides monitoring configuration for CCV services. +type MonitoringConfig struct { + // Enabled enables the monitoring system. + Enabled bool `toml:"Enabled" json:"enabled"` + // Type is the type of monitoring system to use (beholder, noop). + Type string `toml:"Type" json:"type"` + // Beholder is the configuration for the beholder client (Not required if type is noop). + Beholder BeholderConfig `toml:"Beholder" json:"beholder"` +} + +// BeholderConfig wraps OpenTelemetry configuration for the beholder client. +type BeholderConfig struct { + // InsecureConnection disables TLS for the beholder client. + InsecureConnection bool `toml:"InsecureConnection" json:"insecure_connection"` + // CACertFile is the path to the CA certificate file for the beholder client. + CACertFile string `toml:"CACertFile" json:"ca_cert_file"` + // OtelExporterGRPCEndpoint is the endpoint for the beholder client to export to the collector. + OtelExporterGRPCEndpoint string `toml:"OtelExporterGRPCEndpoint" json:"otel_exporter_grpc_endpoint"` + // OtelExporterHTTPEndpoint is the endpoint for the beholder client to export to the collector. + OtelExporterHTTPEndpoint string `toml:"OtelExporterHTTPEndpoint" json:"otel_exporter_http_endpoint"` + // LogStreamingEnabled enables log streaming to the collector. + LogStreamingEnabled bool `toml:"LogStreamingEnabled" json:"log_streaming_enabled"` + // MetricReaderInterval is the interval to scrape metrics (in seconds). + MetricReaderInterval int64 `toml:"MetricReaderInterval" json:"metric_reader_interval"` + // TraceSampleRatio is the ratio of traces to sample. + TraceSampleRatio float64 `toml:"TraceSampleRatio" json:"trace_sample_ratio"` + // TraceBatchTimeout is the timeout for a batch of traces. + TraceBatchTimeout int64 `toml:"TraceBatchTimeout" json:"trace_batch_timeout"` +} + +// Validate performs validation on the monitoring configuration. +func (m *MonitoringConfig) Validate() error { + if m.Enabled && m.Type == "" { + return fmt.Errorf("monitoring type is required when monitoring is enabled") + } + + if m.Enabled && m.Type == "beholder" { + if err := m.Beholder.Validate(); err != nil { + return fmt.Errorf("beholder config validation failed: %w", err) + } + } + + return nil +} + +// Validate performs validation on the beholder configuration. +func (b *BeholderConfig) Validate() error { + if b.MetricReaderInterval <= 0 { + return fmt.Errorf("metric_reader_interval must be positive, got %d", b.MetricReaderInterval) + } + + if b.TraceSampleRatio < 0 || b.TraceSampleRatio > 1 { + return fmt.Errorf("trace_sample_ratio must be between 0 and 1, got %f", b.TraceSampleRatio) + } + + if b.TraceBatchTimeout <= 0 { + return fmt.Errorf("trace_batch_timeout must be positive, got %d", b.TraceBatchTimeout) + } + + return nil +} diff --git a/verifier/pkg/vtypes/config.go b/verifier/pkg/vtypes/config.go index c8c880fb6..cfaf6b156 100644 --- a/verifier/pkg/vtypes/config.go +++ b/verifier/pkg/vtypes/config.go @@ -1,67 +1,9 @@ package vtypes -import ( - "fmt" -) - -// MonitoringConfig provides monitoring configuration for verifier. -type MonitoringConfig struct { - // Enabled enables the monitoring system. - Enabled bool `toml:"Enabled"` - // Type is the type of monitoring system to use (beholder, noop). - Type string `toml:"Type"` - // Beholder is the configuration for the beholder client (Not required if type is noop). - Beholder BeholderConfig `toml:"Beholder"` -} - -// BeholderConfig wraps OpenTelemetry configuration for the beholder client. -type BeholderConfig struct { - // InsecureConnection disables TLS for the beholder client. - InsecureConnection bool `toml:"InsecureConnection"` - // CACertFile is the path to the CA certificate file for the beholder client. - CACertFile string `toml:"CACertFile"` - // OtelExporterGRPCEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterGRPCEndpoint string `toml:"OtelExporterGRPCEndpoint"` - // OtelExporterHTTPEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterHTTPEndpoint string `toml:"OtelExporterHTTPEndpoint"` - // LogStreamingEnabled enables log streaming to the collector. - LogStreamingEnabled bool `toml:"LogStreamingEnabled"` - // MetricReaderInterval is the interval to scrape metrics (in seconds). - MetricReaderInterval int64 `toml:"MetricReaderInterval"` - // TraceSampleRatio is the ratio of traces to sample. - TraceSampleRatio float64 `toml:"TraceSampleRatio"` - // TraceBatchTimeout is the timeout for a batch of traces. - TraceBatchTimeout int64 `toml:"TraceBatchTimeout"` -} - -// Validate performs validation on the monitoring configuration. -func (m *MonitoringConfig) Validate() error { - if m.Enabled && m.Type == "" { - return fmt.Errorf("monitoring type is required when monitoring is enabled") - } - - if m.Enabled && m.Type == "beholder" { - if err := m.Beholder.Validate(); err != nil { - return fmt.Errorf("beholder config validation failed: %w", err) - } - } +import "github.com/smartcontractkit/chainlink-ccv/pkg/monitoring" - return nil -} - -// Validate performs validation on the beholder configuration. -func (b *BeholderConfig) Validate() error { - if b.MetricReaderInterval <= 0 { - return fmt.Errorf("metric_reader_interval must be positive, got %d", b.MetricReaderInterval) - } - - if b.TraceSampleRatio < 0 || b.TraceSampleRatio > 1 { - return fmt.Errorf("trace_sample_ratio must be between 0 and 1, got %f", b.TraceSampleRatio) - } - - if b.TraceBatchTimeout <= 0 { - return fmt.Errorf("trace_batch_timeout must be positive, got %d", b.TraceBatchTimeout) - } - - return nil -} +// Type aliases — canonical definitions live in pkg/monitoring. +type ( + MonitoringConfig = monitoring.MonitoringConfig + BeholderConfig = monitoring.BeholderConfig +) From 0fe1f43891f887af9bf932f96b25c07f801740c5 Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Tue, 21 Apr 2026 16:45:46 -0700 Subject: [PATCH 08/17] lint --- aggregator/pkg/model/config.go | 14 +++++++------- deployment/topology.go | 2 +- executor/config.go | 2 +- indexer/pkg/config/config.go | 6 +++--- indexer/pkg/config/monitoring.go | 2 +- pkg/monitoring/config.go | 28 ++++++++++++++-------------- verifier/pkg/vtypes/config.go | 2 +- 7 files changed, 28 insertions(+), 28 deletions(-) diff --git a/aggregator/pkg/model/config.go b/aggregator/pkg/model/config.go index 5f8c20b31..6b8eb151d 100644 --- a/aggregator/pkg/model/config.go +++ b/aggregator/pkg/model/config.go @@ -18,7 +18,7 @@ import ( // Signer represents a participant in the commit verification process. type Signer struct { - Address string `toml:"address" json:"address"` + Address string `json:"address" toml:"address"` } // SignerIdentifier holds the chain-native signer identifier. @@ -45,9 +45,9 @@ type Committee struct { // The aggregator uses this to verify signatures from each chain's // commit verifier set. // Map structure: source selector -> QuorumConfig - QuorumConfigs map[SourceSelector]*QuorumConfig `toml:"quorumConfigs" json:"quorumConfigs"` + QuorumConfigs map[SourceSelector]*QuorumConfig `json:"quorumConfigs" toml:"quorumConfigs"` // DestinationVerifiers maps destination chain selectors to their verifier contract addresses. - DestinationVerifiers map[DestinationSelector]string `toml:"destinationVerifiers" json:"destinationVerifiers"` + DestinationVerifiers map[DestinationSelector]string `json:"destinationVerifiers" toml:"destinationVerifiers"` // destinationVerifiersParsed holds the parsed addresses, populated during validation. destinationVerifiersParsed map[DestinationSelector]protocol.UnknownAddress } @@ -88,9 +88,9 @@ func (c *Committee) SetQuorumConfig(sourceSelector SourceSelector, quorumConfig // QuorumConfig represents the configuration for a quorum of signers. type QuorumConfig struct { - SourceVerifierAddress string `toml:"sourceVerifierAddress" json:"sourceVerifierAddress"` - Signers []Signer `toml:"signers" json:"signers"` - Threshold uint8 `toml:"threshold" json:"threshold"` + SourceVerifierAddress string `json:"sourceVerifierAddress" toml:"sourceVerifierAddress"` + Signers []Signer `json:"signers" toml:"signers"` + Threshold uint8 `json:"threshold" toml:"threshold"` // sourceVerifierAddressParsed holds the parsed address, populated during validation. sourceVerifierAddressParsed protocol.UnknownAddress } @@ -364,7 +364,7 @@ func (c *RateLimitingConfig) getMostRestrictiveGroupLimit(client auth.ClientConf // Type aliases — canonical definitions live in pkg/monitoring. type ( - MonitoringConfig = monitoring.MonitoringConfig + MonitoringConfig = monitoring.Config BeholderConfig = monitoring.BeholderConfig ) diff --git a/deployment/topology.go b/deployment/topology.go index cfae5f9e9..741b1ac1d 100644 --- a/deployment/topology.go +++ b/deployment/topology.go @@ -138,7 +138,7 @@ type ChainExecutorPoolConfig struct { // Type aliases — canonical definitions live in pkg/monitoring. type ( - MonitoringConfig = monitoring.MonitoringConfig + MonitoringConfig = monitoring.Config BeholderConfig = monitoring.BeholderConfig ) diff --git a/executor/config.go b/executor/config.go index 3dd6ee17c..a1cf7632c 100644 --- a/executor/config.go +++ b/executor/config.go @@ -195,6 +195,6 @@ func (c *Configuration) GetNormalizedConfig() (*Configuration, error) { // Type aliases — canonical definitions live in pkg/monitoring. type ( - MonitoringConfig = monitoring.MonitoringConfig + MonitoringConfig = monitoring.Config BeholderConfig = monitoring.BeholderConfig ) diff --git a/indexer/pkg/config/config.go b/indexer/pkg/config/config.go index 86fd3f53f..f67ffd56f 100644 --- a/indexer/pkg/config/config.go +++ b/indexer/pkg/config/config.go @@ -12,14 +12,14 @@ import ( // GeneratedVerifierConfig contains auto-generated verifier configuration. type GeneratedVerifierConfig struct { - Name string `toml:"Name" json:"name"` - IssuerAddresses []string `toml:"IssuerAddresses" json:"issuerAddresses"` + Name string `json:"name" toml:"Name"` + IssuerAddresses []string `json:"issuerAddresses" toml:"IssuerAddresses"` } // GeneratedConfig contains auto-generated deployment configuration. // This is typically generated by tooling and loaded from a separate file. type GeneratedConfig struct { - Verifier []GeneratedVerifierConfig `toml:"Verifier" json:"verifiers"` + Verifier []GeneratedVerifierConfig `json:"verifiers" toml:"Verifier"` } // Config provides all configuration for the indexer. diff --git a/indexer/pkg/config/monitoring.go b/indexer/pkg/config/monitoring.go index b07a94600..4cf55a037 100644 --- a/indexer/pkg/config/monitoring.go +++ b/indexer/pkg/config/monitoring.go @@ -4,6 +4,6 @@ import "github.com/smartcontractkit/chainlink-ccv/pkg/monitoring" // Type aliases — canonical definitions live in pkg/monitoring. type ( - MonitoringConfig = monitoring.MonitoringConfig + MonitoringConfig = monitoring.Config BeholderConfig = monitoring.BeholderConfig ) diff --git a/pkg/monitoring/config.go b/pkg/monitoring/config.go index 5e9735cb0..a3cdaef23 100644 --- a/pkg/monitoring/config.go +++ b/pkg/monitoring/config.go @@ -2,38 +2,38 @@ package monitoring import "fmt" -// MonitoringConfig provides monitoring configuration for CCV services. -type MonitoringConfig struct { +// Config provides monitoring configuration for CCV services. +type Config struct { // Enabled enables the monitoring system. - Enabled bool `toml:"Enabled" json:"enabled"` + Enabled bool `json:"enabled" toml:"Enabled"` // Type is the type of monitoring system to use (beholder, noop). - Type string `toml:"Type" json:"type"` + Type string `json:"type" toml:"Type"` // Beholder is the configuration for the beholder client (Not required if type is noop). - Beholder BeholderConfig `toml:"Beholder" json:"beholder"` + Beholder BeholderConfig `json:"beholder" toml:"Beholder"` } // BeholderConfig wraps OpenTelemetry configuration for the beholder client. type BeholderConfig struct { // InsecureConnection disables TLS for the beholder client. - InsecureConnection bool `toml:"InsecureConnection" json:"insecure_connection"` + InsecureConnection bool `json:"insecure_connection" toml:"InsecureConnection"` // CACertFile is the path to the CA certificate file for the beholder client. - CACertFile string `toml:"CACertFile" json:"ca_cert_file"` + CACertFile string `json:"ca_cert_file" toml:"CACertFile"` // OtelExporterGRPCEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterGRPCEndpoint string `toml:"OtelExporterGRPCEndpoint" json:"otel_exporter_grpc_endpoint"` + OtelExporterGRPCEndpoint string `json:"otel_exporter_grpc_endpoint" toml:"OtelExporterGRPCEndpoint"` // OtelExporterHTTPEndpoint is the endpoint for the beholder client to export to the collector. - OtelExporterHTTPEndpoint string `toml:"OtelExporterHTTPEndpoint" json:"otel_exporter_http_endpoint"` + OtelExporterHTTPEndpoint string `json:"otel_exporter_http_endpoint" toml:"OtelExporterHTTPEndpoint"` // LogStreamingEnabled enables log streaming to the collector. - LogStreamingEnabled bool `toml:"LogStreamingEnabled" json:"log_streaming_enabled"` + LogStreamingEnabled bool `json:"log_streaming_enabled" toml:"LogStreamingEnabled"` // MetricReaderInterval is the interval to scrape metrics (in seconds). - MetricReaderInterval int64 `toml:"MetricReaderInterval" json:"metric_reader_interval"` + MetricReaderInterval int64 `json:"metric_reader_interval" toml:"MetricReaderInterval"` // TraceSampleRatio is the ratio of traces to sample. - TraceSampleRatio float64 `toml:"TraceSampleRatio" json:"trace_sample_ratio"` + TraceSampleRatio float64 `json:"trace_sample_ratio" toml:"TraceSampleRatio"` // TraceBatchTimeout is the timeout for a batch of traces. - TraceBatchTimeout int64 `toml:"TraceBatchTimeout" json:"trace_batch_timeout"` + TraceBatchTimeout int64 `json:"trace_batch_timeout" toml:"TraceBatchTimeout"` } // Validate performs validation on the monitoring configuration. -func (m *MonitoringConfig) Validate() error { +func (m *Config) Validate() error { if m.Enabled && m.Type == "" { return fmt.Errorf("monitoring type is required when monitoring is enabled") } diff --git a/verifier/pkg/vtypes/config.go b/verifier/pkg/vtypes/config.go index cfaf6b156..fd5603c5f 100644 --- a/verifier/pkg/vtypes/config.go +++ b/verifier/pkg/vtypes/config.go @@ -4,6 +4,6 @@ import "github.com/smartcontractkit/chainlink-ccv/pkg/monitoring" // Type aliases — canonical definitions live in pkg/monitoring. type ( - MonitoringConfig = monitoring.MonitoringConfig + MonitoringConfig = monitoring.Config BeholderConfig = monitoring.BeholderConfig ) From 44900072aff2bb3e8f2fd4b92ed4b3cac8d9ee31 Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Tue, 21 Apr 2026 16:51:15 -0700 Subject: [PATCH 09/17] lint --- aggregator/pkg/model/config.go | 6 +++--- pkg/monitoring/config.go | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/aggregator/pkg/model/config.go b/aggregator/pkg/model/config.go index 6b8eb151d..c6f969774 100644 --- a/aggregator/pkg/model/config.go +++ b/aggregator/pkg/model/config.go @@ -45,7 +45,7 @@ type Committee struct { // The aggregator uses this to verify signatures from each chain's // commit verifier set. // Map structure: source selector -> QuorumConfig - QuorumConfigs map[SourceSelector]*QuorumConfig `json:"quorumConfigs" toml:"quorumConfigs"` + QuorumConfigs map[SourceSelector]*QuorumConfig `json:"quorumConfigs" toml:"quorumConfigs"` // DestinationVerifiers maps destination chain selectors to their verifier contract addresses. DestinationVerifiers map[DestinationSelector]string `json:"destinationVerifiers" toml:"destinationVerifiers"` // destinationVerifiersParsed holds the parsed addresses, populated during validation. @@ -89,8 +89,8 @@ func (c *Committee) SetQuorumConfig(sourceSelector SourceSelector, quorumConfig // QuorumConfig represents the configuration for a quorum of signers. type QuorumConfig struct { SourceVerifierAddress string `json:"sourceVerifierAddress" toml:"sourceVerifierAddress"` - Signers []Signer `json:"signers" toml:"signers"` - Threshold uint8 `json:"threshold" toml:"threshold"` + Signers []Signer `json:"signers" toml:"signers"` + Threshold uint8 `json:"threshold" toml:"threshold"` // sourceVerifierAddressParsed holds the parsed address, populated during validation. sourceVerifierAddressParsed protocol.UnknownAddress } diff --git a/pkg/monitoring/config.go b/pkg/monitoring/config.go index a3cdaef23..299797a25 100644 --- a/pkg/monitoring/config.go +++ b/pkg/monitoring/config.go @@ -15,21 +15,21 @@ type Config struct { // BeholderConfig wraps OpenTelemetry configuration for the beholder client. type BeholderConfig struct { // InsecureConnection disables TLS for the beholder client. - InsecureConnection bool `json:"insecure_connection" toml:"InsecureConnection"` + InsecureConnection bool `json:"insecure_connection" toml:"InsecureConnection"` // CACertFile is the path to the CA certificate file for the beholder client. - CACertFile string `json:"ca_cert_file" toml:"CACertFile"` + CACertFile string `json:"ca_cert_file" toml:"CACertFile"` // OtelExporterGRPCEndpoint is the endpoint for the beholder client to export to the collector. OtelExporterGRPCEndpoint string `json:"otel_exporter_grpc_endpoint" toml:"OtelExporterGRPCEndpoint"` // OtelExporterHTTPEndpoint is the endpoint for the beholder client to export to the collector. OtelExporterHTTPEndpoint string `json:"otel_exporter_http_endpoint" toml:"OtelExporterHTTPEndpoint"` // LogStreamingEnabled enables log streaming to the collector. - LogStreamingEnabled bool `json:"log_streaming_enabled" toml:"LogStreamingEnabled"` + LogStreamingEnabled bool `json:"log_streaming_enabled" toml:"LogStreamingEnabled"` // MetricReaderInterval is the interval to scrape metrics (in seconds). - MetricReaderInterval int64 `json:"metric_reader_interval" toml:"MetricReaderInterval"` + MetricReaderInterval int64 `json:"metric_reader_interval" toml:"MetricReaderInterval"` // TraceSampleRatio is the ratio of traces to sample. - TraceSampleRatio float64 `json:"trace_sample_ratio" toml:"TraceSampleRatio"` + TraceSampleRatio float64 `json:"trace_sample_ratio" toml:"TraceSampleRatio"` // TraceBatchTimeout is the timeout for a batch of traces. - TraceBatchTimeout int64 `json:"trace_batch_timeout" toml:"TraceBatchTimeout"` + TraceBatchTimeout int64 `json:"trace_batch_timeout" toml:"TraceBatchTimeout"` } // Validate performs validation on the monitoring configuration. From b593d71338e4ca87b9dfb0f8e046b96a9102dce7 Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Tue, 21 Apr 2026 16:57:36 -0700 Subject: [PATCH 10/17] lint --- aggregator/pkg/model/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/aggregator/pkg/model/config.go b/aggregator/pkg/model/config.go index c6f969774..cb0c3c2c5 100644 --- a/aggregator/pkg/model/config.go +++ b/aggregator/pkg/model/config.go @@ -89,8 +89,8 @@ func (c *Committee) SetQuorumConfig(sourceSelector SourceSelector, quorumConfig // QuorumConfig represents the configuration for a quorum of signers. type QuorumConfig struct { SourceVerifierAddress string `json:"sourceVerifierAddress" toml:"sourceVerifierAddress"` - Signers []Signer `json:"signers" toml:"signers"` - Threshold uint8 `json:"threshold" toml:"threshold"` + Signers []Signer `json:"signers" toml:"signers"` + Threshold uint8 `json:"threshold" toml:"threshold"` // sourceVerifierAddressParsed holds the parsed address, populated during validation. sourceVerifierAddressParsed protocol.UnknownAddress } From 5edb9f06ae75fcb8966a99233614932497cce9ee Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Tue, 21 Apr 2026 17:09:05 -0700 Subject: [PATCH 11/17] lint --- build/devenv/evm/impl.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/devenv/evm/impl.go b/build/devenv/evm/impl.go index d57b48db0..47cf5b3b4 100644 --- a/build/devenv/evm/impl.go +++ b/build/devenv/evm/impl.go @@ -56,9 +56,9 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chains/evm/deployment/v1_6_0/operations/rmn_remote" "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/adapters" ccipChangesets "github.com/smartcontractkit/chainlink-ccip/deployment/v2_0_0/changesets" - ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/build/devenv/cciptestinterfaces" devenvcommon "github.com/smartcontractkit/chainlink-ccv/build/devenv/common" + ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" "github.com/smartcontractkit/chainlink-ccv/protocol" "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token/lombard" "github.com/smartcontractkit/chainlink-deployments-framework/chain/evm" From f5153d47927e88df11921dcc1b7aad724f153995 Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Wed, 22 Apr 2026 03:36:02 -0700 Subject: [PATCH 12/17] merge errors --- build/devenv/environment.go | 2 +- build/devenv/implcommon.go | 10 ++++------ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/build/devenv/environment.go b/build/devenv/environment.go index bed376f68..0b1f5538b 100644 --- a/build/devenv/environment.go +++ b/build/devenv/environment.go @@ -1108,7 +1108,7 @@ func NewEnvironment() (in *Cfg, err error) { capsBySelector[networkInfo.ChainSelector] = nil } } - combos := devenvcommon.ComputeTokenCombinations(capsBySelector, convertTopologyToCCIP(topology)) + combos := devenvcommon.ComputeTokenCombinations(capsBySelector, topology) ds := datastore.NewMemoryDataStore() for i, impl := range impls { diff --git a/build/devenv/implcommon.go b/build/devenv/implcommon.go index c8e296531..17df44b54 100644 --- a/build/devenv/implcommon.go +++ b/build/devenv/implcommon.go @@ -60,10 +60,8 @@ func DeployContractsForSelector( operations.NewMemoryReporter(), ) - ccipTopology := convertTopologyToCCIP(topology) - // 1. Pre-hook (e.g. EVM deploys CREATE2 factory here). - preDS, err := impl.PreDeployContractsForSelector(ctx, env, selector, ccipTopology) + preDS, err := impl.PreDeployContractsForSelector(ctx, env, selector, topology) if err != nil { return nil, fmt.Errorf("pre-deploy for selector %d: %w", selector, err) } @@ -79,7 +77,7 @@ func DeployContractsForSelector( } // 2. Get chain-specific config (reads pre-deployed addresses from env.DataStore). - cfg, err := impl.GetDeployChainContractsCfg(env, selector, ccipTopology) + cfg, err := impl.GetDeployChainContractsCfg(env, selector, topology) if err != nil { return nil, fmt.Errorf("get deploy config for selector %d: %w", selector, err) } @@ -108,7 +106,7 @@ func DeployContractsForSelector( env.DataStore = merged // 4. Post-hook (e.g. EVM deploys USDC/Lombard pools here). - postDS, err := impl.PostDeployContractsForSelector(ctx, env, selector, ccipTopology) + postDS, err := impl.PostDeployContractsForSelector(ctx, env, selector, topology) if err != nil { return nil, fmt.Errorf("post-deploy for selector %d: %w", selector, err) } @@ -558,7 +556,7 @@ func ConfigureAllTokenTransfers( } } - cfgs, err := tcp.GetTokenTransferConfigs(env, selectors[i], remoteSelectors, convertTopologyToCCIP(topology)) + cfgs, err := tcp.GetTokenTransferConfigs(env, selectors[i], remoteSelectors, topology) if err != nil { return fmt.Errorf("get token transfer configs for selector %d: %w", selectors[i], err) } From 31e9314dcc18a946ed912e332e59972b7ace3b36 Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Wed, 22 Apr 2026 04:04:39 -0700 Subject: [PATCH 13/17] merge errors --- build/devenv/offchainloader/loader.go | 174 -------------------------- 1 file changed, 174 deletions(-) delete mode 100644 build/devenv/offchainloader/loader.go diff --git a/build/devenv/offchainloader/loader.go b/build/devenv/offchainloader/loader.go deleted file mode 100644 index e97e79a84..000000000 --- a/build/devenv/offchainloader/loader.go +++ /dev/null @@ -1,174 +0,0 @@ -package offchainloader - -import ( - "github.com/smartcontractkit/chainlink-ccv/aggregator/pkg/model" - ccvdeployment "github.com/smartcontractkit/chainlink-ccv/deployment" - "github.com/smartcontractkit/chainlink-ccv/indexer/pkg/config" - "github.com/smartcontractkit/chainlink-ccv/pkg/chainaccess" - "github.com/smartcontractkit/chainlink-ccv/protocol" - verifier "github.com/smartcontractkit/chainlink-ccv/verifier/pkg" - "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token" - "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token/cctp" - "github.com/smartcontractkit/chainlink-ccv/verifier/pkg/token/lombard" - "github.com/smartcontractkit/chainlink-deployments-framework/datastore" -) - -func GetAggregatorConfig(ds datastore.DataStore, id string) (*model.Committee, error) { - ccvCfg, err := ccvdeployment.GetAggregatorConfig(ds, id) - if err != nil { - return nil, err - } - return convertCommittee(ccvCfg), nil -} - -func GetIndexerConfig(ds datastore.DataStore, id string) (*config.GeneratedConfig, error) { - ccvCfg, err := ccvdeployment.GetIndexerConfig(ds, id) - if err != nil { - return nil, err - } - return convertIndexerConfig(ccvCfg), nil -} - -func GetTokenVerifierConfig(ds datastore.DataStore, id string) (*token.Config, error) { - ccvCfg, err := ccvdeployment.GetTokenVerifierConfig(ds, id) - if err != nil { - return nil, err - } - return convertTokenVerifierConfig(ccvCfg), nil -} - -func convertCommittee(src *ccvdeployment.Committee) *model.Committee { - if src == nil { - return nil - } - dst := &model.Committee{ - DestinationVerifiers: src.DestinationVerifiers, - } - if src.QuorumConfigs != nil { - dst.QuorumConfigs = make(map[model.SourceSelector]*model.QuorumConfig, len(src.QuorumConfigs)) - for k, qc := range src.QuorumConfigs { - dst.QuorumConfigs[k] = convertQuorumConfig(qc) - } - } - return dst -} - -func convertQuorumConfig(src *ccvdeployment.QuorumConfig) *model.QuorumConfig { - if src == nil { - return nil - } - signers := make([]model.Signer, len(src.Signers)) - for i, s := range src.Signers { - signers[i] = model.Signer{Address: s.Address} - } - return &model.QuorumConfig{ - SourceVerifierAddress: src.SourceVerifierAddress, - Signers: signers, - Threshold: src.Threshold, - } -} - -func convertIndexerConfig(src *ccvdeployment.IndexerGeneratedConfig) *config.GeneratedConfig { - if src == nil { - return nil - } - verifiers := make([]config.GeneratedVerifierConfig, len(src.Verifiers)) - for i, v := range src.Verifiers { - verifiers[i] = config.GeneratedVerifierConfig{ - Name: v.Name, - IssuerAddresses: v.IssuerAddresses, - } - } - return &config.GeneratedConfig{Verifier: verifiers} -} - -func convertTokenVerifierConfig(src *ccvdeployment.TokenVerifierGeneratedConfig) *token.Config { - if src == nil { - return nil - } - dst := &token.Config{ - PyroscopeURL: src.PyroscopeURL, - CommitteeConfig: chainaccess.CommitteeConfig{ - OnRampAddresses: src.OnRampAddresses, - RMNRemoteAddresses: src.RMNRemoteAddresses, - }, - Monitoring: verifier.MonitoringConfig{ - Enabled: src.Monitoring.Enabled, - Type: src.Monitoring.Type, - Beholder: verifier.BeholderConfig{ - InsecureConnection: src.Monitoring.Beholder.InsecureConnection, - CACertFile: src.Monitoring.Beholder.CACertFile, - OtelExporterGRPCEndpoint: src.Monitoring.Beholder.OtelExporterGRPCEndpoint, - OtelExporterHTTPEndpoint: src.Monitoring.Beholder.OtelExporterHTTPEndpoint, - LogStreamingEnabled: src.Monitoring.Beholder.LogStreamingEnabled, - MetricReaderInterval: src.Monitoring.Beholder.MetricReaderInterval, - TraceSampleRatio: src.Monitoring.Beholder.TraceSampleRatio, - TraceBatchTimeout: src.Monitoring.Beholder.TraceBatchTimeout, - }, - }, - } - dst.TokenVerifiers = make([]token.VerifierConfig, len(src.TokenVerifiers)) - for i, tv := range src.TokenVerifiers { - vc := token.VerifierConfig{ - VerifierID: tv.VerifierID, - Type: tv.Type, - Version: tv.Version, - } - if tv.CCTP != nil { - vc.CCTPConfig = convertCCTPConfig(tv.CCTP) - } - if tv.Lombard != nil { - vc.LombardConfig = convertLombardConfig(tv.Lombard) - } - dst.TokenVerifiers[i] = vc - } - return dst -} - -func convertCCTPConfig(src *ccvdeployment.CCTPVerifierConfig) *cctp.CCTPConfig { - if src == nil { - return nil - } - dst := &cctp.CCTPConfig{ - AttestationAPI: src.AttestationAPI, - AttestationAPITimeout: src.AttestationAPITimeout, - AttestationAPIInterval: src.AttestationAPIInterval, - AttestationAPICooldown: src.AttestationAPICooldown, - VerifierVersion: protocol.ByteSlice(src.VerifierVersion), - } - if src.Verifiers != nil { - dst.Verifiers = toAnyMap(src.Verifiers) - } - if src.VerifierResolvers != nil { - dst.VerifierResolvers = toAnyMap(src.VerifierResolvers) - } - return dst -} - -func convertLombardConfig(src *ccvdeployment.LombardVerifierConfig) *lombard.LombardConfig { - if src == nil { - return nil - } - dst := &lombard.LombardConfig{ - AttestationAPI: src.AttestationAPI, - AttestationAPITimeout: src.AttestationAPITimeout, - AttestationAPIInterval: src.AttestationAPIInterval, - AttestationAPIBatchSize: src.AttestationAPIBatchSize, - VerifierVersion: protocol.ByteSlice(src.VerifierVersion), - } - if src.VerifierResolvers != nil { - dst.VerifierResolvers = toAnyMap(src.VerifierResolvers) - } - return dst -} - -func toAnyMap(src map[string]string) map[string]any { - if src == nil { - return nil - } - dst := make(map[string]any, len(src)) - for k, v := range src { - dst[k] = v - } - return dst -} From ae0f30c302fc2f0c2a81049fd6b2ef9b08255303 Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Wed, 22 Apr 2026 04:19:25 -0700 Subject: [PATCH 14/17] lint --- build/devenv/services/committeeverifier/base.go | 2 +- build/devenv/services/common.go | 6 +++--- build/devenv/services/executor.go | 2 +- build/devenv/services/executor/base.go | 4 ++-- build/devenv/services/tokenVerifier.go | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/devenv/services/committeeverifier/base.go b/build/devenv/services/committeeverifier/base.go index 808be22f8..4c5592523 100644 --- a/build/devenv/services/committeeverifier/base.go +++ b/build/devenv/services/committeeverifier/base.go @@ -405,7 +405,7 @@ func baseImageRequest(in *Input, envVars map[string]string, bootstrapConfigFileP } req.Mounts = testcontainers.Mounts() - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // we're still using it... + req.Mounts = append(req.Mounts, testcontainers.BindMount( bootstrapConfigFilePath, bootstrap.DefaultConfigPath, )) diff --git a/build/devenv/services/common.go b/build/devenv/services/common.go index 403764519..004c71bc4 100644 --- a/build/devenv/services/common.go +++ b/build/devenv/services/common.go @@ -46,7 +46,7 @@ func GoSourcePathMounts(rootPath, containerDirTarget string) testcontainers.Cont mounts := make([]testcontainers.ContainerMount, 0, 1) mounts = append(mounts, - testcontainers.BindMount( //nolint:staticcheck // we're still using it... + testcontainers.BindMount( absRootPath, testcontainers.ContainerMountTarget(containerDirTarget), ), @@ -79,11 +79,11 @@ func GoCacheMounts() testcontainers.ContainerMounts { goBuildCachePath = filepath.Join(homeDir, ".cache", "go-build") } mounts = append(mounts, - testcontainers.BindMount( //nolint:staticcheck // we're still using it... + testcontainers.BindMount( goModCachePath, "/go/pkg/mod", ), - testcontainers.BindMount( //nolint:staticcheck // we're still using it... + testcontainers.BindMount( goBuildCachePath, "/root/.cache/go-build", ), diff --git a/build/devenv/services/executor.go b/build/devenv/services/executor.go index 7c556e6db..bb4366d0e 100644 --- a/build/devenv/services/executor.go +++ b/build/devenv/services/executor.go @@ -184,7 +184,7 @@ func NewExecutor(in *ExecutorInput, blockchainOutputs []*ctfblockchain.Output) ( }, } - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // we're still using it... + req.Mounts = append(req.Mounts, testcontainers.BindMount( configFilePath, executor.DefaultConfigFile, )) diff --git a/build/devenv/services/executor/base.go b/build/devenv/services/executor/base.go index f750a9750..c39ed46f3 100644 --- a/build/devenv/services/executor/base.go +++ b/build/devenv/services/executor/base.go @@ -269,7 +269,7 @@ func NewStandalone(in *Input, blockchainOutputs []*ctfblockchain.Output) (*Outpu }, } - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck + req.Mounts = append(req.Mounts, testcontainers.BindMount( configFilePath, executorpkg.DefaultConfigFile, )) @@ -495,7 +495,7 @@ func baseImageRequest(in *Input, envVars map[string]string, bootstrapConfigFileP } req.Mounts = testcontainers.Mounts() - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck + req.Mounts = append(req.Mounts, testcontainers.BindMount( bootstrapConfigFilePath, bootstrap.DefaultConfigPath, )) diff --git a/build/devenv/services/tokenVerifier.go b/build/devenv/services/tokenVerifier.go index db5dde495..bb3884dcd 100644 --- a/build/devenv/services/tokenVerifier.go +++ b/build/devenv/services/tokenVerifier.go @@ -156,7 +156,7 @@ func NewTokenVerifier(in *TokenVerifierInput, blockchainOutputs []*blockchain.Ou } req.Mounts = testcontainers.Mounts() - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // we're still using it... + req.Mounts = append(req.Mounts, testcontainers.BindMount( configFilePath, aggregator.DefaultConfigFile, // TODO: switch to token verifier path, not aggregator path. )) From 1ad1bca9e6837cb8e59c29746deab2527528c276 Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Wed, 22 Apr 2026 04:38:52 -0700 Subject: [PATCH 15/17] merge errors --- deployment/aggregator.go | 20 ------------- deployment/indexer.go | 10 ------- deployment/token_verifier.go | 55 ------------------------------------ 3 files changed, 85 deletions(-) delete mode 100644 deployment/aggregator.go delete mode 100644 deployment/indexer.go delete mode 100644 deployment/token_verifier.go diff --git a/deployment/aggregator.go b/deployment/aggregator.go deleted file mode 100644 index d6701d92f..000000000 --- a/deployment/aggregator.go +++ /dev/null @@ -1,20 +0,0 @@ -package deployment - -type SourceSelector = string - -type DestinationSelector = string - -type Signer struct { - Address string `json:"address"` -} - -type QuorumConfig struct { - SourceVerifierAddress string `json:"sourceVerifierAddress"` - Signers []Signer `json:"signers"` - Threshold uint8 `json:"threshold"` -} - -type Committee struct { - QuorumConfigs map[SourceSelector]*QuorumConfig `json:"quorumConfigs"` - DestinationVerifiers map[DestinationSelector]string `json:"destinationVerifiers"` -} diff --git a/deployment/indexer.go b/deployment/indexer.go deleted file mode 100644 index 462c442df..000000000 --- a/deployment/indexer.go +++ /dev/null @@ -1,10 +0,0 @@ -package deployment - -type IndexerVerifierConfig struct { - Name string `json:"name"` - IssuerAddresses []string `json:"issuerAddresses"` -} - -type IndexerGeneratedConfig struct { - Verifiers []IndexerVerifierConfig `json:"verifiers"` -} diff --git a/deployment/token_verifier.go b/deployment/token_verifier.go deleted file mode 100644 index 1eb6b201d..000000000 --- a/deployment/token_verifier.go +++ /dev/null @@ -1,55 +0,0 @@ -package deployment - -import "time" - -type TokenVerifierGeneratedConfig struct { - PyroscopeURL string `json:"pyroscope_url"` - OnRampAddresses map[string]string `json:"on_ramp_addresses"` - RMNRemoteAddresses map[string]string `json:"rmn_remote_addresses"` - TokenVerifiers []TokenVerifierEntry `json:"token_verifiers"` - Monitoring TokenVerifierMonitoringConfig `json:"monitoring"` -} - -type TokenVerifierEntry struct { - VerifierID string `json:"verifier_id"` - Type string `json:"type"` - Version string `json:"version"` - CCTP *CCTPVerifierConfig `json:"cctp,omitempty"` - Lombard *LombardVerifierConfig `json:"lombard,omitempty"` -} - -type CCTPVerifierConfig struct { - AttestationAPI string `json:"attestation_api"` - AttestationAPITimeout time.Duration `json:"attestation_api_timeout"` - AttestationAPIInterval time.Duration `json:"attestation_api_interval"` - AttestationAPICooldown time.Duration `json:"attestation_api_cooldown"` - VerifierVersion []byte `json:"verifier_version"` - Verifiers map[string]string `json:"verifiers"` - VerifierResolvers map[string]string `json:"verifier_resolvers"` -} - -type LombardVerifierConfig struct { - AttestationAPI string `json:"attestation_api"` - AttestationAPITimeout time.Duration `json:"attestation_api_timeout"` - AttestationAPIInterval time.Duration `json:"attestation_api_interval"` - AttestationAPIBatchSize int `json:"attestation_api_batch_size"` - VerifierVersion []byte `json:"verifier_version"` - VerifierResolvers map[string]string `json:"verifier_resolvers"` -} - -type TokenVerifierMonitoringConfig struct { - Enabled bool `json:"enabled"` - Type string `json:"type"` - Beholder TokenVerifierBeholderConfig `json:"beholder"` -} - -type TokenVerifierBeholderConfig struct { - InsecureConnection bool `json:"insecure_connection"` - CACertFile string `json:"ca_cert_file"` - OtelExporterGRPCEndpoint string `json:"otel_exporter_grpc_endpoint"` - OtelExporterHTTPEndpoint string `json:"otel_exporter_http_endpoint"` - LogStreamingEnabled bool `json:"log_streaming_enabled"` - MetricReaderInterval int64 `json:"metric_reader_interval"` - TraceSampleRatio float64 `json:"trace_sample_ratio"` - TraceBatchTimeout int64 `json:"trace_batch_timeout"` -} From 843e4e8621f13d49cfb299fb5037160bd47a6c1f Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Wed, 22 Apr 2026 11:05:17 -0700 Subject: [PATCH 16/17] re-lint --- build/devenv/services/committeeverifier/base.go | 2 +- build/devenv/services/common.go | 6 +++--- build/devenv/services/executor.go | 2 +- build/devenv/services/executor/base.go | 4 ++-- build/devenv/services/tokenVerifier.go | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/build/devenv/services/committeeverifier/base.go b/build/devenv/services/committeeverifier/base.go index 4c5592523..54da697e6 100644 --- a/build/devenv/services/committeeverifier/base.go +++ b/build/devenv/services/committeeverifier/base.go @@ -405,7 +405,7 @@ func baseImageRequest(in *Input, envVars map[string]string, bootstrapConfigFileP } req.Mounts = testcontainers.Mounts() - req.Mounts = append(req.Mounts, testcontainers.BindMount( + req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier bootstrapConfigFilePath, bootstrap.DefaultConfigPath, )) diff --git a/build/devenv/services/common.go b/build/devenv/services/common.go index 004c71bc4..c0022e562 100644 --- a/build/devenv/services/common.go +++ b/build/devenv/services/common.go @@ -46,7 +46,7 @@ func GoSourcePathMounts(rootPath, containerDirTarget string) testcontainers.Cont mounts := make([]testcontainers.ContainerMount, 0, 1) mounts = append(mounts, - testcontainers.BindMount( + testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier absRootPath, testcontainers.ContainerMountTarget(containerDirTarget), ), @@ -79,11 +79,11 @@ func GoCacheMounts() testcontainers.ContainerMounts { goBuildCachePath = filepath.Join(homeDir, ".cache", "go-build") } mounts = append(mounts, - testcontainers.BindMount( + testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier goModCachePath, "/go/pkg/mod", ), - testcontainers.BindMount( + testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier goBuildCachePath, "/root/.cache/go-build", ), diff --git a/build/devenv/services/executor.go b/build/devenv/services/executor.go index bb4366d0e..5272d18dc 100644 --- a/build/devenv/services/executor.go +++ b/build/devenv/services/executor.go @@ -184,7 +184,7 @@ func NewExecutor(in *ExecutorInput, blockchainOutputs []*ctfblockchain.Output) ( }, } - req.Mounts = append(req.Mounts, testcontainers.BindMount( + req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier configFilePath, executor.DefaultConfigFile, )) diff --git a/build/devenv/services/executor/base.go b/build/devenv/services/executor/base.go index c39ed46f3..0be2a39e8 100644 --- a/build/devenv/services/executor/base.go +++ b/build/devenv/services/executor/base.go @@ -269,7 +269,7 @@ func NewStandalone(in *Input, blockchainOutputs []*ctfblockchain.Output) (*Outpu }, } - req.Mounts = append(req.Mounts, testcontainers.BindMount( + req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier configFilePath, executorpkg.DefaultConfigFile, )) @@ -495,7 +495,7 @@ func baseImageRequest(in *Input, envVars map[string]string, bootstrapConfigFileP } req.Mounts = testcontainers.Mounts() - req.Mounts = append(req.Mounts, testcontainers.BindMount( + req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier bootstrapConfigFilePath, bootstrap.DefaultConfigPath, )) diff --git a/build/devenv/services/tokenVerifier.go b/build/devenv/services/tokenVerifier.go index bb3884dcd..d5d697b35 100644 --- a/build/devenv/services/tokenVerifier.go +++ b/build/devenv/services/tokenVerifier.go @@ -156,7 +156,7 @@ func NewTokenVerifier(in *TokenVerifierInput, blockchainOutputs []*blockchain.Ou } req.Mounts = testcontainers.Mounts() - req.Mounts = append(req.Mounts, testcontainers.BindMount( + req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier configFilePath, aggregator.DefaultConfigFile, // TODO: switch to token verifier path, not aggregator path. )) From 6d6d57dddc77b161bd4f6b3b588b93f8534d864f Mon Sep 17 00:00:00 2001 From: Terry Tata Date: Wed, 22 Apr 2026 11:17:55 -0700 Subject: [PATCH 17/17] suppress --- .golangci.yaml | 4 ++++ build/devenv/services/committeeverifier/base.go | 2 +- build/devenv/services/common.go | 6 +++--- build/devenv/services/executor.go | 2 +- build/devenv/services/executor/base.go | 4 ++-- build/devenv/services/tokenVerifier.go | 2 +- 6 files changed, 12 insertions(+), 8 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 92a120933..b8da6867c 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -442,6 +442,10 @@ linters: - gocyclo - gosec - revive + - path: build/devenv + linters: + - staticcheck + text: "testcontainers.BindMount is deprecated" - path: 'pkg/handlers/validations\.go' linters: - gci diff --git a/build/devenv/services/committeeverifier/base.go b/build/devenv/services/committeeverifier/base.go index 54da697e6..4c5592523 100644 --- a/build/devenv/services/committeeverifier/base.go +++ b/build/devenv/services/committeeverifier/base.go @@ -405,7 +405,7 @@ func baseImageRequest(in *Input, envVars map[string]string, bootstrapConfigFileP } req.Mounts = testcontainers.Mounts() - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier + req.Mounts = append(req.Mounts, testcontainers.BindMount( bootstrapConfigFilePath, bootstrap.DefaultConfigPath, )) diff --git a/build/devenv/services/common.go b/build/devenv/services/common.go index c0022e562..004c71bc4 100644 --- a/build/devenv/services/common.go +++ b/build/devenv/services/common.go @@ -46,7 +46,7 @@ func GoSourcePathMounts(rootPath, containerDirTarget string) testcontainers.Cont mounts := make([]testcontainers.ContainerMount, 0, 1) mounts = append(mounts, - testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier + testcontainers.BindMount( absRootPath, testcontainers.ContainerMountTarget(containerDirTarget), ), @@ -79,11 +79,11 @@ func GoCacheMounts() testcontainers.ContainerMounts { goBuildCachePath = filepath.Join(homeDir, ".cache", "go-build") } mounts = append(mounts, - testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier + testcontainers.BindMount( goModCachePath, "/go/pkg/mod", ), - testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier + testcontainers.BindMount( goBuildCachePath, "/root/.cache/go-build", ), diff --git a/build/devenv/services/executor.go b/build/devenv/services/executor.go index 5272d18dc..bb4366d0e 100644 --- a/build/devenv/services/executor.go +++ b/build/devenv/services/executor.go @@ -184,7 +184,7 @@ func NewExecutor(in *ExecutorInput, blockchainOutputs []*ctfblockchain.Output) ( }, } - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier + req.Mounts = append(req.Mounts, testcontainers.BindMount( configFilePath, executor.DefaultConfigFile, )) diff --git a/build/devenv/services/executor/base.go b/build/devenv/services/executor/base.go index 0be2a39e8..c39ed46f3 100644 --- a/build/devenv/services/executor/base.go +++ b/build/devenv/services/executor/base.go @@ -269,7 +269,7 @@ func NewStandalone(in *Input, blockchainOutputs []*ctfblockchain.Output) (*Outpu }, } - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier + req.Mounts = append(req.Mounts, testcontainers.BindMount( configFilePath, executorpkg.DefaultConfigFile, )) @@ -495,7 +495,7 @@ func baseImageRequest(in *Input, envVars map[string]string, bootstrapConfigFileP } req.Mounts = testcontainers.Mounts() - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier + req.Mounts = append(req.Mounts, testcontainers.BindMount( bootstrapConfigFilePath, bootstrap.DefaultConfigPath, )) diff --git a/build/devenv/services/tokenVerifier.go b/build/devenv/services/tokenVerifier.go index d5d697b35..bb3884dcd 100644 --- a/build/devenv/services/tokenVerifier.go +++ b/build/devenv/services/tokenVerifier.go @@ -156,7 +156,7 @@ func NewTokenVerifier(in *TokenVerifierInput, blockchainOutputs []*blockchain.Ou } req.Mounts = testcontainers.Mounts() - req.Mounts = append(req.Mounts, testcontainers.BindMount( //nolint:staticcheck // TODO: migrate to Files/HostConfigModifier + req.Mounts = append(req.Mounts, testcontainers.BindMount( configFilePath, aggregator.DefaultConfigFile, // TODO: switch to token verifier path, not aggregator path. ))