Skip to content

Commit

Permalink
add contracts and out of gas script linea scenario (#653)
Browse files Browse the repository at this point in the history
  • Loading branch information
thedarkjester authored Feb 4, 2025
1 parent 5fbd7ed commit b5194c0
Show file tree
Hide file tree
Showing 8 changed files with 243 additions and 13 deletions.
6 changes: 1 addition & 5 deletions contracts/.solcover.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
module.exports = {
skipFiles: [
"_testing",
"proxies",
"bridging/token/CustomBridgedToken.sol",
],
skipFiles: ["_testing", "proxies", "bridging/token/CustomBridgedToken.sol"],
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { ethers } from "ethers";
import {
contractName as lineaScenarioDelegatingProxyName,
abi as lineaScenarioDelegatingProxyAbi,
bytecode as lineaScenarioDelegatingProxyBytecode,
} from "./static-artifacts/LineaScenarioDelegatingProxy.json";
import { deployContractFromArtifacts } from "../common/helpers/deployments";

async function main() {
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);

console.log(`Deploying LineaScenarioDelegatingProxy`);
const lineaScenarioDelegatingProxyAddress = await deploylineaScenarioDelegatingProxy(wallet);
console.log(
`LineaScenarioDelegatingProxy Deployed at lineaScenarioDelegatingProxyAddress=${lineaScenarioDelegatingProxyAddress}`,
);
}

async function deploylineaScenarioDelegatingProxy(wallet: ethers.Wallet): Promise<string> {
const walletNonce = await wallet.getNonce();

const lineaScenarioDelegatingProxy = await deployContractFromArtifacts(
lineaScenarioDelegatingProxyName,
lineaScenarioDelegatingProxyAbi,
lineaScenarioDelegatingProxyBytecode,
wallet,
{
nonce: walletNonce,
},
);

const lineaScenarioDelegatingProxyAddress = await lineaScenarioDelegatingProxy.getAddress();

return lineaScenarioDelegatingProxyAddress;
}

main().catch((error) => {
console.error(error);
process.exit(1);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
*******************************************************************************************
1. Set the RPC_URL
2. Set the PRIVATE_KEY
3. Set LINEA_SCENARIO_DELEGATING_PROXY_ADDRESS
4. Set NUMBER_OF_LOOPS
5. set LINEA_SCENARIO
6. set GAS_LIMIT
*******************************************************************************************
*******************************************************************************************
LINEA_SCENARIO_DELEGATING_PROXY_ADDRESS=<address> \
NUMBER_OF_LOOPS=<number> \
LINEA_SCENARIO=<number> \
GAS_LIMIT=<number> \
PRIVATE_KEY=<key> \
RPC_URL=<url> \
npx ts-node local-deployments-artifacts/executeLineaScenarioDelegatingProxyScenario.ts
*******************************************************************************************
*/

import { getRequiredEnvVar } from "../common/helpers/environment";
import { ethers } from "ethers";
import { abi as testerAbi } from "./static-artifacts/LineaScenarioDelegatingProxy.json";

async function main() {
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL);
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);

const testContractAddress = getRequiredEnvVar("LINEA_SCENARIO_DELEGATING_PROXY_ADDRESS");
const lineaScenario = 1; //getRequiredEnvVar("LINEA_SCENARIO");
const numberOfLoops = getRequiredEnvVar("NUMBER_OF_LOOPS");
const gasLimit = getRequiredEnvVar("GAS_LIMIT");

// Equivalent of getContractAt
const delegatingProxy = new ethers.Contract(testContractAddress, testerAbi, wallet);
const executeTx = await delegatingProxy.executeScenario(lineaScenario, numberOfLoops, { gasLimit: gasLimit });
try {
const receipt = await executeTx.wait();
console.log(`Executed transaction with gasUsed=${receipt?.gasUsed} status=${receipt?.status}`);
} catch (error) {
const receipt = await provider.getTransactionReceipt(executeTx.hash);
console.error("Transaction failed - tx receipt=", JSON.stringify(receipt));
}
}

main().catch((error) => {
console.error(error);
process.exit(1);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
{
"_format": "hh-sol-artifact-1",
"contractName": "LineaScenarioDelegatingProxy",
"sourceName": "src/_testing/mocks/base/LineaScenarioDelegatingProxy.sol",
"abi": [
{
"inputs": [
{
"internalType": "enum LineaScenarioTesting.Scenario",
"name": "_scenario",
"type": "uint8"
},
{
"internalType": "uint256",
"name": "_loopIterations",
"type": "uint256"
}
],
"name": "executeScenario",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "enum LineaScenarioTesting.Scenario",
"name": "",
"type": "uint8"
}
],
"name": "executedScenarios",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
}
],
"bytecode": "0x608060405234801561001057600080fd5b506105b1806100206000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c8063632265341461003b578063bfc8045614610062575b600080fd5b61004e61004936600461025e565b61008d565b604051901515815260200160405180910390f35b61004e610070366004610288565b600060208181529281526040808220909352908152205460ff1681565b60008060405161009c9061023d565b604051809103906000f0801580156100b8573d6000803e3d6000fd5b50905060008173ffffffffffffffffffffffffffffffffffffffff1685856040516024016100e7929190610305565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f632265340000000000000000000000000000000000000000000000000000000017905251610168919061034a565b600060405180830381855af49150503d80600081146101a3576040519150601f19603f3d011682016040523d82523d6000602084013e6101a8565b606091505b505073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081209192508291908760018111156101e7576101e76102d6565b60018111156101f8576101f86102d6565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055949350505050565b6102028061037a83390190565b80356002811061025957600080fd5b919050565b6000806040838503121561027157600080fd5b61027a8361024a565b946020939093013593505050565b6000806040838503121561029b57600080fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146102bf57600080fd5b91506102cd6020840161024a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6040810160028410610340577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9281526020015290565b6000825160005b8181101561036b5760208186018101518583015201610351565b50600092019182525091905056fe608060405234801561001057600080fd5b506101e2806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636322653414610030575b600080fd5b61004361003e3660046100ee565b610057565b604051901515815260200160405180910390f35b6000610063838361006a565b9392505050565b600060018360018111156100805761008061011e565b036100e55760005b828110156100a2578061009a8161014d565b915050610088565b600080548591907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183818111156100de576100de61011e565b0217905550505b50600192915050565b6000806040838503121561010157600080fd5b82356002811061011057600080fd5b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036101a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122008b0d6e2c41d2d38087305ac063c4bc5ee7b8c4802e25232107224956548426064736f6c63430008130033a264697066735822122045342910478fd755f4afea9b56e0fffb346af611864b922b89d2451664b941fb64736f6c63430008130033",
"deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c8063632265341461003b578063bfc8045614610062575b600080fd5b61004e61004936600461025e565b61008d565b604051901515815260200160405180910390f35b61004e610070366004610288565b600060208181529281526040808220909352908152205460ff1681565b60008060405161009c9061023d565b604051809103906000f0801580156100b8573d6000803e3d6000fd5b50905060008173ffffffffffffffffffffffffffffffffffffffff1685856040516024016100e7929190610305565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f632265340000000000000000000000000000000000000000000000000000000017905251610168919061034a565b600060405180830381855af49150503d80600081146101a3576040519150601f19603f3d011682016040523d82523d6000602084013e6101a8565b606091505b505073ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604081209192508291908760018111156101e7576101e76102d6565b60018111156101f8576101f86102d6565b8152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055949350505050565b6102028061037a83390190565b80356002811061025957600080fd5b919050565b6000806040838503121561027157600080fd5b61027a8361024a565b946020939093013593505050565b6000806040838503121561029b57600080fd5b823573ffffffffffffffffffffffffffffffffffffffff811681146102bf57600080fd5b91506102cd6020840161024a565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b6040810160028410610340577f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b9281526020015290565b6000825160005b8181101561036b5760208186018101518583015201610351565b50600092019182525091905056fe608060405234801561001057600080fd5b506101e2806100206000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c80636322653414610030575b600080fd5b61004361003e3660046100ee565b610057565b604051901515815260200160405180910390f35b6000610063838361006a565b9392505050565b600060018360018111156100805761008061011e565b036100e55760005b828110156100a2578061009a8161014d565b915050610088565b600080548591907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600183818111156100de576100de61011e565b0217905550505b50600192915050565b6000806040838503121561010157600080fd5b82356002811061011057600080fd5b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036101a5577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b506001019056fea264697066735822122008b0d6e2c41d2d38087305ac063c4bc5ee7b8c4802e25232107224956548426064736f6c63430008130033a264697066735822122045342910478fd755f4afea9b56e0fffb346af611864b922b89d2451664b941fb64736f6c63430008130033",
"linkReferences": {},
"deployedLinkReferences": {}
}
24 changes: 24 additions & 0 deletions contracts/src/_testing/mocks/base/LineaScenarioDelegatingProxy.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.19;

import { LineaScenarioTesting } from "./LineaScenarioTesting.sol";

/// @dev Test ScenarioDelegatingProxy.
contract LineaScenarioDelegatingProxy {
mapping(address => mapping(LineaScenarioTesting.Scenario => bool)) public executedScenarios;

function executeScenario(LineaScenarioTesting.Scenario _scenario, uint256 _loopIterations) external returns (bool) {
// Deploy new scenario contract to consume gas and delegate to.
LineaScenarioTesting lineaScenarioTesting = new LineaScenarioTesting();

// Delegate the call noting that only 63/64 of the gas will be sent into the scenario in order to handle the revert
(bool callSuccess, ) = address(lineaScenarioTesting).delegatecall(
abi.encodeCall(LineaScenarioTesting.executeScenario, (_scenario, _loopIterations))
);

// If you are testing SSTORE out of gas here post delegatecall out of gas, this will never save.
executedScenarios[address(lineaScenarioTesting)][_scenario] = callSuccess;

return callSuccess;
}
}
31 changes: 31 additions & 0 deletions contracts/src/_testing/mocks/base/LineaScenarioTesting.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.19;

/// @dev Test scenarios on Linea.
contract LineaScenarioTesting {
enum Scenario {
RETURN_TRUE,
GAS_GUZZLE
}

Scenario private scenario;

function executeScenario(Scenario _scenario, uint256 _loopIterations) external returns (bool) {
return _executeScenario(_scenario, _loopIterations);
}

function _executeScenario(Scenario _scenario, uint256 _loopIterations) internal returns (bool) {
if (_scenario == Scenario.GAS_GUZZLE) {
// guzzle the gas
uint256 counter;
while (counter < _loopIterations) {
counter++;
}

// silencing the warning - this needs to be external to consume gas.
scenario = _scenario;
}

return true;
}
}
26 changes: 18 additions & 8 deletions contracts/src/_testing/mocks/base/RevertingVerifier.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity 0.8.26;
pragma solidity ^0.8.26;

import { IPlonkVerifier } from "../../../verifiers/interfaces/IPlonkVerifier.sol";

Expand All @@ -17,18 +17,28 @@ contract RevertingVerifier is IPlonkVerifier {
}

function Verify(bytes calldata, uint256[] calldata) external returns (bool) {
if (scenario == Scenario.GAS_GUZZLE) {
_executeScenario(scenario, type(uint256).max);

// defaults to EMPTY_REVERT scenario
revert();
}

function ExecuteScenario(Scenario _scenario, uint256 _loopIterations) external returns (bool) {
return _executeScenario(_scenario, _loopIterations);
}

function _executeScenario(Scenario _scenario, uint256 _loopIterations) internal returns (bool) {
if (_scenario == Scenario.GAS_GUZZLE) {
// guzzle the gas
bool usingGas = true;
while (usingGas) {
usingGas = true;
uint256 counter;
while (counter < _loopIterations) {
counter++;
}

// silencing the warning - this needs to be external to consume gas.
scenario = Scenario.GAS_GUZZLE;
scenario = scenario;
}

// defaults to EMPTY_REVERT scenario
revert();
return true;
}
}
20 changes: 20 additions & 0 deletions makefile-contracts.mk
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,23 @@ evm-opcode-tester-execute-all-opcodes:
RPC_URL=http:\\localhost:8545/ \
npx ts-node local-deployments-artifacts/executeAllOpcodes.ts

deploy-l2-scenario-testing-proxy:
# WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE
cd contracts/; \
PRIVATE_KEY=0x1dd171cec7e2995408b5513004e8207fe88d6820aeff0d82463b3e41df251aae \
RPC_URL=http:\\localhost:8545/ \
npx ts-node local-deployments-artifacts/deployLineaScenarioDelegatingProxy.ts

execute-scenario-testing-proxy-scenario: LINEA_SCENARIO_DELEGATING_PROXY_ADDRESS:=0x2f6dAaF8A81AB675fbD37Ca6Ed5b72cf86237453
execute-scenario-testing-proxy-scenario:
# WARNING: FOR LOCAL DEV ONLY - DO NOT REUSE THESE KEYS ELSEWHERE
# GAS_LIMIT=452500 will cause it to fail
cd contracts/; \
LINEA_SCENARIO_DELEGATING_PROXY_ADDRESS=$(LINEA_SCENARIO_DELEGATING_PROXY_ADDRESS) \
NUMBER_OF_LOOPS=10000000 \
LINEA_SCENARIO=1 \
GAS_LIMIT=452500 \
PRIVATE_KEY=0x1dd171cec7e2995408b5513004e8207fe88d6820aeff0d82463b3e41df251aae \
RPC_URL=http:\\localhost:8545/ \
npx ts-node local-deployments-artifacts/executeLineaScenarioDelegatingProxyScenario.ts

0 comments on commit b5194c0

Please sign in to comment.