Skip to content

Commit 543e2cf

Browse files
committed
contracts: Read latest fork from deploy config in L2 genesis script
1 parent c828635 commit 543e2cf

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

packages/contracts-bedrock/scripts/Config.sol

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ enum OutputMode {
1515

1616
/// @notice Enum of forks available for selection when generating genesis allocs.
1717
enum Fork {
18+
NONE,
1819
DELTA,
1920
ECOTONE,
2021
FJORD
2122
}
2223

23-
/// @notice Always points to the latest fork.
2424
Fork constant LATEST_FORK = Fork.FJORD;
2525

2626
/// @title Config
@@ -89,6 +89,8 @@ library Config {
8989
}
9090

9191
/// @notice Returns the OutputMode for genesis allocs generation.
92+
/// It reads the mode from the environment variable OUTPUT_MODE.
93+
/// If it is unset, OutputMode.ALL is returned.
9294
function outputMode() internal view returns (OutputMode) {
9395
string memory modeStr = vm.envOr("OUTPUT_MODE", string("all"));
9496
bytes32 modeHash = keccak256(bytes(modeStr));
@@ -104,8 +106,14 @@ library Config {
104106
}
105107

106108
/// @notice Returns the latest fork to use for genesis allocs generation.
109+
/// It reads the fork from the environment variable FORK. If it is
110+
/// unset, NONE is returned.
111+
/// If set to the special value "latest", the latest fork is returned.
107112
function fork() internal view returns (Fork) {
108-
string memory forkStr = vm.envOr("FORK", string("latest"));
113+
string memory forkStr = vm.envOr("FORK", string(""));
114+
if (bytes(forkStr).length == 0) {
115+
return Fork.NONE;
116+
}
109117
bytes32 forkHash = keccak256(bytes(forkStr));
110118
if (forkHash == keccak256(bytes("latest"))) {
111119
return LATEST_FORK;

packages/contracts-bedrock/scripts/DeployConfig.s.sol

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,28 @@ import { stdJson } from "forge-std/StdJson.sol";
77
import { Executables } from "scripts/Executables.sol";
88
import { Process } from "scripts/libraries/Process.sol";
99
import { Chains } from "scripts/Chains.sol";
10+
import { Fork } from "scripts/Config.sol";
1011

1112
/// @title DeployConfig
1213
/// @notice Represents the configuration required to deploy the system. It is expected
1314
/// to read the file from JSON. A future improvement would be to have fallback
1415
/// values if they are not defined in the JSON themselves.
1516
contract DeployConfig is Script {
17+
using stdJson for string;
18+
19+
/// @notice Represents an unset offset value, as opposed to 0, which denotes no-offset.
20+
uint256 constant NULL_OFFSET = type(uint256).max;
21+
1622
string internal _json;
1723

1824
address public finalSystemOwner;
1925
address public superchainConfigGuardian;
2026
uint256 public l1ChainID;
2127
uint256 public l2ChainID;
2228
uint256 public l2BlockTime;
29+
uint256 public l2GenesisDeltaTimeOffset;
30+
uint256 public l2GenesisEcotoneTimeOffset;
31+
uint256 public l2GenesisFjordTimeOffset;
2332
uint256 public maxSequencerDrift;
2433
uint256 public sequencerWindowSize;
2534
uint256 public channelTimeout;
@@ -94,6 +103,11 @@ contract DeployConfig is Script {
94103
l1ChainID = stdJson.readUint(_json, "$.l1ChainID");
95104
l2ChainID = stdJson.readUint(_json, "$.l2ChainID");
96105
l2BlockTime = stdJson.readUint(_json, "$.l2BlockTime");
106+
107+
l2GenesisDeltaTimeOffset = _readOr(_json, "$.l2GenesisDeltaTimeOffset", NULL_OFFSET);
108+
l2GenesisEcotoneTimeOffset = _readOr(_json, "$.l2GenesisEcotoneTimeOffset", NULL_OFFSET);
109+
l2GenesisFjordTimeOffset = _readOr(_json, "$.l2GenesisFjordTimeOffset", NULL_OFFSET);
110+
97111
maxSequencerDrift = stdJson.readUint(_json, "$.maxSequencerDrift");
98112
sequencerWindowSize = stdJson.readUint(_json, "$.sequencerWindowSize");
99113
channelTimeout = stdJson.readUint(_json, "$.channelTimeout");
@@ -161,6 +175,17 @@ contract DeployConfig is Script {
161175
useInterop = _readOr(_json, "$.useInterop", false);
162176
}
163177

178+
function latestGenesisFork() public view returns (Fork) {
179+
if (l2GenesisFjordTimeOffset == 0) {
180+
return Fork.FJORD;
181+
} else if (l2GenesisEcotoneTimeOffset == 0) {
182+
return Fork.ECOTONE;
183+
} else if (l2GenesisDeltaTimeOffset == 0) {
184+
return Fork.DELTA;
185+
}
186+
revert("DeployConfig: no supported fork active at genesis");
187+
}
188+
164189
function l1StartingBlockTag() public returns (bytes32) {
165190
try vm.parseJsonBytes32(_json, "$.l1StartingBlockTag") returns (bytes32 tag) {
166191
return tag;
@@ -225,15 +250,20 @@ contract DeployConfig is Script {
225250
}
226251

227252
function _readOr(string memory json, string memory key, bool defaultValue) internal view returns (bool) {
228-
return vm.keyExists(json, key) ? stdJson.readBool(json, key) : defaultValue;
253+
return vm.keyExistsJson(json, key) ? json.readBool(key) : defaultValue;
229254
}
230255

231256
function _readOr(string memory json, string memory key, uint256 defaultValue) internal view returns (uint256) {
232-
return vm.keyExists(json, key) ? stdJson.readUint(json, key) : defaultValue;
257+
return (vm.keyExistsJson(json, key) && !_isNull(json, key)) ? json.readUint(key) : defaultValue;
233258
}
234259

235260
function _readOr(string memory json, string memory key, address defaultValue) internal view returns (address) {
236-
return vm.keyExists(json, key) ? stdJson.readAddress(json, key) : defaultValue;
261+
return vm.keyExistsJson(json, key) ? json.readAddress(key) : defaultValue;
262+
}
263+
264+
function _isNull(string memory json, string memory key) internal pure returns (bool) {
265+
string memory value = json.readString(key);
266+
return (keccak256(bytes(value)) == keccak256(bytes("null")));
237267
}
238268

239269
function _readOr(
@@ -245,6 +275,6 @@ contract DeployConfig is Script {
245275
view
246276
returns (string memory)
247277
{
248-
return vm.keyExists(json, key) ? stdJson.readString(json, key) : defaultValue;
278+
return vm.keyExists(json, key) ? json.readString(key) : defaultValue;
249279
}
250280
}

packages/contracts-bedrock/scripts/L2Genesis.s.sol

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,22 @@ contract L2Genesis is Deployer {
106106
/// Sets the precompiles, proxies, and the implementation accounts to be `vm.dumpState`
107107
/// to generate a L2 genesis alloc.
108108
function runWithStateDump() public {
109-
runWithOptions(Config.outputMode(), Config.fork(), artifactDependencies());
109+
Fork fork = Config.fork();
110+
if (fork == Fork.NONE) {
111+
// Will revert if no deploy config can be found either.
112+
fork = latestDeployConfigGenesisFork();
113+
console.log("L2Genesis: using deploy config fork: %d", uint256(fork));
114+
} else {
115+
console.log("L2Genesis: using env var fork: %d", uint256(fork));
116+
}
117+
runWithOptions(Config.outputMode(), fork, artifactDependencies());
118+
}
119+
120+
function latestDeployConfigGenesisFork() internal returns (Fork) {
121+
DeployConfig cfg =
122+
DeployConfig(address(uint160(uint256(keccak256(abi.encode("optimism.deployconfig"))))));
123+
cfg.read(Config.deployConfigPath());
124+
return cfg.latestGenesisFork();
110125
}
111126

112127
/// @notice Alias for `runWithStateDump` so that no `--sig` needs to be specified.
@@ -127,6 +142,7 @@ contract L2Genesis is Deployer {
127142

128143
/// @notice Build the L2 genesis.
129144
function runWithOptions(OutputMode _mode, Fork _fork, L1Dependencies memory _l1Dependencies) public {
145+
console.log("L2Genesis: outputMode: %d, fork: %d", uint256(_mode), uint256(_fork));
130146
vm.startPrank(deployer);
131147
vm.chainId(cfg.l2ChainID());
132148

0 commit comments

Comments
 (0)