From f6e3f68ff468fd7f6ea1093743641c3b805f8832 Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Thu, 12 Dec 2024 11:48:44 -0800 Subject: [PATCH 01/29] chore: update go-conditional-tests to 0.2.0 (#15652) --- .github/workflows/ci-core-partial.yml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-core-partial.yml b/.github/workflows/ci-core-partial.yml index c9752d4e1e4..35f689090e8 100644 --- a/.github/workflows/ci-core-partial.yml +++ b/.github/workflows/ci-core-partial.yml @@ -46,6 +46,7 @@ jobs: permissions: id-token: write contents: write + actions: write strategy: fail-fast: false matrix: @@ -86,7 +87,7 @@ jobs: go-mod-download-directory: ${{ matrix.type.test-suite == 'ccip-deployment' && matrix.type.module-directory || '' }} - name: Build Tests - uses: smartcontractkit/.github/apps/go-conditional-tests@37882e110590e636627a26371bdbd56ddfcce821 # go-conditional-tests@0.1.0 + uses: smartcontractkit/.github/apps/go-conditional-tests@57f99fbea73056c490c766d50ef582a13ec4f3bb # go-conditional-tests@0.2.0 timeout-minutes: 10 with: pipeline-step: "build" @@ -98,7 +99,7 @@ jobs: build-flags: ${{ matrix.type.build-flags }} - name: Run Tests - uses: smartcontractkit/.github/apps/go-conditional-tests@37882e110590e636627a26371bdbd56ddfcce821 # go-conditional-tests@0.1.0 + uses: smartcontractkit/.github/apps/go-conditional-tests@57f99fbea73056c490c766d50ef582a13ec4f3bb # go-conditional-tests@0.2.0 timeout-minutes: 15 env: CL_DATABASE_URL: ${{ env.DB_URL }} @@ -112,7 +113,7 @@ jobs: github-token: ${{ secrets.GITHUB_TOKEN }} - name: Update Test Index - uses: smartcontractkit/.github/apps/go-conditional-tests@37882e110590e636627a26371bdbd56ddfcce821 # go-conditional-tests@0.1.0 + uses: smartcontractkit/.github/apps/go-conditional-tests@57f99fbea73056c490c766d50ef582a13ec4f3bb # go-conditional-tests@0.2.0 with: pipeline-step: "update" collect-coverage: ${{ needs.filter.outputs.should-collect-coverage }} @@ -130,7 +131,7 @@ jobs: if: ${{ needs.filter.outputs.should-collect-coverage == 'true' }} runs-on: ubuntu-latest steps: - - name: Checkout the repo + - name: Checkout the repo uses: actions/checkout@v4.2.1 with: # fetches all history for all tags and branches to provide more metadata for sonar reports From 52c2db4bff51a5aa2cd67e1c3af71023f1e295de Mon Sep 17 00:00:00 2001 From: "Simon B.Robert" Date: Thu, 12 Dec 2024 15:25:12 -0500 Subject: [PATCH 02/29] Support RMN for CCIP v2 view (#15611) * Support RMN for CCIP v2 view * Write hex strings instead of bytes * Add contract address in error message --- deployment/ccip/changeset/state.go | 9 ++ deployment/ccip/view/v1_6/rmnhome.go | 214 +++++++++++++++++++++++++++ deployment/ccip/view/view.go | 2 + 3 files changed, 225 insertions(+) create mode 100644 deployment/ccip/view/v1_6/rmnhome.go diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index af982f35e0a..45ea9e8f5b8 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -161,6 +161,15 @@ func (c CCIPChainState) GenerateView() (view.ChainView, error) { } chainView.RMN[c.RMNRemote.Address().Hex()] = rmnView } + + if c.RMNHome != nil { + rmnHomeView, err := v1_6.GenerateRMNHomeView(c.RMNHome) + if err != nil { + return chainView, errors.Wrapf(err, "failed to generate rmn home view for rmn home %s", c.RMNHome.Address().String()) + } + chainView.RMNHome[c.RMNHome.Address().Hex()] = rmnHomeView + } + if c.FeeQuoter != nil && c.Router != nil && c.TokenAdminRegistry != nil { fqView, err := v1_6.GenerateFeeQuoterView(c.FeeQuoter, c.Router, c.TokenAdminRegistry) if err != nil { diff --git a/deployment/ccip/view/v1_6/rmnhome.go b/deployment/ccip/view/v1_6/rmnhome.go new file mode 100644 index 00000000000..82d39074d6f --- /dev/null +++ b/deployment/ccip/view/v1_6/rmnhome.go @@ -0,0 +1,214 @@ +package v1_6 + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/smartcontractkit/chainlink/deployment/common/view/types" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" +) + +type RMNHomeView struct { + types.ContractMetaData + CandidateConfig *RMNHomeVersionedConfig `json:"candidateConfig,omitempty"` + ActiveConfig *RMNHomeVersionedConfig `json:"activeConfig,omitempty"` +} + +type RMNHomeVersionedConfig struct { + Version uint32 `json:"version"` + StaticConfig RMNHomeStaticConfig `json:"staticConfig"` + DynamicConfig RMNHomeDynamicConfig `json:"dynamicConfig"` + Digest [32]byte `json:"digest"` +} + +func decodeHexString(hexStr string, expectedLength int) ([]byte, error) { + bytes, err := hex.DecodeString(hexStr) + if err != nil { + return nil, err + } + if len(bytes) != expectedLength { + return nil, fmt.Errorf("invalid length: expected %d, got %d", expectedLength, len(bytes)) + } + return bytes, nil +} + +func (c RMNHomeVersionedConfig) MarshalJSON() ([]byte, error) { + type Alias RMNHomeVersionedConfig + return json.Marshal(&struct { + Digest string `json:"digest"` + *Alias + }{ + Digest: hex.EncodeToString(c.Digest[:]), + Alias: (*Alias)(&c), + }) +} + +func (c *RMNHomeVersionedConfig) UnmarshalJSON(data []byte) error { + type Alias RMNHomeVersionedConfig + aux := &struct { + Digest string `json:"digest"` + *Alias + }{ + Alias: (*Alias)(c), + } + + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + + digestBytes, err := decodeHexString(aux.Digest, 32) + if err != nil { + return err + } + copy(c.Digest[:], digestBytes) + return nil +} + +type RMNHomeStaticConfig struct { + Nodes []RMNHomeNode `json:"nodes"` +} + +type RMNHomeDynamicConfig struct { + SourceChains []RMNHomeSourceChain `json:"sourceChains"` +} + +type RMNHomeSourceChain struct { + ChainSelector uint64 `json:"selector"` + F uint64 `json:"f"` + ObserverNodesBitmap *big.Int `json:"observerNodesBitmap"` +} + +type RMNHomeNode struct { + PeerId [32]byte `json:"peerId"` + OffchainPublicKey [32]byte `json:"offchainPublicKey"` +} + +func (n RMNHomeNode) MarshalJSON() ([]byte, error) { + type Alias RMNHomeNode + return json.Marshal(&struct { + PeerId string `json:"peerId"` + OffchainPublicKey string `json:"offchainPublicKey"` + *Alias + }{ + PeerId: hex.EncodeToString(n.PeerId[:]), + OffchainPublicKey: hex.EncodeToString(n.OffchainPublicKey[:]), + Alias: (*Alias)(&n), + }) +} + +func (n *RMNHomeNode) UnmarshalJSON(data []byte) error { + type Alias RMNHomeNode + aux := &struct { + PeerId string `json:"peerId"` + OffchainPublicKey string `json:"offchainPublicKey"` + *Alias + }{ + Alias: (*Alias)(n), + } + if err := json.Unmarshal(data, &aux); err != nil { + return err + } + + peerIdBytes, err := decodeHexString(aux.PeerId, 32) + if err != nil { + return err + } + copy(n.PeerId[:], peerIdBytes) + + offchainPublicKeyBytes, err := decodeHexString(aux.OffchainPublicKey, 32) + if err != nil { + return err + } + copy(n.OffchainPublicKey[:], offchainPublicKeyBytes) + + return nil +} + +type DigestFunc func(*bind.CallOpts) ([32]byte, error) + +func mapNodes(nodes []rmn_home.RMNHomeNode) []RMNHomeNode { + result := make([]RMNHomeNode, len(nodes)) + for i, node := range nodes { + result[i] = RMNHomeNode{ + PeerId: node.PeerId, + OffchainPublicKey: node.OffchainPublicKey, + } + } + return result +} + +func mapSourceChains(chains []rmn_home.RMNHomeSourceChain) []RMNHomeSourceChain { + result := make([]RMNHomeSourceChain, len(chains)) + for i, chain := range chains { + result[i] = RMNHomeSourceChain{ + ChainSelector: chain.ChainSelector, + F: chain.F, + ObserverNodesBitmap: chain.ObserverNodesBitmap, + } + } + return result +} + +func generateRmnHomeVersionedConfig(reader *rmn_home.RMNHome, digestFunc DigestFunc) (*RMNHomeVersionedConfig, error) { + address := reader.Address() + digest, err := digestFunc(nil) + if err != nil { + return nil, fmt.Errorf("failed to get digest for contract %s: %w", address, err) + } + + if digest == [32]byte{} { + return nil, nil + } + + config, err := reader.GetConfig(nil, digest) + if err != nil { + return nil, fmt.Errorf("failed to get config for contract %s: %w", address, err) + } + + staticConfig := RMNHomeStaticConfig{ + Nodes: mapNodes(config.VersionedConfig.StaticConfig.Nodes), + } + + dynamicConfig := RMNHomeDynamicConfig{ + SourceChains: mapSourceChains(config.VersionedConfig.DynamicConfig.SourceChains), + } + + return &RMNHomeVersionedConfig{ + Version: config.VersionedConfig.Version, + Digest: config.VersionedConfig.ConfigDigest, + StaticConfig: staticConfig, + DynamicConfig: dynamicConfig, + }, nil +} + +func GenerateRMNHomeView(rmnReader *rmn_home.RMNHome) (RMNHomeView, error) { + if rmnReader == nil { + return RMNHomeView{}, nil + } + + address := rmnReader.Address() + + activeConfig, err := generateRmnHomeVersionedConfig(rmnReader, rmnReader.GetActiveDigest) + if err != nil { + return RMNHomeView{}, fmt.Errorf("failed to generate active config for contract %s: %w", address, err) + } + + candidateConfig, err := generateRmnHomeVersionedConfig(rmnReader, rmnReader.GetCandidateDigest) + if err != nil { + return RMNHomeView{}, fmt.Errorf("failed to generate candidate config for contract %s: %w", address, err) + } + + contractMetaData, err := types.NewContractMetaData(rmnReader, rmnReader.Address()) + if err != nil { + return RMNHomeView{}, fmt.Errorf("failed to create contract metadata for contract %s: %w", address, err) + } + + return RMNHomeView{ + ContractMetaData: contractMetaData, + CandidateConfig: candidateConfig, + ActiveConfig: activeConfig, + }, nil +} diff --git a/deployment/ccip/view/view.go b/deployment/ccip/view/view.go index 77781a8a31a..4f216d13008 100644 --- a/deployment/ccip/view/view.go +++ b/deployment/ccip/view/view.go @@ -22,6 +22,7 @@ type ChainView struct { // v1.6 FeeQuoter map[string]v1_6.FeeQuoterView `json:"feeQuoter,omitempty"` NonceManager map[string]v1_6.NonceManagerView `json:"nonceManager,omitempty"` + RMNHome map[string]v1_6.RMNHomeView `json:"rmnHome,omitempty"` RMN map[string]v1_6.RMNRemoteView `json:"rmn,omitempty"` OnRamp map[string]v1_6.OnRampView `json:"onRamp,omitempty"` OffRamp map[string]v1_6.OffRampView `json:"offRamp,omitempty"` @@ -46,6 +47,7 @@ func NewChain() ChainView { // v1.6 FeeQuoter: make(map[string]v1_6.FeeQuoterView), NonceManager: make(map[string]v1_6.NonceManagerView), + RMNHome: make(map[string]v1_6.RMNHomeView), RMN: make(map[string]v1_6.RMNRemoteView), OnRamp: make(map[string]v1_6.OnRampView), OffRamp: make(map[string]v1_6.OffRampView), From 7a5e54c2c73ca329350de3a43e7d218658da7cd4 Mon Sep 17 00:00:00 2001 From: Makram Date: Fri, 13 Dec 2024 01:54:30 +0200 Subject: [PATCH 03/29] deployment/ccip/changeset: mcms optional ccip home cses (#15658) * deployment/ccip/changeset: mcms optional ccip home cses Add MCMS optionality for the rest of the CCIPHome changesets, and organize things a little bit better by moving the AddDON changeset into cs_ccip_home.go out of cs_add_chain.go * fixes * pr comments * one more comment * fix logger --- .../ccip/changeset/accept_ownership_test.go | 4 +- deployment/ccip/changeset/cs_add_chain.go | 170 +-------- .../ccip/changeset/cs_add_chain_test.go | 43 ++- deployment/ccip/changeset/cs_ccip_home.go | 332 ++++++++++++++++-- .../ccip/changeset/cs_ccip_home_test.go | 185 ++++++++-- .../ccip/changeset/cs_initial_add_chain.go | 2 +- 6 files changed, 489 insertions(+), 247 deletions(-) diff --git a/deployment/ccip/changeset/accept_ownership_test.go b/deployment/ccip/changeset/accept_ownership_test.go index 1dbef8e7a0b..9b71e0ad5cb 100644 --- a/deployment/ccip/changeset/accept_ownership_test.go +++ b/deployment/ccip/changeset/accept_ownership_test.go @@ -23,11 +23,11 @@ func Test_NewAcceptOwnershipChangeset(t *testing.T) { dest := allChains[1] timelockContracts := map[uint64]*proposalutils.TimelockExecutionContracts{ - source: &proposalutils.TimelockExecutionContracts{ + source: { Timelock: state.Chains[source].Timelock, CallProxy: state.Chains[source].CallProxy, }, - dest: &proposalutils.TimelockExecutionContracts{ + dest: { Timelock: state.Chains[dest].Timelock, CallProxy: state.Chains[dest].CallProxy, }, diff --git a/deployment/ccip/changeset/cs_add_chain.go b/deployment/ccip/changeset/cs_add_chain.go index b3d0df04c93..ddb6e61d5ba 100644 --- a/deployment/ccip/changeset/cs_add_chain.go +++ b/deployment/ccip/changeset/cs_add_chain.go @@ -8,18 +8,14 @@ import ( "github.com/smartcontractkit/chainlink-ccip/chainconfig" "github.com/smartcontractkit/chainlink-ccip/pkg/types/ccipocr3" - - "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" - "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/fee_quoter" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" ) @@ -136,135 +132,6 @@ func NewChainInboundChangeset( }, nil } -type AddDonAndSetCandidateChangesetConfig struct { - HomeChainSelector uint64 - FeedChainSelector uint64 - NewChainSelector uint64 - PluginType types.PluginType - NodeIDs []string - CCIPOCRParams CCIPOCRParams -} - -func (a AddDonAndSetCandidateChangesetConfig) Validate(e deployment.Environment, state CCIPOnChainState) (deployment.Nodes, error) { - if a.HomeChainSelector == 0 { - return nil, fmt.Errorf("HomeChainSelector must be set") - } - if a.FeedChainSelector == 0 { - return nil, fmt.Errorf("FeedChainSelector must be set") - } - if a.NewChainSelector == 0 { - return nil, fmt.Errorf("ocr config chain selector must be set") - } - if a.PluginType != types.PluginTypeCCIPCommit && - a.PluginType != types.PluginTypeCCIPExec { - return nil, fmt.Errorf("PluginType must be set to either CCIPCommit or CCIPExec") - } - // TODO: validate token config - if len(a.NodeIDs) == 0 { - return nil, fmt.Errorf("nodeIDs must be set") - } - nodes, err := deployment.NodeInfo(a.NodeIDs, e.Offchain) - if err != nil { - return nil, fmt.Errorf("get node info: %w", err) - } - - // check that chain config is set up for the new chain - chainConfig, err := state.Chains[a.HomeChainSelector].CCIPHome.GetChainConfig(nil, a.NewChainSelector) - if err != nil { - return nil, fmt.Errorf("get all chain configs: %w", err) - } - - // FChain should never be zero if a chain config is set in CCIPHome - if chainConfig.FChain == 0 { - return nil, fmt.Errorf("chain config not set up for new chain %d", a.NewChainSelector) - } - - err = a.CCIPOCRParams.Validate() - if err != nil { - return nil, fmt.Errorf("invalid ccip ocr params: %w", err) - } - - if e.OCRSecrets.IsEmpty() { - return nil, fmt.Errorf("OCR secrets must be set") - } - - return nodes, nil -} - -// AddDonAndSetCandidateChangeset adds new DON for destination to home chain -// and sets the commit plugin config as candidateConfig for the don. -func AddDonAndSetCandidateChangeset( - e deployment.Environment, - cfg AddDonAndSetCandidateChangesetConfig, -) (deployment.ChangesetOutput, error) { - state, err := LoadOnchainState(e) - if err != nil { - return deployment.ChangesetOutput{}, err - } - - nodes, err := cfg.Validate(e, state) - if err != nil { - return deployment.ChangesetOutput{}, fmt.Errorf("%w: %w", deployment.ErrInvalidConfig, err) - } - - newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( - e.OCRSecrets, - state.Chains[cfg.NewChainSelector].OffRamp, - e.Chains[cfg.NewChainSelector], - nodes.NonBootstraps(), - state.Chains[cfg.HomeChainSelector].RMNHome.Address(), - cfg.CCIPOCRParams.OCRParameters, - cfg.CCIPOCRParams.CommitOffChainConfig, - cfg.CCIPOCRParams.ExecuteOffChainConfig, - ) - if err != nil { - return deployment.ChangesetOutput{}, err - } - latestDon, err := internal.LatestCCIPDON(state.Chains[cfg.HomeChainSelector].CapabilityRegistry) - if err != nil { - return deployment.ChangesetOutput{}, err - } - commitConfig, ok := newDONArgs[cfg.PluginType] - if !ok { - return deployment.ChangesetOutput{}, fmt.Errorf("missing commit plugin in ocr3Configs") - } - donID := latestDon.Id + 1 - addDonOp, err := newDonWithCandidateOp( - donID, commitConfig, - state.Chains[cfg.HomeChainSelector].CapabilityRegistry, - nodes.NonBootstraps(), - ) - if err != nil { - return deployment.ChangesetOutput{}, err - } - - var ( - timelocksPerChain = map[uint64]common.Address{ - cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].Timelock.Address(), - } - proposerMCMSes = map[uint64]*gethwrappers.ManyChainMultiSig{ - cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].ProposerMcm, - } - ) - prop, err := proposalutils.BuildProposalFromBatches( - timelocksPerChain, - proposerMCMSes, - []timelock.BatchChainOperation{{ - ChainIdentifier: mcms.ChainIdentifier(cfg.HomeChainSelector), - Batch: []mcms.Operation{addDonOp}, - }}, - "setCandidate for commit and AddDon on new Chain", - 0, // minDelay - ) - if err != nil { - return deployment.ChangesetOutput{}, fmt.Errorf("failed to build proposal from batch: %w", err) - } - - return deployment.ChangesetOutput{ - Proposals: []timelock.MCMSWithTimelockProposal{*prop}, - }, nil -} - func applyChainConfigUpdatesOp( e deployment.Environment, state CCIPOnChainState, @@ -304,38 +171,3 @@ func applyChainConfigUpdatesOp( Value: big.NewInt(0), }, nil } - -// newDonWithCandidateOp sets the candidate commit config by calling setCandidate on CCIPHome contract through the AddDON call on CapReg contract -// This should be done first before calling any other UpdateDON calls -// This proposes to set up OCR3 config for the commit plugin for the DON -func newDonWithCandidateOp( - donID uint32, - pluginConfig ccip_home.CCIPHomeOCR3Config, - capReg *capabilities_registry.CapabilitiesRegistry, - nodes deployment.Nodes, -) (mcms.Operation, error) { - encodedSetCandidateCall, err := internal.CCIPHomeABI.Pack( - "setCandidate", - donID, - pluginConfig.PluginType, - pluginConfig, - [32]byte{}, - ) - if err != nil { - return mcms.Operation{}, fmt.Errorf("pack set candidate call: %w", err) - } - addDonTx, err := capReg.AddDON(deployment.SimTransactOpts(), nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ - { - CapabilityId: internal.CCIPCapabilityID, - Config: encodedSetCandidateCall, - }, - }, false, false, nodes.DefaultF()) - if err != nil { - return mcms.Operation{}, fmt.Errorf("could not generate add don tx w/ commit config: %w", err) - } - return mcms.Operation{ - To: capReg.Address(), - Data: addDonTx.Data(), - Value: big.NewInt(0), - }, nil -} diff --git a/deployment/ccip/changeset/cs_add_chain_test.go b/deployment/ccip/changeset/cs_add_chain_test.go index 96b77f1bd7d..a8fdf50b0c1 100644 --- a/deployment/ccip/changeset/cs_add_chain_test.go +++ b/deployment/ccip/changeset/cs_add_chain_test.go @@ -179,16 +179,9 @@ func TestAddChainInbound(t *testing.T) { assertTimelockOwnership(t, e, initialDeploy, state) - nodes, err := deployment.NodeInfo(e.Env.NodeIDs, e.Env.Offchain) - require.NoError(t, err) - // TODO This currently is not working - Able to send the request here but request gets stuck in execution // Send a new message and expect that this is delivered once the chain is completely set up as inbound //TestSendRequest(t, e.Env, state, initialDeploy[0], newChain, true) - var nodeIDs []string - for _, node := range nodes { - nodeIDs = append(nodeIDs, node.NodeID) - } _, err = commonchangeset.ApplyChangesets(t, e.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ e.HomeChainSel: { @@ -203,31 +196,37 @@ func TestAddChainInbound(t *testing.T) { { Changeset: commonchangeset.WrapChangeSet(AddDonAndSetCandidateChangeset), Config: AddDonAndSetCandidateChangesetConfig{ - HomeChainSelector: e.HomeChainSel, - FeedChainSelector: e.FeedChainSel, - NewChainSelector: newChain, - PluginType: types.PluginTypeCCIPCommit, - NodeIDs: nodeIDs, - CCIPOCRParams: DefaultOCRParams( - e.FeedChainSel, - tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[newChain].LinkToken, state.Chains[newChain].Weth9), - nil, - ), + SetCandidateChangesetConfig: SetCandidateChangesetConfig{ + HomeChainSelector: e.HomeChainSel, + FeedChainSelector: e.FeedChainSel, + DONChainSelector: newChain, + PluginType: types.PluginTypeCCIPCommit, + CCIPOCRParams: DefaultOCRParams( + e.FeedChainSel, + tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[newChain].LinkToken, state.Chains[newChain].Weth9), + nil, + ), + MCMS: &MCMSConfig{ + MinDelay: 0, + }, + }, }, }, { - Changeset: commonchangeset.WrapChangeSet(SetCandidatePluginChangeset), - Config: AddDonAndSetCandidateChangesetConfig{ + Changeset: commonchangeset.WrapChangeSet(SetCandidateChangeset), + Config: SetCandidateChangesetConfig{ HomeChainSelector: e.HomeChainSel, FeedChainSelector: e.FeedChainSel, - NewChainSelector: newChain, + DONChainSelector: newChain, PluginType: types.PluginTypeCCIPExec, - NodeIDs: nodeIDs, CCIPOCRParams: DefaultOCRParams( e.FeedChainSel, tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[newChain].LinkToken, state.Chains[newChain].Weth9), nil, ), + MCMS: &MCMSConfig{ + MinDelay: 0, + }, }, }, { @@ -235,13 +234,13 @@ func TestAddChainInbound(t *testing.T) { Config: PromoteAllCandidatesChangesetConfig{ HomeChainSelector: e.HomeChainSel, DONChainSelector: newChain, - NodeIDs: nodeIDs, MCMS: &MCMSConfig{ MinDelay: 0, }, }, }, }) + require.NoError(t, err) // verify if the configs are updated require.NoError(t, ValidateCCIPHomeConfigSetUp( diff --git a/deployment/ccip/changeset/cs_ccip_home.go b/deployment/ccip/changeset/cs_ccip_home.go index 202d4216b60..22fb1fc23fa 100644 --- a/deployment/ccip/changeset/cs_ccip_home.go +++ b/deployment/ccip/changeset/cs_ccip_home.go @@ -10,27 +10,34 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/ccip/changeset/internal" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_home" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" ) var ( + _ deployment.ChangeSet[AddDonAndSetCandidateChangesetConfig] = AddDonAndSetCandidateChangeset _ deployment.ChangeSet[PromoteAllCandidatesChangesetConfig] = PromoteAllCandidatesChangeset - _ deployment.ChangeSet[AddDonAndSetCandidateChangesetConfig] = SetCandidatePluginChangeset + _ deployment.ChangeSet[SetCandidateChangesetConfig] = SetCandidateChangeset ) type PromoteAllCandidatesChangesetConfig struct { HomeChainSelector uint64 + // DONChainSelector is the chain selector of the DON that we want to promote the candidate config of. // Note that each (chain, ccip capability version) pair has a unique DON ID. DONChainSelector uint64 - NodeIDs []string - MCMS *MCMSConfig + + // MCMS is optional MCMS configuration, if provided the changeset will generate an MCMS proposal. + // If nil, the changeset will execute the commands directly using the deployer key + // of the provided environment. + MCMS *MCMSConfig } func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment, state CCIPOnChainState) (deployment.Nodes, error) { @@ -40,7 +47,7 @@ func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment, if err := deployment.IsValidChainSelector(p.DONChainSelector); err != nil { return nil, fmt.Errorf("don chain selector invalid: %w", err) } - if len(p.NodeIDs) == 0 { + if len(e.NodeIDs) == 0 { return nil, fmt.Errorf("NodeIDs must be set") } if state.Chains[p.HomeChainSelector].CCIPHome == nil { @@ -49,8 +56,12 @@ func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment, if state.Chains[p.HomeChainSelector].CapabilityRegistry == nil { return nil, fmt.Errorf("CapabilityRegistry contract does not exist") } + if state.Chains[p.DONChainSelector].OffRamp == nil { + // should not be possible, but a defensive check. + return nil, fmt.Errorf("OffRamp contract does not exist") + } - nodes, err := deployment.NodeInfo(p.NodeIDs, e.Offchain) + nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) if err != nil { return nil, fmt.Errorf("fetch node info: %w", err) } @@ -96,7 +107,10 @@ func (p PromoteAllCandidatesChangesetConfig) Validate(e deployment.Environment, } // PromoteAllCandidatesChangeset generates a proposal to call promoteCandidate on the CCIPHome through CapReg. -// This needs to be called after SetCandidateProposal is executed. +// Note that a DON must exist prior to being able to use this changeset effectively, +// i.e AddDonAndSetCandidateChangeset must be called first. +// This can also be used to promote a 0x0 candidate config to be the active, effectively shutting down the DON. +// At that point you can call the RemoveDON changeset to remove the DON entirely from the capability registry. func PromoteAllCandidatesChangeset( e deployment.Environment, cfg PromoteAllCandidatesChangesetConfig, @@ -160,8 +174,122 @@ func PromoteAllCandidatesChangeset( }, nil } -// SetCandidatePluginChangeset calls setCandidate on the CCIPHome for setting up OCR3 exec Plugin config for the new chain. -func SetCandidatePluginChangeset( +// AddDonAndSetCandidateChangesetConfig is a separate config struct +// because the validation is slightly different from SetCandidateChangesetConfig. +// In particular, we check to make sure we don't already have a DON for the chain. +type AddDonAndSetCandidateChangesetConfig struct { + SetCandidateChangesetConfig +} + +func (a AddDonAndSetCandidateChangesetConfig) Validate(e deployment.Environment, state CCIPOnChainState) (deployment.Nodes, error) { + nodes, err := a.SetCandidateChangesetConfig.Validate(e, state) + if err != nil { + return nil, err + } + + // check if a DON already exists for this chain + donID, err := internal.DonIDForChain( + state.Chains[a.HomeChainSelector].CapabilityRegistry, + state.Chains[a.HomeChainSelector].CCIPHome, + a.DONChainSelector, + ) + if err != nil { + return nil, fmt.Errorf("fetch don id for chain: %w", err) + } + if donID != 0 { + return nil, fmt.Errorf("don already exists in CR for chain %d, it has id %d", a.DONChainSelector, donID) + } + + return nodes, nil +} + +type SetCandidateChangesetConfig struct { + HomeChainSelector uint64 + FeedChainSelector uint64 + + // DONChainSelector is the chain selector of the chain where the DON will be added. + DONChainSelector uint64 + + PluginType types.PluginType + // Note that the PluginType field is used to determine which field in CCIPOCRParams is used. + CCIPOCRParams CCIPOCRParams + + // MCMS is optional MCMS configuration, if provided the changeset will generate an MCMS proposal. + // If nil, the changeset will execute the commands directly using the deployer key + // of the provided environment. + MCMS *MCMSConfig +} + +func (s SetCandidateChangesetConfig) Validate(e deployment.Environment, state CCIPOnChainState) (deployment.Nodes, error) { + if err := deployment.IsValidChainSelector(s.HomeChainSelector); err != nil { + return nil, fmt.Errorf("home chain selector invalid: %w", err) + } + if err := deployment.IsValidChainSelector(s.FeedChainSelector); err != nil { + return nil, fmt.Errorf("feed chain selector invalid: %w", err) + } + if err := deployment.IsValidChainSelector(s.DONChainSelector); err != nil { + return nil, fmt.Errorf("don chain selector invalid: %w", err) + } + if len(e.NodeIDs) == 0 { + return nil, fmt.Errorf("nodeIDs must be set") + } + if state.Chains[s.HomeChainSelector].CCIPHome == nil { + return nil, fmt.Errorf("CCIPHome contract does not exist") + } + if state.Chains[s.HomeChainSelector].CapabilityRegistry == nil { + return nil, fmt.Errorf("CapabilityRegistry contract does not exist") + } + if state.Chains[s.DONChainSelector].OffRamp == nil { + // should not be possible, but a defensive check. + return nil, fmt.Errorf("OffRamp contract does not exist on don chain selector %d", s.DONChainSelector) + } + if s.PluginType != types.PluginTypeCCIPCommit && + s.PluginType != types.PluginTypeCCIPExec { + return nil, fmt.Errorf("PluginType must be set to either CCIPCommit or CCIPExec") + } + + nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) + if err != nil { + return nil, fmt.Errorf("get node info: %w", err) + } + + // TODO: validate token config + // TODO: validate gas config + + // check that chain config is set up for the new chain + chainConfig, err := state.Chains[s.HomeChainSelector].CCIPHome.GetChainConfig(nil, s.DONChainSelector) + if err != nil { + return nil, fmt.Errorf("get all chain configs: %w", err) + } + + // FChain should never be zero if a chain config is set in CCIPHome + if chainConfig.FChain == 0 { + return nil, fmt.Errorf("chain config not set up for new chain %d", s.DONChainSelector) + } + + err = s.CCIPOCRParams.Validate() + if err != nil { + return nil, fmt.Errorf("invalid ccip ocr params: %w", err) + } + + if e.OCRSecrets.IsEmpty() { + return nil, fmt.Errorf("OCR secrets must be set") + } + + return nodes, nil +} + +// AddDonAndSetCandidateChangeset adds new DON for destination to home chain +// and sets the plugin config as candidateConfig for the don. +// +// This is the first step to creating a CCIP DON and must be executed before any +// other changesets (SetCandidateChangeset, PromoteAllCandidatesChangeset) +// can be executed. +// +// Note that these operations must be done together because the createDON call +// in the capability registry calls the capability config contract, so we must +// provide suitable calldata for CCIPHome. +func AddDonAndSetCandidateChangeset( e deployment.Environment, cfg AddDonAndSetCandidateChangesetConfig, ) (deployment.ChangesetOutput, error) { @@ -175,10 +303,153 @@ func SetCandidatePluginChangeset( return deployment.ChangesetOutput{}, fmt.Errorf("%w: %w", deployment.ErrInvalidConfig, err) } + txOpts := e.Chains[cfg.HomeChainSelector].DeployerKey + if cfg.MCMS != nil { + txOpts = deployment.SimTransactOpts() + } + newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( e.OCRSecrets, - state.Chains[cfg.NewChainSelector].OffRamp, - e.Chains[cfg.NewChainSelector], + state.Chains[cfg.DONChainSelector].OffRamp, + e.Chains[cfg.DONChainSelector], + nodes.NonBootstraps(), + state.Chains[cfg.HomeChainSelector].RMNHome.Address(), + cfg.CCIPOCRParams.OCRParameters, + cfg.CCIPOCRParams.CommitOffChainConfig, + cfg.CCIPOCRParams.ExecuteOffChainConfig, + ) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + latestDon, err := internal.LatestCCIPDON(state.Chains[cfg.HomeChainSelector].CapabilityRegistry) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + pluginOCR3Config, ok := newDONArgs[cfg.PluginType] + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("missing commit plugin in ocr3Configs") + } + + expectedDonID := latestDon.Id + 1 + addDonOp, err := newDonWithCandidateOp( + txOpts, + e.Chains[cfg.HomeChainSelector], + expectedDonID, + pluginOCR3Config, + state.Chains[cfg.HomeChainSelector].CapabilityRegistry, + nodes.NonBootstraps(), + cfg.MCMS != nil, + ) + if err != nil { + return deployment.ChangesetOutput{}, err + } + if cfg.MCMS == nil { + return deployment.ChangesetOutput{}, nil + } + + prop, err := proposalutils.BuildProposalFromBatches( + map[uint64]common.Address{ + cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].Timelock.Address(), + }, + map[uint64]*gethwrappers.ManyChainMultiSig{ + cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].ProposerMcm, + }, + []timelock.BatchChainOperation{{ + ChainIdentifier: mcms.ChainIdentifier(cfg.HomeChainSelector), + Batch: []mcms.Operation{addDonOp}, + }}, + fmt.Sprintf("addDON on new Chain && setCandidate for plugin %s", cfg.PluginType.String()), + cfg.MCMS.MinDelay, + ) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to build proposal from batch: %w", err) + } + + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{*prop}, + }, nil +} + +// newDonWithCandidateOp sets the candidate commit config by calling setCandidate on CCIPHome contract through the AddDON call on CapReg contract +// This should be done first before calling any other UpdateDON calls +// This proposes to set up OCR3 config for the commit plugin for the DON +func newDonWithCandidateOp( + txOpts *bind.TransactOpts, + homeChain deployment.Chain, + donID uint32, + pluginConfig ccip_home.CCIPHomeOCR3Config, + capReg *capabilities_registry.CapabilitiesRegistry, + nodes deployment.Nodes, + mcmsEnabled bool, +) (mcms.Operation, error) { + encodedSetCandidateCall, err := internal.CCIPHomeABI.Pack( + "setCandidate", + donID, + pluginConfig.PluginType, + pluginConfig, + [32]byte{}, + ) + if err != nil { + return mcms.Operation{}, fmt.Errorf("pack set candidate call: %w", err) + } + + addDonTx, err := capReg.AddDON( + txOpts, + nodes.PeerIDs(), + []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ + { + CapabilityId: internal.CCIPCapabilityID, + Config: encodedSetCandidateCall, + }, + }, + false, // isPublic + false, // acceptsWorkflows + nodes.DefaultF(), + ) + if err != nil { + return mcms.Operation{}, fmt.Errorf("could not generate add don tx w/ commit config: %w", err) + } + if !mcmsEnabled { + _, err = deployment.ConfirmIfNoError(homeChain, addDonTx, err) + if err != nil { + return mcms.Operation{}, fmt.Errorf("error confirming addDon call: %w", err) + } + } + + return mcms.Operation{ + To: capReg.Address(), + Data: addDonTx.Data(), + Value: big.NewInt(0), + }, nil +} + +// SetCandidateChangeset generates a proposal to call setCandidate on the CCIPHome through the capability registry. +// A DON must exist in order to use this changeset effectively, i.e AddDonAndSetCandidateChangeset must be called first. +func SetCandidateChangeset( + e deployment.Environment, + cfg SetCandidateChangesetConfig, +) (deployment.ChangesetOutput, error) { + state, err := LoadOnchainState(e) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + nodes, err := cfg.Validate(e, state) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("%w: %w", deployment.ErrInvalidConfig, err) + } + + txOpts := e.Chains[cfg.HomeChainSelector].DeployerKey + if cfg.MCMS != nil { + txOpts = deployment.SimTransactOpts() + } + + newDONArgs, err := internal.BuildOCR3ConfigForCCIPHome( + e.OCRSecrets, + state.Chains[cfg.DONChainSelector].OffRamp, + e.Chains[cfg.DONChainSelector], nodes.NonBootstraps(), state.Chains[cfg.HomeChainSelector].RMNHome.Address(), cfg.CCIPOCRParams.OCRParameters, @@ -195,33 +466,37 @@ func SetCandidatePluginChangeset( } setCandidateMCMSOps, err := setCandidateOnExistingDon( + e.Logger, + txOpts, + e.Chains[cfg.HomeChainSelector], config, state.Chains[cfg.HomeChainSelector].CapabilityRegistry, state.Chains[cfg.HomeChainSelector].CCIPHome, - cfg.NewChainSelector, + cfg.DONChainSelector, nodes.NonBootstraps(), + cfg.MCMS != nil, ) if err != nil { return deployment.ChangesetOutput{}, err } - var ( - timelocksPerChain = map[uint64]common.Address{ + if cfg.MCMS == nil { + return deployment.ChangesetOutput{}, nil + } + + prop, err := proposalutils.BuildProposalFromBatches( + map[uint64]common.Address{ cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].Timelock.Address(), - } - proposerMCMSes = map[uint64]*gethwrappers.ManyChainMultiSig{ + }, + map[uint64]*gethwrappers.ManyChainMultiSig{ cfg.HomeChainSelector: state.Chains[cfg.HomeChainSelector].ProposerMcm, - } - ) - prop, err := proposalutils.BuildProposalFromBatches( - timelocksPerChain, - proposerMCMSes, + }, []timelock.BatchChainOperation{{ ChainIdentifier: mcms.ChainIdentifier(cfg.HomeChainSelector), Batch: setCandidateMCMSOps, }}, fmt.Sprintf("SetCandidate for %s plugin", cfg.PluginType.String()), - 0, // minDelay + cfg.MCMS.MinDelay, ) if err != nil { return deployment.ChangesetOutput{}, err @@ -236,11 +511,15 @@ func SetCandidatePluginChangeset( // setCandidateOnExistingDon calls setCandidate on CCIPHome contract through the UpdateDON call on CapReg contract // This proposes to set up OCR3 config for the provided plugin for the DON func setCandidateOnExistingDon( + lggr logger.Logger, + txOpts *bind.TransactOpts, + homeChain deployment.Chain, pluginConfig ccip_home.CCIPHomeOCR3Config, capReg *capabilities_registry.CapabilitiesRegistry, ccipHome *ccip_home.CCIPHome, chainSelector uint64, nodes deployment.Nodes, + mcmsEnabled bool, ) ([]mcms.Operation, error) { // fetch DON ID for the chain donID, err := internal.DonIDForChain(capReg, ccipHome, chainSelector) @@ -251,7 +530,8 @@ func setCandidateOnExistingDon( return nil, fmt.Errorf("don doesn't exist in CR for chain %d", chainSelector) } - fmt.Printf("donID: %d", donID) + lggr.Infof("donID for chain %d: %d", chainSelector, donID) + encodedSetCandidateCall, err := internal.CCIPHomeABI.Pack( "setCandidate", donID, @@ -265,7 +545,7 @@ func setCandidateOnExistingDon( // set candidate call updateDonTx, err := capReg.UpdateDON( - deployment.SimTransactOpts(), + txOpts, donID, nodes.PeerIDs(), []capabilities_registry.CapabilitiesRegistryCapabilityConfiguration{ @@ -280,6 +560,12 @@ func setCandidateOnExistingDon( if err != nil { return nil, fmt.Errorf("update don w/ exec config: %w", err) } + if !mcmsEnabled { + _, err = deployment.ConfirmIfNoError(homeChain, updateDonTx, err) + if err != nil { + return nil, fmt.Errorf("error confirming updateDon call: %w", err) + } + } return []mcms.Operation{{ To: capReg.Address(), diff --git a/deployment/ccip/changeset/cs_ccip_home_test.go b/deployment/ccip/changeset/cs_ccip_home_test.go index 47f262d3f83..c4df4fe32d7 100644 --- a/deployment/ccip/changeset/cs_ccip_home_test.go +++ b/deployment/ccip/changeset/cs_ccip_home_test.go @@ -16,6 +16,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" cctypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/ccip/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/deployment" @@ -164,11 +165,15 @@ func TestActiveCandidate(t *testing.T) { } ) setCommitCandidateOp, err := setCandidateOnExistingDon( + e.Logger, + deployment.SimTransactOpts(), + tenv.Env.Chains[tenv.HomeChainSel], ocr3ConfigMap[cctypes.PluginTypeCCIPCommit], state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome, tenv.FeedChainSel, nodes.NonBootstraps(), + true, ) require.NoError(t, err) setCommitCandidateProposal, err := proposalutils.BuildProposalFromBatches(timelocksPerChain, proposerMCMSes, []timelock.BatchChainOperation{{ @@ -184,11 +189,15 @@ func TestActiveCandidate(t *testing.T) { // create the op for the commit plugin as well setExecCandidateOp, err := setCandidateOnExistingDon( + e.Logger, + deployment.SimTransactOpts(), + tenv.Env.Chains[tenv.HomeChainSel], ocr3ConfigMap[cctypes.PluginTypeCCIPExec], state.Chains[tenv.HomeChainSel].CapabilityRegistry, state.Chains[tenv.HomeChainSel].CCIPHome, tenv.FeedChainSel, nodes.NonBootstraps(), + true, ) require.NoError(t, err) @@ -288,37 +297,9 @@ func Test_PromoteCandidate(t *testing.T) { source := allChains[0] dest := allChains[1] - nodes, err := deployment.NodeInfo(tenv.Env.NodeIDs, tenv.Env.Offchain) - require.NoError(t, err) - - var nodeIDs []string - for _, node := range nodes { - nodeIDs = append(nodeIDs, node.NodeID) - } - if tc.mcmsEnabled { // Transfer ownership to timelock so that we can promote the zero digest later down the line. - _, err = commonchangeset.ApplyChangesets(t, tenv.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ - source: { - Timelock: state.Chains[source].Timelock, - CallProxy: state.Chains[source].CallProxy, - }, - dest: { - Timelock: state.Chains[dest].Timelock, - CallProxy: state.Chains[dest].CallProxy, - }, - tenv.HomeChainSel: { - Timelock: state.Chains[tenv.HomeChainSel].Timelock, - CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, - }, - }, []commonchangeset.ChangesetApplication{ - { - Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), - Config: genTestTransferOwnershipConfig(tenv, allChains, state), - }, - }) - require.NoError(t, err) - assertTimelockOwnership(t, tenv, allChains, state) + transferToTimelock(t, tenv, state, source, dest) } var ( @@ -356,7 +337,6 @@ func Test_PromoteCandidate(t *testing.T) { Config: PromoteAllCandidatesChangesetConfig{ HomeChainSelector: tenv.HomeChainSel, DONChainSelector: dest, - NodeIDs: nodeIDs, MCMS: mcmsConfig, }, }, @@ -378,3 +358,148 @@ func Test_PromoteCandidate(t *testing.T) { }) } } + +func Test_SetCandidate(t *testing.T) { + for _, tc := range []struct { + name string + mcmsEnabled bool + }{ + { + name: "MCMS enabled", + mcmsEnabled: true, + }, + { + name: "MCMS disabled", + mcmsEnabled: false, + }, + } { + t.Run(tc.name, func(t *testing.T) { + ctx := testcontext.Get(t) + tenv := NewMemoryEnvironment(t, + WithChains(2), + WithNodes(4)) + state, err := LoadOnchainState(tenv.Env) + require.NoError(t, err) + + // Deploy to all chains. + allChains := maps.Keys(tenv.Env.Chains) + source := allChains[0] + dest := allChains[1] + + if tc.mcmsEnabled { + // Transfer ownership to timelock so that we can promote the zero digest later down the line. + transferToTimelock(t, tenv, state, source, dest) + } + + var ( + capReg = state.Chains[tenv.HomeChainSel].CapabilityRegistry + ccipHome = state.Chains[tenv.HomeChainSel].CCIPHome + ) + donID, err := internal.DonIDForChain(capReg, ccipHome, dest) + require.NoError(t, err) + require.NotEqual(t, uint32(0), donID) + candidateDigestCommitBefore, err := ccipHome.GetCandidateDigest(&bind.CallOpts{ + Context: ctx, + }, donID, uint8(types.PluginTypeCCIPCommit)) + require.NoError(t, err) + require.Equal(t, [32]byte{}, candidateDigestCommitBefore) + candidateDigestExecBefore, err := ccipHome.GetCandidateDigest(&bind.CallOpts{ + Context: ctx, + }, donID, uint8(types.PluginTypeCCIPExec)) + require.NoError(t, err) + require.Equal(t, [32]byte{}, candidateDigestExecBefore) + + var mcmsConfig *MCMSConfig + if tc.mcmsEnabled { + mcmsConfig = &MCMSConfig{ + MinDelay: 0, + } + } + tokenConfig := NewTestTokenConfig(state.Chains[tenv.FeedChainSel].USDFeeds) + _, err = commonchangeset.ApplyChangesets(t, tenv.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ + tenv.HomeChainSel: { + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, + }, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(SetCandidateChangeset), + Config: SetCandidateChangesetConfig{ + HomeChainSelector: tenv.HomeChainSel, + FeedChainSelector: tenv.FeedChainSel, + DONChainSelector: dest, + PluginType: types.PluginTypeCCIPCommit, + CCIPOCRParams: DefaultOCRParams( + tenv.FeedChainSel, + tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken, state.Chains[dest].Weth9), + nil, + ), + MCMS: mcmsConfig, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(SetCandidateChangeset), + Config: SetCandidateChangesetConfig{ + HomeChainSelector: tenv.HomeChainSel, + FeedChainSelector: tenv.FeedChainSel, + DONChainSelector: dest, + PluginType: types.PluginTypeCCIPExec, + CCIPOCRParams: DefaultOCRParams( + tenv.FeedChainSel, + tokenConfig.GetTokenInfo(logger.TestLogger(t), state.Chains[dest].LinkToken, state.Chains[dest].Weth9), + nil, + ), + MCMS: mcmsConfig, + }, + }, + }) + require.NoError(t, err) + + // after setting a new candidate on both plugins, the candidate config digest + // should be nonzero. + candidateDigestCommitAfter, err := ccipHome.GetCandidateDigest(&bind.CallOpts{ + Context: ctx, + }, donID, uint8(types.PluginTypeCCIPCommit)) + require.NoError(t, err) + require.NotEqual(t, [32]byte{}, candidateDigestCommitAfter) + require.NotEqual(t, candidateDigestCommitBefore, candidateDigestCommitAfter) + + candidateDigestExecAfter, err := ccipHome.GetCandidateDigest(&bind.CallOpts{ + Context: ctx, + }, donID, uint8(types.PluginTypeCCIPExec)) + require.NoError(t, err) + require.NotEqual(t, [32]byte{}, candidateDigestExecAfter) + require.NotEqual(t, candidateDigestExecBefore, candidateDigestExecAfter) + }) + } +} + +func transferToTimelock( + t *testing.T, + tenv DeployedEnv, + state CCIPOnChainState, + source, + dest uint64) { + // Transfer ownership to timelock so that we can promote the zero digest later down the line. + _, err := commonchangeset.ApplyChangesets(t, tenv.Env, map[uint64]*proposalutils.TimelockExecutionContracts{ + source: { + Timelock: state.Chains[source].Timelock, + CallProxy: state.Chains[source].CallProxy, + }, + dest: { + Timelock: state.Chains[dest].Timelock, + CallProxy: state.Chains[dest].CallProxy, + }, + tenv.HomeChainSel: { + Timelock: state.Chains[tenv.HomeChainSel].Timelock, + CallProxy: state.Chains[tenv.HomeChainSel].CallProxy, + }, + }, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), + Config: genTestTransferOwnershipConfig(tenv, []uint64{source, dest}, state), + }, + }) + require.NoError(t, err) + assertTimelockOwnership(t, tenv, []uint64{source, dest}, state) +} diff --git a/deployment/ccip/changeset/cs_initial_add_chain.go b/deployment/ccip/changeset/cs_initial_add_chain.go index 5ba648d74b5..4f8b2ac2722 100644 --- a/deployment/ccip/changeset/cs_initial_add_chain.go +++ b/deployment/ccip/changeset/cs_initial_add_chain.go @@ -483,7 +483,7 @@ func ValidateCCIPHomeConfigSetUp( return fmt.Errorf("fetch don id for chain: %w", err) } if donID == 0 { - return fmt.Errorf("don id for chain(%d) does not exist", chainSel) + return fmt.Errorf("don id for chain (%d) does not exist", chainSel) } // final sanity checks on configs. From 7ca4930c1cf931b4b6d4d45c223a62e00c5edb7e Mon Sep 17 00:00:00 2001 From: Sam Date: Thu, 12 Dec 2024 19:08:46 -0500 Subject: [PATCH 04/29] Attempt fix for duplicate metrics collector error (#15663) * Attempt fix for duplicate metrics collector error * Fix thread busy metrics in llo mercury transmitter --- .../services/llo/mercurytransmitter/server.go | 59 +++++++++++++++---- .../llo/mercurytransmitter/transmitter.go | 34 +---------- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/core/services/llo/mercurytransmitter/server.go b/core/services/llo/mercurytransmitter/server.go index 4e97c0483b3..3ce2b0a4b4a 100644 --- a/core/services/llo/mercurytransmitter/server.go +++ b/core/services/llo/mercurytransmitter/server.go @@ -62,6 +62,22 @@ var ( }, []string{"donID", "serverURL", "code"}, ) + promTransmitConcurrentTransmitGauge = promauto.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "concurrent_transmit_gauge", + Help: "Gauge that measures the number of transmit threads currently waiting on a remote transmit call. You may wish to alert if this exceeds some number for a given period of time, or if it ever reaches its max.", + }, + []string{"donID", "serverURL"}, + ) + promTransmitConcurrentDeleteGauge = prometheus.NewGaugeVec(prometheus.GaugeOpts{ + Namespace: "llo", + Subsystem: "mercurytransmitter", + Name: "concurrent_delete_gauge", + Help: "Gauge that measures the number of delete threads currently waiting on a delete call to the DB. You may wish to alert if this exceeds some number for a given period of time, or if it ever reaches its max.", + }, + []string{"donID", "serverURL"}, + ) ) type ReportPacker interface { @@ -87,12 +103,14 @@ type server struct { evmPremiumLegacyPacker ReportPacker jsonPacker ReportPacker - transmitSuccessCount prometheus.Counter - transmitDuplicateCount prometheus.Counter - transmitConnectionErrorCount prometheus.Counter - transmitQueueDeleteErrorCount prometheus.Counter - transmitQueueInsertErrorCount prometheus.Counter - transmitQueuePushErrorCount prometheus.Counter + transmitSuccessCount prometheus.Counter + transmitDuplicateCount prometheus.Counter + transmitConnectionErrorCount prometheus.Counter + transmitQueueDeleteErrorCount prometheus.Counter + transmitQueueInsertErrorCount prometheus.Counter + transmitQueuePushErrorCount prometheus.Counter + transmitConcurrentTransmitGauge prometheus.Gauge + transmitConcurrentDeleteGauge prometheus.Gauge transmitThreadBusyCount atomic.Int32 deleteThreadBusyCount atomic.Int32 @@ -130,6 +148,8 @@ func newServer(lggr logger.Logger, verboseLogging bool, cfg QueueConfig, client promTransmitQueueDeleteErrorCount.WithLabelValues(donIDStr, serverURL), promTransmitQueueInsertErrorCount.WithLabelValues(donIDStr, serverURL), promTransmitQueuePushErrorCount.WithLabelValues(donIDStr, serverURL), + promTransmitConcurrentTransmitGauge.WithLabelValues(donIDStr, serverURL), + promTransmitConcurrentDeleteGauge.WithLabelValues(donIDStr, serverURL), atomic.Int32{}, atomic.Int32{}, } @@ -161,7 +181,7 @@ func (s *server) runDeleteQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup select { case hash := <-s.deleteQueue: for { - s.deleteThreadBusyCount.Add(1) + s.deleteThreadBusyCountInc() if err := s.pm.orm.Delete(ctx, [][32]byte{hash}); err != nil { s.lggr.Errorw("Failed to delete transmission record", "err", err, "transmissionHash", hash) s.transmitQueueDeleteErrorCount.Inc() @@ -170,7 +190,7 @@ func (s *server) runDeleteQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup // Wait a backoff duration before trying to delete again continue case <-stopCh: - s.deleteThreadBusyCount.Add(-1) + s.deleteThreadBusyCountDec() // abort and return immediately on stop even if items remain in queue return } @@ -179,7 +199,7 @@ func (s *server) runDeleteQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup } // success b.Reset() - s.deleteThreadBusyCount.Add(-1) + s.deleteThreadBusyCountDec() case <-stopCh: // abort and return immediately on stop even if items remain in queue return @@ -187,6 +207,23 @@ func (s *server) runDeleteQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup } } +func (s *server) transmitThreadBusyCountInc() { + val := s.transmitThreadBusyCount.Add(1) + s.transmitConcurrentTransmitGauge.Set(float64(val)) +} +func (s *server) transmitThreadBusyCountDec() { + val := s.transmitThreadBusyCount.Add(-1) + s.transmitConcurrentTransmitGauge.Set(float64(val)) +} +func (s *server) deleteThreadBusyCountInc() { + val := s.deleteThreadBusyCount.Add(1) + s.transmitConcurrentDeleteGauge.Set(float64(val)) +} +func (s *server) deleteThreadBusyCountDec() { + val := s.deleteThreadBusyCount.Add(-1) + s.transmitConcurrentDeleteGauge.Set(float64(val)) +} + func (s *server) runQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup, donIDStr string) { defer wg.Done() // Exponential backoff with very short retry interval (since latency is a priority) @@ -208,8 +245,8 @@ func (s *server) runQueueLoop(stopCh services.StopChan, wg *sync.WaitGroup, donI return false } - s.transmitThreadBusyCount.Add(1) - defer s.transmitThreadBusyCount.Add(-1) + s.transmitThreadBusyCountInc() + defer s.transmitThreadBusyCountDec() req, res, err := func(ctx context.Context) (*pb.TransmitRequest, *pb.TransmitResponse, error) { ctx, cancelFn := context.WithTimeout(ctx, utils.WithJitter(s.transmitTimeout)) diff --git a/core/services/llo/mercurytransmitter/transmitter.go b/core/services/llo/mercurytransmitter/transmitter.go index 8e60bf938a5..23aa4b79e58 100644 --- a/core/services/llo/mercurytransmitter/transmitter.go +++ b/core/services/llo/mercurytransmitter/transmitter.go @@ -116,7 +116,6 @@ type transmitter struct { orm ORM servers map[string]*server registerer prometheus.Registerer - collectors []prometheus.Collector donID uint32 fromAccount string @@ -155,7 +154,6 @@ func newTransmitter(opts Opts) *transmitter { opts.ORM, servers, opts.Registerer, - nil, opts.DonID, fmt.Sprintf("%x", opts.FromAccount), make(services.StopChan), @@ -194,31 +192,6 @@ func (mt *transmitter) Start(ctx context.Context) (err error) { go s.runDeleteQueueLoop(mt.stopCh, mt.wg) go s.runQueueLoop(mt.stopCh, mt.wg, donIDStr) } - mt.collectors = append(mt.collectors, prometheus.NewGaugeFunc( - prometheus.GaugeOpts{ - Namespace: "llo", - Subsystem: "mercurytransmitter", - Name: "concurrent_transmit_gauge", - Help: "Gauge that measures the number of transmit threads currently waiting on a remote transmit call. You may wish to alert if this exceeds some number for a given period of time, or if it ever reaches its max.", - ConstLabels: prometheus.Labels{"donID": donIDStr, "serverURL": s.url, "maxConcurrentTransmits": strconv.FormatInt(int64(nThreads), 10)}, - }, func() float64 { - return float64(s.transmitThreadBusyCount.Load()) - })) - mt.collectors = append(mt.collectors, prometheus.NewGaugeFunc( - prometheus.GaugeOpts{ - Namespace: "llo", - Subsystem: "mercurytransmitter", - Name: "concurrent_delete_gauge", - Help: "Gauge that measures the number of delete threads currently waiting on a delete call to the DB. You may wish to alert if this exceeds some number for a given period of time, or if it ever reaches its max.", - ConstLabels: prometheus.Labels{"donID": donIDStr, "serverURL": s.url, "maxConcurrentDeletes": strconv.FormatInt(int64(nThreads), 10)}, - }, func() float64 { - return float64(s.deleteThreadBusyCount.Load()) - })) - for _, c := range mt.collectors { - if err := mt.registerer.Register(c); err != nil { - return err - } - } } if err := (&services.MultiStart{}).Start(ctx, startClosers...); err != nil { return err @@ -250,12 +223,7 @@ func (mt *transmitter) Close() error { closers = append(closers, s.pm) closers = append(closers, s.c) } - err := services.CloseAll(closers...) - // Unregister all the gauge funcs - for _, c := range mt.collectors { - mt.registerer.Unregister(c) - } - return err + return services.CloseAll(closers...) }) } From 97b05638bd9c69a7a1cf90bb929811a260247cb1 Mon Sep 17 00:00:00 2001 From: Pablo Estrada <139084212+ecPablo@users.noreply.github.com> Date: Thu, 12 Dec 2024 19:28:08 -0600 Subject: [PATCH 05/29] feat: link transfer mcms changesets (#15512) * feat: link transfer with timelock changeset * feat: link transfer and approval integration tests and changesets. * feat: rename files * fix: use deployment.SimTransactOpts() to get tx data * fix: link contract creation * fix: remove approval changeset, not necessary for sending directly from the owner * feat: make config accept a map of chain selectors for the proposal generation * fix: params on deploy link * fix: simplify config args by using state helper functions. * fix: use pointer for value * feat: add mint permissions and minting link changeset * Deploy call proxy instead of using deployer executor keys * inject call proxies in execution methods * skip call proxy when loading chain state * revert all changes * Revert "revert all changes" This reverts commit c17911eb1ff4382b3f80d0edb055d748096dc59f. * chore: rename load state funcs * feat: add mcms config flag * fix: integration tests after merging develop * fix: use contracts from states and code improvements * fix: cs deploy chain args * fix: params ccip boosting * fix: bundle mcms config into single struct * fix: add more validations for config * fix: remove startingOpCount and use proposal utils to derive it * fix: adjust variable names, remove boolean for mcms config, add constants move balance validation to Validate() function * feat: add tests for non mcms case, improve validations, and wait for tx confirmation. * feat: check valid until is in future * feat: add tests for Validate() and small validation fixes * fix: rename MaybeLoadLinkTokenState to MaybeLoadLinkTokenChainState to abstract loading state per chain * Update deployment/common/changeset/example/link_transfer.go Co-authored-by: Graham Goh * fix: error handling and validations * fix: use getDeployer helper * feat: split mint burners into a separate changeset * fix: name TestMintLink on unit test * Update deployment/common/changeset/example/add_mint_burners_link.go Co-authored-by: Graham Goh * Update deployment/common/changeset/example/add_mint_burners_link.go Co-authored-by: Graham Goh * fix: use changeset apply for unit tests environment setup * fix: linting errors * fix: merge conflicts * fix: remove valid unit to reuse util for proposal creation --------- Co-authored-by: Akhil Chainani Co-authored-by: Graham Goh --- deployment/ccip/changeset/state.go | 4 +- .../common/changeset/deploy_link_token.go | 2 +- .../changeset/deploy_link_token_test.go | 2 +- .../example/add_mint_burners_link.go | 70 ++++ .../example/add_mint_burners_link_test.go | 50 +++ .../common/changeset/example/link_transfer.go | 239 +++++++++++ .../changeset/example/link_transfer_test.go | 373 ++++++++++++++++++ .../common/changeset/example/mint_link.go | 43 ++ .../changeset/example/mint_link_test.go | 58 +++ .../common/changeset/internal/mcms_test.go | 2 +- deployment/common/changeset/state.go | 120 +++++- .../transfer_to_mcms_with_timelock_test.go | 6 +- deployment/common/proposalutils/propose.go | 5 +- deployment/environment.go | 2 +- .../changeset/accept_ownership_test.go | 2 +- deployment/keystone/state.go | 2 +- 16 files changed, 955 insertions(+), 25 deletions(-) create mode 100644 deployment/common/changeset/example/add_mint_burners_link.go create mode 100644 deployment/common/changeset/example/add_mint_burners_link_test.go create mode 100644 deployment/common/changeset/example/link_transfer.go create mode 100644 deployment/common/changeset/example/link_transfer_test.go create mode 100644 deployment/common/changeset/example/mint_link.go create mode 100644 deployment/common/changeset/example/mint_link_test.go diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index 45ea9e8f5b8..cd88db1b9ee 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -311,13 +311,13 @@ func LoadOnchainState(e deployment.Environment) (CCIPOnChainState, error) { // LoadChainState Loads all state for a chain into state func LoadChainState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (CCIPChainState, error) { var state CCIPChainState - mcmsWithTimelock, err := commoncs.MaybeLoadMCMSWithTimelockState(chain, addresses) + mcmsWithTimelock, err := commoncs.MaybeLoadMCMSWithTimelockChainState(chain, addresses) if err != nil { return state, err } state.MCMSWithTimelockState = *mcmsWithTimelock - linkState, err := commoncs.MaybeLoadLinkTokenState(chain, addresses) + linkState, err := commoncs.MaybeLoadLinkTokenChainState(chain, addresses) if err != nil { return state, err } diff --git a/deployment/common/changeset/deploy_link_token.go b/deployment/common/changeset/deploy_link_token.go index 292c07c93df..c115a7ee083 100644 --- a/deployment/common/changeset/deploy_link_token.go +++ b/deployment/common/changeset/deploy_link_token.go @@ -12,7 +12,7 @@ import ( var _ deployment.ChangeSet[[]uint64] = DeployLinkToken -// DeployLinkToken deploys a link token contract to the chain identified by the chainSelector. +// DeployLinkToken deploys a link token contract to the chain identified by the ChainSelector. func DeployLinkToken(e deployment.Environment, chains []uint64) (deployment.ChangesetOutput, error) { for _, chain := range chains { _, ok := e.Chains[chain] diff --git a/deployment/common/changeset/deploy_link_token_test.go b/deployment/common/changeset/deploy_link_token_test.go index a61743e9bf4..bc472d2a247 100644 --- a/deployment/common/changeset/deploy_link_token_test.go +++ b/deployment/common/changeset/deploy_link_token_test.go @@ -27,7 +27,7 @@ func TestDeployLinkToken(t *testing.T) { require.NoError(t, err) addrs, err := e.ExistingAddresses.AddressesForChain(chain1) require.NoError(t, err) - state, err := changeset.MaybeLoadLinkTokenState(e.Chains[chain1], addrs) + state, err := changeset.MaybeLoadLinkTokenChainState(e.Chains[chain1], addrs) require.NoError(t, err) // View itself already unit tested _, err = state.GenerateLinkView() diff --git a/deployment/common/changeset/example/add_mint_burners_link.go b/deployment/common/changeset/example/add_mint_burners_link.go new file mode 100644 index 00000000000..7322f99dd60 --- /dev/null +++ b/deployment/common/changeset/example/add_mint_burners_link.go @@ -0,0 +1,70 @@ +package example + +import ( + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/changeset" +) + +type AddMintersBurnersLinkConfig struct { + ChainSelector uint64 + Minters []common.Address + Burners []common.Address +} + +var _ deployment.ChangeSet[*AddMintersBurnersLinkConfig] = AddMintersBurnersLink + +// AddMintersBurnersLink grants the minter / burner role to the provided addresses. +func AddMintersBurnersLink(e deployment.Environment, cfg *AddMintersBurnersLinkConfig) (deployment.ChangesetOutput, error) { + + chain := e.Chains[cfg.ChainSelector] + addresses, err := e.ExistingAddresses.AddressesForChain(cfg.ChainSelector) + if err != nil { + return deployment.ChangesetOutput{}, err + } + linkState, err := changeset.MaybeLoadLinkTokenChainState(chain, addresses) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + for _, minter := range cfg.Minters { + // check if minter is already a minter + isMinter, err := linkState.LinkToken.IsMinter(&bind.CallOpts{Context: e.GetContext()}, minter) + if err != nil { + return deployment.ChangesetOutput{}, err + } + if isMinter { + continue + } + tx, err := linkState.LinkToken.GrantMintRole(chain.DeployerKey, minter) + if err != nil { + return deployment.ChangesetOutput{}, err + } + _, err = deployment.ConfirmIfNoError(chain, tx, err) + if err != nil { + return deployment.ChangesetOutput{}, err + } + } + for _, burner := range cfg.Burners { + // check if burner is already a burner + isBurner, err := linkState.LinkToken.IsBurner(&bind.CallOpts{Context: e.GetContext()}, burner) + if err != nil { + return deployment.ChangesetOutput{}, err + } + if isBurner { + continue + } + tx, err := linkState.LinkToken.GrantBurnRole(chain.DeployerKey, burner) + if err != nil { + return deployment.ChangesetOutput{}, err + } + _, err = deployment.ConfirmIfNoError(chain, tx, err) + if err != nil { + return deployment.ChangesetOutput{}, err + } + } + return deployment.ChangesetOutput{}, nil + +} diff --git a/deployment/common/changeset/example/add_mint_burners_link_test.go b/deployment/common/changeset/example/add_mint_burners_link_test.go new file mode 100644 index 00000000000..4dbfddc0b30 --- /dev/null +++ b/deployment/common/changeset/example/add_mint_burners_link_test.go @@ -0,0 +1,50 @@ +package example_test + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/changeset/example" +) + +// TestAddMintersBurnersLink tests the AddMintersBurnersLink changeset +func TestAddMintersBurnersLink(t *testing.T) { + t.Parallel() + ctx := context.Background() + // Deploy Link Token and Timelock contracts and add addresses to environment + env := setupLinkTransferTestEnv(t) + + chainSelector := env.AllChainSelectors()[0] + chain := env.Chains[chainSelector] + addrs, err := env.ExistingAddresses.AddressesForChain(chainSelector) + require.NoError(t, err) + require.Len(t, addrs, 6) + + mcmsState, err := changeset.MaybeLoadMCMSWithTimelockChainState(chain, addrs) + require.NoError(t, err) + linkState, err := changeset.MaybeLoadLinkTokenChainState(chain, addrs) + require.NoError(t, err) + + timelockAddress := mcmsState.Timelock.Address() + + // Mint some funds + _, err = example.AddMintersBurnersLink(env, &example.AddMintersBurnersLinkConfig{ + ChainSelector: chainSelector, + Minters: []common.Address{timelockAddress}, + Burners: []common.Address{timelockAddress}, + }) + require.NoError(t, err) + + // check timelock balance + isMinter, err := linkState.LinkToken.IsMinter(&bind.CallOpts{Context: ctx}, timelockAddress) + require.NoError(t, err) + require.True(t, isMinter) + isBurner, err := linkState.LinkToken.IsBurner(&bind.CallOpts{Context: ctx}, timelockAddress) + require.NoError(t, err) + require.True(t, isBurner) +} diff --git a/deployment/common/changeset/example/link_transfer.go b/deployment/common/changeset/example/link_transfer.go new file mode 100644 index 00000000000..2e3be48a4d1 --- /dev/null +++ b/deployment/common/changeset/example/link_transfer.go @@ -0,0 +1,239 @@ +package example + +import ( + "errors" + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + ethTypes "github.com/ethereum/go-ethereum/core/types" + owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + chain_selectors "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/deployment/common/types" +) + +const MaxTimelockDelay = 24 * 7 * time.Hour + +type TransferConfig struct { + To common.Address + Value *big.Int +} + +type MCMSConfig struct { + MinDelay time.Duration // delay for timelock worker to execute the transfers. + OverrideRoot bool +} + +type LinkTransferConfig struct { + Transfers map[uint64][]TransferConfig + From common.Address + McmsConfig *MCMSConfig +} + +var _ deployment.ChangeSet[*LinkTransferConfig] = LinkTransfer + +func getDeployer(e deployment.Environment, chain uint64, mcmConfig *MCMSConfig) *bind.TransactOpts { + if mcmConfig == nil { + return e.Chains[chain].DeployerKey + } + + return deployment.SimTransactOpts() +} + +// Validate checks that the LinkTransferConfig is valid. +func (cfg LinkTransferConfig) Validate(e deployment.Environment) error { + ctx := e.GetContext() + // Check that Transfers map has at least one chainSel + if len(cfg.Transfers) == 0 { + return errors.New("transfers map must have at least one chainSel") + } + + // Check transfers config values. + for chainSel, transfers := range cfg.Transfers { + selector, err := chain_selectors.GetSelectorFamily(chainSel) + if err != nil { + return fmt.Errorf("invalid chain selector: %w", err) + } + if selector != chain_selectors.FamilyEVM { + return fmt.Errorf("chain selector %d is not an EVM chain", chainSel) + } + chain, ok := e.Chains[chainSel] + if !ok { + return fmt.Errorf("chain with selector %d not found", chainSel) + } + addrs, err := e.ExistingAddresses.AddressesForChain(chainSel) + if err != nil { + return fmt.Errorf("error getting addresses for chain %d: %w", chainSel, err) + } + if len(transfers) == 0 { + return fmt.Errorf("transfers for chainSel %d must have at least one LinkTransfer", chainSel) + } + totalAmount := big.NewInt(0) + linkState, err := changeset.MaybeLoadLinkTokenChainState(chain, addrs) + if err != nil { + return fmt.Errorf("error loading link token state during validation: %w", err) + } + for _, transfer := range transfers { + if transfer.To == (common.Address{}) { + return errors.New("'to' address for transfers must be set") + } + if transfer.Value == nil { + return errors.New("value for transfers must be set") + } + if transfer.Value.Cmp(big.NewInt(0)) == 0 { + return errors.New("value for transfers must be non-zero") + } + if transfer.Value.Cmp(big.NewInt(0)) == -1 { + return errors.New("value for transfers must be positive") + } + totalAmount.Add(totalAmount, transfer.Value) + } + // check that from address has enough funds for the transfers + balance, err := linkState.LinkToken.BalanceOf(&bind.CallOpts{Context: ctx}, cfg.From) + if balance.Cmp(totalAmount) < 0 { + return fmt.Errorf("sender does not have enough funds for transfers for chain selector %d, required: %s, available: %s", chainSel, totalAmount.String(), balance.String()) + } + } + + if cfg.McmsConfig == nil { + return nil + } + + // Upper bound for min delay (7 days) + if cfg.McmsConfig.MinDelay > MaxTimelockDelay { + return errors.New("minDelay must be less than 7 days") + } + + return nil +} + +// initStatePerChain initializes the state for each chain selector on the provided config +func initStatePerChain(cfg *LinkTransferConfig, e deployment.Environment) ( + linkStatePerChain map[uint64]*changeset.LinkTokenState, + mcmsStatePerChain map[uint64]*changeset.MCMSWithTimelockState, + err error) { + linkStatePerChain = map[uint64]*changeset.LinkTokenState{} + mcmsStatePerChain = map[uint64]*changeset.MCMSWithTimelockState{} + // Load state for each chain + chainSelectors := []uint64{} + for chainSelector := range cfg.Transfers { + chainSelectors = append(chainSelectors, chainSelector) + } + linkStatePerChain, err = changeset.MaybeLoadLinkTokenState(e, chainSelectors) + if err != nil { + return nil, nil, err + } + mcmsStatePerChain, err = changeset.MaybeLoadMCMSWithTimelockState(e, chainSelectors) + if err != nil { + return nil, nil, err + + } + return linkStatePerChain, mcmsStatePerChain, nil +} + +// transferOrBuildTx transfers the LINK tokens or builds the tx for the MCMS proposal +func transferOrBuildTx( + e deployment.Environment, + linkState *changeset.LinkTokenState, + transfer TransferConfig, + opts *bind.TransactOpts, + chain deployment.Chain, + mcmsConfig *MCMSConfig) (*ethTypes.Transaction, error) { + tx, err := linkState.LinkToken.Transfer(opts, transfer.To, transfer.Value) + if err != nil { + return nil, fmt.Errorf("error packing transfer tx data: %w", err) + } + // only wait for tx if we are not using MCMS + if mcmsConfig == nil { + if _, err := deployment.ConfirmIfNoError(chain, tx, err); err != nil { + e.Logger.Errorw("Failed to confirm transfer tx", "chain", chain.String(), "err", err) + return nil, err + } + } + return tx, nil + +} + +// LinkTransfer takes the given link transfers and executes them or creates an MCMS proposal for them. +func LinkTransfer(e deployment.Environment, cfg *LinkTransferConfig) (deployment.ChangesetOutput, error) { + + err := cfg.Validate(e) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("invalid LinkTransferConfig: %w", err) + } + chainSelectors := []uint64{} + for chainSelector := range cfg.Transfers { + chainSelectors = append(chainSelectors, chainSelector) + } + mcmsPerChain := map[uint64]*owner_helpers.ManyChainMultiSig{} + + timelockAddresses := map[uint64]common.Address{} + // Initialize state for each chain + linkStatePerChain, mcmsStatePerChain, err := initStatePerChain(cfg, e) + + allBatches := []timelock.BatchChainOperation{} + for chainSelector := range cfg.Transfers { + chainID := mcms.ChainIdentifier(chainSelector) + chain := e.Chains[chainSelector] + linkAddress := linkStatePerChain[chainSelector].LinkToken.Address() + mcmsState := mcmsStatePerChain[chainSelector] + linkState := linkStatePerChain[chainSelector] + + timelockAddress := mcmsState.Timelock.Address() + + mcmsPerChain[uint64(chainID)] = mcmsState.ProposerMcm + + timelockAddresses[chainSelector] = timelockAddress + batch := timelock.BatchChainOperation{ + ChainIdentifier: chainID, + Batch: []mcms.Operation{}, + } + + opts := getDeployer(e, chainSelector, cfg.McmsConfig) + totalAmount := big.NewInt(0) + for _, transfer := range cfg.Transfers[chainSelector] { + tx, err := transferOrBuildTx(e, linkState, transfer, opts, chain, cfg.McmsConfig) + if err != nil { + return deployment.ChangesetOutput{}, err + } + op := mcms.Operation{ + To: linkAddress, + Data: tx.Data(), + Value: big.NewInt(0), + ContractType: string(types.LinkToken), + } + batch.Batch = append(batch.Batch, op) + totalAmount.Add(totalAmount, transfer.Value) + } + + allBatches = append(allBatches, batch) + } + + if cfg.McmsConfig != nil { + proposal, err := proposalutils.BuildProposalFromBatches( + timelockAddresses, + mcmsPerChain, + allBatches, + "LINK Value transfer proposal", + cfg.McmsConfig.MinDelay, + ) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{*proposal}, + }, nil + } + + return deployment.ChangesetOutput{}, nil +} diff --git a/deployment/common/changeset/example/link_transfer_test.go b/deployment/common/changeset/example/link_transfer_test.go new file mode 100644 index 00000000000..eecfbd37c95 --- /dev/null +++ b/deployment/common/changeset/example/link_transfer_test.go @@ -0,0 +1,373 @@ +package example_test + +import ( + "context" + "math/big" + "testing" + "time" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + chain_selectors "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink/deployment/common/changeset/example" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + "github.com/smartcontractkit/chainlink/v2/core/logger" + + "github.com/stretchr/testify/require" + "go.uber.org/zap/zapcore" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/types" + "github.com/smartcontractkit/chainlink/deployment/environment/memory" +) + +// setupLinkTransferContracts deploys all required contracts for the link transfer tests and returns the updated env. +func setupLinkTransferTestEnv(t *testing.T) deployment.Environment { + + lggr := logger.TestLogger(t) + cfg := memory.MemoryEnvironmentConfig{ + Nodes: 1, + Chains: 2, + } + env := memory.NewMemoryEnvironment(t, lggr, zapcore.DebugLevel, cfg) + chainSelector := env.AllChainSelectors()[0] + config := proposalutils.SingleGroupMCMS(t) + + // Deploy MCMS and Timelock + env, err := changeset.ApplyChangesets(t, env, nil, []changeset.ChangesetApplication{ + { + Changeset: changeset.WrapChangeSet(changeset.DeployLinkToken), + Config: []uint64{chainSelector}, + }, + { + Changeset: changeset.WrapChangeSet(changeset.DeployMCMSWithTimelock), + Config: map[uint64]types.MCMSWithTimelockConfig{ + chainSelector: { + Canceller: config, + Bypasser: config, + Proposer: config, + TimelockMinDelay: big.NewInt(0), + }, + }, + }, + }) + require.NoError(t, err) + return env +} + +// TestLinkTransferMCMS tests the LinkTransfer changeset by sending LINK from a timelock contract +// to the deployer key via mcms proposal. +func TestLinkTransferMCMS(t *testing.T) { + t.Parallel() + ctx := context.Background() + + env := setupLinkTransferTestEnv(t) + chainSelector := env.AllChainSelectors()[0] + chain := env.Chains[chainSelector] + addrs, err := env.ExistingAddresses.AddressesForChain(chainSelector) + require.NoError(t, err) + require.Len(t, addrs, 6) + + mcmsState, err := changeset.MaybeLoadMCMSWithTimelockChainState(chain, addrs) + require.NoError(t, err) + linkState, err := changeset.MaybeLoadLinkTokenChainState(chain, addrs) + require.NoError(t, err) + timelockAddress := mcmsState.Timelock.Address() + + // Mint some funds + // grant minter permissions + tx, err := linkState.LinkToken.GrantMintRole(chain.DeployerKey, chain.DeployerKey.From) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + + tx, err = linkState.LinkToken.Mint(chain.DeployerKey, timelockAddress, big.NewInt(750)) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + + timelocks := map[uint64]*proposalutils.TimelockExecutionContracts{ + chainSelector: { + Timelock: mcmsState.Timelock, + CallProxy: mcmsState.CallProxy, + }, + } + // Apply the changeset + _, err = changeset.ApplyChangesets(t, env, timelocks, []changeset.ChangesetApplication{ + // the changeset produces proposals, ApplyChangesets will sign & execute them. + // in practice, signing and executing are separated processes. + { + Changeset: changeset.WrapChangeSet(example.LinkTransfer), + Config: &example.LinkTransferConfig{ + From: timelockAddress, + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: { + { + To: chain.DeployerKey.From, + Value: big.NewInt(500), + }, + }, + }, + McmsConfig: &example.MCMSConfig{ + MinDelay: 0, + OverrideRoot: true, + }, + }, + }, + }) + require.NoError(t, err) + + // Check new balances + endBalance, err := linkState.LinkToken.BalanceOf(&bind.CallOpts{Context: ctx}, chain.DeployerKey.From) + require.NoError(t, err) + expectedBalance := big.NewInt(500) + require.Equal(t, expectedBalance, endBalance) + + // check timelock balance + endBalance, err = linkState.LinkToken.BalanceOf(&bind.CallOpts{Context: ctx}, timelockAddress) + require.NoError(t, err) + expectedBalance = big.NewInt(250) + require.Equal(t, expectedBalance, endBalance) +} + +// TestLinkTransfer tests the LinkTransfer changeset by sending LINK from a timelock contract to the deployer key. +func TestLinkTransfer(t *testing.T) { + t.Parallel() + ctx := context.Background() + + env := setupLinkTransferTestEnv(t) + chainSelector := env.AllChainSelectors()[0] + chain := env.Chains[chainSelector] + addrs, err := env.ExistingAddresses.AddressesForChain(chainSelector) + require.NoError(t, err) + require.Len(t, addrs, 6) + + mcmsState, err := changeset.MaybeLoadMCMSWithTimelockChainState(chain, addrs) + require.NoError(t, err) + linkState, err := changeset.MaybeLoadLinkTokenChainState(chain, addrs) + require.NoError(t, err) + timelockAddress := mcmsState.Timelock.Address() + + // Mint some funds + // grant minter permissions + tx, err := linkState.LinkToken.GrantMintRole(chain.DeployerKey, chain.DeployerKey.From) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + + tx, err = linkState.LinkToken.Mint(chain.DeployerKey, chain.DeployerKey.From, big.NewInt(750)) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + + timelocks := map[uint64]*proposalutils.TimelockExecutionContracts{ + chainSelector: { + Timelock: mcmsState.Timelock, + CallProxy: mcmsState.CallProxy, + }, + } + + // Apply the changeset + _, err = changeset.ApplyChangesets(t, env, timelocks, []changeset.ChangesetApplication{ + // the changeset produces proposals, ApplyChangesets will sign & execute them. + // in practice, signing and executing are separated processes. + { + Changeset: changeset.WrapChangeSet(example.LinkTransfer), + Config: &example.LinkTransferConfig{ + From: chain.DeployerKey.From, + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: { + { + To: timelockAddress, + Value: big.NewInt(500), + }, + }, + }, + // No MCMSConfig here means we'll execute the txs directly. + }, + }, + }) + require.NoError(t, err) + + // Check new balances + endBalance, err := linkState.LinkToken.BalanceOf(&bind.CallOpts{Context: ctx}, chain.DeployerKey.From) + require.NoError(t, err) + expectedBalance := big.NewInt(250) + require.Equal(t, expectedBalance, endBalance) + + // check timelock balance + endBalance, err = linkState.LinkToken.BalanceOf(&bind.CallOpts{Context: ctx}, timelockAddress) + require.NoError(t, err) + expectedBalance = big.NewInt(500) + require.Equal(t, expectedBalance, endBalance) +} + +func TestValidate(t *testing.T) { + env := setupLinkTransferTestEnv(t) + chainSelector := env.AllChainSelectors()[0] + chain := env.Chains[chainSelector] + addrs, err := env.ExistingAddresses.AddressesForChain(chainSelector) + require.NoError(t, err) + require.Len(t, addrs, 6) + mcmsState, err := changeset.MaybeLoadMCMSWithTimelockChainState(chain, addrs) + require.NoError(t, err) + linkState, err := changeset.MaybeLoadLinkTokenChainState(chain, addrs) + require.NoError(t, err) + tx, err := linkState.LinkToken.GrantMintRole(chain.DeployerKey, chain.DeployerKey.From) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + require.NoError(t, err) + tx, err = linkState.LinkToken.Mint(chain.DeployerKey, chain.DeployerKey.From, big.NewInt(750)) + require.NoError(t, err) + _, err = deployment.ConfirmIfNoError(chain, tx, err) + + require.NoError(t, err) + tests := []struct { + name string + cfg example.LinkTransferConfig + errorMsg string + }{ + { + name: "valid config", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: {{To: mcmsState.Timelock.Address(), Value: big.NewInt(100)}}}, + From: chain.DeployerKey.From, + McmsConfig: &example.MCMSConfig{ + MinDelay: time.Hour, + }, + }, + }, + { + name: "valid non mcms config", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: {{To: mcmsState.Timelock.Address(), Value: big.NewInt(100)}}}, + From: chain.DeployerKey.From, + }, + }, + { + name: "insufficient funds", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: { + {To: chain.DeployerKey.From, Value: big.NewInt(100)}, + {To: chain.DeployerKey.From, Value: big.NewInt(500)}, + {To: chain.DeployerKey.From, Value: big.NewInt(1250)}, + }, + }, + From: mcmsState.Timelock.Address(), + McmsConfig: &example.MCMSConfig{ + MinDelay: time.Hour, + }, + }, + errorMsg: "sender does not have enough funds for transfers for chain selector 909606746561742123, required: 1850, available: 0", + }, + { + name: "invalid config: empty transfers", + cfg: example.LinkTransferConfig{Transfers: map[uint64][]example.TransferConfig{}}, + errorMsg: "transfers map must have at least one chainSel", + }, + { + name: "invalid chain selector", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + 1: {{To: common.Address{}, Value: big.NewInt(100)}}}, + }, + errorMsg: "invalid chain selector: unknown chain selector 1", + }, + { + name: "chain selector not found", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chain_selectors.ETHEREUM_TESTNET_GOERLI_ARBITRUM_1.Selector: {{To: common.Address{}, Value: big.NewInt(100)}}}, + }, + errorMsg: "chain with selector 6101244977088475029 not found", + }, + { + name: "empty transfer list", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: {}, + }, + }, + errorMsg: "transfers for chainSel 909606746561742123 must have at least one LinkTransfer", + }, + { + name: "empty value", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: { + {To: chain.DeployerKey.From, Value: nil}, + }, + }, + }, + errorMsg: "value for transfers must be set", + }, + { + name: "zero value", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: { + {To: chain.DeployerKey.From, Value: big.NewInt(0)}, + }, + }, + }, + errorMsg: "value for transfers must be non-zero", + }, + { + name: "negative value", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: { + {To: chain.DeployerKey.From, Value: big.NewInt(-5)}, + }, + }, + }, + errorMsg: "value for transfers must be positive", + }, + { + name: "non-evm-chain", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chain_selectors.APTOS_MAINNET.Selector: {{To: mcmsState.Timelock.Address(), Value: big.NewInt(100)}}}, + From: chain.DeployerKey.From, + }, + errorMsg: "chain selector 4741433654826277614 is not an EVM chain", + }, + { + name: "delay greater than max allowed", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: {{To: mcmsState.Timelock.Address(), Value: big.NewInt(100)}}}, + From: chain.DeployerKey.From, + McmsConfig: &example.MCMSConfig{ + MinDelay: time.Hour * 24 * 10, + }, + }, + errorMsg: "minDelay must be less than 7 days", + }, + { + name: "invalid config: transfer to address missing", + cfg: example.LinkTransferConfig{ + Transfers: map[uint64][]example.TransferConfig{ + chainSelector: {{To: common.Address{}, Value: big.NewInt(100)}}}, + }, + errorMsg: "'to' address for transfers must be set", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + err := tt.cfg.Validate(env) + if tt.errorMsg != "" { + require.Error(t, err) + require.Contains(t, err.Error(), tt.errorMsg) + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/deployment/common/changeset/example/mint_link.go b/deployment/common/changeset/example/mint_link.go new file mode 100644 index 00000000000..dc50f8a1a27 --- /dev/null +++ b/deployment/common/changeset/example/mint_link.go @@ -0,0 +1,43 @@ +package example + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/common/changeset" +) + +type MintLinkConfig struct { + Amount *big.Int + ChainSelector uint64 + To common.Address +} + +var _ deployment.ChangeSet[*MintLinkConfig] = MintLink + +// MintLink mints LINK to the provided contract. +func MintLink(e deployment.Environment, cfg *MintLinkConfig) (deployment.ChangesetOutput, error) { + + chain := e.Chains[cfg.ChainSelector] + addresses, err := e.ExistingAddresses.AddressesForChain(cfg.ChainSelector) + if err != nil { + return deployment.ChangesetOutput{}, err + } + linkState, err := changeset.MaybeLoadLinkTokenChainState(chain, addresses) + if err != nil { + return deployment.ChangesetOutput{}, err + } + + tx, err := linkState.LinkToken.Mint(chain.DeployerKey, cfg.To, cfg.Amount) + if err != nil { + return deployment.ChangesetOutput{}, err + } + _, err = deployment.ConfirmIfNoError(chain, tx, err) + if err != nil { + return deployment.ChangesetOutput{}, err + } + return deployment.ChangesetOutput{}, nil + +} diff --git a/deployment/common/changeset/example/mint_link_test.go b/deployment/common/changeset/example/mint_link_test.go new file mode 100644 index 00000000000..1c60c3221de --- /dev/null +++ b/deployment/common/changeset/example/mint_link_test.go @@ -0,0 +1,58 @@ +package example_test + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/changeset/example" +) + +// TestMintLink tests the MintLink changeset +func TestMintLink(t *testing.T) { + t.Parallel() + env := setupLinkTransferTestEnv(t) + ctx := env.GetContext() + chainSelector := env.AllChainSelectors()[0] + chain := env.Chains[chainSelector] + + addrs, err := env.ExistingAddresses.AddressesForChain(chainSelector) + require.NoError(t, err) + require.Len(t, addrs, 6) + + mcmsState, err := changeset.MaybeLoadMCMSWithTimelockChainState(chain, addrs) + require.NoError(t, err) + linkState, err := changeset.MaybeLoadLinkTokenChainState(chain, addrs) + require.NoError(t, err) + + _, err = changeset.ApplyChangesets(t, env, nil, []changeset.ChangesetApplication{ + { + Changeset: changeset.WrapChangeSet(example.AddMintersBurnersLink), + Config: &example.AddMintersBurnersLinkConfig{ + ChainSelector: chainSelector, + Minters: []common.Address{chain.DeployerKey.From}, + }, + }, + }) + require.NoError(t, err) + + timelockAddress := mcmsState.Timelock.Address() + + // Mint some funds + _, err = example.MintLink(env, &example.MintLinkConfig{ + ChainSelector: chainSelector, + To: timelockAddress, + Amount: big.NewInt(7568), + }) + require.NoError(t, err) + + // check timelock balance + endBalance, err := linkState.LinkToken.BalanceOf(&bind.CallOpts{Context: ctx}, timelockAddress) + require.NoError(t, err) + expectedBalance := big.NewInt(7568) + require.Equal(t, expectedBalance, endBalance) +} diff --git a/deployment/common/changeset/internal/mcms_test.go b/deployment/common/changeset/internal/mcms_test.go index 8446aab4bfe..ff013717d30 100644 --- a/deployment/common/changeset/internal/mcms_test.go +++ b/deployment/common/changeset/internal/mcms_test.go @@ -40,7 +40,7 @@ func TestDeployMCMSWithTimelockContracts(t *testing.T) { addresses, err := ab.AddressesForChain(chainsel.TEST_90000001.Selector) require.NoError(t, err) require.Len(t, addresses, 5) - mcmsState, err := changeset.MaybeLoadMCMSWithTimelockState(chains[chainsel.TEST_90000001.Selector], addresses) + mcmsState, err := changeset.MaybeLoadMCMSWithTimelockChainState(chains[chainsel.TEST_90000001.Selector], addresses) require.NoError(t, err) v, err := mcmsState.GenerateMCMSWithTimelockView() b, err := json.MarshalIndent(v, "", " ") diff --git a/deployment/common/changeset/state.go b/deployment/common/changeset/state.go index c45fe6ba9b5..0db34abad71 100644 --- a/deployment/common/changeset/state.go +++ b/deployment/common/changeset/state.go @@ -5,6 +5,7 @@ import ( "fmt" "github.com/ethereum/go-ethereum/common" + owner_helpers "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" @@ -22,17 +23,6 @@ type MCMSWithTimelockState struct { *proposalutils.MCMSWithTimelockContracts } -func MaybeLoadMCMSWithTimelockState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (*MCMSWithTimelockState, error) { - contracts, err := proposalutils.MaybeLoadMCMSWithTimelockContracts(chain, addresses) - if err != nil { - return nil, err - } - - return &MCMSWithTimelockState{ - MCMSWithTimelockContracts: contracts, - }, nil -} - func (state MCMSWithTimelockState) GenerateMCMSWithTimelockView() (v1_0.MCMSWithTimelockView, error) { if err := state.Validate(); err != nil { return v1_0.MCMSWithTimelockView{}, err @@ -66,6 +56,91 @@ func (state MCMSWithTimelockState) GenerateMCMSWithTimelockView() (v1_0.MCMSWith }, nil } +// MaybeLoadMCMSWithTimelockState loads the MCMSWithTimelockState state for each chain in the given environment. +func MaybeLoadMCMSWithTimelockState(env deployment.Environment, chainSelectors []uint64) (map[uint64]*MCMSWithTimelockState, error) { + result := map[uint64]*MCMSWithTimelockState{} + for _, chainSelector := range chainSelectors { + chain, ok := env.Chains[chainSelector] + if !ok { + return nil, fmt.Errorf("chain %d not found", chainSelector) + } + addressesChain, err := env.ExistingAddresses.AddressesForChain(chainSelector) + if err != nil { + return nil, err + } + state, err := MaybeLoadMCMSWithTimelockChainState(chain, addressesChain) + if err != nil { + return nil, err + } + result[chainSelector] = state + } + return result, nil +} + +// MaybeLoadMCMSWithTimelockChainState looks for the addresses corresponding to +// contracts deployed with DeployMCMSWithTimelock and loads them into a +// MCMSWithTimelockState struct. If none of the contracts are found, the state struct will be nil. +// An error indicates: +// - 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) +func MaybeLoadMCMSWithTimelockChainState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (*MCMSWithTimelockState, error) { + state := MCMSWithTimelockState{ + MCMSWithTimelockContracts: &proposalutils.MCMSWithTimelockContracts{}, + } + // We expect one of each contract on the chain. + timelock := deployment.NewTypeAndVersion(types.RBACTimelock, deployment.Version1_0_0) + callProxy := deployment.NewTypeAndVersion(types.CallProxy, deployment.Version1_0_0) + proposer := deployment.NewTypeAndVersion(types.ProposerManyChainMultisig, deployment.Version1_0_0) + canceller := deployment.NewTypeAndVersion(types.CancellerManyChainMultisig, deployment.Version1_0_0) + bypasser := deployment.NewTypeAndVersion(types.BypasserManyChainMultisig, deployment.Version1_0_0) + + // Ensure we either have the bundle or not. + _, err := deployment.AddressesContainBundle(addresses, + map[deployment.TypeAndVersion]struct{}{ + timelock: {}, proposer: {}, canceller: {}, bypasser: {}, callProxy: {}, + }) + if err != nil { + return nil, fmt.Errorf("unable to check MCMS contracts on chain %s error: %w", chain.Name(), err) + } + + for address, tvStr := range addresses { + switch tvStr { + case timelock: + tl, err := owner_helpers.NewRBACTimelock(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.Timelock = tl + case callProxy: + cp, err := owner_helpers.NewCallProxy(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.CallProxy = cp + case proposer: + mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.ProposerMcm = mcms + case bypasser: + mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.BypasserMcm = mcms + case canceller: + mcms, err := owner_helpers.NewManyChainMultiSig(common.HexToAddress(address), chain.Client) + if err != nil { + return nil, err + } + state.CancellerMcm = mcms + } + } + return &state, nil +} + type LinkTokenState struct { LinkToken *link_token.LinkToken } @@ -77,7 +152,28 @@ func (s LinkTokenState) GenerateLinkView() (v1_0.LinkTokenView, error) { return v1_0.GenerateLinkTokenView(s.LinkToken) } -func MaybeLoadLinkTokenState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (*LinkTokenState, error) { +// MaybeLoadLinkTokenState loads the LinkTokenState state for each chain in the given environment. +func MaybeLoadLinkTokenState(env deployment.Environment, chainSelectors []uint64) (map[uint64]*LinkTokenState, error) { + result := map[uint64]*LinkTokenState{} + for _, chainSelector := range chainSelectors { + chain, ok := env.Chains[chainSelector] + if !ok { + return nil, fmt.Errorf("chain %d not found", chainSelector) + } + addressesChain, err := env.ExistingAddresses.AddressesForChain(chainSelector) + if err != nil { + return nil, err + } + state, err := MaybeLoadLinkTokenChainState(chain, addressesChain) + if err != nil { + return nil, err + } + result[chainSelector] = state + } + return result, nil +} + +func MaybeLoadLinkTokenChainState(chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (*LinkTokenState, error) { state := LinkTokenState{} linkToken := deployment.NewTypeAndVersion(types.LinkToken, deployment.Version1_0_0) // Perhaps revisit if we have a use case for multiple. diff --git a/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go b/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go index 40cef99a54f..7ba11596a2d 100644 --- a/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go +++ b/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go @@ -34,9 +34,9 @@ func TestTransferToMCMSWithTimelock(t *testing.T) { require.NoError(t, err) addrs, err := e.ExistingAddresses.AddressesForChain(chain1) require.NoError(t, err) - state, err := MaybeLoadMCMSWithTimelockState(e.Chains[chain1], addrs) + state, err := MaybeLoadMCMSWithTimelockChainState(e.Chains[chain1], addrs) require.NoError(t, err) - link, err := MaybeLoadLinkTokenState(e.Chains[chain1], addrs) + link, err := MaybeLoadLinkTokenChainState(e.Chains[chain1], addrs) require.NoError(t, err) e, err = ApplyChangesets(t, e, map[uint64]*proposalutils.TimelockExecutionContracts{ chain1: { @@ -56,7 +56,7 @@ func TestTransferToMCMSWithTimelock(t *testing.T) { }) require.NoError(t, err) // We expect now that the link token is owned by the MCMS timelock. - link, err = MaybeLoadLinkTokenState(e.Chains[chain1], addrs) + link, err = MaybeLoadLinkTokenChainState(e.Chains[chain1], addrs) require.NoError(t, err) o, err := link.LinkToken.Owner(nil) require.NoError(t, err) diff --git a/deployment/common/proposalutils/propose.go b/deployment/common/proposalutils/propose.go index feaee69940e..32a5bcdfda2 100644 --- a/deployment/common/proposalutils/propose.go +++ b/deployment/common/proposalutils/propose.go @@ -15,7 +15,8 @@ const ( DefaultValidUntil = 72 * time.Hour ) -func buildProposalMetadata( + +func BuildProposalMetadata( chainSelectors []uint64, proposerMcmsesPerChain map[uint64]*gethwrappers.ManyChainMultiSig, ) (map[mcms.ChainIdentifier]mcms.ChainMetadata, error) { @@ -56,7 +57,7 @@ func BuildProposalFromBatches( chains.Add(uint64(op.ChainIdentifier)) } - mcmsMd, err := buildProposalMetadata(chains.ToSlice(), proposerMcmsesPerChain) + mcmsMd, err := BuildProposalMetadata(chains.ToSlice(), proposerMcmsesPerChain) if err != nil { return nil, err } diff --git a/deployment/environment.go b/deployment/environment.go index c9de89b8c0c..0823404da2d 100644 --- a/deployment/environment.go +++ b/deployment/environment.go @@ -181,7 +181,7 @@ func MaybeDataErr(err error) error { var d rpc.DataError ok := errors.As(err, &d) if ok { - return d + return fmt.Errorf("%s: %v", d.Error(), d.ErrorData()) } return err } diff --git a/deployment/keystone/changeset/accept_ownership_test.go b/deployment/keystone/changeset/accept_ownership_test.go index 9e9d29e563a..d949e63c7aa 100644 --- a/deployment/keystone/changeset/accept_ownership_test.go +++ b/deployment/keystone/changeset/accept_ownership_test.go @@ -51,7 +51,7 @@ func TestAcceptAllOwnership(t *testing.T) { require.NoError(t, err) addrs, err := env.ExistingAddresses.AddressesForChain(registrySel) require.NoError(t, err) - timelock, err := commonchangeset.MaybeLoadMCMSWithTimelockState(env.Chains[registrySel], addrs) + timelock, err := commonchangeset.MaybeLoadMCMSWithTimelockChainState(env.Chains[registrySel], addrs) require.NoError(t, err) _, err = commonchangeset.ApplyChangesets(t, env, map[uint64]*proposalutils.TimelockExecutionContracts{ diff --git a/deployment/keystone/state.go b/deployment/keystone/state.go index cbf449c7f31..0ac7cdc89ed 100644 --- a/deployment/keystone/state.go +++ b/deployment/keystone/state.go @@ -78,7 +78,7 @@ func GetContractSets(lggr logger.Logger, req *GetContractSetsRequest) (*GetContr func loadContractSet(lggr logger.Logger, chain deployment.Chain, addresses map[string]deployment.TypeAndVersion) (*ContractSet, error) { var out ContractSet - mcmsWithTimelock, err := commonchangeset.MaybeLoadMCMSWithTimelockState(chain, addresses) + mcmsWithTimelock, err := commonchangeset.MaybeLoadMCMSWithTimelockChainState(chain, addresses) if err != nil { return nil, fmt.Errorf("failed to load mcms contract: %w", err) } From 8f1b956efe05aa9ca819d755d6c1386740bd5533 Mon Sep 17 00:00:00 2001 From: Austin <107539019+0xAustinWang@users.noreply.github.com> Date: Fri, 13 Dec 2024 10:57:09 +0800 Subject: [PATCH 06/29] Initialization for Crib (#15501) * wip * test crib integration flow * build failures * changes from ani's comments * some changes * revert isempty check * go lint and compare integers * fix types in test * check for error if there's already a feeds manager * check if job distributors exist first * wip changes * add retries to consistently failing JD cals * update retries with static duration * remove print statements * fix compile error * remove unnecessary mcms changes * build issues * passing deployment * clean up code comments * gomodtidy * lint * formatting strings * use the common changeset utilities when deploying home chain as well * compare nodes job distributors public key against the one we expect * move state reader under deployment module * add RPC type with internal and external rpcs --------- Co-authored-by: Radek Scheibinger --- deployment/address_book.go | 4 +- deployment/environment/crib/ccip_deployer.go | 136 ++++++++++++++++++ deployment/environment/crib/data.go | 81 +++++++++++ deployment/environment/crib/env.go | 45 ++++++ deployment/environment/crib/env_test.go | 18 +++ .../ccip-v2-scripts-address-book.json | 1 + .../ccip-v2-scripts-chains-details.json | 24 ++++ .../ccip-v2-scripts-nodes-details.json | 1 + deployment/environment/crib/types.go | 39 +++++ deployment/environment/devenv/don.go | 88 ++++++++---- .../environment/web/sdk/client/client.go | 16 ++- integration-tests/load/go.mod | 1 + integration-tests/testconfig/ccip/config.go | 22 ++- 13 files changed, 435 insertions(+), 41 deletions(-) create mode 100644 deployment/environment/crib/ccip_deployer.go create mode 100644 deployment/environment/crib/data.go create mode 100644 deployment/environment/crib/env.go create mode 100644 deployment/environment/crib/env_test.go create mode 100644 deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-address-book.json create mode 100644 deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-chains-details.json create mode 100644 deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-nodes-details.json create mode 100644 deployment/environment/crib/types.go diff --git a/deployment/address_book.go b/deployment/address_book.go index 6f605013011..3ce0332a4c3 100644 --- a/deployment/address_book.go +++ b/deployment/address_book.go @@ -89,8 +89,10 @@ type AddressBook interface { Remove(ab AddressBook) error } +type AddressesByChain map[uint64]map[string]TypeAndVersion + type AddressBookMap struct { - addressesByChain map[uint64]map[string]TypeAndVersion + addressesByChain AddressesByChain mtx sync.RWMutex } diff --git a/deployment/environment/crib/ccip_deployer.go b/deployment/environment/crib/ccip_deployer.go new file mode 100644 index 00000000000..aea7ad0cb8f --- /dev/null +++ b/deployment/environment/crib/ccip_deployer.go @@ -0,0 +1,136 @@ +package crib + +import ( + "context" + "errors" + "fmt" + "github.com/ethereum/go-ethereum/common" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/config" + commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" + "github.com/smartcontractkit/chainlink/deployment/environment/devenv" + "github.com/smartcontractkit/chainlink/v2/core/services/relay" + "math/big" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" + "github.com/smartcontractkit/chainlink/v2/core/logger" +) + +// DeployHomeChainContracts deploys the home chain contracts so that the chainlink nodes can be started with the CR address in Capabilities.ExternalRegistry +// DeployHomeChainContracts is to 1. Set up crib with chains and chainlink nodes ( cap reg is not known yet so not setting the config with capreg address) +// Call DeployHomeChain changeset with nodeinfo ( the peer id and all) +func DeployHomeChainContracts(ctx context.Context, lggr logger.Logger, envConfig devenv.EnvironmentConfig, homeChainSel uint64, feedChainSel uint64) (deployment.CapabilityRegistryConfig, deployment.AddressBook, error) { + e, _, err := devenv.NewEnvironment(func() context.Context { return ctx }, lggr, envConfig) + if err != nil { + return deployment.CapabilityRegistryConfig{}, nil, err + } + if e == nil { + return deployment.CapabilityRegistryConfig{}, nil, errors.New("environment is nil") + } + + nodes, err := deployment.NodeInfo(e.NodeIDs, e.Offchain) + if err != nil { + return deployment.CapabilityRegistryConfig{}, e.ExistingAddresses, fmt.Errorf("failed to get node info from env: %w", err) + } + p2pIds := nodes.NonBootstraps().PeerIDs() + *e, err = commonchangeset.ApplyChangesets(nil, *e, nil, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(changeset.DeployHomeChain), + Config: changeset.DeployHomeChainConfig{ + HomeChainSel: homeChainSel, + RMNStaticConfig: changeset.NewTestRMNStaticConfig(), + RMNDynamicConfig: changeset.NewTestRMNDynamicConfig(), + NodeOperators: changeset.NewTestNodeOperator(e.Chains[homeChainSel].DeployerKey.From), + NodeP2PIDsPerNodeOpAdmin: map[string][][32]byte{ + "NodeOperator": p2pIds, + }, + }, + }, + }) + + state, err := changeset.LoadOnchainState(*e) + if err != nil { + return deployment.CapabilityRegistryConfig{}, e.ExistingAddresses, fmt.Errorf("failed to load on chain state: %w", err) + } + capRegAddr := state.Chains[homeChainSel].CapabilityRegistry.Address() + if capRegAddr == common.HexToAddress("0x") { + return deployment.CapabilityRegistryConfig{}, e.ExistingAddresses, fmt.Errorf("cap Reg address not found: %w", err) + } + capRegConfig := deployment.CapabilityRegistryConfig{ + EVMChainID: homeChainSel, + Contract: state.Chains[homeChainSel].CapabilityRegistry.Address(), + NetworkType: relay.NetworkEVM, + } + return capRegConfig, e.ExistingAddresses, nil +} + +func DeployCCIPAndAddLanes(ctx context.Context, lggr logger.Logger, envConfig devenv.EnvironmentConfig, homeChainSel, feedChainSel uint64, ab deployment.AddressBook) (DeployCCIPOutput, error) { + e, _, err := devenv.NewEnvironment(func() context.Context { return ctx }, lggr, envConfig) + if err != nil { + return DeployCCIPOutput{}, fmt.Errorf("failed to initiate new environment: %w", err) + } + e.ExistingAddresses = ab + allChainIds := e.AllChainSelectors() + cfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) + for _, chain := range e.AllChainSelectors() { + mcmsConfig, err := config.NewConfig(1, []common.Address{e.Chains[chain].DeployerKey.From}, []config.Config{}) + if err != nil { + return DeployCCIPOutput{}, fmt.Errorf("failed to create mcms config: %w", err) + } + cfg[chain] = commontypes.MCMSWithTimelockConfig{ + Canceller: *mcmsConfig, + Bypasser: *mcmsConfig, + Proposer: *mcmsConfig, + TimelockMinDelay: big.NewInt(0), + } + } + + // This will not apply any proposals because we pass nil to testing. + // However, setup is ok because we only need to deploy the contracts and distribute job specs + *e, err = commonchangeset.ApplyChangesets(nil, *e, nil, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployLinkToken), + Config: allChainIds, + }, + { + Changeset: commonchangeset.WrapChangeSet(changeset.DeployPrerequisites), + Config: changeset.DeployPrerequisiteConfig{ + ChainSelectors: allChainIds, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), + Config: cfg, + }, + { + Changeset: commonchangeset.WrapChangeSet(changeset.DeployChainContracts), + Config: changeset.DeployChainContractsConfig{ + ChainSelectors: allChainIds, + HomeChainSelector: homeChainSel, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(changeset.CCIPCapabilityJobspec), + Config: struct{}{}, + }, + }) + state, err := changeset.LoadOnchainState(*e) + if err != nil { + return DeployCCIPOutput{}, fmt.Errorf("failed to load onchain state: %w", err) + } + // Add all lanes + err = changeset.AddLanesForAll(*e, state) + if err != nil { + return DeployCCIPOutput{}, fmt.Errorf("failed to add lanes: %w", err) + } + + addresses, err := e.ExistingAddresses.Addresses() + if err != nil { + return DeployCCIPOutput{}, fmt.Errorf("failed to get convert address book to address book map: %w", err) + } + return DeployCCIPOutput{ + AddressBook: *deployment.NewMemoryAddressBookFromMap(addresses), + NodeIDs: e.NodeIDs, + }, err +} diff --git a/deployment/environment/crib/data.go b/deployment/environment/crib/data.go new file mode 100644 index 00000000000..b9197691613 --- /dev/null +++ b/deployment/environment/crib/data.go @@ -0,0 +1,81 @@ +package crib + +import ( + "encoding/json" + "fmt" + "io" + "os" + + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/environment/devenv" +) + +type OutputReader struct { + outputDir string +} + +func NewOutputReader(outputDir string) *OutputReader { + return &OutputReader{outputDir: outputDir} +} + +func (r *OutputReader) ReadNodesDetails() NodesDetails { + byteValue := r.readFile(NodesDetailsFileName) + + var result NodesDetails + + // Unmarshal the JSON into the map + err := json.Unmarshal(byteValue, &result) + if err != nil { + fmt.Println("Error unmarshalling JSON:", err) + panic(err) + } + + return result +} + +func (r *OutputReader) ReadChainConfigs() []devenv.ChainConfig { + byteValue := r.readFile(ChainsConfigsFileName) + + var result []devenv.ChainConfig + + // Unmarshal the JSON into the map + err := json.Unmarshal(byteValue, &result) + if err != nil { + fmt.Println("Error unmarshalling JSON:", err) + panic(err) + } + + return result +} + +func (r *OutputReader) ReadAddressBook() *deployment.AddressBookMap { + byteValue := r.readFile(AddressBookFileName) + + var result map[uint64]map[string]deployment.TypeAndVersion + + // Unmarshal the JSON into the map + err := json.Unmarshal(byteValue, &result) + if err != nil { + fmt.Println("Error unmarshalling JSON:", err) + panic(err) + } + + return deployment.NewMemoryAddressBookFromMap(result) +} + +func (r *OutputReader) readFile(fileName string) []byte { + file, err := os.Open(fmt.Sprintf("%s/%s", r.outputDir, fileName)) + if err != nil { + fmt.Println("Error opening file:", err) + panic(err) + } + defer file.Close() + + // Read the file's content into a byte slice + byteValue, err := io.ReadAll(file) + if err != nil { + fmt.Println("Error reading file:", err) + panic(err) + } + return byteValue +} diff --git a/deployment/environment/crib/env.go b/deployment/environment/crib/env.go new file mode 100644 index 00000000000..3af1acaf754 --- /dev/null +++ b/deployment/environment/crib/env.go @@ -0,0 +1,45 @@ +package crib + +const ( + AddressBookFileName = "ccip-v2-scripts-address-book.json" + NodesDetailsFileName = "ccip-v2-scripts-nodes-details.json" + ChainsConfigsFileName = "ccip-v2-scripts-chains-details.json" +) + +type CRIBEnv struct { + envStateDir string +} + +func NewDevspaceEnvFromStateDir(envStateDir string) CRIBEnv { + return CRIBEnv{ + envStateDir: envStateDir, + } +} + +func (c CRIBEnv) GetConfig() DeployOutput { + reader := NewOutputReader(c.envStateDir) + nodesDetails := reader.ReadNodesDetails() + chainConfigs := reader.ReadChainConfigs() + return DeployOutput{ + AddressBook: reader.ReadAddressBook(), + NodeIDs: nodesDetails.NodeIDs, + Chains: chainConfigs, + } +} + +type RPC struct { + External *string + Internal *string +} + +type ChainConfig struct { + ChainID uint64 // chain id as per EIP-155, mainly applicable for EVM chains + ChainName string // name of the chain populated from chainselector repo + ChainType string // should denote the chain family. Acceptable values are EVM, COSMOS, SOLANA, STARKNET, APTOS etc + WSRPCs []RPC // websocket rpcs to connect to the chain + HTTPRPCs []RPC // http rpcs to connect to the chain +} + +type NodesDetails struct { + NodeIDs []string +} diff --git a/deployment/environment/crib/env_test.go b/deployment/environment/crib/env_test.go new file mode 100644 index 00000000000..262a2540923 --- /dev/null +++ b/deployment/environment/crib/env_test.go @@ -0,0 +1,18 @@ +package crib + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestShouldProvideEnvironmentConfig(t *testing.T) { + t.Parallel() + env := NewDevspaceEnvFromStateDir("testdata/lanes-deployed-state") + config := env.GetConfig() + require.NotNil(t, config) + assert.NotEmpty(t, config.NodeIDs) + assert.NotNil(t, config.AddressBook) + assert.NotEmpty(t, config.Chains) +} diff --git a/deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-address-book.json b/deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-address-book.json new file mode 100644 index 00000000000..e4b2672cb5f --- /dev/null +++ b/deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-address-book.json @@ -0,0 +1 @@ +{"12922642891491394802":{"0x05Aa229Aec102f78CE0E852A812a388F076Aa555":{"Type":"CancellerManyChainMultiSig","Version":"1.0.0"},"0x0D4ff719551E23185Aeb16FFbF2ABEbB90635942":{"Type":"TestRouter","Version":"1.2.0"},"0x0f5D1ef48f12b6f691401bfe88c2037c690a6afe":{"Type":"ProposerManyChainMultiSig","Version":"1.0.0"},"0x2dE080e97B0caE9825375D31f5D0eD5751fDf16D":{"Type":"CCIPReceiver","Version":"1.0.0"},"0x2fc631e4B3018258759C52AF169200213e84ABab":{"Type":"OnRamp","Version":"1.6.0-dev"},"0x5C7c905B505f0Cf40Ab6600d05e677F717916F6B":{"Type":"Router","Version":"1.2.0"},"0x63cf2Cd54fE91e3545D1379abf5bfd194545259d":{"Type":"OffRamp","Version":"1.6.0-dev"},"0x712516e61C8B383dF4A63CFe83d7701Bce54B03e":{"Type":"LinkToken","Version":"1.0.0"},"0x71C95911E9a5D330f4D621842EC243EE1343292e":{"Type":"PriceFeed","Version":"1.0.0"},"0x73eccD6288e117cAcA738BDAD4FEC51312166C1A":{"Type":"RMNRemote","Version":"1.6.0-dev"},"0x8464135c8F25Da09e49BC8782676a84730C318bC":{"Type":"PriceFeed","Version":"1.0.0"},"0x85C5Dd61585773423e378146D4bEC6f8D149E248":{"Type":"TokenAdminRegistry","Version":"1.5.0"},"0x948B3c65b89DF0B4894ABE91E6D02FE579834F8F":{"Type":"WETH9","Version":"1.0.0"},"0xAfe1b5bdEbD4ae65AF2024738bf0735fbb65d44b":{"Type":"FeeQuoter","Version":"1.6.0-dev"},"0xC6bA8C3233eCF65B761049ef63466945c362EdD2":{"Type":"BypasserManyChainMultiSig","Version":"1.0.0"},"0xbCF26943C0197d2eE0E5D05c716Be60cc2761508":{"Type":"AdminManyChainMultiSig","Version":"1.0.0"},"0xcA03Dc4665A8C3603cb4Fd5Ce71Af9649dC00d44":{"Type":"RBACTimelock","Version":"1.0.0"},"0xe6b98F104c1BEf218F3893ADab4160Dc73Eb8367":{"Type":"ARMProxy","Version":"1.0.0"},"0xfbAb4aa40C202E4e80390171E82379824f7372dd":{"Type":"NonceManager","Version":"1.6.0-dev"}},"3379446385462418246":{"0x09635F643e140090A9A8Dcd712eD6285858ceBef":{"Type":"RMNRemote","Version":"1.6.0-dev"},"0x0B306BF915C4d645ff596e518fAf3F9669b97016":{"Type":"LinkToken","Version":"1.0.0"},"0x1613beB3B2C4f22Ee086B2b38C1476A3cE7f78E8":{"Type":"OnRamp","Version":"1.6.0-dev"},"0x2279B7A0a67DB372996a5FaB50D91eAA73d2eBe6":{"Type":"CCIPHome","Version":"1.6.0-dev"},"0x322813Fd9A801c5507c9de605d63CEA4f2CE6c44":{"Type":"ProposerManyChainMultiSig","Version":"1.0.0"},"0x3Aa5ebB10DC797CAC828524e59A333d0A371443c":{"Type":"BypasserManyChainMultiSig","Version":"1.0.0"},"0x4A679253410272dd5232B3Ff7cF5dbB88f295319":{"Type":"RBACTimelock","Version":"1.0.0"},"0x59b670e9fA9D0A427751Af201D676719a970857b":{"Type":"CancellerManyChainMultiSig","Version":"1.0.0"},"0x67d269191c92Caf3cD7723F116c85e6E9bf55933":{"Type":"ARMProxy","Version":"1.0.0"},"0x7a2088a1bFc9d81c55368AE168C2C02570cB814F":{"Type":"CCIPReceiver","Version":"1.0.0"},"0x84eA74d481Ee0A5332c457a4d796187F6Ba67fEB":{"Type":"TokenAdminRegistry","Version":"1.5.0"},"0x851356ae760d987E095750cCeb3bC6014560891C":{"Type":"OffRamp","Version":"1.6.0-dev"},"0x8A791620dd6260079BF849Dc5567aDC3F2FdC318":{"Type":"RMNHome","Version":"1.6.0-dev"},"0x9A676e781A523b5d0C0e43731313A708CB607508":{"Type":"WETH9","Version":"1.0.0"},"0x9A9f2CCfdE556A7E9Ff0848998Aa4a0CFD8863AE":{"Type":"AdminManyChainMultiSig","Version":"1.0.0"},"0x9E545E3C0baAB3E08CdfD552C960A1050f373042":{"Type":"NonceManager","Version":"1.6.0-dev"},"0xE6E340D132b5f46d1e472DebcD681B2aBc16e57E":{"Type":"Router","Version":"1.2.0"},"0xa513E6E4b8f2a923D98304ec87F64353C4D5C853":{"Type":"CapabilitiesRegistry","Version":"1.0.0"},"0xa82fF9aFd8f496c3d6ac40E2a0F282E47488CFc9":{"Type":"FeeQuoter","Version":"1.6.0-dev"},"0xc3e53F4d16Ae77Db1c982e75a937B9f60FE63690":{"Type":"TestRouter","Version":"1.2.0"}}} diff --git a/deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-chains-details.json b/deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-chains-details.json new file mode 100644 index 00000000000..f93ea4ce231 --- /dev/null +++ b/deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-chains-details.json @@ -0,0 +1,24 @@ +[ + { + "ChainID": 1337, + "ChainName": "alpha", + "ChainType": "EVM", + "WSRPCs": [ + "wss://crib-local-geth-1337-ws.local:443" + ], + "HTTPRPCs": [ + "https://crib-local-geth-1337-ws.local:443" + ] + }, + { + "ChainID": 2337, + "ChainName": "alpha", + "ChainType": "EVM", + "WSRPCs": [ + "wss://crib-local-geth-2337-ws.local:443" + ], + "HTTPRPCs": [ + "https://crib-local-geth-2337-ws.local:443" + ] + } +] diff --git a/deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-nodes-details.json b/deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-nodes-details.json new file mode 100644 index 00000000000..477ae0527b1 --- /dev/null +++ b/deployment/environment/crib/testdata/lanes-deployed-state/ccip-v2-scripts-nodes-details.json @@ -0,0 +1 @@ +{"NodeIDs":["node_2URuou3RXmtZu5gLQX8qd","node_m9TTQbUxBx3WjDEjmpVDL","node_4FiKVPtuQjCTvHnS7QpES","node_A4VTgecDwMoG2YYicyjuG","node_jQFpzXDadzaADq147nThS"]} diff --git a/deployment/environment/crib/types.go b/deployment/environment/crib/types.go new file mode 100644 index 00000000000..d19c8424443 --- /dev/null +++ b/deployment/environment/crib/types.go @@ -0,0 +1,39 @@ +package crib + +import ( + "context" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink/deployment" + "github.com/smartcontractkit/chainlink/deployment/environment/devenv" +) + +const ( + CRIB_ENV_NAME = "Crib Environment" +) + +type DeployOutput struct { + NodeIDs []string + Chains []devenv.ChainConfig // chain selector -> Chain Config + AddressBook deployment.AddressBook // Addresses of all contracts +} + +type DeployCCIPOutput struct { + AddressBook deployment.AddressBookMap + NodeIDs []string +} + +func NewDeployEnvironmentFromCribOutput(lggr logger.Logger, output DeployOutput) (*deployment.Environment, error) { + chains, err := devenv.NewChains(lggr, output.Chains) + if err != nil { + return nil, err + } + return deployment.NewEnvironment( + CRIB_ENV_NAME, + lggr, + output.AddressBook, + chains, + output.NodeIDs, + nil, // todo: populate the offchain client using output.DON + func() context.Context { return context.Background() }, deployment.XXXGenerateTestOCRSecrets(), + ), nil +} diff --git a/deployment/environment/devenv/don.go b/deployment/environment/devenv/don.go index 05a3d5bea08..76f6ee92b68 100644 --- a/deployment/environment/devenv/don.go +++ b/deployment/environment/devenv/don.go @@ -2,7 +2,9 @@ package devenv import ( "context" + "errors" "fmt" + chainsel "github.com/smartcontractkit/chain-selectors" "strconv" "strings" "time" @@ -10,8 +12,6 @@ import ( "github.com/hashicorp/go-multierror" "github.com/rs/zerolog" "github.com/sethvargo/go-retry" - chainsel "github.com/smartcontractkit/chain-selectors" - nodev1 "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" clclient "github.com/smartcontractkit/chainlink/deployment/environment/nodeclient" "github.com/smartcontractkit/chainlink/deployment/environment/web/sdk/client" @@ -185,7 +185,7 @@ type JDChainConfigInput struct { // It expects bootstrap nodes to have label with key "type" and value as "bootstrap". // It fetches the account address, peer id, and OCR2 key bundle id and creates the JobDistributorChainConfig. func (n *Node) CreateCCIPOCRSupportedChains(ctx context.Context, chains []JDChainConfigInput, jd JobDistributor) error { - for i, chain := range chains { + for _, chain := range chains { chainId := strconv.FormatUint(chain.ChainID, 10) var account string switch chain.ChainType { @@ -239,35 +239,51 @@ func (n *Node) CreateCCIPOCRSupportedChains(ctx context.Context, chains []JDChai break } } - // JD silently fails to update nodeChainConfig. Therefore, we fetch the node config and - // if it's not updated , throw an error - _, err = n.gqlClient.CreateJobDistributorChainConfig(ctx, client.JobDistributorChainConfigInput{ - JobDistributorID: n.JDId, - ChainID: chainId, - ChainType: chain.ChainType, - AccountAddr: account, - AdminAddr: n.adminAddr, - Ocr2Enabled: true, - Ocr2IsBootstrap: isBootstrap, - Ocr2Multiaddr: n.multiAddr, - Ocr2P2PPeerID: value(peerID), - Ocr2KeyBundleID: ocr2BundleId, - Ocr2Plugins: `{"commit":true,"execute":true,"median":false,"mercury":false}`, + + // retry twice with 5 seconds interval to create JobDistributorChainConfig + err = retry.Do(ctx, retry.WithMaxDuration(10*time.Second, retry.NewConstant(3*time.Second)), func(ctx context.Context) error { + // check the node chain config to see if this chain already exists + nodeChainConfigs, err := jd.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{ + Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ + NodeIds: []string{n.NodeId}, + }}) + if err != nil { + return retry.RetryableError(fmt.Errorf("failed to list node chain configs for node %s, retrying..: %w", n.Name, err)) + } + if nodeChainConfigs != nil { + for _, chainConfig := range nodeChainConfigs.ChainConfigs { + if chainConfig.Chain.Id == chainId { + return nil + } + } + } + + // JD silently fails to update nodeChainConfig. Therefore, we fetch the node config and + // if it's not updated , throw an error + _, err = n.gqlClient.CreateJobDistributorChainConfig(ctx, client.JobDistributorChainConfigInput{ + JobDistributorID: n.JDId, + ChainID: chainId, + ChainType: chain.ChainType, + AccountAddr: account, + AdminAddr: n.adminAddr, + Ocr2Enabled: true, + Ocr2IsBootstrap: isBootstrap, + Ocr2Multiaddr: n.multiAddr, + Ocr2P2PPeerID: value(peerID), + Ocr2KeyBundleID: ocr2BundleId, + Ocr2Plugins: `{"commit":true,"execute":true,"median":false,"mercury":false}`, + }) + // todo: add a check if the chain config failed because of a duplicate in that case, should we update or return success? + if err != nil { + return fmt.Errorf("failed to create CCIPOCR2SupportedChains for node %s: %w", n.Name, err) + } + + return retry.RetryableError(errors.New("retrying CreateChainConfig in JD")) }) + if err != nil { return fmt.Errorf("failed to create CCIPOCR2SupportedChains for node %s: %w", n.Name, err) } - // query the node chain config to check if it's created - nodeChainConfigs, err := jd.ListNodeChainConfigs(context.Background(), &nodev1.ListNodeChainConfigsRequest{ - Filter: &nodev1.ListNodeChainConfigsRequest_Filter{ - NodeIds: []string{n.NodeId}, - }}) - if err != nil { - return fmt.Errorf("failed to list node chain configs for node %s: %w", n.Name, err) - } - if nodeChainConfigs == nil || len(nodeChainConfigs.ChainConfigs) < i+1 { - return fmt.Errorf("failed to create chain config for node %s", n.Name) - } } return nil } @@ -377,6 +393,17 @@ func (n *Node) CreateJobDistributor(ctx context.Context, jd JobDistributor) (str return "", err } // create the job distributor in the node with the csa key + resp, err := n.gqlClient.ListJobDistributors(ctx) + if err != nil { + return "", fmt.Errorf("could not list job distrubutors: %w", err) + } + if len(resp.FeedsManagers.Results) > 0 { + for _, fm := range resp.FeedsManagers.Results { + if fm.GetPublicKey() == csaKey { + return fm.GetId(), nil + } + } + } return n.gqlClient.CreateJobDistributor(ctx, client.JobDistributorInput{ Name: "Job Distributor", Uri: jd.WSRPC, @@ -394,8 +421,9 @@ func (n *Node) SetUpAndLinkJobDistributor(ctx context.Context, jd JobDistributor } // now create the job distributor in the node id, err := n.CreateJobDistributor(ctx, jd) - if err != nil && !strings.Contains(err.Error(), "DuplicateFeedsManagerError") { - return err + if err != nil && + (!strings.Contains(err.Error(), "only a single feeds manager is supported") || !strings.Contains(err.Error(), "DuplicateFeedsManagerError")) { + return fmt.Errorf("failed to create job distributor in node %s: %w", n.Name, err) } // wait for the node to connect to the job distributor err = retry.Do(ctx, retry.WithMaxDuration(1*time.Minute, retry.NewFibonacci(1*time.Second)), func(ctx context.Context) error { diff --git a/deployment/environment/web/sdk/client/client.go b/deployment/environment/web/sdk/client/client.go index 5472591ef94..e0a56b9e642 100644 --- a/deployment/environment/web/sdk/client/client.go +++ b/deployment/environment/web/sdk/client/client.go @@ -4,10 +4,11 @@ import ( "context" "encoding/json" "fmt" + "github.com/Khan/genqlient/graphql" + "github.com/sethvargo/go-retry" "net/http" "strings" - - "github.com/Khan/genqlient/graphql" + "time" "github.com/smartcontractkit/chainlink/deployment/environment/web/sdk/client/doer" "github.com/smartcontractkit/chainlink/deployment/environment/web/sdk/internal/generated" @@ -60,8 +61,15 @@ func New(baseURI string, creds Credentials) (Client, error) { endpoints: ep, credentials: creds, } - - if err := c.login(); err != nil { + + err := retry.Do(context.Background(), retry.WithMaxDuration(10*time.Second, retry.NewFibonacci(2*time.Second)), func(ctx context.Context) error { + err := c.login() + if err != nil { + return retry.RetryableError(fmt.Errorf("retrying login to node: %w", err)) + } + return nil + }) + if err != nil { return nil, fmt.Errorf("failed to login to node: %w", err) } diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 3d240cccc9e..c94ea489c1b 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -398,6 +398,7 @@ require ( github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/segmentio/ksuid v1.0.4 // indirect github.com/sercand/kuberesolver/v5 v5.1.1 // indirect + github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect diff --git a/integration-tests/testconfig/ccip/config.go b/integration-tests/testconfig/ccip/config.go index 72c81f05f47..70c850fd591 100644 --- a/integration-tests/testconfig/ccip/config.go +++ b/integration-tests/testconfig/ccip/config.go @@ -147,6 +147,9 @@ func (o *JDConfig) GetJDDBVersion() string { func (o *Config) Validate() error { var chainIds []int64 for _, net := range o.PrivateEthereumNetworks { + if net.EthereumChainConfig.ChainID < 0 { + return fmt.Errorf("negative chain ID found for network %d", net.EthereumChainConfig.ChainID) + } chainIds = append(chainIds, int64(net.EthereumChainConfig.ChainID)) } homeChainSelector, err := strconv.ParseUint(pointer.GetString(o.HomeChainSelector), 10, 64) @@ -189,14 +192,21 @@ func IsSelectorValid(selector uint64, chainIds []int64) (bool, error) { if err != nil { return false, err } - if chainId >= math.MaxInt64 { - return false, fmt.Errorf("chain id overflows int64: %d", chainId) - } - expId := int64(chainId) - for _, id := range chainIds { - if id == expId { + + for _, cID := range chainIds { + if isEqualUint64AndInt64(chainId, cID) { return true, nil } } return false, nil } + +func isEqualUint64AndInt64(u uint64, i int64) bool { + if i < 0 { + return false // uint64 cannot be equal to a negative int64 + } + if u > math.MaxInt64 { + return false // uint64 cannot be equal to an int64 if it exceeds the maximum int64 value + } + return u == uint64(i) +} From 6f42463b557a9c2193977e60c59f042f3ef28aa0 Mon Sep 17 00:00:00 2001 From: dimitris Date: Fri, 13 Dec 2024 12:07:32 +0200 Subject: [PATCH 07/29] RMN tests CI reliability and one new test scenario (#15677) * re-enable rmn tests with larger runners * add uncurse test case * fix assignment to nil map --- .github/e2e-tests.yml | 16 ++-- integration-tests/smoke/ccip/ccip_rmn_test.go | 94 +++++++++++++++---- 2 files changed, 82 insertions(+), 28 deletions(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 1bf55a64418..93ddbb564b6 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -966,7 +966,7 @@ runner-test-matrix: - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_TwoMessagesOnTwoLanesIncludingBatching$ path: integration-tests/smoke/ccip/ccip_rmn_test.go test_env_type: docker - runs_on: ubuntu-latest + runs_on: ubuntu20.04-8cores-32GB triggers: - PR E2E Core Tests - Nightly E2E Tests @@ -982,7 +982,7 @@ runner-test-matrix: - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_MultipleMessagesOnOneLaneNoWaitForExec$ path: integration-tests/smoke/ccip/ccip_rmn_test.go test_env_type: docker - runs_on: ubuntu-latest + runs_on: ubuntu20.04-8cores-32GB triggers: - PR E2E Core Tests - Nightly E2E Tests @@ -998,7 +998,7 @@ runner-test-matrix: - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_NotEnoughObservers$ path: integration-tests/smoke/ccip/ccip_rmn_test.go test_env_type: docker - runs_on: ubuntu-latest + runs_on: ubuntu20.04-8cores-32GB triggers: - PR E2E Core Tests - Nightly E2E Tests @@ -1014,7 +1014,7 @@ runner-test-matrix: - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_DifferentSigners$ path: integration-tests/smoke/ccip/ccip_rmn_test.go test_env_type: docker - runs_on: ubuntu-latest + runs_on: ubuntu20.04-8cores-32GB triggers: - PR E2E Core Tests - Nightly E2E Tests @@ -1030,7 +1030,7 @@ runner-test-matrix: - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_NotEnoughSigners$ path: integration-tests/smoke/ccip/ccip_rmn_test.go test_env_type: docker - runs_on: ubuntu-latest + runs_on: ubuntu20.04-8cores-32GB triggers: - PR E2E Core Tests - Nightly E2E Tests @@ -1046,7 +1046,7 @@ runner-test-matrix: - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_DifferentRmnNodesForDifferentChains$ path: integration-tests/smoke/ccip/ccip_rmn_test.go test_env_type: docker - runs_on: ubuntu-latest + runs_on: ubuntu20.04-8cores-32GB triggers: - PR E2E Core Tests - Nightly E2E Tests @@ -1062,7 +1062,7 @@ runner-test-matrix: - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_TwoMessagesOneSourceChainCursed$ path: integration-tests/smoke/ccip/ccip_rmn_test.go test_env_type: docker - runs_on: ubuntu-latest + runs_on: ubuntu20.04-8cores-32GB triggers: - PR E2E Core Tests - Nightly E2E Tests @@ -1078,7 +1078,7 @@ runner-test-matrix: - id: smoke/ccip/ccip_rmn_test.go:^TestRMN_GlobalCurseTwoMessagesOnTwoLanes$ path: integration-tests/smoke/ccip/ccip_rmn_test.go test_env_type: docker - runs_on: ubuntu-latest + runs_on: ubuntu20.04-8cores-32GB triggers: - PR E2E Core Tests - Nightly E2E Tests diff --git a/integration-tests/smoke/ccip/ccip_rmn_test.go b/integration-tests/smoke/ccip/ccip_rmn_test.go index c22f9bcf20e..1075b28e9d3 100644 --- a/integration-tests/smoke/ccip/ccip_rmn_test.go +++ b/integration-tests/smoke/ccip/ccip_rmn_test.go @@ -18,11 +18,12 @@ import ( "github.com/rs/zerolog" "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-ccip/pkg/reader" "github.com/smartcontractkit/chainlink-protos/job-distributor/v1/node" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/osutil" "github.com/smartcontractkit/chainlink-testing-framework/lib/utils/testcontext" + "github.com/smartcontractkit/chainlink-ccip/pkg/reader" + "github.com/smartcontractkit/chainlink/deployment/ccip/changeset" "github.com/smartcontractkit/chainlink/deployment/environment/devenv" @@ -35,7 +36,6 @@ import ( ) func TestRMN_TwoMessagesOnTwoLanesIncludingBatching(t *testing.T) { - t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "messages on two lanes including batching", waitForExec: true, @@ -59,7 +59,6 @@ func TestRMN_TwoMessagesOnTwoLanesIncludingBatching(t *testing.T) { } func TestRMN_MultipleMessagesOnOneLaneNoWaitForExec(t *testing.T) { - t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "multiple messages for rmn batching inspection and one rmn node down", waitForExec: false, // do not wait for execution reports @@ -82,7 +81,6 @@ func TestRMN_MultipleMessagesOnOneLaneNoWaitForExec(t *testing.T) { } func TestRMN_NotEnoughObservers(t *testing.T) { - t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "one message but not enough observers, should not get a commit report", passIfNoCommitAfter: 15 * time.Second, @@ -105,7 +103,6 @@ func TestRMN_NotEnoughObservers(t *testing.T) { } func TestRMN_DifferentSigners(t *testing.T) { - t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "different signers and different observers", homeChainConfig: homeChainConfig{ @@ -130,7 +127,6 @@ func TestRMN_DifferentSigners(t *testing.T) { } func TestRMN_NotEnoughSigners(t *testing.T) { - t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "different signers and different observers", passIfNoCommitAfter: 15 * time.Second, @@ -156,7 +152,6 @@ func TestRMN_NotEnoughSigners(t *testing.T) { } func TestRMN_DifferentRmnNodesForDifferentChains(t *testing.T) { - t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "different rmn nodes support different chains", waitForExec: false, @@ -183,13 +178,15 @@ func TestRMN_DifferentRmnNodesForDifferentChains(t *testing.T) { } func TestRMN_TwoMessagesOneSourceChainCursed(t *testing.T) { - t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ - name: "two messages, one source chain is cursed", + name: "two messages, one source chain is cursed the other chain was cursed but curse is revoked", passIfNoCommitAfter: 15 * time.Second, cursedSubjectsPerChain: map[int][]int{ chain1: {chain0}, }, + revokedCursedSubjectsPerChain: map[int]map[int]time.Duration{ + chain0: {globalCurse: 5 * time.Second}, // chain0 will be globally cursed and curse will be revoked later + }, homeChainConfig: homeChainConfig{ f: map[int]int{chain0: 1, chain1: 1}, }, @@ -210,7 +207,6 @@ func TestRMN_TwoMessagesOneSourceChainCursed(t *testing.T) { } func TestRMN_GlobalCurseTwoMessagesOnTwoLanes(t *testing.T) { - t.Skip("This test is flaky and needs to be fixed") runRmnTestCase(t, rmnTestCase{ name: "global curse messages on two lanes", waitForExec: false, @@ -316,6 +312,7 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { t.Logf("Sent all messages, seqNumCommit: %v seqNumExec: %v", seqNumCommit, seqNumExec) tc.callContractsToCurseChains(ctx, t, onChainState, envWithRMN) + tc.callContractsToCurseAndRevokeCurse(ctx, t, onChainState, envWithRMN) tc.enableOracles(ctx, t, envWithRMN, disabledNodes) @@ -428,22 +425,25 @@ type rmnTestCase struct { // If set to a positive value, the test will wait for that duration and will assert that commit report was not delivered. passIfNoCommitAfter time.Duration cursedSubjectsPerChain map[int][]int - waitForExec bool - homeChainConfig homeChainConfig - remoteChainsConfig []remoteChainConfig - rmnNodes []rmnNode - messagesToSend []messageToSend + // revokedCursedSubjectsPerChain is used to revoke this specific curses after a timer expires + revokedCursedSubjectsPerChain map[int]map[int]time.Duration // chainIdx -> subjectIdx -> timer to revoke + waitForExec bool + homeChainConfig homeChainConfig + remoteChainsConfig []remoteChainConfig + rmnNodes []rmnNode + messagesToSend []messageToSend // populated fields after environment setup pf testCasePopulatedFields } type testCasePopulatedFields struct { - chainSelectors []uint64 - rmnHomeNodes []rmn_home.RMNHomeNode - rmnRemoteSigners []rmn_remote.RMNRemoteSigner - rmnHomeSourceChains []rmn_home.RMNHomeSourceChain - cursedSubjectsPerChainSel map[uint64][]uint64 + chainSelectors []uint64 + rmnHomeNodes []rmn_home.RMNHomeNode + rmnRemoteSigners []rmn_remote.RMNRemoteSigner + rmnHomeSourceChains []rmn_home.RMNHomeSourceChain + cursedSubjectsPerChainSel map[uint64][]uint64 + revokedCursedSubjectsPerChainSel map[uint64]map[uint64]time.Duration } func (tc *rmnTestCase) populateFields(t *testing.T, envWithRMN changeset.DeployedEnv, rmnCluster devenv.RMNCluster) { @@ -498,6 +498,22 @@ func (tc *rmnTestCase) populateFields(t *testing.T, envWithRMN changeset.Deploye tc.pf.cursedSubjectsPerChainSel[chainSel] = append(tc.pf.cursedSubjectsPerChainSel[chainSel], subjSel) } } + + // populate revoked cursed subjects with actual chain selectors + tc.pf.revokedCursedSubjectsPerChainSel = make(map[uint64]map[uint64]time.Duration) + for chainIdx, subjects := range tc.revokedCursedSubjectsPerChain { + chainSel := tc.pf.chainSelectors[chainIdx] + for subject, revokeAfter := range subjects { + subjSel := uint64(globalCurse) + if subject != globalCurse { + subjSel = tc.pf.chainSelectors[subject] + } + if _, ok := tc.pf.revokedCursedSubjectsPerChainSel[chainSel]; !ok { + tc.pf.revokedCursedSubjectsPerChainSel[chainSel] = make(map[uint64]time.Duration) + } + tc.pf.revokedCursedSubjectsPerChainSel[chainSel][subjSel] = revokeAfter + } + } } func (tc rmnTestCase) validate() error { @@ -645,6 +661,44 @@ func (tc rmnTestCase) callContractsToCurseChains(ctx context.Context, t *testing } } +func (tc rmnTestCase) callContractsToCurseAndRevokeCurse(ctx context.Context, t *testing.T, onChainState changeset.CCIPOnChainState, envWithRMN changeset.DeployedEnv) { + for _, remoteCfg := range tc.remoteChainsConfig { + remoteSel := tc.pf.chainSelectors[remoteCfg.chainIdx] + chState, ok := onChainState.Chains[remoteSel] + require.True(t, ok) + chain, ok := envWithRMN.Env.Chains[remoteSel] + require.True(t, ok) + + cursedSubjects, ok := tc.revokedCursedSubjectsPerChain[remoteCfg.chainIdx] + if !ok { + continue // nothing to curse on this chain + } + + for subjectDescription, revokeAfter := range cursedSubjects { + subj := reader.GlobalCurseSubject + if subjectDescription != globalCurse { + subj = chainSelectorToBytes16(tc.pf.chainSelectors[subjectDescription]) + } + t.Logf("cursing subject %d (%d)", subj, subjectDescription) + txCurse, errCurse := chState.RMNRemote.Curse(chain.DeployerKey, subj) + _, errConfirm := deployment.ConfirmIfNoError(chain, txCurse, errCurse) + require.NoError(t, errConfirm) + + go func() { + <-time.NewTimer(revokeAfter).C + t.Logf("revoking curse on subject %d (%d)", subj, subjectDescription) + txUncurse, errUncurse := chState.RMNRemote.Uncurse(chain.DeployerKey, subj) + _, errConfirm = deployment.ConfirmIfNoError(chain, txUncurse, errUncurse) + require.NoError(t, errConfirm) + }() + } + + cs, err := chState.RMNRemote.GetCursedSubjects(&bind.CallOpts{Context: ctx}) + require.NoError(t, err) + t.Logf("Cursed subjects: %v", cs) + } +} + func (tc rmnTestCase) enableOracles(ctx context.Context, t *testing.T, envWithRMN changeset.DeployedEnv, nodeIDs []string) { for _, n := range nodeIDs { _, err := envWithRMN.Env.Offchain.EnableNode(ctx, &node.EnableNodeRequest{Id: n}) From debf69b921a01e17f3b609374c59e3ddce90a1eb Mon Sep 17 00:00:00 2001 From: Bartek Tofel Date: Fri, 13 Dec 2024 12:46:01 +0100 Subject: [PATCH 08/29] [TT-1891] add default CHAINLINK_USER_TEAM values for chaos tests (#15598) * add default CHAINLINK_USER_TEAM values for chaos tests * update workflow reference * pass E2E env vars * try chaos without any testsecret vars * go mod tidy --- .github/e2e-tests.yml | 2 + .github/workflows/integration-chaos-tests.yml | 47 +++++++++++++++++-- 2 files changed, 45 insertions(+), 4 deletions(-) diff --git a/.github/e2e-tests.yml b/.github/e2e-tests.yml index 93ddbb564b6..675fa315dfa 100644 --- a/.github/e2e-tests.yml +++ b/.github/e2e-tests.yml @@ -193,6 +193,7 @@ runner-test-matrix: test_cmd: cd integration-tests/chaos && DETACH_RUNNER=false go test -test.run "^TestOCRChaos$" -v -test.parallel=10 -timeout 60m -count=1 -json test_env_vars: TEST_SUITE: chaos + CHAINLINK_USER_TEAM: Foundations # END: OCR tests @@ -624,6 +625,7 @@ runner-test-matrix: pyroscope_env: ci-automation-on-demand-chaos test_env_vars: TEST_SUITE: chaos + CHAINLINK_USER_TEAM: Automation - id: benchmark/automation_test.go:TestAutomationBenchmark path: integration-tests/benchmark/automation_test.go diff --git a/.github/workflows/integration-chaos-tests.yml b/.github/workflows/integration-chaos-tests.yml index 314e54a1ab8..c9f7f2661ec 100644 --- a/.github/workflows/integration-chaos-tests.yml +++ b/.github/workflows/integration-chaos-tests.yml @@ -6,11 +6,49 @@ on: tags: - "*" workflow_dispatch: + inputs: + team: + description: Team to run the tests for (e.g. BIX, CCIP) + required: true + type: string jobs: + run-e2e-tests-workflow-dispatch: + name: Run E2E Tests (Workflow Dispatch) + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0d4a2b2b009c87b5c366d0b97f7a8d7de2f60760 + if: github.event_name == 'workflow_dispatch' + with: + test_path: .github/e2e-tests.yml + chainlink_version: ${{ github.sha }} + require_chainlink_image_versions_in_qa_ecr: ${{ github.sha }} + test_trigger: E2E Chaos Tests + test_log_level: debug + team: ${{ inputs.team }} + secrets: + QA_AWS_REGION: ${{ secrets.QA_AWS_REGION }} + QA_AWS_ROLE_TO_ASSUME: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} + QA_AWS_ACCOUNT_NUMBER: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }} + PROD_AWS_ACCOUNT_NUMBER: ${{ secrets.AWS_ACCOUNT_ID_PROD }} + QA_PYROSCOPE_INSTANCE: ${{ secrets.QA_PYROSCOPE_INSTANCE }} + QA_PYROSCOPE_KEY: ${{ secrets.QA_PYROSCOPE_KEY }} + QA_KUBECONFIG: ${{ secrets.QA_KUBECONFIG }} + GRAFANA_INTERNAL_TENANT_ID: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} + GRAFANA_INTERNAL_BASIC_AUTH: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} + GRAFANA_INTERNAL_HOST: ${{ secrets.GRAFANA_INTERNAL_HOST }} + GRAFANA_INTERNAL_URL_SHORTENER_TOKEN: ${{ secrets.GRAFANA_INTERNAL_URL_SHORTENER_TOKEN }} + LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} + LOKI_URL: ${{ secrets.LOKI_URL }} + LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + AWS_REGION: ${{ secrets.QA_AWS_REGION }} + AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + run-e2e-tests-workflow: - name: Run E2E Tests - uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@5412507526722a7b1c5d719fa686eed5a1bc4035 # ctf-run-tests@0.2.0 + name: Run E2E Tests (Push and Sechedule) + uses: smartcontractkit/.github/.github/workflows/run-e2e-tests.yml@0d4a2b2b009c87b5c366d0b97f7a8d7de2f60760 + if: github.event_name != 'workflow_dispatch' with: test_path: .github/e2e-tests.yml chainlink_version: ${{ github.sha }} @@ -32,8 +70,9 @@ jobs: LOKI_TENANT_ID: ${{ secrets.LOKI_TENANT_ID }} LOKI_URL: ${{ secrets.LOKI_URL }} LOKI_BASIC_AUTH: ${{ secrets.LOKI_BASIC_AUTH }} - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} AWS_REGION: ${{ secrets.QA_AWS_REGION }} AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN: ${{ secrets.AWS_OIDC_IAM_ROLE_VALIDATION_PROD_ARN }} - AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} + AWS_API_GW_HOST_GRAFANA: ${{ secrets.AWS_API_GW_HOST_GRAFANA }} SLACK_BOT_TOKEN: ${{ secrets.QA_SLACK_API_KEY }} + From 38a95531f59cc7d13c84ecd6e053f2bbf8e95b6a Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Fri, 13 Dec 2024 13:01:16 +0100 Subject: [PATCH 09/29] [CAPL-264] Ensure a default timeout is provided for all outgoing requests (#15644) * fix: ensure a default timeout is provided for all outgoing requests * chore: add a subcontext with a timeout + margin * fix: lint --- core/capabilities/compute/compute.go | 7 +- .../webapi/outgoing_connector_handler.go | 27 +++- .../webapi/outgoing_connector_handler_test.go | 132 ++++++++++++++++++ core/capabilities/webapi/target/target.go | 7 +- core/services/workflows/syncer/fetcher.go | 18 +-- 5 files changed, 162 insertions(+), 29 deletions(-) create mode 100644 core/capabilities/webapi/outgoing_connector_handler_test.go diff --git a/core/capabilities/compute/compute.go b/core/capabilities/compute/compute.go index 316e4f00eea..2ba5daefaa6 100644 --- a/core/capabilities/compute/compute.go +++ b/core/capabilities/compute/compute.go @@ -318,18 +318,13 @@ func (c *Compute) createFetcher() func(ctx context.Context, req *wasmpb.FetchReq headersReq[k] = v.String() } - payloadBytes, err := json.Marshal(ghcapabilities.Request{ + resp, err := c.outgoingConnectorHandler.HandleSingleNodeRequest(ctx, messageID, ghcapabilities.Request{ URL: req.Url, Method: req.Method, Headers: headersReq, Body: req.Body, TimeoutMs: req.TimeoutMs, }) - if err != nil { - return nil, fmt.Errorf("failed to marshal fetch request: %w", err) - } - - resp, err := c.outgoingConnectorHandler.HandleSingleNodeRequest(ctx, messageID, payloadBytes) if err != nil { return nil, err } diff --git a/core/capabilities/webapi/outgoing_connector_handler.go b/core/capabilities/webapi/outgoing_connector_handler.go index d18ee971d1a..5ea497cd87d 100644 --- a/core/capabilities/webapi/outgoing_connector_handler.go +++ b/core/capabilities/webapi/outgoing_connector_handler.go @@ -6,6 +6,7 @@ import ( "fmt" "sort" "sync" + "time" "github.com/pkg/errors" @@ -17,6 +18,10 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" ) +const ( + defaultFetchTimeoutMs = 20_000 +) + var _ connector.GatewayConnectorHandler = &OutgoingConnectorHandler{} type OutgoingConnectorHandler struct { @@ -51,8 +56,24 @@ func NewOutgoingConnectorHandler(gc connector.GatewayConnector, config ServiceCo } // HandleSingleNodeRequest sends a request to first available gateway node and blocks until response is received -// TODO: handle retries and timeouts -func (c *OutgoingConnectorHandler) HandleSingleNodeRequest(ctx context.Context, messageID string, payload []byte) (*api.Message, error) { +// TODO: handle retries +func (c *OutgoingConnectorHandler) HandleSingleNodeRequest(ctx context.Context, messageID string, req capabilities.Request) (*api.Message, error) { + // set default timeout if not provided for all outgoing requests + if req.TimeoutMs == 0 { + req.TimeoutMs = defaultFetchTimeoutMs + } + + // Create a subcontext with the timeout plus some margin for the gateway to process the request + timeoutDuration := time.Duration(req.TimeoutMs) * time.Millisecond + margin := 100 * time.Millisecond + ctx, cancel := context.WithTimeout(ctx, timeoutDuration+margin) + defer cancel() + + payload, err := json.Marshal(req) + if err != nil { + return nil, fmt.Errorf("failed to marshal fetch request: %w", err) + } + ch := make(chan *api.Message, 1) c.responseChsMu.Lock() c.responseChs[messageID] = ch @@ -75,7 +96,7 @@ func (c *OutgoingConnectorHandler) HandleSingleNodeRequest(ctx context.Context, } sort.Strings(gatewayIDs) - err := c.gc.SignAndSendToGateway(ctx, gatewayIDs[0], body) + err = c.gc.SignAndSendToGateway(ctx, gatewayIDs[0], body) if err != nil { return nil, errors.Wrap(err, "failed to send request to gateway") } diff --git a/core/capabilities/webapi/outgoing_connector_handler_test.go b/core/capabilities/webapi/outgoing_connector_handler_test.go new file mode 100644 index 00000000000..2090edc6aea --- /dev/null +++ b/core/capabilities/webapi/outgoing_connector_handler_test.go @@ -0,0 +1,132 @@ +package webapi + +import ( + "context" + "encoding/json" + "testing" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/core/logger" + + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/api" + gcmocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector/mocks" + ghcapabilities "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/capabilities" + "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" +) + +func TestHandleSingleNodeRequest(t *testing.T) { + t.Run("OK-timeout_is_not_specify_default_timeout_is_expected", func(t *testing.T) { + ctx := tests.Context(t) + log := logger.TestLogger(t) + connector := gcmocks.NewGatewayConnector(t) + var defaultConfig = ServiceConfig{ + RateLimiter: common.RateLimiterConfig{ + GlobalRPS: 100.0, + GlobalBurst: 100, + PerSenderRPS: 100.0, + PerSenderBurst: 100, + }, + } + connectorHandler, err := NewOutgoingConnectorHandler(connector, defaultConfig, ghcapabilities.MethodComputeAction, log) + require.NoError(t, err) + + msgID := "msgID" + testURL := "http://localhost:8080" + connector.EXPECT().DonID().Return("donID") + connector.EXPECT().GatewayIDs().Return([]string{"gateway1"}) + + // build the expected body with the default timeout + req := ghcapabilities.Request{ + URL: testURL, + TimeoutMs: defaultFetchTimeoutMs, + } + payload, err := json.Marshal(req) + require.NoError(t, err) + + expectedBody := &api.MessageBody{ + MessageId: msgID, + DonId: connector.DonID(), + Method: ghcapabilities.MethodComputeAction, + Payload: payload, + } + + // expect the request body to contain the default timeout + connector.EXPECT().SignAndSendToGateway(mock.Anything, "gateway1", expectedBody).Run(func(ctx context.Context, gatewayID string, msg *api.MessageBody) { + connectorHandler.HandleGatewayMessage(ctx, "gateway1", gatewayResponse(t, msgID)) + }).Return(nil).Times(1) + + _, err = connectorHandler.HandleSingleNodeRequest(ctx, msgID, ghcapabilities.Request{ + URL: testURL, + }) + require.NoError(t, err) + }) + + t.Run("OK-timeout_is_specified", func(t *testing.T) { + ctx := tests.Context(t) + log := logger.TestLogger(t) + connector := gcmocks.NewGatewayConnector(t) + var defaultConfig = ServiceConfig{ + RateLimiter: common.RateLimiterConfig{ + GlobalRPS: 100.0, + GlobalBurst: 100, + PerSenderRPS: 100.0, + PerSenderBurst: 100, + }, + } + connectorHandler, err := NewOutgoingConnectorHandler(connector, defaultConfig, ghcapabilities.MethodComputeAction, log) + require.NoError(t, err) + + msgID := "msgID" + testURL := "http://localhost:8080" + connector.EXPECT().DonID().Return("donID") + connector.EXPECT().GatewayIDs().Return([]string{"gateway1"}) + + // build the expected body with the defined timeout + req := ghcapabilities.Request{ + URL: testURL, + TimeoutMs: 40000, + } + payload, err := json.Marshal(req) + require.NoError(t, err) + + expectedBody := &api.MessageBody{ + MessageId: msgID, + DonId: connector.DonID(), + Method: ghcapabilities.MethodComputeAction, + Payload: payload, + } + + // expect the request body to contain the defined timeout + connector.EXPECT().SignAndSendToGateway(mock.Anything, "gateway1", expectedBody).Run(func(ctx context.Context, gatewayID string, msg *api.MessageBody) { + connectorHandler.HandleGatewayMessage(ctx, "gateway1", gatewayResponse(t, msgID)) + }).Return(nil).Times(1) + + _, err = connectorHandler.HandleSingleNodeRequest(ctx, msgID, ghcapabilities.Request{ + URL: testURL, + TimeoutMs: 40000, + }) + require.NoError(t, err) + }) +} + +func gatewayResponse(t *testing.T, msgID string) *api.Message { + headers := map[string]string{"Content-Type": "application/json"} + body := []byte("response body") + responsePayload, err := json.Marshal(ghcapabilities.Response{ + StatusCode: 200, + Headers: headers, + Body: body, + ExecutionError: false, + }) + require.NoError(t, err) + return &api.Message{ + Body: api.MessageBody{ + MessageId: msgID, + Method: ghcapabilities.MethodWebAPITarget, + Payload: responsePayload, + }, + } +} diff --git a/core/capabilities/webapi/target/target.go b/core/capabilities/webapi/target/target.go index b211e0fe837..4934ab382d5 100644 --- a/core/capabilities/webapi/target/target.go +++ b/core/capabilities/webapi/target/target.go @@ -135,18 +135,13 @@ func (c *Capability) Execute(ctx context.Context, req capabilities.CapabilityReq return capabilities.CapabilityResponse{}, err } - payloadBytes, err := json.Marshal(payload) - if err != nil { - return capabilities.CapabilityResponse{}, err - } - // Default to SingleNode delivery mode deliveryMode := defaultIfNil(workflowCfg.DeliveryMode, webapi.SingleNode) switch deliveryMode { case webapi.SingleNode: // blocking call to handle single node request. waits for response from gateway - resp, err := c.connectorHandler.HandleSingleNodeRequest(ctx, messageID, payloadBytes) + resp, err := c.connectorHandler.HandleSingleNodeRequest(ctx, messageID, payload) if err != nil { return capabilities.CapabilityResponse{}, err } diff --git a/core/services/workflows/syncer/fetcher.go b/core/services/workflows/syncer/fetcher.go index fdd0134909d..6a80739bbfe 100644 --- a/core/services/workflows/syncer/fetcher.go +++ b/core/services/workflows/syncer/fetcher.go @@ -18,10 +18,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/common" ) -const ( - defaultFetchTimeoutMs = 20_000 -) - type FetcherService struct { services.StateMachine lggr logger.Logger @@ -88,17 +84,11 @@ func hash(url string) string { } func (s *FetcherService) Fetch(ctx context.Context, url string) ([]byte, error) { - payloadBytes, err := json.Marshal(ghcapabilities.Request{ - URL: url, - Method: http.MethodGet, - TimeoutMs: defaultFetchTimeoutMs, - }) - if err != nil { - return nil, fmt.Errorf("failed to marshal fetch request: %w", err) - } - messageID := strings.Join([]string{ghcapabilities.MethodWorkflowSyncer, hash(url)}, "/") - resp, err := s.och.HandleSingleNodeRequest(ctx, messageID, payloadBytes) + resp, err := s.och.HandleSingleNodeRequest(ctx, messageID, ghcapabilities.Request{ + URL: url, + Method: http.MethodGet, + }) if err != nil { return nil, err } From 19b122ae50593182a0096e3ec283a32e75535e95 Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Fri, 13 Dec 2024 12:16:14 +0000 Subject: [PATCH 10/29] temp fix to chainreader error when no workflows (#15678) * temp fix to chainreader error when no workflows * tidy --- core/services/workflows/syncer/workflow_registry.go | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/core/services/workflows/syncer/workflow_registry.go b/core/services/workflows/syncer/workflow_registry.go index 223fbe8e758..e68136fdc07 100644 --- a/core/services/workflows/syncer/workflow_registry.go +++ b/core/services/workflows/syncer/workflow_registry.go @@ -6,6 +6,7 @@ import ( "encoding/json" "fmt" "iter" + "strings" "sync" "time" @@ -222,8 +223,16 @@ func (w *workflowRegistry) Start(_ context.Context) error { w.lggr.Debugw("Loading initial workflows for DON", "DON", don.ID) loadWorkflowsHead, err := w.initialWorkflowsStateLoader.LoadWorkflows(ctx, don) if err != nil { - w.lggr.Errorw("failed to load workflows", "err", err) - return + // TODO - this is a temporary fix to handle the case where the chainreader errors because the contract + // contains no workflows. To track: https://smartcontract-it.atlassian.net/browse/CAPPL-393 + if !strings.Contains(err.Error(), "attempting to unmarshal an empty string while arguments are expected") { + w.lggr.Errorw("failed to load workflows", "err", err) + return + } + + loadWorkflowsHead = &types.Head{ + Height: "0", + } } reader, err := w.getContractReader(ctx) From 0ccdc0c4cd6c792e10b2226235c6c6d6f57eb377 Mon Sep 17 00:00:00 2001 From: Mateusz Sekara Date: Fri, 13 Dec 2024 13:51:28 +0100 Subject: [PATCH 11/29] Bump CCIP to the latest version (#15680) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- deployment/go.mod | 2 +- deployment/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 10 files changed, 15 insertions(+), 15 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index d29df20e3fa..557276b94ef 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -303,7 +303,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect github.com/smartcontractkit/chain-selectors v1.0.34 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index c14563ea569..bf807b0881c 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1140,8 +1140,8 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= diff --git a/deployment/go.mod b/deployment/go.mod index fc3d70c3900..d275487ff38 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -28,7 +28,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 github.com/smartcontractkit/chain-selectors v1.0.34 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 diff --git a/deployment/go.sum b/deployment/go.sum index f9fb767d5da..71057f369ae 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1409,8 +1409,8 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= diff --git a/go.mod b/go.mod index 0f8a161768f..31cb8241f0c 100644 --- a/go.mod +++ b/go.mod @@ -78,7 +78,7 @@ require ( github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db diff --git a/go.sum b/go.sum index 76127a91b4b..b6d85bea0ba 100644 --- a/go.sum +++ b/go.sum @@ -1123,8 +1123,8 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index b87192af47e..bf55d2a13fc 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -46,7 +46,7 @@ require ( github.com/slack-go/slack v0.15.0 github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 75f4e862f61..b49443079d0 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1430,8 +1430,8 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index c94ea489c1b..131d3451ed0 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -407,7 +407,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/smartcontractkit/chain-selectors v1.0.34 // indirect github.com/smartcontractkit/chainlink-automation v0.8.1 // indirect - github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 // indirect + github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 96861fdc048..535173d6d4b 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1421,8 +1421,8 @@ github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3f github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0 h1:/1L+v4SxUD2K5RMRbfByyLfePMAgQKeD0onSetPnGmA= -github.com/smartcontractkit/chainlink-ccip v0.0.0-20241211150100-7683331f64a0/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= +github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= From 235d98d77b07c0eb792169f0196db0d9d41ad596 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:08:34 +0100 Subject: [PATCH 12/29] Add metadata for Flakeguard and optimise report aggregation (#15643) * Bump report runner for flakeguard workflow * Add metadata for flakeguard reports * fix * Add repo url * fix * update * fix * to revert: change test to kick off run * fix * fix * fix * bump * revert unit test * bump * downgrade report runner * fix references * use flakeguard with perf optimisations * bump * to revert: fail test * bump * Revert "to revert: fail test" This reverts commit 111a2fc0ce07c547c83a9ad6349d4bc14089097a. * bump flakeguard * downgrade report runner --- .github/workflows/flakeguard-on-demand.yml | 7 ++- .github/workflows/flakeguard.yml | 53 ++++++++++++++++------ 2 files changed, 42 insertions(+), 18 deletions(-) diff --git a/.github/workflows/flakeguard-on-demand.yml b/.github/workflows/flakeguard-on-demand.yml index 0ba84c5ab58..4508da30e6b 100644 --- a/.github/workflows/flakeguard-on-demand.yml +++ b/.github/workflows/flakeguard-on-demand.yml @@ -14,14 +14,13 @@ on: description: 'The path to the project to run the flaky test detection.' default: '.' baseRef: - required: true + required: false type: string - description: 'The base reference or branch to compare changes for detecting flaky tests.' - default: 'origin/develop' + description: 'The base reference or branch to compare changes for detecting flaky tests. Set only when running diffs between branches. E.g. (develop)' headRef: required: false type: string - description: 'The head reference or branch to compare changes for detecting flaky tests. Default is the current branch.' + description: 'The head reference or branch to compare changes for detecting flaky tests. Default is the current branch. E.g. (develop)' runAllTests: required: false type: boolean diff --git a/.github/workflows/flakeguard.yml b/.github/workflows/flakeguard.yml index 4c1aa695c62..82d33e3e124 100644 --- a/.github/workflows/flakeguard.yml +++ b/.github/workflows/flakeguard.yml @@ -15,11 +15,11 @@ on: baseRef: required: false type: string - description: 'The base reference or branch to compare changes for detecting flaky tests.' + description: 'The base reference or branch to compare changes for detecting flaky tests. Set only when running diffs between branches. E.g. (develop)' headRef: required: false type: string - description: 'The head reference or branch to compare changes for detecting flaky tests. Default is the current branch.' + description: 'The head reference or branch to compare changes for detecting flaky tests. Default is the current branch. E.g. (develop)' runAllTests: required: false type: boolean @@ -56,6 +56,7 @@ on: required: true env: + GIT_BASE_REF: ${{ inputs.baseRef }} GIT_HEAD_REF: ${{ inputs.headRef || github.ref }} SKIPPED_TESTS: ${{ fromJSON(inputs.extraArgs)['skipped_tests'] || '' }} # Comma separated list of test names to skip running in the flaky detector. Related issue: TT-1823 DEFAULT_MAX_RUNNER_COUNT: ${{ fromJSON(inputs.extraArgs)['default_max_runner_count'] || '8' }} # The default maximum number of GitHub runners to use for parallel test execution. @@ -80,6 +81,7 @@ jobs: affected_test_packages: ${{ steps.get-tests.outputs.packages }} git_head_sha: ${{ steps.get_commit_sha.outputs.git_head_sha }} git_head_short_sha: ${{ steps.get_commit_sha.outputs.git_head_short_sha }} + git_base_sha: ${{ steps.get_commit_sha.outputs.git_base_sha }} steps: - name: Checkout repository uses: actions/checkout@9bb56186c3b09b4f86b1c65136769dd318469633 # v4.1.2 @@ -87,14 +89,33 @@ jobs: fetch-depth: 0 ref: ${{ env.GIT_HEAD_REF }} - - name: Get commit SHA + - name: Get SHA id: get_commit_sha run: | + # Resolve HEAD SHA git_head_sha=$(git rev-parse HEAD) git_head_short_sha=$(git rev-parse --short HEAD) echo "git_head_sha=$git_head_sha" >> $GITHUB_OUTPUT echo "git_head_short_sha=$git_head_short_sha" >> $GITHUB_OUTPUT + # Print HEAD SHAs to the console + echo "HEAD SHA: $git_head_sha" + echo "HEAD Short SHA: $git_head_short_sha" + + # Conditionally resolve BASE SHA + if [ -n "${{ env.GIT_BASE_REF }}" ]; then + git fetch origin ${{ env.GIT_BASE_REF }} --quiet + + git_base_sha=$(git rev-parse origin/${{ env.GIT_BASE_REF }}) + echo "git_base_sha=$git_base_sha" >> $GITHUB_OUTPUT + + # Print BASE SHA to the console + echo "BASE SHA: $git_base_sha" + else + echo "BASE SHA not provided." + echo "git_base_sha=" >> $GITHUB_OUTPUT + fi + - name: Set up Go 1.21.9 uses: actions/setup-go@v5.0.2 with: @@ -102,7 +123,7 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@404e04e1e2e2dd5a384b09bd05b8d80409b6609a # flakguard@0.1.0 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@fc2d7e38486853d2bed06e9074868087f5b55506 # flakguard@0.1.0 - name: Find new or updated test packages if: ${{ inputs.runAllTests == false }} @@ -115,7 +136,7 @@ jobs: PATH=$PATH:$(go env GOPATH)/bin export PATH - PACKAGES=$(flakeguard find --find-by-test-files-diff=${{ inputs.findByTestFilesDiff }} --find-by-affected-packages=${{ inputs.findByAffectedPackages }} --base-ref=origin/${{ inputs.baseRef }} --project-path=${{ inputs.projectPath }}) + PACKAGES=$(flakeguard find --find-by-test-files-diff=${{ inputs.findByTestFilesDiff }} --find-by-affected-packages=${{ inputs.findByAffectedPackages }} --base-ref=origin/${{ env.GIT_BASE_REF }} --project-path=${{ inputs.projectPath }}) echo $PACKAGES echo "packages=$PACKAGES" >> $GITHUB_OUTPUT @@ -130,7 +151,7 @@ jobs: PATH=$PATH:$(go env GOPATH)/bin export PATH - TEST_FILES=$(flakeguard find --only-show-changed-test-files=true --base-ref=origin/${{ inputs.baseRef }} --project-path=${{ inputs.projectPath }}) + TEST_FILES=$(flakeguard find --only-show-changed-test-files=true --base-ref=origin/${{ env.GIT_BASE_REF }} --project-path=${{ inputs.projectPath }}) echo $TEST_FILES echo "test_files=$TEST_FILES" >> $GITHUB_OUTPUT @@ -261,11 +282,11 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@404e04e1e2e2dd5a384b09bd05b8d80409b6609a # flakguard@0.1.0 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@fc2d7e38486853d2bed06e9074868087f5b55506 # flakguard@0.1.0 - name: Run tests with flakeguard shell: bash - run: flakeguard run --project-path=${{ inputs.projectPath }} --test-packages=${{ matrix.testPackages }} --run-count=${{ env.TEST_REPEAT_COUNT }} --max-pass-ratio=${{ inputs.maxPassRatio }} --race=${{ env.RUN_WITH_RACE }} --shuffle=${{ env.RUN_WITH_SHUFFLE }} --shuffle-seed=${{ env.SHUFFLE_SEED }} --skip-tests=${{ env.SKIPPED_TESTS }} --output-json=test-result.json + run: flakeguard run --project-path=${{ inputs.projectPath }} --test-packages=${{ matrix.testPackages }} --run-count=${{ env.TEST_REPEAT_COUNT }} --max-pass-ratio=${{ inputs.maxPassRatio }} --race=${{ env.RUN_WITH_RACE }} --shuffle=${{ env.RUN_WITH_SHUFFLE }} --shuffle-seed=${{ env.SHUFFLE_SEED }} --skip-tests=${{ env.SKIPPED_TESTS }} --output-json=test-result.json --omit-test-outputs-on-success=true env: CL_DATABASE_URL: ${{ env.DB_URL }} @@ -281,7 +302,7 @@ jobs: needs: [get-tests, run-tests] if: always() name: Report - runs-on: ubuntu-24.04-8cores-32GB-ARM # Use a runner with more resources to avoid OOM errors when aggregating test results. + runs-on: ubuntu-latest outputs: test_results: ${{ steps.results.outputs.results }} steps: @@ -308,7 +329,7 @@ jobs: - name: Install flakeguard shell: bash - run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@404e04e1e2e2dd5a384b09bd05b8d80409b6609a # flakguard@0.1.0 + run: go install github.com/smartcontractkit/chainlink-testing-framework/tools/flakeguard@fc2d7e38486853d2bed06e9074868087f5b55506 # flakguard@0.1.0 - name: Aggregate Flakeguard Results id: results @@ -329,7 +350,11 @@ jobs: --output-path ./flakeguard-report \ --repo-path "${{ github.workspace }}" \ --codeowners-path "${{ github.workspace }}/.github/CODEOWNERS" \ - --max-pass-ratio "${{ inputs.maxPassRatio }}" + --max-pass-ratio "${{ inputs.maxPassRatio }}" \ + --repo-url "${{ inputs.repoUrl }}" \ + --base-sha "${{ needs.get-tests.outputs.git_base_sha }}" \ + --head-sha "${{ needs.get-tests.outputs.git_head_sha }}" \ + --github-workflow-name "${{ github.workflow }}" # Print out the summary file echo -e "\nFlakeguard Summary:" @@ -461,7 +486,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ inputs.runAllTests == true && format('Ran all tests for `{0}` branch.', inputs.headRef) || format('Ran changed tests between `{0}` and `{1}` (`{2}`).', inputs.baseRef, needs.get-tests.outputs.git_head_short_sha, env.GIT_HEAD_REF) }}" + "text": "${{ inputs.runAllTests == true && format('Ran all tests for `{0}` branch.', env.GIT_HEAD_REF) || format('Ran changed tests between `{0}` and `{1}` (`{2}`).', env.GIT_BASE_REF, needs.get-tests.outputs.git_head_short_sha, env.GIT_HEAD_REF) }}" } }, { @@ -481,7 +506,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ format('<{0}/{1}/actions/runs/{2}|View Flaky Detector Details> | <{3}/compare/{4}...{5}#files_bucket|Compare Changes>{6}', github.server_url, github.repository, github.run_id, inputs.repoUrl, inputs.baseRef, needs.get-tests.outputs.git_head_sha, github.event_name == 'pull_request' && format(' | <{0}|View PR>', github.event.pull_request.html_url) || '') }}" + "text": "${{ format('<{0}/{1}/actions/runs/{2}|View Flaky Detector Details> | <{3}/compare/{4}...{5}#files_bucket|Compare Changes>{6}', github.server_url, github.repository, github.run_id, inputs.repoUrl, env.GIT_BASE_REF, needs.get-tests.outputs.git_head_sha, github.event_name == 'pull_request' && format(' | <{0}|View PR>', github.event.pull_request.html_url) || '') }}" } } ] @@ -514,7 +539,7 @@ jobs: "type": "section", "text": { "type": "mrkdwn", - "text": "${{ inputs.runAllTests == true && format('Ran all tests for `{0}` branch.', env.GIT_HEAD_REF) || format('Ran changed tests between `{0}` and `{1}` (`{2}`).', inputs.baseRef, needs.get-tests.outputs.git_head_short_sha, env.GIT_HEAD_REF) }}" + "text": "${{ inputs.runAllTests == true && format('Ran all tests for `{0}` branch.', env.GIT_HEAD_REF) || format('Ran changed tests between `{0}` and `{1}` (`{2}`).', env.GIT_BASE_REF, needs.get-tests.outputs.git_head_short_sha, env.GIT_HEAD_REF) }}" } }, { From 000df4f5d84931c8df7c05e105c0a3c9881f6639 Mon Sep 17 00:00:00 2001 From: "Simon B.Robert" Date: Fri, 13 Dec 2024 08:12:40 -0500 Subject: [PATCH 13/29] Use RMN changeset in e2e tests and refactor RMN remote changeset (#15664) * Use RMN changeset in e2e tests and refactor RMN remote changeset RMN remote changeset was changed to allow more flexibility when configuring remote configs. Allowing a subset of chains to be updated in a single changeset * Address PR comments --- .../ccip/changeset/cs_update_rmn_config.go | 38 ++++++--- .../changeset/cs_update_rmn_config_test.go | 13 ++- integration-tests/smoke/ccip/ccip_rmn_test.go | 82 +++++++------------ 3 files changed, 66 insertions(+), 67 deletions(-) diff --git a/deployment/ccip/changeset/cs_update_rmn_config.go b/deployment/ccip/changeset/cs_update_rmn_config.go index 42eace928c3..c5633e5bfa4 100644 --- a/deployment/ccip/changeset/cs_update_rmn_config.go +++ b/deployment/ccip/changeset/cs_update_rmn_config.go @@ -339,10 +339,14 @@ func buildRMNRemotePerChain(e deployment.Environment, state CCIPOnChainState) ma return timelocksPerChain } +type RMNRemoteConfig struct { + Signers []rmn_remote.RMNRemoteSigner + F uint64 +} + type SetRMNRemoteConfig struct { HomeChainSelector uint64 - Signers []rmn_remote.RMNRemoteSigner - F uint64 + RMNRemoteConfigs map[uint64]RMNRemoteConfig MCMSConfig *MCMSConfig } @@ -352,14 +356,21 @@ func (c SetRMNRemoteConfig) Validate() error { return err } - for i := 0; i < len(c.Signers)-1; i++ { - if c.Signers[i].NodeIndex >= c.Signers[i+1].NodeIndex { - return fmt.Errorf("signers must be in ascending order of nodeIndex") + for chain, config := range c.RMNRemoteConfigs { + err := deployment.IsValidChainSelector(chain) + if err != nil { + return err } - } - if len(c.Signers) < 2*int(c.F)+1 { - return fmt.Errorf("signers count must greater than or equal to %d", 2*c.F+1) + for i := 0; i < len(config.Signers)-1; i++ { + if config.Signers[i].NodeIndex >= config.Signers[i+1].NodeIndex { + return fmt.Errorf("signers must be in ascending order of nodeIndex, but found %d >= %d", config.Signers[i].NodeIndex, config.Signers[i+1].NodeIndex) + } + } + + if len(config.Signers) < 2*int(config.F)+1 { + return fmt.Errorf("signers count (%d) must be greater than or equal to %d", len(config.Signers), 2*config.F+1) + } } return nil @@ -396,9 +407,10 @@ func NewSetRMNRemoteConfigChangeset(e deployment.Environment, config SetRMNRemot rmnRemotePerChain := buildRMNRemotePerChain(e, state) batches := make([]timelock.BatchChainOperation, 0) - for chain, remote := range rmnRemotePerChain { - if remote == nil { - continue + for chain, remoteConfig := range config.RMNRemoteConfigs { + remote, ok := rmnRemotePerChain[chain] + if !ok { + return deployment.ChangesetOutput{}, fmt.Errorf("RMNRemote contract not found for chain %d", chain) } currentVersionConfig, err := remote.GetVersionedConfig(nil) @@ -408,8 +420,8 @@ func NewSetRMNRemoteConfigChangeset(e deployment.Environment, config SetRMNRemot newConfig := rmn_remote.RMNRemoteConfig{ RmnHomeContractConfigDigest: activeConfig, - Signers: config.Signers, - F: config.F, + Signers: remoteConfig.Signers, + F: remoteConfig.F, } if reflect.DeepEqual(currentVersionConfig.Config, newConfig) { diff --git a/deployment/ccip/changeset/cs_update_rmn_config_test.go b/deployment/ccip/changeset/cs_update_rmn_config_test.go index bab70f68fb5..52f00ce01af 100644 --- a/deployment/ccip/changeset/cs_update_rmn_config_test.go +++ b/deployment/ccip/changeset/cs_update_rmn_config_test.go @@ -167,10 +167,19 @@ func updateRMNConfig(t *testing.T, tc updateRMNConfigTestCase) { signers = append(signers, nop.ToRMNRemoteSigner()) } + remoteConfigs := make(map[uint64]RMNRemoteConfig, len(e.Env.Chains)) + for _, chain := range e.Env.Chains { + remoteConfig := RMNRemoteConfig{ + Signers: signers, + F: 0, + } + + remoteConfigs[chain.Selector] = remoteConfig + } + setRemoteConfig := SetRMNRemoteConfig{ HomeChainSelector: e.HomeChainSel, - Signers: signers, - F: 0, + RMNRemoteConfigs: remoteConfigs, MCMSConfig: mcmsConfig, } diff --git a/integration-tests/smoke/ccip/ccip_rmn_test.go b/integration-tests/smoke/ccip/ccip_rmn_test.go index 1075b28e9d3..166f4422fe6 100644 --- a/integration-tests/smoke/ccip/ccip_rmn_test.go +++ b/integration-tests/smoke/ccip/ccip_rmn_test.go @@ -258,9 +258,6 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { require.NoError(t, err) t.Logf("onChainState: %#v", onChainState) - homeChain, ok := envWithRMN.Env.Chains[envWithRMN.HomeChainSel] - require.True(t, ok) - homeChainState, ok := onChainState.Chains[envWithRMN.HomeChainSel] require.True(t, ok) @@ -274,23 +271,28 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { dynamicConfig := rmn_home.RMNHomeDynamicConfig{SourceChains: tc.pf.rmnHomeSourceChains, OffchainConfig: []byte{}} t.Logf("Setting RMNHome candidate with staticConfig: %+v, dynamicConfig: %+v, current candidateDigest: %x", staticConfig, dynamicConfig, allDigests.CandidateConfigDigest[:]) - tx, err := homeChainState.RMNHome.SetCandidate(homeChain.DeployerKey, staticConfig, dynamicConfig, allDigests.CandidateConfigDigest) + + candidateDigest, err := homeChainState.RMNHome.GetCandidateDigest(&bind.CallOpts{Context: ctx}) require.NoError(t, err) - _, err = deployment.ConfirmIfNoError(homeChain, tx, err) + _, err = changeset.NewSetRMNHomeCandidateConfigChangeset(envWithRMN.Env, changeset.SetRMNHomeCandidateConfig{ + HomeChainSelector: envWithRMN.HomeChainSel, + RMNStaticConfig: staticConfig, + RMNDynamicConfig: dynamicConfig, + DigestToOverride: candidateDigest, + }) require.NoError(t, err) - candidateDigest, err := homeChainState.RMNHome.GetCandidateDigest(&bind.CallOpts{Context: ctx}) + candidateDigest, err = homeChainState.RMNHome.GetCandidateDigest(&bind.CallOpts{Context: ctx}) require.NoError(t, err) t.Logf("RMNHome candidateDigest after setting new candidate: %x", candidateDigest[:]) t.Logf("Promoting RMNHome candidate with candidateDigest: %x", candidateDigest[:]) - tx, err = homeChainState.RMNHome.PromoteCandidateAndRevokeActive( - homeChain.DeployerKey, candidateDigest, allDigests.ActiveConfigDigest) - require.NoError(t, err) - - _, err = deployment.ConfirmIfNoError(homeChain, tx, err) + _, err = changeset.NewPromoteCandidateConfigChangeset(envWithRMN.Env, changeset.PromoteRMNHomeCandidateConfig{ + HomeChainSelector: envWithRMN.HomeChainSel, + DigestToPromote: candidateDigest, + }) require.NoError(t, err) // check the active digest is the same as the candidate digest @@ -300,7 +302,23 @@ func runRmnTestCase(t *testing.T, tc rmnTestCase) { "active digest should be the same as the previously candidate digest after promotion, previous candidate: %x, active: %x", candidateDigest[:], activeDigest[:]) - tc.setRmnRemoteConfig(ctx, t, onChainState, activeDigest, envWithRMN) + rmnRemoteConfig := make(map[uint64]changeset.RMNRemoteConfig) + for _, remoteCfg := range tc.remoteChainsConfig { + selector := tc.pf.chainSelectors[remoteCfg.chainIdx] + if remoteCfg.f < 0 { + t.Fatalf("remoteCfg.f is negative: %d", remoteCfg.f) + } + rmnRemoteConfig[selector] = changeset.RMNRemoteConfig{ + F: uint64(remoteCfg.f), + Signers: tc.pf.rmnRemoteSigners, + } + } + + _, err = changeset.NewSetRMNRemoteConfigChangeset(envWithRMN.Env, changeset.SetRMNRemoteConfig{ + HomeChainSelector: envWithRMN.HomeChainSel, + RMNRemoteConfigs: rmnRemoteConfig, + }) + require.NoError(t, err) tc.killMarkedRmnNodes(t, rmnCluster) @@ -524,46 +542,6 @@ func (tc rmnTestCase) validate() error { return nil } -func (tc rmnTestCase) setRmnRemoteConfig( - ctx context.Context, - t *testing.T, - onChainState changeset.CCIPOnChainState, - activeDigest [32]byte, - envWithRMN changeset.DeployedEnv) { - for _, remoteCfg := range tc.remoteChainsConfig { - remoteSel := tc.pf.chainSelectors[remoteCfg.chainIdx] - chState, ok := onChainState.Chains[remoteSel] - require.True(t, ok) - if remoteCfg.f < 0 { - t.Fatalf("negative F: %d", remoteCfg.f) - } - rmnRemoteConfig := rmn_remote.RMNRemoteConfig{ - RmnHomeContractConfigDigest: activeDigest, - Signers: tc.pf.rmnRemoteSigners, - F: uint64(remoteCfg.f), - } - - chain := envWithRMN.Env.Chains[tc.pf.chainSelectors[remoteCfg.chainIdx]] - - t.Logf("Setting RMNRemote config with RMNHome active digest: %x, cfg: %+v", activeDigest[:], rmnRemoteConfig) - tx2, err2 := chState.RMNRemote.SetConfig(chain.DeployerKey, rmnRemoteConfig) - require.NoError(t, err2) - _, err2 = deployment.ConfirmIfNoError(chain, tx2, err2) - require.NoError(t, err2) - - // confirm the config is set correctly - config, err2 := chState.RMNRemote.GetVersionedConfig(&bind.CallOpts{Context: ctx}) - require.NoError(t, err2) - require.Equalf(t, - activeDigest, - config.Config.RmnHomeContractConfigDigest, - "RMNRemote config digest should be the same as the active digest of RMNHome after setting, RMNHome active: %x, RMNRemote config: %x", - activeDigest[:], config.Config.RmnHomeContractConfigDigest[:]) - - t.Logf("RMNRemote config digest after setting: %x", config.Config.RmnHomeContractConfigDigest[:]) - } -} - func (tc rmnTestCase) killMarkedRmnNodes(t *testing.T, rmnCluster devenv.RMNCluster) { for _, n := range tc.rmnNodes { if n.forceExit { From ea2d4f7b8b3e2913e5af516d1f23c3e745af49b4 Mon Sep 17 00:00:00 2001 From: krehermann <16602512+krehermann@users.noreply.github.com> Date: Fri, 13 Dec 2024 07:59:10 -0700 Subject: [PATCH 14/29] logging fix; rm dead code (#15662) --- deployment/keystone/changeset/helpers_test.go | 2 +- deployment/keystone/changeset/update_don_test.go | 16 ++++------------ deployment/keystone/ocr3config.go | 2 +- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/deployment/keystone/changeset/helpers_test.go b/deployment/keystone/changeset/helpers_test.go index d956db991de..f51a4ed610c 100644 --- a/deployment/keystone/changeset/helpers_test.go +++ b/deployment/keystone/changeset/helpers_test.go @@ -41,7 +41,7 @@ func TestSetupTestEnv(t *testing.T) { NumChains: 3, UseMCMS: useMCMS, }) - t.Run(fmt.Sprintf("set up test env using MCMS: %T", useMCMS), func(t *testing.T) { + t.Run(fmt.Sprintf("set up test env using MCMS: %t", useMCMS), func(t *testing.T) { require.NotNil(t, te.Env.ExistingAddresses) require.Len(t, te.Env.Chains, 3) require.NotEmpty(t, te.RegistrySelector) diff --git a/deployment/keystone/changeset/update_don_test.go b/deployment/keystone/changeset/update_don_test.go index 64cb41c14e5..012111c4e62 100644 --- a/deployment/keystone/changeset/update_don_test.go +++ b/deployment/keystone/changeset/update_don_test.go @@ -104,18 +104,10 @@ func TestUpdateDon(t *testing.T) { csOut, err := changeset.UpdateDon(te.Env, &cfg) require.NoError(t, err) - if true { - require.Len(t, csOut.Proposals, 1) - require.Len(t, csOut.Proposals[0].Transactions, 1) // append node capabilties cs, update don - require.Len(t, csOut.Proposals[0].Transactions[0].Batch, 3) // add capabilities, update nodes, update don - require.Nil(t, csOut.AddressBook) - } else { - require.Len(t, csOut.Proposals, 1) - require.Len(t, csOut.Proposals[0].Transactions, 2) // append node capabilties cs, update don - require.Len(t, csOut.Proposals[0].Transactions[0].Batch, 2) // add capabilities, update nodes - require.Len(t, csOut.Proposals[0].Transactions[1].Batch, 1) // update don - require.Nil(t, csOut.AddressBook) - } + require.Len(t, csOut.Proposals, 1) + require.Len(t, csOut.Proposals[0].Transactions, 1) // append node capabilties cs, update don + require.Len(t, csOut.Proposals[0].Transactions[0].Batch, 3) // add capabilities, update nodes, update don + require.Nil(t, csOut.AddressBook) // now apply the changeset such that the proposal is signed and execed contracts := te.ContractSets()[te.RegistrySelector] diff --git a/deployment/keystone/ocr3config.go b/deployment/keystone/ocr3config.go index aed142ea116..d80c4930df4 100644 --- a/deployment/keystone/ocr3config.go +++ b/deployment/keystone/ocr3config.go @@ -328,7 +328,7 @@ func configureOCR3contract(req configureOCR3Request) (*configureOCR3Response, er ) if err != nil { err = DecodeErr(kocr3.OCR3CapabilityABI, err) - return nil, fmt.Errorf("failed to call SetConfig for OCR3 contract %s using mcms: %T: %w", req.contract.Address().String(), req.useMCMS, err) + return nil, fmt.Errorf("failed to call SetConfig for OCR3 contract %s using mcms: %t: %w", req.contract.Address().String(), req.useMCMS, err) } var ops *timelock.BatchChainOperation From bc7724346d4b4fc58b6eba48c45835798e306dcf Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Fri, 13 Dec 2024 16:15:56 +0100 Subject: [PATCH 15/29] [CAPPL-324] rehydrate artifacts from db if they haven't changed (#15668) * fix: rehydrate artifacts from db if they haven't changed * feat: implement GetWorkflowSpecByID --- core/services/workflows/syncer/handler.go | 56 +++++++++++++------ core/services/workflows/syncer/mocks/orm.go | 59 +++++++++++++++++++++ core/services/workflows/syncer/orm.go | 19 +++++++ core/services/workflows/syncer/orm_test.go | 39 ++++++++++++++ 4 files changed, 157 insertions(+), 16 deletions(-) diff --git a/core/services/workflows/syncer/handler.go b/core/services/workflows/syncer/handler.go index 4ef7f952249..534dfd57e7b 100644 --- a/core/services/workflows/syncer/handler.go +++ b/core/services/workflows/syncer/handler.go @@ -400,25 +400,13 @@ func (h *eventHandler) workflowRegisteredEvent( ctx context.Context, payload WorkflowRegistryWorkflowRegisteredV1, ) error { - // Download the contents of binaryURL, configURL and secretsURL and cache them locally. - binary, err := h.fetcher(ctx, payload.BinaryURL) + // Fetch the workflow artifacts from the database or download them from the specified URLs + decodedBinary, config, err := h.getWorkflowArtifacts(ctx, payload) if err != nil { - return fmt.Errorf("failed to fetch binary from %s : %w", payload.BinaryURL, err) - } - - decodedBinary, err := base64.StdEncoding.DecodeString(string(binary)) - if err != nil { - return fmt.Errorf("failed to decode binary: %w", err) - } - - var config []byte - if payload.ConfigURL != "" { - config, err = h.fetcher(ctx, payload.ConfigURL) - if err != nil { - return fmt.Errorf("failed to fetch config from %s : %w", payload.ConfigURL, err) - } + return err } + // Always fetch secrets from the SecretsURL var secrets []byte if payload.SecretsURL != "" { secrets, err = h.fetcher(ctx, payload.SecretsURL) @@ -499,6 +487,42 @@ func (h *eventHandler) workflowRegisteredEvent( return nil } +// getWorkflowArtifacts retrieves the workflow artifacts from the database if they exist, +// or downloads them from the specified URLs if they are not found in the database. +func (h *eventHandler) getWorkflowArtifacts( + ctx context.Context, + payload WorkflowRegistryWorkflowRegisteredV1, +) ([]byte, []byte, error) { + spec, err := h.orm.GetWorkflowSpecByID(ctx, hex.EncodeToString(payload.WorkflowID[:])) + if err != nil { + binary, err2 := h.fetcher(ctx, payload.BinaryURL) + if err2 != nil { + return nil, nil, fmt.Errorf("failed to fetch binary from %s : %w", payload.BinaryURL, err) + } + + decodedBinary, err2 := base64.StdEncoding.DecodeString(string(binary)) + if err2 != nil { + return nil, nil, fmt.Errorf("failed to decode binary: %w", err) + } + + var config []byte + if payload.ConfigURL != "" { + config, err2 = h.fetcher(ctx, payload.ConfigURL) + if err2 != nil { + return nil, nil, fmt.Errorf("failed to fetch config from %s : %w", payload.ConfigURL, err) + } + } + return decodedBinary, config, nil + } + + // there is no update in the BinaryURL or ConfigURL, lets decode the stored artifacts + decodedBinary, err := hex.DecodeString(spec.Workflow) + if err != nil { + return nil, nil, fmt.Errorf("failed to decode stored workflow spec: %w", err) + } + return decodedBinary, []byte(spec.Config), nil +} + func (h *eventHandler) engineFactoryFn(ctx context.Context, id string, owner string, name string, config []byte, binary []byte) (services.Service, error) { moduleConfig := &host.ModuleConfig{Logger: h.lggr, Labeler: h.emitter} sdkSpec, err := host.GetWorkflowSpec(ctx, moduleConfig, binary, config) diff --git a/core/services/workflows/syncer/mocks/orm.go b/core/services/workflows/syncer/mocks/orm.go index da96f422361..09a543d65e3 100644 --- a/core/services/workflows/syncer/mocks/orm.go +++ b/core/services/workflows/syncer/mocks/orm.go @@ -540,6 +540,65 @@ func (_c *ORM_GetWorkflowSpec_Call) RunAndReturn(run func(context.Context, strin return _c } +// GetWorkflowSpecByID provides a mock function with given fields: ctx, id +func (_m *ORM) GetWorkflowSpecByID(ctx context.Context, id string) (*job.WorkflowSpec, error) { + ret := _m.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for GetWorkflowSpecByID") + } + + var r0 *job.WorkflowSpec + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, string) (*job.WorkflowSpec, error)); ok { + return rf(ctx, id) + } + if rf, ok := ret.Get(0).(func(context.Context, string) *job.WorkflowSpec); ok { + r0 = rf(ctx, id) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*job.WorkflowSpec) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, id) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ORM_GetWorkflowSpecByID_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetWorkflowSpecByID' +type ORM_GetWorkflowSpecByID_Call struct { + *mock.Call +} + +// GetWorkflowSpecByID is a helper method to define mock.On call +// - ctx context.Context +// - id string +func (_e *ORM_Expecter) GetWorkflowSpecByID(ctx interface{}, id interface{}) *ORM_GetWorkflowSpecByID_Call { + return &ORM_GetWorkflowSpecByID_Call{Call: _e.mock.On("GetWorkflowSpecByID", ctx, id)} +} + +func (_c *ORM_GetWorkflowSpecByID_Call) Run(run func(ctx context.Context, id string)) *ORM_GetWorkflowSpecByID_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *ORM_GetWorkflowSpecByID_Call) Return(_a0 *job.WorkflowSpec, _a1 error) *ORM_GetWorkflowSpecByID_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *ORM_GetWorkflowSpecByID_Call) RunAndReturn(run func(context.Context, string) (*job.WorkflowSpec, error)) *ORM_GetWorkflowSpecByID_Call { + _c.Call.Return(run) + return _c +} + // Update provides a mock function with given fields: ctx, secretsURL, contents func (_m *ORM) Update(ctx context.Context, secretsURL string, contents string) (int64, error) { ret := _m.Called(ctx, secretsURL, contents) diff --git a/core/services/workflows/syncer/orm.go b/core/services/workflows/syncer/orm.go index bd0501795e6..6289a7ff0b8 100644 --- a/core/services/workflows/syncer/orm.go +++ b/core/services/workflows/syncer/orm.go @@ -52,6 +52,9 @@ type WorkflowSpecsDS interface { // DeleteWorkflowSpec deletes the workflow spec for the given owner and name. DeleteWorkflowSpec(ctx context.Context, owner, name string) error + + // GetWorkflowSpecByID returns the workflow spec for the given workflowID. + GetWorkflowSpecByID(ctx context.Context, id string) (*job.WorkflowSpec, error) } type ORM interface { @@ -370,6 +373,22 @@ func (orm *orm) GetWorkflowSpec(ctx context.Context, owner, name string) (*job.W return &spec, nil } +func (orm *orm) GetWorkflowSpecByID(ctx context.Context, id string) (*job.WorkflowSpec, error) { + query := ` + SELECT * + FROM workflow_specs + WHERE workflow_id = $1 + ` + + var spec job.WorkflowSpec + err := orm.ds.GetContext(ctx, &spec, query, id) + if err != nil { + return nil, err + } + + return &spec, nil +} + func (orm *orm) DeleteWorkflowSpec(ctx context.Context, owner, name string) error { query := ` DELETE FROM workflow_specs diff --git a/core/services/workflows/syncer/orm_test.go b/core/services/workflows/syncer/orm_test.go index a94233e78a1..2e8ffac00df 100644 --- a/core/services/workflows/syncer/orm_test.go +++ b/core/services/workflows/syncer/orm_test.go @@ -197,6 +197,45 @@ func Test_GetWorkflowSpec(t *testing.T) { }) } +func Test_GetWorkflowSpecByID(t *testing.T) { + db := pgtest.NewSqlxDB(t) + ctx := testutils.Context(t) + lggr := logger.TestLogger(t) + orm := &orm{ds: db, lggr: lggr} + + t.Run("gets a workflow spec by ID", func(t *testing.T) { + spec := &job.WorkflowSpec{ + Workflow: "test_workflow", + Config: "test_config", + WorkflowID: "cid-123", + WorkflowOwner: "owner-123", + WorkflowName: "Test Workflow", + Status: job.WorkflowSpecStatusActive, + BinaryURL: "http://example.com/binary", + ConfigURL: "http://example.com/config", + CreatedAt: time.Now(), + SpecType: job.WASMFile, + } + + id, err := orm.UpsertWorkflowSpec(ctx, spec) + require.NoError(t, err) + require.NotZero(t, id) + + dbSpec, err := orm.GetWorkflowSpecByID(ctx, spec.WorkflowID) + require.NoError(t, err) + require.Equal(t, spec.Workflow, dbSpec.Workflow) + + err = orm.DeleteWorkflowSpec(ctx, spec.WorkflowOwner, spec.WorkflowName) + require.NoError(t, err) + }) + + t.Run("fails if no workflow spec exists", func(t *testing.T) { + dbSpec, err := orm.GetWorkflowSpecByID(ctx, "inexistent-workflow-id") + require.Error(t, err) + require.Nil(t, dbSpec) + }) +} + func Test_GetContentsByWorkflowID(t *testing.T) { db := pgtest.NewSqlxDB(t) ctx := testutils.Context(t) From b22f1d7bd14ae2a79d6ca913b3eee08d3d48027a Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Fri, 13 Dec 2024 07:53:35 -0800 Subject: [PATCH 16/29] CCIP-4593 Create rmnproxy setRMN changeset (#15674) * remove deployCCIPContracts * RMNProxy changes * remove comment * add a test * more update * format * skip failing test --- .../ccip/changeset/cs_add_chain_test.go | 1 + deployment/ccip/changeset/cs_deploy_chain.go | 24 +++-- .../changeset/cs_initial_add_chain_test.go | 1 - deployment/ccip/changeset/cs_prerequisites.go | 8 +- .../ccip/changeset/cs_update_rmn_config.go | 100 ++++++++++++++++++ .../changeset/cs_update_rmn_config_test.go | 85 +++++++++++++++ deployment/ccip/changeset/state.go | 38 ++----- deployment/ccip/changeset/test_environment.go | 6 ++ deployment/environment/memory/node.go | 2 + 9 files changed, 223 insertions(+), 42 deletions(-) diff --git a/deployment/ccip/changeset/cs_add_chain_test.go b/deployment/ccip/changeset/cs_add_chain_test.go index a8fdf50b0c1..b349e3451c6 100644 --- a/deployment/ccip/changeset/cs_add_chain_test.go +++ b/deployment/ccip/changeset/cs_add_chain_test.go @@ -30,6 +30,7 @@ import ( ) func TestAddChainInbound(t *testing.T) { + t.Skipf("Skipping test as it is running into timeout issues, move the test into integration in-memory tests") t.Parallel() // 4 chains where the 4th is added after initial deployment. e := NewMemoryEnvironment(t, diff --git a/deployment/ccip/changeset/cs_deploy_chain.go b/deployment/ccip/changeset/cs_deploy_chain.go index 5acb8e15307..6e6d4f907b1 100644 --- a/deployment/ccip/changeset/cs_deploy_chain.go +++ b/deployment/ccip/changeset/cs_deploy_chain.go @@ -31,6 +31,10 @@ var _ deployment.ChangeSet[DeployChainContractsConfig] = DeployChainContracts // DeployChainContracts is idempotent. If there is an error, it will return the successfully deployed addresses and the error so that the caller can call the // changeset again with the same input to retry the failed deployment. // Caller should update the environment's address book with the returned addresses. +// Points to note : +// In case of migrating from legacy ccip to 1.6, the previous RMN address should be set while deploying RMNRemote. +// if there is no existing RMN address found, RMNRemote will be deployed with 0x0 address for previous RMN address +// which will set RMN to 0x0 address immutably in RMNRemote. func DeployChainContracts(env deployment.Environment, c DeployChainContractsConfig) (deployment.ChangesetOutput, error) { if err := c.Validate(); err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("invalid DeployChainContractsConfig: %w", err) @@ -192,6 +196,14 @@ func deployChainContracts( } else { e.Logger.Infow("receiver already deployed", "addr", chainState.Receiver.Address, "chain", chain.String()) } + var rmnLegacyAddr common.Address + if chainState.MockRMN != nil { + rmnLegacyAddr = chainState.MockRMN.Address() + } + // TODO add legacy RMN here when 1.5 contracts are available + if rmnLegacyAddr == (common.Address{}) { + e.Logger.Warnf("No legacy RMN contract found for chain %s, will not setRMN in RMNRemote", chain.String()) + } rmnRemoteContract := chainState.RMNRemote if chainState.RMNRemote == nil { // TODO: Correctly configure RMN remote. @@ -201,8 +213,7 @@ func deployChainContracts( chain.DeployerKey, chain.Client, chain.Selector, - // Indicates no legacy RMN contract - common.HexToAddress("0x0"), + rmnLegacyAddr, ) return deployment.ContractDeploy[*rmn_remote.RMNRemote]{ rmnRemoteAddr, rmnRemote, tx, deployment.NewTypeAndVersion(RMNRemote, deployment.Version1_6_0_dev), err2, @@ -216,6 +227,7 @@ func deployChainContracts( } else { e.Logger.Infow("rmn remote already deployed", "chain", chain.String(), "addr", chainState.RMNRemote.Address) } + activeDigest, err := rmnHome.GetActiveDigest(&bind.CallOpts{}) if err != nil { e.Logger.Errorw("Failed to get active digest", "chain", chain.String(), "err", err) @@ -237,8 +249,8 @@ func deployChainContracts( // we deploy a new RMNProxy so that RMNRemote can be tested first before pointing it to the main Existing RMNProxy // To differentiate between the two RMNProxies, we will deploy new one with Version1_6_0_dev - rmnProxyContract := chainState.RMNProxyNew - if chainState.RMNProxyNew == nil { + rmnProxyContract := chainState.RMNProxy + if chainState.RMNProxy == nil { // we deploy a new rmnproxy contract to test RMNRemote rmnProxy, err := deployment.DeployContract(e.Logger, chain, ab, func(chain deployment.Chain) deployment.ContractDeploy[*rmn_proxy_contract.RMNProxyContract] { @@ -252,12 +264,12 @@ func deployChainContracts( } }) if err != nil { - e.Logger.Errorw("Failed to deploy RMNProxyNew", "chain", chain.String(), "err", err) + e.Logger.Errorw("Failed to deploy RMNProxy", "chain", chain.String(), "err", err) return err } rmnProxyContract = rmnProxy.Contract } else { - e.Logger.Infow("rmn proxy already deployed", "chain", chain.String(), "addr", chainState.RMNProxyNew.Address) + e.Logger.Infow("rmn proxy already deployed", "chain", chain.String(), "addr", chainState.RMNProxy.Address) } if chainState.TestRouter == nil { _, err := deployment.DeployContract(e.Logger, chain, ab, diff --git a/deployment/ccip/changeset/cs_initial_add_chain_test.go b/deployment/ccip/changeset/cs_initial_add_chain_test.go index f344068f11b..7e155b82ed1 100644 --- a/deployment/ccip/changeset/cs_initial_add_chain_test.go +++ b/deployment/ccip/changeset/cs_initial_add_chain_test.go @@ -50,7 +50,6 @@ func TestInitialAddChainAppliedTwice(t *testing.T) { require.NoError(t, err) // send requests chain1, chain2 := allChains[0], allChains[1] - _, err = AddLanes(e.Env, AddLanesConfig{ LaneConfigs: []LaneConfig{ { diff --git a/deployment/ccip/changeset/cs_prerequisites.go b/deployment/ccip/changeset/cs_prerequisites.go index 2386d3bb784..95ef923df83 100644 --- a/deployment/ccip/changeset/cs_prerequisites.go +++ b/deployment/ccip/changeset/cs_prerequisites.go @@ -133,15 +133,11 @@ func deployPrerequisiteContracts(e deployment.Environment, ab deployment.Address weth9Contract = chainState.Weth9 tokenAdminReg = chainState.TokenAdminRegistry registryModule = chainState.RegistryModule - rmnProxy = chainState.RMNProxyExisting + rmnProxy = chainState.RMNProxy r = chainState.Router mc3 = chainState.Multicall3 } if rmnProxy == nil { - // we want to replicate the mainnet scenario where RMNProxy is already deployed with some existing RMN - // This will need us to use two different RMNProxy contracts - // 1. RMNProxyNew with RMNRemote - ( deployed later in chain contracts) - // 2. RMNProxyExisting with mockRMN - ( deployed here, replicating the behavior of existing RMNProxy with already set RMN) rmn, err := deployment.DeployContract(lggr, chain, ab, func(chain deployment.Chain) deployment.ContractDeploy[*mock_rmn_contract.MockRMNContract] { rmnAddr, tx2, rmn, err2 := mock_rmn_contract.DeployMockRMNContract( @@ -149,7 +145,7 @@ func deployPrerequisiteContracts(e deployment.Environment, ab deployment.Address chain.Client, ) return deployment.ContractDeploy[*mock_rmn_contract.MockRMNContract]{ - rmnAddr, rmn, tx2, deployment.NewTypeAndVersion(MockRMN, deployment.Version1_0_0), err2, + Address: rmnAddr, Contract: rmn, Tx: tx2, Tv: deployment.NewTypeAndVersion(MockRMN, deployment.Version1_0_0), Err: err2, } }) if err != nil { diff --git a/deployment/ccip/changeset/cs_update_rmn_config.go b/deployment/ccip/changeset/cs_update_rmn_config.go index c5633e5bfa4..90c1060780c 100644 --- a/deployment/ccip/changeset/cs_update_rmn_config.go +++ b/deployment/ccip/changeset/cs_update_rmn_config.go @@ -11,6 +11,7 @@ import ( "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/mcms" "github.com/smartcontractkit/ccip-owner-contracts/pkg/proposal/timelock" + "github.com/smartcontractkit/chainlink/deployment" "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" @@ -18,6 +19,105 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" ) +type SetRMNRemoteOnRMNProxyConfig struct { + ChainSelectors []uint64 + MCMSConfig *MCMSConfig +} + +func (c SetRMNRemoteOnRMNProxyConfig) Validate(state CCIPOnChainState) error { + for _, chain := range c.ChainSelectors { + err := deployment.IsValidChainSelector(chain) + if err != nil { + return err + } + chainState, exists := state.Chains[chain] + if !exists { + return fmt.Errorf("chain %d not found in state", chain) + } + if chainState.RMNRemote == nil { + return fmt.Errorf("RMNRemote not found for chain %d", chain) + } + if chainState.RMNProxy == nil { + return fmt.Errorf("RMNProxy not found for chain %d", chain) + } + } + return nil +} + +func SetRMNRemoteOnRMNProxy(e deployment.Environment, cfg SetRMNRemoteOnRMNProxyConfig) (deployment.ChangesetOutput, error) { + state, err := LoadOnchainState(e) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to load onchain state: %w", err) + } + if err := cfg.Validate(state); err != nil { + return deployment.ChangesetOutput{}, err + } + var timelockBatch []timelock.BatchChainOperation + multiSigs := make(map[uint64]*gethwrappers.ManyChainMultiSig) + timelocks := make(map[uint64]common.Address) + for _, sel := range cfg.ChainSelectors { + chain, exists := e.Chains[sel] + if !exists { + return deployment.ChangesetOutput{}, fmt.Errorf("chain %d not found", sel) + } + txOpts := chain.DeployerKey + if cfg.MCMSConfig != nil { + txOpts = deployment.SimTransactOpts() + } + mcmsOps, err := setRMNRemoteOnRMNProxyOp(txOpts, chain, state.Chains[sel], cfg.MCMSConfig != nil) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to set RMNRemote on RMNProxy for chain %s: %w", chain.String(), err) + } + if cfg.MCMSConfig != nil { + timelockBatch = append(timelockBatch, timelock.BatchChainOperation{ + ChainIdentifier: mcms.ChainIdentifier(sel), + Batch: []mcms.Operation{mcmsOps}, + }) + multiSigs[sel] = state.Chains[sel].ProposerMcm + timelocks[sel] = state.Chains[sel].Timelock.Address() + } + } + // If we're not using MCMS, we can just return now as we've already confirmed the transactions + if len(timelockBatch) == 0 { + return deployment.ChangesetOutput{}, nil + } + prop, err := proposalutils.BuildProposalFromBatches( + timelocks, + multiSigs, + timelockBatch, + fmt.Sprintf("proposal to set RMNRemote on RMNProxy for chains %v", cfg.ChainSelectors), + cfg.MCMSConfig.MinDelay, + ) + if err != nil { + return deployment.ChangesetOutput{}, err + } + return deployment.ChangesetOutput{ + Proposals: []timelock.MCMSWithTimelockProposal{ + *prop, + }, + }, nil +} + +func setRMNRemoteOnRMNProxyOp(txOpts *bind.TransactOpts, chain deployment.Chain, chainState CCIPChainState, mcmsEnabled bool) (mcms.Operation, error) { + rmnProxy := chainState.RMNProxy + rmnRemoteAddr := chainState.RMNRemote.Address() + setRMNTx, err := rmnProxy.SetARM(txOpts, rmnRemoteAddr) + if err != nil { + return mcms.Operation{}, fmt.Errorf("failed to build call data/transaction to set RMNRemote on RMNProxy for chain %s: %w", chain.String(), err) + } + if !mcmsEnabled { + _, err = deployment.ConfirmIfNoError(chain, setRMNTx, err) + if err != nil { + return mcms.Operation{}, fmt.Errorf("failed to confirm tx to set RMNRemote on RMNProxy for chain %s: %w", chain.String(), deployment.MaybeDataErr(err)) + } + } + return mcms.Operation{ + To: rmnProxy.Address(), + Data: setRMNTx.Data(), + Value: big.NewInt(0), + }, nil +} + type RMNNopConfig struct { NodeIndex uint64 OffchainPublicKey [32]byte diff --git a/deployment/ccip/changeset/cs_update_rmn_config_test.go b/deployment/ccip/changeset/cs_update_rmn_config_test.go index 52f00ce01af..07bf22720c2 100644 --- a/deployment/ccip/changeset/cs_update_rmn_config_test.go +++ b/deployment/ccip/changeset/cs_update_rmn_config_test.go @@ -8,6 +8,8 @@ import ( "github.com/smartcontractkit/chainlink/deployment" commonchangeset "github.com/smartcontractkit/chainlink/deployment/common/changeset" + "github.com/smartcontractkit/chainlink/deployment/common/proposalutils" + commontypes "github.com/smartcontractkit/chainlink/deployment/common/types" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" ) @@ -215,3 +217,86 @@ func buildRMNRemoteAddressPerChain(e deployment.Environment, state CCIPOnChainSt } return rmnRemoteAddressPerChain } + +func TestSetRMNRemoteOnRMNProxy(t *testing.T) { + t.Parallel() + e := NewMemoryEnvironment(t, WithNoJobsAndContracts()) + allChains := e.Env.AllChainSelectors() + mcmsCfg := make(map[uint64]commontypes.MCMSWithTimelockConfig) + var err error + for _, c := range e.Env.AllChainSelectors() { + mcmsCfg[c] = proposalutils.SingleGroupTimelockConfig(t) + } + // Need to deploy prerequisites first so that we can form the USDC config + // no proposals to be made, timelock can be passed as nil here + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, nil, []commonchangeset.ChangesetApplication{ + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployLinkToken), + Config: allChains, + }, + { + Changeset: commonchangeset.WrapChangeSet(DeployPrerequisites), + Config: DeployPrerequisiteConfig{ + ChainSelectors: allChains, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.DeployMCMSWithTimelock), + Config: mcmsCfg, + }, + }) + require.NoError(t, err) + contractsByChain := make(map[uint64][]common.Address) + state, err := LoadOnchainState(e.Env) + require.NoError(t, err) + for _, chain := range allChains { + rmnProxy := state.Chains[chain].RMNProxy + require.NotNil(t, rmnProxy) + contractsByChain[chain] = []common.Address{rmnProxy.Address()} + } + timelockContractsPerChain := make(map[uint64]*proposalutils.TimelockExecutionContracts) + for _, chain := range allChains { + timelockContractsPerChain[chain] = &proposalutils.TimelockExecutionContracts{ + Timelock: state.Chains[chain].Timelock, + CallProxy: state.Chains[chain].CallProxy, + } + } + e.Env, err = commonchangeset.ApplyChangesets(t, e.Env, timelockContractsPerChain, []commonchangeset.ChangesetApplication{ + // transfer ownership of RMNProxy to timelock + { + Changeset: commonchangeset.WrapChangeSet(commonchangeset.TransferToMCMSWithTimelock), + Config: commonchangeset.TransferToMCMSWithTimelockConfig{ + ContractsByChain: contractsByChain, + MinDelay: 0, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(DeployChainContracts), + Config: DeployChainContractsConfig{ + ChainSelectors: allChains, + HomeChainSelector: e.HomeChainSel, + }, + }, + { + Changeset: commonchangeset.WrapChangeSet(SetRMNRemoteOnRMNProxy), + Config: SetRMNRemoteOnRMNProxyConfig{ + ChainSelectors: allChains, + MCMSConfig: &MCMSConfig{ + MinDelay: 0, + }, + }, + }, + }) + require.NoError(t, err) + state, err = LoadOnchainState(e.Env) + require.NoError(t, err) + for _, chain := range allChains { + rmnProxy := state.Chains[chain].RMNProxy + proxyOwner, err := rmnProxy.Owner(nil) + require.NoError(t, err) + require.Equal(t, state.Chains[chain].Timelock.Address(), proxyOwner) + rmnAddr, err := rmnProxy.GetARM(nil) + require.NoError(t, err) + require.Equal(t, rmnAddr, state.Chains[chain].RMNRemote.Address()) + } +} diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index cd88db1b9ee..b51468c1c84 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -87,18 +87,10 @@ type CCIPChainState struct { commoncs.MCMSWithTimelockState commoncs.LinkTokenState commoncs.StaticLinkTokenState - OnRamp *onramp.OnRamp - OffRamp *offramp.OffRamp - FeeQuoter *fee_quoter.FeeQuoter - // We need 2 RMNProxy contracts because we are in the process of migrating to a new version. - // We will switch to the existing one once the migration is complete. - // This is the new RMNProxy contract that will be used for testing RMNRemote before migration. - // Initially RMNProxyNew will point to RMNRemote - RMNProxyNew *rmn_proxy_contract.RMNProxyContract - // Existing RMNProxy contract that is used in production, This already has existing 1.5 RMN set. - // once RMNRemote is tested with RMNProxyNew, as part of migration - // RMNProxyExisting will point to RMNRemote. This will switch over CCIP 1.5 to 1.6 - RMNProxyExisting *rmn_proxy_contract.RMNProxyContract + OnRamp *onramp.OnRamp + OffRamp *offramp.OffRamp + FeeQuoter *fee_quoter.FeeQuoter + RMNProxy *rmn_proxy_contract.RMNProxyContract NonceManager *nonce_manager.NonceManager TokenAdminRegistry *token_admin_registry.TokenAdminRegistry RegistryModule *registry_module_owner_custom.RegistryModuleOwnerCustom @@ -209,12 +201,12 @@ func (c CCIPChainState) GenerateView() (view.ChainView, error) { chainView.CommitStore[c.CommitStore.Address().Hex()] = commitStoreView } - if c.RMNProxyNew != nil { - rmnProxyView, err := v1_0.GenerateRMNProxyView(c.RMNProxyNew) + if c.RMNProxy != nil { + rmnProxyView, err := v1_0.GenerateRMNProxyView(c.RMNProxy) if err != nil { - return chainView, errors.Wrapf(err, "failed to generate rmn proxy view for rmn proxy %s", c.RMNProxyNew.Address().String()) + return chainView, errors.Wrapf(err, "failed to generate rmn proxy view for rmn proxy %s", c.RMNProxy.Address().String()) } - chainView.RMNProxy[c.RMNProxyNew.Address().Hex()] = rmnProxyView + chainView.RMNProxy[c.RMNProxy.Address().Hex()] = rmnProxyView } if c.CCIPHome != nil && c.CapabilityRegistry != nil { chView, err := v1_6.GenerateCCIPHomeView(c.CapabilityRegistry, c.CCIPHome) @@ -361,19 +353,7 @@ func LoadChainState(chain deployment.Chain, addresses map[string]deployment.Type if err != nil { return state, err } - state.RMNProxyExisting = armProxy - case deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_6_0_dev).String(): - armProxy, err := rmn_proxy_contract.NewRMNProxyContract(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.RMNProxyNew = armProxy - case deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_6_0_dev).String(): - armProxy, err := rmn_proxy_contract.NewRMNProxyContract(common.HexToAddress(address), chain.Client) - if err != nil { - return state, err - } - state.RMNProxyNew = armProxy + state.RMNProxy = armProxy case deployment.NewTypeAndVersion(MockRMN, deployment.Version1_0_0).String(): mockRMN, err := mock_rmn_contract.NewMockRMNContract(common.HexToAddress(address), chain.Client) if err != nil { diff --git a/deployment/ccip/changeset/test_environment.go b/deployment/ccip/changeset/test_environment.go index 0efa44d108c..cb0760cee1c 100644 --- a/deployment/ccip/changeset/test_environment.go +++ b/deployment/ccip/changeset/test_environment.go @@ -340,6 +340,12 @@ func NewEnvironmentWithJobsAndContracts(t *testing.T, tc *TestConfigs, tEnv Test HomeChainSelector: e.HomeChainSel, }, }, + { + Changeset: commonchangeset.WrapChangeSet(SetRMNRemoteOnRMNProxy), + Config: SetRMNRemoteOnRMNProxyConfig{ + ChainSelectors: allChains, + }, + }, }) require.NoError(t, err) diff --git a/deployment/environment/memory/node.go b/deployment/environment/memory/node.go index fd08d3cf17b..14b5c9afdd9 100644 --- a/deployment/environment/memory/node.go +++ b/deployment/environment/memory/node.go @@ -286,6 +286,8 @@ func CreateKeys(t *testing.T, } backend := chain.Client.(*Backend).Sim fundAddress(t, chain.DeployerKey, transmitters[evmChainID], assets.Ether(1000).ToInt(), backend) + // in sim chains the send transactions are performed with 0x0 address as the sender + fundAddress(t, chain.DeployerKey, common.Address{}, assets.Ether(1000).ToInt(), backend) } return Keys{ From 6a0f4d5af60523fae065fcd885ba4f553a0493b9 Mon Sep 17 00:00:00 2001 From: Cedric Date: Fri, 13 Dec 2024 17:52:18 +0000 Subject: [PATCH 17/29] [CAPPL-394] Some database changes (#15681) - Allow multiple workflows to reference the same secrets file - Change workflow spec upsert methods so it deletes old workflows --- core/services/workflows/syncer/orm.go | 134 ++++++++++-------- core/services/workflows/syncer/orm_test.go | 42 ++++++ .../workflows/syncer/workflow_registry.go | 2 +- .../migrations/0259_add_workflow_secrets.sql | 3 +- .../0261_remove_unique_constraint_secrets.sql | 10 ++ 5 files changed, 130 insertions(+), 61 deletions(-) create mode 100644 core/store/migrate/migrations/0261_remove_unique_constraint_secrets.sql diff --git a/core/services/workflows/syncer/orm.go b/core/services/workflows/syncer/orm.go index 6289a7ff0b8..ff9336a0893 100644 --- a/core/services/workflows/syncer/orm.go +++ b/core/services/workflows/syncer/orm.go @@ -213,65 +213,73 @@ func (orm *orm) GetSecretsURLHash(owner, secretsURL []byte) ([]byte, error) { func (orm *orm) UpsertWorkflowSpec(ctx context.Context, spec *job.WorkflowSpec) (int64, error) { var id int64 + err := sqlutil.TransactDataSource(ctx, orm.ds, nil, func(tx sqlutil.DataSource) error { + txErr := tx.QueryRowxContext( + ctx, + `DELETE FROM workflow_specs WHERE workflow_owner = $1 AND workflow_name = $2 AND workflow_id != $3`, + spec.WorkflowOwner, + spec.WorkflowName, + spec.WorkflowID, + ).Scan(nil) + if txErr != nil && !errors.Is(txErr, sql.ErrNoRows) { + return fmt.Errorf("failed to clean up previous workflow specs: %w", txErr) + } - query := ` - INSERT INTO workflow_specs ( - workflow, - config, - workflow_id, - workflow_owner, - workflow_name, - status, - binary_url, - config_url, - secrets_id, - created_at, - updated_at, - spec_type - ) VALUES ( - :workflow, - :config, - :workflow_id, - :workflow_owner, - :workflow_name, - :status, - :binary_url, - :config_url, - :secrets_id, - :created_at, - :updated_at, - :spec_type - ) ON CONFLICT (workflow_owner, workflow_name) DO UPDATE - SET - workflow = EXCLUDED.workflow, - config = EXCLUDED.config, - workflow_id = EXCLUDED.workflow_id, - workflow_owner = EXCLUDED.workflow_owner, - workflow_name = EXCLUDED.workflow_name, - status = EXCLUDED.status, - binary_url = EXCLUDED.binary_url, - config_url = EXCLUDED.config_url, - secrets_id = EXCLUDED.secrets_id, - created_at = EXCLUDED.created_at, - updated_at = EXCLUDED.updated_at, - spec_type = EXCLUDED.spec_type - RETURNING id - ` - - stmt, err := orm.ds.PrepareNamedContext(ctx, query) - if err != nil { - return 0, err - } - defer stmt.Close() + query := ` + INSERT INTO workflow_specs ( + workflow, + config, + workflow_id, + workflow_owner, + workflow_name, + status, + binary_url, + config_url, + secrets_id, + created_at, + updated_at, + spec_type + ) VALUES ( + :workflow, + :config, + :workflow_id, + :workflow_owner, + :workflow_name, + :status, + :binary_url, + :config_url, + :secrets_id, + :created_at, + :updated_at, + :spec_type + ) ON CONFLICT (workflow_owner, workflow_name) DO UPDATE + SET + workflow = EXCLUDED.workflow, + config = EXCLUDED.config, + workflow_id = EXCLUDED.workflow_id, + workflow_owner = EXCLUDED.workflow_owner, + workflow_name = EXCLUDED.workflow_name, + status = EXCLUDED.status, + binary_url = EXCLUDED.binary_url, + config_url = EXCLUDED.config_url, + secrets_id = EXCLUDED.secrets_id, + created_at = EXCLUDED.created_at, + updated_at = EXCLUDED.updated_at, + spec_type = EXCLUDED.spec_type + RETURNING id + ` - spec.UpdatedAt = time.Now() - err = stmt.QueryRowxContext(ctx, spec).Scan(&id) + stmt, err := orm.ds.PrepareNamedContext(ctx, query) + if err != nil { + return err + } + defer stmt.Close() - if err != nil { - return 0, err - } + spec.UpdatedAt = time.Now() + return stmt.QueryRowxContext(ctx, spec).Scan(&id) + }) - return id, nil + return id, err } func (orm *orm) UpsertWorkflowSpecWithSecrets( @@ -296,6 +304,17 @@ func (orm *orm) UpsertWorkflowSpecWithSecrets( return fmt.Errorf("failed to create workflow secrets: %w", txErr) } + txErr = tx.QueryRowxContext( + ctx, + `DELETE FROM workflow_specs WHERE workflow_owner = $1 AND workflow_name = $2 AND workflow_id != $3`, + spec.WorkflowOwner, + spec.WorkflowName, + spec.WorkflowID, + ).Scan(nil) + if txErr != nil && !errors.Is(txErr, sql.ErrNoRows) { + return fmt.Errorf("failed to clean up previous workflow specs: %w", txErr) + } + spec.SecretsID = sql.NullInt64{Int64: sid, Valid: true} query := ` @@ -338,10 +357,7 @@ func (orm *orm) UpsertWorkflowSpecWithSecrets( created_at = EXCLUDED.created_at, updated_at = EXCLUDED.updated_at, spec_type = EXCLUDED.spec_type, - secrets_id = CASE - WHEN workflow_specs.secrets_id IS NULL THEN EXCLUDED.secrets_id - ELSE workflow_specs.secrets_id - END + secrets_id = EXCLUDED.secrets_id RETURNING id ` diff --git a/core/services/workflows/syncer/orm_test.go b/core/services/workflows/syncer/orm_test.go index 2e8ffac00df..f47bd6c3731 100644 --- a/core/services/workflows/syncer/orm_test.go +++ b/core/services/workflows/syncer/orm_test.go @@ -6,6 +6,8 @@ import ( "testing" "time" + "github.com/google/uuid" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" "github.com/smartcontractkit/chainlink/v2/core/logger" @@ -411,4 +413,44 @@ func Test_UpsertWorkflowSpecWithSecrets(t *testing.T) { require.NoError(t, err) require.Equal(t, "new contents", contents) }) + + t.Run("updates existing spec and secrets if spec has executions", func(t *testing.T) { + giveURL := "https://example.com" + giveBytes, err := crypto.Keccak256([]byte(giveURL)) + require.NoError(t, err) + giveHash := hex.EncodeToString(giveBytes) + giveContent := "some contents" + + spec := &job.WorkflowSpec{ + Workflow: "test_workflow", + Config: "test_config", + WorkflowID: "cid-123", + WorkflowOwner: "owner-123", + WorkflowName: "Test Workflow", + Status: job.WorkflowSpecStatusActive, + BinaryURL: "http://example.com/binary", + ConfigURL: "http://example.com/config", + CreatedAt: time.Now(), + SpecType: job.WASMFile, + } + + _, err = orm.UpsertWorkflowSpecWithSecrets(ctx, spec, giveURL, giveHash, giveContent) + require.NoError(t, err) + + _, err = db.ExecContext( + ctx, + `INSERT INTO workflow_executions (id, workflow_id, status, created_at) VALUES ($1, $2, $3, $4)`, + uuid.New().String(), + "cid-123", + "started", + time.Now(), + ) + require.NoError(t, err) + + // Update the status + spec.WorkflowID = "cid-456" + + _, err = orm.UpsertWorkflowSpecWithSecrets(ctx, spec, giveURL, giveHash, "new contents") + require.NoError(t, err) + }) } diff --git a/core/services/workflows/syncer/workflow_registry.go b/core/services/workflows/syncer/workflow_registry.go index e68136fdc07..4809f3563ca 100644 --- a/core/services/workflows/syncer/workflow_registry.go +++ b/core/services/workflows/syncer/workflow_registry.go @@ -342,7 +342,7 @@ func (w *workflowRegistry) readRegistryEvents(ctx context.Context, reader Contra for _, event := range events { err := w.handler.Handle(ctx, event.Event) if err != nil { - w.lggr.Errorw("failed to handle event", "err", err) + w.lggr.Errorw("failed to handle event", "err", err, "type", event.Event.EventType) } } } diff --git a/core/store/migrate/migrations/0259_add_workflow_secrets.sql b/core/store/migrate/migrations/0259_add_workflow_secrets.sql index fb76d945571..420f7ed6e49 100644 --- a/core/store/migrate/migrations/0259_add_workflow_secrets.sql +++ b/core/store/migrate/migrations/0259_add_workflow_secrets.sql @@ -38,4 +38,5 @@ DROP INDEX IF EXISTS idx_secrets_url_hash; -- Drop the workflow_artifacts table DROP TABLE IF EXISTS workflow_secrets; --- +goose StatementEnd \ No newline at end of file +-- +goose StatementEnd + diff --git a/core/store/migrate/migrations/0261_remove_unique_constraint_secrets.sql b/core/store/migrate/migrations/0261_remove_unique_constraint_secrets.sql new file mode 100644 index 00000000000..15f59d8ae28 --- /dev/null +++ b/core/store/migrate/migrations/0261_remove_unique_constraint_secrets.sql @@ -0,0 +1,10 @@ +-- +goose Up +-- +goose StatementBegin +-- unique constraint on workflow_owner and workflow_name +ALTER TABLE workflow_specs DROP CONSTRAINT workflow_specs_secrets_id_key; +-- +goose StatementEnd + +-- +goose Down +-- +goose StatementBegin +ALTER TABLE workflow_specs ADD CONSTRAINT workflow_specs_secrets_id_key unique (secrets_id); +-- +goose StatementEnd From 98f222d526d35cf2af78af62b9f41a90217a6741 Mon Sep 17 00:00:00 2001 From: Street <5597260+MStreet3@users.noreply.github.com> Date: Fri, 13 Dec 2024 16:39:49 -0500 Subject: [PATCH 18/29] fix(gateway/connector): await gateway connection before request (#15686) * fix(gateway/connector): enable await before send to gateway * chore(webapi+gateway): lint and test fixes --- core/capabilities/compute/compute_test.go | 2 + .../webapi/outgoing_connector_handler.go | 11 +++- .../webapi/outgoing_connector_handler_test.go | 3 + .../capabilities/webapi/target/target_test.go | 2 +- core/services/gateway/connector/connector.go | 45 +++++++++++-- .../connector/mocks/gateway_connector.go | 63 ++++++++++++++++--- .../services/workflows/syncer/fetcher_test.go | 2 + 7 files changed, 111 insertions(+), 17 deletions(-) diff --git a/core/capabilities/compute/compute_test.go b/core/capabilities/compute/compute_test.go index c4146b7408e..3e5f501fa61 100644 --- a/core/capabilities/compute/compute_test.go +++ b/core/capabilities/compute/compute_test.go @@ -14,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/capabilities" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/wasmtest" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/utils/matches" cappkg "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" @@ -188,6 +189,7 @@ func TestComputeFetch(t *testing.T) { th := setup(t, defaultConfig) th.connector.EXPECT().DonID().Return("don-id") + th.connector.EXPECT().AwaitConnection(matches.AnyContext, "gateway1").Return(nil) th.connector.EXPECT().GatewayIDs().Return([]string{"gateway1", "gateway2"}) msgID := strings.Join([]string{ diff --git a/core/capabilities/webapi/outgoing_connector_handler.go b/core/capabilities/webapi/outgoing_connector_handler.go index 5ea497cd87d..a9ff9ee3aae 100644 --- a/core/capabilities/webapi/outgoing_connector_handler.go +++ b/core/capabilities/webapi/outgoing_connector_handler.go @@ -96,8 +96,15 @@ func (c *OutgoingConnectorHandler) HandleSingleNodeRequest(ctx context.Context, } sort.Strings(gatewayIDs) - err = c.gc.SignAndSendToGateway(ctx, gatewayIDs[0], body) - if err != nil { + selectedGateway := gatewayIDs[0] + + l.Infow("selected gateway, awaiting connection", "gatewayID", selectedGateway) + + if err := c.gc.AwaitConnection(ctx, selectedGateway); err != nil { + return nil, errors.Wrap(err, "await connection canceled") + } + + if err := c.gc.SignAndSendToGateway(ctx, selectedGateway, body); err != nil { return nil, errors.Wrap(err, "failed to send request to gateway") } diff --git a/core/capabilities/webapi/outgoing_connector_handler_test.go b/core/capabilities/webapi/outgoing_connector_handler_test.go index 2090edc6aea..4a8c425d4f1 100644 --- a/core/capabilities/webapi/outgoing_connector_handler_test.go +++ b/core/capabilities/webapi/outgoing_connector_handler_test.go @@ -10,6 +10,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/logger" + "github.com/smartcontractkit/chainlink/v2/core/utils/matches" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/api" gcmocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector/mocks" @@ -36,6 +37,7 @@ func TestHandleSingleNodeRequest(t *testing.T) { msgID := "msgID" testURL := "http://localhost:8080" connector.EXPECT().DonID().Return("donID") + connector.EXPECT().AwaitConnection(matches.AnyContext, "gateway1").Return(nil) connector.EXPECT().GatewayIDs().Return([]string{"gateway1"}) // build the expected body with the default timeout @@ -82,6 +84,7 @@ func TestHandleSingleNodeRequest(t *testing.T) { msgID := "msgID" testURL := "http://localhost:8080" connector.EXPECT().DonID().Return("donID") + connector.EXPECT().AwaitConnection(matches.AnyContext, "gateway1").Return(nil) connector.EXPECT().GatewayIDs().Return([]string{"gateway1"}) // build the expected body with the defined timeout diff --git a/core/capabilities/webapi/target/target_test.go b/core/capabilities/webapi/target/target_test.go index f51cdcd0d70..1af9a107054 100644 --- a/core/capabilities/webapi/target/target_test.go +++ b/core/capabilities/webapi/target/target_test.go @@ -194,7 +194,7 @@ func TestCapability_Execute(t *testing.T) { require.NoError(t, err) gatewayResp := gatewayResponse(t, msgID) - + th.connector.EXPECT().AwaitConnection(mock.Anything, "gateway1").Return(nil) th.connector.On("SignAndSendToGateway", mock.Anything, "gateway1", mock.Anything).Return(nil).Run(func(args mock.Arguments) { th.connectorHandler.HandleGatewayMessage(ctx, "gateway1", gatewayResp) }).Once() diff --git a/core/services/gateway/connector/connector.go b/core/services/gateway/connector/connector.go index a8d356478e9..cab123d4ce5 100644 --- a/core/services/gateway/connector/connector.go +++ b/core/services/gateway/connector/connector.go @@ -28,13 +28,14 @@ type GatewayConnector interface { AddHandler(methods []string, handler GatewayConnectorHandler) error // SendToGateway takes a signed message as argument and sends it to the specified gateway - SendToGateway(ctx context.Context, gatewayId string, msg *api.Message) error + SendToGateway(ctx context.Context, gatewayID string, msg *api.Message) error // SignAndSendToGateway signs the message and sends the message to the specified gateway SignAndSendToGateway(ctx context.Context, gatewayID string, msg *api.MessageBody) error // GatewayIDs returns the list of Gateway IDs GatewayIDs() []string // DonID returns the DON ID DonID() string + AwaitConnection(ctx context.Context, gatewayID string) error } // Signer implementation needs to be provided by a GatewayConnector user (node) @@ -78,12 +79,30 @@ func (c *gatewayConnector) HealthReport() map[string]error { func (c *gatewayConnector) Name() string { return c.lggr.Name() } type gatewayState struct { + // signal channel is closed once the gateway is connected + signalCh chan struct{} + conn network.WSConnectionWrapper config ConnectorGatewayConfig url *url.URL wsClient network.WebSocketClient } +// A gatewayState is connected when the signal channel is closed +func (gs *gatewayState) signal() { + close(gs.signalCh) +} + +// awaitConn blocks until the gateway is connected or the context is done +func (gs *gatewayState) awaitConn(ctx context.Context) error { + select { + case <-ctx.Done(): + return fmt.Errorf("await connection failed: %w", ctx.Err()) + case <-gs.signalCh: + return nil + } +} + func NewGatewayConnector(config *ConnectorConfig, signer Signer, clock clockwork.Clock, lggr logger.Logger) (GatewayConnector, error) { if config == nil || signer == nil || clock == nil || lggr == nil { return nil, errors.New("nil dependency") @@ -125,6 +144,7 @@ func NewGatewayConnector(config *ConnectorConfig, signer Signer, clock clockwork config: gw, url: parsedURL, wsClient: network.NewWebSocketClient(config.WsClientConfig, connector, lggr), + signalCh: make(chan struct{}), } gateways[gw.Id] = gateway urlToId[gw.URL] = gw.Id @@ -150,17 +170,25 @@ func (c *gatewayConnector) AddHandler(methods []string, handler GatewayConnector return nil } -func (c *gatewayConnector) SendToGateway(ctx context.Context, gatewayId string, msg *api.Message) error { +func (c *gatewayConnector) AwaitConnection(ctx context.Context, gatewayID string) error { + gateway, ok := c.gateways[gatewayID] + if !ok { + return fmt.Errorf("invalid Gateway ID %s", gatewayID) + } + return gateway.awaitConn(ctx) +} + +func (c *gatewayConnector) SendToGateway(ctx context.Context, gatewayID string, msg *api.Message) error { data, err := c.codec.EncodeResponse(msg) if err != nil { - return fmt.Errorf("error encoding response for gateway %s: %v", gatewayId, err) + return fmt.Errorf("error encoding response for gateway %s: %w", gatewayID, err) } - gateway, ok := c.gateways[gatewayId] + gateway, ok := c.gateways[gatewayID] if !ok { - return fmt.Errorf("invalid Gateway ID %s", gatewayId) + return fmt.Errorf("invalid Gateway ID %s", gatewayID) } if gateway.conn == nil { - return fmt.Errorf("connector not started") + return errors.New("connector not started") } return gateway.conn.Write(ctx, websocket.BinaryMessage, data) } @@ -242,10 +270,15 @@ func (c *gatewayConnector) reconnectLoop(gatewayState *gatewayState) { } else { c.lggr.Infow("connected successfully", "url", gatewayState.url) closeCh := gatewayState.conn.Reset(conn) + gatewayState.signal() <-closeCh c.lggr.Infow("connection closed", "url", gatewayState.url) + // reset backoff redialBackoff = utils.NewRedialBackoff() + + // reset signal channel + gatewayState.signalCh = make(chan struct{}) } select { case <-c.shutdownCh: diff --git a/core/services/gateway/connector/mocks/gateway_connector.go b/core/services/gateway/connector/mocks/gateway_connector.go index 183fc949cd5..ba5c2213b5f 100644 --- a/core/services/gateway/connector/mocks/gateway_connector.go +++ b/core/services/gateway/connector/mocks/gateway_connector.go @@ -73,6 +73,53 @@ func (_c *GatewayConnector_AddHandler_Call) RunAndReturn(run func([]string, conn return _c } +// AwaitConnection provides a mock function with given fields: ctx, gatewayID +func (_m *GatewayConnector) AwaitConnection(ctx context.Context, gatewayID string) error { + ret := _m.Called(ctx, gatewayID) + + if len(ret) == 0 { + panic("no return value specified for AwaitConnection") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = rf(ctx, gatewayID) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GatewayConnector_AwaitConnection_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'AwaitConnection' +type GatewayConnector_AwaitConnection_Call struct { + *mock.Call +} + +// AwaitConnection is a helper method to define mock.On call +// - ctx context.Context +// - gatewayID string +func (_e *GatewayConnector_Expecter) AwaitConnection(ctx interface{}, gatewayID interface{}) *GatewayConnector_AwaitConnection_Call { + return &GatewayConnector_AwaitConnection_Call{Call: _e.mock.On("AwaitConnection", ctx, gatewayID)} +} + +func (_c *GatewayConnector_AwaitConnection_Call) Run(run func(ctx context.Context, gatewayID string)) *GatewayConnector_AwaitConnection_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(string)) + }) + return _c +} + +func (_c *GatewayConnector_AwaitConnection_Call) Return(_a0 error) *GatewayConnector_AwaitConnection_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *GatewayConnector_AwaitConnection_Call) RunAndReturn(run func(context.Context, string) error) *GatewayConnector_AwaitConnection_Call { + _c.Call.Return(run) + return _c +} + // ChallengeResponse provides a mock function with given fields: _a0, challenge func (_m *GatewayConnector) ChallengeResponse(_a0 *url.URL, challenge []byte) ([]byte, error) { ret := _m.Called(_a0, challenge) @@ -464,9 +511,9 @@ func (_c *GatewayConnector_Ready_Call) RunAndReturn(run func() error) *GatewayCo return _c } -// SendToGateway provides a mock function with given fields: ctx, gatewayId, msg -func (_m *GatewayConnector) SendToGateway(ctx context.Context, gatewayId string, msg *api.Message) error { - ret := _m.Called(ctx, gatewayId, msg) +// SendToGateway provides a mock function with given fields: ctx, gatewayID, msg +func (_m *GatewayConnector) SendToGateway(ctx context.Context, gatewayID string, msg *api.Message) error { + ret := _m.Called(ctx, gatewayID, msg) if len(ret) == 0 { panic("no return value specified for SendToGateway") @@ -474,7 +521,7 @@ func (_m *GatewayConnector) SendToGateway(ctx context.Context, gatewayId string, var r0 error if rf, ok := ret.Get(0).(func(context.Context, string, *api.Message) error); ok { - r0 = rf(ctx, gatewayId, msg) + r0 = rf(ctx, gatewayID, msg) } else { r0 = ret.Error(0) } @@ -489,13 +536,13 @@ type GatewayConnector_SendToGateway_Call struct { // SendToGateway is a helper method to define mock.On call // - ctx context.Context -// - gatewayId string +// - gatewayID string // - msg *api.Message -func (_e *GatewayConnector_Expecter) SendToGateway(ctx interface{}, gatewayId interface{}, msg interface{}) *GatewayConnector_SendToGateway_Call { - return &GatewayConnector_SendToGateway_Call{Call: _e.mock.On("SendToGateway", ctx, gatewayId, msg)} +func (_e *GatewayConnector_Expecter) SendToGateway(ctx interface{}, gatewayID interface{}, msg interface{}) *GatewayConnector_SendToGateway_Call { + return &GatewayConnector_SendToGateway_Call{Call: _e.mock.On("SendToGateway", ctx, gatewayID, msg)} } -func (_c *GatewayConnector_SendToGateway_Call) Run(run func(ctx context.Context, gatewayId string, msg *api.Message)) *GatewayConnector_SendToGateway_Call { +func (_c *GatewayConnector_SendToGateway_Call) Run(run func(ctx context.Context, gatewayID string, msg *api.Message)) *GatewayConnector_SendToGateway_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(string), args[2].(*api.Message)) }) diff --git a/core/services/workflows/syncer/fetcher_test.go b/core/services/workflows/syncer/fetcher_test.go index 8e3e58fba0d..ee59d22608a 100644 --- a/core/services/workflows/syncer/fetcher_test.go +++ b/core/services/workflows/syncer/fetcher_test.go @@ -15,6 +15,7 @@ import ( gcmocks "github.com/smartcontractkit/chainlink/v2/core/services/gateway/connector/mocks" "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/capabilities" ghcapabilities "github.com/smartcontractkit/chainlink/v2/core/services/gateway/handlers/capabilities" + "github.com/smartcontractkit/chainlink/v2/core/utils/matches" ) type wrapper struct { @@ -48,6 +49,7 @@ func TestNewFetcherService(t *testing.T) { fetcher.och.HandleGatewayMessage(ctx, "gateway1", gatewayResp) }).Return(nil).Times(1) connector.EXPECT().DonID().Return("don-id") + connector.EXPECT().AwaitConnection(matches.AnyContext, "gateway1").Return(nil) connector.EXPECT().GatewayIDs().Return([]string{"gateway1", "gateway2"}) payload, err := fetcher.Fetch(ctx, url) From 4e84600bf55b0dfc6a50e1352ba6be80b683b8c9 Mon Sep 17 00:00:00 2001 From: Connor Stein Date: Fri, 13 Dec 2024 16:43:09 -0500 Subject: [PATCH 19/29] MCMS owner rollback to deployer key (#15672) * Rollback test * Fix merge conflicts --- .../transfer_to_mcms_with_timelock.go | 62 +++++++++++++++++++ .../transfer_to_mcms_with_timelock_test.go | 16 +++++ 2 files changed, 78 insertions(+) diff --git a/deployment/common/changeset/transfer_to_mcms_with_timelock.go b/deployment/common/changeset/transfer_to_mcms_with_timelock.go index e48d29af92b..6e792182cf5 100644 --- a/deployment/common/changeset/transfer_to_mcms_with_timelock.go +++ b/deployment/common/changeset/transfer_to_mcms_with_timelock.go @@ -142,3 +142,65 @@ func TransferToMCMSWithTimelock( return deployment.ChangesetOutput{Proposals: []timelock.MCMSWithTimelockProposal{*proposal}}, nil } + +var _ deployment.ChangeSet[TransferToDeployerConfig] = TransferToDeployer + +type TransferToDeployerConfig struct { + ContractAddress common.Address + ChainSel uint64 +} + +// TransferToDeployer relies on the deployer key +// still being a timelock admin and transfers the ownership of a contract +// back to the deployer key. It's effectively the rollback function of transferring +// to the timelock. +func TransferToDeployer(e deployment.Environment, cfg TransferToDeployerConfig) (deployment.ChangesetOutput, error) { + _, ownable, err := LoadOwnableContract(cfg.ContractAddress, e.Chains[cfg.ChainSel].Client) + if err != nil { + return deployment.ChangesetOutput{}, err + } + tx, err := ownable.TransferOwnership(deployment.SimTransactOpts(), e.Chains[cfg.ChainSel].DeployerKey.From) + if err != nil { + return deployment.ChangesetOutput{}, err + } + addrs, err := e.ExistingAddresses.AddressesForChain(cfg.ChainSel) + if err != nil { + return deployment.ChangesetOutput{}, err + } + tls, err := MaybeLoadMCMSWithTimelockChainState(e.Chains[cfg.ChainSel], addrs) + if err != nil { + return deployment.ChangesetOutput{}, err + } + calls := []owner_helpers.RBACTimelockCall{ + { + Target: ownable.Address(), + Data: tx.Data(), + Value: big.NewInt(0), + }, + } + tx, err = tls.Timelock.ScheduleBatch(e.Chains[cfg.ChainSel].DeployerKey, calls, [32]byte{}, [32]byte{}, big.NewInt(0)) + if _, err = deployment.ConfirmIfNoError(e.Chains[cfg.ChainSel], tx, err); err != nil { + return deployment.ChangesetOutput{}, err + } + e.Logger.Infof("scheduled transfer ownership batch with tx %s", tx.Hash().Hex()) + timelockExecutorProxy, err := owner_helpers.NewRBACTimelock(tls.CallProxy.Address(), e.Chains[cfg.ChainSel].Client) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("error creating timelock executor proxy: %w", err) + } + tx, err = timelockExecutorProxy.ExecuteBatch( + e.Chains[cfg.ChainSel].DeployerKey, calls, [32]byte{}, [32]byte{}) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("error executing batch: %w", err) + } + if _, err = deployment.ConfirmIfNoError(e.Chains[cfg.ChainSel], tx, err); err != nil { + return deployment.ChangesetOutput{}, err + } + e.Logger.Infof("executed transfer ownership to deployer key with tx %s", tx.Hash().Hex()) + + tx, err = ownable.AcceptOwnership(e.Chains[cfg.ChainSel].DeployerKey) + if _, err = deployment.ConfirmIfNoError(e.Chains[cfg.ChainSel], tx, err); err != nil { + return deployment.ChangesetOutput{}, err + } + e.Logger.Infof("deployer key accepted ownership tx %s", tx.Hash().Hex()) + return deployment.ChangesetOutput{}, nil +} diff --git a/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go b/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go index 7ba11596a2d..daf4309398f 100644 --- a/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go +++ b/deployment/common/changeset/transfer_to_mcms_with_timelock_test.go @@ -61,4 +61,20 @@ func TestTransferToMCMSWithTimelock(t *testing.T) { o, err := link.LinkToken.Owner(nil) require.NoError(t, err) require.Equal(t, state.Timelock.Address(), o) + + // Try a rollback to the deployer. + e, err = ApplyChangesets(t, e, nil, []ChangesetApplication{ + { + Changeset: WrapChangeSet(TransferToDeployer), + Config: TransferToDeployerConfig{ + ContractAddress: link.LinkToken.Address(), + ChainSel: chain1, + }, + }, + }) + require.NoError(t, err) + + o, err = link.LinkToken.Owner(nil) + require.NoError(t, err) + require.Equal(t, e.Chains[chain1].DeployerKey.From, o) } From 2ec4d6ca8db7c60a2d012933c49a6e1d577b6451 Mon Sep 17 00:00:00 2001 From: Dmytro Haidashenko <34754799+dhaidashenko@users.noreply.github.com> Date: Fri, 13 Dec 2024 22:47:24 +0100 Subject: [PATCH 20/29] BCFR-1086 return finality violation error in health report (#15548) * return finality violation error in health report * gomod * HealthReport tests * propagate headtracker's errors * bump chainlink-common --- core/chains/evm/logpoller/log_poller.go | 6 ++++-- core/chains/evm/logpoller/log_poller_test.go | 9 +++++++-- .../relay/evm/chain_components_test.go | 20 +++++++++++++++++++ core/services/relay/evm/chain_reader.go | 9 ++++++++- 4 files changed, 39 insertions(+), 5 deletions(-) diff --git a/core/chains/evm/logpoller/log_poller.go b/core/chains/evm/logpoller/log_poller.go index 6ef4fefecee..725fdbda63c 100644 --- a/core/chains/evm/logpoller/log_poller.go +++ b/core/chains/evm/logpoller/log_poller.go @@ -23,6 +23,8 @@ import ( pkgerrors "github.com/pkg/errors" "golang.org/x/exp/maps" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/timeutil" @@ -91,6 +93,7 @@ type Client interface { } type HeadTracker interface { + services.Service LatestAndFinalizedBlock(ctx context.Context) (latest, finalized *evmtypes.Head, err error) } @@ -99,7 +102,6 @@ var ( ErrReplayRequestAborted = pkgerrors.New("aborted, replay request cancelled") ErrReplayInProgress = pkgerrors.New("replay request cancelled, but replay is already in progress") ErrLogPollerShutdown = pkgerrors.New("replay aborted due to log poller shutdown") - ErrFinalityViolated = pkgerrors.New("finality violated") ) type logPoller struct { @@ -525,7 +527,7 @@ func (lp *logPoller) Close() error { func (lp *logPoller) Healthy() error { if lp.finalityViolated.Load() { - return ErrFinalityViolated + return commontypes.ErrFinalityViolated } return nil } diff --git a/core/chains/evm/logpoller/log_poller_test.go b/core/chains/evm/logpoller/log_poller_test.go index 7114960efdd..df688cd5e5c 100644 --- a/core/chains/evm/logpoller/log_poller_test.go +++ b/core/chains/evm/logpoller/log_poller_test.go @@ -22,10 +22,13 @@ import ( "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" commonutils "github.com/smartcontractkit/chainlink-common/pkg/utils" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/chaintype" htMocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks" @@ -1106,7 +1109,8 @@ func TestLogPoller_ReorgDeeperThanFinality(t *testing.T) { secondPoll := th.PollAndSaveLogs(testutils.Context(t), firstPoll) assert.Equal(t, firstPoll, secondPoll) - assert.Equal(t, logpoller.ErrFinalityViolated, th.LogPoller.Healthy()) + require.Equal(t, commontypes.ErrFinalityViolated, th.LogPoller.Healthy()) + require.Equal(t, commontypes.ErrFinalityViolated, th.LogPoller.HealthReport()[th.LogPoller.Name()]) // Manually remove re-org'd chain from the log poller to bring it back to life // LogPoller should be healthy again after first poll @@ -1116,7 +1120,8 @@ func TestLogPoller_ReorgDeeperThanFinality(t *testing.T) { // Poll from latest recoveryPoll := th.PollAndSaveLogs(testutils.Context(t), 1) assert.Equal(t, int64(35), recoveryPoll) - assert.NoError(t, th.LogPoller.Healthy()) + require.NoError(t, th.LogPoller.Healthy()) + require.NoError(t, th.LogPoller.HealthReport()[th.LogPoller.Name()]) }) } } diff --git a/core/services/relay/evm/chain_components_test.go b/core/services/relay/evm/chain_components_test.go index bc2703d9678..39b8a35bbf6 100644 --- a/core/services/relay/evm/chain_components_test.go +++ b/core/services/relay/evm/chain_components_test.go @@ -3,6 +3,7 @@ package evm_test import ( "context" "crypto/ecdsa" + "errors" "fmt" "math" "math/big" @@ -12,6 +13,7 @@ import ( "time" "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/common" evmtypes "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethclient/simulated" @@ -19,15 +21,20 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/services" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" commontestutils "github.com/smartcontractkit/chainlink-common/pkg/loop/testutils" clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" + htMocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" + lpMocks "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller/mocks" evmtxmgr "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr" + clevmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/internal/cltest" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" @@ -206,6 +213,19 @@ func TestContractReaderEventsInitValidation(t *testing.T) { } } +func TestChainReader_HealthReport(t *testing.T) { + lp := lpMocks.NewLogPoller(t) + lp.EXPECT().HealthReport().Return(map[string]error{"lp_name": clcommontypes.ErrFinalityViolated}).Once() + ht := htMocks.NewHeadTracker[*clevmtypes.Head, common.Hash](t) + htError := errors.New("head tracker error") + ht.EXPECT().HealthReport().Return(map[string]error{"ht_name": htError}).Once() + cr, err := evm.NewChainReaderService(testutils.Context(t), logger.NullLogger, lp, ht, nil, types.ChainReaderConfig{Contracts: nil}) + require.NoError(t, err) + healthReport := cr.HealthReport() + require.True(t, services.ContainsError(healthReport, clcommontypes.ErrFinalityViolated), "expected chain reader to propagate logpoller's error") + require.True(t, services.ContainsError(healthReport, htError), "expected chain reader to propagate headtracker's error") +} + func TestChainComponents(t *testing.T) { testutils.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/BCFR-1083") t.Parallel() diff --git a/core/services/relay/evm/chain_reader.go b/core/services/relay/evm/chain_reader.go index 99be89eae17..d86c5cd635a 100644 --- a/core/services/relay/evm/chain_reader.go +++ b/core/services/relay/evm/chain_reader.go @@ -20,6 +20,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/types/query" "github.com/smartcontractkit/chainlink-common/pkg/types/query/primitives" "github.com/smartcontractkit/chainlink-common/pkg/values" + evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/logpoller" evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -179,7 +180,13 @@ func (cr *chainReader) Close() error { func (cr *chainReader) Ready() error { return nil } func (cr *chainReader) HealthReport() map[string]error { - return map[string]error{cr.Name(): nil} + report := map[string]error{ + cr.Name(): cr.Healthy(), + } + + commonservices.CopyHealth(report, cr.lp.HealthReport()) + commonservices.CopyHealth(report, cr.ht.HealthReport()) + return report } func (cr *chainReader) Bind(ctx context.Context, bindings []commontypes.BoundContract) error { From a5fe613afc12eeab41c1955cb94108bad4366263 Mon Sep 17 00:00:00 2001 From: Anindita Ghosh <88458927+AnieeG@users.noreply.github.com> Date: Fri, 13 Dec 2024 14:12:47 -0800 Subject: [PATCH 21/29] Helper methods to GetAllTimeLocksForChains and GetAllProposerMCMSForChains (#15691) * remove deployCCIPContracts * review comments from past PR --- deployment/ccip/changeset/cs_deploy_chain.go | 30 +++-------------- .../ccip/changeset/cs_update_rmn_config.go | 12 ++++--- deployment/ccip/changeset/state.go | 32 +++++++++++++++++++ deployment/environment/memory/node.go | 2 +- 4 files changed, 45 insertions(+), 31 deletions(-) diff --git a/deployment/ccip/changeset/cs_deploy_chain.go b/deployment/ccip/changeset/cs_deploy_chain.go index 6e6d4f907b1..065c29755b6 100644 --- a/deployment/ccip/changeset/cs_deploy_chain.go +++ b/deployment/ccip/changeset/cs_deploy_chain.go @@ -19,7 +19,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/offramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/onramp" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_home" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_proxy_contract" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/rmn_remote" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" ) @@ -177,6 +176,10 @@ func deployChainContracts( if chainState.Router == nil { return fmt.Errorf("router not found for chain %s, deploy the prerequisites first", chain.String()) } + rmnProxyContract := chainState.RMNProxy + if chainState.RMNProxy == nil { + return fmt.Errorf("rmn proxy not found for chain %s, deploy the prerequisites first", chain.String()) + } if chainState.Receiver == nil { _, err := deployment.DeployContract(e.Logger, chain, ab, func(chain deployment.Chain) deployment.ContractDeploy[*maybe_revert_message_receiver.MaybeRevertMessageReceiver] { @@ -246,31 +249,6 @@ func deployChainContracts( e.Logger.Errorw("Failed to confirm RMNRemote config", "chain", chain.String(), "err", err) return err } - - // we deploy a new RMNProxy so that RMNRemote can be tested first before pointing it to the main Existing RMNProxy - // To differentiate between the two RMNProxies, we will deploy new one with Version1_6_0_dev - rmnProxyContract := chainState.RMNProxy - if chainState.RMNProxy == nil { - // we deploy a new rmnproxy contract to test RMNRemote - rmnProxy, err := deployment.DeployContract(e.Logger, chain, ab, - func(chain deployment.Chain) deployment.ContractDeploy[*rmn_proxy_contract.RMNProxyContract] { - rmnProxyAddr, tx, rmnProxy, err2 := rmn_proxy_contract.DeployRMNProxyContract( - chain.DeployerKey, - chain.Client, - rmnRemoteContract.Address(), - ) - return deployment.ContractDeploy[*rmn_proxy_contract.RMNProxyContract]{ - rmnProxyAddr, rmnProxy, tx, deployment.NewTypeAndVersion(ARMProxy, deployment.Version1_6_0_dev), err2, - } - }) - if err != nil { - e.Logger.Errorw("Failed to deploy RMNProxy", "chain", chain.String(), "err", err) - return err - } - rmnProxyContract = rmnProxy.Contract - } else { - e.Logger.Infow("rmn proxy already deployed", "chain", chain.String(), "addr", chainState.RMNProxy.Address) - } if chainState.TestRouter == nil { _, err := deployment.DeployContract(e.Logger, chain, ab, func(chain deployment.Chain) deployment.ContractDeploy[*router.Router] { diff --git a/deployment/ccip/changeset/cs_update_rmn_config.go b/deployment/ccip/changeset/cs_update_rmn_config.go index 90c1060780c..96f8eacb4cc 100644 --- a/deployment/ccip/changeset/cs_update_rmn_config.go +++ b/deployment/ccip/changeset/cs_update_rmn_config.go @@ -52,9 +52,15 @@ func SetRMNRemoteOnRMNProxy(e deployment.Environment, cfg SetRMNRemoteOnRMNProxy if err := cfg.Validate(state); err != nil { return deployment.ChangesetOutput{}, err } + timelocks, err := state.GetAllTimeLocksForChains(cfg.ChainSelectors) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get timelocks for chains %v: %w", cfg.ChainSelectors, err) + } + multiSigs, err := state.GetAllProposerMCMSForChains(cfg.ChainSelectors) + if err != nil { + return deployment.ChangesetOutput{}, fmt.Errorf("failed to get proposer MCMS for chains %v: %w", cfg.ChainSelectors, err) + } var timelockBatch []timelock.BatchChainOperation - multiSigs := make(map[uint64]*gethwrappers.ManyChainMultiSig) - timelocks := make(map[uint64]common.Address) for _, sel := range cfg.ChainSelectors { chain, exists := e.Chains[sel] if !exists { @@ -73,8 +79,6 @@ func SetRMNRemoteOnRMNProxy(e deployment.Environment, cfg SetRMNRemoteOnRMNProxy ChainIdentifier: mcms.ChainIdentifier(sel), Batch: []mcms.Operation{mcmsOps}, }) - multiSigs[sel] = state.Chains[sel].ProposerMcm - timelocks[sel] = state.Chains[sel].Timelock.Address() } } // If we're not using MCMS, we can just return now as we've already confirmed the transactions diff --git a/deployment/ccip/changeset/state.go b/deployment/ccip/changeset/state.go index b51468c1c84..2403f3f7cc2 100644 --- a/deployment/ccip/changeset/state.go +++ b/deployment/ccip/changeset/state.go @@ -3,6 +3,8 @@ package changeset import ( "fmt" + "github.com/smartcontractkit/ccip-owner-contracts/pkg/gethwrappers" + burn_mint_token_pool "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/burn_mint_token_pool_1_4_0" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/erc20" @@ -257,6 +259,36 @@ type CCIPOnChainState struct { SolChains map[uint64]SolCCIPChainState } +func (s CCIPOnChainState) GetAllProposerMCMSForChains(chains []uint64) (map[uint64]*gethwrappers.ManyChainMultiSig, error) { + multiSigs := make(map[uint64]*gethwrappers.ManyChainMultiSig) + for _, chain := range chains { + chainState, ok := s.Chains[chain] + if !ok { + return nil, fmt.Errorf("chain %d not found", chain) + } + if chainState.ProposerMcm == nil { + return nil, fmt.Errorf("proposer mcm not found for chain %d", chain) + } + multiSigs[chain] = chainState.ProposerMcm + } + return multiSigs, nil +} + +func (s CCIPOnChainState) GetAllTimeLocksForChains(chains []uint64) (map[uint64]common.Address, error) { + timelocks := make(map[uint64]common.Address) + for _, chain := range chains { + chainState, ok := s.Chains[chain] + if !ok { + return nil, fmt.Errorf("chain %d not found", chain) + } + if chainState.Timelock == nil { + return nil, fmt.Errorf("timelock not found for chain %d", chain) + } + timelocks[chain] = chainState.Timelock.Address() + } + return timelocks, nil +} + func (s CCIPOnChainState) View(chains []uint64) (map[string]view.ChainView, error) { m := make(map[string]view.ChainView) for _, chainSelector := range chains { diff --git a/deployment/environment/memory/node.go b/deployment/environment/memory/node.go index 14b5c9afdd9..84f0d2e443f 100644 --- a/deployment/environment/memory/node.go +++ b/deployment/environment/memory/node.go @@ -286,7 +286,7 @@ func CreateKeys(t *testing.T, } backend := chain.Client.(*Backend).Sim fundAddress(t, chain.DeployerKey, transmitters[evmChainID], assets.Ether(1000).ToInt(), backend) - // in sim chains the send transactions are performed with 0x0 address as the sender + // need to look more into it, but it seems like with sim chains nodes are sending txs with 0x from address fundAddress(t, chain.DeployerKey, common.Address{}, assets.Ether(1000).ToInt(), backend) } From 6491709fb559f43e4b2ce4a213a3241fb742a390 Mon Sep 17 00:00:00 2001 From: Connor Stein Date: Fri, 13 Dec 2024 18:31:43 -0500 Subject: [PATCH 22/29] Bump MCMS lib for salt fix (#15694) * Bump mcms * Mod tidy * Also needs salt * Idempotence * fix release --------- Co-authored-by: AnieeG --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- .../changeset/transfer_to_mcms_with_timelock.go | 13 ++++++++++--- deployment/go.mod | 2 +- deployment/go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.sum | 4 ++-- 8 files changed, 21 insertions(+), 14 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 557276b94ef..26ac0b1ec7b 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -301,7 +301,7 @@ require ( github.com/sethvargo/go-retry v0.2.4 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/shirou/gopsutil/v3 v3.24.3 // indirect - github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix // indirect github.com/smartcontractkit/chain-selectors v1.0.34 // indirect github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index bf807b0881c..f27f4983608 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1134,8 +1134,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix h1:DPJD++yKLSx0EfT+U14P8vLVxjXFmoIETiCO9lVwQo8= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix/go.mod h1:NnT6w4Kj42OFFXhSx99LvJZWPpMjmo4+CpDEWfw61xY= github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3fePb3eCreuAnUA3RBj4= github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= diff --git a/deployment/common/changeset/transfer_to_mcms_with_timelock.go b/deployment/common/changeset/transfer_to_mcms_with_timelock.go index 6e792182cf5..1980dfaa378 100644 --- a/deployment/common/changeset/transfer_to_mcms_with_timelock.go +++ b/deployment/common/changeset/transfer_to_mcms_with_timelock.go @@ -1,6 +1,7 @@ package changeset import ( + "encoding/binary" "fmt" "math/big" "time" @@ -155,10 +156,14 @@ type TransferToDeployerConfig struct { // back to the deployer key. It's effectively the rollback function of transferring // to the timelock. func TransferToDeployer(e deployment.Environment, cfg TransferToDeployerConfig) (deployment.ChangesetOutput, error) { - _, ownable, err := LoadOwnableContract(cfg.ContractAddress, e.Chains[cfg.ChainSel].Client) + owner, ownable, err := LoadOwnableContract(cfg.ContractAddress, e.Chains[cfg.ChainSel].Client) if err != nil { return deployment.ChangesetOutput{}, err } + if owner == e.Chains[cfg.ChainSel].DeployerKey.From { + e.Logger.Infof("Contract %s already owned by deployer", cfg.ContractAddress) + return deployment.ChangesetOutput{}, nil + } tx, err := ownable.TransferOwnership(deployment.SimTransactOpts(), e.Chains[cfg.ChainSel].DeployerKey.From) if err != nil { return deployment.ChangesetOutput{}, err @@ -178,7 +183,9 @@ func TransferToDeployer(e deployment.Environment, cfg TransferToDeployerConfig) Value: big.NewInt(0), }, } - tx, err = tls.Timelock.ScheduleBatch(e.Chains[cfg.ChainSel].DeployerKey, calls, [32]byte{}, [32]byte{}, big.NewInt(0)) + var salt [32]byte + binary.BigEndian.PutUint32(salt[:], uint32(time.Now().Unix())) + tx, err = tls.Timelock.ScheduleBatch(e.Chains[cfg.ChainSel].DeployerKey, calls, [32]byte{}, salt, big.NewInt(0)) if _, err = deployment.ConfirmIfNoError(e.Chains[cfg.ChainSel], tx, err); err != nil { return deployment.ChangesetOutput{}, err } @@ -188,7 +195,7 @@ func TransferToDeployer(e deployment.Environment, cfg TransferToDeployerConfig) return deployment.ChangesetOutput{}, fmt.Errorf("error creating timelock executor proxy: %w", err) } tx, err = timelockExecutorProxy.ExecuteBatch( - e.Chains[cfg.ChainSel].DeployerKey, calls, [32]byte{}, [32]byte{}) + e.Chains[cfg.ChainSel].DeployerKey, calls, [32]byte{}, salt) if err != nil { return deployment.ChangesetOutput{}, fmt.Errorf("error executing batch: %w", err) } diff --git a/deployment/go.mod b/deployment/go.mod index d275487ff38..ffc691b9aca 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -26,7 +26,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/sethvargo/go-retry v0.2.4 - github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 diff --git a/deployment/go.sum b/deployment/go.sum index 71057f369ae..2b8c3819d86 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1403,8 +1403,8 @@ github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrf github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix h1:DPJD++yKLSx0EfT+U14P8vLVxjXFmoIETiCO9lVwQo8= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix/go.mod h1:NnT6w4Kj42OFFXhSx99LvJZWPpMjmo4+CpDEWfw61xY= github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3fePb3eCreuAnUA3RBj4= github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index bf55d2a13fc..0c746729f4d 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -423,7 +423,7 @@ require ( github.com/shirou/gopsutil/v3 v3.24.3 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/sirupsen/logrus v1.9.3 // indirect - github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 // indirect + github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix // indirect github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index b49443079d0..2c6a13a07de 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1424,8 +1424,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.15.0 h1:LE2lj2y9vqqiOf+qIIy0GvEoxgF1N5yLGZffmEZykt0= github.com/slack-go/slack v0.15.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix h1:DPJD++yKLSx0EfT+U14P8vLVxjXFmoIETiCO9lVwQo8= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix/go.mod h1:NnT6w4Kj42OFFXhSx99LvJZWPpMjmo4+CpDEWfw61xY= github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3fePb3eCreuAnUA3RBj4= github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 535173d6d4b..bcb4c488482 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1415,8 +1415,8 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/slack-go/slack v0.15.0 h1:LE2lj2y9vqqiOf+qIIy0GvEoxgF1N5yLGZffmEZykt0= github.com/slack-go/slack v0.15.0/go.mod h1:hlGi5oXA+Gt+yWTPP0plCdRKmjsDxecdHxYQdlMQKOw= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86 h1:qQH6fZZe31nBAG6INHph3z5ysDTPptyu0TR9uoJ1+ok= -github.com/smartcontractkit/ccip-owner-contracts v0.0.0-20240926212305-a6deabdfce86/go.mod h1:WtWOoVQQEHxRHL2hNmuRrvDfYfQG/CioFNoa9Rr2mBE= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix h1:DPJD++yKLSx0EfT+U14P8vLVxjXFmoIETiCO9lVwQo8= +github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix/go.mod h1:NnT6w4Kj42OFFXhSx99LvJZWPpMjmo4+CpDEWfw61xY= github.com/smartcontractkit/chain-selectors v1.0.34 h1:MJ17OGu8+jjl426pcKrJkCf3fePb3eCreuAnUA3RBj4= github.com/smartcontractkit/chain-selectors v1.0.34/go.mod h1:xsKM0aN3YGcQKTPRPDDtPx2l4mlTN1Djmg0VVXV40b8= github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgBc2xpDKBco/Q4h4ydl6+UUU= From d0d9e8bbd8ee7c0c6cd054ca14ba1c3b77e8fcae Mon Sep 17 00:00:00 2001 From: Domino Valdano Date: Fri, 13 Dec 2024 17:52:14 -0800 Subject: [PATCH 23/29] Move txdb and dialects to chainlink-common/pkg/pg (#15064) * Move txdb.go and dialects.go to chainlink-common Along with that: - Replace dialects imports with pgcommon - Replace testutils.Skip* with tests.Skip* - Call RegisterTxDb from NewConnection - Run goimports (somehow there were a few files on develop which were improperly formatted?) * Fix merge conflict with copied txdb driver While rebasing, I found that CCIP has copied the old txdb driver from chainlink into chainlink/integrations-tests. The problem with duplicated code is it makes it more difficult to update. Little did they know, it had already been updated even before they copied it. So this removes the copy and imports the newer version from chainlink-common. The motivation for copying rather than import appears to have come from a lint rule that enforces not being able to import anything from an external package with "internal" in the directory name. This still requires that the NewSqlxDB be copied, but that's just a wrapper around the pgcommon version which reads the db url from the chainlik toml config, which can't be accessed in chainlink-common. * chainlink-common/pkg/pg -> chainlink-common/pkg/sqlutil/pg * Fix lint introduced by rebase * pg.NewSqlxDB -> pg.NewTestDB * Update chainlink-common ref * Fix merge conflict --- GNUmakefile | 7 - .../remote/executable/client_test.go | 6 +- core/chains/evm/gas/models.go | 1 + core/chains/evm/gas/rollups/l1_oracle.go | 1 + core/cmd/shell_local.go | 11 +- core/cmd/shell_local_test.go | 10 +- core/config/database_config.go | 4 +- core/config/docs/defaults.go | 5 +- core/config/toml/types.go | 5 +- core/gethwrappers/go_generate_test.go | 5 +- core/internal/cltest/cltest.go | 5 +- core/internal/features/features_test.go | 5 +- .../testutils/configtest/general_config.go | 6 +- core/internal/testutils/pgtest/pgtest.go | 19 +- core/internal/testutils/pgtest/txdb.go | 509 ----------------- core/internal/testutils/testutils.go | 14 +- core/scripts/go.mod | 10 +- core/scripts/go.sum | 32 +- core/services/chainlink/config_database.go | 5 +- .../chainlink/config_database_test.go | 39 +- .../fluxmonitorv2/flux_monitor_test.go | 2 +- .../fluxmonitorv2/integrations_test.go | 3 +- .../plugins/ocr2keeper/integration_test.go | 4 +- core/services/pg/connection.go | 12 +- core/services/pg/connection_test.go | 10 +- core/services/pg/locked_db.go | 5 +- .../relay/evm/chain_components_test.go | 3 +- .../statuschecker/txm_status_checker_test.go | 5 +- .../vrf/v2/integration_v2_plus_test.go | 3 +- core/services/vrf/v2/integration_v2_test.go | 4 +- core/store/dialects/dialects.go | 18 - core/utils/testutils/heavyweight/orm.go | 11 +- deployment/go.mod | 10 +- deployment/go.sum | 34 +- go.mod | 15 +- go.sum | 42 +- integration-tests/go.mod | 10 +- integration-tests/go.sum | 34 +- integration-tests/load/go.mod | 10 +- integration-tests/load/go.sum | 34 +- integration-tests/utils/pgtest/pgtest.go | 33 +- integration-tests/utils/pgtest/txdb.go | 510 ------------------ internal/testdb/testdb.go | 6 +- 43 files changed, 269 insertions(+), 1248 deletions(-) delete mode 100644 core/internal/testutils/pgtest/txdb.go delete mode 100644 core/store/dialects/dialects.go delete mode 100644 integration-tests/utils/pgtest/txdb.go diff --git a/GNUmakefile b/GNUmakefile index 336efd326a7..b765c63a3f4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -133,13 +133,6 @@ testdb-force: ## Prepares the test database, drops any pesky user connections th testdb-user-only: ## Prepares the test database with user only. go run . local db preparetest --user-only -# Format for CI -.PHONY: presubmit -presubmit: ## Format go files and imports. - goimports -w . - gofmt -w . - go mod tidy - .PHONY: gomods gomods: ## Install gomods go install github.com/jmank88/gomods@v0.1.4 diff --git a/core/capabilities/remote/executable/client_test.go b/core/capabilities/remote/executable/client_test.go index 0314f62b1b7..f4e6add82b0 100644 --- a/core/capabilities/remote/executable/client_test.go +++ b/core/capabilities/remote/executable/client_test.go @@ -12,7 +12,9 @@ import ( commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink-common/pkg/values" + "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/executable" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" "github.com/smartcontractkit/chainlink/v2/core/capabilities/transmission" @@ -29,7 +31,7 @@ const ( ) func Test_Client_DonTopologies(t *testing.T) { - testutils.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/CAPPL-363") + tests.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/CAPPL-363") ctx := testutils.Context(t) transmissionSchedule, err := values.NewMap(map[string]any{ @@ -88,7 +90,7 @@ func Test_Client_DonTopologies(t *testing.T) { } func Test_Client_TransmissionSchedules(t *testing.T) { - testutils.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/CAPPL-363") + tests.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/CAPPL-363") ctx := testutils.Context(t) responseTest := func(t *testing.T, response commoncap.CapabilityResponse, responseError error) { diff --git a/core/chains/evm/gas/models.go b/core/chains/evm/gas/models.go index 6cb89818c8f..2d6fe971d9c 100644 --- a/core/chains/evm/gas/models.go +++ b/core/chains/evm/gas/models.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/rpc" pkgerrors "github.com/pkg/errors" + "github.com/smartcontractkit/chainlink-common/pkg/logger" "github.com/smartcontractkit/chainlink-common/pkg/services" bigmath "github.com/smartcontractkit/chainlink-common/pkg/utils/big_math" diff --git a/core/chains/evm/gas/rollups/l1_oracle.go b/core/chains/evm/gas/rollups/l1_oracle.go index ceecb80c608..d9f12dfa79e 100644 --- a/core/chains/evm/gas/rollups/l1_oracle.go +++ b/core/chains/evm/gas/rollups/l1_oracle.go @@ -10,6 +10,7 @@ import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/rpc" + "github.com/smartcontractkit/chainlink-common/pkg/services" "github.com/smartcontractkit/chainlink-common/pkg/logger" diff --git a/core/cmd/shell_local.go b/core/cmd/shell_local.go index 412231308b6..1fdc1a46d34 100644 --- a/core/cmd/shell_local.go +++ b/core/cmd/shell_local.go @@ -35,6 +35,8 @@ import ( cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" + "github.com/smartcontractkit/chainlink/v2/core/build" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/gas" @@ -47,7 +49,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/sessions" "github.com/smartcontractkit/chainlink/v2/core/shutdown" "github.com/smartcontractkit/chainlink/v2/core/static" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" "github.com/smartcontractkit/chainlink/v2/core/store/migrate" "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/web" @@ -805,7 +806,7 @@ func (s *Shell) PrepareTestDatabase(c *cli.Context) error { // Creating pristine DB copy to speed up FullTestDB dbUrl := cfg.Database().URL() - db, err := sqlx.Open(string(dialects.Postgres), dbUrl.String()) + db, err := sqlx.Open(string(pgcommon.Postgres), dbUrl.String()) if err != nil { return s.errorOut(err) } @@ -1088,7 +1089,7 @@ type dbConfig interface { MaxOpenConns() int MaxIdleConns() int URL() url.URL - Dialect() dialects.DialectName + Dialect() pgcommon.DialectName } func newConnection(ctx context.Context, cfg dbConfig) (*sqlx.DB, error) { @@ -1104,7 +1105,7 @@ func dropAndCreateDB(parsed url.URL, force bool) (err error) { // to a different one. template1 should be present on all postgres installations dbname := parsed.Path[1:] parsed.Path = "/template1" - db, err := sql.Open(string(dialects.Postgres), parsed.String()) + db, err := sql.Open(string(pgcommon.Postgres), parsed.String()) if err != nil { return fmt.Errorf("unable to open postgres database for creating test db: %+v", err) } @@ -1203,7 +1204,7 @@ func checkSchema(dbURL url.URL, prevSchema string) error { } func insertFixtures(dbURL url.URL, pathToFixtures string) (err error) { - db, err := sql.Open(string(dialects.Postgres), dbURL.String()) + db, err := sql.Open(string(pgcommon.Postgres), dbURL.String()) if err != nil { return fmt.Errorf("unable to open postgres database for creating test db: %+v", err) } diff --git a/core/cmd/shell_local_test.go b/core/cmd/shell_local_test.go index 78254c0279e..7cdc8c21840 100644 --- a/core/cmd/shell_local_test.go +++ b/core/cmd/shell_local_test.go @@ -10,6 +10,7 @@ import ( "time" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" "github.com/smartcontractkit/chainlink/v2/common/client" @@ -29,7 +30,6 @@ import ( chainlinkmocks "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/mocks" evmrelayer "github.com/smartcontractkit/chainlink/v2/core/services/relay/evm" "github.com/smartcontractkit/chainlink/v2/core/sessions/localauth" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/smartcontractkit/chainlink/v2/core/utils/testutils/heavyweight" @@ -283,7 +283,7 @@ func TestShell_RebroadcastTransactions_Txm(t *testing.T) { // test multiple connections to the database, and changes made within // the transaction cannot be seen from another connection. config, sqlxDB := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.Database.Dialect = dialects.Postgres + c.Database.Dialect = pgcommon.Postgres // evm config is used in this test. but if set, it must be pass config validation. // simplest to make it nil c.EVM = nil @@ -363,7 +363,7 @@ func TestShell_RebroadcastTransactions_OutsideRange_Txm(t *testing.T) { // test multiple connections to the database, and changes made within // the transaction cannot be seen from another connection. config, sqlxDB := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.Database.Dialect = dialects.Postgres + c.Database.Dialect = pgcommon.Postgres // evm config is used in this test. but if set, it must be pass config validation. // simplest to make it nil c.EVM = nil @@ -441,7 +441,7 @@ func TestShell_RebroadcastTransactions_AddressCheck(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { config, sqlxDB := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.Database.Dialect = dialects.Postgres + c.Database.Dialect = pgcommon.Postgres c.EVM = nil // seems to be needed for config validate @@ -499,7 +499,7 @@ func TestShell_RebroadcastTransactions_AddressCheck(t *testing.T) { func TestShell_CleanupChainTables(t *testing.T) { // Just check if it doesn't error, command itself shouldn't be changed unless major schema changes were made. // It would be really hard to write a test that accounts for schema changes, so this should be enough to alarm us that something broke. - config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.Database.Dialect = dialects.Postgres }) + config, _ := heavyweight.FullTestDBV2(t, func(c *chainlink.Config, s *chainlink.Secrets) { c.Database.Dialect = pgcommon.Postgres }) client := cmd.Shell{ Config: config, Logger: logger.TestLogger(t), diff --git a/core/config/database_config.go b/core/config/database_config.go index f1cdffc2f46..56f8f8165d4 100644 --- a/core/config/database_config.go +++ b/core/config/database_config.go @@ -4,7 +4,7 @@ import ( "net/url" "time" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" ) type Backup interface { @@ -35,7 +35,7 @@ type Database interface { DefaultIdleInTxSessionTimeout() time.Duration DefaultLockTimeout() time.Duration DefaultQueryTimeout() time.Duration - Dialect() dialects.DialectName + Dialect() pgcommon.DialectName LogSQL() bool MaxIdleConns() int MaxOpenConns() int diff --git a/core/config/docs/defaults.go b/core/config/docs/defaults.go index 53e6433a8ef..0d94be1b3cc 100644 --- a/core/config/docs/defaults.go +++ b/core/config/docs/defaults.go @@ -5,9 +5,10 @@ import ( "strings" "github.com/smartcontractkit/chainlink-common/pkg/config" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" + "github.com/smartcontractkit/chainlink/v2/core/config/toml" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink/cfgtest" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" ) var ( @@ -22,7 +23,7 @@ func init() { func CoreDefaults() (c toml.Core) { c.SetFrom(&defaults) - c.Database.Dialect = dialects.Postgres // not user visible - overridden for tests only + c.Database.Dialect = pgcommon.Postgres // not user visible - overridden for tests only c.Tracing.Attributes = make(map[string]string) return } diff --git a/core/config/toml/types.go b/core/config/toml/types.go index 475e95d53df..620f7d96eee 100644 --- a/core/config/toml/types.go +++ b/core/config/toml/types.go @@ -16,6 +16,7 @@ import ( ocrcommontypes "github.com/smartcontractkit/libocr/commontypes" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" "github.com/smartcontractkit/chainlink/v2/core/build" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" @@ -23,10 +24,8 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/config/parse" "github.com/smartcontractkit/chainlink/v2/core/services/keystore/keys/p2pkey" "github.com/smartcontractkit/chainlink/v2/core/sessions" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/core/utils" - configutils "github.com/smartcontractkit/chainlink/v2/core/utils/config" ) @@ -339,7 +338,7 @@ type Database struct { DefaultIdleInTxSessionTimeout *commonconfig.Duration DefaultLockTimeout *commonconfig.Duration DefaultQueryTimeout *commonconfig.Duration - Dialect dialects.DialectName `toml:"-"` + Dialect pgcommon.DialectName `toml:"-"` LogQueries *bool MaxIdleConns *int64 MaxOpenConns *int64 diff --git a/core/gethwrappers/go_generate_test.go b/core/gethwrappers/go_generate_test.go index a6253cb1a66..1066149278f 100644 --- a/core/gethwrappers/go_generate_test.go +++ b/core/gethwrappers/go_generate_test.go @@ -16,7 +16,8 @@ import ( "github.com/fatih/color" cutils "github.com/smartcontractkit/chainlink-common/pkg/utils" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/core/utils" "github.com/stretchr/testify/assert" @@ -29,7 +30,7 @@ const compileCommand = "../../contracts/scripts/native_solc_compile_all" // contract artifacts in contracts/solc with the abi and bytecode stored in the // contract wrapper func TestCheckContractHashesFromLastGoGenerate(t *testing.T) { - testutils.SkipShort(t, "requires compiled artifacts") + tests.SkipShort(t, "requires compiled artifacts") versions, err := ReadVersionsDB() require.NoError(t, err) require.NotEmpty(t, versions.GethVersion, `version DB should have a "GETH_VERSION:" line`) diff --git a/core/internal/cltest/cltest.go b/core/internal/cltest/cltest.go index 7ade85f4bf7..a55c57cc9a2 100644 --- a/core/internal/cltest/cltest.go +++ b/core/internal/cltest/cltest.go @@ -47,6 +47,7 @@ import ( "github.com/smartcontractkit/chainlink-common/pkg/loop" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" "github.com/smartcontractkit/chainlink-common/pkg/utils/mailbox" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/common/client" commonmocks "github.com/smartcontractkit/chainlink/v2/common/types/mocks" @@ -531,7 +532,7 @@ func NewEthMocks(t testing.TB) *evmclimocks.Client { } func NewEthMocksWithStartupAssertions(t testing.TB) *evmclimocks.Client { - testutils.SkipShort(t, "long test") + tests.SkipShort(t, "long test") c := NewEthMocks(t) chHead := make(<-chan *evmtypes.Head) c.On("Dial", mock.Anything).Maybe().Return(nil) @@ -554,7 +555,7 @@ func NewEthMocksWithStartupAssertions(t testing.TB) *evmclimocks.Client { // NewEthMocksWithTransactionsOnBlocksAssertions sets an Eth mock with transactions on blocks func NewEthMocksWithTransactionsOnBlocksAssertions(t testing.TB) *evmclimocks.Client { - testutils.SkipShort(t, "long test") + tests.SkipShort(t, "long test") c := NewEthMocks(t) chHead := make(<-chan *evmtypes.Head) c.On("Dial", mock.Anything).Maybe().Return(nil) diff --git a/core/internal/features/features_test.go b/core/internal/features/features_test.go index 2d0d046857c..88305403f2b 100644 --- a/core/internal/features/features_test.go +++ b/core/internal/features/features_test.go @@ -40,6 +40,7 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/auth" "github.com/smartcontractkit/chainlink/v2/core/bridges" @@ -798,7 +799,7 @@ func setupForwarderEnabledNode(t *testing.T, owner *bind.TransactOpts, portV2 in func TestIntegration_OCR(t *testing.T) { t.Skip("fails after geth upgrade https://github.com/smartcontractkit/chainlink/pull/11809; passes local but fails CI") - testutils.SkipShort(t, "long test") + tests.SkipShort(t, "long test") t.Parallel() tests := []struct { id int @@ -1031,7 +1032,7 @@ observationSource = """ func TestIntegration_OCR_ForwarderFlow(t *testing.T) { t.Skip("fails after geth upgrade https://github.com/smartcontractkit/chainlink/pull/11809") - testutils.SkipShort(t, "long test") + tests.SkipShort(t, "long test") t.Parallel() numOracles := 4 t.Run("ocr_forwarder_flow", func(t *testing.T) { diff --git a/core/internal/testutils/configtest/general_config.go b/core/internal/testutils/configtest/general_config.go index 63aba18c351..f0851c67740 100644 --- a/core/internal/testutils/configtest/general_config.go +++ b/core/internal/testutils/configtest/general_config.go @@ -7,14 +7,16 @@ import ( "github.com/stretchr/testify/require" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" + commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client" evmcfg "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils/big" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" "github.com/smartcontractkit/chainlink/v2/core/store/models" ) @@ -48,7 +50,7 @@ func overrides(c *chainlink.Config, s *chainlink.Secrets) { c.InsecureFastScrypt = ptr(true) c.ShutdownGracePeriod = commonconfig.MustNewDuration(testutils.DefaultWaitTimeout) - c.Database.Dialect = dialects.TransactionWrappedPostgres + c.Database.Dialect = pgcommon.TransactionWrappedPostgres c.Database.Lock.Enabled = ptr(false) c.Database.MaxIdleConns = ptr[int64](20) c.Database.MaxOpenConns = ptr[int64](20) diff --git a/core/internal/testutils/pgtest/pgtest.go b/core/internal/testutils/pgtest/pgtest.go index 8464604b667..ee17d8f4d14 100644 --- a/core/internal/testutils/pgtest/pgtest.go +++ b/core/internal/testutils/pgtest/pgtest.go @@ -3,26 +3,25 @@ package pgtest import ( "testing" - "github.com/google/uuid" "github.com/jmoiron/sqlx" - "github.com/scylladb/go-reflectx" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" "github.com/smartcontractkit/chainlink-common/pkg/utils" + + "github.com/smartcontractkit/chainlink/v2/core/config/env" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" ) func NewSqlxDB(t testing.TB) *sqlx.DB { testutils.SkipShortDB(t) - db, err := sqlx.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String()) - require.NoError(t, err) - t.Cleanup(func() { assert.NoError(t, db.Close()) }) - db.MapperFunc(reflectx.CamelToSnakeASCII) - - return db + dbURL := string(env.DatabaseURL.Get()) + if dbURL == "" { + t.Errorf("you must provide a CL_DATABASE_URL environment variable") + return nil + } + return pg.NewTestDB(t, dbURL) } func MustExec(t *testing.T, ds sqlutil.DataSource, stmt string, args ...interface{}) { diff --git a/core/internal/testutils/pgtest/txdb.go b/core/internal/testutils/pgtest/txdb.go deleted file mode 100644 index 7591054305c..00000000000 --- a/core/internal/testutils/pgtest/txdb.go +++ /dev/null @@ -1,509 +0,0 @@ -package pgtest - -import ( - "context" - "database/sql" - "database/sql/driver" - "flag" - "fmt" - "io" - "net/url" - "strings" - "sync" - "testing" - - "github.com/jmoiron/sqlx" - "go.uber.org/multierr" - - "github.com/smartcontractkit/chainlink/v2/core/config/env" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" -) - -// txdb is a simplified version of https://github.com/DATA-DOG/go-txdb -// -// The original lib has various problems and is hard to understand because it -// tries to be more general. The version in this file is more tightly focused -// to our needs and should be easier to reason about and less likely to have -// subtle bugs/races. -// -// It doesn't currently support savepoints but could be made to if necessary. -// -// Transaction BEGIN/ROLLBACK effectively becomes a no-op, this should have no -// negative impact on normal test operation. -// -// If you MUST test BEGIN/ROLLBACK behaviour, you will have to configure your -// store to use the raw DialectPostgres dialect and setup a one-use database. -// See heavyweight.FullTestDB() as a convenience function to help you do this, -// but please use sparingly because as it's name implies, it is expensive. -func init() { - testing.Init() - if !flag.Parsed() { - flag.Parse() - } - if testing.Short() { - // -short tests don't need a DB - return - } - dbURL := string(env.DatabaseURL.Get()) - if dbURL == "" { - panic("you must provide a CL_DATABASE_URL environment variable") - } - - parsed, err := url.Parse(dbURL) - if err != nil { - panic(err) - } - if parsed.Path == "" { - msg := fmt.Sprintf("invalid %[1]s: `%[2]s`. You must set %[1]s env var to point to your test database. Note that the test database MUST end in `_test` to differentiate from a possible production DB. HINT: Try %[1]s=postgresql://postgres@localhost:5432/chainlink_test?sslmode=disable", env.DatabaseURL, parsed.String()) - panic(msg) - } - if !strings.HasSuffix(parsed.Path, "_test") { - msg := fmt.Sprintf("cannot run tests against database named `%s`. Note that the test database MUST end in `_test` to differentiate from a possible production DB. HINT: Try %s=postgresql://postgres@localhost:5432/chainlink_test?sslmode=disable", parsed.Path[1:], env.DatabaseURL) - panic(msg) - } - name := string(dialects.TransactionWrappedPostgres) - sql.Register(name, &txDriver{ - dbURL: dbURL, - conns: make(map[string]*conn), - }) - sqlx.BindDriver(name, sqlx.DOLLAR) -} - -var _ driver.Conn = &conn{} - -var _ driver.Validator = &conn{} -var _ driver.SessionResetter = &conn{} - -// txDriver is an sql driver which runs on a single transaction. -// When `Close` is called, transaction is rolled back. -type txDriver struct { - sync.Mutex - db *sql.DB - conns map[string]*conn - - dbURL string -} - -func (d *txDriver) Open(dsn string) (driver.Conn, error) { - d.Lock() - defer d.Unlock() - // Open real db connection if its the first call - if d.db == nil { - db, err := sql.Open(string(dialects.Postgres), d.dbURL) - if err != nil { - return nil, err - } - d.db = db - } - c, exists := d.conns[dsn] - if !exists || !c.tryOpen() { - tx, err := d.db.Begin() - if err != nil { - return nil, err - } - c = &conn{tx: tx, opened: 1, dsn: dsn} - c.removeSelf = func() error { - return d.deleteConn(c) - } - d.conns[dsn] = c - } - return c, nil -} - -// deleteConn is called by a connection when it is closed via the `close` method. -// It also auto-closes the DB when the last checked out connection is closed. -func (d *txDriver) deleteConn(c *conn) error { - // must lock here to avoid racing with Open - d.Lock() - defer d.Unlock() - - if d.conns[c.dsn] != c { - return nil // already been replaced - } - delete(d.conns, c.dsn) - if len(d.conns) == 0 && d.db != nil { - if err := d.db.Close(); err != nil { - return err - } - d.db = nil - } - return nil -} - -type conn struct { - sync.Mutex - dsn string - tx *sql.Tx // tx may be shared by many conns, definitive one lives in the map keyed by DSN on the txDriver. Do not modify from conn - closed bool - opened int - removeSelf func() error -} - -func (c *conn) Begin() (driver.Tx, error) { - c.Lock() - defer c.Unlock() - if c.closed { - panic("conn is closed") - } - // Begin is a noop because the transaction was already opened - return tx{c.tx}, nil -} - -// Implement the "ConnBeginTx" interface -func (c *conn) BeginTx(_ context.Context, opts driver.TxOptions) (driver.Tx, error) { - // Context is ignored, because single transaction is shared by all callers, thus caller should not be able to - // control it with local context - return c.Begin() -} - -// Prepare returns a prepared statement, bound to this connection. -func (c *conn) Prepare(query string) (driver.Stmt, error) { - return c.PrepareContext(context.Background(), query) -} - -// Implement the "ConnPrepareContext" interface -func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) { - c.Lock() - defer c.Unlock() - if c.closed { - panic("conn is closed") - } - - // TODO: Fix context handling - // FIXME: It is not safe to give the passed in context to the tx directly - // because the tx is shared by many conns and cancelling the context will - // destroy the tx which can affect other conns - st, err := c.tx.PrepareContext(context.Background(), query) - if err != nil { - return nil, err - } - return &stmt{st, c}, nil -} - -// IsValid is called prior to placing the connection into the -// connection pool by database/sql. The connection will be discarded if false is returned. -func (c *conn) IsValid() bool { - c.Lock() - defer c.Unlock() - return !c.closed -} - -func (c *conn) ResetSession(ctx context.Context) error { - // Ensure bad connections are reported: From database/sql/driver: - // If a connection is never returned to the connection pool but immediately reused, then - // ResetSession is called prior to reuse but IsValid is not called. - c.Lock() - defer c.Unlock() - if c.closed { - return driver.ErrBadConn - } - - return nil -} - -// pgx returns nil -func (c *conn) CheckNamedValue(nv *driver.NamedValue) error { - return nil -} - -// Implement the "QueryerContext" interface -func (c *conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { - c.Lock() - defer c.Unlock() - if c.closed { - panic("conn is closed") - } - - // TODO: Fix context handling - rs, err := c.tx.QueryContext(context.Background(), query, mapNamedArgs(args)...) - if err != nil { - return nil, err - } - defer rs.Close() - - return buildRows(rs) -} - -// Implement the "ExecerContext" interface -func (c *conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { - c.Lock() - defer c.Unlock() - if c.closed { - panic("conn is closed") - } - // TODO: Fix context handling - return c.tx.ExecContext(context.Background(), query, mapNamedArgs(args)...) -} - -// tryOpen attempts to increment the open count, but returns false if closed. -func (c *conn) tryOpen() bool { - c.Lock() - defer c.Unlock() - if c.closed { - return false - } - c.opened++ - return true -} - -// Close invalidates and potentially stops any current -// prepared statements and transactions, marking this -// connection as no longer in use. -// -// Because the sql package maintains a free pool of -// connections and only calls Close when there's a surplus of -// idle connections, it shouldn't be necessary for drivers to -// do their own connection caching. -// -// Drivers must ensure all network calls made by Close -// do not block indefinitely (e.g. apply a timeout). -func (c *conn) Close() (err error) { - if !c.close() { - return - } - // Wait to remove self to avoid nesting locks. - if err := c.removeSelf(); err != nil { - panic(err) - } - return -} - -func (c *conn) close() bool { - c.Lock() - defer c.Unlock() - if c.closed { - // Double close, should be a safe to make this a noop - // PGX allows double close - // See: https://github.com/jackc/pgx/blob/a457da8bffa4f90ad672fa093ee87f20cf06687b/conn.go#L249 - return false - } - - c.opened-- - if c.opened > 0 { - return false - } - if c.tx != nil { - if err := c.tx.Rollback(); err != nil { - panic(err) - } - c.tx = nil - } - c.closed = true - return true -} - -type tx struct { - tx *sql.Tx -} - -func (tx tx) Commit() error { - // Commit is a noop because the transaction will be rolled back at the end - return nil -} - -func (tx tx) Rollback() error { - // Rollback is a noop because the transaction will be rolled back at the end - return nil -} - -type stmt struct { - st *sql.Stmt - conn *conn -} - -func (s stmt) Exec(args []driver.Value) (driver.Result, error) { - s.conn.Lock() - defer s.conn.Unlock() - if s.conn.closed { - panic("conn is closed") - } - return s.st.Exec(mapArgs(args)...) -} - -// Implement the "StmtExecContext" interface -func (s *stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { - s.conn.Lock() - defer s.conn.Unlock() - if s.conn.closed { - panic("conn is closed") - } - // TODO: Fix context handling - return s.st.ExecContext(context.Background(), mapNamedArgs(args)...) -} - -func mapArgs(args []driver.Value) (res []interface{}) { - res = make([]interface{}, len(args)) - for i := range args { - res[i] = args[i] - } - return -} - -func (s stmt) NumInput() int { - return -1 -} - -func (s stmt) Query(args []driver.Value) (driver.Rows, error) { - s.conn.Lock() - defer s.conn.Unlock() - if s.conn.closed { - panic("conn is closed") - } - rows, err := s.st.Query(mapArgs(args)...) - defer func() { - err = multierr.Combine(err, rows.Close()) - }() - if err != nil { - return nil, err - } - return buildRows(rows) -} - -// Implement the "StmtQueryContext" interface -func (s *stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { - s.conn.Lock() - defer s.conn.Unlock() - if s.conn.closed { - panic("conn is closed") - } - // TODO: Fix context handling - rows, err := s.st.QueryContext(context.Background(), mapNamedArgs(args)...) - if err != nil { - return nil, err - } - return buildRows(rows) -} - -func (s stmt) Close() error { - s.conn.Lock() - defer s.conn.Unlock() - return s.st.Close() -} - -func buildRows(r *sql.Rows) (driver.Rows, error) { - set := &rowSets{} - rs := &rows{} - if err := rs.read(r); err != nil { - return set, err - } - set.sets = append(set.sets, rs) - for r.NextResultSet() { - rss := &rows{} - if err := rss.read(r); err != nil { - return set, err - } - set.sets = append(set.sets, rss) - } - return set, nil -} - -// Implement the "RowsNextResultSet" interface -func (rs *rowSets) HasNextResultSet() bool { - return rs.pos+1 < len(rs.sets) -} - -// Implement the "RowsNextResultSet" interface -func (rs *rowSets) NextResultSet() error { - if !rs.HasNextResultSet() { - return io.EOF - } - - rs.pos++ - return nil -} - -type rows struct { - rows [][]driver.Value - pos int - cols []string - colTypes []*sql.ColumnType -} - -func (r *rows) Columns() []string { - return r.cols -} - -func (r *rows) ColumnTypeDatabaseTypeName(index int) string { - return r.colTypes[index].DatabaseTypeName() -} - -func (r *rows) Next(dest []driver.Value) error { - r.pos++ - if r.pos > len(r.rows) { - return io.EOF - } - - for i, val := range r.rows[r.pos-1] { - dest[i] = *(val.(*interface{})) - } - - return nil -} - -func (r *rows) Close() error { - return nil -} - -func (r *rows) read(rs *sql.Rows) error { - var err error - r.cols, err = rs.Columns() - if err != nil { - return err - } - - r.colTypes, err = rs.ColumnTypes() - if err != nil { - return err - } - - for rs.Next() { - values := make([]interface{}, len(r.cols)) - for i := range values { - values[i] = new(interface{}) - } - if err := rs.Scan(values...); err != nil { - return err - } - row := make([]driver.Value, len(r.cols)) - for i, v := range values { - row[i] = driver.Value(v) - } - r.rows = append(r.rows, row) - } - return rs.Err() -} - -type rowSets struct { - sets []*rows - pos int -} - -func (rs *rowSets) Columns() []string { - return rs.sets[rs.pos].cols -} - -func (rs *rowSets) ColumnTypeDatabaseTypeName(index int) string { - return rs.sets[rs.pos].ColumnTypeDatabaseTypeName(index) -} - -func (rs *rowSets) Close() error { - return nil -} - -// advances to next row -func (rs *rowSets) Next(dest []driver.Value) error { - return rs.sets[rs.pos].Next(dest) -} - -func mapNamedArgs(args []driver.NamedValue) (res []interface{}) { - res = make([]interface{}, len(args)) - for i := range args { - name := args[i].Name - if name != "" { - res[i] = sql.Named(name, args[i].Value) - } else { - res[i] = args[i].Value - } - } - return -} diff --git a/core/internal/testutils/testutils.go b/core/internal/testutils/testutils.go index 0504570365b..53b555c0e8b 100644 --- a/core/internal/testutils/testutils.go +++ b/core/internal/testutils/testutils.go @@ -32,6 +32,7 @@ import ( // NOTE: To avoid circular dependencies, this package MUST NOT import // anything from "github.com/smartcontractkit/chainlink/v2/core" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" ) const ( @@ -415,16 +416,9 @@ func WaitForLogMessageCount(t *testing.T, observedLogs *observer.ObservedLogs, m }) } -// SkipShort skips tb during -short runs, and notes why. -func SkipShort(tb testing.TB, why string) { - if testing.Short() { - tb.Skipf("skipping: %s", why) - } -} - // SkipShortDB skips tb during -short runs, and notes the DB dependency. func SkipShortDB(tb testing.TB) { - SkipShort(tb, "DB dependency") + tests.SkipShort(tb, "DB dependency") } func AssertCount(t *testing.T, ds sqlutil.DataSource, tableName string, expected int64) { @@ -454,10 +448,6 @@ func MustDecodeBase64(s string) (b []byte) { return } -func SkipFlakey(t *testing.T, ticketURL string) { - t.Skip("Flakey", ticketURL) -} - func MustRandBytes(n int) (b []byte) { b = make([]byte, n) _, err := rand.Read(b) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 26ac0b1ec7b..11dfa7c26ee 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -33,7 +33,7 @@ require ( github.com/prometheus/client_golang v1.20.5 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v0.8.1 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 @@ -69,7 +69,7 @@ require ( github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb // indirect github.com/VictoriaMetrics/fastcache v1.12.2 // indirect github.com/XSAM/otelsql v0.27.0 // indirect - github.com/andybalholm/brotli v1.1.0 // indirect + github.com/andybalholm/brotli v1.1.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/atombender/go-jsonschema v0.16.1-0.20240916205339-a74cd4e2851c // indirect github.com/avast/retry-go/v4 v4.6.0 // indirect @@ -170,7 +170,7 @@ require ( github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-yaml v1.12.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -238,8 +238,8 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index f27f4983608..959cac27d8f 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -139,9 +139,11 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= +github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow-go/v18 v18.0.0 h1:1dBDaSbH3LtulTyOVYaBCHO3yVRwjV+TZaqn3g6V7ZM= +github.com/apache/arrow-go/v18 v18.0.0/go.mod h1:t6+cWRSmKgdQ6HsxisQjok+jBpKGhRDiqcf3p0p/F+A= github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4= github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -497,8 +499,8 @@ github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAh github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -563,6 +565,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI= +github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -830,11 +834,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -881,6 +885,8 @@ github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYt github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= +github.com/marcboeker/go-duckdb v1.8.3 h1:ZkYwiIZhbYsT6MmJsZ3UPTHrTZccDdM4ztoqSlEMXiQ= +github.com/marcboeker/go-duckdb v1.8.3/go.mod h1:C9bYRE1dPYb1hhfu/SSomm78B0FXmNgRvv6YBW/Hooc= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= @@ -1018,6 +1024,8 @@ github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xl github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -1142,8 +1150,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1304,6 +1312,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= +github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1313,6 +1323,8 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= diff --git a/core/services/chainlink/config_database.go b/core/services/chainlink/config_database.go index fe10c63f71b..fd8aa96419d 100644 --- a/core/services/chainlink/config_database.go +++ b/core/services/chainlink/config_database.go @@ -4,9 +4,10 @@ import ( "net/url" "time" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" + "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/config/toml" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" ) type backupConfig struct { @@ -109,7 +110,7 @@ func (d *databaseConfig) URL() url.URL { return *d.s.URL.URL() } -func (d *databaseConfig) Dialect() dialects.DialectName { +func (d *databaseConfig) Dialect() pgcommon.DialectName { return d.c.Dialect } diff --git a/core/services/chainlink/config_database_test.go b/core/services/chainlink/config_database_test.go index b52d17452aa..f8f864f97ab 100644 --- a/core/services/chainlink/config_database_test.go +++ b/core/services/chainlink/config_database_test.go @@ -7,8 +7,9 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" + "github.com/smartcontractkit/chainlink/v2/core/config" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" ) func TestDatabaseConfig(t *testing.T) { @@ -21,31 +22,31 @@ URL = "postgresql://doesnotexist:justtopassvalidationtests@localhost:5432/chainl require.NoError(t, err) backup := cfg.Database().Backup() - assert.Equal(t, backup.Dir(), "test/backup/dir") - assert.Equal(t, backup.Frequency(), 1*time.Hour) - assert.Equal(t, backup.Mode(), config.DatabaseBackupModeFull) - assert.Equal(t, backup.OnVersionUpgrade(), true) + assert.Equal(t, "test/backup/dir", backup.Dir()) + assert.Equal(t, 1*time.Hour, backup.Frequency()) + assert.Equal(t, config.DatabaseBackupModeFull, backup.Mode()) + assert.True(t, backup.OnVersionUpgrade()) assert.Nil(t, backup.URL()) db := cfg.Database() - assert.Equal(t, db.DefaultIdleInTxSessionTimeout(), 1*time.Minute) - assert.Equal(t, db.DefaultLockTimeout(), 1*time.Hour) - assert.Equal(t, db.DefaultQueryTimeout(), 1*time.Second) - assert.Equal(t, db.LogSQL(), true) - assert.Equal(t, db.MaxIdleConns(), 7) - assert.Equal(t, db.MaxOpenConns(), 13) - assert.Equal(t, db.MigrateDatabase(), true) - assert.Equal(t, db.Dialect(), dialects.Postgres) + assert.Equal(t, 1*time.Minute, db.DefaultIdleInTxSessionTimeout()) + assert.Equal(t, 1*time.Hour, db.DefaultLockTimeout()) + assert.Equal(t, 1*time.Second, db.DefaultQueryTimeout()) + assert.True(t, db.LogSQL()) + assert.Equal(t, 7, db.MaxIdleConns()) + assert.Equal(t, 13, db.MaxOpenConns()) + assert.True(t, db.MigrateDatabase()) + assert.Equal(t, pgcommon.Postgres, db.Dialect()) url := db.URL() assert.NotEqual(t, url.String(), "") lock := db.Lock() - assert.Equal(t, lock.LockingMode(), "none") - assert.Equal(t, lock.LeaseDuration(), 1*time.Minute) - assert.Equal(t, lock.LeaseRefreshInterval(), 1*time.Second) + assert.Equal(t, "none", lock.LockingMode()) + assert.Equal(t, 1*time.Minute, lock.LeaseDuration()) + assert.Equal(t, 1*time.Second, lock.LeaseRefreshInterval()) l := db.Listener() - assert.Equal(t, l.MaxReconnectDuration(), 1*time.Minute) - assert.Equal(t, l.MinReconnectInterval(), 5*time.Minute) - assert.Equal(t, l.FallbackPollInterval(), 2*time.Minute) + assert.Equal(t, 1*time.Minute, l.MaxReconnectDuration()) + assert.Equal(t, 5*time.Minute, l.MinReconnectInterval()) + assert.Equal(t, 2*time.Minute, l.FallbackPollInterval()) } diff --git a/core/services/fluxmonitorv2/flux_monitor_test.go b/core/services/fluxmonitorv2/flux_monitor_test.go index 88b364cdeb3..150db269e45 100644 --- a/core/services/fluxmonitorv2/flux_monitor_test.go +++ b/core/services/fluxmonitorv2/flux_monitor_test.go @@ -150,7 +150,7 @@ type setupOptions struct { // functional options to configure the setup func setup(t *testing.T, ds sqlutil.DataSource, optionFns ...func(*setupOptions)) (*fluxmonitorv2.FluxMonitor, *testMocks) { t.Helper() - testutils.SkipShort(t, "long test") + tests.SkipShort(t, "long test") tm := setupMocks(t) options := setupOptions{ diff --git a/core/services/fluxmonitorv2/integrations_test.go b/core/services/fluxmonitorv2/integrations_test.go index 1d77b694cbe..d30ff4479a8 100644 --- a/core/services/fluxmonitorv2/integrations_test.go +++ b/core/services/fluxmonitorv2/integrations_test.go @@ -25,6 +25,7 @@ import ( commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/bridges" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -95,7 +96,7 @@ func WithMinMaxSubmission(min, max *big.Int) func(cfg *fluxAggregatorUniverseCon // arguments match the arguments of the same name in the FluxAggregator // constructor. func setupFluxAggregatorUniverse(t *testing.T, configOptions ...func(cfg *fluxAggregatorUniverseConfig)) fluxAggregatorUniverse { - testutils.SkipShort(t, "VRFCoordinatorV2Universe") + tests.SkipShort(t, "VRFCoordinatorV2Universe") cfg := &fluxAggregatorUniverseConfig{ MinSubmission: big.NewInt(0), MaxSubmission: big.NewInt(100000000000), diff --git a/core/services/ocr2/plugins/ocr2keeper/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/integration_test.go index 66112756370..2283559365c 100644 --- a/core/services/ocr2/plugins/ocr2keeper/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/integration_test.go @@ -29,6 +29,8 @@ import ( "github.com/smartcontractkit/chainlink-automation/pkg/v2/config" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + evmtypes "github.com/smartcontractkit/chainlink/v2/core/chains/evm/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -200,7 +202,7 @@ func getUpkeepIDFromTx(t *testing.T, registry *keeper_registry_wrapper2_0.Keeper } func TestIntegration_KeeperPluginBasic(t *testing.T) { - testutils.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/AUTO-11072") + tests.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/AUTO-11072") runKeeperPluginBasic(t) } diff --git a/core/services/pg/connection.go b/core/services/pg/connection.go index 64a137762fc..bf3663e82ce 100644 --- a/core/services/pg/connection.go +++ b/core/services/pg/connection.go @@ -19,7 +19,7 @@ import ( "go.opentelemetry.io/otel" semconv "go.opentelemetry.io/otel/semconv/v1.4.0" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" ) // NOTE: This is the default level in Postgres anyway, we just make it @@ -51,7 +51,7 @@ type ConnectionConfig interface { MaxIdleConns() int } -func NewConnection(ctx context.Context, uri string, dialect dialects.DialectName, config ConnectionConfig) (*sqlx.DB, error) { +func NewConnection(ctx context.Context, uri string, dialect pgcommon.DialectName, config ConnectionConfig) (*sqlx.DB, error) { opts := []otelsql.Option{otelsql.WithAttributes(semconv.DBSystemPostgreSQL), otelsql.WithTracerProvider(otel.GetTracerProvider()), otelsql.WithSQLCommenter(true), @@ -70,7 +70,7 @@ func NewConnection(ctx context.Context, uri string, dialect dialects.DialectName lockTimeout, idleInTxSessionTimeout, defaultIsolation.String()) var sqldb *sql.DB - if dialect == dialects.TransactionWrappedPostgres { + if dialect == pgcommon.TransactionWrappedPostgres { // Dbtx uses the uri as a unique identifier for each transaction. Each ORM // should be encapsulated in it's own transaction, and thus needs its own // unique id. @@ -78,7 +78,11 @@ func NewConnection(ctx context.Context, uri string, dialect dialects.DialectName // We can happily throw away the original uri here because if we are using // txdb it should have already been set at the point where we called // txdb.Register - var err error + + err := pgcommon.RegisterTxDb(uri) + if err != nil { + return nil, fmt.Errorf("failed to register txdb: %w", err) + } sqldb, err = otelsql.Open(string(dialect), uuid.New().String(), opts...) if err != nil { return nil, fmt.Errorf("failed to open txdb: %w", err) diff --git a/core/services/pg/connection_test.go b/core/services/pg/connection_test.go index c4314bfb309..3ae70d14637 100644 --- a/core/services/pg/connection_test.go +++ b/core/services/pg/connection_test.go @@ -4,15 +4,13 @@ import ( "testing" "time" - "github.com/google/uuid" _ "github.com/jackc/pgx/v4/stdlib" - "github.com/jmoiron/sqlx" "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/pgtest" ) var _ Getter = &mockGetter{} @@ -67,11 +65,9 @@ func Test_checkVersion(t *testing.T) { func Test_disallowReplica(t *testing.T) { testutils.SkipShortDB(t) - db, err := sqlx.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String()) - require.NoError(t, err) - t.Cleanup(func() { require.NoError(t, db.Close()) }) + db := pgtest.NewSqlxDB(t) - _, err = db.Exec("SET session_replication_role= 'origin'") + _, err := db.Exec("SET session_replication_role= 'origin'") require.NoError(t, err) err = disallowReplica(db) require.NoError(t, err) diff --git a/core/services/pg/locked_db.go b/core/services/pg/locked_db.go index 14ddb2317a5..baea01b43a5 100644 --- a/core/services/pg/locked_db.go +++ b/core/services/pg/locked_db.go @@ -11,10 +11,11 @@ import ( "github.com/jmoiron/sqlx" "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" + "github.com/smartcontractkit/chainlink/v2/core/config" "github.com/smartcontractkit/chainlink/v2/core/logger" "github.com/smartcontractkit/chainlink/v2/core/static" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" ) // LockedDB bounds DB connection and DB locks. @@ -28,7 +29,7 @@ type LockedDBConfig interface { ConnectionConfig URL() url.URL DefaultQueryTimeout() time.Duration - Dialect() dialects.DialectName + Dialect() pg.DialectName } type lockedDb struct { diff --git a/core/services/relay/evm/chain_components_test.go b/core/services/relay/evm/chain_components_test.go index 39b8a35bbf6..1e8c47c51ec 100644 --- a/core/services/relay/evm/chain_components_test.go +++ b/core/services/relay/evm/chain_components_test.go @@ -27,6 +27,7 @@ import ( commontestutils "github.com/smartcontractkit/chainlink-common/pkg/loop/testutils" clcommontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/types/interfacetests" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" htMocks "github.com/smartcontractkit/chainlink/v2/common/headtracker/mocks" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -227,7 +228,7 @@ func TestChainReader_HealthReport(t *testing.T) { } func TestChainComponents(t *testing.T) { - testutils.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/BCFR-1083") + tests.SkipFlakey(t, "https://smartcontract-it.atlassian.net/browse/BCFR-1083") t.Parallel() it := &EVMChainComponentsInterfaceTester[*testing.T]{Helper: &helper{}} // TODO, generated binding tests are broken diff --git a/core/services/relay/evm/statuschecker/txm_status_checker_test.go b/core/services/relay/evm/statuschecker/txm_status_checker_test.go index 456d07e7a7d..7a682d708e2 100644 --- a/core/services/relay/evm/statuschecker/txm_status_checker_test.go +++ b/core/services/relay/evm/statuschecker/txm_status_checker_test.go @@ -10,12 +10,13 @@ import ( "github.com/stretchr/testify/mock" "github.com/smartcontractkit/chainlink-common/pkg/types" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/txmgr/mocks" - "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" ) func Test_CheckMessageStatus(t *testing.T) { - testutils.SkipShort(t, "") + tests.SkipShort(t, "") ctx := context.Background() mockTxManager := mocks.NewMockEvmTxManager(t) checker := NewTxmStatusChecker(mockTxManager.GetTransactionStatus) diff --git a/core/services/vrf/v2/integration_v2_plus_test.go b/core/services/vrf/v2/integration_v2_plus_test.go index 75cffe1057c..d1cc030043d 100644 --- a/core/services/vrf/v2/integration_v2_plus_test.go +++ b/core/services/vrf/v2/integration_v2_plus_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/require" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/config/toml" @@ -66,7 +67,7 @@ type coordinatorV2PlusUniverse struct { } func newVRFCoordinatorV2PlusUniverse(t *testing.T, key ethkey.KeyV2, numConsumers int, trusting bool) coordinatorV2PlusUniverse { - testutils.SkipShort(t, "VRFCoordinatorV2Universe") + tests.SkipShort(t, "VRFCoordinatorV2Universe") oracleTransactor, err := bind.NewKeyedTransactorWithChainID(key.ToEcdsaPrivKey(), testutils.SimulatedChainID) require.NoError(t, err) var ( diff --git a/core/services/vrf/v2/integration_v2_test.go b/core/services/vrf/v2/integration_v2_test.go index d9086a52a33..6cbcc799e1b 100644 --- a/core/services/vrf/v2/integration_v2_test.go +++ b/core/services/vrf/v2/integration_v2_test.go @@ -31,6 +31,8 @@ import ( commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" commonconfig "github.com/smartcontractkit/chainlink-common/pkg/config" "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" + "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + txmgrcommon "github.com/smartcontractkit/chainlink/v2/common/txmgr" txmgrtypes "github.com/smartcontractkit/chainlink/v2/common/txmgr/types" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" @@ -145,7 +147,7 @@ func makeTestTxm(t *testing.T, txStore txmgr.TestEvmTxStore, keyStore keystore.M } func newVRFCoordinatorV2Universe(t *testing.T, key ethkey.KeyV2, numConsumers int) coordinatorV2Universe { - testutils.SkipShort(t, "VRFCoordinatorV2Universe") + tests.SkipShort(t, "VRFCoordinatorV2Universe") oracleTransactor, err := bind.NewKeyedTransactorWithChainID(key.ToEcdsaPrivKey(), testutils.SimulatedChainID) require.NoError(t, err) var ( diff --git a/core/store/dialects/dialects.go b/core/store/dialects/dialects.go deleted file mode 100644 index d250fa1b99b..00000000000 --- a/core/store/dialects/dialects.go +++ /dev/null @@ -1,18 +0,0 @@ -package dialects - -import ( - // need to make sure pgx driver is registered before opening connection - _ "github.com/jackc/pgx/v4/stdlib" -) - -// DialectName is a compiler enforced type used that maps to database dialect names -type DialectName string - -const ( - // Postgres represents the postgres dialect. - Postgres DialectName = "pgx" - // TransactionWrappedPostgres is useful for tests. - // When the connection is opened, it starts a transaction and all - // operations performed on the DB will be within that transaction. - TransactionWrappedPostgres DialectName = "txdb" -) diff --git a/core/utils/testutils/heavyweight/orm.go b/core/utils/testutils/heavyweight/orm.go index 536515e02e4..775eabab0c8 100644 --- a/core/utils/testutils/heavyweight/orm.go +++ b/core/utils/testutils/heavyweight/orm.go @@ -14,12 +14,13 @@ import ( "github.com/jmoiron/sqlx" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" "github.com/smartcontractkit/chainlink/v2/core/internal/testutils/configtest" "github.com/smartcontractkit/chainlink/v2/core/services/chainlink" "github.com/smartcontractkit/chainlink/v2/core/services/pg" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" "github.com/smartcontractkit/chainlink/v2/core/store/models" "github.com/smartcontractkit/chainlink/v2/internal/testdb" ) @@ -53,10 +54,10 @@ const ( ) func (c Kind) PrepareDB(t testing.TB, overrideFn func(c *chainlink.Config, s *chainlink.Secrets)) (chainlink.GeneralConfig, *sqlx.DB) { - testutils.SkipShort(t, "FullTestDB") + tests.SkipShort(t, "FullTestDB") gcfg := configtest.NewGeneralConfigSimulated(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.Database.Dialect = dialects.Postgres + c.Database.Dialect = pgcommon.Postgres if overrideFn != nil { overrideFn(c, s) } @@ -65,7 +66,7 @@ func (c Kind) PrepareDB(t testing.TB, overrideFn func(c *chainlink.Config, s *ch require.NoError(t, os.MkdirAll(gcfg.RootDir(), 0700)) migrationTestDBURL, err := testdb.CreateOrReplace(gcfg.Database().URL(), generateName(), c != KindEmpty) require.NoError(t, err) - db, err := pg.NewConnection(tests.Context(t), migrationTestDBURL, dialects.Postgres, gcfg.Database()) + db, err := pg.NewConnection(tests.Context(t), migrationTestDBURL, pgcommon.Postgres, gcfg.Database()) require.NoError(t, err) t.Cleanup(func() { require.NoError(t, db.Close()) // must close before dropping @@ -74,7 +75,7 @@ func (c Kind) PrepareDB(t testing.TB, overrideFn func(c *chainlink.Config, s *ch }) gcfg = configtest.NewGeneralConfigSimulated(t, func(c *chainlink.Config, s *chainlink.Secrets) { - c.Database.Dialect = dialects.Postgres + c.Database.Dialect = pgcommon.Postgres s.Database.URL = models.MustSecretURL(migrationTestDBURL) if overrideFn != nil { overrideFn(c, s) diff --git a/deployment/go.mod b/deployment/go.mod index ffc691b9aca..a2bf8ec65d9 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -29,7 +29,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 @@ -82,7 +82,7 @@ require ( github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect github.com/alexflint/go-arg v1.4.2 // indirect github.com/alexflint/go-scalar v1.0.0 // indirect - github.com/andybalholm/brotli v1.1.0 // indirect + github.com/andybalholm/brotli v1.1.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/atombender/go-jsonschema v0.16.1-0.20240916205339-a74cd4e2851c // indirect @@ -223,7 +223,7 @@ require ( github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-yaml v1.12.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -315,8 +315,8 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect diff --git a/deployment/go.sum b/deployment/go.sum index 2b8c3819d86..96dd2ed14e8 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -184,9 +184,11 @@ github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2uc github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= +github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow-go/v18 v18.0.0 h1:1dBDaSbH3LtulTyOVYaBCHO3yVRwjV+TZaqn3g6V7ZM= +github.com/apache/arrow-go/v18 v18.0.0/go.mod h1:t6+cWRSmKgdQ6HsxisQjok+jBpKGhRDiqcf3p0p/F+A= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q= github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -638,8 +640,8 @@ github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -707,6 +709,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI= +github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -1032,11 +1036,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= @@ -1091,6 +1095,8 @@ github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYt github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= +github.com/marcboeker/go-duckdb v1.8.3 h1:ZkYwiIZhbYsT6MmJsZ3UPTHrTZccDdM4ztoqSlEMXiQ= +github.com/marcboeker/go-duckdb v1.8.3/go.mod h1:C9bYRE1dPYb1hhfu/SSomm78B0FXmNgRvv6YBW/Hooc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1262,8 +1268,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= -github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= -github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -1411,8 +1417,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1589,6 +1595,8 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= +github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1600,6 +1608,8 @@ github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= diff --git a/go.mod b/go.mod index 31cb8241f0c..40d62c74e34 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/NethermindEth/juno v0.3.1 github.com/NethermindEth/starknet.go v0.7.1-0.20240401080518-34a506f3cfdb github.com/XSAM/otelsql v0.27.0 - github.com/andybalholm/brotli v1.1.0 + github.com/andybalholm/brotli v1.1.1 github.com/avast/retry-go/v4 v4.6.0 github.com/btcsuite/btcd/btcec/v2 v2.3.4 github.com/cometbft/cometbft v0.37.5 @@ -79,7 +79,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db github.com/smartcontractkit/chainlink-feeds v0.1.1 @@ -148,6 +148,7 @@ require ( github.com/Masterminds/goutils v1.1.1 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/VictoriaMetrics/fastcache v1.12.2 // indirect + github.com/apache/arrow-go/v18 v18.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/atombender/go-jsonschema v0.16.1-0.20240916205339-a74cd4e2851c // indirect github.com/bahlo/generic-list-go v0.2.0 // indirect @@ -219,7 +220,7 @@ require ( github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.22.0 // indirect github.com/go-webauthn/x v0.1.5 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-yaml v1.12.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -232,6 +233,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/google/btree v1.1.2 // indirect + github.com/google/flatbuffers v24.3.25+incompatible // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-tpm v0.9.0 // indirect github.com/google/gofuzz v1.2.0 // indirect @@ -269,8 +271,8 @@ require ( github.com/jackpal/go-nat-pmp v1.0.2 // indirect github.com/jmhodges/levigo v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.5 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/leodido/go-urn v1.4.0 // indirect @@ -279,6 +281,7 @@ require ( github.com/logrusorgru/aurora v2.0.3+incompatible // indirect github.com/magiconair/properties v1.8.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect + github.com/marcboeker/go-duckdb v1.8.3 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.14 // indirect @@ -302,6 +305,7 @@ require ( github.com/opencontainers/runc v1.1.10 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 // indirect + github.com/pierrec/lz4/v4 v4.1.21 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect github.com/prometheus/procfs v0.15.1 // indirect @@ -343,6 +347,7 @@ require ( github.com/x448/float16 v0.8.4 // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/yusufpapurcu/wmi v1.2.4 // indirect + github.com/zeebo/xxh3 v1.0.2 // indirect github.com/zondax/hid v0.9.2 // indirect github.com/zondax/ledger-go v0.14.3 // indirect go.dedis.ch/protobuf v1.0.11 // indirect diff --git a/go.sum b/go.sum index b6d85bea0ba..81ae439a469 100644 --- a/go.sum +++ b/go.sum @@ -144,9 +144,13 @@ github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax github.com/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= +github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow-go/v18 v18.0.0 h1:1dBDaSbH3LtulTyOVYaBCHO3yVRwjV+TZaqn3g6V7ZM= +github.com/apache/arrow-go/v18 v18.0.0/go.mod h1:t6+cWRSmKgdQ6HsxisQjok+jBpKGhRDiqcf3p0p/F+A= +github.com/apache/thrift v0.21.0 h1:tdPmh/ptjE1IJnhbhrcl2++TauVjy242rkV/UzJChnE= +github.com/apache/thrift v0.21.0/go.mod h1:W1H8aR/QRtYNvrPeFXBtobyRkd0/YVhTc6i07XIAgDw= github.com/appleboy/gofight/v2 v2.1.2 h1:VOy3jow4vIK8BRQJoC/I9muxyYlJ2yb9ht2hZoS3rf4= github.com/appleboy/gofight/v2 v2.1.2/go.mod h1:frW+U1QZEdDgixycTj4CygQ48yLTUhplt43+Wczp3rw= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= @@ -484,8 +488,8 @@ github.com/go-webauthn/webauthn v0.9.4/go.mod h1:LqupCtzSef38FcxzaklmOn7AykGKhAh github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -550,6 +554,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI= +github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -814,14 +820,16 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/asmfmt v1.3.2 h1:4Ri7ox3EwapiOjCki+hw14RyKk201CN4rzyCJRFLpK4= +github.com/klauspost/asmfmt v1.3.2/go.mod h1:AG8TuvYojzulgDAMCnYn50l/5QV3Bs/tp6j0HLHbNSE= github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= -github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= @@ -868,6 +876,8 @@ github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYt github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= +github.com/marcboeker/go-duckdb v1.8.3 h1:ZkYwiIZhbYsT6MmJsZ3UPTHrTZccDdM4ztoqSlEMXiQ= +github.com/marcboeker/go-duckdb v1.8.3/go.mod h1:C9bYRE1dPYb1hhfu/SSomm78B0FXmNgRvv6YBW/Hooc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -900,6 +910,10 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0 h1:QRUSJEgZn2Snx0EmT/QLXibWjSUDjKWvXIT19NBVp94= github.com/mimoo/StrobeGo v0.0.0-20210601165009-122bf33a46e0/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= +github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 h1:+n/aFZefKZp7spd8DFdX7uMikMLXX4oubIzJF4kv/wI= +github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3/go.mod h1:RagcQ7I8IeTMnF8JTXieKnO4Z6JCsikNEzj0DwauVzE= github.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g= github.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= @@ -1002,6 +1016,8 @@ github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xl github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -1125,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1280,6 +1296,8 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= +github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= +github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1289,6 +1307,10 @@ github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ= +github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 0c746729f4d..2d14d4de774 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -47,7 +47,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19 @@ -105,7 +105,7 @@ require ( github.com/VictoriaMetrics/fastcache v1.12.2 // indirect github.com/XSAM/otelsql v0.27.0 // indirect github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect - github.com/andybalholm/brotli v1.1.0 // indirect + github.com/andybalholm/brotli v1.1.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/atombender/go-jsonschema v0.16.1-0.20240916205339-a74cd4e2851c // indirect @@ -245,7 +245,7 @@ require ( github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-yaml v1.12.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -337,8 +337,8 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 2c6a13a07de..23de4725234 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -180,9 +180,11 @@ github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2uc github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= +github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow-go/v18 v18.0.0 h1:1dBDaSbH3LtulTyOVYaBCHO3yVRwjV+TZaqn3g6V7ZM= +github.com/apache/arrow-go/v18 v18.0.0/go.mod h1:t6+cWRSmKgdQ6HsxisQjok+jBpKGhRDiqcf3p0p/F+A= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -642,8 +644,8 @@ github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -711,6 +713,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI= +github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -1039,11 +1043,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= @@ -1100,6 +1104,8 @@ github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYt github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= +github.com/marcboeker/go-duckdb v1.8.3 h1:ZkYwiIZhbYsT6MmJsZ3UPTHrTZccDdM4ztoqSlEMXiQ= +github.com/marcboeker/go-duckdb v1.8.3/go.mod h1:C9bYRE1dPYb1hhfu/SSomm78B0FXmNgRvv6YBW/Hooc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1279,8 +1285,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= -github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= -github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -1432,8 +1438,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1614,6 +1620,8 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= +github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1625,6 +1633,8 @@ github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 131d3451ed0..7502484079f 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -27,7 +27,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.15.0 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.2 @@ -72,7 +72,7 @@ require ( github.com/VictoriaMetrics/fastcache v1.12.2 // indirect github.com/XSAM/otelsql v0.27.0 // indirect github.com/alecthomas/units v0.0.0-20240626203959-61d1e3462e30 // indirect - github.com/andybalholm/brotli v1.1.0 // indirect + github.com/andybalholm/brotli v1.1.1 // indirect github.com/armon/go-metrics v0.4.1 // indirect github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/atombender/go-jsonschema v0.16.1-0.20240916205339-a74cd4e2851c // indirect @@ -216,7 +216,7 @@ require ( github.com/go-viper/mapstructure/v2 v2.1.0 // indirect github.com/go-webauthn/webauthn v0.9.4 // indirect github.com/go-webauthn/x v0.1.5 // indirect - github.com/goccy/go-json v0.10.2 // indirect + github.com/goccy/go-json v0.10.3 // indirect github.com/goccy/go-yaml v1.12.0 // indirect github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 // indirect github.com/gofrs/flock v0.8.1 // indirect @@ -312,8 +312,8 @@ require ( github.com/json-iterator/go v1.1.12 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.17.9 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/compress v1.17.11 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index bcb4c488482..884f61bf87e 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -184,9 +184,11 @@ github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2uc github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= -github.com/andybalholm/brotli v1.1.0 h1:eLKJA0d02Lf0mVpIDgYnqXcUn0GqVmEFny3VuID1U3M= -github.com/andybalholm/brotli v1.1.0/go.mod h1:sms7XGricyQI9K10gOSf56VKKWS4oLer58Q+mhRPtnY= +github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA= +github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/arrow-go/v18 v18.0.0 h1:1dBDaSbH3LtulTyOVYaBCHO3yVRwjV+TZaqn3g6V7ZM= +github.com/apache/arrow-go/v18 v18.0.0/go.mod h1:t6+cWRSmKgdQ6HsxisQjok+jBpKGhRDiqcf3p0p/F+A= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -636,8 +638,8 @@ github.com/go-webauthn/x v0.1.5 h1:V2TCzDU2TGLd0kSZOXdrqDVV5JB9ILnKxA9S53CSBw0= github.com/go-webauthn/x v0.1.5/go.mod h1:qbzWwcFcv4rTwtCLOZd+icnr6B7oSsAGZJqlt8cukqY= github.com/go-zookeeper/zk v1.0.3 h1:7M2kwOsc//9VeeFiPtf+uSJlVpU66x9Ba5+8XK7/TDg= github.com/go-zookeeper/zk v1.0.3/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= -github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= -github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-yaml v1.12.0 h1:/1WHjnMsI1dlIBQutrvSMGZRQufVO3asrHfTwfACoPM= github.com/goccy/go-yaml v1.12.0/go.mod h1:wKnAMd44+9JAAnGQpWVEgBzGt3YuTaQ4uXoHvE4m7WU= github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+Hoeu/iUR3ruzNvZ+yQfO03a0= @@ -705,6 +707,8 @@ github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Z github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= +github.com/google/flatbuffers v24.3.25+incompatible h1:CX395cjN9Kke9mmalRoL3d81AtFUxJM+yDthflgJGkI= +github.com/google/flatbuffers v24.3.25+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49 h1:0VpGH+cDhbDtdcweoyCVsF3fhN8kejK6rFe/2FFX2nU= github.com/google/gnostic-models v0.6.9-0.20230804172637-c7be7c783f49/go.mod h1:BkkQ4L1KS1xMt2aWSPStnn55ChGC0DPOn2FQYj+f25M= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -1035,11 +1039,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.11.4/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= -github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b h1:udzkj9S/zlT5X367kqJis0QP7YMxobob6zhzq6Yre00= github.com/kolo/xmlrpc v0.0.0-20220921171641-a4b6fa1dd06b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= @@ -1094,6 +1098,8 @@ github.com/manifoldco/promptui v0.9.0 h1:3V4HzJk1TtXW1MTZMP7mdlwbBpIinw3HztaIlYt github.com/manifoldco/promptui v0.9.0/go.mod h1:ka04sppxSGFAtxX0qhlYQjISsg9mR4GWtQEhdbn6Pgg= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f h1:tVvGiZQFjOXP+9YyGqSA6jE55x1XVxmoPYudncxrZ8U= github.com/manyminds/api2go v0.0.0-20171030193247-e7b693844a6f/go.mod h1:Z60vy0EZVSu0bOugCHdcN5ZxFMKSpjRgsnh0XKPFqqk= +github.com/marcboeker/go-duckdb v1.8.3 h1:ZkYwiIZhbYsT6MmJsZ3UPTHrTZccDdM4ztoqSlEMXiQ= +github.com/marcboeker/go-duckdb v1.8.3/go.mod h1:C9bYRE1dPYb1hhfu/SSomm78B0FXmNgRvv6YBW/Hooc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1269,8 +1275,8 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/petermattis/goid v0.0.0-20180202154549-b0b1615b78e5/go.mod h1:jvVRKCrJTQWu0XVbaOlby/2lO20uSCHEMzzplHXte1o= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08 h1:hDSdbBuw3Lefr6R18ax0tZ2BJeNB3NehB3trOwYBsdU= github.com/petermattis/goid v0.0.0-20230317030725-371a4b8eda08/go.mod h1:pxMtw7cyUw6B2bRH0ZBANSPg+AoSud1I1iyJHI69jH4= -github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= -github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.21 h1:yOVMLb6qSIDP67pl/5F7RepeKYu/VmTyEXvuMI5d9mQ= +github.com/pierrec/lz4/v4 v4.1.21/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= @@ -1423,8 +1429,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49 h1:ZA92CTX9JtEArrxgZw7PNctVxFS+/DmSXumkwf1WiMY= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241212163958-6a43e61b9d49/go.mod h1:bQktEJf7sJ0U3SmIcXvbGUox7SmXcnSEZ4kUbT8R5Nk= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= @@ -1605,6 +1611,8 @@ github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4= github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBiLI6FVj/9LpzZWtj1/D6lUovWYBkxHVV3aM= +github.com/xyproto/randomstring v1.0.5 h1:YtlWPoRdgMu3NZtP45drfy1GKoojuR7hmRcnhZqKjWU= +github.com/xyproto/randomstring v1.0.5/go.mod h1:rgmS5DeNXLivK7YprL0pY+lTuhNQW3iGxZ18UQApw/E= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -1616,6 +1624,8 @@ github.com/yuin/gopher-lua v1.1.0 h1:BojcDhfyDWgU2f2TOzYK/g5p2gxMrku8oupLDqlnSqE github.com/yuin/gopher-lua v1.1.0/go.mod h1:GBR0iDaNXjAgGg9zfCvksxSRnQx76gclCIb7kdAd1Pw= github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0= github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= +github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= diff --git a/integration-tests/utils/pgtest/pgtest.go b/integration-tests/utils/pgtest/pgtest.go index 8b11f9ef424..3baccc791b6 100644 --- a/integration-tests/utils/pgtest/pgtest.go +++ b/integration-tests/utils/pgtest/pgtest.go @@ -3,33 +3,18 @@ package pgtest import ( "testing" - "github.com/google/uuid" "github.com/jmoiron/sqlx" - "github.com/scylladb/go-reflectx" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "github.com/smartcontractkit/chainlink-common/pkg/sqlutil" - "github.com/smartcontractkit/chainlink-common/pkg/utils" - "github.com/smartcontractkit/chainlink-common/pkg/utils/tests" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" + "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" + + "github.com/smartcontractkit/chainlink/v2/core/config/env" ) func NewSqlxDB(t testing.TB) *sqlx.DB { - db, err := sqlx.Open(string(dialects.TransactionWrappedPostgres), uuid.New().String()) - require.NoError(t, err) - t.Cleanup(func() { assert.NoError(t, db.Close()) }) - db.MapperFunc(reflectx.CamelToSnakeASCII) - - return db -} - -func MustExec(t *testing.T, ds sqlutil.DataSource, stmt string, args ...interface{}) { - ctx := tests.Context(t) - require.NoError(t, utils.JustError(ds.ExecContext(ctx, stmt, args...))) -} - -func MustCount(t *testing.T, db *sqlx.DB, stmt string, args ...interface{}) (cnt int) { - require.NoError(t, db.Get(&cnt, stmt, args...)) - return + dbURL := string(env.DatabaseURL.Get()) + if dbURL == "" { + t.Errorf("you must provide a CL_DATABASE_URL environment variable") + return nil + } + return pg.NewTestDB(t, dbURL) } diff --git a/integration-tests/utils/pgtest/txdb.go b/integration-tests/utils/pgtest/txdb.go deleted file mode 100644 index f28b6f95f2b..00000000000 --- a/integration-tests/utils/pgtest/txdb.go +++ /dev/null @@ -1,510 +0,0 @@ -package pgtest - -import ( - "context" - "database/sql" - "database/sql/driver" - "flag" - "fmt" - "io" - "net/url" - "strings" - "sync" - "testing" - - "github.com/jmoiron/sqlx" - "go.uber.org/multierr" - - "github.com/smartcontractkit/chainlink/v2/core/config/env" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" -) - -// txdb is a simplified version of https://github.com/DATA-DOG/go-txdb -// -// The original lib has various problems and is hard to understand because it -// tries to be more general. The version in this file is more tightly focused -// to our needs and should be easier to reason about and less likely to have -// subtle bugs/races. -// -// It doesn't currently support savepoints but could be made to if necessary. -// -// Transaction BEGIN/ROLLBACK effectively becomes a no-op, this should have no -// negative impact on normal test operation. -// -// If you MUST test BEGIN/ROLLBACK behaviour, you will have to configure your -// store to use the raw DialectPostgres dialect and setup a one-use database. -// See heavyweight.FullTestDB() as a convenience function to help you do this, -// but please use sparingly because as it's name implies, it is expensive. -func init() { - testing.Init() - if !flag.Parsed() { - flag.Parse() - } - if testing.Short() { - // -short tests don't need a DB - return - } - dbURL := string(env.DatabaseURL.Get()) - if dbURL == "" { - panic("you must provide a CL_DATABASE_URL environment variable") - } - - parsed, err := url.Parse(dbURL) - if err != nil { - panic(err) - } - if parsed.Path == "" { - msg := fmt.Sprintf("invalid %[1]s: `%[2]s`. You must set %[1]s env var to point to your test database. Note that the test database MUST end in `_test` to differentiate from a possible production DB. HINT: Try %[1]s=postgresql://postgres@localhost:5432/chainlink_test?sslmode=disable", env.DatabaseURL, parsed.String()) - panic(msg) - } - if !strings.HasSuffix(parsed.Path, "_test") { - msg := fmt.Sprintf("cannot run tests against database named `%s`. Note that the test database MUST end in `_test` to differentiate from a possible production DB. HINT: Try %s=postgresql://postgres@localhost:5432/chainlink_test?sslmode=disable", parsed.Path[1:], env.DatabaseURL) - panic(msg) - } - name := string(dialects.TransactionWrappedPostgres) - sql.Register(name, &txDriver{ - dbURL: dbURL, - conns: make(map[string]*conn), - }) - sqlx.BindDriver(name, sqlx.DOLLAR) -} - -var _ driver.Conn = &conn{} - -var _ driver.Validator = &conn{} -var _ driver.SessionResetter = &conn{} - -// txDriver is an sql driver which runs on a single transaction. -// When `Close` is called, transaction is rolled back. -type txDriver struct { - sync.Mutex - db *sql.DB - conns map[string]*conn - - dbURL string -} - -func (d *txDriver) Open(dsn string) (driver.Conn, error) { - d.Lock() - defer d.Unlock() - // Open real db connection if its the first call - if d.db == nil { - db, err := sql.Open(string(dialects.Postgres), d.dbURL) - if err != nil { - return nil, err - } - d.db = db - } - c, exists := d.conns[dsn] - if !exists || !c.tryOpen() { - tx, err := d.db.Begin() - if err != nil { - return nil, err - } - c = &conn{tx: tx, opened: 1, dsn: dsn} - c.removeSelf = func() error { - return d.deleteConn(c) - } - d.conns[dsn] = c - } - return c, nil -} - -// deleteConn is called by a connection when it is closed via the `close` method. -// It also auto-closes the DB when the last checked out connection is closed. -func (d *txDriver) deleteConn(c *conn) error { - // must lock here to avoid racing with Open - d.Lock() - defer d.Unlock() - - if d.conns[c.dsn] != c { - return nil // already been replaced - } - delete(d.conns, c.dsn) - if len(d.conns) == 0 && d.db != nil { - if err := d.db.Close(); err != nil { - return err - } - d.db = nil - } - return nil -} - -type conn struct { - sync.Mutex - dsn string - tx *sql.Tx // tx may be shared by many conns, definitive one lives in the map keyed by DSN on the txDriver. Do not modify from conn - closed bool - opened int - removeSelf func() error -} - -func (c *conn) Begin() (driver.Tx, error) { - c.Lock() - defer c.Unlock() - if c.closed { - panic("conn is closed") - } - // Begin is a noop because the transaction was already opened - return tx{c.tx}, nil -} - -// Implement the "ConnBeginTx" interface -func (c *conn) BeginTx(_ context.Context, opts driver.TxOptions) (driver.Tx, error) { - // Context is ignored, because single transaction is shared by all callers, thus caller should not be able to - // control it with local context - return c.Begin() -} - -// Prepare returns a prepared statement, bound to this connection. -func (c *conn) Prepare(query string) (driver.Stmt, error) { - return c.PrepareContext(context.Background(), query) -} - -// Implement the "ConnPrepareContext" interface -func (c *conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error) { - c.Lock() - defer c.Unlock() - if c.closed { - panic("conn is closed") - } - - // TODO: Fix context handling - // FIXME: It is not safe to give the passed in context to the tx directly - // because the tx is shared by many conns and cancelling the context will - // destroy the tx which can affect other conns - st, err := c.tx.PrepareContext(context.Background(), query) - if err != nil { - return nil, err - } - return &stmt{st, c}, nil -} - -// IsValid is called prior to placing the connection into the -// connection pool by database/sql. The connection will be discarded if false is returned. -func (c *conn) IsValid() bool { - c.Lock() - defer c.Unlock() - return !c.closed -} - -func (c *conn) ResetSession(ctx context.Context) error { - // Ensure bad connections are reported: From database/sql/driver: - // If a connection is never returned to the connection pool but immediately reused, then - // ResetSession is called prior to reuse but IsValid is not called. - c.Lock() - defer c.Unlock() - if c.closed { - return driver.ErrBadConn - } - - return nil -} - -// pgx returns nil -func (c *conn) CheckNamedValue(nv *driver.NamedValue) error { - return nil -} - -// Implement the "QueryerContext" interface -func (c *conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { - c.Lock() - defer c.Unlock() - if c.closed { - panic("conn is closed") - } - - // TODO: Fix context handling - rs, err := c.tx.QueryContext(context.Background(), query, mapNamedArgs(args)...) - if err != nil { - return nil, err - } - defer rs.Close() - - return buildRows(rs) -} - -// Implement the "ExecerContext" interface -func (c *conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { - c.Lock() - defer c.Unlock() - if c.closed { - panic("conn is closed") - } - // TODO: Fix context handling - return c.tx.ExecContext(context.Background(), query, mapNamedArgs(args)...) -} - -// tryOpen attempts to increment the open count, but returns false if closed. -func (c *conn) tryOpen() bool { - c.Lock() - defer c.Unlock() - if c.closed { - return false - } - c.opened++ - return true -} - -// Close invalidates and potentially stops any current -// prepared statements and transactions, marking this -// connection as no longer in use. -// -// Because the sql package maintains a free pool of -// connections and only calls Close when there's a surplus of -// idle connections, it shouldn't be necessary for drivers to -// do their own connection caching. -// -// Drivers must ensure all network calls made by Close -// do not block indefinitely (e.g. apply a timeout). -func (c *conn) Close() (err error) { - if !c.close() { - return - } - // Wait to remove self to avoid nesting locks. - if err := c.removeSelf(); err != nil { - panic(err) - } - return -} - -//nolint:revive -func (c *conn) close() bool { - c.Lock() - defer c.Unlock() - if c.closed { - // Double close, should be a safe to make this a noop - // PGX allows double close - // See: https://github.com/jackc/pgx/blob/a457da8bffa4f90ad672fa093ee87f20cf06687b/conn.go#L249 - return false - } - - c.opened-- - if c.opened > 0 { - return false - } - if c.tx != nil { - if err := c.tx.Rollback(); err != nil { - panic(err) - } - c.tx = nil - } - c.closed = true - return true -} - -type tx struct { - tx *sql.Tx -} - -func (tx tx) Commit() error { - // Commit is a noop because the transaction will be rolled back at the end - return nil -} - -func (tx tx) Rollback() error { - // Rollback is a noop because the transaction will be rolled back at the end - return nil -} - -type stmt struct { - st *sql.Stmt - conn *conn -} - -func (s stmt) Exec(args []driver.Value) (driver.Result, error) { - s.conn.Lock() - defer s.conn.Unlock() - if s.conn.closed { - panic("conn is closed") - } - return s.st.Exec(mapArgs(args)...) -} - -// Implement the "StmtExecContext" interface -func (s *stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error) { - s.conn.Lock() - defer s.conn.Unlock() - if s.conn.closed { - panic("conn is closed") - } - // TODO: Fix context handling - return s.st.ExecContext(context.Background(), mapNamedArgs(args)...) -} - -func mapArgs(args []driver.Value) (res []interface{}) { - res = make([]interface{}, len(args)) - for i := range args { - res[i] = args[i] - } - return -} - -func (s stmt) NumInput() int { - return -1 -} - -func (s stmt) Query(args []driver.Value) (driver.Rows, error) { - s.conn.Lock() - defer s.conn.Unlock() - if s.conn.closed { - panic("conn is closed") - } - rows, err := s.st.Query(mapArgs(args)...) - defer func() { - err = multierr.Combine(err, rows.Close()) - }() - if err != nil { - return nil, err - } - return buildRows(rows) -} - -// Implement the "StmtQueryContext" interface -func (s *stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error) { - s.conn.Lock() - defer s.conn.Unlock() - if s.conn.closed { - panic("conn is closed") - } - // TODO: Fix context handling - rows, err := s.st.QueryContext(context.Background(), mapNamedArgs(args)...) - if err != nil { - return nil, err - } - return buildRows(rows) -} - -func (s stmt) Close() error { - s.conn.Lock() - defer s.conn.Unlock() - return s.st.Close() -} - -func buildRows(r *sql.Rows) (driver.Rows, error) { - set := &rowSets{} - rs := &rows{} - if err := rs.read(r); err != nil { - return set, err - } - set.sets = append(set.sets, rs) - for r.NextResultSet() { - rss := &rows{} - if err := rss.read(r); err != nil { - return set, err - } - set.sets = append(set.sets, rss) - } - return set, nil -} - -// Implement the "RowsNextResultSet" interface -func (rs *rowSets) HasNextResultSet() bool { - return rs.pos+1 < len(rs.sets) -} - -// Implement the "RowsNextResultSet" interface -func (rs *rowSets) NextResultSet() error { - if !rs.HasNextResultSet() { - return io.EOF - } - - rs.pos++ - return nil -} - -type rows struct { - rows [][]driver.Value - pos int - cols []string - colTypes []*sql.ColumnType -} - -func (r *rows) Columns() []string { - return r.cols -} - -func (r *rows) ColumnTypeDatabaseTypeName(index int) string { - return r.colTypes[index].DatabaseTypeName() -} - -func (r *rows) Next(dest []driver.Value) error { - r.pos++ - if r.pos > len(r.rows) { - return io.EOF - } - - for i, val := range r.rows[r.pos-1] { - dest[i] = *(val.(*interface{})) - } - - return nil -} - -func (r *rows) Close() error { - return nil -} - -func (r *rows) read(rs *sql.Rows) error { - var err error - r.cols, err = rs.Columns() - if err != nil { - return err - } - - r.colTypes, err = rs.ColumnTypes() - if err != nil { - return err - } - - for rs.Next() { - values := make([]interface{}, len(r.cols)) - for i := range values { - values[i] = new(interface{}) - } - if err := rs.Scan(values...); err != nil { - return err - } - row := make([]driver.Value, len(r.cols)) - for i, v := range values { - row[i] = driver.Value(v) - } - r.rows = append(r.rows, row) - } - return rs.Err() -} - -type rowSets struct { - sets []*rows - pos int -} - -func (rs *rowSets) Columns() []string { - return rs.sets[rs.pos].cols -} - -func (rs *rowSets) ColumnTypeDatabaseTypeName(index int) string { - return rs.sets[rs.pos].ColumnTypeDatabaseTypeName(index) -} - -func (rs *rowSets) Close() error { - return nil -} - -// advances to next row -func (rs *rowSets) Next(dest []driver.Value) error { - return rs.sets[rs.pos].Next(dest) -} - -func mapNamedArgs(args []driver.NamedValue) (res []interface{}) { - res = make([]interface{}, len(args)) - for i := range args { - name := args[i].Name - if name != "" { - res[i] = sql.Named(name, args[i].Value) - } else { - res[i] = args[i].Value - } - } - return -} diff --git a/internal/testdb/testdb.go b/internal/testdb/testdb.go index 88251ae2c6f..1a52b1173e3 100644 --- a/internal/testdb/testdb.go +++ b/internal/testdb/testdb.go @@ -7,7 +7,7 @@ import ( "net/url" "strings" - "github.com/smartcontractkit/chainlink/v2/core/store/dialects" + pgcommon "github.com/smartcontractkit/chainlink-common/pkg/sqlutil/pg" ) const ( @@ -33,7 +33,7 @@ func CreateOrReplace(parsed url.URL, suffix string, withTemplate bool) (string, // Cannot drop test database if we are connected to it, so we must connect // to a different one. 'postgres' should be present on all postgres installations parsed.Path = "/postgres" - db, err := sql.Open(string(dialects.Postgres), parsed.String()) + db, err := sql.Open(string(pgcommon.Postgres), parsed.String()) if err != nil { return "", fmt.Errorf("in order to drop the test database, we need to connect to a separate database"+ " called 'postgres'. But we are unable to open 'postgres' database: %+v\n", err) @@ -66,7 +66,7 @@ func Drop(dbURL url.URL) error { // Cannot drop test database if we are connected to it, so we must connect // to a different one. 'postgres' should be present on all postgres installations dbURL.Path = "/postgres" - db, err := sql.Open(string(dialects.Postgres), dbURL.String()) + db, err := sql.Open(string(pgcommon.Postgres), dbURL.String()) if err != nil { return fmt.Errorf("in order to drop the test database, we need to connect to a separate database"+ " called 'postgres'. But we are unable to open 'postgres' database: %+v\n", err) From b1c33952aa6ee552511a9bdc0d950151d838f9a5 Mon Sep 17 00:00:00 2001 From: Gabriel Paradiso Date: Mon, 16 Dec 2024 11:45:50 +0100 Subject: [PATCH 24/29] fix: add compute hashed capability id and change f to 1 (#15687) --- .../src/05_deploy_initialize_capabilities_registry.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go b/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go index 166022ac753..86dbfa0c404 100644 --- a/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go +++ b/core/scripts/keystone/src/05_deploy_initialize_capabilities_registry.go @@ -294,7 +294,7 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) { panic(innerErr) } - n.HashedCapabilityIds = [][32]byte{ocrid, ctid} + n.HashedCapabilityIds = [][32]byte{ocrid, ctid, aid} nodes = append(nodes, n) } @@ -337,7 +337,7 @@ func (c *deployAndInitializeCapabilitiesRegistryCommand) Run(args []string) { Config: ccfgb, }, } - _, err = reg.AddDON(env.Owner, ps, cfgs, true, true, 2) + _, err = reg.AddDON(env.Owner, ps, cfgs, true, true, 1) if err != nil { log.Printf("workflowDON: failed to AddDON: %s", err) } From 0fb9d70735e1e3d46e482cd52238b3862a663a90 Mon Sep 17 00:00:00 2001 From: Justin Kaseman Date: Mon, 16 Dec 2024 03:39:44 -0800 Subject: [PATCH 25/29] Capability Encoder changes to use PreCodec (#15538) * Draft: Capability Encoder changes to use PreCodec * (refactor): Changes for config changing from codecFactory -> codecs * Bump chainlink-common * Soothe linter --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +- core/services/relay/evm/cap_encoder.go | 58 ++++++++++++++++- core/services/relay/evm/cap_encoder_test.go | 72 +++++++++++++++++++++ deployment/go.mod | 2 +- deployment/go.sum | 4 +- go.mod | 2 +- go.sum | 4 +- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- 12 files changed, 142 insertions(+), 18 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 11dfa7c26ee..7d6dd5c6993 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -33,7 +33,7 @@ require ( github.com/prometheus/client_golang v1.20.5 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chainlink-automation v0.8.1 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 959cac27d8f..6e4972e8666 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1150,8 +1150,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 h1:Pz8jB/6qe10xT10h2S3LFYJrnebNpG5rJ/w16HZGwPQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= diff --git a/core/services/relay/evm/cap_encoder.go b/core/services/relay/evm/cap_encoder.go index 2a6f288a5de..713a9796dd2 100644 --- a/core/services/relay/evm/cap_encoder.go +++ b/core/services/relay/evm/cap_encoder.go @@ -8,6 +8,7 @@ import ( "fmt" consensustypes "github.com/smartcontractkit/chainlink-common/pkg/capabilities/consensus/ocr3/types" + commoncodec "github.com/smartcontractkit/chainlink-common/pkg/codec" commontypes "github.com/smartcontractkit/chainlink-common/pkg/types" "github.com/smartcontractkit/chainlink-common/pkg/values" @@ -17,8 +18,9 @@ import ( ) const ( - abiConfigFieldName = "abi" - encoderName = "user" + abiConfigFieldName = "abi" + subabiConfigFieldName = "subabi" + encoderName = "user" ) type capEncoder struct { @@ -46,9 +48,33 @@ func NewEVMEncoder(config *values.Map) (consensustypes.Encoder, error) { return nil, err } + chainCodecConfig := types.ChainCodecConfig{ + TypeABI: string(jsonSelector), + } + + var subabi map[string]string + subabiConfig, ok := config.Underlying[subabiConfigFieldName] + if ok { + err2 := subabiConfig.UnwrapTo(&subabi) + if err2 != nil { + return nil, err2 + } + codecs, err2 := makePreCodecModifierCodecs(subabi) + if err2 != nil { + return nil, err2 + } + chainCodecConfig.ModifierConfigs = commoncodec.ModifiersConfig{ + &commoncodec.PreCodecModifierConfig{ + Fields: subabi, + Codecs: codecs, + }, + } + } + codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ - encoderName: {TypeABI: string(jsonSelector)}, + encoderName: chainCodecConfig, }} + c, err := codec.NewCodec(codecConfig) if err != nil { return nil, err @@ -57,6 +83,32 @@ func NewEVMEncoder(config *values.Map) (consensustypes.Encoder, error) { return &capEncoder{codec: c}, nil } +func makePreCodecModifierCodecs(subabi map[string]string) (map[string]commontypes.RemoteCodec, error) { + codecs := map[string]commontypes.RemoteCodec{} + for _, abi := range subabi { + selector, err := abiutil.ParseSelector("inner(" + abi + ")") + if err != nil { + return nil, err + } + jsonSelector, err := json.Marshal(selector.Inputs) + if err != nil { + return nil, err + } + emptyName := "" + codecConfig := types.CodecConfig{Configs: map[string]types.ChainCodecConfig{ + emptyName: { + TypeABI: string(jsonSelector), + }, + }} + codec, err := codec.NewCodec(codecConfig) + if err != nil { + return nil, err + } + codecs[abi] = codec + } + return codecs, nil +} + func (c *capEncoder) Encode(ctx context.Context, input values.Map) ([]byte, error) { unwrappedInput, err := input.Unwrap() if err != nil { diff --git a/core/services/relay/evm/cap_encoder_test.go b/core/services/relay/evm/cap_encoder_test.go index d290a7fd2b0..4c0285fc987 100644 --- a/core/services/relay/evm/cap_encoder_test.go +++ b/core/services/relay/evm/cap_encoder_test.go @@ -217,6 +217,78 @@ func TestEVMEncoder_InvalidIDs(t *testing.T) { assert.ErrorContains(t, err, "incorrect length for id") } +func TestEVMEncoder_SubABI(t *testing.T) { + config := map[string]any{ + "abi": "(bytes32 FeedID, bytes Bundle, uint32 Timestamp)[] Reports", + "subabi": map[string]string{ + "Reports.Bundle": "uint256 Ask, uint256 Bid", + }, + } + wrapped, err := values.NewMap(config) + require.NoError(t, err) + enc, err := evm.NewEVMEncoder(wrapped) + require.NoError(t, err) + + type SubReport struct { + Ask int + Bid int + } + type ReportStruct struct { + FeedID [32]byte + Bundle SubReport + Timestamp uint32 + } + reportOne := ReportStruct{ + FeedID: [32]byte{1}, + Bundle: SubReport{ + Ask: 5, + Bid: 6, + }, + Timestamp: 47890122, + } + reportTwo := ReportStruct{ + FeedID: [32]byte{2}, + Bundle: SubReport{ + Ask: 7, + Bid: 8, + }, + Timestamp: 47890122, + } + + // output of a reduce aggregator + metadata fields appended by OCR + input := map[string]any{ + "Reports": []any{reportOne, reportTwo}, + consensustypes.MetadataFieldName: getMetadata(workflowID), + } + wrapped, err = values.NewMap(input) + require.NoError(t, err) + encoded, err := enc.Encode(testutils.Context(t), *wrapped) + require.NoError(t, err) + + expected := + // start of the outer tuple + getHexMetadata() + + // start of the inner tuple (user_fields) + "0000000000000000000000000000000000000000000000000000000000000020" + // offset of Reports array + "0000000000000000000000000000000000000000000000000000000000000002" + // length of Reports array + "0000000000000000000000000000000000000000000000000000000000000040" + // offset of ReportOne + "0000000000000000000000000000000000000000000000000000000000000100" + // offset of ReportTwo + "0100000000000000000000000000000000000000000000000000000000000000" + // ReportOne FeedID + "0000000000000000000000000000000000000000000000000000000000000060" + // offset of ReportOne Bundle + "0000000000000000000000000000000000000000000000000000000002dabeca" + // ReportOne Timestamp + "0000000000000000000000000000000000000000000000000000000000000040" + // length of ReportOne Bundle + "0000000000000000000000000000000000000000000000000000000000000005" + // ReportOne Ask + "0000000000000000000000000000000000000000000000000000000000000006" + // ReportOne Bid + "0200000000000000000000000000000000000000000000000000000000000000" + // ReportTwo FeedID + "0000000000000000000000000000000000000000000000000000000000000060" + // offset of ReportTwo Bundle + "0000000000000000000000000000000000000000000000000000000002dabeca" + // ReportTwo Timestamp + "0000000000000000000000000000000000000000000000000000000000000040" + // length of ReportTwo Bundle + "0000000000000000000000000000000000000000000000000000000000000007" + // ReportTwo Ask + "0000000000000000000000000000000000000000000000000000000000000008" // ReportTwo Bid + + require.Equal(t, expected, hex.EncodeToString(encoded)) +} + func getHexMetadata() string { return "01" + executionID + timestampHex + donIDHex + configVersionHex + workflowID + workflowName + workflowOwnerID + reportID } diff --git a/deployment/go.mod b/deployment/go.mod index a2bf8ec65d9..09fb2ef67e4 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -29,7 +29,7 @@ require ( github.com/smartcontractkit/ccip-owner-contracts v0.0.0-salt-fix github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 diff --git a/deployment/go.sum b/deployment/go.sum index 96dd2ed14e8..2a96b466d27 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1417,8 +1417,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 h1:Pz8jB/6qe10xT10h2S3LFYJrnebNpG5rJ/w16HZGwPQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= diff --git a/go.mod b/go.mod index 40d62c74e34..00e6d46bef5 100644 --- a/go.mod +++ b/go.mod @@ -79,7 +79,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db github.com/smartcontractkit/chainlink-feeds v0.1.1 diff --git a/go.sum b/go.sum index 81ae439a469..5ef70da78db 100644 --- a/go.sum +++ b/go.sum @@ -1141,8 +1141,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 h1:Pz8jB/6qe10xT10h2S3LFYJrnebNpG5rJ/w16HZGwPQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 2d14d4de774..0ae31eb6634 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -47,7 +47,7 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.34 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 23de4725234..47e69ccca40 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1438,8 +1438,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 h1:Pz8jB/6qe10xT10h2S3LFYJrnebNpG5rJ/w16HZGwPQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 7502484079f..c46d2325462 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -27,7 +27,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/rs/zerolog v1.33.0 github.com/slack-go/slack v0.15.0 - github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd + github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.19 github.com/smartcontractkit/chainlink-testing-framework/seth v1.50.9 github.com/smartcontractkit/chainlink-testing-framework/wasp v1.50.2 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 884f61bf87e..4b3cdc4b6a1 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1429,8 +1429,8 @@ github.com/smartcontractkit/chainlink-automation v0.8.1 h1:sTc9LKpBvcKPc1JDYAmgB github.com/smartcontractkit/chainlink-automation v0.8.1/go.mod h1:Iij36PvWZ6blrdC5A/nrQUBuf3MH3JvsBB9sSyc9W08= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b h1:iSQJ6ng4FhEswf8SXunGkaJlVP3E3JlgLB8Oo2f3Ud4= github.com/smartcontractkit/chainlink-ccip v0.0.0-20241213122413-5e8f65dd6b1b/go.mod h1:F8xQAIW0ymb2BZhqn89sWZLXreJhM5KDVF6Qb4y44N0= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd h1:lbq/4m6g1OjtBXSu4Tg3qFwu5zlWeUUu1INQOxDlNxA= -github.com/smartcontractkit/chainlink-common v0.3.1-0.20241213210522-edc5deed9ffd/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805 h1:Pz8jB/6qe10xT10h2S3LFYJrnebNpG5rJ/w16HZGwPQ= +github.com/smartcontractkit/chainlink-common v0.3.1-0.20241214155818-b403079b2805/go.mod h1:yti7e1+G9hhkYhj+L5sVUULn9Bn3bBL5/AxaNqdJ5YQ= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e h1:PRoeby6ZlTuTkv2f+7tVU4+zboTfRzI+beECynF4JQ0= github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e/go.mod h1:mUh5/woemsVaHgTorA080hrYmO3syBCmPdnWc/5dOqk= github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db h1:N1RH1hSr2ACzOFc9hkCcjE8pRBTdcU3p8nsTJByaLes= From 056ad00a8400b368992c608520fb09deb331c6a1 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 16 Dec 2024 06:38:49 -0600 Subject: [PATCH 26/29] bump github.com/gin-contrib/cors v1.7.2 (#15679) --- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- deployment/go.sum | 4 ++-- go.mod | 9 +++++---- go.sum | 22 ++++++++++------------ integration-tests/go.sum | 4 ++-- integration-tests/load/go.sum | 4 ++-- 7 files changed, 24 insertions(+), 25 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 7d6dd5c6993..bc0ac26c66c 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -144,7 +144,7 @@ require ( github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect - github.com/gin-contrib/cors v1.5.0 // indirect + github.com/gin-contrib/cors v1.7.2 // indirect github.com/gin-contrib/expvar v0.0.1 // indirect github.com/gin-contrib/sessions v0.0.5 // indirect github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 6e4972e8666..5a2b74762de 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -414,8 +414,8 @@ github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9y github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= -github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= +github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw= +github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E= github.com/gin-contrib/expvar v0.0.1 h1:IuU5ArEgihz50vG8Onrwz22kJr7Mcvgv9xSSpfU5g+w= github.com/gin-contrib/expvar v0.0.1/go.mod h1:8o2CznfQi1JjktORdHr2/abg3wSV6OCnXh0yGypvvVw= github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE= diff --git a/deployment/go.sum b/deployment/go.sum index 2a96b466d27..acf20814b99 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -550,8 +550,8 @@ github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9y github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= -github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= +github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw= +github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E= github.com/gin-contrib/expvar v0.0.1 h1:IuU5ArEgihz50vG8Onrwz22kJr7Mcvgv9xSSpfU5g+w= github.com/gin-contrib/expvar v0.0.1/go.mod h1:8o2CznfQi1JjktORdHr2/abg3wSV6OCnXh0yGypvvVw= github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE= diff --git a/go.mod b/go.mod index 00e6d46bef5..b62da71eb60 100644 --- a/go.mod +++ b/go.mod @@ -25,7 +25,7 @@ require ( github.com/fxamacker/cbor/v2 v2.7.0 github.com/gagliardetto/solana-go v1.8.4 github.com/getsentry/sentry-go v0.27.0 - github.com/gin-contrib/cors v1.5.0 + github.com/gin-contrib/cors v1.7.2 github.com/gin-contrib/expvar v0.0.1 github.com/gin-contrib/sessions v0.0.5 github.com/gin-contrib/size v0.0.0-20230212012657-e14a14094dc4 @@ -159,13 +159,14 @@ require ( github.com/blendle/zapdriver v1.3.1 // indirect github.com/buger/jsonparser v1.1.1 // indirect github.com/bytecodealliance/wasmtime-go/v23 v23.0.0 // indirect - github.com/bytedance/sonic v1.10.1 // indirect + github.com/bytedance/sonic v1.11.6 // indirect + github.com/bytedance/sonic/loader v0.1.1 // indirect github.com/cenkalti/backoff v2.2.1+incompatible // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash v1.1.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect - github.com/chenzhuoyu/iasm v0.9.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect github.com/cockroachdb/errors v1.11.3 // indirect github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect diff --git a/go.sum b/go.sum index 5ef70da78db..a5cf80cb784 100644 --- a/go.sum +++ b/go.sum @@ -200,10 +200,10 @@ github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMU github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= github.com/bytecodealliance/wasmtime-go/v23 v23.0.0 h1:NJvU4S8KEk1GnF6+FvlnzMD/8wXTj/mYJSG6Q4yu3Pw= github.com/bytecodealliance/wasmtime-go/v23 v23.0.0/go.mod h1:5YIL+Ouiww2zpO7u+iZ1U1G5NvmwQYaXdmCZQGjQM0U= -github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= -github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM= -github.com/bytedance/sonic v1.10.1 h1:7a1wuFXL1cMy7a3f7/VFcEtriuXQnUBhtoVfOZiaysc= -github.com/bytedance/sonic v1.10.1/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4= +github.com/bytedance/sonic v1.11.6 h1:oUp34TzMlL+OY1OUWxHqsdkgC/Zfc85zGqw9siXjrc0= +github.com/bytedance/sonic v1.11.6/go.mod h1:LysEHSvpvDySVdC2f87zGWf6CIKJcAvqab1ZaiQtds4= +github.com/bytedance/sonic/loader v0.1.1 h1:c+e5Pt1k/cy5wMveRDyk2X4B9hF4g7an8N3zCYjJFNM= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= @@ -219,12 +219,6 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= -github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0= -github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA= -github.com/chenzhuoyu/iasm v0.9.0 h1:9fhXjVzq5hUy2gkhhgHl95zG2cEAhw9OSGs8toWWAwo= -github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/readline v1.5.1 h1:upd/6fQk4src78LMRzh5vItIt361/o4uq553V8B5sGI= @@ -233,6 +227,10 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -415,8 +413,8 @@ github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9y github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= -github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= +github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw= +github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E= github.com/gin-contrib/expvar v0.0.1 h1:IuU5ArEgihz50vG8Onrwz22kJr7Mcvgv9xSSpfU5g+w= github.com/gin-contrib/expvar v0.0.1/go.mod h1:8o2CznfQi1JjktORdHr2/abg3wSV6OCnXh0yGypvvVw= github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE= diff --git a/integration-tests/go.sum b/integration-tests/go.sum index 47e69ccca40..ccbe8f342c7 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -552,8 +552,8 @@ github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9y github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= -github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= +github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw= +github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E= github.com/gin-contrib/expvar v0.0.1 h1:IuU5ArEgihz50vG8Onrwz22kJr7Mcvgv9xSSpfU5g+w= github.com/gin-contrib/expvar v0.0.1/go.mod h1:8o2CznfQi1JjktORdHr2/abg3wSV6OCnXh0yGypvvVw= github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE= diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 4b3cdc4b6a1..6f15e93cc8c 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -546,8 +546,8 @@ github.com/gedex/inflector v0.0.0-20170307190818-16278e9db813/go.mod h1:P+oSoE9y github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/cors v1.5.0 h1:DgGKV7DDoOn36DFkNtbHrjoRiT5ExCe+PC9/xp7aKvk= -github.com/gin-contrib/cors v1.5.0/go.mod h1:TvU7MAZ3EwrPLI2ztzTt3tqgvBCq+wn8WpZmfADjupI= +github.com/gin-contrib/cors v1.7.2 h1:oLDHxdg8W/XDoN/8zamqk/Drgt4oVZDvaV0YmvVICQw= +github.com/gin-contrib/cors v1.7.2/go.mod h1:SUJVARKgQ40dmrzgXEVxj2m7Ig1v1qIboQkPDTQ9t2E= github.com/gin-contrib/expvar v0.0.1 h1:IuU5ArEgihz50vG8Onrwz22kJr7Mcvgv9xSSpfU5g+w= github.com/gin-contrib/expvar v0.0.1/go.mod h1:8o2CznfQi1JjktORdHr2/abg3wSV6OCnXh0yGypvvVw= github.com/gin-contrib/sessions v0.0.5 h1:CATtfHmLMQrMNpJRgzjWXD7worTh7g7ritsQfmF+0jE= From 46ac6c997d4680f3847de07cfb79aec6c4e2ed81 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Mon, 16 Dec 2024 06:41:29 -0600 Subject: [PATCH 27/29] bump golang.org/x/crypto@v0.31.0 (#15701) --- core/scripts/go.mod | 10 +++++----- core/scripts/go.sum | 20 ++++++++++---------- deployment/go.mod | 10 +++++----- deployment/go.sum | 20 ++++++++++---------- go.mod | 10 +++++----- go.sum | 20 ++++++++++---------- integration-tests/go.mod | 10 +++++----- integration-tests/go.sum | 20 ++++++++++---------- integration-tests/load/go.mod | 10 +++++----- integration-tests/load/go.sum | 20 ++++++++++---------- 10 files changed, 75 insertions(+), 75 deletions(-) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index bc0ac26c66c..0631a34eb4e 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -380,15 +380,15 @@ require ( go.uber.org/ratelimit v0.3.1 // indirect go.uber.org/zap v1.27.0 // indirect golang.org/x/arch v0.11.0 // indirect - golang.org/x/crypto v0.28.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/term v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 5a2b74762de..80a2c28ea83 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1459,8 +1459,8 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1584,8 +1584,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1668,8 +1668,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1678,8 +1678,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1693,8 +1693,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/deployment/go.mod b/deployment/go.mod index 09fb2ef67e4..cb7405790d2 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -40,7 +40,7 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c golang.org/x/oauth2 v0.23.0 - golang.org/x/sync v0.8.0 + golang.org/x/sync v0.10.0 google.golang.org/grpc v1.67.1 google.golang.org/protobuf v1.35.1 gopkg.in/guregu/null.v4 v4.0.0 @@ -492,12 +492,12 @@ require ( go.uber.org/ratelimit v0.3.1 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.11.0 // indirect - golang.org/x/crypto v0.28.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/term v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect diff --git a/deployment/go.sum b/deployment/go.sum index acf20814b99..5386b30596e 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1756,8 +1756,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1887,8 +1887,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1982,8 +1982,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1994,8 +1994,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2010,8 +2010,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/go.mod b/go.mod index b62da71eb60..219fa7d5d59 100644 --- a/go.mod +++ b/go.mod @@ -110,12 +110,12 @@ require ( go.opentelemetry.io/otel/trace v1.31.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.28.0 + golang.org/x/crypto v0.31.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c golang.org/x/mod v0.21.0 - golang.org/x/sync v0.8.0 - golang.org/x/term v0.25.0 - golang.org/x/text v0.19.0 + golang.org/x/sync v0.10.0 + golang.org/x/term v0.27.0 + golang.org/x/text v0.21.0 golang.org/x/time v0.7.0 golang.org/x/tools v0.26.0 gonum.org/v1/gonum v0.15.1 @@ -375,7 +375,7 @@ require ( go.uber.org/ratelimit v0.3.1 // indirect golang.org/x/arch v0.11.0 // indirect golang.org/x/net v0.30.0 // indirect - golang.org/x/sys v0.26.0 // indirect + golang.org/x/sys v0.28.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect google.golang.org/api v0.202.0 // indirect google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 // indirect diff --git a/go.sum b/go.sum index a5cf80cb784..d9844648227 100644 --- a/go.sum +++ b/go.sum @@ -1445,8 +1445,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1571,8 +1571,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1656,8 +1656,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1667,8 +1667,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1683,8 +1683,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 0ae31eb6634..b6f6feb01aa 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -64,10 +64,10 @@ require ( go.uber.org/atomic v1.11.0 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.28.0 + golang.org/x/crypto v0.31.0 golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c - golang.org/x/sync v0.8.0 - golang.org/x/text v0.19.0 + golang.org/x/sync v0.10.0 + golang.org/x/text v0.21.0 google.golang.org/grpc v1.67.1 gopkg.in/guregu/null.v4 v4.0.0 k8s.io/apimachinery v0.31.2 @@ -509,8 +509,8 @@ require ( golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/term v0.25.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index ccbe8f342c7..e70ce5342c3 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1782,8 +1782,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1913,8 +1913,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -2010,8 +2010,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2022,8 +2022,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2038,8 +2038,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index c46d2325462..86539e78748 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -499,14 +499,14 @@ require ( go.uber.org/zap v1.27.0 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/arch v0.11.0 // indirect - golang.org/x/crypto v0.28.0 // indirect + golang.org/x/crypto v0.31.0 // indirect golang.org/x/mod v0.21.0 // indirect golang.org/x/net v0.30.0 // indirect golang.org/x/oauth2 v0.23.0 // indirect - golang.org/x/sync v0.8.0 // indirect - golang.org/x/sys v0.26.0 // indirect - golang.org/x/term v0.25.0 // indirect - golang.org/x/text v0.19.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/term v0.27.0 // indirect + golang.org/x/text v0.21.0 // indirect golang.org/x/time v0.7.0 // indirect golang.org/x/tools v0.26.0 // indirect golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 6f15e93cc8c..53afd04a0e6 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1773,8 +1773,8 @@ golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/crypto v0.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= -golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -1904,8 +1904,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= -golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1999,8 +1999,8 @@ golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= -golang.org/x/sys v0.26.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -2011,8 +2011,8 @@ golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= -golang.org/x/term v0.25.0 h1:WtHI/ltw4NvSUig5KARz9h521QvRC8RmF/cuYqifU24= -golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -2027,8 +2027,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= -golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 329e8f02fdd4becd333878991a4463423082aaba Mon Sep 17 00:00:00 2001 From: Graham Goh Date: Tue, 17 Dec 2024 00:05:54 +1100 Subject: [PATCH 28/29] feat(job-distributor): support tron chain type on sync (#15699) Able to sync TRON chain type from core node to JD JIRA: https://smartcontract-it.atlassian.net/browse/DPA-1332 --- .changeset/brave-cooks-itch.md | 5 +++++ core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 ++-- core/services/feeds/models.go | 4 ++++ core/services/feeds/models_test.go | 5 +++++ deployment/go.mod | 2 +- deployment/go.sum | 4 ++-- go.mod | 2 +- go.sum | 4 ++-- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 ++-- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 ++-- 13 files changed, 29 insertions(+), 15 deletions(-) create mode 100644 .changeset/brave-cooks-itch.md diff --git a/.changeset/brave-cooks-itch.md b/.changeset/brave-cooks-itch.md new file mode 100644 index 00000000000..1ed3dd7e117 --- /dev/null +++ b/.changeset/brave-cooks-itch.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#updated feat(job-distributor): support tron chain type on sync diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 0631a34eb4e..bbc233803c3 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -308,7 +308,7 @@ require ( github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 // indirect - github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 // indirect + github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib v1.50.13 // indirect diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 80a2c28ea83..ab7950ea73a 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1160,8 +1160,8 @@ github.com/smartcontractkit/chainlink-feeds v0.1.1 h1:JzvUOM/OgGQA1sOqTXXl52R6An github.com/smartcontractkit/chainlink-feeds v0.1.1/go.mod h1:55EZ94HlKCfAsUiKUTNI7QlE/3d3IwTlsU3YNa/nBb4= github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 h1:0ewLMbAz3rZrovdRUCgd028yOXX8KigB4FndAUdI2kM= github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 h1:ZBat8EBvE2LpSQR9U1gEbRV6PfAkiFdINmQ8nVnXIAQ= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= diff --git a/core/services/feeds/models.go b/core/services/feeds/models.go index 93dddd86dae..a6cf103b4e9 100644 --- a/core/services/feeds/models.go +++ b/core/services/feeds/models.go @@ -12,6 +12,7 @@ import ( "gopkg.in/guregu/null.v4" proto "github.com/smartcontractkit/chainlink-protos/orchestrator/feedsmanager" + "github.com/smartcontractkit/chainlink/v2/core/utils/crypto" ) @@ -82,6 +83,7 @@ const ( ChainTypeEVM ChainType = "EVM" ChainTypeSolana ChainType = "SOLANA" ChainTypeStarknet ChainType = "STARKNET" + ChainTypeTron ChainType = "TRON" ) func NewChainType(s string) (ChainType, error) { @@ -94,6 +96,8 @@ func NewChainType(s string) (ChainType, error) { return ChainTypeSolana, nil case "APTOS": return ChainTypeAptos, nil + case "TRON": + return ChainTypeTron, nil default: return ChainTypeUnknown, errors.New("invalid chain type") } diff --git a/core/services/feeds/models_test.go b/core/services/feeds/models_test.go index 13567281735..d0d4382b055 100644 --- a/core/services/feeds/models_test.go +++ b/core/services/feeds/models_test.go @@ -28,6 +28,11 @@ func Test_NewChainType(t *testing.T) { give: "STARKNET", want: ChainTypeStarknet, }, + { + name: "Tron Chain Type", + give: "TRON", + want: ChainTypeTron, + }, { name: "Invalid Chain Type", give: "", diff --git a/deployment/go.mod b/deployment/go.mod index cb7405790d2..5551034d579 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -409,7 +409,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect - github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 // indirect + github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 // indirect github.com/smartcontractkit/chainlink-testing-framework/lib/grafana v1.50.0 // indirect diff --git a/deployment/go.sum b/deployment/go.sum index 5386b30596e..66170b80629 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1427,8 +1427,8 @@ github.com/smartcontractkit/chainlink-feeds v0.1.1 h1:JzvUOM/OgGQA1sOqTXXl52R6An github.com/smartcontractkit/chainlink-feeds v0.1.1/go.mod h1:55EZ94HlKCfAsUiKUTNI7QlE/3d3IwTlsU3YNa/nBb4= github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 h1:0ewLMbAz3rZrovdRUCgd028yOXX8KigB4FndAUdI2kM= github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 h1:ZBat8EBvE2LpSQR9U1gEbRV6PfAkiFdINmQ8nVnXIAQ= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= diff --git a/go.mod b/go.mod index 219fa7d5d59..7dcbbfd631b 100644 --- a/go.mod +++ b/go.mod @@ -83,7 +83,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db github.com/smartcontractkit/chainlink-feeds v0.1.1 - github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 + github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 github.com/smartcontractkit/libocr v0.0.0-20241007185508-adbe57025f12 diff --git a/go.sum b/go.sum index d9844648227..bc6352c2ee0 100644 --- a/go.sum +++ b/go.sum @@ -1147,8 +1147,8 @@ github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db/go.mod h1:yjb9d4q7+m8aGbjfTbkNoNuA4PeSxcUszsSZHDrvS0E= github.com/smartcontractkit/chainlink-feeds v0.1.1 h1:JzvUOM/OgGQA1sOqTXXl52R6AnNt+Wg64sVG+XSA49c= github.com/smartcontractkit/chainlink-feeds v0.1.1/go.mod h1:55EZ94HlKCfAsUiKUTNI7QlE/3d3IwTlsU3YNa/nBb4= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 h1:ZBat8EBvE2LpSQR9U1gEbRV6PfAkiFdINmQ8nVnXIAQ= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index b6f6feb01aa..a29d07dec21 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -427,7 +427,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect - github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 // indirect + github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 // indirect github.com/smartcontractkit/grpc-proxy v0.0.0-20240830132753-a7e17fec5ab7 // indirect diff --git a/integration-tests/go.sum b/integration-tests/go.sum index e70ce5342c3..633e8e9b691 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1448,8 +1448,8 @@ github.com/smartcontractkit/chainlink-feeds v0.1.1 h1:JzvUOM/OgGQA1sOqTXXl52R6An github.com/smartcontractkit/chainlink-feeds v0.1.1/go.mod h1:55EZ94HlKCfAsUiKUTNI7QlE/3d3IwTlsU3YNa/nBb4= github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 h1:0ewLMbAz3rZrovdRUCgd028yOXX8KigB4FndAUdI2kM= github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 h1:ZBat8EBvE2LpSQR9U1gEbRV6PfAkiFdINmQ8nVnXIAQ= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 86539e78748..eb68f0722fb 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -411,7 +411,7 @@ require ( github.com/smartcontractkit/chainlink-cosmos v0.5.2-0.20241202195413-82468150ac1e // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.1-0.20241202141438-a90db35252db // indirect github.com/smartcontractkit/chainlink-feeds v0.1.1 // indirect - github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 // indirect + github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 // indirect github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc // indirect github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 // indirect github.com/smartcontractkit/chainlink-testing-framework/havoc v1.50.2 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 53afd04a0e6..02c9357b14f 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1439,8 +1439,8 @@ github.com/smartcontractkit/chainlink-feeds v0.1.1 h1:JzvUOM/OgGQA1sOqTXXl52R6An github.com/smartcontractkit/chainlink-feeds v0.1.1/go.mod h1:55EZ94HlKCfAsUiKUTNI7QlE/3d3IwTlsU3YNa/nBb4= github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0 h1:0ewLMbAz3rZrovdRUCgd028yOXX8KigB4FndAUdI2kM= github.com/smartcontractkit/chainlink-protos/job-distributor v0.6.0/go.mod h1:/dVVLXrsp+V0AbcYGJo3XMzKg3CkELsweA/TTopCsKE= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2 h1:onBe3DqNrbtOAzKS4PrPIiJX65BGo1aYiYZxFVEW+jc= -github.com/smartcontractkit/chainlink-protos/orchestrator v0.3.2/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0 h1:ZBat8EBvE2LpSQR9U1gEbRV6PfAkiFdINmQ8nVnXIAQ= +github.com/smartcontractkit/chainlink-protos/orchestrator v0.4.0/go.mod h1:m/A3lqD7ms/RsQ9BT5P2uceYY0QX5mIt4KQxT2G6qEo= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc h1:dssRwJhmzJkUN/OajaDj2GsxBn+Tupk3bI1BkPEoJg0= github.com/smartcontractkit/chainlink-solana v1.1.1-0.20241210172617-6fd1891d0fbc/go.mod h1:p8aUDfJeley6oer7y+Ucd3edOtRlMTnWg3mN6rhaLWo= github.com/smartcontractkit/chainlink-starknet/relayer v0.1.1-0.20241202202529-2033490e77b8 h1:tNS7U9lrxkFvEuyxQv11HHOiV9LPDGC9wYEy+yM/Jv4= From b76f9b355741ca07d977809c185a450a0e94c381 Mon Sep 17 00:00:00 2001 From: krehermann <16602512+krehermann@users.noreply.github.com> Date: Mon, 16 Dec 2024 07:23:21 -0700 Subject: [PATCH 29/29] logging, edge case fixes (#15696) --- deployment/common/proposalutils/mcms_helpers.go | 4 +++- deployment/keystone/deploy.go | 4 ++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/deployment/common/proposalutils/mcms_helpers.go b/deployment/common/proposalutils/mcms_helpers.go index 4a7540761ee..51a720a4389 100644 --- a/deployment/common/proposalutils/mcms_helpers.go +++ b/deployment/common/proposalutils/mcms_helpers.go @@ -149,7 +149,9 @@ func RunTimelockExecutor(env deployment.Environment, cfg RunTimelockExecutorConf Value: it.Event.Value, }) } - + if len(calls) == 0 { + return fmt.Errorf("no calls found for chain %d in blocks [%d, %d]", cfg.ChainSelector, *start, *end) + } timelockExecutorProxy, err := owner_helpers.NewRBACTimelock(cfg.TimelockContracts.CallProxy.Address(), env.Chains[cfg.ChainSelector].Client) if err != nil { return fmt.Errorf("error creating timelock executor proxy: %w", err) diff --git a/deployment/keystone/deploy.go b/deployment/keystone/deploy.go index 7d3e5391219..cb7804d0051 100644 --- a/deployment/keystone/deploy.go +++ b/deployment/keystone/deploy.go @@ -483,6 +483,10 @@ func RegisterCapabilities(lggr logger.Logger, req RegisterCapabilitiesRequest) ( for cap := range uniqueCaps { capabilities = append(capabilities, cap) } + if len(capabilities) == 0 { + lggr.Warn("no new capabilities to register") + return &RegisterCapabilitiesResponse{}, nil + } // not using mcms; ignore proposals _, err = AddCapabilities(lggr, &contracts, registryChain, capabilities, false) if err != nil {