From 731499a793d389882baf2ff3da81cf35d2ea6040 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs Date: Mon, 26 Feb 2024 13:42:37 +0200 Subject: [PATCH] =?UTF-8?q?VRF-881:=20fixed=20toml=20config=20for=20VRF=20?= =?UTF-8?q?Load=20tests;=20VRF-882:=20add=20more=20cust=E2=80=A6=20(#11991?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * VRF-881: fixed toml config for VRF Load tests; VRF-882: add more customisation options for BHS job in super scripts * VRF-881: fixing lint * VRF-881: upgrading ctf library * VRF-881: adding load test metric calculation in seconds for VRF V2Plus Consumer contract; adding more parametrization options in setup-env script * VRF-881: PR comments; * VRF-881: fixing Lint issues * VRF-881: fixing BHS tests * VRF-881: adding smoke test type * VRF-881: PR comments * VRF-881: fixing load test * VRF-881: fixing config * VRF-881: fixing e2e tests * VRF-881: fixing sonar * VRF-881: fixing sonar and refactoring * VRF-881: fixing lint issues --- .../on-demand-vrfv2-performance-test.yml | 1 + .../on-demand-vrfv2plus-performance-test.yml | 1 + .../VRFV2PlusLoadTestWithMetrics.sol | 83 +++-- .../vrf_v2plus_load_test_with_metrics.go | 118 ++++-- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/scripts/common/vrf/jobs/jobs.go | 9 +- core/scripts/common/vrf/model/model.go | 8 + core/scripts/common/vrf/setup-envs/README.md | 17 +- core/scripts/common/vrf/setup-envs/main.go | 63 +++- .../vrfv2/testnet/v2scripts/super_scripts.go | 21 +- core/scripts/vrfv2plus/testnet/main.go | 19 +- .../testnet/v2plusscripts/super_scripts.go | 36 +- .../actions/vrf/common/actions.go | 85 ++++- .../actions/vrf/common/errors.go | 1 + .../actions/vrf/common/models.go | 5 + integration-tests/actions/vrf/vrfv2/errors.go | 1 - .../actions/vrf/vrfv2/vrfv2_steps.go | 100 ++--- .../actions/vrf/vrfv2plus/vrfv2plus_steps.go | 288 +++++++-------- .../contracts/contract_vrf_models.go | 13 +- .../contracts/ethereum_vrfv2_contracts.go | 6 + .../contracts/ethereum_vrfv2plus_contracts.go | 55 ++- integration-tests/load/vrfv2/vrfv2_test.go | 58 ++- .../load/vrfv2plus/vrfv2plus_test.go | 68 ++-- integration-tests/smoke/vrfv2_test.go | 6 +- integration-tests/smoke/vrfv2plus_test.go | 89 +++-- .../testconfig/common/vrf/common.go | 277 ++++++++++++++ integration-tests/testconfig/vrfv2/config.go | 341 ++---------------- .../testconfig/vrfv2/example.toml | 4 +- integration-tests/testconfig/vrfv2/vrfv2.toml | 127 +++---- .../testconfig/vrfv2plus/config.go | 104 +----- .../testconfig/vrfv2plus/example.toml | 4 +- .../testconfig/vrfv2plus/vrfv2plus.toml | 146 ++------ integration-tests/testreporters/vrfv2.go | 2 +- integration-tests/testreporters/vrfv2plus.go | 61 ++-- 34 files changed, 1132 insertions(+), 1087 deletions(-) create mode 100644 integration-tests/testconfig/common/vrf/common.go diff --git a/.github/workflows/on-demand-vrfv2-performance-test.yml b/.github/workflows/on-demand-vrfv2-performance-test.yml index 1e8ab9e9b71..33377f2133c 100644 --- a/.github/workflows/on-demand-vrfv2-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2-performance-test.yml @@ -10,6 +10,7 @@ on: description: Performance Test Type of test to run type: choice options: + - "Smoke" - "Soak" - "Load" - "Stress" diff --git a/.github/workflows/on-demand-vrfv2plus-performance-test.yml b/.github/workflows/on-demand-vrfv2plus-performance-test.yml index 23484f963e3..4240486a181 100644 --- a/.github/workflows/on-demand-vrfv2plus-performance-test.yml +++ b/.github/workflows/on-demand-vrfv2plus-performance-test.yml @@ -10,6 +10,7 @@ on: description: Performance Test Type of test to run type: choice options: + - "Smoke" - "Soak" - "Load" - "Stress" diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol index c1330d32237..45eb14ee19d 100644 --- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol +++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFV2PlusLoadTestWithMetrics.sol @@ -12,12 +12,14 @@ import {VRFV2PlusClient} from "../libraries/VRFV2PlusClient.sol"; contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus { uint256 public s_responseCount; uint256 public s_requestCount; - uint256 public s_averageFulfillmentInMillions = 0; // in millions for better precision - uint256 public s_slowestFulfillment = 0; - uint256 public s_fastestFulfillment = 999; + uint256 public s_averageResponseTimeInBlocksMillions = 0; // in millions for better precision + uint256 public s_slowestResponseTimeInBlocks = 0; + uint256 public s_fastestResponseTimeInBlocks = 999; + uint256 public s_slowestResponseTimeInSeconds = 0; + uint256 public s_fastestResponseTimeInSeconds = 999; + uint256 public s_averageResponseTimeInSecondsMillions = 0; + uint256 public s_lastRequestId; - // solhint-disable-next-line chainlink-solidity/prefix-storage-variables-with-s-underscore - mapping(uint256 => uint256) internal requestHeights; // requestIds to block number when rand request was made struct RequestStatus { bool fulfilled; @@ -34,22 +36,38 @@ contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus { // solhint-disable-next-line chainlink-solidity/prefix-internal-functions-with-underscore function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { - uint256 fulfilmentBlockNumber = ChainSpecificUtil._getBlockNumber(); - uint256 requestDelay = fulfilmentBlockNumber - requestHeights[_requestId]; - uint256 requestDelayInMillions = requestDelay * 1_000_000; - - if (requestDelay > s_slowestFulfillment) { - s_slowestFulfillment = requestDelay; - } - s_fastestFulfillment = requestDelay < s_fastestFulfillment ? requestDelay : s_fastestFulfillment; - s_averageFulfillmentInMillions = s_responseCount > 0 - ? (s_averageFulfillmentInMillions * s_responseCount + requestDelayInMillions) / (s_responseCount + 1) - : requestDelayInMillions; - s_requests[_requestId].fulfilled = true; s_requests[_requestId].randomWords = _randomWords; s_requests[_requestId].fulfilmentTimestamp = block.timestamp; - s_requests[_requestId].fulfilmentBlockNumber = fulfilmentBlockNumber; + s_requests[_requestId].fulfilmentBlockNumber = ChainSpecificUtil._getBlockNumber(); + + uint256 responseTimeInBlocks = s_requests[_requestId].fulfilmentBlockNumber - + s_requests[_requestId].requestBlockNumber; + uint256 responseTimeInSeconds = s_requests[_requestId].fulfilmentTimestamp - + s_requests[_requestId].requestTimestamp; + + ( + s_slowestResponseTimeInBlocks, + s_fastestResponseTimeInBlocks, + s_averageResponseTimeInBlocksMillions + ) = _calculateMetrics( + responseTimeInBlocks, + s_fastestResponseTimeInBlocks, + s_slowestResponseTimeInBlocks, + s_averageResponseTimeInBlocksMillions, + s_responseCount + ); + ( + s_slowestResponseTimeInSeconds, + s_fastestResponseTimeInSeconds, + s_averageResponseTimeInSecondsMillions + ) = _calculateMetrics( + responseTimeInSeconds, + s_fastestResponseTimeInSeconds, + s_slowestResponseTimeInSeconds, + s_averageResponseTimeInSecondsMillions, + s_responseCount + ); s_responseCount++; } @@ -86,14 +104,16 @@ contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus { fulfilmentBlockNumber: 0 }); s_requestCount++; - requestHeights[requestId] = requestBlockNumber; } } function reset() external { - s_averageFulfillmentInMillions = 0; // in millions for better precision - s_slowestFulfillment = 0; - s_fastestFulfillment = 999; + s_averageResponseTimeInBlocksMillions = 0; // in millions for better precision + s_slowestResponseTimeInBlocks = 0; + s_fastestResponseTimeInBlocks = 999; + s_averageResponseTimeInSecondsMillions = 0; // in millions for better precision + s_slowestResponseTimeInSeconds = 0; + s_fastestResponseTimeInSeconds = 999; s_requestCount = 0; s_responseCount = 0; } @@ -122,4 +142,23 @@ contract VRFV2PlusLoadTestWithMetrics is VRFConsumerBaseV2Plus { request.fulfilmentBlockNumber ); } + + function _calculateMetrics( + uint256 _responseTime, + uint256 _fastestResponseTime, + uint256 _slowestResponseTime, + uint256 _averageInMillions, + uint256 _responseCount + ) internal returns (uint256 slowest, uint256 fastest, uint256 average) { + uint256 _requestDelayInMillions = _responseTime * 1_000_000; + if (_responseTime > _slowestResponseTime) { + _slowestResponseTime = _responseTime; + } + _fastestResponseTime = _responseTime < _fastestResponseTime ? _responseTime : _fastestResponseTime; + uint256 _averageInMillions = _responseCount > 0 + ? (_averageInMillions * _responseCount + _requestDelayInMillions) / (_responseCount + 1) + : _requestDelayInMillions; + + return (_slowestResponseTime, _fastestResponseTime, _averageInMillions); + } } diff --git a/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go b/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go index 017423772f7..8de1b8c35cd 100644 --- a/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go +++ b/core/gethwrappers/generated/vrf_v2plus_load_test_with_metrics/vrf_v2plus_load_test_with_metrics.go @@ -31,8 +31,8 @@ var ( ) var VRFV2PlusLoadTestWithMetricsMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"_nativePayment\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestCount\",\"type\":\"uint16\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_averageFulfillmentInMillions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fastestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_responseCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestFulfillment\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x6080604052600060055560006006556103e760075534801561002057600080fd5b5060405161136538038061136583398101604081905261003f9161019b565b8033806000816100965760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100c6576100c6816100f1565b5050600280546001600160a01b0319166001600160a01b039390931692909217909155506101cb9050565b6001600160a01b03811633141561014a5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161008d565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156101ad57600080fd5b81516001600160a01b03811681146101c457600080fd5b9392505050565b61118b806101da6000396000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c80638ea9811711610097578063d826f88f11610066578063d826f88f14610252578063d8a4676f14610271578063dc1670db14610296578063f2fde38b1461029f57600080fd5b80638ea98117146101ab5780639eccacf6146101be578063a168fa89146101de578063b1e217491461024957600080fd5b8063737144bc116100d3578063737144bc1461015257806374dba1241461015b57806379ba5097146101645780638da5cb5b1461016c57600080fd5b80631757f11c146101055780631fe543e314610121578063557d2e92146101365780636846de201461013f575b600080fd5b61010e60065481565b6040519081526020015b60405180910390f35b61013461012f366004610d84565b6102b2565b005b61010e60045481565b61013461014d366004610e73565b610338565b61010e60055481565b61010e60075481565b610134610565565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610118565b6101346101b9366004610d15565b610662565b6002546101869073ffffffffffffffffffffffffffffffffffffffff1681565b61021f6101ec366004610d52565b600a602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a001610118565b61010e60085481565b6101346000600581905560068190556103e76007556004819055600355565b61028461027f366004610d52565b61076d565b60405161011896959493929190610ef2565b61010e60035481565b6101346102ad366004610d15565b610852565b60025473ffffffffffffffffffffffffffffffffffffffff16331461032a576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6103348282610866565b5050565b610340610991565b60005b8161ffff168161ffff16101561055b5760006040518060c001604052808881526020018a81526020018961ffff1681526020018763ffffffff1681526020018563ffffffff1681526020016103a76040518060200160405280891515815250610a14565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610405908590600401610f5e565b602060405180830381600087803b15801561041f57600080fd5b505af1158015610433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104579190610d6b565b600881905590506000610468610ad0565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a08401839052878352600a815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690151517815590518051949550919390926104f6926001850192910190610c8a565b506040820151600282015560608201516003820155608082015160048083019190915560a0909201516005909101558054906000610533836110e7565b9091555050600091825260096020526040909120555080610553816110c5565b915050610343565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1633146105e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e6572000000000000000000006044820152606401610321565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff1633148015906106a2575060025473ffffffffffffffffffffffffffffffffffffffff163314155b1561072657336106c760005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff93841660048201529183166024830152919091166044820152606401610321565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000818152600a60209081526040808320815160c081018352815460ff16151581526001820180548451818702810187019095528085526060958795869586958695869591949293858401939092908301828280156107eb57602002820191906000526020600020905b8154815260200190600101908083116107d7575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b61085a610991565b61086381610b6d565b50565b6000610870610ad0565b6000848152600960205260408120549192509061088d90836110ae565b9050600061089e82620f4240611071565b90506006548211156108b05760068290555b60075482106108c1576007546108c3565b815b6007556003546108d35780610906565b6003546108e190600161101e565b816003546005546108f29190611071565b6108fc919061101e565b6109069190611036565b6005556000858152600a6020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558651610958939290910191870190610c8a565b506000858152600a60205260408120426003808301919091556005909101859055805491610985836110e7565b91905055505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a12576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610321565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610a4d91511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b600046610adc81610c63565b15610b6657606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b2857600080fd5b505afa158015610b3c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b609190610d6b565b91505090565b4391505090565b73ffffffffffffffffffffffffffffffffffffffff8116331415610bed576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610321565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600061a4b1821480610c77575062066eed82145b80610c84575062066eee82145b92915050565b828054828255906000526020600020908101928215610cc5579160200282015b82811115610cc5578251825591602001919060010190610caa565b50610cd1929150610cd5565b5090565b5b80821115610cd15760008155600101610cd6565b803561ffff81168114610cfc57600080fd5b919050565b803563ffffffff81168114610cfc57600080fd5b600060208284031215610d2757600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610d4b57600080fd5b9392505050565b600060208284031215610d6457600080fd5b5035919050565b600060208284031215610d7d57600080fd5b5051919050565b60008060408385031215610d9757600080fd5b8235915060208084013567ffffffffffffffff80821115610db757600080fd5b818601915086601f830112610dcb57600080fd5b813581811115610ddd57610ddd61114f565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610e2057610e2061114f565b604052828152858101935084860182860187018b1015610e3f57600080fd5b600095505b83861015610e62578035855260019590950194938601938601610e44565b508096505050505050509250929050565b600080600080600080600060e0888a031215610e8e57600080fd5b87359650610e9e60208901610cea565b955060408801359450610eb360608901610d01565b935060808801358015158114610ec857600080fd5b9250610ed660a08901610d01565b9150610ee460c08901610cea565b905092959891949750929550565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b81811015610f3557845183529383019391830191600101610f19565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b81811015610fd55782810184015186820161010001528301610fb8565b81811115610fe857600061010083880101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169390930161010001949350505050565b6000821982111561103157611031611120565b500190565b60008261106c577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156110a9576110a9611120565b500290565b6000828210156110c0576110c0611120565b500390565b600061ffff808316818114156110dd576110dd611120565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561111957611119611120565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"want\",\"type\":\"address\"}],\"name\":\"OnlyCoordinatorCanFulfill\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"have\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"coordinator\",\"type\":\"address\"}],\"name\":\"OnlyOwnerOrCoordinator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddress\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_requestId\",\"type\":\"uint256\"}],\"name\":\"getRequestStatus\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"internalType\":\"uint256[]\",\"name\":\"randomWords\",\"type\":\"uint256[]\"}],\"name\":\"rawFulfillRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"_subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"_requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"bytes32\",\"name\":\"_keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint32\",\"name\":\"_callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"_nativePayment\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"_numWords\",\"type\":\"uint32\"},{\"internalType\":\"uint16\",\"name\":\"_requestCount\",\"type\":\"uint16\"}],\"name\":\"requestRandomWords\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"reset\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_averageResponseTimeInBlocksMillions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_averageResponseTimeInSecondsMillions\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fastestResponseTimeInBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fastestResponseTimeInSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_lastRequestId\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_requestCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requests\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"fulfilled\",\"type\":\"bool\"},{\"internalType\":\"uint256\",\"name\":\"requestTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentTimestamp\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"requestBlockNumber\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"fulfilmentBlockNumber\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_responseCount\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestResponseTimeInBlocks\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_slowestResponseTimeInSeconds\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_vrfCoordinator\",\"outputs\":[{\"internalType\":\"contractIVRFCoordinatorV2Plus\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_vrfCoordinator\",\"type\":\"address\"}],\"name\":\"setCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x6080604052600060055560006006556103e760075560006008556103e76009556000600a5534801561003057600080fd5b506040516200144f3803806200144f833981016040819052610051916101ad565b8033806000816100a85760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b03848116919091179091558116156100d8576100d881610103565b5050600280546001600160a01b0319166001600160a01b039390931692909217909155506101dd9050565b6001600160a01b03811633141561015c5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161009f565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156101bf57600080fd5b81516001600160a01b03811681146101d657600080fd5b9392505050565b61126280620001ed6000396000f3fe608060405234801561001057600080fd5b50600436106101515760003560e01c80638ea98117116100cd578063b1e2174911610081578063d8a4676f11610066578063d8a4676f146102ec578063dc1670db14610311578063f2fde38b1461031a57600080fd5b8063b1e21749146102b5578063d826f88f146102be57600080fd5b8063a168fa89116100b2578063a168fa8914610238578063a4c52cf5146102a3578063ad00fe61146102ac57600080fd5b80638ea98117146102055780639eccacf61461021857600080fd5b8063557d2e921161012457806379ba50971161010957806379ba5097146101b557806381a4342c146101bd5780638da5cb5b146101c657600080fd5b8063557d2e92146101995780636846de20146101a257600080fd5b806301e5f828146101565780631742748e146101725780631fe543e31461017b57806339aea80a14610190575b600080fd5b61015f60065481565b6040519081526020015b60405180910390f35b61015f600a5481565b61018e610189366004610e5b565b61032d565b005b61015f60075481565b61015f60045481565b61018e6101b0366004610f4a565b6103b3565b61018e6105d3565b61015f60055481565b60005473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610169565b61018e610213366004610dec565b6106d0565b6002546101e09073ffffffffffffffffffffffffffffffffffffffff1681565b610279610246366004610e29565b600c602052600090815260409020805460028201546003830154600484015460059094015460ff90931693919290919085565b6040805195151586526020860194909452928401919091526060830152608082015260a001610169565b61015f60095481565b61015f60085481565b61015f600b5481565b61018e6000600581905560068190556103e76007819055600a82905560088290556009556004819055600355565b6102ff6102fa366004610e29565b6107db565b60405161016996959493929190610fc9565b61015f60035481565b61018e610328366004610dec565b6108c0565b60025473ffffffffffffffffffffffffffffffffffffffff1633146103a5576002546040517f1cf993f400000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911660248201526044015b60405180910390fd5b6103af82826108d4565b5050565b6103bb6109ed565b60005b8161ffff168161ffff1610156105c95760006040518060c001604052808881526020018a81526020018961ffff1681526020018763ffffffff1681526020018563ffffffff1681526020016104226040518060200160405280891515815250610a70565b90526002546040517f9b1c385e00000000000000000000000000000000000000000000000000000000815291925060009173ffffffffffffffffffffffffffffffffffffffff90911690639b1c385e90610480908590600401611035565b602060405180830381600087803b15801561049a57600080fd5b505af11580156104ae573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104d29190610e42565b600b819055905060006104e3610b2c565b6040805160c08101825260008082528251818152602080820185528084019182524284860152606084018390526080840186905260a08401839052878352600c815293909120825181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169015151781559051805194955091939092610571926001850192910190610d61565b506040820151600282015560608201516003820155608082015160048083019190915560a09092015160059091015580549060006105ae836111be565b919050555050505080806105c19061119c565b9150506103be565b5050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610654576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e657200000000000000000000604482015260640161039c565b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b60005473ffffffffffffffffffffffffffffffffffffffff163314801590610710575060025473ffffffffffffffffffffffffffffffffffffffff163314155b15610794573361073560005473ffffffffffffffffffffffffffffffffffffffff1690565b6002546040517f061db9c100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff9384166004820152918316602483015291909116604482015260640161039c565b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000818152600c60209081526040808320815160c081018352815460ff161515815260018201805484518187028101870190955280855260609587958695869586958695919492938584019390929083018282801561085957602002820191906000526020600020905b815481526020019060010190808311610845575b505050505081526020016002820154815260200160038201548152602001600482015481526020016005820154815250509050806000015181602001518260400151836060015184608001518560a001519650965096509650965096505091939550919395565b6108c86109ed565b6108d181610bc9565b50565b6000828152600c6020908152604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811782558351610923939290910191840190610d61565b506000828152600c6020526040902042600390910155610941610b2c565b6000838152600c60205260408120600581018390556004015490916109669190611185565b6000848152600c602052604081206002810154600390910154929350909161098e9190611185565b90506109a582600754600654600554600354610cbf565b600555600755600655600954600854600a546003546109c993859390929091610cbf565b600a55600955600855600380549060006109e2836111be565b919050555050505050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610a6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e657200000000000000000000604482015260640161039c565b565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401610aa991511515815260200190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915292915050565b600046610b3881610d3a565b15610bc257606473ffffffffffffffffffffffffffffffffffffffff1663a3b1b31d6040518163ffffffff1660e01b815260040160206040518083038186803b158015610b8457600080fd5b505afa158015610b98573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bbc9190610e42565b91505090565b4391505090565b73ffffffffffffffffffffffffffffffffffffffff8116331415610c49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640161039c565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000808080610cd189620f4240611148565b905086891115610cdf578896505b878910610cec5787610cee565b885b97506000808611610cff5781610d29565b610d0a8660016110f5565b82610d15888a611148565b610d1f91906110f5565b610d29919061110d565b979a98995096979650505050505050565b600061a4b1821480610d4e575062066eed82145b80610d5b575062066eee82145b92915050565b828054828255906000526020600020908101928215610d9c579160200282015b82811115610d9c578251825591602001919060010190610d81565b50610da8929150610dac565b5090565b5b80821115610da85760008155600101610dad565b803561ffff81168114610dd357600080fd5b919050565b803563ffffffff81168114610dd357600080fd5b600060208284031215610dfe57600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610e2257600080fd5b9392505050565b600060208284031215610e3b57600080fd5b5035919050565b600060208284031215610e5457600080fd5b5051919050565b60008060408385031215610e6e57600080fd5b8235915060208084013567ffffffffffffffff80821115610e8e57600080fd5b818601915086601f830112610ea257600080fd5b813581811115610eb457610eb4611226565b8060051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108582111715610ef757610ef7611226565b604052828152858101935084860182860187018b1015610f1657600080fd5b600095505b83861015610f39578035855260019590950194938601938601610f1b565b508096505050505050509250929050565b600080600080600080600060e0888a031215610f6557600080fd5b87359650610f7560208901610dc1565b955060408801359450610f8a60608901610dd8565b935060808801358015158114610f9f57600080fd5b9250610fad60a08901610dd8565b9150610fbb60c08901610dc1565b905092959891949750929550565b600060c082018815158352602060c08185015281895180845260e086019150828b01935060005b8181101561100c57845183529383019391830191600101610ff0565b505060408501989098525050506060810193909352608083019190915260a09091015292915050565b6000602080835283518184015280840151604084015261ffff6040850151166060840152606084015163ffffffff80821660808601528060808701511660a0860152505060a084015160c08085015280518060e086015260005b818110156110ac578281018401518682016101000152830161108f565b818111156110bf57600061010083880101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169390930161010001949350505050565b60008219821115611108576111086111f7565b500190565b600082611143577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615611180576111806111f7565b500290565b600082821015611197576111976111f7565b500390565b600061ffff808316818114156111b4576111b46111f7565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156111f0576111f06111f7565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea164736f6c6343000806000a", } var VRFV2PlusLoadTestWithMetricsABI = VRFV2PlusLoadTestWithMetricsMetaData.ABI @@ -227,9 +227,9 @@ func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) return _VRFV2PlusLoadTestWithMetrics.Contract.Owner(&_VRFV2PlusLoadTestWithMetrics.CallOpts) } -func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error) { +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SAverageResponseTimeInBlocksMillions(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_averageFulfillmentInMillions") + err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_averageResponseTimeInBlocksMillions") if err != nil { return *new(*big.Int), err @@ -241,17 +241,17 @@ func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SAverag } -func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SAverageFulfillmentInMillions() (*big.Int, error) { - return _VRFV2PlusLoadTestWithMetrics.Contract.SAverageFulfillmentInMillions(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SAverageResponseTimeInBlocksMillions() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SAverageResponseTimeInBlocksMillions(&_VRFV2PlusLoadTestWithMetrics.CallOpts) } -func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SAverageFulfillmentInMillions() (*big.Int, error) { - return _VRFV2PlusLoadTestWithMetrics.Contract.SAverageFulfillmentInMillions(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SAverageResponseTimeInBlocksMillions() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SAverageResponseTimeInBlocksMillions(&_VRFV2PlusLoadTestWithMetrics.CallOpts) } -func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error) { +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SAverageResponseTimeInSecondsMillions(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_fastestFulfillment") + err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_averageResponseTimeInSecondsMillions") if err != nil { return *new(*big.Int), err @@ -263,12 +263,56 @@ func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SFastes } -func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SFastestFulfillment() (*big.Int, error) { - return _VRFV2PlusLoadTestWithMetrics.Contract.SFastestFulfillment(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SAverageResponseTimeInSecondsMillions() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SAverageResponseTimeInSecondsMillions(&_VRFV2PlusLoadTestWithMetrics.CallOpts) } -func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SFastestFulfillment() (*big.Int, error) { - return _VRFV2PlusLoadTestWithMetrics.Contract.SFastestFulfillment(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SAverageResponseTimeInSecondsMillions() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SAverageResponseTimeInSecondsMillions(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +} + +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SFastestResponseTimeInBlocks(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_fastestResponseTimeInBlocks") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SFastestResponseTimeInBlocks() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SFastestResponseTimeInBlocks(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +} + +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SFastestResponseTimeInBlocks() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SFastestResponseTimeInBlocks(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +} + +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SFastestResponseTimeInSeconds(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_fastestResponseTimeInSeconds") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SFastestResponseTimeInSeconds() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SFastestResponseTimeInSeconds(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +} + +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SFastestResponseTimeInSeconds() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SFastestResponseTimeInSeconds(&_VRFV2PlusLoadTestWithMetrics.CallOpts) } func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SLastRequestId(opts *bind.CallOpts) (*big.Int, error) { @@ -370,9 +414,9 @@ func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) return _VRFV2PlusLoadTestWithMetrics.Contract.SResponseCount(&_VRFV2PlusLoadTestWithMetrics.CallOpts) } -func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error) { +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SSlowestResponseTimeInBlocks(opts *bind.CallOpts) (*big.Int, error) { var out []interface{} - err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_slowestFulfillment") + err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_slowestResponseTimeInBlocks") if err != nil { return *new(*big.Int), err @@ -384,12 +428,34 @@ func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SSlowes } -func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SSlowestFulfillment() (*big.Int, error) { - return _VRFV2PlusLoadTestWithMetrics.Contract.SSlowestFulfillment(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SSlowestResponseTimeInBlocks() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SSlowestResponseTimeInBlocks(&_VRFV2PlusLoadTestWithMetrics.CallOpts) } -func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SSlowestFulfillment() (*big.Int, error) { - return _VRFV2PlusLoadTestWithMetrics.Contract.SSlowestFulfillment(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SSlowestResponseTimeInBlocks() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SSlowestResponseTimeInBlocks(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +} + +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SSlowestResponseTimeInSeconds(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFV2PlusLoadTestWithMetrics.contract.Call(opts, &out, "s_slowestResponseTimeInSeconds") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsSession) SSlowestResponseTimeInSeconds() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SSlowestResponseTimeInSeconds(&_VRFV2PlusLoadTestWithMetrics.CallOpts) +} + +func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCallerSession) SSlowestResponseTimeInSeconds() (*big.Int, error) { + return _VRFV2PlusLoadTestWithMetrics.Contract.SSlowestResponseTimeInSeconds(&_VRFV2PlusLoadTestWithMetrics.CallOpts) } func (_VRFV2PlusLoadTestWithMetrics *VRFV2PlusLoadTestWithMetricsCaller) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) { @@ -805,9 +871,13 @@ type VRFV2PlusLoadTestWithMetricsInterface interface { Owner(opts *bind.CallOpts) (common.Address, error) - SAverageFulfillmentInMillions(opts *bind.CallOpts) (*big.Int, error) + SAverageResponseTimeInBlocksMillions(opts *bind.CallOpts) (*big.Int, error) - SFastestFulfillment(opts *bind.CallOpts) (*big.Int, error) + SAverageResponseTimeInSecondsMillions(opts *bind.CallOpts) (*big.Int, error) + + SFastestResponseTimeInBlocks(opts *bind.CallOpts) (*big.Int, error) + + SFastestResponseTimeInSeconds(opts *bind.CallOpts) (*big.Int, error) SLastRequestId(opts *bind.CallOpts) (*big.Int, error) @@ -819,7 +889,9 @@ type VRFV2PlusLoadTestWithMetricsInterface interface { SResponseCount(opts *bind.CallOpts) (*big.Int, error) - SSlowestFulfillment(opts *bind.CallOpts) (*big.Int, error) + SSlowestResponseTimeInBlocks(opts *bind.CallOpts) (*big.Int, error) + + SSlowestResponseTimeInSeconds(opts *bind.CallOpts) (*big.Int, error) SVrfCoordinator(opts *bind.CallOpts) (common.Address, error) diff --git a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 29e0ffacf85..88c5c2ebdd6 100644 --- a/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -104,7 +104,7 @@ vrf_owner_test_consumer: ../../contracts/solc/v0.8.6/VRFV2OwnerTestConsumer/VRFV vrf_ownerless_consumer_example: ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample/VRFOwnerlessConsumerExample.abi ../../contracts/solc/v0.8.6/VRFOwnerlessConsumerExample/VRFOwnerlessConsumerExample.bin 9893b3805863273917fb282eed32274e32aa3d5c2a67a911510133e1218132be vrf_single_consumer_example: ../../contracts/solc/v0.8.6/VRFSingleConsumerExample/VRFSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFSingleConsumerExample/VRFSingleConsumerExample.bin 892a5ed35da2e933f7fd7835cd6f7f70ef3aa63a9c03a22c5b1fd026711b0ece vrf_v2_consumer_wrapper: ../../contracts/solc/v0.8.6/VRFv2Consumer/VRFv2Consumer.abi ../../contracts/solc/v0.8.6/VRFv2Consumer/VRFv2Consumer.bin 12368b3b5e06392440143a13b94c0ea2f79c4c897becc3b060982559e10ace40 -vrf_v2plus_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.bin 0a89cb7ed9dfb42f91e559b03dc351ccdbe14d281a7ab71c63bd3f47eeed7711 +vrf_v2plus_load_test_with_metrics: ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.6/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.bin dfb5ca62b8017ae5e3f03221bc8acb567fcce426b31b40d57590a76a97d267a2 vrf_v2plus_single_consumer: ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.bin 6226d05afa1664033b182bfbdde11d5dfb1d4c8e3eb0bd0448c8bfb76f5b96e4 vrf_v2plus_sub_owner: ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.abi ../../contracts/solc/v0.8.6/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.bin 7541f986571b8a5671a256edc27ae9b8df9bcdff45ac3b96e5609bbfcc320e4e vrf_v2plus_upgraded_version: ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.6/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.bin 09e4186c64cdaf1e5d36405467fb86996d7e4177cb08ecec425a4352d4246140 diff --git a/core/scripts/common/vrf/jobs/jobs.go b/core/scripts/common/vrf/jobs/jobs.go index 66bdf712e5c..571530c15c9 100644 --- a/core/scripts/common/vrf/jobs/jobs.go +++ b/core/scripts/common/vrf/jobs/jobs.go @@ -91,8 +91,8 @@ coordinatorV2Address = "%s" waitBlocks = %d lookbackBlocks = %d blockhashStoreAddress = "%s" -pollPeriod = "30s" -runTimeout = "1m0s" +pollPeriod = "%s" +runTimeout = "%s" evmChainID = "%d" fromAddresses = ["%s"] ` @@ -100,12 +100,13 @@ fromAddresses = ["%s"] schemaVersion = 1 name = "blockhashstore" forwardingAllowed = false +coordinatorV2Address = "%s" coordinatorV2PlusAddress = "%s" waitBlocks = %d lookbackBlocks = %d blockhashStoreAddress = "%s" -pollPeriod = "30s" -runTimeout = "1m0s" +pollPeriod = "%s" +runTimeout = "%s" evmChainID = "%d" fromAddresses = ["%s"] ` diff --git a/core/scripts/common/vrf/model/model.go b/core/scripts/common/vrf/model/model.go index ba919eb3c4b..d9ae7d2fd50 100644 --- a/core/scripts/common/vrf/model/model.go +++ b/core/scripts/common/vrf/model/model.go @@ -58,3 +58,11 @@ type CoordinatorJobSpecConfig struct { RequestTimeout string RevertsPipelineEnabled bool } + +type BHSJobSpecConfig struct { + RunTimeout string + WaitBlocks int + LookBackBlocks int + PollPeriod string + RequestTimeout string +} diff --git a/core/scripts/common/vrf/setup-envs/README.md b/core/scripts/common/vrf/setup-envs/README.md index 372e7358441..d7790a14ada 100644 --- a/core/scripts/common/vrf/setup-envs/README.md +++ b/core/scripts/common/vrf/setup-envs/README.md @@ -44,6 +44,11 @@ go run . \ --request-timeout="30m0s" \ --reverts-pipeline-enabled="true" \ --min-confs=3 \ +--simulation-block="latest" \ +--bhs-job-wait-blocks=30 \ +--bhs-job-look-back-blocks=200 \ +--bhs-job-poll-period="1s" \ +--bhs-job-run-timeout="1m" \ --register-vrf-key-against-address= \ --deploy-vrfv2-owner="true" \ @@ -79,7 +84,17 @@ go run . \ --estimate-gas-multiplier=1.1 \ --poll-period="5s" \ --request-timeout="30m0s" \ ---min-confs=3 +--min-confs=3 \ +--simulation-block="latest" \ +--proving-key-max-gas-price="1e12" \ +--flat-fee-native-ppm=500 \ +--flat-fee-link-discount-ppm=100 \ +--native-premium-percentage=1 \ +--link-premium-percentage=1 \ +--bhs-job-wait-blocks=30 \ +--bhs-job-look-back-blocks=200 \ +--bhs-job-poll-period="1s" \ +--bhs-job-run-timeout="1m" ``` Optional parameters - will not be deployed if specified diff --git a/core/scripts/common/vrf/setup-envs/main.go b/core/scripts/common/vrf/setup-envs/main.go index 6d0f73c0f18..efd9c2bab3e 100644 --- a/core/scripts/common/vrf/setup-envs/main.go +++ b/core/scripts/common/vrf/setup-envs/main.go @@ -67,7 +67,7 @@ func main() { bhfCredsFile := flag.String("bhf-creds-file", "", "Creds to authenticate to the node") numEthKeys := flag.Int("num-eth-keys", 5, "Number of eth keys to create") - maxGasPriceGwei := flag.Int("max-gas-price-gwei", 1e12, "Max gas price gwei of the eth keys") + provingKeyMaxGasPriceString := flag.String("proving-key-max-gas-price", "1e12", "Max Gas Price for proving key set in Coordinator config") numVRFKeys := flag.Int("num-vrf-keys", 1, "Number of vrf keys to create") batchFulfillmentEnabled := flag.Bool("batch-fulfillment-enabled", constants.BatchFulfillmentEnabled, "whether send randomness fulfillments in batches inside one tx from CL node") batchFulfillmentGasMultiplier := flag.Float64("batch-fulfillment-gas-multiplier", 1.1, "") @@ -75,6 +75,10 @@ func main() { pollPeriod := flag.String("poll-period", "300ms", "") requestTimeout := flag.String("request-timeout", "30m0s", "") revertsPipelineEnabled := flag.Bool("reverts-pipeline-enabled", true, "") + bhsJobWaitBlocks := flag.Int("bhs-job-wait-blocks", 30, "") + bhsJobLookBackBlocks := flag.Int("bhs-job-look-back-blocks", 200, "") + bhsJobPollPeriod := flag.String("bhs-job-poll-period", "3s", "") + bhsJobRunTimeout := flag.String("bhs-job-run-timeout", "1m", "") vrfVersion := flag.String("vrf-version", "v2", "VRF version to use") deployContractsAndCreateJobs := flag.Bool("deploy-contracts-and-create-jobs", false, "whether to deploy contracts and create jobs") @@ -94,6 +98,13 @@ func main() { "from this address you can perform `coordinator.oracleWithdraw` to withdraw earned funds from rand request fulfilments") deployVRFOwner := flag.Bool("deploy-vrfv2-owner", true, "whether to deploy VRF owner contracts") useTestCoordinator := flag.Bool("use-test-coordinator", true, "whether to use test coordinator contract or use the normal one") + maxGasLimit := flag.Int64("max-gas-limit", constants.MaxGasLimit, "max gas limit") + stalenessSeconds := flag.Int64("staleness-seconds", constants.StalenessSeconds, "staleness in seconds") + gasAfterPayment := flag.Int64("gas-after-payment", constants.GasAfterPayment, "gas after payment calculation") + flatFeeNativePPM := flag.Int64("flat-fee-native-ppm", 500, "fulfillment flat fee ETH ppm") + flatFeeLinkDiscountPPM := flag.Int64("flat-fee-link-discount-ppm", 100, "fulfillment flat fee discount for LINK payment denominated in native ppm") + nativePremiumPercentage := flag.Int64("native-premium-percentage", 1, "premium percentage for native payment") + linkPremiumPercentage := flag.Int64("link-premium-percentage", 1, "premium percentage for LINK payment") simulationBlock := flag.String("simulation-block", "pending", "simulation block can be 'pending' or 'latest'") e := helpers.SetupEnv(false) @@ -112,6 +123,7 @@ func main() { fundingAmount := decimal.RequireFromString(*nodeSendingKeyFundingAmount).BigInt() subscriptionBalanceJuels := decimal.RequireFromString(*subscriptionBalanceJuelsString).BigInt() subscriptionBalanceNativeWei := decimal.RequireFromString(*subscriptionBalanceNativeWeiString).BigInt() + provingKeyMaxGasPrice := decimal.RequireFromString(*provingKeyMaxGasPriceString).BigInt() if *vrfPrimaryNodeURL != "" { nodesMap[model.VRFPrimaryNodeName] = model.Node{ @@ -154,7 +166,7 @@ func main() { for key, node := range nodesMap { node := node client, app := connectToNode(&node.URL, output, node.CredsFile) - ethKeys := createETHKeysIfNeeded(client, app, output, numEthKeys, &node.URL, maxGasPriceGwei) + ethKeys := createETHKeysIfNeeded(client, app, output, numEthKeys, &node.URL) if key == model.VRFPrimaryNodeName { vrfKeys := createVRFKeyIfNeeded(client, app, output, numVRFKeys, &node.URL) node.VrfKeys = mapVrfKeysToStringArr(vrfKeys) @@ -208,9 +220,9 @@ func main() { coordinatorConfigV2 := v2scripts.CoordinatorConfigV2{ MinConfs: *minConfs, - MaxGasLimit: constants.MaxGasLimit, - StalenessSeconds: constants.StalenessSeconds, - GasAfterPayment: constants.GasAfterPayment, + MaxGasLimit: *maxGasLimit, + StalenessSeconds: *stalenessSeconds, + GasAfterPayment: *gasAfterPayment, FallbackWeiPerUnitLink: constants.FallbackWeiPerUnitLink, FeeConfig: feeConfigV2, } @@ -224,6 +236,12 @@ func main() { RevertsPipelineEnabled: *revertsPipelineEnabled, } + bhsJobSpecConfig := model.BHSJobSpecConfig{ + RunTimeout: *bhsJobRunTimeout, + WaitBlocks: *bhsJobWaitBlocks, + LookBackBlocks: *bhsJobLookBackBlocks, + PollPeriod: *bhsJobPollPeriod, + } jobSpecs = v2scripts.VRFV2DeployUniverse( e, subscriptionBalanceJuels, @@ -233,20 +251,21 @@ func main() { nodesMap, *deployVRFOwner, coordinatorJobSpecConfig, + bhsJobSpecConfig, *useTestCoordinator, *simulationBlock, ) case "v2plus": coordinatorConfigV2Plus := v2plusscripts.CoordinatorConfigV2Plus{ MinConfs: *minConfs, - MaxGasLimit: constants.MaxGasLimit, - StalenessSeconds: constants.StalenessSeconds, - GasAfterPayment: constants.GasAfterPayment, + MaxGasLimit: *maxGasLimit, + StalenessSeconds: *stalenessSeconds, + GasAfterPayment: *gasAfterPayment, FallbackWeiPerUnitLink: constants.FallbackWeiPerUnitLink, - FulfillmentFlatFeeNativePPM: constants.FlatFeeNativePPM, - FulfillmentFlatFeeLinkDiscountPPM: constants.FlatFeeLinkDiscountPPM, - NativePremiumPercentage: constants.NativePremiumPercentage, - LinkPremiumPercentage: constants.LinkPremiumPercentage, + FulfillmentFlatFeeNativePPM: uint32(*flatFeeNativePPM), + FulfillmentFlatFeeLinkDiscountPPM: uint32(*flatFeeLinkDiscountPPM), + NativePremiumPercentage: uint8(*nativePremiumPercentage), + LinkPremiumPercentage: uint8(*linkPremiumPercentage), } coordinatorJobSpecConfig := model.CoordinatorJobSpecConfig{ @@ -256,7 +275,12 @@ func main() { PollPeriod: *pollPeriod, RequestTimeout: *requestTimeout, } - + bhsJobSpecConfig := model.BHSJobSpecConfig{ + RunTimeout: *bhsJobRunTimeout, + WaitBlocks: *bhsJobWaitBlocks, + LookBackBlocks: *bhsJobLookBackBlocks, + PollPeriod: *bhsJobPollPeriod, + } jobSpecs = v2plusscripts.VRFV2PlusDeployUniverse( e, subscriptionBalanceJuels, @@ -264,11 +288,11 @@ func main() { vrfKeyRegistrationConfig, contractAddresses, coordinatorConfigV2Plus, - *batchFulfillmentEnabled, *nativeOnly, nodesMap, - uint64(*maxGasPriceGwei), + provingKeyMaxGasPrice.Uint64(), coordinatorJobSpecConfig, + bhsJobSpecConfig, *simulationBlock, ) } @@ -306,6 +330,10 @@ func fundNodesIfNeeded(node model.Node, key string, e helpers.Environment) { if node.SendingKeyFundingAmount.Cmp(big.NewInt(0)) == 1 { fmt.Println("\nFunding", key, "Node's Sending Keys. Need to fund each key with", node.SendingKeyFundingAmount, "wei") for _, sendingKey := range node.SendingKeys { + fmt.Println("Funding", sendingKey.Address, "with", node.SendingKeyFundingAmount, "wei", "BalanceEth:", sendingKey.BalanceEth.String()) + if sendingKey.BalanceEth == nil { + sendingKey.BalanceEth = big.NewInt(0) + } fundingToSendWei := new(big.Int).Sub(node.SendingKeyFundingAmount, sendingKey.BalanceEth) if fundingToSendWei.Cmp(big.NewInt(0)) == 1 { helpers.FundNode(e, sendingKey.Address, fundingToSendWei) @@ -513,7 +541,7 @@ func createVRFKey(client *clcmd.Shell, app *cli.App, output *bytes.Buffer) prese return newKey } -func createETHKeysIfNeeded(client *clcmd.Shell, app *cli.App, output *bytes.Buffer, numEthKeys *int, nodeURL *string, maxGasPriceGwei *int) []presenters.ETHKeyResource { +func createETHKeysIfNeeded(client *clcmd.Shell, app *cli.App, output *bytes.Buffer, numEthKeys *int, nodeURL *string) []presenters.ETHKeyResource { var allETHKeysNode []presenters.ETHKeyResource var ethKeys []presenters.ETHKeyResource var newKeys []presenters.ETHKeyResource @@ -536,9 +564,6 @@ func createETHKeysIfNeeded(client *clcmd.Shell, app *cli.App, output *bytes.Buff flagSet := flag.NewFlagSet("blah", flag.ExitOnError) flagSet.String("evm-chain-id", os.Getenv("ETH_CHAIN_ID"), "chain id") - if *maxGasPriceGwei > 0 { - helpers.PanicErr(flagSet.Set("max-gas-price-gwei", fmt.Sprintf("%d", *maxGasPriceGwei))) - } err := flagSet.Parse([]string{"-evm-chain-id", os.Getenv("ETH_CHAIN_ID")}) helpers.PanicErr(err) err = client.CreateETHKey(cli.NewContext(app, flagSet, nil)) diff --git a/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go b/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go index 5cfc3f81ce1..b4d29af3aee 100644 --- a/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go +++ b/core/scripts/vrfv2/testnet/v2scripts/super_scripts.go @@ -57,6 +57,10 @@ func DeployUniverseViaCLI(e helpers.Environment) { pollPeriod := deployCmd.String("poll-period", "300ms", "") requestTimeout := deployCmd.String("request-timeout", "30m0s", "") revertsPipelineEnabled := deployCmd.Bool("reverts-pipeline-enabled", true, "") + bhsJobWaitBlocks := flag.Int("bhs-job-wait-blocks", 30, "") + bhsJobLookBackBlocks := flag.Int("bhs-job-look-back-blocks", 200, "") + bhsJobPollPeriod := flag.String("bhs-job-poll-period", "3s", "") + bhsJobRunTimeout := flag.String("bhs-job-run-timeout", "1m", "") deployVRFOwner := deployCmd.Bool("deploy-vrf-owner", true, "whether to deploy VRF owner contracts") useTestCoordinator := deployCmd.Bool("use-test-coordinator", true, "whether to use test coordinator") @@ -157,6 +161,13 @@ func DeployUniverseViaCLI(e helpers.Environment) { RevertsPipelineEnabled: *revertsPipelineEnabled, } + bhsJobSpecConfig := model.BHSJobSpecConfig{ + RunTimeout: *bhsJobRunTimeout, + WaitBlocks: *bhsJobWaitBlocks, + LookBackBlocks: *bhsJobLookBackBlocks, + PollPeriod: *bhsJobPollPeriod, + } + VRFV2DeployUniverse( e, subscriptionBalanceJuels, @@ -166,6 +177,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { nodesMap, *deployVRFOwner, coordinatorJobSpecConfig, + bhsJobSpecConfig, *useTestCoordinator, *simulationBlock, ) @@ -186,6 +198,7 @@ func VRFV2DeployUniverse( nodesMap map[string]model.Node, deployVRFOwner bool, coordinatorJobSpecConfig model.CoordinatorJobSpecConfig, + bhsJobSpecConfig model.BHSJobSpecConfig, useTestCoordinator bool, simulationBlock string, ) model.JobSpecs { @@ -408,10 +421,12 @@ func VRFV2DeployUniverse( formattedBHSJobSpec := fmt.Sprintf( jobs.BHSJobFormatted, contractAddresses.CoordinatorAddress, //coordinatorAddress - 30, //waitBlocks - 200, //lookbackBlocks + bhsJobSpecConfig.WaitBlocks, //waitBlocks + bhsJobSpecConfig.LookBackBlocks, //lookbackBlocks contractAddresses.BhsContractAddress, //bhs address - e.ChainID, //chain id + bhsJobSpecConfig.PollPeriod, + bhsJobSpecConfig.RunTimeout, + e.ChainID, //chain id strings.Join(util.MapToAddressArr(nodesMap[model.BHSNodeName].SendingKeys), "\",\""), //sending addresses ) diff --git a/core/scripts/vrfv2plus/testnet/main.go b/core/scripts/vrfv2plus/testnet/main.go index bed961eb275..d0fba011dab 100644 --- a/core/scripts/vrfv2plus/testnet/main.go +++ b/core/scripts/vrfv2plus/testnet/main.go @@ -867,10 +867,10 @@ func main() { subID := request.String("sub-id", "", "subscription ID") requestConfirmations := request.Uint("request-confirmations", 3, "minimum request confirmations") keyHash := request.String("key-hash", "", "key hash") - cbGasLimit := request.Uint("cb-gas-limit", 100_000, "request callback gas limit") + cbGasLimit := request.Uint("cb-gas-limit", 1_000_000, "request callback gas limit") nativePaymentEnabled := request.Bool("native-payment-enabled", false, "native payment enabled") numWords := request.Uint("num-words", 1, "num words to request") - requests := request.Uint("requests", 10, "number of randomness requests to make per run") + requests := request.Uint("requests", 1, "number of randomness requests to make per run") runs := request.Uint("runs", 1, "number of runs to do. total randomness requests will be (requests * runs).") helpers.ParseArgs(request, os.Args[2:], "consumer-address", "sub-id", "key-hash") keyHashBytes := common.HexToHash(*keyHash) @@ -913,15 +913,24 @@ func main() { requestCount, err := consumer.SRequestCount(nil) helpers.PanicErr(err) fmt.Println("Request Count: ", requestCount) - averageFulfillmentInMillions, err := consumer.SAverageFulfillmentInMillions(nil) + averageFulfillmentInMillions, err := consumer.SAverageResponseTimeInBlocksMillions(nil) helpers.PanicErr(err) fmt.Println("Average Fulfillment In Millions: ", averageFulfillmentInMillions) - slowestFulfillment, err := consumer.SSlowestFulfillment(nil) + slowestFulfillment, err := consumer.SSlowestResponseTimeInBlocks(nil) helpers.PanicErr(err) fmt.Println("Slowest Fulfillment: ", slowestFulfillment) - fastestFulfillment, err := consumer.SFastestFulfillment(nil) + fastestFulfillment, err := consumer.SFastestResponseTimeInBlocks(nil) helpers.PanicErr(err) fmt.Println("Fastest Fulfillment: ", fastestFulfillment) + averageResponseTimeInSecondsMillions, err := consumer.SAverageResponseTimeInBlocksMillions(nil) + helpers.PanicErr(err) + fmt.Println("Average Response Time In Seconds Millions: ", averageResponseTimeInSecondsMillions) + slowestResponseTimeInSeconds, err := consumer.SSlowestResponseTimeInBlocks(nil) + helpers.PanicErr(err) + fmt.Println("Slowest Response Time In Seconds: ", slowestResponseTimeInSeconds) + fastestResponseTimeInSeconds, err := consumer.SFastestResponseTimeInBlocks(nil) + helpers.PanicErr(err) + fmt.Println("Fastest Response Time In Seconds: ", fastestResponseTimeInSeconds) case "eoa-load-test-reset-metrics": request := flag.NewFlagSet("eoa-load-test-reset-metrics", flag.ExitOnError) consumerAddress := request.String("consumer-address", "", "consumer address") diff --git a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go index fcea01b71c8..12c08dd80a3 100644 --- a/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go +++ b/core/scripts/vrfv2plus/testnet/v2plusscripts/super_scripts.go @@ -487,6 +487,10 @@ func DeployUniverseViaCLI(e helpers.Environment) { estimateGasMultiplier := deployCmd.Float64("estimate-gas-multiplier", 1.1, "") pollPeriod := deployCmd.String("poll-period", "300ms", "") requestTimeout := deployCmd.String("request-timeout", "30m0s", "") + bhsJobWaitBlocks := flag.Int("bhs-job-wait-blocks", 30, "") + bhsJobLookBackBlocks := flag.Int("bhs-job-look-back-blocks", 200, "") + bhsJobPollPeriod := flag.String("bhs-job-poll-period", "3s", "") + bhsJobRunTimeout := flag.String("bhs-job-run-timeout", "1m", "") simulationBlock := deployCmd.String("simulation-block", "pending", "simulation block can be 'pending' or 'latest'") // optional flags @@ -503,7 +507,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { flatFeeLinkDiscountPPM := deployCmd.Int64("flat-fee-link-discount-ppm", 100, "fulfillment flat fee discount for LINK payment denominated in native ppm") nativePremiumPercentage := deployCmd.Int64("native-premium-percentage", 1, "premium percentage for native payment") linkPremiumPercentage := deployCmd.Int64("link-premium-percentage", 1, "premium percentage for LINK payment") - gasLaneMaxGas := deployCmd.Int64("gas-lane-max-gas", 1e12, "gas lane max gas price") + provingKeyMaxGasPriceString := deployCmd.String("proving-key-max-gas-price", "1e12", "gas lane max gas price") helpers.ParseArgs( deployCmd, os.Args[2:], @@ -526,6 +530,7 @@ func DeployUniverseViaCLI(e helpers.Environment) { subscriptionBalanceJuels := decimal.RequireFromString(*subscriptionBalanceJuelsString).BigInt() subscriptionBalanceNativeWei := decimal.RequireFromString(*subscriptionBalanceNativeWeiString).BigInt() fundingAmount := decimal.RequireFromString(*nodeSendingKeyFundingAmount).BigInt() + provingKeyMaxGasPrice := decimal.RequireFromString(*provingKeyMaxGasPriceString).BigInt() var vrfPrimaryNodeSendingKeys []string if len(*vrfPrimaryNodeSendingKeysString) > 0 { @@ -577,6 +582,13 @@ func DeployUniverseViaCLI(e helpers.Environment) { RequestTimeout: *requestTimeout, } + bhsJobSpecConfig := model.BHSJobSpecConfig{ + RunTimeout: *bhsJobRunTimeout, + WaitBlocks: *bhsJobWaitBlocks, + LookBackBlocks: *bhsJobLookBackBlocks, + PollPeriod: *bhsJobPollPeriod, + } + VRFV2PlusDeployUniverse( e, subscriptionBalanceJuels, @@ -584,11 +596,11 @@ func DeployUniverseViaCLI(e helpers.Environment) { vrfKeyRegistrationConfig, contractAddresses, coordinatorConfig, - *batchFulfillmentEnabled, *nativeOnly, nodesMap, - uint64(*gasLaneMaxGas), + provingKeyMaxGasPrice.Uint64(), coordinatorJobSpecConfig, + bhsJobSpecConfig, *simulationBlock, ) @@ -605,11 +617,11 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, vrfKeyRegistrationConfig model.VRFKeyRegistrationConfig, contractAddresses model.ContractAddresses, coordinatorConfig CoordinatorConfigV2Plus, - batchFulfillmentEnabled bool, nativeOnly bool, nodesMap map[string]model.Node, - gasLaneMaxGas uint64, + provingKeyMaxGasPrice uint64, coordinatorJobSpecConfig model.CoordinatorJobSpecConfig, + bhsJobSpecConfig model.BHSJobSpecConfig, simulationBlock string, ) model.JobSpecs { var compressedPkHex string @@ -695,7 +707,7 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, //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, vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey, gasLaneMaxGas) + RegisterCoordinatorProvingKey(e, *coordinator, vrfKeyRegistrationConfig.VRFKeyUncompressedPubKey, provingKeyMaxGasPrice) fmt.Println("\nProving key registered, getting proving key hashes from deployed contract...") registerdKeyHash, err2 := coordinator.SProvingKeyHashes(nil, big.NewInt(0)) @@ -789,9 +801,12 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, formattedBHSJobSpec := fmt.Sprintf( jobs.BHSPlusJobFormatted, contractAddresses.CoordinatorAddress, //coordinatorAddress - 30, //waitBlocks - 200, //lookbackBlocks + contractAddresses.CoordinatorAddress, //coordinatorAddress + bhsJobSpecConfig.WaitBlocks, //waitBlocks + bhsJobSpecConfig.LookBackBlocks, //lookbackBlocks contractAddresses.BhsContractAddress, //bhs address + bhsJobSpecConfig.PollPeriod, //pollPeriod + bhsJobSpecConfig.RunTimeout, //runTimeout e.ChainID, //chain id strings.Join(util.MapToAddressArr(nodesMap[model.BHSNodeName].SendingKeys), "\",\""), //sending addresses ) @@ -799,9 +814,12 @@ func VRFV2PlusDeployUniverse(e helpers.Environment, formattedBHSBackupJobSpec := fmt.Sprintf( jobs.BHSPlusJobFormatted, contractAddresses.CoordinatorAddress, //coordinatorAddress + contractAddresses.CoordinatorAddress, //coordinatorAddress 100, //waitBlocks 200, //lookbackBlocks contractAddresses.BhsContractAddress, //bhs adreess + bhsJobSpecConfig.PollPeriod, //pollPeriod + bhsJobSpecConfig.RunTimeout, //runTimeout e.ChainID, //chain id strings.Join(util.MapToAddressArr(nodesMap[model.BHSBackupNodeName].SendingKeys), "\",\""), //sending addresses ) @@ -828,7 +846,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 --native-payment-enabled=true --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/integration-tests/actions/vrf/common/actions.go b/integration-tests/actions/vrf/common/actions.go index 0c779ea90e5..20d44e60de2 100644 --- a/integration-tests/actions/vrf/common/actions.go +++ b/integration-tests/actions/vrf/common/actions.go @@ -1,8 +1,11 @@ package common import ( + "context" "fmt" "math/big" + "sync" + "time" "github.com/ethereum/go-ethereum/common" "github.com/google/uuid" @@ -11,8 +14,9 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" - testconfig "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2" + vrf_common_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/common/vrf" ) func CreateFundAndGetSendingKeys( @@ -65,7 +69,7 @@ func CreateAndFundSendingKeys( func SetupBHSNode( env *test_env.CLClusterTestEnv, - config *testconfig.General, + config *vrf_common_config.General, numberOfTxKeysToCreate int, chainID *big.Int, coordinatorAddress string, @@ -135,3 +139,80 @@ func CreateBHSJob( } return job, nil } + +func WaitForRequestCountEqualToFulfilmentCount( + ctx context.Context, + consumer VRFLoadTestConsumer, + timeout time.Duration, + wg *sync.WaitGroup, +) (*big.Int, *big.Int, error) { + metricsChannel := make(chan *contracts.VRFLoadTestMetrics) + metricsErrorChannel := make(chan error) + + testContext, testCancel := context.WithTimeout(ctx, timeout) + defer testCancel() + + ticker := time.NewTicker(time.Second * 1) + var metrics *contracts.VRFLoadTestMetrics + for { + select { + case <-testContext.Done(): + ticker.Stop() + wg.Done() + return metrics.RequestCount, metrics.FulfilmentCount, + fmt.Errorf("timeout waiting for rand request and fulfilments to be equal AFTER performance test was executed. Request Count: %d, Fulfilment Count: %d", + metrics.RequestCount.Uint64(), metrics.FulfilmentCount.Uint64()) + case <-ticker.C: + go retrieveLoadTestMetrics(ctx, consumer, metricsChannel, metricsErrorChannel) + case metrics = <-metricsChannel: + if metrics.RequestCount.Cmp(metrics.FulfilmentCount) == 0 { + ticker.Stop() + wg.Done() + return metrics.RequestCount, metrics.FulfilmentCount, nil + } + case err := <-metricsErrorChannel: + ticker.Stop() + wg.Done() + return nil, nil, err + } + } +} + +func retrieveLoadTestMetrics( + ctx context.Context, + consumer VRFLoadTestConsumer, + metricsChannel chan *contracts.VRFLoadTestMetrics, + metricsErrorChannel chan error, +) { + metrics, err := consumer.GetLoadTestMetrics(ctx) + if err != nil { + metricsErrorChannel <- err + } + metricsChannel <- metrics +} + +func CreateNodeTypeToNodeMap(cluster *test_env.ClCluster, nodesToCreate []VRFNodeType) map[VRFNodeType]*VRFNode { + var nodesMap = make(map[VRFNodeType]*VRFNode) + for i, nodeType := range nodesToCreate { + nodesMap[nodeType] = &VRFNode{ + CLNode: cluster.Nodes[i], + } + } + return nodesMap +} + +func CreateVRFKeyOnVRFNode(vrfNode *VRFNode, l zerolog.Logger) (*client.VRFKey, string, error) { + l.Info().Str("Node URL", vrfNode.CLNode.API.URL()).Msg("Creating VRF Key on the Node") + vrfKey, err := vrfNode.CLNode.API.MustCreateVRFKey() + if err != nil { + return nil, "", fmt.Errorf("%s, err %w", ErrCreatingVRFKey, err) + } + pubKeyCompressed := vrfKey.Data.ID + l.Info(). + Str("Node URL", vrfNode.CLNode.API.URL()). + Str("Keyhash", vrfKey.Data.Attributes.Hash). + Str("VRF Compressed Key", vrfKey.Data.Attributes.Compressed). + Str("VRF Uncompressed Key", vrfKey.Data.Attributes.Uncompressed). + Msg("VRF Key created on the Node") + return vrfKey, pubKeyCompressed, nil +} diff --git a/integration-tests/actions/vrf/common/errors.go b/integration-tests/actions/vrf/common/errors.go index 36530428468..ba852a4c555 100644 --- a/integration-tests/actions/vrf/common/errors.go +++ b/integration-tests/actions/vrf/common/errors.go @@ -21,6 +21,7 @@ const ( ErrWaitTXsComplete = "error waiting for TXs to complete" ErrRequestRandomness = "error requesting randomness" ErrLoadingCoordinator = "error loading coordinator contract" + ErrCreatingVRFKey = "error creating VRF key" ErrWaitRandomWordsRequestedEvent = "error waiting for RandomWordsRequested event" ErrWaitRandomWordsFulfilledEvent = "error waiting for RandomWordsFulfilled event" diff --git a/integration-tests/actions/vrf/common/models.go b/integration-tests/actions/vrf/common/models.go index ab6ca034800..08a004da484 100644 --- a/integration-tests/actions/vrf/common/models.go +++ b/integration-tests/actions/vrf/common/models.go @@ -1,6 +1,7 @@ package common import ( + "context" "math/big" "time" @@ -68,3 +69,7 @@ type VRFJobSpecConfig struct { VRFOwnerConfig *VRFOwnerConfig SimulationBlock *string } + +type VRFLoadTestConsumer interface { + GetLoadTestMetrics(ctx context.Context) (*contracts.VRFLoadTestMetrics, error) +} diff --git a/integration-tests/actions/vrf/vrfv2/errors.go b/integration-tests/actions/vrf/vrfv2/errors.go index d6b24fe9e07..3ca94dd630d 100644 --- a/integration-tests/actions/vrf/vrfv2/errors.go +++ b/integration-tests/actions/vrf/vrfv2/errors.go @@ -1,7 +1,6 @@ package vrfv2 const ( - ErrCreatingVRFv2Key = "error creating VRFv2 key" ErrDeployVRFV2Wrapper = "error deploying VRFV2Wrapper" ErrCreateVRFV2Jobs = "error creating VRF V2 Jobs" ErrDeployVRFV2Contracts = "error deploying VRFV2 contracts" diff --git a/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go b/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go index 39d7133dd46..121c259278a 100644 --- a/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go +++ b/integration-tests/actions/vrf/vrfv2/vrfv2_steps.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "math/big" - "sync" "time" "github.com/ethereum/go-ethereum/common" @@ -261,16 +260,15 @@ func SetupVRFV2Environment( l zerolog.Logger, ) (*vrfcommon.VRFContracts, []uint64, *vrfcommon.VRFKeyData, map[vrfcommon.VRFNodeType]*vrfcommon.VRFNode, error) { l.Info().Msg("Starting VRFV2 environment setup") - vrfv2Config := vrfv2TestConfig.GetVRFv2Config().General - - vrfContracts, subIDs, err := SetupContracts( + configGeneral := vrfv2TestConfig.GetVRFv2Config().General + vrfContracts, subIDs, err := SetupVRFV2Contracts( env, linkToken, mockNativeLINKFeed, numberOfConsumers, useVRFOwner, useTestCoordinator, - vrfv2Config, + configGeneral, numberOfSubToCreate, l, ) @@ -278,24 +276,11 @@ func SetupVRFV2Environment( return nil, nil, nil, nil, err } - var nodesMap = make(map[vrfcommon.VRFNodeType]*vrfcommon.VRFNode) - for i, nodeType := range nodesToCreate { - nodesMap[nodeType] = &vrfcommon.VRFNode{ - CLNode: env.ClCluster.Nodes[i], - } - } - l.Info().Str("Node URL", nodesMap[vrfcommon.VRF].CLNode.API.URL()).Msg("Creating VRF Key on the Node") - vrfKey, err := nodesMap[vrfcommon.VRF].CLNode.API.MustCreateVRFKey() + nodeTypeToNodeMap := vrfcommon.CreateNodeTypeToNodeMap(env.ClCluster, nodesToCreate) + vrfKey, pubKeyCompressed, err := vrfcommon.CreateVRFKeyOnVRFNode(nodeTypeToNodeMap[vrfcommon.VRF], l) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("%s, err %w", ErrCreatingVRFv2Key, err) + return nil, nil, nil, nil, err } - pubKeyCompressed := vrfKey.Data.ID - l.Info(). - Str("Node URL", nodesMap[vrfcommon.VRF].CLNode.API.URL()). - Str("Keyhash", vrfKey.Data.Attributes.Hash). - Str("VRF Compressed Key", vrfKey.Data.Attributes.Compressed). - Str("VRF Uncompressed Key", vrfKey.Data.Attributes.Uncompressed). - Msg("VRF Key created on the Node") l.Info().Str("Coordinator", vrfContracts.CoordinatorV2.Address()).Msg("Registering Proving Key") provingKey, err := VRFV2RegisterProvingKey(vrfKey, registerProvingKeyAgainstAddress, vrfContracts.CoordinatorV2) @@ -310,7 +295,7 @@ func SetupVRFV2Environment( chainID := env.EVMClient.GetChainID() vrfTXKeyAddressStrings, vrfTXKeyAddresses, err := vrfcommon.CreateFundAndGetSendingKeys( env.EVMClient, - nodesMap[vrfcommon.VRF], + nodeTypeToNodeMap[vrfcommon.VRF], *vrfv2TestConfig.GetCommonConfig().ChainlinkNodeFunding, numberOfTxKeysToCreate, chainID, @@ -318,7 +303,12 @@ func SetupVRFV2Environment( if err != nil { return nil, nil, nil, nil, err } - nodesMap[vrfcommon.VRF].TXKeyAddressStrings = vrfTXKeyAddressStrings + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + } + + nodeTypeToNodeMap[vrfcommon.VRF].TXKeyAddressStrings = vrfTXKeyAddressStrings var vrfOwnerConfig *vrfcommon.VRFOwnerConfig if useVRFOwner { @@ -338,9 +328,9 @@ func SetupVRFV2Environment( } g := errgroup.Group{} - if vrfNode, exists := nodesMap[vrfcommon.VRF]; exists { + if vrfNode, exists := nodeTypeToNodeMap[vrfcommon.VRF]; exists { g.Go(func() error { - err := setupVRFNode(vrfContracts, chainID, vrfv2Config, pubKeyCompressed, vrfOwnerConfig, l, vrfNode) + err := setupVRFNode(vrfContracts, chainID, configGeneral, pubKeyCompressed, vrfOwnerConfig, l, vrfNode) if err != nil { return err } @@ -348,11 +338,11 @@ func SetupVRFV2Environment( }) } - if bhsNode, exists := nodesMap[vrfcommon.BHS]; exists { + if bhsNode, exists := nodeTypeToNodeMap[vrfcommon.BHS]; exists { g.Go(func() error { err := vrfcommon.SetupBHSNode( env, - vrfv2TestConfig.GetVRFv2Config().General, + configGeneral.General, numberOfTxKeysToCreate, chainID, vrfContracts.CoordinatorV2.Address(), @@ -379,7 +369,7 @@ func SetupVRFV2Environment( } l.Info().Msg("VRFV2 environment setup is finished") - return vrfContracts, subIDs, &vrfKeyData, nodesMap, nil + return vrfContracts, subIDs, &vrfKeyData, nodeTypeToNodeMap, nil } func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, vrfv2Config *testconfig.General, pubKeyCompressed string, vrfOwnerConfig *vrfcommon.VRFOwnerConfig, l zerolog.Logger, vrfNode *vrfcommon.VRFNode) error { @@ -424,7 +414,7 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, vrfv2Conf return nil } -func SetupContracts( +func SetupVRFV2Contracts( env *test_env.CLClusterTestEnv, linkToken contracts.LinkToken, mockNativeLINKFeed contracts.MockETHLINKFeed, @@ -943,51 +933,6 @@ func WaitForRequestAndFulfillmentEvents( return randomWordsFulfilledEvent, err } -func WaitForRequestCountEqualToFulfilmentCount(consumer contracts.VRFv2LoadTestConsumer, timeout time.Duration, wg *sync.WaitGroup) (*big.Int, *big.Int, error) { - metricsChannel := make(chan *contracts.VRFLoadTestMetrics) - metricsErrorChannel := make(chan error) - - testContext, testCancel := context.WithTimeout(context.Background(), timeout) - defer testCancel() - - ticker := time.NewTicker(time.Second * 1) - var metrics *contracts.VRFLoadTestMetrics - for { - select { - case <-testContext.Done(): - ticker.Stop() - wg.Done() - return metrics.RequestCount, metrics.FulfilmentCount, - fmt.Errorf("timeout waiting for rand request and fulfilments to be equal AFTER performance test was executed. Request Count: %d, Fulfilment Count: %d", - metrics.RequestCount.Uint64(), metrics.FulfilmentCount.Uint64()) - case <-ticker.C: - go retrieveLoadTestMetrics(consumer, metricsChannel, metricsErrorChannel) - case metrics = <-metricsChannel: - if metrics.RequestCount.Cmp(metrics.FulfilmentCount) == 0 { - ticker.Stop() - wg.Done() - return metrics.RequestCount, metrics.FulfilmentCount, nil - } - case err := <-metricsErrorChannel: - ticker.Stop() - wg.Done() - return nil, nil, err - } - } -} - -func retrieveLoadTestMetrics( - consumer contracts.VRFv2LoadTestConsumer, - metricsChannel chan *contracts.VRFLoadTestMetrics, - metricsErrorChannel chan error, -) { - metrics, err := consumer.GetLoadTestMetrics(context.Background()) - if err != nil { - metricsErrorChannel <- err - } - metricsChannel <- metrics -} - func LogSubDetails(l zerolog.Logger, subscription vrf_coordinator_v2.GetSubscription, subID uint64, coordinator contracts.VRFCoordinatorV2) { l.Debug(). Str("Coordinator", coordinator.Address()). @@ -1008,10 +953,13 @@ func LogRandomnessRequestedEvent( Str("Request ID", randomWordsRequestedEvent.RequestId.String()). Uint64("Subscription ID", randomWordsRequestedEvent.SubId). Str("Sender Address", randomWordsRequestedEvent.Sender.String()). - Interface("Keyhash", randomWordsRequestedEvent.KeyHash). + Str("Keyhash", fmt.Sprintf("0x%x", randomWordsRequestedEvent.KeyHash)). Uint32("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). Uint32("Number of Words", randomWordsRequestedEvent.NumWords). Uint16("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). + Str("TX Hash", randomWordsRequestedEvent.Raw.TxHash.String()). + Uint64("BlockNumber", randomWordsRequestedEvent.Raw.BlockNumber). + Str("BlockHash", randomWordsRequestedEvent.Raw.BlockHash.String()). Msg("RandomnessRequested Event") } @@ -1026,6 +974,8 @@ func LogRandomWordsFulfilledEvent( Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). Str("Request ID", randomWordsFulfilledEvent.RequestId.String()). Bool("Success", randomWordsFulfilledEvent.Success). + Uint64("BlockNumber", randomWordsFulfilledEvent.Raw.BlockNumber). + Str("BlockHash", randomWordsFulfilledEvent.Raw.BlockHash.String()). Msg("RandomWordsFulfilled Event (TX metadata)") } diff --git a/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go b/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go index a3c6352bf37..aaacb541c98 100644 --- a/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/vrfv2plus_steps.go @@ -4,7 +4,6 @@ import ( "context" "fmt" "math/big" - "sync" "time" "golang.org/x/sync/errgroup" @@ -12,7 +11,7 @@ import ( commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" - testconfig "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2" + testconfig "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2plus" "github.com/smartcontractkit/chainlink/integration-tests/types/config/node" "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" @@ -114,7 +113,6 @@ func CreateVRFV2PlusJob( if err != nil { return nil, fmt.Errorf("%s, err %w", ErrCreatingVRFv2PlusJob, err) } - return job, nil } @@ -185,75 +183,28 @@ func SetupVRFV2_5Environment( l zerolog.Logger, ) (*vrfcommon.VRFContracts, []*big.Int, *vrfcommon.VRFKeyData, map[vrfcommon.VRFNodeType]*vrfcommon.VRFNode, error) { l.Info().Msg("Starting VRFV2 Plus environment setup") - l.Info().Msg("Deploying VRFV2 Plus contracts") - vrfContracts, err := DeployVRFV2_5Contracts(env.ContractDeployer, env.EVMClient, numberOfConsumers) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("%s, err %w", ErrDeployVRFV2_5Contracts, err) - } - - l.Info().Str("Coordinator", vrfContracts.CoordinatorV2Plus.Address()).Msg("Setting Coordinator Config") - vrfv2PlusConfig := vrfv2PlusTestConfig.GetVRFv2PlusConfig().General - err = vrfContracts.CoordinatorV2Plus.SetConfig( - *vrfv2PlusConfig.MinimumConfirmations, - *vrfv2PlusConfig.MaxGasLimitCoordinatorConfig, - *vrfv2PlusConfig.StalenessSeconds, - *vrfv2PlusConfig.GasAfterPaymentCalculation, - big.NewInt(*vrfv2PlusConfig.FallbackWeiPerUnitLink), - *vrfv2PlusConfig.FulfillmentFlatFeeNativePPM, - *vrfv2PlusConfig.FulfillmentFlatFeeLinkDiscountPPM, - *vrfv2PlusConfig.NativePremiumPercentage, - *vrfv2PlusConfig.LinkPremiumPercentage, - ) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrSetVRFCoordinatorConfig, err) - } - - l.Info().Str("Coordinator", vrfContracts.CoordinatorV2Plus.Address()).Msg("Setting Link and ETH/LINK feed") - err = vrfContracts.CoordinatorV2Plus.SetLINKAndLINKNativeFeed(linkToken.Address(), mockNativeLINKFeed.Address()) - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("%s, err %w", ErrSetLinkNativeLinkFeed, err) - } - err = env.EVMClient.WaitForEvents() - if err != nil { - return nil, nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) - } - l.Info(). - Str("Coordinator", vrfContracts.CoordinatorV2Plus.Address()). - Int("Number of Subs to create", numberOfSubToCreate). - Msg("Creating and funding subscriptions, adding consumers") - subIDs, err := CreateFundSubsAndAddConsumers( + configGeneral := vrfv2PlusTestConfig.GetVRFv2PlusConfig().General + vrfContracts, subIDs, err := SetupVRFV2PlusContracts( env, - big.NewFloat(*vrfv2PlusConfig.SubscriptionFundingAmountNative), - big.NewFloat(*vrfv2PlusConfig.SubscriptionFundingAmountLink), linkToken, - vrfContracts.CoordinatorV2Plus, vrfContracts.VRFV2PlusConsumer, + mockNativeLINKFeed, + configGeneral, numberOfSubToCreate, - vrfv2plus_config.BillingType(*vrfv2PlusConfig.SubscriptionBillingType)) + numberOfConsumers, + l, + ) if err != nil { return nil, nil, nil, nil, err } - var nodesMap = make(map[vrfcommon.VRFNodeType]*vrfcommon.VRFNode) - for i, nodeType := range nodesToCreate { - nodesMap[nodeType] = &vrfcommon.VRFNode{ - CLNode: env.ClCluster.Nodes[i], - } - } - l.Info().Str("Node URL", nodesMap[vrfcommon.VRF].CLNode.API.URL()).Msg("Creating VRF Key on the Node") - vrfKey, err := nodesMap[vrfcommon.VRF].CLNode.API.MustCreateVRFKey() + nodeTypeToNodeMap := vrfcommon.CreateNodeTypeToNodeMap(env.ClCluster, nodesToCreate) + vrfKey, pubKeyCompressed, err := vrfcommon.CreateVRFKeyOnVRFNode(nodeTypeToNodeMap[vrfcommon.VRF], l) if err != nil { - return nil, nil, nil, nil, fmt.Errorf("%s, err %w", ErrCreatingVRFv2PlusKey, err) + return nil, nil, nil, nil, err } - pubKeyCompressed := vrfKey.Data.ID - l.Info(). - Str("Node URL", nodesMap[vrfcommon.VRF].CLNode.API.URL()). - Str("Keyhash", vrfKey.Data.Attributes.Hash). - Str("VRF Compressed Key", vrfKey.Data.Attributes.Compressed). - Str("VRF Uncompressed Key", vrfKey.Data.Attributes.Uncompressed). - Msg("VRF Key created on the Node") l.Info().Str("Coordinator", vrfContracts.CoordinatorV2Plus.Address()).Msg("Registering Proving Key") - provingKey, err := VRFV2_5RegisterProvingKey(vrfKey, vrfContracts.CoordinatorV2Plus, uint64(*vrfv2PlusConfig.CLNodeMaxGasPriceGWei)*1e9) + provingKey, err := VRFV2_5RegisterProvingKey(vrfKey, vrfContracts.CoordinatorV2Plus, uint64(assets.GWei(*configGeneral.CLNodeMaxGasPriceGWei).Int64())) if err != nil { return nil, nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRegisteringProvingKey, err) } @@ -265,7 +216,7 @@ func SetupVRFV2_5Environment( chainID := env.EVMClient.GetChainID() vrfTXKeyAddressStrings, _, err := vrfcommon.CreateFundAndGetSendingKeys( env.EVMClient, - nodesMap[vrfcommon.VRF], + nodeTypeToNodeMap[vrfcommon.VRF], *vrfv2PlusTestConfig.GetCommonConfig().ChainlinkNodeFunding, numberOfTxKeysToCreate, chainID, @@ -273,12 +224,17 @@ func SetupVRFV2_5Environment( if err != nil { return nil, nil, nil, nil, err } - nodesMap[vrfcommon.VRF].TXKeyAddressStrings = vrfTXKeyAddressStrings + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + } + + nodeTypeToNodeMap[vrfcommon.VRF].TXKeyAddressStrings = vrfTXKeyAddressStrings g := errgroup.Group{} - if vrfNode, exists := nodesMap[vrfcommon.VRF]; exists { + if vrfNode, exists := nodeTypeToNodeMap[vrfcommon.VRF]; exists { g.Go(func() error { - err := setupVRFNode(vrfContracts, chainID, vrfv2PlusConfig.General, pubKeyCompressed, l, vrfNode) + err := setupVRFNode(vrfContracts, chainID, configGeneral, pubKeyCompressed, l, vrfNode) if err != nil { return err } @@ -286,11 +242,11 @@ func SetupVRFV2_5Environment( }) } - if bhsNode, exists := nodesMap[vrfcommon.BHS]; exists { + if bhsNode, exists := nodeTypeToNodeMap[vrfcommon.BHS]; exists { g.Go(func() error { err := vrfcommon.SetupBHSNode( env, - vrfv2PlusConfig.General, + configGeneral.General, numberOfTxKeysToCreate, chainID, vrfContracts.CoordinatorV2Plus.Address(), @@ -317,23 +273,81 @@ func SetupVRFV2_5Environment( } l.Info().Msg("VRFV2 Plus environment setup is finished") - return vrfContracts, subIDs, &vrfKeyData, nodesMap, nil + return vrfContracts, subIDs, &vrfKeyData, nodeTypeToNodeMap, nil } -func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, vrfv2Config *testconfig.General, pubKeyCompressed string, l zerolog.Logger, vrfNode *vrfcommon.VRFNode) error { +func SetupVRFV2PlusContracts( + env *test_env.CLClusterTestEnv, + linkToken contracts.LinkToken, + mockNativeLINKFeed contracts.MockETHLINKFeed, + configGeneral *testconfig.General, + numberOfSubToCreate int, + numberOfConsumers int, + l zerolog.Logger, +) (*vrfcommon.VRFContracts, []*big.Int, error) { + l.Info().Msg("Deploying VRFV2 Plus contracts") + vrfContracts, err := DeployVRFV2_5Contracts(env.ContractDeployer, env.EVMClient, numberOfConsumers) + if err != nil { + return nil, nil, fmt.Errorf("%s, err %w", ErrDeployVRFV2_5Contracts, err) + } + + l.Info().Str("Coordinator", vrfContracts.CoordinatorV2Plus.Address()).Msg("Setting Coordinator Config") + err = vrfContracts.CoordinatorV2Plus.SetConfig( + *configGeneral.MinimumConfirmations, + *configGeneral.MaxGasLimitCoordinatorConfig, + *configGeneral.StalenessSeconds, + *configGeneral.GasAfterPaymentCalculation, + big.NewInt(*configGeneral.FallbackWeiPerUnitLink), + *configGeneral.FulfillmentFlatFeeNativePPM, + *configGeneral.FulfillmentFlatFeeLinkDiscountPPM, + *configGeneral.NativePremiumPercentage, + *configGeneral.LinkPremiumPercentage, + ) + if err != nil { + return nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrSetVRFCoordinatorConfig, err) + } + + l.Info().Str("Coordinator", vrfContracts.CoordinatorV2Plus.Address()).Msg("Setting Link and ETH/LINK feed") + err = vrfContracts.CoordinatorV2Plus.SetLINKAndLINKNativeFeed(linkToken.Address(), mockNativeLINKFeed.Address()) + if err != nil { + return nil, nil, fmt.Errorf("%s, err %w", ErrSetLinkNativeLinkFeed, err) + } + err = env.EVMClient.WaitForEvents() + if err != nil { + return nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) + } + l.Info(). + Str("Coordinator", vrfContracts.CoordinatorV2Plus.Address()). + Int("Number of Subs to create", numberOfSubToCreate). + Msg("Creating and funding subscriptions, adding consumers") + subIDs, err := CreateFundSubsAndAddConsumers( + env, + big.NewFloat(*configGeneral.SubscriptionFundingAmountNative), + big.NewFloat(*configGeneral.SubscriptionFundingAmountLink), + linkToken, + vrfContracts.CoordinatorV2Plus, vrfContracts.VRFV2PlusConsumer, + numberOfSubToCreate, + ) + if err != nil { + return nil, nil, err + } + return vrfContracts, subIDs, nil +} + +func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, config *vrfv2plus_config.General, pubKeyCompressed string, l zerolog.Logger, vrfNode *vrfcommon.VRFNode) error { vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{ - ForwardingAllowed: *vrfv2Config.VRFJobForwardingAllowed, + ForwardingAllowed: *config.VRFJobForwardingAllowed, CoordinatorAddress: contracts.CoordinatorV2Plus.Address(), FromAddresses: vrfNode.TXKeyAddressStrings, EVMChainID: chainID.String(), - MinIncomingConfirmations: int(*vrfv2Config.MinimumConfirmations), + MinIncomingConfirmations: int(*config.MinimumConfirmations), PublicKey: pubKeyCompressed, - EstimateGasMultiplier: *vrfv2Config.VRFJobEstimateGasMultiplier, - BatchFulfillmentEnabled: *vrfv2Config.VRFJobBatchFulfillmentEnabled, - BatchFulfillmentGasMultiplier: *vrfv2Config.VRFJobBatchFulfillmentGasMultiplier, - PollPeriod: vrfv2Config.VRFJobPollPeriod.Duration, - RequestTimeout: vrfv2Config.VRFJobRequestTimeout.Duration, - SimulationBlock: vrfv2Config.VRFJobSimulationBlock, + EstimateGasMultiplier: *config.VRFJobEstimateGasMultiplier, + BatchFulfillmentEnabled: *config.VRFJobBatchFulfillmentEnabled, + BatchFulfillmentGasMultiplier: *config.VRFJobBatchFulfillmentGasMultiplier, + PollPeriod: config.VRFJobPollPeriod.Duration, + RequestTimeout: config.VRFJobRequestTimeout.Duration, + SimulationBlock: config.VRFJobSimulationBlock, VRFOwnerConfig: nil, } @@ -352,7 +366,7 @@ func setupVRFNode(contracts *vrfcommon.VRFContracts, chainID *big.Int, vrfv2Conf // Key = '...' nodeConfig := node.NewConfig(vrfNode.CLNode.NodeConfig, node.WithLogPollInterval(1*time.Second), - node.WithVRFv2EVMEstimator(vrfNode.TXKeyAddressStrings, *vrfv2Config.CLNodeMaxGasPriceGWei), + node.WithVRFv2EVMEstimator(vrfNode.TXKeyAddressStrings, *config.CLNodeMaxGasPriceGWei), ) l.Info().Msg("Restarting Node with new sending key PriceMax configuration") err = vrfNode.CLNode.Restart(nodeConfig) @@ -370,7 +384,6 @@ func CreateFundSubsAndAddConsumers( coordinator contracts.VRFCoordinatorV2_5, consumers []contracts.VRFv2PlusLoadTestConsumer, numberOfSubToCreate int, - subscriptionBillingType vrfv2plus_config.BillingType, ) ([]*big.Int, error) { subIDs, err := CreateSubsAndFund( env, @@ -379,7 +392,6 @@ func CreateFundSubsAndAddConsumers( linkToken, coordinator, numberOfSubToCreate, - subscriptionBillingType, ) if err != nil { return nil, err @@ -413,7 +425,6 @@ func CreateSubsAndFund( linkToken contracts.LinkToken, coordinator contracts.VRFCoordinatorV2_5, subAmountToCreate int, - subscriptionBillingType vrfv2plus_config.BillingType, ) ([]*big.Int, error) { subs, err := CreateSubs(env, coordinator, subAmountToCreate) if err != nil { @@ -430,7 +441,6 @@ func CreateSubsAndFund( linkToken, coordinator, subs, - subscriptionBillingType, ) if err != nil { return nil, err @@ -498,45 +508,22 @@ func FundSubscriptions( linkAddress contracts.LinkToken, coordinator contracts.VRFCoordinatorV2_5, subIDs []*big.Int, - subscriptionBillingType vrfv2plus_config.BillingType, ) error { for _, subID := range subIDs { - switch subscriptionBillingType { - case vrfv2plus_config.BillingType_Native: - //Native Billing - amountWei := conversions.EtherToWei(subscriptionFundingAmountNative) - err := coordinator.FundSubscriptionWithNative( - subID, - amountWei, - ) - if err != nil { - return fmt.Errorf("%s, err %w", ErrFundSubWithNativeToken, err) - } - case vrfv2plus_config.BillingType_Link: - //Link Billing - amountJuels := conversions.EtherToWei(subscriptionFundingAmountLink) - err := FundVRFCoordinatorV2_5Subscription(linkAddress, coordinator, env.EVMClient, subID, amountJuels) - if err != nil { - return fmt.Errorf("%s, err %w", vrfcommon.ErrFundSubWithLinkToken, err) - } - case vrfv2plus_config.BillingType_Link_and_Native: - //Native Billing - amountWei := conversions.EtherToWei(subscriptionFundingAmountNative) - err := coordinator.FundSubscriptionWithNative( - subID, - amountWei, - ) - if err != nil { - return fmt.Errorf("%s, err %w", ErrFundSubWithNativeToken, err) - } - //Link Billing - amountJuels := conversions.EtherToWei(subscriptionFundingAmountLink) - err = FundVRFCoordinatorV2_5Subscription(linkAddress, coordinator, env.EVMClient, subID, amountJuels) - if err != nil { - return fmt.Errorf("%s, err %w", vrfcommon.ErrFundSubWithLinkToken, err) - } - default: - return fmt.Errorf("invalid billing type: %s", subscriptionBillingType) + //Native Billing + amountWei := conversions.EtherToWei(subscriptionFundingAmountNative) + err := coordinator.FundSubscriptionWithNative( + subID, + amountWei, + ) + if err != nil { + return fmt.Errorf("%s, err %w", ErrFundSubWithNativeToken, err) + } + //Link Billing + amountJuels := conversions.EtherToWei(subscriptionFundingAmountLink) + err = FundVRFCoordinatorV2_5Subscription(linkAddress, coordinator, env.EVMClient, subID, amountJuels) + if err != nil { + return fmt.Errorf("%s, err %w", vrfcommon.ErrFundSubWithLinkToken, err) } } err := env.EVMClient.WaitForEvents() @@ -743,7 +730,14 @@ func SetupVRFV2PlusWrapperEnvironment( return nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitTXsComplete, err) } - err = FundSubscriptions(env, big.NewFloat(*vrfv2PlusTestConfig.GetVRFv2PlusConfig().General.SubscriptionFundingAmountNative), big.NewFloat(*vrfv2PlusTestConfig.GetVRFv2PlusConfig().General.SubscriptionFundingAmountLink), linkToken, coordinator, []*big.Int{wrapperSubID}, vrfv2plus_config.BillingType(*vrfv2PlusTestConfig.GetVRFv2PlusConfig().General.SubscriptionBillingType)) + err = FundSubscriptions( + env, + big.NewFloat(*vrfv2PlusTestConfig.GetVRFv2PlusConfig().General.SubscriptionFundingAmountNative), + big.NewFloat(*vrfv2PlusTestConfig.GetVRFv2PlusConfig().General.SubscriptionFundingAmountLink), + linkToken, + coordinator, + []*big.Int{wrapperSubID}, + ) if err != nil { return nil, nil, err } @@ -911,39 +905,6 @@ func WaitForRequestAndFulfillmentEvents( return randomWordsFulfilledEvent, err } -func WaitForRequestCountEqualToFulfilmentCount(consumer contracts.VRFv2PlusLoadTestConsumer, timeout time.Duration, wg *sync.WaitGroup) (*big.Int, *big.Int, error) { - metricsChannel := make(chan *contracts.VRFLoadTestMetrics) - metricsErrorChannel := make(chan error) - - testContext, testCancel := context.WithTimeout(context.Background(), timeout) - defer testCancel() - - ticker := time.NewTicker(time.Second * 1) - var metrics *contracts.VRFLoadTestMetrics - for { - select { - case <-testContext.Done(): - ticker.Stop() - wg.Done() - return metrics.RequestCount, metrics.FulfilmentCount, - fmt.Errorf("timeout waiting for rand request and fulfilments to be equal AFTER performance test was executed. Request Count: %d, Fulfilment Count: %d", - metrics.RequestCount.Uint64(), metrics.FulfilmentCount.Uint64()) - case <-ticker.C: - go retrieveLoadTestMetrics(consumer, metricsChannel, metricsErrorChannel) - case metrics = <-metricsChannel: - if metrics.RequestCount.Cmp(metrics.FulfilmentCount) == 0 { - ticker.Stop() - wg.Done() - return metrics.RequestCount, metrics.FulfilmentCount, nil - } - case err := <-metricsErrorChannel: - ticker.Stop() - wg.Done() - return nil, nil, err - } - } -} - func ReturnFundsForFulfilledRequests(client blockchain.EVMClient, coordinator contracts.VRFCoordinatorV2_5, l zerolog.Logger) error { linkTotalBalance, err := coordinator.GetLinkTotalBalance(context.Background()) if err != nil { @@ -977,18 +938,6 @@ func ReturnFundsForFulfilledRequests(client blockchain.EVMClient, coordinator co return nil } -func retrieveLoadTestMetrics( - consumer contracts.VRFv2PlusLoadTestConsumer, - metricsChannel chan *contracts.VRFLoadTestMetrics, - metricsErrorChannel chan error, -) { - metrics, err := consumer.GetLoadTestMetrics(context.Background()) - if err != nil { - metricsErrorChannel <- err - } - metricsChannel <- metrics -} - func LogSubDetails(l zerolog.Logger, subscription vrf_coordinator_v2_5.GetSubscription, subID *big.Int, coordinator contracts.VRFCoordinatorV2_5) { l.Debug(). Str("Coordinator", coordinator.Address()). @@ -1010,7 +959,7 @@ func LogRandomnessRequestedEventUpgraded( Str("Request ID", randomWordsRequestedEvent.RequestId.String()). Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). Str("Sender Address", randomWordsRequestedEvent.Sender.String()). - Interface("Keyhash", fmt.Sprintf("0x%x", randomWordsRequestedEvent.KeyHash)). + Str("Keyhash", fmt.Sprintf("0x%x", randomWordsRequestedEvent.KeyHash)). Uint32("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). Uint32("Number of Words", randomWordsRequestedEvent.NumWords). Uint16("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). @@ -1044,10 +993,13 @@ func LogRandomnessRequestedEvent( Str("Request ID", randomWordsRequestedEvent.RequestId.String()). Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). Str("Sender Address", randomWordsRequestedEvent.Sender.String()). - Interface("Keyhash", fmt.Sprintf("0x%x", randomWordsRequestedEvent.KeyHash)). + Str("Keyhash", fmt.Sprintf("0x%x", randomWordsRequestedEvent.KeyHash)). Uint32("Callback Gas Limit", randomWordsRequestedEvent.CallbackGasLimit). Uint32("Number of Words", randomWordsRequestedEvent.NumWords). Uint16("Minimum Request Confirmations", randomWordsRequestedEvent.MinimumRequestConfirmations). + Str("TX Hash", randomWordsRequestedEvent.Raw.TxHash.String()). + Uint64("BlockNumber", randomWordsRequestedEvent.Raw.BlockNumber). + Str("BlockHash", randomWordsRequestedEvent.Raw.BlockHash.String()). Msg("RandomnessRequested Event") } @@ -1065,6 +1017,8 @@ func LogRandomWordsFulfilledEvent( Str("Subscription ID", randomWordsFulfilledEvent.SubId.String()). Str("Request ID", randomWordsFulfilledEvent.RequestId.String()). Bool("Success", randomWordsFulfilledEvent.Success). + Uint64("BlockNumber", randomWordsFulfilledEvent.Raw.BlockNumber). + Str("BlockHash", randomWordsFulfilledEvent.Raw.BlockHash.String()). Msg("RandomWordsFulfilled Event (TX metadata)") } diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index 7775df798be..4f68d304256 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -338,9 +338,12 @@ type LoadTestRequestStatus struct { } type VRFLoadTestMetrics struct { - RequestCount *big.Int - FulfilmentCount *big.Int - AverageFulfillmentInMillions *big.Int - SlowestFulfillment *big.Int - FastestFulfillment *big.Int + RequestCount *big.Int + FulfilmentCount *big.Int + AverageFulfillmentInMillions *big.Int + SlowestFulfillment *big.Int + FastestFulfillment *big.Int + AverageResponseTimeInSecondsMillions *big.Int + SlowestResponseTimeInSeconds *big.Int + FastestResponseTimeInSeconds *big.Int } diff --git a/integration-tests/contracts/ethereum_vrfv2_contracts.go b/integration-tests/contracts/ethereum_vrfv2_contracts.go index 7501521ac33..fc7a5a7a138 100644 --- a/integration-tests/contracts/ethereum_vrfv2_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2_contracts.go @@ -913,6 +913,9 @@ func (v *EthereumVRFv2LoadTestConsumer) GetLoadTestMetrics(ctx context.Context) averageFulfillmentInMillions, slowestFulfillment, fastestFulfillment, + nil, + nil, + nil, }, nil } @@ -1036,6 +1039,9 @@ func (v *EthereumVRFV2WrapperLoadTestConsumer) GetLoadTestMetrics(ctx context.Co averageFulfillmentInMillions, slowestFulfillment, fastestFulfillment, + nil, + nil, + nil, }, nil } diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index d8a5b30c703..9f728b33043 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -522,14 +522,14 @@ func (v *EthereumVRFv2PlusLoadTestConsumer) GetLoadTestMetrics(ctx context.Conte if err != nil { return nil, err } - averageFulfillmentInMillions, err := v.consumer.SAverageFulfillmentInMillions(&bind.CallOpts{ + averageFulfillmentInMillions, err := v.consumer.SAverageResponseTimeInBlocksMillions(&bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, }) if err != nil { return nil, err } - slowestFulfillment, err := v.consumer.SSlowestFulfillment(&bind.CallOpts{ + slowestFulfillment, err := v.consumer.SSlowestResponseTimeInBlocks(&bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, }) @@ -537,7 +537,30 @@ func (v *EthereumVRFv2PlusLoadTestConsumer) GetLoadTestMetrics(ctx context.Conte if err != nil { return nil, err } - fastestFulfillment, err := v.consumer.SFastestFulfillment(&bind.CallOpts{ + fastestFulfillment, err := v.consumer.SFastestResponseTimeInBlocks(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) + if err != nil { + return nil, err + } + + averageResponseTimeInSeconds, err := v.consumer.SAverageResponseTimeInSecondsMillions(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) + if err != nil { + return nil, err + } + slowestResponseTimeInSeconds, err := v.consumer.SSlowestResponseTimeInSeconds(&bind.CallOpts{ + From: common.HexToAddress(v.client.GetDefaultWallet().Address()), + Context: ctx, + }) + + if err != nil { + return nil, err + } + fastestResponseTimeInSeconds, err := v.consumer.SFastestResponseTimeInSeconds(&bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, }) @@ -546,11 +569,14 @@ func (v *EthereumVRFv2PlusLoadTestConsumer) GetLoadTestMetrics(ctx context.Conte } return &VRFLoadTestMetrics{ - requestCount, - fulfilmentCount, - averageFulfillmentInMillions, - slowestFulfillment, - fastestFulfillment, + RequestCount: requestCount, + FulfilmentCount: fulfilmentCount, + AverageFulfillmentInMillions: averageFulfillmentInMillions, + SlowestFulfillment: slowestFulfillment, + FastestFulfillment: fastestFulfillment, + AverageResponseTimeInSecondsMillions: averageResponseTimeInSeconds, + SlowestResponseTimeInSeconds: slowestResponseTimeInSeconds, + FastestResponseTimeInSeconds: fastestResponseTimeInSeconds, }, nil } @@ -1036,10 +1062,13 @@ func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) GetLoadTestMetrics(ctx contex } return &VRFLoadTestMetrics{ - requestCount, - fulfilmentCount, - averageFulfillmentInMillions, - slowestFulfillment, - fastestFulfillment, + RequestCount: requestCount, + FulfilmentCount: fulfilmentCount, + AverageFulfillmentInMillions: averageFulfillmentInMillions, + SlowestFulfillment: slowestFulfillment, + FastestFulfillment: fastestFulfillment, + AverageResponseTimeInSecondsMillions: nil, + SlowestResponseTimeInSeconds: nil, + FastestResponseTimeInSeconds: nil, }, nil } diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index 5eae49058cb..e99f353d149 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -15,6 +15,7 @@ import ( "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" + "github.com/smartcontractkit/chainlink-testing-framework/utils/testcontext" "github.com/smartcontractkit/chainlink/integration-tests/actions" vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2" @@ -69,20 +70,10 @@ func TestVRFV2Performance(t *testing.T) { Str("RateLimitUnitDuration", vrfv2Config.Performance.RateLimitUnitDuration.String()). Uint16("RandomnessRequestCountPerRequest", *vrfv2Config.General.RandomnessRequestCountPerRequest). Uint16("RandomnessRequestCountPerRequestDeviation", *vrfv2Config.General.RandomnessRequestCountPerRequestDeviation). - Bool("UseExistingEnv", *vrfv2Config.Performance.UseExistingEnv). + Bool("UseExistingEnv", *vrfv2Config.General.UseExistingEnv). Msg("Performance Test Configuration") - if *vrfv2Config.Performance.UseExistingEnv { - //todo: temporary solution with envconfig and toml config until VRF-662 is implemented - cfg := testConfig.VRFv2 - - vrfv2Config.Performance.CoordinatorAddress = cfg.ExistingEnvConfig.CoordinatorAddress - vrfv2Config.Performance.ConsumerAddress = cfg.ExistingEnvConfig.ConsumerAddress - vrfv2Config.Performance.LinkAddress = cfg.ExistingEnvConfig.LinkAddress - vrfv2Config.General.SubscriptionFundingAmountLink = cfg.ExistingEnvConfig.SubFunding.SubFundsLink - vrfv2Config.Performance.SubID = cfg.ExistingEnvConfig.SubID - vrfv2Config.Performance.KeyHash = cfg.ExistingEnvConfig.KeyHash - + if *vrfv2Config.General.UseExistingEnv { env, err = test_env.NewCLTestEnvBuilder(). WithTestInstance(t). WithTestConfig(&testConfig). @@ -94,9 +85,9 @@ func TestVRFV2Performance(t *testing.T) { Str("Network Name", env.EVMClient.GetNetworkName()). Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") } else { - if *vrfv2Config.Common.CancelSubsAfterTestRun { + if *vrfv2Config.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - cancelSubsAndReturnFunds(subIDs, l) + cancelSubsAndReturnFunds(testcontext.Get(t), subIDs, l) } } }). @@ -104,24 +95,24 @@ func TestVRFV2Performance(t *testing.T) { require.NoError(t, err, "error creating test env") - coordinator, err := env.ContractLoader.LoadVRFCoordinatorV2(*vrfv2Config.Performance.CoordinatorAddress) + coordinator, err := env.ContractLoader.LoadVRFCoordinatorV2(*vrfv2Config.ExistingEnvConfig.CoordinatorAddress) require.NoError(t, err) var consumers []contracts.VRFv2LoadTestConsumer - if *cfg.ExistingEnvConfig.CreateFundSubsAndAddConsumers { - linkToken, err := env.ContractLoader.LoadLINKToken(*vrfv2Config.Performance.LinkAddress) + if *vrfv2Config.ExistingEnvConfig.CreateFundSubsAndAddConsumers { + linkToken, err := env.ContractLoader.LoadLINKToken(*vrfv2Config.ExistingEnvConfig.LinkAddress) require.NoError(t, err) consumers, err = vrfv2.DeployVRFV2Consumers(env.ContractDeployer, coordinator.Address(), 1) require.NoError(t, err) err = env.EVMClient.WaitForEvents() require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) l.Info(). - Str("Coordinator", *cfg.ExistingEnvConfig.CoordinatorAddress). + Str("Coordinator", *vrfv2Config.ExistingEnvConfig.CoordinatorAddress). Int("Number of Subs to create", *vrfv2Config.General.NumberOfSubToCreate). Msg("Creating and funding subscriptions, deploying and adding consumers to subs") subIDs, err = vrfv2.CreateFundSubsAndAddConsumers( env, - big.NewFloat(*cfg.General.SubscriptionFundingAmountLink), + big.NewFloat(*vrfv2Config.General.SubscriptionFundingAmountLink), linkToken, coordinator, consumers, @@ -129,13 +120,13 @@ func TestVRFV2Performance(t *testing.T) { ) require.NoError(t, err) } else { - consumer, err := env.ContractLoader.LoadVRFv2LoadTestConsumer(*vrfv2Config.Performance.ConsumerAddress) + consumer, err := env.ContractLoader.LoadVRFv2LoadTestConsumer(*vrfv2Config.ExistingEnvConfig.ConsumerAddress) require.NoError(t, err) consumers = append(consumers, consumer) - subIDs = append(subIDs, *vrfv2Config.Performance.SubID) + subIDs = append(subIDs, *vrfv2Config.ExistingEnvConfig.SubID) } - err = FundNodesIfNeeded(&testConfig, env.EVMClient, l) + err = FundNodesIfNeeded(testcontext.Get(t), &testConfig, env.EVMClient, l) require.NoError(t, err) vrfContracts = &vrfcommon.VRFContracts{ @@ -147,14 +138,10 @@ func TestVRFV2Performance(t *testing.T) { vrfKeyData = &vrfcommon.VRFKeyData{ VRFKey: nil, EncodedProvingKey: [2]*big.Int{}, - KeyHash: common.HexToHash(*vrfv2Config.Performance.KeyHash), + KeyHash: common.HexToHash(*vrfv2Config.ExistingEnvConfig.KeyHash), } } else { - //todo: temporary solution with envconfig and toml config until VRF-662 is implemented - testConfig.Common.ChainlinkNodeFunding = testConfig.VRFv2.NewEnvConfig.NodeSendingKeyFunding - vrfv2Config.General.SubscriptionFundingAmountLink = testConfig.VRFv2.NewEnvConfig.Funding.SubFundsLink - network, err := actions.EthereumNetworkConfigFromConfig(l, &testConfig) require.NoError(t, err, "Error building ethereum network config") env, err = test_env.NewCLTestEnvBuilder(). @@ -172,9 +159,9 @@ func TestVRFV2Performance(t *testing.T) { Str("Network Name", env.EVMClient.GetNetworkName()). Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") } else { - if *testConfig.VRFv2.Common.CancelSubsAfterTestRun { + if *testConfig.VRFv2.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - cancelSubsAndReturnFunds(subIDs, l) + cancelSubsAndReturnFunds(testcontext.Get(t), subIDs, l) } } if err := env.Cleanup(); err != nil { @@ -217,11 +204,10 @@ func TestVRFV2Performance(t *testing.T) { l.Debug().Int("Number of Subs", len(subIDs)).Msg("Subs involved in the test") for _, subID := range subIDs { - subscription, err := vrfContracts.CoordinatorV2.GetSubscription(context.Background(), subID) + subscription, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subID) require.NoError(t, err, "error getting subscription information for subscription %d", subID) vrfv2.LogSubDetails(l, subscription, subID, vrfContracts.CoordinatorV2) } - singleFeedConfig := &wasp.Config{ T: t, LoadType: wasp.RPS, @@ -259,7 +245,7 @@ func TestVRFV2Performance(t *testing.T) { var wg sync.WaitGroup wg.Add(1) //todo - timeout should be configurable depending on the perf test type - requestCount, fulfilmentCount, err := vrfv2.WaitForRequestCountEqualToFulfilmentCount(consumer, 2*time.Minute, &wg) + requestCount, fulfilmentCount, err := vrfcommon.WaitForRequestCountEqualToFulfilmentCount(testcontext.Get(t), consumer, 2*time.Minute, &wg) require.NoError(t, err) wg.Wait() @@ -271,13 +257,13 @@ func TestVRFV2Performance(t *testing.T) { } -func cancelSubsAndReturnFunds(subIDs []uint64, l zerolog.Logger) { +func cancelSubsAndReturnFunds(ctx context.Context, subIDs []uint64, l zerolog.Logger) { for _, subID := range subIDs { l.Info(). Uint64("Returning funds from SubID", subID). Str("Returning funds to", eoaWalletAddress). Msg("Canceling subscription and returning funds to subscription owner") - pendingRequestsExist, err := vrfContracts.CoordinatorV2.PendingRequestsExist(context.Background(), subID) + pendingRequestsExist, err := vrfContracts.CoordinatorV2.PendingRequestsExist(ctx, subID) if err != nil { l.Error().Err(err).Msg("Error checking if pending requests exist") } @@ -292,12 +278,12 @@ func cancelSubsAndReturnFunds(subIDs []uint64, l zerolog.Logger) { } } -func FundNodesIfNeeded(vrfv2TestConfig tc.VRFv2TestConfig, client blockchain.EVMClient, l zerolog.Logger) error { +func FundNodesIfNeeded(ctx context.Context, vrfv2TestConfig tc.VRFv2TestConfig, client blockchain.EVMClient, l zerolog.Logger) error { cfg := vrfv2TestConfig.GetVRFv2Config() if cfg.ExistingEnvConfig.NodeSendingKeyFundingMin != nil && *cfg.ExistingEnvConfig.NodeSendingKeyFundingMin > 0 { for _, sendingKey := range cfg.ExistingEnvConfig.NodeSendingKeys { address := common.HexToAddress(sendingKey) - sendingKeyBalance, err := client.BalanceAt(context.Background(), address) + sendingKeyBalance, err := client.BalanceAt(ctx, address) if err != nil { return err } diff --git a/integration-tests/load/vrfv2plus/vrfv2plus_test.go b/integration-tests/load/vrfv2plus/vrfv2plus_test.go index 877c5b3d1b7..13c694c0290 100644 --- a/integration-tests/load/vrfv2plus/vrfv2plus_test.go +++ b/integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -26,7 +26,6 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" - vrfv2plus_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2plus" ) var ( @@ -69,18 +68,10 @@ func TestVRFV2PlusPerformance(t *testing.T) { Str("RateLimitUnitDuration", vrfv2PlusConfig.Performance.RateLimitUnitDuration.String()). Uint16("RandomnessRequestCountPerRequest", *vrfv2PlusConfig.General.RandomnessRequestCountPerRequest). Uint16("RandomnessRequestCountPerRequestDeviation", *vrfv2PlusConfig.General.RandomnessRequestCountPerRequestDeviation). - Bool("UseExistingEnv", *vrfv2PlusConfig.Performance.UseExistingEnv). + Bool("UseExistingEnv", *vrfv2PlusConfig.General.UseExistingEnv). Msg("Performance Test Configuration") - if *vrfv2PlusConfig.Performance.UseExistingEnv { - //todo: temporary solution with envconfig and toml config until VRF-662 is implemented - vrfv2PlusConfig.Performance.CoordinatorAddress = testConfig.VRFv2Plus.ExistingEnvConfig.CoordinatorAddress - vrfv2PlusConfig.Performance.ConsumerAddress = testConfig.VRFv2Plus.ExistingEnvConfig.ConsumerAddress - vrfv2PlusConfig.Performance.LinkAddress = testConfig.VRFv2Plus.ExistingEnvConfig.LinkAddress - vrfv2PlusConfig.General.SubscriptionFundingAmountLink = testConfig.VRFv2Plus.ExistingEnvConfig.SubFunding.SubFundsLink - vrfv2PlusConfig.General.SubscriptionFundingAmountNative = testConfig.VRFv2Plus.ExistingEnvConfig.SubFunding.SubFundsNative - vrfv2PlusConfig.Performance.SubID = testConfig.VRFv2Plus.ExistingEnvConfig.SubID - vrfv2PlusConfig.Performance.KeyHash = testConfig.VRFv2Plus.ExistingEnvConfig.KeyHash + if *vrfv2PlusConfig.General.UseExistingEnv { env, err = test_env.NewCLTestEnvBuilder(). WithTestInstance(t). @@ -93,9 +84,9 @@ func TestVRFV2PlusPerformance(t *testing.T) { Str("Network Name", env.EVMClient.GetNetworkName()). Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") } else { - if *testConfig.VRFv2Plus.Common.CancelSubsAfterTestRun { + if *testConfig.VRFv2Plus.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - cancelSubsAndReturnFunds(subIDs, l) + cancelSubsAndReturnFunds(testcontext.Get(t), subIDs, l) } } }). @@ -103,19 +94,19 @@ func TestVRFV2PlusPerformance(t *testing.T) { require.NoError(t, err, "error creating test env") - coordinator, err := env.ContractLoader.LoadVRFCoordinatorV2_5(*vrfv2PlusConfig.Performance.CoordinatorAddress) + coordinator, err := env.ContractLoader.LoadVRFCoordinatorV2_5(*vrfv2PlusConfig.ExistingEnvConfig.CoordinatorAddress) require.NoError(t, err) var consumers []contracts.VRFv2PlusLoadTestConsumer if *testConfig.VRFv2Plus.ExistingEnvConfig.CreateFundSubsAndAddConsumers { - linkToken, err := env.ContractLoader.LoadLINKToken(*vrfv2PlusConfig.Performance.LinkAddress) + linkToken, err := env.ContractLoader.LoadLINKToken(*vrfv2PlusConfig.ExistingEnvConfig.LinkAddress) require.NoError(t, err) consumers, err = vrfv2plus.DeployVRFV2PlusConsumers(env.ContractDeployer, coordinator, 1) require.NoError(t, err) err = env.EVMClient.WaitForEvents() require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) l.Info(). - Str("Coordinator", *vrfv2PlusConfig.Performance.CoordinatorAddress). + Str("Coordinator", *vrfv2PlusConfig.ExistingEnvConfig.CoordinatorAddress). Int("Number of Subs to create", *vrfv2PlusConfig.General.NumberOfSubToCreate). Msg("Creating and funding subscriptions, deploying and adding consumers to subs") subIDs, err = vrfv2plus.CreateFundSubsAndAddConsumers( @@ -126,20 +117,19 @@ func TestVRFV2PlusPerformance(t *testing.T) { coordinator, consumers, *vrfv2PlusConfig.General.NumberOfSubToCreate, - vrfv2plus_config.BillingType(*vrfv2PlusConfig.General.SubscriptionBillingType), ) require.NoError(t, err) } else { - consumer, err := env.ContractLoader.LoadVRFv2PlusLoadTestConsumer(*vrfv2PlusConfig.Performance.ConsumerAddress) + consumer, err := env.ContractLoader.LoadVRFv2PlusLoadTestConsumer(*vrfv2PlusConfig.ExistingEnvConfig.ConsumerAddress) require.NoError(t, err) consumers = append(consumers, consumer) var ok bool - subID := big.NewInt(int64(*vrfv2PlusConfig.Performance.SubID)) + subID, ok := new(big.Int).SetString(*vrfv2PlusConfig.ExistingEnvConfig.SubID, 10) require.True(t, ok) subIDs = append(subIDs, subID) } - err = FundNodesIfNeeded(&testConfig, env.EVMClient, l) + err = FundNodesIfNeeded(testcontext.Get(t), &testConfig, env.EVMClient, l) require.NoError(t, err) vrfContracts = &vrfcommon.VRFContracts{ @@ -151,15 +141,10 @@ func TestVRFV2PlusPerformance(t *testing.T) { vrfv2PlusData = &vrfcommon.VRFKeyData{ VRFKey: nil, EncodedProvingKey: [2]*big.Int{}, - KeyHash: common.HexToHash(*vrfv2PlusConfig.Performance.KeyHash), + KeyHash: common.HexToHash(*vrfv2PlusConfig.ExistingEnvConfig.KeyHash), } } else { - //todo: temporary solution with envconfig and toml config until VRF-662 is implemented - testConfig.Common.ChainlinkNodeFunding = testConfig.VRFv2.NewEnvConfig.NodeSendingKeyFunding - vrfv2PlusConfig.General.SubscriptionFundingAmountLink = testConfig.VRFv2Plus.NewEnvConfig.Funding.SubFundsLink - vrfv2PlusConfig.General.SubscriptionFundingAmountNative = testConfig.VRFv2Plus.NewEnvConfig.Funding.SubFundsNative - network, err := actions.EthereumNetworkConfigFromConfig(l, &testConfig) require.NoError(t, err, "Error building ethereum network config") env, err = test_env.NewCLTestEnvBuilder(). @@ -177,9 +162,9 @@ func TestVRFV2PlusPerformance(t *testing.T) { Str("Network Name", env.EVMClient.GetNetworkName()). Msg("Network is a simulated network. Skipping fund return for Coordinator Subscriptions.") } else { - if *testConfig.VRFv2Plus.Common.CancelSubsAfterTestRun { + if *testConfig.VRFv2Plus.General.CancelSubsAfterTestRun { //cancel subs and return funds to sub owner - cancelSubsAndReturnFunds(subIDs, l) + cancelSubsAndReturnFunds(testcontext.Get(t), subIDs, l) } } if err := env.Cleanup(); err != nil { @@ -256,7 +241,7 @@ func TestVRFV2PlusPerformance(t *testing.T) { var wg sync.WaitGroup wg.Add(1) //todo - timeout should be configurable depending on the perf test type - requestCount, fulfilmentCount, err := vrfv2plus.WaitForRequestCountEqualToFulfilmentCount(consumer, 2*time.Minute, &wg) + requestCount, fulfilmentCount, err := vrfcommon.WaitForRequestCountEqualToFulfilmentCount(testcontext.Get(t), consumer, 2*time.Minute, &wg) require.NoError(t, err) wg.Wait() @@ -268,13 +253,13 @@ func TestVRFV2PlusPerformance(t *testing.T) { } -func cancelSubsAndReturnFunds(subIDs []*big.Int, l zerolog.Logger) { +func cancelSubsAndReturnFunds(ctx context.Context, subIDs []*big.Int, l zerolog.Logger) { for _, subID := range subIDs { l.Info(). Str("Returning funds from SubID", subID.String()). Str("Returning funds to", eoaWalletAddress). Msg("Canceling subscription and returning funds to subscription owner") - pendingRequestsExist, err := vrfContracts.CoordinatorV2Plus.PendingRequestsExist(context.Background(), subID) + pendingRequestsExist, err := vrfContracts.CoordinatorV2Plus.PendingRequestsExist(ctx, subID) if err != nil { l.Error().Err(err).Msg("Error checking if pending requests exist") } @@ -289,12 +274,12 @@ func cancelSubsAndReturnFunds(subIDs []*big.Int, l zerolog.Logger) { } } -func FundNodesIfNeeded(vrfv2plusTestConfig tc.VRFv2PlusTestConfig, client blockchain.EVMClient, l zerolog.Logger) error { +func FundNodesIfNeeded(ctx context.Context, vrfv2plusTestConfig tc.VRFv2PlusTestConfig, client blockchain.EVMClient, l zerolog.Logger) error { cfg := vrfv2plusTestConfig.GetVRFv2PlusConfig() - if *cfg.ExistingEnvConfig.NodeSendingKeyFundingMin > 0 { + if cfg.ExistingEnvConfig.NodeSendingKeyFundingMin != nil && *cfg.ExistingEnvConfig.NodeSendingKeyFundingMin > 0 { for _, sendingKey := range cfg.ExistingEnvConfig.NodeSendingKeys { address := common.HexToAddress(sendingKey) - sendingKeyBalance, err := client.BalanceAt(context.Background(), address) + sendingKeyBalance, err := client.BalanceAt(ctx, address) if err != nil { return err } @@ -339,11 +324,16 @@ func teardown( //set report data for Slack notification testReporter.SetReportData( testType, - metrics.RequestCount, - metrics.FulfilmentCount, - metrics.AverageFulfillmentInMillions, - metrics.SlowestFulfillment, - metrics.FastestFulfillment, + testreporters.VRFLoadTestMetrics{ + RequestCount: metrics.RequestCount, + FulfilmentCount: metrics.FulfilmentCount, + AverageFulfillmentInMillions: metrics.AverageFulfillmentInMillions, + SlowestFulfillment: metrics.SlowestFulfillment, + FastestFulfillment: metrics.FastestFulfillment, + AverageResponseTimeInSecondsMillions: metrics.AverageResponseTimeInSecondsMillions, + SlowestResponseTimeInSeconds: metrics.SlowestResponseTimeInSeconds, + FastestResponseTimeInSeconds: metrics.FastestResponseTimeInSeconds, + }, testConfig, ) diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index e0c304a3951..18a28c6ecbb 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -15,7 +15,6 @@ import ( "github.com/stretchr/testify/require" commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" "github.com/smartcontractkit/chainlink-testing-framework/logging" "github.com/smartcontractkit/chainlink-testing-framework/utils/conversions" "github.com/smartcontractkit/chainlink-testing-framework/utils/ptr" @@ -533,8 +532,7 @@ func TestVRFv2MultipleSendingKeys(t *testing.T) { require.NoError(t, err, "error requesting randomness and waiting for fulfilment") //todo - move TransactionByHash to EVMClient in CTF - fulfillmentTx, _, err := env.EVMClient.(*blockchain.EthereumMultinodeClient).DefaultClient.(*blockchain.EthereumClient). - Client.TransactionByHash(testcontext.Get(t), randomWordsFulfilledEvent.Raw.TxHash) + fulfillmentTx, _, err := actions.GetTxByHash(testcontext.Get(t), env.EVMClient, randomWordsFulfilledEvent.Raw.TxHash) require.NoError(t, err, "error getting tx from hash") fulfillmentTxFromAddress, err := actions.GetTxFromAddress(fulfillmentTx) require.NoError(t, err, "error getting tx from address") @@ -617,7 +615,7 @@ func TestVRFOwner(t *testing.T) { err = linkToken.Transfer( vrfv2Contracts.VRFV2Consumer[0].Address(), - conversions.EtherToWei(big.NewFloat(5)), + conversions.EtherToWei(big.NewFloat(*configCopy.VRFv2.General.SubscriptionFundingAmountLink)), ) require.NoError(t, err, "error transferring link to consumer contract") diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index e13f12b2a43..07360afcbeb 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -25,7 +25,6 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/actions" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" - vrfv2plus_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2plus" it_utils "github.com/smartcontractkit/chainlink/integration-tests/utils" ) @@ -88,7 +87,7 @@ func TestVRFv2Plus(t *testing.T) { var isNativeBilling = false subBalanceBeforeRequest := subscription.Balance - jobRunsBeforeTest, err := env.ClCluster.Nodes[0].API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) + jobRunsBeforeTest, err := nodesMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) require.NoError(t, err, "error reading job runs") // test and assert @@ -108,13 +107,17 @@ func TestVRFv2Plus(t *testing.T) { ) require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + require.False(t, randomWordsFulfilledEvent.OnlyPremium, "RandomWordsFulfilled Event's `OnlyPremium` field should be false") + require.Equal(t, isNativeBilling, randomWordsFulfilledEvent.NativePayment, "RandomWordsFulfilled Event's `NativePayment` field should be false") + require.True(t, randomWordsFulfilledEvent.Success, "RandomWordsFulfilled Event's `Success` field should be true") + expectedSubBalanceJuels := new(big.Int).Sub(subBalanceBeforeRequest, randomWordsFulfilledEvent.Payment) subscription, err = vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) require.NoError(t, err, "error getting subscription information") subBalanceAfterRequest := subscription.Balance require.Equal(t, expectedSubBalanceJuels, subBalanceAfterRequest) - jobRuns, err := env.ClCluster.Nodes[0].API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) + jobRuns, err := nodesMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) require.NoError(t, err, "error reading job runs") require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data)) @@ -129,14 +132,13 @@ func TestVRFv2Plus(t *testing.T) { require.Equal(t, 1, w.Cmp(big.NewInt(0)), "Expected the VRF job give an answer bigger than 0") } }) - t.Run("Native Billing", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) testConfig := configCopy.VRFv2Plus.General var isNativeBilling = true subNativeTokenBalanceBeforeRequest := subscription.NativeBalance - jobRunsBeforeTest, err := env.ClCluster.Nodes[0].API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) + jobRunsBeforeTest, err := nodesMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) require.NoError(t, err, "error reading job runs") // test and assert @@ -155,13 +157,16 @@ func TestVRFv2Plus(t *testing.T) { l, ) require.NoError(t, err, "error requesting randomness and waiting for fulfilment") + require.False(t, randomWordsFulfilledEvent.OnlyPremium) + require.Equal(t, isNativeBilling, randomWordsFulfilledEvent.NativePayment) + require.True(t, randomWordsFulfilledEvent.Success) expectedSubBalanceWei := new(big.Int).Sub(subNativeTokenBalanceBeforeRequest, randomWordsFulfilledEvent.Payment) subscription, err = vrfv2PlusContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) require.NoError(t, err) subBalanceAfterRequest := subscription.NativeBalance require.Equal(t, expectedSubBalanceWei, subBalanceAfterRequest) - jobRuns, err := env.ClCluster.Nodes[0].API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) + jobRuns, err := nodesMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) require.NoError(t, err, "error reading job runs") require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data)) @@ -308,7 +313,6 @@ func TestVRFv2Plus(t *testing.T) { vrfv2PlusContracts.CoordinatorV2Plus, vrfv2PlusContracts.VRFV2PlusConsumer, 1, - vrfv2plus_config.BillingType(*configCopy.GetVRFv2PlusConfig().General.SubscriptionBillingType), ) require.NoError(t, err) subIDForCancelling := subIDsForCancelling[0] @@ -408,7 +412,6 @@ func TestVRFv2Plus(t *testing.T) { vrfv2PlusContracts.CoordinatorV2Plus, vrfv2PlusContracts.VRFV2PlusConsumer, 1, - vrfv2plus_config.BillingType(*configCopy.GetVRFv2PlusConfig().General.SubscriptionBillingType), ) require.NoError(t, err) @@ -556,7 +559,6 @@ func TestVRFv2Plus(t *testing.T) { "Active subscription ids should not contain sub id after sub cancellation", ) }) - t.Run("Owner Withdraw", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) subIDsForWithdraw, err := vrfv2plus.CreateFundSubsAndAddConsumers( @@ -567,7 +569,6 @@ func TestVRFv2Plus(t *testing.T) { vrfv2PlusContracts.CoordinatorV2Plus, vrfv2PlusContracts.VRFV2PlusConsumer, 1, - vrfv2plus_config.BillingType(*configCopy.GetVRFv2PlusConfig().General.SubscriptionBillingType), ) require.NoError(t, err) subIDForWithdraw := subIDsForWithdraw[0] @@ -678,7 +679,7 @@ func TestVRFv2PlusMultipleSendingKeys(t *testing.T) { require.NoError(t, err, "error deploying LINK contract") numberOfTxKeysToCreate := 2 - vrfv2PlusContracts, subIDs, vrfv2PlusData, _, err := vrfv2plus.SetupVRFV2_5Environment( + vrfv2PlusContracts, subIDs, vrfv2PlusData, nodesMap, err := vrfv2plus.SetupVRFV2_5Environment( env, []vrfcommon.VRFNodeType{vrfcommon.VRF}, &config, @@ -700,8 +701,8 @@ func TestVRFv2PlusMultipleSendingKeys(t *testing.T) { t.Run("Request Randomness with multiple sending keys", func(t *testing.T) { configCopy := config.MustCopy().(tc.TestConfig) - var isNativeBilling = false - txKeys, _, err := env.ClCluster.Nodes[0].API.ReadTxKeys("evm") + var isNativeBilling = true + txKeys, _, err := nodesMap[vrfcommon.VRF].CLNode.API.ReadTxKeys("evm") require.NoError(t, err, "error reading tx keys") require.Equal(t, numberOfTxKeysToCreate+1, len(txKeys.Data)) @@ -829,21 +830,21 @@ func TestVRFv2PlusMigration(t *testing.T) { require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) vrfJobSpecConfig := vrfcommon.VRFJobSpecConfig{ - ForwardingAllowed: false, + ForwardingAllowed: *vrfv2PlusConfig.VRFJobForwardingAllowed, CoordinatorAddress: newCoordinator.Address(), FromAddresses: nodesMap[vrfcommon.VRF].TXKeyAddressStrings, EVMChainID: env.EVMClient.GetChainID().String(), MinIncomingConfirmations: int(*vrfv2PlusConfig.MinimumConfirmations), PublicKey: vrfv2PlusData.VRFKey.Data.ID, - EstimateGasMultiplier: 1, - BatchFulfillmentEnabled: false, - BatchFulfillmentGasMultiplier: 1.15, - PollPeriod: time.Second * 1, - RequestTimeout: time.Hour * 24, + EstimateGasMultiplier: *vrfv2PlusConfig.VRFJobEstimateGasMultiplier, + BatchFulfillmentEnabled: *vrfv2PlusConfig.VRFJobBatchFulfillmentEnabled, + BatchFulfillmentGasMultiplier: *vrfv2PlusConfig.VRFJobBatchFulfillmentGasMultiplier, + PollPeriod: vrfv2PlusConfig.VRFJobPollPeriod.Duration, + RequestTimeout: vrfv2PlusConfig.VRFJobRequestTimeout.Duration, } _, err = vrfv2plus.CreateVRFV2PlusJob( - env.ClCluster.NodeAPIs()[0], + nodesMap[vrfcommon.VRF].CLNode.API, vrfJobSpecConfig, ) require.NoError(t, err, vrfv2plus.ErrCreateVRFV2PlusJobs) @@ -1000,23 +1001,25 @@ func TestVRFV2PlusWithBHS(t *testing.T) { mockETHLinkFeed, numberOfTxKeysToCreate, 1, - 1, + 2, l, ) require.NoError(t, err, "error setting up VRF v2_5 env") - subID := subIDs[0] - - subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) - require.NoError(t, err, "error getting subscription information") - - vrfv2plus.LogSubDetails(l, subscription, subID, vrfContracts.CoordinatorV2Plus) - var isNativeBilling = false + var isNativeBilling = true t.Run("BHS Job with complete E2E - wait 256 blocks to see if Rand Request is fulfilled", func(t *testing.T) { t.Skip("Skipped since should be run on-demand on live testnet due to long execution time") + + subID := subIDs[0] + + subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + + vrfv2plus.LogSubDetails(l, subscription, subID, vrfContracts.CoordinatorV2Plus) + //BHS node should fill in blockhashes into BHS contract depending on the waitBlocks and lookBackBlocks settings configCopy := config.MustCopy().(tc.TestConfig) - _, err := vrfContracts.VRFV2PlusConsumer[0].RequestRandomness( + _, err = vrfContracts.VRFV2PlusConsumer[0].RequestRandomness( vrfKeyData.KeyHash, subID, *configCopy.VRFv2Plus.General.MinimumConfirmations, @@ -1049,7 +1052,6 @@ func TestVRFV2PlusWithBHS(t *testing.T) { linkToken, vrfContracts.CoordinatorV2Plus, subIDs, - vrfv2plus_config.BillingType_Link, ) require.NoError(t, err, "error funding subscriptions") randomWordsFulfilledEvent, err := vrfContracts.CoordinatorV2Plus.WaitForRandomWordsFulfilledEvent( @@ -1063,12 +1065,28 @@ func TestVRFV2PlusWithBHS(t *testing.T) { require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) l.Debug().Bool("Fulfilment Status", status.Fulfilled).Msg("Random Words Request Fulfilment Status") + + randRequestBlockHash, err := vrfContracts.BHS.GetBlockHash(testcontext.Get(t), big.NewInt(int64(randRequestBlockNumber))) + require.NoError(t, err, "error getting blockhash for a blocknumber which was stored in BHS contract") + + l.Info(). + Str("Randomness Request's Blockhash", randomWordsRequestedEvent.Raw.BlockHash.String()). + Str("Block Hash stored by BHS contract", fmt.Sprintf("0x%x", randRequestBlockHash)). + Msg("BHS Contract's stored Blockhash for Randomness Request") + require.Equal(t, 0, randomWordsRequestedEvent.Raw.BlockHash.Cmp(randRequestBlockHash)) }) t.Run("BHS Job should fill in blockhashes into BHS contract for unfulfilled requests", func(t *testing.T) { + subID := subIDs[1] + + subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) + require.NoError(t, err, "error getting subscription information") + + vrfv2plus.LogSubDetails(l, subscription, subID, vrfContracts.CoordinatorV2Plus) + //BHS node should fill in blockhashes into BHS contract depending on the waitBlocks and lookBackBlocks settings configCopy := config.MustCopy().(tc.TestConfig) - _, err := vrfContracts.VRFV2PlusConsumer[0].RequestRandomness( + _, err = vrfContracts.VRFV2PlusConsumer[0].RequestRandomness( vrfKeyData.KeyHash, subID, *configCopy.VRFv2Plus.General.MinimumConfirmations, @@ -1099,9 +1117,6 @@ func TestVRFV2PlusWithBHS(t *testing.T) { err = env.EVMClient.WaitForEvents() require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - metrics, err := vrfContracts.VRFV2PlusConsumer[0].GetLoadTestMetrics(testcontext.Get(t)) - require.Equal(t, 0, metrics.RequestCount.Cmp(big.NewInt(1))) - require.Equal(t, 0, metrics.FulfilmentCount.Cmp(big.NewInt(0))) var clNodeTxs *client.TransactionsData var txHash string @@ -1196,9 +1211,9 @@ func TestVRFv2PlusPendingBlockSimulationAndZeroConfirmationDelays(t *testing.T) vrfv2plus.LogSubDetails(l, subscription, subID, vrfv2PlusContracts.CoordinatorV2Plus) - var isNativeBilling = false + var isNativeBilling = true - jobRunsBeforeTest, err := env.ClCluster.Nodes[0].API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) + jobRunsBeforeTest, err := nodesMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) require.NoError(t, err, "error reading job runs") l.Info().Uint16("minimumConfirmationDelay", *config.VRFv2Plus.General.MinimumConfirmations).Msg("Minimum Confirmation Delay") @@ -1220,7 +1235,7 @@ func TestVRFv2PlusPendingBlockSimulationAndZeroConfirmationDelays(t *testing.T) ) require.NoError(t, err, "error requesting randomness and waiting for fulfilment") - jobRuns, err := env.ClCluster.Nodes[0].API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) + jobRuns, err := nodesMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodesMap[vrfcommon.VRF].Job.Data.ID) require.NoError(t, err, "error reading job runs") require.Equal(t, len(jobRunsBeforeTest.Data)+1, len(jobRuns.Data)) diff --git a/integration-tests/testconfig/common/vrf/common.go b/integration-tests/testconfig/common/vrf/common.go new file mode 100644 index 00000000000..ca6f44f27c0 --- /dev/null +++ b/integration-tests/testconfig/common/vrf/common.go @@ -0,0 +1,277 @@ +package vrf + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/pkg/errors" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" +) + +type Config struct { + General *General `toml:"General"` + ExistingEnvConfig *ExistingEnvConfig `toml:"ExistingEnv"` + Performance *PerformanceConfig `toml:"Performance"` +} + +const ( + ErrDeviationShouldBeLessThanOriginal = "`RandomnessRequestCountPerRequestDeviation` should be less than `RandomnessRequestCountPerRequest`" +) + +func (c *Config) Validate() error { + if c.General != nil { + if err := c.General.Validate(); err != nil { + return err + } + } + if c.ExistingEnvConfig != nil { + if err := c.ExistingEnvConfig.Validate(); err != nil { + return err + } + } + if c.Performance != nil { + if err := c.Performance.Validate(); err != nil { + return err + } + } + return nil +} + +type PerformanceConfig struct { + TestDuration *blockchain.StrDuration `toml:"test_duration"` + RPS *int64 `toml:"rps"` + RateLimitUnitDuration *blockchain.StrDuration `toml:"rate_limit_unit_duration"` +} + +func (c *PerformanceConfig) Validate() error { + if c.TestDuration == nil || c.TestDuration.Duration == 0 { + return errors.New("test_duration must be set to a positive value") + } + if c.RPS == nil || *c.RPS == 0 { + return errors.New("rps must be set to a positive value") + } + if c.RateLimitUnitDuration == nil { + return errors.New("rate_limit_unit_duration must be set ") + } + + return nil +} + +type ExistingEnvConfig struct { + CoordinatorAddress *string `toml:"coordinator_address"` + ConsumerAddress *string `toml:"consumer_address"` + LinkAddress *string `toml:"link_address"` + KeyHash *string `toml:"key_hash"` + CreateFundSubsAndAddConsumers *bool `toml:"create_fund_subs_and_add_consumers"` + NodeSendingKeys []string `toml:"node_sending_keys"` + Funding +} + +func (c *ExistingEnvConfig) Validate() error { + if c.CreateFundSubsAndAddConsumers == nil { + return errors.New("create_fund_subs_and_add_consumers must be set ") + } + if c.CoordinatorAddress == nil { + return errors.New("coordinator_address must be set when using existing environment") + } + if !common.IsHexAddress(*c.CoordinatorAddress) { + return errors.New("coordinator_address must be a valid hex address") + } + if c.KeyHash == nil { + return errors.New("key_hash must be set when using existing environment") + } + if *c.KeyHash == "" { + return errors.New("key_hash must be a non-empty string") + } + if *c.CreateFundSubsAndAddConsumers { + if err := c.Funding.Validate(); err != nil { + return err + } + } else { + if c.ConsumerAddress == nil || *c.ConsumerAddress == "" { + return errors.New("consumer_address must be set when using existing environment") + } + if !common.IsHexAddress(*c.ConsumerAddress) { + return errors.New("consumer_address must be a valid hex address") + } + } + + if c.NodeSendingKeys != nil { + for _, key := range c.NodeSendingKeys { + if !common.IsHexAddress(key) { + return errors.New("node_sending_keys must be a valid hex address") + } + } + } + + return nil +} + +type Funding struct { + NodeSendingKeyFundingMin *float64 `toml:"node_sending_key_funding_min"` +} + +func (c *Funding) Validate() error { + if c.NodeSendingKeyFundingMin != nil && *c.NodeSendingKeyFundingMin <= 0 { + return errors.New("when set node_sending_key_funding_min must be a positive value") + } + + return nil +} + +type General struct { + UseExistingEnv *bool `toml:"use_existing_env"` + CancelSubsAfterTestRun *bool `toml:"cancel_subs_after_test_run"` + CLNodeMaxGasPriceGWei *int64 `toml:"cl_node_max_gas_price_gwei"` // Max gas price in GWei for the chainlink node + LinkNativeFeedResponse *int64 `toml:"link_native_feed_response"` // Response of the LINK/ETH feed + MinimumConfirmations *uint16 `toml:"minimum_confirmations"` // Minimum number of confirmations for the VRF Coordinator + SubscriptionFundingAmountLink *float64 `toml:"subscription_funding_amount_link"` // Amount of LINK to fund the subscription with + NumberOfWords *uint32 `toml:"number_of_words"` // Number of words to request + CallbackGasLimit *uint32 `toml:"callback_gas_limit"` // Gas limit for the callback + MaxGasLimitCoordinatorConfig *uint32 `toml:"max_gas_limit_coordinator_config"` // Max gas limit for the VRF Coordinator config + FallbackWeiPerUnitLink *int64 `toml:"fallback_wei_per_unit_link"` // Fallback wei per unit LINK for the VRF Coordinator config + StalenessSeconds *uint32 `toml:"staleness_seconds"` // Staleness in seconds for the VRF Coordinator config + GasAfterPaymentCalculation *uint32 `toml:"gas_after_payment_calculation"` // Gas after payment calculation for the VRF Coordinator + + NumberOfSubToCreate *int `toml:"number_of_sub_to_create"` // Number of subscriptions to create + + RandomnessRequestCountPerRequest *uint16 `toml:"randomness_request_count_per_request"` // How many randomness requests to send per request + RandomnessRequestCountPerRequestDeviation *uint16 `toml:"randomness_request_count_per_request_deviation"` // How many randomness requests to send per request + + RandomWordsFulfilledEventTimeout *blockchain.StrDuration `toml:"random_words_fulfilled_event_timeout"` // How long to wait for the RandomWordsFulfilled event to be emitted + + // Wrapper Config + WrapperGasOverhead *uint32 `toml:"wrapped_gas_overhead"` + CoordinatorGasOverhead *uint32 `toml:"coordinator_gas_overhead"` + WrapperPremiumPercentage *uint8 `toml:"wrapper_premium_percentage"` + WrapperMaxNumberOfWords *uint8 `toml:"wrapper_max_number_of_words"` + WrapperConsumerFundingAmountNativeToken *float64 `toml:"wrapper_consumer_funding_amount_native_token"` + WrapperConsumerFundingAmountLink *int64 `toml:"wrapper_consumer_funding_amount_link"` + + //VRF Job Config + VRFJobForwardingAllowed *bool `toml:"vrf_job_forwarding_allowed"` + VRFJobEstimateGasMultiplier *float64 `toml:"vrf_job_estimate_gas_multiplier"` + VRFJobBatchFulfillmentEnabled *bool `toml:"vrf_job_batch_fulfillment_enabled"` + VRFJobBatchFulfillmentGasMultiplier *float64 `toml:"vrf_job_batch_fulfillment_gas_multiplier"` + VRFJobPollPeriod *blockchain.StrDuration `toml:"vrf_job_poll_period"` + VRFJobRequestTimeout *blockchain.StrDuration `toml:"vrf_job_request_timeout"` + VRFJobSimulationBlock *string `toml:"vrf_job_simulation_block"` + + //BHS Job Config + BHSJobWaitBlocks *int `toml:"bhs_job_wait_blocks"` + BHSJobLookBackBlocks *int `toml:"bhs_job_lookback_blocks"` + BHSJobPollPeriod *blockchain.StrDuration `toml:"bhs_job_poll_period"` + BHSJobRunTimeout *blockchain.StrDuration `toml:"bhs_job_run_timeout"` +} + +func (c *General) Validate() error { + if c.UseExistingEnv == nil { + return errors.New("use_existing_env must not be nil") + } + if c.CLNodeMaxGasPriceGWei == nil || *c.CLNodeMaxGasPriceGWei == 0 { + return errors.New("max_gas_price_gwei must be set to a positive value") + } + if c.LinkNativeFeedResponse == nil || *c.LinkNativeFeedResponse == 0 { + return errors.New("link_native_feed_response must be set to a positive value") + } + if c.MinimumConfirmations == nil { + return errors.New("minimum_confirmations must be set to a non-negative value") + } + if c.SubscriptionFundingAmountLink == nil || *c.SubscriptionFundingAmountLink < 0 { + return errors.New("subscription_funding_amount_link must be set to non-negative value") + } + if c.NumberOfWords == nil || *c.NumberOfWords == 0 { + return errors.New("number_of_words must be set to a positive value") + } + if c.CallbackGasLimit == nil || *c.CallbackGasLimit == 0 { + return errors.New("callback_gas_limit must be set to a positive value") + } + if c.MaxGasLimitCoordinatorConfig == nil || *c.MaxGasLimitCoordinatorConfig == 0 { + return errors.New("max_gas_limit_coordinator_config must be set to a positive value") + } + if c.FallbackWeiPerUnitLink == nil || *c.FallbackWeiPerUnitLink == 0 { + return errors.New("fallback_wei_per_unit_link must be set to a positive value") + } + if c.StalenessSeconds == nil || *c.StalenessSeconds == 0 { + return errors.New("staleness_seconds must be set to a positive value") + } + if c.GasAfterPaymentCalculation == nil || *c.GasAfterPaymentCalculation == 0 { + return errors.New("gas_after_payment_calculation must be set to a positive value") + } + if c.NumberOfSubToCreate == nil || *c.NumberOfSubToCreate == 0 { + return errors.New("number_of_sub_to_create must be set to a positive value") + } + if c.RandomnessRequestCountPerRequest == nil || *c.RandomnessRequestCountPerRequest == 0 { + return errors.New("randomness_request_count_per_request must be set to a positive value") + } + if c.RandomnessRequestCountPerRequestDeviation == nil { + return errors.New("randomness_request_count_per_request_deviation must be set to a non-negative value") + } + if c.RandomWordsFulfilledEventTimeout == nil || c.RandomWordsFulfilledEventTimeout.Duration == 0 { + return errors.New("random_words_fulfilled_event_timeout must be set to a positive value") + } + if c.WrapperGasOverhead == nil { + return errors.New("wrapped_gas_overhead must be set to a non-negative value") + } + if c.CoordinatorGasOverhead == nil || *c.CoordinatorGasOverhead == 0 { + return errors.New("coordinator_gas_overhead must be set to a non-negative value") + } + if c.WrapperPremiumPercentage == nil || *c.WrapperPremiumPercentage == 0 { + return errors.New("wrapper_premium_percentage must be set to a positive value") + } + if c.WrapperMaxNumberOfWords == nil || *c.WrapperMaxNumberOfWords == 0 { + return errors.New("wrapper_max_number_of_words must be set to a positive value") + } + if c.WrapperConsumerFundingAmountNativeToken == nil || *c.WrapperConsumerFundingAmountNativeToken < 0 { + return errors.New("wrapper_consumer_funding_amount_native_token must be set to a non-negative value") + } + if c.WrapperConsumerFundingAmountLink == nil || *c.WrapperConsumerFundingAmountLink < 0 { + return errors.New("wrapper_consumer_funding_amount_link must be set to a non-negative value") + } + if *c.RandomnessRequestCountPerRequest <= *c.RandomnessRequestCountPerRequestDeviation { + return errors.New(ErrDeviationShouldBeLessThanOriginal) + } + + if c.VRFJobForwardingAllowed == nil { + return errors.New("vrf_job_forwarding_allowed must be set") + } + + if c.VRFJobBatchFulfillmentEnabled == nil { + return errors.New("vrf_job_batch_fulfillment_enabled must be set") + } + if c.VRFJobEstimateGasMultiplier == nil || *c.VRFJobEstimateGasMultiplier < 0 { + return errors.New("vrf_job_estimate_gas_multiplier must be set to a non-negative value") + } + if c.VRFJobBatchFulfillmentGasMultiplier == nil || *c.VRFJobBatchFulfillmentGasMultiplier < 0 { + return errors.New("vrf_job_batch_fulfillment_gas_multiplier must be set to a non-negative value") + } + + if c.VRFJobPollPeriod == nil || c.VRFJobPollPeriod.Duration == 0 { + return errors.New("vrf_job_poll_period must be set to a non-negative value") + } + + if c.VRFJobRequestTimeout == nil || c.VRFJobRequestTimeout.Duration == 0 { + return errors.New("vrf_job_request_timeout must be set to a non-negative value") + } + + if c.VRFJobSimulationBlock != nil && (*c.VRFJobSimulationBlock != "latest" && *c.VRFJobSimulationBlock != "pending") { + return errors.New("simulation_block must be nil or \"latest\" or \"pending\"") + } + + if c.BHSJobLookBackBlocks == nil || *c.BHSJobLookBackBlocks < 0 { + return errors.New("bhs_job_lookback_blocks must be set to a non-negative value") + } + + if c.BHSJobPollPeriod == nil || c.BHSJobPollPeriod.Duration == 0 { + return errors.New("bhs_job_poll_period must be set to a non-negative value") + } + + if c.BHSJobRunTimeout == nil || c.BHSJobRunTimeout.Duration == 0 { + return errors.New("bhs_job_run_timeout must be set to a non-negative value") + } + + if c.BHSJobWaitBlocks == nil || *c.BHSJobWaitBlocks < 0 { + return errors.New("bhs_job_wait_blocks must be set to a non-negative value") + } + + return nil +} diff --git a/integration-tests/testconfig/vrfv2/config.go b/integration-tests/testconfig/vrfv2/config.go index c9037b59085..dcfd959880b 100644 --- a/integration-tests/testconfig/vrfv2/config.go +++ b/integration-tests/testconfig/vrfv2/config.go @@ -5,27 +5,16 @@ import ( "github.com/ethereum/go-ethereum/common" - "github.com/smartcontractkit/chainlink-testing-framework/blockchain" -) - -const ( - ErrDeviationShouldBeLessThanOriginal = "`RandomnessRequestCountPerRequestDeviation` should be less than `RandomnessRequestCountPerRequest`" + vrf_common_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/common/vrf" ) type Config struct { - Common *Common `toml:"Common"` - General *General `toml:"General"` - ExistingEnvConfig *ExistingEnvConfig `toml:"ExistingEnv"` - NewEnvConfig *NewEnvConfig `toml:"NewEnv"` - Performance *PerformanceConfig `toml:"Performance"` + General *General `toml:"General"` + ExistingEnvConfig *ExistingEnvConfig `toml:"ExistingEnv"` + Performance *vrf_common_config.PerformanceConfig `toml:"Performance"` } func (c *Config) Validate() error { - if c.Common != nil { - if err := c.Common.Validate(); err != nil { - return err - } - } if c.General != nil { if err := c.General.Validate(); err != nil { return err @@ -35,250 +24,61 @@ func (c *Config) Validate() error { if err := c.Performance.Validate(); err != nil { return err } - if *c.Performance.UseExistingEnv { - if c.ExistingEnvConfig != nil { - if err := c.ExistingEnvConfig.Validate(); err != nil { - return err - } - } - } else { - if c.NewEnvConfig != nil { - if err := c.NewEnvConfig.Validate(); err != nil { - return err - } - } - } - } - - return nil -} - -type Common struct { - CancelSubsAfterTestRun *bool `toml:"cancel_subs_after_test_run"` -} - -func (c *Common) Validate() error { - return nil -} - -type PerformanceConfig struct { - TestDuration *blockchain.StrDuration `toml:"test_duration"` - RPS *int64 `toml:"rps"` - RateLimitUnitDuration *blockchain.StrDuration `toml:"rate_limit_unit_duration"` - - // Using existing environment and contracts - UseExistingEnv *bool `toml:"use_existing_env"` - CoordinatorAddress *string - ConsumerAddress *string - LinkAddress *string - SubID *uint64 - KeyHash *string -} - -func (c *PerformanceConfig) Validate() error { - if c.TestDuration == nil || c.TestDuration.Duration == 0 { - return errors.New("test_duration must be set to a positive value") - } - if c.RPS == nil || *c.RPS == 0 { - return errors.New("rps must be set to a positive value") - } - if c.RateLimitUnitDuration == nil { - return errors.New("rate_limit_unit_duration must be set ") } - if c.UseExistingEnv == nil { - return errors.New("use_existing_env must be set ") + if c.ExistingEnvConfig != nil && *c.General.UseExistingEnv { + if err := c.ExistingEnvConfig.Validate(); err != nil { + return err + } } - return nil } type ExistingEnvConfig struct { - CoordinatorAddress *string `toml:"coordinator_address"` - ConsumerAddress *string `toml:"consumer_address"` - LinkAddress *string `toml:"link_address"` - SubID *uint64 `toml:"sub_id"` - KeyHash *string `toml:"key_hash"` - CreateFundSubsAndAddConsumers *bool `toml:"create_fund_subs_and_add_consumers"` - NodeSendingKeys []string `toml:"node_sending_keys"` - Funding + *vrf_common_config.ExistingEnvConfig + SubID *uint64 `toml:"sub_id"` } func (c *ExistingEnvConfig) Validate() error { - if c.CreateFundSubsAndAddConsumers == nil { - return errors.New("create_fund_subs_and_add_consumers must be set ") - } - if c.CoordinatorAddress == nil { - return errors.New("coordinator_address must be set when using existing environment") - } - if !common.IsHexAddress(*c.CoordinatorAddress) { - return errors.New("coordinator_address must be a valid hex address") - } - if c.KeyHash == nil { - return errors.New("key_hash must be set when using existing environment") - } - if *c.KeyHash == "" { - return errors.New("key_hash must be a non-empty string") - } - if c.LinkAddress != nil && !common.IsHexAddress(*c.LinkAddress) { - return errors.New("link_address must be a valid hex address") - } - - if *c.CreateFundSubsAndAddConsumers { - if err := c.Funding.Validate(); err != nil { + if c.ExistingEnvConfig != nil { + if err := c.ExistingEnvConfig.Validate(); err != nil { return err } - if err := c.Funding.SubFunding.Validate(); err != nil { - return err - } - } else { - if c.ConsumerAddress == nil || *c.ConsumerAddress == "" { - return errors.New("consumer_address must be set when using existing environment") - } - if !common.IsHexAddress(*c.ConsumerAddress) { - return errors.New("consumer_address must be a valid hex address") - } + } + if !*c.CreateFundSubsAndAddConsumers { if c.SubID == nil { return errors.New("sub_id must be set when using existing environment") } + if *c.SubID == 0 { - return errors.New("sub_id must be a positive value") + return errors.New("sub_id must be positive value") } - } - if c.NodeSendingKeys != nil { - for _, key := range c.NodeSendingKeys { - if !common.IsHexAddress(key) { - return errors.New("node_sending_keys must be a valid hex address") - } + if c.LinkAddress != nil && !common.IsHexAddress(*c.LinkAddress) { + return errors.New("link_address must be a valid hex address") } } - return nil -} - -type NewEnvConfig struct { - *Funding -} - -func (c *NewEnvConfig) Validate() error { - if c.Funding != nil { - return c.Funding.Validate() - } - - return nil -} - -type Funding struct { - SubFunding - NodeSendingKeyFunding *float64 `toml:"node_sending_key_funding"` - NodeSendingKeyFundingMin *float64 `toml:"node_sending_key_funding_min"` -} - -func (c *Funding) Validate() error { - if c.NodeSendingKeyFunding != nil && *c.NodeSendingKeyFunding <= 0 { - return errors.New("when set node_sending_key_funding must be a positive value") - } - if c.NodeSendingKeyFundingMin != nil && *c.NodeSendingKeyFundingMin <= 0 { - return errors.New("when set node_sending_key_funding_min must be a positive value") - } - - return nil -} - -type SubFunding struct { - SubFundsLink *float64 `toml:"sub_funds_link"` -} - -func (c *SubFunding) Validate() error { - if c.SubFundsLink != nil && *c.SubFundsLink < 0 { - return errors.New("when set sub_funds_link must be a non-negative value") - } - - return nil + return c.Funding.Validate() } type General struct { - CLNodeMaxGasPriceGWei *int64 `toml:"cl_node_max_gas_price_gwei"` // Max gas price in GWei for the chainlink node - LinkNativeFeedResponse *int64 `toml:"link_native_feed_response"` // Response of the LINK/ETH feed - MinimumConfirmations *uint16 `toml:"minimum_confirmations" ` // Minimum number of confirmations for the VRF Coordinator - SubscriptionFundingAmountLink *float64 `toml:"subscription_funding_amount_link"` // Amount of LINK to fund the subscription with - NumberOfWords *uint32 `toml:"number_of_words" ` // Number of words to request - CallbackGasLimit *uint32 `toml:"callback_gas_limit" ` // Gas limit for the callback - MaxGasLimitCoordinatorConfig *uint32 `toml:"max_gas_limit_coordinator_config"` // Max gas limit for the VRF Coordinator config - FallbackWeiPerUnitLink *int64 `toml:"fallback_wei_per_unit_link"` // Fallback wei per unit LINK for the VRF Coordinator config - StalenessSeconds *uint32 `toml:"staleness_seconds" ` // Staleness in seconds for the VRF Coordinator config - GasAfterPaymentCalculation *uint32 `toml:"gas_after_payment_calculation" ` // Gas after payment calculation for the VRF Coordinator - FulfillmentFlatFeeLinkPPMTier1 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_1"` - FulfillmentFlatFeeLinkPPMTier2 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_2"` - FulfillmentFlatFeeLinkPPMTier3 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_3"` - FulfillmentFlatFeeLinkPPMTier4 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_4"` - FulfillmentFlatFeeLinkPPMTier5 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_5"` - ReqsForTier2 *int64 `toml:"reqs_for_tier_2"` - ReqsForTier3 *int64 `toml:"reqs_for_tier_3"` - ReqsForTier4 *int64 `toml:"reqs_for_tier_4"` - ReqsForTier5 *int64 `toml:"reqs_for_tier_5"` - - NumberOfSubToCreate *int `toml:"number_of_sub_to_create"` // Number of subscriptions to create - - RandomnessRequestCountPerRequest *uint16 `toml:"randomness_request_count_per_request"` // How many randomness requests to send per request - RandomnessRequestCountPerRequestDeviation *uint16 `toml:"randomness_request_count_per_request_deviation"` // How many randomness requests to send per request - - RandomWordsFulfilledEventTimeout *blockchain.StrDuration `toml:"random_words_fulfilled_event_timeout"` // How long to wait for the RandomWordsFulfilled event to be emitted - - // Wrapper Config - WrapperGasOverhead *uint32 `toml:"wrapped_gas_overhead"` - CoordinatorGasOverhead *uint32 `toml:"coordinator_gas_overhead"` - WrapperPremiumPercentage *uint8 `toml:"wrapper_premium_percentage"` - WrapperMaxNumberOfWords *uint8 `toml:"wrapper_max_number_of_words"` - WrapperConsumerFundingAmountNativeToken *float64 `toml:"wrapper_consumer_funding_amount_native_token"` - WrapperConsumerFundingAmountLink *int64 `toml:"wrapper_consumer_funding_amount_link"` - - //VRF Job Config - VRFJobForwardingAllowed *bool `toml:"vrf_job_forwarding_allowed"` - VRFJobEstimateGasMultiplier *float64 `toml:"vrf_job_estimate_gas_multiplier"` - VRFJobBatchFulfillmentEnabled *bool `toml:"vrf_job_batch_fulfillment_enabled"` - VRFJobBatchFulfillmentGasMultiplier *float64 `toml:"vrf_job_batch_fulfillment_gas_multiplier"` - VRFJobPollPeriod *blockchain.StrDuration `toml:"vrf_job_poll_period"` - VRFJobRequestTimeout *blockchain.StrDuration `toml:"vrf_job_request_timeout"` - VRFJobSimulationBlock *string `toml:"vrf_job_simulation_block"` - - //BHS Job Config - BHSJobWaitBlocks *int `toml:"bhs_job_wait_blocks"` - BHSJobLookBackBlocks *int `toml:"bhs_job_lookback_blocks"` - BHSJobPollPeriod *blockchain.StrDuration `toml:"bhs_job_poll_period"` - BHSJobRunTimeout *blockchain.StrDuration `toml:"bhs_job_run_timeout"` + *vrf_common_config.General + FulfillmentFlatFeeLinkPPMTier1 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_1"` + FulfillmentFlatFeeLinkPPMTier2 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_2"` + FulfillmentFlatFeeLinkPPMTier3 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_3"` + FulfillmentFlatFeeLinkPPMTier4 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_4"` + FulfillmentFlatFeeLinkPPMTier5 *uint32 `toml:"fulfilment_flat_fee_link_ppm_tier_5"` + ReqsForTier2 *int64 `toml:"reqs_for_tier_2"` + ReqsForTier3 *int64 `toml:"reqs_for_tier_3"` + ReqsForTier4 *int64 `toml:"reqs_for_tier_4"` + ReqsForTier5 *int64 `toml:"reqs_for_tier_5"` } func (c *General) Validate() error { - if c.CLNodeMaxGasPriceGWei == nil || *c.CLNodeMaxGasPriceGWei == 0 { - return errors.New("max_gas_price_gwei must be set to a positive value") - } - if c.LinkNativeFeedResponse == nil || *c.LinkNativeFeedResponse == 0 { - return errors.New("link_native_feed_response must be set to a positive value") - } - if c.MinimumConfirmations == nil { - return errors.New("minimum_confirmations must be set to a non-negative value") - } - if c.SubscriptionFundingAmountLink == nil || *c.SubscriptionFundingAmountLink == 0 { - return errors.New("subscription_funding_amount_link must be set to a positive value") - } - if c.NumberOfWords == nil || *c.NumberOfWords == 0 { - return errors.New("number_of_words must be set to a positive value") - } - if c.CallbackGasLimit == nil || *c.CallbackGasLimit == 0 { - return errors.New("callback_gas_limit must be set to a positive value") - } - if c.MaxGasLimitCoordinatorConfig == nil || *c.MaxGasLimitCoordinatorConfig == 0 { - return errors.New("max_gas_limit_coordinator_config must be set to a positive value") - } - if c.FallbackWeiPerUnitLink == nil || *c.FallbackWeiPerUnitLink == 0 { - return errors.New("fallback_wei_per_unit_link must be set to a positive value") - } - if c.StalenessSeconds == nil || *c.StalenessSeconds == 0 { - return errors.New("staleness_seconds must be set to a positive value") - } - if c.GasAfterPaymentCalculation == nil || *c.GasAfterPaymentCalculation == 0 { - return errors.New("gas_after_payment_calculation must be set to a positive value") + if c.General != nil { + if err := c.General.Validate(); err != nil { + return err + } } if c.FulfillmentFlatFeeLinkPPMTier1 == nil || *c.FulfillmentFlatFeeLinkPPMTier1 == 0 { return errors.New("fulfilment_flat_fee_link_ppm_tier_1 must be set to a positive value") @@ -307,81 +107,6 @@ func (c *General) Validate() error { if c.ReqsForTier5 == nil || *c.ReqsForTier5 < 0 { return errors.New("reqs_for_tier_5 must be set to a non-negative value") } - if c.NumberOfSubToCreate == nil || *c.NumberOfSubToCreate == 0 { - return errors.New("number_of_sub_to_create must be set to a positive value") - } - if c.RandomnessRequestCountPerRequest == nil || *c.RandomnessRequestCountPerRequest == 0 { - return errors.New("randomness_request_count_per_request must be set to a positive value") - } - if c.RandomnessRequestCountPerRequestDeviation == nil { - return errors.New("randomness_request_count_per_request_deviation must be set to a non-negative value") - } - if c.RandomWordsFulfilledEventTimeout == nil || c.RandomWordsFulfilledEventTimeout.Duration == 0 { - return errors.New("random_words_fulfilled_event_timeout must be set to a positive value") - } - if c.WrapperGasOverhead == nil { - return errors.New("wrapped_gas_overhead must be set to a non-negative value") - } - if c.CoordinatorGasOverhead == nil || *c.CoordinatorGasOverhead == 0 { - return errors.New("coordinator_gas_overhead must be set to a non-negative value") - } - if c.WrapperPremiumPercentage == nil || *c.WrapperPremiumPercentage == 0 { - return errors.New("wrapper_premium_percentage must be set to a positive value") - } - if c.WrapperMaxNumberOfWords == nil || *c.WrapperMaxNumberOfWords == 0 { - return errors.New("wrapper_max_number_of_words must be set to a positive value") - } - if c.WrapperConsumerFundingAmountNativeToken == nil || *c.WrapperConsumerFundingAmountNativeToken < 0 { - return errors.New("wrapper_consumer_funding_amount_native_token must be set to a non-negative value") - } - if c.WrapperConsumerFundingAmountLink == nil || *c.WrapperConsumerFundingAmountLink < 0 { - return errors.New("wrapper_consumer_funding_amount_link must be set to a non-negative value") - } - if *c.RandomnessRequestCountPerRequest <= *c.RandomnessRequestCountPerRequestDeviation { - return errors.New(ErrDeviationShouldBeLessThanOriginal) - } - - if c.VRFJobForwardingAllowed == nil { - return errors.New("vrf_job_forwarding_allowed must be set") - } - - if c.VRFJobBatchFulfillmentEnabled == nil { - return errors.New("vrf_job_batch_fulfillment_enabled must be set") - } - if c.VRFJobEstimateGasMultiplier == nil || *c.VRFJobEstimateGasMultiplier < 0 { - return errors.New("vrf_job_estimate_gas_multiplier must be set to a non-negative value") - } - if c.VRFJobBatchFulfillmentGasMultiplier == nil || *c.VRFJobBatchFulfillmentGasMultiplier < 0 { - return errors.New("vrf_job_batch_fulfillment_gas_multiplier must be set to a non-negative value") - } - - if c.VRFJobPollPeriod == nil || c.VRFJobPollPeriod.Duration == 0 { - return errors.New("vrf_job_poll_period must be set to a non-negative value") - } - - if c.VRFJobRequestTimeout == nil || c.VRFJobRequestTimeout.Duration == 0 { - return errors.New("vrf_job_request_timeout must be set to a non-negative value") - } - - if c.BHSJobLookBackBlocks == nil || *c.BHSJobLookBackBlocks < 0 { - return errors.New("bhs_job_lookback_blocks must be set to a non-negative value") - } - - if c.BHSJobPollPeriod == nil || c.BHSJobPollPeriod.Duration == 0 { - return errors.New("bhs_job_poll_period must be set to a non-negative value") - } - - if c.BHSJobRunTimeout == nil || c.BHSJobRunTimeout.Duration == 0 { - return errors.New("bhs_job_run_timeout must be set to a non-negative value") - } - - if c.BHSJobWaitBlocks == nil || *c.BHSJobWaitBlocks < 0 { - return errors.New("bhs_job_wait_blocks must be set to a non-negative value") - } - - if c.VRFJobSimulationBlock != nil && (*c.VRFJobSimulationBlock != "latest" && *c.VRFJobSimulationBlock != "pending") { - return errors.New("simulation_block must be nil or \"latest\" or \"pending\"") - } return nil } diff --git a/integration-tests/testconfig/vrfv2/example.toml b/integration-tests/testconfig/vrfv2/example.toml index bc826ebe05e..651749486fd 100644 --- a/integration-tests/testconfig/vrfv2/example.toml +++ b/integration-tests/testconfig/vrfv2/example.toml @@ -75,10 +75,8 @@ chainlink_node_funding = 0.5 # Product part [VRFv2] -[VRFv2.Common] -cancel_subs_after_test_run = true - [VRFv2.General] +cancel_subs_after_test_run = true max_gas_price_gwei = 1000 link_native_feed_response = 1000000000000000000 minimum_confirmations = 3 diff --git a/integration-tests/testconfig/vrfv2/vrfv2.toml b/integration-tests/testconfig/vrfv2/vrfv2.toml index a4f4536208a..3ce3135b3aa 100644 --- a/integration-tests/testconfig/vrfv2/vrfv2.toml +++ b/integration-tests/testconfig/vrfv2/vrfv2.toml @@ -4,10 +4,14 @@ chainlink_node_funding = 0.1 [VRFv2] [VRFv2.General] +cancel_subs_after_test_run = true +use_existing_env = false +subscription_funding_amount_link = 5.0 + cl_node_max_gas_price_gwei = 10 link_native_feed_response = 1000000000000000000 minimum_confirmations = 3 -subscription_funding_amount_link = 5.0 + number_of_words = 3 callback_gas_limit = 1000000 max_gas_limit_coordinator_config = 2500000 @@ -48,110 +52,65 @@ bhs_job_lookback_blocks = 250 bhs_job_poll_period = "1s" bhs_job_run_timeout = "24h" -# load test specific config -[Load.VRFv2] -[Load.VRFv2.Common] -cancel_subs_after_test_run = true - -[Load.VRFv2.General] -minimum_confirmations = 3 -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 - -[Load.VRFv2.Performance] -# approx 60 RPM - 1 tx request with 3 rand requests in each tx every 3 seconds -rate_limit_unit_duration = "3s" -rps = 1 -[Load.VRFv2.NewEnv] -sub_funds_link = 1000 -node_sending_key_funding = 1000 +# PERFORMANCE test specific config -[Load.VRFv2.ExistingEnv] +[VRFv2.ExistingEnv] +coordinator_address = "" +consumer_address = "" sub_id = 1 +key_hash = "" create_fund_subs_and_add_consumers = true -sub_funds_link = 10 -node_sending_key_funding_min = 1 -node_sending_keys = [] - -# soak test specific config -[Soak.VRFv2] -[VRFv2.Common] -cancel_subs_after_test_run = true +link_address = "" +node_sending_key_funding_min = 10 +node_sending_keys = [ + "", + "", + "" +] + +#SOAK TEST CONFIG +[Soak.Common] +chainlink_node_funding = 0.1 [Soak.VRFv2.General] -minimum_confirmations = 3 randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 +subscription_funding_amount_link = 5.0 [Soak.VRFv2.Performance] -# 10 RPM - 1 tx request with 1 rand request in each tx every 6 seconds -rate_limit_unit_duration = "6s" +test_duration = "1m" +rate_limit_unit_duration = "3s" rps = 1 -[Soak.VRFv2.NewEnv] -sub_funds_link = 1000 -node_sending_key_funding = 1000 - -[Soak.VRFv2.ExistingEnv] -sub_id = 1 -create_fund_subs_and_add_consumers = true -sub_funds_link = 10 -node_sending_key_funding_min = 1 -node_sending_keys = [] - -# spike test specific config -[Spike.VRFv2] -[Spike.VRFv2.Common] -cancel_subs_after_test_run = true +# LOAD TEST CONFIG +[Load.Common] +chainlink_node_funding = 0.1 -[Spike.VRFv2.General] -minimum_confirmations = 3 -randomness_request_count_per_request = 150 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +[Load.VRFv2.General] +randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 +subscription_funding_amount_link = 5.0 -[Spike.VRFv2.Performance] -# approx 150 RPM - 1 tx request with 150 rand requests in each tx every 60 seconds -rate_limit_unit_duration = "1m" +[Load.VRFv2.Performance] +test_duration = "2m" +rate_limit_unit_duration = "3s" rps = 1 -[Spike.VRFv2.NewEnv] -sub_funds_link = 1000 -node_sending_key_funding = 1000 - -[Spike.VRFv2.ExistingEnv] -sub_id = 1 -create_fund_subs_and_add_consumers = true -sub_funds_link = 10 -node_sending_key_funding_min = 1 -node_sending_keys = [] -# stress test specific config -[Stress.VRFv2] -[Stress.VRFv2.Common] -cancel_subs_after_test_run = true +# STRESS TEST CONFIG +[Stress.Common] +chainlink_node_funding = 0.1 [Stress.VRFv2.General] -minimum_confirmations = 3 -randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 +subscription_funding_amount_link = 5.0 [Stress.VRFv2.Performance] -# approx 540 RPM - 3 tx requests per second with 4 rand requests in each tx -rate_limit_unit_duration = "1s" -rps = 3 - -[Stress.VRFv2.NewEnv] -sub_funds_link = 1000 -node_sending_key_funding = 1000 - -[Stress.VRFv2.ExistingEnv] -sub_id = 1 -create_fund_subs_and_add_consumers = true -sub_funds_link = 10 -node_sending_key_funding_min = 1 -node_sending_keys = [] +test_duration = "2m" +rate_limit_unit_duration = "3s" +rps = 1 diff --git a/integration-tests/testconfig/vrfv2plus/config.go b/integration-tests/testconfig/vrfv2plus/config.go index b300b75dfc4..fe05dbd9d18 100644 --- a/integration-tests/testconfig/vrfv2plus/config.go +++ b/integration-tests/testconfig/vrfv2plus/config.go @@ -3,7 +3,7 @@ package testconfig import ( "errors" - vrfv2 "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2" + vrf_common_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/common/vrf" ) type BillingType string @@ -15,19 +15,12 @@ const ( ) type Config struct { - Common *Common `toml:"Common"` - General *General `toml:"General"` - ExistingEnvConfig *ExistingEnvConfig `toml:"ExistingEnv"` - NewEnvConfig *NewEnvConfig `toml:"NewEnv"` - Performance *vrfv2.PerformanceConfig `toml:"Performance"` + General *General `toml:"General"` + ExistingEnvConfig *ExistingEnvConfig `toml:"ExistingEnv"` + Performance *vrf_common_config.PerformanceConfig `toml:"Performance"` } func (c *Config) Validate() error { - if c.Common != nil { - if err := c.Common.Validate(); err != nil { - return err - } - } if c.General != nil { if err := c.General.Validate(); err != nil { return err @@ -37,37 +30,17 @@ func (c *Config) Validate() error { if err := c.Performance.Validate(); err != nil { return err } - if *c.Performance.UseExistingEnv { - if c.ExistingEnvConfig != nil { - if err := c.ExistingEnvConfig.Validate(); err != nil { - return err - } - } - } else { - if c.NewEnvConfig != nil { - if err := c.NewEnvConfig.Validate(); err != nil { - return err - } - } + } + if c.ExistingEnvConfig != nil && *c.General.UseExistingEnv { + if err := c.ExistingEnvConfig.Validate(); err != nil { + return err } } - return nil } -type Common struct { - *vrfv2.Common -} - -func (c *Common) Validate() error { - if c.Common == nil { - return nil - } - return c.Common.Validate() -} - type General struct { - *vrfv2.General + *vrf_common_config.General SubscriptionBillingType *string `toml:"subscription_billing_type"` // Billing type for the subscription SubscriptionFundingAmountNative *float64 `toml:"subscription_funding_amount_native"` // Amount of LINK to fund the subscription with FulfillmentFlatFeeNativePPM *uint32 `toml:"fulfillment_flat_fee_native_ppm"` // Flat fee in ppm for native currency for the VRF Coordinator config @@ -102,25 +75,12 @@ func (c *General) Validate() error { if c.LinkPremiumPercentage == nil { return errors.New("link_premium_percentage must not be nil") } - return nil } -type NewEnvConfig struct { - *Funding -} - -func (c *NewEnvConfig) Validate() error { - if c.Funding == nil { - return nil - } - - return c.Funding.Validate() -} - type ExistingEnvConfig struct { - *vrfv2.ExistingEnvConfig - Funding + *vrf_common_config.ExistingEnvConfig + SubID *string `toml:"sub_id"` } func (c *ExistingEnvConfig) Validate() error { @@ -129,42 +89,10 @@ func (c *ExistingEnvConfig) Validate() error { return err } } - - return c.Funding.Validate() -} - -type Funding struct { - SubFunding - NodeSendingKeyFunding *float64 `toml:"node_sending_key_funding"` - NodeSendingKeyFundingMin *float64 `toml:"node_sending_key_funding_min"` -} - -func (c *Funding) Validate() error { - if c.NodeSendingKeyFunding != nil && *c.NodeSendingKeyFunding <= 0 { - return errors.New("when set node_sending_key_funding must be a positive value") - } - if c.NodeSendingKeyFundingMin != nil && *c.NodeSendingKeyFundingMin <= 0 { - return errors.New("when set node_sending_key_funding_min must be a positive value") - } - - return c.SubFunding.Validate() -} - -type SubFunding struct { - SubFundsLink *float64 `toml:"sub_funds_link"` - SubFundsNative *float64 `toml:"sub_funds_native"` -} - -func (c *SubFunding) Validate() error { - if c.SubFundsLink == nil || c.SubFundsNative == nil { - return errors.New("both sub_funds_link and sub_funds_native must be set") - } - if c.SubFundsLink != nil && *c.SubFundsLink < 0 { - return errors.New("sub_funds_link must be a non-negative number") - } - if c.SubFundsNative != nil && *c.SubFundsNative < 0 { - return errors.New("sub_funds_native must be a non-negative number") + if !*c.CreateFundSubsAndAddConsumers { + if c.SubID == nil && *c.SubID == "" { + return errors.New("sub_id must be set when using existing environment") + } } - - return nil + return c.Funding.Validate() } diff --git a/integration-tests/testconfig/vrfv2plus/example.toml b/integration-tests/testconfig/vrfv2plus/example.toml index 6595dce18ca..095bc06520a 100644 --- a/integration-tests/testconfig/vrfv2plus/example.toml +++ b/integration-tests/testconfig/vrfv2plus/example.toml @@ -75,10 +75,8 @@ chainlink_node_funding = 0.5 # Product part [VRFv2Plus] -[VRFv2Plus.Common] -cancel_subs_after_test_run = true - [VRFv2Plus.General] +cancel_subs_after_test_run = true max_gas_price_gwei = 1000 link_native_feed_response = 1000000000000000000 minimum_confirmations = 3 diff --git a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml index 79f328e278f..96b1a3f7224 100644 --- a/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml +++ b/integration-tests/testconfig/vrfv2plus/vrfv2plus.toml @@ -4,26 +4,22 @@ chainlink_node_funding = 0.1 [VRFv2Plus] [VRFv2Plus.General] +cancel_subs_after_test_run = true +use_existing_env = false +subscription_funding_amount_link = 5.0 +subscription_funding_amount_native=1 + cl_node_max_gas_price_gwei = 10 link_native_feed_response = 1000000000000000000 minimum_confirmations = 3 subscription_billing_type = "LINK_AND_NATIVE" -subscription_funding_amount_link = 5.0 + number_of_words = 3 callback_gas_limit = 1000000 max_gas_limit_coordinator_config = 2500000 fallback_wei_per_unit_link = 60000000000000000 staleness_seconds = 86400 gas_after_payment_calculation = 33825 -fulfilment_flat_fee_link_ppm_tier_1 = 500 -fulfilment_flat_fee_link_ppm_tier_2 = 500 -fulfilment_flat_fee_link_ppm_tier_3 = 500 -fulfilment_flat_fee_link_ppm_tier_4 = 500 -fulfilment_flat_fee_link_ppm_tier_5 = 500 -reqs_for_tier_2 = 0 -reqs_for_tier_3 = 0 -reqs_for_tier_4 = 0 -reqs_for_tier_5 = 0 number_of_sub_to_create = 1 randomness_request_count_per_request = 1 randomness_request_count_per_request_deviation = 0 @@ -34,7 +30,6 @@ wrapper_premium_percentage = 25 wrapper_max_number_of_words = 10 wrapper_consumer_funding_amount_native_token = 1.0 wrapper_consumer_funding_amount_link = 10 -subscription_funding_amount_native=1 fulfillment_flat_fee_link_ppm=500 fulfillment_flat_fee_native_ppm=500 fulfillment_flat_fee_link_discount_ppm=100 @@ -43,7 +38,7 @@ link_premium_percentage=1 # VRF Job config vrf_job_forwarding_allowed = false -vrf_job_estimate_gas_multiplier = 1.0 +vrf_job_estimate_gas_multiplier = 1.1 vrf_job_batch_fulfillment_enabled = false vrf_job_batch_fulfillment_gas_multiplier = 1.15 vrf_job_poll_period = "1s" @@ -55,124 +50,63 @@ bhs_job_lookback_blocks = 250 bhs_job_poll_period = "1s" bhs_job_run_timeout = "24h" -# load test specific config -[Load.VRFv2Plus] -[Load.VRFv2Plus.Common] -cancel_subs_after_test_run = true - -[Load.VRFv2Plus.General] -minimum_confirmations = 3 -randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting -number_of_sub_to_create = 1 - -[Load.VRFv2Plus.Performance] -test_duration = "2m" -# approx 60 RPM - 1 tx request with 3 rand requests in each tx every 3 seconds -rate_limit_unit_duration = "3s" -rps = 1 - -[Load.VRFv2Plus.NewEnv] -sub_funds_link = 1 -sub_funds_native = 1 -node_funds = 10 -node_sending_key_funding = 1000 +# PERFORMANCE test specific config -[Load.VRFv2Plus.ExistingEnv] -sub_id = 1 +[VRFv2Plus.ExistingEnv] +coordinator_address = "" +consumer_address = "" +sub_id = "" +key_hash = "" create_fund_subs_and_add_consumers = true link_address = "" -sub_funds_link = 10 node_sending_key_funding_min = 1 node_sending_keys = [] -# soak test specific config -[Soak.VRFv2Plus] -[Soak.VRFv2Plus.Common] -cancel_subs_after_test_run = true +#SOAK TEST CONFIG +[Soak.Common] +chainlink_node_funding = 0.1 [Soak.VRFv2Plus.General] -minimum_confirmations = 3 -randomness_request_count_per_request = 1 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 +subscription_funding_amount_link = 5.0 +subscription_funding_amount_native=1 [Soak.VRFv2Plus.Performance] test_duration = "2m" -# 10 RPM - 1 tx request with 1 rand request in each tx every 6 seconds -rate_limit_unit_duration = "6s" +rate_limit_unit_duration = "3s" rps = 1 -use_existing_env = false -[Soak.VRFv2Plus.NewEnv] -sub_funds_link = 1 -sub_funds_native = 1 -node_funds = 10 -node_sending_key_funding = 1000 - -[Soak.VRFv2Plus.ExistingEnv] -sub_id = 1 -create_fund_subs_and_add_consumers = true -sub_funds_link = 10 -node_sending_key_funding_min = 1 -node_sending_keys = [] - -# spike test specific config -[Spike.VRFv2Plus] -[Spike.VRFv2Plus.Common] -cancel_subs_after_test_run = true +# LOAD TEST CONFIG +[Load.Common] +chainlink_node_funding = 0.1 -[Spike.VRFv2Plus.General] -minimum_confirmations = 3 -randomness_request_count_per_request = 150 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +[Load.VRFv2Plus.General] +randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 +subscription_funding_amount_link = 5.0 +subscription_funding_amount_native=1 -[Spike.VRFv2Plus.Performance] +[Load.VRFv2Plus.Performance] test_duration = "2m" -# approx 150 RPM - 1 tx request with 150 rand requests in each tx every 60 seconds -rate_limit_unit_duration = "1m" +rate_limit_unit_duration = "3s" rps = 1 -[Spike.VRFv2Plus.NewEnv] -sub_funds_link = 1 -sub_funds_native = 1 -node_funds = 10 -node_sending_key_funding = 1000 -[Spike.VRFv2Plus.ExistingEnv] -sub_id = 1 -create_fund_subs_and_add_consumers = true -sub_funds_link = 10 -node_sending_key_funding_min = 1 -node_sending_keys = [] - -# stress test specific config -[Stress.VRFv2Plus] -[Stress.VRFv2Plus.Common] -cancel_subs_after_test_run = true +# STRESS TEST CONFIG +[Stress.Common] +chainlink_node_funding = 0.1 [Stress.VRFv2Plus.General] -minimum_confirmations = 3 -randomness_request_count_per_request = 4 # amount of randomness requests to make per one TX request -randomness_request_count_per_request_deviation = 0 #NOTE - deviation should be less than randomness_request_count_per_request setting +randomness_request_count_per_request = 3 # amount of randomness requests to make per one TX request +randomness_request_count_per_request_deviation = 2 #NOTE - deviation should be less than randomness_request_count_per_request setting number_of_sub_to_create = 1 +subscription_funding_amount_link = 5.0 +subscription_funding_amount_native=1 [Stress.VRFv2Plus.Performance] test_duration = "2m" -# approx 540 RPM - 3 tx requests per second with 4 rand requests in each tx -rate_limit_unit_duration = "1s" -rps = 3 - -[Stress.VRFv2Plus.NewEnv] -sub_funds_link = 1 -sub_funds_native = 1 -node_funds = 10 -node_sending_key_funding = 1000 - -[Stress.VRFv2Plus.ExistingEnv] -sub_id = 1 -create_fund_subs_and_add_consumers = true -sub_funds_link = 10 -node_sending_key_funding_min = 1 -node_sending_keys = [] \ No newline at end of file +rate_limit_unit_duration = "3s" +rps = 1 diff --git a/integration-tests/testreporters/vrfv2.go b/integration-tests/testreporters/vrfv2.go index 4f4c7dc8fd1..d94c66abc59 100644 --- a/integration-tests/testreporters/vrfv2.go +++ b/integration-tests/testreporters/vrfv2.go @@ -77,7 +77,7 @@ func (o *VRFV2TestReporter) SendSlackNotification(t *testing.T, slackClient *sla "RandomnessRequestCountPerRequestDeviation: %d\n", o.TestType, perfCfg.TestDuration.Duration.Truncate(time.Second).String(), - *perfCfg.UseExistingEnv, + *o.VRFv2TestConfig.GetVRFv2Config().General.UseExistingEnv, o.RequestCount.String(), o.FulfilmentCount.String(), o.AverageFulfillmentInMillions.String(), diff --git a/integration-tests/testreporters/vrfv2plus.go b/integration-tests/testreporters/vrfv2plus.go index 8d384b07868..ddbf1f35e24 100644 --- a/integration-tests/testreporters/vrfv2plus.go +++ b/integration-tests/testreporters/vrfv2plus.go @@ -15,31 +15,30 @@ import ( ) type VRFV2PlusTestReporter struct { - TestType string - RequestCount *big.Int - FulfilmentCount *big.Int - AverageFulfillmentInMillions *big.Int - SlowestFulfillment *big.Int - FastestFulfillment *big.Int - VRFv2PlusTestConfig types.VRFv2PlusTestConfig + TestType string + LoadTestMetrics VRFLoadTestMetrics + VRFv2PlusTestConfig types.VRFv2PlusTestConfig +} + +type VRFLoadTestMetrics struct { + RequestCount *big.Int + FulfilmentCount *big.Int + AverageFulfillmentInMillions *big.Int + SlowestFulfillment *big.Int + FastestFulfillment *big.Int + AverageResponseTimeInSecondsMillions *big.Int + SlowestResponseTimeInSeconds *big.Int + FastestResponseTimeInSeconds *big.Int } func (o *VRFV2PlusTestReporter) SetReportData( testType string, - RequestCount *big.Int, - FulfilmentCount *big.Int, - AverageFulfillmentInMillions *big.Int, - SlowestFulfillment *big.Int, - FastestFulfillment *big.Int, - vtfv2PlusTestConfig types.VRFv2PlusTestConfig, + metrics VRFLoadTestMetrics, + testConfig types.VRFv2PlusTestConfig, ) { o.TestType = testType - o.RequestCount = RequestCount - o.FulfilmentCount = FulfilmentCount - o.AverageFulfillmentInMillions = AverageFulfillmentInMillions - o.SlowestFulfillment = SlowestFulfillment - o.FastestFulfillment = FastestFulfillment - o.VRFv2PlusTestConfig = vtfv2PlusTestConfig + o.LoadTestMetrics = metrics + o.VRFv2PlusTestConfig = testConfig } // SendSlackNotification sends a slack message to a slack webhook @@ -63,21 +62,27 @@ func (o *VRFV2PlusTestReporter) SendSlackNotification(t *testing.T, slackClient "Use Existing Env: %t\n"+ "Request Count: %s\n"+ "Fulfilment Count: %s\n"+ - "AverageFulfillmentInMillions: %s\n"+ - "Slowest Fulfillment: %s\n"+ - "Fastest Fulfillment: %s \n"+ + "AverageFulfillmentInMillions (blocks): %s\n"+ + "Slowest Fulfillment (blocks): %s\n"+ + "Fastest Fulfillment (blocks): %s \n"+ + "AverageFulfillmentInMillions (seconds): %s\n"+ + "Slowest Fulfillment (seconds): %s\n"+ + "Fastest Fulfillment (seconds): %s \n"+ "RPS: %d\n"+ "RateLimitUnitDuration: %s\n"+ "RandomnessRequestCountPerRequest: %d\n"+ "RandomnessRequestCountPerRequestDeviation: %d\n", o.TestType, vrfv2lusConfig.TestDuration.Duration.Truncate(time.Second).String(), - *vrfv2lusConfig.UseExistingEnv, - o.RequestCount.String(), - o.FulfilmentCount.String(), - o.AverageFulfillmentInMillions.String(), - o.SlowestFulfillment.String(), - o.FastestFulfillment.String(), + *o.VRFv2PlusTestConfig.GetVRFv2PlusConfig().General.UseExistingEnv, + o.LoadTestMetrics.RequestCount.String(), + o.LoadTestMetrics.FulfilmentCount.String(), + o.LoadTestMetrics.AverageFulfillmentInMillions.String(), + o.LoadTestMetrics.SlowestFulfillment.String(), + o.LoadTestMetrics.FastestFulfillment.String(), + o.LoadTestMetrics.AverageResponseTimeInSecondsMillions.String(), + o.LoadTestMetrics.SlowestResponseTimeInSeconds.String(), + o.LoadTestMetrics.FastestResponseTimeInSeconds.String(), *vrfv2lusConfig.RPS, vrfv2lusConfig.RateLimitUnitDuration.String(), *o.VRFv2PlusTestConfig.GetVRFv2PlusConfig().General.RandomnessRequestCountPerRequest,