Commit 2bc4731d authored by Maurelian's avatar Maurelian Committed by GitHub

ctb: Introduce Process library with run() method (#10677)

* ctb: Introduce Process library with run() method

* ctb: Replace vm.ffi with Process.run
parent be68885e
...@@ -12,6 +12,7 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; ...@@ -12,6 +12,7 @@ import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
import { LibString } from "@solady/utils/LibString.sol"; import { LibString } from "@solady/utils/LibString.sol";
import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol"; import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol";
import { IAddressManager } from "scripts/interfaces/IAddressManager.sol"; import { IAddressManager } from "scripts/interfaces/IAddressManager.sol";
import { Process } from "scripts/libraries/Process.sol";
/// @notice Represents a deployment. Is serialized to JSON as a key/value /// @notice Represents a deployment. Is serialized to JSON as a key/value
/// pair. Can be accessed from within scripts. /// pair. Can be accessed from within scripts.
...@@ -71,7 +72,7 @@ abstract contract Artifacts { ...@@ -71,7 +72,7 @@ abstract contract Artifacts {
commands[0] = "bash"; commands[0] = "bash";
commands[1] = "-c"; commands[1] = "-c";
commands[2] = string.concat("jq -cr < ", _path); commands[2] = string.concat("jq -cr < ", _path);
string memory json = string(vm.ffi(commands)); string memory json = string(Process.run(commands));
string[] memory keys = vm.parseJsonKeys(json, ""); string[] memory keys = vm.parseJsonKeys(json, "");
for (uint256 i; i < keys.length; i++) { for (uint256 i; i < keys.length; i++) {
string memory key = keys[i]; string memory key = keys[i];
...@@ -198,7 +199,7 @@ abstract contract Artifacts { ...@@ -198,7 +199,7 @@ abstract contract Artifacts {
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat(Executables.jq, " 'keys' <<< '", json, "'"); cmd[2] = string.concat(Executables.jq, " 'keys' <<< '", json, "'");
bytes memory res = vm.ffi(cmd); bytes memory res = Process.run(cmd);
string[] memory names = stdJson.readStringArray(string(res), ""); string[] memory names = stdJson.readStringArray(string(res), "");
Deployment[] memory deployments = new Deployment[](names.length); Deployment[] memory deployments = new Deployment[](names.length);
......
...@@ -56,6 +56,7 @@ import { Types } from "scripts/Types.sol"; ...@@ -56,6 +56,7 @@ import { Types } from "scripts/Types.sol";
import { LibStateDiff } from "scripts/libraries/LibStateDiff.sol"; import { LibStateDiff } from "scripts/libraries/LibStateDiff.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol"; import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol";
import { Process } from "scripts/libraries/Process.sol";
/// @title Deploy /// @title Deploy
/// @notice Script used to deploy a bedrock system. The entire system is deployed within the `run` function. /// @notice Script used to deploy a bedrock system. The entire system is deployed within the `run` function.
...@@ -1342,11 +1343,11 @@ contract Deploy is Deployer { ...@@ -1342,11 +1343,11 @@ contract Deploy is Deployer {
commands[0] = "bash"; commands[0] = "bash";
commands[1] = "-c"; commands[1] = "-c";
commands[2] = string.concat("[[ -f ", filePath, " ]] && echo \"present\""); commands[2] = string.concat("[[ -f ", filePath, " ]] && echo \"present\"");
if (vm.ffi(commands).length == 0) { if (Process.run(commands).length == 0) {
revert("Cannon prestate dump not found, generate it with `make cannon-prestate` in the monorepo root."); revert("Cannon prestate dump not found, generate it with `make cannon-prestate` in the monorepo root.");
} }
commands[2] = string.concat("cat ", filePath, " | jq -r .pre"); commands[2] = string.concat("cat ", filePath, " | jq -r .pre");
mipsAbsolutePrestate_ = Claim.wrap(abi.decode(vm.ffi(commands), (bytes32))); mipsAbsolutePrestate_ = Claim.wrap(abi.decode(Process.run(commands), (bytes32)));
console.log( console.log(
"[Cannon Dispute Game] Using devnet MIPS Absolute prestate: %s", "[Cannon Dispute Game] Using devnet MIPS Absolute prestate: %s",
vm.toString(Claim.unwrap(mipsAbsolutePrestate_)) vm.toString(Claim.unwrap(mipsAbsolutePrestate_))
......
...@@ -5,6 +5,7 @@ import { Script } from "forge-std/Script.sol"; ...@@ -5,6 +5,7 @@ import { Script } from "forge-std/Script.sol";
import { console2 as console } from "forge-std/console2.sol"; import { console2 as console } from "forge-std/console2.sol";
import { stdJson } from "forge-std/StdJson.sol"; import { stdJson } from "forge-std/StdJson.sol";
import { Executables } from "scripts/Executables.sol"; import { Executables } from "scripts/Executables.sol";
import { Process } from "scripts/libraries/Process.sol";
import { Chains } from "scripts/Chains.sol"; import { Chains } from "scripts/Chains.sol";
/// @title DeployConfig /// @title DeployConfig
...@@ -182,7 +183,7 @@ contract DeployConfig is Script { ...@@ -182,7 +183,7 @@ contract DeployConfig is Script {
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat("cast block ", vm.toString(tag), " --json | ", Executables.jq, " .timestamp"); cmd[2] = string.concat("cast block ", vm.toString(tag), " --json | ", Executables.jq, " .timestamp");
bytes memory res = vm.ffi(cmd); bytes memory res = Process.run(cmd);
return stdJson.readUint(string(res), ""); return stdJson.readUint(string(res), "");
} }
return uint256(_l2OutputOracleStartingTimestamp); return uint256(_l2OutputOracleStartingTimestamp);
...@@ -219,7 +220,7 @@ contract DeployConfig is Script { ...@@ -219,7 +220,7 @@ contract DeployConfig is Script {
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat("cast block ", _tag, " --json | ", Executables.jq, " -r .hash"); cmd[2] = string.concat("cast block ", _tag, " --json | ", Executables.jq, " -r .hash");
bytes memory res = vm.ffi(cmd); bytes memory res = Process.run(cmd);
return abi.decode(res, (bytes32)); return abi.decode(res, (bytes32));
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { Vm } from "forge-std/Vm.sol"; import { Vm } from "forge-std/Vm.sol";
import { Process } from "scripts/libraries/Process.sol";
/// @notice The executables used in ffi commands. These are set here /// @notice The executables used in ffi commands. These are set here
/// to have a single source of truth in case absolute paths /// to have a single source of truth in case absolute paths
...@@ -24,6 +25,6 @@ library Executables { ...@@ -24,6 +25,6 @@ library Executables {
commands[0] = bash; commands[0] = bash;
commands[1] = "-c"; commands[1] = "-c";
commands[2] = "cast abi-encode 'f(string)' $(git rev-parse HEAD)"; commands[2] = "cast abi-encode 'f(string)' $(git rev-parse HEAD)";
return abi.decode(vm.ffi(commands), (string)); return abi.decode(Process.run(commands), (string));
} }
} }
...@@ -8,6 +8,7 @@ import { FaultDisputeGame_Init } from "test/dispute/FaultDisputeGame.t.sol"; ...@@ -8,6 +8,7 @@ import { FaultDisputeGame_Init } from "test/dispute/FaultDisputeGame.t.sol";
import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol"; import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol"; import { FaultDisputeGame } from "src/dispute/FaultDisputeGame.sol";
import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol"; import { IFaultDisputeGame } from "src/dispute/interfaces/IFaultDisputeGame.sol";
import { Process } from "scripts/libraries/Process.sol";
import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Types.sol";
import "src/dispute/lib/Errors.sol"; import "src/dispute/lib/Errors.sol";
...@@ -79,6 +80,6 @@ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init { ...@@ -79,6 +80,6 @@ contract FaultDisputeGameViz is Script, FaultDisputeGame_Init {
commands[0] = "python3"; commands[0] = "python3";
commands[1] = "scripts/dag-viz.py"; commands[1] = "scripts/dag-viz.py";
commands[2] = vm.toString(abi.encode(gameData)); commands[2] = vm.toString(abi.encode(gameData));
vm.ffi(commands); Process.run(commands);
} }
} }
...@@ -4,6 +4,7 @@ pragma solidity ^0.8.0; ...@@ -4,6 +4,7 @@ pragma solidity ^0.8.0;
import { Vm } from "forge-std/Vm.sol"; import { Vm } from "forge-std/Vm.sol";
import { Executables } from "scripts/Executables.sol"; import { Executables } from "scripts/Executables.sol";
import { stdJson } from "forge-std/StdJson.sol"; import { stdJson } from "forge-std/StdJson.sol";
import { Process } from "scripts/libraries/Process.sol";
/// @notice Contains information about a storage slot. Mirrors the layout of the storage /// @notice Contains information about a storage slot. Mirrors the layout of the storage
/// slot object in Forge artifacts so that we can deserialize JSON into this struct. /// slot object in Forge artifacts so that we can deserialize JSON into this struct.
...@@ -41,7 +42,7 @@ library ForgeArtifacts { ...@@ -41,7 +42,7 @@ library ForgeArtifacts {
cmd[2] = string.concat( cmd[2] = string.concat(
Executables.echo, " ", _name, " | ", Executables.sed, " -E 's/[.][0-9]+\\.[0-9]+\\.[0-9]+//g'" Executables.echo, " ", _name, " | ", Executables.sed, " -E 's/[.][0-9]+\\.[0-9]+\\.[0-9]+//g'"
); );
bytes memory res = vm.ffi(cmd); bytes memory res = Process.run(cmd);
out_ = string(res); out_ = string(res);
} }
...@@ -58,7 +59,7 @@ library ForgeArtifacts { ...@@ -58,7 +59,7 @@ library ForgeArtifacts {
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat(Executables.jq, " -r '.storageLayout' < ", _getForgeArtifactPath(_name)); cmd[2] = string.concat(Executables.jq, " -r '.storageLayout' < ", _getForgeArtifactPath(_name));
bytes memory res = vm.ffi(cmd); bytes memory res = Process.run(cmd);
layout_ = string(res); layout_ = string(res);
} }
...@@ -68,7 +69,7 @@ library ForgeArtifacts { ...@@ -68,7 +69,7 @@ library ForgeArtifacts {
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat(Executables.jq, " -r '.abi' < ", _getForgeArtifactPath(_name)); cmd[2] = string.concat(Executables.jq, " -r '.abi' < ", _getForgeArtifactPath(_name));
bytes memory res = vm.ffi(cmd); bytes memory res = Process.run(cmd);
abi_ = string(res); abi_ = string(res);
} }
...@@ -78,7 +79,7 @@ library ForgeArtifacts { ...@@ -78,7 +79,7 @@ library ForgeArtifacts {
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat(Executables.jq, " '.methodIdentifiers | keys' < ", _getForgeArtifactPath(_name)); cmd[2] = string.concat(Executables.jq, " '.methodIdentifiers | keys' < ", _getForgeArtifactPath(_name));
bytes memory res = vm.ffi(cmd); bytes memory res = Process.run(cmd);
ids_ = stdJson.readStringArray(string(res), ""); ids_ = stdJson.readStringArray(string(res), "");
} }
...@@ -87,7 +88,7 @@ library ForgeArtifacts { ...@@ -87,7 +88,7 @@ library ForgeArtifacts {
cmd[0] = Executables.bash; cmd[0] = Executables.bash;
cmd[1] = "-c"; cmd[1] = "-c";
cmd[2] = string.concat(Executables.forge, " config --json | ", Executables.jq, " -r .out"); cmd[2] = string.concat(Executables.forge, " config --json | ", Executables.jq, " -r .out");
bytes memory res = vm.ffi(cmd); bytes memory res = Process.run(cmd);
string memory contractName = _stripSemver(_name); string memory contractName = _stripSemver(_name);
dir_ = string.concat(vm.projectRoot(), "/", string(res), "/", contractName, ".sol"); dir_ = string.concat(vm.projectRoot(), "/", string(res), "/", contractName, ".sol");
} }
...@@ -112,7 +113,7 @@ library ForgeArtifacts { ...@@ -112,7 +113,7 @@ library ForgeArtifacts {
Executables.jq, Executables.jq,
" -R -s -c 'split(\"\n\") | map(select(length > 0))'" " -R -s -c 'split(\"\n\") | map(select(length > 0))'"
); );
bytes memory res = vm.ffi(cmd); bytes memory res = Process.run(cmd);
string[] memory files = stdJson.readStringArray(string(res), ""); string[] memory files = stdJson.readStringArray(string(res), "");
out_ = string.concat(directory, "/", files[0]); out_ = string.concat(directory, "/", files[0]);
} }
...@@ -139,7 +140,7 @@ library ForgeArtifacts { ...@@ -139,7 +140,7 @@ library ForgeArtifacts {
Executables.jq, Executables.jq,
" '.storage[] | select(.label == \"_initialized\" and .type == \"t_uint8\")'" " '.storage[] | select(.label == \"_initialized\" and .type == \"t_uint8\")'"
); );
bytes memory rawSlot = vm.parseJson(string(vm.ffi(command))); bytes memory rawSlot = vm.parseJson(string(Process.run(command)));
slot_ = abi.decode(rawSlot, (StorageSlot)); slot_ = abi.decode(rawSlot, (StorageSlot));
} }
...@@ -184,7 +185,7 @@ library ForgeArtifacts { ...@@ -184,7 +185,7 @@ library ForgeArtifacts {
Executables.jq, Executables.jq,
" -R -s 'split(\"\n\")[:-1]'" " -R -s 'split(\"\n\")[:-1]'"
); );
string[] memory contractNames = abi.decode(vm.parseJson(string(vm.ffi(command))), (string[])); string[] memory contractNames = abi.decode(vm.parseJson(string(Process.run(command))), (string[]));
abis_ = new Abi[](contractNames.length); abis_ = new Abi[](contractNames.length);
......
...@@ -25,6 +25,7 @@ import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; ...@@ -25,6 +25,7 @@ import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { L1StandardBridge } from "src/L1/L1StandardBridge.sol"; import { L1StandardBridge } from "src/L1/L1StandardBridge.sol";
import { FeeVault } from "src/universal/FeeVault.sol"; import { FeeVault } from "src/universal/FeeVault.sol";
import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol"; import { EIP1967Helper } from "test/mocks/EIP1967Helper.sol";
import { Process } from "scripts/libraries/Process.sol";
interface IInitializable { interface IInitializable {
function initialize(address _addr) external; function initialize(address _addr) external;
...@@ -557,7 +558,7 @@ contract L2Genesis is Deployer { ...@@ -557,7 +558,7 @@ contract L2Genesis is Deployer {
commands[0] = "bash"; commands[0] = "bash";
commands[1] = "-c"; commands[1] = "-c";
commands[2] = string.concat("cat <<< $(jq -S '.' ", _path, ") > ", _path); commands[2] = string.concat("cat <<< $(jq -S '.' ", _path, ") > ", _path);
vm.ffi(commands); Process.run(commands);
} }
/// @notice Funds the default dev accounts with ether /// @notice Funds the default dev accounts with ether
......
...@@ -4,6 +4,7 @@ pragma solidity 0.8.15; ...@@ -4,6 +4,7 @@ pragma solidity 0.8.15;
import { Script } from "forge-std/Script.sol"; import { Script } from "forge-std/Script.sol";
import { stdJson } from "forge-std/StdJson.sol"; import { stdJson } from "forge-std/StdJson.sol";
import { console2 as console } from "forge-std/console2.sol"; import { console2 as console } from "forge-std/console2.sol";
import { Process } from "scripts/libraries/Process.sol";
contract SemverLock is Script { contract SemverLock is Script {
function run() public { function run() public {
...@@ -12,7 +13,7 @@ contract SemverLock is Script { ...@@ -12,7 +13,7 @@ contract SemverLock is Script {
commands[0] = "bash"; commands[0] = "bash";
commands[1] = "-c"; commands[1] = "-c";
commands[2] = "grep -rl '@custom:semver' src | jq -Rs 'split(\"\\n\") | map(select(length > 0))'"; commands[2] = "grep -rl '@custom:semver' src | jq -Rs 'split(\"\\n\") | map(select(length > 0))'";
string memory rawFiles = string(vm.ffi(commands)); string memory rawFiles = string(Process.run(commands));
string[] memory files = vm.parseJsonStringArray(rawFiles, ""); string[] memory files = vm.parseJsonStringArray(rawFiles, "");
writeSemverLock(files); writeSemverLock(files);
...@@ -26,17 +27,17 @@ contract SemverLock is Script { ...@@ -26,17 +27,17 @@ contract SemverLock is Script {
string[] memory commands = new string[](2); string[] memory commands = new string[](2);
commands[0] = "cat"; commands[0] = "cat";
commands[1] = _files[i]; commands[1] = _files[i];
string memory fileContents = string(vm.ffi(commands)); string memory fileContents = string(Process.run(commands));
// Grab the contract name // Grab the contract name
commands = new string[](3); commands = new string[](3);
commands[0] = "bash"; commands[0] = "bash";
commands[1] = "-c"; commands[1] = "-c";
commands[2] = string.concat("echo \"", _files[i], "\"| sed -E \'s|src/.*/(.+)\\.sol|\\1|\'"); commands[2] = string.concat("echo \"", _files[i], "\"| sed -E \'s|src/.*/(.+)\\.sol|\\1|\'");
string memory contractName = string(vm.ffi(commands)); string memory contractName = string(Process.run(commands));
commands[2] = "forge config --json | jq -r .out"; commands[2] = "forge config --json | jq -r .out";
string memory artifactsDir = string(vm.ffi(commands)); string memory artifactsDir = string(Process.run(commands));
// Handle the case where there are multiple artifacts for a contract. This happens // Handle the case where there are multiple artifacts for a contract. This happens
// when the same contract is compiled with multiple compiler versions. // when the same contract is compiled with multiple compiler versions.
...@@ -44,7 +45,7 @@ contract SemverLock is Script { ...@@ -44,7 +45,7 @@ contract SemverLock is Script {
commands[2] = string.concat( commands[2] = string.concat(
"ls -1 --color=never ", contractArtifactDir, " | jq -R -s -c 'split(\"\n\") | map(select(length > 0))'" "ls -1 --color=never ", contractArtifactDir, " | jq -R -s -c 'split(\"\n\") | map(select(length > 0))'"
); );
string memory artifactFiles = string(vm.ffi(commands)); string memory artifactFiles = string(Process.run(commands));
string[] memory files = stdJson.readStringArray(artifactFiles, ""); string[] memory files = stdJson.readStringArray(artifactFiles, "");
require(files.length > 0, string.concat("No artifacts found for ", contractName)); require(files.length > 0, string.concat("No artifacts found for ", contractName));
......
...@@ -15,7 +15,7 @@ To build, run `pnpm build:go-ffi` from this directory or the `contract-bedrock` ...@@ -15,7 +15,7 @@ To build, run `pnpm build:go-ffi` from this directory or the `contract-bedrock`
### In a Forge Test ### In a Forge Test
To use `go-ffi` in a forge test, simply invoke the binary via the `vm.ffi` cheatcode. To use `go-ffi` in a forge test, simply invoke the binary using the solidity `Process` library's `run` method.
```solidity ```solidity
function myFFITest() public { function myFFITest() public {
...@@ -23,7 +23,7 @@ function myFFITest() public { ...@@ -23,7 +23,7 @@ function myFFITest() public {
commands[0] = "./scripts/go-ffi/go-ffi"; commands[0] = "./scripts/go-ffi/go-ffi";
commands[1] = "trie"; commands[1] = "trie";
commands[2] = "valid"; commands[2] = "valid";
bytes memory result = vm.ffi(commands); bytes memory result = Process.run(commands);
// Do something with the result of the command // Do something with the result of the command
} }
......
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import { Vm } from "forge-std/Vm.sol";
library Process {
/// @notice Error for when an ffi command fails.
error FfiFailed(string);
/// @notice Foundry cheatcode VM.
Vm private constant vm = Vm(address(uint160(uint256(keccak256("hevm cheat code")))));
function run(string[] memory cmd) internal returns (bytes memory stdout_) {
Vm.FfiResult memory result = vm.tryFfi(cmd);
if (result.exitCode != 0) {
string memory command;
for (uint256 i = 0; i < cmd.length; i++) {
command = string.concat(command, cmd[i], " ");
}
revert FfiFailed(string.concat("Command: ", command, "\nError: ", string(result.stderr)));
}
stdout_ = result.stdout;
}
}
...@@ -5,6 +5,7 @@ import { Test } from "forge-std/Test.sol"; ...@@ -5,6 +5,7 @@ import { Test } from "forge-std/Test.sol";
import { L2Genesis, OutputMode, L1Dependencies } from "scripts/L2Genesis.s.sol"; import { L2Genesis, OutputMode, L1Dependencies } from "scripts/L2Genesis.s.sol";
import { Predeploys } from "src/libraries/Predeploys.sol"; import { Predeploys } from "src/libraries/Predeploys.sol";
import { Constants } from "src/libraries/Constants.sol"; import { Constants } from "src/libraries/Constants.sol";
import { Process } from "scripts/libraries/Process.sol";
/// @title L2GenesisTest /// @title L2GenesisTest
/// @notice Test suite for L2Genesis script. /// @notice Test suite for L2Genesis script.
...@@ -25,7 +26,7 @@ contract L2GenesisTest is Test { ...@@ -25,7 +26,7 @@ contract L2GenesisTest is Test {
commands[0] = "bash"; commands[0] = "bash";
commands[1] = "-c"; commands[1] = "-c";
commands[2] = "mktemp"; commands[2] = "mktemp";
bytes memory result = vm.ffi(commands); bytes memory result = Process.run(commands);
return string(result); return string(result);
} }
...@@ -36,7 +37,7 @@ contract L2GenesisTest is Test { ...@@ -36,7 +37,7 @@ contract L2GenesisTest is Test {
commands[0] = "bash"; commands[0] = "bash";
commands[1] = "-c"; commands[1] = "-c";
commands[2] = string.concat("rm ", path); commands[2] = string.concat("rm ", path);
vm.ffi(commands); Process.run(commands);
} }
/// @notice Returns the number of top level keys in a JSON object at a given /// @notice Returns the number of top level keys in a JSON object at a given
...@@ -46,7 +47,7 @@ contract L2GenesisTest is Test { ...@@ -46,7 +47,7 @@ contract L2GenesisTest is Test {
commands[0] = "bash"; commands[0] = "bash";
commands[1] = "-c"; commands[1] = "-c";
commands[2] = string.concat("jq 'keys | length' < ", path, " | xargs cast abi-encode 'f(uint256)'"); commands[2] = string.concat("jq 'keys | length' < ", path, " | xargs cast abi-encode 'f(uint256)'");
return abi.decode(vm.ffi(commands), (uint256)); return abi.decode(Process.run(commands), (uint256));
} }
/// @notice Helper function to run a function with a temporary dump file. /// @notice Helper function to run a function with a temporary dump file.
...@@ -63,7 +64,7 @@ contract L2GenesisTest is Test { ...@@ -63,7 +64,7 @@ contract L2GenesisTest is Test {
commands[1] = "-c"; commands[1] = "-c";
commands[2] = commands[2] =
string.concat("jq -r '.[\"", vm.toLowercase(vm.toString(_addr)), "\"].storage | length' < ", _path); string.concat("jq -r '.[\"", vm.toLowercase(vm.toString(_addr)), "\"].storage | length' < ", _path);
return vm.parseUint(string(vm.ffi(commands))); return vm.parseUint(string(Process.run(commands)));
} }
/// @notice Returns the number of accounts that contain particular code at a given path to a genesis file. /// @notice Returns the number of accounts that contain particular code at a given path to a genesis file.
...@@ -79,7 +80,7 @@ contract L2GenesisTest is Test { ...@@ -79,7 +80,7 @@ contract L2GenesisTest is Test {
path, path,
" | xargs cast abi-encode 'f(uint256)'" " | xargs cast abi-encode 'f(uint256)'"
); );
return abi.decode(vm.ffi(commands), (uint256)); return abi.decode(Process.run(commands), (uint256));
} }
/// @notice Returns the number of accounts that have a particular slot set. /// @notice Returns the number of accounts that have a particular slot set.
...@@ -94,7 +95,7 @@ contract L2GenesisTest is Test { ...@@ -94,7 +95,7 @@ contract L2GenesisTest is Test {
path, path,
" | xargs cast abi-encode 'f(uint256)'" " | xargs cast abi-encode 'f(uint256)'"
); );
return abi.decode(vm.ffi(commands), (uint256)); return abi.decode(Process.run(commands), (uint256));
} }
/// @notice Returns the number of accounts that have a particular slot set to a particular value. /// @notice Returns the number of accounts that have a particular slot set to a particular value.
...@@ -118,7 +119,7 @@ contract L2GenesisTest is Test { ...@@ -118,7 +119,7 @@ contract L2GenesisTest is Test {
path, path,
" | xargs cast abi-encode 'f(uint256)'" " | xargs cast abi-encode 'f(uint256)'"
); );
return abi.decode(vm.ffi(commands), (uint256)); return abi.decode(Process.run(commands), (uint256));
} }
/// @notice Tests the genesis predeploys setup using a temp file for the case where useInterop is false. /// @notice Tests the genesis predeploys setup using a temp file for the case where useInterop is false.
......
...@@ -7,6 +7,7 @@ import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; ...@@ -7,6 +7,7 @@ import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol"; import { PreimageKeyLib } from "src/cannon/PreimageKeyLib.sol";
import { LibKeccak } from "@lib-keccak/LibKeccak.sol"; import { LibKeccak } from "@lib-keccak/LibKeccak.sol";
import { Bytes } from "src/libraries/Bytes.sol"; import { Bytes } from "src/libraries/Bytes.sol";
import { Process } from "scripts/libraries/Process.sol";
import "src/cannon/libraries/CannonErrors.sol"; import "src/cannon/libraries/CannonErrors.sol";
import "src/cannon/libraries/CannonTypes.sol"; import "src/cannon/libraries/CannonTypes.sol";
...@@ -1346,7 +1347,7 @@ contract PreimageOracle_LargePreimageProposals_Test is Test { ...@@ -1346,7 +1347,7 @@ contract PreimageOracle_LargePreimageProposals_Test is Test {
commands[2] = "gen_proof"; commands[2] = "gen_proof";
commands[3] = vm.toString(abi.encodePacked(leaves)); commands[3] = vm.toString(abi.encodePacked(leaves));
commands[4] = vm.toString(_leafIdx); commands[4] = vm.toString(_leafIdx);
(root_, proof_) = abi.decode(vm.ffi(commands), (bytes32, bytes32[])); (root_, proof_) = abi.decode(Process.run(commands), (bytes32, bytes32[]));
} }
fallback() external payable { } fallback() external payable { }
......
...@@ -4,6 +4,7 @@ pragma solidity 0.8.15; ...@@ -4,6 +4,7 @@ pragma solidity 0.8.15;
import { Types } from "src/libraries/Types.sol"; import { Types } from "src/libraries/Types.sol";
import { Vm } from "forge-std/Vm.sol"; import { Vm } from "forge-std/Vm.sol";
import { Strings } from "@openzeppelin/contracts/utils/Strings.sol"; import { Strings } from "@openzeppelin/contracts/utils/Strings.sol";
import { Process } from "scripts/libraries/Process.sol";
/// @title FFIInterface /// @title FFIInterface
/// @notice This contract is set into state using `etch` and therefore must not have constructor logic. /// @notice This contract is set into state using `etch` and therefore must not have constructor logic.
...@@ -27,7 +28,7 @@ contract FFIInterface { ...@@ -27,7 +28,7 @@ contract FFIInterface {
cmds[7] = vm.toString(_tx.gasLimit); cmds[7] = vm.toString(_tx.gasLimit);
cmds[8] = vm.toString(_tx.data); cmds[8] = vm.toString(_tx.data);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
( (
bytes32 stateRoot, bytes32 stateRoot,
bytes32 storageRoot, bytes32 storageRoot,
...@@ -61,7 +62,7 @@ contract FFIInterface { ...@@ -61,7 +62,7 @@ contract FFIInterface {
cmds[7] = vm.toString(_gasLimit); cmds[7] = vm.toString(_gasLimit);
cmds[8] = vm.toString(_data); cmds[8] = vm.toString(_data);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (bytes32)); return abi.decode(result, (bytes32));
} }
...@@ -87,7 +88,7 @@ contract FFIInterface { ...@@ -87,7 +88,7 @@ contract FFIInterface {
cmds[7] = vm.toString(_gasLimit); cmds[7] = vm.toString(_gasLimit);
cmds[8] = vm.toString(_data); cmds[8] = vm.toString(_data);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (bytes32)); return abi.decode(result, (bytes32));
} }
...@@ -109,7 +110,7 @@ contract FFIInterface { ...@@ -109,7 +110,7 @@ contract FFIInterface {
cmds[5] = Strings.toHexString(uint256(_messagePasserStorageRoot)); cmds[5] = Strings.toHexString(uint256(_messagePasserStorageRoot));
cmds[6] = Strings.toHexString(uint256(_latestBlockhash)); cmds[6] = Strings.toHexString(uint256(_latestBlockhash));
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (bytes32)); return abi.decode(result, (bytes32));
} }
...@@ -138,7 +139,7 @@ contract FFIInterface { ...@@ -138,7 +139,7 @@ contract FFIInterface {
cmds[9] = vm.toString(_gas); cmds[9] = vm.toString(_gas);
cmds[10] = vm.toString(_data); cmds[10] = vm.toString(_data);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (bytes32)); return abi.decode(result, (bytes32));
} }
...@@ -157,7 +158,7 @@ contract FFIInterface { ...@@ -157,7 +158,7 @@ contract FFIInterface {
cmds[10] = vm.toString(txn.l1BlockHash); cmds[10] = vm.toString(txn.l1BlockHash);
cmds[11] = vm.toString(txn.logIndex); cmds[11] = vm.toString(txn.logIndex);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (bytes)); return abi.decode(result, (bytes));
} }
...@@ -183,7 +184,7 @@ contract FFIInterface { ...@@ -183,7 +184,7 @@ contract FFIInterface {
cmds[7] = vm.toString(_gasLimit); cmds[7] = vm.toString(_gasLimit);
cmds[8] = vm.toString(_data); cmds[8] = vm.toString(_data);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (bytes)); return abi.decode(result, (bytes));
} }
...@@ -194,7 +195,7 @@ contract FFIInterface { ...@@ -194,7 +195,7 @@ contract FFIInterface {
cmds[2] = "decodeVersionedNonce"; cmds[2] = "decodeVersionedNonce";
cmds[3] = vm.toString(nonce); cmds[3] = vm.toString(nonce);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (uint256, uint256)); return abi.decode(result, (uint256, uint256));
} }
...@@ -207,7 +208,7 @@ contract FFIInterface { ...@@ -207,7 +208,7 @@ contract FFIInterface {
cmds[1] = "trie"; cmds[1] = "trie";
cmds[2] = variant; cmds[2] = variant;
return abi.decode(vm.ffi(cmds), (bytes32, bytes, bytes, bytes[])); return abi.decode(Process.run(cmds), (bytes32, bytes, bytes, bytes[]));
} }
function getCannonMemoryProof(uint32 pc, uint32 insn) external returns (bytes32, bytes memory) { function getCannonMemoryProof(uint32 pc, uint32 insn) external returns (bytes32, bytes memory) {
...@@ -217,7 +218,7 @@ contract FFIInterface { ...@@ -217,7 +218,7 @@ contract FFIInterface {
cmds[2] = "cannonMemoryProof"; cmds[2] = "cannonMemoryProof";
cmds[3] = vm.toString(pc); cmds[3] = vm.toString(pc);
cmds[4] = vm.toString(insn); cmds[4] = vm.toString(insn);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
(bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes));
return (memRoot, proof); return (memRoot, proof);
} }
...@@ -239,7 +240,7 @@ contract FFIInterface { ...@@ -239,7 +240,7 @@ contract FFIInterface {
cmds[4] = vm.toString(insn); cmds[4] = vm.toString(insn);
cmds[5] = vm.toString(memAddr); cmds[5] = vm.toString(memAddr);
cmds[6] = vm.toString(memVal); cmds[6] = vm.toString(memVal);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
(bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes)); (bytes32 memRoot, bytes memory proof) = abi.decode(result, (bytes32, bytes));
return (memRoot, proof); return (memRoot, proof);
} }
...@@ -251,7 +252,7 @@ contract FFIInterface { ...@@ -251,7 +252,7 @@ contract FFIInterface {
cmds[2] = "encodeScalarEcotone"; cmds[2] = "encodeScalarEcotone";
cmds[3] = vm.toString(_basefeeScalar); cmds[3] = vm.toString(_basefeeScalar);
cmds[4] = vm.toString(_blobbasefeeScalar); cmds[4] = vm.toString(_blobbasefeeScalar);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (bytes32)); return abi.decode(result, (bytes32));
} }
...@@ -261,7 +262,7 @@ contract FFIInterface { ...@@ -261,7 +262,7 @@ contract FFIInterface {
cmds[1] = "diff"; cmds[1] = "diff";
cmds[2] = "decodeScalarEcotone"; cmds[2] = "decodeScalarEcotone";
cmds[3] = vm.toString(_scalar); cmds[3] = vm.toString(_scalar);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (uint32, uint32)); return abi.decode(result, (uint32, uint32));
} }
...@@ -283,7 +284,7 @@ contract FFIInterface { ...@@ -283,7 +284,7 @@ contract FFIInterface {
cmds[5] = vm.toString(_name); cmds[5] = vm.toString(_name);
cmds[6] = vm.toString(_symbol); cmds[6] = vm.toString(_symbol);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (bytes)); return abi.decode(result, (bytes));
} }
...@@ -294,7 +295,7 @@ contract FFIInterface { ...@@ -294,7 +295,7 @@ contract FFIInterface {
cmds[2] = "encodeDependency"; cmds[2] = "encodeDependency";
cmds[3] = vm.toString(_chainId); cmds[3] = vm.toString(_chainId);
bytes memory result = vm.ffi(cmds); bytes memory result = Process.run(cmds);
return abi.decode(result, (bytes)); return abi.decode(result, (bytes));
} }
} }
...@@ -46,8 +46,6 @@ import { WETH } from "src/L2/WETH.sol"; ...@@ -46,8 +46,6 @@ import { WETH } from "src/L2/WETH.sol";
/// up behind proxies. In the future we will migrate to importing the genesis JSON /// up behind proxies. In the future we will migrate to importing the genesis JSON
/// file that is created to set up the L2 contracts instead of setting them up manually. /// file that is created to set up the L2 contracts instead of setting them up manually.
contract Setup { contract Setup {
error FfiFailed(string);
/// @notice The address of the foundry Vm contract. /// @notice The address of the foundry Vm contract.
Vm private constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); Vm private constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D);
......
...@@ -10,6 +10,7 @@ import { SuperchainConfig } from "src/L1/SuperchainConfig.sol"; ...@@ -10,6 +10,7 @@ import { SuperchainConfig } from "src/L1/SuperchainConfig.sol";
import { ResourceMetering } from "src/L1/ResourceMetering.sol"; import { ResourceMetering } from "src/L1/ResourceMetering.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol"; import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol"; import { ForgeArtifacts } from "scripts/ForgeArtifacts.sol";
import { Process } from "scripts/libraries/Process.sol";
import "src/L1/ProtocolVersions.sol"; import "src/L1/ProtocolVersions.sol";
import "src/dispute/lib/Types.sol"; import "src/dispute/lib/Types.sol";
import "scripts/Deployer.sol"; import "scripts/Deployer.sol";
...@@ -388,7 +389,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -388,7 +389,7 @@ contract Initializer_Test is Bridge_Initializer {
Executables.jq, Executables.jq,
" -R -s 'split(\"\n\")[:-1]'" " -R -s 'split(\"\n\")[:-1]'"
); );
string[] memory l1ContractNames = abi.decode(vm.parseJson(string(vm.ffi(command))), (string[])); string[] memory l1ContractNames = abi.decode(vm.parseJson(string(Process.run(command))), (string[]));
for (uint256 i; i < l1ContractNames.length; i++) { for (uint256 i; i < l1ContractNames.length; i++) {
string memory contractName = l1ContractNames[i]; string memory contractName = l1ContractNames[i];
...@@ -404,7 +405,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -404,7 +405,7 @@ contract Initializer_Test is Bridge_Initializer {
Executables.jq, Executables.jq,
" '.[] | select(.name == \"initialize\" and .type == \"function\")'" " '.[] | select(.name == \"initialize\" and .type == \"function\")'"
); );
bytes memory res = vm.ffi(command); bytes memory res = Process.run(command);
// If the contract has an `initialize()` function, the resulting query will be non-empty. // If the contract has an `initialize()` function, the resulting query will be non-empty.
// In this case, increment the number of `Initializable` contracts. // In this case, increment the number of `Initializable` contracts.
...@@ -425,7 +426,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -425,7 +426,7 @@ contract Initializer_Test is Bridge_Initializer {
Executables.jq, Executables.jq,
" -R -s 'split(\"\n\")[:-1]'" " -R -s 'split(\"\n\")[:-1]'"
); );
string[] memory l2ContractNames = abi.decode(vm.parseJson(string(vm.ffi(command))), (string[])); string[] memory l2ContractNames = abi.decode(vm.parseJson(string(Process.run(command))), (string[]));
for (uint256 i; i < l2ContractNames.length; i++) { for (uint256 i; i < l2ContractNames.length; i++) {
string memory contractName = l2ContractNames[i]; string memory contractName = l2ContractNames[i];
...@@ -441,7 +442,7 @@ contract Initializer_Test is Bridge_Initializer { ...@@ -441,7 +442,7 @@ contract Initializer_Test is Bridge_Initializer {
Executables.jq, Executables.jq,
" '.[] | select(.name == \"initialize\" and .type == \"function\")'" " '.[] | select(.name == \"initialize\" and .type == \"function\")'"
); );
bytes memory res = vm.ffi(command); bytes memory res = Process.run(command);
// If the contract has an `initialize()` function, the resulting query will be non-empty. // If the contract has an `initialize()` function, the resulting query will be non-empty.
// In this case, increment the number of `Initializable` contracts. // In this case, increment the number of `Initializable` contracts.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment