diff --git a/core/scripts/common/vrf/model/model.go b/core/scripts/common/vrf/model/model.go index bd0e3bbe364..42deb424536 100644 --- a/core/scripts/common/vrf/model/model.go +++ b/core/scripts/common/vrf/model/model.go @@ -44,3 +44,8 @@ type ContractAddresses struct { CoordinatorAddress common.Address BatchCoordinatorAddress common.Address } + +type VRFKeyRegistrationConfig struct { + VRFKeyUncompressedPubKey string + RegisterAgainstAddress string +} diff --git a/core/scripts/common/vrf/setup-envs/README.md b/core/scripts/common/vrf/setup-envs/README.md index 33515338a24..f3b391f0eed 100644 --- a/core/scripts/common/vrf/setup-envs/README.md +++ b/core/scripts/common/vrf/setup-envs/README.md @@ -35,7 +35,9 @@ go run . \ --min-confs=3 \ --num-eth-keys=1 \ --num-vrf-keys=1 \ ---sending-key-funding-amount="1e17" +--sending-key-funding-amount="1e17" \ +--register-vrf-key-against-address= ``` Optional parameters - will not be deployed if specified (NOT WORKING YET) diff --git a/core/scripts/common/vrf/setup-envs/main.go b/core/scripts/common/vrf/setup-envs/main.go index 6748408f476..7c2530ffd47 100644 --- a/core/scripts/common/vrf/setup-envs/main.go +++ b/core/scripts/common/vrf/setup-envs/main.go @@ -85,6 +85,8 @@ func main() { batchBHSAddressString := flag.String("batch-bhs-address", "", "address of Batch BHS contract") coordinatorAddressString := flag.String("coordinator-address", "", "address of VRF Coordinator contract") batchCoordinatorAddressString := flag.String("batch-coordinator-address", "", "address Batch VRF Coordinator contract") + registerVRFKeyAgainstAddress := flag.String("register-vrf-key-against-address", "", "VRF Key registration against address - "+ + "from this address you can perform `coordinator.oracleWithdraw` to withdraw earned funds from rand request fulfilments") e := helpers.SetupEnv(false) flag.Parse() @@ -171,6 +173,11 @@ func main() { BatchCoordinatorAddress: common.HexToAddress(*batchCoordinatorAddressString), } + vrfKeyRegistrationConfig := model.VRFKeyRegistrationConfig{ + VRFKeyUncompressedPubKey: nodesMap[model.VRFPrimaryNodeName].VrfKeys[0], + RegisterAgainstAddress: *registerVRFKeyAgainstAddress, + } + var jobSpecs model.JobSpecs switch *vrfVersion { @@ -188,10 +195,10 @@ func main() { } coordinatorConfigV2 := v2scripts.CoordinatorConfigV2{ - MinConfs: minConfs, - MaxGasLimit: &constants.MaxGasLimit, - StalenessSeconds: &constants.StalenessSeconds, - GasAfterPayment: &constants.GasAfterPayment, + MinConfs: *minConfs, + MaxGasLimit: constants.MaxGasLimit, + StalenessSeconds: constants.StalenessSeconds, + GasAfterPayment: constants.GasAfterPayment, FallbackWeiPerUnitLink: constants.FallbackWeiPerUnitLink, FeeConfig: feeConfigV2, } @@ -199,7 +206,7 @@ func main() { jobSpecs = v2scripts.VRFV2DeployUniverse( e, subscriptionBalanceJuels, - &nodesMap[model.VRFPrimaryNodeName].VrfKeys[0], + vrfKeyRegistrationConfig, contractAddresses, coordinatorConfigV2, *batchFulfillmentEnabled, @@ -211,10 +218,10 @@ func main() { FulfillmentFlatFeeNativePPM: uint32(constants.FlatFeeNativePPM), } coordinatorConfigV2Plus := v2plusscripts.CoordinatorConfigV2Plus{ - MinConfs: minConfs, - MaxGasLimit: &constants.MaxGasLimit, - StalenessSeconds: &constants.StalenessSeconds, - GasAfterPayment: &constants.GasAfterPayment, + MinConfs: *minConfs, + MaxGasLimit: constants.MaxGasLimit, + StalenessSeconds: constants.StalenessSeconds, + GasAfterPayment: constants.GasAfterPayment, FallbackWeiPerUnitLink: constants.FallbackWeiPerUnitLink, FeeConfig: feeConfigV2Plus, } @@ -223,7 +230,7 @@ func main() { e, subscriptionBalanceJuels, subscriptionBalanceNativeWei, - &nodesMap[model.VRFPrimaryNodeName].VrfKeys[0], + vrfKeyRegistrationConfig, contractAddresses, coordinatorConfigV2Plus, *batchFulfillmentEnabled, diff --git a/core/scripts/vrfv2/testnet/README.md b/core/scripts/vrfv2/testnet/README.md index 1b2d986f554..b527c576fd0 100644 --- a/core/scripts/vrfv2/testnet/README.md +++ b/core/scripts/vrfv2/testnet/README.md @@ -57,11 +57,19 @@ To deploy a full VRF environment on-chain, run: ```shell go run . deploy-universe \ ---sending-key-funding-amount 100000000000000000 \ ---subscription-balance=10000000000000000000 \ +--subscription-balance=5000000000000000000 \ #5 LINK --uncompressed-pub-key= \ ---vrf-primary-node-sending-keys="" \ ---batch-fulfillment-enabled false +--vrf-primary-node-sending-keys="" \ #used to fund the keys and for sample VRF Job Spec generation +--sending-key-funding-amount 100000000000000000 \ #0.1 ETH, fund addresses specified in vrf-primary-node-sending-keys +--batch-fulfillment-enabled false \ #only used for sample VRF Job Spec generation +--register-vrf-key-against-address=<"from this address you can perform `coordinator.oracleWithdraw` to withdraw earned funds from rand request fulfilments> +``` +```shell +go run . deploy-universe \ +--subscription-balance=5000000000000000000 \ +--uncompressed-pub-key="0xf3706e247a7b205c8a8bd25a6e8c4650474da496151371085d45beeead27e568c1a5e8330c7fa718f8a31226efbff6632ed6f8ed470b637aa9be2b948e9dcef6" \ +--batch-fulfillment-enabled false \ +--register-vrf-key-against-address="0x23b5613fc04949F4A53d1cc8d6BCCD21ffc38C11" ``` ## Deploying the Consumer Contract diff --git a/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go b/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go index 23ad8e1374b..b623ae63084 100644 --- a/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go +++ b/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go @@ -26,10 +26,10 @@ import ( ) type CoordinatorConfigV2 struct { - MinConfs *int - MaxGasLimit *int64 - StalenessSeconds *int64 - GasAfterPayment *int64 + MinConfs int + MaxGasLimit int64 + StalenessSeconds int64 + GasAfterPayment int64 FallbackWeiPerUnitLink *big.Int FeeConfig vrf_coordinator_v2.VRFCoordinatorV2FeeConfig } @@ -52,7 +52,10 @@ func DeployUniverseViaCLI(e helpers.Environment) { // optional flags fallbackWeiPerUnitLinkString := deployCmd.String("fallback-wei-per-unit-link", constants.FallbackWeiPerUnitLink.String(), "fallback wei/link ratio") - registerKeyUncompressedPubKey := deployCmd.String("uncompressed-pub-key", "", "uncompressed public key") + registerVRFKeyUncompressedPubKey := deployCmd.String("uncompressed-pub-key", "", "uncompressed public key") + registerVRFKeyAgainstAddress := deployCmd.String("register-vrf-key-against-address", "", "VRF Key registration against address - "+ + "from this address you can perform `coordinator.oracleWithdraw` to withdraw earned funds from rand request fulfilments") + vrfPrimaryNodeSendingKeysString := deployCmd.String("vrf-primary-node-sending-keys", "", "VRF Primary Node sending keys") minConfs := deployCmd.Int("min-confs", constants.MinConfs, "min confs") @@ -119,18 +122,23 @@ func DeployUniverseViaCLI(e helpers.Environment) { } coordinatorConfig := CoordinatorConfigV2{ - MinConfs: minConfs, - MaxGasLimit: maxGasLimit, - StalenessSeconds: stalenessSeconds, - GasAfterPayment: gasAfterPayment, + MinConfs: *minConfs, + MaxGasLimit: *maxGasLimit, + StalenessSeconds: *stalenessSeconds, + GasAfterPayment: *gasAfterPayment, FallbackWeiPerUnitLink: fallbackWeiPerUnitLink, FeeConfig: feeConfig, } + vrfKeyRegistrationConfig := model.VRFKeyRegistrationConfig{ + VRFKeyUncompressedPubKey: *registerVRFKeyUncompressedPubKey, + RegisterAgainstAddress: *registerVRFKeyAgainstAddress, + } + VRFV2DeployUniverse( e, subscriptionBalanceJuels, - registerKeyUncompressedPubKey, + vrfKeyRegistrationConfig, contractAddresses, coordinatorConfig, *batchFulfillmentEnabled, @@ -147,7 +155,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { func VRFV2DeployUniverse( e helpers.Environment, subscriptionBalanceJuels *big.Int, - registerKeyUncompressedPubKey *string, + vrfKeyRegistrationConfig model.VRFKeyRegistrationConfig, contractAddresses model.ContractAddresses, coordinatorConfig CoordinatorConfigV2, batchFulfillmentEnabled bool, @@ -155,14 +163,14 @@ func VRFV2DeployUniverse( ) model.JobSpecs { var compressedPkHex string var keyHash common.Hash - if len(*registerKeyUncompressedPubKey) > 0 { + if len(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey) > 0 { // Put key in ECDSA format - if strings.HasPrefix(*registerKeyUncompressedPubKey, "0x") { - *registerKeyUncompressedPubKey = strings.Replace(*registerKeyUncompressedPubKey, "0x", "04", 1) + if strings.HasPrefix(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey, "0x") { + vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey = strings.Replace(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey, "0x", "04", 1) } // Generate compressed public key and key hash - pubBytes, err := hex.DecodeString(*registerKeyUncompressedPubKey) + pubBytes, err := hex.DecodeString(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey) helpers.PanicErr(err) pk, err := crypto.UnmarshalPubkey(pubBytes) helpers.PanicErr(err) @@ -217,10 +225,10 @@ func VRFV2DeployUniverse( SetCoordinatorConfig( e, *coordinator, - uint16(*coordinatorConfig.MinConfs), - uint32(*coordinatorConfig.MaxGasLimit), - uint32(*coordinatorConfig.StalenessSeconds), - uint32(*coordinatorConfig.GasAfterPayment), + uint16(coordinatorConfig.MinConfs), + uint32(coordinatorConfig.MaxGasLimit), + uint32(coordinatorConfig.StalenessSeconds), + uint32(coordinatorConfig.GasAfterPayment), coordinatorConfig.FallbackWeiPerUnitLink, coordinatorConfig.FeeConfig, ) @@ -228,12 +236,12 @@ func VRFV2DeployUniverse( fmt.Println("\nConfig set, getting current config from deployed contract...") PrintCoordinatorConfig(coordinator) - if len(*registerKeyUncompressedPubKey) > 0 { + if len(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey) > 0 { fmt.Println("\nRegistering proving key...") //NOTE - register proving key against EOA account, and not against Oracle's sending address in other to be able // easily withdraw funds from Coordinator contract back to EOA account - RegisterCoordinatorProvingKey(e, *coordinator, *registerKeyUncompressedPubKey, e.Owner.From.String()) + RegisterCoordinatorProvingKey(e, *coordinator, vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey, vrfKeyRegistrationConfig.RegisterAgainstAddress) fmt.Println("\nProving key registered, getting proving key hashes from deployed contract...") _, _, provingKeyHashes, configErr := coordinator.GetRequestConfig(nil) @@ -271,7 +279,7 @@ func VRFV2DeployUniverse( contractAddresses.BatchCoordinatorAddress, //batchCoordinatorAddress batchFulfillmentEnabled, //batchFulfillmentEnabled compressedPkHex, //publicKey - *coordinatorConfig.MinConfs, //minIncomingConfirmations + coordinatorConfig.MinConfs, //minIncomingConfirmations e.ChainID, //evmChainID strings.Join(util.MapToAddressArr(nodesMap[model.VRFPrimaryNodeName].SendingKeys), "\",\""), //fromAddresses contractAddresses.CoordinatorAddress, @@ -348,7 +356,7 @@ func VRFV2DeployUniverse( "\nVRF Subscription Id:", subID, "\nVRF Subscription Balance:", *subscriptionBalanceJuels, "\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), + 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: ", fmt.Sprintf("go run . eoa-load-test-read-metrics --consumer-address=%s", consumerAddress), "\nA node can now be configured to run a VRF job with the below job spec :\n", diff --git a/core/scripts/vrfv2plus/testnet/README.md b/core/scripts/vrfv2plus/testnet/README.md index b95ec99d5fb..6402569c560 100644 --- a/core/scripts/vrfv2plus/testnet/README.md +++ b/core/scripts/vrfv2plus/testnet/README.md @@ -58,7 +58,16 @@ cd /core/scripts/vrfv2/testnet - Not specifying `--link-eth-feed` would make the super script deploy a new LINK-ETH feed contract and use it for funding VRF V2+ subscription ```shell -go run . deploy-universe --link-address=$LINK --link-eth-feed=$LINK_ETH_FEED --subscription-balance= --uncompressed-pub-key=$PUB_KEY --oracle-address=$ORACLE_ADDRESS +go run . deploy-universe \ +--link-address=$LINK \ +--link-eth-feed=$LINK_ETH_FEED \ +--subscription-balance=5000000000000000000 \ #5 LINK +--subscription-balance-native=1000000000000000000 \ #1 ETH +--uncompressed-pub-key= \ +--vrf-primary-node-sending-keys="" \ #used to fund the keys and for sample VRF Job Spec generation +--sending-key-funding-amount 100000000000000000 \ #0.1 ETH, fund addresses specified in vrf-primary-node-sending-keys +--batch-fulfillment-enabled false \ #only used for sample VRF Job Spec generation +--register-vrf-key-against-address="" # from this address you can perform `coordinator.oracleWithdraw` to withdraw earned funds from rand request fulfilments ``` ## Deploying the Consumer Contract diff --git a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go index 752e06bbb25..50584d885a2 100644 --- a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go +++ b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go @@ -39,10 +39,10 @@ import ( var coordinatorV2PlusABI = evmtypes.MustGetABI(vrf_coordinator_v2plus_interface.IVRFCoordinatorV2PlusInternalABI) type CoordinatorConfigV2Plus struct { - MinConfs *int - MaxGasLimit *int64 - StalenessSeconds *int64 - GasAfterPayment *int64 + MinConfs int + MaxGasLimit int64 + StalenessSeconds int64 + GasAfterPayment int64 FallbackWeiPerUnitLink *big.Int FeeConfig vrf_coordinator_v2_5.VRFCoordinatorV25FeeConfig } @@ -481,7 +481,10 @@ func DeployUniverseViaCLI(e helpers.Environment) { // optional flags fallbackWeiPerUnitLinkString := deployCmd.String("fallback-wei-per-unit-link", "6e16", "fallback wei/link ratio") - registerKeyUncompressedPubKey := deployCmd.String("uncompressed-pub-key", "", "uncompressed public key") + registerVRFKeyUncompressedPubKey := deployCmd.String("uncompressed-pub-key", "", "uncompressed public key") + registerVRFKeyAgainstAddress := deployCmd.String("register-vrf-key-against-address", "", "VRF Key registration against address - "+ + "from this address you can perform `coordinator.oracleWithdraw` to withdraw earned funds from rand request fulfilments") + vrfPrimaryNodeSendingKeysString := deployCmd.String("vrf-primary-node-sending-keys", "", "VRF Primary Node sending keys") minConfs := deployCmd.Int("min-confs", constants.MinConfs, "min confs") nodeSendingKeyFundingAmount := deployCmd.String("sending-key-funding-amount", constants.NodeSendingKeyFundingAmount, "CL node sending key funding amount") @@ -505,10 +508,17 @@ func DeployUniverseViaCLI(e helpers.Environment) { FulfillmentFlatFeeNativePPM: uint32(*flatFeeEthPPM), } - vrfPrimaryNodeSendingKeys := strings.Split(*vrfPrimaryNodeSendingKeysString, ",") + var vrfPrimaryNodeSendingKeys []string + if len(*vrfPrimaryNodeSendingKeysString) > 0 { + vrfPrimaryNodeSendingKeys = strings.Split(*vrfPrimaryNodeSendingKeysString, ",") + } nodesMap := make(map[string]model.Node) + fundingAmount, ok := new(big.Int).SetString(*nodeSendingKeyFundingAmount, 10) + if !ok { + panic(fmt.Sprintf("failed to parse node sending key funding amount '%s'", *nodeSendingKeyFundingAmount)) + } nodesMap[model.VRFPrimaryNodeName] = model.Node{ SendingKeys: util.MapToSendingKeyArr(vrfPrimaryNodeSendingKeys), SendingKeyFundingAmount: fundingAmount, @@ -529,19 +539,24 @@ func DeployUniverseViaCLI(e helpers.Environment) { } coordinatorConfig := CoordinatorConfigV2Plus{ - MinConfs: minConfs, - MaxGasLimit: maxGasLimit, - StalenessSeconds: stalenessSeconds, - GasAfterPayment: gasAfterPayment, + MinConfs: *minConfs, + MaxGasLimit: *maxGasLimit, + StalenessSeconds: *stalenessSeconds, + GasAfterPayment: *gasAfterPayment, FallbackWeiPerUnitLink: fallbackWeiPerUnitLink, FeeConfig: feeConfig, } + vrfKeyRegistrationConfig := model.VRFKeyRegistrationConfig{ + VRFKeyUncompressedPubKey: *registerVRFKeyUncompressedPubKey, + RegisterAgainstAddress: *registerVRFKeyAgainstAddress, + } + VRFV2PlusDeployUniverse( e, subscriptionBalanceJuels, subscriptionBalanceNativeWei, - registerKeyUncompressedPubKey, + vrfKeyRegistrationConfig, contractAddresses, coordinatorConfig, *batchFulfillmentEnabled, @@ -558,7 +573,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { func VRFV2PlusDeployUniverse(e helpers.Environment, subscriptionBalanceJuels *big.Int, subscriptionBalanceNativeWei *big.Int, - registerKeyUncompressedPubKey *string, + vrfKeyRegistrationConfig model.VRFKeyRegistrationConfig, contractAddresses model.ContractAddresses, coordinatorConfig CoordinatorConfigV2Plus, batchFulfillmentEnabled bool, @@ -566,14 +581,14 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, ) model.JobSpecs { var compressedPkHex string var keyHash common.Hash - if len(*registerKeyUncompressedPubKey) > 0 { + if len(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey) > 0 { // Put key in ECDSA format - if strings.HasPrefix(*registerKeyUncompressedPubKey, "0x") { - *registerKeyUncompressedPubKey = strings.Replace(*registerKeyUncompressedPubKey, "0x", "04", 1) + if strings.HasPrefix(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey, "0x") { + vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey = strings.Replace(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey, "0x", "04", 1) } // Generate compressed public key and key hash - pubBytes, err := hex.DecodeString(*registerKeyUncompressedPubKey) + pubBytes, err := hex.DecodeString(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey) helpers.PanicErr(err) pk, err := crypto.UnmarshalPubkey(pubBytes) helpers.PanicErr(err) @@ -628,10 +643,10 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, SetCoordinatorConfig( e, *coordinator, - uint16(*coordinatorConfig.MinConfs), - uint32(*coordinatorConfig.MaxGasLimit), - uint32(*coordinatorConfig.StalenessSeconds), - uint32(*coordinatorConfig.GasAfterPayment), + uint16(coordinatorConfig.MinConfs), + uint32(coordinatorConfig.MaxGasLimit), + uint32(coordinatorConfig.StalenessSeconds), + uint32(coordinatorConfig.GasAfterPayment), coordinatorConfig.FallbackWeiPerUnitLink, coordinatorConfig.FeeConfig, ) @@ -639,12 +654,12 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, fmt.Println("\nConfig set, getting current config from deployed contract...") PrintCoordinatorConfig(coordinator) - if len(*registerKeyUncompressedPubKey) > 0 { + if len(vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey) > 0 { fmt.Println("\nRegistering proving key...") //NOTE - register proving key against EOA account, and not against Oracle's sending address in other to be able // easily withdraw funds from Coordinator contract back to EOA account - RegisterCoordinatorProvingKey(e, *coordinator, *registerKeyUncompressedPubKey, e.Owner.From.String()) + RegisterCoordinatorProvingKey(e, *coordinator, vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey, vrfKeyRegistrationConfig.RegisterAgainstAddress) fmt.Println("\nProving key registered, getting proving key hashes from deployed contract...") _, _, provingKeyHashes, configErr := coordinator.GetRequestConfig(nil) @@ -690,7 +705,7 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, contractAddresses.BatchCoordinatorAddress, //batchCoordinatorAddress batchFulfillmentEnabled, //batchFulfillmentEnabled compressedPkHex, //publicKey - *coordinatorConfig.MinConfs, //minIncomingConfirmations + coordinatorConfig.MinConfs, //minIncomingConfirmations e.ChainID, //evmChainID strings.Join(util.MapToAddressArr(nodesMap[model.VRFPrimaryNodeName].SendingKeys), "\",\""), //fromAddresses contractAddresses.CoordinatorAddress, @@ -768,7 +783,7 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, "\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), + 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: ", fmt.Sprintf("go run . eoa-load-test-read-metrics --consumer-address=%s", consumerAddress), "\nA node can now be configured to run a VRF job with the below job spec :\n",