Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
27e4cdf
wip
Apr 21, 2021
d4da797
Update service.ts
Apr 21, 2021
56f5079
wip
Apr 21, 2021
a413738
wip - ts compiles
Apr 21, 2021
d39afca
Delete .DS_Store
jliphard Apr 21, 2021
faeca27
Delete .DS_Store
jliphard Apr 21, 2021
63762a2
Delete .DS_Store
jliphard Apr 21, 2021
f01a9a1
Update .gitignore
Apr 21, 2021
7930e09
Merge branch 'add_fraud_prover' of github.com:jliphard/optimism into …
Apr 21, 2021
618c7f6
Update .gitignore
Apr 21, 2021
f50a452
remove .d.ts files - sorry
Apr 21, 2021
56c8758
Update .gitignore
jliphard Apr 21, 2021
48a2d1a
lint
Apr 21, 2021
ecc9ca1
fix lint and add basic documentation and set up
Apr 22, 2021
ac81f4b
Update ovmcontext.spec.ts
Apr 22, 2021
36bd424
undo lint changes in other part of the repo
Apr 22, 2021
aa4812b
undo lint changes
Apr 22, 2021
b3b86e1
undo certain lint changes
Apr 22, 2021
12210f5
final lint issues
Apr 22, 2021
ba3d53f
Update service.ts
jliphard Apr 22, 2021
9496cd0
Delete yarn-error.log
jliphard Apr 22, 2021
2665332
Delete yarn-error.log
jliphard Apr 22, 2021
ab93f55
delete error logs
Apr 22, 2021
da72af4
Merge branch 'wip' of github.com:jliphard/optimism into wip
Apr 22, 2021
54d4723
Delete yarn.lock
jliphard Apr 22, 2021
283127c
Document spinup of a basic Verifier / Fraud prover pair
Apr 22, 2021
863bbd1
Merge pull request #2 from jliphard/wip
jliphard Apr 22, 2021
d79ba0e
renamed run-fraud-prover -> run for consistency with other packages
Apr 22, 2021
cec6ccd
Create yarn.lock
Apr 23, 2021
a511fed
Improved wording
Apr 23, 2021
ce696e6
Update yarn.lock
Apr 23, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@ packages/data-transport-layer/db
*.swp

.env
.DS_Store
*.spec.ts
*.d.ts
12 changes: 12 additions & 0 deletions packages/fraud-prover/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Universal Options
L1_NODE_WEB3_URL=http://localhost:9545
L2_NODE_WEB3_URL=http://localhost:8045
L1_WALLET_KEY=0x00000000000000000000000000000000000000000000000
RELAY_GAS_LIMIT=4000000
POLLING_INTERVAL=5000
L2_BLOCK_OFFSET=1
L1_START_OFFSET=0
L1_BLOCK_FINALITY=0
FROM_L2_TRANSACTION_INDEX=0
RUN_GAS_LIMIT=9500000
ADDRESS_MANAGER_ADDRESS=
1 change: 1 addition & 0 deletions packages/fraud-prover/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# @eth-optimism/fraud-prover
239 changes: 239 additions & 0 deletions packages/fraud-prover/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
# Fraud Prover

Contains an executable fraud prover.

## Configuration

All configuration is done via environment variables. See below for more information.

## Building & Running

1. Make sure dependencies are installed just run `yarn` in the base directory
2. Build `yarn build`
3. Run `yarn start`

## Testing & linting

- See lint errors with `yarn lint`; auto-fix with `yarn lint --fix`

## Envs (Need to reconcile with the below - ToDo)

| Environment Variable | Required? | Default Value | Description |
| ----------- | --------- | ------------- | ----------- |
| `L1_WALLET_KEY` | Yes | N/A | Private key for an account on Layer 1 (Ethereum) to be used to submit fraud proof transactions. |
| `L2_NODE_WEB3_URL` | No | http://localhost:9545 | HTTP endpoint for a Layer 2 (Optimism) Verifier node. |
| `L1_NODE_WEB3_URL` | No | http://localhost:8545 | HTTP endpoint for a Layer 1 (Ethereum) node. |
| `RELAY_GAS_LIMIT` | No | 9,000,000 | Maximum amount of gas to provide to fraud proof transactions (except for the "transaction execution" step). |
| `RUN_GAS_LIMIT` | No | 9,000,000 | Maximum amount of gas to provide to the "transaction execution" step. |
| `POLLING_INTERVAL` | No | 5,000 | Time (in milliseconds) to wait while polling for new transactions. |
| `L2_BLOCK_OFFSET` | No | 1 | Offset between the `CanonicalTransactionChain` contract on Layer 1 and the blocks on Layer 2. Currently defaults to 1, but will likely be removed as soon as possible. |
| `L1_BLOCK_FINALITY` | No | 0 | Number of Layer 1 blocks to wait before considering a given event. |
| `L1_START_OFFSET` | No | 0 | Layer 1 block number to start scanning for transactions from. |
| `FROM_L2_TRANSACTION_INDEX` | No | 0 | Layer 2 block number to start scanning for transactions from. |

## Local testing

The fraud prover will first connect to the relevant chains and then look for mismatched state roots. Note that the *Fraud Prover* does not connect to the *Sequencer*, rather, it connects to the *Verifier*, and the Verifier in turn is looking at the L1. Assuming _your sequencer is not fraudulant_, the standard Fraud Prover output looks like this:

```

{"level":30,"time":1619122304289,"msg":"Looking for mismatched state roots..."}
{"level":30,"time":1619122304295,"nextAttemptInS":5,"msg":"Did not find any mismatched state roots"}
{"level":30,"time":1619122309301,"msg":"Looking for mismatched state roots..."}
{"level":30,"time":1619122309306,"nextAttemptInS":5,"msg":"Did not find any mismatched state roots"}
{"level":30,"time":1619122314311,"msg":"Looking for mismatched state roots..."}

```

When you spin up your local test system some small changes to the generic `local.env.yaml` and `local.yaml` are needed. Also, you will have to provide two extra files, `wait-for-l1-and-l2.sh`. For your testing conveniance, also adding a `Dockerfile.fraud_prover`.

### local.yaml Settings

Add to your `local.yaml`
```
all the usual things here (L2, Batch submitter, Message Relay, Hardhat, Deployer), but then...

verifier:
image: ethereumoptimism/go-ethereum
volumes:
- verifier:/root/.ethereum:rw
ports:
- 8045:8045
- 8046:8046

fraud_prover:
image: ethereumoptimism/fraud-prover:latest

volumes:

geth:

verifier:
```

### local.env.yaml Settings

Add to your `local.env.yaml`
```

x-var: &L1_NODE_WEB3_URL
L1_NODE_WEB3_URL=http://l1_chain:9545

x-var: &DEPLOYER_HTTP
DEPLOYER_HTTP=http://deployer:8080

x-var: &ADDRESS_MANAGER_ADDRESS
ADDRESS_MANAGER_ADDRESS=0xYOUR_ADDRESS_MANAGER_HERE

services:

all the usual things here (L2, Batch submitter, Message Relay, Hardhat, Deployer), but then...

verifier:
environment:
- *DEPLOYER_HTTP
- *L1_NODE_WEB3_URL
- ROLLUP_VERIFIER_ENABLE=true
- ETH1_SYNC_SERVICE_ENABLE=true
- ETH1_CTC_DEPLOYMENT_HEIGHT=8
- ETH1_CONFIRMATION_DEPTH=0
- ROLLUP_CLIENT_HTTP=http://data_transport_layer:7878
- ROLLUP_POLL_INTERVAL_FLAG=3s
- USING_OVM=true
- CHAIN_ID=420
- NETWORK_ID=420
- DEV=true
- DATADIR=/root/.ethereum
- RPC_ENABLE=true
- RPC_ADDR=verifier
- RPC_CORS_DOMAIN=*
- RPC_VHOSTS=*
- RPC_PORT=8045
- WS=true
- WS_ADDR=0.0.0.0
- IPC_DISABLE=true
- TARGET_GAS_LIMIT=9000000
- RPC_API=eth,net,rollup,web3
- WS_API=eth,net,rollup,web3
- WS_ORIGINS=*
- GASPRICE=0
- NO_USB=true
- GCMODE=archive
- NO_DISCOVER=true
- ROLLUP_STATE_DUMP_PATH=http://deployer:8080/dumps/state-dump.latest.json
- RETRIES=60

fraud_prover:
environment:
- NO_TIMEOUT=true
- *L1_NODE_WEB3_URL
- *ADDRESS_MANAGER_ADDRESS
- L2_NODE_WEB3_URL=http://verifier:8045
- L1_WALLET_KEY=0xYOUR_FP_WALLET_KEY_HERE
- POLLING_INTERVAL=5000
- RUN_GAS_LIMIT=8999999
- RELAY_GAS_LIMIT=8999999
- FROM_L2_TRANSACTION_INDEX=0
- L2_BLOCK_OFFSET=1
- L1_START_OFFSET=8
- RETRIES=60
```

### Fraud Prover spinup wait-for-l1-and-l2.sh

```bash

#!/bin/bash

# Copyright Optimism PBC 2020
# MIT License
# github.com/ethereum-optimism

cmd="$@"
JSON='{"jsonrpc":"2.0","id":0,"method":"net_version","params":[]}'

RETRIES=${RETRIES:-50}
until $(curl --silent --fail \
--output /dev/null \
-H "Content-Type: application/json" \
--data "$JSON" "$L1_NODE_WEB3_URL"); do
sleep 1
echo "Will wait $((RETRIES--)) more times for $L1_NODE_WEB3_URL to be up..."

if [ "$RETRIES" -lt 0 ]; then
echo "Timeout waiting for layer one node at $L1_NODE_WEB3_URL"
exit 1
fi
done
echo "Connected to L1 Node at $L1_NODE_WEB3_URL"

RETRIES=${RETRIES:-50}
until $(curl --silent --fail \
--output /dev/null \
-H "Content-Type: application/json" \
--data "$JSON" "$L2_NODE_WEB3_URL"); do
sleep 1
echo "Will wait $((RETRIES--)) more times for $L2_NODE_WEB3_URL to be up..."

if [ "$RETRIES" -lt 0 ]; then
echo "Timeout waiting for layer two node at $L2_NODE_WEB3_URL"
exit 1
fi
done
echo "Connected to L2 Verifier Node at $L2_NODE_WEB3_URL"

if [ ! -z "$DEPLOYER_HTTP" ]; then
RETRIES=${RETRIES:-50}
until $(curl --silent --fail \
--output /dev/null \
"$DEPLOYER_HTTP/addresses.json"); do
sleep 1
echo "Will wait $((RETRIES--)) more times for $DEPLOYER_HTTP to be up..."

if [ "$RETRIES" -lt 0 ]; then
echo "Timeout waiting for contract deployment"
exit 1
fi
done
echo "Contracts are deployed"
ADDRESS_MANAGER_ADDRESS=$(curl --silent $DEPLOYER_HTTP/addresses.json | jq -r .AddressManager)
exec env \
ADDRESS_MANAGER_ADDRESS=$ADDRESS_MANAGER_ADDRESS \
L1_BLOCK_OFFSET=$L1_BLOCK_OFFSET \
$cmd
else
exec $cmd
fi

```

### Fraud Prover Dockerfile.fraud_prover

```

FROM node:14-buster as base

RUN apt-get update && apt-get install -y bash curl jq

FROM base as build

RUN apt-get update && apt-get install -y bash git python build-essential

ADD . /opt/fraud-prover

RUN cd /opt/fraud-prover yarn install yarn build

FROM base

RUN apt-get update && apt-get install -y bash curl jq

COPY --from=build /opt/fraud-prover /opt/fraud-prover

COPY wait-for-l1-and-l2.sh /opt/
RUN chmod +x /opt/wait-for-l1-and-l2.sh
RUN chmod +x /opt/fraud-prover/exec/run.js
RUN ln -s /opt/fraud-prover/exec/run.js /usr/local/bin/

ENTRYPOINT ["/opt/wait-for-l1-and-l2.sh", "run.js"]

```
10 changes: 10 additions & 0 deletions packages/fraud-prover/exec/run.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env node

const main = require("../dist/exec/run").default

;(async () => {
await main()
})().catch((err) => {
console.log(err)
process.exit(1)
})
41 changes: 41 additions & 0 deletions packages/fraud-prover/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "@eth-optimism/fraud-prover",
"version": "0.0.1",
"private": true,
"description": "[Optimism] Fraud Prover Service",
"main": "dist/index",
"types": "dist/index",
"files": [
"dist/index"
],
"scripts": {
"start": "node ./exec/run.js",
"build": "tsc -p ./tsconfig.build.json",
"clean": "rimraf dist/ ./tsconfig.build.tsbuildinfo",
"lint": "yarn lint:fix && yarn lint:check",
"lint:check": "tslint --format stylish --project .",
"lint:fix": "prettier --config prettier-config.json --write \"{src,exec,test}/**/*.ts\""
},
"keywords": [
"optimism",
"ethereum",
"fraud-prover"
],
"homepage": "https://github.com/ethereum-optimism/optimism-monorepo/tree/master/packages/fraud-prover#readme",
"license": "MIT",
"author": "Optimism",
"repository": {
"type": "git",
"url": "https://github.com/ethereum-optimism/optimism.git"
},
"dependencies": {
"@eth-optimism/core-utils": "^0.2.0",
"@eth-optimism/contracts": "^0.2.2",
"ethereumjs-util": "^7.0.7",
"dotenv": "^8.2.0",
"ethers": "^5.1.0",
"merkle-patricia-tree": "^4.0.0",
"merkletreejs": "^0.2.18",
"rlp": "^2.2.6"
}
}
1 change: 1 addition & 0 deletions packages/fraud-prover/prettier-config.json
63 changes: 63 additions & 0 deletions packages/fraud-prover/src/exec/run.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { Wallet, providers } from 'ethers'
import { FraudProverService } from '../service'
import { config } from 'dotenv'
config()

const env = process.env
const L2_NODE_WEB3_URL = env.L2_NODE_WEB3_URL
const L1_NODE_WEB3_URL = env.L1_NODE_WEB3_URL
const ADDRESS_MANAGER_ADDRESS = env.ADDRESS_MANAGER_ADDRESS
const L1_WALLET_KEY = env.L1_WALLET_KEY
const MNEMONIC = env.MNEMONIC
const HD_PATH = env.HD_PATH
const RELAY_GAS_LIMIT = env.RELAY_GAS_LIMIT || '4000000'
const RUN_GAS_LIMIT = env.RUN_GAS_LIMIT || '95000000'
const POLLING_INTERVAL = env.POLLING_INTERVAL || '5000'
//const GET_LOGS_INTERVAL = env.GET_LOGS_INTERVAL || '2000'
const L2_BLOCK_OFFSET = env.L2_BLOCK_OFFSET || '1'
const L1_START_OFFSET = env.L1_BLOCK_OFFSET || '1'
const L1_BLOCK_FINALITY = env.L1_BLOCK_FINALITY || '0'
const FROM_L2_TRANSACTION_INDEX = env.FROM_L2_TRANSACTION_INDEX || '0'

const main = async () => {
if (!ADDRESS_MANAGER_ADDRESS) {
throw new Error('Must pass ADDRESS_MANAGER_ADDRESS')
}
if (!L1_NODE_WEB3_URL) {
throw new Error('Must pass L1_NODE_WEB3_URL')
}
if (!L2_NODE_WEB3_URL) {
throw new Error('Must pass L2_NODE_WEB3_URL')
}

const l2Provider = new providers.JsonRpcProvider(L2_NODE_WEB3_URL)
const l1Provider = new providers.JsonRpcProvider(L1_NODE_WEB3_URL)

let wallet: Wallet
if (L1_WALLET_KEY) {
wallet = new Wallet(L1_WALLET_KEY, l1Provider)
} else if (MNEMONIC) {
wallet = Wallet.fromMnemonic(MNEMONIC, HD_PATH)
wallet = wallet.connect(l1Provider)
} else {
throw new Error('Must pass one of L1_WALLET_KEY or MNEMONIC')
}

const service = new FraudProverService({
l1RpcProvider: l1Provider,
l2RpcProvider: l2Provider,
addressManagerAddress: ADDRESS_MANAGER_ADDRESS,
l1Wallet: wallet,
deployGasLimit: parseInt(RELAY_GAS_LIMIT, 10), //should reconcile naming
runGasLimit: parseInt(RUN_GAS_LIMIT, 10), //should reconcile naming
fromL2TransactionIndex: parseInt(FROM_L2_TRANSACTION_INDEX, 10),
pollingInterval: parseInt(POLLING_INTERVAL, 10),
l2BlockOffset: parseInt(L2_BLOCK_OFFSET, 10),
l1StartOffset: parseInt(L1_START_OFFSET, 10),
l1BlockFinality: parseInt(L1_BLOCK_FINALITY, 10),
//getLogsInterval: parseInt(GET_LOGS_INTERVAL, 10),
})

await service.start()
}
export default main
Loading