diff --git a/.circleci/config.yml b/.circleci/config.yml index 3cec20de7aa37..00add8e9a786e 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-fault-proofs/allocs-l1.json" - ".devnet-fault-proofs/addresses.json" - - ".devnet-fault-proofs/allocs-l2.json" - ".devnet-fault-proofs/allocs-l2-delta.json" - ".devnet-fault-proofs/allocs-l2-ecotone.json" + - ".devnet-fault-proofs/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 @@ -1000,9 +1000,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 @@ -1245,9 +1245,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 c9a4ee03606d2..c992b7216f25f 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_FPAC = os.getenv('DEVNET_FPAC') == "true" @@ -173,9 +176,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) @@ -220,7 +223,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_FPAC == True: # Also regenerate if FPAC. # The FPAC 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 a534957243bd7..6cd0bbe7d27f5 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 21034c04a7d46..d53fd06971241 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/scripts/Config.sol b/packages/contracts-bedrock/scripts/Config.sol index 1a7692d498ff6..458fed4fd8fbb 100644 --- a/packages/contracts-bedrock/scripts/Config.sol +++ b/packages/contracts-bedrock/scripts/Config.sol @@ -3,6 +3,26 @@ pragma solidity ^0.8.0; import { Vm, VmSafe } from "forge-std/Vm.sol"; +/// @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 { + NONE, + LATEST, + ALL +} + +enum Fork { + DELTA, + ECOTONE, + FJORD +} + +Fork constant LATEST_FORK = Fork.FJORD; + /// @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 +87,34 @@ library Config { function drippieOwnerPrivateKey() internal view returns (uint256 _env) { _env = vm.envUint("DRIPPIE_OWNER_PRIVATE_KEY"); } + + function outputMode() internal view returns (OutputMode) { + string memory modeStr = vm.envOr("OUTPUT_MODE", string("all")); + 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)); + } + } + + function fork() internal view returns (Fork) { + string memory forkStr = vm.envOr("FORK", string("latest")); + 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/L2Genesis.s.sol b/packages/contracts-bedrock/scripts/L2Genesis.s.sol index f2607b56f5e0d..5986dcf4afbde 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, Fork, 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: @@ -120,7 +106,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(), Config.fork(), artifactDependencies()); } /// @notice Alias for `runWithStateDump` so that no `--sig` needs to be specified. @@ -130,11 +116,15 @@ 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()); + } + + 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 { vm.startPrank(deployer); vm.chainId(cfg.l2ChainID()); @@ -147,28 +137,29 @@ 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) { - return; - } - if (_mode == OutputMode.OUTPUT_ALL) { + if (_mode == OutputMode.ALL || _fork == Fork.DELTA && _mode == OutputMode.LATEST) { writeGenesisAllocs(Config.stateDumpPath("-delta")); } + if (_fork == Fork.DELTA) { + return; + } activateEcotone(); - if (_mode == OutputMode.LOCAL_ECOTONE) { - return; - } - if (_mode == OutputMode.OUTPUT_ALL) { + if (_mode == OutputMode.ALL || _fork == Fork.ECOTONE && _mode == OutputMode.LATEST) { writeGenesisAllocs(Config.stateDumpPath("-ecotone")); } + if (_fork == Fork.ECOTONE) { + return; + } activateFjord(); - if (_mode == OutputMode.OUTPUT_ALL || _mode == OutputMode.DEFAULT_LATEST) { - writeGenesisAllocs(Config.stateDumpPath("")); + if (_mode == OutputMode.ALL || _fork == Fork.FJORD && _mode == OutputMode.LATEST) { + writeGenesisAllocs(Config.stateDumpPath("-fjord")); + } + if (_fork == Fork.FJORD) { + return; } } diff --git a/packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol b/packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol index 3b04804fb0e22..21f7b98f666bf 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 eb1e603c9f167..9dfef5e613dda 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 9844e6ddd7ccd..f9fc5eb7842aa 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 } 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"; @@ -57,7 +59,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 +177,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 %d", uint256(l2Fork)); l2Genesis.runWithOptions( - l2OutputMode, + OutputMode.NONE, + l2Fork, L1Dependencies({ l1CrossDomainMessengerProxy: payable(address(l1CrossDomainMessenger)), l1StandardBridgeProxy: payable(address(l1StandardBridge)),