Skip to content

Commit

Permalink
Genesis configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
mdehoog committed Sep 29, 2024
1 parent 0fee7f6 commit d4f9828
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 58 deletions.
8 changes: 6 additions & 2 deletions enclave/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ func (p *PerChainConfig) ToRollupConfig() *rollup.Config {
func (p *PerChainConfig) ForceDefaults() {
p.BlockTime = 1
p.Genesis.L2.Number = 0
p.Genesis.SystemConfig.GasLimit = uint64(deployConfig.L2GenesisBlockGasLimit)
p.Genesis.SystemConfig.Overhead = eth.Bytes32{}
p.Genesis.SystemConfig.Scalar = deployConfig.FeeScalar()
}

func (p *PerChainConfig) Hash() (common.Hash, error) {
Expand All @@ -122,6 +120,9 @@ func (p *PerChainConfig) MarshalBinary() (data []byte, err error) {
{Name: "genesisL1Number", Type: uint64Type},
{Name: "genesisL2Hash", Type: bytes32Type},
{Name: "genesisL2Time", Type: uint64Type},
{Name: "genesisBatcherAddress", Type: addressType},
{Name: "genesisScalar", Type: bytes32Type},
{Name: "genesisGasLimit", Type: uint64Type},
{Name: "depositContractAddress", Type: addressType},
{Name: "l1SystemConfigAddress", Type: addressType},
}
Expand All @@ -132,6 +133,9 @@ func (p *PerChainConfig) MarshalBinary() (data []byte, err error) {
p.Genesis.L1.Number,
p.Genesis.L2.Hash,
p.Genesis.L2Time,
p.Genesis.SystemConfig.BatcherAddr,
p.Genesis.SystemConfig.Scalar,
p.Genesis.SystemConfig.GasLimit,
p.DepositContractAddress,
p.L1SystemConfigAddress,
)
Expand Down
2 changes: 1 addition & 1 deletion script/DeploySystem.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ contract DeploySystem is Deploy {
_proxy: payable(l2OutputOracleProxy),
_implementation: l2OutputOracle,
_innerCallData: abi.encodeCall(
OutputOracle.initialize, (0)
OutputOracle.initialize, (0, 0)
)
});

Expand Down
127 changes: 75 additions & 52 deletions src/DeployChain.sol
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,15 @@ import { L1CrossDomainMessenger } from "@eth-optimism-bedrock/src/L1/L1CrossDoma
import { L1ERC721Bridge } from "@eth-optimism-bedrock/src/L1/L1ERC721Bridge.sol";
import { OptimismMintableERC20Factory } from "@eth-optimism-bedrock/src/universal/OptimismMintableERC20Factory.sol";
import { ResourceMetering } from "@eth-optimism-bedrock/src/L1/ResourceMetering.sol";
import { Hashing } from "@eth-optimism-bedrock/src/libraries/Hashing.sol";
import { Types } from "@eth-optimism-bedrock/src/libraries/Types.sol";
import { Constants } from "@eth-optimism-bedrock/src/libraries/Constants.sol";

contract DeployChain {
struct PerChainConfig {
uint256 chainID;
bytes32 genesisL1Hash;
uint64 genesisL1Number;
bytes32 genesisL2Hash;
uint64 genesisL2Time;
address depositContractAddress;
address l1SystemConfigAddress;
}

struct Deploy {
uint64 l1Number;
bytes32 l1Hash;
uint64 l2Time;
address l2OutputOracle;
address systemConfig;
address optimismPortal;
Expand All @@ -35,6 +31,8 @@ contract DeployChain {
address optimismMintableERC20Factory;
}

bytes32 public constant MESSAGE_PASSER_STORAGE_HASH = 0x8ed4baae3a927be3dea54996b4d5899f8c01e7594bf50b17dc1e741388ce3d12;

address public immutable proxyAdmin;
address public immutable portal;
address public immutable systemConfig;
Expand Down Expand Up @@ -67,23 +65,17 @@ contract DeployChain {
superchainConfig = _superchainConfig;
}

function setupProxy(address proxy, bytes32 salt) internal returns (address instance) {
address _proxyAdmin = proxyAdmin;
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x60678060095f395ff363204e1c7a60e01b5f5273000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, proxy))
mstore(add(ptr, 0x28), 0x6004525f5f60245f730000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x31), shl(0x60, _proxyAdmin))
mstore(add(ptr, 0x45), 0x5afa3d5f5f3e3d60201416604d573d5ffd5b5f5f365f5f51365f5f375af43d5f)
mstore(add(ptr, 0x65), 0x5f3e5f3d91606557fd5bf3000000000000000000000000000000000000000000)
instance := create2(0, ptr, 0x70, salt)
}
require(instance != address(0), "Proxy: create2 failed");
}

function deploy(bytes32 salt, uint256 chainID, bytes32 genesisHash) external returns (Deploy memory) {
function deploy(
bytes32 salt,
uint256 chainID,
bytes32 genesisL2Hash,
bytes32 genesisL2StateRoot,
address batcherAddress,
uint32 basefeeScalar,
uint32 blobbasefeeScalar,
uint64 gasLimit,
address unsafeBlockSigner
) external returns (Deploy memory) {
address _outputOracle = setupProxy(outputOracle, salt);
address _systemConfig = setupProxy(systemConfig, salt);
address _portal = setupProxy(portal, salt);
Expand All @@ -92,37 +84,41 @@ contract DeployChain {
address _l1ERC721Bridge = setupProxy(l1ERC721Bridge, salt);
address _optimismMintableERC20Factory = setupProxy(optimismMintableERC20Factory, salt);

PerChainConfig memory config = PerChainConfig({
chainID: chainID,
genesisL1Hash: blockhash(block.number-1),
genesisL1Number: uint64(block.number-1),
genesisL2Hash: genesisHash,
genesisL2Time: uint64(block.timestamp-2),
depositContractAddress: _portal,
l1SystemConfigAddress: _systemConfig
});
bytes32 scalar = bytes32((uint256(0x01) << 248) | (uint256(blobbasefeeScalar) << 32) | basefeeScalar);
uint64 genesisL1Number = uint64(block.number - 1);
bytes32 genesisL1Hash = blockhash(uint256(genesisL1Number));
uint64 genesisL2Time = uint64(block.timestamp - 2);
bytes32 configHash = keccak256(abi.encodePacked(
uint64(0), // version
config.chainID,
config.genesisL1Hash,
config.genesisL1Number,
config.genesisL2Hash,
config.genesisL2Time,
config.depositContractAddress,
config.l1SystemConfigAddress
chainID,
genesisL1Hash,
genesisL1Number,
genesisL2Hash,
genesisL2Time,
batcherAddress,
scalar,
gasLimit,
_portal,
_systemConfig
));

OutputOracle(_outputOracle).initialize(configHash);
bytes32 genesisOutputRoot = Hashing.hashOutputRootProof(Types.OutputRootProof({
version: 0,
stateRoot: genesisL2StateRoot,
messagePasserStorageRoot: MESSAGE_PASSER_STORAGE_HASH,
latestBlockhash: genesisL2Hash
}));

OutputOracle(_outputOracle).initialize(configHash, genesisOutputRoot);

SystemConfigOwnable _configTemplate = SystemConfigOwnable(systemConfig);
SystemConfigOwnable(_systemConfig).initialize({
_basefeeScalar: _configTemplate.basefeeScalar(),
_blobbasefeeScalar: _configTemplate.blobbasefeeScalar(),
_batcherHash: _configTemplate.batcherHash(),
_gasLimit: _configTemplate.gasLimit(),
_unsafeBlockSigner: _configTemplate.unsafeBlockSigner(),
_config: _configTemplate.resourceConfig(),
_batchInbox: _configTemplate.batchInbox(),
_basefeeScalar: basefeeScalar,
_blobbasefeeScalar: blobbasefeeScalar,
_batcherHash: bytes32(uint256(uint160(batcherAddress))),
_gasLimit: gasLimit,
_unsafeBlockSigner: unsafeBlockSigner,
_config: Constants.DEFAULT_RESOURCE_CONFIG(),
_batchInbox: calculateBatchInbox(chainID),
_addresses: SystemConfig.Addresses({
l1CrossDomainMessenger: _l1CrossDomainMessenger,
l1ERC721Bridge: _l1ERC721Bridge,
Expand Down Expand Up @@ -162,6 +158,9 @@ contract DeployChain {
);

return Deploy({
l1Number: genesisL1Number,
l1Hash: genesisL1Hash,
l2Time: genesisL2Time,
l2OutputOracle: _outputOracle,
systemConfig: _systemConfig,
optimismPortal: _portal,
Expand All @@ -171,4 +170,28 @@ contract DeployChain {
optimismMintableERC20Factory: _optimismMintableERC20Factory
});
}

function setupProxy(address proxy, bytes32 salt) internal returns (address instance) {
address _proxyAdmin = proxyAdmin;
/// @solidity memory-safe-assembly
assembly {
let ptr := mload(0x40)
mstore(ptr, 0x60678060095f395ff363204e1c7a60e01b5f5273000000000000000000000000)
mstore(add(ptr, 0x14), shl(0x60, proxy))
mstore(add(ptr, 0x28), 0x6004525f5f60245f730000000000000000000000000000000000000000000000)
mstore(add(ptr, 0x31), shl(0x60, _proxyAdmin))
mstore(add(ptr, 0x45), 0x5afa3d5f5f3e3d60201416604d573d5ffd5b5f5f365f5f51365f5f375af43d5f)
mstore(add(ptr, 0x65), 0x5f3e5f3d91606557fd5bf3000000000000000000000000000000000000000000)
instance := create2(0, ptr, 0x70, salt)
}
require(instance != address(0), "Proxy: create2 failed");
}

function calculateBatchInbox(uint256 chainID) internal returns (address) {
uint256 inbox = 0;
for (; chainID > 0; chainID /= 10) {
inbox = (inbox << 4) | (chainID % 10);
}
return address(uint160(inbox | (0xff << 152)));
}
}
10 changes: 7 additions & 3 deletions src/OutputOracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,17 @@ contract OutputOracle is Initializable, ISemver {
) {
systemConfigGlobal = _systemConfigGlobal;
maxOutputCount = _maxOutputCount;
initialize(0);
initialize(0, 0);
}

/// @notice Initializer.
function initialize(bytes32 _configHash) public initializer {
function initialize(bytes32 _configHash, bytes32 _genesisOutputRoot) public initializer {
configHash = _configHash;
latestOutputIndex = maxOutputCount-1;
l2Outputs.push(Types.OutputProposal({
outputRoot: _genesisOutputRoot,
timestamp: uint128(block.timestamp),
l2BlockNumber: uint128(0)
}));
}

function proposer() public view returns (address) {
Expand Down

0 comments on commit d4f9828

Please sign in to comment.