diff --git a/core/capabilities/launcher.go b/core/capabilities/launcher.go index 1f15ddd8087..921ca1cf0a1 100644 --- a/core/capabilities/launcher.go +++ b/core/capabilities/launcher.go @@ -501,7 +501,7 @@ func (w *launcher) addRemoteCapability(ctx context.Context, cid string, capabili methodConfig := capabilityConfig.CapabilityMethodConfig if methodConfig != nil { // v2 capability - handle via CombinedClient - errAdd := w.addRemoteCapabilityV2(ctx, capability.ID, methodConfig, myDON, remoteDON) + errAdd := w.addRemoteCapabilityV2(ctx, capability.ID, methodConfig, myDON, remoteDON, localRegistry) if errAdd != nil { return fmt.Errorf("failed to add remote v2 capability %s: %w", capability.ID, errAdd) } @@ -592,7 +592,7 @@ func (w *launcher) addRemoteCapability(ctx context.Context, cid string, capabili w.cachedShims.executableClients[shimKey] = execCap } // V1 capabilities read transmission schedule from every request - if errCfg := execCap.SetConfig(info, myDON.DON, defaultTargetRequestTimeout, nil); errCfg != nil { + if errCfg := execCap.SetConfig(info, myDON.DON, defaultTargetRequestTimeout, nil, nil); errCfg != nil { return nil, fmt.Errorf("failed to set trigger config: %w", errCfg) } return execCap.(capabilityService), nil @@ -618,7 +618,7 @@ func (w *launcher) addRemoteCapability(ctx context.Context, cid string, capabili w.cachedShims.executableClients[shimKey] = execCap } // V1 capabilities read transmission schedule from every request - if errCfg := execCap.SetConfig(info, myDON.DON, defaultTargetRequestTimeout, nil); errCfg != nil { + if errCfg := execCap.SetConfig(info, myDON.DON, defaultTargetRequestTimeout, nil, nil); errCfg != nil { return nil, fmt.Errorf("failed to set trigger config: %w", errCfg) } return execCap.(capabilityService), nil @@ -929,7 +929,7 @@ func signersFor(don registrysyncer.DON, localRegistry *registrysyncer.LocalRegis } // Add a V2 capability with multiple methods, using CombinedClient. -func (w *launcher) addRemoteCapabilityV2(ctx context.Context, capID string, methodConfig map[string]capabilities.CapabilityMethodConfig, myDON registrysyncer.DON, remoteDON registrysyncer.DON) error { +func (w *launcher) addRemoteCapabilityV2(ctx context.Context, capID string, methodConfig map[string]capabilities.CapabilityMethodConfig, myDON registrysyncer.DON, remoteDON registrysyncer.DON, localRegistry *registrysyncer.LocalRegistry) error { info, err := capabilities.NewRemoteCapabilityInfo( capID, capabilities.CapabilityTypeCombined, @@ -984,7 +984,12 @@ func (w *launcher) addRemoteCapabilityV2(ctx context.Context, capID string, meth Schedule: transmission.EnumToString(config.RemoteExecutableConfig.TransmissionSchedule), DeltaStage: config.RemoteExecutableConfig.DeltaStage, } - err := client.SetConfig(info, myDON.DON, config.RemoteExecutableConfig.RequestTimeout, transmissionConfig) + + signers, err := signersFor(remoteDON, localRegistry) + if err != nil { + return fmt.Errorf("failed to get signers for executable client: %w", err) + } + err = client.SetConfig(info, myDON.DON, config.RemoteExecutableConfig.RequestTimeout, transmissionConfig, signers) if err != nil { w.lggr.Errorw("failed to update client config", "capID", capID, "method", method, "error", err) continue diff --git a/core/capabilities/remote/executable/client.go b/core/capabilities/remote/executable/client.go index fe664aa6988..96abdc76eb3 100644 --- a/core/capabilities/remote/executable/client.go +++ b/core/capabilities/remote/executable/client.go @@ -46,12 +46,14 @@ type dynamicConfig struct { requestTimeout time.Duration // Has to be set only for V2 capabilities. V1 capabilities read transmission schedule from every request. transmissionConfig *transmission.TransmissionConfig + // Has to be set only for V2 capabilities using OCR. + signers [][]byte } type Client interface { commoncap.ExecutableCapability Receive(ctx context.Context, msg *types.MessageBody) - SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, requestTimeout time.Duration, transmissionConfig *transmission.TransmissionConfig) error + SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, requestTimeout time.Duration, transmissionConfig *transmission.TransmissionConfig, signers [][]byte) error } var _ Client = &client{} @@ -78,7 +80,7 @@ func NewClient(capabilityID string, capMethodName string, dispatcher types.Dispa // SetConfig sets the remote capability configuration dynamically // TransmissionConfig has to be set only for V2 capabilities. V1 capabilities read transmission schedule from every request. -func (c *client) SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, requestTimeout time.Duration, transmissionConfig *transmission.TransmissionConfig) error { +func (c *client) SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, requestTimeout time.Duration, transmissionConfig *transmission.TransmissionConfig, signers [][]byte) error { if remoteCapabilityInfo.ID == "" || remoteCapabilityInfo.ID != c.capabilityID { return fmt.Errorf("capability info provided does not match the client's capabilityID: %s != %s", remoteCapabilityInfo.ID, c.capabilityID) } @@ -98,6 +100,7 @@ func (c *client) SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localD localDONInfo: localDonInfo, requestTimeout: requestTimeout, transmissionConfig: transmissionConfig, + signers: signers, }) c.lggr.Infow("SetConfig", "remoteDONName", remoteCapabilityInfo.DON.Name, "remoteDONID", remoteCapabilityInfo.DON.ID, "requestTimeout", requestTimeout, "transmissionConfig", transmissionConfig) return nil @@ -234,7 +237,7 @@ func (c *client) Execute(ctx context.Context, capReq commoncap.CapabilityRequest } req, err := request.NewClientExecuteRequest(ctx, c.lggr, capReq, cfg.remoteCapabilityInfo, cfg.localDONInfo, c.dispatcher, - cfg.requestTimeout, cfg.transmissionConfig, c.capMethodName) + cfg.requestTimeout, cfg.transmissionConfig, c.capMethodName, cfg.signers) if err != nil { return commoncap.CapabilityResponse{}, fmt.Errorf("failed to create client request: %w", err) } diff --git a/core/capabilities/remote/executable/client_test.go b/core/capabilities/remote/executable/client_test.go index 93c463f59c1..4d82eb85e57 100644 --- a/core/capabilities/remote/executable/client_test.go +++ b/core/capabilities/remote/executable/client_test.go @@ -243,7 +243,7 @@ func testClient(t *testing.T, numWorkflowPeers int, workflowNodeResponseTimeout for i := range numWorkflowPeers { workflowPeerDispatcher := broker.NewDispatcherForNode(workflowPeers[i]) caller := executable.NewClient(capInfo.ID, "", workflowPeerDispatcher, lggr) - err := caller.SetConfig(capInfo, workflowDonInfo, workflowNodeResponseTimeout, nil) + err := caller.SetConfig(capInfo, workflowDonInfo, workflowNodeResponseTimeout, nil, nil) require.NoError(t, err) servicetest.Run(t, caller) broker.RegisterReceiverNode(workflowPeers[i], caller) @@ -403,7 +403,7 @@ func TestClient_SetConfig(t *testing.T) { DeltaStage: 10 * time.Millisecond, } - err := client.SetConfig(validCapInfo, validDonInfo, validTimeout, transmissionConfig) + err := client.SetConfig(validCapInfo, validDonInfo, validTimeout, transmissionConfig, nil) require.NoError(t, err) // Verify config was set @@ -418,7 +418,7 @@ func TestClient_SetConfig(t *testing.T) { CapabilityType: commoncap.CapabilityTypeAction, } - err := client.SetConfig(invalidCapInfo, validDonInfo, validTimeout, nil) + err := client.SetConfig(invalidCapInfo, validDonInfo, validTimeout, nil, nil) require.Error(t, err) assert.Contains(t, err.Error(), "capability info provided does not match the client's capabilityID") assert.Contains(t, err.Error(), "different_capability@1.0.0 != test_capability@1.0.0") @@ -431,7 +431,7 @@ func TestClient_SetConfig(t *testing.T) { F: 0, } - err := client.SetConfig(validCapInfo, invalidDonInfo, validTimeout, nil) + err := client.SetConfig(validCapInfo, invalidDonInfo, validTimeout, nil, nil) require.Error(t, err) assert.Contains(t, err.Error(), "empty localDonInfo provided") }) @@ -439,7 +439,7 @@ func TestClient_SetConfig(t *testing.T) { t.Run("successful config update", func(t *testing.T) { // Set initial config initialTimeout := 10 * time.Second - err := client.SetConfig(validCapInfo, validDonInfo, initialTimeout, nil) + err := client.SetConfig(validCapInfo, validDonInfo, initialTimeout, nil, nil) require.NoError(t, err) // Replace with new config @@ -450,7 +450,7 @@ func TestClient_SetConfig(t *testing.T) { F: 1, } - err = client.SetConfig(validCapInfo, newDonInfo, newTimeout, nil) + err = client.SetConfig(validCapInfo, newDonInfo, newTimeout, nil, nil) require.NoError(t, err) // Verify the config was completely replaced @@ -494,7 +494,7 @@ func TestClient_SetConfig_StartClose(t *testing.T) { }) t.Run("start succeeds after config set", func(t *testing.T) { - require.NoError(t, client.SetConfig(validCapInfo, validDonInfo, validTimeout, nil)) + require.NoError(t, client.SetConfig(validCapInfo, validDonInfo, validTimeout, nil, nil)) require.NoError(t, client.Start(ctx)) require.NoError(t, client.Close()) }) @@ -504,12 +504,12 @@ func TestClient_SetConfig_StartClose(t *testing.T) { freshClient := executable.NewClient(capabilityID, "execute", dispatcher, lggr) // Set initial config and start - require.NoError(t, freshClient.SetConfig(validCapInfo, validDonInfo, validTimeout, nil)) + require.NoError(t, freshClient.SetConfig(validCapInfo, validDonInfo, validTimeout, nil, nil)) require.NoError(t, freshClient.Start(ctx)) // Update config while running validCapInfo.Description = "new description" - require.NoError(t, freshClient.SetConfig(validCapInfo, validDonInfo, validTimeout, nil)) + require.NoError(t, freshClient.SetConfig(validCapInfo, validDonInfo, validTimeout, nil, nil)) // Verify config was updated info, err := freshClient.Info(ctx) diff --git a/core/capabilities/remote/executable/endtoend_test.go b/core/capabilities/remote/executable/endtoend_test.go index 996c0ca4657..2917df3124b 100644 --- a/core/capabilities/remote/executable/endtoend_test.go +++ b/core/capabilities/remote/executable/endtoend_test.go @@ -309,7 +309,7 @@ func testRemoteExecutableCapability(ctx context.Context, t *testing.T, underlyin for i := range numWorkflowPeers { workflowPeerDispatcher := broker.NewDispatcherForNode(workflowPeers[i]) workflowNode := executable.NewClient(capInfo.ID, "", workflowPeerDispatcher, lggr) - err := workflowNode.SetConfig(capInfo, workflowDonInfo, workflowNodeTimeout, nil) + err := workflowNode.SetConfig(capInfo, workflowDonInfo, workflowNodeTimeout, nil, nil) require.NoError(t, err) servicetest.Run(t, workflowNode) broker.RegisterReceiverNode(workflowPeers[i], workflowNode) diff --git a/core/capabilities/remote/executable/request/client_request.go b/core/capabilities/remote/executable/request/client_request.go index a771be2ad7c..e78bf39b08c 100644 --- a/core/capabilities/remote/executable/request/client_request.go +++ b/core/capabilities/remote/executable/request/client_request.go @@ -14,6 +14,7 @@ import ( ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types" + "github.com/smartcontractkit/chainlink-common/keystore/corekeys/ocr2key" "github.com/smartcontractkit/chainlink-common/pkg/beholder" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" caperrors "github.com/smartcontractkit/chainlink-common/pkg/capabilities/errors" @@ -60,19 +61,23 @@ type clientResponse struct { } type ClientRequest struct { - id string - cancelFn context.CancelFunc - responseCh chan clientResponse - createdAt time.Time - responseIDCount map[[32]byte]int - meteringResponses map[[32]byte][]commoncap.MeteringNodeDetail - errorCount map[string]int - totalErrorCount int - responseReceived map[p2ptypes.PeerID]bool - lggr logger.Logger - - requiredIdenticalResponses int - remoteNodeCount int + id string + cancelFn context.CancelFunc + responseCh chan clientResponse + createdAt time.Time + responseIDCount map[[32]byte]int + meteringResponses map[[32]byte][]commoncap.MeteringNodeDetail + errorCount map[string]int + totalErrorCount int + payloadNotAvailableCount int + responseReceived map[p2ptypes.PeerID]bool + lggr logger.Logger + signers [][]byte + workflowExecutionID string + referenceID string + + requiredResponseConfirmations int + remoteNodeCount int requestTimeout time.Duration @@ -85,6 +90,7 @@ type ClientRequest struct { func NewClientExecuteRequest(ctx context.Context, lggr logger.Logger, req commoncap.CapabilityRequest, remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, dispatcher types.Dispatcher, requestTimeout time.Duration, transmissionConfig *transmission.TransmissionConfig, capMethodName string, + signers [][]byte, ) (*ClientRequest, error) { rawRequest, err := proto.MarshalOptions{Deterministic: true}.Marshal(pb.CapabilityRequestToProto(req)) if err != nil { @@ -114,7 +120,7 @@ func NewClientExecuteRequest(ctx context.Context, lggr logger.Logger, req common } lggr = logger.With(lggr, "requestId", requestID) // cap ID and method name included in the parent logger - return newClientRequest(ctx, lggr, requestID, remoteCapabilityInfo, localDonInfo, dispatcher, requestTimeout, tc, types.MethodExecute, rawRequest, workflowExecutionID, req.Metadata.ReferenceID, capMethodName) + return newClientRequest(ctx, lggr, requestID, remoteCapabilityInfo, localDonInfo, dispatcher, requestTimeout, tc, types.MethodExecute, rawRequest, workflowExecutionID, req.Metadata.ReferenceID, capMethodName, signers) } var defaultDelayMargin = 10 * time.Second @@ -122,6 +128,7 @@ var defaultDelayMargin = 10 * time.Second func newClientRequest(ctx context.Context, lggr logger.Logger, requestID string, remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, dispatcher types.Dispatcher, requestTimeout time.Duration, tc transmission.TransmissionConfig, methodType string, rawRequest []byte, workflowExecutionID string, stepRef string, capMethodName string, + signers [][]byte, ) (*ClientRequest, error) { remoteCapabilityDonInfo := remoteCapabilityInfo.DON if remoteCapabilityDonInfo == nil { @@ -214,19 +221,22 @@ func newClientRequest(ctx context.Context, lggr logger.Logger, requestID string, } return &ClientRequest{ - id: requestID, - cancelFn: cancelFn, - createdAt: time.Now(), - requestTimeout: requestTimeout, - requiredIdenticalResponses: int(remoteCapabilityDonInfo.F + 1), - remoteNodeCount: len(remoteCapabilityDonInfo.Members), - responseIDCount: make(map[[32]byte]int), - meteringResponses: make(map[[32]byte][]commoncap.MeteringNodeDetail), - errorCount: make(map[string]int), - responseReceived: responseReceived, - responseCh: make(chan clientResponse, 1), - wg: &wg, - lggr: lggr, + id: requestID, + cancelFn: cancelFn, + createdAt: time.Now(), + requestTimeout: requestTimeout, + requiredResponseConfirmations: int(remoteCapabilityDonInfo.F + 1), + remoteNodeCount: len(remoteCapabilityDonInfo.Members), + responseIDCount: make(map[[32]byte]int), + meteringResponses: make(map[[32]byte][]commoncap.MeteringNodeDetail), + errorCount: make(map[string]int), + responseReceived: responseReceived, + responseCh: make(chan clientResponse, 1), + wg: &wg, + lggr: lggr, + signers: signers, + workflowExecutionID: workflowExecutionID, + referenceID: stepRef, }, nil } @@ -328,29 +338,32 @@ func (c *ClientRequest) OnMessage(_ context.Context, msg *types.MessageBody) err c.responseReceived[sender] = true if msg.Error == types.Error_OK { + resp, err := pb.UnmarshalCapabilityResponse(msg.Payload) + if err != nil { + return fmt.Errorf("failed to unmarshal capability response: %w", err) + } + // metering reports per node are aggregated into a single array of values. for any single node message, the // metering values are extracted from the CapabilityResponse, added to an array, and the CapabilityResponse // is marshalled without the metering value to get the hash. each node could have a different metering value // which would result in different hashes. removing the metering detail allows for direct comparison of results. - responseID, metadata, err := c.getMessageHashAndMetadata(msg) + responseID, err := c.getMessageHash(resp) if err != nil { return fmt.Errorf("failed to get message hash: %w", err) } - lggr := logger.With(c.lggr, "responseID", hex.EncodeToString(responseID[:]), "requiredCount", c.requiredIdenticalResponses, "peer", sender) + lggr := logger.With(c.lggr, "responseID", hex.EncodeToString(responseID[:]), "requiredCount", c.requiredResponseConfirmations, "peer", sender) nodeReports, exists := c.meteringResponses[responseID] if !exists { nodeReports = make([]commoncap.MeteringNodeDetail, 0) } - if len(metadata.Metering) == 1 { - rpt := metadata.Metering[0] - rpt.Peer2PeerID = sender.String() - - nodeReports = append(nodeReports, rpt) + rpt, err := commoncap.ExtractMeteringFromMetadata(sender, resp.Metadata) + if err != nil { + lggr.Warnw("invalid metering detail", "err", err) } else { - lggr.Warnw("node metering detail did not contain exactly 1 record", "records", len(metadata.Metering)) + nodeReports = append(nodeReports, rpt) } c.responseIDCount[responseID]++ @@ -360,7 +373,7 @@ func (c *ClientRequest) OnMessage(_ context.Context, msg *types.MessageBody) err lggr.Warnw("received multiple unique responses for the same request", "count for responseID", len(c.responseIDCount)) } - if c.responseIDCount[responseID] == c.requiredIdenticalResponses { + if c.responseIDCount[responseID] == c.requiredResponseConfirmations || c.hasValidAttestation(resp) { payload, err := c.encodePayloadWithMetadata(msg, commoncap.ResponseMetadata{Metering: nodeReports}) if err != nil { return fmt.Errorf("failed to encode payload with metadata: %w", err) @@ -370,6 +383,16 @@ func (c *ClientRequest) OnMessage(_ context.Context, msg *types.MessageBody) err } } else { c.lggr.Debugw("received error from peer", "error", msg.Error, "errorMsg", msg.ErrorMsg, "peer", sender) + if commoncap.ErrResponsePayloadNotAvailable.Is(errors.New(msg.ErrorMsg)) { + c.payloadNotAvailableCount++ + if c.payloadNotAvailableCount == c.remoteNodeCount-c.requiredResponseConfirmations+1 { + // return an error to indicate unexpected state, but do not send an error as we might still receive a response with valid attestation. + return fmt.Errorf("unexpected state: received %d payload not available responses, while max allowed is %d. This means a bug in the code, please investigate", + c.payloadNotAvailableCount, c.remoteNodeCount-c.requiredResponseConfirmations) + } + return nil + } + c.errorCount[msg.ErrorMsg]++ c.totalErrorCount++ @@ -377,9 +400,9 @@ func (c *ClientRequest) OnMessage(_ context.Context, msg *types.MessageBody) err c.lggr.Warnw("received multiple different errors for the same request", "numDifferentErrors", len(c.errorCount)) } - if c.errorCount[msg.ErrorMsg] == c.requiredIdenticalResponses { + if c.errorCount[msg.ErrorMsg] == c.requiredResponseConfirmations { c.sendResponse(clientResponse{Err: newRemoteCapabilityExecuteError(msg.Error, msg.ErrorMsg)}) - } else if c.totalErrorCount == c.remoteNodeCount-c.requiredIdenticalResponses+1 { + } else if c.totalErrorCount == c.remoteNodeCount-c.requiredResponseConfirmations+1 { c.sendResponse(clientResponse{Err: newRemoteCapabilityExecuteErrorWithMessage( fmt.Sprintf("received %d errors, last error %s : %s", c.totalErrorCount, msg.Error, msg.ErrorMsg), msg.ErrorMsg, @@ -389,6 +412,59 @@ func (c *ClientRequest) OnMessage(_ context.Context, msg *types.MessageBody) err return nil } +func (c *ClientRequest) hasValidAttestation(resp commoncap.CapabilityResponse) bool { + if resp.OCRAttestation == nil { + return false + } + + err := c.verifyAttestation(resp) + if err != nil { + c.lggr.Errorw("Attestation is present, but not valid. This is most likely a bug and requires investigation - falling back to identical responses verification", "error", err) + return false + } + + return true +} + +func (c *ClientRequest) verifyAttestation(resp commoncap.CapabilityResponse) error { + attestation := resp.OCRAttestation + if attestation == nil { + return errors.New("attestation is missing") + } + + if len(attestation.Sigs) < c.requiredResponseConfirmations { + return fmt.Errorf("not enough signatures: got %d, need at least %d", len(attestation.Sigs), c.requiredResponseConfirmations) + } + + if len(c.signers) < c.requiredResponseConfirmations { + return fmt.Errorf("number of configured OCR signers is less than required confirmations: got %d, need at least %d", len(c.signers), c.requiredResponseConfirmations) + } + + reportData, err := commoncap.ResponseToReportData(c.workflowExecutionID, c.referenceID, resp.Payload.Value, resp.Metadata) + if err != nil { + return fmt.Errorf("failed to convert response to report data: %w", err) + } + sigData := ocr2key.ReportToSigData3(attestation.ConfigDigest, attestation.SequenceNumber, reportData[:]) + signed := make([]bool, len(c.signers)) + for _, sig := range attestation.Sigs { + if int(sig.Signer) >= len(c.signers) { + return fmt.Errorf("invalid signer index: %d", sig.Signer) + } + + if signed[sig.Signer] { + return fmt.Errorf("duplicate signature from signer index: %d", sig.Signer) + } + + if !ocr2key.EvmVerifyBlob(c.signers[sig.Signer], sigData, sig.Signature) { + return fmt.Errorf("invalid signature from signer index: %d", sig.Signer) + } + + signed[sig.Signer] = true + } + + return nil +} + func (c *ClientRequest) sendResponse(response clientResponse) { c.responseCh <- response close(c.responseCh) @@ -400,23 +476,17 @@ func (c *ClientRequest) sendResponse(response clientResponse) { c.lggr.Debugw("received OK response") } -func (c *ClientRequest) getMessageHashAndMetadata(msg *types.MessageBody) ([32]byte, commoncap.ResponseMetadata, error) { - var metadata commoncap.ResponseMetadata - - resp, err := pb.UnmarshalCapabilityResponse(msg.Payload) - if err != nil { - return [32]byte{}, metadata, err - } - - metadata = resp.Metadata - resp.Metadata = commoncap.ResponseMetadata{} - - payload, err := pb.MarshalCapabilityResponse(resp) +func (c *ClientRequest) getMessageHash(msg commoncap.CapabilityResponse) ([32]byte, error) { + // clear metadata to ensure it doesn't affect the hash, as different nodes might have different metadata (e.g. different metering values) + // since msg is passed as value, this won't affect the original message + msg.Metadata = commoncap.ResponseMetadata{} + msg.OCRAttestation = nil + payload, err := pb.MarshalCapabilityResponse(msg) if err != nil { - return [32]byte{}, metadata, err + return [32]byte{}, err } - return sha256.Sum256(payload), metadata, nil + return sha256.Sum256(payload), nil } func (c *ClientRequest) encodePayloadWithMetadata(msg *types.MessageBody, metadata commoncap.ResponseMetadata) ([]byte, error) { diff --git a/core/capabilities/remote/executable/request/client_request_internal_test.go b/core/capabilities/remote/executable/request/client_request_internal_test.go new file mode 100644 index 00000000000..2193bc3fa50 --- /dev/null +++ b/core/capabilities/remote/executable/request/client_request_internal_test.go @@ -0,0 +1,191 @@ +package request + +import ( + "crypto/rand" + "testing" + + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" + "github.com/stretchr/testify/require" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/types/known/anypb" + + "github.com/smartcontractkit/chainlink-common/keystore/corekeys" + "github.com/smartcontractkit/chainlink-common/keystore/corekeys/ocr2key" + commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" + "github.com/smartcontractkit/chainlink-common/pkg/logger" + "github.com/smartcontractkit/chainlink-protos/cre/go/values" +) + +func Test_ClientRequest_VerifyAttestation(t *testing.T) { + const workflowExecutionID = "95ef5e32deb99a10ee6804bc4af13855687559d7ff6552ac6dbb2ce0abbadeed" + const referenceID = "step1" + spendUnit, spendValue := "testunit", "42" + + val, err := values.NewMap(map[string]any{"response": "attested"}) + require.NoError(t, err) + valueProto := values.ProtoMap(val) + valueBytes, err := proto.Marshal(valueProto) + require.NoError(t, err) + + configDigest := ocrtypes.ConfigDigest{1, 2, 3, 4, 5} + seqNr := uint64(100) + + kb1, err := ocr2key.New(corekeys.EVM) + require.NoError(t, err) + kb2, err := ocr2key.New(corekeys.EVM) + require.NoError(t, err) + + validResp := commoncap.CapabilityResponse{ + Metadata: commoncap.ResponseMetadata{ + Metering: []commoncap.MeteringNodeDetail{ + {SpendUnit: spendUnit, SpendValue: spendValue}, + }, + }, + Payload: &anypb.Any{TypeUrl: "type.googleapis.com/values.v1.Map", Value: valueBytes}, + } + + reportData, err := commoncap.ResponseToReportData(workflowExecutionID, referenceID, valueBytes, validResp.Metadata) + require.NoError(t, err) + + sig1, err := kb1.Sign3(configDigest, seqNr, reportData[:]) + require.NoError(t, err) + sig2, err := kb2.Sign3(configDigest, seqNr, reportData[:]) + require.NoError(t, err) + + signers := [][]byte{kb1.PublicKey(), kb2.PublicKey()} + + validResp.OCRAttestation = &commoncap.OCRAttestation{ + ConfigDigest: configDigest, + SequenceNumber: seqNr, + Sigs: []commoncap.AttributedSignature{ + {Signer: 0, Signature: sig1}, + {Signer: 1, Signature: sig2}, + }, + } + + c := &ClientRequest{ + lggr: logger.Test(t), + signers: signers, + workflowExecutionID: workflowExecutionID, + referenceID: referenceID, + requiredResponseConfirmations: 2, + } + + t.Run("not enough signers returns error", func(t *testing.T) { + cBad := &ClientRequest{ + workflowExecutionID: workflowExecutionID, + referenceID: referenceID, + lggr: logger.Test(t), + requiredResponseConfirmations: 2, + } + err := cBad.verifyAttestation(validResp) + require.Error(t, err) + require.Contains(t, err.Error(), "number of configured OCR signers is less than required confirmations: got 0, need at least 2") + }) + + t.Run("not enough signatures returns error", func(t *testing.T) { + respFewSigs := commoncap.CapabilityResponse{ + Metadata: commoncap.ResponseMetadata{ + Metering: []commoncap.MeteringNodeDetail{{SpendUnit: spendUnit, SpendValue: spendValue}}, + }, + Payload: &anypb.Any{TypeUrl: "type.googleapis.com/values.v1.Map", Value: valueBytes}, + OCRAttestation: &commoncap.OCRAttestation{ + ConfigDigest: configDigest, + SequenceNumber: seqNr, + Sigs: []commoncap.AttributedSignature{{Signer: 0, Signature: sig1}}, + }, + } + err := c.verifyAttestation(respFewSigs) + require.Error(t, err) + require.Contains(t, err.Error(), "not enough signatures") + }) + + t.Run("invalid signer index returns error", func(t *testing.T) { + respBadSigner := commoncap.CapabilityResponse{ + Metadata: commoncap.ResponseMetadata{ + Metering: []commoncap.MeteringNodeDetail{{SpendUnit: spendUnit, SpendValue: spendValue}}, + }, + Payload: &anypb.Any{TypeUrl: "type.googleapis.com/values.v1.Map", Value: valueBytes}, + OCRAttestation: &commoncap.OCRAttestation{ + ConfigDigest: configDigest, + SequenceNumber: seqNr, + Sigs: []commoncap.AttributedSignature{ + {Signer: 0, Signature: sig1}, + {Signer: 99, Signature: sig2}, + }, + }, + } + err := c.verifyAttestation(respBadSigner) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid signer index") + }) + + t.Run("duplicate signature returns error", func(t *testing.T) { + respDupSig := commoncap.CapabilityResponse{ + Metadata: commoncap.ResponseMetadata{ + Metering: []commoncap.MeteringNodeDetail{{SpendUnit: spendUnit, SpendValue: spendValue}}, + }, + Payload: &anypb.Any{TypeUrl: "type.googleapis.com/values.v1.Map", Value: valueBytes}, + OCRAttestation: &commoncap.OCRAttestation{ + ConfigDigest: configDigest, + SequenceNumber: seqNr, + Sigs: []commoncap.AttributedSignature{ + {Signer: 0, Signature: sig1}, + {Signer: 0, Signature: sig1}, + }, + }, + } + err := c.verifyAttestation(respDupSig) + require.Error(t, err) + require.Contains(t, err.Error(), "duplicate signature") + }) + + t.Run("invalid signature returns error", func(t *testing.T) { + badSig := make([]byte, 65) + _, err := rand.Read(badSig) + require.NoError(t, err) + respBadSig := commoncap.CapabilityResponse{ + Metadata: commoncap.ResponseMetadata{ + Metering: []commoncap.MeteringNodeDetail{{SpendUnit: spendUnit, SpendValue: spendValue}}, + }, + Payload: &anypb.Any{TypeUrl: "type.googleapis.com/values.v1.Map", Value: valueBytes}, + OCRAttestation: &commoncap.OCRAttestation{ + ConfigDigest: configDigest, + SequenceNumber: seqNr, + Sigs: []commoncap.AttributedSignature{ + {Signer: 0, Signature: sig1}, + {Signer: 1, Signature: badSig}, + }, + }, + } + err = c.verifyAttestation(respBadSig) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid signature") + }) + + t.Run("wrong payload bytes produces invalid signature", func(t *testing.T) { + wrongBytes := []byte("tampered") + respWrongPayload := commoncap.CapabilityResponse{ + Metadata: commoncap.ResponseMetadata{ + Metering: []commoncap.MeteringNodeDetail{{SpendUnit: spendUnit, SpendValue: spendValue}}, + }, + Payload: &anypb.Any{TypeUrl: "x", Value: wrongBytes}, + OCRAttestation: &commoncap.OCRAttestation{ + ConfigDigest: configDigest, + SequenceNumber: seqNr, + Sigs: []commoncap.AttributedSignature{ + {Signer: 0, Signature: sig1}, + {Signer: 1, Signature: sig2}, + }, + }, + } + err := c.verifyAttestation(respWrongPayload) + require.Error(t, err) + require.Contains(t, err.Error(), "invalid signature") + }) + + t.Run("valid attestation succeeds", func(t *testing.T) { + err := c.verifyAttestation(validResp) + require.NoError(t, err) + }) +} diff --git a/core/capabilities/remote/executable/request/client_request_test.go b/core/capabilities/remote/executable/request/client_request_test.go index a871c2b6335..3b42dd37b88 100644 --- a/core/capabilities/remote/executable/request/client_request_test.go +++ b/core/capabilities/remote/executable/request/client_request_test.go @@ -8,15 +8,20 @@ import ( "testing" "time" + ocrtypes "github.com/smartcontractkit/libocr/offchainreporting2plus/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "go.uber.org/zap/zapcore" + "google.golang.org/protobuf/types/known/anypb" + "github.com/smartcontractkit/chainlink-common/keystore/corekeys" + "github.com/smartcontractkit/chainlink-common/keystore/corekeys/ocr2key" "github.com/smartcontractkit/chainlink-common/pkg/beholder/beholdertest" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" caperrors "github.com/smartcontractkit/chainlink-common/pkg/capabilities/errors" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" "github.com/smartcontractkit/chainlink-protos/cre/go/values" + pbvalues "github.com/smartcontractkit/chainlink-protos/cre/go/values/pb" "github.com/smartcontractkit/chainlink-protos/workflows/go/events" "google.golang.org/protobuf/proto" @@ -86,7 +91,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { dispatcher := newClientRequestTestDispatcher() req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, - workflowDonInfo, dispatcher, 10*time.Minute, nil, "") + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", nil) defer req.Cancel(errors.New("test end")) require.NoError(t, err) @@ -137,7 +142,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { dispatcher := newClientRequestTestDispatcher() req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, - workflowDonInfo, dispatcher, 10*time.Minute, nil, "") + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", nil) require.NoError(t, err) defer req.Cancel(errors.New("test end")) @@ -171,7 +176,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { dispatcher := newClientRequestTestDispatcher() req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, - workflowDonInfo, dispatcher, 10*time.Minute, nil, "") + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", nil) require.NoError(t, err) defer req.Cancel(errors.New("test end")) @@ -202,7 +207,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { dispatcher := newClientRequestTestDispatcher() req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, - workflowDonInfo, dispatcher, 10*time.Minute, nil, "") + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", nil) require.NoError(t, err) defer req.Cancel(errors.New("test end")) @@ -244,7 +249,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { dispatcher := newClientRequestTestDispatcher() req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, - workflowDonInfo, dispatcher, 10*time.Minute, nil, "") + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", nil) require.NoError(t, err) defer req.Cancel(errors.New("test end")) @@ -288,7 +293,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { dispatcher := newClientRequestTestDispatcher() req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, - workflowDonInfo, dispatcher, 10*time.Minute, nil, "") + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", nil) require.NoError(t, err) defer req.Cancel(errors.New("test end")) @@ -347,7 +352,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { dispatcher := newClientRequestTestDispatcher() req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, - workflowDonInfo, dispatcher, 10*time.Minute, nil, "") + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", nil) require.NoError(t, err) defer req.Cancel(errors.New("test end")) @@ -377,6 +382,236 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { assert.Equal(t, resp, values.NewString("response1")) }) + t.Run("Execute Request With Valid Attestation", func(t *testing.T) { + const F = 1 + const N = 3*F + 1 + capabilityPeers, capDonInfo, capInfo := capabilityDon(t, N, F) + + configDigest := ocrtypes.ConfigDigest{1, 2, 3, 4, 5} + kb1, err := ocr2key.New(corekeys.EVM) + require.NoError(t, err) + kb2, err := ocr2key.New(corekeys.EVM) + require.NoError(t, err) + + seqNr := uint64(100) + + payload, err := values.NewMap(map[string]int{ + "number": 42, + }) + require.NoError(t, err) + payloadAsAny, err := anypb.New(values.Proto(payload)) + require.NoError(t, err) + + spendUnit, spendValue := "testunit", "42" + capResponse := commoncap.CapabilityResponse{ + Metadata: commoncap.ResponseMetadata{ + Metering: []commoncap.MeteringNodeDetail{ + {SpendUnit: spendUnit, SpendValue: spendValue}, + }, + }, + Payload: payloadAsAny, + } + + reportData, err := commoncap.ResponseToReportData(capabilityRequest.Metadata.WorkflowExecutionID, capabilityRequest.Metadata.ReferenceID, payloadAsAny.Value, capResponse.Metadata) + require.NoError(t, err) + + sig1, err := kb1.Sign3(configDigest, seqNr, reportData[:]) + require.NoError(t, err) + sig2, err := kb2.Sign3(configDigest, seqNr, reportData[:]) + require.NoError(t, err) + + capResponse.OCRAttestation = &commoncap.OCRAttestation{ + ConfigDigest: configDigest, + SequenceNumber: seqNr, + Sigs: []commoncap.AttributedSignature{ + {Signer: 0, Signature: sig1}, + {Signer: 1, Signature: sig2}, + }, + } + + rawResponseWithAttestation, err := pb.MarshalCapabilityResponse(capResponse) + require.NoError(t, err) + + ocrSigners := [][]byte{kb1.PublicKey(), kb2.PublicKey()} + + assertValidResponse := func(t *testing.T, result []byte) { + capResponse, err := pb.UnmarshalCapabilityResponse(result) + require.NoError(t, err) + + var pbValue pbvalues.Value + require.NoError(t, capResponse.Payload.UnmarshalTo(&pbValue)) + receivedValue, err := values.FromProto(&pbValue) + require.NoError(t, err) + + var receivedMap map[string]int + require.NoError(t, receivedValue.UnwrapTo(&receivedMap)) + + assert.Equal(t, 42, receivedMap["number"]) + require.GreaterOrEqual(t, len(capResponse.Metadata.Metering), 1) + require.Equal(t, spendUnit, capResponse.Metadata.Metering[0].SpendUnit) + require.Equal(t, spendValue, capResponse.Metadata.Metering[0].SpendValue) + } + + t.Run("succeeds on first peer with valid attestation", func(t *testing.T) { + ctx := t.Context() + + dispatcher := &clientRequestTestDispatcher{msgs: make(chan *types.MessageBody, 100)} + req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", ocrSigners) + require.NoError(t, err) + defer req.Cancel(errors.New("test end")) + + for range N { + <-dispatcher.msgs + } + + assert.Empty(t, dispatcher.msgs) + + msg := &types.MessageBody{ + CapabilityId: capInfo.ID, + CapabilityDonId: capDonInfo.ID, + CallerDonId: workflowDonInfo.ID, + Method: types.MethodExecute, + Payload: rawResponseWithAttestation, + MessageId: []byte("messageID"), + } + msg.Sender = capabilityPeers[0][:] + err = req.OnMessage(ctx, msg) + require.NoError(t, err) + + response := <-req.ResponseChan() + assertValidResponse(t, response.Result) + }) + t.Run("attestation is not valid, but we fallback to identical responses", func(t *testing.T) { + ctx := t.Context() + + dispatcher := &clientRequestTestDispatcher{msgs: make(chan *types.MessageBody, 100)} + req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", ocrSigners) + require.NoError(t, err) + defer req.Cancel(errors.New("test end")) + + for range N { + <-dispatcher.msgs + } + + assert.Empty(t, dispatcher.msgs) + + for i := range F + 1 { + respInvalidAtt := commoncap.CapabilityResponse{ + Metadata: commoncap.ResponseMetadata{ + Metering: []commoncap.MeteringNodeDetail{ + {SpendUnit: spendUnit, SpendValue: spendValue}, + }, + }, + OCRAttestation: &commoncap.OCRAttestation{ + ConfigDigest: configDigest, + // make the sequence number invalid + SequenceNumber: seqNr + uint64(i) + 1, // #nosec G115 -- i is non-negative and within uint64 range + Sigs: []commoncap.AttributedSignature{ + {Signer: 0, Signature: sig1}, + {Signer: 1, Signature: sig2}, + }, + }, + Payload: payloadAsAny, + } + + rawRespInvalidAtt, err := pb.MarshalCapabilityResponse(respInvalidAtt) + require.NoError(t, err) + + msg := &types.MessageBody{ + CapabilityId: capInfo.ID, + CapabilityDonId: capDonInfo.ID, + CallerDonId: workflowDonInfo.ID, + Method: types.MethodExecute, + Payload: rawRespInvalidAtt, + MessageId: []byte("messageID"), + } + msg.Sender = capabilityPeers[i][:] + err = req.OnMessage(ctx, msg) + require.NoError(t, err) + } + + response := <-req.ResponseChan() + assertValidResponse(t, response.Result) + }) + + t.Run("2F peers return ErrResponsePayloadNotAvailable then success", func(t *testing.T) { + ctx := t.Context() + dispatcher := &clientRequestTestDispatcher{msgs: make(chan *types.MessageBody, 100)} + req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", ocrSigners) + require.NoError(t, err) + defer req.Cancel(errors.New("test end")) + + for range N { + <-dispatcher.msgs + } + + assert.Empty(t, dispatcher.msgs) + + for i := range 2 * F { + msgNA := &types.MessageBody{ + CapabilityId: capInfo.ID, + CapabilityDonId: capDonInfo.ID, + CallerDonId: workflowDonInfo.ID, + Method: types.MethodExecute, + MessageId: []byte("messageID"), + Error: types.Error_INTERNAL_ERROR, + ErrorMsg: commoncap.ErrResponsePayloadNotAvailable.Error(), + } + msgNA.Sender = capabilityPeers[i][:] + require.NoError(t, req.OnMessage(ctx, msgNA)) + } + + msgOK := &types.MessageBody{ + CapabilityId: capInfo.ID, + CapabilityDonId: capDonInfo.ID, + CallerDonId: workflowDonInfo.ID, + Method: types.MethodExecute, + Payload: rawResponseWithAttestation, + MessageId: []byte("messageID"), + } + msgOK.Sender = capabilityPeers[2*F][:] + require.NoError(t, req.OnMessage(ctx, msgOK)) + + response := <-req.ResponseChan() + assertValidResponse(t, response.Result) + }) + + t.Run("2F+1 peers return ErrResponsePayloadNotAvailable", func(t *testing.T) { + ctx := t.Context() + dispatcher := &clientRequestTestDispatcher{msgs: make(chan *types.MessageBody, 100)} + req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", ocrSigners) + require.NoError(t, err) + defer req.Cancel(errors.New("test end")) + + for range N { + <-dispatcher.msgs + } + + assert.Empty(t, dispatcher.msgs) + + noPayloadMsg := types.MessageBody{ + CapabilityId: capInfo.ID, + CapabilityDonId: capDonInfo.ID, + CallerDonId: workflowDonInfo.ID, + Method: types.MethodExecute, + MessageId: []byte("messageID"), + Error: types.Error_INTERNAL_ERROR, + ErrorMsg: commoncap.ErrResponsePayloadNotAvailable.Error(), + } + + for i := range 2 * F { + noPayloadMsg.Sender = capabilityPeers[i][:] + require.NoError(t, req.OnMessage(ctx, &noPayloadMsg)) + } + + noPayloadMsg.Sender = capabilityPeers[2*F][:] + require.Error(t, req.OnMessage(ctx, &noPayloadMsg)) + }) + }) t.Run("Executes full schedule", func(t *testing.T) { beholderTester := beholdertest.NewObserver(t) @@ -402,6 +637,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { 10*time.Minute, nil, "", + nil, ) require.NoError(t, err) defer req.Cancel(errors.New("test end")) @@ -516,6 +752,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { 10*time.Minute, nil, "", + nil, ) require.NoError(t, err) defer req.Cancel(errors.New("test end")) @@ -605,7 +842,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { dispatcher := newClientRequestTestDispatcher() req, err := request.NewClientExecuteRequest(ctx, logger.Test(t), capabilityRequest, capInfo, - workflowDonInfo, dispatcher, 10*time.Minute, nil, "") + workflowDonInfo, dispatcher, 10*time.Minute, nil, "", nil) require.NoError(t, err) defer req.Cancel(errors.New("test end")) @@ -670,6 +907,7 @@ func Test_ClientRequest_MessageValidation(t *testing.T) { DeltaStage: 1000 * time.Millisecond, }, "", + nil, ) require.NoError(t, err) defer req.Cancel(errors.New("test end")) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 2a90f49dd86..147759f682a 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -46,8 +46,8 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.98 github.com/smartcontractkit/chainlink-automation v0.8.1 github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260415165642-49f23e4d76cc - github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 - github.com/smartcontractkit/chainlink-common/keystore v1.0.2 + github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a + github.com/smartcontractkit/chainlink-common/keystore v1.1.0 github.com/smartcontractkit/chainlink-data-streams v0.1.13 github.com/smartcontractkit/chainlink-deployments-framework v0.96.0 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260416173445-80f6efde0a03 diff --git a/core/scripts/go.sum b/core/scripts/go.sum index fe3715cec86..060f37edd14 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1650,10 +1650,10 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f2 github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f23e4d76cc/go.mod h1:Ex2OUp35VJuCcRAjuBKwP+cevEPOSjy1pZXm3ncV4kQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3 h1:NTvhSs8sh0ZYr3JUw8GvPZcLQaeh6t2nleKg7hfnOnQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3/go.mod h1:sJeU9at/+chXZfh7io5HzW6C3fgDxjpEB6U1dsS+BnE= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 h1:WSNUds78NMlwDttROK/hJZ6ZOremyrR5JXJmPlT8hO8= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71/go.mod h1:kOIIjzxuRXK31j1JdZgUAGjqbGwmJ5gU5qI+FMkP6/I= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a h1:mUEbGLi++YLS6nd6oaFHZ9tAqw0t2ojLu1cZAjCoZmU= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a/go.mod h1:ohOxnxpzD382PS3nN4zhdJmWD+rsBh8zTLGGHhTdJCE= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0 h1:2wzySccgk2fpWusPKO0bpeAZzfSU9eq6CS5U+JwYaVo= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0/go.mod h1:6JexOOhPhknQ0QMuppFIlOpm6wCp54yZMxai+tWugwY= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4 h1:NOUsjsMzNecbjiPWUQGlRSRAutEvCFrqqyETDJeh5q4= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4/go.mod h1:Zpvul9sTcZNAZOVzt5vBl1XZGNvQebFpnpn3/KOQvOQ= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk= diff --git a/deployment/go.mod b/deployment/go.mod index bcdfcc5bd90..ff0673e864e 100644 --- a/deployment/go.mod +++ b/deployment/go.mod @@ -42,8 +42,8 @@ require ( github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260415165642-49f23e4d76cc github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260415165642-49f23e4d76cc github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f23e4d76cc - github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 - github.com/smartcontractkit/chainlink-common/keystore v1.0.2 + github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a + github.com/smartcontractkit/chainlink-common/keystore v1.1.0 github.com/smartcontractkit/chainlink-deployments-framework v0.96.0 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260416173445-80f6efde0a03 github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260403151002-2c91155b5501 diff --git a/deployment/go.sum b/deployment/go.sum index 465fb3b8f63..7632741375c 100644 --- a/deployment/go.sum +++ b/deployment/go.sum @@ -1396,10 +1396,10 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f2 github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f23e4d76cc/go.mod h1:Ex2OUp35VJuCcRAjuBKwP+cevEPOSjy1pZXm3ncV4kQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3 h1:NTvhSs8sh0ZYr3JUw8GvPZcLQaeh6t2nleKg7hfnOnQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3/go.mod h1:sJeU9at/+chXZfh7io5HzW6C3fgDxjpEB6U1dsS+BnE= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 h1:WSNUds78NMlwDttROK/hJZ6ZOremyrR5JXJmPlT8hO8= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71/go.mod h1:kOIIjzxuRXK31j1JdZgUAGjqbGwmJ5gU5qI+FMkP6/I= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a h1:mUEbGLi++YLS6nd6oaFHZ9tAqw0t2ojLu1cZAjCoZmU= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a/go.mod h1:ohOxnxpzD382PS3nN4zhdJmWD+rsBh8zTLGGHhTdJCE= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0 h1:2wzySccgk2fpWusPKO0bpeAZzfSU9eq6CS5U+JwYaVo= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0/go.mod h1:6JexOOhPhknQ0QMuppFIlOpm6wCp54yZMxai+tWugwY= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk= diff --git a/go.mod b/go.mod index 6c390e783b9..9daf4cedb59 100644 --- a/go.mod +++ b/go.mod @@ -84,8 +84,8 @@ require ( github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260415165642-49f23e4d76cc github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260415165642-49f23e4d76cc github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3 - github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 - github.com/smartcontractkit/chainlink-common/keystore v1.0.2 + github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a + github.com/smartcontractkit/chainlink-common/keystore v1.1.0 github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 github.com/smartcontractkit/chainlink-data-streams v0.1.13 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260416173445-80f6efde0a03 diff --git a/go.sum b/go.sum index 12e998eedcf..c64be459c02 100644 --- a/go.sum +++ b/go.sum @@ -1244,10 +1244,10 @@ github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260 github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260415165642-49f23e4d76cc/go.mod h1:67YbnoglYD61Pz/jTVCgav9wFq7S35OU8UyQSvPllRw= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3 h1:NTvhSs8sh0ZYr3JUw8GvPZcLQaeh6t2nleKg7hfnOnQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3/go.mod h1:sJeU9at/+chXZfh7io5HzW6C3fgDxjpEB6U1dsS+BnE= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 h1:WSNUds78NMlwDttROK/hJZ6ZOremyrR5JXJmPlT8hO8= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71/go.mod h1:kOIIjzxuRXK31j1JdZgUAGjqbGwmJ5gU5qI+FMkP6/I= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a h1:mUEbGLi++YLS6nd6oaFHZ9tAqw0t2ojLu1cZAjCoZmU= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a/go.mod h1:ohOxnxpzD382PS3nN4zhdJmWD+rsBh8zTLGGHhTdJCE= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0 h1:2wzySccgk2fpWusPKO0bpeAZzfSU9eq6CS5U+JwYaVo= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0/go.mod h1:6JexOOhPhknQ0QMuppFIlOpm6wCp54yZMxai+tWugwY= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 0b245b7beab..2af0cc593c0 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -29,8 +29,8 @@ require ( github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260415165642-49f23e4d76cc github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260415165642-49f23e4d76cc github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260415165642-49f23e4d76cc - github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 - github.com/smartcontractkit/chainlink-common/keystore v1.0.2 + github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a + github.com/smartcontractkit/chainlink-common/keystore v1.1.0 github.com/smartcontractkit/chainlink-deployments-framework v0.96.0 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260416173445-80f6efde0a03 github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20260119171452-39c98c3b33cd diff --git a/integration-tests/go.sum b/integration-tests/go.sum index e98e0a2f5ce..7b35610e9c7 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1381,10 +1381,10 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f2 github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f23e4d76cc/go.mod h1:Ex2OUp35VJuCcRAjuBKwP+cevEPOSjy1pZXm3ncV4kQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3 h1:NTvhSs8sh0ZYr3JUw8GvPZcLQaeh6t2nleKg7hfnOnQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3/go.mod h1:sJeU9at/+chXZfh7io5HzW6C3fgDxjpEB6U1dsS+BnE= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 h1:WSNUds78NMlwDttROK/hJZ6ZOremyrR5JXJmPlT8hO8= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71/go.mod h1:kOIIjzxuRXK31j1JdZgUAGjqbGwmJ5gU5qI+FMkP6/I= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a h1:mUEbGLi++YLS6nd6oaFHZ9tAqw0t2ojLu1cZAjCoZmU= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a/go.mod h1:ohOxnxpzD382PS3nN4zhdJmWD+rsBh8zTLGGHhTdJCE= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0 h1:2wzySccgk2fpWusPKO0bpeAZzfSU9eq6CS5U+JwYaVo= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0/go.mod h1:6JexOOhPhknQ0QMuppFIlOpm6wCp54yZMxai+tWugwY= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index a513ea2fcea..15618ab378e 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -20,7 +20,7 @@ require ( github.com/smartcontractkit/chainlink-ccip/chains/evm v0.0.0-20260415165642-49f23e4d76cc github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260415165642-49f23e4d76cc github.com/smartcontractkit/chainlink-ccip/chains/solana/gobindings v0.0.0-20260415165642-49f23e4d76cc - github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 + github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a github.com/smartcontractkit/chainlink-deployments-framework v0.96.0 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260416173445-80f6efde0a03 github.com/smartcontractkit/chainlink-testing-framework/framework v0.15.16 @@ -481,7 +481,7 @@ require ( github.com/smartcontractkit/chainlink-ccip/ccv/chains/evm v0.0.0-20260408145530-22e2d05695cd // indirect github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f23e4d76cc // indirect github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3 // indirect - github.com/smartcontractkit/chainlink-common/keystore v1.0.2 // indirect + github.com/smartcontractkit/chainlink-common/keystore v1.1.0 // indirect github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 // indirect github.com/smartcontractkit/chainlink-data-streams v0.1.13 // indirect github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260403151002-2c91155b5501 // indirect diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index c98a1687fc6..abacc6404c4 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1649,10 +1649,10 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f2 github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f23e4d76cc/go.mod h1:Ex2OUp35VJuCcRAjuBKwP+cevEPOSjy1pZXm3ncV4kQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3 h1:NTvhSs8sh0ZYr3JUw8GvPZcLQaeh6t2nleKg7hfnOnQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3/go.mod h1:sJeU9at/+chXZfh7io5HzW6C3fgDxjpEB6U1dsS+BnE= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 h1:WSNUds78NMlwDttROK/hJZ6ZOremyrR5JXJmPlT8hO8= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71/go.mod h1:kOIIjzxuRXK31j1JdZgUAGjqbGwmJ5gU5qI+FMkP6/I= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a h1:mUEbGLi++YLS6nd6oaFHZ9tAqw0t2ojLu1cZAjCoZmU= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a/go.mod h1:ohOxnxpzD382PS3nN4zhdJmWD+rsBh8zTLGGHhTdJCE= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0 h1:2wzySccgk2fpWusPKO0bpeAZzfSU9eq6CS5U+JwYaVo= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0/go.mod h1:6JexOOhPhknQ0QMuppFIlOpm6wCp54yZMxai+tWugwY= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10 h1:FJAFgXS9oqASnkS03RE1HQwYQQxrO4l46O5JSzxqLgg= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.10/go.mod h1:oiDa54M0FwxevWwyAX773lwdWvFYYlYHHQV1LQ5HpWY= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk= diff --git a/system-tests/lib/go.mod b/system-tests/lib/go.mod index 4708cf7a372..47eebba208b 100644 --- a/system-tests/lib/go.mod +++ b/system-tests/lib/go.mod @@ -32,8 +32,8 @@ require ( github.com/smartcontractkit/chain-selectors v1.0.98 github.com/smartcontractkit/chainlink-aptos v0.0.0-20260407161350-a86b1969da65 github.com/smartcontractkit/chainlink-ccip/chains/solana v0.0.0-20260415165642-49f23e4d76cc - github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 - github.com/smartcontractkit/chainlink-common/keystore v1.0.2 + github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a + github.com/smartcontractkit/chainlink-common/keystore v1.1.0 github.com/smartcontractkit/chainlink-deployments-framework v0.96.0 github.com/smartcontractkit/chainlink-evm v0.3.4-0.20260416173445-80f6efde0a03 github.com/smartcontractkit/chainlink-evm/gethwrappers v0.0.0-20260119171452-39c98c3b33cd diff --git a/system-tests/lib/go.sum b/system-tests/lib/go.sum index 022b4fb389b..fd0318c70f2 100644 --- a/system-tests/lib/go.sum +++ b/system-tests/lib/go.sum @@ -1615,10 +1615,10 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f2 github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f23e4d76cc/go.mod h1:Ex2OUp35VJuCcRAjuBKwP+cevEPOSjy1pZXm3ncV4kQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3 h1:NTvhSs8sh0ZYr3JUw8GvPZcLQaeh6t2nleKg7hfnOnQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3/go.mod h1:sJeU9at/+chXZfh7io5HzW6C3fgDxjpEB6U1dsS+BnE= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 h1:WSNUds78NMlwDttROK/hJZ6ZOremyrR5JXJmPlT8hO8= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71/go.mod h1:kOIIjzxuRXK31j1JdZgUAGjqbGwmJ5gU5qI+FMkP6/I= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a h1:mUEbGLi++YLS6nd6oaFHZ9tAqw0t2ojLu1cZAjCoZmU= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a/go.mod h1:ohOxnxpzD382PS3nN4zhdJmWD+rsBh8zTLGGHhTdJCE= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0 h1:2wzySccgk2fpWusPKO0bpeAZzfSU9eq6CS5U+JwYaVo= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0/go.mod h1:6JexOOhPhknQ0QMuppFIlOpm6wCp54yZMxai+tWugwY= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4 h1:NOUsjsMzNecbjiPWUQGlRSRAutEvCFrqqyETDJeh5q4= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4/go.mod h1:Zpvul9sTcZNAZOVzt5vBl1XZGNvQebFpnpn3/KOQvOQ= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk= diff --git a/system-tests/tests/go.mod b/system-tests/tests/go.mod index ab178d08a6a..c81e1ebda89 100644 --- a/system-tests/tests/go.mod +++ b/system-tests/tests/go.mod @@ -58,8 +58,8 @@ require ( github.com/rs/zerolog v1.34.0 github.com/shopspring/decimal v1.4.0 github.com/smartcontractkit/chain-selectors v1.0.98 - github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 - github.com/smartcontractkit/chainlink-common/keystore v1.0.2 + github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a + github.com/smartcontractkit/chainlink-common/keystore v1.1.0 github.com/smartcontractkit/chainlink-data-streams v0.1.13 github.com/smartcontractkit/chainlink-deployments-framework v0.96.0 github.com/smartcontractkit/chainlink-evm/contracts/cre/gobindings v0.0.0-20260403151002-2c91155b5501 diff --git a/system-tests/tests/go.sum b/system-tests/tests/go.sum index 8e663f3a2a5..68eb7c47ba0 100644 --- a/system-tests/tests/go.sum +++ b/system-tests/tests/go.sum @@ -1830,10 +1830,10 @@ github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f2 github.com/smartcontractkit/chainlink-ccip/deployment v0.0.0-20260415165642-49f23e4d76cc/go.mod h1:Ex2OUp35VJuCcRAjuBKwP+cevEPOSjy1pZXm3ncV4kQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3 h1:NTvhSs8sh0ZYr3JUw8GvPZcLQaeh6t2nleKg7hfnOnQ= github.com/smartcontractkit/chainlink-ccv v0.0.0-20260423133643-8d6a915c04b3/go.mod h1:sJeU9at/+chXZfh7io5HzW6C3fgDxjpEB6U1dsS+BnE= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71 h1:WSNUds78NMlwDttROK/hJZ6ZOremyrR5JXJmPlT8hO8= -github.com/smartcontractkit/chainlink-common v0.11.2-0.20260421191147-d10b9943ac71/go.mod h1:kOIIjzxuRXK31j1JdZgUAGjqbGwmJ5gU5qI+FMkP6/I= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2 h1:AWisx4JT3QV8tcgh6J5NCrex+wAgTYpWyHsyNPSXzsQ= -github.com/smartcontractkit/chainlink-common/keystore v1.0.2/go.mod h1:rSkIHdomyak3YnUtXLenl6poIq8q0V3UZPiiyYqPdGA= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a h1:mUEbGLi++YLS6nd6oaFHZ9tAqw0t2ojLu1cZAjCoZmU= +github.com/smartcontractkit/chainlink-common v0.11.2-0.20260422075950-29f37fa83c8a/go.mod h1:ohOxnxpzD382PS3nN4zhdJmWD+rsBh8zTLGGHhTdJCE= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0 h1:2wzySccgk2fpWusPKO0bpeAZzfSU9eq6CS5U+JwYaVo= +github.com/smartcontractkit/chainlink-common/keystore v1.1.0/go.mod h1:6JexOOhPhknQ0QMuppFIlOpm6wCp54yZMxai+tWugwY= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4 h1:NOUsjsMzNecbjiPWUQGlRSRAutEvCFrqqyETDJeh5q4= github.com/smartcontractkit/chainlink-common/pkg/chipingress v0.0.11-0.20251211140724-319861e514c4/go.mod h1:Zpvul9sTcZNAZOVzt5vBl1XZGNvQebFpnpn3/KOQvOQ= github.com/smartcontractkit/chainlink-common/pkg/monitoring v0.0.0-20251215152504-b1e41f508340 h1:PsjEI+5jZIz9AS4eOsLS5VpSWJINf38clXV3wryPyMk=