Skip to content

Commit

Permalink
contracts: Make L2 genesis script configurable
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastianst committed Jun 6, 2024
1 parent b40933e commit 9f3f68a
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 55 deletions.
12 changes: 6 additions & 6 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1000,9 +1000,9 @@ jobs:
name: Load devnet-allocs
command: |
mkdir -p .devnet
cp /tmp/workspace/.devnet<<parameters.fpac>>/allocs-l2.json .devnet/allocs-l2.json
cp /tmp/workspace/.devnet<<parameters.fpac>>/allocs-l2-delta.json .devnet/allocs-l2-delta.json
cp /tmp/workspace/.devnet<<parameters.fpac>>/allocs-l2-ecotone.json .devnet/allocs-l2-ecotone.json
cp /tmp/workspace/.devnet<<parameters.fpac>>/allocs-l2-fjord.json .devnet/allocs-l2-fjord.json
cp /tmp/workspace/.devnet<<parameters.fpac>>/allocs-l1.json .devnet/allocs-l1.json
cp /tmp/workspace/.devnet<<parameters.fpac>>/addresses.json .devnet/addresses.json
cp /tmp/workspace/packages/contracts-bedrock/deploy-config/devnetL1.json packages/contracts-bedrock/deploy-config/devnetL1.json
Expand Down Expand Up @@ -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"
Expand Down
11 changes: 7 additions & 4 deletions bedrock-devnet/devnet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion op-chain-ops/genesis/layer_two.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 (
Expand Down
5 changes: 1 addition & 4 deletions op-e2e/config/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
50 changes: 50 additions & 0 deletions packages/contracts-bedrock/scripts/Config.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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));
}
}
}
51 changes: 21 additions & 30 deletions packages/contracts-bedrock/scripts/L2Genesis.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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.
Expand All @@ -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());

Expand All @@ -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;
}
}

Expand Down
8 changes: 4 additions & 4 deletions packages/contracts-bedrock/test/L2/GasPriceOracle.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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(
Expand Down
4 changes: 2 additions & 2 deletions packages/contracts-bedrock/test/L2Genesis.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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;
Expand Down
11 changes: 7 additions & 4 deletions packages/contracts-bedrock/test/setup/Setup.sol
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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)),
Expand Down

0 comments on commit 9f3f68a

Please sign in to comment.