From 482633768be731462c7aa9b32b8eafb74289ad2e Mon Sep 17 00:00:00 2001 From: Sebastian Stammler Date: Tue, 11 Jun 2024 23:20:27 +0200 Subject: [PATCH] contracts: Make L2 genesis script configurable (#10764) * contracts: Make L2 genesis script configurable * contracts: Read latest fork from deploy config in L2 genesis script * contracts: add README entry for new L2 genesis script env vars * address review --- .circleci/config.yml | 12 +-- bedrock-devnet/devnet/__init__.py | 11 ++- op-chain-ops/genesis/layer_two.go | 2 +- op-e2e/config/init.go | 5 +- packages/contracts-bedrock/README.md | 12 +++ packages/contracts-bedrock/scripts/Config.sol | 90 +++++++++++++++++++ .../scripts/DeployConfig.s.sol | 51 ++++++++++- .../contracts-bedrock/scripts/L2Genesis.s.sol | 58 ++++++------ .../test/L2/GasPriceOracle.t.sol | 8 +- .../contracts-bedrock/test/L2Genesis.t.sol | 4 +- .../contracts-bedrock/test/setup/Setup.sol | 13 ++- 11 files changed, 207 insertions(+), 59 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index bafc24310b01..de393bf98188 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -243,25 +243,25 @@ jobs: - "packages/contracts-bedrock/tsconfig.tsbuildinfo" - "packages/contracts-bedrock/tsconfig.build.tsbuildinfo" - ".devnet/allocs-l1.json" - - ".devnet/allocs-l2.json" - ".devnet/allocs-l2-delta.json" - ".devnet/allocs-l2-ecotone.json" + - ".devnet/allocs-l2-fjord.json" - ".devnet/addresses.json" - ".devnet-l2oo/allocs-l1.json" - ".devnet-l2oo/addresses.json" - - ".devnet-l2oo/allocs-l2.json" - ".devnet-l2oo/allocs-l2-delta.json" - ".devnet-l2oo/allocs-l2-ecotone.json" + - ".devnet-l2oo/allocs-l2-fjord.json" - ".devnet-plasma/allocs-l1.json" - ".devnet-plasma/addresses.json" - - ".devnet-plasma/allocs-l2.json" - ".devnet-plasma/allocs-l2-delta.json" - ".devnet-plasma/allocs-l2-ecotone.json" + - ".devnet-plasma/allocs-l2-fjord.json" - ".devnet-plasma-generic/allocs-l1.json" - ".devnet-plasma-generic/addresses.json" - - ".devnet-plasma-generic/allocs-l2.json" - ".devnet-plasma-generic/allocs-l2-delta.json" - ".devnet-plasma-generic/allocs-l2-ecotone.json" + - ".devnet-plasma-generic/allocs-l2-fjord.json" - "packages/contracts-bedrock/deploy-config/devnetL1.json" - "packages/contracts-bedrock/deployments/devnetL1" - notify-failures-on-develop @@ -928,9 +928,9 @@ jobs: name: Load devnet-allocs command: | mkdir -p .devnet - cp /tmp/workspace/.devnet<>/allocs-l2.json .devnet/allocs-l2.json cp /tmp/workspace/.devnet<>/allocs-l2-delta.json .devnet/allocs-l2-delta.json cp /tmp/workspace/.devnet<>/allocs-l2-ecotone.json .devnet/allocs-l2-ecotone.json + cp /tmp/workspace/.devnet<>/allocs-l2-fjord.json .devnet/allocs-l2-fjord.json cp /tmp/workspace/.devnet<>/allocs-l1.json .devnet/allocs-l1.json cp /tmp/workspace/.devnet<>/addresses.json .devnet/addresses.json cp /tmp/workspace/packages/contracts-bedrock/deploy-config/devnetL1.json packages/contracts-bedrock/deploy-config/devnetL1.json @@ -1113,9 +1113,9 @@ jobs: - persist_to_workspace: root: . paths: - - ".devnet/allocs-l2.json" - ".devnet/allocs-l2-delta.json" - ".devnet/allocs-l2-ecotone.json" + - ".devnet/allocs-l2-fjord.json" - ".devnet/allocs-l1.json" - ".devnet/addresses.json" - "packages/contracts-bedrock/deploy-config/devnetL1.json" diff --git a/bedrock-devnet/devnet/__init__.py b/bedrock-devnet/devnet/__init__.py index f034efee128e..182172d3412d 100644 --- a/bedrock-devnet/devnet/__init__.py +++ b/bedrock-devnet/devnet/__init__.py @@ -26,6 +26,9 @@ log = logging.getLogger() +# Global constants +FORKS = ["delta", "ecotone", "fjord"] + # Global environment variables DEVNET_NO_BUILD = os.getenv('DEVNET_NO_BUILD') == "true" DEVNET_L2OO = os.getenv('DEVNET_L2OO') == "true" @@ -171,9 +174,9 @@ def devnet_l2_allocs(paths): # For the previous forks, and the latest fork (default, thus empty prefix), # move the forge-dumps into place as .devnet allocs. - for suffix in ["-delta", "-ecotone", ""]: - input_path = pjoin(paths.contracts_bedrock_dir, f"state-dump-901{suffix}.json") - output_path = pjoin(paths.devnet_dir, f'allocs-l2{suffix}.json') + for fork in FORKS: + input_path = pjoin(paths.contracts_bedrock_dir, f"state-dump-901-{fork}.json") + output_path = pjoin(paths.devnet_dir, f'allocs-l2-{fork}.json') shutil.move(src=input_path, dst=output_path) log.info("Generated L2 allocs: "+output_path) @@ -218,7 +221,7 @@ def devnet_deploy(paths): log.info('L2 genesis and rollup configs already generated.') else: log.info('Generating L2 genesis and rollup configs.') - l2_allocs_path = pjoin(paths.devnet_dir, 'allocs-l2.json') + l2_allocs_path = pjoin(paths.devnet_dir, f'allocs-l2-{FORKS[-1]}.json') if os.path.exists(l2_allocs_path) == False or DEVNET_L2OO == True: # Also regenerate if L2OO. # The L2OO flag may affect the L1 deployments addresses, which may affect the L2 genesis. diff --git a/op-chain-ops/genesis/layer_two.go b/op-chain-ops/genesis/layer_two.go index a534957243bd..6cd0bbe7d27f 100644 --- a/op-chain-ops/genesis/layer_two.go +++ b/op-chain-ops/genesis/layer_two.go @@ -24,7 +24,7 @@ type L2AllocsMode string const ( L2AllocsDelta L2AllocsMode = "delta" L2AllocsEcotone L2AllocsMode = "ecotone" - L2AllocsFjord L2AllocsMode = "" // the default in solidity scripting / testing + L2AllocsFjord L2AllocsMode = "fjord" ) var ( diff --git a/op-e2e/config/init.go b/op-e2e/config/init.go index 21034c04a7d4..d53fd0697124 100644 --- a/op-e2e/config/init.go +++ b/op-e2e/config/init.go @@ -113,10 +113,7 @@ func init() { } l2Allocs = make(map[genesis.L2AllocsMode]*genesis.ForgeAllocs) mustL2Allocs := func(mode genesis.L2AllocsMode) { - name := "allocs-l2" - if mode != "" { - name += "-" + string(mode) - } + name := "allocs-l2-" + string(mode) allocs, err := genesis.LoadForgeAllocs(filepath.Join(l2AllocsDir, name+".json")) if err != nil { panic(err) diff --git a/packages/contracts-bedrock/README.md b/packages/contracts-bedrock/README.md index f012c447910d..76f9d4b96f8e 100644 --- a/packages/contracts-bedrock/README.md +++ b/packages/contracts-bedrock/README.md @@ -319,6 +319,18 @@ STATE_DUMP_PATH= \ Create or modify a file `.json` inside of the [`deploy-config`](./deploy-config/) folder. Use the env var `DEPLOY_CONFIG_PATH` to use a particular deploy config file at runtime. +The script will read the latest active fork from the deploy config and the L2 genesis allocs generated will be +compatible with this fork. The automatically detected fork can be overwritten by setting the environment variable +`FORK` either to the lower-case fork name (currently `delta`, `ecotone`, or `fjord`) or to `latest`, which will select +the latest fork available (currently `fjord`). + +By default, the script will dump the L2 genesis allocs of the detected or selected fork only, to the file at `STATE_DUMP_PATH`. +The optional environment variable `OUTPUT_MODE` allows to modify this behavior by setting it to one of the following values: +* `latest` (default) - only dump the selected fork's allocs. +* `all` - also dump all intermediary fork's allocs. This only works if `STATE_DUMP_PATH` is _not_ set. In this case, all allocs + will be written to files `/state-dump-.json`. Another path cannot currently be specified for this use case. +* `none` - won't dump any allocs. Only makes sense for internal test usage. + #### Custom Gas Token The Custom Gas Token feature is a Beta feature of the MIT licensed OP Stack. diff --git a/packages/contracts-bedrock/scripts/Config.sol b/packages/contracts-bedrock/scripts/Config.sol index 1a7692d498ff..0bf567b3dd1c 100644 --- a/packages/contracts-bedrock/scripts/Config.sol +++ b/packages/contracts-bedrock/scripts/Config.sol @@ -3,6 +3,56 @@ pragma solidity ^0.8.0; import { Vm, VmSafe } from "forge-std/Vm.sol"; +/// @notice Enum representing different ways of outputting genesis allocs. +/// @custom:value NONE No output, used in internal tests. +/// @custom:value LATEST Output allocs only for latest fork. +/// @custom:value ALL Output allocs for all intermediary forks. +enum OutputMode { + NONE, + LATEST, + ALL +} + +library OutputModeUtils { + function toString(OutputMode _mode) internal pure returns (string memory) { + if (_mode == OutputMode.NONE) { + return "none"; + } else if (_mode == OutputMode.LATEST) { + return "latest"; + } else if (_mode == OutputMode.ALL) { + return "all"; + } else { + return "unknown"; + } + } +} + +/// @notice Enum of forks available for selection when generating genesis allocs. +enum Fork { + NONE, + DELTA, + ECOTONE, + FJORD +} + +Fork constant LATEST_FORK = Fork.FJORD; + +library ForkUtils { + function toString(Fork _fork) internal pure returns (string memory) { + if (_fork == Fork.NONE) { + return "none"; + } else if (_fork == Fork.DELTA) { + return "delta"; + } else if (_fork == Fork.ECOTONE) { + return "ecotone"; + } else if (_fork == Fork.FJORD) { + return "fjord"; + } else { + return "unknown"; + } + } +} + /// @title Config /// @notice Contains all env var based config. Add any new env var parsing to this file /// to ensure that all config is in a single place. @@ -67,4 +117,44 @@ library Config { function drippieOwnerPrivateKey() internal view returns (uint256 _env) { _env = vm.envUint("DRIPPIE_OWNER_PRIVATE_KEY"); } + + /// @notice Returns the OutputMode for genesis allocs generation. + /// It reads the mode from the environment variable OUTPUT_MODE. + /// If it is unset, OutputMode.ALL is returned. + function outputMode() internal view returns (OutputMode) { + string memory modeStr = vm.envOr("OUTPUT_MODE", string("latest")); + bytes32 modeHash = keccak256(bytes(modeStr)); + if (modeHash == keccak256(bytes("none"))) { + return OutputMode.NONE; + } else if (modeHash == keccak256(bytes("latest"))) { + return OutputMode.LATEST; + } else if (modeHash == keccak256(bytes("all"))) { + return OutputMode.ALL; + } else { + revert(string.concat("Config: unknown output mode: ", modeStr)); + } + } + + /// @notice Returns the latest fork to use for genesis allocs generation. + /// It reads the fork from the environment variable FORK. If it is + /// unset, NONE is returned. + /// If set to the special value "latest", the latest fork is returned. + function fork() internal view returns (Fork) { + string memory forkStr = vm.envOr("FORK", string("")); + if (bytes(forkStr).length == 0) { + return Fork.NONE; + } + bytes32 forkHash = keccak256(bytes(forkStr)); + if (forkHash == keccak256(bytes("latest"))) { + return LATEST_FORK; + } else if (forkHash == keccak256(bytes("delta"))) { + return Fork.DELTA; + } else if (forkHash == keccak256(bytes("ecotone"))) { + return Fork.ECOTONE; + } else if (forkHash == keccak256(bytes("fjord"))) { + return Fork.FJORD; + } else { + revert(string.concat("Config: unknown fork: ", forkStr)); + } + } } diff --git a/packages/contracts-bedrock/scripts/DeployConfig.s.sol b/packages/contracts-bedrock/scripts/DeployConfig.s.sol index 38f58688acaf..25869e97f080 100644 --- a/packages/contracts-bedrock/scripts/DeployConfig.s.sol +++ b/packages/contracts-bedrock/scripts/DeployConfig.s.sol @@ -7,12 +7,19 @@ import { stdJson } from "forge-std/StdJson.sol"; import { Executables } from "scripts/Executables.sol"; import { Process } from "scripts/libraries/Process.sol"; import { Chains } from "scripts/Chains.sol"; +import { Config, Fork, ForkUtils } from "scripts/Config.sol"; /// @title DeployConfig /// @notice Represents the configuration required to deploy the system. It is expected /// to read the file from JSON. A future improvement would be to have fallback /// values if they are not defined in the JSON themselves. contract DeployConfig is Script { + using stdJson for string; + using ForkUtils for Fork; + + /// @notice Represents an unset offset value, as opposed to 0, which denotes no-offset. + uint256 constant NULL_OFFSET = type(uint256).max; + string internal _json; address public finalSystemOwner; @@ -20,6 +27,9 @@ contract DeployConfig is Script { uint256 public l1ChainID; uint256 public l2ChainID; uint256 public l2BlockTime; + uint256 public l2GenesisDeltaTimeOffset; + uint256 public l2GenesisEcotoneTimeOffset; + uint256 public l2GenesisFjordTimeOffset; uint256 public maxSequencerDrift; uint256 public sequencerWindowSize; uint256 public channelTimeout; @@ -94,6 +104,11 @@ contract DeployConfig is Script { l1ChainID = stdJson.readUint(_json, "$.l1ChainID"); l2ChainID = stdJson.readUint(_json, "$.l2ChainID"); l2BlockTime = stdJson.readUint(_json, "$.l2BlockTime"); + + l2GenesisDeltaTimeOffset = _readOr(_json, "$.l2GenesisDeltaTimeOffset", NULL_OFFSET); + l2GenesisEcotoneTimeOffset = _readOr(_json, "$.l2GenesisEcotoneTimeOffset", NULL_OFFSET); + l2GenesisFjordTimeOffset = _readOr(_json, "$.l2GenesisFjordTimeOffset", NULL_OFFSET); + maxSequencerDrift = stdJson.readUint(_json, "$.maxSequencerDrift"); sequencerWindowSize = stdJson.readUint(_json, "$.sequencerWindowSize"); channelTimeout = stdJson.readUint(_json, "$.channelTimeout"); @@ -161,6 +176,18 @@ contract DeployConfig is Script { useInterop = _readOr(_json, "$.useInterop", false); } + function fork() public view returns (Fork fork_) { + // let env var take precedence + fork_ = Config.fork(); + if (fork_ == Fork.NONE) { + // Will revert if no deploy config can be found either. + fork_ = latestGenesisFork(); + console.log("DeployConfig: using deploy config fork: %s", fork_.toString()); + } else { + console.log("DeployConfig: using env var fork: %s", fork_.toString()); + } + } + function l1StartingBlockTag() public returns (bytes32) { try vm.parseJsonBytes32(_json, "$.l1StartingBlockTag") returns (bytes32 tag) { return tag; @@ -215,6 +242,17 @@ contract DeployConfig is Script { customGasTokenAddress = _token; } + function latestGenesisFork() internal view returns (Fork) { + if (l2GenesisFjordTimeOffset == 0) { + return Fork.FJORD; + } else if (l2GenesisEcotoneTimeOffset == 0) { + return Fork.ECOTONE; + } else if (l2GenesisDeltaTimeOffset == 0) { + return Fork.DELTA; + } + revert("DeployConfig: no supported fork active at genesis"); + } + function _getBlockByTag(string memory _tag) internal returns (bytes32) { string[] memory cmd = new string[](3); cmd[0] = Executables.bash; @@ -225,15 +263,20 @@ contract DeployConfig is Script { } function _readOr(string memory json, string memory key, bool defaultValue) internal view returns (bool) { - return vm.keyExists(json, key) ? stdJson.readBool(json, key) : defaultValue; + return vm.keyExistsJson(json, key) ? json.readBool(key) : defaultValue; } function _readOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) { - return vm.keyExists(json, key) ? stdJson.readUint(json, key) : defaultValue; + return (vm.keyExistsJson(json, key) && !_isNull(json, key)) ? json.readUint(key) : defaultValue; } function _readOr(string memory json, string memory key, address defaultValue) internal view returns (address) { - return vm.keyExists(json, key) ? stdJson.readAddress(json, key) : defaultValue; + return vm.keyExistsJson(json, key) ? json.readAddress(key) : defaultValue; + } + + function _isNull(string memory json, string memory key) internal pure returns (bool) { + string memory value = json.readString(key); + return (keccak256(bytes(value)) == keccak256(bytes("null"))); } function _readOr( @@ -245,6 +288,6 @@ contract DeployConfig is Script { view returns (string memory) { - return vm.keyExists(json, key) ? stdJson.readString(json, key) : defaultValue; + return vm.keyExists(json, key) ? json.readString(key) : defaultValue; } } diff --git a/packages/contracts-bedrock/scripts/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index cca52a3c272c..44607c534650 100644 --- a/packages/contracts-bedrock/scripts/L2Genesis.s.sol +++ b/packages/contracts-bedrock/scripts/L2Genesis.s.sol @@ -5,7 +5,7 @@ import { Script } from "forge-std/Script.sol"; import { console2 as console } from "forge-std/console2.sol"; import { Deployer } from "scripts/Deployer.sol"; -import { Config } from "scripts/Config.sol"; +import { Config, OutputMode, OutputModeUtils, Fork, ForkUtils, LATEST_FORK } from "scripts/Config.sol"; import { Artifacts } from "scripts/Artifacts.s.sol"; import { DeployConfig } from "scripts/DeployConfig.s.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; @@ -37,20 +37,6 @@ struct L1Dependencies { address payable l1ERC721BridgeProxy; } -/// @notice Enum representing different ways of outputting genesis allocs. -/// @custom:value DEFAULT_LATEST Represents only latest L2 allocs, written to output path. -/// @custom:value LOCAL_LATEST Represents latest L2 allocs, not output anywhere, but kept in-process. -/// @custom:value LOCAL_ECOTONE Represents Ecotone-upgrade L2 allocs, not output anywhere, but kept in-process. -/// @custom:value LOCAL_DELTA Represents Delta-upgrade L2 allocs, not output anywhere, but kept in-process. -/// @custom:value OUTPUT_ALL Represents creation of one L2 allocs file for every upgrade. -enum OutputMode { - DEFAULT_LATEST, - LOCAL_LATEST, - LOCAL_ECOTONE, - LOCAL_DELTA, - OUTPUT_ALL -} - /// @title L2Genesis /// @notice Generates the genesis state for the L2 network. /// The following safety invariants are used when setting state: @@ -59,6 +45,9 @@ enum OutputMode { /// 2. A contract must be deployed using the `new` syntax if there are immutables in the code. /// Any other side effects from the init code besides setting the immutables must be cleaned up afterwards. contract L2Genesis is Deployer { + using ForkUtils for Fork; + using OutputModeUtils for OutputMode; + uint256 public constant PRECOMPILE_COUNT = 256; uint80 internal constant DEV_ACCOUNT_FUND_AMT = 10_000 ether; @@ -120,7 +109,7 @@ contract L2Genesis is Deployer { /// Sets the precompiles, proxies, and the implementation accounts to be `vm.dumpState` /// to generate a L2 genesis alloc. function runWithStateDump() public { - runWithOptions(OutputMode.DEFAULT_LATEST, artifactDependencies()); + runWithOptions(Config.outputMode(), cfg.fork(), artifactDependencies()); } /// @notice Alias for `runWithStateDump` so that no `--sig` needs to be specified. @@ -130,11 +119,18 @@ contract L2Genesis is Deployer { /// @notice This is used by op-e2e to have a version of the L2 allocs for each upgrade. function runWithAllUpgrades() public { - runWithOptions(OutputMode.OUTPUT_ALL, artifactDependencies()); + runWithOptions(OutputMode.ALL, LATEST_FORK, artifactDependencies()); + } + + /// @notice This is used by foundry tests to enable the latest fork with the + /// given L1 dependencies. + function runWithLatestLocal(L1Dependencies memory _l1Dependencies) public { + runWithOptions(OutputMode.NONE, LATEST_FORK, _l1Dependencies); } /// @notice Build the L2 genesis. - function runWithOptions(OutputMode _mode, L1Dependencies memory _l1Dependencies) public { + function runWithOptions(OutputMode _mode, Fork _fork, L1Dependencies memory _l1Dependencies) public { + console.log("L2Genesis: outputMode: %s, fork: %s", _mode.toString(), _fork.toString()); vm.startPrank(deployer); vm.chainId(cfg.l2ChainID()); @@ -147,28 +143,30 @@ contract L2Genesis is Deployer { } vm.stopPrank(); - // Genesis is "complete" at this point, but some hardfork activation steps remain. - // Depending on the "Output Mode" we perform the activations and output the necessary state dumps. - if (_mode == OutputMode.LOCAL_DELTA) { + if (writeForkGenesisAllocs(_fork, Fork.DELTA, _mode)) { return; } - if (_mode == OutputMode.OUTPUT_ALL) { - writeGenesisAllocs(Config.stateDumpPath("-delta")); - } activateEcotone(); - if (_mode == OutputMode.LOCAL_ECOTONE) { + if (writeForkGenesisAllocs(_fork, Fork.ECOTONE, _mode)) { return; } - if (_mode == OutputMode.OUTPUT_ALL) { - writeGenesisAllocs(Config.stateDumpPath("-ecotone")); - } activateFjord(); - if (_mode == OutputMode.OUTPUT_ALL || _mode == OutputMode.DEFAULT_LATEST) { - writeGenesisAllocs(Config.stateDumpPath("")); + if (writeForkGenesisAllocs(_fork, Fork.FJORD, _mode)) { + return; + } + } + + function writeForkGenesisAllocs(Fork _latest, Fork _current, OutputMode _mode) internal returns (bool isLatest_) { + if (_mode == OutputMode.ALL || _latest == _current && _mode == OutputMode.LATEST) { + string memory suffix = string.concat("-", _current.toString()); + writeGenesisAllocs(Config.stateDumpPath(suffix)); + } + if (_latest == _current) { + isLatest_ = true; } } diff --git a/packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol b/packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol index 3b04804fb0e2..21f7b98f666b 100644 --- a/packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol +++ b/packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol @@ -3,7 +3,7 @@ pragma solidity 0.8.15; // Testing utilities import { CommonTest } from "test/setup/CommonTest.sol"; -import { OutputMode } from "scripts/L2Genesis.s.sol"; +import { Fork } from "scripts/Config.sol"; // Libraries import { Encoding } from "src/libraries/Encoding.sol"; @@ -39,7 +39,7 @@ contract GasPriceOracleBedrock_Test is GasPriceOracle_Test { /// @dev Sets up the test suite. function setUp() public virtual override { // The gasPriceOracle tests rely on an L2 genesis that is not past Ecotone. - l2OutputMode = OutputMode.LOCAL_DELTA; + l2Fork = Fork.DELTA; super.setUp(); assertEq(gasPriceOracle.isEcotone(), false); @@ -120,7 +120,7 @@ contract GasPriceOracleBedrock_Test is GasPriceOracle_Test { contract GasPriceOracleEcotone_Test is GasPriceOracle_Test { /// @dev Sets up the test suite. function setUp() public virtual override { - l2OutputMode = OutputMode.LOCAL_ECOTONE; // activate ecotone + l2Fork = Fork.ECOTONE; super.setUp(); assertEq(gasPriceOracle.isEcotone(), true); @@ -213,7 +213,7 @@ contract GasPriceOracleEcotone_Test is GasPriceOracle_Test { contract GasPriceOracleFjordActive_Test is GasPriceOracle_Test { /// @dev Sets up the test suite. function setUp() public virtual override { - l2OutputMode = OutputMode.LOCAL_LATEST; // activate fjord + l2Fork = Fork.FJORD; super.setUp(); bytes memory calldataPacked = Encoding.encodeSetL1BlockValuesEcotone( diff --git a/packages/contracts-bedrock/test/L2Genesis.t.sol b/packages/contracts-bedrock/test/L2Genesis.t.sol index f01a3818b880..f851f62d634d 100644 --- a/packages/contracts-bedrock/test/L2Genesis.t.sol +++ b/packages/contracts-bedrock/test/L2Genesis.t.sol @@ -2,7 +2,7 @@ pragma solidity 0.8.15; import { Test } from "forge-std/Test.sol"; -import { L2Genesis, OutputMode, L1Dependencies } from "scripts/L2Genesis.s.sol"; +import { L2Genesis, L1Dependencies } from "scripts/L2Genesis.s.sol"; import { Predeploys } from "src/libraries/Predeploys.sol"; import { Constants } from "src/libraries/Constants.sol"; import { Process } from "scripts/libraries/Process.sol"; @@ -181,7 +181,7 @@ contract L2GenesisTest is Test { /// @notice Tests the number of accounts in the genesis setup function _test_allocs_size(string memory _path) internal { genesis.cfg().setFundDevAccounts(false); - genesis.runWithOptions(OutputMode.LOCAL_LATEST, _dummyL1Deps()); + genesis.runWithLatestLocal(_dummyL1Deps()); genesis.writeGenesisAllocs(_path); uint256 expected = 0; diff --git a/packages/contracts-bedrock/test/setup/Setup.sol b/packages/contracts-bedrock/test/setup/Setup.sol index 42b235dc8a77..3193ce80e6e6 100644 --- a/packages/contracts-bedrock/test/setup/Setup.sol +++ b/packages/contracts-bedrock/test/setup/Setup.sol @@ -25,8 +25,10 @@ import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol"; import { DeployConfig } from "scripts/DeployConfig.s.sol"; +import { Fork, LATEST_FORK } from "scripts/Config.sol"; import { Deploy } from "scripts/Deploy.s.sol"; -import { L2Genesis, L1Dependencies, OutputMode } from "scripts/L2Genesis.s.sol"; +import { L2Genesis, L1Dependencies } from "scripts/L2Genesis.s.sol"; +import { OutputMode, Fork, ForkUtils } from "scripts/Config.sol"; import { L2OutputOracle } from "src/L1/L2OutputOracle.sol"; import { ProtocolVersions } from "src/L1/ProtocolVersions.sol"; import { SystemConfig } from "src/L1/SystemConfig.sol"; @@ -46,6 +48,8 @@ import { WETH } from "src/L2/WETH.sol"; /// 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. contract Setup { + using ForkUtils for Fork; + /// @notice The address of the foundry Vm contract. Vm private constant vm = Vm(0x7109709ECfa91a80626fF3989D68f67F5b1DD12D); @@ -57,7 +61,7 @@ contract Setup { L2Genesis(address(uint160(uint256(keccak256(abi.encode("optimism.l2genesis")))))); // @notice Allows users of Setup to override what L2 genesis is being created. - OutputMode l2OutputMode = OutputMode.LOCAL_LATEST; + Fork l2Fork = LATEST_FORK; OptimismPortal optimismPortal; OptimismPortal2 optimismPortal2; @@ -175,9 +179,10 @@ contract Setup { /// @dev Sets up the L2 contracts. Depends on `L1()` being called first. function L2() public { - console.log("Setup: creating L2 genesis, with output mode %d", uint256(l2OutputMode)); + console.log("Setup: creating L2 genesis with fork %s", l2Fork.toString()); l2Genesis.runWithOptions( - l2OutputMode, + OutputMode.NONE, + l2Fork, L1Dependencies({ l1CrossDomainMessengerProxy: payable(address(l1CrossDomainMessenger)), l1StandardBridgeProxy: payable(address(l1StandardBridge)),