Skip to content

Commit

Permalink
move testing contracts from integration-tests/contracts/ethereum/src …
Browse files Browse the repository at this point in the history
…to contracts/src/v0.8/automation/testhelpers (#11046)
  • Loading branch information
shileiwill authored Oct 24, 2023
1 parent b87571c commit a2ae7cb
Show file tree
Hide file tree
Showing 31 changed files with 1,621 additions and 3,285 deletions.
9 changes: 9 additions & 0 deletions contracts/scripts/native_solc_compile_all_automation
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ compileContract automation/v2_1/AutomationUtils2_1.sol
compileContract automation/v2_1/AutomationForwarderLogic.sol
compileContract automation/testhelpers/LogTriggeredStreamsLookup.sol
compileContract automation/testhelpers/DummyProtocol.sol

compileContract automation/testhelpers/KeeperBase.sol
compileContract automation/testhelpers/KeeperCompatibleInterface.sol
compileContract automation/testhelpers/KeeperConsumer.sol
compileContract automation/testhelpers/KeeperConsumerPerformance.sol
compileContract automation/testhelpers/PerformDataChecker.sol
compileContract automation/testhelpers/UpkeepPerformCounterRestrictive.sol
compileContract automation/testhelpers/UpkeepCounter.sol

compileContract automation/interfaces/StreamsLookupCompatibleInterface.sol

compileContract tests/VerifiableLoadUpkeep.sol
Expand Down
1 change: 1 addition & 0 deletions contracts/scripts/native_solc_compile_all_vrf
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ compileContract vrf/VRFV2Wrapper.sol
compileContract vrf/interfaces/VRFV2WrapperInterface.sol
compileContract vrf/VRFV2WrapperConsumerBase.sol
compileContract vrf/testhelpers/VRFV2WrapperConsumerExample.sol
compileContract vrf/testhelpers/VRFv2Consumer.sol

# VRF Consumers and Mocks
compileContract vrf/testhelpers/VRFExternalSubOwnerExample.sol
Expand Down
21 changes: 21 additions & 0 deletions contracts/src/v0.8/automation/testhelpers/KeeperBase.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

contract KeeperBase {
/**
* @notice method that allows it to be simulated via eth_call by checking that
* the sender is the zero address.
*/
function preventExecution() internal view {
require(tx.origin == address(0), "only for simulated backend");
}

/**
* @notice modifier that allows it to be simulated via eth_call by checking
* that the sender is the zero address.
*/
modifier cannotExecute() {
preventExecution();
_;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.16;

interface KeeperCompatibleInterface {
/**
* @notice method that is simulated by the keepers to see if any work actually
* needs to be performed. This method does does not actually need to be
* executable, and since it is only ever simulated it can consume lots of gas.
* @dev To ensure that it is never called, you may want to add the
* cannotExecute modifier from KeeperBase to your implementation of this
* method.
* @param checkData specified in the upkeep registration so it is always the
* same for a registered upkeep. This can easily be broken down into specific
* arguments using `abi.decode`, so multiple upkeeps can be registered on the
* same contract and easily differentiated by the contract.
* @return upkeepNeeded boolean to indicate whether the keeper should call
* performUpkeep or not.
* @return performData bytes that the keeper should call performUpkeep with, if
* upkeep is needed. If you would like to encode data to decode later, try
* `abi.encode`.
*/
function checkUpkeep(bytes calldata checkData) external returns (bool upkeepNeeded, bytes memory performData);

/**
* @notice method that is actually executed by the keepers, via the registry.
* The data returned by the checkUpkeep simulation will be passed into
* this method to actually be executed.
* @dev The input to this method should not be trusted, and the caller of the
* method should not even be restricted to any single registry. Anyone should
* be able call it, and the input should be validated, there is no guarantee
* that the data passed in is the performData returned from checkUpkeep. This
* could happen due to malicious keepers, racing keepers, or simply a state
* change while the performUpkeep transaction is waiting for confirmation.
* Always validate the data passed in.
* @param performData is the data which was passed back from the checkData
* simulation. If it is encoded, it can easily be decoded into other types by
* calling `abi.decode`. This data should not be trusted, and should be
* validated against the contract's current state.
*/
function performUpkeep(bytes calldata performData) external;
}
26 changes: 26 additions & 0 deletions contracts/src/v0.8/automation/testhelpers/KeeperConsumer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
pragma solidity 0.8.16;

import "./KeeperCompatibleInterface.sol";
import "./KeeperBase.sol";

contract KeeperConsumer is KeeperCompatibleInterface, KeeperBase {
uint public counter;
uint public immutable interval;
uint public lastTimeStamp;

constructor(uint updateInterval) public {
interval = updateInterval;
lastTimeStamp = block.timestamp;
counter = 0;
}

function checkUpkeep(
bytes calldata checkData
) external view override cannotExecute returns (bool upkeepNeeded, bytes memory performData) {
return (true, checkData);
}

function performUpkeep(bytes calldata performData) external override {
counter = counter + 1;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity 0.7.6;
pragma solidity 0.8.16;

contract KeeperConsumerPerformance {
event PerformingUpkeep(bool eligible, address from, uint256 initialCall, uint256 nextEligible, uint256 blockNumber);
Expand All @@ -13,7 +13,12 @@ contract KeeperConsumerPerformance {

uint256 public count = 0;

constructor(uint256 _testRange, uint256 _averageEligibilityCadence, uint256 _checkGasToBurn, uint256 _performGasToBurn) {
constructor(
uint256 _testRange,
uint256 _averageEligibilityCadence,
uint256 _checkGasToBurn,
uint256 _performGasToBurn
) {
testRange = _testRange;
averageEligibilityCadence = _averageEligibilityCadence;
checkGasToBurn = _checkGasToBurn;
Expand Down Expand Up @@ -80,4 +85,4 @@ contract KeeperConsumerPerformance {
function rand() private view returns (uint256) {
return uint256(keccak256(abi.encode(blockhash(block.number - 1), address(this))));
}
}
}
29 changes: 29 additions & 0 deletions contracts/src/v0.8/automation/testhelpers/PerformDataChecker.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.16;

import "./KeeperCompatibleInterface.sol";

contract PerformDataChecker is KeeperCompatibleInterface {
uint256 public counter;
bytes public s_expectedData;

constructor(bytes memory expectedData) {
s_expectedData = expectedData;
}

function setExpectedData(bytes calldata expectedData) external {
s_expectedData = expectedData;
}

function checkUpkeep(
bytes calldata checkData
) external view override returns (bool upkeepNeeded, bytes memory performData) {
return (keccak256(checkData) == keccak256(s_expectedData), checkData);
}

function performUpkeep(bytes calldata performData) external override {
if (keccak256(performData) == keccak256(s_expectedData)) {
counter++;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pragma solidity 0.7.6;
pragma solidity 0.8.16;

contract UpkeepPerformCounterRestrictive {
event PerformingUpkeep(bool eligible, address from, uint256 initialCall, uint256 nextEligible, uint256 blockNumber);
Expand Down
64 changes: 64 additions & 0 deletions contracts/src/v0.8/vrf/testhelpers/VRFv2Consumer.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// SPDX-License-Identifier: MIT
// An example of a consumer contract that relies on a subscription for funding.
pragma solidity 0.8.6;

import "../interfaces/VRFCoordinatorV2Interface.sol";
import "../VRFConsumerBaseV2.sol";
import "../../shared/access/ConfirmedOwner.sol";

/**
* THIS IS AN EXAMPLE CONTRACT THAT USES HARDCODED VALUES FOR CLARITY.
* THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
* DO NOT USE THIS CODE IN PRODUCTION.
*/

contract VRFv2Consumer is VRFConsumerBaseV2, ConfirmedOwner {
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(uint256 requestId, uint256[] randomWords);

struct RequestStatus {
bool fulfilled; // whether the request has been successfully fulfilled
bool exists; // whether a requestId exists
uint256[] randomWords;
}
mapping(uint256 => RequestStatus) public s_requests; /* requestId --> requestStatus */
VRFCoordinatorV2Interface COORDINATOR;

// past requests Id.
uint256[] public requestIds;
uint256 public lastRequestId;

constructor(address vrfCoordinator) VRFConsumerBaseV2(vrfCoordinator) ConfirmedOwner(msg.sender) {
COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator);
}

// Assumes the subscription is funded sufficiently.
function requestRandomWords(
uint64 subId,
uint32 callbackGasLimit,
uint16 requestConfirmations,
uint32 numWords,
bytes32 keyHash
) external onlyOwner returns (uint256 requestId) {
// Will revert if subscription is not set and funded.
requestId = COORDINATOR.requestRandomWords(keyHash, subId, requestConfirmations, callbackGasLimit, numWords);
s_requests[requestId] = RequestStatus({randomWords: new uint256[](0), exists: true, fulfilled: false});
requestIds.push(requestId);
lastRequestId = requestId;
emit RequestSent(requestId, numWords);
return requestId;
}

function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override {
require(s_requests[_requestId].exists, "request not found");
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords = _randomWords;
emit RequestFulfilled(_requestId, _randomWords);
}

function getRequestStatus(uint256 _requestId) external view returns (bool fulfilled, uint256[] memory randomWords) {
require(s_requests[_requestId].exists, "request not found");
RequestStatus memory request = s_requests[_requestId];
return (request.fulfilled, request.randomWords);
}
}
Loading

0 comments on commit a2ae7cb

Please sign in to comment.