diff --git a/integration-tests/actions/vrf/common/actions.go b/integration-tests/actions/vrf/common/actions.go index 77a93644873..2e543452dc4 100644 --- a/integration-tests/actions/vrf/common/actions.go +++ b/integration-tests/actions/vrf/common/actions.go @@ -1,8 +1,11 @@ package common import ( + "context" "fmt" "math/big" + "sync" + "time" "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" @@ -11,6 +14,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" vrf_common_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/common/vrf" ) @@ -135,3 +139,54 @@ func CreateBHSJob( } return job, nil } + +func WaitForRequestCountEqualToFulfilmentCount( + ctx context.Context, + consumer VRFLoadTestConsumer, + timeout time.Duration, + wg *sync.WaitGroup, +) (*big.Int, *big.Int, error) { + metricsChannel := make(chan *contracts.VRFLoadTestMetrics) + metricsErrorChannel := make(chan error) + + testContext, testCancel := context.WithTimeout(ctx, timeout) + defer testCancel() + + ticker := time.NewTicker(time.Second * 1) + var metrics *contracts.VRFLoadTestMetrics + for { + select { + case <-testContext.Done(): + ticker.Stop() + wg.Done() + return metrics.RequestCount, metrics.FulfilmentCount, + fmt.Errorf("timeout waiting for rand request and fulfilments to be equal AFTER performance test was executed. Request Count: %d, Fulfilment Count: %d", + metrics.RequestCount.Uint64(), metrics.FulfilmentCount.Uint64()) + case <-ticker.C: + go retrieveLoadTestMetrics(ctx, consumer, metricsChannel, metricsErrorChannel) + case metrics = <-metricsChannel: + if metrics.RequestCount.Cmp(metrics.FulfilmentCount) == 0 { + ticker.Stop() + wg.Done() + return metrics.RequestCount, metrics.FulfilmentCount, nil + } + case err := <-metricsErrorChannel: + ticker.Stop() + wg.Done() + return nil, nil, err + } + } +} + +func retrieveLoadTestMetrics( + ctx context.Context, + consumer VRFLoadTestConsumer, + metricsChannel chan *contracts.VRFLoadTestMetrics, + metricsErrorChannel chan error, +) { + metrics, err := consumer.GetLoadTestMetrics(ctx) + if err != nil { + metricsErrorChannel <- err + } + metricsChannel <- metrics +} diff --git a/integration-tests/actions/vrf/common/models.go b/integration-tests/actions/vrf/common/models.go index ab6ca034800..08a004da484 100644 --- a/integration-tests/actions/vrf/common/models.go +++ b/integration-tests/actions/vrf/common/models.go @@ -1,6 +1,7 @@ package common import ( + "context" "math/big" "time" @@ -68,3 +69,7 @@ type VRFJobSpecConfig struct { VRFOwnerConfig *VRFOwnerConfig SimulationBlock *string } + +type VRFLoadTestConsumer interface { + GetLoadTestMetrics(ctx context.Context) (*contracts.VRFLoadTestMetrics, error) +} diff --git a/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go b/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go index 55b41f21856..08331905e0b 100644 --- a/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go +++ b/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "math/big" - "sync" "time" "github.com/ethereum/go-ethereum/common" @@ -943,51 +942,6 @@ func WaitForRequestAndFulfillmentEvents( return randomWordsFulfilledEvent, err } -func WaitForRequestCountEqualToFulfilmentCount(consumer contracts.VRFv2LoadTestConsumer, timeout time.Duration, wg *sync.WaitGroup) (*big.Int, *big.Int, error) { - metricsChannel := make(chan *contracts.VRFLoadTestMetrics) - metricsErrorChannel := make(chan error) - - testContext, testCancel := context.WithTimeout(context.Background(), timeout) - defer testCancel() - - ticker := time.NewTicker(time.Second * 1) - var metrics *contracts.VRFLoadTestMetrics - for { - select { - case <-testContext.Done(): - ticker.Stop() - wg.Done() - return metrics.RequestCount, metrics.FulfilmentCount, - fmt.Errorf("timeout waiting for rand request and fulfilments to be equal AFTER performance test was executed. Request Count: %d, Fulfilment Count: %d", - metrics.RequestCount.Uint64(), metrics.FulfilmentCount.Uint64()) - case <-ticker.C: - go retrieveLoadTestMetrics(consumer, metricsChannel, metricsErrorChannel) - case metrics = <-metricsChannel: - if metrics.RequestCount.Cmp(metrics.FulfilmentCount) == 0 { - ticker.Stop() - wg.Done() - return metrics.RequestCount, metrics.FulfilmentCount, nil - } - case err := <-metricsErrorChannel: - ticker.Stop() - wg.Done() - return nil, nil, err - } - } -} - -func retrieveLoadTestMetrics( - consumer contracts.VRFv2LoadTestConsumer, - metricsChannel chan *contracts.VRFLoadTestMetrics, - metricsErrorChannel chan error, -) { - metrics, err := consumer.GetLoadTestMetrics(context.Background()) - if err != nil { - metricsErrorChannel <- err - } - metricsChannel <- metrics -} - func LogSubDetails(l zerolog.Logger, subscription vrf_coordinator_v2.GetSubscription, subID uint64, coordinator contracts.VRFCoordinatorV2) { l.Debug(). Str("Coordinator", coordinator.Address()). diff --git a/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go b/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go index d2ffc3a93c0..27dd9de5967 100644 --- a/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "math/big" - "sync" "time" "golang.org/x/sync/errgroup" @@ -895,39 +894,6 @@ func WaitForRequestAndFulfillmentEvents( return randomWordsFulfilledEvent, err } -func WaitForRequestCountEqualToFulfilmentCount(consumer contracts.VRFv2PlusLoadTestConsumer, timeout time.Duration, wg *sync.WaitGroup) (*big.Int, *big.Int, error) { - metricsChannel := make(chan *contracts.VRFLoadTestMetrics) - metricsErrorChannel := make(chan error) - - testContext, testCancel := context.WithTimeout(context.Background(), timeout) - defer testCancel() - - ticker := time.NewTicker(time.Second * 1) - var metrics *contracts.VRFLoadTestMetrics - for { - select { - case <-testContext.Done(): - ticker.Stop() - wg.Done() - return metrics.RequestCount, metrics.FulfilmentCount, - fmt.Errorf("timeout waiting for rand request and fulfilments to be equal AFTER performance test was executed. Request Count: %d, Fulfilment Count: %d", - metrics.RequestCount.Uint64(), metrics.FulfilmentCount.Uint64()) - case <-ticker.C: - go retrieveLoadTestMetrics(consumer, metricsChannel, metricsErrorChannel) - case metrics = <-metricsChannel: - if metrics.RequestCount.Cmp(metrics.FulfilmentCount) == 0 { - ticker.Stop() - wg.Done() - return metrics.RequestCount, metrics.FulfilmentCount, nil - } - case err := <-metricsErrorChannel: - ticker.Stop() - wg.Done() - return nil, nil, err - } - } -} - func ReturnFundsForFulfilledRequests(client blockchain.EVMClient, coordinator contracts.VRFCoordinatorV2_5, l zerolog.Logger) error { linkTotalBalance, err := coordinator.GetLinkTotalBalance(context.Background()) if err != nil { @@ -961,18 +927,6 @@ func ReturnFundsForFulfilledRequests(client blockchain.EVMClient, coordinator co return nil } -func retrieveLoadTestMetrics( - consumer contracts.VRFv2PlusLoadTestConsumer, - metricsChannel chan *contracts.VRFLoadTestMetrics, - metricsErrorChannel chan error, -) { - metrics, err := consumer.GetLoadTestMetrics(context.Background()) - if err != nil { - metricsErrorChannel <- err - } - metricsChannel <- metrics -} - func LogSubDetails(l zerolog.Logger, subscription vrf_coordinator_v2_5.GetSubscription, subID *big.Int, coordinator contracts.VRFCoordinatorV2_5) { l.Debug(). Str("Coordinator", coordinator.Address()). diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index 45464bd3a31..e99f353d149 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" + "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2" @@ -86,7 +87,7 @@ func TestVRFV2Performance(t *testing.T) { } else { if *vrfv2Config.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - cancelSubsAndReturnFunds(subIDs, l) + cancelSubsAndReturnFunds(testcontext.Get(t), subIDs, l) } } }). @@ -125,7 +126,7 @@ func TestVRFV2Performance(t *testing.T) { subIDs = append(subIDs, *vrfv2Config.ExistingEnvConfig.SubID) } - err = FundNodesIfNeeded(&testConfig, env.EVMClient, l) + err = FundNodesIfNeeded(testcontext.Get(t), &testConfig, env.EVMClient, l) require.NoError(t, err) vrfContracts = &vrfcommon.VRFContracts{ @@ -160,7 +161,7 @@ func TestVRFV2Performance(t *testing.T) { } else { if *testConfig.VRFv2.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - cancelSubsAndReturnFunds(subIDs, l) + cancelSubsAndReturnFunds(testcontext.Get(t), subIDs, l) } } if err := env.Cleanup(); err != nil { @@ -203,7 +204,7 @@ func TestVRFV2Performance(t *testing.T) { l.Debug().Int("Number of Subs", len(subIDs)).Msg("Subs involved in the test") for _, subID := range subIDs { - subscription, err := vrfContracts.CoordinatorV2.GetSubscription(context.Background(), subID) + subscription, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subID) require.NoError(t, err, "error getting subscription information for subscription %d", subID) vrfv2.LogSubDetails(l, subscription, subID, vrfContracts.CoordinatorV2) } @@ -244,7 +245,7 @@ func TestVRFV2Performance(t *testing.T) { var wg sync.WaitGroup wg.Add(1) //todo - timeout should be configurable depending on the perf test type - requestCount, fulfilmentCount, err := vrfv2.WaitForRequestCountEqualToFulfilmentCount(consumer, 2*time.Minute, &wg) + requestCount, fulfilmentCount, err := vrfcommon.WaitForRequestCountEqualToFulfilmentCount(testcontext.Get(t), consumer, 2*time.Minute, &wg) require.NoError(t, err) wg.Wait() @@ -256,13 +257,13 @@ func TestVRFV2Performance(t *testing.T) { } -func cancelSubsAndReturnFunds(subIDs []uint64, l zerolog.Logger) { +func cancelSubsAndReturnFunds(ctx context.Context, subIDs []uint64, l zerolog.Logger) { for _, subID := range subIDs { l.Info(). Uint64("Returning funds from SubID", subID). Str("Returning funds to", eoaWalletAddress). Msg("Canceling subscription and returning funds to subscription owner") - pendingRequestsExist, err := vrfContracts.CoordinatorV2.PendingRequestsExist(context.Background(), subID) + pendingRequestsExist, err := vrfContracts.CoordinatorV2.PendingRequestsExist(ctx, subID) if err != nil { l.Error().Err(err).Msg("Error checking if pending requests exist") } @@ -277,12 +278,12 @@ func cancelSubsAndReturnFunds(subIDs []uint64, l zerolog.Logger) { } } -func FundNodesIfNeeded(vrfv2TestConfig tc.VRFv2TestConfig, client blockchain.EVMClient, l zerolog.Logger) error { +func FundNodesIfNeeded(ctx context.Context, vrfv2TestConfig tc.VRFv2TestConfig, client blockchain.EVMClient, l zerolog.Logger) error { cfg := vrfv2TestConfig.GetVRFv2Config() if cfg.ExistingEnvConfig.NodeSendingKeyFundingMin != nil && *cfg.ExistingEnvConfig.NodeSendingKeyFundingMin > 0 { for _, sendingKey := range cfg.ExistingEnvConfig.NodeSendingKeys { address := common.HexToAddress(sendingKey) - sendingKeyBalance, err := client.BalanceAt(context.Background(), address) + sendingKeyBalance, err := client.BalanceAt(ctx, address) if err != nil { return err } diff --git a/integration-tests/load/vrfv2plus/vrfv2plus_test.go b/integration-tests/load/vrfv2plus/vrfv2plus_test.go index bb7f977666d..13c694c0290 100644 --- a/integration-tests/load/vrfv2plus/vrfv2plus_test.go +++ b/integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -86,7 +86,7 @@ func TestVRFV2PlusPerformance(t *testing.T) { } else { if *testConfig.VRFv2Plus.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - cancelSubsAndReturnFunds(subIDs, l) + cancelSubsAndReturnFunds(testcontext.Get(t), subIDs, l) } } }). @@ -129,7 +129,7 @@ func TestVRFV2PlusPerformance(t *testing.T) { subIDs = append(subIDs, subID) } - err = FundNodesIfNeeded(&testConfig, env.EVMClient, l) + err = FundNodesIfNeeded(testcontext.Get(t), &testConfig, env.EVMClient, l) require.NoError(t, err) vrfContracts = &vrfcommon.VRFContracts{ @@ -164,7 +164,7 @@ func TestVRFV2PlusPerformance(t *testing.T) { } else { if *testConfig.VRFv2Plus.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - cancelSubsAndReturnFunds(subIDs, l) + cancelSubsAndReturnFunds(testcontext.Get(t), subIDs, l) } } if err := env.Cleanup(); err != nil { @@ -241,7 +241,7 @@ func TestVRFV2PlusPerformance(t *testing.T) { var wg sync.WaitGroup wg.Add(1) //todo - timeout should be configurable depending on the perf test type - requestCount, fulfilmentCount, err := vrfv2plus.WaitForRequestCountEqualToFulfilmentCount(consumer, 2*time.Minute, &wg) + requestCount, fulfilmentCount, err := vrfcommon.WaitForRequestCountEqualToFulfilmentCount(testcontext.Get(t), consumer, 2*time.Minute, &wg) require.NoError(t, err) wg.Wait() @@ -253,13 +253,13 @@ func TestVRFV2PlusPerformance(t *testing.T) { } -func cancelSubsAndReturnFunds(subIDs []*big.Int, l zerolog.Logger) { +func cancelSubsAndReturnFunds(ctx context.Context, subIDs []*big.Int, l zerolog.Logger) { for _, subID := range subIDs { l.Info(). Str("Returning funds from SubID", subID.String()). Str("Returning funds to", eoaWalletAddress). Msg("Canceling subscription and returning funds to subscription owner") - pendingRequestsExist, err := vrfContracts.CoordinatorV2Plus.PendingRequestsExist(context.Background(), subID) + pendingRequestsExist, err := vrfContracts.CoordinatorV2Plus.PendingRequestsExist(ctx, subID) if err != nil { l.Error().Err(err).Msg("Error checking if pending requests exist") } @@ -274,12 +274,12 @@ func cancelSubsAndReturnFunds(subIDs []*big.Int, l zerolog.Logger) { } } -func FundNodesIfNeeded(vrfv2plusTestConfig tc.VRFv2PlusTestConfig, client blockchain.EVMClient, l zerolog.Logger) error { +func FundNodesIfNeeded(ctx context.Context, vrfv2plusTestConfig tc.VRFv2PlusTestConfig, client blockchain.EVMClient, l zerolog.Logger) error { cfg := vrfv2plusTestConfig.GetVRFv2PlusConfig() - if *cfg.ExistingEnvConfig.NodeSendingKeyFundingMin > 0 { + if cfg.ExistingEnvConfig.NodeSendingKeyFundingMin != nil && *cfg.ExistingEnvConfig.NodeSendingKeyFundingMin > 0 { for _, sendingKey := range cfg.ExistingEnvConfig.NodeSendingKeys { address := common.HexToAddress(sendingKey) - sendingKeyBalance, err := client.BalanceAt(context.Background(), address) + sendingKeyBalance, err := client.BalanceAt(ctx, address) if err != nil { return err }