Commit 66943d0c authored by clabby's avatar clabby Committed by GitHub

feat(ctb): `useFaultProofs` runtime override (#9399)

* Add `useFaultProofs` runtime override

updates

* Update gas snapshot

* improve CI matrix names

* revert e2e changes
parent 71074e80
......@@ -1026,9 +1026,17 @@ jobs:
environment:
DOCKER_BUILDKIT: 1
DEVNET_NO_BUILD: 'true'
DEVNET_FPAC: <<parameters.devnet_fpac>>
# Default value; Can be overridden.
DEVNET_FPAC: 'false'
steps:
- checkout
- when:
condition:
equal: ['fault-proofs', <<parameters.devnet_fpac>>]
steps:
- run:
name: Set DEVNET_FPAC = true
command: echo 'export DEVNET_FPAC=true' >> $BASH_ENV
- check-changed:
patterns: op-(.+),packages,ops-bedrock,bedrock-devnet
- run:
......@@ -1641,7 +1649,7 @@ workflows:
- devnet:
matrix:
parameters:
devnet_fpac: ["false", "true"]
devnet_fpac: ["legacy", "fault-proofs"]
requires:
- pnpm-monorepo
- op-batcher-docker-build
......
......@@ -5,7 +5,7 @@ GasBenchMark_L1StandardBridge_Deposit:test_depositERC20_benchmark_1() (gas: 4061
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_0() (gas: 450330)
GasBenchMark_L1StandardBridge_Deposit:test_depositETH_benchmark_1() (gas: 3496057)
GasBenchMark_L1StandardBridge_Finalize:test_finalizeETHWithdrawal_benchmark() (gas: 59803)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92973)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68382)
GasBenchMark_L2OutputOracle:test_proposeL2Output_benchmark() (gas: 92951)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark() (gas: 68360)
GasBenchMark_OptimismPortal:test_depositTransaction_benchmark_1() (gas: 68991)
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155559)
\ No newline at end of file
GasBenchMark_OptimismPortal:test_proveWithdrawalTransaction_benchmark() (gas: 155557)
\ No newline at end of file
......@@ -43,6 +43,15 @@
"systemConfigStartBlock": 0,
"requiredProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"recommendedProtocolVersion": "0x0000000000000000000000000000000000000000000000000000000000000000",
"faultGameAbsolutePrestate": "0x0000000000000000000000000000000000000000000000000000000000000000",
"faultGameMaxDepth": 8,
"faultGameMaxDuration": 2400,
"faultGameGenesisBlock": 0,
"faultGameGenesisOutputRoot": "0x0000000000000000000000000000000000000000000000000000000000000000",
"faultGameSplitDepth": 4,
"preimageOracleMinProposalSize": 10000,
"preimageOracleChallengePeriod": 120,
"preimageOracleCancunActivationTimestamp": 0,
"proofMaturityDelaySeconds": 12,
"disputeGameFinalityDelaySeconds": 6,
"respectedGameType": 0,
......
......@@ -12,7 +12,7 @@ import { SafeProxyFactory } from "safe-contracts/proxies/SafeProxyFactory.sol";
import { Enum as SafeOps } from "safe-contracts/common/Enum.sol";
import { Deployer } from "scripts/Deployer.sol";
import { DeployConfig } from "scripts/DeployConfig.s.sol";
import "scripts/DeployConfig.s.sol";
import { ProxyAdmin } from "src/universal/ProxyAdmin.sol";
import { AddressManager } from "src/legacy/AddressManager.sol";
......@@ -238,12 +238,20 @@ contract Deploy is Deployer {
function setUp() public virtual override {
super.setUp();
// Load the `useFaultProofs` slot value prior to etching the DeployConfig's bytecode and reading the deploy
// config file. If this slot has already been set, it will override the preference in the deploy config.
bytes32 useFaultProofsOverride = vm.load(address(cfg), USE_FAULT_PROOFS_SLOT);
string memory path = string.concat(vm.projectRoot(), "/deploy-config/", deploymentContext, ".json");
vm.etch(address(cfg), vm.getDeployedCode("DeployConfig.s.sol:DeployConfig"));
vm.label(address(cfg), "DeployConfig");
vm.allowCheatcodes(address(cfg));
cfg.read(path);
if (useFaultProofsOverride != 0) {
vm.store(address(cfg), USE_FAULT_PROOFS_SLOT, useFaultProofsOverride);
}
console.log("Deploying from %s", deployScript);
console.log("Deployment context: %s", deploymentContext);
}
......@@ -329,13 +337,17 @@ contract Deploy is Deployer {
console.log("Deploying proxies");
deployERC1967Proxy("OptimismPortalProxy");
deployERC1967Proxy("L2OutputOracleProxy");
deployERC1967Proxy("SystemConfigProxy");
deployL1StandardBridgeProxy();
deployL1CrossDomainMessengerProxy();
deployERC1967Proxy("OptimismMintableERC20FactoryProxy");
deployERC1967Proxy("L1ERC721BridgeProxy");
// Both the DisputeGameFactory and L2OutputOracle proxies are deployed regardles of whether FPAC is enabled
// to prevent a nastier refactor to the deploy scripts. In the future, the L2OutputOracle will be removed. If
// fault proofs are not enabled, the DisputeGameFactory proxy will be unused.
deployERC1967Proxy("DisputeGameFactoryProxy");
deployERC1967Proxy("L2OutputOracleProxy");
transferAddressManagerOwnership(); // to the ProxyAdmin
}
......@@ -343,14 +355,16 @@ contract Deploy is Deployer {
/// @notice Deploy all of the implementations
function deployImplementations() public {
console.log("Deploying implementations");
deployOptimismPortal();
deployOptimismPortal2();
deployL1CrossDomainMessenger();
deployL2OutputOracle();
deployOptimismMintableERC20Factory();
deploySystemConfig();
deployL1StandardBridge();
deployL1ERC721Bridge();
deployOptimismPortal();
deployL2OutputOracle();
// Fault proofs
deployOptimismPortal2();
deployDisputeGameFactory();
deployPreimageOracle();
deployMips();
......@@ -359,20 +373,19 @@ contract Deploy is Deployer {
/// @notice Initialize all of the implementations
function initializeImplementations() public {
console.log("Initializing implementations");
initializeDisputeGameFactory();
initializeSystemConfig();
initializeL1StandardBridge();
initializeL1ERC721Bridge();
initializeOptimismMintableERC20Factory();
initializeL1CrossDomainMessenger();
initializeL2OutputOracle();
initializeDisputeGameFactory();
// Selectively initialize either the original OptimismPortal or the
// new OptimismPortal2. Since this will upgrade the proxy, we cannot
// initialize both. FPAC warning can be removed once we're done with
// the old OptimismPortal contract.
// Selectively initialize either the original OptimismPortal or the new OptimismPortal2. Since this will upgrade
// the proxy, we cannot initialize both. FPAC warning can be removed once we're done with the old OptimismPortal
// contract.
if (cfg.useFaultProofs()) {
console.log("WARNING: FPAC is enabled and using OptimismPortal2");
console.log("WARNING: FPAC is enabled. Initializing the OptimismPortal proxy with the OptimismPortal2.");
initializeOptimismPortal2();
} else {
initializeOptimismPortal();
......@@ -629,7 +642,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the DisputeGameFactory
function deployDisputeGameFactory() public onlyTestnetOrDevnet broadcast returns (address addr_) {
function deployDisputeGameFactory() public broadcast returns (address addr_) {
console.log("Deploying DisputeGameFactory implementation");
DisputeGameFactory factory = new DisputeGameFactory{ salt: _implSalt() }();
save("DisputeGameFactory", address(factory));
......@@ -660,7 +673,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy the PreimageOracle
function deployPreimageOracle() public onlyTestnetOrDevnet broadcast returns (address addr_) {
function deployPreimageOracle() public broadcast returns (address addr_) {
console.log("Deploying PreimageOracle implementation");
PreimageOracle preimageOracle = new PreimageOracle{ salt: _implSalt() }({
_minProposalSize: cfg.preimageOracleMinProposalSize(),
......@@ -674,7 +687,7 @@ contract Deploy is Deployer {
}
/// @notice Deploy Mips
function deployMips() public onlyTestnetOrDevnet broadcast returns (address addr_) {
function deployMips() public broadcast returns (address addr_) {
console.log("Deploying Mips implementation");
MIPS mips = new MIPS{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle")));
save("Mips", address(mips));
......@@ -773,7 +786,7 @@ contract Deploy is Deployer {
}
/// @notice Initialize the DisputeGameFactory
function initializeDisputeGameFactory() public onlyTestnetOrDevnet broadcast {
function initializeDisputeGameFactory() public broadcast {
console.log("Upgrading and initializing DisputeGameFactory proxy");
address disputeGameFactoryProxy = mustGetAddress("DisputeGameFactoryProxy");
address disputeGameFactory = mustGetAddress("DisputeGameFactory");
......@@ -1092,7 +1105,7 @@ contract Deploy is Deployer {
}
/// @notice Transfer ownership of the DisputeGameFactory contract to the final system owner
function transferDisputeGameFactoryOwnership() public onlyTestnetOrDevnet broadcast {
function transferDisputeGameFactoryOwnership() public broadcast {
console.log("Transferring DisputeGameFactory ownership to Safe");
DisputeGameFactory disputeGameFactory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
address owner = disputeGameFactory.owner();
......@@ -1132,7 +1145,7 @@ contract Deploy is Deployer {
}
/// @notice Sets the implementation for the `FAULT` game type in the `DisputeGameFactory`
function setCannonFaultGameImplementation(bool _allowUpgrade) public onlyTestnetOrDevnet broadcast {
function setCannonFaultGameImplementation(bool _allowUpgrade) public broadcast {
console.log("Setting Cannon FaultDisputeGame implementation");
DisputeGameFactory factory = DisputeGameFactory(mustGetAddress("DisputeGameFactoryProxy"));
......
......@@ -7,6 +7,10 @@ import { stdJson } from "forge-std/StdJson.sol";
import { Executables } from "scripts/Executables.sol";
import { Chains } from "scripts/Chains.sol";
// Global constant for the `useFaultProofs` slot in the DeployConfig contract, which can be overridden in the testing
// environment.
bytes32 constant USE_FAULT_PROOFS_SLOT = bytes32(uint256(61));
/// @title DeployConfig
/// @notice Represents the configuration required to deploy the system. It is expected
/// to read the file from JSON. A future improvement would be to have fallback
......@@ -109,27 +113,22 @@ contract DeployConfig is Script {
systemConfigStartBlock = stdJson.readUint(_json, "$.systemConfigStartBlock");
requiredProtocolVersion = stdJson.readUint(_json, "$.requiredProtocolVersion");
recommendedProtocolVersion = stdJson.readUint(_json, "$.recommendedProtocolVersion");
useFaultProofs = stdJson.readBool(_json, "$.useFaultProofs");
proofMaturityDelaySeconds = stdJson.readUint(_json, "$.proofMaturityDelaySeconds");
disputeGameFinalityDelaySeconds = stdJson.readUint(_json, "$.disputeGameFinalityDelaySeconds");
respectedGameType = stdJson.readUint(_json, "$.respectedGameType");
useFaultProofs = stdJson.readBool(_json, "$.useFaultProofs");
if (
block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet || block.chainid == Chains.Sepolia
|| block.chainid == Chains.Goerli
) {
faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate");
faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth");
faultGameSplitDepth = stdJson.readUint(_json, "$.faultGameSplitDepth");
faultGameMaxDuration = stdJson.readUint(_json, "$.faultGameMaxDuration");
faultGameGenesisBlock = stdJson.readUint(_json, "$.faultGameGenesisBlock");
faultGameGenesisOutputRoot = stdJson.readBytes32(_json, "$.faultGameGenesisOutputRoot");
faultGameAbsolutePrestate = stdJson.readUint(_json, "$.faultGameAbsolutePrestate");
faultGameMaxDepth = stdJson.readUint(_json, "$.faultGameMaxDepth");
faultGameSplitDepth = stdJson.readUint(_json, "$.faultGameSplitDepth");
faultGameMaxDuration = stdJson.readUint(_json, "$.faultGameMaxDuration");
faultGameGenesisBlock = stdJson.readUint(_json, "$.faultGameGenesisBlock");
faultGameGenesisOutputRoot = stdJson.readBytes32(_json, "$.faultGameGenesisOutputRoot");
preimageOracleMinProposalSize = stdJson.readUint(_json, "$.preimageOracleMinProposalSize");
preimageOracleChallengePeriod = stdJson.readUint(_json, "$.preimageOracleChallengePeriod");
preimageOracleCancunActivationTimestamp =
stdJson.readUint(_json, "$.preimageOracleCancunActivationTimestamp");
}
preimageOracleMinProposalSize = stdJson.readUint(_json, "$.preimageOracleMinProposalSize");
preimageOracleChallengePeriod = stdJson.readUint(_json, "$.preimageOracleChallengePeriod");
preimageOracleCancunActivationTimestamp = stdJson.readUint(_json, "$.preimageOracleCancunActivationTimestamp");
}
function l1StartingBlockTag() public returns (bytes32) {
......
......@@ -5,6 +5,7 @@ import { Test } from "forge-std/Test.sol";
import { Setup } from "test/setup/Setup.sol";
import { Events } from "test/setup/Events.sol";
import { FFIInterface } from "test/setup/FFIInterface.sol";
import "scripts/DeployConfig.s.sol";
/// @title CommonTest
/// @dev An extenstion to `Test` that sets up the optimism smart contracts.
......@@ -86,4 +87,20 @@ contract CommonTest is Test, Setup, Events {
vm.prank(proposer);
l2OutputOracle.proposeL2Output(proposedOutput2, nextBlockNumber, 0, 0);
}
function enableFaultProofs() public {
// Check if the system has already been deployed, based off of the heuristic that alice and bob have not been
// set by the `setUp` function yet.
if (!(alice == address(0) && bob == address(0))) {
revert("CommonTest: Cannot enable fault proofs after deployment. Consider overriding `setUp`.");
}
// Set `useFaultProofs` to `true` in the deploy config so that the deploy script deploys the Fault Proof system.
// This directly overrides the deploy config's `useFaultProofs` value, if the test requires it.
vm.store(
address(uint160(uint256(keccak256(abi.encode("optimism.deployconfig"))))),
USE_FAULT_PROOFS_SLOT,
bytes32(uint256(1))
);
}
}
......@@ -18,6 +18,8 @@ import { LegacyERC20ETH } from "src/legacy/LegacyERC20ETH.sol";
import { StandardBridge } from "src/universal/StandardBridge.sol";
import { FeeVault } from "src/universal/FeeVault.sol";
import { OptimismPortal } from "src/L1/OptimismPortal.sol";
import { OptimismPortal2 } from "src/L1/OptimismPortal2.sol";
import { DisputeGameFactory } from "src/dispute/DisputeGameFactory.sol";
import { L1CrossDomainMessenger } from "src/L1/L1CrossDomainMessenger.sol";
import { DeployConfig } from "scripts/DeployConfig.s.sol";
import { Deploy } from "scripts/Deploy.s.sol";
......@@ -46,6 +48,8 @@ contract Setup {
Deploy internal constant deploy = Deploy(address(uint160(uint256(keccak256(abi.encode("optimism.deploy"))))));
OptimismPortal optimismPortal;
OptimismPortal2 optimismPortal2;
DisputeGameFactory disputeGameFactory;
L2OutputOracle l2OutputOracle;
SystemConfig systemConfig;
L1StandardBridge l1StandardBridge;
......@@ -95,6 +99,8 @@ contract Setup {
deploy.run();
optimismPortal = OptimismPortal(deploy.mustGetAddress("OptimismPortalProxy"));
optimismPortal2 = OptimismPortal2(deploy.mustGetAddress("OptimismPortalProxy"));
disputeGameFactory = DisputeGameFactory(deploy.mustGetAddress("DisputeGameFactoryProxy"));
l2OutputOracle = L2OutputOracle(deploy.mustGetAddress("L2OutputOracleProxy"));
systemConfig = SystemConfig(deploy.mustGetAddress("SystemConfigProxy"));
l1StandardBridge = L1StandardBridge(deploy.mustGetAddress("L1StandardBridgeProxy"));
......@@ -110,6 +116,8 @@ contract Setup {
vm.label(deploy.mustGetAddress("L2OutputOracleProxy"), "L2OutputOracleProxy");
vm.label(address(optimismPortal), "OptimismPortal");
vm.label(deploy.mustGetAddress("OptimismPortalProxy"), "OptimismPortalProxy");
vm.label(address(disputeGameFactory), "DisputeGameFactory");
vm.label(deploy.mustGetAddress("DisputeGameFactoryProxy"), "DisputeGameFactoryProxy");
vm.label(address(systemConfig), "SystemConfig");
vm.label(deploy.mustGetAddress("SystemConfigProxy"), "SystemConfigProxy");
vm.label(address(l1StandardBridge), "L1StandardBridge");
......
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