From 6bf8ea1310cdb7fa60177ae9d07c4cc120f93a9d Mon Sep 17 00:00:00 2001 From: clabby Date: Fri, 31 Mar 2023 20:58:37 -0400 Subject: [PATCH] Add mock dispute game factory / OP stack devnet script --- .env.devnet | 6 +-- .gitmodules | 3 ++ bin/src/op-challenger.rs | 11 +++--- start_devnet.sh | 19 ++++++++++ testdata/README.md | 3 ++ testdata/mock-dgf/.gitignore | 14 +++++++ testdata/mock-dgf/foundry.toml | 7 ++++ testdata/mock-dgf/lib/forge-std | 1 + testdata/mock-dgf/script/DeployMocks.s.sol | 18 +++++++++ .../mock-dgf/src/MockDisputeGameFactory.sol | 38 +++++++++++++++++++ .../src/MockDisputeGame_OutputAttestation.sol | 11 ++++++ testdata/mock-dgf/test/Mocks.t.sol | 23 +++++++++++ 12 files changed, 146 insertions(+), 8 deletions(-) create mode 100644 .gitmodules create mode 100755 start_devnet.sh create mode 100644 testdata/README.md create mode 100644 testdata/mock-dgf/.gitignore create mode 100644 testdata/mock-dgf/foundry.toml create mode 160000 testdata/mock-dgf/lib/forge-std create mode 100644 testdata/mock-dgf/script/DeployMocks.s.sol create mode 100644 testdata/mock-dgf/src/MockDisputeGameFactory.sol create mode 100644 testdata/mock-dgf/src/MockDisputeGame_OutputAttestation.sol create mode 100644 testdata/mock-dgf/test/Mocks.t.sol diff --git a/.env.devnet b/.env.devnet index 7462b5a..48cb47f 100644 --- a/.env.devnet +++ b/.env.devnet @@ -1,9 +1,9 @@ # Devnet Specs: https://github.com/ethereum-optimism/optimism/blob/develop/specs/meta/devnet.md -export OP_CHALLENGER_KEY="0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" +export OP_CHALLENGER_KEY="ac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80" export OP_CHALLENGER_L1_WS="ws://127.0.0.1:8546" export OP_CHALLENGER_TRUSTED_OP_NODE_RPC="http://localhost:7545" export OP_CHALLENGER_L2OO="0x6900000000000000000000000000000000000000" -# TODO -export OP_CHALLENGER_DGF="0x0000000000000000000000000000000000000000" +# Paste the DisputeGameFactory env variable logged by `start_devnet.sh` here. + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..2ddf5a7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "testdata/mock-dgf/lib/forge-std"] + path = testdata/mock-dgf/lib/forge-std + url = https://github.com/foundry-rs/forge-std diff --git a/bin/src/op-challenger.rs b/bin/src/op-challenger.rs index 7f4cb5b..a55979b 100644 --- a/bin/src/op-challenger.rs +++ b/bin/src/op-challenger.rs @@ -3,7 +3,7 @@ use anyhow::{anyhow, Result}; use clap::{ArgAction, Parser}; use ethers::{ - prelude::{Address, Provider, SignerMiddleware, Ws}, + prelude::{Address, MiddlewareBuilder, Provider, Ws}, providers::Http, }; use op_challenger_driver::{ @@ -90,10 +90,11 @@ async fn main() -> Result<()> { // Connect to the websocket endpoint. tracing::debug!(target: "op-challenger-cli", "Connecting to websocket endpoint..."); - let ws_endpoint = Arc::new(SignerMiddleware::new( - Provider::::connect(driver_config.l1_ws_endpoint.clone()).await?, - signer_key.parse()?, - )); + let ws_endpoint = Arc::new( + Provider::::connect(driver_config.l1_ws_endpoint.clone()) + .await? + .with_signer(signer_key.parse()?), + ); tracing::info!(target: "op-challenger-cli", "Websocket connected successfully @ {}", &driver_config.l1_ws_endpoint); // Connect to the node endpoint. diff --git a/start_devnet.sh b/start_devnet.sh new file mode 100755 index 0000000..0d0c929 --- /dev/null +++ b/start_devnet.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Set up environment variables +source .env.devnet + +# Change accordingly +MONOREPO_DIR="$HOME/dev/optimism/monorepo" + +# Boot up the devnet +(cd $MONOREPO_DIR && make devnet-up) + +# Deploy the mock dispute game contract +(cd ./testdata/mock-dgf && forge script script/DeployMocks.s.sol --rpc-url http://localhost:8545 --private-key $OP_CHALLENGER_KEY --broadcast) + +echo "----------------------------------------------------------------" +echo " - Paste the environment variable logged by the forge script" +echo " - into the \`.env.devnet\` file and then source it again before" +echo " - running the \`op-challenger\`." +echo "----------------------------------------------------------------" diff --git a/testdata/README.md b/testdata/README.md new file mode 100644 index 0000000..b61e878 --- /dev/null +++ b/testdata/README.md @@ -0,0 +1,3 @@ +# `testdata` + +Various periphery components used for testing the `op-challenger`. diff --git a/testdata/mock-dgf/.gitignore b/testdata/mock-dgf/.gitignore new file mode 100644 index 0000000..85198aa --- /dev/null +++ b/testdata/mock-dgf/.gitignore @@ -0,0 +1,14 @@ +# Compiler files +cache/ +out/ + +# Ignores development broadcast logs +!/broadcast +/broadcast/*/31337/ +/broadcast/**/dry-run/ + +# Docs +docs/ + +# Dotenv file +.env diff --git a/testdata/mock-dgf/foundry.toml b/testdata/mock-dgf/foundry.toml new file mode 100644 index 0000000..47621a0 --- /dev/null +++ b/testdata/mock-dgf/foundry.toml @@ -0,0 +1,7 @@ +[profile.default] +src = 'src' +out = 'out' +libs = ['lib'] + +[fmt] +bracket_spacing = true diff --git a/testdata/mock-dgf/lib/forge-std b/testdata/mock-dgf/lib/forge-std new file mode 160000 index 0000000..8d0971b --- /dev/null +++ b/testdata/mock-dgf/lib/forge-std @@ -0,0 +1 @@ +Subproject commit 8d0971b66e204e20782e2d01855deb02736b0e48 diff --git a/testdata/mock-dgf/script/DeployMocks.s.sol b/testdata/mock-dgf/script/DeployMocks.s.sol new file mode 100644 index 0000000..01d0343 --- /dev/null +++ b/testdata/mock-dgf/script/DeployMocks.s.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Script.sol"; +import { MockDisputeGameFactory } from "src/MockDisputeGameFactory.sol"; +import { MockDisputeGame_OutputAttestation } from "src/MockDisputeGame_OutputAttestation.sol"; + +/// @notice This script deploys the mock dispute game factory. +contract DeployMocks is Script { + function run() public { + // Deploy the mock dispute game factory + vm.broadcast(); + MockDisputeGameFactory mock = new MockDisputeGameFactory(); + + // Write the address to the devnet ENV + console.log(string.concat("ENV Variable: export OP_CHALLENGER_DGF=\"", vm.toString(address(mock)), "\"")); + } +} diff --git a/testdata/mock-dgf/src/MockDisputeGameFactory.sol b/testdata/mock-dgf/src/MockDisputeGameFactory.sol new file mode 100644 index 0000000..535f974 --- /dev/null +++ b/testdata/mock-dgf/src/MockDisputeGameFactory.sol @@ -0,0 +1,38 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +import { MockDisputeGame_OutputAttestation } from "./MockDisputeGame_OutputAttestation.sol"; + +/// @notice The type of proof system being used. +enum GameType { + /// @dev The game will use a `IDisputeGame` implementation that utilizes fault proofs. + FAULT, + /// @dev The game will use a `IDisputeGame` implementation that utilizes validity proofs. + VALIDITY, + /// @dev The game will use a `IDisputeGame` implementation that utilizes attestation proofs. + ATTESTATION +} + +/// @notice A `Claim` type represents a 32 byte hash or other unique identifier for a claim about +/// a certain piece of information. +/// @dev For the `FAULT` `GameType`, this will be a root of the merklized state of the fault proof +/// program at the end of the state transition. +/// For the `ATTESTATION` `GameType`, this will be an output root. +type Claim is bytes32; + +/// @title MockDisputeGameFactory +/// @dev This contract is used for testing the `op-challenger`'s `OutputAttestationDriver` +/// on a local devnet. +contract MockDisputeGameFactory { + event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim); + + /// @notice Creates a new DisputeGame proxy contract. + /// @param gameType The type of the DisputeGame - used to decide the proxy implementation + /// @param rootClaim The root claim of the DisputeGame. + /// @param extraData Any extra data that should be provided to the created dispute game. + function create(GameType gameType, Claim rootClaim, bytes calldata extraData) external returns (MockDisputeGame_OutputAttestation mock) { + mock = new MockDisputeGame_OutputAttestation(); + emit DisputeGameCreated(address(mock), gameType, rootClaim); + extraData; // Unused + } +} diff --git a/testdata/mock-dgf/src/MockDisputeGame_OutputAttestation.sol b/testdata/mock-dgf/src/MockDisputeGame_OutputAttestation.sol new file mode 100644 index 0000000..19a34b8 --- /dev/null +++ b/testdata/mock-dgf/src/MockDisputeGame_OutputAttestation.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +/// @title MockDisputeGame_OutputAttestation +/// @dev This contract is used for testing the `op-challenger`'s `OutputAttestationDriver` +/// on a local devnet. +contract MockDisputeGame_OutputAttestation { + function challenge(bytes calldata _signature) external { + // Do nothing + } +} diff --git a/testdata/mock-dgf/test/Mocks.t.sol b/testdata/mock-dgf/test/Mocks.t.sol new file mode 100644 index 0000000..874ed09 --- /dev/null +++ b/testdata/mock-dgf/test/Mocks.t.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.13; + +import "forge-std/Test.sol"; +import { MockDisputeGameFactory, GameType, Claim } from "src/MockDisputeGameFactory.sol"; + +contract MocksTest is Test { + MockDisputeGameFactory factory; + + event DisputeGameCreated(address indexed disputeProxy, GameType indexed gameType, Claim indexed rootClaim); + + function setUp() public { + factory = new MockDisputeGameFactory(); + } + + function testCreate(uint8 gameType, Claim rootClaim, bytes calldata extraData) external { + vm.assume(gameType <= 2); + + vm.expectEmit(false, true, true, false); + emit DisputeGameCreated(address(0), GameType(gameType), rootClaim); + factory.create(GameType(gameType), rootClaim, extraData); + } +}