From baf06c43e2b1de17429cee0a27399672941e206a Mon Sep 17 00:00:00 2001 From: "chainlink-release-pusher[bot]" <247132074+chainlink-release-pusher[bot]@users.noreply.github.com> Date: Tue, 29 Sep 2026 19:13:04 +0000 Subject: [PATCH 1/3] Bump version to v2.67.0 for next release cycle (#23860) * Bump version and update CHANGELOG for v2.67.0 (cherry picked from commit df15279b3ab71f1e86f5deed72647949e69d3d7f) * Add minor changeset for next release cycle --------- Co-authored-by: chainlink-releases-bot --- .changeset/clever-towns-tan.md | 5 ----- .changeset/flat-worms-teach.md | 5 ----- .changeset/gold-turtles-chew.md | 5 ----- ...bump-1790100824.md => minor-bump-1790705550.md} | 0 CHANGELOG.md | 14 ++++++++++++++ package.json | 2 +- 6 files changed, 15 insertions(+), 16 deletions(-) delete mode 100644 .changeset/clever-towns-tan.md delete mode 100644 .changeset/flat-worms-teach.md delete mode 100644 .changeset/gold-turtles-chew.md rename .changeset/{minor-bump-1790100824.md => minor-bump-1790705550.md} (100%) diff --git a/.changeset/clever-towns-tan.md b/.changeset/clever-towns-tan.md deleted file mode 100644 index 1f21b72f0f2..00000000000 --- a/.changeset/clever-towns-tan.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": patch ---- - -#updated observation cache TTL and bridge cache-fallback test coverage diff --git a/.changeset/flat-worms-teach.md b/.changeset/flat-worms-teach.md deleted file mode 100644 index a982cf507e0..00000000000 --- a/.changeset/flat-worms-teach.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -Added feature to the EVM BalanceMonitor to allow tracking balance of ERC-20 type fee tokens #added diff --git a/.changeset/gold-turtles-chew.md b/.changeset/gold-turtles-chew.md deleted file mode 100644 index 66f85c9d812..00000000000 --- a/.changeset/gold-turtles-chew.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"chainlink": minor ---- - -postgres: adding support for v18, removing support for v14 #nops diff --git a/.changeset/minor-bump-1790100824.md b/.changeset/minor-bump-1790705550.md similarity index 100% rename from .changeset/minor-bump-1790100824.md rename to .changeset/minor-bump-1790705550.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 4269f8935b1..207f2f22556 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,19 @@ # Changelog Chainlink Core +## 2.67.0 + +### Minor Changes + +- [#23854](https://github.com/smartcontractkit/chainlink/pull/23854) [`abf0837`](https://github.com/smartcontractkit/chainlink/commit/abf08375e7630761d012366e2522ca496657f294) - Added feature to the EVM BalanceMonitor to allow tracking balance of ERC-20 type fee tokens #added + +- [#23762](https://github.com/smartcontractkit/chainlink/pull/23762) [`5e84e21`](https://github.com/smartcontractkit/chainlink/commit/5e84e21688d668b32e858f945013677a35d6df28) - postgres: adding support for v18, removing support for v14 #nops + +- [#23799](https://github.com/smartcontractkit/chainlink/pull/23799) [`5a5156a`](https://github.com/smartcontractkit/chainlink/commit/5a5156a9230f06974e719aa5185515e8b445f6c5) - Minor bump to start next version + +### Patch Changes + +- [#23797](https://github.com/smartcontractkit/chainlink/pull/23797) [`e33d885`](https://github.com/smartcontractkit/chainlink/commit/e33d885589671852c40999501946b834b886313e) - #updated observation cache TTL and bridge cache-fallback test coverage + ## 2.66.0 ### Minor Changes diff --git a/package.json b/package.json index cefa619e680..3b6ad86e64e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chainlink", - "version": "2.66.0", + "version": "2.67.0", "description": "node of the decentralized oracle network, bridging on and off-chain computation", "main": "index.js", "scripts": { From 79f4327a1ed1083caa3434d0b1881cd0b305fb43 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Tue, 29 Sep 2026 19:17:54 +0000 Subject: [PATCH 2/3] Lint Roller 12: deployment (keystone), devenv (#23504) * lint(deployment): fix violations (part 2, devenv) * lint(deployment): drop redundant AddressBook nolints, fix ccipocr3 imports, remove dead tmplFS * lint: more fixes * lint: fix URI * lint: deprecated fix --- deployment/ccip/view/v1_6/ccip_home.go | 16 +- deployment/common/view/nops.go | 36 ++-- deployment/common/view/v1_0/capreg.go | 52 +++-- deployment/common/view/v2_0/capreg.go | 39 ++-- deployment/common/view/v2_0/capreg_test.go | 10 +- .../configure_capabilities_registry.go | 2 +- .../v2/changeset/set_dons_families_test.go | 3 +- deployment/cre/contracts/contracts_test.go | 1 - .../jobs/operations/propose_gateway_job.go | 17 +- deployment/cre/jobs/pkg/cre_settings_job.go | 2 +- deployment/cre/jobs/pkg/fs.go | 6 - deployment/cre/jobs/pkg/ocr3_bootstrap.tmpl | 12 -- deployment/cre/jobs/settings.go | 3 +- deployment/cre/ocr3/config.go | 14 +- deployment/cre/ocr3/config_test.go | 5 +- deployment/cre/ocr3/ocr3_1/config_dkg.go | 10 +- deployment/cre/ocr3/registry_config.go | 8 - deployment/cre/ocr3/types_test.go | 32 +-- .../changeset/register_nodes_with_jd_test.go | 83 ++++---- deployment/cre/test/env_setup.go | 2 +- deployment/data-feeds/offchain/jd.go | 37 ++-- deployment/environment.go | 7 +- deployment/environment/crib/ccip_deployer.go | 51 ++--- deployment/environment/crib/env.go | 8 +- deployment/environment/crib/types.go | 4 +- deployment/environment/devenv/chain.go | 7 +- deployment/environment/devenv/don.go | 14 +- deployment/environment/devenv/environment.go | 2 +- deployment/environment/devenv/fast-filler.go | 18 +- .../devenv/internal/kms/kms_client.go | 45 +++-- deployment/environment/devenv/jd.go | 2 +- deployment/environment/devenv/rmn.go | 183 +++++++++--------- .../environment/nodeclient/chainlink.go | 47 +++-- .../nodeclient/chainlink_models.go | 4 +- deployment/environment/test/jd.go | 39 ++-- .../environment/web/sdk/client/client.go | 2 +- .../environment/web/sdk/client/types.go | 4 +- .../environment/web/sdk/client/types_test.go | 8 +- deployment/helpers/build_solana.go | 3 +- .../internal/jdtestutils/client_test.go | 4 +- .../keystone/changeset/add_capabilities.go | 2 +- deployment/keystone/changeset/add_dons.go | 2 +- .../keystone/changeset/add_nodes_test.go | 10 +- .../changeset/deploy_balance_reader.go | 3 +- .../keystone/changeset/deploy_forwarder.go | 13 +- .../changeset/deploy_forwarder_test.go | 2 +- .../keystone/changeset/deploy_ocr3_test.go | 3 +- .../changeset/internal/addrbook/addrbook.go | 1 - .../changeset/internal/contract_set.go | 3 + .../keystone/changeset/internal/deploy.go | 57 ++---- .../keystone/changeset/internal/state_mcms.go | 2 + .../keystone/changeset/internal/types.go | 21 +- .../changeset/internal/update_nodes.go | 10 +- .../deploy_capability_registry_op.go | 2 +- .../deploy_configure_forwarders_seq.go | 5 +- .../contracts/deploy_workflow_registry_op.go | 2 +- deployment/keystone/changeset/state.go | 14 +- .../keystone/changeset/test/env_setup.go | 12 +- .../keystone/changeset/test/registry.go | 22 +-- .../update_node_capabilities_test.go | 2 +- deployment/keystone/changeset/view_test.go | 14 +- .../workflowregistry/update_allowed_dons.go | 2 +- .../update_allowed_dons_test.go | 3 +- .../update_authorized_addresses.go | 2 +- .../update_authorized_addresses_test.go | 3 +- .../workflow_registry_deployer.go | 3 + deployment/keystone/scripts/main.go | 2 +- .../test/changeset/capability_registry.go | 6 +- .../changesets/deploy_evm_link_tokens.go | 2 +- .../changesets/deploy_sol_link_tokens.go | 2 +- deployment/utils/nodetestutils/node.go | 11 +- .../automation_receiver_set_call_allowed.go | 8 +- ...receiver_set_expected_workflow_identity.go | 12 +- .../changeset/ethbalmon_accept_ownership.go | 8 +- .../vault/changeset/ethbalmon_deploy.go | 11 +- .../ethbalmon_set_keeper_registry_address.go | 8 +- .../changeset/ethbalmon_set_watchlist.go | 9 +- .../changeset/ethbalmon_transfer_ownership.go | 9 +- .../vault/changeset/ethbalmon_withdraw.go | 9 +- system-tests/lib/cre/don.go | 2 +- 80 files changed, 516 insertions(+), 640 deletions(-) delete mode 100644 deployment/cre/jobs/pkg/fs.go delete mode 100644 deployment/cre/jobs/pkg/ocr3_bootstrap.tmpl diff --git a/deployment/ccip/view/v1_6/ccip_home.go b/deployment/ccip/view/v1_6/ccip_home.go index e4215038f24..f69d5b32ebb 100644 --- a/deployment/ccip/view/v1_6/ccip_home.go +++ b/deployment/ccip/view/v1_6/ccip_home.go @@ -16,7 +16,7 @@ import ( capabilities_registry "github.com/smartcontractkit/chainlink-evm/gethwrappers/keystone/generated/capabilities_registry_1_1_0" "github.com/smartcontractkit/chainlink-common/keystore/corekeys/p2pkey" - ccipocr3common "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink/deployment/ccip/shared" "github.com/smartcontractkit/chainlink/deployment/internal/view" @@ -201,12 +201,12 @@ func toCCIPHomeVersionedConfig(cfg ccip_home.CCIPHomeVersionedConfig, pluginType peerID := p2pkey.PeerID(n.P2pId) nodes = append(nodes, CCIPHomeOCR3Node{ P2pID: peerID.String(), - SignerKey: ccipocr3common.UnknownAddress(n.SignerKey).String(), - TransmitterKey: ccipocr3common.UnknownAddress(n.TransmitterKey).String(), + SignerKey: ccipocr3.UnknownAddress(n.SignerKey).String(), + TransmitterKey: ccipocr3.UnknownAddress(n.TransmitterKey).String(), }) } - offRampAddr := ccipocr3common.UnknownAddress(cfg.Config.OfframpAddress).String() - rmnAddr := ccipocr3common.UnknownAddress(cfg.Config.RmnHomeAddress).String() + offRampAddr := ccipocr3.UnknownAddress(cfg.Config.OfframpAddress).String() + rmnAddr := ccipocr3.UnknownAddress(cfg.Config.RmnHomeAddress).String() c := CCIPHomeVersionedConfig{ Version: cfg.Version, ConfigDigest: cfg.ConfigDigest[:], @@ -238,10 +238,10 @@ func populateDecodedOCRParams(config *CCIPHomeOCR3Config, ccipHomeCfg ccip_home. identities := make([]OracleIdentity, 0, len(publicConfig.OracleIdentities)) for _, o := range publicConfig.OracleIdentities { identities = append(identities, OracleIdentity{ - OffchainPublicKey: ccipocr3common.UnknownAddress(o.OffchainPublicKey[:]).String(), - OnchainPublicKey: ccipocr3common.UnknownAddress(o.OnchainPublicKey[:]).String(), + OffchainPublicKey: ccipocr3.UnknownAddress(o.OffchainPublicKey[:]).String(), + OnchainPublicKey: ccipocr3.UnknownAddress(o.OnchainPublicKey[:]).String(), PeerID: o.PeerID, - TransmitAccount: ccipocr3common.UnknownAddress(o.TransmitAccount[:]).String(), + TransmitAccount: ccipocr3.UnknownAddress(o.TransmitAccount[:]).String(), }) } if pluginType == cciptypes.PluginTypeCCIPCommit { diff --git a/deployment/common/view/nops.go b/deployment/common/view/nops.go index 18c3fa83489..edc5c018b7b 100644 --- a/deployment/common/view/nops.go +++ b/deployment/common/view/nops.go @@ -221,24 +221,22 @@ func GenerateNOPsViewV2(ctx context.Context, lggr logger.Logger, nodeIDs []strin } fullNodeInfo := NopNodeInfoV2{ - NopView: NopView{ - NodeID: node.NodeID, - PeerID: node.PeerID.String(), - IsBootstrap: node.IsBootstrap, - OCRKeys: make(map[string]OCRKeyView), - PayeeAddress: node.AdminAddr, - CSAKey: nodeDetails.PublicKey, - WorkflowKey: nodeDetails.GetWorkflowKey(), - IsConnected: nodeDetails.IsConnected, - IsEnabled: nodeDetails.IsEnabled, - Version: nodeDetails.Version, - Labels: labels, - ApprovedJobspecs: jobspecs[node.NodeID], - ProposedJobspecs: proposedSpecs[node.NodeID], - }, - NodeName: nodeName, - Deployment: deploymentKey, - Networks: networks, + NodeID: node.NodeID, + PeerID: node.PeerID.String(), + IsBootstrap: node.IsBootstrap, + OCRKeys: make(map[string]OCRKeyView), + PayeeAddress: node.AdminAddr, + CSAKey: nodeDetails.PublicKey, + WorkflowKey: nodeDetails.GetWorkflowKey(), + IsConnected: nodeDetails.IsConnected, + IsEnabled: nodeDetails.IsEnabled, + Version: nodeDetails.Version, + Labels: labels, + ApprovedJobspecs: jobspecs[node.NodeID], + ProposedJobspecs: proposedSpecs[node.NodeID], + NodeName: nodeName, + Deployment: deploymentKey, + Networks: networks, } for details, ocrConfig := range node.SelToOCRConfig { fullNodeInfo.OCRKeys[details.ChainName] = OCRKeyView{ @@ -294,7 +292,7 @@ func defaultNopNameRemapper(nodeName, deploymentKey string) string { return nopName } -func ApprovedJobspecs(ctx context.Context, lggr logger.Logger, nodeIDs []string, oc cldf_offchain.Client) (nodeJobsView map[string]map[string]JobView, proposedJobsView map[string]map[string]JobView, verr error) { +func ApprovedJobspecs(ctx context.Context, lggr logger.Logger, nodeIDs []string, oc cldf_offchain.Client) (nodeJobsView, proposedJobsView map[string]map[string]JobView, verr error) { nodeJobsView = make(map[string]map[string]JobView) proposedJobsView = make(map[string]map[string]JobView) diff --git a/deployment/common/view/v1_0/capreg.go b/deployment/common/view/v1_0/capreg.go index 92a18d075f8..96e2270e100 100644 --- a/deployment/common/view/v1_0/capreg.go +++ b/deployment/common/view/v1_0/capreg.go @@ -192,7 +192,7 @@ func (v *CapabilityRegistryView) NodesToNodesParams() ([]capabilities_registry.C } nodesParams = append(nodesParams, capabilities_registry.CapabilitiesRegistryNodeParams{ Signer: signer, - P2pId: node.P2pId, + P2pId: node.P2pID, EncryptionPublicKey: encryptionPubKey, NodeOperatorId: node.NodeOperatorID, HashedCapabilityIds: capIDs, @@ -310,14 +310,12 @@ type DonUniversalMetadata struct { // NewDonView creates a DonView from a CapabilitiesRegistryDONInfo. func NewDonView(d capabilities_registry.CapabilitiesRegistryDONInfo) DonView { return DonView{ - DonUniversalMetadata: DonUniversalMetadata{ - ID: d.Id, - ConfigCount: d.ConfigCount, - F: d.F, - IsPublic: d.IsPublic, - AcceptsWorkflows: d.AcceptsWorkflows, - }, - NodeP2PIds: p2pIds(d.NodeP2PIds), + ID: d.Id, + ConfigCount: d.ConfigCount, + F: d.F, + IsPublic: d.IsPublic, + AcceptsWorkflows: d.AcceptsWorkflows, + NodeP2PIds: p2pIDs(d.NodeP2PIds), CapabilityConfigurations: NewCapabilityConfigurations(d.CapabilityConfigurations), } } @@ -377,23 +375,21 @@ type NodeUniversalMetadata struct { ConfigCount uint32 `json:"config_count"` WorkflowDONID uint32 `json:"workflow_don_id"` Signer string `json:"signer"` // hex 32 bytes - P2pId p2pkey.PeerID `json:"p2p_id"` + P2pID p2pkey.PeerID `json:"p2p_id"` EncryptionPublicKey string `json:"encryption_public_key"` // hex 32 bytes } // NewNodeView creates a NodeView from a CapabilitiesRegistryNodeInfoProviderNodeInfo. func NewNodeView(n capabilities_registry.INodeInfoProviderNodeInfo) NodeView { return NodeView{ - NodeUniversalMetadata: NodeUniversalMetadata{ - ConfigCount: n.ConfigCount, - WorkflowDONID: n.WorkflowDONId, - Signer: hex.EncodeToString(n.Signer[:]), - P2pId: n.P2pId, - EncryptionPublicKey: hex.EncodeToString(n.EncryptionPublicKey[:]), - }, - NodeOperatorID: n.NodeOperatorId, - CapabilityIDs: hexIds(n.HashedCapabilityIds), - CapabilityDONIDs: n.CapabilitiesDONIds, + ConfigCount: n.ConfigCount, + WorkflowDONID: n.WorkflowDONId, + Signer: hex.EncodeToString(n.Signer[:]), + P2pID: n.P2pId, + EncryptionPublicKey: hex.EncodeToString(n.EncryptionPublicKey[:]), + NodeOperatorID: n.NodeOperatorId, + CapabilityIDs: hexIDs(n.HashedCapabilityIds), + CapabilityDONIDs: n.CapabilitiesDONIds, } } @@ -466,15 +462,15 @@ func nodeNop(n NodeView, nops []NopView) (NopView, error) { return NopView{}, fmt.Errorf("could not find nop for node %d", n.NodeOperatorID) } -func p2pIds(rawIds [][32]byte) []p2pkey.PeerID { +func p2pIDs(rawIDs [][32]byte) []p2pkey.PeerID { var out []p2pkey.PeerID - for _, id := range rawIds { + for _, id := range rawIDs { out = append(out, p2pkey.PeerID(id)) } return out } -func hexIds(ids [][32]byte) []string { +func hexIDs(ids [][32]byte) []string { var out []string for _, id := range ids { out = append(out, hex.EncodeToString(id[:])) @@ -482,11 +478,11 @@ func hexIds(ids [][32]byte) []string { return out } -func (v DonView) hasNode(node NodeView) bool { - donId := big.NewInt(int64(v.ID)) - return slices.ContainsFunc(node.CapabilityDONIDs, func(elem *big.Int) bool { return elem.Cmp(donId) == 0 }) || node.WorkflowDONID == v.ID +func (dv DonView) hasNode(node NodeView) bool { + donID := big.NewInt(int64(dv.ID)) + return slices.ContainsFunc(node.CapabilityDONIDs, func(elem *big.Int) bool { return elem.Cmp(donID) == 0 }) || node.WorkflowDONID == dv.ID } -func (v DonView) hasCapability(candidate CapabilityView) bool { - return slices.ContainsFunc(v.CapabilityConfigurations, func(elem CapabilitiesConfiguration) bool { return elem.ID == candidate.ID }) +func (dv DonView) hasCapability(candidate CapabilityView) bool { + return slices.ContainsFunc(dv.CapabilityConfigurations, func(elem CapabilitiesConfiguration) bool { return elem.ID == candidate.ID }) } diff --git a/deployment/common/view/v2_0/capreg.go b/deployment/common/view/v2_0/capreg.go index b8026dc2aa6..1aaeb4060d9 100644 --- a/deployment/common/view/v2_0/capreg.go +++ b/deployment/common/view/v2_0/capreg.go @@ -394,16 +394,14 @@ func NewDonView(d capabilities_registry.CapabilitiesRegistryDONInfo) (DonView, e return DonView{}, fmt.Errorf("failed to create capability configurations for don %d: %w", d.Id, err) } return DonView{ - DonUniversalMetadata: DonUniversalMetadata{ - ID: d.Id, - Name: d.Name, - ConfigCount: d.ConfigCount, - F: d.F, - IsPublic: d.IsPublic, - AcceptsWorkflows: d.AcceptsWorkflows, - DONFamilies: d.DonFamilies, - Config: donCfg, - }, + ID: d.Id, + Name: d.Name, + ConfigCount: d.ConfigCount, + F: d.F, + IsPublic: d.IsPublic, + AcceptsWorkflows: d.AcceptsWorkflows, + DONFamilies: d.DonFamilies, + Config: donCfg, NodeP2PIds: p2pIDs(d.NodeP2PIds), CapabilityConfigurations: capCgfs, }, nil @@ -579,23 +577,20 @@ type NodeUniversalMetadata struct { P2pID p2pkey.PeerID `json:"p2p_id"` CSAKey string `json:"csa_key"` // hex 32 bytes EncryptionPublicKey string `json:"encryption_public_key"` // hex 32 bytes - } // NewNodeView creates a NodeView from a CapabilitiesRegistryNodeInfoProviderNodeInfo. func NewNodeView(n capabilities_registry.INodeInfoProviderNodeInfo) NodeView { return NodeView{ - NodeUniversalMetadata: NodeUniversalMetadata{ - ConfigCount: n.ConfigCount, - WorkflowDONID: n.WorkflowDONId, - Signer: hex.EncodeToString(n.Signer[:]), - P2pID: n.P2pId, - EncryptionPublicKey: hex.EncodeToString(n.EncryptionPublicKey[:]), - CSAKey: hex.EncodeToString(n.CsaKey[:]), - }, - NodeOperatorID: n.NodeOperatorId, - CapabilityIDs: n.CapabilityIds, - CapabilityDONIDs: n.CapabilitiesDONIds, + ConfigCount: n.ConfigCount, + WorkflowDONID: n.WorkflowDONId, + Signer: hex.EncodeToString(n.Signer[:]), + P2pID: n.P2pId, + EncryptionPublicKey: hex.EncodeToString(n.EncryptionPublicKey[:]), + CSAKey: hex.EncodeToString(n.CsaKey[:]), + NodeOperatorID: n.NodeOperatorId, + CapabilityIDs: n.CapabilityIds, + CapabilityDONIDs: n.CapabilitiesDONIds, } } diff --git a/deployment/common/view/v2_0/capreg_test.go b/deployment/common/view/v2_0/capreg_test.go index b9cd88342d4..b6cf3d57ec2 100644 --- a/deployment/common/view/v2_0/capreg_test.go +++ b/deployment/common/view/v2_0/capreg_test.go @@ -256,12 +256,14 @@ func assertTest(t *testing.T, f fields, want []v2_0.DonDenormalizedView, wantErr t.Errorf("CapRegView.Denormalize() error = %v, wantErr %v", err, wantErr) return } + require.Len(t, got, len(want)) for i := range got { - assert.Equal(t, want[i].Don, got[i].Don) + assert.Equal(t, want[i].Don, got[i].Don) //nolint:gosec // G602 - require.Len above guarantees len(want) == len(got) + require.Len(t, got[i].Nodes, len(want[i].Nodes)) //nolint:gosec // G602 - require.Len above guarantees len(want) == len(got) for j := range got[i].Nodes { - assert.Equal(t, want[i].Nodes[j].NodeUniversalMetadata, got[i].Nodes[j].NodeUniversalMetadata, "NodeUniversalMetadata mismatch at index %d for don %d", j, i) - assert.Equal(t, want[i].Nodes[j].Nop, got[i].Nodes[j].Nop, "Nop mismatch at index %d for don %d", j, i) + assert.Equal(t, want[i].Nodes[j].NodeUniversalMetadata, got[i].Nodes[j].NodeUniversalMetadata, "NodeUniversalMetadata mismatch at index %d for don %d", j, i) //nolint:gosec // G602 - require.Len above guarantees len(want[i].Nodes) == len(got[i].Nodes) + assert.Equal(t, want[i].Nodes[j].Nop, got[i].Nodes[j].Nop, "Nop mismatch at index %d for don %d", j, i) //nolint:gosec // G602 - require.Len above guarantees len(want[i].Nodes) == len(got[i].Nodes) } - assert.Equal(t, want[i].Capabilities, got[i].Capabilities) + assert.Equal(t, want[i].Capabilities, got[i].Capabilities) //nolint:gosec // G602 - require.Len above guarantees len(want) == len(got) } } diff --git a/deployment/cre/capabilities_registry/v2/changeset/configure_capabilities_registry.go b/deployment/cre/capabilities_registry/v2/changeset/configure_capabilities_registry.go index efe29478207..2aed23729e4 100644 --- a/deployment/cre/capabilities_registry/v2/changeset/configure_capabilities_registry.go +++ b/deployment/cre/capabilities_registry/v2/changeset/configure_capabilities_registry.go @@ -142,7 +142,7 @@ func (l ConfigureCapabilitiesRegistry) Apply(e cldf.Environment, config Configur sequences.ConfigureCapabilitiesRegistryInput{ RegistryChainSel: config.ChainSelector, MCMSConfig: config.MCMSConfig, - ContractAddress: contractAddr, + ContractAddress: contractAddr, //nolint:staticcheck // ContractAddress is deprecated in favor of RegistryRef RegistryRef: registryRef, Nops: nops, Capabilities: capabilities, diff --git a/deployment/cre/capabilities_registry/v2/changeset/set_dons_families_test.go b/deployment/cre/capabilities_registry/v2/changeset/set_dons_families_test.go index fa6b24448c7..116acd3f8af 100644 --- a/deployment/cre/capabilities_registry/v2/changeset/set_dons_families_test.go +++ b/deployment/cre/capabilities_registry/v2/changeset/set_dons_families_test.go @@ -7,9 +7,10 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + mcmstypes "github.com/smartcontractkit/mcms/types" + "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/runtime" capabilities_registry_v2 "github.com/smartcontractkit/chainlink-evm/gethwrappers/workflow/generated/capabilities_registry_wrapper_v2" - mcmstypes "github.com/smartcontractkit/mcms/types" "github.com/smartcontractkit/chainlink-common/keystore/corekeys/p2pkey" "github.com/smartcontractkit/chainlink/deployment/common/view/v2_0" diff --git a/deployment/cre/contracts/contracts_test.go b/deployment/cre/contracts/contracts_test.go index f6799b39353..f58dc4057b5 100644 --- a/deployment/cre/contracts/contracts_test.go +++ b/deployment/cre/contracts/contracts_test.go @@ -80,7 +80,6 @@ func TestGetOwnableContractV2(t *testing.T) { targetAddrStr := targetAddr.String() nonExistentAddr := testutils.NewAddress() nonExistentAddrStr := nonExistentAddr.String() - v1 := semver.MustParse("1.1.0") // Create an address ref for existing address addrRef := datastore.AddressRef{ diff --git a/deployment/cre/jobs/operations/propose_gateway_job.go b/deployment/cre/jobs/operations/propose_gateway_job.go index 2cb040243bc..8c03cd03826 100644 --- a/deployment/cre/jobs/operations/propose_gateway_job.go +++ b/deployment/cre/jobs/operations/propose_gateway_job.go @@ -68,24 +68,21 @@ var ProposeGatewayJob = operations.NewOperation[ProposeGatewayJobInput, ProposeG ) // proposeGatewayJob builds a gateway job spec and then proposes it to the nodes of a DON. -// When ServiceCentricFormatEnabled is true, it derives the set of unique DON names from -// input.Services; otherwise it uses the don-centric input.DONs list. +// It requires ServiceCentricFormatEnabled to be true and derives the set of unique DON +// names from input.Services; the legacy don-centric input.DONs format is no longer supported. func proposeGatewayJob(b operations.Bundle, deps ProposeGatewayJobDeps, input ProposeGatewayJobInput) (ProposeGatewayJobOutput, error) { requestTimeoutSec := int(input.GatewayRequestTimeoutSec) if requestTimeoutSec == 0 { requestTimeoutSec = defaultGatewayRequestTimeoutSec } - var gj pkg.GatewayJob - if input.ServiceCentricFormatEnabled { - built, err := buildServiceCentricJob(deps, input, requestTimeoutSec) - if err != nil { - return ProposeGatewayJobOutput{}, err - } - gj = built - } else { + if !input.ServiceCentricFormatEnabled { return ProposeGatewayJobOutput{}, errors.New("ServiceCentricFormatEnabled has to be true - legacy format is no longer supported") } + gj, err := buildServiceCentricJob(deps, input, requestTimeoutSec) + if err != nil { + return ProposeGatewayJobOutput{}, err + } if err := gj.Validate(); err != nil { return ProposeGatewayJobOutput{}, err diff --git a/deployment/cre/jobs/pkg/cre_settings_job.go b/deployment/cre/jobs/pkg/cre_settings_job.go index cfbde12f724..bfe819ea90f 100644 --- a/deployment/cre/jobs/pkg/cre_settings_job.go +++ b/deployment/cre/jobs/pkg/cre_settings_job.go @@ -13,7 +13,7 @@ import ( const ( templateName = "cre-settings.tmpl" // We expect there to only be 1 CRESettings job per node, and they share a fixed UUID for clarity. - externalJobUUID = "8561c20c-7d06-421e-a155-3baf21b1622b" + externalJobUUID = "8561c20c-7d06-421e-a155-3baf21b1622b" shardAssignmentJobUUID = "a3f8c1d2-4e5b-6a7c-8d9e-0f1a2b3c4d5e" ) diff --git a/deployment/cre/jobs/pkg/fs.go b/deployment/cre/jobs/pkg/fs.go deleted file mode 100644 index 0e308a53364..00000000000 --- a/deployment/cre/jobs/pkg/fs.go +++ /dev/null @@ -1,6 +0,0 @@ -package pkg - -import "embed" - -//go:embed *tmpl -var tmplFS embed.FS diff --git a/deployment/cre/jobs/pkg/ocr3_bootstrap.tmpl b/deployment/cre/jobs/pkg/ocr3_bootstrap.tmpl deleted file mode 100644 index 8f9cbdba9a7..00000000000 --- a/deployment/cre/jobs/pkg/ocr3_bootstrap.tmpl +++ /dev/null @@ -1,12 +0,0 @@ -type = "bootstrap" -schemaVersion = 1 -name = "{{ .JobName }}" -externalJobID = "{{ .ExternalJobID }}" -contractID = "{{ .ContractID }}" -contractConfigTrackerPollInterval = "1s" -contractConfigConfirmations = 1 -relay = "evm" - -[relayConfig] -chainID = {{ .ChainID }} -providerType = "ocr3-capability" diff --git a/deployment/cre/jobs/settings.go b/deployment/cre/jobs/settings.go index e23cfd4b424..944f47338b3 100644 --- a/deployment/cre/jobs/settings.go +++ b/deployment/cre/jobs/settings.go @@ -90,8 +90,7 @@ func ensureSchema(tree toml.Tree) (errs error) { } schema := cresettings.Default // copy if err := toml2.NewDecoder(strings.NewReader(string(b))).DisallowUnknownFields().Decode(&schema); err != nil { - var missingErr *toml2.StrictMissingError - if errors.As(err, &missingErr) { + if missingErr, ok := errors.AsType[*toml2.StrictMissingError](err); ok { return fmt.Errorf("unknown fields - if these are new fields, then chainlink-common must be updated:\n%s", missingErr.String()) } return fmt.Errorf("invalid toml settings: %w", err) diff --git a/deployment/cre/ocr3/config.go b/deployment/cre/ocr3/config.go index 99fe7e0c07a..9f043bb0ca4 100644 --- a/deployment/cre/ocr3/config.go +++ b/deployment/cre/ocr3/config.go @@ -32,9 +32,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/ocrcommon" ) -var ( - OCR3Capability cldf.ContractType = "OCR3Capability" // https://github.com/smartcontractkit/chainlink/blob/50c1b3dbf31bd145b312739b08967600a5c67f30/contracts/src/v0.8/keystone/OCR3Capability.sol#L12 -) +var OCR3Capability cldf.ContractType = "OCR3Capability" // https://github.com/smartcontractkit/chainlink/blob/50c1b3dbf31bd145b312739b08967600a5c67f30/contracts/src/v0.8/keystone/OCR3Capability.sol#L12 type TopLevelConfigSource struct { OracleConfig OracleConfig @@ -537,12 +535,10 @@ func MakeIdentities(nca []NodeKeys) ([]confighelper.OracleIdentityExtra, error) identities := []confighelper.OracleIdentityExtra{} for index := range nca { identities = append(identities, confighelper.OracleIdentityExtra{ - OracleIdentity: confighelper.OracleIdentity{ - OnchainPublicKey: onchainPubKeys[index], - OffchainPublicKey: offchainPubKeysBytes[index], - PeerID: nca[index].P2PPeerID, - TransmitAccount: types.Account(nca[index].EthAddress), - }, + OnchainPublicKey: onchainPubKeys[index], + OffchainPublicKey: offchainPubKeysBytes[index], + PeerID: nca[index].P2PPeerID, + TransmitAccount: types.Account(nca[index].EthAddress), ConfigEncryptionPublicKey: configPubKeysBytes[index], }) } diff --git a/deployment/cre/ocr3/config_test.go b/deployment/cre/ocr3/config_test.go index 1e759e6eca0..fea3e0eb112 100644 --- a/deployment/cre/ocr3/config_test.go +++ b/deployment/cre/ocr3/config_test.go @@ -12,7 +12,6 @@ import ( chain_selectors "github.com/smartcontractkit/chain-selectors" types2 "github.com/smartcontractkit/libocr/offchainreporting2/types" "github.com/smartcontractkit/libocr/offchainreporting2plus/types" - types3 "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/keystore/corekeys" @@ -202,10 +201,10 @@ func loadTestData(t *testing.T, path string) []deployment.Node { copy(opk[:], b) b = common.Hex2Bytes(ocrKey.ConfigEncryptionPublicKey) - var cpk types3.ConfigEncryptionPublicKey + var cpk types.ConfigEncryptionPublicKey copy(cpk[:], b) - var pubkey types3.OnchainPublicKey + var pubkey types.OnchainPublicKey if strings.HasPrefix(chain, "ethereum") { // convert from pubkey to address pubkey = common.HexToAddress(ocrKey.OnchainPublicKey).Bytes() diff --git a/deployment/cre/ocr3/ocr3_1/config_dkg.go b/deployment/cre/ocr3/ocr3_1/config_dkg.go index 8dd66e6519b..97dde10421b 100644 --- a/deployment/cre/ocr3/ocr3_1/config_dkg.go +++ b/deployment/cre/ocr3/ocr3_1/config_dkg.go @@ -105,12 +105,10 @@ func GenerateDKGConfig(cfg V3_1OracleConfig, nca []ocr3.NodeKeys, secrets ocr.OC identities := make([]confighelper.OracleIdentityExtra, 0, len(nca)) for i := range nca { identities = append(identities, confighelper.OracleIdentityExtra{ - OracleIdentity: confighelper.OracleIdentity{ - OnchainPublicKey: onchainKeys[i], - OffchainPublicKey: offchainPubKeysBytes[i], - PeerID: nca[i].P2PPeerID, - TransmitAccount: transmitAccounts[i], - }, + OnchainPublicKey: onchainKeys[i], + OffchainPublicKey: offchainPubKeysBytes[i], + PeerID: nca[i].P2PPeerID, + TransmitAccount: transmitAccounts[i], ConfigEncryptionPublicKey: configPubKeysBytes[i], }) } diff --git a/deployment/cre/ocr3/registry_config.go b/deployment/cre/ocr3/registry_config.go index 5f3a112619c..6356cc5c58f 100644 --- a/deployment/cre/ocr3/registry_config.go +++ b/deployment/cre/ocr3/registry_config.go @@ -91,14 +91,6 @@ func ValidateOCR3Config(signers [][]byte, transmitters [][]byte, f uint32) error return nil } -// ocr3ConfigsJSON is a helper struct for parsing the ocr3Configs field from -// a CapabilityConfig protobuf via JSON roundtrip. -type ocr3ConfigsJSON struct { - Ocr3Configs map[string]struct { - ConfigCount uint64 `json:"configCount"` - } `json:"ocr3Configs"` -} - // GetCurrentOCR3ConfigCount reads the current OCR3 config count for a // capability/DON from the on-chain registry. Returns 0 if no config exists. func GetCurrentOCR3ConfigCount( diff --git a/deployment/cre/ocr3/types_test.go b/deployment/cre/ocr3/types_test.go index 0da30b027f0..1f8e6d39d26 100644 --- a/deployment/cre/ocr3/types_test.go +++ b/deployment/cre/ocr3/types_test.go @@ -36,47 +36,47 @@ func Test_toNodeKeys(t *testing.T) { } p2pID := p2pkey.MustNewV2XXXTestingOnly(big.NewInt(100)) - pubKey_1 := "11114981a6119ca3f932cdb8c402d71a72d672adae7849f581ecff8b8e1098e7" // valid csa key - signing_1 := common.Hex2Bytes("11117293a4Cc2621b61193135a95928735e4795f") // valid eth address - admin_1 := common.HexToAddress("0x1111567890123456789012345678901234567890") // valid eth address - signing_2 := common.Hex2Bytes("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") // valid key + pubKey1 := "11114981a6119ca3f932cdb8c402d71a72d672adae7849f581ecff8b8e1098e7" // valid csa key + signing1 := common.Hex2Bytes("11117293a4Cc2621b61193135a95928735e4795f") // valid eth address + admin1 := common.HexToAddress("0x1111567890123456789012345678901234567890") // valid eth address + signing2 := common.Hex2Bytes("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee") // valid key var encryptionpubkey [32]byte - if _, err := hex.Decode(encryptionpubkey[:], []byte(pubKey_1)); err != nil { + if _, err := hex.Decode(encryptionpubkey[:], []byte(pubKey1)); err != nil { panic(fmt.Sprintf("failed to decode pubkey %s: %v", encryptionpubkey, err)) } keys := toNodeKeys(&deployment.Node{ NodeID: "p2p_123", Name: "node 1", PeerID: p2pID.PeerID(), - CSAKey: pubKey_1, - AdminAddr: admin_1.String(), + CSAKey: pubKey1, + AdminAddr: admin1.String(), SelToOCRConfig: map[chainsel.ChainDetails]deployment.OCRConfig{ registryChainDetails: { OffchainPublicKey: types.OffchainPublicKey(common.FromHex("1111111111111111111111111111111111111111111111111111111111111111")), - OnchainPublicKey: signing_1, + OnchainPublicKey: signing1, PeerID: p2pID.PeerID(), - TransmitAccount: types.Account(admin_1.String()), + TransmitAccount: types.Account(admin1.String()), ConfigEncryptionPublicKey: encryptionpubkey, KeyBundleID: "abcd", }, aptosChainDetails: { TransmitAccount: "ff", - OnchainPublicKey: signing_2, + OnchainPublicKey: signing2, KeyBundleID: "aptos", }, }, }, registryChainSel.Selector, []string{chainsel.FamilyAptos}) require.Equal(t, NodeKeys{ - EthAddress: admin_1.String(), + EthAddress: admin1.String(), AptosBundleID: "aptos", - AptosOnchainPublicKey: hex.EncodeToString(signing_2), + AptosOnchainPublicKey: hex.EncodeToString(signing2), P2PPeerID: strings.TrimPrefix(p2pID.PeerID().String(), "p2p_"), OCR2BundleID: "abcd", - OCR2OnchainPublicKey: hex.EncodeToString(signing_1), + OCR2OnchainPublicKey: hex.EncodeToString(signing1), OCR2OffchainPublicKey: "1111111111111111111111111111111111111111111111111111111111111111", - OCR2ConfigPublicKey: pubKey_1, - CSAPublicKey: pubKey_1, - EncryptionPublicKey: pubKey_1, + OCR2ConfigPublicKey: pubKey1, + CSAPublicKey: pubKey1, + EncryptionPublicKey: pubKey1, }, keys) } diff --git a/deployment/cre/pkg/offchain/changeset/register_nodes_with_jd_test.go b/deployment/cre/pkg/offchain/changeset/register_nodes_with_jd_test.go index 24a7b922bdb..cd3c2560827 100644 --- a/deployment/cre/pkg/offchain/changeset/register_nodes_with_jd_test.go +++ b/deployment/cre/pkg/offchain/changeset/register_nodes_with_jd_test.go @@ -11,7 +11,6 @@ import ( "github.com/smartcontractkit/chainlink-deployments-framework/engine/test/runtime" cldf_offchain "github.com/smartcontractkit/chainlink-deployments-framework/offchain" - "github.com/smartcontractkit/chainlink-deployments-framework/offchain/node" nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" "github.com/smartcontractkit/chainlink/deployment/cre/pkg/offchain" @@ -39,20 +38,16 @@ func TestCsRegisterNodesWithJD_Apply(t *testing.T) { Name: test.DONName, Nodes: []offchain.NodeCfg{ { - MinimalNodeCfg: node.MinimalNodeCfg{ - Name: "node-1", - CSAKey: "fake-csa-key-1", - }, - P2PID: "fake-p2p-id", - Zone: zone, + Name: "node-1", + CSAKey: "fake-csa-key-1", + P2PID: "fake-p2p-id", + Zone: zone, }, { - MinimalNodeCfg: node.MinimalNodeCfg{ - Name: "node-2", - CSAKey: "fake-csa-key-2", - }, - P2PID: "fake-p2p-id", - Zone: zone, + Name: "node-2", + CSAKey: "fake-csa-key-2", + P2PID: "fake-p2p-id", + Zone: zone, }, }, }, @@ -108,11 +103,9 @@ func TestCsRegisterNodesWithJD_Apply(t *testing.T) { Name: test.DONName, Nodes: []offchain.NodeCfg{ { - MinimalNodeCfg: node.MinimalNodeCfg{ - Name: "register-node-error", // this name triggers the error in the test JD client - CSAKey: "register-node-error-key-1", - }, - Zone: zone, + Name: "register-node-error", // this name triggers the error in the test JD client + CSAKey: "register-node-error-key-1", + Zone: zone, }, }, }, @@ -164,24 +157,18 @@ func TestCsRegisterNodesWithJD_Apply(t *testing.T) { Name: test.DONName, Nodes: []offchain.NodeCfg{ { - MinimalNodeCfg: node.MinimalNodeCfg{ - Name: nodes[0].Name, - CSAKey: nodes[0].PublicKey, - }, - Zone: zone, + Name: nodes[0].Name, + CSAKey: nodes[0].PublicKey, + Zone: zone, }, { - MinimalNodeCfg: node.MinimalNodeCfg{ - Name: "register-node-error", // this name triggers the error in the test JD client - CSAKey: "test-csa-key-1", - }, + Name: "register-node-error", // this name triggers the error in the test JD client + CSAKey: "test-csa-key-1", }, { - MinimalNodeCfg: node.MinimalNodeCfg{ - Name: nodes[2].Name, - CSAKey: nodes[2].PublicKey, - }, - Zone: zone, + Name: nodes[2].Name, + CSAKey: nodes[2].PublicKey, + Zone: zone, }, }, }, @@ -287,11 +274,9 @@ func TestCsRegisterNodesWithJD_Apply(t *testing.T) { Name: test.DONName, Nodes: []offchain.NodeCfg{ { - MinimalNodeCfg: node.MinimalNodeCfg{ - Name: firstNode.Name, - CSAKey: firstNode.PublicKey, - }, - Zone: zone, + Name: firstNode.Name, + CSAKey: firstNode.PublicKey, + Zone: zone, }, }, }, @@ -376,11 +361,9 @@ func TestCsRegisterNodesWithJD_Apply(t *testing.T) { Name: test.DONName, Nodes: []offchain.NodeCfg{ { - MinimalNodeCfg: node.MinimalNodeCfg{ - Name: "update-node-error", // this name triggers the error in the test JD client - CSAKey: firstNode.PublicKey, - }, - Zone: zone, + Name: "update-node-error", // this name triggers the error in the test JD client + CSAKey: firstNode.PublicKey, + Zone: zone, }, }, }, @@ -416,12 +399,12 @@ func TestCsRegisterNodesWithJDV2_Apply(t *testing.T) { Name: test.DONName, Nodes: []offchain.NodeCfg{ { - MinimalNodeCfg: node.MinimalNodeCfg{Name: "node-1", CSAKey: "csa-key-1"}, - Zone: test.Zone, + Name: "node-1", CSAKey: "csa-key-1", + Zone: test.Zone, }, { - MinimalNodeCfg: node.MinimalNodeCfg{Name: "node-2", CSAKey: "csa-key-2"}, - Zone: test.Zone, + Name: "node-2", CSAKey: "csa-key-2", + Zone: test.Zone, }, }, }, @@ -475,8 +458,8 @@ func TestCsRegisterNodesWithJDV2_Apply(t *testing.T) { Name: "", Nodes: []offchain.NodeCfg{ { - MinimalNodeCfg: node.MinimalNodeCfg{Name: "node-1", CSAKey: "csa-key-1"}, - Zone: test.Zone, + Name: "node-1", CSAKey: "csa-key-1", + Zone: test.Zone, }, }, }, @@ -506,8 +489,8 @@ func TestCsRegisterNodesWithJDV2_Apply(t *testing.T) { Name: test.DONName, Nodes: []offchain.NodeCfg{ { - MinimalNodeCfg: node.MinimalNodeCfg{Name: nodes[0].Name, CSAKey: nodes[0].PublicKey}, - Zone: test.Zone, + Name: nodes[0].Name, CSAKey: nodes[0].PublicKey, + Zone: test.Zone, }, }, }, diff --git a/deployment/cre/test/env_setup.go b/deployment/cre/test/env_setup.go index ee88bf47931..60361a69311 100644 --- a/deployment/cre/test/env_setup.go +++ b/deployment/cre/test/env_setup.go @@ -225,7 +225,7 @@ func configureCapabilitiesRegistry(t *testing.T, h *Harness) { runtime.ChangesetTask(changeset2.ConfigureCapabilitiesRegistry{}, changeset2.ConfigureCapabilitiesRegistryInput{ ChainSelector: h.RegistrySelector, - CapabilitiesRegistryAddress: h.RegistryAddress.Hex(), + CapabilitiesRegistryAddress: h.RegistryAddress.Hex(), //nolint:staticcheck // CapabilitiesRegistryAddress is deprecated in favor of RegistryRef Nops: []changeset2.CapabilitiesRegistryNodeOperator{ { Name: "Operator 1", diff --git a/deployment/data-feeds/offchain/jd.go b/deployment/data-feeds/offchain/jd.go index aed67c51574..de4bcd04f1c 100644 --- a/deployment/data-feeds/offchain/jd.go +++ b/deployment/data-feeds/offchain/jd.go @@ -8,7 +8,6 @@ import ( jobv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/job" nodeapiv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/shared/ptypes" - jdtypesv1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/shared/ptypes" cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" @@ -28,48 +27,48 @@ type NodesFilter struct { const defaultZone = "zone-a" func (f *NodesFilter) filter() *nodeapiv1.ListNodesRequest_Filter { - selectors := []*jdtypesv1.Selector{ + selectors := []*ptypes.Selector{ { Key: "don_id", - Op: jdtypesv1.SelectorOp_EQ, + Op: ptypes.SelectorOp_EQ, Value: new(strconv.FormatUint(f.DONID, 10)), }, { Key: "environment", - Op: jdtypesv1.SelectorOp_EQ, + Op: ptypes.SelectorOp_EQ, Value: &f.EnvLabel, }, { Key: "product", - Op: jdtypesv1.SelectorOp_EQ, + Op: ptypes.SelectorOp_EQ, Value: &f.ProductLabel, }, } if f.IsBootstrap { - selectors = append(selectors, &jdtypesv1.Selector{ + selectors = append(selectors, &ptypes.Selector{ Key: devenv.LabelNodeTypeKey, - Op: jdtypesv1.SelectorOp_EQ, + Op: ptypes.SelectorOp_EQ, Value: new(devenv.LabelNodeTypeValueBootstrap), }) } else { - selectors = append(selectors, &jdtypesv1.Selector{ + selectors = append(selectors, &ptypes.Selector{ Key: devenv.LabelNodeTypeKey, - Op: jdtypesv1.SelectorOp_EQ, + Op: ptypes.SelectorOp_EQ, Value: new(devenv.LabelNodeTypeValuePlugin), }) } if f.Zone == defaultZone { // default zone nodes do not have a zone label - selectors = append(selectors, &jdtypesv1.Selector{ + selectors = append(selectors, &ptypes.Selector{ Key: "zone", - Op: jdtypesv1.SelectorOp_NOT_EXIST, + Op: ptypes.SelectorOp_NOT_EXIST, }) } else { - selectors = append(selectors, &jdtypesv1.Selector{ + selectors = append(selectors, &ptypes.Selector{ Key: "zone", - Op: jdtypesv1.SelectorOp_EQ, + Op: ptypes.SelectorOp_EQ, Value: &f.Zone, }) } @@ -173,25 +172,25 @@ func ProposeJobs(ctx context.Context, env cldf.Environment, workflowJobSpec stri func DeleteJobs(ctx context.Context, env cldf.Environment, jobIDs []string, workflowName string, environment string, zone string) { if len(jobIDs) == 0 { env.Logger.Debugf("jobIDs not present. Listing jobs to delete via workflow name") - jobSelectors := []*jdtypesv1.Selector{ + jobSelectors := []*ptypes.Selector{ { Key: "workflow_name", - Op: jdtypesv1.SelectorOp_EQ, + Op: ptypes.SelectorOp_EQ, Value: &workflowName, }, } if environment != "" { - jobSelectors = append(jobSelectors, &jdtypesv1.Selector{ + jobSelectors = append(jobSelectors, &ptypes.Selector{ Key: "environment", - Op: jdtypesv1.SelectorOp_EQ, + Op: ptypes.SelectorOp_EQ, Value: &environment, }) } if zone != "" { - jobSelectors = append(jobSelectors, &jdtypesv1.Selector{ + jobSelectors = append(jobSelectors, &ptypes.Selector{ Key: "zone", - Op: jdtypesv1.SelectorOp_EQ, + Op: ptypes.SelectorOp_EQ, Value: &zone, }) } diff --git a/deployment/environment.go b/deployment/environment.go index 6cde0abbd85..f31eef5cf0f 100644 --- a/deployment/environment.go +++ b/deployment/environment.go @@ -234,7 +234,8 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) { // if nodeIDs starts with `p2p_` lookup by p2p_id instead filterByPeerIDs := strings.HasPrefix(nodeIDs[0], "p2p_") var filter *nodev1.ListNodesRequest_Filter - if filterByPeerIDs { + switch { + case filterByPeerIDs: selector := strings.Join(nodeIDs, ",") filter = &nodev1.ListNodesRequest_Filter{ Enabled: 1, @@ -246,12 +247,12 @@ func NodeInfo(nodeIDs []string, oc NodeChainConfigsLister) (Nodes, error) { }, }, } - } else if strings.HasPrefix(nodeIDs[0], "node_") { + case strings.HasPrefix(nodeIDs[0], "node_"): filter = &nodev1.ListNodesRequest_Filter{ Enabled: 1, Ids: nodeIDs, } - } else { + default: filter = &nodev1.ListNodesRequest_Filter{ Enabled: 1, PublicKeys: nodeIDs, diff --git a/deployment/environment/crib/ccip_deployer.go b/deployment/environment/crib/ccip_deployer.go index c2c845baf8f..695fdada3cf 100644 --- a/deployment/environment/crib/ccip_deployer.go +++ b/deployment/environment/crib/ccip_deployer.go @@ -25,11 +25,10 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_6_0/rmn_home" "github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_6_0/rmn_remote" evm_fee_quoter "github.com/smartcontractkit/chainlink-ccip/chains/evm/gobindings/generated/v1_6_3/fee_quoter" - cciptypes "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" "github.com/smartcontractkit/chainlink-ccip/pluginconfig" "github.com/smartcontractkit/chainlink-common/keystore/corekeys/p2pkey" "github.com/smartcontractkit/chainlink-common/pkg/logger" - ccipocr3common "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" + "github.com/smartcontractkit/chainlink-common/pkg/types/ccipocr3" cldf_chain "github.com/smartcontractkit/chainlink-deployments-framework/chain" "github.com/smartcontractkit/chainlink-deployments-framework/datastore" cldf "github.com/smartcontractkit/chainlink-deployments-framework/deployment" @@ -301,8 +300,8 @@ func setupChains(lggr logger.Logger, e *cldf.Environment, homeChainSel, feedChai //nolint:gosec // this should always be less than max uint8 FChain: uint8(len(nodeInfo.NonBootstraps().PeerIDs()) / 3), EncodableChainConfig: chainconfig.ChainConfig{ - GasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(1000)}, - DAGasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(1_000_000)}, + GasPriceDeviationPPB: ccipocr3.BigInt{Int: big.NewInt(1000)}, + DAGasPriceDeviationPPB: ccipocr3.BigInt{Int: big.NewInt(1_000_000)}, OptimisticConfirmations: 1, }, } @@ -322,8 +321,8 @@ func setupChains(lggr logger.Logger, e *cldf.Environment, homeChainSel, feedChai // #nosec G115 - Overflow is not a concern in this test scenario FChain: uint8(len(nodeInfo.NonBootstraps().PeerIDs()) / 3), EncodableChainConfig: chainconfig.ChainConfig{ - GasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(testhelpers.DefaultGasPriceDeviationPPB)}, - DAGasPriceDeviationPPB: cciptypes.BigInt{Int: big.NewInt(testhelpers.DefaultDAGasPriceDeviationPPB)}, + GasPriceDeviationPPB: ccipocr3.BigInt{Int: big.NewInt(testhelpers.DefaultGasPriceDeviationPPB)}, + DAGasPriceDeviationPPB: ccipocr3.BigInt{Int: big.NewInt(testhelpers.DefaultDAGasPriceDeviationPPB)}, OptimisticConfirmations: globals.OptimisticConfirmations, }, } @@ -1013,10 +1012,10 @@ func mustOCR(e *cldf.Environment, homeChainSel, feedChainSel uint64, newDons, rm for _, selector := range solSelectors { // TODO: this is a workaround for tokenConfig.GetTokenInfo - tokenInfo := map[cciptypes.UnknownEncodedAddress]pluginconfig.TokenInfo{} - tokenInfo[cciptypes.UnknownEncodedAddress(state.SolChains[selector].LinkToken.String())] = tokenConfig.TokenSymbolToInfo[shared.LinkSymbol] + tokenInfo := map[ccipocr3.UnknownEncodedAddress]ccipocr3.TokenInfo{} + tokenInfo[ccipocr3.UnknownEncodedAddress(state.SolChains[selector].LinkToken.String())] = tokenConfig.TokenSymbolToInfo[shared.LinkSymbol] // TODO: point this to proper SOL feed, apparently 0 signified SOL - tokenInfo[ccipocr3common.UnknownEncodedAddress(solana.WrappedSol.String())] = tokenConfig.TokenSymbolToInfo[shared.WethSymbol] + tokenInfo[ccipocr3.UnknownEncodedAddress(solana.WrappedSol.String())] = tokenConfig.TokenSymbolToInfo[shared.WethSymbol] commitOCRConfigPerSelector[selector] = v1_6.DeriveOCRParamsForCommit(chainType, feedChainSel, tokenInfo, func(params v1_6.CCIPOCRParams) v1_6.CCIPOCRParams { params.OCRParameters.MaxDurationQuery = 100 * time.Millisecond @@ -1048,10 +1047,8 @@ func mustOCR(e *cldf.Environment, homeChainSel, feedChainSel uint64, newDons, rm // Add the DONs and candidate commit OCR instances for the chain cldf.CreateLegacyChangeSet(v1_6.AddDonAndSetCandidateChangeset), v1_6.AddDonAndSetCandidateChangesetConfig{ - SetCandidateConfigBase: v1_6.SetCandidateConfigBase{ - HomeChainSelector: homeChainSel, - FeedChainSelector: feedChainSel, - }, + HomeChainSelector: homeChainSel, + FeedChainSelector: feedChainSel, PluginInfo: v1_6.SetCandidatePluginInfo{ OCRConfigPerRemoteChainSelector: commitOCRConfigPerSelector, PluginType: types.PluginTypeCCIPCommit, @@ -1063,10 +1060,8 @@ func mustOCR(e *cldf.Environment, homeChainSel, feedChainSel uint64, newDons, rm // Update commit OCR instances for existing chains cldf.CreateLegacyChangeSet(v1_6.SetCandidateChangeset), v1_6.SetCandidateChangesetConfig{ - SetCandidateConfigBase: v1_6.SetCandidateConfigBase{ - HomeChainSelector: homeChainSel, - FeedChainSelector: feedChainSel, - }, + HomeChainSelector: homeChainSel, + FeedChainSelector: feedChainSel, PluginInfo: []v1_6.SetCandidatePluginInfo{ { OCRConfigPerRemoteChainSelector: commitOCRConfigPerSelector, @@ -1081,10 +1076,8 @@ func mustOCR(e *cldf.Environment, homeChainSel, feedChainSel uint64, newDons, rm // Add the exec OCR instances for the new chains cldf.CreateLegacyChangeSet(v1_6.SetCandidateChangeset), v1_6.SetCandidateChangesetConfig{ - SetCandidateConfigBase: v1_6.SetCandidateConfigBase{ - HomeChainSelector: homeChainSel, - FeedChainSelector: feedChainSel, - }, + HomeChainSelector: homeChainSel, + FeedChainSelector: feedChainSel, PluginInfo: []v1_6.SetCandidatePluginInfo{ { OCRConfigPerRemoteChainSelector: execOCRConfigPerSelector, @@ -1289,15 +1282,13 @@ func GenerateRMNNodeIdentities(rmnNodeCount uint, rageProxyImageURI, rageProxyIm } rmnNodeConfigs[i] = RMNNodeConfig{ - RMNNopConfig: v1_6.RMNNopConfig{ - NodeIndex: uint64(i), - OffchainPublicKey: [32]byte(keys.OffchainPublicKey), - EVMOnChainPublicKey: keys.EVMOnchainPublicKey, - PeerID: newPeerID, - }, - RageProxyKeystore: rawKeystore, - RMNKeystore: rawRMNKeystore, - Passphrase: afnPassphrase, + NodeIndex: uint64(i), + OffchainPublicKey: [32]byte(keys.OffchainPublicKey), + EVMOnChainPublicKey: keys.EVMOnchainPublicKey, + PeerID: newPeerID, + RageProxyKeystore: rawKeystore, + RMNKeystore: rawRMNKeystore, + Passphrase: afnPassphrase, } } return rmnNodeConfigs, nil diff --git a/deployment/environment/crib/env.go b/deployment/environment/crib/env.go index 64b5b873e6e..e5bdfa125b6 100644 --- a/deployment/environment/crib/env.go +++ b/deployment/environment/crib/env.go @@ -14,7 +14,7 @@ const ( RMNNodeIdentitiesFileName = "rmn-node-identities.json" ) -type CRIBEnv struct { +type Env struct { lggr logger.Logger cribEnvStateDirPath string } @@ -25,14 +25,14 @@ type DeployerKeys struct { AptosKey string } -func NewDevspaceEnvFromStateDir(lggr logger.Logger, envStateDir string) CRIBEnv { - return CRIBEnv{ +func NewDevspaceEnvFromStateDir(lggr logger.Logger, envStateDir string) Env { + return Env{ lggr: lggr, cribEnvStateDirPath: envStateDir, } } -func (c CRIBEnv) GetConfig(deployerKeys DeployerKeys) (DeployOutput, error) { +func (c Env) GetConfig(deployerKeys DeployerKeys) (DeployOutput, error) { reader := NewOutputReader(c.cribEnvStateDirPath) nodesDetails, err := reader.ReadNodesDetails() if err != nil { diff --git a/deployment/environment/crib/types.go b/deployment/environment/crib/types.go index e58614ada02..5f8fbd0b346 100644 --- a/deployment/environment/crib/types.go +++ b/deployment/environment/crib/types.go @@ -12,7 +12,7 @@ import ( ) const ( - CRIB_ENV_NAME = "Crib Environment" + CribEnvName = "Crib Environment" ) type DeployOutput struct { @@ -33,7 +33,7 @@ func NewDeployEnvironmentFromCribOutput(ctx context.Context, lggr logger.Logger, } return cldf.NewEnvironment( - CRIB_ENV_NAME, + CribEnvName, lggr, output.AddressBook, datastore.NewMemoryDataStore().Seal(), diff --git a/deployment/environment/devenv/chain.go b/deployment/environment/devenv/chain.go index e5e64c990b9..bad7afa395d 100644 --- a/deployment/environment/devenv/chain.go +++ b/deployment/environment/devenv/chain.go @@ -77,9 +77,8 @@ func (c *ChainConfig) SetUsers(pvtkeys []string) error { if c.DeployerKey != nil { c.Users = []*bind.TransactOpts{c.DeployerKey} return nil - } else { - return errors.New("no private keys provided for users, deployer key is also not set") } + return errors.New("no private keys provided for users, deployer key is also not set") } for _, pvtKeyStr := range pvtkeys { pvtKey, err := crypto.HexToECDSA(pvtKeyStr) @@ -118,7 +117,7 @@ func (c *ChainConfig) SetDeployerKey(pvtKeyStr *string) error { c.DeployerKey = deployer return nil } - kmsConfig, err := kms.KMSConfigFromEnvVars() + kmsConfig, err := kms.ConfigFromEnvVars() if err != nil { return fmt.Errorf("failed to get kms config from env vars: %w", err) } @@ -126,7 +125,7 @@ func (c *ChainConfig) SetDeployerKey(pvtKeyStr *string) error { if err != nil { return fmt.Errorf("failed to create KMS client: %w", err) } - evmKMSClient := kms.NewEVMKMSClient(kmsClient, kmsConfig.KmsDeployerKeyId) + evmKMSClient := kms.NewEVMKMSClient(kmsClient, kmsConfig.KmsDeployerKeyID) chainID, success := new(big.Int).SetString(c.ChainID, 10) if !success { return fmt.Errorf("invalid chainID %s", c.ChainID) diff --git a/deployment/environment/devenv/don.go b/deployment/environment/devenv/don.go index 1cc5bc8e805..08497eba9b0 100644 --- a/deployment/environment/devenv/don.go +++ b/deployment/environment/devenv/don.go @@ -92,12 +92,12 @@ func (don *DON) ReplayAllLogs(blockbyChain map[uint64]uint64) error { return nil } -func (don *DON) NodeIds() []string { - var nodeIds []string +func (don *DON) NodeIDs() []string { + var nodeIDs []string for _, node := range don.Nodes { - nodeIds = append(nodeIds, node.NodeID) + nodeIDs = append(nodeIDs, node.NodeID) } - return nodeIds + return nodeIDs } func (don *DON) CreateSupportedChains(ctx context.Context, chains []ChainConfig, jd JobDistributor) error { @@ -505,7 +505,7 @@ func (n *Node) CreateJobDistributor(ctx context.Context, jd JobDistributor) (str } return n.gqlClient.CreateJobDistributor(ctx, client.JobDistributorInput{ Name: "Job Distributor", - Uri: jd.WSRPC, + URI: jd.WSRPC, PublicKey: csaKey, }) } @@ -547,8 +547,8 @@ func (n *Node) SetUpAndLinkJobDistributor(ctx context.Context, jd JobDistributor return nil } -func (n *Node) ExportEVMKeysForChain(chainId string) ([]*clclient.ExportedEVMKey, error) { - return n.restClient.ExportEVMKeysForChain(chainId) +func (n *Node) ExportEVMKeysForChain(chainID string) ([]*clclient.ExportedEVMKey, error) { + return n.restClient.ExportEVMKeysForChain(chainID) } // ReplayLogs replays logs for the chains on the node for given block numbers for each chain diff --git a/deployment/environment/devenv/environment.go b/deployment/environment/devenv/environment.go index c41f328ef2d..206920a8998 100644 --- a/deployment/environment/devenv/environment.go +++ b/deployment/environment/devenv/environment.go @@ -43,7 +43,7 @@ func NewEnvironment(ctx func() context.Context, lggr logger.Logger, config Envir if err != nil { return nil, nil, err } - nodeIDs = jd.don.NodeIds() + nodeIDs = jd.don.NodeIDs() } return cldf.NewEnvironment( diff --git a/deployment/environment/devenv/fast-filler.go b/deployment/environment/devenv/fast-filler.go index 60f8261f6ba..4899b7dc836 100644 --- a/deployment/environment/devenv/fast-filler.go +++ b/deployment/environment/devenv/fast-filler.go @@ -83,16 +83,14 @@ func (f *CCIPFastFiller) Start(ctx context.Context, t *testing.T) error { } req := testcontainers.GenericContainerRequest{ - ContainerRequest: testcontainers.ContainerRequest{ - Networks: f.networks, - Image: f.image, - WaitingFor: wait.ForLog("Relayer started"), - Files: []testcontainers.ContainerFile{ - { - Reader: bytes.NewReader(configContent), - ContainerFilePath: "/app/config.json", - FileMode: 0644, - }, + Networks: f.networks, + Image: f.image, + WaitingFor: wait.ForLog("Relayer started"), + Files: []testcontainers.ContainerFile{ + { + Reader: bytes.NewReader(configContent), + ContainerFilePath: "/app/config.json", + FileMode: 0o644, }, }, Logger: l, diff --git a/deployment/environment/devenv/internal/kms/kms_client.go b/deployment/environment/devenv/internal/kms/kms_client.go index 91af80fd304..f2806fe6406 100644 --- a/deployment/environment/devenv/internal/kms/kms_client.go +++ b/deployment/environment/devenv/internal/kms/kms_client.go @@ -11,9 +11,12 @@ import ( "math/big" "os" + //nolint:staticcheck // aws-sdk-go v1 is used across this package "github.com/aws/aws-sdk-go/aws/session" + //nolint:staticcheck // aws-sdk-go v1 is used across this package "github.com/aws/aws-sdk-go/aws" + //nolint:staticcheck // aws-sdk-go v1 is used across this package "github.com/aws/aws-sdk-go/service/kms" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -47,19 +50,19 @@ type asn1ECDSASig struct { } // TODO: Mockery gen then test with a regular eth key behind the interface. -type KMSClient interface { +type Client interface { GetPublicKey(input *kms.GetPublicKeyInput) (*kms.GetPublicKeyOutput, error) Sign(input *kms.SignInput) (*kms.SignOutput, error) } type KMS struct { - KmsDeployerKeyId string + KmsDeployerKeyID string KmsDeployerKeyRegion string AwsProfileName string } -func NewKMSClient(config KMS) (KMSClient, error) { - if config.KmsDeployerKeyId == "" { +func NewKMSClient(config KMS) (Client, error) { + if config.KmsDeployerKeyID == "" { return nil, errors.New("KMS key ID is required") } if config.KmsDeployerKeyRegion == "" { @@ -75,12 +78,12 @@ func NewKMSClient(config KMS) (KMSClient, error) { } type EVMKMSClient struct { - Client KMSClient + Client Client KeyID string PublicKey *ecdsa.PublicKey // singleton } -func NewEVMKMSClient(client KMSClient, keyID string) *EVMKMSClient { +func NewEVMKMSClient(client Client, keyID string) *EVMKMSClient { return &EVMKMSClient{ Client: client, KeyID: keyID, @@ -148,7 +151,7 @@ func (c *EVMKMSClient) SignHash(hash []byte) ([]byte, error) { return nil, fmt.Errorf("failed to get public key: %w", err) } - sig, err := kmsToEthSig(signOutput.Signature, secp256k1.S256().Marshal(pubKey.X, pubKey.Y), hash) + sig, err := kmsToEthSig(signOutput.Signature, secp256k1.S256().Marshal(pubKey.X, pubKey.Y), hash) //nolint:staticcheck // raw coordinates for secp256k1 marshalling if err != nil { return nil, fmt.Errorf("failed to convert KMS signature to Ethereum signature: %w", err) } @@ -163,7 +166,7 @@ func (c *EVMKMSClient) GetECDSAPublicKey() (*ecdsa.PublicKey, error) { } getPubKeyOutput, err := c.Client.GetPublicKey(&kms.GetPublicKeyInput{ - KeyId: new(c.KeyID), + KeyId: &c.KeyID, }) if err != nil { return nil, fmt.Errorf("can not get public key from KMS for KeyId=%s: %w", c.KeyID, err) @@ -182,15 +185,15 @@ func (c *EVMKMSClient) GetECDSAPublicKey() (*ecdsa.PublicKey, error) { return c.PublicKey, nil } -func kmsToEthSig(kmsSig, ecdsaPubKeyBytes, hash []byte) ([]byte, error) { - var asn1Sig asn1ECDSASig - _, err := asn1.Unmarshal(kmsSig, &asn1Sig) +func kmsToEthSig(signature, ecdsaPubKeyBytes, hash []byte) ([]byte, error) { + var ecdsaSig asn1ECDSASig + _, err := asn1.Unmarshal(signature, &ecdsaSig) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to unmarshal signature: %w", err) } - rBytes := asn1Sig.R.Bytes - sBytes := asn1Sig.S.Bytes + rBytes := ecdsaSig.R.Bytes + sBytes := ecdsaSig.S.Bytes // Adjust S value from signature to match Eth standard. // See: https://aws.amazon.com/blogs/database/part2-use-aws-kms-to-securely-manage-ethereum-accounts/ @@ -207,7 +210,9 @@ func kmsToEthSig(kmsSig, ecdsaPubKeyBytes, hash []byte) ([]byte, error) { // See: https://aws.amazon.com/blogs/database/part2-use-aws-kms-to-securely-manage-ethereum-accounts/ func recoverEthSignature(expectedPublicKeyBytes, txHash, r, s []byte) ([]byte, error) { rsSig := append(padTo32Bytes(r), padTo32Bytes(s)...) - ethSig := append(rsSig, []byte{0}...) + ethSig := make([]byte, len(rsSig)+1) + copy(ethSig, rsSig) + ethSig[len(rsSig)] = 0 recoveredPublicKeyBytes, err := crypto.Ecrecover(txHash, ethSig) if err != nil { @@ -215,7 +220,7 @@ func recoverEthSignature(expectedPublicKeyBytes, txHash, r, s []byte) ([]byte, e } if hex.EncodeToString(recoveredPublicKeyBytes) != hex.EncodeToString(expectedPublicKeyBytes) { - ethSig = append(rsSig, []byte{1}...) + ethSig[len(rsSig)] = 1 recoveredPublicKeyBytes, err = crypto.Ecrecover(txHash, ethSig) if err != nil { return nil, fmt.Errorf("failing to call Ecrecover: %w", err) @@ -243,7 +248,7 @@ type AwsSessionFn func(config KMS) *session.Session var awsSessionFromEnvVarsFn = func(config KMS) *session.Session { return session.Must( session.NewSession(&aws.Config{ - Region: new(config.KmsDeployerKeyRegion), + Region: &config.KmsDeployerKeyRegion, CredentialsChainVerboseErrors: new(true), })) } @@ -254,16 +259,16 @@ var awsSessionFromProfileFn = func(config KMS) *session.Session { SharedConfigState: session.SharedConfigEnable, Profile: config.AwsProfileName, Config: aws.Config{ - Region: new(config.KmsDeployerKeyRegion), + Region: &config.KmsDeployerKeyRegion, CredentialsChainVerboseErrors: new(true), }, })) } -func KMSConfigFromEnvVars() (KMS, error) { +func ConfigFromEnvVars() (KMS, error) { var config KMS var exists bool - config.KmsDeployerKeyId, exists = os.LookupEnv("KMS_DEPLOYER_KEY_ID") + config.KmsDeployerKeyID, exists = os.LookupEnv("KMS_DEPLOYER_KEY_ID") if !exists { return config, errors.New("KMS_DEPLOYER_KEY_ID is required") } diff --git a/deployment/environment/devenv/jd.go b/deployment/environment/devenv/jd.go index ba052989626..f4a1e7b1927 100644 --- a/deployment/environment/devenv/jd.go +++ b/deployment/environment/devenv/jd.go @@ -44,7 +44,7 @@ func NewJDClient(ctx context.Context, cfg JDConfig) (cldf_offchain.Client, error donJDClient := &JobDistributor{ JobDistributor: jdClient, } - if cfg.NodeInfo != nil && len(cfg.NodeInfo) > 0 { + if len(cfg.NodeInfo) > 0 { donJDClient.don, err = NewRegisteredDON(ctx, cfg.NodeInfo, *donJDClient) if err != nil { return nil, fmt.Errorf("failed to create registered DON: %w", err) diff --git a/deployment/environment/devenv/rmn.go b/deployment/environment/devenv/rmn.go index f66e88270d4..31334861210 100644 --- a/deployment/environment/devenv/rmn.go +++ b/deployment/environment/devenv/rmn.go @@ -66,12 +66,10 @@ func NewRage2ProxyComponent( } rmn := &RageProxy{ - EnvComponent: test_env.EnvComponent{ - ContainerName: rageName, - ContainerImage: imageName, - ContainerVersion: imageVersion, - Networks: networks, - }, + ContainerName: rageName, + ContainerImage: imageName, + ContainerVersion: imageVersion, + Networks: networks, Passphrase: DefaultAFNPassphrase, proxyListenerPort: listenPort, proxyPort: proxyPort, @@ -106,20 +104,18 @@ type RMNKeys struct { EVMOnchainPublicKey common.Address } -func GenerateRMNKeyStore(lggr zerolog.Logger, image string, version string, platform string) (keys RMNKeys, fileString string, passphrase string, err error) { +func GenerateRMNKeyStore(lggr zerolog.Logger, image, version, platform string) (keys RMNKeys, fileString, passphrase string, err error) { container, err := docker.StartContainerWithRetry(lggr, tc.GenericContainerRequest{ - ContainerRequest: tc.ContainerRequest{ - AutoRemove: false, - Image: fmt.Sprintf("%s:%s", image, version), - Env: map[string]string{ - "AFN_PASSPHRASE": DefaultAFNPassphrase, - }, - Cmd: []string{"afn2proxy", "--generate", "--keystore", RMNKeyStore}, - WaitingFor: tcwait.ForExit(), - ImagePlatform: platform, + AutoRemove: false, + Image: fmt.Sprintf("%s:%s", image, version), + Env: map[string]string{ + "AFN_PASSPHRASE": DefaultAFNPassphrase, }, - Started: true, - Logger: &lggr, + Cmd: []string{"afn2proxy", "--generate", "--keystore", RMNKeyStore}, + WaitingFor: tcwait.ForExit(), + ImagePlatform: platform, + Started: true, + Logger: &lggr, }) defer func() { if terminateErr := container.Terminate(context.Background()); terminateErr != nil { @@ -161,27 +157,25 @@ func GenerateRMNKeyStore(lggr zerolog.Logger, image string, version string, plat return keys, fileString, passphrase, nil } -func GeneratePeerID(lggr zerolog.Logger, image string, version string, imagePlatform string) (peerID p2ptypes.PeerID, content string, passphrase string, err error) { +func GeneratePeerID(lggr zerolog.Logger, image, version, imagePlatform string) (peerID p2ptypes.PeerID, content, passphrase string, err error) { container, err := docker.StartContainerWithRetry(lggr, tc.GenericContainerRequest{ - ContainerRequest: tc.ContainerRequest{ - AutoRemove: false, - Image: fmt.Sprintf("%s:%s", image, version), - Env: map[string]string{ - "RAGEPROXY_PASSPHRASE": DefaultAFNPassphrase, - }, - Cmd: []string{"rageproxy", "--generate", "--keystore", ProxyKeyStore}, - WaitingFor: tcwait.ForExit(), - ImagePlatform: imagePlatform, + AutoRemove: false, + Image: fmt.Sprintf("%s:%s", image, version), + Env: map[string]string{ + "RAGEPROXY_PASSPHRASE": DefaultAFNPassphrase, }, - Started: true, - Logger: &lggr, + Cmd: []string{"rageproxy", "--generate", "--keystore", ProxyKeyStore}, + WaitingFor: tcwait.ForExit(), + ImagePlatform: imagePlatform, + Started: true, + Logger: &lggr, }) - defer (func() { + defer func() { err := container.Terminate(context.Background()) if err != nil { log.Printf("Failed to stop container: %v", err) } - })() + }() if err != nil { return p2ptypes.PeerID{}, "", "", err @@ -226,36 +220,34 @@ func (proxy *RageProxy) Start(t *testing.T, lggr zerolog.Logger, networks []stri } } container, err := docker.StartContainerWithRetry(lggr, tc.GenericContainerRequest{ - ContainerRequest: tc.ContainerRequest{ - Name: proxy.ContainerName, - Networks: networks, - Image: fmt.Sprintf("%s:%s", proxy.ContainerImage, proxy.ContainerVersion), - Env: map[string]string{ - "RAGEPROXY_PASSPHRASE": proxy.Passphrase, - }, - ExposedPorts: []string{ - test_env.NatPortFormat(proxy.proxyPort), - test_env.NatPortFormat(proxy.proxyListenerPort), + Name: proxy.ContainerName, + Networks: networks, + Image: fmt.Sprintf("%s:%s", proxy.ContainerImage, proxy.ContainerVersion), + Env: map[string]string{ + "RAGEPROXY_PASSPHRASE": proxy.Passphrase, + }, + ExposedPorts: []string{ + test_env.NatPortFormat(proxy.proxyPort), + test_env.NatPortFormat(proxy.proxyListenerPort), + }, + Files: []tc.ContainerFile{ + { + HostFilePath: sharedRageProxy, + ContainerFilePath: "/app/cfg/rageproxy-shared.json", + FileMode: 0o644, }, - Files: []tc.ContainerFile{ - { - HostFilePath: sharedRageProxy, - ContainerFilePath: "/app/cfg/rageproxy-shared.json", - FileMode: 0644, - }, - { - HostFilePath: localRageProxy, - ContainerFilePath: "/app/cfg/rageproxy-local.json", - FileMode: 0644, - }, + { + HostFilePath: localRageProxy, + ContainerFilePath: "/app/cfg/rageproxy-local.json", + FileMode: 0o644, }, - WaitingFor: tcwait.ForExec([]string{"cat", ProxyKeyStore}), - LifecycleHooks: []tc.ContainerLifecycleHooks{ - { - PostStarts: proxy.PostStartsHooks, - PostStops: proxy.PostStopsHooks, - PreTerminates: proxy.PreTerminatesHooks, - }, + }, + WaitingFor: tcwait.ForExec([]string{"cat", ProxyKeyStore}), + LifecycleHooks: []tc.ContainerLifecycleHooks{ + { + PostStarts: proxy.PostStartsHooks, + PostStops: proxy.PostStopsHooks, + PreTerminates: proxy.PreTerminatesHooks, }, }, Started: true, @@ -265,7 +257,8 @@ func (proxy *RageProxy) Start(t *testing.T, lggr zerolog.Logger, networks []stri return nil, err } _, reader, err := container.Exec(context.Background(), []string{ - "cat", ProxyKeyStore}, exec.Multiplexed()) + "cat", ProxyKeyStore, + }, exec.Multiplexed()) if err != nil { return nil, fmt.Errorf("unable to cat keystore: %w", err) } @@ -299,18 +292,17 @@ func NewAFN2ProxyComponent( imageName, imageVersion string, shared SharedConfig, - local LocalConfig) (*AFN2Proxy, error) { + local LocalConfig, +) (*AFN2Proxy, error) { afnName := fmt.Sprintf("%s-%s", name, uuid.NewString()[0:8]) rmn := &AFN2Proxy{ - EnvComponent: test_env.EnvComponent{ - ContainerName: afnName, - ContainerImage: imageName, - ContainerVersion: imageVersion, - Networks: networks, - }, - AFNPassphrase: DefaultAFNPassphrase, - Shared: shared, - Local: local, + ContainerName: afnName, + ContainerImage: imageName, + ContainerVersion: imageVersion, + Networks: networks, + AFNPassphrase: DefaultAFNPassphrase, + Shared: shared, + Local: local, } return rmn, nil @@ -358,32 +350,30 @@ func (rmn *AFN2Proxy) Start(t *testing.T, lggr zerolog.Logger, reuse bool, netwo } } container, err := docker.StartContainerWithRetry(lggr, tc.GenericContainerRequest{ - ContainerRequest: tc.ContainerRequest{ - Name: rmn.ContainerName, - Networks: networks, - Image: fmt.Sprintf("%s:%s", rmn.ContainerImage, rmn.ContainerVersion), - Env: map[string]string{ - "AFN_PASSPHRASE": rmn.AFNPassphrase, + Name: rmn.ContainerName, + Networks: networks, + Image: fmt.Sprintf("%s:%s", rmn.ContainerImage, rmn.ContainerVersion), + Env: map[string]string{ + "AFN_PASSPHRASE": rmn.AFNPassphrase, + }, + Files: []tc.ContainerFile{ + { + HostFilePath: sharedAFN2Proxy, + ContainerFilePath: "/app/cfg/afn2proxy-shared.toml", + FileMode: 0o644, }, - Files: []tc.ContainerFile{ - { - HostFilePath: sharedAFN2Proxy, - ContainerFilePath: "/app/cfg/afn2proxy-shared.toml", - FileMode: 0644, - }, - { - HostFilePath: localAFN2Proxy, - ContainerFilePath: "/app/cfg/afn2proxy-local.toml", - FileMode: 0644, - }, + { + HostFilePath: localAFN2Proxy, + ContainerFilePath: "/app/cfg/afn2proxy-local.toml", + FileMode: 0o644, }, - WaitingFor: tcwait.ForExec([]string{"cat", RMNKeyStore}), - LifecycleHooks: []tc.ContainerLifecycleHooks{ - { - PostStarts: rmn.PostStartsHooks, - PostStops: rmn.PostStopsHooks, - PreTerminates: rmn.PreTerminatesHooks, - }, + }, + WaitingFor: tcwait.ForExec([]string{"cat", RMNKeyStore}), + LifecycleHooks: []tc.ContainerLifecycleHooks{ + { + PostStarts: rmn.PostStartsHooks, + PostStops: rmn.PostStopsHooks, + PreTerminates: rmn.PreTerminatesHooks, }, }, Started: true, @@ -394,7 +384,8 @@ func (rmn *AFN2Proxy) Start(t *testing.T, lggr zerolog.Logger, reuse bool, netwo return nil, err } _, reader, err := container.Exec(context.Background(), []string{ - "cat", RMNKeyStore}, exec.Multiplexed()) + "cat", RMNKeyStore, + }, exec.Multiplexed()) if err != nil { return nil, fmt.Errorf("unable to cat keystore: %w", err) } diff --git a/deployment/environment/nodeclient/chainlink.go b/deployment/environment/nodeclient/chainlink.go index 5bad9e337bc..82c13f16e86 100644 --- a/deployment/environment/nodeclient/chainlink.go +++ b/deployment/environment/nodeclient/chainlink.go @@ -61,9 +61,7 @@ func NewChainlinkClient(c *ChainlinkConfig, logger zerolog.Logger) (*ChainlinkCl func initRestyClient(url string, email string, password string, headers map[string]string, timeout *time.Duration) (*resty.Client, error) { isDebug := os.Getenv("RESTY_DEBUG") == "true" - // G402 - TODO: certificates - //nolint - rc := resty.New().SetBaseURL(url).SetHeaders(headers).SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).SetDebug(isDebug) + rc := resty.New().SetBaseURL(url).SetHeaders(headers).SetTLSClientConfig(&tls.Config{InsecureSkipVerify: true}).SetDebug(isDebug) //nolint:gosec // G402 - TODO: certificates if timeout != nil { rc.SetTimeout(*timeout) } @@ -74,12 +72,11 @@ func initRestyClient(url string, email string, password string, headers map[stri retryCount := 20 for range retryCount { resp, err = rc.R().SetBody(session).Post("/sessions") - if err != nil { - log.Warn().Err(err).Str("URL", url).Interface("Session Details", session).Msg("Error connecting to Chainlink node, retrying") - time.Sleep(5 * time.Second) - } else { + if err == nil { break } + log.Warn().Err(err).Str("URL", url).Interface("Session Details", session).Msg("Error connecting to Chainlink node, retrying") + time.Sleep(5 * time.Second) } if err != nil { return nil, fmt.Errorf("error connecting to chainlink node after %d attempts: %w", retryCount, err) @@ -483,7 +480,7 @@ func (c *ChainlinkClient) MustReadP2PKeys() (*P2PKeys, error) { } err = VerifyStatusCode(resp.StatusCode(), http.StatusOK) if len(p2pKeys.Data) == 0 { - err = fmt.Errorf("Found no P2P Keys on the Chainlink node. Node URL: %s", c.Config.URL) + err = fmt.Errorf("found no P2P keys on the Chainlink node. Node URL: %s", c.Config.URL) c.l.Err(err).Msg("Error getting P2P keys") return nil, err } @@ -526,12 +523,12 @@ func (c *ChainlinkClient) MustReadETHKeys() (*ETHKeys, error) { } // UpdateEthKeyMaxGasPriceGWei updates the maxGasPriceGWei for an eth key -func (c *ChainlinkClient) UpdateEthKeyMaxGasPriceGWei(keyId string, gWei int) (*ETHKey, *http.Response, error) { +func (c *ChainlinkClient) UpdateEthKeyMaxGasPriceGWei(keyID string, gWei int) (*ETHKey, *http.Response, error) { ethKey := ÐKey{} - c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", keyId).Int("maxGasPriceGWei", gWei).Msg("Update maxGasPriceGWei for eth key") + c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", keyID).Int("maxGasPriceGWei", gWei).Msg("Update maxGasPriceGWei for eth key") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ - "keyId": keyId, + "keyId": keyID, }). SetQueryParams(map[string]string{ "maxGasPriceGWei": strconv.Itoa(gWei), @@ -555,7 +552,7 @@ func (c *ChainlinkClient) ReadPrimaryETHKey() (*ETHKeyData, error) { return nil, err } if len(ethKeys.Data) == 0 { - return nil, fmt.Errorf("Error retrieving primary eth key on node %s: No ETH keys present", c.URL()) + return nil, fmt.Errorf("error retrieving primary eth key on node %s: no ETH keys present", c.URL()) } return ðKeys.Data[0], nil } @@ -567,7 +564,7 @@ func (c *ChainlinkClient) ReadETHKeyAtIndex(keyIndex int) (*ETHKeyData, error) { return nil, err } if len(ethKeys.Data) == 0 { - return nil, fmt.Errorf("Error retrieving primary eth key on node %s: No ETH keys present", c.URL()) + return nil, fmt.Errorf("error retrieving primary eth key on node %s: no ETH keys present", c.URL()) } return ðKeys.Data[keyIndex], nil } @@ -600,14 +597,14 @@ func (c *ChainlinkClient) EthAddresses() ([]string, error) { } // EthAddresses returns the ETH addresses of the Chainlink node for a specific chain id -func (c *ChainlinkClient) EthAddressesForChain(chainId string) ([]string, error) { +func (c *ChainlinkClient) EthAddressesForChain(chainID string) ([]string, error) { var ethAddresses []string ethKeys, err := c.MustReadETHKeys() if err != nil { return nil, err } for _, ethKey := range ethKeys.Data { - if ethKey.Attributes.ChainID == chainId { + if ethKey.Attributes.ChainID == chainID { ethAddresses = append(ethAddresses, ethKey.Attributes.Address) } } @@ -615,13 +612,13 @@ func (c *ChainlinkClient) EthAddressesForChain(chainId string) ([]string, error) } // PrimaryEthAddressForChain returns the primary ETH address for the Chainlink node for mentioned chain -func (c *ChainlinkClient) PrimaryEthAddressForChain(chainId string) (string, error) { +func (c *ChainlinkClient) PrimaryEthAddressForChain(chainID string) (string, error) { ethKeys, err := c.MustReadETHKeys() if err != nil { return "", err } for _, ethKey := range ethKeys.Data { - if ethKey.Attributes.ChainID == chainId { + if ethKey.Attributes.ChainID == chainID { return ethKey.Attributes.Address, nil } } @@ -685,14 +682,14 @@ func (c *ChainlinkClient) ExportEVMKeysForChain(chainid string) ([]*ExportedEVMK } // CreateTxKey creates a tx key on the Chainlink node -func (c *ChainlinkClient) CreateTxKey(chain string, chainId string) (*TxKey, *http.Response, error) { +func (c *ChainlinkClient) CreateTxKey(chain string, chainID string) (*TxKey, *http.Response, error) { txKey := &TxKey{} c.l.Info().Str(NodeURL, c.Config.URL).Msg("Creating Tx Key") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ "chain": chain, }). - SetQueryParam("evmChainID", chainId). + SetQueryParam("evmChainID", chainID). SetResult(txKey). Post("/v2/keys/{chain}") if err != nil { @@ -820,12 +817,12 @@ func (c *ChainlinkClient) MustCreateVRFKey() (*VRFKey, error) { } // ExportVRFKey exports a vrf key by key id -func (c *ChainlinkClient) ExportVRFKey(keyId string) (*VRFExportKey, *http.Response, error) { +func (c *ChainlinkClient) ExportVRFKey(keyID string) (*VRFExportKey, *http.Response, error) { vrfExportKey := &VRFExportKey{} - c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", keyId).Msg("Exporting VRF Key") + c.l.Info().Str(NodeURL, c.Config.URL).Str("ID", keyID).Msg("Exporting VRF Key") resp, err := c.APIClient.R(). SetPathParams(map[string]string{ - "keyId": keyId, + "keyId": keyID, }). SetResult(vrfExportKey). Post("/v2/keys/vrf/export/{keyId}") @@ -1181,7 +1178,7 @@ func VerifyStatusCodeWithResponse(res *resty.Response, expStatusCd int) error { return nil } -func CreateNodeKeysBundle(nodes []*ChainlinkClient, chainName string, chainId string) ([]NodeKeysBundle, []*CLNodesWithKeys, error) { +func CreateNodeKeysBundle(nodes []*ChainlinkClient, chainName string, chainID string) ([]NodeKeysBundle, []*CLNodesWithKeys, error) { nkb := make([]NodeKeysBundle, 0) var clNodes []*CLNodesWithKeys for _, n := range nodes { @@ -1211,7 +1208,7 @@ func CreateNodeKeysBundle(nodes []*ChainlinkClient, chainName string, chainId st } // if no txkey is found for the chain, create a new one if txKey == nil { - txKey, _, err = n.CreateTxKey(chainName, chainId) + txKey, _, err = n.CreateTxKey(chainName, chainID) if err != nil { return nil, nil, err } @@ -1231,7 +1228,7 @@ func CreateNodeKeysBundle(nodes []*ChainlinkClient, chainName string, chainId st if ocrKey == nil { return nil, nil, fmt.Errorf("no OCR key found for chain %s", chainName) } - ethAddress, err := n.PrimaryEthAddressForChain(chainId) + ethAddress, err := n.PrimaryEthAddressForChain(chainID) if err != nil { return nil, nil, err } diff --git a/deployment/environment/nodeclient/chainlink_models.go b/deployment/environment/nodeclient/chainlink_models.go index 3eea5732eb7..3fa09919fa2 100644 --- a/deployment/environment/nodeclient/chainlink_models.go +++ b/deployment/environment/nodeclient/chainlink_models.go @@ -538,7 +538,7 @@ type StarkNetChainCreate struct { type StarkNetNodeAttributes struct { Name string `json:"name"` ChainID string `json:"chainId"` - Url string `json:"url"` + URL string `json:"url"` } // StarkNetNode is the model that represents the starknet node when read @@ -1081,7 +1081,7 @@ func (o *OCR2TaskJobSpec) String() (string, error) { MaxTaskDuration: o.MaxTaskDuration, ContractID: o.OCR2OracleSpec.ContractID, FeedID: feedID, - Relay: string(o.OCR2OracleSpec.Relay), + Relay: o.OCR2OracleSpec.Relay, PluginType: string(o.OCR2OracleSpec.PluginType), RelayConfig: string(relayConfig), PluginConfig: o.OCR2OracleSpec.PluginConfig, diff --git a/deployment/environment/test/jd.go b/deployment/environment/test/jd.go index bc1a2e08713..9a526d4de9d 100644 --- a/deployment/environment/test/jd.go +++ b/deployment/environment/test/jd.go @@ -19,9 +19,11 @@ import ( "github.com/smartcontractkit/chainlink-common/keystore/corekeys/p2pkey" ) -var _ nodev1.NodeServiceClient = (*JDNodeService)(nil) -var _ jobv1.JobServiceClient = (*JDNodeService)(nil) -var _ csav1.CSAServiceClient = (*JDNodeService)(nil) +var ( + _ nodev1.NodeServiceClient = (*JDNodeService)(nil) + _ jobv1.JobServiceClient = (*JDNodeService)(nil) + _ csav1.CSAServiceClient = (*JDNodeService)(nil) +) // JDNodeService is a mock implementation of the JobDistributor that supports // the Node methods @@ -174,12 +176,10 @@ func (s *JDNodeService) ListNodeChainConfigs(ctx context.Context, req *nodev1.Li func newWrapperFromRegister(req *nodev1.RegisterNodeRequest) (*wrappedNode, error) { return &wrappedNode{ - Node: deployment.Node{ - NodeID: uuid.New().String(), - Name: req.Name, - CSAKey: req.PublicKey, - Labels: req.Labels, - }, + NodeID: uuid.New().String(), + Name: req.Name, + CSAKey: req.PublicKey, + Labels: req.Labels, enabled: true, }, nil } @@ -241,12 +241,10 @@ func (s *JDNodeService) ListProposedJobRequests() ([]*jobv1.ProposeJobRequest, e func newWrapperFromUpdate(req *nodev1.UpdateNodeRequest) (*wrappedNode, error) { return &wrappedNode{ - Node: deployment.Node{ - NodeID: req.Id, - Name: req.Name, - CSAKey: req.PublicKey, - Labels: req.Labels, - }, + NodeID: req.Id, + Name: req.Name, + CSAKey: req.PublicKey, + Labels: req.Labels, enabled: true, }, nil } @@ -302,6 +300,7 @@ type p2pKey string func (p p2pKey) String() string { return string(p) } + func (p p2pKey) Validate() error { _, err := p2pkey.MakePeerID(p.String()) return err @@ -348,16 +347,6 @@ func (s *store) getNode(id string) (*wrappedNode, error) { return n, nil } -func (s *store) getNodeByP2P(p2p p2pKey) (*wrappedNode, error) { - s.mu.RLock() - defer s.mu.RUnlock() - id, ok := s.p2pToID[p2p] - if !ok { - return nil, fmt.Errorf("node not found for p2p %s", p2p) - } - return s.getNode(id) -} - func (s *store) getNodeByCSA(csa csaKey) (*wrappedNode, error) { s.mu.RLock() defer s.mu.RUnlock() diff --git a/deployment/environment/web/sdk/client/client.go b/deployment/environment/web/sdk/client/client.go index 32322285459..f4fcf244d07 100644 --- a/deployment/environment/web/sdk/client/client.go +++ b/deployment/environment/web/sdk/client/client.go @@ -381,7 +381,7 @@ func (c *client) login() error { payload := strings.NewReader(string(b)) - req, err := http.NewRequest("POST", c.endpoints.Sessions, payload) + req, err := http.NewRequestWithContext(context.Background(), "POST", c.endpoints.Sessions, payload) if err != nil { return err } diff --git a/deployment/environment/web/sdk/client/types.go b/deployment/environment/web/sdk/client/types.go index e4f6ff75bce..eb8f6d776e2 100644 --- a/deployment/environment/web/sdk/client/types.go +++ b/deployment/environment/web/sdk/client/types.go @@ -11,7 +11,7 @@ import ( type JobDistributorInput struct { Name string `json:"name"` - Uri string `json:"uri"` + URI string `json:"uri"` PublicKey string `json:"publicKey"` } @@ -38,7 +38,7 @@ type JobDistributorChainConfigInput struct { } type JobProposalApprovalSuccessSpec struct { - Id string `json:"id"` + ID string `json:"id"` Definition string `json:"definition"` Version int `json:"version"` Status string `json:"status"` diff --git a/deployment/environment/web/sdk/client/types_test.go b/deployment/environment/web/sdk/client/types_test.go index e96473dec23..87d27ad4ec5 100644 --- a/deployment/environment/web/sdk/client/types_test.go +++ b/deployment/environment/web/sdk/client/types_test.go @@ -21,7 +21,7 @@ func TestDecodeInput(t *testing.T) { name: "success", args: args{&JobDistributorInput{ Name: "name", - Uri: "uri", + URI: "uri", PublicKey: "publicKey", }, &generated.CreateFeedsManagerInput{}}, wantErr: false, @@ -31,7 +31,7 @@ func TestDecodeInput(t *testing.T) { name: "non-pointer", args: args{&JobDistributorInput{ Name: "name", - Uri: "uri", + URI: "uri", PublicKey: "publicKey", }, generated.CreateFeedsManagerInput{}}, wantErr: true, @@ -41,7 +41,7 @@ func TestDecodeInput(t *testing.T) { name: "incorrect type", args: args{&JobDistributorInput{ Name: "name", - Uri: "uri", + URI: "uri", PublicKey: "publicKey", }, generated.CreateFeedsManagerChainConfigInput{}}, wantErr: true, @@ -51,7 +51,7 @@ func TestDecodeInput(t *testing.T) { name: "success", args: args{&JobDistributorInput{ Name: "name", - Uri: "uri", + URI: "uri", PublicKey: "publicKey", }, &generated.UpdateFeedsManagerInput{}}, wantErr: false, diff --git a/deployment/helpers/build_solana.go b/deployment/helpers/build_solana.go index cb597748034..7830075e29b 100644 --- a/deployment/helpers/build_solana.go +++ b/deployment/helpers/build_solana.go @@ -3,6 +3,7 @@ package helpers import ( "bufio" "bytes" + "context" "fmt" "os" "os/exec" @@ -56,7 +57,7 @@ type DomainParams struct { // Run a command in a specific directory func RunCommand(command string, args []string, workDir string) (string, error) { - cmd := exec.Command(command, args...) + cmd := exec.CommandContext(context.Background(), command, args...) cmd.Dir = workDir var stdout, stderr bytes.Buffer cmd.Stdout = &stdout diff --git a/deployment/internal/jdtestutils/client_test.go b/deployment/internal/jdtestutils/client_test.go index 5c13418c415..908307f9f49 100644 --- a/deployment/internal/jdtestutils/client_test.go +++ b/deployment/internal/jdtestutils/client_test.go @@ -350,7 +350,7 @@ func TestJobClientJobAPI(t *testing.T) { } // need some non-ocr job type to avoid the ocr validation and the p2pwrapper check -func testJobProposalTOML(t *testing.T, externalJobId string) string { +func testJobProposalTOML(t *testing.T, externalJobID string) string { tomlString := ` type = "standardcapabilities" schemaVersion = 1 @@ -360,5 +360,5 @@ forwardingAllowed = false command = "/home/capabilities/nowhere" config = "" ` - return fmt.Sprintf(tomlString, externalJobId, externalJobId) + return fmt.Sprintf(tomlString, externalJobID, externalJobID) } diff --git a/deployment/keystone/changeset/add_capabilities.go b/deployment/keystone/changeset/add_capabilities.go index 9d450747e54..d6f98f0582a 100644 --- a/deployment/keystone/changeset/add_capabilities.go +++ b/deployment/keystone/changeset/add_capabilities.go @@ -84,7 +84,7 @@ func (r *AddCapabilitiesRequest) Validate(env cldf.Environment) error { func shouldUseDatastore(env cldf.Environment, ref datastore.AddressRefKey) error { if addrs, err := env.DataStore.Addresses().Fetch(); err == nil { if len(addrs) != 0 && ref == nil { - return errors.New("This environment has been migrated to DataStore: address ref key must not be nil") + return errors.New("this environment has been migrated to DataStore: address ref key must not be nil") } } return nil diff --git a/deployment/keystone/changeset/add_dons.go b/deployment/keystone/changeset/add_dons.go index e3f0a37f2ba..d4ff9cf88d8 100644 --- a/deployment/keystone/changeset/add_dons.go +++ b/deployment/keystone/changeset/add_dons.go @@ -42,7 +42,7 @@ func (d *RegisterableDon) Validate() error { return errors.New("name is required") } if d.F == 0 { - return errors.New("F is required") + return errors.New("f is required") } if len(d.P2PIDs) == 0 { return errors.New("P2PIDs is required") diff --git a/deployment/keystone/changeset/add_nodes_test.go b/deployment/keystone/changeset/add_nodes_test.go index 3a1859cf721..fd027ded1d1 100644 --- a/deployment/keystone/changeset/add_nodes_test.go +++ b/deployment/keystone/changeset/add_nodes_test.go @@ -41,7 +41,7 @@ func TestAddNodes(t *testing.T) { mcmsConfig *changeset.MCMSConfig } - var mcCases = []mcmsCase{ + mcCases := []mcmsCase{ {name: "no mcms", mcmsConfig: nil}, {name: "with mcms", mcmsConfig: &changeset.MCMSConfig{MinDelay: 0}}, } @@ -56,16 +56,14 @@ func TestAddNodes(t *testing.T) { UseMCMS: mcmsConfig != nil, }) - var cases = []testCase{ + cases := []testCase{ { name: "error - unregistered nop", input: input{ te: te, CreateNodeRequests: map[string]*changeset.CreateNodeRequest{ - "test-node": &changeset.CreateNodeRequest{ - NOPIdentity: changeset.NOPIdentity{ - RegistrationID: math.MaxUint32, - }, + "test-node": { + RegistrationID: math.MaxUint32, Signer: [32]byte{0: 4}, EncryptionPublicKey: [32]byte{0: 23}, P2PID: testPeerID(t, "test-peer-id"), diff --git a/deployment/keystone/changeset/deploy_balance_reader.go b/deployment/keystone/changeset/deploy_balance_reader.go index 5131eeee9de..3a992a6b22a 100644 --- a/deployment/keystone/changeset/deploy_balance_reader.go +++ b/deployment/keystone/changeset/deploy_balance_reader.go @@ -21,6 +21,7 @@ type DeployBalanceReaderRequest struct { // DeployBalanceReader deploys the BalanceReader contract to all chains in the environment // callers must merge the output addressbook with the existing one +// // Deprecated: use DeployBalanceReaderV2 instead func DeployBalanceReader(env cldf.Environment, cfg DeployBalanceReaderRequest) (cldf.ChangesetOutput, error) { out := cldf.ChangesetOutput{ @@ -42,7 +43,7 @@ func DeployBalanceReader(env cldf.Environment, cfg DeployBalanceReaderRequest) ( if err != nil { return cldf.ChangesetOutput{}, fmt.Errorf("failed to deploy BalanceReader to chain selector %d: %w", sel, err) } - if err := out.AddressBook.Merge(csOut.AddressBook); err != nil { //nolint:staticcheck // TODO CRE-400 + if err := out.AddressBook.Merge(csOut.AddressBook); err != nil { return cldf.ChangesetOutput{}, fmt.Errorf("failed to merge address book for chain selector %d: %w", sel, err) } if err := out.DataStore.Merge(csOut.DataStore.Seal()); err != nil { diff --git a/deployment/keystone/changeset/deploy_forwarder.go b/deployment/keystone/changeset/deploy_forwarder.go index 9ec4d947041..346748014f8 100644 --- a/deployment/keystone/changeset/deploy_forwarder.go +++ b/deployment/keystone/changeset/deploy_forwarder.go @@ -30,7 +30,7 @@ type DeployForwarderRequest struct { func DeployForwarder(env cldf.Environment, cfg DeployForwarderRequest) (cldf.ChangesetOutput, error) { var out cldf.ChangesetOutput out.DataStore = datastore.NewMemoryDataStore() - out.AddressBook = cldf.NewMemoryAddressBook() //nolint:staticcheck // keeping the address book since not everything has been migrated to datastore + out.AddressBook = cldf.NewMemoryAddressBook() selectors := cfg.ChainSelectors if len(selectors) == 0 { @@ -44,7 +44,8 @@ func DeployForwarder(env cldf.Environment, cfg DeployForwarderRequest) (cldf.Cha creforwarder.DeployOpDeps{Env: &env}, creforwarder.DeployOpInput{ ChainSelector: sel, Qualifier: cfg.Qualifier, - }) + }, + ) if err != nil { return cldf.ChangesetOutput{}, fmt.Errorf("failed to deploy KeystoneForwarder to chain selector %d: %w", sel, err) } @@ -54,7 +55,7 @@ func DeployForwarder(env cldf.Environment, cfg DeployForwarderRequest) (cldf.Cha return cldf.ChangesetOutput{}, fmt.Errorf("failed to merge datastore for chain selector %d: %w", sel, err) } // merge the address book outputs - if err := out.AddressBook.Merge(report.Output.AddressBook); err != nil { //nolint:staticcheck // keeping the address book since not everything has been migrated to datastore + if err := out.AddressBook.Merge(report.Output.AddressBook); err != nil { return cldf.ChangesetOutput{}, fmt.Errorf("failed to merge address book for chain selector %d: %w", sel, err) } } @@ -71,7 +72,8 @@ func DeployForwarderV2(env cldf.Environment, req *DeployRequestV2) (cldf.Changes creforwarder.DeployOpDeps{Env: &env}, creforwarder.DeployOpInput{ ChainSelector: req.ChainSel, Qualifier: req.Qualifier, - }) + }, + ) if err != nil { return nil, fmt.Errorf("failed to deploy KeystoneForwarder to chain selector %d: %w", req.ChainSel, err) } @@ -127,6 +129,9 @@ func ConfigureForwardContracts(env cldf.Environment, req ConfigureForwardContrac Name: req.WFDonName, RegistryChainSel: req.RegistryChainSel, }) + if err != nil { + return cldf.ChangesetOutput{}, fmt.Errorf("failed to get registered don: %w", err) + } cfg := creforwarder.DonConfiguration{ Name: req.WFDonName, ID: wfDon.Info.Id, diff --git a/deployment/keystone/changeset/deploy_forwarder_test.go b/deployment/keystone/changeset/deploy_forwarder_test.go index e67c78456e5..00ea44512c8 100644 --- a/deployment/keystone/changeset/deploy_forwarder_test.go +++ b/deployment/keystone/changeset/deploy_forwarder_test.go @@ -97,7 +97,7 @@ func TestConfigureForwarders(t *testing.T) { return nil, iterator.Error() } } - return + return result, err } requireConfigUpdate := func(t *testing.T, forwarder *forwarder.KeystoneForwarder, skippedConfigSet bool) { diff --git a/deployment/keystone/changeset/deploy_ocr3_test.go b/deployment/keystone/changeset/deploy_ocr3_test.go index 00b7351e9bc..aaee0712ee8 100644 --- a/deployment/keystone/changeset/deploy_ocr3_test.go +++ b/deployment/keystone/changeset/deploy_ocr3_test.go @@ -236,7 +236,8 @@ func TestConfigureOCR3(t *testing.T) { // Deploy a new OCR3 contract resp, err := changeset.DeployOCR3V2(te.Env, &changeset.DeployRequestV2{ ChainSel: registrySel, - Qualifier: "test-ocr-contract"}) + Qualifier: "test-ocr-contract", + }) require.NoError(t, err) require.NotNil(t, resp) require.NoError(t, te.Env.ExistingAddresses.Merge(resp.AddressBook)) diff --git a/deployment/keystone/changeset/internal/addrbook/addrbook.go b/deployment/keystone/changeset/internal/addrbook/addrbook.go index 093b034faf9..0c1558581dd 100644 --- a/deployment/keystone/changeset/internal/addrbook/addrbook.go +++ b/deployment/keystone/changeset/internal/addrbook/addrbook.go @@ -2,7 +2,6 @@ // // Addressbook is deprecated but this remains as a temporary solution // for backwards compatibility. - package addrbook import ( diff --git a/deployment/keystone/changeset/internal/contract_set.go b/deployment/keystone/changeset/internal/contract_set.go index 67e05eb10d9..cefd46b9708 100644 --- a/deployment/keystone/changeset/internal/contract_set.go +++ b/deployment/keystone/changeset/internal/contract_set.go @@ -12,6 +12,9 @@ import ( // and saves the address in the address book. This mutates the address book. func DeployCapabilitiesRegistry(_ context.Context, chain cldf_evm.Chain, ab cldf.AddressBook) (*DeployResponse, error) { capabilitiesRegistryDeployer, err := NewCapabilitiesRegistryDeployer() + if err != nil { + return nil, fmt.Errorf("failed to create CapabilitiesRegistryDeployer: %w", err) + } capabilitiesRegistryResp, err := capabilitiesRegistryDeployer.Deploy(DeployRequest{Chain: chain}) if err != nil { return nil, fmt.Errorf("failed to deploy CapabilitiesRegistry: %w", err) diff --git a/deployment/keystone/changeset/internal/deploy.go b/deployment/keystone/changeset/internal/deploy.go index e8c29ba6222..a86e08f9a19 100644 --- a/deployment/keystone/changeset/internal/deploy.go +++ b/deployment/keystone/changeset/internal/deploy.go @@ -1,16 +1,13 @@ package internal import ( - "bytes" "context" - "crypto/sha256" "encoding/hex" "errors" "fmt" "math" "math/big" "slices" - "sort" "strings" "time" @@ -280,15 +277,15 @@ func ConfigureRegistry(ctx context.Context, lggr logger.Logger, req *ConfigureRe }) } - nodeIdToP2PID := map[string][32]byte{} + nodeIDToP2PID := map[string][32]byte{} for nodeID, params := range nodesResp.NodeIDToParams { - nodeIdToP2PID[nodeID] = params.P2pId + nodeIDToP2PID[nodeID] = params.P2pId } // register DONS donsResp, err := RegisterDons(lggr, RegisterDonsRequest{ Env: req.Env, RegistryChainSelector: req.RegistryChainSel, - NodeIDToP2PID: nodeIdToP2PID, + NodeIDToP2PID: nodeIDToP2PID, DonToCapabilities: donToCapabilities, DonsToRegister: donsToRegister, }) @@ -802,17 +799,6 @@ type RegisterDonsResponse struct { Ops *mcmstypes.BatchOperation } -func sortedHash(p2pids [][32]byte) string { - sha256Hash := sha256.New() - sort.Slice(p2pids, func(i, j int) bool { - return bytes.Compare(p2pids[i][:], p2pids[j][:]) < 0 - }) - for _, id := range p2pids { - sha256Hash.Write(id[:]) - } - return hex.EncodeToString(sha256Hash.Sum(nil)) -} - func RegisterDons(lggr logger.Logger, req RegisterDonsRequest) (*RegisterDonsResponse, error) { if err := req.Validate(); err != nil { return nil, fmt.Errorf("invalid request: %w", err) @@ -831,7 +817,7 @@ func RegisterDons(lggr logger.Logger, req RegisterDonsRequest) (*RegisterDonsRes lggr.Infow("registering DONs...", "len", len(req.DonsToRegister)) // track hash of sorted p2pids to don name because the registry return value does not include the don name // and we need to map it back to the don name to access the other mapping data such as the don's capabilities & nodes - p2pIdsToDon := make(map[string]string) + p2pIDsToDon := make(map[string]string) var addedDons = 0 donInfos, err := registry.GetDONs(&bind.CallOpts{}) @@ -841,13 +827,13 @@ func RegisterDons(lggr logger.Logger, req RegisterDonsRequest) (*RegisterDonsRes } existingDONs := make(map[string]struct{}) for _, donInfo := range donInfos { - existingDONs[sortedHash(donInfo.NodeP2PIds)] = struct{}{} + existingDONs[SortedHash(donInfo.NodeP2PIds)] = struct{}{} } lggr.Infow("fetched existing DONs...", "len", len(donInfos), "lenByNodesHash", len(existingDONs)) transactions := make([]mcmstypes.Transaction, 0) for _, don := range req.DonsToRegister { - var p2pIds [][32]byte + var p2pIDs [][32]byte for _, n := range don.Nodes { if n.IsBootstrap { continue @@ -856,11 +842,11 @@ func RegisterDons(lggr logger.Logger, req RegisterDonsRequest) (*RegisterDonsRes if !ok { return nil, fmt.Errorf("node params not found for non-bootstrap node %s", n.NodeID) } - p2pIds = append(p2pIds, p2pID) + p2pIDs = append(p2pIDs, p2pID) } - p2pSortedHash := sortedHash(p2pIds) - p2pIdsToDon[p2pSortedHash] = don.Name + p2pSortedHash := SortedHash(p2pIDs) + p2pIDsToDon[p2pSortedHash] = don.Name if _, ok := existingDONs[p2pSortedHash]; ok { lggr.Debugw("don already exists, ignoring", "don", don.Name, "p2p sorted hash", p2pSortedHash) @@ -897,8 +883,8 @@ func RegisterDons(lggr logger.Logger, req RegisterDonsRequest) (*RegisterDonsRes } lggr.Debugw("calling add don", "don", don.Name, "p2p sorted hash", p2pSortedHash, "cgs", cfgs, "wfSupported", wfSupported, "f", don.F, - "p2pids", p2pIds, "node count", len(p2pIds)) - tx, err := registry.AddDON(txOpts, p2pIds, cfgs, true, wfSupported, don.F) + "p2pids", p2pIDs, "node count", len(p2pIDs)) + tx, err := registry.AddDON(txOpts, p2pIDs, cfgs, true, wfSupported, don.F) if err != nil { err = cldf.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err) return nil, fmt.Errorf("failed to call AddDON for don '%s' p2p2Id hash %s capability %v: %w", don.Name, p2pSortedHash, cfgs, err) @@ -942,13 +928,12 @@ func RegisterDons(lggr logger.Logger, req RegisterDonsRequest) (*RegisterDonsRes for i := range 10 { lggr.Debugw("attempting to get DONs from registry", "attempt#", i) donInfos, err = registry.GetDONs(&bind.CallOpts{}) - if !containsAllDONs(donInfos, p2pIdsToDon) { - lggr.Debugw("some expected dons not registered yet, re-checking after a delay ...") - time.Sleep(2 * time.Second) - } else { + if containsAllDONs(donInfos, p2pIDsToDon) { foundAll = true break } + lggr.Debugw("some expected dons not registered yet, re-checking after a delay ...") + time.Sleep(2 * time.Second) } if err != nil { err = cldf.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err) @@ -962,9 +947,9 @@ func RegisterDons(lggr logger.Logger, req RegisterDonsRequest) (*RegisterDonsRes DonInfos: make(map[string]capabilities_registry.CapabilitiesRegistryDONInfo), } for i, donInfo := range donInfos { - donName, ok := p2pIdsToDon[sortedHash(donInfo.NodeP2PIds)] + donName, ok := p2pIDsToDon[SortedHash(donInfo.NodeP2PIds)] if !ok { - lggr.Debugw("irrelevant DON found in the registry, ignoring", "p2p sorted hash", sortedHash(donInfo.NodeP2PIds)) + lggr.Debugw("irrelevant DON found in the registry, ignoring", "p2p sorted hash", SortedHash(donInfo.NodeP2PIds)) continue } lggr.Debugw("adding don info to the response (keyed by DON name)", "don", donName) @@ -974,16 +959,16 @@ func RegisterDons(lggr logger.Logger, req RegisterDonsRequest) (*RegisterDonsRes return &resp, nil } -// are all DONs from p2pIdsToDon in donInfos -func containsAllDONs(donInfos []capabilities_registry.CapabilitiesRegistryDONInfo, p2pIdsToDon map[string]string) bool { +// are all DONs from p2pIDsToDon in donInfos +func containsAllDONs(donInfos []capabilities_registry.CapabilitiesRegistryDONInfo, p2pIDsToDon map[string]string) bool { found := make(map[string]struct{}) for _, donInfo := range donInfos { - hash := sortedHash(donInfo.NodeP2PIds) - if _, ok := p2pIdsToDon[hash]; ok { + hash := SortedHash(donInfo.NodeP2PIds) + if _, ok := p2pIDsToDon[hash]; ok { found[hash] = struct{}{} } } - return len(found) == len(p2pIdsToDon) + return len(found) == len(p2pIDsToDon) } type ForwarderConfig struct { diff --git a/deployment/keystone/changeset/internal/state_mcms.go b/deployment/keystone/changeset/internal/state_mcms.go index b72d169c616..52341dca29a 100644 --- a/deployment/keystone/changeset/internal/state_mcms.go +++ b/deployment/keystone/changeset/internal/state_mcms.go @@ -19,6 +19,7 @@ import ( // for a MCMSWithTimelock contract deployment. // It is public for use in product specific packages. // Either all fields are nil or all fields are non-nil. +// // Deprecated: use MCMSWithTimelockState from deployment/common/changeset/state/evm.go instead // if you are changing this, please make the similar changes in deployment/common/changeset/state type MCMSWithTimelockState struct { @@ -33,6 +34,7 @@ type MCMSWithTimelockState struct { // - Found but was unable to load a contract // - It only found part of the bundle of contracts // - If found more than one instance of a contract (we expect one bundle in the given addresses) +// // Deprecated: use MaybeLoadMCMSWithTimelockChainState from deployment/common/changeset/state/evm.go instead // if you are changing this, please make the similar changes in deployment/common/changeset/state func MaybeLoadMCMSWithTimelockChainState( diff --git a/deployment/keystone/changeset/internal/types.go b/deployment/keystone/changeset/internal/types.go index 46a83e13863..0b84916b216 100644 --- a/deployment/keystone/changeset/internal/types.go +++ b/deployment/keystone/changeset/internal/types.go @@ -19,7 +19,6 @@ import ( "github.com/smartcontractkit/chainlink/deployment" - capabilities_registry "github.com/smartcontractkit/chainlink-evm/gethwrappers/keystone/generated/capabilities_registry_1_1_0" kcr "github.com/smartcontractkit/chainlink-evm/gethwrappers/keystone/generated/capabilities_registry_1_1_0" "github.com/smartcontractkit/chainlink-common/keystore/corekeys/p2pkey" @@ -52,11 +51,11 @@ type DonNode struct { type CapabilityHost struct { NodeID string // globally unique - Capabilities []capabilities_registry.CapabilitiesRegistryCapability + Capabilities []kcr.CapabilitiesRegistryCapability } type Nop struct { - capabilities_registry.CapabilitiesRegistryNodeOperator + kcr.CapabilitiesRegistryNodeOperator NodeIDs []string // nodes run by this operator } @@ -123,15 +122,15 @@ func (v DonCapabilities) Validate() error { return nil } -func NodeOperator(name string, adminAddress string) capabilities_registry.CapabilitiesRegistryNodeOperator { - return capabilities_registry.CapabilitiesRegistryNodeOperator{ +func NodeOperator(name string, adminAddress string) kcr.CapabilitiesRegistryNodeOperator { + return kcr.CapabilitiesRegistryNodeOperator{ Name: name, Admin: adminAddr(adminAddress), } } -func NopsToNodes(donInfos []DonInfo, dons []DonCapabilities, chainSelector uint64) (map[capabilities_registry.CapabilitiesRegistryNodeOperator][]string, error) { - out := make(map[capabilities_registry.CapabilitiesRegistryNodeOperator][]string) +func NopsToNodes(donInfos []DonInfo, dons []DonCapabilities, chainSelector uint64) (map[kcr.CapabilitiesRegistryNodeOperator][]string, error) { + out := make(map[kcr.CapabilitiesRegistryNodeOperator][]string) for _, don := range dons { for _, nop := range don.Nops { idx := slices.IndexFunc(donInfos, func(donInfo DonInfo) bool { @@ -210,7 +209,7 @@ func MapDonsToNodes(dons []DonInfo, excludeBootstraps bool, registryChainSel uin // RegisteredDon is a representation of a don that exists in the in the capabilities registry all with the enriched node data type RegisteredDon struct { Name string - Info capabilities_registry.CapabilitiesRegistryDONInfo + Info kcr.CapabilitiesRegistryDONInfo Nodes []deployment.Node } @@ -218,7 +217,7 @@ type RegisteredDonConfig struct { Name string NodeIDs []string // ids in the offchain client RegistryChainSel uint64 - Registry *capabilities_registry.CapabilitiesRegistry + Registry *kcr.CapabilitiesRegistry } func NewRegisteredDon(env cldf.Environment, cfg RegisteredDonConfig) (*RegisteredDon, error) { @@ -252,10 +251,10 @@ func NewRegisteredDon(env cldf.Environment, cfg RegisteredDonConfig) (*Registere if err != nil { return nil, fmt.Errorf("failed to get node info: %w", err) } - want := sortedHash(nodes.PeerIDs()) + want := SortedHash(nodes.PeerIDs()) var don *kcr.CapabilitiesRegistryDONInfo for i, d := range di { - got := sortedHash(d.NodeP2PIds) + got := SortedHash(d.NodeP2PIds) if got == want { don = &di[i] } diff --git a/deployment/keystone/changeset/internal/update_nodes.go b/deployment/keystone/changeset/internal/update_nodes.go index fdb4cd0220c..816fad801ce 100644 --- a/deployment/keystone/changeset/internal/update_nodes.go +++ b/deployment/keystone/changeset/internal/update_nodes.go @@ -198,12 +198,12 @@ func AppendCapabilities(lggr logger.Logger, registry *kcr.CapabilitiesRegistry, func makeNodeParams(registry *kcr.CapabilitiesRegistry, p2pToUpdates map[p2pkey.PeerID]NodeUpdate) ([]kcr.CapabilitiesRegistryNodeParams, error) { var out []kcr.CapabilitiesRegistryNodeParams - var p2pIds []p2pkey.PeerID + var p2pIDs []p2pkey.PeerID for p2pID := range p2pToUpdates { - p2pIds = append(p2pIds, p2pID) + p2pIDs = append(p2pIDs, p2pID) } - nodes, err := registry.GetNodesByP2PIds(&bind.CallOpts{}, PeerIDsToBytes(p2pIds)) + nodes, err := registry.GetNodesByP2PIds(&bind.CallOpts{}, PeerIDsToBytes(p2pIDs)) if err != nil { err = cldf.DecodeErr(kcr.CapabilitiesRegistryABI, err) return nil, fmt.Errorf("failed to get nodes by p2p ids: %w", err) @@ -216,7 +216,7 @@ func makeNodeParams(registry *kcr.CapabilitiesRegistry, ids := node.HashedCapabilityIds if len(updates.Capabilities) > 0 { - is, err := capabilityIds(registry, updates.Capabilities) + is, err := capabilityIDs(registry, updates.Capabilities) if err != nil { return nil, fmt.Errorf("failed to get capability ids: %w", err) } @@ -261,7 +261,7 @@ func makeNodeParams(registry *kcr.CapabilitiesRegistry, return out, nil } -func capabilityIds(registry *kcr.CapabilitiesRegistry, caps []kcr.CapabilitiesRegistryCapability) ([][32]byte, error) { +func capabilityIDs(registry *kcr.CapabilitiesRegistry, caps []kcr.CapabilitiesRegistryCapability) ([][32]byte, error) { out := make([][32]byte, len(caps)) for i, cap := range caps { id, err := registry.GetHashedCapabilityId(&bind.CallOpts{}, cap.LabelledName, cap.Version) diff --git a/deployment/keystone/changeset/operations/contracts/deploy_capability_registry_op.go b/deployment/keystone/changeset/operations/contracts/deploy_capability_registry_op.go index a0af6be2fa3..2d3f338b289 100644 --- a/deployment/keystone/changeset/operations/contracts/deploy_capability_registry_op.go +++ b/deployment/keystone/changeset/operations/contracts/deploy_capability_registry_op.go @@ -39,7 +39,7 @@ var DeployCapabilityRegistryOp = operations.NewOperation[DeployCapabilityRegistr } return DeployCapabilityRegistryOutput{ Addresses: capabilityRegistryOutput.DataStore.Addresses(), - AddressBook: capabilityRegistryOutput.AddressBook, //nolint:staticcheck // keeping the address book since not everything has been migrated to datastore + AddressBook: capabilityRegistryOutput.AddressBook, }, nil }, ) diff --git a/deployment/keystone/changeset/operations/contracts/deploy_configure_forwarders_seq.go b/deployment/keystone/changeset/operations/contracts/deploy_configure_forwarders_seq.go index 7e3e239c196..bf6075b26fe 100644 --- a/deployment/keystone/changeset/operations/contracts/deploy_configure_forwarders_seq.go +++ b/deployment/keystone/changeset/operations/contracts/deploy_configure_forwarders_seq.go @@ -148,7 +148,8 @@ var DeployConfigureForwardersSeq = operations.NewSequence[DeployConfigureForward proposal, err := proposeutils.BuildProposalFromBatchesV2( *deps.Env, timelockAddressByChain, proposerAddressByChain, inspectorPerChain, - batches, "Transfer ownership to timelock", *input.MCMSConfig) + batches, "Transfer ownership to timelock", *input.MCMSConfig, + ) if err != nil { return DeployConfigureForwardersSeqOutput{AddressBook: ab, Addresses: as.Addresses()}, fmt.Errorf("failed to build proposal for transfer ownership to timelock: %w", err) } @@ -326,6 +327,7 @@ func transferOwnershipOp( return fmt.Errorf("failed to load ownable contract for chain selector %d: %w", target, err) } // transfer ownership to timelock (we send this on chain directly, does not need to go through MCMS) + //nolint:staticcheck // deprecated upstream; replacement op not published yet (see cld-changesets op_transfer_accept_ownership.go) _, err = operations.ExecuteOperation(b, opsevm.OpEVMTransferOwnership, opsevm.OpEVMOwnershipDeps{ Chain: chain, @@ -341,6 +343,7 @@ func transferOwnershipOp( return fmt.Errorf("failed to transfer ownership of forwarder to timelock for chain selector %d: %w", target, err) } // accept ownership as timelock (timelock needs to sign this, so we send it through MCMS) + //nolint:staticcheck // deprecated upstream; replacement op not published yet (see cld-changesets op_transfer_accept_ownership.go) acceptOwnershipReport, err := operations.ExecuteOperation(b, opsevm.OpEVMAcceptOwnership, opsevm.OpEVMOwnershipDeps{ Chain: chain, diff --git a/deployment/keystone/changeset/operations/contracts/deploy_workflow_registry_op.go b/deployment/keystone/changeset/operations/contracts/deploy_workflow_registry_op.go index 99a5dbc3c55..7ee6ea9ab89 100644 --- a/deployment/keystone/changeset/operations/contracts/deploy_workflow_registry_op.go +++ b/deployment/keystone/changeset/operations/contracts/deploy_workflow_registry_op.go @@ -40,7 +40,7 @@ var DeployWorkflowRegistryOp = operations.NewOperation[DeployWorkflowRegistryInp } return DeployWorkflowRegistryOutput{ Addresses: workfloRegistryOutput.DataStore.Addresses(), - AddressBook: workfloRegistryOutput.AddressBook, //nolint:staticcheck // keeping the address book since not everything has been migrated to datastore + AddressBook: workfloRegistryOutput.AddressBook, }, nil }, ) diff --git a/deployment/keystone/changeset/state.go b/deployment/keystone/changeset/state.go index b34133389f6..3507ce7cafb 100644 --- a/deployment/keystone/changeset/state.go +++ b/deployment/keystone/changeset/state.go @@ -45,13 +45,11 @@ type ContractSet struct { func (cs ContractSet) Convert() internal.ContractSet { return internal.ContractSet{ - MCMSWithTimelockState: internal.MCMSWithTimelockState{ - MCMSWithTimelockContracts: cs.MCMSWithTimelockContracts, - }, - Forwarder: cs.Forwarder, - WorkflowRegistry: cs.WorkflowRegistry, - OCR3: cs.OCR3, - CapabilitiesRegistry: cs.CapabilitiesRegistry, + MCMSWithTimelockContracts: cs.MCMSWithTimelockContracts, + Forwarder: cs.Forwarder, + WorkflowRegistry: cs.WorkflowRegistry, + OCR3: cs.OCR3, + CapabilitiesRegistry: cs.CapabilitiesRegistry, } } @@ -116,7 +114,7 @@ func GetContractSets(lggr logger.Logger, req *GetContractSetsRequest) (*GetContr func loadContractSet(lggr logger.Logger, chain cldf_evm.Chain, addresses map[string]cldf.TypeAndVersion) (*ContractSet, error) { var out ContractSet - mcmsWithTimelock, err := internal.MaybeLoadMCMSWithTimelockChainState(chain, addresses) + mcmsWithTimelock, err := internal.MaybeLoadMCMSWithTimelockChainState(chain, addresses) //nolint:staticcheck // SA1019 MaybeLoadMCMSWithTimelockChainState is deprecated if err != nil { return nil, fmt.Errorf("failed to load mcms contract: %w", err) } diff --git a/deployment/keystone/changeset/test/env_setup.go b/deployment/keystone/changeset/test/env_setup.go index bc8c0e0d1b0..9d6cb42bf33 100644 --- a/deployment/keystone/changeset/test/env_setup.go +++ b/deployment/keystone/changeset/test/env_setup.go @@ -81,9 +81,11 @@ type testEnvIface interface { } // TODO: separate the config into different types; wf should expand to types of ocr keybundles; writer to target chains; ... -type WFDonConfig = DonConfig -type AssetDonConfig = DonConfig -type WriterDonConfig = DonConfig +type ( + WFDonConfig = DonConfig + AssetDonConfig = DonConfig + WriterDonConfig = DonConfig +) type EnvWrapperConfig struct { WFDonConfig @@ -345,11 +347,11 @@ func setupTestEnv(t *testing.T, c EnvWrapperConfig) EnvWrapper { }, } - var ocr3Config = ocr3.OracleConfig{ + ocr3Config := ocr3.OracleConfig{ MaxFaultyOracles: dons.Get(c.WFDonConfig.Name).F(), TransmissionSchedule: []int{dons.Get(c.WFDonConfig.Name).N()}, } - var allDons = []internal.DonCapabilities{wfDonCapabilities, cwDonCapabilities, assetDonCapabilities} + allDons := []internal.DonCapabilities{wfDonCapabilities, cwDonCapabilities, assetDonCapabilities} csOut, err := changeset.ConfigureInitialContractsChangeset(env, changeset.InitialContractsCfg{ RegistryChainSel: registryChainSel, diff --git a/deployment/keystone/changeset/test/registry.go b/deployment/keystone/changeset/test/registry.go index 76190913c2c..8adda264d96 100644 --- a/deployment/keystone/changeset/test/registry.go +++ b/deployment/keystone/changeset/test/registry.go @@ -211,7 +211,7 @@ func ToP2PToCapabilities( t.Helper() out := make(map[p2pkey.PeerID][][32]byte) for p2pID := range in { - out[p2pID] = mustCapabilityIds(t, registry, caps) + out[p2pID] = mustCapabilityIDs(t, registry, caps) } return out } @@ -307,7 +307,7 @@ func addDons( } } -func defaultCapConfig(t *testing.T, cap capabilities_registry.CapabilitiesRegistryCapability) []byte { +func defaultCapConfig(t *testing.T, c capabilities_registry.CapabilitiesRegistryCapability) []byte { empty := &capabilitiespb.CapabilityConfig{ DefaultConfig: values.Proto(values.EmptyMap()).GetMapValue(), } @@ -319,13 +319,13 @@ func defaultCapConfig(t *testing.T, cap capabilities_registry.CapabilitiesRegist // CapabilityCache tracks registered capabilities by name type CapabilityCache struct { t *testing.T - nameToId map[string][32]byte + nameToID map[string][32]byte } func NewCapabilityCache(t *testing.T, registry *capabilities_registry.CapabilitiesRegistry) *CapabilityCache { cache := &CapabilityCache{ t: t, - nameToId: make(map[string][32]byte), + nameToID: make(map[string][32]byte), } caps, err := registry.GetCapabilities(nil) require.NoError(t, err) @@ -337,12 +337,12 @@ func NewCapabilityCache(t *testing.T, registry *capabilities_registry.Capabiliti } id, err := registry.GetHashedCapabilityId(&bind.CallOpts{}, c.LabelledName, c.Version) require.NoError(t, err) - cache.nameToId[internal.CapabilityID(c)] = id + cache.nameToID[internal.CapabilityID(c)] = id } return cache } func (cc *CapabilityCache) Get(c capabilities_registry.CapabilitiesRegistryCapability) ([32]byte, bool) { - id, exists := cc.nameToId[internal.CapabilityID(c)] + id, exists := cc.nameToID[internal.CapabilityID(c)] return id, exists } @@ -356,7 +356,7 @@ func (cc *CapabilityCache) AddCapabilities(_ logger.Logger, chain cldf_evm.Chain seen := make(map[capabilities_registry.CapabilitiesRegistryCapability]struct{}) var toRegister []capabilities_registry.CapabilitiesRegistryCapability for _, c := range capabilities { - id, cached := cc.nameToId[internal.CapabilityID(c)] + id, cached := cc.nameToID[internal.CapabilityID(c)] if cached { out = append(out, internal.RegisteredCapability{ CapabilitiesRegistryCapability: c, @@ -392,7 +392,7 @@ func (cc *CapabilityCache) AddCapabilities(_ logger.Logger, chain cldf_evm.Chain Config: GetDefaultCapConfig(t, capb), }) // cache the id - cc.nameToId[internal.CapabilityID(capb)] = id + cc.nameToID[internal.CapabilityID(capb)] = id } return out } @@ -406,7 +406,7 @@ func testChain(t *testing.T) cldf_evm.Chain { return chains[0].(cldf_evm.Chain) } -func capabilityIds(registry *capabilities_registry.CapabilitiesRegistry, rcs []internal.RegisteredCapability) ([][32]byte, error) { +func capabilityIDs(registry *capabilities_registry.CapabilitiesRegistry, rcs []internal.RegisteredCapability) ([][32]byte, error) { out := make([][32]byte, len(rcs)) for i := range rcs { id, err := registry.GetHashedCapabilityId(&bind.CallOpts{}, rcs[i].LabelledName, rcs[i].Version) @@ -418,9 +418,9 @@ func capabilityIds(registry *capabilities_registry.CapabilitiesRegistry, rcs []i return out, nil } -func mustCapabilityIds(t *testing.T, registry *capabilities_registry.CapabilitiesRegistry, rcs []internal.RegisteredCapability) [][32]byte { +func mustCapabilityIDs(t *testing.T, registry *capabilities_registry.CapabilitiesRegistry, rcs []internal.RegisteredCapability) [][32]byte { t.Helper() - out, err := capabilityIds(registry, rcs) + out, err := capabilityIDs(registry, rcs) require.NoError(t, err) return out } diff --git a/deployment/keystone/changeset/update_node_capabilities_test.go b/deployment/keystone/changeset/update_node_capabilities_test.go index ff210902e2a..43efb63b98c 100644 --- a/deployment/keystone/changeset/update_node_capabilities_test.go +++ b/deployment/keystone/changeset/update_node_capabilities_test.go @@ -154,7 +154,7 @@ func getNodeCapabilities(registry *kcr.CapabilitiesRegistry, p2pIDs []p2pkey.Pee if err != nil { panic(err) } - var capMap = make(map[[32]byte]kcr.CapabilitiesRegistryCapability) + capMap := make(map[[32]byte]kcr.CapabilitiesRegistryCapability) for _, c := range caps { capMap[c.HashedId] = kcr.CapabilitiesRegistryCapability{ LabelledName: c.LabelledName, diff --git a/deployment/keystone/changeset/view_test.go b/deployment/keystone/changeset/view_test.go index 8cd4fae5829..27c7dab2c94 100644 --- a/deployment/keystone/changeset/view_test.go +++ b/deployment/keystone/changeset/view_test.go @@ -145,7 +145,6 @@ func TestKeystoneView(t *testing.T) { require.NoError(t, err) require.NotNil(t, resp) require.NoError(t, resp.DataStore.Merge(env.Env.DataStore)) - //nolint:staticcheck // Temporarily using deprecated AddressBook until migration is complete localAddrsBook = resp.AddressBook env.Env.DataStore = resp.DataStore.Seal() @@ -154,7 +153,6 @@ func TestKeystoneView(t *testing.T) { require.NoError(t, err) require.NotNil(t, resp) require.NoError(t, resp.DataStore.Merge(env.Env.DataStore)) - //nolint:staticcheck // Temporarily using deprecated AddressBook until migration is complete require.NoError(t, localAddrsBook.Merge(resp.AddressBook)) env.Env.DataStore = resp.DataStore.Seal() @@ -163,7 +161,6 @@ func TestKeystoneView(t *testing.T) { require.NoError(t, err) require.NotNil(t, resp) require.NoError(t, resp.DataStore.Merge(env.Env.DataStore)) - //nolint:staticcheck // Temporarily using deprecated AddressBook until migration is complete require.NoError(t, localAddrsBook.Merge(resp.AddressBook)) env.Env.DataStore = resp.DataStore.Seal() @@ -172,7 +169,6 @@ func TestKeystoneView(t *testing.T) { require.NoError(t, err) require.NotNil(t, resp) require.NoError(t, resp.DataStore.Merge(env.Env.DataStore)) - //nolint:staticcheck // Temporarily using deprecated AddressBook until migration is complete require.NoError(t, localAddrsBook.Merge(resp.AddressBook)) env.Env.DataStore = resp.DataStore.Seal() @@ -243,18 +239,16 @@ func TestKeystoneView(t *testing.T) { {Capability: internal.OCR3Cap, Config: ocr3CapCfg}, }, } - var allDons = []internal.DonCapabilities{wfDonCapabilities} + allDons := []internal.DonCapabilities{wfDonCapabilities} cr, err := contracts.GetOwnedContractV2[*capabilities_registry.CapabilitiesRegistry]( env.Env.DataStore.Addresses(), env.Env.BlockChains.EVMChains()[env.RegistrySelector], capabilityRegistryAddr, "", ) require.NoError(t, err) _, err = internal.ConfigureRegistry(t.Context(), env.Env.Logger, &internal.ConfigureRegistryRequest{ - ConfigureContractsRequest: internal.ConfigureContractsRequest{ - RegistryChainSel: env.RegistrySelector, - Env: &env.Env, - Dons: allDons, - }, + RegistryChainSel: env.RegistrySelector, + Env: &env.Env, + Dons: allDons, CapabilitiesRegistry: cr.Contract, }, nil) require.NoError(t, err) diff --git a/deployment/keystone/changeset/workflowregistry/update_allowed_dons.go b/deployment/keystone/changeset/workflowregistry/update_allowed_dons.go index 6dd8b32cf2d..4dd79e001bf 100644 --- a/deployment/keystone/changeset/workflowregistry/update_allowed_dons.go +++ b/deployment/keystone/changeset/workflowregistry/update_allowed_dons.go @@ -26,7 +26,7 @@ type UpdateAllowedDonsRequest struct { func (r *UpdateAllowedDonsRequest) Validate() error { if len(r.DonIDs) == 0 { - return errors.New("Must provide at least one DonID") + return errors.New("must provide at least one DonID") } return nil } diff --git a/deployment/keystone/changeset/workflowregistry/update_allowed_dons_test.go b/deployment/keystone/changeset/workflowregistry/update_allowed_dons_test.go index c50b2c1dca0..355b28f7f9b 100644 --- a/deployment/keystone/changeset/workflowregistry/update_allowed_dons_test.go +++ b/deployment/keystone/changeset/workflowregistry/update_allowed_dons_test.go @@ -38,7 +38,8 @@ func TestUpdateAllowedDons(t *testing.T) { BlockChains: cldf_chain.NewBlockChains( map[uint64]cldf_chain.BlockChain{ chainSel: resp.Chain, - }), + }, + ), } _, err = workflowregistry.UpdateAllowedDons( diff --git a/deployment/keystone/changeset/workflowregistry/update_authorized_addresses.go b/deployment/keystone/changeset/workflowregistry/update_authorized_addresses.go index 5fd7d7fe503..11ac267aa7d 100644 --- a/deployment/keystone/changeset/workflowregistry/update_authorized_addresses.go +++ b/deployment/keystone/changeset/workflowregistry/update_authorized_addresses.go @@ -28,7 +28,7 @@ type UpdateAuthorizedAddressesRequest struct { func (r *UpdateAuthorizedAddressesRequest) Validate() error { if len(r.Addresses) == 0 { - return errors.New("Must provide at least 1 address") + return errors.New("must provide at least 1 address") } return nil diff --git a/deployment/keystone/changeset/workflowregistry/update_authorized_addresses_test.go b/deployment/keystone/changeset/workflowregistry/update_authorized_addresses_test.go index a6e5c5b63f9..3df2ca924f9 100644 --- a/deployment/keystone/changeset/workflowregistry/update_authorized_addresses_test.go +++ b/deployment/keystone/changeset/workflowregistry/update_authorized_addresses_test.go @@ -39,7 +39,8 @@ func TestUpdateAuthorizedAddresses(t *testing.T) { BlockChains: cldf_chain.NewBlockChains( map[uint64]cldf_chain.BlockChain{ chainSel: resp.Chain, - }), + }, + ), } addr := "0xc0ffee254729296a45a3885639AC7E10F9d54979" diff --git a/deployment/keystone/changeset/workflowregistry/workflow_registry_deployer.go b/deployment/keystone/changeset/workflowregistry/workflow_registry_deployer.go index e53499159d4..5fdbcc8d569 100644 --- a/deployment/keystone/changeset/workflowregistry/workflow_registry_deployer.go +++ b/deployment/keystone/changeset/workflowregistry/workflow_registry_deployer.go @@ -66,6 +66,9 @@ func (c *workflowRegistryDeployer) Deploy(req changeset.DeployRequest) (*changes // and saves the address in the address book. This mutates the address book. func deployWorkflowRegistry(chain cldf_evm.Chain, ab cldf.AddressBook) (*changeset.DeployResponse, error) { deployer, err := newWorkflowRegistryDeployer() + if err != nil { + return nil, fmt.Errorf("failed to create WorkflowRegistryDeployer: %w", err) + } resp, err := deployer.Deploy(changeset.DeployRequest{Chain: chain}) if err != nil { return nil, fmt.Errorf("failed to deploy WorkflowRegistry: %w", err) diff --git a/deployment/keystone/scripts/main.go b/deployment/keystone/scripts/main.go index 75b7a033e04..3bdb8c5ef4b 100644 --- a/deployment/keystone/scripts/main.go +++ b/deployment/keystone/scripts/main.go @@ -405,7 +405,7 @@ func runJDCommand(cmd *cobra.Command, args []string) error { if !jdFound { jobID, err := cl.CreateJobDistributor(ctx, client.JobDistributorInput{ Name: jdConfig.Name, - Uri: jdConfig.URI, + URI: jdConfig.URI, PublicKey: jdConfig.PublicKey, }) diff --git a/deployment/keystone/test/changeset/capability_registry.go b/deployment/keystone/test/changeset/capability_registry.go index 908e59040d3..c23d7242864 100644 --- a/deployment/keystone/test/changeset/capability_registry.go +++ b/deployment/keystone/test/changeset/capability_registry.go @@ -73,11 +73,11 @@ func HydrateCapabilityRegistry(t *testing.T, v v1_0.CapabilityRegistryView, env if err != nil { return nil, fmt.Errorf("failed to convert capability configurations to capability configuration params: %w", err) } - var peerIds [][32]byte + var peerIDs [][32]byte for _, id := range don.NodeP2PIds { - peerIds = append(peerIds, id) + peerIDs = append(peerIDs, id) } - tx, err = deployedContract.AddDON(chain.DeployerKey, peerIds, cfgs, don.IsPublic, don.AcceptsWorkflows, don.F) + tx, err = deployedContract.AddDON(chain.DeployerKey, peerIDs, cfgs, don.IsPublic, don.AcceptsWorkflows, don.F) if _, err = cldf.ConfirmIfNoError(chain, tx, cldf.DecodeErr(capabilities_registry.CapabilitiesRegistryABI, err)); err != nil { return nil, fmt.Errorf("failed to add don: %w", err) } diff --git a/deployment/tokens/changesets/deploy_evm_link_tokens.go b/deployment/tokens/changesets/deploy_evm_link_tokens.go index 5ad0da7137b..fd6327105af 100644 --- a/deployment/tokens/changesets/deploy_evm_link_tokens.go +++ b/deployment/tokens/changesets/deploy_evm_link_tokens.go @@ -77,7 +77,7 @@ func (deployEVMLinkTokens) Apply( seqDeps = seqs.SeqDeployEVMTokensDeps{ EVMChains: e.BlockChains.EVMChains(), - AddrBook: out.AddressBook, //nolint:staticcheck // Will be removed once the address book is no longer required. + AddrBook: out.AddressBook, Datastore: out.DataStore, } seqInput = seqs.SeqDeployEVMTokensInput{ diff --git a/deployment/tokens/changesets/deploy_sol_link_tokens.go b/deployment/tokens/changesets/deploy_sol_link_tokens.go index 276e7b59392..93ad77aa50e 100644 --- a/deployment/tokens/changesets/deploy_sol_link_tokens.go +++ b/deployment/tokens/changesets/deploy_sol_link_tokens.go @@ -53,7 +53,7 @@ func (deploySolLinkTokens) Apply( seqDeps = seqs.SeqDeploySolTokensDeps{ SolChains: e.BlockChains.SolanaChains(), - AddrBook: out.AddressBook, //nolint:staticcheck // Will be removed once the address book is no longer required. + AddrBook: out.AddressBook, Datastore: out.DataStore, } seqInput = seqs.SeqDeploySolTokensInput{ diff --git a/deployment/utils/nodetestutils/node.go b/deployment/utils/nodetestutils/node.go index c1c61095cfe..e90632d6eb4 100644 --- a/deployment/utils/nodetestutils/node.go +++ b/deployment/utils/nodetestutils/node.go @@ -50,7 +50,6 @@ import ( configv2 "github.com/smartcontractkit/chainlink/v2/core/config/toml" "github.com/smartcontractkit/chainlink/v2/core/logger/audit" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/services/cre" feeds2 "github.com/smartcontractkit/chainlink/v2/core/services/feeds" feedsMocks "github.com/smartcontractkit/chainlink/v2/core/services/feeds/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/keystore" @@ -492,12 +491,10 @@ func NewNode( require.NoError(t, master.OCR2().EnsureKeys(ctx, corekeys.EVM, corekeys.Solana, corekeys.Aptos, corekeys.Stellar)) app, err := chainlink.NewApplication(ctx, chainlink.ApplicationOpts{ - Opts: cre.Opts{ - CapabilitiesRegistry: capreg.NewRegistry(lggr), - }, - Config: cfg, - DS: db, - KeyStore: master, + CapabilitiesRegistry: capreg.NewRegistry(lggr), + Config: cfg, + DS: db, + KeyStore: master, // TODO BCF-2513 Stop injecting ethClient via override, instead use httptest. EVMFactoryConfigFn: func(fc *chainlink.EVMFactoryConfig) { // Create ChainStores that always sign with 1337 diff --git a/deployment/vault/changeset/automation_receiver_set_call_allowed.go b/deployment/vault/changeset/automation_receiver_set_call_allowed.go index c3a431eae9d..9043f8b8fb2 100644 --- a/deployment/vault/changeset/automation_receiver_set_call_allowed.go +++ b/deployment/vault/changeset/automation_receiver_set_call_allowed.go @@ -233,11 +233,9 @@ var SetCallAllowedProposalOperation = operations.NewOperation( ChainSelector: mcmstypes.ChainSelector(input.ChainSelector), Transactions: []mcmstypes.Transaction{ { - OperationMetadata: mcmstypes.OperationMetadata{ - ContractType: vaulttypes.AutomationReceiverContractType, - Tags: []string{ - "setCallAllowed", - }, + ContractType: vaulttypes.AutomationReceiverContractType, + Tags: []string{ + "setCallAllowed", }, To: automationReceiverAddr, Data: setCallAllowedTx.Data(), diff --git a/deployment/vault/changeset/automation_receiver_set_expected_workflow_identity.go b/deployment/vault/changeset/automation_receiver_set_expected_workflow_identity.go index 964f0d1dff2..dc445b2ea7d 100644 --- a/deployment/vault/changeset/automation_receiver_set_expected_workflow_identity.go +++ b/deployment/vault/changeset/automation_receiver_set_expected_workflow_identity.go @@ -231,19 +231,15 @@ var SetExpectedWorkflowIdentityProposalOperation = operations.NewOperation( ChainSelector: mcmstypes.ChainSelector(input.ChainSelector), Transactions: []mcmstypes.Transaction{ { - OperationMetadata: mcmstypes.OperationMetadata{ - ContractType: vaulttypes.AutomationReceiverContractType, - Tags: []string{"setExpectedAuthor"}, - }, + ContractType: vaulttypes.AutomationReceiverContractType, + Tags: []string{"setExpectedAuthor"}, To: automationReceiverAddr, Data: authorTx.Data(), AdditionalFields: json.RawMessage(`{"value": 0}`), }, { - OperationMetadata: mcmstypes.OperationMetadata{ - ContractType: vaulttypes.AutomationReceiverContractType, - Tags: []string{"setExpectedWorkflowName"}, - }, + ContractType: vaulttypes.AutomationReceiverContractType, + Tags: []string{"setExpectedWorkflowName"}, To: automationReceiverAddr, Data: nameTx.Data(), AdditionalFields: json.RawMessage(`{"value": 0}`), diff --git a/deployment/vault/changeset/ethbalmon_accept_ownership.go b/deployment/vault/changeset/ethbalmon_accept_ownership.go index 0d188d05fa1..b90be4f5413 100644 --- a/deployment/vault/changeset/ethbalmon_accept_ownership.go +++ b/deployment/vault/changeset/ethbalmon_accept_ownership.go @@ -178,11 +178,9 @@ var EthBalMonAcceptOwnershipOperation = operations.NewOperation( ChainSelector: mcmstypes.ChainSelector(input.ChainSelector), Transactions: []mcmstypes.Transaction{ { - OperationMetadata: mcmstypes.OperationMetadata{ - ContractType: vaulttypes.EthBalMonContractType, - Tags: []string{ - "acceptOwnership", - }, + ContractType: vaulttypes.EthBalMonContractType, + Tags: []string{ + "acceptOwnership", }, To: ethBalMonAddr, Data: acceptOwnershipTx.Data(), diff --git a/deployment/vault/changeset/ethbalmon_deploy.go b/deployment/vault/changeset/ethbalmon_deploy.go index 55fd22f6e93..a34fae16518 100644 --- a/deployment/vault/changeset/ethbalmon_deploy.go +++ b/deployment/vault/changeset/ethbalmon_deploy.go @@ -26,8 +26,7 @@ const defaultEthBalMonMinWaitPeriodSeconds uint64 = 60 var DeployEthBalMonChangeSet cldf.ChangeSetV2[vaulttypes.DeployEthBalMonInput] = deployEthBalMon{} -type deployEthBalMon struct { -} +type deployEthBalMon struct{} func effectiveMinWaitPeriodSeconds(v uint64) uint64 { if v == 0 { @@ -599,7 +598,6 @@ var DeployEthBalMonContractOperation = operations.NewOperation( ) return out, nil - }, ) @@ -673,7 +671,6 @@ var TransferOwnershipOperation = operations.NewOperation( ) return out, nil - }, ) @@ -742,10 +739,8 @@ func BuildAcceptOwnershipTimelockProposal( ChainSelector: mcmstypes.ChainSelector(chainSelector), Transactions: []mcmstypes.Transaction{ { - OperationMetadata: mcmstypes.OperationMetadata{ - ContractType: vaulttypes.EthBalMonContractType, - Tags: []string{"acceptOwnership"}, - }, + ContractType: vaulttypes.EthBalMonContractType, + Tags: []string{"acceptOwnership"}, To: contractAddr, Data: acceptOwnershipTx.Data(), AdditionalFields: json.RawMessage(`{"value": 0}`), diff --git a/deployment/vault/changeset/ethbalmon_set_keeper_registry_address.go b/deployment/vault/changeset/ethbalmon_set_keeper_registry_address.go index 0b04361232f..879a48399de 100644 --- a/deployment/vault/changeset/ethbalmon_set_keeper_registry_address.go +++ b/deployment/vault/changeset/ethbalmon_set_keeper_registry_address.go @@ -229,11 +229,9 @@ var SetKeeperRegistryOperation = operations.NewOperation( ChainSelector: mcmstypes.ChainSelector(input.ChainSelector), Transactions: []mcmstypes.Transaction{ { - OperationMetadata: mcmstypes.OperationMetadata{ - ContractType: vaulttypes.EthBalMonContractType, - Tags: []string{ - "setKeeperRegistryAddress", - }, + ContractType: vaulttypes.EthBalMonContractType, + Tags: []string{ + "setKeeperRegistryAddress", }, To: ethBalMonAddr, Data: setKeeperRegistryTx.Data(), diff --git a/deployment/vault/changeset/ethbalmon_set_watchlist.go b/deployment/vault/changeset/ethbalmon_set_watchlist.go index 2ad34b7b90f..dd44a4f1c34 100644 --- a/deployment/vault/changeset/ethbalmon_set_watchlist.go +++ b/deployment/vault/changeset/ethbalmon_set_watchlist.go @@ -102,7 +102,6 @@ var EthBalMonSetWatchListSequence = operations.NewSequence( } proposal, err := proposeutils.BuildProposalFromBatchesV2(deps.Environment, timelockAddresses, mcmAddressByChain, nil, batches, "EthBalMon SetWatchList", ethBalMonProposalTimelockConfig(input.MCMSConfig)) - if err != nil { return EthBalMonSetWatchListSeqOutput{}, fmt.Errorf("failed to build timelock proposal: %w", err) } @@ -192,11 +191,9 @@ var EthBalMonSetWatchListOperation = operations.NewOperation( ChainSelector: mcmstypes.ChainSelector(input.ChainSelector), Transactions: []mcmstypes.Transaction{ { - OperationMetadata: mcmstypes.OperationMetadata{ - ContractType: vaulttypes.EthBalMonContractType, - Tags: []string{ - "setWatchList", - }, + ContractType: vaulttypes.EthBalMonContractType, + Tags: []string{ + "setWatchList", }, To: ethBalMonAddr, Data: setWatchListTx.Data(), diff --git a/deployment/vault/changeset/ethbalmon_transfer_ownership.go b/deployment/vault/changeset/ethbalmon_transfer_ownership.go index b0d18228627..186b6a48e7a 100644 --- a/deployment/vault/changeset/ethbalmon_transfer_ownership.go +++ b/deployment/vault/changeset/ethbalmon_transfer_ownership.go @@ -96,7 +96,6 @@ var EthBalMonTransferOwnershipSequence = operations.NewSequence( } proposal, err := proposeutils.BuildProposalFromBatchesV2(deps.Environment, timelockAddresses, mcmAddressByChain, nil, batches, "EthBalMon transferOwnership", ethBalMonProposalTimelockConfig(input.MCMSConfig)) - if err != nil { return EthBalMonTransferOwnershipSeqOutput{}, fmt.Errorf("failed to build timelock proposal: %w", err) } @@ -180,11 +179,9 @@ var EthBalMonTransferOwnershipOperation = operations.NewOperation( ChainSelector: mcmstypes.ChainSelector(input.ChainSelector), Transactions: []mcmstypes.Transaction{ { - OperationMetadata: mcmstypes.OperationMetadata{ - ContractType: vaulttypes.EthBalMonContractType, - Tags: []string{ - "transferOwnership", - }, + ContractType: vaulttypes.EthBalMonContractType, + Tags: []string{ + "transferOwnership", }, To: ethBalMonAddr, Data: transferOwnershipTx.Data(), diff --git a/deployment/vault/changeset/ethbalmon_withdraw.go b/deployment/vault/changeset/ethbalmon_withdraw.go index b1e6d3bfedf..8648bd36b0f 100644 --- a/deployment/vault/changeset/ethbalmon_withdraw.go +++ b/deployment/vault/changeset/ethbalmon_withdraw.go @@ -98,7 +98,6 @@ var EthBalMonWithdrawSequence = operations.NewSequence( } proposal, err := proposeutils.BuildProposalFromBatchesV2(deps.Environment, timelockAddresses, mcmAddressByChain, nil, batches, "EthBalMon Withdraw", ethBalMonProposalTimelockConfig(input.MCMSConfig)) - if err != nil { return EthBalMonWithdrawSeqOutput{}, fmt.Errorf("failed to build timelock proposal: %w", err) } @@ -183,11 +182,9 @@ var EthBalMonWithdrawOperation = operations.NewOperation( ChainSelector: mcmstypes.ChainSelector(input.ChainSelector), Transactions: []mcmstypes.Transaction{ { - OperationMetadata: mcmstypes.OperationMetadata{ - ContractType: vaulttypes.EthBalMonContractType, - Tags: []string{ - "withdraw", - }, + ContractType: vaulttypes.EthBalMonContractType, + Tags: []string{ + "withdraw", }, To: ethBalMonAddr, Data: withdrawTx.Data(), diff --git a/system-tests/lib/cre/don.go b/system-tests/lib/cre/don.go index fa1bf36dc92..5d918a816f8 100644 --- a/system-tests/lib/cre/don.go +++ b/system-tests/lib/cre/don.go @@ -790,7 +790,7 @@ func (n *Node) CreateJobDistributor(ctx context.Context, jd *jd.JobDistributor) } return n.Clients.GQLClient.CreateJobDistributor(ctx, client.JobDistributorInput{ Name: "Job Distributor", - Uri: jd.WSRPC, + URI: jd.WSRPC, PublicKey: csaKey, }) } From 9bb04449c87a12a9a45286b24ea512c2b78ab8a2 Mon Sep 17 00:00:00 2001 From: chainchad <96362174+chainchad@users.noreply.github.com> Date: Tue, 29 Sep 2026 19:47:23 +0000 Subject: [PATCH 3/3] Create new deploy job for releases (#23846) * Create new deploy job for releases * Use self repository syntax to reference action --- .../actions/dispatch-release-fanout/README.md | 46 +++++++ .../dispatch-release-fanout/action.yml | 118 ++++++++++++++++++ .github/workflows/build-publish.yml | 31 +++++ 3 files changed, 195 insertions(+) create mode 100644 .github/actions/dispatch-release-fanout/README.md create mode 100644 .github/actions/dispatch-release-fanout/action.yml diff --git a/.github/actions/dispatch-release-fanout/README.md b/.github/actions/dispatch-release-fanout/README.md new file mode 100644 index 00000000000..4e42bf34b8b --- /dev/null +++ b/.github/actions/dispatch-release-fanout/README.md @@ -0,0 +1,46 @@ +# dispatch-release-fanout + +Tells the internal deployment hub which images a release published. The hub +classifies each tag into a release channel and dispatches the image-bump +workflow in every deployment repo subscribed to that `(stream, channel)`, which +opens the tag-bump PR there. + +One dispatch carries every image the build published. This repo holds no +deployment topology: which repo consumes `core` vs `ccip`, and which channel +each environment tracks, is configured in the hub and in the deployment repos. + +```yaml +- uses: ./.github/actions/dispatch-release-fanout + with: + gati-profile: ${{ secrets.GATI_PROFILE_IMAGE_BUMP_HUB }} + hub-repo: ${{ secrets.REPO_IMAGE_BUMP_HUB }} + images: | + core=2.65.1-rc.0 + ccip=2.65.1-ccip-rc.0 +``` + +## Required secrets + +This repository is public and the hub is internal, so neither the hub's name +nor the GATI profile that names it is committed here. + +| Secret | Value | +| ------------------------------ | --------------------------------------------------------------------------- | +| `REPO_IMAGE_BUMP_HUB` | `owner/name` of the hub repository | +| `GATI_PROFILE_IMAGE_BUMP_HUB` | GATI v2 profile granting `actions:write` on that repo (a `presets/…` entry) | + +The calling job needs `id-token: write` — the profile is minted from this +repository's OIDC identity, and grants nothing beyond starting one workflow in +the hub. It cannot read or write any repository's contents. + +## Behaviour + +- `images` entries with an empty tag are dropped, so a caller can pass an image + whose build failed or was skipped without special-casing it. If every entry + is empty the action warns and exits 0 without dispatching. +- A tag which is unrecognized by the hub for its stream is *not routed* + and does not fail: the hub warns and still delivers the other images in the + same dispatch. +- The dispatch is fire-and-forget. It returns as soon as the hub accepts it, + and reports nothing about what the hub did — read the hub's own run, linked + by the `correlation-id` in this action's job summary. diff --git a/.github/actions/dispatch-release-fanout/action.yml b/.github/actions/dispatch-release-fanout/action.yml new file mode 100644 index 00000000000..d442c5d470b --- /dev/null +++ b/.github/actions/dispatch-release-fanout/action.yml @@ -0,0 +1,118 @@ +name: dispatch-release-fanout +description: + "Tell the internal deployment hub which images this release published, so it + can open image-bump PRs in the deployment repos subscribed to them" + +# The hub classifies each tag into a release channel (beta / rc / stable) and +# dispatches each subscribed deployment repo's own image-bump workflow. One +# dispatch carries every image a build published; the hub decides what is +# routed where, so this repo holds no deployment topology. +# +# The hub repository is internal and this repository is public, so its name and +# the GATI profile that reaches it are both supplied from secrets rather than +# committed here. See the README next to this file. + +inputs: + gati-profile: + description: + "GATI v2 token profile granting actions:write on the hub repository. + Supply from a secret." + required: true + hub-repo: + description: + "owner/name of the hub repository to dispatch. Supply from a secret." + required: true + hub-workflow: + description: "Workflow file in the hub to dispatch." + required: false + default: "fanout.yaml" + hub-ref: + description: + "Branch in the hub to run the workflow from. The hub's own credentials + are pinned to its default branch, so overriding this will fail its token + request." + required: false + default: "main" + producer: + description: + "Producer key the hub routes on. Must match a producers/.yaml entry + in the hub." + required: false + default: "smartcontractkit/chainlink" + images: + description: | + Multiline `stream=tag` pairs, one per image this build published: + + core=2.65.1-rc.0 + ccip=2.65.1-ccip-rc.0 + + `stream` must be declared by the producer in the hub. Entries with an + empty tag are dropped, so a caller can pass an image whose build was + skipped or failed without special-casing it. + required: true + correlation-id: + description: + "Opaque id traversing along every hop of the fan-out. Defaults to this + run." + required: false + source-run-url: + description: "URL of this run, recorded by every downstream hop." + required: false + +runs: + using: composite + steps: + - name: Setup GitHub Token + id: setup-github-token + uses: smartcontractkit/.github/actions/setup-github-token@setup-github-token/v1 + with: + profile: ${{ inputs.gati-profile }} + + - name: Dispatch fan-out + shell: bash + env: + GH_TOKEN: ${{ steps.setup-github-token.outputs.access-token }} + HUB_REPO: ${{ inputs.hub-repo }} + HUB_WORKFLOW: ${{ inputs.hub-workflow }} + HUB_REF: ${{ inputs.hub-ref }} + PRODUCER: ${{ inputs.producer }} + IMAGES: ${{ inputs.images }} + CORRELATION_ID: ${{ inputs.correlation-id }} + SOURCE_RUN_URL: ${{ inputs.source-run-url }} + run: | + set -euo pipefail + + images_json="$(printf '%s\n' "${IMAGES}" | jq -Rn -c ' + [ inputs + | gsub("^\\s+|\\s+$"; "") + | select(length > 0) + | split("=") + | select(length == 2 and (.[1] | length) > 0) + | {stream: .[0], tag: .[1]} + ]')" + + if [[ "${images_json}" == "[]" ]]; then + echo "::warning::No published images to fan out; nothing dispatched." + exit 0 + fi + + correlation_id="${CORRELATION_ID:-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}}" + source_run_url="${SOURCE_RUN_URL:-${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}}" + + gh workflow run "${HUB_WORKFLOW}" \ + --repo "${HUB_REPO}" \ + --ref "${HUB_REF}" \ + --field "producer=${PRODUCER}" \ + --field "images=${images_json}" \ + --field "correlation-id=${correlation_id}" \ + --field "source-run-url=${source_run_url}" + + { + echo "### Release fan-out dispatched" + echo + echo "| field | value |" + echo "| --- | --- |" + echo "| producer | \`${PRODUCER}\` |" + echo "| images | \`${images_json}\` |" + echo "| correlation-id | \`${correlation_id}\` |" + } | tee -a "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/build-publish.yml b/.github/workflows/build-publish.yml index 0e31768235c..d92272bafe8 100644 --- a/.github/workflows/build-publish.yml +++ b/.github/workflows/build-publish.yml @@ -228,6 +228,37 @@ jobs: repo-destination: ${{ secrets.REPO_K8S_DEPLOY }} oci-image-tag: ${{ needs.docker-core.outputs.docker-manifest-tag }} + # Hand every image this build published to the deployment hub, which opens + # the tag-bump PRs in the deployment repos subscribed to them. + # + # This will eventually replace the `deploy` job in this workflow. + dispatch-release-fanout: + name: "Dispatch release fan-out" + needs: [checks, docker-core, docker-ccip] + # Fans out whatever published. Either image alone is a valid dispatch: the + # action drops the empty entry, and the hub routes per stream. + # + # !cancelled() rather than always(): a cancelled release must not go on to + # request deployment PRs for the images it had already pushed. + if: | + !cancelled() && ( + needs.docker-core.result == 'success' || + needs.docker-ccip.result == 'success' + ) + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - name: Dispatch release fan-out + uses: $/.github/actions/dispatch-release-fanout + with: + gati-profile: ${{ secrets.GATI_PROFILE_IMAGE_BUMP_HUB }} + hub-repo: ${{ secrets.REPO_IMAGE_BUMP_HUB }} + images: | + core=${{ needs.docker-core.result == 'success' && needs.docker-core.outputs.docker-manifest-tag || '' }} + ccip=${{ needs.docker-ccip.result == 'success' && needs.docker-ccip.outputs.docker-manifest-tag || '' }} + # Notify Slack channel for new git tags associated with pre-releases. # Final release notifications originate from the release coordinator repo. slack-notify: