Commit 9e976947 authored by Joshua Gutow's avatar Joshua Gutow Committed by GitHub

ops: Use starting L1 Block for timestamp everywhere (#3085)

* ops: Use starting L1 Block for timestamp everywhere

This transitions the starting timestamp to a new flow. The L2 rollup
is anchored on a L1 block. The L2 genesis block & rollup config use
the timestamp of the L1 start block as the their time. Properly
threading this through the HH tasks is a little tricky but possible.
This is because we have two flows: creating a L1 network & placing
the rollup on that and creating a rollup on an existing L1 network
(like goerli). There is still a L1 starting time for the first flow.

This also fixes a circular dependcy that previously existed. The
starting timestamp was provided and served as the starting timestamp
for the L1 genesis & the "L2 Starting Time" in the L2 Output Oracle.
The actual L2 genesis & rollup start time were based on when the
Optimism Portal contract was deployed (after the L2 Output Oracle
contract must have been deployed). The rollup is resilient to being
started before contracts are fully deployed, so using a specific
L1 block as the start is the cleanest solution I have seen.

* Fix lint

* Update packages/contracts-bedrock/deploy-config/goerli.ts

* Add undefined checks to l1StartingBlockTag

* lint

* fix checks
Co-authored-by: default avatarMatthew Slipper <me@matthewslipper.com>
Co-authored-by: default avatarmergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
parent 966e1b19
......@@ -58,9 +58,9 @@ function wait_up {
mkdir -p ./.devnet
if [ ! -f ./.devnet/rollup.json ]; then
GENESIS_TIMESTAMP=$(date +%s | xargs printf "0x%x")
L1_GENESIS_TIMESTAMP=$(date +%s | xargs printf "0x%x")
else
GENESIS_TIMESTAMP=$(jq '.timestamp' < .devnet/genesis-l1.json)
L1_GENESIS_TIMESTAMP=$(jq '.timestamp' < .devnet/genesis-l1.json)
fi
# Regenerate the L1 genesis file if necessary. The existence of the genesis
......@@ -69,7 +69,7 @@ if [ ! -f ./.devnet/genesis-l1.json ]; then
echo "Regenerating L1 genesis."
(
cd $CONTRACTS_BEDROCK
L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP npx hardhat genesis-l1 \
L1_GENESIS_TIMESTAMP=$L1_GENESIS_TIMESTAMP npx hardhat genesis-l1 \
--outfile genesis-l1.json
mv genesis-l1.json ../../.devnet/genesis-l1.json
)
......@@ -89,7 +89,7 @@ if [ ! -d $CONTRACTS_BEDROCK/deployments/$NETWORK ]; then
(
echo "Deploying contracts."
cd $CONTRACTS_BEDROCK
L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP yarn hardhat --network $NETWORK deploy
L1_GENESIS_TIMESTAMP=$L1_GENESIS_TIMESTAMP yarn hardhat --network $NETWORK deploy
)
else
echo "Contracts already deployed, skipping."
......@@ -99,7 +99,7 @@ if [ ! -f ./.devnet/genesis-l2.json ]; then
(
echo "Creating L2 genesis file."
cd $CONTRACTS_BEDROCK
L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP npx hardhat --network $NETWORK genesis-l2
L1_GENESIS_TIMESTAMP=$L1_GENESIS_TIMESTAMP npx hardhat --network $NETWORK genesis-l2
mv genesis.json ../../.devnet/genesis-l2.json
echo "Created L2 genesis."
)
......@@ -120,7 +120,7 @@ if [ ! -f ./.devnet/rollup.json ]; then
(
echo "Building rollup config..."
cd $CONTRACTS_BEDROCK
L2OO_STARTING_BLOCK_TIMESTAMP=$GENESIS_TIMESTAMP npx hardhat --network $NETWORK rollup-config
L1_GENESIS_TIMESTAMP=$L1_GENESIS_TIMESTAMP npx hardhat --network $NETWORK rollup-config
mv rollup.json ../../.devnet/rollup.json
)
else
......
......@@ -2,19 +2,20 @@ import { ethers } from 'ethers'
const { env } = process
const startingTimestamp =
typeof env.L2OO_STARTING_BLOCK_TIMESTAMP === 'string'
? ethers.BigNumber.from(env.L2OO_STARTING_BLOCK_TIMESTAMP).toNumber()
const l1GenesisTimestamp =
typeof env.L1_GENESIS_TIMESTAMP === 'string'
? ethers.BigNumber.from(env.L1_GENESIS_TIMESTAMP).toNumber()
: Math.floor(Date.now() / 1000)
const config = {
submissionInterval: 6,
genesisOutput: ethers.constants.HashZero,
historicalBlocks: 0,
l1StartingBlockTag: 'earliest',
startingBlockNumber: 0,
l2BlockTime: 2,
startingTimestamp,
l1GenesisTimestamp,
sequencerAddress: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
l2CrossDomainMessengerOwner: ethers.constants.AddressZero,
......
import { ethers } from 'ethers'
const sequencerAddress = '0x6c23a0dcdfc44b7a57bed148de598895e398d984'
const startingTimestamp = 1658777882
const l1StartingBlockTag =
'0xafce66a0a2446856112e4069b275ad32b1f4a607888f9c4c59eddf9be81f8670'
const config = {
submissionInterval: 6,
......@@ -9,7 +10,7 @@ const config = {
historicalBlocks: 0,
startingBlockNumber: 0,
l2BlockTime: 2,
startingTimestamp,
l1StartingBlockTag,
sequencerAddress,
l2CrossDomainMessengerOwner: ethers.constants.AddressZero,
......
......@@ -2,9 +2,9 @@ import { ethers } from 'ethers'
const { env } = process
const startingTimestamp =
typeof env.L2OO_STARTING_BLOCK_TIMESTAMP === 'string'
? ethers.BigNumber.from(env.L2OO_STARTING_BLOCK_TIMESTAMP).toNumber()
const l1GenesisTimestamp =
typeof env.L1_GENESIS_TIMESTAMP === 'string'
? ethers.BigNumber.from(env.L1_GENESIS_TIMESTAMP).toNumber()
: Math.floor(Date.now() / 1000)
const config = {
......@@ -12,8 +12,9 @@ const config = {
genesisOutput: ethers.constants.HashZero,
historicalBlocks: 0,
startingBlockNumber: 0,
l1StartingBlockTag: 'earliest',
l2BlockTime: 2,
startingTimestamp,
l1GenesisTimestamp,
sequencerAddress: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8',
maxSequencerDrift: 10,
sequencerWindowSize: 4,
......
......@@ -10,13 +10,10 @@ const deployFn: DeployFunction = async (hre) => {
const { deployer } = await hre.getNamedAccounts()
const { deployConfig } = hre
if (
typeof deployConfig.startingTimestamp !== 'number' ||
isNaN(deployConfig.startingTimestamp)
) {
throw new Error(
'Cannot deploy L2OutputOracle without specifying a valid startingTimestamp.'
)
const l1 = hre.ethers.getDefaultProvider()
const l1StartingBlock = await l1.getBlock(deployConfig.l1StartingBlockTag)
if (l1StartingBlock === null) {
throw new Error(`Cannot fetch block tag ${deployConfig.l1StartingBlockTag}`)
}
await deploy('L2OutputOracleProxy', {
......@@ -34,7 +31,7 @@ const deployFn: DeployFunction = async (hre) => {
deployConfig.genesisOutput,
deployConfig.historicalBlocks,
deployConfig.startingBlockNumber,
deployConfig.startingTimestamp,
l1StartingBlock.timestamp,
deployConfig.l2BlockTime,
deployConfig.sequencerAddress,
deployConfig.outputOracleOwner,
......@@ -84,7 +81,7 @@ const deployFn: DeployFunction = async (hre) => {
}
const startingTimestamp = await L2OutputOracle.STARTING_TIMESTAMP()
if (!startingTimestamp.eq(BigNumber.from(deployConfig.startingTimestamp))) {
if (!startingTimestamp.eq(BigNumber.from(l1StartingBlock.timestamp))) {
throw new Error('starting timestamp misconfigured')
}
const l2BlockTime = await L2OutputOracle.L2_BLOCK_TIME()
......
......@@ -74,18 +74,15 @@ const config: HardhatUserConfig = {
historicalBlocks: {
type: 'number',
},
startingBlockNumber: {
type: 'number',
},
startingTimestamp: {
type: 'number',
},
sequencerAddress: {
type: 'address',
},
outputOracleOwner: {
type: 'address',
},
l1StartingBlockTag: {
type: 'string',
},
},
external: {
contracts: [
......
......@@ -61,7 +61,7 @@ task('genesis-l1', 'create a genesis config')
}
}
const timestamp = hre.deployConfig.startingTimestamp
const timestamp = hre.deployConfig.l1GenesisTimestamp
if (timestamp === undefined) {
throw new Error('Must configure starting block timestamp')
}
......
......@@ -462,8 +462,12 @@ task('genesis-l2', 'create a genesis config')
}
}
const portal = await hre.deployments.get('OptimismPortalProxy')
const l1StartingBlock = await l1.getBlock(portal.receipt.blockHash)
const l1StartingBlock = await l1.getBlock(deployConfig.l1StartingBlockTag)
if (l1StartingBlock === null) {
throw new Error(
`Cannot fetch block tag ${deployConfig.l1StartingBlockTag}`
)
}
if (l1StartingBlock === null) {
console.log(`Unable to fetch L1 starting timestamp`)
......
......@@ -23,13 +23,18 @@ task('rollup-config', 'create a genesis config')
const l2Genesis = await l2.getBlock('earliest')
const portal = await hre.deployments.get('OptimismPortalProxy')
const l1StartingBlock = await l1.getBlock(portal.receipt.blockHash)
const l1StartingBlock = await l1.getBlock(deployConfig.l1StartingBlockTag)
if (l1StartingBlock === null) {
throw new Error(
`Cannot fetch block tag ${deployConfig.l1StartingBlockTag}`
)
}
const config: OpNodeConfig = {
genesis: {
l1: {
hash: portal.receipt.blockHash,
number: portal.receipt.blockNumber,
hash: l1StartingBlock.hash,
number: l1StartingBlock.number,
},
l2: {
hash: l2Genesis.hash,
......
......@@ -4,7 +4,5 @@
"rootDir": "./src",
"outDir": "./dist"
},
"include": [
"src/**/*"
]
"include": ["src/**/*"]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment