From e848ae908a8af0c776329cdc1e8e43b887f450e8 Mon Sep 17 00:00:00 2001 From: Ilja Pavlovs Date: Fri, 19 Apr 2024 11:52:37 +0300 Subject: [PATCH] VRF-1014: refactoring VRF e2e tests (#12798) * VRF-1014: refactoring VRF e2e tests * VRF-1014: fixing lint * VRF-1014: fixing lint * VRF-1014: fixing VRF v2 test * VRF-1014: making logging more DRY * VRF-1014: fixing lint * VRF-1014: fixing lint * VRF-1014: fixing sonar * VRF-1014: fixing tests * VRF-1014: fixing tests --- .../VRFCoordinatorV2PlusUpgradedVersion.sol | 385 +++++++++++------- .../vrf_v2plus_upgraded_version.go | 305 +++++++++++--- ...rapper-dependency-versions-do-not-edit.txt | 2 +- .../actions/vrf/common/logging_helpers.go | 129 ++++++ .../actions/vrf/vrfv2/contract_steps.go | 62 ++- .../actions/vrf/vrfv2/logging_helpers.go | 65 --- .../actions/vrf/vrfv2plus/contract_steps.go | 321 +++++---------- .../actions/vrf/vrfv2plus/logging_helpers.go | 172 +------- .../contracts/contract_vrf_models.go | 56 ++- .../contracts/ethereum_vrf_common.go | 124 ++++++ .../contracts/ethereum_vrfv2_contracts.go | 130 +++--- .../contracts/ethereum_vrfv2plus_contracts.go | 187 +++++++-- integration-tests/load/vrfv2/vrfv2_test.go | 5 +- integration-tests/load/vrfv2plus/gun.go | 2 +- .../load/vrfv2plus/vrfv2plus_test.go | 4 +- integration-tests/smoke/vrfv2_test.go | 30 +- integration-tests/smoke/vrfv2plus_test.go | 138 +++---- 17 files changed, 1220 insertions(+), 897 deletions(-) create mode 100644 integration-tests/actions/vrf/common/logging_helpers.go create mode 100644 integration-tests/contracts/ethereum_vrf_common.go diff --git a/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol b/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol index 6599a68a96e..c88d7dec397 100644 --- a/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol +++ b/contracts/src/v0.8/vrf/dev/testhelpers/VRFCoordinatorV2PlusUpgradedVersion.sol @@ -5,6 +5,7 @@ import {BlockhashStoreInterface} from "../../interfaces/BlockhashStoreInterface. // solhint-disable-next-line no-unused-import import {IVRFCoordinatorV2Plus, IVRFSubscriptionV2Plus} from "../interfaces/IVRFCoordinatorV2Plus.sol"; import {VRF} from "../../../vrf/VRF.sol"; +import {VRFTypes} from "../../VRFTypes.sol"; import {VRFConsumerBaseV2Plus, IVRFMigratableConsumerV2Plus} from "../VRFConsumerBaseV2Plus.sol"; import {ChainSpecificUtil} from "../../../ChainSpecificUtil.sol"; import {SubscriptionAPI} from "../SubscriptionAPI.sol"; @@ -30,37 +31,39 @@ contract VRFCoordinatorV2PlusUpgradedVersion is // 5k is plenty for an EXTCODESIZE call (2600) + warm CALL (100) // and some arithmetic operations. uint256 private constant GAS_FOR_CALL_EXACT_CHECK = 5_000; + // upper bound limit for premium percentages to make sure fee calculations don't overflow + uint8 private constant PREMIUM_PERCENTAGE_MAX = 155; error InvalidRequestConfirmations(uint16 have, uint16 min, uint16 max); error GasLimitTooBig(uint32 have, uint32 want); error NumWordsTooBig(uint32 have, uint32 want); + error MsgDataTooBig(uint256 have, uint32 max); error ProvingKeyAlreadyRegistered(bytes32 keyHash); error NoSuchProvingKey(bytes32 keyHash); error InvalidLinkWeiPrice(int256 linkWei); + error LinkDiscountTooHigh(uint32 flatFeeLinkDiscountPPM, uint32 flatFeeNativePPM); + error InvalidPremiumPercentage(uint8 premiumPercentage, uint8 max); error NoCorrespondingRequest(); error IncorrectCommitment(); error BlockhashNotInStore(uint256 blockNum); error PaymentTooLarge(); error InvalidExtraArgsTag(); + error GasPriceExceeded(uint256 gasPrice, uint256 maxGas); /// @notice emitted when version in the request doesn't match expected version error InvalidVersion(uint8 requestVersion, uint8 expectedVersion); /// @notice emitted when transferred balance (msg.value) does not match the metadata in V1MigrationData error InvalidNativeBalance(uint256 transferredValue, uint96 expectedValue); error SubscriptionIDCollisionFound(); - struct RequestCommitment { - uint64 blockNum; - uint256 subId; - uint32 callbackGasLimit; - uint32 numWords; - address sender; - bytes extraArgs; + struct ProvingKey { + bool exists; // proving key exists + uint64 maxGas; // gas lane max gas price for fulfilling requests } - mapping(bytes32 => bool) /* keyHash */ /* exists */ internal s_provingKeys; + mapping(bytes32 => ProvingKey) /* keyHash */ /* provingKey */ public s_provingKeys; bytes32[] public s_provingKeyHashes; mapping(uint256 => bytes32) /* requestID */ /* commitment */ public s_requestCommitments; + event ProvingKeyRegistered(bytes32 keyHash, uint64 maxGas); - event ProvingKeyRegistered(bytes32 keyHash); event RandomWordsRequested( bytes32 indexed keyHash, uint256 requestId, @@ -72,26 +75,18 @@ contract VRFCoordinatorV2PlusUpgradedVersion is bytes extraArgs, address indexed sender ); + event RandomWordsFulfilled( uint256 indexed requestId, uint256 outputSeed, - uint256 indexed subID, + uint256 indexed subId, uint96 payment, - bool success + bool nativePayment, + bool success, + bool onlyPremium ); - int256 internal s_fallbackWeiPerUnitLink; - - FeeConfig internal s_feeConfig; - - struct FeeConfig { - // Flat fee charged per fulfillment in millionths of link - // So fee range is [0, 2^32/10^6]. - uint32 fulfillmentFlatFeeLinkPPM; - // Flat fee charged per fulfillment in millionths of native. - // So fee range is [0, 2^32/10^6]. - uint32 fulfillmentFlatFeeNativePPM; - } + int256 public s_fallbackWeiPerUnitLink; event ConfigSet( uint16 minimumRequestConfirmations, @@ -99,26 +94,30 @@ contract VRFCoordinatorV2PlusUpgradedVersion is uint32 stalenessSeconds, uint32 gasAfterPaymentCalculation, int256 fallbackWeiPerUnitLink, + uint32 fulfillmentFlatFeeNativePPM, + uint32 fulfillmentFlatFeeLinkDiscountPPM, uint8 nativePremiumPercentage, uint8 linkPremiumPercentage ); + event FallbackWeiPerUnitLinkUsed(uint256 requestId, int256 fallbackWeiPerUnitLink); + constructor(address blockhashStore) SubscriptionAPI() { BLOCKHASH_STORE = BlockhashStoreInterface(blockhashStore); } /** - * @notice Registers a proving key to an oracle. + * @notice Registers a proving key to. * @param publicProvingKey key that oracle can use to submit vrf fulfillments */ - function registerProvingKey(uint256[2] calldata publicProvingKey) external onlyOwner { + function registerProvingKey(uint256[2] calldata publicProvingKey, uint64 maxGas) external onlyOwner { bytes32 kh = hashOfKey(publicProvingKey); - if (s_provingKeys[kh]) { + if (s_provingKeys[kh].exists) { revert ProvingKeyAlreadyRegistered(kh); } - s_provingKeys[kh] = true; + s_provingKeys[kh] = ProvingKey({exists: true, maxGas: maxGas}); s_provingKeyHashes.push(kh); - emit ProvingKeyRegistered(kh); + emit ProvingKeyRegistered(kh, maxGas); } /** @@ -136,6 +135,8 @@ contract VRFCoordinatorV2PlusUpgradedVersion is * @param stalenessSeconds if the native/link feed is more stale then this, use the fallback price * @param gasAfterPaymentCalculation gas used in doing accounting after completing the gas measurement * @param fallbackWeiPerUnitLink fallback native/link price in the case of a stale feed + * @param fulfillmentFlatFeeNativePPM flat fee in native for native payment + * @param fulfillmentFlatFeeLinkDiscountPPM flat fee discount for link payment in native * @param nativePremiumPercentage native premium percentage * @param linkPremiumPercentage link premium percentage */ @@ -160,6 +161,15 @@ contract VRFCoordinatorV2PlusUpgradedVersion is if (fallbackWeiPerUnitLink <= 0) { revert InvalidLinkWeiPrice(fallbackWeiPerUnitLink); } + if (fulfillmentFlatFeeLinkDiscountPPM > fulfillmentFlatFeeNativePPM) { + revert LinkDiscountTooHigh(fulfillmentFlatFeeLinkDiscountPPM, fulfillmentFlatFeeNativePPM); + } + if (nativePremiumPercentage > PREMIUM_PERCENTAGE_MAX) { + revert InvalidPremiumPercentage(nativePremiumPercentage, PREMIUM_PERCENTAGE_MAX); + } + if (linkPremiumPercentage > PREMIUM_PERCENTAGE_MAX) { + revert InvalidPremiumPercentage(linkPremiumPercentage, PREMIUM_PERCENTAGE_MAX); + } s_config = Config({ minimumRequestConfirmations: minimumRequestConfirmations, maxGasLimit: maxGasLimit, @@ -178,6 +188,8 @@ contract VRFCoordinatorV2PlusUpgradedVersion is stalenessSeconds, gasAfterPaymentCalculation, fallbackWeiPerUnitLink, + fulfillmentFlatFeeNativePPM, + fulfillmentFlatFeeLinkDiscountPPM, nativePremiumPercentage, linkPremiumPercentage ); @@ -232,18 +244,18 @@ contract VRFCoordinatorV2PlusUpgradedVersion is */ function requestRandomWords( VRFV2PlusClient.RandomWordsRequest calldata req - ) external override nonReentrant returns (uint256) { + ) external override nonReentrant returns (uint256 requestId) { // Input validation using the subscription storage. - if (s_subscriptionConfigs[req.subId].owner == address(0)) { + uint256 subId = req.subId; + if (s_subscriptionConfigs[subId].owner == address(0)) { revert InvalidSubscription(); } // Its important to ensure that the consumer is in fact who they say they // are, otherwise they could use someone else's subscription balance. - // A nonce of 0 indicates consumer is not allocated to the sub. mapping(uint256 => ConsumerConfig) storage consumerConfigs = s_consumers[msg.sender]; - ConsumerConfig memory consumerConfig = consumerConfigs[req.subId]; + ConsumerConfig memory consumerConfig = consumerConfigs[subId]; if (!consumerConfig.active) { - revert InvalidConsumer(req.subId, msg.sender); + revert InvalidConsumer(subId, msg.sender); } // Input validation using the config storage word. if ( @@ -265,19 +277,21 @@ contract VRFCoordinatorV2PlusUpgradedVersion is if (req.numWords > MAX_NUM_WORDS) { revert NumWordsTooBig(req.numWords, MAX_NUM_WORDS); } + // Note we do not check whether the keyHash is valid to save gas. // The consequence for users is that they can send requests // for invalid keyHashes which will simply not be fulfilled. ++consumerConfig.nonce; - (uint256 requestId, uint256 preSeed) = _computeRequestId(req.keyHash, msg.sender, req.subId, consumerConfig.nonce); + ++consumerConfig.pendingReqCount; + uint256 preSeed; + (requestId, preSeed) = _computeRequestId(req.keyHash, msg.sender, subId, consumerConfig.nonce); - VRFV2PlusClient.ExtraArgsV1 memory extraArgs = _fromBytes(req.extraArgs); - bytes memory extraArgsBytes = VRFV2PlusClient._argsToBytes(extraArgs); + bytes memory extraArgsBytes = VRFV2PlusClient._argsToBytes(_fromBytes(req.extraArgs)); s_requestCommitments[requestId] = keccak256( abi.encode( requestId, ChainSpecificUtil._getBlockNumber(), - req.subId, + subId, req.callbackGasLimit, req.numWords, msg.sender, @@ -288,14 +302,14 @@ contract VRFCoordinatorV2PlusUpgradedVersion is req.keyHash, requestId, preSeed, - req.subId, + subId, req.requestConfirmations, req.callbackGasLimit, req.numWords, extraArgsBytes, msg.sender ); - s_consumers[msg.sender][req.subId] = consumerConfig; + consumerConfigs[subId] = consumerConfig; return requestId; } @@ -344,18 +358,19 @@ contract VRFCoordinatorV2PlusUpgradedVersion is } struct Output { - bytes32 keyHash; + ProvingKey provingKey; uint256 requestId; uint256 randomness; } function _getRandomnessFromProof( Proof memory proof, - RequestCommitment memory rc + VRFTypes.RequestCommitmentV2Plus memory rc ) internal view returns (Output memory) { bytes32 keyHash = hashOfKey(proof.pk); + ProvingKey memory key = s_provingKeys[keyHash]; // Only registered proving keys are permitted. - if (!s_provingKeys[keyHash]) { + if (!key.exists) { revert NoSuchProvingKey(keyHash); } uint256 requestId = uint256(keccak256(abi.encode(keyHash, proof.seed))); @@ -381,179 +396,232 @@ contract VRFCoordinatorV2PlusUpgradedVersion is // The seed actually used by the VRF machinery, mixing in the blockhash uint256 actualSeed = uint256(keccak256(abi.encodePacked(proof.seed, blockHash))); uint256 randomness = VRF._randomValueFromVRFProof(proof, actualSeed); // Reverts on failure - return Output(keyHash, requestId, randomness); + return Output(key, requestId, randomness); + } + + function _getValidatedGasPrice(bool onlyPremium, uint64 gasLaneMaxGas) internal view returns (uint256 gasPrice) { + if (tx.gasprice > gasLaneMaxGas) { + if (onlyPremium) { + // if only the premium amount needs to be billed, then the premium is capped by the gas lane max + return uint256(gasLaneMaxGas); + } else { + // Ensure gas price does not exceed the gas lane max gas price + revert GasPriceExceeded(tx.gasprice, gasLaneMaxGas); + } + } + return tx.gasprice; + } + + function _deliverRandomness( + uint256 requestId, + VRFTypes.RequestCommitmentV2Plus memory rc, + uint256[] memory randomWords + ) internal returns (bool success) { + VRFConsumerBaseV2Plus v; + bytes memory resp = abi.encodeWithSelector(v.rawFulfillRandomWords.selector, requestId, randomWords); + // Call with explicitly the amount of callback gas requested + // Important to not let them exhaust the gas budget and avoid oracle payment. + // Do not allow any non-view/non-pure coordinator functions to be called + // during the consumers callback code via reentrancyLock. + // Note that _callWithExactGas will revert if we do not have sufficient gas + // to give the callee their requested amount. + s_config.reentrancyLock = true; + success = _callWithExactGas(rc.callbackGasLimit, rc.sender, resp); + s_config.reentrancyLock = false; + return success; } /* - * @notice Fulfill a randomness request + * @notice Fulfill a randomness request. * @param proof contains the proof and randomness * @param rc request commitment pre-image, committed to at request time + * @param onlyPremium only charge premium * @return payment amount billed to the subscription * @dev simulated offchain to determine if sufficient balance is present to fulfill the request */ function fulfillRandomWords( Proof memory proof, - RequestCommitment memory rc, - bool - ) external nonReentrant returns (uint96) { + VRFTypes.RequestCommitmentV2Plus memory rc, + bool onlyPremium + ) external nonReentrant returns (uint96 payment) { uint256 startGas = gasleft(); + // fulfillRandomWords msg.data has 772 bytes and with an additional + // buffer of 32 bytes, we get 804 bytes. + /* Data size split: + * fulfillRandomWords function signature - 4 bytes + * proof - 416 bytes + * pk - 64 bytes + * gamma - 64 bytes + * c - 32 bytes + * s - 32 bytes + * seed - 32 bytes + * uWitness - 32 bytes + * cGammaWitness - 64 bytes + * sHashWitness - 64 bytes + * zInv - 32 bytes + * requestCommitment - 320 bytes + * blockNum - 32 bytes + * subId - 32 bytes + * callbackGasLimit - 32 bytes + * numWords - 32 bytes + * sender - 32 bytes + * extraArgs - 128 bytes + * onlyPremium - 32 bytes + */ + if (msg.data.length > 804) { + revert MsgDataTooBig(msg.data.length, 804); + } Output memory output = _getRandomnessFromProof(proof, rc); + uint256 gasPrice = _getValidatedGasPrice(onlyPremium, output.provingKey.maxGas); - uint256[] memory randomWords = new uint256[](rc.numWords); - for (uint256 i = 0; i < rc.numWords; i++) { - randomWords[i] = uint256(keccak256(abi.encode(output.randomness, i))); + uint256[] memory randomWords; + uint256 randomness = output.randomness; + // stack too deep error + { + uint256 numWords = rc.numWords; + randomWords = new uint256[](numWords); + for (uint256 i = 0; i < numWords; ++i) { + randomWords[i] = uint256(keccak256(abi.encode(randomness, i))); + } } delete s_requestCommitments[output.requestId]; - VRFConsumerBaseV2Plus v; - bytes memory resp = abi.encodeWithSelector(v.rawFulfillRandomWords.selector, output.requestId, randomWords); - // Call with explicitly the amount of callback gas requested - // Important to not let them exhaust the gas budget and avoid oracle payment. - // Do not allow any non-view/non-pure coordinator functions to be called - // during the consumers callback code via reentrancyLock. - // Note that _callWithExactGas will revert if we do not have sufficient gas - // to give the callee their requested amount. - s_config.reentrancyLock = true; - bool success = _callWithExactGas(rc.callbackGasLimit, rc.sender, resp); - s_config.reentrancyLock = false; + bool success = _deliverRandomness(output.requestId, rc, randomWords); // Increment the req count for the subscription. - uint64 reqCount = s_subscriptions[rc.subId].reqCount; - s_subscriptions[rc.subId].reqCount = reqCount + 1; + ++s_subscriptions[rc.subId].reqCount; + // Decrement the pending req count for the consumer. + --s_consumers[rc.sender][rc.subId].pendingReqCount; + + bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1; // stack too deep error { - bool nativePayment = uint8(rc.extraArgs[rc.extraArgs.length - 1]) == 1; - // We want to charge users exactly for how much gas they use in their callback. - // The gasAfterPaymentCalculation is meant to cover these additional operations where we - // decrement the subscription balance and increment the oracles withdrawable balance. - uint96 payment = _calculatePaymentAmount( - startGas, - s_config.gasAfterPaymentCalculation, - tx.gasprice, - nativePayment - ); - if (nativePayment) { - if (s_subscriptions[rc.subId].nativeBalance < payment) { - revert InsufficientBalance(); - } - s_subscriptions[rc.subId].nativeBalance -= payment; - s_withdrawableNative += payment; - } else { - if (s_subscriptions[rc.subId].balance < payment) { - revert InsufficientBalance(); - } - s_subscriptions[rc.subId].balance -= payment; - s_withdrawableTokens += payment; + // We want to charge users exactly for how much gas they use in their callback with + // an additional premium. If onlyPremium is true, only premium is charged without + // the gas cost. The gasAfterPaymentCalculation is meant to cover these additional + // operations where we decrement the subscription balance and increment the + // withdrawable balance. + bool isFeedStale; + (payment, isFeedStale) = _calculatePaymentAmount(startGas, gasPrice, nativePayment, onlyPremium); + if (isFeedStale) { + emit FallbackWeiPerUnitLinkUsed(output.requestId, s_fallbackWeiPerUnitLink); } + } + + _chargePayment(payment, nativePayment, rc.subId); - // Include payment in the event for tracking costs. - // event RandomWordsFulfilled(uint256 indexed requestId, uint256 outputSeed, uint96 payment, bytes extraArgs, bool success); - emit RandomWordsFulfilled(output.requestId, output.randomness, rc.subId, payment, success); + // Include payment in the event for tracking costs. + emit RandomWordsFulfilled(output.requestId, randomness, rc.subId, payment, nativePayment, success, onlyPremium); + + return payment; + } - return payment; + function _chargePayment(uint96 payment, bool nativePayment, uint256 subId) internal { + Subscription storage subcription = s_subscriptions[subId]; + if (nativePayment) { + uint96 prevBal = subcription.nativeBalance; + if (prevBal < payment) { + revert InsufficientBalance(); + } + subcription.nativeBalance = prevBal - payment; + s_withdrawableNative += payment; + } else { + uint96 prevBal = subcription.balance; + if (prevBal < payment) { + revert InsufficientBalance(); + } + subcription.balance = prevBal - payment; + s_withdrawableTokens += payment; } } function _calculatePaymentAmount( uint256 startGas, - uint256 gasAfterPaymentCalculation, uint256 weiPerUnitGas, - bool nativePayment - ) internal view returns (uint96) { + bool nativePayment, + bool onlyPremium + ) internal view returns (uint96, bool) { if (nativePayment) { - return - _calculatePaymentAmountNative( - startGas, - gasAfterPaymentCalculation, - s_feeConfig.fulfillmentFlatFeeNativePPM, - weiPerUnitGas - ); - } - return - _calculatePaymentAmountLink( - startGas, - gasAfterPaymentCalculation, - s_feeConfig.fulfillmentFlatFeeLinkPPM, - weiPerUnitGas - ); + return (_calculatePaymentAmountNative(startGas, weiPerUnitGas, onlyPremium), false); + } + return _calculatePaymentAmountLink(startGas, weiPerUnitGas, onlyPremium); } function _calculatePaymentAmountNative( uint256 startGas, - uint256 gasAfterPaymentCalculation, - uint32 fulfillmentFlatFeePPM, - uint256 weiPerUnitGas + uint256 weiPerUnitGas, + bool onlyPremium ) internal view returns (uint96) { // Will return non-zero on chains that have this enabled uint256 l1CostWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data); // calculate the payment without the premium - uint256 baseFeeWei = weiPerUnitGas * (gasAfterPaymentCalculation + startGas - gasleft()); - // calculate the flat fee in wei - uint256 flatFeeWei = 1e12 * uint256(fulfillmentFlatFeePPM); - // return the final fee with the flat fee and l1 cost (if applicable) added - return uint96(baseFeeWei + flatFeeWei + l1CostWei); + uint256 baseFeeWei = weiPerUnitGas * (s_config.gasAfterPaymentCalculation + startGas - gasleft()); + // calculate flat fee in native + uint256 flatFeeWei = 1e12 * uint256(s_config.fulfillmentFlatFeeNativePPM); + if (onlyPremium) { + return uint96((((l1CostWei + baseFeeWei) * (s_config.nativePremiumPercentage)) / 100) + flatFeeWei); + } else { + return uint96((((l1CostWei + baseFeeWei) * (100 + s_config.nativePremiumPercentage)) / 100) + flatFeeWei); + } } // Get the amount of gas used for fulfillment function _calculatePaymentAmountLink( uint256 startGas, - uint256 gasAfterPaymentCalculation, - uint32 fulfillmentFlatFeeLinkPPM, - uint256 weiPerUnitGas - ) internal view returns (uint96) { - int256 weiPerUnitLink; - weiPerUnitLink = _getFeedData(); + uint256 weiPerUnitGas, + bool onlyPremium + ) internal view returns (uint96, bool) { + (int256 weiPerUnitLink, bool isFeedStale) = _getFeedData(); if (weiPerUnitLink <= 0) { revert InvalidLinkWeiPrice(weiPerUnitLink); } // Will return non-zero on chains that have this enabled uint256 l1CostWei = ChainSpecificUtil._getCurrentTxL1GasFees(msg.data); // (1e18 juels/link) ((wei/gas * gas) + l1wei) / (wei/link) = juels - uint256 paymentNoFee = (1e18 * (weiPerUnitGas * (gasAfterPaymentCalculation + startGas - gasleft()) + l1CostWei)) / + uint256 paymentNoFee = (1e18 * + (weiPerUnitGas * (s_config.gasAfterPaymentCalculation + startGas - gasleft()) + l1CostWei)) / uint256(weiPerUnitLink); - uint256 fee = 1e12 * uint256(fulfillmentFlatFeeLinkPPM); - if (paymentNoFee > (1e27 - fee)) { + // calculate the flat fee in wei + uint256 flatFeeWei = 1e12 * + uint256(s_config.fulfillmentFlatFeeNativePPM - s_config.fulfillmentFlatFeeLinkDiscountPPM); + uint256 flatFeeJuels = (1e18 * flatFeeWei) / uint256(weiPerUnitLink); + uint256 payment; + if (onlyPremium) { + payment = ((paymentNoFee * (s_config.linkPremiumPercentage)) / 100 + flatFeeJuels); + } else { + payment = ((paymentNoFee * (100 + s_config.linkPremiumPercentage)) / 100 + flatFeeJuels); + } + if (payment > 1e27) { revert PaymentTooLarge(); // Payment + fee cannot be more than all of the link in existence. } - return uint96(paymentNoFee + fee); + return (uint96(payment), isFeedStale); } - function _getFeedData() private view returns (int256) { + function _getFeedData() private view returns (int256 weiPerUnitLink, bool isFeedStale) { uint32 stalenessSeconds = s_config.stalenessSeconds; - bool staleFallback = stalenessSeconds > 0; uint256 timestamp; - int256 weiPerUnitLink; (, weiPerUnitLink, , timestamp, ) = LINK_NATIVE_FEED.latestRoundData(); // solhint-disable-next-line not-rely-on-time - if (staleFallback && stalenessSeconds < block.timestamp - timestamp) { + isFeedStale = stalenessSeconds > 0 && stalenessSeconds < block.timestamp - timestamp; + if (isFeedStale) { weiPerUnitLink = s_fallbackWeiPerUnitLink; } - return weiPerUnitLink; + return (weiPerUnitLink, isFeedStale); } - /* - * @notice Check to see if there exists a request commitment consumers - * for all consumers and keyhashes for a given sub. - * @param subId - ID of the subscription - * @return true if there exists at least one unfulfilled request for the subscription, false - * otherwise. - * @dev Looping is bounded to MAX_CONSUMERS*(number of keyhashes). - * @dev Used to disable subscription canceling while outstanding request are present. + /** + * @inheritdoc IVRFSubscriptionV2Plus */ function pendingRequestExists(uint256 subId) public view override returns (bool) { - SubscriptionConfig memory subConfig = s_subscriptionConfigs[subId]; - for (uint256 i = 0; i < subConfig.consumers.length; i++) { - for (uint256 j = 0; j < s_provingKeyHashes.length; j++) { - (uint256 reqId, ) = _computeRequestId( - s_provingKeyHashes[j], - subConfig.consumers[i], - subId, - s_consumers[subConfig.consumers[i]][subId].nonce - ); - if (s_requestCommitments[reqId] != 0) { - return true; - } + address[] storage consumers = s_subscriptionConfigs[subId].consumers; + uint256 consumersLength = consumers.length; + if (consumersLength == 0) { + return false; + } + for (uint256 i = 0; i < consumersLength; ++i) { + if (s_consumers[consumers[i]][subId].pendingReqCount > 0) { + return true; } } return false; @@ -572,7 +640,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is // Note bounded by MAX_CONSUMERS address[] memory consumers = s_subscriptionConfigs[subId].consumers; uint256 lastConsumerIndex = consumers.length - 1; - for (uint256 i = 0; i < consumers.length; i++) { + for (uint256 i = 0; i < consumers.length; ++i) { if (consumers[i] == consumer) { address last = consumers[lastConsumerIndex]; // Storage write to preserve last element @@ -582,7 +650,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is break; } } - delete s_consumers[consumer][subId]; + s_consumers[consumer][subId].active = false; emit SubscriptionConsumerRemoved(subId, consumer); } @@ -627,7 +695,8 @@ contract VRFCoordinatorV2PlusUpgradedVersion is } function _isTargetRegistered(address target) internal view returns (bool) { - for (uint256 i = 0; i < s_migrationTargets.length; i++) { + uint256 migrationTargetsLength = s_migrationTargets.length; + for (uint256 i = 0; i < migrationTargetsLength; ++i) { if (s_migrationTargets[i] == target) { return true; } @@ -647,16 +716,16 @@ contract VRFCoordinatorV2PlusUpgradedVersion is if (!_isTargetRegistered(newCoordinator)) { revert CoordinatorNotRegistered(newCoordinator); } - (uint96 balance, uint96 nativeBalance, , address owner, address[] memory consumers) = getSubscription(subId); + (uint96 balance, uint96 nativeBalance, , address subOwner, address[] memory consumers) = getSubscription(subId); // solhint-disable-next-line gas-custom-errors - require(owner == msg.sender, "Not subscription owner"); + require(subOwner == msg.sender, "Not subscription owner"); // solhint-disable-next-line gas-custom-errors require(!pendingRequestExists(subId), "Pending request exists"); V1MigrationData memory migrationData = V1MigrationData({ - fromVersion: migrationVersion(), + fromVersion: 1, subId: subId, - subOwner: owner, + subOwner: subOwner, consumers: consumers, linkBalance: balance, nativeBalance: nativeBalance @@ -674,7 +743,7 @@ contract VRFCoordinatorV2PlusUpgradedVersion is // despite the fact that we follow best practices this is still probably safest // to prevent any re-entrancy possibilities. s_config.reentrancyLock = true; - for (uint256 i = 0; i < consumers.length; i++) { + for (uint256 i = 0; i < consumers.length; ++i) { IVRFMigratableConsumerV2Plus(consumers[i]).setCoordinator(newCoordinator); } s_config.reentrancyLock = false; diff --git a/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go b/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go index 79861507e14..a3ef3b83e43 100644 --- a/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go +++ b/core/gethwrappers/generated/vrf_v2plus_upgraded_version/vrf_v2plus_upgraded_version.go @@ -30,15 +30,6 @@ var ( _ = abi.ConvertType ) -type VRFCoordinatorV2PlusUpgradedVersionRequestCommitment struct { - BlockNum uint64 - SubId *big.Int - CallbackGasLimit uint32 - NumWords uint32 - Sender common.Address - ExtraArgs []byte -} - type VRFProof struct { Pk [2]*big.Int Gamma [2]*big.Int @@ -51,6 +42,15 @@ type VRFProof struct { ZInv *big.Int } +type VRFTypesRequestCommitmentV2Plus struct { + BlockNum uint64 + SubId *big.Int + CallbackGasLimit uint32 + NumWords uint32 + Sender common.Address + ExtraArgs []byte +} + type VRFV2PlusClientRandomWordsRequest struct { KeyHash [32]byte SubId *big.Int @@ -61,8 +61,8 @@ type VRFV2PlusClientRandomWordsRequest struct { } var VRFCoordinatorV2PlusUpgradedVersionMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transferredValue\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"expectedValue\",\"type\":\"uint96\"}],\"name\":\"InvalidNativeBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"expectedVersion\",\"type\":\"uint8\"}],\"name\":\"InvalidVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIDCollisionFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subID\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFCoordinatorV2PlusUpgradedVersion.RequestCommitment\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"migrationVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60a06040523480156200001157600080fd5b5060405162005e3438038062005e3483398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160a01b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160a01b0381168114620001a957600080fd5b9392505050565b608051615c61620001d3600039600081816104f401526134790152615c616000f3fe6080604052600436106101e05760003560e01c8062012291146101e5578063088070f5146102125780630ae09540146102e057806315c48b841461030257806318e3dd271461032a5780631b6b6d2314610369578063294daa49146103965780632f622e6b146103b2578063301f42e9146103d2578063405b84fa146103f257806340d6bb821461041257806341af6c871461043d57806351cff8d91461046d5780635d06b4ab1461048d57806364d51a2a146104ad57806365982744146104c2578063689c4517146104e257806372e9d5651461051657806379ba5097146105365780637bce14d11461054b5780638402595e1461056b57806386fe91c71461058b5780638da5cb5b146105ab57806395b55cfc146105c95780639b1c385e146105dc5780639d40a6fd1461060a578063a21a23e414610637578063a4c0ed361461064c578063a63e0bfb1461066c578063aa433aff1461068c578063aefb212f146106ac578063b2a7cac5146106d9578063bec4c08c146106f9578063caf70c4a14610719578063cb63179714610739578063ce3f471914610759578063d98e620e1461076c578063dac83d291461078c578063dc311dd3146107ac578063e72f6e30146107dd578063ee9d2d38146107fd578063f2fde38b1461082a575b600080fd5b3480156101f157600080fd5b506101fa61084a565b60405161020993929190614c80565b60405180910390f35b34801561021e57600080fd5b50600c546102839061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e08401521661010082015261012001610209565b3480156102ec57600080fd5b506103006102fb366004614cff565b6108c6565b005b34801561030e57600080fd5b5061031760c881565b60405161ffff9091168152602001610209565b34801561033657600080fd5b50600a5461035190600160601b90046001600160601b031681565b6040516001600160601b039091168152602001610209565b34801561037557600080fd5b50600254610389906001600160a01b031681565b6040516102099190614d2f565b3480156103a257600080fd5b5060405160028152602001610209565b3480156103be57600080fd5b506103006103cd366004614d43565b61090e565b3480156103de57600080fd5b506103516103ed366004614f9d565b610a5d565b3480156103fe57600080fd5b5061030061040d366004614cff565b610ef3565b34801561041e57600080fd5b506104286101f481565b60405163ffffffff9091168152602001610209565b34801561044957600080fd5b5061045d61045836600461508b565b6112b5565b6040519015158152602001610209565b34801561047957600080fd5b50610300610488366004614d43565b61145b565b34801561049957600080fd5b506103006104a8366004614d43565b6115dd565b3480156104b957600080fd5b50610317606481565b3480156104ce57600080fd5b506103006104dd3660046150a4565b611694565b3480156104ee57600080fd5b506103897f000000000000000000000000000000000000000000000000000000000000000081565b34801561052257600080fd5b50600354610389906001600160a01b031681565b34801561054257600080fd5b506103006116f4565b34801561055757600080fd5b506103006105663660046150d2565b61179e565b34801561057757600080fd5b50610300610586366004614d43565b611897565b34801561059757600080fd5b50600a54610351906001600160601b031681565b3480156105b757600080fd5b506000546001600160a01b0316610389565b6103006105d736600461508b565b6119a3565b3480156105e857600080fd5b506105fc6105f73660046150fa565b611ac4565b604051908152602001610209565b34801561061657600080fd5b5060075461062a906001600160401b031681565b6040516102099190615134565b34801561064357600080fd5b506105fc611e95565b34801561065857600080fd5b50610300610667366004615190565b612068565b34801561067857600080fd5b5061030061068736600461520e565b6121e2565b34801561069857600080fd5b506103006106a736600461508b565b6123eb565b3480156106b857600080fd5b506106cc6106c73660046152af565b612433565b604051610209919061530c565b3480156106e557600080fd5b506103006106f436600461508b565b612535565b34801561070557600080fd5b50610300610714366004614cff565b61262a565b34801561072557600080fd5b506105fc61073436600461531f565b61271c565b34801561074557600080fd5b50610300610754366004614cff565b61274c565b61030061076736600461533b565b6129b6565b34801561077857600080fd5b506105fc61078736600461508b565b612d26565b34801561079857600080fd5b506103006107a7366004614cff565b612d47565b3480156107b857600080fd5b506107cc6107c736600461508b565b612ddd565b6040516102099594939291906153b5565b3480156107e957600080fd5b506103006107f8366004614d43565b612ecb565b34801561080957600080fd5b506105fc61081836600461508b565b600f6020526000908152604090205481565b34801561083657600080fd5b50610300610845366004614d43565b613088565b600c54600e805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff169391928391908301828280156108b457602002820191906000526020600020905b8154815260200190600101908083116108a0575b50505050509050925092509250909192565b816108d08161309c565b6108d86130fd565b6108e1836112b5565b156108ff57604051631685ecdd60e31b815260040160405180910390fd5b610909838361312a565b505050565b6109166130fd565b61091e6132cf565b600b54600160601b90046001600160601b031660000361095157604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c6109748380615420565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b03166109bc9190615420565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610a36576040519150601f19603f3d011682016040523d82523d6000602084013e610a3b565b606091505b50509050806109095760405163950b247960e01b815260040160405180910390fd5b6000610a676130fd565b60005a90506000610a788686613322565b90506000856060015163ffffffff166001600160401b03811115610a9e57610a9e614d60565b604051908082528060200260200182016040528015610ac7578160200160208202803683370190505b50905060005b866060015163ffffffff16811015610b3e57826040015181604051602001610af6929190615440565b6040516020818303038152906040528051906020012060001c828281518110610b2157610b2161544e565b602090810291909101015280610b3681615464565b915050610acd565b50602080830180516000908152600f9092526040808320839055905190518291631fe543e360e01b91610b769190869060240161547d565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b1790559089015160808a0151919250600091610bdb9163ffffffff169084613582565b600c805460ff60301b1916905560208a810151600090815260069091526040902054909150600160c01b90046001600160401b0316610c1b816001615496565b6020808c0151600090815260069091526040812080546001600160401b0393909316600160c01b026001600160c01b039093169290921790915560a08b01518051610c68906001906154b6565b81518110610c7857610c7861544e565b602091010151600c5460f89190911c6001149150600090610ca9908a90600160581b900463ffffffff163a856135ce565b90508115610da1576020808d01516000908152600690915260409020546001600160601b03808316600160601b909204161015610cf957604051631e9acf1760e31b815260040160405180910390fd5b60208c81015160009081526006909152604090208054829190600c90610d30908490600160601b90046001600160601b0316615420565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600b600c8282829054906101000a90046001600160601b0316610d7891906154c9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550610e7c565b6020808d01516000908152600690915260409020546001600160601b0380831691161015610de257604051631e9acf1760e31b815260040160405180910390fd5b6020808d015160009081526006909152604081208054839290610e0f9084906001600160601b0316615420565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600b60008282829054906101000a90046001600160601b0316610e5791906154c9565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b8b6020015188602001517f49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa78a604001518488604051610ed9939291909283526001600160601b039190911660208301521515604082015260600190565b60405180910390a3985050505050505050505b9392505050565b610efb6130fd565b610f048161361d565b610f2c5780604051635428d44960e01b8152600401610f239190614d2f565b60405180910390fd5b600080600080610f3b86612ddd565b945094505093509350336001600160a01b0316826001600160a01b031614610f9e5760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610f23565b610fa7866112b5565b15610fed5760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610f23565b60006040518060c00160405280611002600290565b60ff168152602001888152602001846001600160a01b03168152602001838152602001866001600160601b03168152602001856001600160601b0316815250905060008160405160200161105691906154e9565b604051602081830303815290604052905061107088613686565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b038816906110a99085906004016155ae565b6000604051808303818588803b1580156110c257600080fd5b505af11580156110d6573d6000803e3d6000fd5b50506002546001600160a01b0316158015935091506110ff905057506001600160601b03861615155b156111ba5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611136908a908a906004016155c1565b6020604051808303816000875af1158015611155573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061117991906155e3565b6111ba5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610f23565b600c805460ff60301b1916600160301b17905560005b8351811015611263578381815181106111eb576111eb61544e565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b815260040161121e9190614d2f565b600060405180830381600087803b15801561123857600080fd5b505af115801561124c573d6000803e3d6000fd5b50505050808061125b90615464565b9150506111d0565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906112a39089908b90615600565b60405180910390a15050505050505050565b6000818152600560209081526040808320815160608101835281546001600160a01b039081168252600183015416818501526002820180548451818702810187018652818152879693958601939092919083018282801561133f57602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611321575b505050505081525050905060005b8160400151518110156114515760005b600e5481101561143e576000611407600e838154811061137f5761137f61544e565b9060005260206000200154856040015185815181106113a0576113a061544e565b60200260200101518860046000896040015189815181106113c3576113c361544e565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208d825290925290205461010090046001600160401b031661382e565b506000818152600f60205260409020549091501561142b5750600195945050505050565b508061143681615464565b91505061135d565b508061144981615464565b91505061134d565b5060009392505050565b6114636130fd565b61146b6132cf565b6002546001600160a01b03166114945760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166000036114c057604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006114dc8380615420565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166115249190615420565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061157990859085906004016155c1565b6020604051808303816000875af1158015611598573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115bc91906155e3565b6115d957604051631e9acf1760e31b815260040160405180910390fd5b5050565b6115e56132cf565b6115ee8161361d565b1561160e578060405163ac8a27ef60e01b8152600401610f239190614d2f565b601280546001810182556000919091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af0162590611689908390614d2f565b60405180910390a150565b61169c6132cf565b6002546001600160a01b0316156116c657604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b031633146117475760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610f23565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6117a66132cf565b6040805180820182526000916117d591908490600290839083908082843760009201919091525061271c915050565b6000818152600d602052604090205490915060ff161561180b57604051634a0b8fa760e01b815260048101829052602401610f23565b6000818152600d6020526040808220805460ff19166001908117909155600e805491820181559092527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd909101829055517fc9583fd3afa3d7f16eb0b88d0268e7d05c09bafa4b21e092cbd1320e1bc8089d9061188b9083815260200190565b60405180910390a15050565b61189f6132cf565b600a544790600160601b90046001600160601b0316818111156118d95780826040516354ced18160e11b8152600401610f23929190615440565b818110156109095760006118ed82846154b6565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d806000811461193c576040519150601f19603f3d011682016040523d82523d6000602084013e611941565b606091505b50509050806119635760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c8583604051611994929190615600565b60405180910390a15050505050565b6119ab6130fd565b6000818152600560205260409020546001600160a01b03166119e057604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611a0f83856154c9565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611a5791906154c9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e902823484611aaa9190615619565b604051611ab8929190615440565b60405180910390a25050565b6000611ace6130fd565b6020808301356000908152600590915260409020546001600160a01b0316611b0957604051630fb532db60e11b815260040160405180910390fd5b336000908152600460209081526040808320858301358452808352928190208151606081018352905460ff811615158083526001600160401b036101008304811695840195909552600160481b9091049093169181019190915290611b89578360200135336040516379bfd40160e01b8152600401610f2392919061562c565b600c5461ffff16611ba06060860160408701615643565b61ffff161080611bc3575060c8611bbd6060860160408701615643565b61ffff16115b15611bfd57611bd86060850160408601615643565b600c5460405163539c34bb60e11b8152610f23929161ffff169060c89060040161565e565b600c5462010000900463ffffffff16611c1c608086016060870161567c565b63ffffffff161115611c6257611c38608085016060860161567c565b600c54604051637aebf00f60e11b8152610f23929162010000900463ffffffff1690600401615697565b6101f4611c7560a086016080870161567c565b63ffffffff161115611caf57611c9160a085016080860161567c565b6101f46040516311ce1afb60e21b8152600401610f23929190615697565b806020018051611cbe906156ae565b6001600160401b031690526020818101516000918291611ce69188359133918a01359061382e565b90925090506000611d02611cfd60a08901896156dc565b6138b7565b90506000611d0f82613938565b905083611d1a6139a9565b60208a0135611d2f60808c0160608d0161567c565b611d3f60a08d0160808e0161567c565b3386604051602001611d579796959493929190615722565b60405160208183030381529060405280519060200120600f600086815260200190815260200160002081905550336001600160a01b0316886020013589600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e87878d6040016020810190611dce9190615643565b8e6060016020810190611de1919061567c565b8f6080016020810190611df4919061567c565b89604051611e079695949392919061576e565b60405180910390a45050336000908152600460209081526040808320898301358452825291829020855181549287015193909601516001600160401b03908116600160481b02600160481b600160881b03199190941661010002610100600160481b0319971515979097166001600160481b031990931692909217959095171617909255925050505b919050565b6000611e9f6130fd565b6007546001600160401b031633611eb76001436154b6565b6040516001600160601b0319606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f1981840301815291905280516020909101209150611f1c816001615496565b600780546001600160401b0319166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b9190921602176001600160c01b0316600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b03928316178355935160018301805490951691161790925592518051929493919261201a9260028501920190614b8e565b5061202a91506008905084613a2a565b50827f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d3360405161205b9190614d2f565b60405180910390a2505090565b6120706130fd565b6002546001600160a01b0316331461209b576040516344b0e3c360e01b815260040160405180910390fd5b602081146120bc57604051638129bbcd60e01b815260040160405180910390fd5b60006120ca8284018461508b565b6000818152600560205260409020549091506001600160a01b031661210257604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b03169186919061212983856154c9565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b031661217191906154c9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a8287846121c49190615619565b6040516121d2929190615440565b60405180910390a2505050505050565b6121ea6132cf565b60c861ffff8a16111561221757888960c860405163539c34bb60e11b8152600401610f239392919061565e565b6000851361223b576040516321ea67b360e11b815260048101869052602401610f23565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b90990298909816600160781b600160b81b0319600160581b90960263ffffffff60581b19600160381b90980297909716600160301b600160781b03196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f95cb2ddab6d2297c29a4861691de69b3969c464aa4a9c44258b101ff02ff375a906123d8908b908b908b908b908b908990899061ffff97909716875263ffffffff95861660208801529385166040870152919093166060850152608084019290925260ff91821660a08401521660c082015260e00190565b60405180910390a1505050505050505050565b6123f36132cf565b6000818152600560205260409020546001600160a01b03168061242957604051630fb532db60e11b815260040160405180910390fd5b6115d9828261312a565b606060006124416008613a36565b905080841061246357604051631390f2a160e01b815260040160405180910390fd5b600061246f8486615619565b90508181118061247d575083155b6124875780612489565b815b9050600061249786836154b6565b9050806001600160401b038111156124b1576124b1614d60565b6040519080825280602002602001820160405280156124da578160200160208202803683370190505b50935060005b8181101561252a576124fd6124f58883615619565b600890613a40565b85828151811061250f5761250f61544e565b602090810291909101015261252381615464565b90506124e0565b505050505b92915050565b61253d6130fd565b6000818152600560205260409020546001600160a01b03168061257357604051630fb532db60e11b815260040160405180910390fd5b6000828152600560205260409020600101546001600160a01b031633146125ca576000828152600560205260409081902060010154905163d084e97560e01b8152610f23916001600160a01b031690600401614d2f565b600082815260056020526040908190208054336001600160a01b031991821681178355600190920180549091169055905183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c938691611ab89185916157ad565b816126348161309c565b61263c6130fd565b6001600160a01b03821660009081526004602090815260408083208684529091529020805460ff161561266f5750505050565b60008481526005602052604090206002018054606319016126a3576040516305a48e0f60e01b815260040160405180910390fd5b8154600160ff1990911681178355815490810182556000828152602090200180546001600160a01b0319166001600160a01b03861617905560405185907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e19061270d908790614d2f565b60405180910390a25050505050565b60008160405160200161272f91906157ea565b604051602081830303815290604052805190602001209050919050565b816127568161309c565b61275e6130fd565b612767836112b5565b1561278557604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b038216600090815260046020908152604080832086845290915290205460ff166127cd5782826040516379bfd40160e01b8152600401610f2392919061562c565b60008381526005602090815260408083206002018054825181850281018501909352808352919290919083018282801561283057602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612812575b5050505050905060006001825161284791906154b6565b905060005b825181101561295257846001600160a01b03168382815181106128715761287161544e565b60200260200101516001600160a01b03160361294057600083838151811061289b5761289b61544e565b60200260200101519050806005600089815260200190815260200160002060020183815481106128cd576128cd61544e565b600091825260208083209190910180546001600160a01b0319166001600160a01b039490941693909317909255888152600590915260409020600201805480612918576129186157f8565b600082815260209020810160001990810180546001600160a01b031916905501905550612952565b8061294a81615464565b91505061284c565b506001600160a01b03841660009081526004602090815260408083208884529091529081902080546001600160881b03191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a79061270d908790614d2f565b60006129c482840184615825565b9050806000015160ff166001146129fd57805160405163237d181f60e21b815260ff909116600482015260016024820152604401610f23565b8060a001516001600160601b03163414612a415760a08101516040516306acf13560e41b81523460048201526001600160601b039091166024820152604401610f23565b6020808201516000908152600590915260409020546001600160a01b031615612a7d576040516326afa43560e11b815260040160405180910390fd5b60005b816060015151811015612b7657604051806060016040528060011515815260200160006001600160401b0316815260200160006001600160401b03168152506004600084606001518481518110612ad957612ad961544e565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208684015182528352819020835181549385015194909201516001600160481b0319909316911515610100600160481b031916919091176101006001600160401b039485160217600160481b600160881b031916600160481b939092169290920217905580612b6e81615464565b915050612a80565b50604080516060808201835260808401516001600160601b03908116835260a0850151811660208085019182526000858701818152828901805183526006845288832097518854955192516001600160401b0316600160c01b026001600160c01b03938816600160601b026001600160c01b0319909716919097161794909417169390931790945584518084018652868601516001600160a01b03908116825281860184815294880151828801908152925184526005865295909220825181549087166001600160a01b0319918216178255935160018201805491909716941693909317909455925180519192612c7592600285019290910190614b8e565b5050506080810151600a8054600090612c989084906001600160601b03166154c9565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508060a00151600a600c8282829054906101000a90046001600160601b0316612ce491906154c9565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550612d2081602001516008613a2a90919063ffffffff16565b50505050565b600e8181548110612d3657600080fd5b600091825260209091200154905081565b81612d518161309c565b612d596130fd565b600083815260056020526040902060018101546001600160a01b03848116911614612d20576001810180546001600160a01b0319166001600160a01b03851617905560405184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a190612dcf90339087906157ad565b60405180910390a250505050565b600081815260056020526040812054819081906001600160a01b0316606081612e1957604051630fb532db60e11b815260040160405180910390fd5b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612eb157602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612e93575b505050505090509450945094509450945091939590929450565b612ed36132cf565b6002546001600160a01b0316612efc5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612f2d903090600401614d2f565b602060405180830381865afa158015612f4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f6e9190615950565b600a549091506001600160601b031681811115612fa25780826040516354ced18160e11b8152600401610f23929190615440565b81811015610909576000612fb682846154b6565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612fe99087908590600401615600565b6020604051808303816000875af1158015613008573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302c91906155e3565b61304957604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600848260405161307a929190615600565b60405180910390a150505050565b6130906132cf565b61309981613a4c565b50565b6000818152600560205260409020546001600160a01b0316806130d257604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146115d95780604051636c51fda960e11b8152600401610f239190614d2f565b600c54600160301b900460ff16156131285760405163769dd35360e11b815260040160405180910390fd5b565b60008061313684613686565b60025491935091506001600160a01b03161580159061315d57506001600160601b03821615155b156131fd5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061319d9086906001600160601b03871690600401615600565b6020604051808303816000875af11580156131bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131e091906155e3565b6131fd57604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613253576040519150601f19603f3d011682016040523d82523d6000602084013e613258565b606091505b505090508061327a5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c49060600161270d565b6000546001600160a01b031633146131285760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610f23565b6040805160608101825260008082526020820181905291810191909152600061334e846000015161271c565b6000818152600d602052604090205490915060ff1661338357604051631dfd6e1360e21b815260048101829052602401610f23565b600081856080015160405160200161339c929190615440565b60408051601f1981840301815291815281516020928301206000818152600f90935290822054909250908190036133e657604051631b44092560e11b815260040160405180910390fd5b845160208087015160408089015160608a015160808b015160a08c01519351613415978a979096959101615969565b60405160208183030381529060405280519060200120811461344a5760405163354a450b60e21b815260040160405180910390fd5b60006134598660000151613aef565b905080613511578551604051631d2827a760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e9413d38916134ad9190600401615134565b602060405180830381865afa1580156134ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134ee9190615950565b90508061351157855160405163175dadad60e01b8152610f239190600401615134565b6000876080015182604051602001613533929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c9050600061355a8983613bbd565b6040805160608101825297885260208801969096529486019490945250929695505050505050565b60005a61138881101561359457600080fd5b6113888103905084604082048203116135ac57600080fd5b50823b6135b857600080fd5b60008083516020850160008789f1949350505050565b600081156135fb576011546135f49086908690600160201b900463ffffffff1686613c28565b9050613615565b601154613612908690869063ffffffff1686613cca565b90505b949350505050565b6000805b60125481101561367d57826001600160a01b0316601282815481106136485761364861544e565b6000918252602090912001546001600160a01b03160361366b5750600192915050565b8061367581615464565b915050613621565b50600092915050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b8181101561372857600460008483815481106136db576136db61544e565b60009182526020808320909101546001600160a01b031683528281019390935260409182018120898252909252902080546001600160881b031916905561372181615464565b90506136bd565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906137606002830182614bf3565b505060008581526006602052604081205561377c600886613def565b506001600160601b038416156137cf57600a80548591906000906137aa9084906001600160601b0316615420565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156138275782600a600c8282829054906101000a90046001600160601b03166138029190615420565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b60408051602081018690526001600160a01b03851691810191909152606081018390526001600160401b03821660808201526000908190819060a00160408051601f198184030181529082905280516020918201209250613893918991849101615440565b60408051808303601f19018152919052805160209091012097909650945050505050565b60408051602081019091526000815260008290036138e4575060408051602081019091526000815261252f565b63125fa26760e31b6138f683856159bd565b6001600160e01b0319161461391e57604051632923fee760e11b815260040160405180910390fd5b61392b82600481866159ed565b810190610eec9190615a17565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa8260405160240161397191511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b6000466139b581613dfb565b15613a235760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156139f9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a1d9190615950565b91505090565b4391505090565b6000610eec8383613e1e565b600061252f825490565b6000610eec8383613e6d565b336001600160a01b03821603613a9e5760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610f23565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613afb81613dfb565b15613bae57610100836001600160401b0316613b156139a9565b613b1f91906154b6565b1180613b3b5750613b2e6139a9565b836001600160401b031610155b15613b495750600092915050565b6040516315a03d4160e11b8152606490632b407a8290613b6d908690600401615134565b602060405180830381865afa158015613b8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eec9190615950565b50506001600160401b03164090565b6000613bf18360000151846020015185604001518660600151868860a001518960c001518a60e001518b6101000151613e97565b60038360200151604051602001613c09929190615a62565b60408051601f1981840301815291905280516020909101209392505050565b600080613c6b6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506140b292505050565b905060005a613c7a8888615619565b613c8491906154b6565b613c8e9085615a76565b90506000613ca763ffffffff871664e8d4a51000615a76565b905082613cb48284615619565b613cbe9190615619565b98975050505050505050565b600080613cd561417c565b905060008113613cfb576040516321ea67b360e11b815260048101829052602401610f23565b6000613d3d6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506140b292505050565b9050600082825a613d4e8b8b615619565b613d5891906154b6565b613d629088615a76565b613d6c9190615619565b613d7e90670de0b6b3a7640000615a76565b613d889190615aa3565b90506000613da163ffffffff881664e8d4a51000615a76565b9050613db881676765c793fa10079d601b1b6154b6565b821115613dd85760405163e80fa38160e01b815260040160405180910390fd5b613de28183615619565b9998505050505050505050565b6000610eec8383614238565b600061a4b1821480613e0f575062066eed82145b8061252f57505062066eee1490565b6000818152600183016020526040812054613e655750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561252f565b50600061252f565b6000826000018281548110613e8457613e8461544e565b9060005260206000200154905092915050565b613ea089614332565b613ee95760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610f23565b613ef288614332565b613f365760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610f23565b613f3f83614332565b613f8b5760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610f23565b613f9482614332565b613fdf5760405162461bcd60e51b815260206004820152601c60248201527b73486173685769746e657373206973206e6f74206f6e20637572766560201b6044820152606401610f23565b613feb878a88876143f5565b6140335760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610f23565b600061403f8a87614509565b90506000614052898b878b86898961456d565b90506000614063838d8d8a86614680565b9050808a146140a45760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610f23565b505050505050505050505050565b6000466140be81613dfb565b1561410257606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613b8a573d6000803e3d6000fd5b61410b816146c0565b1561367d57600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615c0d60489139604051602001614151929190615ab7565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613b6d91906155ae565b600c5460035460408051633fabe5a360e21b81529051600093600160381b900463ffffffff169283151592859283926001600160a01b03169163feaf968c9160048083019260a09291908290030181865afa1580156141df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906142039190615afd565b509450909250849150508015614227575061421e82426154b6565b8463ffffffff16105b156136155750601054949350505050565b6000818152600183016020526040812054801561432157600061425c6001836154b6565b8554909150600090614270906001906154b6565b90508181146142d55760008660000182815481106142905761429061544e565b90600052602060002001549050808760000184815481106142b3576142b361544e565b6000918252602080832090910192909255918252600188019052604090208390555b85548690806142e6576142e66157f8565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061252f565b600091505061252f565b5092915050565b80516000906401000003d019116143805760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610f23565b60208201516401000003d019116143ce5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610f23565b60208201516401000003d0199080096143ee8360005b60200201516146fa565b1492915050565b60006001600160a01b03821661443b5760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610f23565b60208401516000906001161561445257601c614455565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe19918203925060009190890987516040805160008082526020909101918290529293506001916144bf91869188918790615b4d565b6020604051602081039080840390855afa1580156144e1573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614511614c11565b61453e6001848460405160200161452a93929190615b6b565b60405160208183030381529060405261471e565b90505b61454a81614332565b61252f578051604080516020810192909252614566910161452a565b9050614541565b614575614c11565b825186516401000003d01991829006919006036145d45760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610f23565b6145df87898861476b565b6146245760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610f23565b61462f84868561476b565b6146755760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610f23565b613cbe868484614889565b60006002868686858760405160200161469e96959493929190615b8c565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a8214806146d257506101a482145b806146df575062aa37dc82145b806146eb575061210582145b8061252f57505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614726614c11565b61472f8261494c565b815261474461473f8260006143e4565b614987565b6020820181905260029006600103611e90576020810180516401000003d019039052919050565b6000826000036147ab5760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610f23565b835160208501516000906147c190600290615be6565b156147cd57601c6147d0565b601b5b9050600070014551231950b75fc4402da1732fc9bebe19838709604080516000808252602090910191829052919250600190614813908390869088908790615b4d565b6020604051602081039080840390855afa158015614835573d6000803e3d6000fd5b5050506020604051035190506000866040516020016148549190615bfa565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614891614c11565b8351602080860151855191860151600093849384936148b2939091906149a7565b919450925090506401000003d01985820960011461490e5760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610f23565b60405180604001604052806401000003d0198061492d5761492d615a8d565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611e9057604080516020808201939093528151808203840181529082019091528051910120614954565b600061252f8260026149a06401000003d0196001615619565b901c614a87565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a08905060006149e783838585614b21565b90985090506149f888828e88614b45565b9098509050614a0988828c87614b45565b90985090506000614a1c8d878b85614b45565b9098509050614a2d88828686614b21565b9098509050614a3e88828e89614b45565b9098509050818114614a73576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614a77565b8196505b5050505050509450945094915050565b600080614a92614c2f565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614ac4614c4d565b60208160c0846005600019fa925082600003614b175760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610f23565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614be3579160200282015b82811115614be357825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614bae565b50614bef929150614c6b565b5090565b50805460008255906000526020600020908101906130999190614c6b565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614bef5760008155600101614c6c565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015614cd157845183529383019391830191600101614cb5565b509098975050505050505050565b6001600160a01b038116811461309957600080fd5b8035611e9081614cdf565b60008060408385031215614d1257600080fd5b823591506020830135614d2481614cdf565b809150509250929050565b6001600160a01b0391909116815260200190565b600060208284031215614d5557600080fd5b8135610eec81614cdf565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b0381118282101715614d9857614d98614d60565b60405290565b60405161012081016001600160401b0381118282101715614d9857614d98614d60565b604051601f8201601f191681016001600160401b0381118282101715614de957614de9614d60565b604052919050565b600082601f830112614e0257600080fd5b604080519081016001600160401b0381118282101715614e2457614e24614d60565b8060405250806040840185811115614e3b57600080fd5b845b81811015614e55578035835260209283019201614e3d565b509195945050505050565b803563ffffffff81168114611e9057600080fd5b600082601f830112614e8557600080fd5b81356001600160401b03811115614e9e57614e9e614d60565b614eb1601f8201601f1916602001614dc1565b818152846020838601011115614ec657600080fd5b816020850160208301376000918101602001919091529392505050565b600060c08284031215614ef557600080fd5b614efd614d76565b905081356001600160401b038082168214614f1757600080fd5b81835260208401356020840152614f3060408501614e60565b6040840152614f4160608501614e60565b6060840152614f5260808501614cf4565b608084015260a0840135915080821115614f6b57600080fd5b50614f7884828501614e74565b60a08301525092915050565b801515811461309957600080fd5b8035611e9081614f84565b60008060008385036101e0811215614fb457600080fd5b6101a080821215614fc457600080fd5b614fcc614d9e565b9150614fd88787614df1565b8252614fe78760408801614df1565b60208301526080860135604083015260a0860135606083015260c0860135608083015261501660e08701614cf4565b60a083015261010061502a88828901614df1565b60c084015261503d886101408901614df1565b60e0840152610180870135908301529093508401356001600160401b0381111561506657600080fd5b61507286828701614ee3565b9250506150826101c08501614f92565b90509250925092565b60006020828403121561509d57600080fd5b5035919050565b600080604083850312156150b757600080fd5b82356150c281614cdf565b91506020830135614d2481614cdf565b6000604082840312156150e457600080fd5b826040830111156150f457600080fd5b50919050565b60006020828403121561510c57600080fd5b81356001600160401b0381111561512257600080fd5b820160c08185031215610eec57600080fd5b6001600160401b0391909116815260200190565b60008083601f84011261515a57600080fd5b5081356001600160401b0381111561517157600080fd5b60208301915083602082850101111561518957600080fd5b9250929050565b600080600080606085870312156151a657600080fd5b84356151b181614cdf565b93506020850135925060408501356001600160401b038111156151d357600080fd5b6151df87828801615148565b95989497509550505050565b803561ffff81168114611e9057600080fd5b803560ff81168114611e9057600080fd5b60008060008060008060008060006101208a8c03121561522d57600080fd5b6152368a6151eb565b985061524460208b01614e60565b975061525260408b01614e60565b965061526060608b01614e60565b955060808a0135945061527560a08b01614e60565b935061528360c08b01614e60565b925061529160e08b016151fd565b91506152a06101008b016151fd565b90509295985092959850929598565b600080604083850312156152c257600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015615301578151875295820195908201906001016152e5565b509495945050505050565b602081526000610eec60208301846152d1565b60006040828403121561533157600080fd5b610eec8383614df1565b6000806020838503121561534e57600080fd5b82356001600160401b0381111561536457600080fd5b61537085828601615148565b90969095509350505050565b600081518084526020808501945080840160005b838110156153015781516001600160a01b031687529582019590820190600101615390565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a0608082018190526000906153ff9083018461537c565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6001600160601b0382811682821603908082111561432b5761432b61540a565b918252602082015260400190565b634e487b7160e01b600052603260045260246000fd5b6000600182016154765761547661540a565b5060010190565b82815260406020820152600061361560408301846152d1565b6001600160401b0381811683821601908082111561432b5761432b61540a565b8181038181111561252f5761252f61540a565b6001600160601b0381811683821601908082111561432b5761432b61540a565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261552e60e084018261537c565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b60005b83811015615579578181015183820152602001615561565b50506000910152565b6000815180845261559a81602086016020860161555e565b601f01601f19169290920160200192915050565b602081526000610eec6020830184615582565b6001600160a01b039290921682526001600160601b0316602082015260400190565b6000602082840312156155f557600080fd5b8151610eec81614f84565b6001600160a01b03929092168252602082015260400190565b8082018082111561252f5761252f61540a565b9182526001600160a01b0316602082015260400190565b60006020828403121561565557600080fd5b610eec826151eb565b61ffff93841681529183166020830152909116604082015260600190565b60006020828403121561568e57600080fd5b610eec82614e60565b63ffffffff92831681529116602082015260400190565b60006001600160401b038281166002600160401b031981016156d2576156d261540a565b6001019392505050565b6000808335601e198436030181126156f357600080fd5b8301803591506001600160401b0382111561570d57600080fd5b60200191503681900382131561518957600080fd5b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613de290830184615582565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a0830152613cbe60c0830184615582565b6001600160a01b0392831681529116602082015260400190565b8060005b6002811015612d205781518452602093840193909101906001016157cb565b6040810161252f82846157c7565b634e487b7160e01b600052603160045260246000fd5b80356001600160601b0381168114611e9057600080fd5b6000602080838503121561583857600080fd5b82356001600160401b038082111561584f57600080fd5b9084019060c0828703121561586357600080fd5b61586b614d76565b615874836151fd565b81528383013584820152604083013561588c81614cdf565b60408201526060830135828111156158a357600080fd5b8301601f810188136158b457600080fd5b8035838111156158c6576158c6614d60565b8060051b93506158d7868501614dc1565b818152938201860193868101908a8611156158f157600080fd5b928701925b8584101561591b578335925061590b83614cdf565b82825292870192908701906158f6565b6060850152506159309150506080840161580e565b608082015261594160a0840161580e565b60a08201529695505050505050565b60006020828403121561596257600080fd5b5051919050565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c08201819052600090613de290830184615582565b6001600160e01b031981358181169160048510156159e55780818660040360031b1b83161692505b505092915050565b600080858511156159fd57600080fd5b83861115615a0a57600080fd5b5050820193919092039150565b600060208284031215615a2957600080fd5b604051602081016001600160401b0381118282101715615a4b57615a4b614d60565b6040528235615a5981614f84565b81529392505050565b82815260608101610eec60208301846157c7565b808202811582820484141761252f5761252f61540a565b634e487b7160e01b600052601260045260246000fd5b600082615ab257615ab2615a8d565b500490565b60008351615ac981846020880161555e565b835190830190615add81836020880161555e565b01949350505050565b80516001600160501b0381168114611e9057600080fd5b600080600080600060a08688031215615b1557600080fd5b615b1e86615ae6565b9450602086015193506040860151925060608601519150615b4160808701615ae6565b90509295509295909350565b93845260ff9290921660208401526040830152606082015260800190565b838152615b7b60208201846157c7565b606081019190915260800192915050565b868152615b9c60208201876157c7565b615ba960608201866157c7565b615bb660a08201856157c7565b615bc360e08201846157c7565b60609190911b6001600160601b0319166101208201526101340195945050505050565b600082615bf557615bf5615a8d565b500690565b615c0481836157c7565b60400191905056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"blockhashStore\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"internalBalance\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"externalBalance\",\"type\":\"uint256\"}],\"name\":\"BalanceInvariantViolated\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"blockNum\",\"type\":\"uint256\"}],\"name\":\"BlockhashNotInStore\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorNotRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToSendNative\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FailedToTransferLink\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"GasLimitTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"gasPrice\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxGas\",\"type\":\"uint256\"}],\"name\":\"GasPriceExceeded\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IncorrectCommitment\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"IndexOutOfRange\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InsufficientBalance\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidCalldata\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"InvalidConsumer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidExtraArgsTag\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"int256\",\"name\":\"linkWei\",\"type\":\"int256\"}],\"name\":\"InvalidLinkWeiPrice\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"transferredValue\",\"type\":\"uint256\"},{\"internalType\":\"uint96\",\"name\":\"expectedValue\",\"type\":\"uint96\"}],\"name\":\"InvalidNativeBalance\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"premiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"max\",\"type\":\"uint8\"}],\"name\":\"InvalidPremiumPercentage\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"have\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"min\",\"type\":\"uint16\"},{\"internalType\":\"uint16\",\"name\":\"max\",\"type\":\"uint16\"}],\"name\":\"InvalidRequestConfirmations\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidSubscription\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint8\",\"name\":\"requestVersion\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"expectedVersion\",\"type\":\"uint8\"}],\"name\":\"InvalidVersion\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"flatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"flatFeeNativePPM\",\"type\":\"uint32\"}],\"name\":\"LinkDiscountTooHigh\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"LinkNotSet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"have\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"max\",\"type\":\"uint32\"}],\"name\":\"MsgDataTooBig\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"proposedOwner\",\"type\":\"address\"}],\"name\":\"MustBeRequestedOwner\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"MustBeSubOwner\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NoCorrespondingRequest\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"NoSuchProvingKey\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"have\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"want\",\"type\":\"uint32\"}],\"name\":\"NumWordsTooBig\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyCallableFromLink\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PaymentTooLarge\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingRequestExists\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"}],\"name\":\"ProvingKeyAlreadyRegistered\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"Reentrant\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SubscriptionIDCollisionFound\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TooManyConsumers\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"ConfigSet\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"coordinatorAddress\",\"type\":\"address\"}],\"name\":\"CoordinatorRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"}],\"name\":\"FallbackWeiPerUnitLinkUsed\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"FundsRecovered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"MigrationCompleted\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"}],\"name\":\"NativeFundsRecovered\",\"type\":\"event\"},{\"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\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"ProvingKeyRegistered\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"outputSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"nativePayment\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"success\",\"type\":\"bool\"},{\"indexed\":false,\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"RandomWordsFulfilled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"preSeed\",\"type\":\"uint256\"},{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"RandomWordsRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountLink\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"amountNative\",\"type\":\"uint256\"}],\"name\":\"SubscriptionCanceled\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"SubscriptionConsumerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"owner\",\"type\":\"address\"}],\"name\":\"SubscriptionCreated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFunded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"oldNativeBalance\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"uint256\",\"name\":\"newNativeBalance\",\"type\":\"uint256\"}],\"name\":\"SubscriptionFundedWithNative\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"SubscriptionOwnerTransferred\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"BLOCKHASH_STORE\",\"outputs\":[{\"internalType\":\"contractBlockhashStoreInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK\",\"outputs\":[{\"internalType\":\"contractLinkTokenInterface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"LINK_NATIVE_FEED\",\"outputs\":[{\"internalType\":\"contractAggregatorV3Interface\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_CONSUMERS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_NUM_WORDS\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"MAX_REQUEST_CONFIRMATIONS\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"acceptSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"addConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"cancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"createSubscription\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint256[2]\",\"name\":\"pk\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"gamma\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"c\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"s\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"seed\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"uWitness\",\"type\":\"address\"},{\"internalType\":\"uint256[2]\",\"name\":\"cGammaWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256[2]\",\"name\":\"sHashWitness\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint256\",\"name\":\"zInv\",\"type\":\"uint256\"}],\"internalType\":\"structVRF.Proof\",\"name\":\"proof\",\"type\":\"tuple\"},{\"components\":[{\"internalType\":\"uint64\",\"name\":\"blockNum\",\"type\":\"uint64\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFTypes.RequestCommitmentV2Plus\",\"name\":\"rc\",\"type\":\"tuple\"},{\"internalType\":\"bool\",\"name\":\"onlyPremium\",\"type\":\"bool\"}],\"name\":\"fulfillRandomWords\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"payment\",\"type\":\"uint96\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"fundSubscriptionWithNative\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"startIndex\",\"type\":\"uint256\"},{\"internalType\":\"uint256\",\"name\":\"maxCount\",\"type\":\"uint256\"}],\"name\":\"getActiveSubscriptionIds\",\"outputs\":[{\"internalType\":\"uint256[]\",\"name\":\"ids\",\"type\":\"uint256[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getRequestConfig\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"},{\"internalType\":\"bytes32[]\",\"name\":\"\",\"type\":\"bytes32[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"getSubscription\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"balance\",\"type\":\"uint96\"},{\"internalType\":\"uint96\",\"name\":\"nativeBalance\",\"type\":\"uint96\"},{\"internalType\":\"uint64\",\"name\":\"reqCount\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"subOwner\",\"type\":\"address\"},{\"internalType\":\"address[]\",\"name\":\"consumers\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicKey\",\"type\":\"uint256[2]\"}],\"name\":\"hashOfKey\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newCoordinator\",\"type\":\"address\"}],\"name\":\"migrate\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"migrationVersion\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"stateMutability\":\"pure\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"encodedData\",\"type\":\"bytes\"}],\"name\":\"onMigration\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"},{\"internalType\":\"uint256\",\"name\":\"amount\",\"type\":\"uint256\"},{\"internalType\":\"bytes\",\"name\":\"data\",\"type\":\"bytes\"}],\"name\":\"onTokenTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"ownerCancelSubscription\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"}],\"name\":\"pendingRequestExists\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"recoverNativeFunds\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"target\",\"type\":\"address\"}],\"name\":\"registerMigratableCoordinator\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256[2]\",\"name\":\"publicProvingKey\",\"type\":\"uint256[2]\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"name\":\"registerProvingKey\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"consumer\",\"type\":\"address\"}],\"name\":\"removeConsumer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes32\",\"name\":\"keyHash\",\"type\":\"bytes32\"},{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"uint16\",\"name\":\"requestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"callbackGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"numWords\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"extraArgs\",\"type\":\"bytes\"}],\"internalType\":\"structVRFV2PlusClient.RandomWordsRequest\",\"name\":\"req\",\"type\":\"tuple\"}],\"name\":\"requestRandomWords\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"requestId\",\"type\":\"uint256\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"subId\",\"type\":\"uint256\"},{\"internalType\":\"address\",\"name\":\"newOwner\",\"type\":\"address\"}],\"name\":\"requestSubscriptionOwnerTransfer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_config\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"bool\",\"name\":\"reentrancyLock\",\"type\":\"bool\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_currentSubNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_fallbackWeiPerUnitLink\",\"outputs\":[{\"internalType\":\"int256\",\"name\":\"\",\"type\":\"int256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_provingKeyHashes\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"name\":\"s_provingKeys\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"exists\",\"type\":\"bool\"},{\"internalType\":\"uint64\",\"name\":\"maxGas\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"name\":\"s_requestCommitments\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"s_totalNativeBalance\",\"outputs\":[{\"internalType\":\"uint96\",\"name\":\"\",\"type\":\"uint96\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint16\",\"name\":\"minimumRequestConfirmations\",\"type\":\"uint16\"},{\"internalType\":\"uint32\",\"name\":\"maxGasLimit\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"stalenessSeconds\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"gasAfterPaymentCalculation\",\"type\":\"uint32\"},{\"internalType\":\"int256\",\"name\":\"fallbackWeiPerUnitLink\",\"type\":\"int256\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeNativePPM\",\"type\":\"uint32\"},{\"internalType\":\"uint32\",\"name\":\"fulfillmentFlatFeeLinkDiscountPPM\",\"type\":\"uint32\"},{\"internalType\":\"uint8\",\"name\":\"nativePremiumPercentage\",\"type\":\"uint8\"},{\"internalType\":\"uint8\",\"name\":\"linkPremiumPercentage\",\"type\":\"uint8\"}],\"name\":\"setConfig\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"link\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"linkNativeFeed\",\"type\":\"address\"}],\"name\":\"setLINKAndLINKNativeFeed\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdraw\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"addresspayable\",\"name\":\"recipient\",\"type\":\"address\"}],\"name\":\"withdrawNative\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60a06040523480156200001157600080fd5b506040516200613f3803806200613f83398101604081905262000034916200017e565b33806000816200008b5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000be57620000be81620000d3565b5050506001600160a01b0316608052620001b0565b336001600160a01b038216036200012d5760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000082565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b6000602082840312156200019157600080fd5b81516001600160a01b0381168114620001a957600080fd5b9392505050565b608051615f6c620001d36000396000818161052e01526133610152615f6c6000f3fe6080604052600436106101f65760003560e01c8062012291146101fb578063043bd6ae14610228578063088070f51461024c5780630ae095401461031a57806315c48b841461033c57806318e3dd27146103645780631b6b6d23146103a3578063294daa49146103d05780632f622e6b146103ec578063301f42e91461040c578063405b84fa1461042c57806340d6bb821461044c57806341af6c871461047757806351cff8d9146104a75780635d06b4ab146104c757806364d51a2a146104e757806365982744146104fc578063689c45171461051c57806372e9d5651461055057806379ba5097146105705780637a5a2aef146105855780638402595e146105a557806386fe91c7146105c55780638da5cb5b146105e557806395b55cfc146106035780639b1c385e146106165780639d40a6fd14610636578063a21a23e414610663578063a4c0ed3614610678578063a63e0bfb14610698578063aa433aff146106b8578063aefb212f146106d8578063b2a7cac514610705578063bec4c08c14610725578063caf70c4a14610745578063cb63179714610765578063ce3f471914610785578063d98e620e14610798578063da2f2610146107b8578063dac83d2914610817578063dc311dd314610837578063e72f6e3014610868578063ee9d2d3814610888578063f2fde38b146108b5575b600080fd5b34801561020757600080fd5b506102106108d5565b60405161021f93929190614eeb565b60405180910390f35b34801561023457600080fd5b5061023e60105481565b60405190815260200161021f565b34801561025857600080fd5b50600c546102bd9061ffff81169063ffffffff62010000820481169160ff600160301b8204811692600160381b8304811692600160581b8104821692600160781b8204831692600160981b83041691600160b81b8104821691600160c01b9091041689565b6040805161ffff909a168a5263ffffffff98891660208b01529615159689019690965293861660608801529185166080870152841660a08601529290921660c084015260ff91821660e0840152166101008201526101200161021f565b34801561032657600080fd5b5061033a610335366004614f6a565b610951565b005b34801561034857600080fd5b5061035160c881565b60405161ffff909116815260200161021f565b34801561037057600080fd5b50600a5461038b90600160601b90046001600160601b031681565b6040516001600160601b03909116815260200161021f565b3480156103af57600080fd5b506002546103c3906001600160a01b031681565b60405161021f9190614f9a565b3480156103dc57600080fd5b506040516002815260200161021f565b3480156103f857600080fd5b5061033a610407366004614fae565b610999565b34801561041857600080fd5b5061038b6104273660046151fd565b610ae8565b34801561043857600080fd5b5061033a610447366004614f6a565b610e02565b34801561045857600080fd5b506104626101f481565b60405163ffffffff909116815260200161021f565b34801561048357600080fd5b506104976104923660046152eb565b6111a5565b604051901515815260200161021f565b3480156104b357600080fd5b5061033a6104c2366004614fae565b611259565b3480156104d357600080fd5b5061033a6104e2366004614fae565b6113db565b3480156104f357600080fd5b50610351606481565b34801561050857600080fd5b5061033a610517366004615304565b611492565b34801561052857600080fd5b506103c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561055c57600080fd5b506003546103c3906001600160a01b031681565b34801561057c57600080fd5b5061033a6114f2565b34801561059157600080fd5b5061033a6105a0366004615332565b61159c565b3480156105b157600080fd5b5061033a6105c0366004614fae565b6116d8565b3480156105d157600080fd5b50600a5461038b906001600160601b031681565b3480156105f157600080fd5b506000546001600160a01b03166103c3565b61033a6106113660046152eb565b6117e4565b34801561062257600080fd5b5061023e61063136600461536c565b611905565b34801561064257600080fd5b50600754610656906001600160401b031681565b60405161021f91906153a6565b34801561066f57600080fd5b5061023e611cbf565b34801561068457600080fd5b5061033a610693366004615402565b611e92565b3480156106a457600080fd5b5061033a6106b3366004615480565b61200c565b3480156106c457600080fd5b5061033a6106d33660046152eb565b6122ae565b3480156106e457600080fd5b506106f86106f3366004615521565b6122f6565b60405161021f919061557e565b34801561071157600080fd5b5061033a6107203660046152eb565b6123f8565b34801561073157600080fd5b5061033a610740366004614f6a565b6124ed565b34801561075157600080fd5b5061023e610760366004615591565b6125df565b34801561077157600080fd5b5061033a610780366004614f6a565b61260f565b61033a6107933660046155ad565b612871565b3480156107a457600080fd5b5061023e6107b33660046152eb565b612bd8565b3480156107c457600080fd5b506107f86107d33660046152eb565b600d6020526000908152604090205460ff81169061010090046001600160401b031682565b6040805192151583526001600160401b0390911660208301520161021f565b34801561082357600080fd5b5061033a610832366004614f6a565b612bf9565b34801561084357600080fd5b506108576108523660046152eb565b612c8f565b60405161021f959493929190615627565b34801561087457600080fd5b5061033a610883366004614fae565b612d7d565b34801561089457600080fd5b5061023e6108a33660046152eb565b600f6020526000908152604090205481565b3480156108c157600080fd5b5061033a6108d0366004614fae565b612f3a565b600c54600e805460408051602080840282018101909252828152600094859460609461ffff8316946201000090930463ffffffff1693919283919083018282801561093f57602002820191906000526020600020905b81548152602001906001019080831161092b575b50505050509050925092509250909192565b8161095b81612f4e565b610963612faf565b61096c836111a5565b1561098a57604051631685ecdd60e31b815260040160405180910390fd5b6109948383612fdc565b505050565b6109a1612faf565b6109a9613181565b600b54600160601b90046001600160601b03166000036109dc57604051631e9acf1760e31b815260040160405180910390fd5b600b8054600160601b90046001600160601b0316908190600c6109ff8380615692565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a600c8282829054906101000a90046001600160601b0316610a479190615692565b92506101000a8154816001600160601b0302191690836001600160601b031602179055506000826001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114610ac1576040519150601f19603f3d011682016040523d82523d6000602084013e610ac6565b606091505b50509050806109945760405163950b247960e01b815260040160405180910390fd5b6000610af2612faf565b60005a9050610324361115610b2957604051630f28961b60e01b815236600482015261032460248201526044015b60405180910390fd5b6000610b3586866131d4565b90506000610b4b8583600001516020015161346b565b60408301516060888101519293509163ffffffff16806001600160401b03811115610b7857610b78614fcb565b604051908082528060200260200182016040528015610ba1578160200160208202803683370190505b50925060005b81811015610c08578281604051602001610bc29291906156b2565b6040516020818303038152906040528051906020012060001c848281518110610bed57610bed6156c0565b6020908102919091010152610c01816156d6565b9050610ba7565b5050602080850180516000908152600f9092526040822082905551610c2e908a856134b9565b60208a8101516000908152600690915260409020805491925090601890610c6490600160c01b90046001600160401b03166156ef565b82546101009290920a6001600160401b0381810219909316918316021790915560808a01516001600160a01b03166000908152600460209081526040808320828e01518452909152902080549091600991610cc791600160481b9091041661571d565b91906101000a8154816001600160401b0302191690836001600160401b0316021790555060008960a0015160018b60a0015151610d049190615740565b81518110610d1457610d146156c0565b60209101015160f81c60011490506000610d308887848d613554565b90995090508015610d7b577f6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a8760200151601054604051610d729291906156b2565b60405180910390a15b50610d8b88828c6020015161358c565b6020808b015187820151604080518781526001600160601b038d16948101949094528415159084015284151560608401528b1515608084015290917faeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b79060a00160405180910390a3505050505050505b9392505050565b610e0a612faf565b610e13816136df565b610e325780604051635428d44960e01b8152600401610b209190614f9a565b600080600080610e4186612c8f565b945094505093509350336001600160a01b0316826001600160a01b031614610ea45760405162461bcd60e51b81526020600482015260166024820152752737ba1039bab139b1b934b83a34b7b71037bbb732b960511b6044820152606401610b20565b610ead866111a5565b15610ef35760405162461bcd60e51b815260206004820152601660248201527550656e64696e6720726571756573742065786973747360501b6044820152606401610b20565b6040805160c0810182526001815260208082018990526001600160a01b03851682840152606082018490526001600160601b038088166080840152861660a083015291519091600091610f4891849101615753565b6040516020818303038152906040529050610f628861374a565b505060405163ce3f471960e01b81526001600160a01b0388169063ce3f4719906001600160601b03881690610f9b908590600401615818565b6000604051808303818588803b158015610fb457600080fd5b505af1158015610fc8573d6000803e3d6000fd5b50506002546001600160a01b031615801593509150610ff1905057506001600160601b03861615155b156110ac5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611028908a908a9060040161582b565b6020604051808303816000875af1158015611047573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061106b919061584d565b6110ac5760405162461bcd60e51b8152602060048201526012602482015271696e73756666696369656e742066756e647360701b6044820152606401610b20565b600c805460ff60301b1916600160301b17905560005b8351811015611153578381815181106110dd576110dd6156c0565b60200260200101516001600160a01b0316638ea98117896040518263ffffffff1660e01b81526004016111109190614f9a565b600060405180830381600087803b15801561112a57600080fd5b505af115801561113e573d6000803e3d6000fd5b505050508061114c906156d6565b90506110c2565b50600c805460ff60301b191690556040517fd63ca8cb945956747ee69bfdc3ea754c24a4caf7418db70e46052f7850be4187906111939089908b9061586a565b60405180910390a15050505050505050565b600081815260056020526040812060020180548083036111c9575060009392505050565b60005b8181101561124e576000600460008584815481106111ec576111ec6156c0565b60009182526020808320909101546001600160a01b0316835282810193909352604091820181208982529092529020546001600160401b03600160481b90910416111561123e57506001949350505050565b611247816156d6565b90506111cc565b506000949350505050565b611261612faf565b611269613181565b6002546001600160a01b03166112925760405163c1f0c0a160e01b815260040160405180910390fd5b600b546001600160601b03166000036112be57604051631e9acf1760e31b815260040160405180910390fd5b600b80546001600160601b031690819060006112da8380615692565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555080600a60008282829054906101000a90046001600160601b03166113229190615692565b82546001600160601b039182166101009390930a92830291909202199091161790555060025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb90611377908590859060040161582b565b6020604051808303816000875af1158015611396573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113ba919061584d565b6113d757604051631e9acf1760e31b815260040160405180910390fd5b5050565b6113e3613181565b6113ec816136df565b1561140c578060405163ac8a27ef60e01b8152600401610b209190614f9a565b601180546001810182556000919091527f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680180546001600160a01b0319166001600160a01b0383161790556040517fb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af0162590611487908390614f9a565b60405180910390a150565b61149a613181565b6002546001600160a01b0316156114c457604051631688c53760e11b815260040160405180910390fd5b600280546001600160a01b039384166001600160a01b03199182161790915560038054929093169116179055565b6001546001600160a01b031633146115455760405162461bcd60e51b815260206004820152601660248201527526bab9ba10313290383937b837b9b2b21037bbb732b960511b6044820152606401610b20565b60008054336001600160a01b0319808316821784556001805490911690556040516001600160a01b0390921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b6115a4613181565b6040805180820182526000916115d39190859060029083908390808284376000920191909152506125df915050565b6000818152600d602052604090205490915060ff161561160957604051634a0b8fa760e01b815260048101829052602401610b20565b60408051808201825260018082526001600160401b0385811660208085019182526000878152600d9091528581209451855492516001600160481b0319909316901515610100600160481b03191617610100929093169190910291909117909255600e805491820181559091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01829055517f9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd3906116cb9083908590615883565b60405180910390a1505050565b6116e0613181565b600a544790600160601b90046001600160601b03168181111561171a5780826040516354ced18160e11b8152600401610b209291906156b2565b8181101561099457600061172e8284615740565b90506000846001600160a01b03168260405160006040518083038185875af1925050503d806000811461177d576040519150601f19603f3d011682016040523d82523d6000602084013e611782565b606091505b50509050806117a45760405163950b247960e01b815260040160405180910390fd5b7f4aed7c8eed0496c8c19ea2681fcca25741c1602342e38b045d9f1e8e905d2e9c85836040516117d592919061586a565b60405180910390a15050505050565b6117ec612faf565b6000818152600560205260409020546001600160a01b031661182157604051630fb532db60e11b815260040160405180910390fd5b60008181526006602052604090208054600160601b90046001600160601b0316903490600c611850838561589a565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555034600a600c8282829054906101000a90046001600160601b0316611898919061589a565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f7603b205d03651ee812f803fccde89f1012e545a9c99f0abfea9cedd0fd8e9028234846118eb91906158ba565b6040516118f99291906156b2565b60405180910390a25050565b600061190f612faf565b602080830135600081815260059092526040909120546001600160a01b031661194b57604051630fb532db60e11b815260040160405180910390fd5b336000908152600460209081526040808320848452808352928190208151606081018352905460ff811615158083526001600160401b036101008304811695840195909552600160481b90910490931691810191909152906119c45782336040516379bfd40160e01b8152600401610b209291906158cd565b600c5461ffff166119db60608701604088016158e4565b61ffff1610806119fe575060c86119f860608701604088016158e4565b61ffff16115b15611a3857611a1360608601604087016158e4565b600c5460405163539c34bb60e11b8152610b20929161ffff169060c8906004016158ff565b600c5462010000900463ffffffff16611a57608087016060880161591d565b63ffffffff161115611a9d57611a73608086016060870161591d565b600c54604051637aebf00f60e11b8152610b20929162010000900463ffffffff1690600401615938565b6101f4611ab060a087016080880161591d565b63ffffffff161115611aea57611acc60a086016080870161591d565b6101f46040516311ce1afb60e21b8152600401610b20929190615938565b806020018051611af9906156ef565b6001600160401b03169052604081018051611b13906156ef565b6001600160401b031690526020810151600090611b3690873590339087906138f2565b90955090506000611b5a611b55611b5060a08a018a61594f565b61397b565b6139fc565b905085611b65613a6d565b86611b7660808b0160608c0161591d565b611b8660a08c0160808d0161591d565b3386604051602001611b9e9796959493929190615995565b60405160208183030381529060405280519060200120600f600088815260200190815260200160002081905550336001600160a01b03168588600001357feb0e3652e0f44f417695e6e90f2f42c99b65cd7169074c5a654b16b9748c3a4e89868c6040016020810190611c1191906158e4565b8d6060016020810190611c24919061591d565b8e6080016020810190611c37919061591d565b89604051611c4a969594939291906159ee565b60405180910390a4505060009283526020918252604092839020815181549383015192909401516001600160481b0319909316931515610100600160481b031916939093176101006001600160401b039283160217600160481b600160881b031916600160481b91909216021790555b919050565b6000611cc9612faf565b6007546001600160401b031633611ce1600143615740565b6040516001600160601b0319606093841b81166020830152914060348201523090921b1660548201526001600160c01b031960c083901b16606882015260700160408051601f1981840301815291905280516020909101209150611d46816001615a2d565b600780546001600160401b0319166001600160401b03928316179055604080516000808252608082018352602080830182815283850183815260608086018581528a86526006855287862093518454935191516001600160601b039182166001600160c01b031990951694909417600160601b9190921602176001600160c01b0316600160c01b9290981691909102969096179055835194850184523385528481018281528585018481528884526005835294909220855181546001600160a01b03199081166001600160a01b039283161783559351600183018054909516911617909255925180519294939192611e449260028501920190614df9565b50611e5491506008905084613aee565b50827f1d3015d7ba850fa198dc7b1a3f5d42779313a681035f77c8c03764c61005518d33604051611e859190614f9a565b60405180910390a2505090565b611e9a612faf565b6002546001600160a01b03163314611ec5576040516344b0e3c360e01b815260040160405180910390fd5b60208114611ee657604051638129bbcd60e01b815260040160405180910390fd5b6000611ef4828401846152eb565b6000818152600560205260409020549091506001600160a01b0316611f2c57604051630fb532db60e11b815260040160405180910390fd5b600081815260066020526040812080546001600160601b031691869190611f53838561589a565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555084600a60008282829054906101000a90046001600160601b0316611f9b919061589a565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550817f1ced9348ff549fceab2ac57cd3a9de38edaaab274b725ee82c23e8fc8c4eec7a828784611fee91906158ba565b604051611ffc9291906156b2565b60405180910390a2505050505050565b612014613181565b60c861ffff8a16111561204157888960c860405163539c34bb60e11b8152600401610b20939291906158ff565b60008513612065576040516321ea67b360e11b815260048101869052602401610b20565b8363ffffffff168363ffffffff1611156120965782846040516313c06e5960e11b8152600401610b20929190615938565b609b60ff831611156120c05781609b604051631d66288d60e11b8152600401610b20929190615a4d565b609b60ff821611156120ea5780609b604051631d66288d60e11b8152600401610b20929190615a4d565b604080516101208101825261ffff8b1680825263ffffffff808c16602084018190526000848601528b8216606085018190528b8316608086018190528a841660a08701819052938a1660c0870181905260ff808b1660e08901819052908a16610100909801889052600c8054600160c01b90990260ff60c01b19600160b81b9093029290921661ffff60b81b19600160981b90940263ffffffff60981b19600160781b90990298909816600160781b600160b81b0319600160581b90960263ffffffff60581b19600160381b90980297909716600160301b600160781b03196201000090990265ffffffffffff19909c16909a179a909a1796909616979097179390931791909116959095179290921793909316929092179190911790556010869055517f2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b69061229b908b908b908b908b908b908b908b908b908b9061ffff99909916895263ffffffff97881660208a0152958716604089015293861660608801526080870192909252841660a086015290921660c084015260ff91821660e0840152166101008201526101200190565b60405180910390a1505050505050505050565b6122b6613181565b6000818152600560205260409020546001600160a01b0316806122ec57604051630fb532db60e11b815260040160405180910390fd5b6113d78282612fdc565b606060006123046008613afa565b905080841061232657604051631390f2a160e01b815260040160405180910390fd5b600061233284866158ba565b905081811180612340575083155b61234a578061234c565b815b9050600061235a8683615740565b9050806001600160401b0381111561237457612374614fcb565b60405190808252806020026020018201604052801561239d578160200160208202803683370190505b50935060005b818110156123ed576123c06123b888836158ba565b600890613b04565b8582815181106123d2576123d26156c0565b60209081029190910101526123e6816156d6565b90506123a3565b505050505b92915050565b612400612faf565b6000818152600560205260409020546001600160a01b03168061243657604051630fb532db60e11b815260040160405180910390fd5b6000828152600560205260409020600101546001600160a01b0316331461248d576000828152600560205260409081902060010154905163d084e97560e01b8152610b20916001600160a01b031690600401614f9a565b600082815260056020526040908190208054336001600160a01b031991821681178355600190920180549091169055905183917fd4114ab6e9af9f597c52041f32d62dc57c5c4e4c0d4427006069635e216c9386916118f9918591615a61565b816124f781612f4e565b6124ff612faf565b6001600160a01b03821660009081526004602090815260408083208684529091529020805460ff16156125325750505050565b6000848152600560205260409020600201805460631901612566576040516305a48e0f60e01b815260040160405180910390fd5b8154600160ff1990911681178355815490810182556000828152602090200180546001600160a01b0319166001600160a01b03861617905560405185907f1e980d04aa7648e205713e5e8ea3808672ac163d10936d36f91b2c88ac1575e1906125d0908790614f9a565b60405180910390a25050505050565b6000816040516020016125f29190615a9e565b604051602081830303815290604052805190602001209050919050565b8161261981612f4e565b612621612faf565b61262a836111a5565b1561264857604051631685ecdd60e31b815260040160405180910390fd5b6001600160a01b038216600090815260046020908152604080832086845290915290205460ff166126905782826040516379bfd40160e01b8152600401610b209291906158cd565b6000838152600560209081526040808320600201805482518185028101850190935280835291929091908301828280156126f357602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116126d5575b5050505050905060006001825161270a9190615740565b905060005b825181101561281357846001600160a01b0316838281518110612734576127346156c0565b60200260200101516001600160a01b03160361280357600083838151811061275e5761275e6156c0565b6020026020010151905080600560008981526020019081526020016000206002018381548110612790576127906156c0565b600091825260208083209190910180546001600160a01b0319166001600160a01b0394909416939093179092558881526005909152604090206002018054806127db576127db615aac565b600082815260209020810160001990810180546001600160a01b031916905501905550612813565b61280c816156d6565b905061270f565b506001600160a01b038416600090815260046020908152604080832088845290915290819020805460ff191690555185907f32158c6058347c1601b2d12bc696ac6901d8a9a9aa3ba10c27ab0a983e8425a7906125d0908790614f9a565b600061287f82840184615ad9565b9050806000015160ff166001146128af57805160405163237d181f60e21b8152610b209190600190600401615a4d565b8060a001516001600160601b031634146128f35760a08101516040516306acf13560e41b81523460048201526001600160601b039091166024820152604401610b20565b6020808201516000908152600590915260409020546001600160a01b03161561292f576040516326afa43560e11b815260040160405180910390fd5b60005b816060015151811015612a2857604051806060016040528060011515815260200160006001600160401b0316815260200160006001600160401b0316815250600460008460600151848151811061298b5761298b6156c0565b6020908102919091018101516001600160a01b0316825281810192909252604090810160009081208684015182528352819020835181549385015194909201516001600160481b0319909316911515610100600160481b031916919091176101006001600160401b039485160217600160481b600160881b031916600160481b939092169290920217905580612a20816156d6565b915050612932565b50604080516060808201835260808401516001600160601b03908116835260a0850151811660208085019182526000858701818152828901805183526006845288832097518854955192516001600160401b0316600160c01b026001600160c01b03938816600160601b026001600160c01b0319909716919097161794909417169390931790945584518084018652868601516001600160a01b03908116825281860184815294880151828801908152925184526005865295909220825181549087166001600160a01b0319918216178255935160018201805491909716941693909317909455925180519192612b2792600285019290910190614df9565b5050506080810151600a8054600090612b4a9084906001600160601b031661589a565b92506101000a8154816001600160601b0302191690836001600160601b031602179055508060a00151600a600c8282829054906101000a90046001600160601b0316612b96919061589a565b92506101000a8154816001600160601b0302191690836001600160601b03160217905550612bd281602001516008613aee90919063ffffffff16565b50505050565b600e8181548110612be857600080fd5b600091825260209091200154905081565b81612c0381612f4e565b612c0b612faf565b600083815260056020526040902060018101546001600160a01b03848116911614612bd2576001810180546001600160a01b0319166001600160a01b03851617905560405184907f21a4dad170a6bf476c31bbcf4a16628295b0e450672eec25d7c93308e05344a190612c819033908790615a61565b60405180910390a250505050565b600081815260056020526040812054819081906001600160a01b0316606081612ccb57604051630fb532db60e11b815260040160405180910390fd5b600086815260066020908152604080832054600583529281902060020180548251818502810185019093528083526001600160601b0380861695600160601b810490911694600160c01b9091046001600160401b0316938893929091839190830182828015612d6357602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612d45575b505050505090509450945094509450945091939590929450565b612d85613181565b6002546001600160a01b0316612dae5760405163c1f0c0a160e01b815260040160405180910390fd5b6002546040516370a0823160e01b81526000916001600160a01b0316906370a0823190612ddf903090600401614f9a565b602060405180830381865afa158015612dfc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e209190615c04565b600a549091506001600160601b031681811115612e545780826040516354ced18160e11b8152600401610b209291906156b2565b81811015610994576000612e688284615740565b60025460405163a9059cbb60e01b81529192506001600160a01b03169063a9059cbb90612e9b908790859060040161586a565b6020604051808303816000875af1158015612eba573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ede919061584d565b612efb57604051631f01ff1360e21b815260040160405180910390fd5b7f59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b4366008482604051612f2c92919061586a565b60405180910390a150505050565b612f42613181565b612f4b81613b10565b50565b6000818152600560205260409020546001600160a01b031680612f8457604051630fb532db60e11b815260040160405180910390fd5b336001600160a01b038216146113d75780604051636c51fda960e11b8152600401610b209190614f9a565b600c54600160301b900460ff1615612fda5760405163769dd35360e11b815260040160405180910390fd5b565b600080612fe88461374a565b60025491935091506001600160a01b03161580159061300f57506001600160601b03821615155b156130af5760025460405163a9059cbb60e01b81526001600160a01b039091169063a9059cbb9061304f9086906001600160601b0387169060040161586a565b6020604051808303816000875af115801561306e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613092919061584d565b6130af57604051631e9acf1760e31b815260040160405180910390fd5b6000836001600160a01b0316826001600160601b031660405160006040518083038185875af1925050503d8060008114613105576040519150601f19603f3d011682016040523d82523d6000602084013e61310a565b606091505b505090508061312c5760405163950b247960e01b815260040160405180910390fd5b604080516001600160a01b03861681526001600160601b03808616602083015284169181019190915285907f8c74ce8b8cf87f5eb001275c8be27eb34ea2b62bfab6814fcc62192bb63e81c4906060016125d0565b6000546001600160a01b03163314612fda5760405162461bcd60e51b815260206004820152601660248201527527b7363c9031b0b63630b1363290313c9037bbb732b960511b6044820152606401610b20565b6040805160a0810182526000606082018181526080830182905282526020820181905291810191909152600061320d84600001516125df565b6000818152600d602090815260409182902082518084019093525460ff811615158084526101009091046001600160401b0316918301919091529192509061326b57604051631dfd6e1360e21b815260048101839052602401610b20565b60008286608001516040516020016132849291906156b2565b60408051601f1981840301815291815281516020928301206000818152600f90935290822054909250908190036132ce57604051631b44092560e11b815260040160405180910390fd5b85516020808801516040808a015160608b015160808c015160a08d015193516132fd978a979096959101615c1d565b6040516020818303038152906040528051906020012081146133325760405163354a450b60e21b815260040160405180910390fd5b60006133418760000151613bb3565b9050806133f9578651604051631d2827a760e31b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163e9413d389161339591906004016153a6565b602060405180830381865afa1580156133b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133d69190615c04565b9050806133f957865160405163175dadad60e01b8152610b2091906004016153a6565b600088608001518260405160200161341b929190918252602082015260400190565b6040516020818303038152906040528051906020012060001c905060006134428a83613c81565b604080516060810182529788526020880196909652948601949094525092979650505050505050565b6000816001600160401b03163a11156134b157821561349457506001600160401b0381166123f2565b3a8260405163435e532d60e11b8152600401610b20929190615883565b503a92915050565b6000806000631fe543e360e01b86856040516024016134d9929190615c71565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b031990941693909317909252600c805460ff60301b1916600160301b17905590860151608087015191925061353d9163ffffffff9091169083613cec565b600c805460ff60301b191690559695505050505050565b600080831561357357613568868685613d38565b600091509150613583565b61357e868685613e49565b915091505b94509492505050565b6000818152600660205260409020821561364b5780546001600160601b03600160601b90910481169085168110156135d757604051631e9acf1760e31b815260040160405180910390fd5b6135e18582615692565b8254600160601b600160c01b031916600160601b6001600160601b039283168102919091178455600b805488939192600c9261362192869290041661589a565b92506101000a8154816001600160601b0302191690836001600160601b0316021790555050612bd2565b80546001600160601b0390811690851681101561367b57604051631e9acf1760e31b815260040160405180910390fd5b6136858582615692565b82546001600160601b0319166001600160601b03918216178355600b805487926000916136b49185911661589a565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505050505050565b601154600090815b8181101561374057836001600160a01b03166011828154811061370c5761370c6156c0565b6000918252602090912001546001600160a01b031603613730575060019392505050565b613739816156d6565b90506136e7565b5060009392505050565b60008181526005602090815260408083206006909252822054600290910180546001600160601b0380841694600160601b90940416925b818110156137ec576004600084838154811061379f5761379f6156c0565b60009182526020808320909101546001600160a01b031683528281019390935260409182018120898252909252902080546001600160881b03191690556137e5816156d6565b9050613781565b50600085815260056020526040812080546001600160a01b031990811682556001820180549091169055906138246002830182614e5e565b505060008581526006602052604081205561384060088661403a565b506001600160601b0384161561389357600a805485919060009061386e9084906001600160601b0316615692565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b6001600160601b038316156138eb5782600a600c8282829054906101000a90046001600160601b03166138c69190615692565b92506101000a8154816001600160601b0302191690836001600160601b031602179055505b5050915091565b60408051602081018690526001600160a01b03851691810191909152606081018390526001600160401b03821660808201526000908190819060a00160408051601f1981840301815290829052805160209182012092506139579189918491016156b2565b60408051808303601f19018152919052805160209091012097909650945050505050565b60408051602081019091526000815260008290036139a857506040805160208101909152600081526123f2565b63125fa26760e31b6139ba8385615c92565b6001600160e01b031916146139e257604051632923fee760e11b815260040160405180910390fd5b6139ef8260048186615cc2565b810190610dfb9190615cec565b60607f92fd13387c7fe7befbc38d303d6468778fb9731bc4583f17d92989c6fcfdeaaa82604051602401613a3591511515815260200190565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915292915050565b600046613a7981614046565b15613ae75760646001600160a01b031663a3b1b31d6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613abd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ae19190615c04565b91505090565b4391505090565b6000610dfb8383614069565b60006123f2825490565b6000610dfb83836140b8565b336001600160a01b03821603613b625760405162461bcd60e51b815260206004820152601760248201527621b0b73737ba103a3930b739b332b9103a379039b2b63360491b6044820152606401610b20565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b600046613bbf81614046565b15613c7257610100836001600160401b0316613bd9613a6d565b613be39190615740565b1180613bff5750613bf2613a6d565b836001600160401b031610155b15613c0d5750600092915050565b6040516315a03d4160e11b8152606490632b407a8290613c319086906004016153a6565b602060405180830381865afa158015613c4e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dfb9190615c04565b50506001600160401b03164090565b6000613cb58360000151846020015185604001518660600151868860a001518960c001518a60e001518b61010001516140e2565b60038360200151604051602001613ccd929190615d37565b60408051601f1981840301815291905280516020909101209392505050565b60005a611388811015613cfe57600080fd5b611388810390508460408204820311613d1657600080fd5b50823b613d2257600080fd5b60008083516020850160008789f1949350505050565b600080613d7b6000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506142fd92505050565b905060005a600c54613d9b908890600160581b900463ffffffff166158ba565b613da59190615740565b613daf9086615d4b565b600c54909150600090613dd490600160781b900463ffffffff1664e8d4a51000615d4b565b90508415613e2057600c548190606490600160b81b900460ff16613df885876158ba565b613e029190615d4b565b613e0c9190615d78565b613e1691906158ba565b9350505050610dfb565b600c548190606490613e3c90600160b81b900460ff1682615d8c565b60ff16613df885876158ba565b600080600080613e576143d0565b9150915060008213613e7f576040516321ea67b360e11b815260048101839052602401610b20565b6000613ec16000368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506142fd92505050565b9050600083825a600c54613ee3908d90600160581b900463ffffffff166158ba565b613eed9190615740565b613ef7908b615d4b565b613f0191906158ba565b613f1390670de0b6b3a7640000615d4b565b613f1d9190615d78565b600c54909150600090613f469063ffffffff600160981b8204811691600160781b900416615da5565b613f5b9063ffffffff1664e8d4a51000615d4b565b9050600085613f7283670de0b6b3a7640000615d4b565b613f7c9190615d78565b905060008915613fbd57600c548290606490613fa290600160c01b900460ff1687615d4b565b613fac9190615d78565b613fb691906158ba565b9050613ffd565b600c548290606490613fd990600160c01b900460ff1682615d8c565b613fe69060ff1687615d4b565b613ff09190615d78565b613ffa91906158ba565b90505b676765c793fa10079d601b1b8111156140295760405163e80fa38160e01b815260040160405180910390fd5b9b949a509398505050505050505050565b6000610dfb8383614497565b600061a4b182148061405a575062066eed82145b806123f257505062066eee1490565b60008181526001830160205260408120546140b0575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556123f2565b5060006123f2565b60008260000182815481106140cf576140cf6156c0565b9060005260206000200154905092915050565b6140eb89614591565b6141345760405162461bcd60e51b815260206004820152601a6024820152797075626c6963206b6579206973206e6f74206f6e20637572766560301b6044820152606401610b20565b61413d88614591565b6141815760405162461bcd60e51b815260206004820152601560248201527467616d6d61206973206e6f74206f6e20637572766560581b6044820152606401610b20565b61418a83614591565b6141d65760405162461bcd60e51b815260206004820152601d60248201527f6347616d6d615769746e657373206973206e6f74206f6e2063757276650000006044820152606401610b20565b6141df82614591565b61422a5760405162461bcd60e51b815260206004820152601c60248201527b73486173685769746e657373206973206e6f74206f6e20637572766560201b6044820152606401610b20565b614236878a8887614654565b61427e5760405162461bcd60e51b81526020600482015260196024820152786164647228632a706b2b732a6729213d5f755769746e65737360381b6044820152606401610b20565b600061428a8a87614768565b9050600061429d898b878b8689896147cc565b905060006142ae838d8d8a866148eb565b9050808a146142ef5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b6044820152606401610b20565b505050505050505050505050565b60004661430981614046565b1561434d57606c6001600160a01b031663c6f7de0e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015613c4e573d6000803e3d6000fd5b6143568161492b565b156143c757600f602160991b016001600160a01b03166349948e0e84604051806080016040528060488152602001615f186048913960405160200161439c929190615dc2565b6040516020818303038152906040526040518263ffffffff1660e01b8152600401613c319190615818565b50600092915050565b600c5460035460408051633fabe5a360e21b815290516000938493600160381b90910463ffffffff169284926001600160a01b039092169163feaf968c9160048082019260a0929091908290030181865afa158015614433573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906144579190615e08565b50919650909250505063ffffffff821615801590614483575061447a8142615740565b8263ffffffff16105b925082156144915760105493505b50509091565b600081815260018301602052604081205480156145805760006144bb600183615740565b85549091506000906144cf90600190615740565b90508181146145345760008660000182815481106144ef576144ef6156c0565b9060005260206000200154905080876000018481548110614512576145126156c0565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061454557614545615aac565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506123f2565b60009150506123f2565b5092915050565b80516000906401000003d019116145df5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420782d6f7264696e61746560701b6044820152606401610b20565b60208201516401000003d0191161462d5760405162461bcd60e51b8152602060048201526012602482015271696e76616c696420792d6f7264696e61746560701b6044820152606401610b20565b60208201516401000003d01990800961464d8360005b6020020151614965565b1492915050565b60006001600160a01b03821661469a5760405162461bcd60e51b815260206004820152600b60248201526a626164207769746e65737360a81b6044820152606401610b20565b6020840151600090600116156146b157601c6146b4565b601b5b9050600070014551231950b75fc4402da1732fc9bebe1985876000602002015109865170014551231950b75fc4402da1732fc9bebe199182039250600091908909875160408051600080825260209091019182905292935060019161471e91869188918790615e58565b6020604051602081039080840390855afa158015614740573d6000803e3d6000fd5b5050604051601f1901516001600160a01b039081169088161495505050505050949350505050565b614770614e7c565b61479d6001848460405160200161478993929190615e76565b604051602081830303815290604052614989565b90505b6147a981614591565b6123f25780516040805160208101929092526147c59101614789565b90506147a0565b6147d4614e7c565b825186516401000003d01991829006919006036148335760405162461bcd60e51b815260206004820152601e60248201527f706f696e747320696e2073756d206d7573742062652064697374696e637400006044820152606401610b20565b61483e8789886149d6565b6148835760405162461bcd60e51b8152602060048201526016602482015275119a5c9cdd081b5d5b0818da1958dac819985a5b195960521b6044820152606401610b20565b61488e8486856149d6565b6148d45760405162461bcd60e51b815260206004820152601760248201527614d958dbdb99081b5d5b0818da1958dac819985a5b1959604a1b6044820152606401610b20565b6148df868484614af4565b98975050505050505050565b60006002868686858760405160200161490996959493929190615e97565b60408051601f1981840301815291905280516020909101209695505050505050565b6000600a82148061493d57506101a482145b8061494a575062aa37dc82145b80614956575061210582145b806123f257505062014a331490565b6000806401000003d01980848509840990506401000003d019600782089392505050565b614991614e7c565b61499a82614bb7565b81526149af6149aa826000614643565b614bf2565b6020820181905260029006600103611cba576020810180516401000003d019039052919050565b600082600003614a165760405162461bcd60e51b815260206004820152600b60248201526a3d32b9379039b1b0b630b960a91b6044820152606401610b20565b83516020850151600090614a2c90600290615ef1565b15614a3857601c614a3b565b601b5b9050600070014551231950b75fc4402da1732fc9bebe19838709604080516000808252602090910191829052919250600190614a7e908390869088908790615e58565b6020604051602081039080840390855afa158015614aa0573d6000803e3d6000fd5b505050602060405103519050600086604051602001614abf9190615f05565b60408051601f1981840301815291905280516020909101206001600160a01b0392831692169190911498975050505050505050565b614afc614e7c565b835160208086015185519186015160009384938493614b1d93909190614c12565b919450925090506401000003d019858209600114614b795760405162461bcd60e51b815260206004820152601960248201527834b73b2d1036bab9ba1031329034b73b32b939b29037b3103d60391b6044820152606401610b20565b60405180604001604052806401000003d01980614b9857614b98615d62565b87860981526020016401000003d0198785099052979650505050505050565b805160208201205b6401000003d0198110611cba57604080516020808201939093528151808203840181529082019091528051910120614bbf565b60006123f2826002614c0b6401000003d01960016158ba565b901c614cf2565b60008080600180826401000003d019896401000003d019038808905060006401000003d0198b6401000003d019038a0890506000614c5283838585614d8c565b9098509050614c6388828e88614db0565b9098509050614c7488828c87614db0565b90985090506000614c878d878b85614db0565b9098509050614c9888828686614d8c565b9098509050614ca988828e89614db0565b9098509050818114614cde576401000003d019818a0998506401000003d01982890997506401000003d0198183099650614ce2565b8196505b5050505050509450945094915050565b600080614cfd614e9a565b6020808252818101819052604082015260608101859052608081018490526401000003d01960a0820152614d2f614eb8565b60208160c0846005600019fa925082600003614d825760405162461bcd60e51b81526020600482015260126024820152716269674d6f64457870206661696c7572652160701b6044820152606401610b20565b5195945050505050565b6000806401000003d0198487096401000003d0198487099097909650945050505050565b600080806401000003d019878509905060006401000003d01987876401000003d019030990506401000003d0198183086401000003d01986890990999098509650505050505050565b828054828255906000526020600020908101928215614e4e579160200282015b82811115614e4e57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190614e19565b50614e5a929150614ed6565b5090565b5080546000825590600052602060002090810190612f4b9190614ed6565b60405180604001604052806002906020820280368337509192915050565b6040518060c001604052806006906020820280368337509192915050565b60405180602001604052806001906020820280368337509192915050565b5b80821115614e5a5760008155600101614ed7565b60006060820161ffff86168352602063ffffffff86168185015260606040850152818551808452608086019150828701935060005b81811015614f3c57845183529383019391830191600101614f20565b509098975050505050505050565b6001600160a01b0381168114612f4b57600080fd5b8035611cba81614f4a565b60008060408385031215614f7d57600080fd5b823591506020830135614f8f81614f4a565b809150509250929050565b6001600160a01b0391909116815260200190565b600060208284031215614fc057600080fd5b8135610dfb81614f4a565b634e487b7160e01b600052604160045260246000fd5b60405160c081016001600160401b038111828210171561500357615003614fcb565b60405290565b60405161012081016001600160401b038111828210171561500357615003614fcb565b604051601f8201601f191681016001600160401b038111828210171561505457615054614fcb565b604052919050565b600082601f83011261506d57600080fd5b604080519081016001600160401b038111828210171561508f5761508f614fcb565b80604052508060408401858111156150a657600080fd5b845b818110156150c05780358352602092830192016150a8565b509195945050505050565b80356001600160401b0381168114611cba57600080fd5b803563ffffffff81168114611cba57600080fd5b600060c0828403121561510857600080fd5b615110614fe1565b905061511b826150cb565b815260208083013581830152615133604084016150e2565b6040830152615144606084016150e2565b6060830152608083013561515781614f4a565b608083015260a08301356001600160401b038082111561517657600080fd5b818501915085601f83011261518a57600080fd5b81358181111561519c5761519c614fcb565b6151ae601f8201601f1916850161502c565b915080825286848285010111156151c457600080fd5b80848401858401376000848284010152508060a085015250505092915050565b8015158114612f4b57600080fd5b8035611cba816151e4565b60008060008385036101e081121561521457600080fd5b6101a08082121561522457600080fd5b61522c615009565b9150615238878761505c565b8252615247876040880161505c565b60208301526080860135604083015260a0860135606083015260c0860135608083015261527660e08701614f5f565b60a083015261010061528a8882890161505c565b60c084015261529d88610140890161505c565b60e0840152610180870135908301529093508401356001600160401b038111156152c657600080fd5b6152d2868287016150f6565b9250506152e26101c085016151f2565b90509250925092565b6000602082840312156152fd57600080fd5b5035919050565b6000806040838503121561531757600080fd5b823561532281614f4a565b91506020830135614f8f81614f4a565b6000806060838503121561534557600080fd5b604083018481111561535657600080fd5b839250615362816150cb565b9150509250929050565b60006020828403121561537e57600080fd5b81356001600160401b0381111561539457600080fd5b820160c08185031215610dfb57600080fd5b6001600160401b0391909116815260200190565b60008083601f8401126153cc57600080fd5b5081356001600160401b038111156153e357600080fd5b6020830191508360208285010111156153fb57600080fd5b9250929050565b6000806000806060858703121561541857600080fd5b843561542381614f4a565b93506020850135925060408501356001600160401b0381111561544557600080fd5b615451878288016153ba565b95989497509550505050565b803561ffff81168114611cba57600080fd5b803560ff81168114611cba57600080fd5b60008060008060008060008060006101208a8c03121561549f57600080fd5b6154a88a61545d565b98506154b660208b016150e2565b97506154c460408b016150e2565b96506154d260608b016150e2565b955060808a013594506154e760a08b016150e2565b93506154f560c08b016150e2565b925061550360e08b0161546f565b91506155126101008b0161546f565b90509295985092959850929598565b6000806040838503121561553457600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b8381101561557357815187529582019590820190600101615557565b509495945050505050565b602081526000610dfb6020830184615543565b6000604082840312156155a357600080fd5b610dfb838361505c565b600080602083850312156155c057600080fd5b82356001600160401b038111156155d657600080fd5b6155e2858286016153ba565b90969095509350505050565b600081518084526020808501945080840160005b838110156155735781516001600160a01b031687529582019590820190600101615602565b6001600160601b038681168252851660208201526001600160401b03841660408201526001600160a01b038316606082015260a060808201819052600090615671908301846155ee565b979650505050505050565b634e487b7160e01b600052601160045260246000fd5b6001600160601b0382811682821603908082111561458a5761458a61567c565b918252602082015260400190565b634e487b7160e01b600052603260045260246000fd5b6000600182016156e8576156e861567c565b5060010190565b60006001600160401b038281166002600160401b031981016157135761571361567c565b6001019392505050565b60006001600160401b038216806157365761573661567c565b6000190192915050565b818103818111156123f2576123f261567c565b6020815260ff82511660208201526020820151604082015260018060a01b0360408301511660608201526000606083015160c0608084015261579860e08401826155ee565b60808501516001600160601b0390811660a0868101919091529095015190941660c0909301929092525090919050565b60005b838110156157e35781810151838201526020016157cb565b50506000910152565b600081518084526158048160208601602086016157c8565b601f01601f19169290920160200192915050565b602081526000610dfb60208301846157ec565b6001600160a01b039290921682526001600160601b0316602082015260400190565b60006020828403121561585f57600080fd5b8151610dfb816151e4565b6001600160a01b03929092168252602082015260400190565b9182526001600160401b0316602082015260400190565b6001600160601b0381811683821601908082111561458a5761458a61567c565b808201808211156123f2576123f261567c565b9182526001600160a01b0316602082015260400190565b6000602082840312156158f657600080fd5b610dfb8261545d565b61ffff93841681529183166020830152909116604082015260600190565b60006020828403121561592f57600080fd5b610dfb826150e2565b63ffffffff92831681529116602082015260400190565b6000808335601e1984360301811261596657600080fd5b8301803591506001600160401b0382111561598057600080fd5b6020019150368190038213156153fb57600080fd5b878152602081018790526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c082018190526000906159e1908301846157ec565b9998505050505050505050565b86815285602082015261ffff85166040820152600063ffffffff808616606084015280851660808401525060c060a08301526148df60c08301846157ec565b6001600160401b0381811683821601908082111561458a5761458a61567c565b60ff92831681529116602082015260400190565b6001600160a01b0392831681529116602082015260400190565b8060005b6002811015612bd2578151845260209384019390910190600101615a7f565b604081016123f28284615a7b565b634e487b7160e01b600052603160045260246000fd5b80356001600160601b0381168114611cba57600080fd5b60006020808385031215615aec57600080fd5b82356001600160401b0380821115615b0357600080fd5b9084019060c08287031215615b1757600080fd5b615b1f614fe1565b615b288361546f565b815283830135848201526040830135615b4081614f4a565b6040820152606083013582811115615b5757600080fd5b8301601f81018813615b6857600080fd5b803583811115615b7a57615b7a614fcb565b8060051b9350615b8b86850161502c565b818152938201860193868101908a861115615ba557600080fd5b928701925b85841015615bcf5783359250615bbf83614f4a565b8282529287019290870190615baa565b606085015250615be491505060808401615ac2565b6080820152615bf560a08401615ac2565b60a08201529695505050505050565b600060208284031215615c1657600080fd5b5051919050565b8781526001600160401b03871660208201526040810186905263ffffffff8581166060830152841660808201526001600160a01b03831660a082015260e060c082018190526000906159e1908301846157ec565b828152604060208201526000615c8a6040830184615543565b949350505050565b6001600160e01b03198135818116916004851015615cba5780818660040360031b1b83161692505b505092915050565b60008085851115615cd257600080fd5b83861115615cdf57600080fd5b5050820193919092039150565b600060208284031215615cfe57600080fd5b604051602081016001600160401b0381118282101715615d2057615d20614fcb565b6040528235615d2e816151e4565b81529392505050565b82815260608101610dfb6020830184615a7b565b80820281158282048414176123f2576123f261567c565b634e487b7160e01b600052601260045260246000fd5b600082615d8757615d87615d62565b500490565b60ff81811683821601908111156123f2576123f261567c565b63ffffffff82811682821603908082111561458a5761458a61567c565b60008351615dd48184602088016157c8565b835190830190615de88183602088016157c8565b01949350505050565b80516001600160501b0381168114611cba57600080fd5b600080600080600060a08688031215615e2057600080fd5b615e2986615df1565b9450602086015193506040860151925060608601519150615e4c60808701615df1565b90509295509295909350565b93845260ff9290921660208401526040830152606082015260800190565b838152615e866020820184615a7b565b606081019190915260800192915050565b868152615ea76020820187615a7b565b615eb46060820186615a7b565b615ec160a0820185615a7b565b615ece60e0820184615a7b565b60609190911b6001600160601b0319166101208201526101340195945050505050565b600082615f0057615f00615d62565b500690565b615f0f8183615a7b565b60400191905056fe307866666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666666a164736f6c6343000813000a", } var VRFCoordinatorV2PlusUpgradedVersionABI = VRFCoordinatorV2PlusUpgradedVersionMetaData.ABI @@ -559,6 +559,28 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SCurrentSubNonce(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) } +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_fallbackWeiPerUnitLink") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SFallbackWeiPerUnitLink() (*big.Int, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) +} + +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SFallbackWeiPerUnitLink() (*big.Int, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SFallbackWeiPerUnitLink(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts) +} + func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { var out []interface{} err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_provingKeyHashes", arg0) @@ -581,6 +603,36 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionC return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeyHashes(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0) } +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (SProvingKeys, + + error) { + var out []interface{} + err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_provingKeys", arg0) + + outstruct := new(SProvingKeys) + if err != nil { + return *outstruct, err + } + + outstruct.Exists = *abi.ConvertType(out[0], new(bool)).(*bool) + outstruct.MaxGas = *abi.ConvertType(out[1], new(uint64)).(*uint64) + + return *outstruct, err + +} + +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) SProvingKeys(arg0 [32]byte) (SProvingKeys, + + error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeys(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0) +} + +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCallerSession) SProvingKeys(arg0 [32]byte) (SProvingKeys, + + error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.SProvingKeys(&_VRFCoordinatorV2PlusUpgradedVersion.CallOpts, arg0) +} + func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionCaller) SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) { var out []interface{} err := _VRFCoordinatorV2PlusUpgradedVersion.contract.Call(opts, &out, "s_requestCommitments", arg0) @@ -707,16 +759,16 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionT return _VRFCoordinatorV2PlusUpgradedVersion.Contract.CreateSubscription(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment, arg2 bool) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "fulfillRandomWords", proof, rc, arg2) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "fulfillRandomWords", proof, rc, onlyPremium) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment, arg2 bool) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc, arg2) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) FulfillRandomWords(proof VRFProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc, onlyPremium) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) FulfillRandomWords(proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment, arg2 bool) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc, arg2) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) FulfillRandomWords(proof VRFProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.FulfillRandomWords(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, proof, rc, onlyPremium) } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) { @@ -815,16 +867,16 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionT return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterMigratableCoordinator(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, target) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "registerProvingKey", publicProvingKey) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.contract.Transact(opts, "registerProvingKey", publicProvingKey, maxGas) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RegisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, publicProvingKey) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionSession) RegisterProvingKey(publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, publicProvingKey, maxGas) } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RegisterProvingKey(publicProvingKey [2]*big.Int) (*types.Transaction, error) { - return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, publicProvingKey) +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactorSession) RegisterProvingKey(publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) { + return _VRFCoordinatorV2PlusUpgradedVersion.Contract.RegisterProvingKey(&_VRFCoordinatorV2PlusUpgradedVersion.TransactOpts, publicProvingKey, maxGas) } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionTransactor) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) { @@ -984,14 +1036,16 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator) Close() error { } type VRFCoordinatorV2PlusUpgradedVersionConfigSet struct { - MinimumRequestConfirmations uint16 - MaxGasLimit uint32 - StalenessSeconds uint32 - GasAfterPaymentCalculation uint32 - FallbackWeiPerUnitLink *big.Int - NativePremiumPercentage uint8 - LinkPremiumPercentage uint8 - Raw types.Log + MinimumRequestConfirmations uint16 + MaxGasLimit uint32 + StalenessSeconds uint32 + GasAfterPaymentCalculation uint32 + FallbackWeiPerUnitLink *big.Int + FulfillmentFlatFeeNativePPM uint32 + FulfillmentFlatFeeLinkDiscountPPM uint32 + NativePremiumPercentage uint8 + LinkPremiumPercentage uint8 + Raw types.Log } func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterConfigSet(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionConfigSetIterator, error) { @@ -1163,6 +1217,124 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionF return event, nil } +type VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator struct { + Event *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +func (it *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator) Error() error { + return it.fail +} + +func (it *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed struct { + RequestId *big.Int + FallbackWeiPerUnitLink *big.Int + Raw types.Log +} + +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterFallbackWeiPerUnitLinkUsed(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator, error) { + + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "FallbackWeiPerUnitLinkUsed") + if err != nil { + return nil, err + } + return &VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "FallbackWeiPerUnitLinkUsed", logs: logs, sub: sub}, nil +} + +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchFallbackWeiPerUnitLinkUsed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) (event.Subscription, error) { + + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "FallbackWeiPerUnitLinkUsed") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "FallbackWeiPerUnitLinkUsed", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) ParseFallbackWeiPerUnitLinkUsed(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed, error) { + event := new(VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) + if err := _VRFCoordinatorV2PlusUpgradedVersion.contract.UnpackLog(event, "FallbackWeiPerUnitLinkUsed", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + type VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator struct { Event *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered @@ -1851,6 +2023,7 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegisteredIterator) Close type VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered struct { KeyHash [32]byte + MaxGas uint64 Raw types.Log } @@ -1967,46 +2140,48 @@ func (it *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator) Close } type VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled struct { - RequestId *big.Int - OutputSeed *big.Int - SubID *big.Int - Payment *big.Int - Success bool - Raw types.Log + RequestId *big.Int + OutputSeed *big.Int + SubId *big.Int + Payment *big.Int + NativePayment bool + Success bool + OnlyPremium bool + Raw types.Log } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subID []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } - var subIDRule []interface{} - for _, subIDItem := range subID { - subIDRule = append(subIDRule, subIDItem) + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) } - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIDRule) + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.FilterLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) if err != nil { return nil, err } return &VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator{contract: _VRFCoordinatorV2PlusUpgradedVersion.contract, event: "RandomWordsFulfilled", logs: logs, sub: sub}, nil } -func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subID []*big.Int) (event.Subscription, error) { +func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersionFilterer) WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) { var requestIdRule []interface{} for _, requestIdItem := range requestId { requestIdRule = append(requestIdRule, requestIdItem) } - var subIDRule []interface{} - for _, subIDItem := range subID { - subIDRule = append(subIDRule, subIDItem) + var subIdRule []interface{} + for _, subIdItem := range subId { + subIdRule = append(subIdRule, subIdItem) } - logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIDRule) + logs, sub, err := _VRFCoordinatorV2PlusUpgradedVersion.contract.WatchLogs(opts, "RandomWordsFulfilled", requestIdRule, subIdRule) if err != nil { return nil, err } @@ -3250,6 +3425,10 @@ type SConfig struct { NativePremiumPercentage uint8 LinkPremiumPercentage uint8 } +type SProvingKeys struct { + Exists bool + MaxGas uint64 +} func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion) ParseLog(log types.Log) (generated.AbigenLog, error) { switch log.Topics[0] { @@ -3257,6 +3436,8 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion) return _VRFCoordinatorV2PlusUpgradedVersion.ParseConfigSet(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["CoordinatorRegistered"].ID: return _VRFCoordinatorV2PlusUpgradedVersion.ParseCoordinatorRegistered(log) + case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["FallbackWeiPerUnitLinkUsed"].ID: + return _VRFCoordinatorV2PlusUpgradedVersion.ParseFallbackWeiPerUnitLinkUsed(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["FundsRecovered"].ID: return _VRFCoordinatorV2PlusUpgradedVersion.ParseFundsRecovered(log) case _VRFCoordinatorV2PlusUpgradedVersion.abi.Events["MigrationCompleted"].ID: @@ -3296,13 +3477,17 @@ func (_VRFCoordinatorV2PlusUpgradedVersion *VRFCoordinatorV2PlusUpgradedVersion) } func (VRFCoordinatorV2PlusUpgradedVersionConfigSet) Topic() common.Hash { - return common.HexToHash("0x95cb2ddab6d2297c29a4861691de69b3969c464aa4a9c44258b101ff02ff375a") + return common.HexToHash("0x2c6b6b12413678366b05b145c5f00745bdd00e739131ab5de82484a50c9d78b6") } func (VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered) Topic() common.Hash { return common.HexToHash("0xb7cabbfc11e66731fc77de0444614282023bcbd41d16781c753a431d0af01625") } +func (VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) Topic() common.Hash { + return common.HexToHash("0x6ca648a381f22ead7e37773d934e64885dcf861fbfbb26c40354cbf0c4662d1a") +} + func (VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) Topic() common.Hash { return common.HexToHash("0x59bfc682b673f8cbf945f1e454df9334834abf7dfe7f92237ca29ecb9b436600") } @@ -3324,11 +3509,11 @@ func (VRFCoordinatorV2PlusUpgradedVersionOwnershipTransferred) Topic() common.Ha } func (VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered) Topic() common.Hash { - return common.HexToHash("0xc9583fd3afa3d7f16eb0b88d0268e7d05c09bafa4b21e092cbd1320e1bc8089d") + return common.HexToHash("0x9b911b2c240bfbef3b6a8f7ed6ee321d1258bb2a3fe6becab52ac1cd3210afd3") } func (VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled) Topic() common.Hash { - return common.HexToHash("0x49580fdfd9497e1ed5c1b1cec0495087ae8e3f1267470ec2fb015db32e3d6aa7") + return common.HexToHash("0xaeb4b4786571e184246d39587f659abf0e26f41f6a3358692250382c0cdb47b7") } func (VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested) Topic() common.Hash { @@ -3406,8 +3591,14 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { SCurrentSubNonce(opts *bind.CallOpts) (uint64, error) + SFallbackWeiPerUnitLink(opts *bind.CallOpts) (*big.Int, error) + SProvingKeyHashes(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) + SProvingKeys(opts *bind.CallOpts, arg0 [32]byte) (SProvingKeys, + + error) + SRequestCommitments(opts *bind.CallOpts, arg0 *big.Int) ([32]byte, error) STotalBalance(opts *bind.CallOpts) (*big.Int, error) @@ -3424,7 +3615,7 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { CreateSubscription(opts *bind.TransactOpts) (*types.Transaction, error) - FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFCoordinatorV2PlusUpgradedVersionRequestCommitment, arg2 bool) (*types.Transaction, error) + FulfillRandomWords(opts *bind.TransactOpts, proof VRFProof, rc VRFTypesRequestCommitmentV2Plus, onlyPremium bool) (*types.Transaction, error) FundSubscriptionWithNative(opts *bind.TransactOpts, subId *big.Int) (*types.Transaction, error) @@ -3442,7 +3633,7 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { RegisterMigratableCoordinator(opts *bind.TransactOpts, target common.Address) (*types.Transaction, error) - RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int) (*types.Transaction, error) + RegisterProvingKey(opts *bind.TransactOpts, publicProvingKey [2]*big.Int, maxGas uint64) (*types.Transaction, error) RemoveConsumer(opts *bind.TransactOpts, subId *big.Int, consumer common.Address) (*types.Transaction, error) @@ -3472,6 +3663,12 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { ParseCoordinatorRegistered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionCoordinatorRegistered, error) + FilterFallbackWeiPerUnitLinkUsed(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsedIterator, error) + + WatchFallbackWeiPerUnitLinkUsed(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed) (event.Subscription, error) + + ParseFallbackWeiPerUnitLinkUsed(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionFallbackWeiPerUnitLinkUsed, error) + FilterFundsRecovered(opts *bind.FilterOpts) (*VRFCoordinatorV2PlusUpgradedVersionFundsRecoveredIterator, error) WatchFundsRecovered(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionFundsRecovered) (event.Subscription, error) @@ -3508,9 +3705,9 @@ type VRFCoordinatorV2PlusUpgradedVersionInterface interface { ParseProvingKeyRegistered(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionProvingKeyRegistered, error) - FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subID []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error) + FilterRandomWordsFulfilled(opts *bind.FilterOpts, requestId []*big.Int, subId []*big.Int) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilledIterator, error) - WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subID []*big.Int) (event.Subscription, error) + WatchRandomWordsFulfilled(opts *bind.WatchOpts, sink chan<- *VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, requestId []*big.Int, subId []*big.Int) (event.Subscription, error) ParseRandomWordsFulfilled(log types.Log) (*VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, 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 d7a1fa84424..8299cd5ff15 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 @@ -99,7 +99,7 @@ vrf_v2_consumer_wrapper: ../../contracts/solc/v0.8.6/VRFv2Consumer/VRFv2Consumer vrf_v2plus_load_test_with_metrics: ../../contracts/solc/v0.8.19/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.abi ../../contracts/solc/v0.8.19/VRFV2PlusLoadTestWithMetrics/VRFV2PlusLoadTestWithMetrics.bin 593dbcdcc212fc9ec69fe71684711d112433cc31218fe21305ace9229ac29289 vrf_v2plus_single_consumer: ../../contracts/solc/v0.8.19/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusSingleConsumerExample/VRFV2PlusSingleConsumerExample.bin cfdfb97b1b0801ee778410d54b1f6541395ac01ab592ffd6c3feaf4a3ac3eca2 vrf_v2plus_sub_owner: ../../contracts/solc/v0.8.19/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.abi ../../contracts/solc/v0.8.19/VRFV2PlusExternalSubOwnerExample/VRFV2PlusExternalSubOwnerExample.bin 6032a081ad15453e52af1cf37c74a9f77f2a30bc14b2cb35f564eabc4b0b4c2e -vrf_v2plus_upgraded_version: ../../contracts/solc/v0.8.19/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.bin 4a7df5b066bc3944622009659828fae35bc39d15cf4d218c1560dbdf39b10de2 +vrf_v2plus_upgraded_version: ../../contracts/solc/v0.8.19/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.abi ../../contracts/solc/v0.8.19/VRFCoordinatorV2PlusUpgradedVersion/VRFCoordinatorV2PlusUpgradedVersion.bin 50429c68bc9e4edcddc4b15d65867bff9ae308314b52ed997e7d5665f0703148 vrfv2_proxy_admin: ../../contracts/solc/v0.8.6/VRFV2ProxyAdmin/VRFV2ProxyAdmin.abi ../../contracts/solc/v0.8.6/VRFV2ProxyAdmin/VRFV2ProxyAdmin.bin 402b1103087ffe1aa598854a8f8b38f8cd3de2e3aaa86369e28017a9157f4980 vrfv2_reverting_example: ../../contracts/solc/v0.8.6/VRFV2RevertingExample/VRFV2RevertingExample.abi ../../contracts/solc/v0.8.6/VRFV2RevertingExample/VRFV2RevertingExample.bin 1ae46f80351d428bd85ba58b9041b2a608a1845300d79a8fed83edf96606de87 vrfv2_transparent_upgradeable_proxy: ../../contracts/solc/v0.8.6/VRFV2TransparentUpgradeableProxy/VRFV2TransparentUpgradeableProxy.abi ../../contracts/solc/v0.8.6/VRFV2TransparentUpgradeableProxy/VRFV2TransparentUpgradeableProxy.bin fe1a8e6852fbd06d91f64315c5cede86d340891f5b5cc981fb5b86563f7eac3f diff --git a/integration-tests/actions/vrf/common/logging_helpers.go b/integration-tests/actions/vrf/common/logging_helpers.go new file mode 100644 index 00000000000..f9c8a031678 --- /dev/null +++ b/integration-tests/actions/vrf/common/logging_helpers.go @@ -0,0 +1,129 @@ +package common + +import ( + "fmt" + "math/big" + + "github.com/rs/zerolog" + + commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_owner" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" +) + +func LogSubDetails( + l zerolog.Logger, + subscription contracts.Subscription, + subID string, + coordinator contracts.Coordinator, +) { + log := l.Info(). + Str("Coordinator", coordinator.Address()). + Str("Link Balance", (*commonassets.Link)(subscription.Balance).Link()). + Str("Subscription ID", subID). + Str("Subscription Owner", subscription.SubOwner.String()). + Interface("Subscription Consumers", subscription.Consumers) + if subscription.NativeBalance != nil { + log = log.Str("Native Token Balance", assets.FormatWei(subscription.NativeBalance)) + } + log.Msg("Subscription Data") +} + +func LogRandomnessRequestedEvent( + l zerolog.Logger, + coordinator contracts.Coordinator, + randomWordsRequestedEvent *contracts.CoordinatorRandomWordsRequested, + isNativeBilling bool, +) { + l.Info(). + Str("Coordinator", coordinator.Address()). + Bool("Native Billing", isNativeBilling). + Str("Request ID", randomWordsRequestedEvent.RequestId.String()). + Str("Subscription ID", randomWordsRequestedEvent.SubId). + Str("Sender Address", randomWordsRequestedEvent.Sender.String()). + 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") +} + +func LogRandomWordsFulfilledEvent( + l zerolog.Logger, + coordinator contracts.Coordinator, + randomWordsFulfilledEvent *contracts.CoordinatorRandomWordsFulfilled, + isNativeBilling bool, +) { + l.Info(). + Bool("Native Billing", isNativeBilling). + Str("Coordinator", coordinator.Address()). + Str("Total Payment", randomWordsFulfilledEvent.Payment.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Str("Subscription ID", randomWordsFulfilledEvent.SubId). + 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)") +} + +func LogFulfillmentDetailsLinkBilling( + l zerolog.Logger, + wrapperConsumerJuelsBalanceBeforeRequest *big.Int, + wrapperConsumerJuelsBalanceAfterRequest *big.Int, + consumerStatus vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, + randomWordsFulfilledEvent *contracts.CoordinatorRandomWordsFulfilled, +) { + l.Info(). + Str("Consumer Balance Before Request (Link)", (*commonassets.Link)(wrapperConsumerJuelsBalanceBeforeRequest).Link()). + Str("Consumer Balance After Request (Link)", (*commonassets.Link)(wrapperConsumerJuelsBalanceAfterRequest).Link()). + Bool("Fulfilment Status", consumerStatus.Fulfilled). + Str("Paid by Consumer Contract (Link)", (*commonassets.Link)(consumerStatus.Paid).Link()). + Str("Paid by Coordinator Sub (Link)", (*commonassets.Link)(randomWordsFulfilledEvent.Payment).Link()). + Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). + Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). + Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). + Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Msg("Random Words Fulfilment Details For Link Billing") +} + +func LogFulfillmentDetailsNativeBilling( + l zerolog.Logger, + wrapperConsumerBalanceBeforeRequestWei *big.Int, + wrapperConsumerBalanceAfterRequestWei *big.Int, + consumerStatus vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, + randomWordsFulfilledEvent *contracts.CoordinatorRandomWordsFulfilled, +) { + l.Info(). + Str("Consumer Balance Before Request", assets.FormatWei(wrapperConsumerBalanceBeforeRequestWei)). + Str("Consumer Balance After Request", assets.FormatWei(wrapperConsumerBalanceAfterRequestWei)). + Bool("Fulfilment Status", consumerStatus.Fulfilled). + Str("Paid by Consumer Contract", assets.FormatWei(consumerStatus.Paid)). + Str("Paid by Coordinator Sub", assets.FormatWei(randomWordsFulfilledEvent.Payment)). + Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). + Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). + Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). + Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). + Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). + Msg("Random Words Request Fulfilment Details For Native Billing") +} + +func LogRandomWordsForcedEvent( + l zerolog.Logger, + vrfOwner contracts.VRFOwner, + randomWordsForcedEvent *vrf_owner.VRFOwnerRandomWordsForced, +) { + l.Debug(). + Str("VRFOwner", vrfOwner.Address()). + Uint64("Sub ID", randomWordsForcedEvent.SubId). + Str("TX Hash", randomWordsForcedEvent.Raw.TxHash.String()). + Str("Request ID", randomWordsForcedEvent.RequestId.String()). + Str("Sender", randomWordsForcedEvent.Sender.String()). + Msg("RandomWordsForced Event (TX metadata)") +} diff --git a/integration-tests/actions/vrf/vrfv2/contract_steps.go b/integration-tests/actions/vrf/vrfv2/contract_steps.go index 46b84eb836b..bd4535ebf77 100644 --- a/integration-tests/actions/vrf/vrfv2/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2/contract_steps.go @@ -452,7 +452,7 @@ func FundVRFCoordinatorV2Subscription( func DirectFundingRequestRandomnessAndWaitForFulfillment( l zerolog.Logger, consumer contracts.VRFv2WrapperLoadTestConsumer, - coordinator contracts.VRFCoordinatorV2, + coordinator contracts.Coordinator, subID uint64, vrfv2KeyData *vrfcommon.VRFKeyData, minimumConfirmations uint16, @@ -461,7 +461,7 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( randomnessRequestCountPerRequest uint16, randomnessRequestCountPerRequestDeviation uint16, randomWordsFulfilledEventTimeout time.Duration, -) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, error) { +) (*contracts.CoordinatorRandomWordsFulfilled, error) { logRandRequest( l, consumer.Address(), @@ -496,7 +496,7 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( func RequestRandomnessAndWaitForFulfillment( l zerolog.Logger, consumer contracts.VRFv2LoadTestConsumer, - coordinator contracts.VRFCoordinatorV2, + coordinator contracts.Coordinator, subID uint64, vrfKeyData *vrfcommon.VRFKeyData, minimumConfirmations uint16, @@ -505,7 +505,7 @@ func RequestRandomnessAndWaitForFulfillment( randomnessRequestCountPerRequest uint16, randomnessRequestCountPerRequestDeviation uint16, randomWordsFulfilledEventTimeout time.Duration, -) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, error) { +) (*contracts.CoordinatorRandomWordsFulfilled, error) { randomWordsRequestedEvent, err := RequestRandomness( l, consumer, @@ -536,7 +536,7 @@ func RequestRandomnessAndWaitForFulfillment( func RequestRandomness( l zerolog.Logger, consumer contracts.VRFv2LoadTestConsumer, - coordinator contracts.VRFCoordinatorV2, + coordinator contracts.Coordinator, subID uint64, vrfKeyData *vrfcommon.VRFKeyData, minimumConfirmations uint16, @@ -544,7 +544,7 @@ func RequestRandomness( numberOfWords uint32, randomnessRequestCountPerRequest uint16, randomnessRequestCountPerRequestDeviation uint16, -) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { +) (*contracts.CoordinatorRandomWordsRequested, error) { logRandRequest( l, consumer.Address(), @@ -569,7 +569,7 @@ func RequestRandomness( if err != nil { return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) } - LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent) + vrfcommon.LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent, false) return randomWordsRequestedEvent, err } @@ -577,7 +577,7 @@ func RequestRandomness( func RequestRandomnessWithForceFulfillAndWaitForFulfillment( l zerolog.Logger, consumer contracts.VRFv2LoadTestConsumer, - coordinator contracts.VRFCoordinatorV2, + coordinator contracts.Coordinator, vrfOwner contracts.VRFOwner, vrfv2KeyData *vrfcommon.VRFKeyData, minimumConfirmations uint16, @@ -588,9 +588,10 @@ func RequestRandomnessWithForceFulfillAndWaitForFulfillment( subTopUpAmount *big.Int, linkAddress common.Address, randomWordsFulfilledEventTimeout time.Duration, -) (*vrf_coordinator_v2.VRFCoordinatorV2ConfigSet, *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, *vrf_owner.VRFOwnerRandomWordsForced, error) { +) (*contracts.CoordinatorConfigSet, *contracts.CoordinatorRandomWordsFulfilled, *vrf_owner.VRFOwnerRandomWordsForced, error) { logRandRequest(l, consumer.Address(), coordinator.Address(), 0, minimumConfirmations, callbackGasLimit, numberOfWords, randomnessRequestCountPerRequest, randomnessRequestCountPerRequestDeviation, vrfv2KeyData.KeyHash) - _, err := consumer.RequestRandomWordsWithForceFulfill( + randomWordsRequestedEvent, err := consumer.RequestRandomWordsWithForceFulfill( + coordinator, vrfv2KeyData.KeyHash, minimumConfirmations, callbackGasLimit, @@ -603,20 +604,11 @@ func RequestRandomnessWithForceFulfillAndWaitForFulfillment( return nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) } - randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfv2KeyData.KeyHash}, - nil, - []common.Address{common.HexToAddress(consumer.Address())}, - time.Minute*1, - ) - if err != nil { - return nil, nil, nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsRequestedEvent, err) - } - LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent) + vrfcommon.LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent, false) errorChannel := make(chan error) - configSetEventChannel := make(chan *vrf_coordinator_v2.VRFCoordinatorV2ConfigSet) - randWordsFulfilledEventChannel := make(chan *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled) + configSetEventChannel := make(chan *contracts.CoordinatorConfigSet) + randWordsFulfilledEventChannel := make(chan *contracts.CoordinatorRandomWordsFulfilled) randWordsForcedEventChannel := make(chan *vrf_owner.VRFOwnerRandomWordsForced) go func() { @@ -632,8 +624,10 @@ func RequestRandomnessWithForceFulfillAndWaitForFulfillment( go func() { randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( - []*big.Int{randomWordsRequestedEvent.RequestId}, - randomWordsFulfilledEventTimeout, + contracts.RandomWordsFulfilledEventFilter{ + RequestIds: []*big.Int{randomWordsRequestedEvent.RequestId}, + Timeout: randomWordsFulfilledEventTimeout, + }, ) if err != nil { l.Error().Err(err).Msg("error waiting for RandomWordsFulfilledEvent") @@ -656,8 +650,8 @@ func RequestRandomnessWithForceFulfillAndWaitForFulfillment( randWordsForcedEventChannel <- randomWordsForcedEvent }() - var configSetEvent *vrf_coordinator_v2.VRFCoordinatorV2ConfigSet - var randomWordsFulfilledEvent *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled + var configSetEvent *contracts.CoordinatorConfigSet + var randomWordsFulfilledEvent *contracts.CoordinatorRandomWordsFulfilled var randomWordsForcedEvent *vrf_owner.VRFOwnerRandomWordsForced for i := 0; i < 3; i++ { select { @@ -665,9 +659,9 @@ func RequestRandomnessWithForceFulfillAndWaitForFulfillment( return nil, nil, nil, err case configSetEvent = <-configSetEventChannel: case randomWordsFulfilledEvent = <-randWordsFulfilledEventChannel: - LogRandomWordsFulfilledEvent(l, coordinator, randomWordsFulfilledEvent) + vrfcommon.LogRandomWordsFulfilledEvent(l, coordinator, randomWordsFulfilledEvent, false) case randomWordsForcedEvent = <-randWordsForcedEventChannel: - LogRandomWordsForcedEvent(l, vrfOwner, randomWordsForcedEvent) + vrfcommon.LogRandomWordsForcedEvent(l, vrfOwner, randomWordsForcedEvent) case <-time.After(randomWordsFulfilledEventTimeout): err = fmt.Errorf("timeout waiting for ConfigSet, RandomWordsFulfilled and RandomWordsForced events") } @@ -676,19 +670,21 @@ func RequestRandomnessWithForceFulfillAndWaitForFulfillment( } func WaitRandomWordsFulfilledEvent( - coordinator contracts.VRFCoordinatorV2, + coordinator contracts.Coordinator, requestId *big.Int, randomWordsFulfilledEventTimeout time.Duration, l zerolog.Logger, -) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, error) { +) (*contracts.CoordinatorRandomWordsFulfilled, error) { randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( - []*big.Int{requestId}, - randomWordsFulfilledEventTimeout, + contracts.RandomWordsFulfilledEventFilter{ + RequestIds: []*big.Int{requestId}, + Timeout: randomWordsFulfilledEventTimeout, + }, ) if err != nil { return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsFulfilledEvent, err) } - LogRandomWordsFulfilledEvent(l, coordinator, randomWordsFulfilledEvent) + vrfcommon.LogRandomWordsFulfilledEvent(l, coordinator, randomWordsFulfilledEvent, false) return randomWordsFulfilledEvent, err } diff --git a/integration-tests/actions/vrf/vrfv2/logging_helpers.go b/integration-tests/actions/vrf/vrfv2/logging_helpers.go index 82c45267aaf..248eebf45f1 100644 --- a/integration-tests/actions/vrf/vrfv2/logging_helpers.go +++ b/integration-tests/actions/vrf/vrfv2/logging_helpers.go @@ -4,73 +4,8 @@ import ( "fmt" "github.com/rs/zerolog" - - commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" - "github.com/smartcontractkit/chainlink/integration-tests/contracts" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_owner" ) -func LogSubDetails(l zerolog.Logger, subscription vrf_coordinator_v2.GetSubscription, subID uint64, coordinator contracts.VRFCoordinatorV2) { - l.Debug(). - Str("Coordinator", coordinator.Address()). - Str("Link Balance", (*commonassets.Link)(subscription.Balance).Link()). - Uint64("Subscription ID", subID). - Str("Subscription Owner", subscription.Owner.String()). - Interface("Subscription Consumers", subscription.Consumers). - Msg("Subscription Data") -} - -func LogRandomnessRequestedEvent( - l zerolog.Logger, - coordinator contracts.VRFCoordinatorV2, - randomWordsRequestedEvent *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, -) { - l.Info(). - Str("Coordinator", coordinator.Address()). - Str("Request ID", randomWordsRequestedEvent.RequestId.String()). - Uint64("Subscription ID", randomWordsRequestedEvent.SubId). - Str("Sender Address", randomWordsRequestedEvent.Sender.String()). - 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") -} - -func LogRandomWordsFulfilledEvent( - l zerolog.Logger, - coordinator contracts.VRFCoordinatorV2, - randomWordsFulfilledEvent *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, -) { - l.Info(). - Str("Coordinator", coordinator.Address()). - Str("Total Payment", randomWordsFulfilledEvent.Payment.String()). - 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)") -} - -func LogRandomWordsForcedEvent( - l zerolog.Logger, - vrfOwner contracts.VRFOwner, - randomWordsForcedEvent *vrf_owner.VRFOwnerRandomWordsForced, -) { - l.Debug(). - Str("VRFOwner", vrfOwner.Address()). - Uint64("Sub ID", randomWordsForcedEvent.SubId). - Str("TX Hash", randomWordsForcedEvent.Raw.TxHash.String()). - Str("Request ID", randomWordsForcedEvent.RequestId.String()). - Str("Sender", randomWordsForcedEvent.Sender.String()). - Msg("RandomWordsForced Event (TX metadata)") -} - func logRandRequest( l zerolog.Logger, consumer string, diff --git a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go index acc509fb58b..77937dd8de9 100644 --- a/integration-tests/actions/vrf/vrfv2plus/contract_steps.go +++ b/integration-tests/actions/vrf/vrfv2plus/contract_steps.go @@ -19,8 +19,6 @@ import ( tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" vrfv2plus_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2plus" chainlinkutils "github.com/smartcontractkit/chainlink/v2/core/chains/evm/utils" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" ) func DeployVRFV2_5Contracts( @@ -93,6 +91,7 @@ func VRFV2_5RegisterProvingKey( func VRFV2PlusUpgradedVersionRegisterProvingKey( vrfKey *client.VRFKey, coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, + gasLaneMaxGasPrice uint64, ) (vrfcommon.VRFEncodedProvingKey, error) { provingKey, err := actions.EncodeOnChainVRFProvingKey(*vrfKey) if err != nil { @@ -100,6 +99,7 @@ func VRFV2PlusUpgradedVersionRegisterProvingKey( } err = coordinator.RegisterProvingKey( provingKey, + gasLaneMaxGasPrice, ) if err != nil { return vrfcommon.VRFEncodedProvingKey{}, fmt.Errorf("%s, err %w", vrfcommon.ErrRegisterProvingKey, err) @@ -331,15 +331,15 @@ func GetCoordinatorTotalBalance(coordinator contracts.VRFCoordinatorV2_5) (linkT return } -func RequestRandomnessAndWaitForRequestedEvent( +func RequestRandomness( consumer contracts.VRFv2PlusLoadTestConsumer, - coordinator contracts.VRFCoordinatorV2_5, + coordinator contracts.Coordinator, vrfKeyData *vrfcommon.VRFKeyData, subID *big.Int, isNativeBilling bool, config *vrfv2plus_config.General, l zerolog.Logger, -) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested, error) { +) (*contracts.CoordinatorRandomWordsRequested, error) { LogRandRequest( l, consumer.Address(), @@ -349,154 +349,95 @@ func RequestRandomnessAndWaitForRequestedEvent( vrfKeyData.KeyHash, config, ) - ch := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested) - errorChannel := make(chan error) - go func() { - _, err := consumer.RequestRandomness( - vrfKeyData.KeyHash, - subID, - *config.MinimumConfirmations, - *config.CallbackGasLimit, - isNativeBilling, - *config.NumberOfWords, - *config.RandomnessRequestCountPerRequest, - ) - if err != nil { - l.Error().Err(err).Msg(err.Error()) - errorChannel <- err - } - }() - go func() { - randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKeyData.KeyHash}, - []*big.Int{subID}, - []common.Address{common.HexToAddress(consumer.Address())}, - time.Minute*1, - ) - if err != nil { - l.Error().Err(err).Msg("error waiting for RandomnessRequested events") - errorChannel <- err - } - LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent, isNativeBilling) - ch <- randomWordsRequestedEvent - }() - for { - select { - case err := <-errorChannel: - return nil, err - case event := <-ch: - return event, nil - case <-time.After(config.RandomWordsFulfilledEventTimeout.Duration): - return nil, fmt.Errorf("timeout waiting for RandomnessRequested events") - } - } -} - -func RequestRandomnessAndWaitForFulfillment( - consumer contracts.VRFv2PlusLoadTestConsumer, - coordinator contracts.VRFCoordinatorV2_5, - vrfKeyData *vrfcommon.VRFKeyData, - subID *big.Int, - isNativeBilling bool, - config *vrfv2plus_config.General, - l zerolog.Logger, -) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { - LogRandRequest( - l, - consumer.Address(), - coordinator.Address(), + randomWordsRequestedEvent, err := consumer.RequestRandomness( + coordinator, + vrfKeyData.KeyHash, subID, + *config.MinimumConfirmations, + *config.CallbackGasLimit, isNativeBilling, - vrfKeyData.KeyHash, - config, + *config.NumberOfWords, + *config.RandomnessRequestCountPerRequest, ) - ch := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled) - errorChannel := make(chan error) - go func() { - _, err := consumer.RequestRandomness( - vrfKeyData.KeyHash, - subID, - *config.MinimumConfirmations, - *config.CallbackGasLimit, - isNativeBilling, - *config.NumberOfWords, - *config.RandomnessRequestCountPerRequest, - ) - if err != nil { - l.Error().Err(err).Msg(err.Error()) - errorChannel <- err - } - }() - go func() { - fulfillmentEvents, err := WaitForRequestAndFulfillmentEvents( - consumer.Address(), - coordinator, - vrfKeyData, - subID, - isNativeBilling, - config.RandomWordsFulfilledEventTimeout.Duration, - l, - ) - if err != nil { - l.Error().Err(err).Msg("error waiting for RandomnessRequested and RandomWordsFulfilled events") - errorChannel <- err - } - ch <- fulfillmentEvents - }() - for { - select { - case err := <-errorChannel: - return nil, err - case fulfillmentEvent := <-ch: - return fulfillmentEvent, nil - case <-time.After(config.RandomWordsFulfilledEventTimeout.Duration): - return nil, fmt.Errorf("timeout waiting for RandomnessRequested and RandomWordsFulfilled events") - } + if err != nil { + return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) } + vrfcommon.LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent, isNativeBilling) + + return randomWordsRequestedEvent, err } -func RequestRandomnessAndWaitForFulfillmentUpgraded( +func RequestRandomnessAndWaitForFulfillment( consumer contracts.VRFv2PlusLoadTestConsumer, - coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, + coordinator contracts.Coordinator, vrfKeyData *vrfcommon.VRFKeyData, subID *big.Int, isNativeBilling bool, config *vrfv2plus_config.General, l zerolog.Logger, -) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { - LogRandRequest( - l, - consumer.Address(), - coordinator.Address(), +) (*contracts.CoordinatorRandomWordsFulfilled, error) { + randomWordsRequestedEvent, err := RequestRandomness( + consumer, + coordinator, + vrfKeyData, subID, isNativeBilling, - vrfKeyData.KeyHash, config, - ) - _, err := consumer.RequestRandomness( - vrfKeyData.KeyHash, - subID, - *config.MinimumConfirmations, - *config.CallbackGasLimit, - isNativeBilling, - *config.NumberOfWords, - *config.RandomnessRequestCountPerRequest, + l, ) if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) + return nil, err } - return WaitForRequestAndFulfillmentEventsUpgraded( - consumer.Address(), + randomWordsFulfilledEvent, err := WaitRandomWordsFulfilledEvent( coordinator, - vrfKeyData, + randomWordsRequestedEvent.RequestId, subID, isNativeBilling, config.RandomWordsFulfilledEventTimeout.Duration, l, ) + if err != nil { + return nil, err + } + return randomWordsFulfilledEvent, nil + } +//func RequestRandomnessAndWaitForFulfillmentUpgraded( +// consumer contracts.VRFv2PlusLoadTestConsumer, +// coordinator contracts.Coordinator, +// vrfKeyData *vrfcommon.VRFKeyData, +// subID *big.Int, +// isNativeBilling bool, +// config *vrfv2plus_config.General, +// l zerolog.Logger, +//) (*contracts.CoordinatorRandomWordsFulfilled, error) { +// +// randomWordsRequestedEvent, err := RequestRandomness( +// consumer, +// coordinator, +// vrfKeyData, +// subID, +// isNativeBilling, +// config, +// l, +// ) +// +// if err != nil { +// return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrRequestRandomness, err) +// } +// +// return WaitForRandomWordsFulfilledEventUpgraded( +// coordinator, +// randomWordsRequestedEvent.RequestId, +// subID, +// isNativeBilling, +// config.RandomWordsFulfilledEventTimeout.Duration, +// l, +// ) +//} + func DeployVRFV2PlusDirectFundingContracts( contractDeployer contracts.ContractDeployer, chainClient blockchain.EVMClient, @@ -527,69 +468,66 @@ func DeployVRFV2PlusDirectFundingContracts( return &VRFV2PlusWrapperContracts{vrfv2PlusWrapper, consumers}, nil } -func WrapperRequestRandomness( - consumer contracts.VRFv2PlusWrapperLoadTestConsumer, - coordinatorAddress string, - vrfKeyData *vrfcommon.VRFKeyData, - subID *big.Int, - isNativeBilling bool, - config *vrfv2plus_config.General, - l zerolog.Logger) (string, error) { +func WrapperRequestRandomness(consumer contracts.VRFv2PlusWrapperLoadTestConsumer, coordinator contracts.Coordinator, vrfKeyData *vrfcommon.VRFKeyData, subID *big.Int, isNativeBilling bool, config *vrfv2plus_config.General, l zerolog.Logger) (*contracts.CoordinatorRandomWordsRequested, string, error) { LogRandRequest( l, consumer.Address(), - coordinatorAddress, + coordinator.Address(), subID, isNativeBilling, vrfKeyData.KeyHash, config, ) + var randomWordsRequestedEvent *contracts.CoordinatorRandomWordsRequested + var err error if isNativeBilling { - _, err := consumer.RequestRandomnessNative( + randomWordsRequestedEvent, err = consumer.RequestRandomnessNative( + coordinator, *config.MinimumConfirmations, *config.CallbackGasLimit, *config.NumberOfWords, *config.RandomnessRequestCountPerRequest, ) if err != nil { - return "", fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingNativePayment, err) + return nil, "", fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingNativePayment, err) } } else { - _, err := consumer.RequestRandomness( + randomWordsRequestedEvent, err = consumer.RequestRandomness( + coordinator, *config.MinimumConfirmations, *config.CallbackGasLimit, *config.NumberOfWords, *config.RandomnessRequestCountPerRequest, ) if err != nil { - return "", fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingLinkPayment, err) + return nil, "", fmt.Errorf("%s, err %w", ErrRequestRandomnessDirectFundingLinkPayment, err) } } + vrfcommon.LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent, isNativeBilling) wrapperAddress, err := consumer.GetWrapper(context.Background()) if err != nil { - return "", fmt.Errorf("error getting wrapper address, err: %w", err) + return nil, "", fmt.Errorf("error getting wrapper address, err: %w", err) } - return wrapperAddress.Hex(), nil + return randomWordsRequestedEvent, wrapperAddress.Hex(), nil } func DirectFundingRequestRandomnessAndWaitForFulfillment( consumer contracts.VRFv2PlusWrapperLoadTestConsumer, - coordinator contracts.VRFCoordinatorV2_5, + coordinator contracts.Coordinator, vrfKeyData *vrfcommon.VRFKeyData, subID *big.Int, isNativeBilling bool, config *vrfv2plus_config.General, l zerolog.Logger, -) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { - wrapperAddress, err := WrapperRequestRandomness(consumer, coordinator.Address(), vrfKeyData, subID, +) (*contracts.CoordinatorRandomWordsFulfilled, error) { + randomWordsRequestedEvent, _, err := WrapperRequestRandomness(consumer, coordinator, vrfKeyData, subID, isNativeBilling, config, l) if err != nil { return nil, fmt.Errorf("error getting wrapper address, err: %w", err) } - return WaitForRequestAndFulfillmentEvents( - wrapperAddress, + return WaitRandomWordsFulfilledEvent( coordinator, - vrfKeyData, + randomWordsRequestedEvent.RequestId, subID, isNativeBilling, config.RandomWordsFulfilledEventTimeout.Duration, @@ -597,95 +535,26 @@ func DirectFundingRequestRandomnessAndWaitForFulfillment( ) } -func DirectFundingRequestRandomnessAndWaitForFulfillmentUpgraded( - consumer contracts.VRFv2PlusWrapperLoadTestConsumer, - coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, - vrfKeyData *vrfcommon.VRFKeyData, - subID *big.Int, - isNativeBilling bool, - config *vrfv2plus_config.General, - l zerolog.Logger, -) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { - wrapperAddress, err := WrapperRequestRandomness(consumer, coordinator.Address(), vrfKeyData, subID, - isNativeBilling, config, l) - if err != nil { - return nil, fmt.Errorf("error getting wrapper address, err: %w", err) - } - return WaitForRequestAndFulfillmentEventsUpgraded( - wrapperAddress, - coordinator, - vrfKeyData, - subID, - isNativeBilling, - config.RandomWordsFulfilledEventTimeout.Duration, - l, - ) -} - -func WaitForRequestAndFulfillmentEvents( - consumerAddress string, - coordinator contracts.VRFCoordinatorV2_5, - vrfKeyData *vrfcommon.VRFKeyData, +func WaitRandomWordsFulfilledEvent( + coordinator contracts.Coordinator, + requestId *big.Int, subID *big.Int, isNativeBilling bool, randomWordsFulfilledEventTimeout time.Duration, l zerolog.Logger, -) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { - randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKeyData.KeyHash}, - []*big.Int{subID}, - []common.Address{common.HexToAddress(consumerAddress)}, - time.Minute*1, - ) - if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsRequestedEvent, err) - } - - LogRandomnessRequestedEvent(l, coordinator, randomWordsRequestedEvent, isNativeBilling) - +) (*contracts.CoordinatorRandomWordsFulfilled, error) { randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( - []*big.Int{subID}, - []*big.Int{randomWordsRequestedEvent.RequestId}, - randomWordsFulfilledEventTimeout, + contracts.RandomWordsFulfilledEventFilter{ + SubIDs: []*big.Int{subID}, + RequestIds: []*big.Int{requestId}, + Timeout: randomWordsFulfilledEventTimeout, + }, ) if err != nil { return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsFulfilledEvent, err) } - LogRandomWordsFulfilledEvent(l, coordinator, randomWordsFulfilledEvent, isNativeBilling) - return randomWordsFulfilledEvent, err -} - -func WaitForRequestAndFulfillmentEventsUpgraded( - consumerAddress string, - coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, - vrfKeyData *vrfcommon.VRFKeyData, - subID *big.Int, - isNativeBilling bool, - randomWordsFulfilledEventTimeout time.Duration, - l zerolog.Logger, -) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { - randomWordsRequestedEvent, err := coordinator.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKeyData.KeyHash}, - []*big.Int{subID}, - []common.Address{common.HexToAddress(consumerAddress)}, - time.Minute*1, - ) - if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsRequestedEvent, err) - } - - LogRandomnessRequestedEventUpgraded(l, coordinator, randomWordsRequestedEvent, isNativeBilling) - - randomWordsFulfilledEvent, err := coordinator.WaitForRandomWordsFulfilledEvent( - []*big.Int{subID}, - []*big.Int{randomWordsRequestedEvent.RequestId}, - randomWordsFulfilledEventTimeout, - ) - if err != nil { - return nil, fmt.Errorf("%s, err %w", vrfcommon.ErrWaitRandomWordsFulfilledEvent, err) - } - LogRandomWordsFulfilledEventUpgraded(l, coordinator, randomWordsFulfilledEvent, isNativeBilling) + vrfcommon.LogRandomWordsFulfilledEvent(l, coordinator, randomWordsFulfilledEvent, isNativeBilling) return randomWordsFulfilledEvent, err } diff --git a/integration-tests/actions/vrf/vrfv2plus/logging_helpers.go b/integration-tests/actions/vrf/vrfv2plus/logging_helpers.go index 995af9ee76c..b613298f1fd 100644 --- a/integration-tests/actions/vrf/vrfv2plus/logging_helpers.go +++ b/integration-tests/actions/vrf/vrfv2plus/logging_helpers.go @@ -6,165 +6,12 @@ import ( "github.com/rs/zerolog" - commonassets "github.com/smartcontractkit/chainlink-common/pkg/assets" - vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/contracts" vrfv2plus_config "github.com/smartcontractkit/chainlink/integration-tests/testconfig/vrfv2plus" - "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_v2plus_upgraded_version" - "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrfv2plus_wrapper_load_test_consumer" ) -func LogSubDetails(l zerolog.Logger, subscription vrf_coordinator_v2_5.GetSubscription, subID *big.Int, coordinator contracts.VRFCoordinatorV2_5) { - l.Debug(). - Str("Coordinator", coordinator.Address()). - Str("Link Balance", (*commonassets.Link)(subscription.Balance).Link()). - Str("Native Token Balance", assets.FormatWei(subscription.NativeBalance)). - Str("Subscription ID", subID.String()). - Str("Subscription Owner", subscription.SubOwner.String()). - Interface("Subscription Consumers", subscription.Consumers). - Msg("Subscription Data") -} - -func LogRandomnessRequestedEventUpgraded( - l zerolog.Logger, - coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, - randomWordsRequestedEvent *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, - isNativeBilling bool, -) { - l.Debug(). - Str("Coordinator", coordinator.Address()). - Bool("Native Billing", isNativeBilling). - Str("Request ID", randomWordsRequestedEvent.RequestId.String()). - Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). - Str("Sender Address", randomWordsRequestedEvent.Sender.String()). - 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). - Msg("RandomnessRequested Event") -} - -func LogRandomWordsFulfilledEventUpgraded( - l zerolog.Logger, - coordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, - randomWordsFulfilledEvent *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, - isNativeBilling bool, -) { - l.Debug(). - Str("Coordinator", coordinator.Address()). - Bool("Native Billing", isNativeBilling). - Str("Total Payment in Juels", randomWordsFulfilledEvent.Payment.String()). - Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). - Str("Subscription ID", randomWordsFulfilledEvent.SubID.String()). - Str("Request ID", randomWordsFulfilledEvent.RequestId.String()). - Bool("Success", randomWordsFulfilledEvent.Success). - Msg("RandomWordsFulfilled Event (TX metadata)") -} - -func LogRandomnessRequestedEvent( - l zerolog.Logger, - coordinator contracts.VRFCoordinatorV2_5, - randomWordsRequestedEvent *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested, - isNativeBilling bool, -) { - l.Info(). - Str("Coordinator", coordinator.Address()). - Bool("Native Billing", isNativeBilling). - Str("Request ID", randomWordsRequestedEvent.RequestId.String()). - Str("Subscription ID", randomWordsRequestedEvent.SubId.String()). - Str("Sender Address", randomWordsRequestedEvent.Sender.String()). - 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") -} - -func LogRandomWordsFulfilledEvent( - l zerolog.Logger, - coordinator contracts.VRFCoordinatorV2_5, - randomWordsFulfilledEvent *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, - isNativeBilling bool, -) { - l.Info(). - Bool("Native Billing", isNativeBilling). - Str("Coordinator", coordinator.Address()). - Str("Total Payment", randomWordsFulfilledEvent.Payment.String()). - Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). - Str("Subscription ID", randomWordsFulfilledEvent.SubId.String()). - Str("Request ID", randomWordsFulfilledEvent.RequestId.String()). - Bool("Success", randomWordsFulfilledEvent.Success). - Uint64("BlockNumber", randomWordsFulfilledEvent.Raw.BlockNumber). - Str("BlockHash", randomWordsFulfilledEvent.Raw.BlockHash.String()). - Msg("RandomWordsFulfilled Event (TX metadata)") -} - -func LogMigrationCompletedEvent(l zerolog.Logger, migrationCompletedEvent *vrf_coordinator_v2_5.VRFCoordinatorV25MigrationCompleted, vrfv2PlusContracts *vrfcommon.VRFContracts) { - l.Info(). - Str("Subscription ID", migrationCompletedEvent.SubId.String()). - Str("Migrated From Coordinator", vrfv2PlusContracts.CoordinatorV2Plus.Address()). - Str("Migrated To Coordinator", migrationCompletedEvent.NewCoordinator.String()). - Msg("MigrationCompleted Event") -} - -func LogSubDetailsAfterMigration(l zerolog.Logger, newCoordinator contracts.VRFCoordinatorV2PlusUpgradedVersion, subID *big.Int, migratedSubscription vrf_v2plus_upgraded_version.GetSubscription) { - l.Info(). - Str("New Coordinator", newCoordinator.Address()). - Str("Subscription ID", subID.String()). - Str("Juels Balance", migratedSubscription.Balance.String()). - Str("Native Token Balance", migratedSubscription.NativeBalance.String()). - Str("Subscription Owner", migratedSubscription.SubOwner.String()). - Interface("Subscription Consumers", migratedSubscription.Consumers). - Msg("Subscription Data After Migration to New Coordinator") -} - -func LogFulfillmentDetailsLinkBilling( - l zerolog.Logger, - wrapperConsumerJuelsBalanceBeforeRequest *big.Int, - wrapperConsumerJuelsBalanceAfterRequest *big.Int, - consumerStatus vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, - randomWordsFulfilledEvent *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, -) { - l.Info(). - Str("Consumer Balance Before Request (Link)", (*commonassets.Link)(wrapperConsumerJuelsBalanceBeforeRequest).Link()). - Str("Consumer Balance After Request (Link)", (*commonassets.Link)(wrapperConsumerJuelsBalanceAfterRequest).Link()). - Bool("Fulfilment Status", consumerStatus.Fulfilled). - Str("Paid by Consumer Contract (Link)", (*commonassets.Link)(consumerStatus.Paid).Link()). - Str("Paid by Coordinator Sub (Link)", (*commonassets.Link)(randomWordsFulfilledEvent.Payment).Link()). - Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). - Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). - Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). - Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). - Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). - Msg("Random Words Fulfilment Details For Link Billing") -} - -func LogFulfillmentDetailsNativeBilling( - l zerolog.Logger, - wrapperConsumerBalanceBeforeRequestWei *big.Int, - wrapperConsumerBalanceAfterRequestWei *big.Int, - consumerStatus vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, - randomWordsFulfilledEvent *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, -) { - l.Info(). - Str("Consumer Balance Before Request", assets.FormatWei(wrapperConsumerBalanceBeforeRequestWei)). - Str("Consumer Balance After Request", assets.FormatWei(wrapperConsumerBalanceAfterRequestWei)). - Bool("Fulfilment Status", consumerStatus.Fulfilled). - Str("Paid by Consumer Contract", assets.FormatWei(consumerStatus.Paid)). - Str("Paid by Coordinator Sub", assets.FormatWei(randomWordsFulfilledEvent.Payment)). - Str("RequestTimestamp", consumerStatus.RequestTimestamp.String()). - Str("FulfilmentTimestamp", consumerStatus.FulfilmentTimestamp.String()). - Str("RequestBlockNumber", consumerStatus.RequestBlockNumber.String()). - Str("FulfilmentBlockNumber", consumerStatus.FulfilmentBlockNumber.String()). - Str("TX Hash", randomWordsFulfilledEvent.Raw.TxHash.String()). - Msg("Random Words Request Fulfilment Details For Native Billing") -} - func LogRandRequest( l zerolog.Logger, consumer string, @@ -186,3 +33,22 @@ func LogRandRequest( Uint16("RandomnessRequestCountPerRequestDeviation", *config.RandomnessRequestCountPerRequestDeviation). Msg("Requesting randomness") } + +func LogMigrationCompletedEvent(l zerolog.Logger, migrationCompletedEvent *vrf_coordinator_v2_5.VRFCoordinatorV25MigrationCompleted, coordinator contracts.Coordinator) { + l.Info(). + Str("Subscription ID", migrationCompletedEvent.SubId.String()). + Str("Migrated From Coordinator", coordinator.Address()). + Str("Migrated To Coordinator", migrationCompletedEvent.NewCoordinator.String()). + Msg("MigrationCompleted Event") +} + +func LogSubDetailsAfterMigration(l zerolog.Logger, newCoordinator contracts.Coordinator, subID *big.Int, migratedSubscription vrf_v2plus_upgraded_version.GetSubscription) { + l.Info(). + Str("New Coordinator", newCoordinator.Address()). + Str("Subscription ID", subID.String()). + Str("Juels Balance", migratedSubscription.Balance.String()). + Str("Native Token Balance", migratedSubscription.NativeBalance.String()). + Str("Subscription Owner", migratedSubscription.SubOwner.String()). + Interface("Subscription Consumers", migratedSubscription.Consumers). + Msg("Subscription Data After Migration to New Coordinator") +} diff --git a/integration-tests/contracts/contract_vrf_models.go b/integration-tests/contracts/contract_vrf_models.go index 4dff9c98b61..e23149c7de4 100644 --- a/integration-tests/contracts/contract_vrf_models.go +++ b/integration-tests/contracts/contract_vrf_models.go @@ -60,23 +60,23 @@ type VRFCoordinatorV2 interface { CreateSubscription() (*types.Transaction, error) AddConsumer(subId uint64, consumerAddress string) error Address() string - GetSubscription(ctx context.Context, subID uint64) (vrf_coordinator_v2.GetSubscription, error) + GetSubscription(ctx context.Context, subID uint64) (Subscription, error) GetOwner(ctx context.Context) (common.Address, error) PendingRequestsExist(ctx context.Context, subID uint64) (bool, error) OwnerCancelSubscription(subID uint64) (*types.Transaction, error) ParseSubscriptionCanceled(log types.Log) (*vrf_coordinator_v2.VRFCoordinatorV2SubscriptionCanceled, error) - ParseRandomWordsRequested(log types.Log) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) + ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error) ParseLog(log types.Log) (generated.AbigenLog, error) CancelSubscription(subID uint64, to common.Address) (*types.Transaction, error) FindSubscriptionID(subID uint64) (uint64, error) - WaitForRandomWordsFulfilledEvent(requestID []*big.Int, timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, error) + WaitForRandomWordsFulfilledEvent(filter RandomWordsFulfilledEventFilter) (*CoordinatorRandomWordsFulfilled, error) WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []uint64, sender []common.Address, timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) WaitForSubscriptionCanceledEvent(subID []uint64, timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2SubscriptionCanceled, error) WaitForSubscriptionConsumerAdded(subID []uint64, timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2SubscriptionConsumerAdded, error) WaitForSubscriptionConsumerRemoved(subID []uint64, timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2SubscriptionConsumerRemoved, error) WaitForSubscriptionCreatedEvent(subID []uint64, timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2SubscriptionCreated, error) WaitForSubscriptionFunded(subID []uint64, timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2SubscriptionFunded, error) - WaitForConfigSetEvent(timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2ConfigSet, error) + WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error) OracleWithdraw(recipient common.Address, amount *big.Int) error } @@ -109,7 +109,7 @@ type VRFCoordinatorV2_5 interface { FundSubscriptionWithNative(subId *big.Int, nativeTokenAmount *big.Int) error Address() string PendingRequestsExist(ctx context.Context, subID *big.Int) (bool, error) - GetSubscription(ctx context.Context, subID *big.Int) (vrf_coordinator_v2_5.GetSubscription, error) + GetSubscription(ctx context.Context, subID *big.Int) (Subscription, error) OwnerCancelSubscription(subID *big.Int) (*types.Transaction, error) CancelSubscription(subID *big.Int, to common.Address) (*types.Transaction, error) Withdraw(recipient common.Address) error @@ -119,9 +119,10 @@ type VRFCoordinatorV2_5 interface { FindSubscriptionID(subID *big.Int) (*big.Int, error) WaitForSubscriptionCreatedEvent(timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25SubscriptionCreated, error) WaitForSubscriptionCanceledEvent(subID *big.Int, timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25SubscriptionCanceled, error) - WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) - WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested, error) + WaitForRandomWordsFulfilledEvent(filter RandomWordsFulfilledEventFilter) (*CoordinatorRandomWordsFulfilled, error) WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25MigrationCompleted, error) + ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error) + WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error) } type VRFCoordinatorV2PlusUpgradedVersion interface { @@ -142,6 +143,7 @@ type VRFCoordinatorV2PlusUpgradedVersion interface { ) error RegisterProvingKey( publicProvingKey [2]*big.Int, + gasLaneMaxGasPrice uint64, ) error HashOfKey(ctx context.Context, pubKey [2]*big.Int) ([32]byte, error) CreateSubscription() error @@ -155,9 +157,10 @@ type VRFCoordinatorV2PlusUpgradedVersion interface { GetSubscription(ctx context.Context, subID *big.Int) (vrf_v2plus_upgraded_version.GetSubscription, error) GetActiveSubscriptionIds(ctx context.Context, startIndex *big.Int, maxCount *big.Int) ([]*big.Int, error) FindSubscriptionID() (*big.Int, error) - WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) + WaitForRandomWordsFulfilledEvent(filter RandomWordsFulfilledEventFilter) (*CoordinatorRandomWordsFulfilled, error) WaitForMigrationCompletedEvent(timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted, error) - WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, error) + ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error) + WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error) } type VRFV2Wrapper interface { @@ -211,15 +214,16 @@ type VRFv2Consumer interface { type VRFv2LoadTestConsumer interface { Address() string RequestRandomness( - coordinator VRFCoordinatorV2, + coordinator Coordinator, keyHash [32]byte, subID uint64, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16, - ) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) + ) (*CoordinatorRandomWordsRequested, error) RequestRandomWordsWithForceFulfill( + coordinator Coordinator, keyHash [32]byte, requestConfirmations uint16, callbackGasLimit uint32, @@ -227,7 +231,7 @@ type VRFv2LoadTestConsumer interface { requestCount uint16, subTopUpAmount *big.Int, linkAddress common.Address, - ) (*types.Transaction, error) + ) (*CoordinatorRandomWordsRequested, error) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrf_load_test_with_metrics.GetRequestStatus, error) GetLastRequestId(ctx context.Context) (*big.Int, error) GetLoadTestMetrics(ctx context.Context) (*VRFLoadTestMetrics, error) @@ -237,7 +241,7 @@ type VRFv2LoadTestConsumer interface { type VRFv2WrapperLoadTestConsumer interface { Address() string Fund(ethAmount *big.Float) error - RequestRandomness(coordinator VRFCoordinatorV2, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) + RequestRandomness(coordinator Coordinator, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*CoordinatorRandomWordsRequested, error) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrfv2_wrapper_load_test_consumer.GetRequestStatus, error) GetLastRequestId(ctx context.Context) (*big.Int, error) GetWrapper(ctx context.Context) (common.Address, error) @@ -246,7 +250,15 @@ type VRFv2WrapperLoadTestConsumer interface { type VRFv2PlusLoadTestConsumer interface { Address() string - RequestRandomness(keyHash [32]byte, subID *big.Int, requestConfirmations uint16, callbackGasLimit uint32, nativePayment bool, numWords uint32, requestCount uint16) (*types.Transaction, error) + RequestRandomness( + coordinator Coordinator, + keyHash [32]byte, subID *big.Int, + requestConfirmations uint16, + callbackGasLimit uint32, + nativePayment bool, + numWords uint32, + requestCount uint16, + ) (*CoordinatorRandomWordsRequested, error) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrf_v2plus_load_test_with_metrics.GetRequestStatus, error) GetLastRequestId(ctx context.Context) (*big.Int, error) GetLoadTestMetrics(ctx context.Context) (*VRFLoadTestMetrics, error) @@ -257,8 +269,20 @@ type VRFv2PlusLoadTestConsumer interface { type VRFv2PlusWrapperLoadTestConsumer interface { Address() string Fund(ethAmount *big.Float) error - RequestRandomness(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) - RequestRandomnessNative(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) + RequestRandomness( + coordinator Coordinator, + requestConfirmations uint16, + callbackGasLimit uint32, + numWords uint32, + requestCount uint16, + ) (*CoordinatorRandomWordsRequested, error) + RequestRandomnessNative( + coordinator Coordinator, + requestConfirmations uint16, + callbackGasLimit uint32, + numWords uint32, + requestCount uint16, + ) (*CoordinatorRandomWordsRequested, error) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, error) GetLastRequestId(ctx context.Context) (*big.Int, error) GetWrapper(ctx context.Context) (common.Address, error) diff --git a/integration-tests/contracts/ethereum_vrf_common.go b/integration-tests/contracts/ethereum_vrf_common.go new file mode 100644 index 00000000000..d7eafe42a07 --- /dev/null +++ b/integration-tests/contracts/ethereum_vrf_common.go @@ -0,0 +1,124 @@ +package contracts + +import ( + "fmt" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + + "github.com/smartcontractkit/chainlink-testing-framework/blockchain" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/vrf_coordinator_v2_5" +) + +type Coordinator interface { + ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error) + Address() string + WaitForRandomWordsFulfilledEvent(filter RandomWordsFulfilledEventFilter) (*CoordinatorRandomWordsFulfilled, error) + WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error) +} + +type Subscription struct { + Balance *big.Int + NativeBalance *big.Int + ReqCount uint64 + SubOwner common.Address + Consumers []common.Address +} + +type CoordinatorConfigSet struct { + MinimumRequestConfirmations uint16 + MaxGasLimit uint32 + StalenessSeconds uint32 + GasAfterPaymentCalculation uint32 + FallbackWeiPerUnitLink *big.Int + FulfillmentFlatFeeNativePPM uint32 + FulfillmentFlatFeeLinkDiscountPPM uint32 + NativePremiumPercentage uint8 + LinkPremiumPercentage uint8 + FeeConfig VRFCoordinatorV2FeeConfig + Raw types.Log +} + +type VRFCoordinatorV2FeeConfig struct { + FulfillmentFlatFeeLinkPPMTier1 uint32 + FulfillmentFlatFeeLinkPPMTier2 uint32 + FulfillmentFlatFeeLinkPPMTier3 uint32 + FulfillmentFlatFeeLinkPPMTier4 uint32 + FulfillmentFlatFeeLinkPPMTier5 uint32 + ReqsForTier2 *big.Int + ReqsForTier3 *big.Int + ReqsForTier4 *big.Int + ReqsForTier5 *big.Int +} + +type RandomWordsFulfilledEventFilter struct { + RequestIds []*big.Int + SubIDs []*big.Int + Timeout time.Duration +} + +type CoordinatorRandomWordsFulfilled struct { + RequestId *big.Int + OutputSeed *big.Int + SubId string + Payment *big.Int + NativePayment bool + Success bool + OnlyPremium bool + Raw types.Log +} + +type CoordinatorRandomWordsRequested struct { + KeyHash [32]byte + RequestId *big.Int + PreSeed *big.Int + SubId string + MinimumRequestConfirmations uint16 + CallbackGasLimit uint32 + NumWords uint32 + ExtraArgs []byte + Sender common.Address + Raw types.Log +} + +func parseRequestRandomnessLogs(coordinator Coordinator, logs []*types.Log) (*CoordinatorRandomWordsRequested, error) { + var randomWordsRequestedEvent *CoordinatorRandomWordsRequested + var err error + for _, eventLog := range logs { + for _, topic := range eventLog.Topics { + if topic.Cmp(vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested{}.Topic()) == 0 { + randomWordsRequestedEvent, err = coordinator.ParseRandomWordsRequested(*eventLog) + if err != nil { + return nil, fmt.Errorf("parse RandomWordsRequested log failed, err: %w", err) + } + } + if topic.Cmp(vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested{}.Topic()) == 0 { + randomWordsRequestedEvent, err = coordinator.ParseRandomWordsRequested(*eventLog) + if err != nil { + return nil, fmt.Errorf("parse RandomWordsRequested log failed, err: %w", err) + } + } + } + } + return randomWordsRequestedEvent, nil +} + +func RetrieveRequestRandomnessLogs(coordinator Coordinator, client blockchain.EVMClient, tx *types.Transaction) (*CoordinatorRandomWordsRequested, error) { + err := client.ProcessTransaction(tx) + if err != nil { + return nil, fmt.Errorf("ProcessTransaction failed, err: %w", err) + } + err = client.WaitForEvents() + if err != nil { + return nil, fmt.Errorf("WaitForEvents failed, err: %w", err) + } + receipt, err := client.GetTxReceipt(tx.Hash()) + if err != nil { + return nil, fmt.Errorf("GetTxReceipt failed, err: %w", err) + } + return parseRequestRandomnessLogs(coordinator, receipt.Logs) + +} diff --git a/integration-tests/contracts/ethereum_vrfv2_contracts.go b/integration-tests/contracts/ethereum_vrfv2_contracts.go index ed99fb91109..c5116856d48 100644 --- a/integration-tests/contracts/ethereum_vrfv2_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2_contracts.go @@ -5,6 +5,7 @@ import ( "encoding/hex" "fmt" "math/big" + "strconv" "time" "github.com/ethereum/go-ethereum" @@ -248,16 +249,22 @@ func (v *EthereumVRFCoordinatorV2) HashOfKey(ctx context.Context, pubKey [2]*big return hash, nil } -func (v *EthereumVRFCoordinatorV2) GetSubscription(ctx context.Context, subID uint64) (vrf_coordinator_v2.GetSubscription, error) { +func (v *EthereumVRFCoordinatorV2) GetSubscription(ctx context.Context, subID uint64) (Subscription, error) { opts := &bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, } subscription, err := v.coordinator.GetSubscription(opts, subID) if err != nil { - return vrf_coordinator_v2.GetSubscription{}, err + return Subscription{}, err } - return subscription, nil + return Subscription{ + Balance: subscription.Balance, + NativeBalance: nil, + SubOwner: subscription.Owner, + Consumers: subscription.Consumers, + ReqCount: subscription.ReqCount, + }, nil } func (v *EthereumVRFCoordinatorV2) GetOwner(ctx context.Context) (common.Address, error) { @@ -448,8 +455,24 @@ func (v *EthereumVRFCoordinatorV2) ParseSubscriptionCanceled(log types.Log) (*vr return v.coordinator.ParseSubscriptionCanceled(log) } -func (v *EthereumVRFCoordinatorV2) ParseRandomWordsRequested(log types.Log) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { - return v.coordinator.ParseRandomWordsRequested(log) +func (v *EthereumVRFCoordinatorV2) ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error) { + requested, err := v.coordinator.ParseRandomWordsRequested(log) + if err != nil { + return nil, fmt.Errorf("failed to parse RandomWordsRequested event: %w", err) + } + + return &CoordinatorRandomWordsRequested{ + KeyHash: requested.KeyHash, + RequestId: requested.RequestId, + PreSeed: requested.PreSeed, + SubId: strconv.FormatUint(requested.SubId, 10), + MinimumRequestConfirmations: requested.MinimumRequestConfirmations, + CallbackGasLimit: requested.CallbackGasLimit, + NumWords: requested.NumWords, + Sender: requested.Sender, + ExtraArgs: nil, + Raw: requested.Raw, + }, nil } func (v *EthereumVRFCoordinatorV2) ParseLog(log types.Log) (generated.AbigenLog, error) { @@ -492,9 +515,9 @@ func (v *EthereumVRFCoordinatorV2) FindSubscriptionID(subID uint64) (uint64, err return subscriptionIterator.Event.SubId, nil } -func (v *EthereumVRFCoordinatorV2) WaitForRandomWordsFulfilledEvent(requestID []*big.Int, timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled, error) { +func (v *EthereumVRFCoordinatorV2) WaitForRandomWordsFulfilledEvent(filter RandomWordsFulfilledEventFilter) (*CoordinatorRandomWordsFulfilled, error) { randomWordsFulfilledEventsChannel := make(chan *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsFulfilled) - subscription, err := v.coordinator.WatchRandomWordsFulfilled(nil, randomWordsFulfilledEventsChannel, requestID) + subscription, err := v.coordinator.WatchRandomWordsFulfilled(nil, randomWordsFulfilledEventsChannel, filter.RequestIds) if err != nil { return nil, err } @@ -504,10 +527,16 @@ func (v *EthereumVRFCoordinatorV2) WaitForRandomWordsFulfilledEvent(requestID [] select { case err := <-subscription.Err(): return nil, err - case <-time.After(timeout): + case <-time.After(filter.Timeout): return nil, fmt.Errorf("timeout waiting for RandomWordsFulfilled event") case randomWordsFulfilledEvent := <-randomWordsFulfilledEventsChannel: - return randomWordsFulfilledEvent, nil + return &CoordinatorRandomWordsFulfilled{ + RequestId: randomWordsFulfilledEvent.RequestId, + OutputSeed: randomWordsFulfilledEvent.OutputSeed, + Payment: randomWordsFulfilledEvent.Payment, + Success: randomWordsFulfilledEvent.Success, + Raw: randomWordsFulfilledEvent.Raw, + }, nil } } } @@ -632,7 +661,7 @@ func (v *EthereumVRFCoordinatorV2) WaitForSubscriptionConsumerRemoved(subID []ui } } -func (v *EthereumVRFCoordinatorV2) WaitForConfigSetEvent(timeout time.Duration) (*vrf_coordinator_v2.VRFCoordinatorV2ConfigSet, error) { +func (v *EthereumVRFCoordinatorV2) WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error) { eventsChannel := make(chan *vrf_coordinator_v2.VRFCoordinatorV2ConfigSet) subscription, err := v.coordinator.WatchConfigSet(nil, eventsChannel) if err != nil { @@ -647,7 +676,24 @@ func (v *EthereumVRFCoordinatorV2) WaitForConfigSetEvent(timeout time.Duration) case <-time.After(timeout): return nil, fmt.Errorf("timeout waiting for ConfigSet event") case event := <-eventsChannel: - return event, nil + return &CoordinatorConfigSet{ + MinimumRequestConfirmations: event.MinimumRequestConfirmations, + MaxGasLimit: event.MaxGasLimit, + StalenessSeconds: event.StalenessSeconds, + GasAfterPaymentCalculation: event.GasAfterPaymentCalculation, + FallbackWeiPerUnitLink: event.FallbackWeiPerUnitLink, + FeeConfig: VRFCoordinatorV2FeeConfig{ + FulfillmentFlatFeeLinkPPMTier1: event.FeeConfig.FulfillmentFlatFeeLinkPPMTier1, + FulfillmentFlatFeeLinkPPMTier2: event.FeeConfig.FulfillmentFlatFeeLinkPPMTier2, + FulfillmentFlatFeeLinkPPMTier3: event.FeeConfig.FulfillmentFlatFeeLinkPPMTier3, + FulfillmentFlatFeeLinkPPMTier4: event.FeeConfig.FulfillmentFlatFeeLinkPPMTier4, + FulfillmentFlatFeeLinkPPMTier5: event.FeeConfig.FulfillmentFlatFeeLinkPPMTier5, + ReqsForTier2: event.FeeConfig.ReqsForTier2, + ReqsForTier3: event.FeeConfig.ReqsForTier3, + ReqsForTier4: event.FeeConfig.ReqsForTier4, + ReqsForTier5: event.FeeConfig.ReqsForTier5, + }, + }, nil } } } @@ -794,14 +840,14 @@ func (v *EthereumVRFv2LoadTestConsumer) Address() string { } func (v *EthereumVRFv2LoadTestConsumer) RequestRandomness( - coordinator VRFCoordinatorV2, + coordinator Coordinator, keyHash [32]byte, subID uint64, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16, -) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { +) (*CoordinatorRandomWordsRequested, error) { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return nil, err @@ -810,23 +856,15 @@ func (v *EthereumVRFv2LoadTestConsumer) RequestRandomness( if err != nil { return nil, fmt.Errorf("RequestRandomWords failed, err: %w", err) } - err = v.client.ProcessTransaction(tx) - if err != nil { - return nil, fmt.Errorf("ProcessTransaction failed, err: %w", err) - } - err = v.client.WaitForEvents() - if err != nil { - return nil, fmt.Errorf("WaitForEvents failed, err: %w", err) - } - receipt, err := v.client.GetTxReceipt(tx.Hash()) + randomWordsRequestedEvent, err := RetrieveRequestRandomnessLogs(coordinator, v.client, tx) if err != nil { - return nil, fmt.Errorf("GetTxReceipt failed, err: %w", err) + return nil, err } - randomWordsRequestedEvent, err := parseRequestRandomnessLogs(coordinator, receipt.Logs) - return randomWordsRequestedEvent, err + return randomWordsRequestedEvent, nil } func (v *EthereumVRFv2LoadTestConsumer) RequestRandomWordsWithForceFulfill( + coordinator Coordinator, keyHash [32]byte, requestConfirmations uint16, callbackGasLimit uint32, @@ -834,7 +872,7 @@ func (v *EthereumVRFv2LoadTestConsumer) RequestRandomWordsWithForceFulfill( requestCount uint16, subTopUpAmount *big.Int, linkAddress common.Address, -) (*types.Transaction, error) { +) (*CoordinatorRandomWordsRequested, error) { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return nil, err @@ -849,10 +887,14 @@ func (v *EthereumVRFv2LoadTestConsumer) RequestRandomWordsWithForceFulfill( subTopUpAmount, linkAddress, ) + if err != nil { + return nil, fmt.Errorf("RequestRandomWords failed, err: %w", err) + } + randomWordsRequestedEvent, err := RetrieveRequestRandomnessLogs(coordinator, v.client, tx) if err != nil { return nil, err } - return tx, v.client.ProcessTransaction(tx) + return randomWordsRequestedEvent, nil } func (v *EthereumVRFv2Consumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrf_v2_consumer_wrapper.GetRequestStatus, error) { @@ -990,7 +1032,7 @@ func (v *EthereumVRFV2WrapperLoadTestConsumer) Fund(ethAmount *big.Float) error return v.client.Fund(v.address.Hex(), ethAmount, gasEstimates) } -func (v *EthereumVRFV2WrapperLoadTestConsumer) RequestRandomness(coordinator VRFCoordinatorV2, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { +func (v *EthereumVRFV2WrapperLoadTestConsumer) RequestRandomness(coordinator Coordinator, requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*CoordinatorRandomWordsRequested, error) { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return nil, err @@ -999,23 +1041,11 @@ func (v *EthereumVRFV2WrapperLoadTestConsumer) RequestRandomness(coordinator VRF if err != nil { return nil, err } - err = v.client.ProcessTransaction(tx) + randomWordsRequestedEvent, err := RetrieveRequestRandomnessLogs(coordinator, v.client, tx) if err != nil { return nil, err } - err = v.client.WaitForEvents() - if err != nil { - return nil, fmt.Errorf("WaitForEvents failed, err: %w", err) - } - receipt, err := v.client.GetTxReceipt(tx.Hash()) - if err != nil { - return nil, fmt.Errorf("GetTxReceipt failed, err: %w", err) - } - randomWordsRequestedEvent, err := parseRequestRandomnessLogs(coordinator, receipt.Logs) - if err != nil { - return nil, err - } - return randomWordsRequestedEvent, err + return randomWordsRequestedEvent, nil } func (v *EthereumVRFV2WrapperLoadTestConsumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrfv2_wrapper_load_test_consumer.GetRequestStatus, error) { @@ -1199,19 +1229,3 @@ func (v *EthereumVRFMockETHLINKFeed) SetBlockTimestampDeduction(blockTimestampDe } return v.client.ProcessTransaction(tx) } - -func parseRequestRandomnessLogs(coordinator VRFCoordinatorV2, logs []*types.Log) (*vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested, error) { - var randomWordsRequestedEvent *vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested - var err error - for _, eventLog := range logs { - for _, topic := range eventLog.Topics { - if topic.Cmp(vrf_coordinator_v2.VRFCoordinatorV2RandomWordsRequested{}.Topic()) == 0 { - randomWordsRequestedEvent, err = coordinator.ParseRandomWordsRequested(*eventLog) - if err != nil { - return nil, fmt.Errorf("parse RandomWordsRequested log failed, err: %w", err) - } - } - } - } - return randomWordsRequestedEvent, nil -} diff --git a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go index 432f700fa04..1c2bbcd0113 100644 --- a/integration-tests/contracts/ethereum_vrfv2plus_contracts.go +++ b/integration-tests/contracts/ethereum_vrfv2plus_contracts.go @@ -165,16 +165,42 @@ func (v *EthereumVRFCoordinatorV2_5) PendingRequestsExist(ctx context.Context, s return pendingRequestExists, nil } -func (v *EthereumVRFCoordinatorV2_5) GetSubscription(ctx context.Context, subID *big.Int) (vrf_coordinator_v2_5.GetSubscription, error) { +func (v *EthereumVRFCoordinatorV2_5) ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error) { + randomWordsRequested, err := v.coordinator.ParseRandomWordsRequested(log) + if err != nil { + return nil, fmt.Errorf("parse RandomWordsRequested log failed, err: %w", err) + } + coordinatorRandomWordsRequested := &CoordinatorRandomWordsRequested{ + KeyHash: randomWordsRequested.KeyHash, + RequestId: randomWordsRequested.RequestId, + PreSeed: randomWordsRequested.PreSeed, + SubId: randomWordsRequested.SubId.String(), + MinimumRequestConfirmations: randomWordsRequested.MinimumRequestConfirmations, + CallbackGasLimit: randomWordsRequested.CallbackGasLimit, + NumWords: randomWordsRequested.NumWords, + ExtraArgs: randomWordsRequested.ExtraArgs, + Sender: randomWordsRequested.Sender, + Raw: randomWordsRequested.Raw, + } + return coordinatorRandomWordsRequested, nil +} + +func (v *EthereumVRFCoordinatorV2_5) GetSubscription(ctx context.Context, subID *big.Int) (Subscription, error) { opts := &bind.CallOpts{ From: common.HexToAddress(v.client.GetDefaultWallet().Address()), Context: ctx, } subscription, err := v.coordinator.GetSubscription(opts, subID) if err != nil { - return vrf_coordinator_v2_5.GetSubscription{}, err + return Subscription{}, err } - return subscription, nil + return Subscription{ + Balance: subscription.Balance, + NativeBalance: subscription.NativeBalance, + SubOwner: subscription.SubOwner, + Consumers: subscription.Consumers, + ReqCount: subscription.ReqCount, + }, nil } func (v *EthereumVRFCoordinatorV2_5) GetLinkTotalBalance(ctx context.Context) (*big.Int, error) { @@ -455,9 +481,9 @@ func (v *EthereumVRFCoordinatorV2_5) WaitForSubscriptionCanceledEvent(subID *big } } -func (v *EthereumVRFCoordinatorV2_5) WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled, error) { +func (v *EthereumVRFCoordinatorV2_5) WaitForRandomWordsFulfilledEvent(filter RandomWordsFulfilledEventFilter) (*CoordinatorRandomWordsFulfilled, error) { randomWordsFulfilledEventsChannel := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsFulfilled) - subscription, err := v.coordinator.WatchRandomWordsFulfilled(nil, randomWordsFulfilledEventsChannel, requestID, subID) + subscription, err := v.coordinator.WatchRandomWordsFulfilled(nil, randomWordsFulfilledEventsChannel, filter.RequestIds, filter.SubIDs) if err != nil { return nil, err } @@ -467,30 +493,48 @@ func (v *EthereumVRFCoordinatorV2_5) WaitForRandomWordsFulfilledEvent(subID []*b select { case err := <-subscription.Err(): return nil, err - case <-time.After(timeout): + case <-time.After(filter.Timeout): return nil, fmt.Errorf("timeout waiting for RandomWordsFulfilled event") case randomWordsFulfilledEvent := <-randomWordsFulfilledEventsChannel: - return randomWordsFulfilledEvent, nil + return &CoordinatorRandomWordsFulfilled{ + RequestId: randomWordsFulfilledEvent.RequestId, + OutputSeed: randomWordsFulfilledEvent.OutputSeed, + SubId: randomWordsFulfilledEvent.SubId.String(), + Payment: randomWordsFulfilledEvent.Payment, + NativePayment: randomWordsFulfilledEvent.NativePayment, + Success: randomWordsFulfilledEvent.Success, + OnlyPremium: randomWordsFulfilledEvent.OnlyPremium, + Raw: randomWordsFulfilledEvent.Raw, + }, nil } } } -func (v *EthereumVRFCoordinatorV2_5) WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested, error) { - randomWordsFulfilledEventsChannel := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25RandomWordsRequested) - subscription, err := v.coordinator.WatchRandomWordsRequested(nil, randomWordsFulfilledEventsChannel, keyHash, subID, sender) +func (v *EthereumVRFCoordinatorV2_5) WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error) { + eventsChannel := make(chan *vrf_coordinator_v2_5.VRFCoordinatorV25ConfigSet) + subscription, err := v.coordinator.WatchConfigSet(nil, eventsChannel) if err != nil { return nil, err } defer subscription.Unsubscribe() - for { select { case err := <-subscription.Err(): return nil, err case <-time.After(timeout): - return nil, fmt.Errorf("timeout waiting for RandomWordsRequested event") - case randomWordsFulfilledEvent := <-randomWordsFulfilledEventsChannel: - return randomWordsFulfilledEvent, nil + return nil, fmt.Errorf("timeout waiting for ConfigSet event") + case event := <-eventsChannel: + return &CoordinatorConfigSet{ + MinimumRequestConfirmations: event.MinimumRequestConfirmations, + MaxGasLimit: event.MaxGasLimit, + StalenessSeconds: event.StalenessSeconds, + GasAfterPaymentCalculation: event.GasAfterPaymentCalculation, + FallbackWeiPerUnitLink: event.FallbackWeiPerUnitLink, + FulfillmentFlatFeeNativePPM: event.FulfillmentFlatFeeNativePPM, + FulfillmentFlatFeeLinkDiscountPPM: event.FulfillmentFlatFeeLinkDiscountPPM, + NativePremiumPercentage: event.NativePremiumPercentage, + LinkPremiumPercentage: event.LinkPremiumPercentage, + }, nil } } } @@ -518,7 +562,15 @@ func (v *EthereumVRFCoordinatorV2_5) WaitForMigrationCompletedEvent(timeout time func (v *EthereumVRFv2PlusLoadTestConsumer) Address() string { return v.address.Hex() } -func (v *EthereumVRFv2PlusLoadTestConsumer) RequestRandomness(keyHash [32]byte, subID *big.Int, requestConfirmations uint16, callbackGasLimit uint32, nativePayment bool, numWords uint32, requestCount uint16) (*types.Transaction, error) { +func (v *EthereumVRFv2PlusLoadTestConsumer) RequestRandomness( + coordinator Coordinator, + keyHash [32]byte, subID *big.Int, + requestConfirmations uint16, + callbackGasLimit uint32, + nativePayment bool, + numWords uint32, + requestCount uint16, +) (*CoordinatorRandomWordsRequested, error) { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return nil, err @@ -527,8 +579,11 @@ func (v *EthereumVRFv2PlusLoadTestConsumer) RequestRandomness(keyHash [32]byte, if err != nil { return nil, err } - - return tx, v.client.ProcessTransaction(tx) + randomWordsRequestedEvent, err := RetrieveRequestRandomnessLogs(coordinator, v.client, tx) + if err != nil { + return nil, err + } + return randomWordsRequestedEvent, nil } func (v *EthereumVRFv2PlusLoadTestConsumer) ResetMetrics() error { @@ -734,7 +789,8 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) SetConfig( fulfillmentFlatFeeNativePPM uint32, fulfillmentFlatFeeLinkDiscountPPM uint32, nativePremiumPercentage uint8, - linkPremiumPercentage uint8) error { + linkPremiumPercentage uint8, +) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err @@ -775,12 +831,13 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) SetLINKAndLINKNativeFeed(l func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) RegisterProvingKey( publicProvingKey [2]*big.Int, + gasLaneMaxGas uint64, ) error { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return err } - tx, err := v.coordinator.RegisterProvingKey(opts, publicProvingKey) + tx, err := v.coordinator.RegisterProvingKey(opts, publicProvingKey, gasLaneMaxGas) if err != nil { return err } @@ -895,9 +952,9 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) FindSubscriptionID() (*big return subscriptionIterator.Event.SubId, nil } -func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForRandomWordsFulfilledEvent(subID []*big.Int, requestID []*big.Int, timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled, error) { +func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForRandomWordsFulfilledEvent(filter RandomWordsFulfilledEventFilter) (*CoordinatorRandomWordsFulfilled, error) { randomWordsFulfilledEventsChannel := make(chan *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsFulfilled) - subscription, err := v.coordinator.WatchRandomWordsFulfilled(nil, randomWordsFulfilledEventsChannel, requestID, subID) + subscription, err := v.coordinator.WatchRandomWordsFulfilled(nil, randomWordsFulfilledEventsChannel, filter.RequestIds, filter.SubIDs) if err != nil { return nil, err } @@ -907,10 +964,19 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForRandomWordsFulfille select { case err := <-subscription.Err(): return nil, err - case <-time.After(timeout): + case <-time.After(filter.Timeout): return nil, fmt.Errorf("timeout waiting for RandomWordsFulfilled event") case randomWordsFulfilledEvent := <-randomWordsFulfilledEventsChannel: - return randomWordsFulfilledEvent, nil + return &CoordinatorRandomWordsFulfilled{ + RequestId: randomWordsFulfilledEvent.RequestId, + OutputSeed: randomWordsFulfilledEvent.OutputSeed, + SubId: randomWordsFulfilledEvent.SubId.String(), + Payment: randomWordsFulfilledEvent.Payment, + NativePayment: randomWordsFulfilledEvent.NativePayment, + Success: randomWordsFulfilledEvent.Success, + OnlyPremium: randomWordsFulfilledEvent.OnlyPremium, + Raw: randomWordsFulfilledEvent.Raw, + }, nil } } } @@ -919,7 +985,7 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForMigrationCompletedE eventsChannel := make(chan *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionMigrationCompleted) subscription, err := v.coordinator.WatchMigrationCompleted(nil, eventsChannel) if err != nil { - return nil, err + return nil, fmt.Errorf("parse RandomWordsRequested log failed, err: %w", err) } defer subscription.Unsubscribe() @@ -935,22 +1001,51 @@ func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForMigrationCompletedE } } -func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForRandomWordsRequestedEvent(keyHash [][32]byte, subID []*big.Int, sender []common.Address, timeout time.Duration) (*vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested, error) { - eventsChannel := make(chan *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionRandomWordsRequested) - subscription, err := v.coordinator.WatchRandomWordsRequested(nil, eventsChannel, keyHash, subID, sender) +func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) ParseRandomWordsRequested(log types.Log) (*CoordinatorRandomWordsRequested, error) { + randomWordsRequested, err := v.coordinator.ParseRandomWordsRequested(log) if err != nil { return nil, err } - defer subscription.Unsubscribe() + coordinatorRandomWordsRequested := &CoordinatorRandomWordsRequested{ + KeyHash: randomWordsRequested.KeyHash, + RequestId: randomWordsRequested.RequestId, + PreSeed: randomWordsRequested.PreSeed, + SubId: randomWordsRequested.SubId.String(), + MinimumRequestConfirmations: randomWordsRequested.MinimumRequestConfirmations, + CallbackGasLimit: randomWordsRequested.CallbackGasLimit, + NumWords: randomWordsRequested.NumWords, + ExtraArgs: randomWordsRequested.ExtraArgs, + Sender: randomWordsRequested.Sender, + Raw: randomWordsRequested.Raw, + } + return coordinatorRandomWordsRequested, nil +} +func (v *EthereumVRFCoordinatorV2PlusUpgradedVersion) WaitForConfigSetEvent(timeout time.Duration) (*CoordinatorConfigSet, error) { + eventsChannel := make(chan *vrf_v2plus_upgraded_version.VRFCoordinatorV2PlusUpgradedVersionConfigSet) + subscription, err := v.coordinator.WatchConfigSet(nil, eventsChannel) + if err != nil { + return nil, err + } + defer subscription.Unsubscribe() for { select { case err := <-subscription.Err(): return nil, err case <-time.After(timeout): - return nil, fmt.Errorf("timeout waiting for RandomWordsRequested event") - case randomWordsRequestedEvent := <-eventsChannel: - return randomWordsRequestedEvent, nil + return nil, fmt.Errorf("timeout waiting for ConfigSet event") + case event := <-eventsChannel: + return &CoordinatorConfigSet{ + MinimumRequestConfirmations: event.MinimumRequestConfirmations, + MaxGasLimit: event.MaxGasLimit, + StalenessSeconds: event.StalenessSeconds, + GasAfterPaymentCalculation: event.GasAfterPaymentCalculation, + FallbackWeiPerUnitLink: event.FallbackWeiPerUnitLink, + FulfillmentFlatFeeNativePPM: event.FulfillmentFlatFeeNativePPM, + FulfillmentFlatFeeLinkDiscountPPM: event.FulfillmentFlatFeeLinkDiscountPPM, + NativePremiumPercentage: event.NativePremiumPercentage, + LinkPremiumPercentage: event.LinkPremiumPercentage, + }, nil } } } @@ -1020,7 +1115,13 @@ func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) Fund(ethAmount *big.Float) er return v.client.Fund(v.address.Hex(), ethAmount, gasEstimates) } -func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) RequestRandomness(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) { +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) RequestRandomness( + coordinator Coordinator, + requestConfirmations uint16, + callbackGasLimit uint32, + numWords uint32, + requestCount uint16, +) (*CoordinatorRandomWordsRequested, error) { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return nil, err @@ -1029,11 +1130,20 @@ func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) RequestRandomness(requestConf if err != nil { return nil, err } - - return tx, v.client.ProcessTransaction(tx) + randomWordsRequestedEvent, err := RetrieveRequestRandomnessLogs(coordinator, v.client, tx) + if err != nil { + return nil, err + } + return randomWordsRequestedEvent, nil } -func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) RequestRandomnessNative(requestConfirmations uint16, callbackGasLimit uint32, numWords uint32, requestCount uint16) (*types.Transaction, error) { +func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) RequestRandomnessNative( + coordinator Coordinator, + requestConfirmations uint16, + callbackGasLimit uint32, + numWords uint32, + requestCount uint16, +) (*CoordinatorRandomWordsRequested, error) { opts, err := v.client.TransactionOpts(v.client.GetDefaultWallet()) if err != nil { return nil, err @@ -1042,8 +1152,11 @@ func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) RequestRandomnessNative(reque if err != nil { return nil, err } - - return tx, v.client.ProcessTransaction(tx) + randomWordsRequestedEvent, err := RetrieveRequestRandomnessLogs(coordinator, v.client, tx) + if err != nil { + return nil, err + } + return randomWordsRequestedEvent, nil } func (v *EthereumVRFV2PlusWrapperLoadTestConsumer) GetRequestStatus(ctx context.Context, requestID *big.Int) (vrfv2plus_wrapper_load_test_consumer.GetRequestStatus, error) { diff --git a/integration-tests/load/vrfv2/vrfv2_test.go b/integration-tests/load/vrfv2/vrfv2_test.go index b27395769db..e420d66ec8c 100644 --- a/integration-tests/load/vrfv2/vrfv2_test.go +++ b/integration-tests/load/vrfv2/vrfv2_test.go @@ -2,6 +2,7 @@ package loadvrfv2 import ( "math/big" + "strconv" "sync" "testing" "time" @@ -119,7 +120,7 @@ func TestVRFV2Performance(t *testing.T) { for _, subID := range subIDs { 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) + vrfcommon.LogSubDetails(l, subscription, strconv.FormatUint(subID, 10), vrfContracts.CoordinatorV2) } subIDsForCancellingAfterTest = subIDs l.Debug().Int("Number of Subs", len(subIDs)).Msg("Subs involved in the test") @@ -267,7 +268,7 @@ func TestVRFV2BHSPerformance(t *testing.T) { for _, subID := range underfundedSubIDs { 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) + vrfcommon.LogSubDetails(l, subscription, strconv.FormatUint(subID, 10), vrfContracts.CoordinatorV2) } subIDsForCancellingAfterTest = underfundedSubIDs l.Debug().Int("Number of Subs", len(underfundedSubIDs)).Msg("Subs involved in the test") diff --git a/integration-tests/load/vrfv2plus/gun.go b/integration-tests/load/vrfv2plus/gun.go index 8be30afd412..8a99392fa57 100644 --- a/integration-tests/load/vrfv2plus/gun.go +++ b/integration-tests/load/vrfv2plus/gun.go @@ -44,7 +44,7 @@ func (m *BHSTestGun) Call(_ *wasp.Generator) *wasp.Response { if err != nil { return &wasp.Response{Error: err.Error(), Failed: true} } - _, err = vrfv2plus.RequestRandomnessAndWaitForRequestedEvent( + _, err = vrfv2plus.RequestRandomness( //the same consumer is used for all requests and in all subs m.contracts.VRFV2PlusConsumer[0], m.contracts.CoordinatorV2Plus, diff --git a/integration-tests/load/vrfv2plus/vrfv2plus_test.go b/integration-tests/load/vrfv2plus/vrfv2plus_test.go index bb9c33f43a6..d461b4cde20 100644 --- a/integration-tests/load/vrfv2plus/vrfv2plus_test.go +++ b/integration-tests/load/vrfv2plus/vrfv2plus_test.go @@ -118,7 +118,7 @@ func TestVRFV2PlusPerformance(t *testing.T) { for _, subID := range subIDs { subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) require.NoError(t, err, "error getting subscription information for subscription %s", subID.String()) - vrfv2plus.LogSubDetails(l, subscription, subID, vrfContracts.CoordinatorV2Plus) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) } subIDsForCancellingAfterTest = subIDs l.Info().Int("Number of Subs", len(subIDs)).Msg("Subs involved in the test") @@ -268,7 +268,7 @@ func TestVRFV2PlusBHSPerformance(t *testing.T) { for _, subID := range underfundedSubIDs { subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) require.NoError(t, err, "error getting subscription information for subscription %s", subID.String()) - vrfv2plus.LogSubDetails(l, subscription, subID, vrfContracts.CoordinatorV2Plus) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) } subIDsForCancellingAfterTest = underfundedSubIDs l.Debug().Int("Number of Subs", len(underfundedSubIDs)).Msg("Subs involved in the test") diff --git a/integration-tests/smoke/vrfv2_test.go b/integration-tests/smoke/vrfv2_test.go index a834d1be757..be29ba45182 100644 --- a/integration-tests/smoke/vrfv2_test.go +++ b/integration-tests/smoke/vrfv2_test.go @@ -3,6 +3,7 @@ package smoke import ( "fmt" "math/big" + "strconv" "strings" "sync" "testing" @@ -24,6 +25,7 @@ import ( vrfcommon "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/common" "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2" "github.com/smartcontractkit/chainlink/integration-tests/client" + "github.com/smartcontractkit/chainlink/integration-tests/contracts" "github.com/smartcontractkit/chainlink/integration-tests/docker/test_env" tc "github.com/smartcontractkit/chainlink/integration-tests/testconfig" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/blockhash_store" @@ -96,7 +98,7 @@ func TestVRFv2Basic(t *testing.T) { subIDForRequestRandomness := subIDsForRequestRandomness[0] subscription, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subIDForRequestRandomness) require.NoError(t, err, "error getting subscription information") - vrfv2.LogSubDetails(l, subscription, subIDForRequestRandomness, vrfContracts.CoordinatorV2) + vrfcommon.LogSubDetails(l, subscription, strconv.FormatUint(subIDForRequestRandomness, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForRequestRandomness...) subBalanceBeforeRequest := subscription.Balance @@ -152,7 +154,7 @@ func TestVRFv2Basic(t *testing.T) { subIDForJobRuns := subIDsForJobRuns[0] subscription, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subIDForJobRuns) require.NoError(t, err, "error getting subscription information") - vrfv2.LogSubDetails(l, subscription, subIDForJobRuns, vrfContracts.CoordinatorV2) + vrfcommon.LogSubDetails(l, subscription, strconv.FormatUint(subIDForJobRuns, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForJobRuns...) jobRunsBeforeTest, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.MustReadRunsByJob(nodeTypeToNodeMap[vrfcommon.VRF].Job.Data.ID) @@ -276,7 +278,7 @@ func TestVRFv2Basic(t *testing.T) { subIDForOracleWithdraw := subIDsForOracleWithDraw[0] subscription, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subIDForOracleWithdraw) require.NoError(t, err, "error getting subscription information") - vrfv2.LogSubDetails(l, subscription, subIDForOracleWithdraw, vrfContracts.CoordinatorV2) + vrfcommon.LogSubDetails(l, subscription, strconv.FormatUint(subIDForOracleWithdraw, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForOracleWithDraw...) fulfilledEventLink, err := vrfv2.RequestRandomnessAndWaitForFulfillment( @@ -337,7 +339,7 @@ func TestVRFv2Basic(t *testing.T) { subIDForCancelling := subIDsForCancelling[0] subscription, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subIDForCancelling) require.NoError(t, err, "error getting subscription information") - vrfv2.LogSubDetails(l, subscription, subIDForCancelling, vrfContracts.CoordinatorV2) + vrfcommon.LogSubDetails(l, subscription, strconv.FormatUint(subIDForCancelling, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForCancelling...) testWalletAddress, err := actions.GenerateWallet() @@ -423,7 +425,7 @@ func TestVRFv2Basic(t *testing.T) { subIDForOwnerCancelling := subIDsForOwnerCancelling[0] subscriptionForCancelling, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subIDForOwnerCancelling) require.NoError(t, err, "error getting subscription information") - vrfv2.LogSubDetails(l, subscriptionForCancelling, subIDForOwnerCancelling, vrfContracts.CoordinatorV2) + vrfcommon.LogSubDetails(l, subscriptionForCancelling, strconv.FormatUint(subIDForOwnerCancelling, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForOwnerCancelling...) // No GetActiveSubscriptionIds function available - skipping check @@ -590,7 +592,7 @@ func TestVRFv2MultipleSendingKeys(t *testing.T) { subIDForMultipleSendingKeys := subIDsForMultipleSendingKeys[0] subscriptionForMultipleSendingKeys, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subIDForMultipleSendingKeys) require.NoError(t, err, "error getting subscription information") - vrfv2.LogSubDetails(l, subscriptionForMultipleSendingKeys, subIDForMultipleSendingKeys, vrfContracts.CoordinatorV2) + vrfcommon.LogSubDetails(l, subscriptionForMultipleSendingKeys, strconv.FormatUint(subIDForMultipleSendingKeys, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForMultipleSendingKeys...) txKeys, _, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.ReadTxKeys("evm") @@ -698,7 +700,7 @@ func TestVRFOwner(t *testing.T) { subIDForForceFulfill := subIDsForForceFulfill[0] subscriptionForMultipleSendingKeys, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subIDForForceFulfill) require.NoError(t, err, "error getting subscription information") - vrfv2.LogSubDetails(l, subscriptionForMultipleSendingKeys, subIDForForceFulfill, vrfContracts.CoordinatorV2) + vrfcommon.LogSubDetails(l, subscriptionForMultipleSendingKeys, strconv.FormatUint(subIDForForceFulfill, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForForceFulfill...) vrfCoordinatorOwner, err := vrfContracts.CoordinatorV2.GetOwner(testcontext.Get(t)) @@ -850,7 +852,7 @@ func TestVRFV2WithBHS(t *testing.T) { subIDForBHS := subIDsForBHS[0] subscriptionForBHS, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subIDForBHS) require.NoError(t, err, "error getting subscription information") - vrfv2.LogSubDetails(l, subscriptionForBHS, subIDForBHS, vrfContracts.CoordinatorV2) + vrfcommon.LogSubDetails(l, subscriptionForBHS, strconv.FormatUint(subIDForBHS, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForBHS...) randomWordsRequestedEvent, err := vrfv2.RequestRandomness( @@ -867,7 +869,7 @@ func TestVRFV2WithBHS(t *testing.T) { ) require.NoError(t, err, "error requesting randomness") - vrfv2.LogRandomnessRequestedEvent(l, vrfContracts.CoordinatorV2, randomWordsRequestedEvent) + vrfcommon.LogRandomnessRequestedEvent(l, vrfContracts.CoordinatorV2, randomWordsRequestedEvent, false) randRequestBlockNumber := randomWordsRequestedEvent.Raw.BlockNumber var wg sync.WaitGroup wg.Add(1) @@ -878,11 +880,13 @@ func TestVRFV2WithBHS(t *testing.T) { err = vrfv2.FundSubscriptions(testEnv, chainID, big.NewFloat(*configCopy.VRFv2.General.SubscriptionFundingAmountLink), vrfContracts.LinkToken, vrfContracts.CoordinatorV2, subIDsForBHS) require.NoError(t, err, "error funding subscriptions") randomWordsFulfilledEvent, err := vrfContracts.CoordinatorV2.WaitForRandomWordsFulfilledEvent( - []*big.Int{randomWordsRequestedEvent.RequestId}, - time.Second*30, + contracts.RandomWordsFulfilledEventFilter{ + RequestIds: []*big.Int{randomWordsRequestedEvent.RequestId}, + Timeout: configCopy.VRFv2.General.RandomWordsFulfilledEventTimeout.Duration, + }, ) require.NoError(t, err, "error waiting for randomness fulfilled event") - vrfv2.LogRandomWordsFulfilledEvent(l, vrfContracts.CoordinatorV2, randomWordsFulfilledEvent) + vrfcommon.LogRandomWordsFulfilledEvent(l, vrfContracts.CoordinatorV2, randomWordsFulfilledEvent, false) status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) @@ -909,7 +913,7 @@ func TestVRFV2WithBHS(t *testing.T) { subIDForBHS := subIDsForBHS[0] subscriptionForBHS, err := vrfContracts.CoordinatorV2.GetSubscription(testcontext.Get(t), subIDForBHS) require.NoError(t, err, "error getting subscription information") - vrfv2.LogSubDetails(l, subscriptionForBHS, subIDForBHS, vrfContracts.CoordinatorV2) + vrfcommon.LogSubDetails(l, subscriptionForBHS, strconv.FormatUint(subIDForBHS, 10), vrfContracts.CoordinatorV2) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForBHS...) randomWordsRequestedEvent, err := vrfv2.RequestRandomness( diff --git a/integration-tests/smoke/vrfv2plus_test.go b/integration-tests/smoke/vrfv2plus_test.go index 2f58c2d0003..20871a12b77 100644 --- a/integration-tests/smoke/vrfv2plus_test.go +++ b/integration-tests/smoke/vrfv2plus_test.go @@ -23,6 +23,7 @@ import ( "github.com/smartcontractkit/chainlink/integration-tests/actions/vrf/vrfv2plus" "github.com/smartcontractkit/chainlink/integration-tests/client" "github.com/smartcontractkit/chainlink/integration-tests/contracts" + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/generated/blockhash_store" "github.com/smartcontractkit/chainlink/integration-tests/actions" @@ -99,7 +100,7 @@ func TestVRFv2Plus(t *testing.T) { subIDForRequestRandomness := subIDsForRequestRandomness[0] subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subIDForRequestRandomness) require.NoError(t, err, "error getting subscription information") - vrfv2plus.LogSubDetails(l, subscription, subIDForRequestRandomness, vrfContracts.CoordinatorV2Plus) + vrfcommon.LogSubDetails(l, subscription, subIDForRequestRandomness.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDsForRequestRandomness...) subBalanceBeforeRequest := subscription.Balance @@ -163,7 +164,7 @@ func TestVRFv2Plus(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) subNativeTokenBalanceBeforeRequest := subscription.NativeBalance @@ -262,7 +263,7 @@ func TestVRFv2Plus(t *testing.T) { //todo: uncomment when VRF-651 will be fixed //require.Equal(t, 1, consumerStatus.Paid.Cmp(randomWordsFulfilledEvent.Payment), "Expected Consumer contract pay more than the Coordinator Sub") - vrfv2plus.LogFulfillmentDetailsLinkBilling(l, wrapperConsumerJuelsBalanceBeforeRequest, wrapperConsumerJuelsBalanceAfterRequest, consumerStatus, randomWordsFulfilledEvent) + vrfcommon.LogFulfillmentDetailsLinkBilling(l, wrapperConsumerJuelsBalanceBeforeRequest, wrapperConsumerJuelsBalanceAfterRequest, consumerStatus, randomWordsFulfilledEvent) require.Equal(t, *testConfig.NumberOfWords, uint32(len(consumerStatus.RandomWords))) for _, w := range consumerStatus.RandomWords { @@ -311,7 +312,7 @@ func TestVRFv2Plus(t *testing.T) { //todo: uncomment when VRF-651 will be fixed //require.Equal(t, 1, consumerStatus.Paid.Cmp(randomWordsFulfilledEvent.Payment), "Expected Consumer contract pay more than the Coordinator Sub") - vrfv2plus.LogFulfillmentDetailsNativeBilling(l, wrapperConsumerBalanceBeforeRequestWei, wrapperConsumerBalanceAfterRequestWei, consumerStatus, randomWordsFulfilledEvent) + vrfcommon.LogFulfillmentDetailsNativeBilling(l, wrapperConsumerBalanceBeforeRequestWei, wrapperConsumerBalanceAfterRequestWei, consumerStatus, randomWordsFulfilledEvent) require.Equal(t, *testConfig.NumberOfWords, uint32(len(consumerStatus.RandomWords))) for _, w := range consumerStatus.RandomWords { @@ -336,7 +337,7 @@ func TestVRFv2Plus(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) testWalletAddress, err := actions.GenerateWallet() @@ -444,7 +445,7 @@ func TestVRFv2Plus(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) activeSubscriptionIdsBeforeSubCancellation, err := vrfContracts.CoordinatorV2Plus.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) require.NoError(t, err) @@ -593,7 +594,7 @@ func TestVRFv2Plus(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) fulfilledEventLink, err := vrfv2plus.RequestRandomnessAndWaitForFulfillment( @@ -730,7 +731,7 @@ func TestVRFv2PlusMultipleSendingKeys(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) txKeys, _, err := nodeTypeToNodeMap[vrfcommon.VRF].CLNode.API.ReadTxKeys("evm") @@ -839,7 +840,7 @@ func TestVRFv2PlusMigration(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) activeSubIdsOldCoordinatorBeforeMigration, err := vrfContracts.CoordinatorV2Plus.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) @@ -857,7 +858,7 @@ func TestVRFv2PlusMigration(t *testing.T) { err = evmClient.WaitForEvents() require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - _, err = vrfv2plus.VRFV2PlusUpgradedVersionRegisterProvingKey(vrfKey.VRFKey, newCoordinator) + _, err = vrfv2plus.VRFV2PlusUpgradedVersionRegisterProvingKey(vrfKey.VRFKey, newCoordinator, uint64(assets.GWei(*configCopy.VRFv2Plus.General.CLNodeMaxGasPriceGWei).Int64())) require.NoError(t, err, fmt.Errorf("%s, err: %w", vrfcommon.ErrRegisteringProvingKey, err)) err = newCoordinator.SetConfig( @@ -921,7 +922,7 @@ func TestVRFv2PlusMigration(t *testing.T) { err = evmClient.WaitForEvents() require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - vrfv2plus.LogMigrationCompletedEvent(l, migrationCompletedEvent, vrfContracts) + vrfv2plus.LogMigrationCompletedEvent(l, migrationCompletedEvent, vrfContracts.CoordinatorV2Plus) oldCoordinatorLinkTotalBalanceAfterMigration, oldCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfContracts.CoordinatorV2Plus) require.NoError(t, err) @@ -976,7 +977,7 @@ func TestVRFv2PlusMigration(t *testing.T) { require.Equal(t, 0, expectedEthTotalBalanceForOldCoordinator.Cmp(oldCoordinatorEthTotalBalanceAfterMigration)) //Verify rand requests fulfills with Link Token billing - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillmentUpgraded( + _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[0], newCoordinator, vrfKey, @@ -988,7 +989,7 @@ func TestVRFv2PlusMigration(t *testing.T) { require.NoError(t, err, "error requesting randomness and waiting for fulfilment") //Verify rand requests fulfills with Native Token billing - _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillmentUpgraded( + _, err = vrfv2plus.RequestRandomnessAndWaitForFulfillment( consumers[1], newCoordinator, vrfKey, @@ -1023,7 +1024,7 @@ func TestVRFv2PlusMigration(t *testing.T) { subscription, err := vrfContracts.CoordinatorV2Plus.GetSubscription(testcontext.Get(t), subID) require.NoError(t, err, "error getting subscription information") - vrfv2plus.LogSubDetails(l, subscription, subID, vrfContracts.CoordinatorV2Plus) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) activeSubIdsOldCoordinatorBeforeMigration, err := vrfContracts.CoordinatorV2Plus.GetActiveSubscriptionIds(testcontext.Get(t), big.NewInt(0), big.NewInt(0)) require.NoError(t, err, "error occurred getting active sub ids") @@ -1041,7 +1042,7 @@ func TestVRFv2PlusMigration(t *testing.T) { err = evmClient.WaitForEvents() require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - _, err = vrfv2plus.VRFV2PlusUpgradedVersionRegisterProvingKey(vrfKey.VRFKey, newCoordinator) + _, err = vrfv2plus.VRFV2PlusUpgradedVersionRegisterProvingKey(vrfKey.VRFKey, newCoordinator, uint64(assets.GWei(*configCopy.VRFv2Plus.General.CLNodeMaxGasPriceGWei).Int64())) require.NoError(t, err, fmt.Errorf("%s, err: %w", vrfcommon.ErrRegisteringProvingKey, err)) err = newCoordinator.SetConfig( @@ -1106,7 +1107,7 @@ func TestVRFv2PlusMigration(t *testing.T) { err = evmClient.WaitForEvents() require.NoError(t, err, vrfcommon.ErrWaitTXsComplete) - vrfv2plus.LogMigrationCompletedEvent(l, migrationCompletedEvent, vrfContracts) + vrfv2plus.LogMigrationCompletedEvent(l, migrationCompletedEvent, vrfContracts.CoordinatorV2Plus) oldCoordinatorLinkTotalBalanceAfterMigration, oldCoordinatorEthTotalBalanceAfterMigration, err := vrfv2plus.GetCoordinatorTotalBalance(vrfContracts.CoordinatorV2Plus) require.NoError(t, err) @@ -1160,7 +1161,7 @@ func TestVRFv2PlusMigration(t *testing.T) { // Verify rand requests fulfills with Link Token billing isNativeBilling := false - randomWordsFulfilledEvent, err := vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillmentUpgraded( + randomWordsFulfilledEvent, err := vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillment( wrapperContracts.LoadTestConsumers[0], newCoordinator, vrfKey, @@ -1176,7 +1177,7 @@ func TestVRFv2PlusMigration(t *testing.T) { // Verify rand requests fulfills with Native Token billing isNativeBilling = true - randomWordsFulfilledEvent, err = vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillmentUpgraded( + randomWordsFulfilledEvent, err = vrfv2plus.DirectFundingRequestRandomnessAndWaitForFulfillment( wrapperContracts.LoadTestConsumers[0], newCoordinator, vrfKey, @@ -1269,28 +1270,20 @@ func TestVRFV2PlusWithBHS(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) - _, err = consumers[0].RequestRandomness( - vrfKey.KeyHash, + randomWordsRequestedEvent, err := vrfv2plus.RequestRandomness( + consumers[0], + vrfContracts.CoordinatorV2Plus, + vrfKey, subID, - *configCopy.VRFv2Plus.General.MinimumConfirmations, - *configCopy.VRFv2Plus.General.CallbackGasLimit, isNativeBilling, - *configCopy.VRFv2Plus.General.NumberOfWords, - *configCopy.VRFv2Plus.General.RandomnessRequestCountPerRequest, + configCopy.VRFv2Plus.General, + l, ) require.NoError(t, err, "error requesting randomness") - randomWordsRequestedEvent, err := vrfContracts.CoordinatorV2Plus.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKey.KeyHash}, - []*big.Int{subID}, - []common.Address{common.HexToAddress(consumers[0].Address())}, - time.Minute*1, - ) - require.NoError(t, err, "error waiting for randomness requested event") - vrfv2plus.LogRandomnessRequestedEvent(l, vrfContracts.CoordinatorV2Plus, randomWordsRequestedEvent, isNativeBilling) randRequestBlockNumber := randomWordsRequestedEvent.Raw.BlockNumber var wg sync.WaitGroup wg.Add(1) @@ -1309,12 +1302,14 @@ func TestVRFV2PlusWithBHS(t *testing.T) { ) require.NoError(t, err, "error funding subscriptions") randomWordsFulfilledEvent, err := vrfContracts.CoordinatorV2Plus.WaitForRandomWordsFulfilledEvent( - []*big.Int{subID}, - []*big.Int{randomWordsRequestedEvent.RequestId}, - time.Second*30, + contracts.RandomWordsFulfilledEventFilter{ + RequestIds: []*big.Int{randomWordsRequestedEvent.RequestId}, + SubIDs: []*big.Int{subID}, + Timeout: configCopy.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + }, ) require.NoError(t, err, "error waiting for randomness fulfilled event") - vrfv2plus.LogRandomWordsFulfilledEvent(l, vrfContracts.CoordinatorV2Plus, randomWordsFulfilledEvent, isNativeBilling) + vrfcommon.LogRandomWordsFulfilledEvent(l, vrfContracts.CoordinatorV2Plus, randomWordsFulfilledEvent, isNativeBilling) status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) @@ -1350,29 +1345,20 @@ func TestVRFV2PlusWithBHS(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) //BHS node should fill in blockhashes into BHS contract depending on the waitBlocks and lookBackBlocks settings - _, err = consumers[0].RequestRandomness( - vrfKey.KeyHash, + randomWordsRequestedEvent, err := vrfv2plus.RequestRandomness( + consumers[0], + vrfContracts.CoordinatorV2Plus, + vrfKey, subID, - *configCopy.VRFv2Plus.General.MinimumConfirmations, - *configCopy.VRFv2Plus.General.CallbackGasLimit, isNativeBilling, - *configCopy.VRFv2Plus.General.NumberOfWords, - *configCopy.VRFv2Plus.General.RandomnessRequestCountPerRequest, + configCopy.VRFv2Plus.General, + l, ) require.NoError(t, err, "error requesting randomness") - - randomWordsRequestedEvent, err := vrfContracts.CoordinatorV2Plus.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKey.KeyHash}, - []*big.Int{subID}, - []common.Address{common.HexToAddress(consumers[0].Address())}, - time.Minute*1, - ) - require.NoError(t, err, "error waiting for randomness requested event") - vrfv2plus.LogRandomnessRequestedEvent(l, vrfContracts.CoordinatorV2Plus, randomWordsRequestedEvent, isNativeBilling) randRequestBlockNumber := randomWordsRequestedEvent.Raw.BlockNumber _, err = vrfContracts.BHS.GetBlockHash(testcontext.Get(t), big.NewInt(int64(randRequestBlockNumber))) require.Error(t, err, "error not occurred when getting blockhash for a blocknumber which was not stored in BHS contract") @@ -1507,28 +1493,20 @@ func TestVRFV2PlusWithBHF(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) - _, err = consumers[0].RequestRandomness( - vrfKey.KeyHash, + randomWordsRequestedEvent, err := vrfv2plus.RequestRandomness( + consumers[0], + vrfContracts.CoordinatorV2Plus, + vrfKey, subID, - *configCopy.VRFv2Plus.General.MinimumConfirmations, - *configCopy.VRFv2Plus.General.CallbackGasLimit, isNativeBilling, - *configCopy.VRFv2Plus.General.NumberOfWords, - *configCopy.VRFv2Plus.General.RandomnessRequestCountPerRequest, + configCopy.VRFv2Plus.General, + l, ) require.NoError(t, err, "error requesting randomness") - randomWordsRequestedEvent, err := vrfContracts.CoordinatorV2Plus.WaitForRandomWordsRequestedEvent( - [][32]byte{vrfKey.KeyHash}, - []*big.Int{subID}, - []common.Address{common.HexToAddress(consumers[0].Address())}, - time.Minute*1, - ) - require.NoError(t, err, "error waiting for randomness requested event") - vrfv2plus.LogRandomnessRequestedEvent(l, vrfContracts.CoordinatorV2Plus, randomWordsRequestedEvent, isNativeBilling) randRequestBlockNumber := randomWordsRequestedEvent.Raw.BlockNumber var wg sync.WaitGroup wg.Add(1) @@ -1550,12 +1528,14 @@ func TestVRFV2PlusWithBHF(t *testing.T) { ) require.NoError(t, err, "error funding subscriptions") randomWordsFulfilledEvent, err := vrfContracts.CoordinatorV2Plus.WaitForRandomWordsFulfilledEvent( - []*big.Int{subID}, - []*big.Int{randomWordsRequestedEvent.RequestId}, - time.Minute*2, + contracts.RandomWordsFulfilledEventFilter{ + RequestIds: []*big.Int{randomWordsRequestedEvent.RequestId}, + SubIDs: []*big.Int{subID}, + Timeout: configCopy.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + }, ) require.NoError(t, err, "error waiting for randomness fulfilled event") - vrfv2plus.LogRandomWordsFulfilledEvent(l, vrfContracts.CoordinatorV2Plus, randomWordsFulfilledEvent, isNativeBilling) + vrfcommon.LogRandomWordsFulfilledEvent(l, vrfContracts.CoordinatorV2Plus, randomWordsFulfilledEvent, isNativeBilling) status, err := consumers[0].GetRequestStatus(testcontext.Get(t), randomWordsFulfilledEvent.RequestId) require.NoError(t, err, "error getting rand request status") require.True(t, status.Fulfilled) @@ -1656,11 +1636,11 @@ func TestVRFv2PlusReplayAfterTimeout(t *testing.T) { 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) // 2. create request but without fulfilment - e.g. simulation failure (insufficient balance in the sub, ) - initialReqRandomWordsRequestedEvent, err := vrfv2plus.RequestRandomnessAndWaitForRequestedEvent( + initialReqRandomWordsRequestedEvent, err := vrfv2plus.RequestRandomness( consumers[0], vrfContracts.CoordinatorV2Plus, vrfKey, @@ -1761,9 +1741,11 @@ func TestVRFv2PlusReplayAfterTimeout(t *testing.T) { Str("subID", subID.String()). Msg("Waiting for initalReqRandomWordsFulfilledEvent") initalReqRandomWordsFulfilledEvent, err := vrfContracts.CoordinatorV2Plus.WaitForRandomWordsFulfilledEvent( - []*big.Int{subID}, - []*big.Int{initialReqRandomWordsRequestedEvent.RequestId}, - configCopy.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + contracts.RandomWordsFulfilledEventFilter{ + RequestIds: []*big.Int{initialReqRandomWordsRequestedEvent.RequestId}, + SubIDs: []*big.Int{subID}, + Timeout: configCopy.VRFv2Plus.General.RandomWordsFulfilledEventTimeout.Duration, + }, ) require.NoError(t, err, "error waiting for initial request RandomWordsFulfilledEvent") @@ -1847,7 +1829,7 @@ func TestVRFv2PlusPendingBlockSimulationAndZeroConfirmationDelays(t *testing.T) 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) + vrfcommon.LogSubDetails(l, subscription, subID.String(), vrfContracts.CoordinatorV2Plus) subIDsForCancellingAfterTest = append(subIDsForCancellingAfterTest, subIDs...) var isNativeBilling = true