Commit e165a7ea authored by Mark Tyneway's avatar Mark Tyneway Committed by GitHub

contracts: clean up deploy script abstractions (#12336)

* contracts: clean up deploy script abstractions

Move the implementation deployments into `deployImplementations`
and the initializations into the initizer function so that things
are grouped more logically. Even though we use OPSM for modern
deployments, the legacy code is still in the repo. This change
makes it easier to implement Standard L2 Genesis, where we depend
on the `OptimismPortal` being initialized before the `SystemConfig`,
since the `SystemConfig` makes calls to the portal during its
`initialize` call.

* op-e2e: remove dependency on contracts existing

Modularizes the functionality more

* lint: fix
parent e9b5eebe
...@@ -327,18 +327,21 @@ func testMixedWithdrawalValidity(t *testing.T, allocType config.AllocType) { ...@@ -327,18 +327,21 @@ func testMixedWithdrawalValidity(t *testing.T, allocType config.AllocType) {
_ = depositContract _ = depositContract
require.NoError(t, err) require.NoError(t, err)
l2OutputOracle, err := bindings.NewL2OutputOracleCaller(cfg.L1Deployments.L2OutputOracleProxy, l1Client) var l2OutputOracle *bindings.L2OutputOracleCaller
require.NoError(t, err) var disputeGameFactory *bindings.DisputeGameFactoryCaller
var optimismPortal2 *bindingspreview.OptimismPortal2Caller
finalizationPeriod, err := l2OutputOracle.FINALIZATIONPERIODSECONDS(nil) if allocType.UsesProofs() {
require.NoError(t, err) disputeGameFactory, err = bindings.NewDisputeGameFactoryCaller(cfg.L1Deployments.DisputeGameFactoryProxy, l1Client)
require.Equal(t, cfg.DeployConfig.FinalizationPeriodSeconds, finalizationPeriod.Uint64()) require.NoError(t, err)
optimismPortal2, err = bindingspreview.NewOptimismPortal2Caller(cfg.L1Deployments.OptimismPortalProxy, l1Client)
disputeGameFactory, err := bindings.NewDisputeGameFactoryCaller(cfg.L1Deployments.DisputeGameFactoryProxy, l1Client) require.NoError(t, err)
require.NoError(t, err) } else {
l2OutputOracle, err = bindings.NewL2OutputOracleCaller(cfg.L1Deployments.L2OutputOracleProxy, l1Client)
optimismPortal2, err := bindingspreview.NewOptimismPortal2Caller(cfg.L1Deployments.OptimismPortalProxy, l1Client) require.NoError(t, err)
require.NoError(t, err) finalizationPeriod, err := l2OutputOracle.FINALIZATIONPERIODSECONDS(nil)
require.NoError(t, err)
require.Equal(t, cfg.DeployConfig.FinalizationPeriodSeconds, finalizationPeriod.Uint64())
}
// Create a struct used to track our transactors and their transactions sent. // Create a struct used to track our transactors and their transactions sent.
type TestAccountState struct { type TestAccountState struct {
...@@ -429,7 +432,6 @@ func testMixedWithdrawalValidity(t *testing.T, allocType config.AllocType) { ...@@ -429,7 +432,6 @@ func testMixedWithdrawalValidity(t *testing.T, allocType config.AllocType) {
transactor.ExpectedL2Nonce = transactor.ExpectedL2Nonce + 1 transactor.ExpectedL2Nonce = transactor.ExpectedL2Nonce + 1
// Wait for the finalization period, then we can finalize this withdrawal. // Wait for the finalization period, then we can finalize this withdrawal.
require.NotEqual(t, cfg.L1Deployments.L2OutputOracleProxy, common.Address{})
var blockNumber uint64 var blockNumber uint64
if allocType.UsesProofs() { if allocType.UsesProofs() {
blockNumber, err = wait.ForGamePublished(ctx, l1Client, cfg.L1Deployments.OptimismPortalProxy, cfg.L1Deployments.DisputeGameFactoryProxy, receipt.BlockNumber) blockNumber, err = wait.ForGamePublished(ctx, l1Client, cfg.L1Deployments.OptimismPortalProxy, cfg.L1Deployments.DisputeGameFactoryProxy, receipt.BlockNumber)
......
...@@ -288,19 +288,6 @@ contract Deploy is Deployer { ...@@ -288,19 +288,6 @@ contract Deploy is Deployer {
// Deploy Current OPChain Contracts // Deploy Current OPChain Contracts
deployOpChain(); deployOpChain();
// Deploy and setup the legacy (pre-faultproofs) contracts
deployERC1967Proxy("L2OutputOracleProxy");
deployL2OutputOracle();
initializeL2OutputOracle();
// The OptimismPortalProxy contract is used both with and without Fault Proofs enabled, and is deployed by
// deployOPChain. So we only need to deploy the legacy OptimismPortal implementation and initialize with it
// when Fault Proofs are disabled.
if (!cfg.useFaultProofs()) {
deployOptimismPortal();
initializeOptimismPortal();
}
if (cfg.useAltDA()) { if (cfg.useAltDA()) {
bytes32 typeHash = keccak256(bytes(cfg.daCommitmentType())); bytes32 typeHash = keccak256(bytes(cfg.daCommitmentType()));
bytes32 keccakHash = keccak256(bytes("KeccakCommitment")); bytes32 keccakHash = keccak256(bytes("KeccakCommitment"));
...@@ -384,6 +371,12 @@ contract Deploy is Deployer { ...@@ -384,6 +371,12 @@ contract Deploy is Deployer {
} }
di.run(dii, dio); di.run(dii, dio);
// Temporary patch for legacy system
if (!cfg.useFaultProofs()) {
deployOptimismPortal();
deployL2OutputOracle();
}
save("L1CrossDomainMessenger", address(dio.l1CrossDomainMessengerImpl())); save("L1CrossDomainMessenger", address(dio.l1CrossDomainMessengerImpl()));
save("OptimismMintableERC20Factory", address(dio.optimismMintableERC20FactoryImpl())); save("OptimismMintableERC20Factory", address(dio.optimismMintableERC20FactoryImpl()));
save("SystemConfig", address(dio.systemConfigImpl())); save("SystemConfig", address(dio.systemConfigImpl()));
...@@ -456,6 +449,11 @@ contract Deploy is Deployer { ...@@ -456,6 +449,11 @@ contract Deploy is Deployer {
deployAnchorStateRegistry(); deployAnchorStateRegistry();
// Deploy and setup the legacy (pre-faultproofs) contracts
if (!cfg.useFaultProofs()) {
deployERC1967Proxy("L2OutputOracleProxy");
}
initializeOpChain(); initializeOpChain();
setAlphabetFaultGameImplementation({ _allowUpgrade: false }); setAlphabetFaultGameImplementation({ _allowUpgrade: false });
...@@ -471,13 +469,8 @@ contract Deploy is Deployer { ...@@ -471,13 +469,8 @@ contract Deploy is Deployer {
/// initialize function /// initialize function
function initializeOpChain() public { function initializeOpChain() public {
console.log("Initializing Op Chain proxies"); console.log("Initializing Op Chain proxies");
// The OptimismPortal Proxy is shared between the legacy and current deployment path, so we should initialize
// the OptimismPortal2 only if using FaultProofs.
if (cfg.useFaultProofs()) {
console.log("Fault proofs enabled. Initializing the OptimismPortal proxy with the OptimismPortal2.");
initializeOptimismPortal2();
}
initializeOptimismPortal();
initializeSystemConfig(); initializeSystemConfig();
initializeL1StandardBridge(); initializeL1StandardBridge();
initializeL1ERC721Bridge(); initializeL1ERC721Bridge();
...@@ -487,6 +480,10 @@ contract Deploy is Deployer { ...@@ -487,6 +480,10 @@ contract Deploy is Deployer {
initializeDelayedWETH(); initializeDelayedWETH();
initializePermissionedDelayedWETH(); initializePermissionedDelayedWETH();
initializeAnchorStateRegistry(); initializeAnchorStateRegistry();
if (!cfg.useFaultProofs()) {
initializeL2OutputOracle();
}
} }
/// @notice Add AltDA setup to the OP chain /// @notice Add AltDA setup to the OP chain
...@@ -643,23 +640,50 @@ contract Deploy is Deployer { ...@@ -643,23 +640,50 @@ contract Deploy is Deployer {
/// @notice Deploy the OptimismPortal /// @notice Deploy the OptimismPortal
function deployOptimismPortal() public broadcast returns (address addr_) { function deployOptimismPortal() public broadcast returns (address addr_) {
if (cfg.useInterop()) { if (cfg.useFaultProofs()) {
console.log("Attempting to deploy OptimismPortal with interop, this config is a noop"); // Could also verify this inside DeployConfig but doing it here is a bit more reliable.
} require(
uint32(cfg.respectedGameType()) == cfg.respectedGameType(),
"Deploy: respectedGameType must fit into uint32"
);
addr_ = DeployUtils.create2AndSave({ addr_ = DeployUtils.create2AndSave({
_save: this, _save: this,
_salt: _implSalt(), _salt: _implSalt(),
_name: "OptimismPortal", _name: "OptimismPortal2",
_args: DeployUtils.encodeConstructor(abi.encodeCall(IOptimismPortal.__constructor__, ())) _args: DeployUtils.encodeConstructor(
}); abi.encodeCall(
IOptimismPortal2.__constructor__,
(cfg.proofMaturityDelaySeconds(), cfg.disputeGameFinalityDelaySeconds())
)
)
});
// Override the `OptimismPortal2` contract to the deployed implementation. This is necessary
// to check the `OptimismPortal2` implementation alongside dependent contracts, which
// are always proxies.
Types.ContractSet memory contracts = _proxies();
contracts.OptimismPortal2 = addr_;
ChainAssertions.checkOptimismPortal2({ _contracts: contracts, _cfg: cfg, _isProxy: false });
} else {
if (cfg.useInterop()) {
console.log("Attempting to deploy OptimismPortal with interop, this config is a noop");
}
// Override the `OptimismPortal` contract to the deployed implementation. This is necessary addr_ = DeployUtils.create2AndSave({
// to check the `OptimismPortal` implementation alongside dependent contracts, which _save: this,
// are always proxies. _salt: _implSalt(),
Types.ContractSet memory contracts = _proxies(); _name: "OptimismPortal",
contracts.OptimismPortal = addr_; _args: DeployUtils.encodeConstructor(abi.encodeCall(IOptimismPortal.__constructor__, ()))
ChainAssertions.checkOptimismPortal({ _contracts: contracts, _cfg: cfg, _isProxy: false }); });
// Override the `OptimismPortal` contract to the deployed implementation. This is necessary
// to check the `OptimismPortal` implementation alongside dependent contracts, which
// are always proxies.
Types.ContractSet memory contracts = _proxies();
contracts.OptimismPortal = addr_;
ChainAssertions.checkOptimismPortal({ _contracts: contracts, _cfg: cfg, _isProxy: false });
}
} }
/// @notice Deploy the L2OutputOracle /// @notice Deploy the L2OutputOracle
...@@ -1128,63 +1152,59 @@ contract Deploy is Deployer { ...@@ -1128,63 +1152,59 @@ contract Deploy is Deployer {
/// @notice Initialize the OptimismPortal /// @notice Initialize the OptimismPortal
function initializeOptimismPortal() public broadcast { function initializeOptimismPortal() public broadcast {
console.log("Upgrading and initializing OptimismPortal proxy");
address optimismPortalProxy = mustGetAddress("OptimismPortalProxy"); address optimismPortalProxy = mustGetAddress("OptimismPortalProxy");
address optimismPortal = mustGetAddress("OptimismPortal");
address l2OutputOracleProxy = mustGetAddress("L2OutputOracleProxy");
address systemConfigProxy = mustGetAddress("SystemConfigProxy"); address systemConfigProxy = mustGetAddress("SystemConfigProxy");
address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy");
if (cfg.useFaultProofs()) {
IProxyAdmin proxyAdmin = IProxyAdmin(payable(mustGetAddress("ProxyAdmin"))); console.log("Upgrading and initializing OptimismPortal2 proxy");
proxyAdmin.upgradeAndCall({ address optimismPortal2 = mustGetAddress("OptimismPortal2");
_proxy: payable(optimismPortalProxy), address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy");
_implementation: optimismPortal,
_data: abi.encodeCall( IProxyAdmin proxyAdmin = IProxyAdmin(payable(mustGetAddress("ProxyAdmin")));
IOptimismPortal.initialize, proxyAdmin.upgradeAndCall({
( _proxy: payable(optimismPortalProxy),
IL2OutputOracle(l2OutputOracleProxy), _implementation: optimismPortal2,
ISystemConfig(systemConfigProxy), _data: abi.encodeCall(
ISuperchainConfig(superchainConfigProxy) IOptimismPortal2.initialize,
(
IDisputeGameFactory(disputeGameFactoryProxy),
ISystemConfig(systemConfigProxy),
ISuperchainConfig(superchainConfigProxy),
GameType.wrap(uint32(cfg.respectedGameType()))
)
) )
) });
});
IOptimismPortal portal = IOptimismPortal(payable(optimismPortalProxy)); IOptimismPortal2 portal = IOptimismPortal2(payable(optimismPortalProxy));
string memory version = portal.version(); string memory version = portal.version();
console.log("OptimismPortal version: %s", version); console.log("OptimismPortal2 version: %s", version);
ChainAssertions.checkOptimismPortal({ _contracts: _proxies(), _cfg: cfg, _isProxy: true }); ChainAssertions.checkOptimismPortal2({ _contracts: _proxies(), _cfg: cfg, _isProxy: true });
} } else {
console.log("Upgrading and initializing OptimismPortal proxy");
/// @notice Initialize the OptimismPortal2 address optimismPortal = mustGetAddress("OptimismPortal");
function initializeOptimismPortal2() public broadcast { address l2OutputOracleProxy = mustGetAddress("L2OutputOracleProxy");
console.log("Upgrading and initializing OptimismPortal2 proxy");
address optimismPortalProxy = mustGetAddress("OptimismPortalProxy"); IProxyAdmin proxyAdmin = IProxyAdmin(payable(mustGetAddress("ProxyAdmin")));
address optimismPortal2 = mustGetAddress("OptimismPortal2"); proxyAdmin.upgradeAndCall({
address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy"); _proxy: payable(optimismPortalProxy),
address systemConfigProxy = mustGetAddress("SystemConfigProxy"); _implementation: optimismPortal,
address superchainConfigProxy = mustGetAddress("SuperchainConfigProxy"); _data: abi.encodeCall(
IOptimismPortal.initialize,
IProxyAdmin proxyAdmin = IProxyAdmin(payable(mustGetAddress("ProxyAdmin"))); (
proxyAdmin.upgradeAndCall({ IL2OutputOracle(l2OutputOracleProxy),
_proxy: payable(optimismPortalProxy), ISystemConfig(systemConfigProxy),
_implementation: optimismPortal2, ISuperchainConfig(superchainConfigProxy)
_data: abi.encodeCall( )
IOptimismPortal2.initialize,
(
IDisputeGameFactory(disputeGameFactoryProxy),
ISystemConfig(systemConfigProxy),
ISuperchainConfig(superchainConfigProxy),
GameType.wrap(uint32(cfg.respectedGameType()))
) )
) });
});
IOptimismPortal2 portal = IOptimismPortal2(payable(optimismPortalProxy)); IOptimismPortal portal = IOptimismPortal(payable(optimismPortalProxy));
string memory version = portal.version(); string memory version = portal.version();
console.log("OptimismPortal2 version: %s", version); console.log("OptimismPortal version: %s", version);
ChainAssertions.checkOptimismPortal2({ _contracts: _proxies(), _cfg: cfg, _isProxy: true }); ChainAssertions.checkOptimismPortal({ _contracts: _proxies(), _cfg: cfg, _isProxy: true });
}
} }
/// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner /// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner
......
...@@ -147,7 +147,6 @@ contract Setup { ...@@ -147,7 +147,6 @@ contract Setup {
optimismPortal2 = IOptimismPortal2(deploy.mustGetAddress("OptimismPortalProxy")); optimismPortal2 = IOptimismPortal2(deploy.mustGetAddress("OptimismPortalProxy"));
disputeGameFactory = IDisputeGameFactory(deploy.mustGetAddress("DisputeGameFactoryProxy")); disputeGameFactory = IDisputeGameFactory(deploy.mustGetAddress("DisputeGameFactoryProxy"));
delayedWeth = IDelayedWETH(deploy.mustGetAddress("DelayedWETHProxy")); delayedWeth = IDelayedWETH(deploy.mustGetAddress("DelayedWETHProxy"));
l2OutputOracle = IL2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy"));
systemConfig = ISystemConfig(deploy.mustGetAddress("SystemConfigProxy")); systemConfig = ISystemConfig(deploy.mustGetAddress("SystemConfigProxy"));
l1StandardBridge = IL1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy")); l1StandardBridge = IL1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy"));
l1CrossDomainMessenger = IL1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessengerProxy")); l1CrossDomainMessenger = IL1CrossDomainMessenger(deploy.mustGetAddress("L1CrossDomainMessengerProxy"));
...@@ -159,8 +158,6 @@ contract Setup { ...@@ -159,8 +158,6 @@ contract Setup {
superchainConfig = ISuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy")); superchainConfig = ISuperchainConfig(deploy.mustGetAddress("SuperchainConfigProxy"));
anchorStateRegistry = IAnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy")); anchorStateRegistry = IAnchorStateRegistry(deploy.mustGetAddress("AnchorStateRegistryProxy"));
vm.label(address(l2OutputOracle), "L2OutputOracle");
vm.label(deploy.mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy");
vm.label(address(optimismPortal), "OptimismPortal"); vm.label(address(optimismPortal), "OptimismPortal");
vm.label(deploy.mustGetAddress("OptimismPortalProxy"), "OptimismPortalProxy"); vm.label(deploy.mustGetAddress("OptimismPortalProxy"), "OptimismPortalProxy");
vm.label(address(disputeGameFactory), "DisputeGameFactory"); vm.label(address(disputeGameFactory), "DisputeGameFactory");
...@@ -184,6 +181,12 @@ contract Setup { ...@@ -184,6 +181,12 @@ contract Setup {
vm.label(deploy.mustGetAddress("SuperchainConfigProxy"), "SuperchainConfigProxy"); vm.label(deploy.mustGetAddress("SuperchainConfigProxy"), "SuperchainConfigProxy");
vm.label(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), "L1CrossDomainMessenger_aliased"); vm.label(AddressAliasHelper.applyL1ToL2Alias(address(l1CrossDomainMessenger)), "L1CrossDomainMessenger_aliased");
if (!deploy.cfg().useFaultProofs()) {
l2OutputOracle = IL2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy"));
vm.label(address(l2OutputOracle), "L2OutputOracle");
vm.label(deploy.mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy");
}
if (deploy.cfg().useAltDA()) { if (deploy.cfg().useAltDA()) {
dataAvailabilityChallenge = dataAvailabilityChallenge =
IDataAvailabilityChallenge(deploy.mustGetAddress("DataAvailabilityChallengeProxy")); IDataAvailabilityChallenge(deploy.mustGetAddress("DataAvailabilityChallengeProxy"));
......
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