From c0703455e35aa036117ea4540d12b5518c6329f9 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs Date: Thu, 28 Mar 2024 00:06:34 +0200 Subject: [PATCH] =?UTF-8?q?VRF-961:=20refactor=20VRF=20V2=20e2e=20tests=20?= =?UTF-8?q?-=20do=20not=20wait=20for=20RandomWordsReque=E2=80=A6=20(#12610?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * VRF-961: refactor VRF V2 e2e tests - do not wait for RandomWordsRequested event, but get event from the TX receipt * VRF-961: fixing Sonar * VRF-961: removing comments --- .../actions/vrf/vrfv2/contract_steps.go | 153 +++++------------- .../contracts/contract_vrf_models.go | 13 +- .../contracts/ethereum_vrfv2_contracts.go | 61 ++++++- integration-tests/load/vrfv2/gun.go | 3 +- integration-tests/smoke/vrfv2_test.go | 32 ++-- integration-tests/smoke/vrfv2plus_test.go | 2 +- 6 files changed, 118 insertions(+), 146 deletions(-) diff --git a/integration-tests/actions/vrf/vrfv2/contract_steps.go b/integration-tests/actions/vrf/vrfv2/contract_steps.go index f797e18c499..46b84eb836b 100644 --- a/integration-tests/actions/vrf/vrfv2/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2/contract_steps.go @@ -450,7 +450,6 @@ func FundVRFCoordinatorV2Subscription( } func DirectFundingRequestRandomnessAndWaitForFulfillment( - ctx context.Context, l zerolog.Logger, consumer contracts.VRFv2WrapperLoadTestConsumer, coordinator contracts.VRFCoordinatorV2, @@ -475,7 +474,8 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( randomnessRequestCountPerRequestDeviation, vrfv2KeyData.KeyHash, ) - _, err := consumer.RequestRandomness( + randomWordsRequestedEvent, err := consumer.RequestRandomness( + coordinator, minimumConfirmations, callbackGasLimit, numberOfWords, @@ -484,15 +484,9 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( if err != nil { return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) } - wrapperAddress, err := consumer.GetWrapper(ctx) - if err != nil { - return nil, fmt.Errorf("error getting wrapper address, err: %w", err) - } - fulfillmentEvents, err := WaitForRequestAndFulfillmentEvents( - wrapperAddress.String(), + fulfillmentEvents, err := WaitRandomWordsFulfilledEvent( coordinator, - vrfv2KeyData, - subID, + randomWordsRequestedEvent.RequestId, randomWordsFulfilledEventTimeout, l, ) @@ -512,62 +506,34 @@ func RequestRandomnessAndWaitForFulfillment( randomnessRequestCountPerRequestDeviation uint16, randomWordsFulfilledEventTimeout time.Duration, ) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, error) { - logRandRequest( + randomWordsRequestedEvent, err := RequestRandomness( l, - consumer.Address(), - coordinator.Address(), + consumer, + coordinator, subID, + vrfKeyData, minimumConfirmations, callbackGasLimit, numberOfWords, randomnessRequestCountPerRequest, randomnessRequestCountPerRequestDeviation, - vrfKeyData.KeyHash, ) - ch := make(chan *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled) - errorChannel := make(chan error) - go func() { - _, err := consumer.RequestRandomness( - vrfKeyData.KeyHash, - subID, - minimumConfirmations, - callbackGasLimit, - numberOfWords, - randomnessRequestCountPerRequest, - ) - if err != nil { - l.Error().Err(err).Msg(err.Error()) - errorChannel <- err - } - }() - go func() { - fulfillmentEvents, err := WaitForRequestAndFulfillmentEvents( - consumer.Address(), - coordinator, - vrfKeyData, - subID, - randomWordsFulfilledEventTimeout, - l, - ) - if err != nil { - l.Error().Err(err).Msg("error waiting for RandomnessRequested and RandomWordsFulfilled events") - errorChannel <- err - } - ch <- fulfillmentEvents - }() - for { - select { - case err := <-errorChannel: - return nil, err - case fulfillmentEvent := <-ch: - return fulfillmentEvent, nil - case <-time.After(randomWordsFulfilledEventTimeout): - return nil, fmt.Errorf("timeout waiting for RandomnessRequested and RandomWordsFulfilled events") - } + if err != nil { + return nil, err } + fulfillmentEvents, err := WaitRandomWordsFulfilledEvent( + coordinator, + randomWordsRequestedEvent.RequestId, + randomWordsFulfilledEventTimeout, + l, + ) + if err != nil { + return nil, err + } + return fulfillmentEvents, nil } -func RequestRandomnessAndWaitForRequestedEvent( +func RequestRandomness( l zerolog.Logger, consumer contracts.VRFv2LoadTestConsumer, coordinator contracts.VRFCoordinatorV2, @@ -578,7 +544,6 @@ func RequestRandomnessAndWaitForRequestedEvent( numberOfWords uint32, randomnessRequestCountPerRequest uint16, randomnessRequestCountPerRequestDeviation uint16, - randomWordsRequestedEventTimeout time.Duration, ) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { logRandRequest( l, @@ -592,50 +557,21 @@ func RequestRandomnessAndWaitForRequestedEvent( randomnessRequestCountPerRequestDeviation, vrfKeyData.KeyHash, ) - ch := make(chan *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested) - errorChannel := make(chan error) - go func() { - _, err := consumer.RequestRandomness( - vrfKeyData.KeyHash, - subID, - minimumConfirmations, - callbackGasLimit, - numberOfWords, - randomnessRequestCountPerRequest, - ) - if err != nil { - l.Error().Err(err).Msg(err.Error()) - errorChannel <- err - } - }() - go func() { - randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKeyData.KeyHash}, - []uint64{subID}, - []common.Address{common.HexToAddress(consumer.Address())}, - time.Minute*1, - ) - if err != nil { - l.Error().Err(err).Msg(err.Error()) - errorChannel <- err - } - LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent) - if err != nil { - l.Error().Err(err).Msg("error waiting for RandomnessRequested events") - errorChannel <- err - } - ch <- randomWordsRequestedEvent - }() - for { - select { - case err := <-errorChannel: - return nil, err - case randRequestedEvent := <-ch: - return randRequestedEvent, nil - case <-time.After(randomWordsRequestedEventTimeout): - return nil, fmt.Errorf("timeout waiting for RandomnessRequested events") - } + randomWordsRequestedEvent, err := consumer.RequestRandomness( + coordinator, + vrfKeyData.KeyHash, + subID, + minimumConfirmations, + callbackGasLimit, + numberOfWords, + randomnessRequestCountPerRequest, + ) + if err != nil { + return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) } + LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent) + + return randomWordsRequestedEvent, err } func RequestRandomnessWithForceFulfillAndWaitForFulfillment( @@ -739,27 +675,14 @@ func RequestRandomnessWithForceFulfillAndWaitForFulfillment( return configSetEvent, randomWordsFulfilledEvent, randomWordsForcedEvent, err } -func WaitForRequestAndFulfillmentEvents( - consumerAddress string, +func WaitRandomWordsFulfilledEvent( coordinator contracts.VRFCoordinatorV2, - vrfv2KeyData *vrfcommon.VRFKeyData, - subID uint64, + requestId *big.Int, randomWordsFulfilledEventTimeout time.Duration, l zerolog.Logger, ) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, error) { - randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfv2KeyData.KeyHash}, - []uint64{subID}, - []common.Address{common.HexToAddress(consumerAddress)}, - time.Minute*1, - ) - if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsRequestedEvent, err) - } - LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent) - randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( - []*big.Int{randomWordsRequestedEvent.RequestId}, + []*big.Int{requestId}, randomWordsFulfilledEventTimeout, ) if err != nil { diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index 4e2054dbe56..c991a2fd98d 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -65,6 +65,7 @@ type VRFCoordinatorV2 interface { PendingRequestsExist(ctx context.Context, subID uint64) (bool, error) OwnerCancelSubscription(subID uint64) (*types.Transaction, error) ParseSubscriptionCanceled(log types.Log) (*vrf_coordinator_v2.VRFCoordinatorV2SubscriptionCanceled, error) + ParseRandomWordsRequested(log types.Log) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) ParseLog(log types.Log) (generated.AbigenLog, error) CancelSubscription(subID uint64, to common.Address) (*types.Transaction, error) FindSubscriptionID(subID uint64) (uint64, error) @@ -209,7 +210,15 @@ type VRFv2Consumer interface { type VRFv2LoadTestConsumer interface { Address() string - RequestRandomness(hash [32]byte, subID uint64, confs uint16, gasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) + RequestRandomness( + coordinator VRFCoordinatorV2, + keyHash [32]byte, + subID uint64, + requestConfirmations uint16, + callbackGasLimit uint32, + numWords uint32, + requestCount uint16, + ) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) RequestRandomWordsWithForceFulfill( keyHash [32]byte, requestConfirmations uint16, @@ -228,7 +237,7 @@ type VRFv2LoadTestConsumer interface { type VRFv2WrapperLoadTestConsumer interface { Address() string Fund(ethAmount *big.Float) error - RequestRandomness(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) + RequestRandomness(coordinator VRFCoordinatorV2, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrfv2_wrapper_load_test_consumer.GetRequestStatus, error) GetLastRequestId(ctx context.Context) (*big.Int, error) GetWrapper(ctx context.Context) (common.Address, error) diff --git a/integration-tests/contracts/ethereum_vrfv2_contracts.go b/integration-tests/contracts/ethereum_vrfv2_contracts.go index 111440a251c..2679796076a 100644 --- a/integration-tests/contracts/ethereum_vrfv2_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2_contracts.go @@ -448,6 +448,10 @@ func (v *EthereumVRFCoordinatorV2) ParseSubscriptionCanceled(log types.Log) (*vr return v.coordinator.ParseSubscriptionCanceled(log) } +func (v *EthereumVRFCoordinatorV2) ParseRandomWordsRequested(log types.Log) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { + return v.coordinator.ParseRandomWordsRequested(log) +} + func (v *EthereumVRFCoordinatorV2) ParseLog(log types.Log) (generated.AbigenLog, error) { return v.coordinator.ParseLog(log) } @@ -790,23 +794,36 @@ func (v *EthereumVRFv2LoadTestConsumer) Address() string { } func (v *EthereumVRFv2LoadTestConsumer) RequestRandomness( + coordinator VRFCoordinatorV2, keyHash [32]byte, subID uint64, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16, -) (*types.Transaction, error) { +) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return nil, err } - tx, err := v.consumer.RequestRandomWords(opts, subID, requestConfirmations, keyHash, callbackGasLimit, numWords, requestCount) if err != nil { - return nil, err + return nil, fmt.Errorf("RequestRandomWords failed, err: %w", err) } - return tx, v.client.ProcessTransaction(tx) + err = v.client.ProcessTransaction(tx) + if err != nil { + return nil, fmt.Errorf("ProcessTransaction failed, err: %w", err) + } + err = v.client.WaitForEvents() + if err != nil { + return nil, fmt.Errorf("WaitForEvents failed, err: %w", err) + } + receipt, err := v.client.GetTxReceipt(tx.Hash()) + if err != nil { + return nil, fmt.Errorf("GetTxReceipt failed, err: %w", err) + } + randomWordsRequestedEvent, err := parseRequestRandomnessLogs(coordinator, receipt.Logs) + return randomWordsRequestedEvent, err } func (v *EthereumVRFv2LoadTestConsumer) RequestRandomWordsWithForceFulfill( @@ -971,7 +988,7 @@ func (v *EthereumVRFV2WrapperLoadTestConsumer) Fund(ethAmount *big.Float) error return v.client.Fund(v.address.Hex(), ethAmount, gasEstimates) } -func (v *EthereumVRFV2WrapperLoadTestConsumer) RequestRandomness(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) { +func (v *EthereumVRFV2WrapperLoadTestConsumer) RequestRandomness(coordinator VRFCoordinatorV2, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return nil, err @@ -980,7 +997,23 @@ func (v *EthereumVRFV2WrapperLoadTestConsumer) RequestRandomness(requestConfirma if err != nil { return nil, err } - return tx, v.client.ProcessTransaction(tx) + err = v.client.ProcessTransaction(tx) + if err != nil { + return nil, err + } + err = v.client.WaitForEvents() + if err != nil { + return nil, fmt.Errorf("WaitForEvents failed, err: %w", err) + } + receipt, err := v.client.GetTxReceipt(tx.Hash()) + if err != nil { + return nil, fmt.Errorf("GetTxReceipt failed, err: %w", err) + } + randomWordsRequestedEvent, err := parseRequestRandomnessLogs(coordinator, receipt.Logs) + if err != nil { + return nil, err + } + return randomWordsRequestedEvent, err } func (v *EthereumVRFV2WrapperLoadTestConsumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrfv2_wrapper_load_test_consumer.GetRequestStatus, error) { @@ -1162,3 +1195,19 @@ func (v *EthereumVRFMockETHLINKFeed) SetBlockTimestampDeduction(blockTimestampDe } return v.client.ProcessTransaction(tx) } + +func parseRequestRandomnessLogs(coordinator VRFCoordinatorV2, logs []*types.Log) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { + var randomWordsRequestedEvent *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested + var err error + for _, eventLog := range logs { + for _, topic := range eventLog.Topics { + if topic.Cmp(vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested{}.Topic()) == 0 { + randomWordsRequestedEvent, err = coordinator.ParseRandomWordsRequested(*eventLog) + if err != nil { + return nil, fmt.Errorf("parse RandomWordsRequested log failed, err: %w", err) + } + } + } + } + return randomWordsRequestedEvent, nil +} diff --git a/integration-tests/load/vrfv2/gun.go b/integration-tests/load/vrfv2/gun.go index 6f95752ae94..71d3113e60f 100644 --- a/integration-tests/load/vrfv2/gun.go +++ b/integration-tests/load/vrfv2/gun.go @@ -37,7 +37,7 @@ func NewBHSTestGun( // Call implements example gun call, assertions on response bodies should be done here func (m *BHSTestGun) Call(_ *wasp.Generator) *wasp.Response { - _, err := vrfv2.RequestRandomnessAndWaitForRequestedEvent( + _, err := vrfv2.RequestRandomness( m.logger, m.contracts.VRFV2Consumers[0], m.contracts.CoordinatorV2, @@ -48,7 +48,6 @@ func (m *BHSTestGun) Call(_ *wasp.Generator) *wasp.Response { *m.testConfig.General.NumberOfWords, *m.testConfig.General.RandomnessRequestCountPerRequest, *m.testConfig.General.RandomnessRequestCountPerRequestDeviation, - m.testConfig.General.RandomWordsFulfilledEventTimeout.Duration, ) //todo - might need to store randRequestBlockNumber and blockhash to verify that it was stored in BHS contract at the end of the test if err != nil { diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index 381164cca46..9834cd77973 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -206,7 +206,6 @@ func TestVRFv2Basic(t *testing.T) { // Request Randomness and wait for fulfillment event randomWordsFulfilledEvent, err := vrfv2.DirectFundingRequestRandomnessAndWaitForFulfillment( - testcontext.Get(t), l, wrapperConsumer, vrfContracts.CoordinatorV2, @@ -854,23 +853,20 @@ func TestVRFV2WithBHS(t *testing.T) { vrfv2.LogSubDetails(l, subscriptionForBHS, subIDForBHS, vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForBHS...) - _, err = consumers[0].RequestRandomness( - vrfKey.KeyHash, + randomWordsRequestedEvent, err := vrfv2.RequestRandomness( + l, + consumers[0], + vrfContracts.CoordinatorV2, subIDForBHS, + vrfKey, *configCopy.VRFv2.General.MinimumConfirmations, *configCopy.VRFv2.General.CallbackGasLimit, *configCopy.VRFv2.General.NumberOfWords, *configCopy.VRFv2.General.RandomnessRequestCountPerRequest, + *configCopy.VRFv2.General.RandomnessRequestCountPerRequestDeviation, ) require.NoError(t, err, "error requesting randomness") - randomWordsRequestedEvent, err := vrfContracts.CoordinatorV2.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKey.KeyHash}, - []uint64{subIDForBHS}, - []common.Address{common.HexToAddress(consumers[0].Address())}, - time.Minute*1, - ) - require.NoError(t, err, "error waiting for randomness requested event") vrfv2.LogRandomnessRequestedEvent(l, vrfContracts.CoordinatorV2, randomWordsRequestedEvent) randRequestBlockNumber := randomWordsRequestedEvent.Raw.BlockNumber var wg sync.WaitGroup @@ -916,24 +912,20 @@ func TestVRFV2WithBHS(t *testing.T) { vrfv2.LogSubDetails(l, subscriptionForBHS, subIDForBHS, vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForBHS...) - _, err = consumers[0].RequestRandomness( - vrfKey.KeyHash, + randomWordsRequestedEvent, err := vrfv2.RequestRandomness( + l, + consumers[0], + vrfContracts.CoordinatorV2, subIDForBHS, + vrfKey, *configCopy.VRFv2.General.MinimumConfirmations, *configCopy.VRFv2.General.CallbackGasLimit, *configCopy.VRFv2.General.NumberOfWords, *configCopy.VRFv2.General.RandomnessRequestCountPerRequest, + *configCopy.VRFv2.General.RandomnessRequestCountPerRequestDeviation, ) require.NoError(t, err, "error requesting randomness") - randomWordsRequestedEvent, err := vrfContracts.CoordinatorV2.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKey.KeyHash}, - []uint64{subIDForBHS}, - []common.Address{common.HexToAddress(consumers[0].Address())}, - time.Minute*1, - ) - require.NoError(t, err, "error waiting for randomness requested event") - vrfv2.LogRandomnessRequestedEvent(l, vrfContracts.CoordinatorV2, randomWordsRequestedEvent) randRequestBlockNumber := randomWordsRequestedEvent.Raw.BlockNumber _, err = vrfContracts.BHS.GetBlockHash(testcontext.Get(t), big.NewInt(int64(randRequestBlockNumber))) diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 18e90dcc9a9..c5a35704b1a 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -1301,7 +1301,7 @@ func TestVRFV2PlusWithBHS(t *testing.T) { err = vrfv2plus.FundSubscriptions( env, chainID, - big.NewFloat(*configCopy.VRFv2Plus.General.SubscriptionFundingAmountNative), + big.NewFloat(*configCopy.VRFv2Plus.General.SubscriptionRefundingAmountNative), big.NewFloat(*configCopy.VRFv2Plus.General.SubscriptionRefundingAmountLink), vrfContracts.LinkToken, vrfContracts.CoordinatorV2Plus,