@@ -336,29 +336,15 @@ func Test_ClientRequest_MessageValidation(t *testing.T) {
336336 assert .Equal (t , resp , values .NewString ("response1" ))
337337 })
338338 t .Run ("Execute Request With Valid Attestation" , func (t * testing.T ) {
339- ctx := t .Context ()
340- capabilityPeers , capDonInfo , capInfo := capabilityDon (t , 4 , 1 )
339+ const F = 1
340+ const N = 3 * F + 1
341+ capabilityPeers , capDonInfo , capInfo := capabilityDon (t , N , F )
341342
342343 configDigest := ocrtypes.ConfigDigest {1 , 2 , 3 , 4 , 5 }
343344 kb1 , err := ocr2key .New (corekeys .EVM )
344345 require .NoError (t , err )
345346 kb2 , err := ocr2key .New (corekeys .EVM )
346347 require .NoError (t , err )
347- dispatcher := & clientRequestTestDispatcher {msgs : make (chan * types.MessageBody , 100 )}
348- req , err := request .NewClientExecuteRequest (ctx , logger .Test (t ), capabilityRequest , capInfo ,
349- workflowDonInfo , dispatcher , 10 * time .Minute , nil , "" , map [string ]ocrtypes.ContractConfig {
350- pb .OCR3ConfigDefaultKey : {
351- ConfigDigest : configDigest ,
352- Signers : []ocrtypes.OnchainPublicKey {kb1 .PublicKey (), kb2 .PublicKey ()},
353- F : 1 ,
354- },
355- })
356- require .NoError (t , err )
357- defer req .Cancel (errors .New ("test end" ))
358-
359- <- dispatcher .msgs
360- <- dispatcher .msgs
361- assert .Empty (t , dispatcher .msgs )
362348
363349 seqNr := uint64 (100 )
364350
@@ -372,9 +358,9 @@ func Test_ClientRequest_MessageValidation(t *testing.T) {
372358 spendUnit , spendValue := "testunit" , "42"
373359 reportData := commoncap .ResponseToReportData (capabilityRequest .Metadata .WorkflowExecutionID , capabilityRequest .Metadata .ReferenceID , payloadAsAny .Value , spendUnit , spendValue )
374360
375- sig1 , err := kb1 .Sign3 (configDigest , seqNr , reportData )
361+ sig1 , err := kb1 .Sign3 (configDigest , seqNr , reportData [:] )
376362 require .NoError (t , err )
377- sig2 , err := kb2 .Sign3 (configDigest , seqNr , reportData )
363+ sig2 , err := kb2 .Sign3 (configDigest , seqNr , reportData [:] )
378364 require .NoError (t , err )
379365
380366 rawResponseWithAttestation , err := pb .MarshalCapabilityResponse (commoncap.CapabilityResponse {
@@ -395,31 +381,135 @@ func Test_ClientRequest_MessageValidation(t *testing.T) {
395381 })
396382 require .NoError (t , err )
397383
398- msg := & types.MessageBody {
399- CapabilityId : capInfo .ID ,
400- CapabilityDonId : capDonInfo .ID ,
401- CallerDonId : workflowDonInfo .ID ,
402- Method : types .MethodExecute ,
403- Payload : rawResponseWithAttestation ,
404- MessageId : []byte ("messageID" ),
384+ ocrConfigs := map [string ]ocrtypes.ContractConfig {
385+ pb .OCR3ConfigDefaultKey : {
386+ ConfigDigest : configDigest ,
387+ Signers : []ocrtypes.OnchainPublicKey {kb1 .PublicKey (), kb2 .PublicKey ()},
388+ F : F ,
389+ },
405390 }
406- msg .Sender = capabilityPeers [0 ][:]
407- err = req .OnMessage (ctx , msg )
408- require .NoError (t , err )
409391
410- response := <- req . ResponseChan ()
411- capResponse , err := pb .UnmarshalCapabilityResponse (response . Result )
412- require .NoError (t , err )
392+ assertValidResponse := func ( t * testing. T , result [] byte ) {
393+ capResponse , err := pb .UnmarshalCapabilityResponse (result )
394+ require .NoError (t , err )
413395
414- var pbValue pbvalues.Value
415- require .NoError (t , capResponse .Payload .UnmarshalTo (& pbValue ))
416- receivedValue , err := values .FromProto (& pbValue )
417- require .NoError (t , err )
396+ var pbValue pbvalues.Value
397+ require .NoError (t , capResponse .Payload .UnmarshalTo (& pbValue ))
398+ receivedValue , err := values .FromProto (& pbValue )
399+ require .NoError (t , err )
400+
401+ var receivedMap map [string ]int
402+ require .NoError (t , receivedValue .UnwrapTo (& receivedMap ))
403+
404+ assert .Equal (t , 42 , receivedMap ["number" ])
405+ }
418406
419- var receivedMap map [ string ] int
420- require . NoError ( t , receivedValue . UnwrapTo ( & receivedMap ) )
407+ t . Run ( "succeeds on first peer with valid attestation" , func ( t * testing. T ) {
408+ ctx := t . Context ( )
421409
422- assert .Equal (t , 42 , receivedMap ["number" ])
410+ dispatcher := & clientRequestTestDispatcher {msgs : make (chan * types.MessageBody , 100 )}
411+ req , err := request .NewClientExecuteRequest (ctx , logger .Test (t ), capabilityRequest , capInfo ,
412+ workflowDonInfo , dispatcher , 10 * time .Minute , nil , "" , ocrConfigs )
413+ require .NoError (t , err )
414+ defer req .Cancel (errors .New ("test end" ))
415+
416+ for range N {
417+ <- dispatcher .msgs
418+ }
419+
420+ assert .Empty (t , dispatcher .msgs )
421+
422+ msg := & types.MessageBody {
423+ CapabilityId : capInfo .ID ,
424+ CapabilityDonId : capDonInfo .ID ,
425+ CallerDonId : workflowDonInfo .ID ,
426+ Method : types .MethodExecute ,
427+ Payload : rawResponseWithAttestation ,
428+ MessageId : []byte ("messageID" ),
429+ }
430+ msg .Sender = capabilityPeers [0 ][:]
431+ err = req .OnMessage (ctx , msg )
432+ require .NoError (t , err )
433+
434+ response := <- req .ResponseChan ()
435+ assertValidResponse (t , response .Result )
436+ })
437+
438+ t .Run ("2F peers return ErrResponsePayloadNotAvailable then success" , func (t * testing.T ) {
439+ ctx := t .Context ()
440+ dispatcher := & clientRequestTestDispatcher {msgs : make (chan * types.MessageBody , 100 )}
441+ req , err := request .NewClientExecuteRequest (ctx , logger .Test (t ), capabilityRequest , capInfo ,
442+ workflowDonInfo , dispatcher , 10 * time .Minute , nil , "" , ocrConfigs )
443+ require .NoError (t , err )
444+ defer req .Cancel (errors .New ("test end" ))
445+
446+ for range N {
447+ <- dispatcher .msgs
448+ }
449+
450+ assert .Empty (t , dispatcher .msgs )
451+
452+ for i := range 2 * F {
453+ msgNA := & types.MessageBody {
454+ CapabilityId : capInfo .ID ,
455+ CapabilityDonId : capDonInfo .ID ,
456+ CallerDonId : workflowDonInfo .ID ,
457+ Method : types .MethodExecute ,
458+ MessageId : []byte ("messageID" ),
459+ Error : types .Error_INTERNAL_ERROR ,
460+ ErrorMsg : commoncap .ErrResponsePayloadNotAvailable .Error (),
461+ }
462+ msgNA .Sender = capabilityPeers [i ][:]
463+ require .NoError (t , req .OnMessage (ctx , msgNA ))
464+ }
465+
466+ msgOK := & types.MessageBody {
467+ CapabilityId : capInfo .ID ,
468+ CapabilityDonId : capDonInfo .ID ,
469+ CallerDonId : workflowDonInfo .ID ,
470+ Method : types .MethodExecute ,
471+ Payload : rawResponseWithAttestation ,
472+ MessageId : []byte ("messageID" ),
473+ }
474+ msgOK .Sender = capabilityPeers [2 * F ][:]
475+ require .NoError (t , req .OnMessage (ctx , msgOK ))
476+
477+ response := <- req .ResponseChan ()
478+ assertValidResponse (t , response .Result )
479+ })
480+
481+ t .Run ("2F+1 peers return ErrResponsePayloadNotAvailable" , func (t * testing.T ) {
482+ ctx := t .Context ()
483+ dispatcher := & clientRequestTestDispatcher {msgs : make (chan * types.MessageBody , 100 )}
484+ req , err := request .NewClientExecuteRequest (ctx , logger .Test (t ), capabilityRequest , capInfo ,
485+ workflowDonInfo , dispatcher , 10 * time .Minute , nil , "" , ocrConfigs )
486+ require .NoError (t , err )
487+ defer req .Cancel (errors .New ("test end" ))
488+
489+ for range N {
490+ <- dispatcher .msgs
491+ }
492+
493+ assert .Empty (t , dispatcher .msgs )
494+
495+ noPayloadMsg := types.MessageBody {
496+ CapabilityId : capInfo .ID ,
497+ CapabilityDonId : capDonInfo .ID ,
498+ CallerDonId : workflowDonInfo .ID ,
499+ Method : types .MethodExecute ,
500+ MessageId : []byte ("messageID" ),
501+ Error : types .Error_INTERNAL_ERROR ,
502+ ErrorMsg : commoncap .ErrResponsePayloadNotAvailable .Error (),
503+ }
504+
505+ for i := range 2 * F {
506+ noPayloadMsg .Sender = capabilityPeers [i ][:]
507+ require .NoError (t , req .OnMessage (ctx , & noPayloadMsg ))
508+ }
509+
510+ noPayloadMsg .Sender = capabilityPeers [2 * F ][:]
511+ require .Error (t , req .OnMessage (ctx , & noPayloadMsg ))
512+ })
423513 })
424514
425515 t .Run ("Executes full schedule" , func (t * testing.T ) {
0 commit comments