From 78b9a283b93ed5cbc2c9694e2447736424507b24 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs Date: Thu, 12 Oct 2023 19:06:42 +0300 Subject: [PATCH] VRF-598: adjust tests to run VRF V2 Plus load tests against already deployed contracts (#10908) --- .../on-demand-vrfv2plus-load-test.yml | 33 ++- .../testnet/v2plusscripts/super_scripts.go | 3 +- .../vrfv2plus/vrfv2plus_config/config.go | 6 + .../actions/vrfv2plus/vrfv2plus_steps.go | 192 +++++++++++++++--- .../contracts/contract_loader.go | 42 ++++ .../contracts/contract_vrf_models.go | 1 + .../contracts/ethereum_vrfv2plus_contracts.go | 12 ++ integration-tests/load/vrfv2plus/config.go | 43 ++-- integration-tests/load/vrfv2plus/config.toml | 37 ++-- .../load/vrfv2plus/onchain_monitoring.go | 45 ++-- .../load/vrfv2plus/vrfv2plus_test.go | 133 ++++++++---- integration-tests/smoke/vrfv2plus_test.go | 58 +----- 12 files changed, 412 insertions(+), 193 deletions(-) diff --git a/.github/workflows/on-demand-vrfv2plus-load-test.yml b/.github/workflows/on-demand-vrfv2plus-load-test.yml index dcfd2def52d..28c47b453de 100644 --- a/.github/workflows/on-demand-vrfv2plus-load-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-load-test.yml @@ -38,27 +38,22 @@ on: chainlinkVersion: description: Container image version for the Chainlink nodes required: true - default: "2.5.0" + default: "2.6.0-beta0" testDuration: description: Duration of the test (time string) required: false default: 1m - chainlinkNodeFunding: - description: How much to fund each Chainlink node (in ETH) - required: false - default: ".1" - rps: - description: Requests Per Second - required: false - default: 1 - rateLimitDuration: - description: How long to wait between requests - required: false - default: 1m randomnessRequestCountPerRequest: description: Randomness request Count per one TX request required: false default: 1 + useExistingEnv: + description: Whether to deploy a new contracts or use an existing one + required: false + default: false + configBase64: + description: TOML config in base64 + required: false jobs: vrfv2plus_load_test: name: ${{ inputs.network }} VRFV2 Plus Load Test @@ -72,15 +67,15 @@ jobs: env: SELECTED_NETWORKS: ${{ inputs.network }} VRFV2PLUS_TEST_DURATION: ${{ inputs.testDuration }} - VRFV2PLUS_CHAINLINK_NODE_FUNDING: ${{ inputs.chainlinkNodeFunding }} - VRFV2PLUS_RATE_LIMIT_UNIT_DURATION: ${{ inputs.rateLimitDuration }} - VRFV2PLUS_RPS: ${{ inputs.rps }} + VRFV2PLUS_RATE_LIMIT_UNIT_DURATION: 1m + VRFV2PLUS_RPS: 1 VRFV2PLUS_RANDOMNESS_REQUEST_COUNT_PER_REQUEST: ${{ inputs.randomnessRequestCountPerRequest }} - + VRFV2PLUS_USE_EXISTING_ENV: ${{ inputs.useExistingEnv }} + CONFIG: ${{ inputs.configBase64 }} TEST_LOG_LEVEL: debug REF_NAME: ${{ github.head_ref || github.ref_name }} - ENV_JOB_IMAGE_BASE: ${{ secrets.QA_AWS_ACCOUNT_NUMBER }}.dkr.ecr.${{ secrets.QA_AWS_REGION }}.amazonaws.com/chainlink-tests - + CHAINLINK_IMAGE: ${{ inputs.chainlinkImage }} + CHAINLINK_VERSION: ${{ inputs.chainlinkVersion }} WASP_LOG_LEVEL: info steps: - name: Collect Metrics diff --git a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go index 4e93d20f6d6..f805e7b74f0 100644 --- a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go +++ b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go @@ -748,7 +748,8 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, "\nBatch VRF Coordinator Address:", contractAddresses.BatchCoordinatorAddress, "\nVRF Consumer Address:", consumerAddress, "\nVRF Subscription Id:", subID, - "\nVRF Subscription Balance:", *subscriptionBalanceJuels, + "\nVRF Subscription LINK Balance:", *subscriptionBalanceJuels, + "\nVRF Subscription Native Balance:", *subscriptionBalanceNativeWei, "\nPossible VRF Request command: ", fmt.Sprintf("go run . eoa-load-test-request-with-metrics --consumer-address=%s --sub-id=%d --key-hash=%s --request-confirmations %d --requests 1 --runs 1 --cb-gas-limit 1_000_000", consumerAddress, subID, keyHash, *coordinatorConfig.MinConfs), "\nRetrieve Request Status: ", diff --git a/integration-tests/actions/vrfv2plus/vrfv2plus_config/config.go b/integration-tests/actions/vrfv2plus/vrfv2plus_config/config.go index 3c210786bf8..0ff9b4afa7d 100644 --- a/integration-tests/actions/vrfv2plus/vrfv2plus_config/config.go +++ b/integration-tests/actions/vrfv2plus/vrfv2plus_config/config.go @@ -32,4 +32,10 @@ type VRFV2PlusConfig struct { TestDuration time.Duration `envconfig:"TEST_DURATION" default:"3m"` // How long to run the test for RPS int64 `envconfig:"RPS" default:"1"` // How many requests per second to send RateLimitUnitDuration time.Duration `envconfig:"RATE_LIMIT_UNIT_DURATION" default:"1m"` + //Using existing environment and contracts + UseExistingEnv bool `envconfig:"USE_EXISTING_ENV" default:"false"` // Whether to use an existing environment or create a new one + CoordinatorAddress string `envconfig:"COORDINATOR_ADDRESS" default:""` // Coordinator address + ConsumerAddress string `envconfig:"CONSUMER_ADDRESS" default:""` // Consumer address + SubID string `envconfig:"SUB_ID" default:""` // Subscription ID + KeyHash string `envconfig:"KEY_HASH" default:""` } diff --git a/integration-tests/actions/vrfv2plus/vrfv2plus_steps.go b/integration-tests/actions/vrfv2plus/vrfv2plus_steps.go index 0e68f785237..5d4b963f763 100644 --- a/integration-tests/actions/vrfv2plus/vrfv2plus_steps.go +++ b/integration-tests/actions/vrfv2plus/vrfv2plus_steps.go @@ -3,6 +3,8 @@ package vrfv2plus import ( "context" "fmt" + "github.com/smartcontractkit/chainlink/v2/core/assets" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" "math/big" "time" @@ -509,9 +511,9 @@ func RequestRandomnessAndWaitForFulfillment( subID *big.Int, isNativeBilling bool, vrfv2PlusConfig vrfv2plus_config.VRFV2PlusConfig, - //todo - should it be here? l zerolog.Logger, ) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { + logRandRequest(consumer.Address(), coordinator.Address(), subID, isNativeBilling, vrfv2PlusConfig, l) _, err := consumer.RequestRandomness( vrfv2PlusData.KeyHash, subID, @@ -525,7 +527,7 @@ func RequestRandomnessAndWaitForFulfillment( return nil, errors.Wrap(err, ErrRequestRandomness) } - return WaitForRequestAndFulfillmentEvents(consumer.Address(), coordinator, vrfv2PlusData, subID, l) + return WaitForRequestAndFulfillmentEvents(consumer.Address(), coordinator, vrfv2PlusData, subID, isNativeBilling, l) } func RequestRandomnessAndWaitForFulfillmentUpgraded( @@ -537,6 +539,7 @@ func RequestRandomnessAndWaitForFulfillmentUpgraded( vrfv2PlusConfig vrfv2plus_config.VRFV2PlusConfig, l zerolog.Logger, ) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { + logRandRequest(consumer.Address(), coordinator.Address(), subID, isNativeBilling, vrfv2PlusConfig, l) _, err := consumer.RequestRandomness( vrfv2PlusData.KeyHash, subID, @@ -560,15 +563,7 @@ func RequestRandomnessAndWaitForFulfillmentUpgraded( return nil, errors.Wrap(err, ErrWaitRandomWordsRequestedEvent) } - l.Debug(). - Str("Request ID", randomWordsRequestedEvent.RequestId.String()). - Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). - Str("Sender Address", randomWordsRequestedEvent.Sender.String()). - Interface("Keyhash", randomWordsRequestedEvent.KeyHash). - Uint32("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). - Uint32("Number of Words", randomWordsRequestedEvent.NumWords). - Uint16("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). - Msg("RandomnessRequested Event") + LogRandomnessRequestedEventUpgraded(l, coordinator, randomWordsRequestedEvent) randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( []*big.Int{subID}, @@ -578,14 +573,8 @@ func RequestRandomnessAndWaitForFulfillmentUpgraded( if err != nil { return nil, errors.Wrap(err, ErrWaitRandomWordsFulfilledEvent) } + LogRandomWordsFulfilledEventUpgraded(l, coordinator, randomWordsFulfilledEvent) - l.Debug(). - Str("Total Payment in Juels", randomWordsFulfilledEvent.Payment.String()). - Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). - Str("Subscription ID", randomWordsFulfilledEvent.SubID.String()). - Str("Request ID", randomWordsFulfilledEvent.RequestId.String()). - Bool("Success", randomWordsFulfilledEvent.Success). - Msg("RandomWordsFulfilled Event (TX metadata)") return randomWordsFulfilledEvent, err } @@ -598,6 +587,7 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( vrfv2PlusConfig vrfv2plus_config.VRFV2PlusConfig, l zerolog.Logger, ) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { + logRandRequest(consumer.Address(), coordinator.Address(), subID, isNativeBilling, vrfv2PlusConfig, l) if isNativeBilling { _, err := consumer.RequestRandomnessNative( vrfv2PlusConfig.MinimumConfirmations, @@ -623,7 +613,7 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( if err != nil { return nil, errors.Wrap(err, "error getting wrapper address") } - return WaitForRequestAndFulfillmentEvents(wrapperAddress.String(), coordinator, vrfv2PlusData, subID, l) + return WaitForRequestAndFulfillmentEvents(wrapperAddress.String(), coordinator, vrfv2PlusData, subID, isNativeBilling, l) } func WaitForRequestAndFulfillmentEvents( @@ -631,6 +621,7 @@ func WaitForRequestAndFulfillmentEvents( coordinator contracts.VRFCoordinatorV2_5, vrfv2PlusData *VRFV2PlusData, subID *big.Int, + isNativeBilling bool, l zerolog.Logger, ) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( @@ -643,15 +634,7 @@ func WaitForRequestAndFulfillmentEvents( return nil, errors.Wrap(err, ErrWaitRandomWordsRequestedEvent) } - l.Debug(). - Str("Request ID", randomWordsRequestedEvent.RequestId.String()). - Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). - Str("Sender Address", randomWordsRequestedEvent.Sender.String()). - Interface("Keyhash", randomWordsRequestedEvent.KeyHash). - Uint32("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). - Uint32("Number of Words", randomWordsRequestedEvent.NumWords). - Uint16("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). - Msg("RandomnessRequested Event") + LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent, isNativeBilling) randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( []*big.Int{subID}, @@ -662,12 +645,163 @@ func WaitForRequestAndFulfillmentEvents( return nil, errors.Wrap(err, ErrWaitRandomWordsFulfilledEvent) } + LogRandomWordsFulfilledEvent(l, coordinator, randomWordsFulfilledEvent, isNativeBilling) + return randomWordsFulfilledEvent, err +} + +func LogSubDetails(l zerolog.Logger, subscription vrf_coordinator_v2_5.GetSubscription, subID *big.Int, coordinator contracts.VRFCoordinatorV2_5) { + l.Debug(). + Str("Coordinator", coordinator.Address()). + Str("Link Balance", (*assets.Link)(subscription.Balance).Link()). + Str("Native Token Balance", assets.FormatWei(subscription.NativeBalance)). + Str("Subscription ID", subID.String()). + Str("Subscription Owner", subscription.Owner.String()). + Interface("Subscription Consumers", subscription.Consumers). + Msg("Subscription Data") +} + +func LogRandomnessRequestedEventUpgraded( + l zerolog.Logger, + coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, + randomWordsRequestedEvent *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, +) { + l.Debug(). + Str("Coordinator", coordinator.Address()). + Str("Request ID", randomWordsRequestedEvent.RequestId.String()). + Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). + Str("Sender Address", randomWordsRequestedEvent.Sender.String()). + Interface("Keyhash", randomWordsRequestedEvent.KeyHash). + Uint32("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). + Uint32("Number of Words", randomWordsRequestedEvent.NumWords). + Uint16("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). + Msg("RandomnessRequested Event") +} + +func LogRandomWordsFulfilledEventUpgraded( + l zerolog.Logger, + coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, + randomWordsFulfilledEvent *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, +) { l.Debug(). + Str("Coordinator", coordinator.Address()). Str("Total Payment in Juels", randomWordsFulfilledEvent.Payment.String()). Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Str("Subscription ID", randomWordsFulfilledEvent.SubID.String()). + Str("Request ID", randomWordsFulfilledEvent.RequestId.String()). + Bool("Success", randomWordsFulfilledEvent.Success). + Msg("RandomWordsFulfilled Event (TX metadata)") +} + +func LogRandomnessRequestedEvent( + l zerolog.Logger, + coordinator contracts.VRFCoordinatorV2_5, + randomWordsRequestedEvent *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested, + isNativeBilling bool, +) { + l.Debug(). + Str("Coordinator", coordinator.Address()). + Bool("Native Billing", isNativeBilling). + Str("Request ID", randomWordsRequestedEvent.RequestId.String()). + Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). + Str("Sender Address", randomWordsRequestedEvent.Sender.String()). + Interface("Keyhash", randomWordsRequestedEvent.KeyHash). + Uint32("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). + Uint32("Number of Words", randomWordsRequestedEvent.NumWords). + Uint16("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). + Msg("RandomnessRequested Event") +} + +func LogRandomWordsFulfilledEvent( + l zerolog.Logger, + coordinator contracts.VRFCoordinatorV2_5, + randomWordsFulfilledEvent *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, + isNativeBilling bool, +) { + l.Debug(). + Bool("Native Billing", isNativeBilling). + Str("Coordinator", coordinator.Address()). + Str("Total Payment", randomWordsFulfilledEvent.Payment.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). Str("Subscription ID", randomWordsFulfilledEvent.SubId.String()). Str("Request ID", randomWordsFulfilledEvent.RequestId.String()). Bool("Success", randomWordsFulfilledEvent.Success). Msg("RandomWordsFulfilled Event (TX metadata)") - return randomWordsFulfilledEvent, err +} + +func LogMigrationCompletedEvent(l zerolog.Logger, migrationCompletedEvent *vrf_coordinator_v2_5.VRFCoordinatorV25MigrationCompleted, vrfv2PlusContracts *VRFV2_5Contracts) { + l.Debug(). + Str("Subscription ID", migrationCompletedEvent.SubId.String()). + Str("Migrated From Coordinator", vrfv2PlusContracts.Coordinator.Address()). + Str("Migrated To Coordinator", migrationCompletedEvent.NewCoordinator.String()). + Msg("MigrationCompleted Event") +} + +func LogSubDetailsAfterMigration(l zerolog.Logger, newCoordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, subID *big.Int, migratedSubscription vrf_v2plus_upgraded_version.GetSubscription) { + l.Debug(). + Str("New Coordinator", newCoordinator.Address()). + Str("Subscription ID", subID.String()). + Str("Juels Balance", migratedSubscription.Balance.String()). + Str("Native Token Balance", migratedSubscription.NativeBalance.String()). + Str("Subscription Owner", migratedSubscription.Owner.String()). + Interface("Subscription Consumers", migratedSubscription.Consumers). + Msg("Subscription Data After Migration to New Coordinator") +} + +func LogFulfillmentDetailsLinkBilling( + l zerolog.Logger, + wrapperConsumerJuelsBalanceBeforeRequest *big.Int, + wrapperConsumerJuelsBalanceAfterRequest *big.Int, + consumerStatus vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, + randomWordsFulfilledEvent *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, +) { + l.Debug(). + Str("Consumer Balance Before Request (Link)", (*assets.Link)(wrapperConsumerJuelsBalanceBeforeRequest).Link()). + Str("Consumer Balance After Request (Link)", (*assets.Link)(wrapperConsumerJuelsBalanceAfterRequest).Link()). + Bool("Fulfilment Status", consumerStatus.Fulfilled). + Str("Paid by Consumer Contract (Link)", (*assets.Link)(consumerStatus.Paid).Link()). + Str("Paid by Coordinator Sub (Link)", (*assets.Link)(randomWordsFulfilledEvent.Payment).Link()). + Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). + Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). + Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). + Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Msg("Random Words Fulfilment Details For Link Billing") +} + +func LogFulfillmentDetailsNativeBilling( + l zerolog.Logger, + wrapperConsumerBalanceBeforeRequestWei *big.Int, + wrapperConsumerBalanceAfterRequestWei *big.Int, + consumerStatus vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, + randomWordsFulfilledEvent *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, +) { + l.Debug(). + Str("Consumer Balance Before Request", assets.FormatWei(wrapperConsumerBalanceBeforeRequestWei)). + Str("Consumer Balance After Request", assets.FormatWei(wrapperConsumerBalanceAfterRequestWei)). + Bool("Fulfilment Status", consumerStatus.Fulfilled). + Str("Paid by Consumer Contract", assets.FormatWei(consumerStatus.Paid)). + Str("Paid by Coordinator Sub", assets.FormatWei(randomWordsFulfilledEvent.Payment)). + Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). + Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). + Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). + Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Msg("Random Words Request Fulfilment Details For Native Billing") +} + +func logRandRequest( + consumer string, + coordinator string, + subID *big.Int, + isNativeBilling bool, + vrfv2PlusConfig vrfv2plus_config.VRFV2PlusConfig, + l zerolog.Logger) { + l.Debug(). + Str("Consumer", consumer). + Str("Coordinator", coordinator). + Str("subID", subID.String()). + Bool("IsNativePayment", isNativeBilling). + Uint16("MinimumConfirmations", vrfv2PlusConfig.MinimumConfirmations). + Uint16("RandomnessRequestCountPerRequest", vrfv2PlusConfig.RandomnessRequestCountPerRequest). + Msg("Requesting randomness") } diff --git a/integration-tests/contracts/contract_loader.go b/integration-tests/contracts/contract_loader.go index be5a9aa5e8f..4dda2d3f0c4 100644 --- a/integration-tests/contracts/contract_loader.go +++ b/integration-tests/contracts/contract_loader.go @@ -2,6 +2,8 @@ package contracts import ( "errors" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics" "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" @@ -39,6 +41,10 @@ type ContractLoader interface { LoadMercuryRewardManager(addr common.Address) (MercuryRewardManager, error) LoadWERC20Mock(addr common.Address) (WERC20Mock, error) + + // VRF + LoadVRFCoordinatorV2_5(addr string) (VRFCoordinatorV2_5, error) + LoadVRFv2PlusLoadTestConsumer(addr string) (VRFv2PlusLoadTestConsumer, error) } // NewContractLoader returns an instance of a contract Loader based on the client type @@ -306,3 +312,39 @@ func (e *EthereumContractLoader) LoadWERC20Mock(addr common.Address) (WERC20Mock address: addr, }, err } + +func (e *EthereumContractLoader) LoadVRFCoordinatorV2_5(addr string) (VRFCoordinatorV2_5, error) { + address := common.HexToAddress(addr) + instance, err := e.client.LoadContract("VRFCoordinatorV2_5", address, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return vrf_coordinator_v2_5.NewVRFCoordinatorV25(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumVRFCoordinatorV2_5{ + address: &address, + client: e.client, + coordinator: instance.(*vrf_coordinator_v2_5.VRFCoordinatorV25), + }, err +} + +func (e *EthereumContractLoader) LoadVRFv2PlusLoadTestConsumer(addr string) (VRFv2PlusLoadTestConsumer, error) { + address := common.HexToAddress(addr) + instance, err := e.client.LoadContract("VRFV2PlusLoadTestWithMetrics", address, func( + address common.Address, + backend bind.ContractBackend, + ) (interface{}, error) { + return vrf_v2plus_load_test_with_metrics.NewVRFV2PlusLoadTestWithMetrics(address, backend) + }) + if err != nil { + return nil, err + } + return &EthereumVRFv2PlusLoadTestConsumer{ + client: e.client, + consumer: instance.(*vrf_v2plus_load_test_with_metrics.VRFV2PlusLoadTestWithMetrics), + address: &address, + }, err +} diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index f766ee7e3a0..ed46b08dbbf 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -170,6 +170,7 @@ type VRFv2PlusLoadTestConsumer interface { GetLastRequestId(ctx context.Context) (*big.Int, error) GetLoadTestMetrics(ctx context.Context) (*VRFLoadTestMetrics, error) GetCoordinator(ctx context.Context) (common.Address, error) + ResetMetrics() error } type VRFv2PlusWrapperLoadTestConsumer interface { diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index 15a9770f4e5..463b392dac4 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -343,6 +343,18 @@ func (v *EthereumVRFv2PlusLoadTestConsumer) RequestRandomness(keyHash [32]byte, return tx, v.client.ProcessTransaction(tx) } +func (v *EthereumVRFv2PlusLoadTestConsumer) ResetMetrics() error { + opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) + if err != nil { + return err + } + tx, err := v.consumer.Reset(opts) + if err != nil { + return err + } + return v.client.ProcessTransaction(tx) +} + func (v *EthereumVRFv2PlusLoadTestConsumer) GetCoordinator(ctx context.Context) (common.Address, error) { return v.consumer.SVrfCoordinator(&bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), diff --git a/integration-tests/load/vrfv2plus/config.go b/integration-tests/load/vrfv2plus/config.go index 17178a458e6..3b76d64cc7f 100644 --- a/integration-tests/load/vrfv2plus/config.go +++ b/integration-tests/load/vrfv2plus/config.go @@ -1,11 +1,11 @@ package loadvrfv2plus import ( + "encoding/base64" "github.com/pelletier/go-toml/v2" "github.com/pkg/errors" "github.com/rs/zerolog/log" "github.com/smartcontractkit/chainlink/v2/core/store/models" - "math/big" "os" ) @@ -17,20 +17,31 @@ const ( ) type PerformanceConfig struct { - Soak *Soak `toml:"Soak"` - Load *Load `toml:"Load"` - SoakVolume *SoakVolume `toml:"SoakVolume"` - LoadVolume *LoadVolume `toml:"LoadVolume"` - Common *Common `toml:"Common"` + Soak *Soak `toml:"Soak"` + Load *Load `toml:"Load"` + SoakVolume *SoakVolume `toml:"SoakVolume"` + LoadVolume *LoadVolume `toml:"LoadVolume"` + Common *Common `toml:"Common"` + ExistingEnvConfig *ExistingEnvConfig `toml:"ExistingEnvConfig"` +} + +type ExistingEnvConfig struct { + CoordinatorAddress string `toml:"coordinator_address"` + ConsumerAddress string `toml:"consumer_address"` + SubID string `toml:"sub_id"` + KeyHash string `toml:"key_hash"` } type Common struct { Funding + IsNativePayment bool `toml:"is_native_payment"` + MinimumConfirmations uint16 `toml:"minimum_confirmations"` } type Funding struct { - NodeFunds *big.Float `toml:"node_funds"` - SubFunds *big.Int `toml:"sub_funds"` + NodeFunds float64 `toml:"node_funds"` + SubFundsLink int64 `toml:"sub_funds_link"` + SubFundsNative int64 `toml:"sub_funds_native"` } type Soak struct { @@ -61,14 +72,22 @@ type LoadVolume struct { func ReadConfig() (*PerformanceConfig, error) { var cfg *PerformanceConfig - d, err := os.ReadFile(DefaultConfigFilename) - if err != nil { - return nil, errors.Wrap(err, ErrReadPerfConfig) + rawConfig := os.Getenv("CONFIG") + var d []byte + var err error + if rawConfig == "" { + d, err = os.ReadFile(DefaultConfigFilename) + if err != nil { + return nil, errors.Wrap(err, ErrReadPerfConfig) + } + } else { + d, err = base64.StdEncoding.DecodeString(rawConfig) } err = toml.Unmarshal(d, &cfg) if err != nil { return nil, errors.Wrap(err, ErrUnmarshalPerfConfig) } - log.Debug().Interface("PerformanceConfig", cfg).Msg("Parsed performance config") + + log.Debug().Interface("Config", cfg).Msg("Parsed config") return cfg, nil } diff --git a/integration-tests/load/vrfv2plus/config.toml b/integration-tests/load/vrfv2plus/config.toml index 03169b4c9d7..d77c22badb8 100644 --- a/integration-tests/load/vrfv2plus/config.toml +++ b/integration-tests/load/vrfv2plus/config.toml @@ -1,27 +1,14 @@ -# testing one product (jobs + contracts) by varying RPS -[Soak] -rps = 1 -duration = "1m" - -[Load] -rps_from = 1 -rps_increase = 1 -rps_steps = 10 -duration = "3m" - -# testing multiple products (jobs + contracts) by varying instances, deploying more of the same type with stable RPS for each product -[SoakVolume] -products = 5 -pace = "1s" -duration = "3m" - -[LoadVolume] -products_from = 1 -products_increase = 1 -products_steps = 10 -pace = "1s" -duration = "3m" [Common] -node_funds = 10 -sub_funds = 100 +node_funds = 0.1 +is_native_payment = false +minimum_confirmations = 3 +sub_funds_link = 10 +sub_funds_native = 1 + +[ExistingEnvConfig] +coordinator_address = "0x4931Ce2e341398c8eD8A5D0F6ADb920476D6DaBb" +consumer_address = "0x087F232165D9bA1A602f148025e5D0666953F64a" +sub_id = "52116875585187328970776211988181422347535732407068188096422095950800466618218" +key_hash = "0x4c422465ed6a06cfc84575a5437fef7b9dc6263133f648afbe6ae7b2c694d3b3" + diff --git a/integration-tests/load/vrfv2plus/onchain_monitoring.go b/integration-tests/load/vrfv2plus/onchain_monitoring.go index b22bf8259d1..0ae27fe6be0 100644 --- a/integration-tests/load/vrfv2plus/onchain_monitoring.go +++ b/integration-tests/load/vrfv2plus/onchain_monitoring.go @@ -18,30 +18,33 @@ const ( ErrLokiPush = "failed to push monitoring metrics to Loki" ) -func MonitorLoadStats(t *testing.T, vrfv2PlusContracts *vrfv2plus.VRFV2_5Contracts, labels map[string]string) { +func MonitorLoadStats(lc *wasp.LokiClient, vrfv2PlusContracts *vrfv2plus.VRFV2_5Contracts, labels map[string]string) { go func() { - updatedLabels := make(map[string]string) - for k, v := range labels { - updatedLabels[k] = v - } - updatedLabels["type"] = LokiTypeLabel - updatedLabels["go_test_name"] = t.Name() - updatedLabels["gen_name"] = "performance" - lc, err := wasp.NewLokiClient(wasp.NewEnvLokiConfig()) - if err != nil { - log.Error().Err(err).Msg(ErrLokiClient) - return - } for { time.Sleep(1 * time.Second) - //todo - should work with multiple consumers and consumers having different keyhashes and wallets - metrics, err := vrfv2PlusContracts.LoadTestConsumers[0].GetLoadTestMetrics(context.Background()) - if err != nil { - log.Error().Err(err).Msg(ErrMetrics) - } - if err := lc.HandleStruct(wasp.LabelsMapToModel(updatedLabels), time.Now(), metrics); err != nil { - log.Error().Err(err).Msg(ErrLokiPush) - } + SendLoadTestMetricsToLoki(vrfv2PlusContracts, lc, labels) } }() } + +func UpdateLabels(labels map[string]string, t *testing.T) map[string]string { + updatedLabels := make(map[string]string) + for k, v := range labels { + updatedLabels[k] = v + } + updatedLabels["type"] = LokiTypeLabel + updatedLabels["go_test_name"] = t.Name() + updatedLabels["gen_name"] = "performance" + return updatedLabels +} + +func SendLoadTestMetricsToLoki(vrfv2PlusContracts *vrfv2plus.VRFV2_5Contracts, lc *wasp.LokiClient, updatedLabels map[string]string) { + //todo - should work with multiple consumers and consumers having different keyhashes and wallets + metrics, err := vrfv2PlusContracts.LoadTestConsumers[0].GetLoadTestMetrics(context.Background()) + if err != nil { + log.Error().Err(err).Msg(ErrMetrics) + } + if err := lc.HandleStruct(wasp.LabelsMapToModel(updatedLabels), time.Now(), metrics); err != nil { + log.Error().Err(err).Msg(ErrLokiPush) + } +} diff --git a/integration-tests/load/vrfv2plus/vrfv2plus_test.go b/integration-tests/load/vrfv2plus/vrfv2plus_test.go index 805b9711eda..5221a9860f6 100644 --- a/integration-tests/load/vrfv2plus/vrfv2plus_test.go +++ b/integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -3,15 +3,15 @@ package loadvrfv2plus import ( "context" "fmt" - "math/big" - "sync" - "testing" - "time" - + "github.com/ethereum/go-ethereum/common" "github.com/kelseyhightower/envconfig" "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/wasp" "github.com/stretchr/testify/require" + "math/big" + "sync" + "testing" + "time" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrfv2plus" @@ -21,43 +21,89 @@ import ( ) func TestVRFV2PlusLoad(t *testing.T) { - + cfg, err := ReadConfig() + require.NoError(t, err) var vrfv2PlusConfig vrfv2plus_config.VRFV2PlusConfig - err := envconfig.Process("VRFV2PLUS", &vrfv2PlusConfig) + err = envconfig.Process("VRFV2PLUS", &vrfv2PlusConfig) require.NoError(t, err) l := logging.GetTestLogger(t) + //todo: temporary solution with envconfig and toml config until VRF-662 is implemented + vrfv2PlusConfig.ChainlinkNodeFunding = cfg.Common.NodeFunds + vrfv2PlusConfig.IsNativePayment = cfg.Common.IsNativePayment + vrfv2PlusConfig.MinimumConfirmations = cfg.Common.MinimumConfirmations + vrfv2PlusConfig.SubscriptionFundingAmountLink = cfg.Common.Funding.SubFundsLink + vrfv2PlusConfig.SubscriptionFundingAmountNative = cfg.Common.Funding.SubFundsNative + + var env *test_env.CLClusterTestEnv + var vrfv2PlusContracts *vrfv2plus.VRFV2_5Contracts + var subID *big.Int + var vrfv2PlusData *vrfv2plus.VRFV2PlusData + if vrfv2PlusConfig.UseExistingEnv { + //todo: temporary solution with envconfig and toml config until VRF-662 is implemented + vrfv2PlusConfig.CoordinatorAddress = cfg.ExistingEnvConfig.CoordinatorAddress + vrfv2PlusConfig.ConsumerAddress = cfg.ExistingEnvConfig.ConsumerAddress + vrfv2PlusConfig.SubID = cfg.ExistingEnvConfig.SubID + vrfv2PlusConfig.KeyHash = cfg.ExistingEnvConfig.KeyHash + + env, err = test_env.NewCLTestEnvBuilder(). + WithTestLogger(t). + Build() + + require.NoError(t, err, "error creating test env") + + coordinator, err := env.ContractLoader.LoadVRFCoordinatorV2_5(vrfv2PlusConfig.CoordinatorAddress) + require.NoError(t, err) + + consumer, err := env.ContractLoader.LoadVRFv2PlusLoadTestConsumer(vrfv2PlusConfig.ConsumerAddress) + require.NoError(t, err) - env, err := test_env.NewCLTestEnvBuilder(). - WithTestLogger(t). - WithGeth(). - WithCLNodes(1). - WithFunding(big.NewFloat(vrfv2PlusConfig.ChainlinkNodeFunding)). - WithLogWatcher(). - Build() - require.NoError(t, err, "error creating test env") + vrfv2PlusContracts = &vrfv2plus.VRFV2_5Contracts{ + Coordinator: coordinator, + LoadTestConsumers: []contracts.VRFv2PlusLoadTestConsumer{consumer}, + BHS: nil, + } + var ok bool + subID, ok = new(big.Int).SetString(vrfv2PlusConfig.SubID, 10) + require.True(t, ok) + + vrfv2PlusData = &vrfv2plus.VRFV2PlusData{ + VRFV2PlusKeyData: vrfv2plus.VRFV2PlusKeyData{ + VRFKey: nil, + EncodedProvingKey: [2]*big.Int{}, + KeyHash: common.HexToHash(vrfv2PlusConfig.KeyHash), + }, + VRFJob: nil, + PrimaryEthAddress: "", + ChainID: nil, + } + } else { + env, err = test_env.NewCLTestEnvBuilder(). + WithTestLogger(t). + WithGeth(). + WithCLNodes(1). + WithFunding(big.NewFloat(vrfv2PlusConfig.ChainlinkNodeFunding)). + WithLogWatcher(). + Build() - env.ParallelTransactions(true) + require.NoError(t, err, "error creating test env") - mockETHLinkFeed, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, big.NewInt(vrfv2PlusConfig.LinkNativeFeedResponse)) - require.NoError(t, err, "error deploying mock ETH/LINK feed") + env.ParallelTransactions(true) - linkToken, err := actions.DeployLINKToken(env.ContractDeployer) - require.NoError(t, err, "error deploying LINK contract") + mockETHLinkFeed, err := actions.DeployMockETHLinkFeed(env.ContractDeployer, big.NewInt(vrfv2PlusConfig.LinkNativeFeedResponse)) + require.NoError(t, err, "error deploying mock ETH/LINK feed") - vrfv2PlusContracts, subID, vrfv2PlusData, err := vrfv2plus.SetupVRFV2_5Environment(env, vrfv2PlusConfig, linkToken, mockETHLinkFeed, 1) - require.NoError(t, err, "error setting up VRF v2_5 env") + linkToken, err := actions.DeployLINKToken(env.ContractDeployer) + require.NoError(t, err, "error deploying LINK contract") + + vrfv2PlusContracts, subID, vrfv2PlusData, err = vrfv2plus.SetupVRFV2_5Environment(env, vrfv2PlusConfig, linkToken, mockETHLinkFeed, 1) + require.NoError(t, err, "error setting up VRF v2_5 env") + } subscription, err := vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID) require.NoError(t, err, "error getting subscription information") - l.Debug(). - Str("Juels Balance", subscription.Balance.String()). - Str("Native Token Balance", subscription.NativeBalance.String()). - Str("Subscription ID", subID.String()). - Str("Subscription Owner", subscription.Owner.String()). - Interface("Subscription Consumers", subscription.Consumers). - Msg("Subscription Data") + vrfv2plus.LogSubDetails(l, subscription, subID, vrfv2PlusContracts.Coordinator) labels := map[string]string{ "branch": "vrfv2Plus_healthcheck", @@ -67,9 +113,18 @@ func TestVRFV2PlusLoad(t *testing.T) { l.Info(). Str("Test Duration", vrfv2PlusConfig.TestDuration.Truncate(time.Second).String()). Int64("RPS", vrfv2PlusConfig.RPS). + Str("RateLimitUnitDuration", vrfv2PlusConfig.RateLimitUnitDuration.String()). Uint16("RandomnessRequestCountPerRequest", vrfv2PlusConfig.RandomnessRequestCountPerRequest). + Bool("UseExistingEnv", vrfv2PlusConfig.UseExistingEnv). Msg("Load Test Configs") + lokiConfig := wasp.NewEnvLokiConfig() + lc, err := wasp.NewLokiClient(lokiConfig) + if err != nil { + l.Error().Err(err).Msg(ErrLokiClient) + return + } + singleFeedConfig := &wasp.Config{ T: t, LoadType: wasp.RPS, @@ -80,21 +135,26 @@ func TestVRFV2PlusLoad(t *testing.T) { vrfv2PlusData.KeyHash, subID, vrfv2PlusConfig, - l), + l, + ), Labels: labels, - LokiConfig: wasp.NewEnvLokiConfig(), + LokiConfig: lokiConfig, CallTimeout: 2 * time.Minute, } - - MonitorLoadStats(t, vrfv2PlusContracts, labels) + consumer := vrfv2PlusContracts.LoadTestConsumers[0] + err = consumer.ResetMetrics() + require.NoError(t, err) + updatedLabels := UpdateLabels(labels, t) + MonitorLoadStats(lc, vrfv2PlusContracts, updatedLabels) // is our "job" stable at all, no memory leaks, no flaking performance under some RPS? t.Run("vrfv2plus soak test", func(t *testing.T) { + singleFeedConfig.Schedule = wasp.Plain( vrfv2PlusConfig.RPS, vrfv2PlusConfig.TestDuration, ) - _, err := wasp.NewProfile(). + _, err = wasp.NewProfile(). Add(wasp.NewGenerator(singleFeedConfig)). Run(true) require.NoError(t, err) @@ -108,8 +168,9 @@ func TestVRFV2PlusLoad(t *testing.T) { Interface("Fulfilment Count", fulfilmentCount). Msg("Final Request/Fulfilment Stats") require.NoError(t, err) - wg.Wait() + //send final results + SendLoadTestMetricsToLoki(vrfv2PlusContracts, lc, updatedLabels) }) } @@ -135,10 +196,12 @@ func WaitForRequestCountEqualToFulfilmentCount(consumer contracts.VRFv2PlusLoadT go getLoadTestMetrics(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 } diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 14e5a3b1e16..659616330b5 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -51,13 +51,7 @@ func TestVRFv2Plus(t *testing.T) { subscription, err := vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID) require.NoError(t, err, "error getting subscription information") - l.Debug(). - Str("Juels Balance", subscription.Balance.String()). - Str("Native Token Balance", subscription.NativeBalance.String()). - Str("Subscription ID", subID.String()). - Str("Subscription Owner", subscription.Owner.String()). - Interface("Subscription Consumers", subscription.Consumers). - Msg("Subscription Data") + vrfv2plus.LogSubDetails(l, subscription, subID, vrfv2PlusContracts.Coordinator) t.Run("VRFV2 Plus With Link Billing", func(t *testing.T) { var isNativeBilling = false @@ -190,18 +184,7 @@ func TestVRFv2Plus(t *testing.T) { //todo: uncomment when VRF-651 will be fixed //require.Equal(t, 1, consumerStatus.Paid.Cmp(randomWordsFulfilledEvent.Payment), "Expected Consumer contract pay more than the Coordinator Sub") - l.Debug(). - Str("Consumer Balance Before Request (Juels)", wrapperConsumerJuelsBalanceBeforeRequest.String()). - Str("Consumer Balance After Request (Juels)", wrapperConsumerJuelsBalanceAfterRequest.String()). - Bool("Fulfilment Status", consumerStatus.Fulfilled). - Str("Paid in Juels by Consumer Contract", consumerStatus.Paid.String()). - Str("Paid in Juels by Coordinator Sub", randomWordsFulfilledEvent.Payment.String()). - Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). - Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). - Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). - Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). - Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). - Msg("Random Words Request Fulfilment Status") + vrfv2plus.LogFulfillmentDetailsLinkBilling(l, wrapperConsumerJuelsBalanceBeforeRequest, wrapperConsumerJuelsBalanceAfterRequest, consumerStatus, randomWordsFulfilledEvent) require.Equal(t, vrfv2PlusConfig.NumberOfWords, uint32(len(consumerStatus.RandomWords))) for _, w := range consumerStatus.RandomWords { @@ -249,18 +232,7 @@ func TestVRFv2Plus(t *testing.T) { //todo: uncomment when VRF-651 will be fixed //require.Equal(t, 1, consumerStatus.Paid.Cmp(randomWordsFulfilledEvent.Payment), "Expected Consumer contract pay more than the Coordinator Sub") - l.Debug(). - Str("Consumer Balance Before Request (WEI)", wrapperConsumerBalanceBeforeRequestWei.String()). - Str("Consumer Balance After Request (WEI)", wrapperConsumerBalanceAfterRequestWei.String()). - Bool("Fulfilment Status", consumerStatus.Fulfilled). - Str("Paid in Juels by Consumer Contract", consumerStatus.Paid.String()). - Str("Paid in Juels by Coordinator Sub", randomWordsFulfilledEvent.Payment.String()). - Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). - Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). - Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). - Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). - Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). - Msg("Random Words Request Fulfilment Status") + vrfv2plus.LogFulfillmentDetailsNativeBilling(l, wrapperConsumerBalanceBeforeRequestWei, wrapperConsumerBalanceAfterRequestWei, consumerStatus, randomWordsFulfilledEvent) require.Equal(t, vrfv2PlusConfig.NumberOfWords, uint32(len(consumerStatus.RandomWords))) for _, w := range consumerStatus.RandomWords { @@ -270,6 +242,7 @@ func TestVRFv2Plus(t *testing.T) { }) } + func TestVRFv2PlusMigration(t *testing.T) { t.Parallel() l := logging.GetTestLogger(t) @@ -298,13 +271,7 @@ func TestVRFv2PlusMigration(t *testing.T) { subscription, err := vrfv2PlusContracts.Coordinator.GetSubscription(context.Background(), subID) require.NoError(t, err, "error getting subscription information") - l.Debug(). - Str("Juels Balance", subscription.Balance.String()). - Str("Native Token Balance", subscription.NativeBalance.String()). - Str("Subscription ID", subID.String()). - Str("Subscription Owner", subscription.Owner.String()). - Interface("Subscription Consumers", subscription.Consumers). - Msg("Subscription Data") + vrfv2plus.LogSubDetails(l, subscription, subID, vrfv2PlusContracts.Coordinator) activeSubIdsOldCoordinatorBeforeMigration, err := vrfv2PlusContracts.Coordinator.GetActiveSubscriptionIds(context.Background(), big.NewInt(0), big.NewInt(0)) require.NoError(t, err, "error occurred getting active sub ids") @@ -373,11 +340,7 @@ func TestVRFv2PlusMigration(t *testing.T) { err = env.EVMClient.WaitForEvents() require.NoError(t, err, vrfv2plus.ErrWaitTXsComplete) - l.Debug(). - Str("Subscription ID", migrationCompletedEvent.SubId.String()). - Str("Migrated From Coordinator", vrfv2PlusContracts.Coordinator.Address()). - Str("Migrated To Coordinator", migrationCompletedEvent.NewCoordinator.String()). - Msg("MigrationCompleted Event") + vrfv2plus.LogMigrationCompletedEvent(l, migrationCompletedEvent, vrfv2PlusContracts) oldCoordinatorLinkTotalBalanceAfterMigration, oldCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfv2PlusContracts.Coordinator) require.NoError(t, err) @@ -388,14 +351,7 @@ func TestVRFv2PlusMigration(t *testing.T) { migratedSubscription, err := newCoordinator.GetSubscription(context.Background(), subID) require.NoError(t, err, "error getting subscription information") - l.Debug(). - Str("New Coordinator", newCoordinator.Address()). - Str("Subscription ID", subID.String()). - Str("Juels Balance", migratedSubscription.Balance.String()). - Str("Native Token Balance", migratedSubscription.NativeBalance.String()). - Str("Subscription Owner", migratedSubscription.Owner.String()). - Interface("Subscription Consumers", migratedSubscription.Consumers). - Msg("Subscription Data After Migration to New Coordinator") + vrfv2plus.LogSubDetailsAfterMigration(l, newCoordinator, subID, migratedSubscription) //Verify that Coordinators were updated in Consumers for _, consumer := range vrfv2PlusContracts.LoadTestConsumers {