From e16b6cec1784ce2f3f5f62d5ef728ad11e7dd934 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 11 Jun 2024 11:44:37 -0500 Subject: [PATCH 1/9] .github: add PR template (#13507) --- .github/pull_request_template.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000000..daf9acf724f --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,13 @@ + + +https://smartcontract-it.atlassian.net/browse/... + + + +Requires: +- https://github.com/smartcontractkit/chainlink-common/pull/123456 + + + +Supports: +- https://github.com/smartcontractkit/ccip/pull/456789 From cf9a2213b17163411ed685a2ce4fadca8e8b49d2 Mon Sep 17 00:00:00 2001 From: Cedric Date: Tue, 11 Jun 2024 18:01:04 +0100 Subject: [PATCH 2/9] [chore] Don't hardcode the trigger id (#13506) --- core/services/workflows/engine.go | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/core/services/workflows/engine.go b/core/services/workflows/engine.go index 47638f71434..0bedd63f163 100644 --- a/core/services/workflows/engine.go +++ b/core/services/workflows/engine.go @@ -22,11 +22,6 @@ import ( "github.com/smartcontractkit/chainlink/v2/core/services/workflows/store" ) -const ( - // NOTE: max 32 bytes per ID - consider enforcing exactly 32 bytes? - mockedTriggerID = "cccccccccc0000000000000000000000" -) - type donInfo struct { *capabilities.DON PeerID func() *p2ptypes.PeerID @@ -217,8 +212,8 @@ func (e *Engine) init(ctx context.Context) { } e.logger.Debug("registering triggers") - for _, t := range e.workflow.triggers { - err := e.registerTrigger(ctx, t) + for idx, t := range e.workflow.triggers { + err := e.registerTrigger(ctx, t, idx) if err != nil { e.logger.Errorf("failed to register trigger: %s", err) } @@ -277,11 +272,15 @@ func (e *Engine) resumeInProgressExecutions(ctx context.Context) error { return nil } +func generateTriggerId(workflowID string, triggerIdx int) string { + return fmt.Sprintf("wf_%s_trigger_%d", workflowID, triggerIdx) +} + // registerTrigger is used during the initialization phase to bind a trigger to this workflow -func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability) error { +func (e *Engine) registerTrigger(ctx context.Context, t *triggerCapability, triggerIdx int) error { triggerInputs, err := values.NewMap( map[string]any{ - "triggerId": mockedTriggerID, + "triggerId": generateTriggerId(e.workflow.id, triggerIdx), }, ) if err != nil { @@ -649,10 +648,10 @@ func (e *Engine) executeStep(ctx context.Context, l logger.Logger, msg stepReque return inputs, output, err } -func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability) error { +func (e *Engine) deregisterTrigger(ctx context.Context, t *triggerCapability, triggerIdx int) error { triggerInputs, err := values.NewMap( map[string]any{ - "triggerId": mockedTriggerID, + "triggerId": generateTriggerId(e.workflow.id, triggerIdx), }, ) if err != nil { @@ -687,8 +686,8 @@ func (e *Engine) Close() error { // any triggers to ensure no new executions are triggered, // then we'll close down any background goroutines, // and finally, we'll deregister any workflow steps. - for _, t := range e.workflow.triggers { - err := e.deregisterTrigger(ctx, t) + for idx, t := range e.workflow.triggers { + err := e.deregisterTrigger(ctx, t, idx) if err != nil { return err } From 15f02f65c1ac3cfc89e726597a981ddf206eea2b Mon Sep 17 00:00:00 2001 From: Matthew Pendrey Date: Tue, 11 Jun 2024 18:13:50 +0100 Subject: [PATCH 3/9] remove shared secret from transmission protocol (#13501) --- .changeset/pink-ants-reply.md | 5 +++ .../remote/target/request/client_request.go | 8 +---- .../transmission/local_target_capability.go | 8 +---- .../local_target_capability_test.go | 15 ++------ .../capabilities/transmission/transmission.go | 34 ++++++++++++------- .../transmission/transmission_test.go | 31 ++++++++--------- core/scripts/go.mod | 2 +- core/scripts/go.sum | 4 +-- core/services/workflows/delegate.go | 20 ++--------- 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 +-- 15 files changed, 62 insertions(+), 83 deletions(-) create mode 100644 .changeset/pink-ants-reply.md diff --git a/.changeset/pink-ants-reply.md b/.changeset/pink-ants-reply.md new file mode 100644 index 00000000000..fab4ef31f7f --- /dev/null +++ b/.changeset/pink-ants-reply.md @@ -0,0 +1,5 @@ +--- +"chainlink": minor +--- + +#internal remove shared secret from transmission schedule diff --git a/core/capabilities/remote/target/request/client_request.go b/core/capabilities/remote/target/request/client_request.go index 5f49040e0fb..eb33a9ac70a 100644 --- a/core/capabilities/remote/target/request/client_request.go +++ b/core/capabilities/remote/target/request/client_request.go @@ -48,13 +48,7 @@ func NewClientRequest(ctx context.Context, lggr logger.Logger, req commoncap.Cap return nil, fmt.Errorf("failed to marshal capability request: %w", err) } - tc, err := transmission.ExtractTransmissionConfig(req.Config) - if err != nil { - return nil, fmt.Errorf("failed to extract transmission config from request config: %w", err) - } - - peerIDToTransmissionDelay, err := transmission.GetPeerIDToTransmissionDelay(remoteCapabilityDonInfo.Members, localDonInfo.Config.SharedSecret, - messageID, tc) + peerIDToTransmissionDelay, err := transmission.GetPeerIDToTransmissionDelay(remoteCapabilityDonInfo.Members, req) if err != nil { return nil, fmt.Errorf("failed to get peer ID to transmission delay: %w", err) } diff --git a/core/capabilities/transmission/local_target_capability.go b/core/capabilities/transmission/local_target_capability.go index 4fddd93d403..23a9e8f0bf8 100644 --- a/core/capabilities/transmission/local_target_capability.go +++ b/core/capabilities/transmission/local_target_capability.go @@ -34,13 +34,7 @@ func (l *LocalTargetCapability) Execute(ctx context.Context, req capabilities.Ca return l.TargetCapability.Execute(ctx, req) } - tc, err := ExtractTransmissionConfig(req.Config) - if err != nil { - return nil, fmt.Errorf("failed to extract transmission config from request config: %w", err) - } - - peerIDToTransmissionDelay, err := GetPeerIDToTransmissionDelay(l.don.Members, l.don.Config.SharedSecret, - req.Metadata.WorkflowID+req.Metadata.WorkflowExecutionID, tc) + peerIDToTransmissionDelay, err := GetPeerIDToTransmissionDelay(l.don.Members, req) if err != nil { return nil, fmt.Errorf("failed to get peer ID to transmission delay map: %w", err) } diff --git a/core/capabilities/transmission/local_target_capability_test.go b/core/capabilities/transmission/local_target_capability_test.go index 6b4d040f0fa..ef3e6ce5832 100644 --- a/core/capabilities/transmission/local_target_capability_test.go +++ b/core/capabilities/transmission/local_target_capability_test.go @@ -3,7 +3,6 @@ package transmission import ( "context" "crypto/rand" - "encoding/hex" "testing" "time" @@ -44,11 +43,6 @@ func TestScheduledExecutionStrategy_LocalDON(t *testing.T) { }, ) - // The combination of this key and the metadata above - // will yield the permutation [3, 2, 0, 1] - key, err := hex.DecodeString("fb13ca015a9ec60089c7141e9522de79") - require.NoError(t, err) - testCases := []struct { name string position int @@ -67,7 +61,7 @@ func TestScheduledExecutionStrategy_LocalDON(t *testing.T) { name: "position 1; oneAtATime", position: 1, schedule: "oneAtATime", - low: 200 * time.Millisecond, + low: 100 * time.Millisecond, high: 300 * time.Millisecond, }, { @@ -82,7 +76,7 @@ func TestScheduledExecutionStrategy_LocalDON(t *testing.T) { position: 3, schedule: "oneAtATime", low: 100 * time.Millisecond, - high: 200 * time.Millisecond, + high: 300 * time.Millisecond, }, { name: "position 0; allAtOnce", @@ -128,7 +122,7 @@ func TestScheduledExecutionStrategy_LocalDON(t *testing.T) { Config: m, Metadata: capabilities.RequestMetadata{ WorkflowID: "mock-workflow-id", - WorkflowExecutionID: "mock-execution-id", + WorkflowExecutionID: "mock-execution-id-1", }, } @@ -140,9 +134,6 @@ func TestScheduledExecutionStrategy_LocalDON(t *testing.T) { } don := capabilities.DON{ Members: ids, - Config: capabilities.DONConfig{ - SharedSecret: [16]byte(key), - }, } peerID := ids[tc.position] localTargetCapability := NewLocalTargetCapability(log, peerID, don, mt) diff --git a/core/capabilities/transmission/transmission.go b/core/capabilities/transmission/transmission.go index 5121a9bf9f3..b41be5bcaa5 100644 --- a/core/capabilities/transmission/transmission.go +++ b/core/capabilities/transmission/transmission.go @@ -4,13 +4,15 @@ import ( "fmt" "time" - "golang.org/x/crypto/sha3" + "github.com/pkg/errors" "github.com/smartcontractkit/libocr/permutation" - ragep2ptypes "github.com/smartcontractkit/libocr/ragep2p/types" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/values" - p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" + + "golang.org/x/crypto/sha3" ) var ( @@ -25,7 +27,7 @@ type TransmissionConfig struct { DeltaStage time.Duration } -func ExtractTransmissionConfig(config *values.Map) (TransmissionConfig, error) { +func extractTransmissionConfig(config *values.Map) (TransmissionConfig, error) { var tc struct { DeltaStage string Schedule string @@ -47,11 +49,21 @@ func ExtractTransmissionConfig(config *values.Map) (TransmissionConfig, error) { } // GetPeerIDToTransmissionDelay returns a map of PeerID to the time.Duration that the node with that PeerID should wait -// before transmitting. If a node is not in the map, it should not transmit. The sharedSecret is shared by nodes in the -// same DON and used to generate a deterministic schedule for the transmission delays. -func GetPeerIDToTransmissionDelay(donPeerIDs []ragep2ptypes.PeerID, sharedSecret [16]byte, transmissionID string, tc TransmissionConfig) (map[p2ptypes.PeerID]time.Duration, error) { +// before transmitting the capability request. If a node is not in the map, it should not transmit. +func GetPeerIDToTransmissionDelay(donPeerIDs []types.PeerID, req capabilities.CapabilityRequest) (map[types.PeerID]time.Duration, error) { + tc, err := extractTransmissionConfig(req.Config) + if err != nil { + return nil, fmt.Errorf("failed to extract transmission config from request: %w", err) + } + + if req.Metadata.WorkflowID == "" || req.Metadata.WorkflowExecutionID == "" { + return nil, errors.New("workflow ID and workflow execution ID must be set in request metadata") + } + + transmissionID := req.Metadata.WorkflowID + req.Metadata.WorkflowExecutionID + donMemberCount := len(donPeerIDs) - key := transmissionScheduleSeed(sharedSecret, transmissionID) + key := transmissionScheduleSeed(transmissionID) schedule, err := createTransmissionSchedule(tc.Schedule, donMemberCount) if err != nil { return nil, err @@ -59,7 +71,7 @@ func GetPeerIDToTransmissionDelay(donPeerIDs []ragep2ptypes.PeerID, sharedSecret picked := permutation.Permutation(donMemberCount, key) - peerIDToTransmissionDelay := map[p2ptypes.PeerID]time.Duration{} + peerIDToTransmissionDelay := map[types.PeerID]time.Duration{} for i, peerID := range donPeerIDs { delay := delayFor(i, schedule, picked, tc.DeltaStage) if delay != nil { @@ -96,11 +108,9 @@ func createTransmissionSchedule(scheduleType string, N int) ([]int, error) { return nil, fmt.Errorf("unknown schedule type %s", scheduleType) } -func transmissionScheduleSeed(sharedSecret [16]byte, transmissionID string) [16]byte { +func transmissionScheduleSeed(transmissionID string) [16]byte { hash := sha3.NewLegacyKeccak256() - hash.Write(sharedSecret[:]) hash.Write([]byte(transmissionID)) - var key [16]byte copy(key[:], hash.Sum(nil)) return key diff --git a/core/capabilities/transmission/transmission_test.go b/core/capabilities/transmission/transmission_test.go index bbdaaa27fe2..fba233eadb0 100644 --- a/core/capabilities/transmission/transmission_test.go +++ b/core/capabilities/transmission/transmission_test.go @@ -1,7 +1,6 @@ package transmission import ( - "encoding/hex" "fmt" "testing" "time" @@ -9,6 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/values" p2ptypes "github.com/smartcontractkit/chainlink/v2/core/services/p2p/types" ) @@ -26,7 +26,6 @@ func Test_GetPeerIDToTransmissionDelay(t *testing.T) { testCases := []struct { name string peerName string - sharedSecret string schedule string deltaStage string workflowExecutionID string @@ -35,21 +34,19 @@ func Test_GetPeerIDToTransmissionDelay(t *testing.T) { { "TestOneAtATime", "one", - "fb13ca015a9ec60089c7141e9522de79", "oneAtATime", "100ms", "mock-execution-id", map[string]time.Duration{ "one": 300 * time.Millisecond, - "two": 200 * time.Millisecond, + "two": 100 * time.Millisecond, "three": 0 * time.Millisecond, - "four": 100 * time.Millisecond, + "four": 200 * time.Millisecond, }, }, { "TestAllAtOnce", "one", - "fb13ca015a9ec60089c7141e9522de79", "allAtOnce", "100ms", "mock-execution-id", @@ -63,33 +60,35 @@ func Test_GetPeerIDToTransmissionDelay(t *testing.T) { { "TestOneAtATimeWithDifferentExecutionID", "one", - "fb13ca015a9ec60089c7141e9522de79", "oneAtATime", "100ms", "mock-execution-id2", map[string]time.Duration{ "one": 0 * time.Millisecond, - "two": 300 * time.Millisecond, + "two": 200 * time.Millisecond, "three": 100 * time.Millisecond, - "four": 200 * time.Millisecond, + "four": 300 * time.Millisecond, }, }, } for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - sharedSecret, err := hex.DecodeString(tc.sharedSecret) - require.NoError(t, err) - - m, err := values.NewMap(map[string]any{ + transmissionCfg, err := values.NewMap(map[string]any{ "schedule": tc.schedule, "deltaStage": tc.deltaStage, }) require.NoError(t, err) - transmissionCfg, err := ExtractTransmissionConfig(m) - require.NoError(t, err) - peerIdToDelay, err := GetPeerIDToTransmissionDelay(ids, [16]byte(sharedSecret), "mock-workflow-id"+tc.workflowExecutionID, transmissionCfg) + capabilityRequest := capabilities.CapabilityRequest{ + Config: transmissionCfg, + Metadata: capabilities.RequestMetadata{ + WorkflowID: "mock-workflow-id", + WorkflowExecutionID: tc.workflowExecutionID, + }, + } + + peerIdToDelay, err := GetPeerIDToTransmissionDelay(ids, capabilityRequest) require.NoError(t, err) assert.Equal(t, tc.expectedDelays["one"], peerIdToDelay[peer1]) diff --git a/core/scripts/go.mod b/core/scripts/go.mod index 015074faef3..2d7739ba7cb 100644 --- a/core/scripts/go.mod +++ b/core/scripts/go.mod @@ -24,7 +24,7 @@ require ( github.com/prometheus/client_golang v1.17.0 github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef github.com/smartcontractkit/chainlink-vrf v0.0.0-20240222010609-cd67d123c772 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/core/scripts/go.sum b/core/scripts/go.sum index 84a5bbc522f..55462b56394 100644 --- a/core/scripts/go.sum +++ b/core/scripts/go.sum @@ -1212,8 +1212,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce h1:/CjY8L4lVJh9E8NKg3bdAgsxj+zKg9XYtXR71ZWWMXo= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce/go.mod h1:L32xvCpk84Nglit64OhySPMP1tM3TTBK7Tw0qZl7Sd4= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef h1:70N67MKSMYwhGfVMC0Ekfc3yQmFvw3FhXe61M2KZdW4= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef/go.mod h1:L32xvCpk84Nglit64OhySPMP1tM3TTBK7Tw0qZl7Sd4= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240524214833-c362c2ebbd2d h1:5tgMC5Gi2UAOKZ+m28W8ubjLeR0pQCAcrz6eQ0rW510= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240524214833-c362c2ebbd2d/go.mod h1:0UNuO3nDt9MFsZPaHJBEUolxVkN0iC69j1ccDp95e8k= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/core/services/workflows/delegate.go b/core/services/workflows/delegate.go index 219499d443b..eff066af3a1 100644 --- a/core/services/workflows/delegate.go +++ b/core/services/workflows/delegate.go @@ -2,7 +2,6 @@ package workflows import ( "context" - "encoding/hex" "fmt" "github.com/google/uuid" @@ -38,8 +37,8 @@ func (d *Delegate) BeforeJobDeleted(spec job.Job) {} func (d *Delegate) OnDeleteJob(context.Context, job.Job) error { return nil } // ServicesForSpec satisfies the job.Delegate interface. -func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.ServiceCtx, error) { - dinfo, err := initializeDONInfo(d.logger) +func (d *Delegate) ServicesForSpec(_ context.Context, spec job.Job) ([]job.ServiceCtx, error) { + dinfo, err := initializeDONInfo() if err != nil { d.logger.Errorw("could not add initialize don info", err) } @@ -62,17 +61,7 @@ func (d *Delegate) ServicesForSpec(ctx context.Context, spec job.Job) ([]job.Ser return []job.ServiceCtx{engine}, nil } -func initializeDONInfo(lggr logger.Logger) (*capabilities.DON, error) { - var key [16]byte - - // TODO: fetch the key and DONInfo from the registry - keyString := "44fb5c1ee8ee48846c808a383da3aba3" - k, err := hex.DecodeString(keyString) - if err != nil { - lggr.Errorf("could not decode key %s: %w", keyString, err) - } - key = [16]byte(k) - +func initializeDONInfo() (*capabilities.DON, error) { p2pStrings := []string{ "12D3KooWBCF1XT5Wi8FzfgNCqRL76Swv8TRU3TiD4QiJm8NMNX7N", "12D3KooWG1AyvwmCpZ93J8pBQUE1SuzrjDXnT4BeouncHR3jWLCG", @@ -97,9 +86,6 @@ func initializeDONInfo(lggr logger.Logger) (*capabilities.DON, error) { return &capabilities.DON{ ID: "00010203", Members: p2pIDs, - Config: capabilities.DONConfig{ - SharedSecret: key, - }, }, nil } diff --git a/go.mod b/go.mod index 1bbf21835af..3627d68a7b3 100644 --- a/go.mod +++ b/go.mod @@ -72,7 +72,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/smartcontractkit/chain-selectors v1.0.10 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240524214833-c362c2ebbd2d github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 github.com/smartcontractkit/chainlink-feeds v0.0.0-20240522213638-159fb2d99917 diff --git a/go.sum b/go.sum index af9f73918d4..9ddd1f14411 100644 --- a/go.sum +++ b/go.sum @@ -1171,8 +1171,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce h1:/CjY8L4lVJh9E8NKg3bdAgsxj+zKg9XYtXR71ZWWMXo= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce/go.mod h1:L32xvCpk84Nglit64OhySPMP1tM3TTBK7Tw0qZl7Sd4= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef h1:70N67MKSMYwhGfVMC0Ekfc3yQmFvw3FhXe61M2KZdW4= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef/go.mod h1:L32xvCpk84Nglit64OhySPMP1tM3TTBK7Tw0qZl7Sd4= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240524214833-c362c2ebbd2d h1:5tgMC5Gi2UAOKZ+m28W8ubjLeR0pQCAcrz6eQ0rW510= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240524214833-c362c2ebbd2d/go.mod h1:0UNuO3nDt9MFsZPaHJBEUolxVkN0iC69j1ccDp95e8k= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/go.mod b/integration-tests/go.mod index 83fbad89e23..b7758a599c3 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -27,7 +27,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef github.com/smartcontractkit/chainlink-testing-framework v1.30.3 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 diff --git a/integration-tests/go.sum b/integration-tests/go.sum index d53326cba3d..a8ac8556222 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1512,8 +1512,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce h1:/CjY8L4lVJh9E8NKg3bdAgsxj+zKg9XYtXR71ZWWMXo= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce/go.mod h1:L32xvCpk84Nglit64OhySPMP1tM3TTBK7Tw0qZl7Sd4= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef h1:70N67MKSMYwhGfVMC0Ekfc3yQmFvw3FhXe61M2KZdW4= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef/go.mod h1:L32xvCpk84Nglit64OhySPMP1tM3TTBK7Tw0qZl7Sd4= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240524214833-c362c2ebbd2d h1:5tgMC5Gi2UAOKZ+m28W8ubjLeR0pQCAcrz6eQ0rW510= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240524214833-c362c2ebbd2d/go.mod h1:0UNuO3nDt9MFsZPaHJBEUolxVkN0iC69j1ccDp95e8k= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 4ef564b289c..08ab4475078 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -16,7 +16,7 @@ require ( github.com/rs/zerolog v1.30.0 github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 - github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce + github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef github.com/smartcontractkit/chainlink-testing-framework v1.30.3 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 45b5e8fdc7f..85ae0860ae2 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1502,8 +1502,8 @@ github.com/smartcontractkit/chain-selectors v1.0.10 h1:t9kJeE6B6G+hKD0GYR4kGJSCq github.com/smartcontractkit/chain-selectors v1.0.10/go.mod h1:d4Hi+E1zqjy9HqMkjBE5q1vcG9VGgxf5VxiRHfzi2kE= github.com/smartcontractkit/chainlink-automation v1.0.4 h1:iyW181JjKHLNMnDleI8umfIfVVlwC7+n5izbLSFgjw8= github.com/smartcontractkit/chainlink-automation v1.0.4/go.mod h1:u4NbPZKJ5XiayfKHD/v3z3iflQWqvtdhj13jVZXj/cM= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce h1:/CjY8L4lVJh9E8NKg3bdAgsxj+zKg9XYtXR71ZWWMXo= -github.com/smartcontractkit/chainlink-common v0.1.7-0.20240607135320-c9bc0a2ac0ce/go.mod h1:L32xvCpk84Nglit64OhySPMP1tM3TTBK7Tw0qZl7Sd4= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef h1:70N67MKSMYwhGfVMC0Ekfc3yQmFvw3FhXe61M2KZdW4= +github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef/go.mod h1:L32xvCpk84Nglit64OhySPMP1tM3TTBK7Tw0qZl7Sd4= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240524214833-c362c2ebbd2d h1:5tgMC5Gi2UAOKZ+m28W8ubjLeR0pQCAcrz6eQ0rW510= github.com/smartcontractkit/chainlink-cosmos v0.4.1-0.20240524214833-c362c2ebbd2d/go.mod h1:0UNuO3nDt9MFsZPaHJBEUolxVkN0iC69j1ccDp95e8k= github.com/smartcontractkit/chainlink-data-streams v0.0.0-20240220203239-09be0ea34540 h1:xFSv8561jsLtF6gYZr/zW2z5qUUAkcFkApin2mnbYTo= From 813c06026226f23d8b3397ae7b6c2e274c022965 Mon Sep 17 00:00:00 2001 From: Jordan Krage Date: Tue, 11 Jun 2024 13:59:52 -0500 Subject: [PATCH 4/9] core/capabilities/remote/target: defer WaitGroup.Done; Close services on t.Cleanup; elinimate redundant context cancellation (#13492) --- .../capabilities/remote/target/client_test.go | 21 ++++------- .../remote/target/endtoend_test.go | 32 ++++++----------- .../capabilities/remote/target/server_test.go | 9 ++--- .../v21/logprovider/integration_test.go | 3 +- .../threshold/decryption_queue_test.go | 36 +++++++------------ 5 files changed, 33 insertions(+), 68 deletions(-) diff --git a/core/capabilities/remote/target/client_test.go b/core/capabilities/remote/target/client_test.go index 8665ffe7544..5f9261eed8f 100644 --- a/core/capabilities/remote/target/client_test.go +++ b/core/capabilities/remote/target/client_test.go @@ -11,7 +11,7 @@ import ( commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" "github.com/smartcontractkit/chainlink-common/pkg/capabilities/pb" - "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" @@ -22,8 +22,7 @@ import ( ) func Test_Client_DonTopologies(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) transmissionSchedule, err := values.NewMap(map[string]any{ "schedule": transmission.Schedule_OneAtATime, @@ -60,8 +59,7 @@ func Test_Client_DonTopologies(t *testing.T) { } func Test_Client_TransmissionSchedules(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) @@ -99,8 +97,7 @@ func Test_Client_TransmissionSchedules(t *testing.T) { } func Test_Client_TimesOutIfInsufficientCapabilityPeerResponses(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) @@ -166,14 +163,13 @@ func testClient(ctx context.Context, t *testing.T, numWorkflowPeers int, workflo } callers := make([]commoncap.TargetCapability, numWorkflowPeers) - srvcs := make([]services.Service, numWorkflowPeers) + for i := 0; i < numWorkflowPeers; i++ { workflowPeerDispatcher := broker.NewDispatcherForNode(workflowPeers[i]) caller := target.NewClient(capInfo, workflowDonInfo, workflowPeerDispatcher, workflowNodeResponseTimeout, lggr) - require.NoError(t, caller.Start(ctx)) + servicetest.Run(t, caller) broker.RegisterReceiverNode(workflowPeers[i], caller) callers[i] = caller - srvcs[i] = caller } executeInputs, err := values.NewMap( @@ -190,6 +186,7 @@ func testClient(ctx context.Context, t *testing.T, numWorkflowPeers int, workflo // Fire off all the requests for _, caller := range callers { go func(caller commoncap.TargetCapability) { + defer wg.Done() responseCh, err := caller.Execute(ctx, commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ @@ -201,14 +198,10 @@ func testClient(ctx context.Context, t *testing.T, numWorkflowPeers int, workflo }) responseTest(t, responseCh, err) - wg.Done() }(caller) } wg.Wait() - for i := 0; i < numWorkflowPeers; i++ { - require.NoError(t, srvcs[i].Close()) - } } // Simple client that only responds once it has received a message from each workflow peer diff --git a/core/capabilities/remote/target/endtoend_test.go b/core/capabilities/remote/target/endtoend_test.go index a5379250e5e..c9e9fea28f0 100644 --- a/core/capabilities/remote/target/endtoend_test.go +++ b/core/capabilities/remote/target/endtoend_test.go @@ -14,7 +14,7 @@ import ( "github.com/stretchr/testify/require" commoncap "github.com/smartcontractkit/chainlink-common/pkg/capabilities" - "github.com/smartcontractkit/chainlink-common/pkg/services" + "github.com/smartcontractkit/chainlink-common/pkg/services/servicetest" "github.com/smartcontractkit/chainlink-common/pkg/values" "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/target" remotetypes "github.com/smartcontractkit/chainlink/v2/core/capabilities/remote/types" @@ -25,8 +25,7 @@ import ( ) func Test_RemoteTargetCapability_InsufficientCapabilityResponses(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) @@ -46,8 +45,7 @@ func Test_RemoteTargetCapability_InsufficientCapabilityResponses(t *testing.T) { } func Test_RemoteTargetCapability_InsufficientWorkflowRequests(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) @@ -69,8 +67,7 @@ func Test_RemoteTargetCapability_InsufficientWorkflowRequests(t *testing.T) { } func Test_RemoteTargetCapability_TransmissionSchedules(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) @@ -102,8 +99,7 @@ func Test_RemoteTargetCapability_TransmissionSchedules(t *testing.T) { } func Test_RemoteTargetCapability_DonTopologies(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) @@ -138,8 +134,7 @@ func Test_RemoteTargetCapability_DonTopologies(t *testing.T) { } func Test_RemoteTargetCapability_CapabilityError(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) @@ -159,8 +154,7 @@ func Test_RemoteTargetCapability_CapabilityError(t *testing.T) { } func Test_RemoteTargetCapability_RandomCapabilityError(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) responseTest := func(t *testing.T, responseCh <-chan commoncap.CapabilityResponse, responseError error) { require.NoError(t, responseError) @@ -226,27 +220,24 @@ func testRemoteTarget(ctx context.Context, t *testing.T, underlying commoncap.Ta workflowDonInfo.ID: workflowDonInfo, } - srvcs := []services.Service{} capabilityNodes := make([]remotetypes.Receiver, numCapabilityPeers) for i := 0; i < numCapabilityPeers; i++ { capabilityPeer := capabilityPeers[i] capabilityDispatcher := broker.NewDispatcherForNode(capabilityPeer) capabilityNode := target.NewServer(capabilityPeer, underlying, capInfo, capDonInfo, workflowDONs, capabilityDispatcher, capabilityNodeResponseTimeout, lggr) - require.NoError(t, capabilityNode.Start(ctx)) + servicetest.Run(t, capabilityNode) broker.RegisterReceiverNode(capabilityPeer, capabilityNode) capabilityNodes[i] = capabilityNode - srvcs = append(srvcs, capabilityNode) } workflowNodes := make([]commoncap.TargetCapability, numWorkflowPeers) for i := 0; i < numWorkflowPeers; i++ { workflowPeerDispatcher := broker.NewDispatcherForNode(workflowPeers[i]) workflowNode := target.NewClient(capInfo, workflowDonInfo, workflowPeerDispatcher, workflowNodeTimeout, lggr) - require.NoError(t, workflowNode.Start(ctx)) + servicetest.Run(t, workflowNode) broker.RegisterReceiverNode(workflowPeers[i], workflowNode) workflowNodes[i] = workflowNode - srvcs = append(srvcs, workflowNode) } executeInputs, err := values.NewMap( @@ -262,6 +253,7 @@ func testRemoteTarget(ctx context.Context, t *testing.T, underlying commoncap.Ta for _, caller := range workflowNodes { go func(caller commoncap.TargetCapability) { + defer wg.Done() responseCh, err := caller.Execute(ctx, commoncap.CapabilityRequest{ Metadata: commoncap.RequestMetadata{ @@ -273,14 +265,10 @@ func testRemoteTarget(ctx context.Context, t *testing.T, underlying commoncap.Ta }) responseTest(t, responseCh, err) - wg.Done() }(caller) } wg.Wait() - for _, srv := range srvcs { - require.NoError(t, srv.Close()) - } } type testMessageBroker struct { diff --git a/core/capabilities/remote/target/server_test.go b/core/capabilities/remote/target/server_test.go index e6d85ebff25..80c0d5bc6e0 100644 --- a/core/capabilities/remote/target/server_test.go +++ b/core/capabilities/remote/target/server_test.go @@ -19,8 +19,7 @@ import ( ) func Test_Server_RespondsAfterSufficientRequests(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) numCapabilityPeers := 4 @@ -47,8 +46,7 @@ func Test_Server_RespondsAfterSufficientRequests(t *testing.T) { } func Test_Server_InsufficientCallers(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) numCapabilityPeers := 4 @@ -75,8 +73,7 @@ func Test_Server_InsufficientCallers(t *testing.T) { } func Test_Server_CapabilityError(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) numCapabilityPeers := 4 diff --git a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go index 46314dde418..ace17ca2dbc 100644 --- a/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go +++ b/core/services/ocr2/plugins/ocr2keeper/evmregistry/v21/logprovider/integration_test.go @@ -145,8 +145,7 @@ func TestIntegration_LogEventProvider(t *testing.T) { } func TestIntegration_LogEventProvider_UpdateConfig(t *testing.T) { - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) backend, stopMining, accounts := setupBackend(t) defer stopMining() diff --git a/core/services/ocr2/plugins/threshold/decryption_queue_test.go b/core/services/ocr2/plugins/threshold/decryption_queue_test.go index 2a9f8d4c85b..a017b883b3d 100644 --- a/core/services/ocr2/plugins/threshold/decryption_queue_test.go +++ b/core/services/ocr2/plugins/threshold/decryption_queue_test.go @@ -36,8 +36,7 @@ func Test_decryptionQueue_Decrypt_ReturnResultAfterCallingDecrypt(t *testing.T) dq.SetResult([]byte("1"), []byte("decrypted"), nil) }() - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) pt, err := dq.Decrypt(ctx, []byte("1"), []byte("encrypted")) require.NoError(t, err) @@ -50,8 +49,7 @@ func Test_decryptionQueue_Decrypt_CiphertextIdTooLarge(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(1, 1000, 16, testutils.WaitTimeout(t), lggr) - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) _, err := dq.Decrypt(ctx, []byte("largeCiphertextId"), []byte("ciphertext")) assert.Equal(t, err.Error(), "ciphertextId too large") @@ -61,8 +59,7 @@ func Test_decryptionQueue_Decrypt_EmptyCiphertextId(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(1, 1000, 64, testutils.WaitTimeout(t), lggr) - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) _, err := dq.Decrypt(ctx, []byte(""), []byte("ciphertext")) assert.Equal(t, err.Error(), "ciphertextId is empty") @@ -72,8 +69,7 @@ func Test_decryptionQueue_Decrypt_CiphertextTooLarge(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(1, 10, 64, testutils.WaitTimeout(t), lggr) - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) _, err := dq.Decrypt(ctx, []byte("1"), []byte("largeciphertext")) assert.Equal(t, err.Error(), "ciphertext too large") @@ -83,8 +79,7 @@ func Test_decryptionQueue_Decrypt_EmptyCiphertext(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(1, 1000, 64, testutils.WaitTimeout(t), lggr) - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) _, err := dq.Decrypt(ctx, []byte("1"), []byte("")) assert.Equal(t, err.Error(), "ciphertext is empty") @@ -94,8 +89,7 @@ func Test_decryptionQueue_Decrypt_DuplicateCiphertextId(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(1, 1000, 64, testutils.WaitTimeout(t), lggr) - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) go func() { _, err := dq.Decrypt(ctx, []byte("1"), []byte("encrypted")) @@ -179,8 +173,7 @@ func Test_decryptionQueue_GetCiphertext(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(3, 1000, 64, testutils.WaitTimeout(t), lggr) - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) go func() { _, err := dq.Decrypt(ctx, []byte("7"), []byte("encrypted")) @@ -210,8 +203,7 @@ func Test_decryptionQueue_Decrypt_DecryptCalledAfterReadyResult(t *testing.T) { dq.SetResult([]byte("9"), []byte("decrypted"), nil) - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) pt, err := dq.Decrypt(ctx, []byte("9"), []byte("encrypted")) require.NoError(t, err) @@ -264,8 +256,7 @@ func Test_decryptionQueue_Decrypt_UserErrorDuringDecryption(t *testing.T) { dq.SetResult(ciphertextId, nil, decryptionPlugin.ErrAggregation) }() - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) _, err := dq.Decrypt(ctx, ciphertextId, []byte("encrypted")) assert.Equal(t, err.Error(), "pending decryption request for ciphertextId 0x120f was closed without a response") @@ -281,8 +272,7 @@ func Test_decryptionQueue_Decrypt_HandleClosedChannelWithoutPlaintextResponse(t close(dq.pendingRequests[string(ciphertextId)].chPlaintext) }() - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) _, err := dq.Decrypt(ctx, ciphertextId, []byte("encrypted")) assert.Equal(t, err.Error(), "pending decryption request for ciphertextId 0x00ff was closed without a response") @@ -380,8 +370,7 @@ func Test_decryptionQueue_GetRequests_PendingRequestQueueShorterThanRequestCount lggr := logger.TestLogger(t) dq := NewDecryptionQueue(4, 1000, 64, testutils.WaitTimeout(t), lggr) - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) go func() { _, err := dq.Decrypt(ctx, []byte("11"), []byte("encrypted")) @@ -425,8 +414,7 @@ func Test_decryptionQueue_Start(t *testing.T) { lggr := logger.TestLogger(t) dq := NewDecryptionQueue(4, 1000, 64, testutils.WaitTimeout(t), lggr) - ctx, cancel := context.WithCancel(testutils.Context(t)) - defer cancel() + ctx := testutils.Context(t) err := dq.Start(ctx) From 9647852fe2399ad19ee376b7ee5ef6d24c6aca59 Mon Sep 17 00:00:00 2001 From: Lukasz <120112546+lukaszcl@users.noreply.github.com> Date: Tue, 11 Jun 2024 23:59:48 +0200 Subject: [PATCH 5/9] Add test for reorg above finality (#13513) * Add test for reorg above finality * Fix * Bump CTF * Fix replace * Fix goimports --- integration-tests/docker/test_env/cl_node.go | 14 +++- integration-tests/go.mod | 2 +- integration-tests/go.sum | 4 +- integration-tests/load/go.mod | 2 +- integration-tests/load/go.sum | 4 +- .../smoke/reorg_above_finality_test.go | 83 +++++++++++++++++++ 6 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 integration-tests/smoke/reorg_above_finality_test.go diff --git a/integration-tests/docker/test_env/cl_node.go b/integration-tests/docker/test_env/cl_node.go index 90b237ac6a1..73e22c58ab3 100644 --- a/integration-tests/docker/test_env/cl_node.go +++ b/integration-tests/docker/test_env/cl_node.go @@ -352,6 +352,8 @@ func (n *ClNode) containerStartOrRestart(restartDb bool) error { Str("userEmail", n.UserEmail). Str("userPassword", n.UserPassword). Msg("Started Chainlink Node container") + nodeConfig, _ := n.GetNodeConfigStr() + n.l.Info().Str("containerName", n.ContainerName).Msgf("Chainlink Node config:\n%s", nodeConfig) clClient, err := client.NewChainlinkClient(&client.ChainlinkConfig{ URL: clEndpoint, Email: n.UserEmail, @@ -399,17 +401,25 @@ func (n *ClNode) ExecGetVersion() (string, error) { return "", errors.Errorf("could not find chainlink version in command output '%'", output) } +func (n ClNode) GetNodeConfigStr() (string, error) { + data, err := toml.Marshal(n.NodeConfig) + if err != nil { + return "", err + } + return string(data), nil +} + func (n *ClNode) getContainerRequest(secrets string) ( *tc.ContainerRequest, error) { configFile, err := os.CreateTemp("", "node_config") if err != nil { return nil, err } - data, err := toml.Marshal(n.NodeConfig) + configStr, err := n.GetNodeConfigStr() if err != nil { return nil, err } - _, err = configFile.WriteString(string(data)) + _, err = configFile.WriteString(configStr) if err != nil { return nil, err } diff --git a/integration-tests/go.mod b/integration-tests/go.mod index b7758a599c3..25598610c6b 100644 --- a/integration-tests/go.mod +++ b/integration-tests/go.mod @@ -28,7 +28,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef - github.com/smartcontractkit/chainlink-testing-framework v1.30.3 + github.com/smartcontractkit/chainlink-testing-framework v1.30.4 github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 github.com/smartcontractkit/chainlink/v2 v2.0.0-00010101000000-000000000000 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/integration-tests/go.sum b/integration-tests/go.sum index a8ac8556222..376233fc0d2 100644 --- a/integration-tests/go.sum +++ b/integration-tests/go.sum @@ -1524,8 +1524,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240605170242-555ff582f36 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240605170242-555ff582f36a/go.mod h1:QqcZSwLgEIn7YraAIRmomnBMAuVFephiHrIWVlkWbFI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240531021326-99118e47f696 h1:h1E87+z+JcUEfvbJVF56SnZA/YUFE5ewUE61MaR/Ewg= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240531021326-99118e47f696/go.mod h1:OiWUTrrpSLLTMh7FINWjEh6mmDJCVPaC4yEsDCVaWdU= -github.com/smartcontractkit/chainlink-testing-framework v1.30.3 h1:3mL0dBI/+8nTSh9GdxYyhNIAPTjSBThPGJnjcjjDaIg= -github.com/smartcontractkit/chainlink-testing-framework v1.30.3/go.mod h1:E6uNEZhZZid9PHv6/Kq5Vn63GlO61ZcKB+/f0DKo3Q4= +github.com/smartcontractkit/chainlink-testing-framework v1.30.4 h1:kf6zRL6v5D047gynYNNqXGl9QBvnQSa4LMs1iHLRu64= +github.com/smartcontractkit/chainlink-testing-framework v1.30.4/go.mod h1:E6uNEZhZZid9PHv6/Kq5Vn63GlO61ZcKB+/f0DKo3Q4= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240328204215-ac91f55f1449 h1:fX/xmGm1GBsD1ZZnooNT+eWA0hiTAqFlHzOC5CY4dy8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240328204215-ac91f55f1449/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= diff --git a/integration-tests/load/go.mod b/integration-tests/load/go.mod index 08ab4475078..8f70870bcb4 100644 --- a/integration-tests/load/go.mod +++ b/integration-tests/load/go.mod @@ -17,7 +17,7 @@ require ( github.com/slack-go/slack v0.12.2 github.com/smartcontractkit/chainlink-automation v1.0.4 github.com/smartcontractkit/chainlink-common v0.1.7-0.20240611144925-2baf0f2a3fef - github.com/smartcontractkit/chainlink-testing-framework v1.30.3 + github.com/smartcontractkit/chainlink-testing-framework v1.30.4 github.com/smartcontractkit/chainlink/integration-tests v0.0.0-20240214231432-4ad5eb95178c github.com/smartcontractkit/chainlink/v2 v2.9.0-beta0.0.20240216210048-da02459ddad8 github.com/smartcontractkit/libocr v0.0.0-20240419185742-fd3cab206b2c diff --git a/integration-tests/load/go.sum b/integration-tests/load/go.sum index 85ae0860ae2..832c83cb3e6 100644 --- a/integration-tests/load/go.sum +++ b/integration-tests/load/go.sum @@ -1514,8 +1514,8 @@ github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240605170242-555ff582f36 github.com/smartcontractkit/chainlink-solana v1.0.3-0.20240605170242-555ff582f36a/go.mod h1:QqcZSwLgEIn7YraAIRmomnBMAuVFephiHrIWVlkWbFI= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240531021326-99118e47f696 h1:h1E87+z+JcUEfvbJVF56SnZA/YUFE5ewUE61MaR/Ewg= github.com/smartcontractkit/chainlink-starknet/relayer v0.0.1-beta-test.0.20240531021326-99118e47f696/go.mod h1:OiWUTrrpSLLTMh7FINWjEh6mmDJCVPaC4yEsDCVaWdU= -github.com/smartcontractkit/chainlink-testing-framework v1.30.3 h1:3mL0dBI/+8nTSh9GdxYyhNIAPTjSBThPGJnjcjjDaIg= -github.com/smartcontractkit/chainlink-testing-framework v1.30.3/go.mod h1:E6uNEZhZZid9PHv6/Kq5Vn63GlO61ZcKB+/f0DKo3Q4= +github.com/smartcontractkit/chainlink-testing-framework v1.30.4 h1:kf6zRL6v5D047gynYNNqXGl9QBvnQSa4LMs1iHLRu64= +github.com/smartcontractkit/chainlink-testing-framework v1.30.4/go.mod h1:E6uNEZhZZid9PHv6/Kq5Vn63GlO61ZcKB+/f0DKo3Q4= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240328204215-ac91f55f1449 h1:fX/xmGm1GBsD1ZZnooNT+eWA0hiTAqFlHzOC5CY4dy8= github.com/smartcontractkit/chainlink-testing-framework/grafana v0.0.0-20240328204215-ac91f55f1449/go.mod h1:DC8sQMyTlI/44UCTL8QWFwb0bYNoXCfjwCv2hMivYZU= github.com/smartcontractkit/chainlink-vrf v0.0.0-20231120191722-fef03814f868 h1:FFdvEzlYwcuVHkdZ8YnZR/XomeMGbz5E2F2HZI3I3w8= diff --git a/integration-tests/smoke/reorg_above_finality_test.go b/integration-tests/smoke/reorg_above_finality_test.go new file mode 100644 index 00000000000..26e909e84e8 --- /dev/null +++ b/integration-tests/smoke/reorg_above_finality_test.go @@ -0,0 +1,83 @@ +package smoke + +import ( + "math/big" + "testing" + "time" + + ctf_client "github.com/smartcontractkit/chainlink-testing-framework/client" + + "github.com/stretchr/testify/require" + + "github.com/smartcontractkit/chainlink-testing-framework/logging" + "github.com/smartcontractkit/chainlink/integration-tests/actions" + "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" + tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" +) + +func TestReorgAboveFinality(t *testing.T) { + t.Parallel() + + l := logging.GetTestLogger(t) + config, err := tc.GetConfig("Smoke", tc.OCR2) + require.NoError(t, err, "Error getting config") + + privateNetworkConf, err := actions.EthereumNetworkConfigFromConfig(l, &config) + require.NoError(t, err) + + nodeFinalityDepthInt := int64(10) + + testEnv, err := test_env.NewCLTestEnvBuilder(). + WithTestInstance(t). + WithTestConfig(&config). + WithPrivateEthereumNetwork(privateNetworkConf.EthereumNetworkConfig). + WithMockAdapter(). + WithCLNodes(6). + WithFunding(big.NewFloat(*config.Common.ChainlinkNodeFunding)). + WithoutCleanup(). + WithSeth(). + Build() + require.NoError(t, err) + + network := testEnv.EVMNetworks[0] + client := ctf_client.NewRPCClient(network.HTTPURLs[0]) + + // Wait for chain to progress + targetBlockNumber := nodeFinalityDepthInt * 3 + require.Eventually(t, func() bool { + bn, err := client.BlockNumber() + require.NoError(t, err) + l.Info().Int64("blockNumber", bn).Int64("targetBlockNumber", targetBlockNumber).Msg("Waiting for chain to progress above target block number") + return bn > nodeFinalityDepthInt*3 + }, 3*time.Minute, 3*time.Second, "chain did not progress above the target block number") + + // Run reorg above finality depth + reorgDepth := int(nodeFinalityDepthInt) + 20 + l.Info(). + Str("URL", client.URL). + Int64("nodeFinalityDepth", nodeFinalityDepthInt). + Int("reorgDepth", reorgDepth). + Msg("Starting blockchain reorg on Simulated Geth chain") + err = client.GethSetHead(reorgDepth) + require.NoError(t, err, "Error starting blockchain reorg on Simulated Geth chain") + + l.Info().Msg("Waiting for all nodes to report finality violation") + nodes := testEnv.ClCluster.NodeAPIs() + require.Eventually(t, func() bool { + violatedResponses := 0 + for _, node := range nodes { + resp, _, err := node.Health() + require.NoError(t, err) + for _, d := range resp.Data { + if d.Attributes.Name == "EVM.1337.LogPoller" && d.Attributes.Output == "finality violated" && d.Attributes.Status == "failing" { + violatedResponses++ + } + } + l.Info().Msgf("Resp: %v", resp) + } + + l.Info().Int("violatedResponses", violatedResponses).Int("nodes", len(nodes)).Msg("Checking if all nodes reported finality violation") + return violatedResponses == len(nodes) + }, 3*time.Minute, 5*time.Second, "not all the nodes report finality violation") + l.Info().Msg("All nodes reported finality violation") +} From 76506ba87bbece3309b554190f6785d74270bf8b Mon Sep 17 00:00:00 2001 From: Erik Burton Date: Tue, 11 Jun 2024 15:19:54 -0700 Subject: [PATCH 6/9] chore: releng gha version bumps (#13515) * chore: update gha-workflow-validator to 0.2.0 * chore: update push-gha-metrics-action to 3.0.1 * chore: pin setup-gap to 0.2.2 --- .../workflows/automation-nightly-tests.yml | 2 +- .../workflows/automation-ondemand-tests.yml | 2 +- .github/workflows/ci-core.yml | 2 +- .../evm-version-compatibility-tests.yml | 2 +- .github/workflows/gha-workflow-validation.yml | 4 ++-- .github/workflows/integration-tests.yml | 6 ++--- .github/workflows/live-testnet-tests.yml | 22 +++++++++---------- .github/workflows/live-vrf-tests.yml | 2 +- .github/workflows/solidity.yml | 6 +++-- 9 files changed, 25 insertions(+), 23 deletions(-) diff --git a/.github/workflows/automation-nightly-tests.yml b/.github/workflows/automation-nightly-tests.yml index c4c6a4be063..183ead14477 100644 --- a/.github/workflows/automation-nightly-tests.yml +++ b/.github/workflows/automation-nightly-tests.yml @@ -88,7 +88,7 @@ jobs: with: ref: ${{ github.head_ref || github.ref_name }} - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} diff --git a/.github/workflows/automation-ondemand-tests.yml b/.github/workflows/automation-ondemand-tests.yml index a42ddf81e56..b2212dc5fb4 100644 --- a/.github/workflows/automation-ondemand-tests.yml +++ b/.github/workflows/automation-ondemand-tests.yml @@ -218,7 +218,7 @@ jobs: echo "version=${{ inputs.chainlinkVersionUpdate }}" >>$GITHUB_OUTPUT fi - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} diff --git a/.github/workflows/ci-core.yml b/.github/workflows/ci-core.yml index 9f6fbd8fae4..02fa900bf95 100644 --- a/.github/workflows/ci-core.yml +++ b/.github/workflows/ci-core.yml @@ -225,7 +225,7 @@ jobs: - name: Collect Metrics if: ${{ needs.filter.outputs.changes == 'true' && always() }} id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@2954caaadb1b194740b24fde41daf3f4e6d1eba7 + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: id: ${{ matrix.type.id }} org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} diff --git a/.github/workflows/evm-version-compatibility-tests.yml b/.github/workflows/evm-version-compatibility-tests.yml index d67abb6a24c..a14d46cc790 100644 --- a/.github/workflows/evm-version-compatibility-tests.yml +++ b/.github/workflows/evm-version-compatibility-tests.yml @@ -229,7 +229,7 @@ jobs: echo "run_command=./smoke/${{ matrix.evm_node.product }}_test.go" >> "$GITHUB_OUTPUT" fi - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} diff --git a/.github/workflows/gha-workflow-validation.yml b/.github/workflows/gha-workflow-validation.yml index b48e4a0f922..1ec502432ca 100644 --- a/.github/workflows/gha-workflow-validation.yml +++ b/.github/workflows/gha-workflow-validation.yml @@ -14,14 +14,14 @@ jobs: runs-on: ubuntu-latest steps: - name: GHA Workflow Validator - uses: smartcontractkit/.github/actions/gha-workflow-validator@7d4c3591affba99d0b073e527569ec6638518d41 # gha-workflow-validator@0.1.0 + uses: smartcontractkit/.github/actions/gha-workflow-validator@d316f66b2990ea4daa479daa3de6fc92b00f863e # gha-workflow-validator@0.2.0 env: GITHUB_TOKEN: ${{ github.token }} - name: Collect Metrics if: always() id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@dea9b546553cb4ca936607c2267a09c004e4ab3f # v3.0.0 + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: id: lint-gh-workflows org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index d57ac9c26e2..c56b67e2f60 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -322,7 +322,7 @@ jobs: echo "run_command=./smoke/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" fi - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -437,7 +437,7 @@ jobs: echo "run_command=./smoke/${{ matrix.product.name }}_test.go" >> "$GITHUB_OUTPUT" fi - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -660,7 +660,7 @@ jobs: run: | docker logs otel-collector - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} diff --git a/.github/workflows/live-testnet-tests.yml b/.github/workflows/live-testnet-tests.yml index 667c8a2074f..b9ecde6116d 100644 --- a/.github/workflows/live-testnet-tests.yml +++ b/.github/workflows/live-testnet-tests.yml @@ -248,7 +248,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -331,7 +331,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -414,7 +414,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -497,7 +497,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -576,7 +576,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -659,7 +659,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -742,7 +742,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -825,7 +825,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -904,7 +904,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -983,7 +983,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} @@ -1062,7 +1062,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} diff --git a/.github/workflows/live-vrf-tests.yml b/.github/workflows/live-vrf-tests.yml index 745d7db19fb..22bc2fed345 100644 --- a/.github/workflows/live-vrf-tests.yml +++ b/.github/workflows/live-vrf-tests.yml @@ -139,7 +139,7 @@ jobs: with: fetch-depth: 0 - name: Setup GAP for Grafana - uses: smartcontractkit/.github/actions/setup-gap@main + uses: smartcontractkit/.github/actions/setup-gap@6c9d62fdad050cfb8b59376ded291f1350705944 # setup-gap@0.2.2 with: # aws inputs aws-region: ${{ secrets.AWS_REGION }} diff --git a/.github/workflows/solidity.yml b/.github/workflows/solidity.yml index 50e00b4583d..dff35b3cc93 100644 --- a/.github/workflows/solidity.yml +++ b/.github/workflows/solidity.yml @@ -192,8 +192,9 @@ jobs: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@0281b09807758be1dcc41651e44e62b353808c47 # v2.1.0 + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: + id: solidity-publish-beta org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} @@ -234,8 +235,9 @@ jobs: - name: Collect Metrics id: collect-gha-metrics - uses: smartcontractkit/push-gha-metrics-action@0281b09807758be1dcc41651e44e62b353808c47 # v2.1.0 + uses: smartcontractkit/push-gha-metrics-action@d9da21a2747016b3e13de58c7d4115a3d5c97935 # v3.0.1 with: + id: solitidy-publish-prod org-id: ${{ secrets.GRAFANA_INTERNAL_TENANT_ID }} basic-auth: ${{ secrets.GRAFANA_INTERNAL_BASIC_AUTH }} hostname: ${{ secrets.GRAFANA_INTERNAL_HOST }} From ca8391fae5b1714f6d0370a83e1bcd8c0f0d70cb Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Tue, 11 Jun 2024 19:02:33 -0400 Subject: [PATCH 7/9] Better Fund Return with More Wallets (#13517) --- integration-tests/actions/actions.go | 54 ++++++++++++++++++++++++---- 1 file changed, 47 insertions(+), 7 deletions(-) diff --git a/integration-tests/actions/actions.go b/integration-tests/actions/actions.go index d666a497666..2a55ae5b946 100644 --- a/integration-tests/actions/actions.go +++ b/integration-tests/actions/actions.go @@ -4,6 +4,7 @@ package actions import ( "context" "crypto/ecdsa" + "encoding/hex" "encoding/json" "errors" "fmt" @@ -362,8 +363,9 @@ func DeleteAllJobs(chainlinkNodes []*client.ChainlinkK8sClient) error { return nil } -// ReturnFunds attempts to return all the funds from the chainlink nodes to the network's default address -// all from a remote, k8s style environment +// ReturnFunds attempts to return all the funds from the chainlink nodes and other wallets to the network's default wallet, +// which will always be the first wallet in the list of wallets. If errors are encountered, it will keep trying other wallets +// and return all errors encountered. func ReturnFunds(chainlinkNodes []*client.ChainlinkK8sClient, blockchainClient blockchain.EVMClient) error { if blockchainClient == nil { return fmt.Errorf("blockchain client is nil, unable to return funds from chainlink nodes") @@ -375,29 +377,67 @@ func ReturnFunds(chainlinkNodes []*client.ChainlinkK8sClient, blockchainClient b return nil } + // If we fail to return funds from some addresses, we still want to try to return funds from the rest + encounteredErrors := []error{} + + if len(blockchainClient.GetWallets()) > 1 { + if err := blockchainClient.SetDefaultWallet(0); err != nil { + encounteredErrors = append(encounteredErrors, err) + } else { + for walletIndex := 1; walletIndex < len(blockchainClient.GetWallets()); walletIndex++ { + decodedKey, err := hex.DecodeString(blockchainClient.GetWallets()[walletIndex].PrivateKey()) + if err != nil { + encounteredErrors = append(encounteredErrors, err) + continue + } + privKey, err := crypto.ToECDSA(decodedKey) + if err != nil { + encounteredErrors = append(encounteredErrors, err) + continue + } + + err = blockchainClient.ReturnFunds(privKey) + if err != nil { + encounteredErrors = append(encounteredErrors, err) + continue + } + } + } + } + for _, chainlinkNode := range chainlinkNodes { fundedKeys, err := chainlinkNode.ExportEVMKeysForChain(blockchainClient.GetChainID().String()) if err != nil { - return err + encounteredErrors = append(encounteredErrors, err) + continue } for _, key := range fundedKeys { keyToDecrypt, err := json.Marshal(key) if err != nil { - return err + encounteredErrors = append(encounteredErrors, err) + continue } // This can take up a good bit of RAM and time. When running on the remote-test-runner, this can lead to OOM // issues. So we avoid running in parallel; slower, but safer. decryptedKey, err := keystore.DecryptKey(keyToDecrypt, client.ChainlinkKeyPassword) if err != nil { - return err + encounteredErrors = append(encounteredErrors, err) + continue } err = blockchainClient.ReturnFunds(decryptedKey.PrivateKey) if err != nil { - log.Error().Err(err).Str("Address", fundedKeys[0].Address).Msg("Error returning funds from Chainlink node") + encounteredErrors = append(encounteredErrors, fmt.Errorf("error returning funds from chainlink node: %w", err)) + continue } } } - return blockchainClient.WaitForEvents() + if err := blockchainClient.WaitForEvents(); err != nil { + encounteredErrors = append(encounteredErrors, err) + } + if len(encounteredErrors) > 0 { + return fmt.Errorf("encountered errors while returning funds: %v", encounteredErrors) + } + return nil } // FundAddresses will fund a list of addresses with an amount of native currency From 0d305d776bba946620298d998cefeeb37349c1b6 Mon Sep 17 00:00:00 2001 From: Adam Hamrick Date: Tue, 11 Jun 2024 20:31:30 -0400 Subject: [PATCH 8/9] Adds missing GHA versions (#13510) --- .github/workflows/client-compatibility-tests.yml | 2 +- .github/workflows/on-demand-keeper-smoke-tests.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/client-compatibility-tests.yml b/.github/workflows/client-compatibility-tests.yml index 595a497c1eb..6734a6738a7 100644 --- a/.github/workflows/client-compatibility-tests.yml +++ b/.github/workflows/client-compatibility-tests.yml @@ -39,7 +39,7 @@ jobs: expression: '^[0-9]+\.[0-9]+\.[0-9]+(\-slots\-per\-epoch)?' steps: - name: Update internal ECR if the latest Ethereum client image does not exist - uses: smartcontractkit/chainlink-testing-framework/.github/actions/update-internal-mirrors@7eb04a030823b316d8dd5bb555f1e49593a503fc + uses: smartcontractkit/chainlink-testing-framework/.github/actions/update-internal-mirrors@5eea86ee4f7742b4e944561a570a6b268e712d9e # v1.30.3 with: aws_region: ${{ secrets.QA_AWS_REGION }} role_to_assume: ${{ secrets.QA_AWS_ROLE_TO_ASSUME }} diff --git a/.github/workflows/on-demand-keeper-smoke-tests.yml b/.github/workflows/on-demand-keeper-smoke-tests.yml index fed0b0f317e..452c8478d00 100644 --- a/.github/workflows/on-demand-keeper-smoke-tests.yml +++ b/.github/workflows/on-demand-keeper-smoke-tests.yml @@ -151,7 +151,7 @@ jobs: ## Run this step when changes that require tests to be run are made - name: Run Tests - uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@519851800779323566b7b7c22cc21bff95dbb639 + uses: smartcontractkit/chainlink-github-actions/chainlink-testing-framework/run-tests@fc3e0df622521019f50d772726d6bf8dc919dd38 # v2.3.19 with: test_command_to_run: cd ./integration-tests && go test -timeout 30m -count=1 -json -test.parallel=${{ matrix.product.nodes }} ${{ steps.build-go-test-command.outputs.run_command }} 2>&1 | tee /tmp/gotest.log | gotestloghelper -ci -singlepackage -hidepassingtests=false -hidepassinglogs test_download_vendor_packages_command: cd ./integration-tests && go mod download From e0f2553c5e7fb91996af5407df1ef39c99912ff3 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs Date: Wed, 12 Jun 2024 08:40:02 +0300 Subject: [PATCH 9/9] VRF-1109: Add Fulfillment Response Time in 90, 95 Percentiles to VRF v2 Plus superscript (#13302) --- core/scripts/vrfv2plus/testnet/main.go | 4 ++ .../vrfv2plus/testnet/v2plusscripts/util.go | 39 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/core/scripts/vrfv2plus/testnet/main.go b/core/scripts/vrfv2plus/testnet/main.go index 7b47a2f8529..1fabd20b60f 100644 --- a/core/scripts/vrfv2plus/testnet/main.go +++ b/core/scripts/vrfv2plus/testnet/main.go @@ -960,6 +960,10 @@ func main() { fastestResponseTimeInSeconds, err := consumer.SFastestResponseTimeInBlocks(nil) helpers.PanicErr(err) fmt.Println("Fastest Response Time In Seconds: ", fastestResponseTimeInSeconds) + p90FulfillmentBlockTime, p95FulfillmentBlockTime, err := v2plusscripts.CalculateFulfillmentResponseTimePercentiles(e, consumer) + helpers.PanicErr(err) + fmt.Println("P90 Fulfillment Block Time: ", p90FulfillmentBlockTime) + fmt.Println("P95 Fulfillment Block Time: ", p95FulfillmentBlockTime) case "eoa-load-test-reset-metrics": request := flag.NewFlagSet("eoa-load-test-reset-metrics", flag.ExitOnError) consumerAddress := request.String("consumer-address", "", "consumer address") diff --git a/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go b/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go index 3d511605811..091b324443a 100644 --- a/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go +++ b/core/scripts/vrfv2plus/testnet/v2plusscripts/util.go @@ -6,6 +6,8 @@ import ( "fmt" "math/big" + "github.com/montanaflynn/stats" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" "github.com/ethereum/go-ethereum/accounts/abi/bind" @@ -316,3 +318,40 @@ func EoaV2PlusLoadTestConsumerWithMetricsDeploy(e helpers.Environment, consumerC helpers.PanicErr(err) return helpers.ConfirmContractDeployed(context.Background(), e.Ec, tx, e.ChainID) } + +func CalculateFulfillmentResponseTimePercentiles(e helpers.Environment, consumer *vrf_v2plus_load_test_with_metrics.VRFV2PlusLoadTestWithMetrics) (float64, float64, error) { + var responseTimesInBlocks []uint32 + for { + currentResponseTimesInBlocks, err := consumer.GetRequestBlockTimes(&bind.CallOpts{ + From: e.Owner.From, + Context: context.Background(), + }, big.NewInt(int64(len(responseTimesInBlocks))), big.NewInt(1000)) + if err != nil { + return 0, 0, err + } + if len(currentResponseTimesInBlocks) == 0 { + break + } + responseTimesInBlocks = append(responseTimesInBlocks, currentResponseTimesInBlocks...) + } + var p90FulfillmentBlockTime, p95FulfillmentBlockTime float64 + var err error + if len(responseTimesInBlocks) == 0 { + p90FulfillmentBlockTime = 0 + p95FulfillmentBlockTime = 0 + } else { + responseTimesInBlocksFloat64 := make([]float64, len(responseTimesInBlocks)) + for i, value := range responseTimesInBlocks { + responseTimesInBlocksFloat64[i] = float64(value) + } + p90FulfillmentBlockTime, err = stats.Percentile(responseTimesInBlocksFloat64, 90) + if err != nil { + return 0, 0, err + } + p95FulfillmentBlockTime, err = stats.Percentile(responseTimesInBlocksFloat64, 95) + if err != nil { + return 0, 0, err + } + } + return p90FulfillmentBlockTime, p95FulfillmentBlockTime, nil +}