Commit 164fe8af authored by Kelvin Fichter's avatar Kelvin Fichter

feat(ctb): move L2OO genesis setup to init

Moves genesis output, timestamp, and block number setup to the
initializer. This is necessary because we will not have this information
at deploy time for the migration deployment.
parent d94ca27c
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -103,6 +103,8 @@ func BuildL1DeveloperGenesis(config *DeployConfig) (*core.Genesis, error) {
data, err = l2ooABI.Pack(
"initialize",
config.L2OutputOracleGenesisL2Output,
big.NewInt(0),
uint642Big(uint64(config.L1GenesisBlockTimestamp)),
config.L2OutputOracleProposer,
config.L2OutputOracleOwner,
)
......@@ -275,10 +277,10 @@ func deployL1Contracts(config *DeployConfig, backend *backends.SimulatedBackend)
Name: "L2OutputOracle",
Args: []interface{}{
uint642Big(config.L2OutputOracleSubmissionInterval),
uint642Big(config.L2BlockTime),
[32]byte(config.L2OutputOracleGenesisL2Output),
big.NewInt(0),
uint642Big(uint64(config.L1GenesisBlockTimestamp)),
uint642Big(config.L2BlockTime),
config.L2OutputOracleProposer,
config.L2OutputOracleOwner,
},
......@@ -337,8 +339,8 @@ func l1Deployer(backend *backends.SimulatedBackend, opts *bind.TransactOpts, dep
opts,
backend,
deployment.Args[0].(*big.Int),
deployment.Args[1].([32]byte),
deployment.Args[2].(*big.Int),
deployment.Args[1].(*big.Int),
deployment.Args[2].([32]byte),
deployment.Args[3].(*big.Int),
deployment.Args[4].(*big.Int),
deployment.Args[5].(common.Address),
......
......@@ -55,7 +55,7 @@ func TestBuildL1DeveloperGenesis(t *testing.T) {
require.NoError(t, err)
require.EqualValues(t, config.L2OutputOracleSubmissionInterval, interval.Uint64())
startBlock, err := oracle.STARTINGBLOCKNUMBER(callOpts)
startBlock, err := oracle.StartingBlockNumber(callOpts)
require.NoError(t, err)
require.EqualValues(t, 0, startBlock.Uint64())
......
......@@ -5,7 +5,7 @@ GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 1122
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 348176)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 112253)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 40502)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 68620)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 72807)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 74956)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 35693)
CrossDomainMessenger_Test:testFuzz_baseGas(uint32) (runs: 256, μ: 20196, ~: 20196)
......@@ -85,30 +85,30 @@ L2CrossDomainMessenger_Test:test_L2MessengerSendMessage() (gas: 122423)
L2CrossDomainMessenger_Test:test_L2MessengerTwiceSendMessage() (gas: 134632)
L2CrossDomainMessenger_Test:test_L2MessengerXDomainSenderReverts() (gas: 10568)
L2CrossDomainMessenger_Test:test_L2MessengerxDomainMessageSenderResets() (gas: 52615)
L2OutputOracleTest:testCannot_ProposeWithUnmatchedBlockhash() (gas: 26776)
L2OutputOracleTest:testCannot_constructWithBadTimestamp() (gas: 50351)
L2OutputOracleTest:testCannot_deleteL2Outputs_afterLatest() (gas: 194584)
L2OutputOracleTest:testCannot_deleteL2Outputs_ifNotOwner() (gas: 18871)
L2OutputOracleTest:testCannot_deleteL2Outputs_nonExistent() (gas: 86711)
L2OutputOracleTest:testCannot_proposeEmptyOutput() (gas: 24085)
L2OutputOracleTest:testCannot_proposeFutureTimetamp() (gas: 26043)
L2OutputOracleTest:testCannot_proposeL2OutputIfNotProposer() (gas: 23515)
L2OutputOracleTest:testCannot_proposeOnWrongFork() (gas: 26371)
L2OutputOracleTest:testCannot_proposeUnexpectedBlockNumber() (gas: 25955)
L2OutputOracleTest:test_changeProposer() (gas: 47212)
L2OutputOracleTest:test_computeL2Timestamp() (gas: 30430)
L2OutputOracleTest:test_constructor() (gas: 45691)
L2OutputOracleTest:test_deleteOutputs_multipleOutputs() (gas: 203841)
L2OutputOracleTest:test_deleteOutputs_singleOutput() (gas: 94524)
L2OutputOracleTest:test_getL2Output() (gas: 84525)
L2OutputOracleTest:test_latestBlockNumber() (gas: 76229)
L2OutputOracleTest:test_nextBlockNumber() (gas: 15120)
L2OutputOracleTest:test_proposeWithBlockhashAndHeight() (gas: 75035)
L2OutputOracleTest:test_proposingAnotherOutput() (gas: 76837)
L2OutputOracleTest:test_updateOwner() (gas: 36063)
L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 17381)
L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 22376)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 38217)
L2OutputOracleTest:testCannot_ProposeWithUnmatchedBlockhash() (gas: 31173)
L2OutputOracleTest:testCannot_constructWithBadTimestamp() (gas: 73077)
L2OutputOracleTest:testCannot_deleteL2Outputs_afterLatest() (gas: 199643)
L2OutputOracleTest:testCannot_deleteL2Outputs_ifNotOwner() (gas: 18827)
L2OutputOracleTest:testCannot_deleteL2Outputs_nonExistent() (gas: 91042)
L2OutputOracleTest:testCannot_proposeEmptyOutput() (gas: 28482)
L2OutputOracleTest:testCannot_proposeFutureTimetamp() (gas: 30440)
L2OutputOracleTest:testCannot_proposeL2OutputIfNotProposer() (gas: 27703)
L2OutputOracleTest:testCannot_proposeOnWrongFork() (gas: 30768)
L2OutputOracleTest:testCannot_proposeUnexpectedBlockNumber() (gas: 30143)
L2OutputOracleTest:test_changeProposer() (gas: 47124)
L2OutputOracleTest:test_computeL2Timestamp() (gas: 37255)
L2OutputOracleTest:test_constructor() (gas: 50016)
L2OutputOracleTest:test_deleteOutputs_multipleOutputs() (gas: 209200)
L2OutputOracleTest:test_deleteOutputs_singleOutput() (gas: 99133)
L2OutputOracleTest:test_getL2Output() (gas: 89416)
L2OutputOracleTest:test_latestBlockNumber() (gas: 80604)
L2OutputOracleTest:test_nextBlockNumber() (gas: 15121)
L2OutputOracleTest:test_proposeWithBlockhashAndHeight() (gas: 79432)
L2OutputOracleTest:test_proposingAnotherOutput() (gas: 81212)
L2OutputOracleTest:test_updateOwner() (gas: 36019)
L2OutputOracleUpgradeable_Test:test_cannotInitImpl() (gas: 21727)
L2OutputOracleUpgradeable_Test:test_cannotInitProxy() (gas: 26731)
L2OutputOracleUpgradeable_Test:test_initValuesOnProxy() (gas: 42544)
L2OutputOracleUpgradeable_Test:test_upgrading() (gas: 180457)
L2StandardBridge_Test:test_cannotWithdrawEthWithoutSendingIt() (gas: 21749)
L2StandardBridge_Test:test_finalizeBridgeETH_incorrectValueReverts() (gas: 23733)
......@@ -150,23 +150,23 @@ OptimismPortalUpgradeable_Test:test_initialize_cannotInitImpl_reverts() (gas: 10
OptimismPortalUpgradeable_Test:test_initialize_cannotInitProxy_reverts() (gas: 15767)
OptimismPortalUpgradeable_Test:test_params_initValuesOnProxy_success() (gas: 16010)
OptimismPortalUpgradeable_Test:test_upgradeToAndCall_upgrading_success() (gas: 180435)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 195163)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 197363)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputRootChanges_reverts() (gas: 199477)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifOutputTimestampIsNotFinalized_reverts() (gas: 201677)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalNotProven_reverts() (gas: 39634)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 192839)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 193168)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 173211)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 233445)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 235161)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_success() (gas: 227144)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 329759)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 193617)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 83389)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_ifWithdrawalProofNotOldEnough_reverts() (gas: 197153)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onInsufficientGas_reverts() (gas: 195340)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onRecentWithdrawal_reverts() (gas: 175375)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReentrancy_reverts() (gas: 235617)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_onReplay_reverts() (gas: 239939)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_provenWithdrawalHash_success() (gas: 231608)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_targetFails_fails() (gas: 334223)
OptimismPortal_FinalizeWithdrawal_Test:test_finalizeWithdrawalTransaction_timestampLessThanL2OracleStart_reverts() (gas: 195767)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onInvalidOutputRootProof_reverts() (gas: 85539)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_onSelfCall_reverts() (gas: 50754)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_oninvalidWithdrawalProof_reverts() (gas: 136647)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_success() (gas: 276836)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 188898)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_success() (gas: 179214)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_oninvalidWithdrawalProof_reverts() (gas: 138797)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProveChangedOutputRoot_success() (gas: 279136)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_replayProve_reverts() (gas: 191198)
OptimismPortal_FinalizeWithdrawal_Test:test_proveWithdrawalTransaction_validWithdrawalProof_success() (gas: 181364)
OptimismPortal_Test:test_OptimismPortalConstructor() (gas: 17298)
OptimismPortal_Test:test_OptimismPortalReceiveEth_success() (gas: 127483)
OptimismPortal_Test:test_depositTransaction_NoValueContract_success() (gas: 76706)
......@@ -178,7 +178,7 @@ OptimismPortal_Test:test_depositTransaction_withEthValueAndContractContractCreat
OptimismPortal_Test:test_depositTransaction_withEthValueAndEOAContractCreation_success() (gas: 75852)
OptimismPortal_Test:test_depositTransaction_withEthValueFromContract_success() (gas: 83370)
OptimismPortal_Test:test_depositTransaction_withEthValueFromEOA_success() (gas: 83964)
OptimismPortal_Test:test_isBlockFinalized_success() (gas: 104802)
OptimismPortal_Test:test_isBlockFinalized_success() (gas: 109865)
OptimismPortal_Test:test_simple_isBlockFinalized_success() (gas: 24142)
Proxy_Test:test_clashingFunctionSignatures() (gas: 101347)
Proxy_Test:test_implementationKey() (gas: 20887)
......
......@@ -64,25 +64,29 @@
➡ contracts/L1/L2OutputOracle.sol:L2OutputOracle
=======================
+-------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------+
| Name | Type | Slot | Offset | Bytes | Contract |
+==============================================================================================================================================+
| _initialized | uint8 | 0 | 0 | 1 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|-------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| _initializing | bool | 0 | 1 | 1 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|-------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| __gap | uint256[50] | 1 | 0 | 1600 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|-------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| _owner | address | 51 | 0 | 20 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|-------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| __gap | uint256[49] | 52 | 0 | 1568 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|-------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| proposer | address | 101 | 0 | 20 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|-------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| latestBlockNumber | uint256 | 102 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|-------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| l2Outputs | mapping(uint256 => struct Types.OutputProposal) | 103 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
+-------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------+
+---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------+
| Name | Type | Slot | Offset | Bytes | Contract |
+================================================================================================================================================+
| _initialized | uint8 | 0 | 0 | 1 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| _initializing | bool | 0 | 1 | 1 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| __gap | uint256[50] | 1 | 0 | 1600 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| _owner | address | 51 | 0 | 20 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| __gap | uint256[49] | 52 | 0 | 1568 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| startingBlockNumber | uint256 | 101 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| startingTimestamp | uint256 | 102 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| proposer | address | 103 | 0 | 20 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| latestBlockNumber | uint256 | 104 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
|---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------|
| l2Outputs | mapping(uint256 => struct Types.OutputProposal) | 105 | 0 | 32 | contracts/L1/L2OutputOracle.sol:L2OutputOracle |
+---------------------+-------------------------------------------------+------+--------+-------+------------------------------------------------+
=======================
➡ contracts/L1/OptimismPortal.sol:OptimismPortal
......
......@@ -22,19 +22,19 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
uint256 public immutable SUBMISSION_INTERVAL;
/**
* @notice The number of the first L2 block recorded in this contract.
* @notice The time between L2 blocks in seconds.
*/
uint256 public immutable STARTING_BLOCK_NUMBER;
uint256 public immutable L2_BLOCK_TIME;
/**
* @notice The timestamp of the first L2 block recorded in this contract.
* @notice The number of the first L2 block recorded in this contract.
*/
uint256 public immutable STARTING_TIMESTAMP;
uint256 public startingBlockNumber;
/**
* @notice The time between L2 blocks in seconds.
* @notice The timestamp of the first L2 block recorded in this contract.
*/
uint256 public immutable L2_BLOCK_TIME;
uint256 public startingTimestamp;
/**
* @notice The address of the proposer;
......@@ -93,49 +93,54 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
* @custom:semver 0.0.1
*
* @param _submissionInterval Interval in blocks at which checkpoints must be submitted.
* @param _genesisL2Output The initial L2 output of the L2 chain.
* @param _l2BlockTime The time per L2 block, in seconds.
* @param _startingL2Output The initial L2 output of the L2 chain.
* @param _startingBlockNumber The number of the first L2 block.
* @param _startingTimestamp The timestamp of the first L2 block.
* @param _l2BlockTime The time per L2 block, in seconds.
* @param _proposer The address of the proposer.
* @param _owner The address of the owner.
*/
constructor(
uint256 _submissionInterval,
bytes32 _genesisL2Output,
uint256 _l2BlockTime,
bytes32 _startingL2Output,
uint256 _startingBlockNumber,
uint256 _startingTimestamp,
uint256 _l2BlockTime,
address _proposer,
address _owner
) Semver(0, 0, 1) {
require(
_startingTimestamp <= block.timestamp,
"L2OutputOracle: starting L2 timestamp must be less than current time"
);
SUBMISSION_INTERVAL = _submissionInterval;
STARTING_BLOCK_NUMBER = _startingBlockNumber;
STARTING_TIMESTAMP = _startingTimestamp;
L2_BLOCK_TIME = _l2BlockTime;
initialize(_genesisL2Output, _proposer, _owner);
initialize(_startingL2Output, _startingBlockNumber, _startingTimestamp, _proposer, _owner);
}
/**
* @notice Initializer.
*
* @param _genesisL2Output The initial L2 output of the L2 chain.
* @param _startingL2Output Output for the first recoded L2 block.
* @param _startingBlockNumber Block number for the first recoded L2 block.
* @param _startingTimestamp Timestamp for the first recoded L2 block.
* @param _proposer The address of the proposer.
* @param _owner The address of the owner.
*/
function initialize(
bytes32 _genesisL2Output,
bytes32 _startingL2Output,
uint256 _startingBlockNumber,
uint256 _startingTimestamp,
address _proposer,
address _owner
) public initializer {
l2Outputs[STARTING_BLOCK_NUMBER] = Types.OutputProposal(_genesisL2Output, block.timestamp);
latestBlockNumber = STARTING_BLOCK_NUMBER;
require(
_startingTimestamp <= block.timestamp,
"L2OutputOracle: starting L2 timestamp must be less than current time"
);
startingBlockNumber = _startingBlockNumber;
latestBlockNumber = _startingBlockNumber;
startingTimestamp = _startingTimestamp;
l2Outputs[startingBlockNumber] = Types.OutputProposal(_startingL2Output, block.timestamp);
__Ownable_init();
changeProposer(_proposer);
_transferOwnership(_owner);
......@@ -230,7 +235,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
* L2 block number provided is between checkpoints, this function will rerutn the next
* proposal for the next checkpoint.
* Reverts if the output proposal is either not found, or predates
* the STARTING_BLOCK_NUMBER.
* the startingBlockNumber.
*
* @param _l2BlockNumber The L2 block number of the target block.
*/
......@@ -245,7 +250,7 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
);
// Find the distance between _l2BlockNumber, and the checkpoint block before it.
uint256 offset = (_l2BlockNumber - STARTING_BLOCK_NUMBER) % SUBMISSION_INTERVAL;
uint256 offset = (_l2BlockNumber - startingBlockNumber) % SUBMISSION_INTERVAL;
// If the offset is zero, then the _l2BlockNumber should be checkpointed.
// Otherwise, we'll look up the next block that will be checkpointed.
......@@ -290,6 +295,6 @@ contract L2OutputOracle is OwnableUpgradeable, Semver {
* @param _l2BlockNumber The L2 block number of the target block.
*/
function computeL2Timestamp(uint256 _l2BlockNumber) public view returns (uint256) {
return STARTING_TIMESTAMP + ((_l2BlockNumber - STARTING_BLOCK_NUMBER) * L2_BLOCK_TIME);
return startingTimestamp + ((_l2BlockNumber - startingBlockNumber) * L2_BLOCK_TIME);
}
}
......@@ -251,7 +251,7 @@ contract OptimismPortal is Initializable, ResourceMetering, Semver {
// Ensure that the proven withdrawal's timestamp is greater than the
// L2 Oracle's starting timestamp.
require(
provenWithdrawal.timestamp >= L2_ORACLE.STARTING_TIMESTAMP(),
provenWithdrawal.timestamp >= L2_ORACLE.startingTimestamp(),
"OptimismPortal: withdrawal timestamp less than L2 Oracle starting timestamp"
);
......
......@@ -56,14 +56,22 @@ contract BaseSystemDictator is Ownable {
}
/**
* @notice Set of implementation addresses.
* @notice Fixed L2OutputOracle config.
*/
struct L2OutputOracleConfig {
bytes32 l2OutputOracleGenesisL2Output;
address l2OutputOracleProposer;
address l2OutputOracleOwner;
}
/**
* @notice Dynamic L2OutputOracle config.
*/
struct L2OutputOracleDynamicConfig {
bytes32 l2OutputOracleStartingL2Output;
uint256 l2OutputOracleStartingBlockNumber;
uint256 l2OutputOracleStartingTimestamp;
}
/**
* @notice Values for the system config contract.
*/
......@@ -91,11 +99,21 @@ contract BaseSystemDictator is Ownable {
*/
DeployConfig public config;
/**
* @notice Dynamic configuration for the L2OutputOracle.
*/
L2OutputOracleDynamicConfig public l2OutputOracleDynamicConfig;
/**
* @notice Current step;
*/
uint8 public currentStep = 1;
/**
* @notice Whether or not dynamic config has been set.
*/
bool public dynamicConfigSet;
/**
* @notice Checks that the current step is the expected step, then bumps the current step.
*
......@@ -114,4 +132,16 @@ contract BaseSystemDictator is Ownable {
config = _config;
_transferOwnership(config.globalConfig.controller);
}
/**
* @notice Allows the owner to update dynamic L2OutputOracle config.
*
* @param _l2OutputOracleDynamicConfig Dynamic L2OutputOracle config.
*/
function updateL2OutputOracleDynamicConfig(
L2OutputOracleDynamicConfig memory _l2OutputOracleDynamicConfig
) external onlyOwner {
l2OutputOracleDynamicConfig = _l2OutputOracleDynamicConfig;
dynamicConfigSet = true;
}
}
......@@ -143,6 +143,12 @@ contract MigrationSystemDictator is BaseSystemDictator {
* @notice Upgrades and initializes proxy contracts.
*/
function step5() external onlyOwner step(5) {
// Dynamic config must be set before we can initialize the L2OutputOracle.
require(
dynamicConfigSet,
"MigrationSystemDictator: dynamic oracle config is not yet initialized"
);
// Upgrade and initialize the L2OutputOracle.
config.globalConfig.proxyAdmin.upgradeAndCall(
payable(config.proxyAddressConfig.l2OutputOracleProxy),
......@@ -150,7 +156,9 @@ contract MigrationSystemDictator is BaseSystemDictator {
abi.encodeCall(
L2OutputOracle.initialize,
(
config.l2OutputOracleConfig.l2OutputOracleGenesisL2Output,
l2OutputOracleDynamicConfig.l2OutputOracleStartingL2Output,
l2OutputOracleDynamicConfig.l2OutputOracleStartingBlockNumber,
l2OutputOracleDynamicConfig.l2OutputOracleStartingTimestamp,
config.l2OutputOracleConfig.l2OutputOracleProposer,
config.l2OutputOracleConfig.l2OutputOracleOwner
)
......
......@@ -120,10 +120,10 @@ contract L2OutputOracle_Initializer is CommonTest {
// Deploy the L2OutputOracle and transfer owernship to the proposer
oracleImpl = new L2OutputOracle(
submissionInterval,
l2BlockTime,
genesisL2Output,
startingBlockNumber,
startingTimestamp,
l2BlockTime,
proposer,
owner
);
......@@ -131,7 +131,10 @@ contract L2OutputOracle_Initializer is CommonTest {
vm.prank(multisig);
proxy.upgradeToAndCall(
address(oracleImpl),
abi.encodeCall(L2OutputOracle.initialize, (genesisL2Output, proposer, owner))
abi.encodeCall(
L2OutputOracle.initialize,
(genesisL2Output, startingBlockNumber, startingTimestamp, proposer, owner)
)
);
oracle = L2OutputOracle(address(proxy));
vm.label(address(oracle), "L2OutputOracle");
......
......@@ -18,8 +18,8 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
assertEq(oracle.owner(), owner);
assertEq(oracle.SUBMISSION_INTERVAL(), submissionInterval);
assertEq(oracle.latestBlockNumber(), startingBlockNumber);
assertEq(oracle.STARTING_BLOCK_NUMBER(), startingBlockNumber);
assertEq(oracle.STARTING_TIMESTAMP(), startingTimestamp);
assertEq(oracle.startingBlockNumber(), startingBlockNumber);
assertEq(oracle.startingTimestamp(), startingTimestamp);
assertEq(oracle.proposer(), proposer);
assertEq(oracle.owner(), owner);
......@@ -33,11 +33,11 @@ contract L2OutputOracleTest is L2OutputOracle_Initializer {
new L2OutputOracle(
submissionInterval,
l2BlockTime,
genesisL2Output,
startingBlockNumber,
// startingTimestamp is in the future
block.timestamp + 1,
l2BlockTime,
proposer,
owner
);
......@@ -370,9 +370,9 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
function test_initValuesOnProxy() external {
assertEq(submissionInterval, oracleImpl.SUBMISSION_INTERVAL());
assertEq(startingBlockNumber, oracleImpl.STARTING_BLOCK_NUMBER());
assertEq(startingTimestamp, oracleImpl.STARTING_TIMESTAMP());
assertEq(l2BlockTime, oracleImpl.L2_BLOCK_TIME());
assertEq(startingBlockNumber, oracleImpl.startingBlockNumber());
assertEq(startingTimestamp, oracleImpl.startingTimestamp());
Types.OutputProposal memory initOutput = oracleImpl.getL2Output(startingBlockNumber);
assertEq(genesisL2Output, initOutput.outputRoot);
......@@ -384,12 +384,24 @@ contract L2OutputOracleUpgradeable_Test is L2OutputOracle_Initializer {
function test_cannotInitProxy() external {
vm.expectRevert("Initializable: contract is already initialized");
L2OutputOracle(payable(proxy)).initialize(genesisL2Output, proposer, owner);
L2OutputOracle(payable(proxy)).initialize(
genesisL2Output,
startingBlockNumber,
startingTimestamp,
proposer,
owner
);
}
function test_cannotInitImpl() external {
vm.expectRevert("Initializable: contract is already initialized");
L2OutputOracle(oracleImpl).initialize(genesisL2Output, proposer, owner);
L2OutputOracle(oracleImpl).initialize(
genesisL2Output,
startingBlockNumber,
startingTimestamp,
proposer,
owner
);
}
function test_upgrading() external {
......
......@@ -528,10 +528,10 @@ contract OptimismPortal_FinalizeWithdrawal_Test is Portal_Initializer {
// Warp to after the finalization period
vm.warp(block.timestamp + op.FINALIZATION_PERIOD_SECONDS() + 1);
// Mock a STARTING_TIMESTAMP change on the L2 Oracle
// Mock a startingTimestamp change on the L2 Oracle
vm.mockCall(
address(op.L2_ORACLE()),
abi.encodeWithSignature("STARTING_TIMESTAMP()"),
abi.encodeWithSignature("startingTimestamp()"),
abi.encode(block.timestamp + 1)
);
......
import assert from 'assert'
import { ethers } from 'ethers'
import { DeployFunction } from 'hardhat-deploy/dist/types'
import '@eth-optimism/hardhat-deploy-config'
......@@ -11,30 +9,15 @@ import {
} from '../src/deploy-utils'
const deployFn: DeployFunction = async (hre) => {
// Use default starting time if starting time is not provided.
let deployL2StartingTimestamp =
hre.deployConfig.l2OutputOracleStartingTimestamp
if (deployL2StartingTimestamp < 0) {
const l1StartingBlock = await hre.ethers.provider.getBlock(
hre.deployConfig.l1StartingBlockTag
)
if (l1StartingBlock === null) {
throw new Error(
`Cannot fetch block tag ${hre.deployConfig.l1StartingBlockTag}`
)
}
deployL2StartingTimestamp = l1StartingBlock.timestamp
}
await deployAndVerifyAndThen({
hre,
name: 'L2OutputOracle',
args: [
hre.deployConfig.l2OutputOracleSubmissionInterval,
hre.deployConfig.l2OutputOracleGenesisL2Output,
hre.deployConfig.l2OutputOracleStartingBlockNumber,
deployL2StartingTimestamp,
hre.deployConfig.l2BlockTime,
ethers.constants.HashZero,
0,
0,
hre.deployConfig.l2OutputOracleProposer,
hre.deployConfig.l2OutputOracleOwner,
],
......@@ -44,16 +27,6 @@ const deployFn: DeployFunction = async (hre) => {
'SUBMISSION_INTERVAL',
hre.deployConfig.l2OutputOracleSubmissionInterval
)
await assertContractVariable(
contract,
'STARTING_BLOCK_NUMBER',
hre.deployConfig.l2OutputOracleStartingBlockNumber
)
await assertContractVariable(
contract,
'STARTING_TIMESTAMP',
deployL2StartingTimestamp
)
await assertContractVariable(
contract,
'L2_BLOCK_TIME',
......@@ -69,24 +42,6 @@ const deployFn: DeployFunction = async (hre) => {
'owner',
hre.deployConfig.l2OutputOracleOwner
)
// Has to be done separately since l2Output is a mapping.
if (
hre.deployConfig.l2OutputOracleGenesisL2Output ===
ethers.constants.HashZero
) {
console.log(
`[WARNING] Genesis L2 output is ZERO and should NOT BE ZERO if you are deploying to prod`
)
} else {
const output = await contract.getL2Output(
hre.deployConfig.l2OutputOracleStartingBlockNumber
)
assert(
output.outputRoot === hre.deployConfig.l2OutputOracleGenesisL2Output,
`[FATAL] L2OutputOracleImpl genesis output is ${output.outputRoot} but should be ${hre.deployConfig.l2OutputOracleGenesisL2Output}`
)
}
},
})
}
......
......@@ -32,7 +32,6 @@ export interface DictatorConfig {
systemConfigImpl: string
}
l2OutputOracleConfig: {
l2OutputOracleGenesisL2Output: string
l2OutputOracleProposer: string
l2OutputOracleOwner: string
}
......@@ -352,8 +351,6 @@ export const makeDictatorConfig = async (
systemConfigImpl: await getDeploymentAddress(hre, 'SystemConfig'),
},
l2OutputOracleConfig: {
l2OutputOracleGenesisL2Output:
hre.deployConfig.l2OutputOracleGenesisL2Output,
l2OutputOracleProposer: hre.deployConfig.l2OutputOracleProposer,
l2OutputOracleOwner: hre.deployConfig.l2OutputOracleOwner,
},
......
......@@ -236,13 +236,24 @@ export class CrossChainMessenger {
return this._l2OutputOracleParameters
}
// Temporary logic to support legacy Bedrock testnets.
// TODO: Remove this once all legacy testnets are deprecated.
let startingBlockNumber: number
try {
startingBlockNumber = (
await this.contracts.l1.L2OutputOracle.startingBlockNumber()
).toNumber()
} catch {
startingBlockNumber = (
await this.contracts.l1.L2OutputOracle.STARTING_BLOCK_NUMBER()
).toNumber()
}
this._l2OutputOracleParameters = {
startingBlockNumber,
submissionInterval: (
await this.contracts.l1.L2OutputOracle.SUBMISSION_INTERVAL()
).toNumber(),
startingBlockNumber: (
await this.contracts.l1.L2OutputOracle.STARTING_BLOCK_NUMBER()
).toNumber(),
l2BlockTime: (
await this.contracts.l1.L2OutputOracle.L2_BLOCK_TIME()
).toNumber(),
......
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