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:
- run:
name: Copy AltDA allocs to .devnet-altda
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:
name: Generate default allocs
command: make devnet-allocs
......@@ -279,6 +285,12 @@ jobs:
- ".devnet-altda-generic/allocs-l2-ecotone.json"
- ".devnet-altda-generic/allocs-l2-fjord.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/deployments/devnetL1"
- notify-failures-on-develop
......@@ -928,6 +940,13 @@ jobs:
- run:
name: Set OP_E2E_USE_ALTDA = true
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:
patterns: op-(.+),cannon,contracts-bedrock
- run:
......@@ -1071,6 +1090,16 @@ jobs:
- "op-program/bin/prestate.json"
- "op-program/bin/meta.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:
name: Save Go build cache
key: golang-build-cache-cannon-prestate-{{ checksum "go.sum" }}
......@@ -2078,7 +2107,12 @@ workflows:
- go-mod-download
- contracts-bedrock-build
- 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
target: test-cannon
parallelism: 4
......
......@@ -134,10 +134,12 @@ reproducible-prestate: ## Builds reproducible-prestate binary
.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.
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):
make cannon-prestate
make cannon-prestate-mt
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
......
......@@ -40,8 +40,9 @@ test-devnet: pre-test
$(go_test) $(go_test_flags) ./devnet
.PHONY: test-devnet
cannon-prestate:
cannon-prestates:
make -C .. cannon-prestate
make -C .. cannon-prestate-mt
.PHONY: cannon-prestate
# 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
pre-test-cannon:
@if [ ! -e ../op-program/bin ]; then \
make cannon-prestate; \
make cannon-prestates; \
fi
.PHONY: pre-test-cannon
......
......@@ -106,7 +106,12 @@ func applyCannonConfig(c *config.Config, t *testing.T, rollupCfg *rollup.Config,
root := FindMonorepoRoot(t)
c.Cannon.VmBin = root + "cannon/bin/cannon"
c.Cannon.Server = root + "op-program/bin/op-program"
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
genesisBytes, err := json.Marshal(l2Genesis)
......
......@@ -249,3 +249,8 @@ func UseAltDA() bool {
return (os.Getenv("OP_E2E_USE_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";
import { AnchorStateRegistry } from "src/dispute/AnchorStateRegistry.sol";
import { PreimageOracle } from "src/cannon/PreimageOracle.sol";
import { MIPS } from "src/cannon/MIPS.sol";
import { MIPS2 } from "src/cannon/MIPS2.sol";
import { StorageSetter } from "src/universal/StorageSetter.sol";
// Libraries
......@@ -827,16 +828,32 @@ contract Deploy is Deployer {
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_) {
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");
MIPS mips = new MIPS{ salt: _implSalt() }(IPreimageOracle(mustGetAddress("PreimageOracle")));
save("Mips", address(mips));
console.log("MIPS deployed at %s", 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
function deployAnchorStateRegistry() public broadcast returns (address addr_) {
console.log("Deploying AnchorStateRegistry implementation");
......@@ -1405,10 +1422,25 @@ contract Deploy is Deployer {
});
}
/// @notice Loads the mips absolute prestate from the prestate-proof for devnets otherwise
/// from the config.
/// @notice Load the appropriate mips absolute prestate for devenets depending on config environment.
function loadMipsAbsolutePrestate() internal returns (Claim mipsAbsolutePrestate_) {
if (block.chainid == Chains.LocalDevnet || block.chainid == Chains.GethDevnet) {
if (Config.useMultithreadedCannon()) {
return _loadDevnetMtMipsAbsolutePrestate();
} else {
return _loadDevnetStMipsAbsolutePrestate();
}
} else {
console.log(
"[Cannon Dispute Game] Using absolute prestate from config: %x", cfg.faultGameAbsolutePrestate()
);
mipsAbsolutePrestate_ = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate()));
}
}
/// @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);
......@@ -1424,12 +1456,28 @@ contract Deploy is Deployer {
"[Cannon Dispute Game] Using devnet MIPS Absolute prestate: %s",
vm.toString(Claim.unwrap(mipsAbsolutePrestate_))
);
} else {
console.log(
"[Cannon Dispute Game] Using absolute prestate from config: %x", cfg.faultGameAbsolutePrestate()
}
/// @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."
);
mipsAbsolutePrestate_ = Claim.wrap(bytes32(cfg.faultGameAbsolutePrestate()));
}
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`
......
......@@ -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.
/// It reads the fork from the environment variable FORK. If it is
/// unset, NONE is returned.
......
......@@ -144,8 +144,8 @@
"sourceCodeHash": "0xee1aef5a502f9491b7b83dab46ea2f0fc286f87ace31edcc1367c840d462bdfe"
},
"src/cannon/MIPS2.sol": {
"initCodeHash": "0x3430ef0ee7697e7b98589deffb3a303cd8ce73bdc69df2edc5c957cee7486a72",
"sourceCodeHash": "0xb05a2081aa93881871d08bd95610639dfb64e5d3ce0e8fa5fd212e7ae3c3fe60"
"initCodeHash": "0xeab5f44d7fa7af1072f500c754bb55aa92409a79b2765a66efed47461c0c4049",
"sourceCodeHash": "0xcf180ff2cab8d0a34f3bb19d7145f5bf7f67dd379722ece765d09b38dcfed2f6"
},
"src/cannon/PreimageOracle.sol": {
"initCodeHash": "0x801e52f9c8439fcf7089575fa93272dfb874641dbfc7d82f36d979c987271c0b",
......
......@@ -10,6 +10,19 @@
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "oracle",
"outputs": [
{
"internalType": "contract IPreimageOracle",
"name": "oracle_",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
......
......@@ -52,8 +52,8 @@ contract MIPS2 is ISemver {
}
/// @notice The semantic version of the MIPS2 contract.
/// @custom:semver 1.0.0-beta.7
string public constant version = "1.0.0-beta.7";
/// @custom:semver 1.0.0-beta.8
string public constant version = "1.0.0-beta.8";
/// @notice The preimage oracle contract.
IPreimageOracle internal immutable ORACLE;
......@@ -78,6 +78,12 @@ contract MIPS2 is ISemver {
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.
/// Will revert if any required input state is missing.
/// @param _stateData The encoded state witness data.
......
......@@ -2,6 +2,7 @@
pragma solidity ^0.8.0;
import { ISemver } from "src/universal/interfaces/ISemver.sol";
import { IPreimageOracle } from "src/cannon/interfaces/IPreimageOracle.sol";
/// @title IMIPS2
/// @notice Interface for the MIPS2 contract.
......@@ -10,5 +11,6 @@ interface IMIPS2 is ISemver {
error InvalidMemoryProof();
error InvalidSecondMemoryProof();
function oracle() external view returns (IPreimageOracle oracle_);
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