Commit d5957fad authored by Inphi's avatar Inphi Committed by GitHub

op-e2e: Setup mt-cannon for tests (#11881)

* op-e2e: Use mt-cannon

Introduces a `USE_MT_CANNON` env to optionally enables MT-Cannon in
op-e2e integration tests

* a couple of fixes

* fix todo
parent 3dbcee1c
...@@ -236,6 +236,12 @@ jobs: ...@@ -236,6 +236,12 @@ jobs:
- run: - run:
name: Copy AltDA allocs to .devnet-altda name: Copy AltDA allocs to .devnet-altda
command: cp -r .devnet/ .devnet-altda-generic/ command: cp -r .devnet/ .devnet-altda-generic/
- run:
name: Generate MT-Cannon allocs
command: USE_MT_CANNON="true" make devnet-allocs
- run:
name: Copy MT-Cannon allocs to .devnet-mt-cannon
command: cp -r .devnet/ .devnet-mt-cannon/
- run: - run:
name: Generate default allocs name: Generate default allocs
command: make devnet-allocs command: make devnet-allocs
...@@ -279,6 +285,12 @@ jobs: ...@@ -279,6 +285,12 @@ jobs:
- ".devnet-altda-generic/allocs-l2-ecotone.json" - ".devnet-altda-generic/allocs-l2-ecotone.json"
- ".devnet-altda-generic/allocs-l2-fjord.json" - ".devnet-altda-generic/allocs-l2-fjord.json"
- ".devnet-altda-generic/allocs-l2-granite.json" - ".devnet-altda-generic/allocs-l2-granite.json"
- ".devnet-mt-cannon/allocs-l1.json"
- ".devnet-mt-cannon/addresses.json"
- ".devnet-mt-cannon/allocs-l2-delta.json"
- ".devnet-mt-cannon/allocs-l2-ecotone.json"
- ".devnet-mt-cannon/allocs-l2-fjord.json"
- ".devnet-mt-cannon/allocs-l2-granite.json"
- "packages/contracts-bedrock/deploy-config/devnetL1.json" - "packages/contracts-bedrock/deploy-config/devnetL1.json"
- "packages/contracts-bedrock/deployments/devnetL1" - "packages/contracts-bedrock/deployments/devnetL1"
- notify-failures-on-develop - notify-failures-on-develop
...@@ -928,6 +940,13 @@ jobs: ...@@ -928,6 +940,13 @@ jobs:
- run: - run:
name: Set OP_E2E_USE_ALTDA = true name: Set OP_E2E_USE_ALTDA = true
command: echo 'export OP_E2E_USE_ALTDA=true' >> $BASH_ENV command: echo 'export OP_E2E_USE_ALTDA=true' >> $BASH_ENV
- when:
condition:
equal: ['-mt-cannon', <<parameters.variant>>]
steps:
- run:
name: Set OP_E2E_USE_MT_CANNON = true
command: echo 'export OP_E2E_USE_MT_CANNON=true' >> $BASH_ENV
- check-changed: - check-changed:
patterns: op-(.+),cannon,contracts-bedrock patterns: op-(.+),cannon,contracts-bedrock
- run: - run:
...@@ -1071,6 +1090,16 @@ jobs: ...@@ -1071,6 +1090,16 @@ jobs:
- "op-program/bin/prestate.json" - "op-program/bin/prestate.json"
- "op-program/bin/meta.json" - "op-program/bin/meta.json"
- "op-program/bin/prestate-proof.json" - "op-program/bin/prestate-proof.json"
- run:
name: generate cannon-mt prestate
command: make cannon-prestate-mt
- save_cache:
key: cannon-prestate-mt-{{ checksum "./cannon/bin/cannon" }}-{{ checksum "op-program/bin/op-program-client.elf" }}
name: Save MT-Cannon prestate to cache
paths:
- "op-program/bin/prestate-mt.json"
- "op-program/bin/meta-mt.json"
- "op-program/bin/prestate-proof-mt.json"
- save_cache: - save_cache:
name: Save Go build cache name: Save Go build cache
key: golang-build-cache-cannon-prestate-{{ checksum "go.sum" }} key: golang-build-cache-cannon-prestate-{{ checksum "go.sum" }}
...@@ -2078,7 +2107,12 @@ workflows: ...@@ -2078,7 +2107,12 @@ workflows:
- go-mod-download - go-mod-download
- contracts-bedrock-build - contracts-bedrock-build
- go-e2e-test: - go-e2e-test:
name: op-e2e-cannon-tests name: op-e2e-cannon-tests<< matrix.variant >>
matrix:
parameters:
variant: [""]
# TODO(#11893): add mt-cannon to matrix once it's stable
#variant: ["", "-mt-cannon"]
module: op-e2e module: op-e2e
target: test-cannon target: test-cannon
parallelism: 4 parallelism: 4
......
...@@ -134,10 +134,12 @@ reproducible-prestate: ## Builds reproducible-prestate binary ...@@ -134,10 +134,12 @@ reproducible-prestate: ## Builds reproducible-prestate binary
.PHONY: reproducible-prestate .PHONY: reproducible-prestate
# Include any files required for the devnet to build and run. This appears to be the only one that's actually needed. # Include any files required for the devnet to build and run. This appears to be the only one that's actually needed.
DEVNET_CANNON_PRESTATE_FILES := op-program/bin/prestate-proof.json op-program/bin/prestate.json DEVNET_CANNON_PRESTATE_FILES := op-program/bin/prestate-proof.json op-program/bin/prestate.json op-program/bin/prestate-proof-mt.json op-program/bin/prestate-mt.json
$(DEVNET_CANNON_PRESTATE_FILES): $(DEVNET_CANNON_PRESTATE_FILES):
make cannon-prestate make cannon-prestate
make cannon-prestate-mt
cannon-prestate: op-program cannon ## Generates prestate using cannon and op-program cannon-prestate: op-program cannon ## Generates prestate using cannon and op-program
./cannon/bin/cannon load-elf --path op-program/bin/op-program-client.elf --out op-program/bin/prestate.json --meta op-program/bin/meta.json ./cannon/bin/cannon load-elf --path op-program/bin/op-program-client.elf --out op-program/bin/prestate.json --meta op-program/bin/meta.json
......
...@@ -40,8 +40,9 @@ test-devnet: pre-test ...@@ -40,8 +40,9 @@ test-devnet: pre-test
$(go_test) $(go_test_flags) ./devnet $(go_test) $(go_test_flags) ./devnet
.PHONY: test-devnet .PHONY: test-devnet
cannon-prestate: cannon-prestates:
make -C .. cannon-prestate make -C .. cannon-prestate
make -C .. cannon-prestate-mt
.PHONY: cannon-prestate .PHONY: cannon-prestate
# We depend on the absolute pre-state generated by cannon to deploy the dispute game contracts. # We depend on the absolute pre-state generated by cannon to deploy the dispute game contracts.
...@@ -54,7 +55,7 @@ pre-test: pre-test-cannon pre-test-allocs ...@@ -54,7 +55,7 @@ pre-test: pre-test-cannon pre-test-allocs
pre-test-cannon: pre-test-cannon:
@if [ ! -e ../op-program/bin ]; then \ @if [ ! -e ../op-program/bin ]; then \
make cannon-prestate; \ make cannon-prestates; \
fi fi
.PHONY: pre-test-cannon .PHONY: pre-test-cannon
......
...@@ -106,7 +106,12 @@ func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config, ...@@ -106,7 +106,12 @@ func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config,
root := FindMonorepoRoot(t) root := FindMonorepoRoot(t)
c.Cannon.VmBin = root + "cannon/bin/cannon" c.Cannon.VmBin = root + "cannon/bin/cannon"
c.Cannon.Server = root + "op-program/bin/op-program" c.Cannon.Server = root + "op-program/bin/op-program"
c.CannonAbsolutePreState = root + "op-program/bin/prestate.json" if e2eutils.UseMTCannon() {
t.Log("Using MT-Cannon absolute prestate")
c.CannonAbsolutePreState = root + "op-program/bin/prestate-mt.bin.gz"
} else {
c.CannonAbsolutePreState = root + "op-program/bin/prestate.json"
}
c.Cannon.SnapshotFreq = 10_000_000 c.Cannon.SnapshotFreq = 10_000_000
genesisBytes, err := json.Marshal(l2Genesis) genesisBytes, err := json.Marshal(l2Genesis)
......
...@@ -249,3 +249,8 @@ func UseAltDA() bool { ...@@ -249,3 +249,8 @@ func UseAltDA() bool {
return (os.Getenv("OP_E2E_USE_ALTDA") == "true" || return (os.Getenv("OP_E2E_USE_ALTDA") == "true" ||
os.Getenv("DEVNET_ALTDA") == "true") os.Getenv("DEVNET_ALTDA") == "true")
} }
func UseMTCannon() bool {
return (os.Getenv("OP_E2E_USE_MT_CANNON") == "true" ||
os.Getenv("USE_MT_CANNON") == "true")
}
...@@ -38,6 +38,7 @@ import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol"; ...@@ -38,6 +38,7 @@ import { DelayedWETH } from "src/dispute/weth/DelayedWETH.sol";
import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol"; import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol"; import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { MIPS } from "src/cannon/MIPS.sol"; import { MIPS } from "src/cannon/MIPS.sol";
import { MIPS2 } from "src/cannon/MIPS2.sol";
import { StorageSetter } from "src/universal/StorageSetter.sol"; import { StorageSetter } from "src/universal/StorageSetter.sol";
// Libraries // Libraries
...@@ -827,16 +828,32 @@ contract Deploy is Deployer { ...@@ -827,16 +828,32 @@ contract Deploy is Deployer {
addr_ = address(preimageOracle); addr_ = address(preimageOracle);
} }
/// @notice Deploy Mips /// @notice Deploy Mips VM. Deploys either MIPS or MIPS2 depending on the environment
function deployMips() public broadcast returns (address addr_) { function deployMips() public broadcast returns (address addr_) {
if (Config.useMultithreadedCannon()) {
addr_ = _deployMips2();
} else {
addr_ = _deployMips();
}
save("Mips", address(addr_));
}
/// @notice Deploy MIPS
function _deployMips() internal returns (address addr_) {
console.log("Deploying Mips implementation"); console.log("Deploying Mips implementation");
MIPS mips = new MIPS{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle"))); MIPS mips = new MIPS{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle")));
save("Mips", address(mips));
console.log("MIPS deployed at %s", address(mips)); console.log("MIPS deployed at %s", address(mips));
addr_ = address(mips); addr_ = address(mips);
} }
/// @notice Deploy MIPS2
function _deployMips2() internal returns (address addr_) {
console.log("Deploying Mips2 implementation");
MIPS2 mips2 = new MIPS2{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle")));
console.log("MIPS2 deployed at %s", address(mips2));
addr_ = address(mips2);
}
/// @notice Deploy the AnchorStateRegistry /// @notice Deploy the AnchorStateRegistry
function deployAnchorStateRegistry() public broadcast returns (address addr_) { function deployAnchorStateRegistry() public broadcast returns (address addr_) {
console.log("Deploying AnchorStateRegistry implementation"); console.log("Deploying AnchorStateRegistry implementation");
...@@ -1405,25 +1422,14 @@ contract Deploy is Deployer { ...@@ -1405,25 +1422,14 @@ contract Deploy is Deployer {
}); });
} }
/// @notice Loads the mips absolute prestate from the prestate-proof for devnets otherwise /// @notice Load the appropriate mips absolute prestate for devenets depending on config environment.
/// from the config.
function loadMipsAbsolutePrestate() internal returns (Claim mipsAbsolutePrestate_) { function loadMipsAbsolutePrestate() internal returns (Claim mipsAbsolutePrestate_) {
if (block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet) { if (block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet) {
// Fetch the absolute prestate dump if (Config.useMultithreadedCannon()) {
string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof.json"); return _loadDevnetMtMipsAbsolutePrestate();
string[] memory commands = new string[](3); } else {
commands[0] = "bash"; return _loadDevnetStMipsAbsolutePrestate();
commands[1] = "-c";
commands[2] = string.concat("[[ -f ", filePath, " ]] && echo \"present\"");
if (Process.run(commands).length == 0) {
revert("Cannon prestate dump not found, generate it with `make cannon-prestate` in the monorepo root.");
} }
commands[2] = string.concat("cat ", filePath, " | jq -r .pre");
mipsAbsolutePrestate_ = Claim.wrap(abi.decode(Process.run(commands), (bytes32)));
console.log(
"[Cannon Dispute Game] Using devnet MIPS Absolute prestate: %s",
vm.toString(Claim.unwrap(mipsAbsolutePrestate_))
);
} else { } else {
console.log( console.log(
"[Cannon Dispute Game] Using absolute prestate from config: %x", cfg.faultGameAbsolutePrestate() "[Cannon Dispute Game] Using absolute prestate from config: %x", cfg.faultGameAbsolutePrestate()
...@@ -1432,6 +1438,48 @@ contract Deploy is Deployer { ...@@ -1432,6 +1438,48 @@ contract Deploy is Deployer {
} }
} }
/// @notice Loads the singlethreaded mips absolute prestate from the prestate-proof for devnets otherwise
/// from the config.
function _loadDevnetStMipsAbsolutePrestate() internal returns (Claim mipsAbsolutePrestate_) {
// Fetch the absolute prestate dump
string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof.json");
string[] memory commands = new string[](3);
commands[0] = "bash";
commands[1] = "-c";
commands[2] = string.concat("[[ -f ", filePath, " ]] && echo \"present\"");
if (Process.run(commands).length == 0) {
revert("Cannon prestate dump not found, generate it with `make cannon-prestate` in the monorepo root.");
}
commands[2] = string.concat("cat ", filePath, " | jq -r .pre");
mipsAbsolutePrestate_ = Claim.wrap(abi.decode(Process.run(commands), (bytes32)));
console.log(
"[Cannon Dispute Game] Using devnet MIPS Absolute prestate: %s",
vm.toString(Claim.unwrap(mipsAbsolutePrestate_))
);
}
/// @notice Loads the multithreaded mips absolute prestate from the prestate-proof-mt for devnets otherwise
/// from the config.
function _loadDevnetMtMipsAbsolutePrestate() internal returns (Claim mipsAbsolutePrestate_) {
// Fetch the absolute prestate dump
string memory filePath = string.concat(vm.projectRoot(), "/../../op-program/bin/prestate-proof-mt.json");
string[] memory commands = new string[](3);
commands[0] = "bash";
commands[1] = "-c";
commands[2] = string.concat("[[ -f ", filePath, " ]] && echo \"present\"");
if (Process.run(commands).length == 0) {
revert(
"MT-Cannon prestate dump not found, generate it with `make cannon-prestate-mt` in the monorepo root."
);
}
commands[2] = string.concat("cat ", filePath, " | jq -r .pre");
mipsAbsolutePrestate_ = Claim.wrap(abi.decode(Process.run(commands), (bytes32)));
console.log(
"[MT-Cannon Dispute Game] Using devnet MIPS2 Absolute prestate: %s",
vm.toString(Claim.unwrap(mipsAbsolutePrestate_))
);
}
/// @notice Sets the implementation for the `CANNON` game type in the `DisputeGameFactory` /// @notice Sets the implementation for the `CANNON` game type in the `DisputeGameFactory`
function setCannonFaultGameImplementation(bool _allowUpgrade) public broadcast { function setCannonFaultGameImplementation(bool _allowUpgrade) public broadcast {
console.log("Setting Cannon FaultDisputeGame implementation"); console.log("Setting Cannon FaultDisputeGame implementation");
......
...@@ -138,6 +138,11 @@ library Config { ...@@ -138,6 +138,11 @@ library Config {
} }
} }
/// @notice Returns true if multithreaded Cannon is used for the deployment.
function useMultithreadedCannon() internal view returns (bool _enabled) {
_enabled = vm.envOr("USE_MT_CANNON", false);
}
/// @notice Returns the latest fork to use for genesis allocs generation. /// @notice Returns the latest fork to use for genesis allocs generation.
/// It reads the fork from the environment variable FORK. If it is /// It reads the fork from the environment variable FORK. If it is
/// unset, NONE is returned. /// unset, NONE is returned.
......
...@@ -144,8 +144,8 @@ ...@@ -144,8 +144,8 @@
"sourceCodeHash": "0xee1aef5a502f9491b7b83dab46ea2f0fc286f87ace31edcc1367c840d462bdfe" "sourceCodeHash": "0xee1aef5a502f9491b7b83dab46ea2f0fc286f87ace31edcc1367c840d462bdfe"
}, },
"src/cannon/MIPS2.sol": { "src/cannon/MIPS2.sol": {
"initCodeHash": "0x3430ef0ee7697e7b98589deffb3a303cd8ce73bdc69df2edc5c957cee7486a72", "initCodeHash": "0xeab5f44d7fa7af1072f500c754bb55aa92409a79b2765a66efed47461c0c4049",
"sourceCodeHash": "0xb05a2081aa93881871d08bd95610639dfb64e5d3ce0e8fa5fd212e7ae3c3fe60" "sourceCodeHash": "0xcf180ff2cab8d0a34f3bb19d7145f5bf7f67dd379722ece765d09b38dcfed2f6"
}, },
"src/cannon/PreimageOracle.sol": { "src/cannon/PreimageOracle.sol": {
"initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b", "initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b",
......
...@@ -10,6 +10,19 @@ ...@@ -10,6 +10,19 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "constructor" "type": "constructor"
}, },
{
"inputs": [],
"name": "oracle",
"outputs": [
{
"internalType": "contract IPreimageOracle",
"name": "oracle_",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
......
...@@ -52,8 +52,8 @@ contract MIPS2 is ISemver { ...@@ -52,8 +52,8 @@ contract MIPS2 is ISemver {
} }
/// @notice The semantic version of the MIPS2 contract. /// @notice The semantic version of the MIPS2 contract.
/// @custom:semver 1.0.0-beta.7 /// @custom:semver 1.0.0-beta.8
string public constant version = "1.0.0-beta.7"; string public constant version = "1.0.0-beta.8";
/// @notice The preimage oracle contract. /// @notice The preimage oracle contract.
IPreimageOracle internal immutable ORACLE; IPreimageOracle internal immutable ORACLE;
...@@ -78,6 +78,12 @@ contract MIPS2 is ISemver { ...@@ -78,6 +78,12 @@ contract MIPS2 is ISemver {
ORACLE = _oracle; ORACLE = _oracle;
} }
/// @notice Getter for the pre-image oracle contract.
/// @return oracle_ The IPreimageOracle contract.
function oracle() external view returns (IPreimageOracle oracle_) {
oracle_ = ORACLE;
}
/// @notice Executes a single step of the multi-threaded vm. /// @notice Executes a single step of the multi-threaded vm.
/// Will revert if any required input state is missing. /// Will revert if any required input state is missing.
/// @param _stateData The encoded state witness data. /// @param _stateData The encoded state witness data.
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
import { ISemver } from "src/universal/interfaces/ISemver.sol"; import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol";
/// @title IMIPS2 /// @title IMIPS2
/// @notice Interface for the MIPS2 contract. /// @notice Interface for the MIPS2 contract.
...@@ -10,5 +11,6 @@ interface IMIPS2 is ISemver { ...@@ -10,5 +11,6 @@ interface IMIPS2 is ISemver {
error InvalidMemoryProof(); error InvalidMemoryProof();
error InvalidSecondMemoryProof(); error InvalidSecondMemoryProof();
function oracle() external view returns (IPreimageOracle oracle_);
function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32); function step(bytes memory _stateData, bytes memory _proof, bytes32 _localContext) external returns (bytes32);
} }
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