Skip to content

Commit c0f5a3c

Browse files
authored
CRE Don2Don accept OCR attestation of a response (#21607)
* CRE Don2Don accept OCR attestation of a response * Gracefully handle payload not available error * Use signers instead of full OCR config * Refactor ocr attestation * test fix * Proper error handing and OCRAttestation * Bump chainlink-common * bump common * Bump keystore * bump keystore
1 parent 4844800 commit c0f5a3c

21 files changed

Lines changed: 627 additions & 120 deletions

File tree

core/capabilities/launcher.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ func (w *launcher) addRemoteCapability(ctx context.Context, cid string, capabili
501501

502502
methodConfig := capabilityConfig.CapabilityMethodConfig
503503
if methodConfig != nil { // v2 capability - handle via CombinedClient
504-
errAdd := w.addRemoteCapabilityV2(ctx, capability.ID, methodConfig, myDON, remoteDON)
504+
errAdd := w.addRemoteCapabilityV2(ctx, capability.ID, methodConfig, myDON, remoteDON, localRegistry)
505505
if errAdd != nil {
506506
return fmt.Errorf("failed to add remote v2 capability %s: %w", capability.ID, errAdd)
507507
}
@@ -592,7 +592,7 @@ func (w *launcher) addRemoteCapability(ctx context.Context, cid string, capabili
592592
w.cachedShims.executableClients[shimKey] = execCap
593593
}
594594
// V1 capabilities read transmission schedule from every request
595-
if errCfg := execCap.SetConfig(info, myDON.DON, defaultTargetRequestTimeout, nil); errCfg != nil {
595+
if errCfg := execCap.SetConfig(info, myDON.DON, defaultTargetRequestTimeout, nil, nil); errCfg != nil {
596596
return nil, fmt.Errorf("failed to set trigger config: %w", errCfg)
597597
}
598598
return execCap.(capabilityService), nil
@@ -618,7 +618,7 @@ func (w *launcher) addRemoteCapability(ctx context.Context, cid string, capabili
618618
w.cachedShims.executableClients[shimKey] = execCap
619619
}
620620
// V1 capabilities read transmission schedule from every request
621-
if errCfg := execCap.SetConfig(info, myDON.DON, defaultTargetRequestTimeout, nil); errCfg != nil {
621+
if errCfg := execCap.SetConfig(info, myDON.DON, defaultTargetRequestTimeout, nil, nil); errCfg != nil {
622622
return nil, fmt.Errorf("failed to set trigger config: %w", errCfg)
623623
}
624624
return execCap.(capabilityService), nil
@@ -929,7 +929,7 @@ func signersFor(don registrysyncer.DON, localRegistry *registrysyncer.LocalRegis
929929
}
930930

931931
// Add a V2 capability with multiple methods, using CombinedClient.
932-
func (w *launcher) addRemoteCapabilityV2(ctx context.Context, capID string, methodConfig map[string]capabilities.CapabilityMethodConfig, myDON registrysyncer.DON, remoteDON registrysyncer.DON) error {
932+
func (w *launcher) addRemoteCapabilityV2(ctx context.Context, capID string, methodConfig map[string]capabilities.CapabilityMethodConfig, myDON registrysyncer.DON, remoteDON registrysyncer.DON, localRegistry *registrysyncer.LocalRegistry) error {
933933
info, err := capabilities.NewRemoteCapabilityInfo(
934934
capID,
935935
capabilities.CapabilityTypeCombined,
@@ -984,7 +984,12 @@ func (w *launcher) addRemoteCapabilityV2(ctx context.Context, capID string, meth
984984
Schedule: transmission.EnumToString(config.RemoteExecutableConfig.TransmissionSchedule),
985985
DeltaStage: config.RemoteExecutableConfig.DeltaStage,
986986
}
987-
err := client.SetConfig(info, myDON.DON, config.RemoteExecutableConfig.RequestTimeout, transmissionConfig)
987+
988+
signers, err := signersFor(remoteDON, localRegistry)
989+
if err != nil {
990+
return fmt.Errorf("failed to get signers for executable client: %w", err)
991+
}
992+
err = client.SetConfig(info, myDON.DON, config.RemoteExecutableConfig.RequestTimeout, transmissionConfig, signers)
988993
if err != nil {
989994
w.lggr.Errorw("failed to update client config", "capID", capID, "method", method, "error", err)
990995
continue

core/capabilities/remote/executable/client.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,12 +46,14 @@ type dynamicConfig struct {
4646
requestTimeout time.Duration
4747
// Has to be set only for V2 capabilities. V1 capabilities read transmission schedule from every request.
4848
transmissionConfig *transmission.TransmissionConfig
49+
// Has to be set only for V2 capabilities using OCR.
50+
signers [][]byte
4951
}
5052

5153
type Client interface {
5254
commoncap.ExecutableCapability
5355
Receive(ctx context.Context, msg *types.MessageBody)
54-
SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, requestTimeout time.Duration, transmissionConfig *transmission.TransmissionConfig) error
56+
SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, requestTimeout time.Duration, transmissionConfig *transmission.TransmissionConfig, signers [][]byte) error
5557
}
5658

5759
var _ Client = &client{}
@@ -78,7 +80,7 @@ func NewClient(capabilityID string, capMethodName string, dispatcher types.Dispa
7880

7981
// SetConfig sets the remote capability configuration dynamically
8082
// TransmissionConfig has to be set only for V2 capabilities. V1 capabilities read transmission schedule from every request.
81-
func (c *client) SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, requestTimeout time.Duration, transmissionConfig *transmission.TransmissionConfig) error {
83+
func (c *client) SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localDonInfo commoncap.DON, requestTimeout time.Duration, transmissionConfig *transmission.TransmissionConfig, signers [][]byte) error {
8284
if remoteCapabilityInfo.ID == "" || remoteCapabilityInfo.ID != c.capabilityID {
8385
return fmt.Errorf("capability info provided does not match the client's capabilityID: %s != %s", remoteCapabilityInfo.ID, c.capabilityID)
8486
}
@@ -98,6 +100,7 @@ func (c *client) SetConfig(remoteCapabilityInfo commoncap.CapabilityInfo, localD
98100
localDONInfo: localDonInfo,
99101
requestTimeout: requestTimeout,
100102
transmissionConfig: transmissionConfig,
103+
signers: signers,
101104
})
102105
c.lggr.Infow("SetConfig", "remoteDONName", remoteCapabilityInfo.DON.Name, "remoteDONID", remoteCapabilityInfo.DON.ID, "requestTimeout", requestTimeout, "transmissionConfig", transmissionConfig)
103106
return nil
@@ -234,7 +237,7 @@ func (c *client) Execute(ctx context.Context, capReq commoncap.CapabilityRequest
234237
}
235238

236239
req, err := request.NewClientExecuteRequest(ctx, c.lggr, capReq, cfg.remoteCapabilityInfo, cfg.localDONInfo, c.dispatcher,
237-
cfg.requestTimeout, cfg.transmissionConfig, c.capMethodName)
240+
cfg.requestTimeout, cfg.transmissionConfig, c.capMethodName, cfg.signers)
238241
if err != nil {
239242
return commoncap.CapabilityResponse{}, fmt.Errorf("failed to create client request: %w", err)
240243
}

core/capabilities/remote/executable/client_test.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ func testClient(t *testing.T, numWorkflowPeers int, workflowNodeResponseTimeout
243243
for i := range numWorkflowPeers {
244244
workflowPeerDispatcher := broker.NewDispatcherForNode(workflowPeers[i])
245245
caller := executable.NewClient(capInfo.ID, "", workflowPeerDispatcher, lggr)
246-
err := caller.SetConfig(capInfo, workflowDonInfo, workflowNodeResponseTimeout, nil)
246+
err := caller.SetConfig(capInfo, workflowDonInfo, workflowNodeResponseTimeout, nil, nil)
247247
require.NoError(t, err)
248248
servicetest.Run(t, caller)
249249
broker.RegisterReceiverNode(workflowPeers[i], caller)
@@ -403,7 +403,7 @@ func TestClient_SetConfig(t *testing.T) {
403403
DeltaStage: 10 * time.Millisecond,
404404
}
405405

406-
err := client.SetConfig(validCapInfo, validDonInfo, validTimeout, transmissionConfig)
406+
err := client.SetConfig(validCapInfo, validDonInfo, validTimeout, transmissionConfig, nil)
407407
require.NoError(t, err)
408408

409409
// Verify config was set
@@ -418,7 +418,7 @@ func TestClient_SetConfig(t *testing.T) {
418418
CapabilityType: commoncap.CapabilityTypeAction,
419419
}
420420

421-
err := client.SetConfig(invalidCapInfo, validDonInfo, validTimeout, nil)
421+
err := client.SetConfig(invalidCapInfo, validDonInfo, validTimeout, nil, nil)
422422
require.Error(t, err)
423423
assert.Contains(t, err.Error(), "capability info provided does not match the client's capabilityID")
424424
assert.Contains(t, err.Error(), "different_capability@1.0.0 != test_capability@1.0.0")
@@ -431,15 +431,15 @@ func TestClient_SetConfig(t *testing.T) {
431431
F: 0,
432432
}
433433

434-
err := client.SetConfig(validCapInfo, invalidDonInfo, validTimeout, nil)
434+
err := client.SetConfig(validCapInfo, invalidDonInfo, validTimeout, nil, nil)
435435
require.Error(t, err)
436436
assert.Contains(t, err.Error(), "empty localDonInfo provided")
437437
})
438438

439439
t.Run("successful config update", func(t *testing.T) {
440440
// Set initial config
441441
initialTimeout := 10 * time.Second
442-
err := client.SetConfig(validCapInfo, validDonInfo, initialTimeout, nil)
442+
err := client.SetConfig(validCapInfo, validDonInfo, initialTimeout, nil, nil)
443443
require.NoError(t, err)
444444

445445
// Replace with new config
@@ -450,7 +450,7 @@ func TestClient_SetConfig(t *testing.T) {
450450
F: 1,
451451
}
452452

453-
err = client.SetConfig(validCapInfo, newDonInfo, newTimeout, nil)
453+
err = client.SetConfig(validCapInfo, newDonInfo, newTimeout, nil, nil)
454454
require.NoError(t, err)
455455

456456
// Verify the config was completely replaced
@@ -494,7 +494,7 @@ func TestClient_SetConfig_StartClose(t *testing.T) {
494494
})
495495

496496
t.Run("start succeeds after config set", func(t *testing.T) {
497-
require.NoError(t, client.SetConfig(validCapInfo, validDonInfo, validTimeout, nil))
497+
require.NoError(t, client.SetConfig(validCapInfo, validDonInfo, validTimeout, nil, nil))
498498
require.NoError(t, client.Start(ctx))
499499
require.NoError(t, client.Close())
500500
})
@@ -504,12 +504,12 @@ func TestClient_SetConfig_StartClose(t *testing.T) {
504504
freshClient := executable.NewClient(capabilityID, "execute", dispatcher, lggr)
505505

506506
// Set initial config and start
507-
require.NoError(t, freshClient.SetConfig(validCapInfo, validDonInfo, validTimeout, nil))
507+
require.NoError(t, freshClient.SetConfig(validCapInfo, validDonInfo, validTimeout, nil, nil))
508508
require.NoError(t, freshClient.Start(ctx))
509509

510510
// Update config while running
511511
validCapInfo.Description = "new description"
512-
require.NoError(t, freshClient.SetConfig(validCapInfo, validDonInfo, validTimeout, nil))
512+
require.NoError(t, freshClient.SetConfig(validCapInfo, validDonInfo, validTimeout, nil, nil))
513513

514514
// Verify config was updated
515515
info, err := freshClient.Info(ctx)

core/capabilities/remote/executable/endtoend_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ func testRemoteExecutableCapability(ctx context.Context, t *testing.T, underlyin
309309
for i := range numWorkflowPeers {
310310
workflowPeerDispatcher := broker.NewDispatcherForNode(workflowPeers[i])
311311
workflowNode := executable.NewClient(capInfo.ID, "", workflowPeerDispatcher, lggr)
312-
err := workflowNode.SetConfig(capInfo, workflowDonInfo, workflowNodeTimeout, nil)
312+
err := workflowNode.SetConfig(capInfo, workflowDonInfo, workflowNodeTimeout, nil, nil)
313313
require.NoError(t, err)
314314
servicetest.Run(t, workflowNode)
315315
broker.RegisterReceiverNode(workflowPeers[i], workflowNode)

0 commit comments

Comments
 (0)