Skip to content

Commit

Permalink
(test): Add Functions Gas tests (#10657)
Browse files Browse the repository at this point in the history
  • Loading branch information
justinkaseman authored Oct 4, 2023
1 parent 30dfa21 commit a35a7e1
Show file tree
Hide file tree
Showing 11 changed files with 734 additions and 281 deletions.
36 changes: 25 additions & 11 deletions contracts/gas-snapshots/functions.gas-snapshot
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
FunctionsBilling_EstimateCost:test_EstimateCost_RevertsIfGasPriceAboveCeiling() (gas: 32391)
FunctionsBilling_EstimateCost:test_EstimateCost_Success() (gas: 53002)
FunctionsBilling_GetConfig:test_GetConfig_Success() (gas: 23088)
FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_RevertIfNotOwner() (gas: 13274)
FunctionsBilling_OracleWithdrawAll:test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() (gas: 146635)
FunctionsClient_FulfillRequest:test_FulfillRequest_MaximumGas() (gas: 499079)
FunctionsClient_FulfillRequest:test_FulfillRequest_MinimumGas() (gas: 200226)
FunctionsClient__SendRequest:test__SendRequest_RevertIfInvalidCallbackGasLimit() (gas: 54991)
FunctionsCoordinator_Constructor:test_Constructor_Success() (gas: 11956)
FunctionsOracle_sendRequest:testEmptyRequestDataReverts() (gas: 13452)
FunctionsOracle_setDONPublicKey:testEmptyPublicKeyReverts() (gas: 10974)
FunctionsOracle_setDONPublicKey:testOnlyOwnerReverts() (gas: 11255)
Expand All @@ -12,6 +17,9 @@ FunctionsOracle_setRegistry:testOnlyOwnerReverts() (gas: 10927)
FunctionsOracle_setRegistry:testSetRegistrySuccess() (gas: 35791)
FunctionsOracle_setRegistry:testSetRegistry_gas() (gas: 31987)
FunctionsOracle_typeAndVersion:testTypeAndVersionSuccess() (gas: 6905)
FunctionsRequest_DEFAULT_BUFFER_SIZE:test_DEFAULT_BUFFER_SIZE() (gas: 246)
FunctionsRequest_EncodeCBOR:test_EncodeCBOR_Success() (gas: 223)
FunctionsRequest_REQUEST_DATA_VERSION:test_REQUEST_DATA_VERSION() (gas: 225)
FunctionsRouter_Constructor:test_Constructor_Success() (gas: 12073)
FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedCostExceedsCommitment() (gas: 172948)
FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedInsufficientGas() (gas: 163234)
Expand All @@ -21,9 +29,9 @@ FunctionsRouter_Fulfill:test_Fulfill_RequestNotProcessedSubscriptionBalanceInvar
FunctionsRouter_Fulfill:test_Fulfill_RevertIfNotCommittedCoordinator() (gas: 28063)
FunctionsRouter_Fulfill:test_Fulfill_RevertIfPaused() (gas: 156949)
FunctionsRouter_Fulfill:test_Fulfill_SuccessClientNoLongerExists() (gas: 297578)
FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 311147)
FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2076842)
FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 515646)
FunctionsRouter_Fulfill:test_Fulfill_SuccessFulfilled() (gas: 311169)
FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackReverts() (gas: 2485366)
FunctionsRouter_Fulfill:test_Fulfill_SuccessUserCallbackRunsOutOfGas() (gas: 515855)
FunctionsRouter_GetAdminFee:test_GetAdminFee_Success() (gas: 18005)
FunctionsRouter_GetAllowListId:test_GetAllowListId_Success() (gas: 12926)
FunctionsRouter_GetConfig:test_GetConfig_Success() (gas: 37136)
Expand Down Expand Up @@ -86,10 +94,10 @@ FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNoSubs
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotAllowedSender() (gas: 57929)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfNotSubscriptionOwner() (gas: 89316)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPaused() (gas: 20191)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 193277)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_RevertIfPendingRequests() (gas: 193222)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitAllBalanceAsDeposit() (gas: 113352)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessForfeitSomeBalanceAsDeposit() (gas: 124604)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessRecieveDeposit() (gas: 310123)
FunctionsSubscriptions_CancelSubscription:test_CancelSubscription_SuccessRecieveDeposit() (gas: 310090)
FunctionsSubscriptions_Constructor:test_Constructor_Success() (gas: 7654)
FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfNotAllowedSender() (gas: 28637)
FunctionsSubscriptions_CreateSubscriptionWithConsumer:test_CreateSubscriptionWithConsumer_RevertIfPaused() (gas: 17948)
Expand Down Expand Up @@ -118,15 +126,15 @@ FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Reve
FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_Success() (gas: 54867)
FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessDeletesSubscription() (gas: 48362)
FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessSubOwnerRefunded() (gas: 50896)
FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 163911)
FunctionsSubscriptions_OwnerCancelSubscription:test_OwnerCancelSubscription_SuccessWhenRequestInFlight() (gas: 163867)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfAmountMoreThanBalance() (gas: 17924)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfBalanceInvariant() (gas: 165)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_RevertIfNotOwner() (gas: 15555)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessIfNoAmount() (gas: 37396)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessPaysRecipient() (gas: 54435)
FunctionsSubscriptions_OwnerWithdraw:test_OwnerWithdraw_SuccessSetsBalanceToZero() (gas: 37790)
FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessFalseIfNoPendingRequests() (gas: 15025)
FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 175411)
FunctionsSubscriptions_PendingRequestExists:test_PendingRequestExists_SuccessTrueIfPendingRequests() (gas: 175356)
FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfEmptyNewOwner() (gas: 27610)
FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfInvalidNewOwner() (gas: 57707)
FunctionsSubscriptions_ProposeSubscriptionOwnerTransfer:test_ProposeSubscriptionOwnerTransfer_RevertIfNoSubscription() (gas: 15000)
Expand All @@ -141,7 +149,7 @@ FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNoSubscription
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotAllowedSender() (gas: 57778)
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfNotSubscriptionOwner() (gas: 87186)
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPaused() (gas: 18004)
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 190709)
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_RevertIfPendingRequests() (gas: 190654)
FunctionsSubscriptions_RemoveConsumer:test_RemoveConsumer_Success() (gas: 41979)
FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNoSubscription() (gas: 12847)
FunctionsSubscriptions_SetFlags:test_SetFlags_RevertIfNotOwner() (gas: 15640)
Expand All @@ -156,9 +164,9 @@ FunctionsSubscriptions_createSubscription:test_CreateSubscription_Success() (gas
FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfAcceptorIsNotSender() (gas: 25837)
FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfBlockedSender() (gas: 44348)
FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfInvalidSigner() (gas: 23597)
FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1458254)
FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientContractIsNotSender() (gas: 1866530)
FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_RevertIfRecipientIsNotSender() (gas: 26003)
FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1538373)
FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForContract() (gas: 1946649)
FunctionsTermsOfServiceAllowList_AcceptTermsOfService:test_AcceptTermsOfService_SuccessIfAcceptingForSelf() (gas: 94684)
FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_RevertIfNotOwner() (gas: 15469)
FunctionsTermsOfServiceAllowList_BlockSender:test_BlockSender_Success() (gas: 50421)
Expand All @@ -173,4 +181,10 @@ FunctionsTermsOfServiceAllowList_IsBlockedSender:test_IsBlockedSender_SuccessTru
FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_RevertIfNotOwner() (gas: 13525)
FunctionsTermsOfServiceAllowList_UnblockSender:test_UnblockSender_Success() (gas: 95184)
FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_RevertIfNotOwner() (gas: 13727)
FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22073)
FunctionsTermsOfServiceAllowList_UpdateConfig:test_UpdateConfig_Success() (gas: 22073)
Gas_AcceptTermsOfService:test_AcceptTermsOfService_Gas() (gas: 84675)
Gas_AddConsumer:test_AddConsumer_Gas() (gas: 79067)
Gas_CreateSubscription:test_CreateSubscription_Gas() (gas: 73353)
Gas_FundSubscription:test_FundSubscription_Gas() (gas: 38501)
Gas_SendRequest:test_SendRequest_MaximumGas() (gas: 958006)
Gas_SendRequest:test_SendRequest_MinimumGas() (gas: 156382)
199 changes: 199 additions & 0 deletions contracts/src/v0.8/functions/tests/v1_0_0/FunctionsBilling.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {FunctionsCoordinator} from "../../dev/v1_0_0/FunctionsCoordinator.sol";
import {FunctionsBilling} from "../../dev/v1_0_0/FunctionsBilling.sol";
import {FunctionsRequest} from "../../dev/v1_0_0/libraries/FunctionsRequest.sol";

import {FunctionsRouterSetup, FunctionsSubscriptionSetup, FunctionsMultipleFulfillmentsSetup} from "./Setup.t.sol";

/// @notice #constructor
contract FunctionsBilling_Constructor {

}

/// @notice #getConfig
contract FunctionsBilling_GetConfig is FunctionsRouterSetup {
function test_GetConfig_Success() public {
// Send as stranger
vm.stopPrank();
vm.startPrank(STRANGER_ADDRESS);

FunctionsBilling.Config memory config = s_functionsCoordinator.getConfig();
assertEq(config.feedStalenessSeconds, getCoordinatorConfig().feedStalenessSeconds);
assertEq(config.gasOverheadBeforeCallback, getCoordinatorConfig().gasOverheadBeforeCallback);
assertEq(config.gasOverheadAfterCallback, getCoordinatorConfig().gasOverheadAfterCallback);
assertEq(config.requestTimeoutSeconds, getCoordinatorConfig().requestTimeoutSeconds);
assertEq(config.donFee, getCoordinatorConfig().donFee);
assertEq(config.maxSupportedRequestDataVersion, getCoordinatorConfig().maxSupportedRequestDataVersion);
assertEq(config.fulfillmentGasPriceOverEstimationBP, getCoordinatorConfig().fulfillmentGasPriceOverEstimationBP);
assertEq(config.fallbackNativePerUnitLink, getCoordinatorConfig().fallbackNativePerUnitLink);
}
}

/// @notice #updateConfig
contract FunctionsBilling_UpdateConfig {

}

/// @notice #getDONFee
contract FunctionsBilling_GetDONFee {

}

/// @notice #getAdminFee
contract FunctionsBilling_GetAdminFee {

}

/// @notice #getWeiPerUnitLink
contract FunctionsBilling_GetWeiPerUnitLink {

}

/// @notice #_getJuelsPerGas
contract FunctionsBilling__GetJuelsPerGas {
// TODO: make contract internal function helper
}

/// @notice #estimateCost
contract FunctionsBilling_EstimateCost is FunctionsSubscriptionSetup {
function setUp() public virtual override {
FunctionsSubscriptionSetup.setUp();

// Get cost estimate as stranger
vm.stopPrank();
vm.startPrank(STRANGER_ADDRESS);
}

uint256 private constant REASONABLE_GAS_PRICE_CEILING = 1_000_000_000_000_000; // 1 million gwei

function test_EstimateCost_RevertsIfGasPriceAboveCeiling() public {
// Build minimal valid request data
string memory sourceCode = "return 'hello world';";
FunctionsRequest.Request memory request;
FunctionsRequest.initializeRequest(
request,
FunctionsRequest.Location.Inline,
FunctionsRequest.CodeLanguage.JavaScript,
sourceCode
);
bytes memory requestData = FunctionsRequest.encodeCBOR(request);

uint32 callbackGasLimit = 5_500;
uint256 gasPriceWei = REASONABLE_GAS_PRICE_CEILING + 1;

vm.expectRevert(FunctionsBilling.InvalidCalldata.selector);

s_functionsCoordinator.estimateCost(s_subscriptionId, requestData, callbackGasLimit, gasPriceWei);
}

function test_EstimateCost_Success() public {
// Build minimal valid request data
string memory sourceCode = "return 'hello world';";
FunctionsRequest.Request memory request;
FunctionsRequest.initializeRequest(
request,
FunctionsRequest.Location.Inline,
FunctionsRequest.CodeLanguage.JavaScript,
sourceCode
);
bytes memory requestData = FunctionsRequest.encodeCBOR(request);

uint32 callbackGasLimit = 5_500;
uint256 gasPriceWei = 1;

uint96 costEstimate = s_functionsCoordinator.estimateCost(
s_subscriptionId,
requestData,
callbackGasLimit,
gasPriceWei
);
uint96 expectedCostEstimate = 10873200;
assertEq(costEstimate, expectedCostEstimate);
}
}

/// @notice #_calculateCostEstimate
contract FunctionsBilling__CalculateCostEstimate {
// TODO: make contract internal function helper
}

/// @notice #_startBilling
contract FunctionsBilling__StartBilling {
// TODO: make contract internal function helper
}

/// @notice #_computeRequestId
contract FunctionsBilling__ComputeRequestId {
// TODO: make contract internal function helper
}

/// @notice #_fulfillAndBill
contract FunctionsBilling__FulfillAndBill {
// TODO: make contract internal function helper
}

/// @notice #deleteCommitment
contract FunctionsBilling_DeleteCommitment {

}

/// @notice #oracleWithdraw
contract FunctionsBilling_OracleWithdraw {

}

/// @notice #oracleWithdrawAll
contract FunctionsBilling_OracleWithdrawAll is FunctionsMultipleFulfillmentsSetup {
function setUp() public virtual override {
// Use no DON fee so that a transmitter has a balance of 0
s_donFee = 0;

FunctionsMultipleFulfillmentsSetup.setUp();
}

function test_OracleWithdrawAll_RevertIfNotOwner() public {
// Send as stranger
vm.stopPrank();
vm.startPrank(STRANGER_ADDRESS);

vm.expectRevert("Only callable by owner");
s_functionsCoordinator.oracleWithdrawAll();
}

function test_OracleWithdrawAll_SuccessPaysTransmittersWithBalance() public {
uint256 transmitter1BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1);
assertEq(transmitter1BalanceBefore, 0);
uint256 transmitter2BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_2);
assertEq(transmitter2BalanceBefore, 0);
uint256 transmitter3BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_3);
assertEq(transmitter3BalanceBefore, 0);
uint256 transmitter4BalanceBefore = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_4);
assertEq(transmitter4BalanceBefore, 0);

s_functionsCoordinator.oracleWithdrawAll();

uint96 expectedTransmitterBalance = s_fulfillmentCoordinatorBalance / 3;

uint256 transmitter1BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_1);
assertEq(transmitter1BalanceAfter, expectedTransmitterBalance);
uint256 transmitter2BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_2);
assertEq(transmitter2BalanceAfter, expectedTransmitterBalance);
uint256 transmitter3BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_3);
assertEq(transmitter3BalanceAfter, expectedTransmitterBalance);
// Transmitter 4 has no balance
uint256 transmitter4BalanceAfter = s_linkToken.balanceOf(NOP_TRANSMITTER_ADDRESS_4);
assertEq(transmitter4BalanceAfter, 0);
}
}

/// @notice #_getTransmitters
contract FunctionsBilling__GetTransmitters {
// TODO: make contract internal function helper
}

/// @notice #_disperseFeePool
contract FunctionsBilling__DisperseFeePool {
// TODO: make contract internal function helper
}
36 changes: 34 additions & 2 deletions contracts/src/v0.8/functions/tests/v1_0_0/FunctionsClient.t.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,46 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

import {BaseTest} from "./BaseTest.t.sol";
import {FunctionsRouter} from "../../dev/v1_0_0/FunctionsRouter.sol";
import {FunctionsSubscriptions} from "../../dev/v1_0_0/FunctionsSubscriptions.sol";
import {FunctionsRequest} from "../../dev/v1_0_0/libraries/FunctionsRequest.sol";
import {FunctionsResponse} from "../../dev/v1_0_0/libraries/FunctionsResponse.sol";

import {FunctionsSubscriptionSetup} from "./Setup.t.sol";

/// @notice #constructor
contract FunctionsClient_Constructor {

}

/// @notice #_sendRequest
contract FunctionsClient__SendRequest {

contract FunctionsClient__SendRequest is FunctionsSubscriptionSetup {
// TODO: make contract internal function helper

function test__SendRequest_RevertIfInvalidCallbackGasLimit() public {
// Build minimal valid request data
string memory sourceCode = "return 'hello world';";
FunctionsRequest.Request memory request;
FunctionsRequest.initializeRequest(
request,
FunctionsRequest.Location.Inline,
FunctionsRequest.CodeLanguage.JavaScript,
sourceCode
);
bytes memory requestData = FunctionsRequest.encodeCBOR(request);

uint8 MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX = 0;
bytes32 subscriptionFlags = s_functionsRouter.getFlags(s_subscriptionId);
uint8 callbackGasLimitsIndexSelector = uint8(subscriptionFlags[MAX_CALLBACK_GAS_LIMIT_FLAGS_INDEX]);

FunctionsRouter.Config memory config = s_functionsRouter.getConfig();
uint32[] memory _maxCallbackGasLimits = config.maxCallbackGasLimits;
uint32 maxCallbackGasLimit = _maxCallbackGasLimits[callbackGasLimitsIndexSelector];

vm.expectRevert(abi.encodeWithSelector(FunctionsRouter.GasLimitTooBig.selector, maxCallbackGasLimit));
s_functionsClient.sendRequestBytes(requestData, s_subscriptionId, 500_000, s_donId);
}
}

/// @notice #fulfillRequest
Expand Down
Loading

0 comments on commit a35a7e1

Please sign in to comment.