Skip to content

Commit

Permalink
VRF-543: add test for verifying round robin for multiple sending keys… (
Browse files Browse the repository at this point in the history
#11382)

* VRF-543: add test for verifying round robin for multiple sending keys in VRF v2 and VRF V2 Plus

* VRF-543: fixing lint issue
  • Loading branch information
iljapavlovs authored Nov 27, 2023
1 parent b87f21e commit 9686592
Show file tree
Hide file tree
Showing 11 changed files with 318 additions and 48 deletions.
23 changes: 23 additions & 0 deletions integration-tests/actions/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strings"
"testing"

"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"

"github.com/ethereum/go-ethereum"
Expand Down Expand Up @@ -458,3 +459,25 @@ func GenerateWallet() (common.Address, error) {
}
return crypto.PubkeyToAddress(*publicKeyECDSA), nil
}

// todo - move to CTF
func FundAddress(client blockchain.EVMClient, sendingKey string, fundingToSendEth *big.Float) error {
address := common.HexToAddress(sendingKey)
gasEstimates, err := client.EstimateGas(ethereum.CallMsg{
To: &address,
})
if err != nil {
return err
}
err = client.Fund(sendingKey, fundingToSendEth, gasEstimates)
if err != nil {
return err
}
return nil
}

// todo - move to CTF
func GetTxFromAddress(tx *types.Transaction) (string, error) {
from, err := types.Sender(types.LatestSignerForChainID(tx.ChainId()), tx)
return from.String(), err
}
45 changes: 33 additions & 12 deletions integration-tests/actions/vrfv2_actions/vrfv2_steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (

var (
ErrNodePrimaryKey = "error getting node's primary ETH key"
ErrNodeNewTxKey = "error creating node's EVM transaction key"
ErrCreatingProvingKeyHash = "error creating a keyHash from the proving key"
ErrRegisteringProvingKey = "error registering a proving key on Coordinator contract"
ErrRegisterProvingKey = "error registering proving keys"
Expand Down Expand Up @@ -105,7 +106,7 @@ func DeployVRFV2Consumers(contractDeployer contracts.ContractDeployer, coordinat
func CreateVRFV2Job(
chainlinkNode *client.ChainlinkClient,
coordinatorAddress string,
nativeTokenPrimaryKeyAddress string,
nativeTokenKeyAddresses []string,
pubKeyCompressed string,
chainID string,
minIncomingConfirmations uint16,
Expand All @@ -122,7 +123,7 @@ func CreateVRFV2Job(
job, err := chainlinkNode.MustCreateJob(&client.VRFV2JobSpec{
Name: fmt.Sprintf("vrf-v2-%s", jobUUID),
CoordinatorAddress: coordinatorAddress,
FromAddresses: []string{nativeTokenPrimaryKeyAddress},
FromAddresses: nativeTokenKeyAddresses,
EVMChainID: chainID,
MinIncomingConfirmations: int(minIncomingConfirmations),
PublicKey: pubKeyCompressed,
Expand Down Expand Up @@ -181,6 +182,7 @@ func SetupVRFV2Environment(
linkToken contracts.LinkToken,
mockNativeLINKFeed contracts.MockETHLINKFeed,
registerProvingKeyAgainstAddress string,
numberOfTxKeysToCreate int,
numberOfConsumers int,
numberOfSubToCreate int,
l zerolog.Logger,
Expand Down Expand Up @@ -254,17 +256,21 @@ func SetupVRFV2Environment(
}

chainID := env.EVMClient.GetChainID()

newNativeTokenKeyAddresses, err := CreateAndFundSendingKeys(env, vrfv2Config, numberOfTxKeysToCreate, chainID)
if err != nil {
return nil, nil, nil, err
}
nativeTokenPrimaryKeyAddress, err := env.ClCluster.NodeAPIs()[0].PrimaryEthAddress()
if err != nil {
return nil, nil, nil, fmt.Errorf("%s, err %w", ErrNodePrimaryKey, err)
}
allNativeTokenKeyAddresses := append(newNativeTokenKeyAddresses, nativeTokenPrimaryKeyAddress)

l.Info().Msg("Creating VRFV2 Job")
vrfV2job, err := CreateVRFV2Job(
env.ClCluster.NodeAPIs()[0],
vrfv2Contracts.Coordinator.Address(),
nativeTokenPrimaryKeyAddress,
allNativeTokenKeyAddresses,
pubKeyCompressed,
chainID.String(),
vrfv2Config.MinimumConfirmations,
Expand All @@ -276,12 +282,8 @@ func SetupVRFV2Environment(
// this part is here because VRFv2 can work with only a specific key
// [[EVM.KeySpecific]]
// Key = '...'
addr, err := env.ClCluster.Nodes[0].API.PrimaryEthAddress()
if err != nil {
return nil, nil, nil, fmt.Errorf("%s, err %w", ErrGetPrimaryKey, err)
}
nodeConfig := node.NewConfig(env.ClCluster.Nodes[0].NodeConfig,
node.WithVRFv2EVMEstimator(addr, vrfv2Config.CLNodeMaxGasPriceGWei),
node.WithVRFv2EVMEstimator(allNativeTokenKeyAddresses, vrfv2Config.CLNodeMaxGasPriceGWei),
)
l.Info().Msg("Restarting Node with new sending key PriceMax configuration")
err = env.ClCluster.Nodes[0].Restart(nodeConfig)
Expand All @@ -306,6 +308,25 @@ func SetupVRFV2Environment(
return vrfv2Contracts, subIDs, &data, nil
}

func CreateAndFundSendingKeys(env *test_env.CLClusterTestEnv, vrfv2Config vrfv2_config.VRFV2Config, numberOfNativeTokenAddressesToCreate int, chainID *big.Int) ([]string, error) {
var newNativeTokenKeyAddresses []string
for i := 0; i < numberOfNativeTokenAddressesToCreate; i++ {
newTxKey, response, err := env.ClCluster.NodeAPIs()[0].CreateTxKey("evm", chainID.String())
if err != nil {
return nil, fmt.Errorf("%s, err %w", ErrNodeNewTxKey, err)
}
if response.StatusCode != 200 {
return nil, fmt.Errorf("error creating transaction key - response code, err %d", response.StatusCode)
}
newNativeTokenKeyAddresses = append(newNativeTokenKeyAddresses, newTxKey.Data.ID)
err = actions.FundAddress(env.EVMClient, newTxKey.Data.ID, big.NewFloat(vrfv2Config.ChainlinkNodeFunding))
if err != nil {
return nil, err
}
}
return newNativeTokenKeyAddresses, nil
}

func CreateFundSubsAndAddConsumers(
env *test_env.CLClusterTestEnv,
vrfv2Config vrfv2_config.VRFV2Config,
Expand Down Expand Up @@ -448,7 +469,7 @@ func RequestRandomnessAndWaitForFulfillment(
l zerolog.Logger,
) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, error) {
logRandRequest(consumer.Address(), coordinator.Address(), subID, vrfv2Config, l)
err := consumer.RequestRandomness(
_, err := consumer.RequestRandomness(
vrfv2Data.KeyHash,
subID,
vrfv2Config.MinimumConfirmations,
Expand All @@ -460,14 +481,15 @@ func RequestRandomnessAndWaitForFulfillment(
return nil, fmt.Errorf("%s, err %w", ErrRequestRandomness, err)
}

return WaitForRequestAndFulfillmentEvents(
fulfillmentEvents, err := WaitForRequestAndFulfillmentEvents(
consumer.Address(),
coordinator,
vrfv2Data,
subID,
randomWordsFulfilledEventTimeout,
l,
)
return fulfillmentEvents, err
}

func WaitForRequestAndFulfillmentEvents(
Expand All @@ -489,7 +511,6 @@ func WaitForRequestAndFulfillmentEvents(
}

LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent)

randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent(
[]*big.Int{randomWordsRequestedEvent.RequestId},
randomWordsFulfilledEventTimeout,
Expand Down
42 changes: 31 additions & 11 deletions integration-tests/actions/vrfv2plus/vrfv2plus_steps.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import (
"sync"
"time"

"github.com/smartcontractkit/chainlink-testing-framework/utils/conversions"

commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets"
"github.com/smartcontractkit/chainlink-testing-framework/utils/conversions"
"github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets"
"github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer"

Expand All @@ -31,6 +30,7 @@ import (

var (
ErrNodePrimaryKey = "error getting node's primary ETH key"
ErrNodeNewTxKey = "error creating node's EVM transaction key"
ErrCreatingProvingKeyHash = "error creating a keyHash from the proving key"
ErrRegisteringProvingKey = "error registering a proving key on Coordinator contract"
ErrRegisterProvingKey = "error registering proving keys"
Expand Down Expand Up @@ -112,7 +112,7 @@ func DeployVRFV2PlusConsumers(contractDeployer contracts.ContractDeployer, coord
func CreateVRFV2PlusJob(
chainlinkNode *client.ChainlinkClient,
coordinatorAddress string,
nativeTokenPrimaryKeyAddress string,
nativeTokenKeyAddresses []string,
pubKeyCompressed string,
chainID string,
minIncomingConfirmations uint16,
Expand All @@ -129,7 +129,7 @@ func CreateVRFV2PlusJob(
job, err := chainlinkNode.MustCreateJob(&client.VRFV2PlusJobSpec{
Name: fmt.Sprintf("vrf-v2-plus-%s", jobUUID),
CoordinatorAddress: coordinatorAddress,
FromAddresses: []string{nativeTokenPrimaryKeyAddress},
FromAddresses: nativeTokenKeyAddresses,
EVMChainID: chainID,
MinIncomingConfirmations: int(minIncomingConfirmations),
PublicKey: pubKeyCompressed,
Expand Down Expand Up @@ -207,6 +207,7 @@ func SetupVRFV2_5Environment(
linkToken contracts.LinkToken,
mockNativeLINKFeed contracts.MockETHLINKFeed,
registerProvingKeyAgainstAddress string,
numberOfTxKeysToCreate int,
numberOfConsumers int,
numberOfSubToCreate int,
l zerolog.Logger,
Expand Down Expand Up @@ -273,17 +274,21 @@ func SetupVRFV2_5Environment(
}

chainID := env.EVMClient.GetChainID()

newNativeTokenKeyAddresses, err := CreateAndFundSendingKeys(env, vrfv2PlusConfig, numberOfTxKeysToCreate, chainID)
if err != nil {
return nil, nil, nil, err
}
nativeTokenPrimaryKeyAddress, err := env.ClCluster.NodeAPIs()[0].PrimaryEthAddress()
if err != nil {
return nil, nil, nil, fmt.Errorf("%s, err %w", ErrNodePrimaryKey, err)
}
allNativeTokenKeyAddresses := append(newNativeTokenKeyAddresses, nativeTokenPrimaryKeyAddress)

l.Info().Msg("Creating VRFV2 Plus Job")
job, err := CreateVRFV2PlusJob(
env.ClCluster.NodeAPIs()[0],
vrfv2_5Contracts.Coordinator.Address(),
nativeTokenPrimaryKeyAddress,
allNativeTokenKeyAddresses,
pubKeyCompressed,
chainID.String(),
vrfv2PlusConfig.MinimumConfirmations,
Expand All @@ -295,12 +300,8 @@ func SetupVRFV2_5Environment(
// this part is here because VRFv2 can work with only a specific key
// [[EVM.KeySpecific]]
// Key = '...'
addr, err := env.ClCluster.Nodes[0].API.PrimaryEthAddress()
if err != nil {
return nil, nil, nil, fmt.Errorf("%s, err %w", ErrGetPrimaryKey, err)
}
nodeConfig := node.NewConfig(env.ClCluster.Nodes[0].NodeConfig,
node.WithVRFv2EVMEstimator(addr, vrfv2PlusConfig.CLNodeMaxGasPriceGWei),
node.WithVRFv2EVMEstimator(allNativeTokenKeyAddresses, vrfv2PlusConfig.CLNodeMaxGasPriceGWei),
)
l.Info().Msg("Restarting Node with new sending key PriceMax configuration")
err = env.ClCluster.Nodes[0].Restart(nodeConfig)
Expand All @@ -325,6 +326,25 @@ func SetupVRFV2_5Environment(
return vrfv2_5Contracts, subIDs, &data, nil
}

func CreateAndFundSendingKeys(env *test_env.CLClusterTestEnv, vrfv2PlusConfig vrfv2plus_config.VRFV2PlusConfig, numberOfNativeTokenAddressesToCreate int, chainID *big.Int) ([]string, error) {
var newNativeTokenKeyAddresses []string
for i := 0; i < numberOfNativeTokenAddressesToCreate; i++ {
newTxKey, response, err := env.ClCluster.NodeAPIs()[0].CreateTxKey("evm", chainID.String())
if err != nil {
return nil, fmt.Errorf("%s, err %w", ErrNodeNewTxKey, err)
}
if response.StatusCode != 200 {
return nil, fmt.Errorf("error creating transaction key - response code, err %d", response.StatusCode)
}
newNativeTokenKeyAddresses = append(newNativeTokenKeyAddresses, newTxKey.Data.ID)
err = actions.FundAddress(env.EVMClient, newTxKey.Data.ID, big.NewFloat(vrfv2PlusConfig.ChainlinkNodeFunding))
if err != nil {
return nil, err
}
}
return newNativeTokenKeyAddresses, nil
}

func CreateFundSubsAndAddConsumers(
env *test_env.CLClusterTestEnv,
vrfv2PlusConfig vrfv2plus_config.VRFV2PlusConfig,
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/contracts/contract_vrf_models.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ type VRFv2Consumer interface {

type VRFv2LoadTestConsumer interface {
Address() string
RequestRandomness(hash [32]byte, subID uint64, confs uint16, gasLimit uint32, numWords uint32, requestCount uint16) error
RequestRandomness(hash [32]byte, subID uint64, confs uint16, gasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error)
GetRequestStatus(ctx context.Context, requestID *big.Int) (vrf_load_test_with_metrics.GetRequestStatus, error)
GetLastRequestId(ctx context.Context) (*big.Int, error)
GetLoadTestMetrics(ctx context.Context) (*VRFLoadTestMetrics, error)
Expand Down
15 changes: 11 additions & 4 deletions integration-tests/contracts/ethereum_vrfv2_contracts.go
Original file line number Diff line number Diff line change
Expand Up @@ -441,17 +441,24 @@ func (v *EthereumVRFv2LoadTestConsumer) Address() string {
return v.address.Hex()
}

func (v *EthereumVRFv2LoadTestConsumer) RequestRandomness(keyHash [32]byte, subID uint64, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) error {
func (v *EthereumVRFv2LoadTestConsumer) RequestRandomness(
keyHash [32]byte,
subID uint64,
requestConfirmations uint16,
callbackGasLimit uint32,
numWords uint32,
requestCount uint16,
) (*types.Transaction, error) {
opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet())
if err != nil {
return err
return nil, err
}

tx, err := v.consumer.RequestRandomWords(opts, subID, requestConfirmations, keyHash, callbackGasLimit, numWords, requestCount)
if err != nil {
return err
return nil, err
}
return v.client.ProcessTransaction(tx)
return tx, v.client.ProcessTransaction(tx)
}

func (v *EthereumVRFv2Consumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrf_v2_consumer_wrapper.GetRequestStatus, error) {
Expand Down
2 changes: 1 addition & 1 deletion integration-tests/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
github.com/cli/go-gh/v2 v2.0.0
github.com/ethereum/go-ethereum v1.12.0
github.com/go-resty/resty/v2 v2.7.0
github.com/google/go-cmp v0.5.9
github.com/google/uuid v1.3.1
github.com/jmoiron/sqlx v1.3.5
github.com/kelseyhightower/envconfig v1.4.0
Expand Down Expand Up @@ -191,7 +192,6 @@ require (
github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect
github.com/google/btree v1.1.2 // indirect
github.com/google/gnostic v0.6.9 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/go-tpm v0.9.0 // indirect
github.com/google/gofuzz v1.2.0 // indirect
Expand Down
10 changes: 2 additions & 8 deletions integration-tests/load/vrfv2/vrfv2_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"testing"
"time"

"github.com/ethereum/go-ethereum"
"github.com/ethereum/go-ethereum/common"
"github.com/kelseyhightower/envconfig"
"github.com/rs/zerolog"
Expand Down Expand Up @@ -199,6 +198,7 @@ func TestVRFV2Performance(t *testing.T) {
mockETHLinkFeed,
//register proving key against EOA address in order to return funds to this address
env.EVMClient.GetDefaultWallet().Address(),
0,
1,
vrfv2Config.NumberOfSubToCreate,
l,
Expand Down Expand Up @@ -302,13 +302,7 @@ func FundNodesIfNeeded(cfg *PerformanceConfig, client blockchain.EVMClient, l ze
Str("Should have at least", fundingAtLeast.String()).
Str("Funding Amount in ETH", fundingToSendEth.String()).
Msg("Funding Node's Sending Key")
gasEstimates, err := client.EstimateGas(ethereum.CallMsg{
To: &address,
})
if err != nil {
return err
}
err = client.Fund(sendingKey, fundingToSendEth, gasEstimates)
err := actions.FundAddress(client, sendingKey, fundingToSendEth)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions integration-tests/load/vrfv2plus/vrfv2plus_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ func TestVRFV2PlusPerformance(t *testing.T) {
mockETHLinkFeed,
//register proving key against EOA address in order to return funds to this address
env.EVMClient.GetDefaultWallet().Address(),
0,
1,
vrfv2PlusConfig.NumberOfSubToCreate,
l,
Expand Down
Loading

0 comments on commit 9686592

Please sign in to comment.