From c2bd5e32d2e84eef8cb6ced5d63b002911301810 Mon Sep 17 00:00:00 2001 From: Ino Murko Date: Mon, 21 Feb 2022 23:15:53 +0100 Subject: [PATCH] Brown bear v0.0.5 (#410) * [Geth] Fix msg.sender in turing (#405) * Fix msg.sender in turing * Update gas price (cherry picked from commit 693f8d45d75ef4b2a40b52ce0687538702026a29) * Update image tags (#401) Co-authored-by: CAPtheorem <79423264+CAPtheorem@users.noreply.github.com> (cherry picked from commit 01b288b2bb548909c2cd65aed081a19c2ed16729) * [Community Verifier] Update images for community verifier (#402) * Update image tags * Fix a docker tag. Changes to be committed: modified: boba_community/fraud-detector/docker-compose-fraud-detector.yml Co-authored-by: Michael Montour Co-authored-by: CAPtheorem <79423264+CAPtheorem@users.noreply.github.com> (cherry picked from commit 8c1b041defcf75a99826afe8837ad58204985d99) * Clean dtl logs (#403) Co-authored-by: CAPtheorem <79423264+CAPtheorem@users.noreply.github.com> (cherry picked from commit 55afe5b053b2b361098555d608a53d7523dc5a05) * reduce the upstream diff (#407) * reduce the upstream diff * Update config.go Boba fork numbers (cherry picked from commit 94a3960961c73f4a18530397d1a21b73d6e4f18e) * disable cache (#408) * disable cache * make lint * minor odds and ends; remove stale documentation * update tests (cherry picked from commit 055822900f7d59a2bd91de229d7bf9f2e99652be) * [ops] Enable RPC forward (#381) * Enable RPC forward * Fix typo Co-authored-by: Ino Murko Co-authored-by: CAPtheorem <79423264+CAPtheorem@users.noreply.github.com> (cherry picked from commit f18e74d677b2986ec1c8076ba8ffc4d728a62f19) * doc: add price data feed overview (#409) * add md * rem image * Update Price_Data_Feeds_Overview.md Co-authored-by: CAPtheorem <79423264+CAPtheorem@users.noreply.github.com> (cherry picked from commit 021add65aa25deab872e5b22ab1405465f9c87d0) * Add more packages in builder (#386) Co-authored-by: CAPtheorem <79423264+CAPtheorem@users.noreply.github.com> (cherry picked from commit 7208b4766a50426e1948a3babb5c1f49d7685ab7) * Add SEQUENCER_CLIENT_HTTP (#411) (cherry picked from commit bbb44932631f439002d761fbb57d757f8527763c) Co-authored-by: Boyuan-Chen <46272347+Boyuan-Chen@users.noreply.github.com> Co-authored-by: CAPtheorem <79423264+CAPtheorem@users.noreply.github.com> Co-authored-by: Souradeep Das --- .github/workflows/boba-publish-master.yml | 1 + .../boba-node/docker-compose-replica.yml | 13 +- .../docker/Dockerfile.data-transport-layer | 4 +- boba_community/fraud-detector/README.md | 47 ++-- .../fraud-detector/deployments/README.md | 3 - .../fraud-detector/deployments/local/env | 7 - .../deployments/local/state-dump.latest.json | 100 -------- .../fraud-detector/deployments/mainnet/env | 6 - .../docker-compose-fraud-detector.yml | 57 ++--- .../docker/Dockerfile.verifier_dtl | 5 +- .../mainnet => docker}/state-dump.latest.json | 0 boba_documentation/Community_Verifier.md | 2 +- boba_documentation/Developing_on_Windows.md | 52 ---- boba_documentation/Frontend_Development.md | 6 +- .../Price_Data_Feeds_Overview.md | 222 ++++++++++++++++++ boba_documentation/Readme.md | 140 ----------- boba_documentation/Service_maintenance.md | 168 ------------- boba_examples/boba-straw/README.md | 1 + boba_examples/truffle-erc20/README.md | 2 +- integration-tests/test/rpc.spec.ts | 95 ++++++++ l2geth/CHANGELOG.md | 13 + l2geth/Makefile | 2 +- l2geth/README.md | 55 ++--- l2geth/accounts/abi/abi.go | 28 +-- l2geth/accounts/abi/bind/bind_test.go | 10 - l2geth/build/update-license.go | 2 +- l2geth/cmd/faucet/faucet.go | 2 +- l2geth/cmd/geth/accountcmd_test.go | 2 +- l2geth/cmd/geth/chaincmd.go | 2 +- .../contracts/checkpointoracle/oracle_test.go | 2 - l2geth/core/blockchain_test.go | 8 +- l2geth/core/genesis_test.go | 2 - l2geth/core/state/statedb.go | 2 +- l2geth/core/state/statedb_test.go | 4 +- l2geth/core/state_processor.go | 6 +- l2geth/core/state_transition.go | 12 +- l2geth/core/types/transaction_meta.go | 2 +- l2geth/core/vm/evm.go | 143 ++++++----- l2geth/core/vm/instructions.go | 8 +- l2geth/eth/handler_test.go | 4 - l2geth/eth/tracers/tracers_test.go | 4 - l2geth/internal/ethapi/api.go | 49 ++-- l2geth/les/handler_test.go | 20 -- l2geth/les/odr_test.go | 2 - l2geth/les/request_test.go | 2 - l2geth/les/sync_test.go | 4 - l2geth/light/odr_test.go | 2 - l2geth/miner/worker.go | 31 +-- l2geth/mobile/types.go | 6 + l2geth/node/config_test.go | 1 - l2geth/package.json | 2 +- l2geth/params/config.go | 23 ++ l2geth/rollup/rcfg/config.go | 14 +- l2geth/rollup/sync_service.go | 15 +- l2geth/tests/block_test.go | 10 - l2geth/tests/state_test.go | 3 - l2geth/tests/transaction_test.go | 1 - ops/docker-compose-side.yml | 2 + ops/docker-compose.yml | 2 + ops/docker/Dockerfile.monorepo | 2 +- packages/boba/gateway/public/index.html | 2 +- packages/boba/gateway/public/manifest.json | 4 +- packages/boba/turing/test.js | 134 ++++++----- packages/boba/turing/test/003_stable_swap.ts | 2 +- packages/boba/turing/test/005_lending.ts | 2 +- .../data-transport-layer/src/client/client.ts | 2 +- .../handlers/sequencer-batch-appended.ts | 40 ++-- 67 files changed, 688 insertions(+), 933 deletions(-) delete mode 100644 boba_community/fraud-detector/deployments/README.md delete mode 100644 boba_community/fraud-detector/deployments/local/env delete mode 100644 boba_community/fraud-detector/deployments/local/state-dump.latest.json delete mode 100644 boba_community/fraud-detector/deployments/mainnet/env rename boba_community/fraud-detector/{deployments/mainnet => docker}/state-dump.latest.json (100%) delete mode 100644 boba_documentation/Developing_on_Windows.md create mode 100644 boba_documentation/Price_Data_Feeds_Overview.md delete mode 100644 boba_documentation/Readme.md delete mode 100644 boba_documentation/Service_maintenance.md diff --git a/.github/workflows/boba-publish-master.yml b/.github/workflows/boba-publish-master.yml index 0f2b5694d..f1bdf28eb 100644 --- a/.github/workflows/boba-publish-master.yml +++ b/.github/workflows/boba-publish-master.yml @@ -53,6 +53,7 @@ jobs: run: | for i in $(docker images --format "{{.Repository}}:{{.Tag}}" | grep bobanetwork); do docker image tag "$i" bobanetwork/$(echo $i | awk -F'/' '{print $2}' | awk -F':' '{print $1}'):${{ steps.tag.outputs.VERSION }} + docker image tag "$i" bobanetwork/$(echo $i | awk -F'/' '{print $2}' | awk -F':' '{print $1}'):release done docker images docker images | grep ${{ steps.tag.outputs.VERSION }} diff --git a/boba_community/boba-node/docker-compose-replica.yml b/boba_community/boba-node/docker-compose-replica.yml index c6fc36338..f29248387 100644 --- a/boba_community/boba-node/docker-compose-replica.yml +++ b/boba_community/boba-node/docker-compose-replica.yml @@ -8,12 +8,6 @@ x-l1_rpc_geth: &l1_rpc_geth version: "3" services: - builder: - image: bobanetwork/builder:latest - build: - context: ../.. - dockerfile: ./ops/docker/Dockerfile.monorepo - dtl: image: bobanetwork/data-transport-layer:latest build: @@ -37,12 +31,9 @@ services: replica: depends_on: - dtl - image: bobanetwork/l2geth:latest + image: bobanetwork/l2geth:release deploy: replicas: 1 - build: - context: ../.. - dockerfile: ./ops/docker/Dockerfile.geth entrypoint: sh ./geth.sh env_file: - ../../ops/envs/geth.env @@ -58,6 +49,8 @@ services: BLOCK_SIGNER_KEY: "6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d27" BLOCK_SIGNER_ADDRESS: "0x00000398232E2064F896018496b4b44b3D62751F" ROLLUP_POLL_INTERVAL_FLAG: "10s" + ROLLUP_ENFORCE_FEES: 'true' + EMERGENCY_FORK_NUMBER: 310215 ports: - ${L2GETH_HTTP_PORT:-8549}:8545 - ${L2GETH_WS_PORT:-8550}:8546 diff --git a/boba_community/boba-node/docker/Dockerfile.data-transport-layer b/boba_community/boba-node/docker/Dockerfile.data-transport-layer index 5e492a93c..43bd0064e 100644 --- a/boba_community/boba-node/docker/Dockerfile.data-transport-layer +++ b/boba_community/boba-node/docker/Dockerfile.data-transport-layer @@ -1,5 +1,5 @@ -FROM bobanetwork/data-transport-layer +FROM bobanetwork/data-transport-layer:release COPY boba-node/docker/state-dump.latest.json /opt/optimism/packages/data-transport-layer/state-dumps/state-dump.latest.json -ENTRYPOINT ["node", "dist/src/services/run.js"] \ No newline at end of file +ENTRYPOINT ["node", "dist/src/services/run.js"] diff --git a/boba_community/fraud-detector/README.md b/boba_community/fraud-detector/README.md index cc7eb7a8f..690d9cbfc 100644 --- a/boba_community/fraud-detector/README.md +++ b/boba_community/fraud-detector/README.md @@ -12,7 +12,7 @@ Docker scripts and python source code for running a *Verifier*, a *DTL* (data tr ## 0. Concepts -This repo allows you to: +This repo allows you to: 1. Run your own Boba geth L2 on your computer. In this case, the geth L2 will run in its `Verifier` mode. In `Verifier` mode, the geth will sync from L1 and use the transaction data from the L1 contracts to compute what the state roots should be, *if the operator is honest*. @@ -22,17 +22,17 @@ The central idea is that if two (or more) systems look at the same transactions, ## 1. Errors and State Root Mismatches in the Boba Mainnet -* For the first 10 blocks, the chainID was set (incorrectly) to 28 rather than 288. Therefore, the EIP155 signatures fail for those blocks, and the Verifier cannot sync those blocks. This has been addressed by setting the L1_MAINNET_DEPLOYMENT_BLOCK to 10 blocks past the zero block. +* For the first 10 blocks, the chainID was set (incorrectly) to 28 rather than 288. Therefore, the EIP155 signatures fail for those blocks, and the Verifier cannot sync those blocks. This has been addressed by setting the L1_MAINNET_DEPLOYMENT_BLOCK to 10 blocks past the zero block. -* There is one state root mismatch at L2 block 155, arising from a two second discrepancy in a timestamp, that was ultimately caused by a too-small setting for the number of confirmations (DATA_TRANSPORT_LAYER__CONFIRMATIONS). This value was therefore increased to 4. The 2 second block 155 timestamp discrepancy has been addressed in a custom docker image (`omgx/data-transport-layer:rc1.0-surgery`). +* There is one state root mismatch at L2 block 155, arising from a two second discrepancy in a timestamp, that was ultimately caused by a too-small setting for the number of confirmations (DATA_TRANSPORT_LAYER__CONFIRMATIONS). This value was therefore increased to 4. The 2 second block 155 timestamp discrepancy has been addressed in a custom docker image (`omgx/data-transport-layer:rc1.0-surgery`). ## 2. What do when you discover a state root mismatch -Congratulations! The security of the L2 depends on community monitoring of the operator's actions. If you have discovered a state root mismatch, please file a GitHub issue (https://github.com/omgnetwork/optimism-v2/issues). We should have a good response / clarification for you quickly. In the future, with the Boba governance token, additional mechanisms will be released to incentivize and reward community monitoring of the Boba L2. +Congratulations! The security of the L2 depends on community monitoring of the operator's actions. If you have discovered a state root mismatch, please file a GitHub issue (https://github.com/omgnetwork/optimism-v2/issues). We should have a good response / clarification for you quickly. In the future, with the Boba governance token, additional mechanisms will be released to incentivize and reward community monitoring of the Boba L2. ## 3. Running the Fraud Detector, the Verifier, and the Data Transport Layer (DTL) -**Requirements**: you will need a command line and Docker. Before filing GitHub issues, please make sure Docker is installed and *running*. +**Requirements**: you will need a command line and Docker. Before filing GitHub issues, please make sure Docker is installed and *running*. **Open a terminal window**. First, clone the project and install needed dependencies: @@ -43,38 +43,27 @@ $ yarn install $ yarn build ``` -Then, add your Infura key to `boba_community/fraud-detector/deployments/mainnet/env`. If you do not have an Infura key, you can obtain one for free from [Infura](https://infura.io). +Then, add your Infura key to `boba_community/fraud-detector/docker-compose-fraud-detector.yml`. If you do not have an Infura key, you can obtain one for free from [Infura](https://infura.io). ```bash +x-l1_rpc_dtl: &l1_rpc_dtl + DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT: 'https://mainnet.infura.io/v3/YOUR_INFURA_KEY' -#boba_community/fraud-detector/deployments/mainnet/env - -TARGET_NAME="mainnet" -L1_RPC_ENDPOINT="https://mainnet.infura.io/v3/YOUR_INFURA_KEY_HERE" -L2_RPC_ENDPOINT="https://mainnet.boba.network" -ETH1_CTC_DEPLOYMENT_HEIGHT=13502893 -ADDRESS_MANAGER="0x8376ac6C3f73a25Dd994E0b0669ca7ee0C02F089" -L2_CHAIN_ID=288 - +x-l1_node_web3_url: &l1_node_web3_url + L1_NODE_WEB3_URL: 'https://mainnet.infura.io/v3/YOUR_INFURA_KEY' ``` Next, navigate to `boba_community/fraud-detector` and build the needed Docker images: ``` $ cd boba_community/fraud-detector -$ docker-compose -f docker-compose-fraud-detector.yml --env-file deployments/local/env build -``` - -You may need to create the default docker network: - -``` -$ docker network create ops_default +$ docker-compose -f docker-compose-fraud-detector.yml build ``` Finally, spin up the `Fraud Detector` and other neccessary services (the `Verifier L2 Geth` and the `Data Transport Layer`) ``` -$ docker-compose -f docker-compose-fraud-detector.yml --env-file deployments/mainnet/env up +$ docker-compose -f docker-compose-fraud-detector.yml up ``` The system will start and the `Verifier L2 Geth` will begin to sync with the Boba L2 via data it deposited into the core Boba contracts on Ethereum Mainnet. **The sync process can take 1/2 hour to complete**. During the sync process, you will see the Verifier gradually catch up with the Boba L2: @@ -107,7 +96,7 @@ verifier_dtl_1 | {"level":30,"time":1636133786230,"method":"GET","url":"/bat verifier_dtl_1 | {"level":30,"time":1636133786232,"method":"GET","url":"/batch/transaction/latest","elapsed":1,"msg":"Served HTTP Request"} verifier_l2geth_1 | DEBUG[11-05|17:36:26.243] Served eth_blockNumber conn=172.18.0.4:44544 reqid=147 t=24.086µs verifier_l2geth_1 | DEBUG[11-05|17:36:26.244] Served eth_getBlockByNumber conn=172.18.0.4:44544 reqid=148 t=177.276µs -fraud-detector_1 | INFO 20211105T173626 74 13508337 0xd05bfa4e2269e584b95348b070673d2f64a5ee8dbb198f7fa78ee7deac338007 0xd05bfa4e2269e584b95348b070673d2f64a5ee8dbb198f7fa78ee7deac338007 0xd05bfa4e2269e584b95348b070673d2f64a5ee8dbb198f7fa78ee7deac338007 +fraud-detector_1 | INFO 20211105T173626 74 13508337 0xd05bfa4e2269e584b95348b070673d2f64a5ee8dbb198f7fa78ee7deac338007 0xd05bfa4e2269e584b95348b070673d2f64a5ee8dbb198f7fa78ee7deac338007 0xd05bfa4e2269e584b95348b070673d2f64a5ee8dbb198f7fa78ee7deac338007 ``` @@ -115,7 +104,7 @@ At that point, the `Fraud Detector` can compare the public state roots (deposite ```bash -fraud-detector_1 | INFO 20211105T173626 79 13508337 +fraud-detector_1 | INFO 20211105T173626 79 13508337 0x4809dde56bb792a27ea26b16b75790705edcaf67c2f7db33bb95417277897c0d #the SCC-STATEROOT, written into Ethereum Mainnet by Boba Mainnet 0x4809dde56bb792a27ea26b16b75790705edcaf67c2f7db33bb95417277897c0d #the L2-STATEROOT, as reported by Boba Mainnet 0x4809dde56bb792a27ea26b16b75790705edcaf67c2f7db33bb95417277897c0d #the VERIFIER-STATEROOT you just calculated @@ -127,10 +116,10 @@ If all three of these roots agree, then Boba Mainnet has been operating truthful ```bash ... -fraud-detector_1 | INFO 20211105T175039 7788 13557689 - 0x0b40758bc7b6c2f9a95dc4af995a3c514a3b217d58e426c4f12bc94a0d6c8a0c - 0x0b40758bc7b6c2f9a95dc4af995a3c514a3b217d58e426c4f12bc94a0d6c8a0c - 0x0b40758bc7b6c2f9a95dc4af995a3c514a3b217d58e426c4f12bc94a0d6c8a0c +fraud-detector_1 | INFO 20211105T175039 7788 13557689 + 0x0b40758bc7b6c2f9a95dc4af995a3c514a3b217d58e426c4f12bc94a0d6c8a0c + 0x0b40758bc7b6c2f9a95dc4af995a3c514a3b217d58e426c4f12bc94a0d6c8a0c + 0x0b40758bc7b6c2f9a95dc4af995a3c514a3b217d58e426c4f12bc94a0d6c8a0c fraud-detector_1 | DEBUG 20211105T175040 Caught up to L1 tip. Waiting for new events from startBlock 13557996 verifier_dtl_1 | {"level":30,"time":1636134645380,"highestSyncedL1Block":13558055,"targetL1Block":13558056,"msg":"Synchronizing events from Layer 1 (Ethereum)"} ... diff --git a/boba_community/fraud-detector/deployments/README.md b/boba_community/fraud-detector/deployments/README.md deleted file mode 100644 index c94e3e595..000000000 --- a/boba_community/fraud-detector/deployments/README.md +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains the state-dump files and other parameters which are -necessary to set up a verifier l2geth node with the same genesis block as -the environment it is verifying. diff --git a/boba_community/fraud-detector/deployments/local/env b/boba_community/fraud-detector/deployments/local/env deleted file mode 100644 index ddd1b5dfa..000000000 --- a/boba_community/fraud-detector/deployments/local/env +++ /dev/null @@ -1,7 +0,0 @@ -TARGET_NAME="local" -L1_RPC_ENDPOINT="http://l1_chain:8545" -L2_RPC_ENDPOINT="http://l2geth:8545" -ETH1_CTC_DEPLOYMENT_HEIGHT=1 -ADDRESS_MANAGER="0x5FbDB2315678afecb367f032d93F642f64180aa3" -L2_CHAIN_ID=31338 -abcd="whatever" diff --git a/boba_community/fraud-detector/deployments/local/state-dump.latest.json b/boba_community/fraud-detector/deployments/local/state-dump.latest.json deleted file mode 100644 index 779450c7f..000000000 --- a/boba_community/fraud-detector/deployments/local/state-dump.latest.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "commit": "0000000000000000000000000000000000000000", - "config": { - "chainId": 31338, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "clique": { - "period": 0, - "epoch": 30000 - } - }, - "difficulty": "1", - "gasLimit": "11000000", - "extradata": "0x000000000000000000000000000000000000000000000000000000000000000000000398232E2064F896018496b4b44b3D62751F0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "alloc": { - "0x4200000000000000000000000000000000000000": { - "balance": "00", - "storage": {}, - "code": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806382e3702d1461003b578063cafa81dc14610072575b600080fd5b61005e610049366004610112565b60006020819052908152604090205460ff1681565b604051901515815260200160405180910390f35b61008561008036600461015a565b610087565b005b6001600080833360405160200161009f929190610229565b604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815291815281516020928301208352908201929092520160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001691151591909117905550565b60006020828403121561012457600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561016c57600080fd5b813567ffffffffffffffff8082111561018457600080fd5b818401915084601f83011261019857600080fd5b8135818111156101aa576101aa61012b565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156101f0576101f061012b565b8160405282815287602084870101111561020957600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000835160005b8181101561024a5760208187018101518583015201610230565b81811115610259576000828501525b5060609390931b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016919092019081526014019291505056fea164736f6c6343000809000a" - }, - "0x4200000000000000000000000000000000000002": { - "balance": "00", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000000000000000000000000000000000000000000" - }, - "code": "0x608060405234801561001057600080fd5b50600436106100725760003560e01c80639b19251a116100505780639b19251a146100e9578063b1540a011461011c578063bdc7b54f1461012f57600080fd5b806308fd63221461007757806313af40351461008c5780638da5cb5b1461009f575b600080fd5b61008a610085366004610614565b610137565b005b61008a61009a366004610650565b610271565b6000546100bf9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61010c6100f7366004610650565b60016020526000908152604090205460ff1681565b60405190151581526020016100e0565b61010c61012a366004610650565b61047c565b61008a6104cd565b60005473ffffffffffffffffffffffffffffffffffffffff1633146101e3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f46756e6374696f6e2063616e206f6e6c792062652063616c6c6564206279207460448201527f6865206f776e6572206f66207468697320636f6e74726163742e00000000000060648201526084015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660008181526001602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168515159081179091558251938452908301527f8daaf060c3306c38e068a75c054bf96ecd85a3db1252712c4d93632744c42e0d910160405180910390a15050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610318576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f46756e6374696f6e2063616e206f6e6c792062652063616c6c6564206279207460448201527f6865206f776e6572206f66207468697320636f6e74726163742e00000000000060648201526084016101da565b73ffffffffffffffffffffffffffffffffffffffff81166103e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605b60248201527f4f564d5f4465706c6f79657257686974656c6973743a2077686974656c69737460448201527f2063616e206f6e6c792062652064697361626c65642076696120656e61626c6560648201527f417262697472617279436f6e74726163744465706c6f796d656e740000000000608482015260a4016101da565b6000546040805173ffffffffffffffffffffffffffffffffffffffff928316815291831660208301527fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c910160405180910390a1600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6000805473ffffffffffffffffffffffffffffffffffffffff1615806104c7575073ffffffffffffffffffffffffffffffffffffffff821660009081526001602052604090205460ff165b92915050565b60005473ffffffffffffffffffffffffffffffffffffffff163314610574576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603a60248201527f46756e6374696f6e2063616e206f6e6c792062652063616c6c6564206279207460448201527f6865206f776e6572206f66207468697320636f6e74726163742e00000000000060648201526084016101da565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681527fc0e106cf568e50698fdbde1eff56f5a5c966cc7958e37e276918e9e4ccdf8cd49060200160405180910390a1600080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b803573ffffffffffffffffffffffffffffffffffffffff8116811461060f57600080fd5b919050565b6000806040838503121561062757600080fd5b610630836105eb565b91506020830135801515811461064557600080fd5b809150509250929050565b60006020828403121561066257600080fd5b61066b826105eb565b939250505056fea164736f6c6343000809000a" - }, - "0x4200000000000000000000000000000000000007": { - "balance": "00", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000000000000000000000000000000000000000dead", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x000000000000000000000000c6e7df5e7b4f2a278906862b61205850344d4e7d", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x00000000000000000000000000000000000000000000000000000000000186a0" - }, - "code": "0x608060405234801561001057600080fd5b50600436106100885760003560e01c8063a71198691161005b578063a71198691461012a578063b1b1b2091461014a578063cbd4ece91461016d578063ecc704281461018057600080fd5b806321d800ec1461008d5780633dbb202b146100c55780636e296e45146100da57806382e3702d14610107575b600080fd5b6100b061009b366004610826565b60006020819052908152604090205460ff1681565b60405190151581526020015b60405180910390f35b6100d86100d3366004610942565b610197565b005b6100e26102e2565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100bc565b6100b0610115366004610826565b60026020526000908152604090205460ff1681565b6005546100e29073ffffffffffffffffffffffffffffffffffffffff1681565b6100b0610158366004610826565b60016020526000908152604090205460ff1681565b6100d861017b3660046109ad565b61038b565b61018960035481565b6040519081526020016100bc565b60006101a784338560035461078d565b80516020808301919091206000908152600290915260409081902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517fcafa81dc0000000000000000000000000000000000000000000000000000000081529091507342000000000000000000000000000000000000009063cafa81dc9061023c908490600401610a89565b600060405180830381600087803b15801561025657600080fd5b505af115801561026a573d6000803e3d6000fd5b505050508373ffffffffffffffffffffffffffffffffffffffff167fcb0f7ffd78f9aee47a248fae8db181db6eee833039123e026dcbff529522e52a3385600354866040516102bc9493929190610aa3565b60405180910390a26001600360008282546102d79190610aef565b909155505050505050565b60045460009073ffffffffffffffffffffffffffffffffffffffff1661dead141561036e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f78446f6d61696e4d65737361676553656e646572206973206e6f74207365740060448201526064015b60405180910390fd5b5060045473ffffffffffffffffffffffffffffffffffffffff1690565b60055473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffeeeeffffffffffffffffffffffffffffffffeeef330173ffffffffffffffffffffffffffffffffffffffff161461046a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f50726f7669646564206d65737361676520636f756c64206e6f7420626520766560448201527f7269666965642e000000000000000000000000000000000000000000000000006064820152608401610365565b60006104788585858561078d565b8051602080830191909120600081815260019092526040909120549192509060ff1615610527576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f50726f7669646564206d6573736167652068617320616c72656164792062656560448201527f6e2072656365697665642e0000000000000000000000000000000000000000006064820152608401610365565b73ffffffffffffffffffffffffffffffffffffffff8616734200000000000000000000000000000000000000141561059957600090815260016020819052604090912080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016909117905550610787565b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff878116919091179091556040516000918816906105f2908790610b2e565b6000604051808303816000865af19150503d806000811461062f576040519150601f19603f3d011682016040523d82523d6000602084013e610634565b606091505b5050600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001661dead1790559050801515600114156106d557600082815260016020819052604080832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169092179091555183917f4641df4a962071e12719d8c8c8e5ac7fc4d97b927346a3d7a335b1f7517e133c91a2610701565b60405182907f99d0e048484baa1b1540b1367cb128acd7ab2946d1ed91ec10e3c85e4bf51b8f90600090a25b600083334360405160200161071893929190610b4a565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181528151602092830120600090815291829052902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055505050505b50505050565b6060848484846040516024016107a69493929190610b9c565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fcbd4ece9000000000000000000000000000000000000000000000000000000001790529050949350505050565b60006020828403121561083857600080fd5b5035919050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461086357600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126108a857600080fd5b813567ffffffffffffffff808211156108c3576108c3610868565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561090957610909610868565b8160405283815286602085880101111561092257600080fd5b836020870160208301376000602085830101528094505050505092915050565b60008060006060848603121561095757600080fd5b6109608461083f565b9250602084013567ffffffffffffffff81111561097c57600080fd5b61098886828701610897565b925050604084013563ffffffff811681146109a257600080fd5b809150509250925092565b600080600080608085870312156109c357600080fd5b6109cc8561083f565b93506109da6020860161083f565b9250604085013567ffffffffffffffff8111156109f657600080fd5b610a0287828801610897565b949793965093946060013593505050565b60005b83811015610a2e578181015183820152602001610a16565b838111156107875750506000910152565b60008151808452610a57816020860160208601610a13565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610a9c6020830184610a3f565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff85168152608060208201526000610ad26080830186610a3f565b905083604083015263ffffffff8316606083015295945050505050565b60008219821115610b29577f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b500190565b60008251610b40818460208701610a13565b9190910192915050565b60008451610b5c818460208901610a13565b60609490941b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001691909301908152601481019190915260340192915050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525060806040830152610bd56080830185610a3f565b90508260608301529594505050505056fea164736f6c6343000809000a" - }, - "0x420000000000000000000000000000000000000F": { - "balance": "00", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x0000000000000000000000000000000000000000000000000000000000000abe", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x000000000000000000000000000000000000000000000000000000000016e360", - "0x0000000000000000000000000000000000000000000000000000000000000005": "0x0000000000000000000000000000000000000000000000000000000000000001" - }, - "code": "0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80638c8885c811610097578063de26c4a111610066578063de26c4a1146101cc578063f2fde38b146101df578063f45e65d8146101f2578063fe173b97146101fb57600080fd5b80638c8885c81461016b5780638da5cb5b1461017e578063bede39b5146101a6578063bf1fe420146101b957600080fd5b806349948e0e116100d357806349948e0e14610134578063519b4bd3146101475780637046559714610150578063715018a61461016357600080fd5b80630c18c162146100fa578063313ce567146101165780633577afc51461011f575b600080fd5b61010360035481565b6040519081526020015b60405180910390f35b61010360055481565b61013261012d3660046108d0565b610204565b005b610103610142366004610918565b6102c6565b61010360025481565b61013261015e3660046108d0565b610322565b6101326103d8565b6101326101793660046108d0565b610465565b60005460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161010d565b6101326101b43660046108d0565b61051b565b6101326101c73660046108d0565b6105d1565b6101036101da366004610918565b610687565b6101326101ed3660046109e7565b61072b565b61010360045481565b61010360015481565b60005473ffffffffffffffffffffffffffffffffffffffff16331461028a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b60038190556040518181527f32740b35c0ea213650f60d44366b4fb211c9033b50714e4a1d34e65d5beb9bb4906020015b60405180910390a150565b6000806102d283610687565b90506000600254826102e49190610a53565b90506000600554600a6102f79190610bb2565b90506000600454836103099190610a53565b905060006103178383610bbe565b979650505050505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146103a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610281565b60048190556040518181527f3336cd9708eaf2769a0f0dc0679f30e80f15dcd88d1921b5a16858e8b85c591a906020016102bb565b60005473ffffffffffffffffffffffffffffffffffffffff163314610459576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610281565b610463600061085b565b565b60005473ffffffffffffffffffffffffffffffffffffffff1633146104e6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610281565b60058190556040518181527fd68112a8707e326d08be3656b528c1bcc5bbbfc47f4177e2179b14d8640838c1906020016102bb565b60005473ffffffffffffffffffffffffffffffffffffffff16331461059c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610281565b60028190556040518181527f351fb23757bb5ea0546c85b7996ddd7155f96b939ebaa5ff7bc49c75f27f2c44906020016102bb565b60005473ffffffffffffffffffffffffffffffffffffffff163314610652576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610281565b60018190556040518181527ffcdccc6074c6c42e4bd578aa9870c697dc976a270968452d2b8c8dc369fae396906020016102bb565b600080805b8351811015610704578381815181106106a7576106a7610bf9565b01602001517fff00000000000000000000000000000000000000000000000000000000000000166106e4576106dd600483610c28565b91506106f2565b6106ef601083610c28565b91505b806106fc81610c40565b91505061068c565b506000600354826107159190610c28565b905061072381610440610c28565b949350505050565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107ac576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610281565b73ffffffffffffffffffffffffffffffffffffffff811661084f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610281565b6108588161085b565b50565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156108e257600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60006020828403121561092a57600080fd5b813567ffffffffffffffff8082111561094257600080fd5b818401915084601f83011261095657600080fd5b813581811115610968576109686108e9565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019083821181831017156109ae576109ae6108e9565b816040528281528760208487010111156109c757600080fd5b826020860160208301376000928101602001929092525095945050505050565b6000602082840312156109f957600080fd5b813573ffffffffffffffffffffffffffffffffffffffff81168114610a1d57600080fd5b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615610a8b57610a8b610a24565b500290565b600181815b80851115610ae957817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610acf57610acf610a24565b80851615610adc57918102915b93841c9390800290610a95565b509250929050565b600082610b0057506001610bac565b81610b0d57506000610bac565b8160018114610b235760028114610b2d57610b49565b6001915050610bac565b60ff841115610b3e57610b3e610a24565b50506001821b610bac565b5060208310610133831016604e8410600b8410161715610b6c575081810a610bac565b610b768383610a90565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115610ba857610ba8610a24565b0290505b92915050565b6000610a1d8383610af1565b600082610bf4577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008219821115610c3b57610c3b610a24565b500190565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415610c7257610c72610a24565b506001019056fea164736f6c6343000809000a" - }, - "0x4200000000000000000000000000000000000010": { - "balance": "00", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000322813fd9a801c5507c9de605d63cea4f2ce6c44", - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000004200000000000000000000000000000000000007" - }, - "code": "0x608060405234801561001057600080fd5b50600436106100675760003560e01c80633cb747bf116100505780633cb747bf146100ca578063662a633a146100ea578063a3a79548146100fd57600080fd5b806332b7006d1461006c57806336c717c114610081575b600080fd5b61007f61007a366004610d0f565b610110565b005b6001546100a19073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b6000546100a19073ffffffffffffffffffffffffffffffffffffffff1681565b61007f6100f8366004610d80565b610126565b61007f61010b366004610e18565b6106c1565b61011f853333878787876106d8565b5050505050565b60015473ffffffffffffffffffffffffffffffffffffffff1661015e60005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461021d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f4f564d5f58434841494e3a206d657373656e67657220636f6e7472616374207560448201527f6e61757468656e7469636174656400000000000000000000000000000000000060648201526084015b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff1661025360005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16636e296e456040518163ffffffff1660e01b815260040160206040518083038186803b15801561029857600080fd5b505afa1580156102ac573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906102d09190610e9b565b73ffffffffffffffffffffffffffffffffffffffff1614610373576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f4f564d5f58434841494e3a2077726f6e672073656e646572206f662063726f7360448201527f732d646f6d61696e206d657373616765000000000000000000000000000000006064820152608401610214565b61039d877f1d1d8b6300000000000000000000000000000000000000000000000000000000610a32565b801561045357508673ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156103ec57600080fd5b505af1158015610400573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104249190610e9b565b73ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff16145b15610567576040517f40c10f1900000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8681166004830152602482018690528816906340c10f1990604401600060405180830381600087803b1580156104c857600080fd5b505af11580156104dc573d6000803e3d6000fd5b505050508573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff167fb0444523268717a02698be47d0803aa7468c00acbed2f8bd93a0459cde61dd898888888860405161055a9493929190610f08565b60405180910390a46106b7565b600063a9f9e67560e01b8989888a89898960405160240161058e9796959493929190610f3e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526001549091506106339073ffffffffffffffffffffffffffffffffffffffff16600083610a57565b8673ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f7ea89a4591614515571c2b51f5ea06494056f261c10ab1ed8c03c7590d87bce0898989896040516106ad9493929190610f08565b60405180910390a4505b5050505050505050565b6106d0863387878787876106d8565b505050505050565b6040517f9dc29fac0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff881690639dc29fac90604401600060405180830381600087803b15801561074657600080fd5b505af115801561075a573d6000803e3d6000fd5b5050505060008773ffffffffffffffffffffffffffffffffffffffff1663c01e1bd66040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156107a857600080fd5b505af11580156107bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107e09190610e9b565b9050606073ffffffffffffffffffffffffffffffffffffffff891673420000000000000000000000000000000000000614156108d5576040517f1532ec340000000000000000000000000000000000000000000000000000000090610851908a908a908a9089908990602401610f9b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091529050610994565b6040517fa9f9e67500000000000000000000000000000000000000000000000000000000906109149084908c908c908c908c908b908b90602401610f3e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915290505b6001546109b89073ffffffffffffffffffffffffffffffffffffffff168683610a57565b3373ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f73d170910aba9e6d50b102db522b1dbcd796216f5128b445aa2135272886497e8a8a89896040516106ad9493929190610f08565b6000610a3d83610ae8565b8015610a4e5750610a4e8383610b4c565b90505b92915050565b6000546040517f3dbb202b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff90911690633dbb202b90610ab190869085908790600401611016565b600060405180830381600087803b158015610acb57600080fd5b505af1158015610adf573d6000803e3d6000fd5b50505050505050565b6000610b14827f01ffc9a700000000000000000000000000000000000000000000000000000000610b4c565b8015610a515750610b45827fffffffff00000000000000000000000000000000000000000000000000000000610b4c565b1592915050565b604080517fffffffff00000000000000000000000000000000000000000000000000000000831660248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f01ffc9a7000000000000000000000000000000000000000000000000000000001790529051600091908290819073ffffffffffffffffffffffffffffffffffffffff87169061753090610c06908690611092565b6000604051808303818686fa925050503d8060008114610c42576040519150601f19603f3d011682016040523d82523d6000602084013e610c47565b606091505b5091509150602081511015610c625760009350505050610a51565b818015610c7e575080806020019051810190610c7e91906110ae565b9695505050505050565b73ffffffffffffffffffffffffffffffffffffffff81168114610caa57600080fd5b50565b803563ffffffff81168114610cc157600080fd5b919050565b60008083601f840112610cd857600080fd5b50813567ffffffffffffffff811115610cf057600080fd5b602083019150836020828501011115610d0857600080fd5b9250929050565b600080600080600060808688031215610d2757600080fd5b8535610d3281610c88565b945060208601359350610d4760408701610cad565b9250606086013567ffffffffffffffff811115610d6357600080fd5b610d6f88828901610cc6565b969995985093965092949392505050565b600080600080600080600060c0888a031215610d9b57600080fd5b8735610da681610c88565b96506020880135610db681610c88565b95506040880135610dc681610c88565b94506060880135610dd681610c88565b93506080880135925060a088013567ffffffffffffffff811115610df957600080fd5b610e058a828b01610cc6565b989b979a50959850939692959293505050565b60008060008060008060a08789031215610e3157600080fd5b8635610e3c81610c88565b95506020870135610e4c81610c88565b945060408701359350610e6160608801610cad565b9250608087013567ffffffffffffffff811115610e7d57600080fd5b610e8989828a01610cc6565b979a9699509497509295939492505050565b600060208284031215610ead57600080fd5b8151610eb881610c88565b9392505050565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152606060408201526000610c7e606083018486610ebf565b600073ffffffffffffffffffffffffffffffffffffffff808a1683528089166020840152808816604084015280871660608401525084608083015260c060a0830152610f8e60c083018486610ebf565b9998505050505050505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525084604083015260806060830152610fdb608083018486610ebf565b979650505050505050565b60005b83811015611001578181015183820152602001610fe9565b83811115611010576000848401525b50505050565b73ffffffffffffffffffffffffffffffffffffffff841681526060602082015260008351806060840152611051816080850160208801610fe6565b63ffffffff93909316604083015250601f919091017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160160800192915050565b600082516110a4818460208701610fe6565b9190910192915050565b6000602082840312156110c057600080fd5b81518015158114610eb857600080fdfea164736f6c6343000809000a" - }, - "0x4200000000000000000000000000000000000011": { - "balance": "00", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000391716d440c151c42cdf1c95c1d83a5427bca52c" - }, - "code": "0x6080604052600436106100385760003560e01c80633ccfd60b14610044578063d3e5792b1461005b578063d4ff92181461008a57600080fd5b3661003f57005b600080fd5b34801561005057600080fd5b506100596100dc565b005b34801561006757600080fd5b5061007767d02ab486cedc000081565b6040519081526020015b60405180910390f35b34801561009657600080fd5b506000546100b79073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610081565b67d02ab486cedc000047101561019e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605760248201527f4f564d5f53657175656e6365724665655661756c743a2077697468647261776160448201527f6c20616d6f756e74206d7573742062652067726561746572207468616e206d6960648201527f6e696d756d207769746864726177616c20616d6f756e74000000000000000000608482015260a40160405180910390fd5b600080546040805160208101825283815290517fa3a795480000000000000000000000000000000000000000000000000000000081527342000000000000000000000000000000000000109363a3a7954893610230937342000000000000000000000000000000000000069373ffffffffffffffffffffffffffffffffffffffff909216924792909190600401610264565b600060405180830381600087803b15801561024a57600080fd5b505af115801561025e573d6000803e3d6000fd5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff808816835260208188168185015286604085015263ffffffff8616606085015260a06080850152845191508160a085015260005b828110156102cb5785810182015185820160c0015281016102af565b828111156102dd57600060c084870101525b5050601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160c001969550505050505056fea164736f6c6343000809000a" - }, - "0x4200000000000000000000000000000000000012": { - "balance": "00", - "storage": {}, - "code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c80630769a96914610030575b600080fd5b61004361003e366004610262565b610045565b005b73ffffffffffffffffffffffffffffffffffffffff84166100c6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f4d7573742070726f76696465204c3120746f6b656e2061646472657373000000604482015260640160405180910390fd5b6000734200000000000000000000000000000000000010858585856040516100ed9061017b565b6100fb959493929190610375565b604051809103906000f080158015610117573d6000803e3d6000fd5b5090508073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fceeb8e7d520d7f3b65fc11a262b91066940193b05d4f93df07cfdced0eb551cf60405160405180910390a35050505050565b6113fd806103d783390190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126101c857600080fd5b813567ffffffffffffffff808211156101e3576101e3610188565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561022957610229610188565b8160405283815286602085880101111561024257600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561027857600080fd5b843573ffffffffffffffffffffffffffffffffffffffff8116811461029c57600080fd5b9350602085013567ffffffffffffffff808211156102b957600080fd5b6102c5888389016101b7565b945060408701359150808211156102db57600080fd5b506102e8878288016101b7565b925050606085013560ff811681146102ff57600080fd5b939692955090935050565b6000815180845260005b8181101561033057602081850181015186830182015201610314565b81811115610342576000602083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600073ffffffffffffffffffffffffffffffffffffffff808816835280871660208401525060a060408301526103ae60a083018661030a565b82810360608401526103c0818661030a565b91505060ff83166080830152969550505050505056fe60a06040523480156200001157600080fd5b50604051620013fd380380620013fd833981016040819052620000349162000234565b8251839083906200004d906003906020850190620000a4565b50805162000063906004906020840190620000a4565b5050600580546001600160a01b039687166001600160a01b0319918216179091556006805497909616961695909517909355505060ff16608052506200031d565b828054620000b290620002e0565b90600052602060002090601f016020900481019282620000d6576000855562000121565b82601f10620000f157805160ff191683800117855562000121565b8280016001018555821562000121579182015b828111156200012157825182559160200191906001019062000104565b506200012f92915062000133565b5090565b5b808211156200012f576000815560010162000134565b80516001600160a01b03811681146200016257600080fd5b919050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200018f57600080fd5b81516001600160401b0380821115620001ac57620001ac62000167565b604051601f8301601f19908116603f01168101908282118183101715620001d757620001d762000167565b81604052838152602092508683858801011115620001f457600080fd5b600091505b83821015620002185785820183015181830184015290820190620001f9565b838211156200022a5760008385830101525b9695505050505050565b600080600080600060a086880312156200024d57600080fd5b62000258866200014a565b945062000268602087016200014a565b60408701519094506001600160401b03808211156200028657600080fd5b6200029489838a016200017d565b94506060880151915080821115620002ab57600080fd5b50620002ba888289016200017d565b925050608086015160ff81168114620002d257600080fd5b809150509295509295909350565b600181811c90821680620002f557607f821691505b602082108114156200031757634e487b7160e01b600052602260045260246000fd5b50919050565b6080516110c462000339600039600061018101526110c46000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c806370a0823111610097578063a9059cbb11610066578063a9059cbb14610237578063ae1f6aaf1461024a578063c01e1bd61461028f578063dd62ed3e146102af57600080fd5b806370a08231146101d357806395d89b41146102095780639dc29fac14610211578063a457c2d71461022457600080fd5b806323b872dd116100d357806323b872dd14610167578063313ce5671461017a57806339509351146101ab57806340c10f19146101be57600080fd5b806301ffc9a71461010557806306fdde031461012d578063095ea7b31461014257806318160ddd14610155575b600080fd5b610118610113366004610e6c565b6102f5565b60405190151581526020015b60405180910390f35b6101356103b5565b6040516101249190610eb5565b610118610150366004610f51565b610447565b6002545b604051908152602001610124565b610118610175366004610f7b565b61045d565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610124565b6101186101b9366004610f51565b61052e565b6101d16101cc366004610f51565b610577565b005b6101596101e1366004610fb7565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61013561063c565b6101d161021f366004610f51565b61064b565b610118610232366004610f51565b610704565b610118610245366004610f51565b6107c2565b60065461026a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b60055461026a9073ffffffffffffffffffffffffffffffffffffffff1681565b6101596102bd366004610fd2565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60007f01ffc9a7a5cef8baa21ed3c5c0d7e23accb804b619e9333b597f47a0d84076e27f1d1d8b63000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000084167f01ffc9a70000000000000000000000000000000000000000000000000000000014806103ad57507fffffffff00000000000000000000000000000000000000000000000000000000848116908216145b949350505050565b6060600380546103c490611005565b80601f01602080910402602001604051908101604052809291908181526020018280546103f090611005565b801561043d5780601f106104125761010080835404028352916020019161043d565b820191906000526020600020905b81548152906001019060200180831161042057829003601f168201915b5050505050905090565b60006104543384846107cf565b50600192915050565b600061046a84848461094f565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600160209081526040808320338452909152902054828110156105165760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b61052385338584036107cf565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091610454918590610572908690611088565b6107cf565b60065473ffffffffffffffffffffffffffffffffffffffff1633146105de5760405162461bcd60e51b815260206004820181905260248201527f4f6e6c79204c32204272696467652063616e206d696e7420616e64206275726e604482015260640161050d565b6105e88282610bb5565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161063091815260200190565b60405180910390a25050565b6060600480546103c490611005565b60065473ffffffffffffffffffffffffffffffffffffffff1633146106b25760405162461bcd60e51b815260206004820181905260248201527f4f6e6c79204c32204272696467652063616e206d696e7420616e64206275726e604482015260640161050d565b6106bc8282610cbb565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161063091815260200190565b33600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff86168452909152812054828110156107ab5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161050d565b6107b833858584036107cf565b5060019392505050565b600061045433848461094f565b73ffffffffffffffffffffffffffffffffffffffff83166108575760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161050d565b73ffffffffffffffffffffffffffffffffffffffff82166108e05760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161050d565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff83166109d85760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161050d565b73ffffffffffffffffffffffffffffffffffffffff8216610a615760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161050d565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610afd5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161050d565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260208190526040808220858503905591851681529081208054849290610b41908490611088565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610ba791815260200190565b60405180910390a350505050565b73ffffffffffffffffffffffffffffffffffffffff8216610c185760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161050d565b8060026000828254610c2a9190611088565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610c64908490611088565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610d445760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161050d565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610de05760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161050d565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120838303905560028054849290610e1c9084906110a0565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610942565b600060208284031215610e7e57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610eae57600080fd5b9392505050565b600060208083528351808285015260005b81811015610ee257858101830151858201604001528201610ec6565b81811115610ef4576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610f4c57600080fd5b919050565b60008060408385031215610f6457600080fd5b610f6d83610f28565b946020939093013593505050565b600080600060608486031215610f9057600080fd5b610f9984610f28565b9250610fa760208501610f28565b9150604084013590509250925092565b600060208284031215610fc957600080fd5b610eae82610f28565b60008060408385031215610fe557600080fd5b610fee83610f28565b9150610ffc60208401610f28565b90509250929050565b600181811c9082168061101957607f821691505b60208210811415611053577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561109b5761109b611059565b500190565b6000828210156110b2576110b2611059565b50039056fea164736f6c6343000809000aa164736f6c6343000809000a" - }, - "0x4200000000000000000000000000000000000013": { - "balance": "00", - "storage": {}, - "code": "0x4B60005260206000F3" - }, - "0x4200000000000000000000000000000000000006": { - "balance": "00", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000006": "0x0000000000000000000000004200000000000000000000000000000000000010", - "0x0000000000000000000000000000000000000000000000000000000000000003": "0x457468657200000000000000000000000000000000000000000000000000000a", - "0x0000000000000000000000000000000000000000000000000000000000000004": "0x4554480000000000000000000000000000000000000000000000000000000006" - }, - "code": "0x608060405234801561001057600080fd5b50600436106101005760003560e01c806370a0823111610097578063a9059cbb11610066578063a9059cbb14610237578063ae1f6aaf1461024a578063c01e1bd61461028f578063dd62ed3e146102af57600080fd5b806370a08231146101d357806395d89b41146102095780639dc29fac14610211578063a457c2d71461022457600080fd5b806323b872dd116100d357806323b872dd14610167578063313ce5671461017a57806339509351146101ab57806340c10f19146101be57600080fd5b806301ffc9a71461010557806306fdde031461012d578063095ea7b31461014257806318160ddd14610155575b600080fd5b610118610113366004610c8f565b6102f5565b60405190151581526020015b60405180910390f35b6101356103b5565b6040516101249190610cd8565b610118610150366004610d74565b610447565b6002545b604051908152602001610124565b610118610175366004610d9e565b6104fd565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610124565b6101186101b9366004610d74565b6105ae565b6101d16101cc366004610d74565b61065f565b005b6101596101e1366004610dda565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b61013561073e565b6101d161021f366004610d74565b61074d565b610118610232366004610d74565b610820565b610118610245366004610d74565b6108d1565b60065461026a9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610124565b60055461026a9073ffffffffffffffffffffffffffffffffffffffff1681565b6101596102bd366004610df5565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b60007f01ffc9a7a5cef8baa21ed3c5c0d7e23accb804b619e9333b597f47a0d84076e27f1d1d8b63000000000000000000000000000000000000000000000000000000007fffffffff0000000000000000000000000000000000000000000000000000000084167f01ffc9a70000000000000000000000000000000000000000000000000000000014806103ad57507fffffffff00000000000000000000000000000000000000000000000000000000848116908216145b949350505050565b6060600380546103c490610e28565b80601f01602080910402602001604051908101604052809291908181526020018280546103f090610e28565b801561043d5780601f106104125761010080835404028352916020019161043d565b820191906000526020600020905b81548152906001019060200180831161042057829003601f168201915b5050505050905090565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f4f564d5f4554483a20617070726f76652069732064697361626c65642070656e60448201527f64696e67206675727468657220636f6d6d756e6974792064697363757373696f60648201527f6e2e000000000000000000000000000000000000000000000000000000000000608482015260009060a4015b60405180910390fd5b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604760248201527f4f564d5f4554483a207472616e7366657246726f6d2069732064697361626c6560448201527f642070656e64696e67206675727468657220636f6d6d756e697479206469736360648201527f757373696f6e2e00000000000000000000000000000000000000000000000000608482015260009060a4016104f4565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4f564d5f4554483a20696e637265617365416c6c6f77616e636520697320646960448201527f7361626c65642070656e64696e67206675727468657220636f6d6d756e69747960648201527f2064697363757373696f6e2e0000000000000000000000000000000000000000608482015260009060a4016104f4565b60065473ffffffffffffffffffffffffffffffffffffffff1633146106e0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f6e6c79204c32204272696467652063616e206d696e7420616e64206275726e60448201526064016104f4565b6106ea8282610982565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161073291815260200190565b60405180910390a25050565b6060600480546103c490610e28565b60065473ffffffffffffffffffffffffffffffffffffffff1633146107ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f6e6c79204c32204272696467652063616e206d696e7420616e64206275726e60448201526064016104f4565b6107d88282610aa2565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161073291815260200190565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604c60248201527f4f564d5f4554483a206465637265617365416c6c6f77616e636520697320646960448201527f7361626c65642070656e64696e67206675727468657220636f6d6d756e69747960648201527f2064697363757373696f6e2e0000000000000000000000000000000000000000608482015260009060a4016104f4565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604360248201527f4f564d5f4554483a207472616e736665722069732064697361626c656420706560448201527f6e64696e67206675727468657220636f6d6d756e69747920646973637573736960648201527f6f6e2e0000000000000000000000000000000000000000000000000000000000608482015260009060a4016104f4565b73ffffffffffffffffffffffffffffffffffffffff82166109ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016104f4565b8060026000828254610a119190610eab565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610a4b908490610eab565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff8216610b45576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016104f4565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015610bfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016104f4565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602081905260408120838303905560028054849290610c37908490610ec3565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b600060208284031215610ca157600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610cd157600080fd5b9392505050565b600060208083528351808285015260005b81811015610d0557858101830151858201604001528201610ce9565b81811115610d17576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114610d6f57600080fd5b919050565b60008060408385031215610d8757600080fd5b610d9083610d4b565b946020939093013593505050565b600080600060608486031215610db357600080fd5b610dbc84610d4b565b9250610dca60208501610d4b565b9150604084013590509250925092565b600060208284031215610dec57600080fd5b610cd182610d4b565b60008060408385031215610e0857600080fd5b610e1183610d4b565b9150610e1f60208401610d4b565b90509250929050565b600181811c90821680610e3c57607f821691505b60208210811415610e76577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008219821115610ebe57610ebe610e7c565b500190565b600082821015610ed557610ed5610e7c565b50039056fea164736f6c6343000809000a" - }, - "0xDeadDeAddeAddEAddeadDEaDDEAdDeaDDeAD0000": { - "balance": "00", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x577261707065642045746865720000000000000000000000000000000000001a", - "0x0000000000000000000000000000000000000000000000000000000000000001": "0x5745544800000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000012" - }, - "code": "0x6080604052600436106100bc5760003560e01c8063313ce56711610074578063a9059cbb1161004e578063a9059cbb146102cb578063d0e30db0146100bc578063dd62ed3e14610311576100bc565b8063313ce5671461024b57806370a082311461027657806395d89b41146102b6576100bc565b806318160ddd116100a557806318160ddd146101aa57806323b872dd146101d15780632e1a7d4d14610221576100bc565b806306fdde03146100c6578063095ea7b314610150575b6100c4610359565b005b3480156100d257600080fd5b506100db6103a8565b6040805160208082528351818301528351919283929083019185019080838360005b838110156101155781810151838201526020016100fd565b50505050905090810190601f1680156101425780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561015c57600080fd5b506101966004803603604081101561017357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610454565b604080519115158252519081900360200190f35b3480156101b657600080fd5b506101bf6104c7565b60408051918252519081900360200190f35b3480156101dd57600080fd5b50610196600480360360608110156101f457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013590911690604001356104cb565b34801561022d57600080fd5b506100c46004803603602081101561024457600080fd5b503561066b565b34801561025757600080fd5b50610260610700565b6040805160ff9092168252519081900360200190f35b34801561028257600080fd5b506101bf6004803603602081101561029957600080fd5b503573ffffffffffffffffffffffffffffffffffffffff16610709565b3480156102c257600080fd5b506100db61071b565b3480156102d757600080fd5b50610196600480360360408110156102ee57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135169060200135610793565b34801561031d57600080fd5b506101bf6004803603604081101561033457600080fd5b5073ffffffffffffffffffffffffffffffffffffffff813581169160200135166107a7565b33600081815260036020908152604091829020805434908101909155825190815291517fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c9281900390910190a2565b6000805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b820191906000526020600020905b81548152906001019060200180831161042f57829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552908352818420869055815186815291519394909390927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925928290030190a350600192915050565b4790565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600360205260408120548211156104fd57600080fd5b73ffffffffffffffffffffffffffffffffffffffff84163314801590610573575073ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14155b156105ed5773ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020548211156105b557600080fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526004602090815260408083203384529091529020805483900390555b73ffffffffffffffffffffffffffffffffffffffff808516600081815260036020908152604080832080548890039055938716808352918490208054870190558351868152935191937fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef929081900390910190a35060019392505050565b3360009081526003602052604090205481111561068757600080fd5b33600081815260036020526040808220805485900390555183156108fc0291849190818181858888f193505050501580156106c6573d6000803e3d6000fd5b5060408051828152905133917f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65919081900360200190a250565b60025460ff1681565b60036020526000908152604090205481565b60018054604080516020600284861615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f8101849004840282018401909252818152929183018282801561044c5780601f106104215761010080835404028352916020019161044c565b60006107a03384846104cb565b9392505050565b60046020908152600092835260408084209091529082529020548156fea265627a7a723158208c8d5eb81396ab38071a6f1e1993fa1d9a8c68b0bb30b6fabe5951e251fc82ac64736f6c63430005110032" - } - } -} \ No newline at end of file diff --git a/boba_community/fraud-detector/deployments/mainnet/env b/boba_community/fraud-detector/deployments/mainnet/env deleted file mode 100644 index 4e9d0ffbf..000000000 --- a/boba_community/fraud-detector/deployments/mainnet/env +++ /dev/null @@ -1,6 +0,0 @@ -TARGET_NAME="mainnet" -L1_RPC_ENDPOINT="https://mainnet.infura.io/v3/YOUR_INFURA_KEY_HERE" -L2_RPC_ENDPOINT="https://mainnet.boba.network" -ETH1_CTC_DEPLOYMENT_HEIGHT=13502893 -ADDRESS_MANAGER="0x8376ac6C3f73a25Dd994E0b0669ca7ee0C02F089" -L2_CHAIN_ID=288 diff --git a/boba_community/fraud-detector/docker-compose-fraud-detector.yml b/boba_community/fraud-detector/docker-compose-fraud-detector.yml index 009857739..3f5fe521b 100644 --- a/boba_community/fraud-detector/docker-compose-fraud-detector.yml +++ b/boba_community/fraud-detector/docker-compose-fraud-detector.yml @@ -1,49 +1,38 @@ version: "3" -# An "--env-file" must be supplied to docker-compose. Example: -# docker-compose -# -f docker-compose-fraud-detector.yml \ -# --env-file deployments/local/env \ -# build -# For non-local targets, INFURA_API_KEY must also be set -networks: - default: - external: true - name: ops_default +x-l1_rpc_dtl: &l1_rpc_dtl + DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT: 'https://mainnet.infura.io/v3/YOUR_INFURA_KEY' + +x-l1_node_web3_url: &l1_node_web3_url + L1_NODE_WEB3_URL: 'https://mainnet.infura.io/v3/YOUR_INFURA_KEY' services: verifier_dtl: - image: bobanetwork/verifier_dtl:${TARGET_NAME} + image: bobanetwork/verifier_dtl:latest build: context: ../.. dockerfile: ./boba_community/fraud-detector/docker/Dockerfile.verifier_dtl - args: - TARGET_NAME: ${TARGET_NAME} env_file: - ../../ops/envs/dtl.env environment: - DATA_TRANSPORT_LAYER__L1_RPC_ENDPOINT: ${L1_RPC_ENDPOINT} + <<: *l1_rpc_dtl DATA_TRANSPORT_LAYER__CONFIRMATIONS: 8 + DATA_TRANSPORT_LAYER__SYNC_FROM_L1: 'true' DATA_TRANSPORT_LAYER__SYNC_FROM_L2: 'false' - DATA_TRANSPORT_LAYER__L2_CHAIN_ID: ${L2_CHAIN_ID} - DATA_TRANSPORT_LAYER__ADDRESS_MANAGER: ${ADDRESS_MANAGER} + DATA_TRANSPORT_LAYER__L2_CHAIN_ID: 288 + DATA_TRANSPORT_LAYER__ADDRESS_MANAGER: '0x8376ac6C3f73a25Dd994E0b0669ca7ee0C02F089' DATA_TRANSPORT_LAYER__POLLING_INTERVAL: 10000 - DATA_TRANSPORT_LAYER__ETH1_CTC_DEPLOYMENT_HEIGHT: ${ETH1_CTC_DEPLOYMENT_HEIGHT} -# ports: -# - ${DTL_PORT:-7878}:7878 -# - ${REGISTRY_PORT:-8080}:8081 -# volumes: -# - /var/tmp/verifier/dtl_db:/db + DATA_TRANSPORT_LAYER__ETH1_CTC_DEPLOYMENT_HEIGHT: 13502893 + ports: + - ${DTL_PORT:-7878}:7878 + - ${REGISTRY_PORT:-8080}:8081 verifier_l2geth: depends_on: - verifier_dtl - image: bobanetwork/l2geth:${TARGET_NAME} + image: bobanetwork/l2geth:release deploy: replicas: 1 - build: - context: ../.. - dockerfile: ./ops/docker/Dockerfile.geth entrypoint: sh ./geth.sh env_file: - ../../ops/envs/geth.env @@ -58,31 +47,31 @@ services: BLOCK_SIGNER_KEY: "6587ae678cf4fc9a33000cdbf9f35226b71dcc6a4684a31203241f9bcfd55d27" BLOCK_SIGNER_ADDRESS: "0x00000398232E2064F896018496b4b44b3D62751F" ROLLUP_POLL_INTERVAL_FLAG: "10s" + ROLLUP_ENFORCE_FEES: 'true' + EMERGENCY_FORK_NUMBER: 310215 ports: - ${VERIFIER_HTTP_PORT:-8547}:8545 - ${VERIFIER_WS_PORT:-8548}:8546 -# volumes: -# - /var/tmp/verifier/l2geth_vol:/root/.ethereum fraud-detector: depends_on: - verifier_dtl - verifier_l2geth - image: bobanetwork/fraud-detector:${TARGET_NAME} + image: bobanetwork/fraud-detector:latest deploy: replicas: 1 build: context: ../.. dockerfile: ./boba_community/fraud-detector/docker/Dockerfile.fraud-detector environment: - L1_NODE_WEB3_URL: ${L1_RPC_ENDPOINT} + <<: *l1_node_web3_url L1_CONFIRMATIONS: 8 - L2_NODE_WEB3_URL: ${L2_RPC_ENDPOINT} + L2_NODE_WEB3_URL: https://lightning-replica.boba.network L2_CHECK_INTERVAL: 10 VERIFIER_WEB3_URL: http://verifier_l2geth:8545 - ADDRESS_MANAGER_ADDRESS: ${ADDRESS_MANAGER} - L1_DEPLOYMENT_BLOCK: ${ETH1_CTC_DEPLOYMENT_HEIGHT} + ADDRESS_MANAGER_ADDRESS: '0x8376ac6C3f73a25Dd994E0b0669ca7ee0C02F089' + L1_DEPLOYMENT_BLOCK: 13502893 L2_START_BLOCK: 1 ports: - ${FRAUD_CHECKER_HTTP_PORT:-8555}:8555 - + diff --git a/boba_community/fraud-detector/docker/Dockerfile.verifier_dtl b/boba_community/fraud-detector/docker/Dockerfile.verifier_dtl index 66570a886..bc275eede 100644 --- a/boba_community/fraud-detector/docker/Dockerfile.verifier_dtl +++ b/boba_community/fraud-detector/docker/Dockerfile.verifier_dtl @@ -1,6 +1,5 @@ -FROM bobanetwork/data-transport-layer -ARG TARGET_NAME +FROM bobanetwork/data-transport-layer:release -COPY boba_community/fraud-detector/deployments/${TARGET_NAME}/state-dump.latest.json /opt/optimism/packages/data-transport-layer/state-dumps/state-dump.latest.json +COPY boba_community/fraud-detector/docker/state-dump.latest.json /opt/optimism/packages/data-transport-layer/state-dumps/state-dump.latest.json ENTRYPOINT ["node", "dist/src/services/run.js"] diff --git a/boba_community/fraud-detector/deployments/mainnet/state-dump.latest.json b/boba_community/fraud-detector/docker/state-dump.latest.json similarity index 100% rename from boba_community/fraud-detector/deployments/mainnet/state-dump.latest.json rename to boba_community/fraud-detector/docker/state-dump.latest.json diff --git a/boba_documentation/Community_Verifier.md b/boba_documentation/Community_Verifier.md index 818b49ce1..0ca2c8437 100644 --- a/boba_documentation/Community_Verifier.md +++ b/boba_documentation/Community_Verifier.md @@ -1,3 +1,3 @@ # Detecting Fraud in the Boba Mainnet -This material has been moved to the main Boba user docs [here](https://docs.boba.network/user-docs/002_fraud-detector). \ No newline at end of file +This material has been moved to the main Boba user docs [here](https://docs.boba.network/user-docs/002_fraud-detection). \ No newline at end of file diff --git a/boba_documentation/Developing_on_Windows.md b/boba_documentation/Developing_on_Windows.md deleted file mode 100644 index 830cc8368..000000000 --- a/boba_documentation/Developing_on_Windows.md +++ /dev/null @@ -1,52 +0,0 @@ -# Developing for Boba on Windows - -## Prequisites - -- User folder can't have a space - - A lot of the other programs we're using can't handle a space in paths. - So make sure there's no spaces for your users folder. -- [Windows Terminal](#windows-terminal) -- [Git](#git) -- [Docker](#docker) -- [NVM](#nvm) -- [Yarn](#yarn) - -### Windows terminal - -Windows terminal is a great substitute for terminal on MacOS/Linux. First download windows terminal from [here](https://www.microsoft.com/en-us/p/windows-terminal/9n0dx20hk701#activetab=pivot:overviewtab). -Now that you have it installed we're going to install [Ubuntu](https://ubuntu.com/tutorials/ubuntu-on-windows#1-overview). Ubuntu creates a WSL2 environment for us to develop and it's on bash! Follow all the instructions from the link it's pretty straightforward to follow this guide. Once you have Ubuntu we're going to do everything from there not from powershell or cmd because they don't have access to all the bash commands. Make sure for all the other steps that you're running Windows Terminal as an administator as it'll make everything a lot easier. To do that right click on the app and then run as administrator. - -### Git - -Git should already be installed on your Ubuntu server but in case it's not follow [this](https://www.digitalocean.com/community/tutorials/how-to-install-git-on-ubuntu-18-04-quickstart) guide to get it up and running. - -### Docker - -Install Docker from [here](https://docs.docker.com/docker-for-windows/install/). Follow through the instructions and restart your computer. If you run into this error: -> `Hardware assisted virtualization and data execution protection must be enabled in the BIOS` - -You're going to want to restart your computer and hold down **esc, f1, f2, f3, f4, f8 or delete** depending on your chip. It should tell you waht to hold when you're restarting to enter your bios settings. Then you're going to want to enable virtualization from here. This setting may be hidden under advanced → CPA configuration and then virtualization. Save this and then Docker should be up and running! - -### NVM - -On your Ubuntu terminal **running as an admin** run the following command to instal cURL: -> `sudo apt-get install curl` - -Then install nvm (node version manager): -> `curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bash` - -To verify installation, enter: `command -v nvm`. This should return 'nvm', if you receive 'command not found' or no response at all, close your current terminal, reopen it, and try again. - -You can then use `nvm install [node-version]` to install whatever version of node you want. We recommend 14.17.3. Then use `nvm use [node-version]` to use that as your default. You can read more about NVM [here](https://github.com/nvm-sh/nvm). If you ran into any issues installing a lot of troubleshooting options can be found there as well. - -### Yarn - -Installing yarn is super easy with all the infrastructure we have use: - ->`npm install --global yarn` - -## All Done! - -You should have everything you need to follow the rest of the tutorial [here](https://github.com/omgnetwork/optimism/). Good luck and have fun developing on L2! - - diff --git a/boba_documentation/Frontend_Development.md b/boba_documentation/Frontend_Development.md index 39bc46b03..7623b7755 100644 --- a/boba_documentation/Frontend_Development.md +++ b/boba_documentation/Frontend_Development.md @@ -84,8 +84,4 @@ rpcUrl: `http://localhost:8545` **The default for all development is a local chain that you spin up on your local machine through Docker.** -However, in very rare circumstances, such as testing timelock logic for the DAO, it may be useful to work with a live chain. - -To develop on non-local other chains, you will need to obtain either Rinkeby ETH (e.g. from https://faucet.rinkeby.io) or for work on Mainnet, ETH. Once you have some ETH, then your first step will be to bridge some to the L2, since otherwise you will not be able to do anything on the L2 and all your function calls will fail. - -One you have obtained some eth, then simply select the chain you want to work on from the top left dropdown, such as Rinkeby. Note that Rinkeby is used for active development, and therefore, may be down, have undocumented features, or otherwise require steps that are not part of this standard writeup. \ No newline at end of file +However, in very rare circumstances, such as testing timelock logic for the DAO, it may be useful to work with a live chain. To develop on other chains, you will need to obtain either Rinkeby ETH (e.g. from https://faucet.rinkeby.io) or for work on Mainnet, ETH. Once you have some ETH, then your first step will be to bridge some to the L2, since otherwise you will not be able to do anything on the L2 and all your function calls will fail. Once you have obtained some ETH, then set the chain you want to work on in the .env. Note that Rinkeby is used for active development, and therefore, may be down, have undocumented features, or otherwise require steps that are not part of this writeup. \ No newline at end of file diff --git a/boba_documentation/Price_Data_Feeds_Overview.md b/boba_documentation/Price_Data_Feeds_Overview.md new file mode 100644 index 000000000..3b4aeb1b9 --- /dev/null +++ b/boba_documentation/Price_Data_Feeds_Overview.md @@ -0,0 +1,222 @@ +# Price Data Feeds - Overview + +- [Price Data Feeds - Overview](#price-data-feeds---overview) + * [1. Boba-Straw](#1-boba-straw) + - [Feeds supported:](#feeds-supported-) + + [1.a I want to be a data source](#1a-i-want-to-be-a-data-source) + - [Rounds and on-chain aggregation](#rounds-and-on-chain-aggregation) + - [Submitting price data - basics](#submitting-price-data---basics) + * [step 0:](#step-0-) + * [step 1:](#step-1-) + - [Actually submitting price data](#actually-submitting-price-data) + * [step 3:](#step-3-) + + [1.b I want my contracts to receive data](#1b-i-want-my-contracts-to-receive-data) + - [Extracting the price](#extracting-the-price) + - [Alternate data queries](#alternate-data-queries) + * [2. Witnet Price Feeds](#2-witnet-price-feeds) + - [Feeds supported:](#feeds-supported--1) + + [I want my contracts to receive data](#i-want-my-contracts-to-receive-data) + * [3. Turing](#3-turing) + - [Feeds supported:](#feeds-supported--2) + + [I want my contracts to receive data](#i-want-my-contracts-to-receive-data-1) + +Price Feed oracles are an essential part of Boba, which allow smart contracts to work with external data and open the path to many more use cases. Currently Boba has several options to get real world price data directly into your contracts - each different in the way they operate to procure data for smart contracts to consume. This list will be updated frequently: + +1. Boba-Straw +2. Witnet +3. Turing (Rinkeby) + +## 1. Boba-Straw + +Boba-Straw, Boba's self-operated price feed oracle is based on ChainLink's implementation and can handle price data aggregation from multiple trusted external entities (data oracles), on-chain. Currently, Boba-Straw is powered by Folkvang, our first data oracle. To further increase reliability and precision, we are adding more data-sources. Data oracles accumulate $BOBA for every submission to offset operational and gas costs. To be a data-provider oracle and earn $BOBA refer to the section below. In the near future, $BOBA might also be used as a "fee" token to utilize/subscribe to these feeds. + +#### Feeds supported: + +*Mainnet*: [ETH/USD, BOBA/USD, WBTC/USD, OMG/USD] + +*Rinkeby*: [ETH/USD, BOBA/USD, WBTC/USD, OMG/USD] + +*Fee*: free, in the future $BOBA subscription based + +*Quick-Link - Mainnet*: https://blockexplorer.boba.network/address/0x01a109AB8603ad1B6Ef5f3B2B00d4847e6E554b1 + +*Quick-Link - Rinkeby*: https://blockexplorer.rinkeby.boba.network/address/0xf3EBFc93C53694E3679c52ACacB9C7fD6d7f362E + +### 1.a I want to be a data source + +To be a data oracle and help Boba-Straw by submitting price data: + +- You must have reliable, independent price data. While price data from all oracles is aggregated and determined on-chain, more layers of data-aggregation helps build reliability + +- You must react to the rounds for aggregation, to seamlessly work with other independent data providers + +To find the when and hows of submitting data, let's take a quick look at the round structure first. + +#### Rounds and on-chain aggregation + +Token price data aggregation happens in rounds, triggered by oracles when there is a need for price update. The 'price' answer of the latest *finalized round* is the latest price. Here, `finalized round` refers to a round with >= min submissions. + +For a round of aggregation, independent oracles submit their 'price' answers. When a round receives enough submissions (>= min submissions), the price update is accepted and computed to the median of all submissions for the specific round. Then for a further price update we move to the next round. + +The 'price' answer for the round isn't finalized/accepted until the round has received a certain 'min no of answer submissions' from separate oracles. While the round moves between having min < submissions < max, the computed answer can vary depending on the data received up till that point. And after the 'max no of submissions on the round' the 'price' answer is finalized and fixed. If a round does not receive 'min no of answer submissions', the round can be superseded after a timeout period (currently 3mins). + +#### Submitting price data - basics + +##### step 0: + +To be eligible to submit price data, the oracle (and the oracle admin) addresses needs to be added by the admin + +- oracle - the address that will submit the price + +- oracle admin - the address that will control withdrawals of accumulated $BOBA + +##### step 1: + +The rules of the game to manage the round co-ordination between all the independent data oracles are: + +- Trigger a round if you notice a price update that needs to be recorded + +- Keep checking and provide your answer for the round if someone else has triggered a round + +- Make sure you do not try to trigger a new round when the last round is unfinished and the timeout period hasn't elapsed. There is a 'restartDelay' - the minimum number of rounds you have to wait before you can trigger a new round. + +Use the **`function oracleRoundState(address _oracle, uint32 _queriedRoundId)`** to determine eligibility for specific roundId. The same method **`oracleRoundstate(_oracle, 0)`** can also be used to suggest the next eligible round for the oracle. + +#### Actually submitting price data + +##### step 3: + +The main contracts to interact with are the respective FluxAggregators for each feed. + +*To submit data to the feed* the oracles need to call **`submit(roundId, value)`** + +Here, `value` is the price to submit, note: in decimals as returned by the contract (currently set to 8) and `roundId` refers to round, which is consecutive and starts from 1 for the specific feed. The oracle can only submit once for a specific round. + +For more info refer: + +[[contracts]](https://github.com/omgnetwork/optimism-v2/tree/develop/packages/boba/contracts/contracts/oracle) + +[[examples]](https://github.com/omgnetwork/optimism-v2/tree/develop/boba_examples/boba-straw) + +### 1.b I want my contracts to receive data + +To fetch price feed data directly into your contracts, make your contract call the "Feed Registry" to extract the current and historical prices for all the feeds on Boba-Straw: + +*Feed Registry (Mainnet)*: 0x01a109AB8603ad1B6Ef5f3B2B00d4847e6E554b1 + +*Feed Registry (Rinkeby)*: 0xf3EBFc93C53694E3679c52ACacB9C7fD6d7f362E + +Feeds are registered to the registry in the form of base/quote pairs, these terms used here and throughout - 'base' refers to the crypto asset/token and 'quote' refers to the asset (or fiat currency) to use as a reference for the price. + +A quick note on fees and subscription: Currently the feed is free to use for the contracts. Once we transition to the $BOBA subscription model, you would have to pay $BOBA and pre-subscribe your contracts (time based) to extract data from the feed. + +#### Extracting the price + +To get the latest price data call method **`latestRoundData(base, quote)`** + +To get the price data from a certain past round (historical price) call method **`getRoundData(base, quote, roundId)`**. The `roundId` supplied here is phaseId plus aggregator roundId, for reference query the latest `roundId`. The answer returned will be of the form of decimals specified on the contract call method **`decimals(base, quote)`**. + +For example, + +```javascript +import "@boba/contracts/oracle/FeedRegistry.sol"; + +contract MyContract { + +address feedRegistryAddress = '0x01a109AB8603ad1B6Ef5f3B2B00d4847e6E554b1'; + + function readFromPriceFeed() external view returns(int256) { + FeedRegistry feedRegistry = FeedRegistry(feedRegistryAddress); + + address bobaTokenAddress = '0xa18bF3994C0Cc6E3b63ac420308E5383f53120D7'; + address USD = address(840); + + (,int256 value,,uint256 time,) = feedRegistry.latestRoundData(bobaTokenAddress, USD); + // do something with time + + return value; + } + +} +``` + +`base` is always the token address and `quote` is fiat in the ISO_4217 form + +#### Alternate data queries + +While the above is the recommended way to ask for the price data, and check time along with it, there is also the option to only query the price: + +For the latest price call **`latestAnswer(base, quote)`**. + +For the price from a certain past round call **`getAnswer(base, quote, roundId)`**. `roundId` supplied here is `phaseId` plus aggregator `roundId`. + +For the latest completed round call **`latestRound(base, quote)`**. + +To get the latest timestamp call **`latestTimestamp(base, quote)`**. + +## 2. Witnet Price Feeds + +Witnet is a decentralized oracle network, with multiple price feeds currently live on Boba. The price feed is backed by several witnesses/witnet nodes whose data are aggregated and averaged to provide a decentralized and reliable price. Learn more about Witnet protocol [here]( https://docs.witnet.io/) + +#### Feeds supported: + +*Mainnet*: [BOBA/USDT, BTC/USD, ETH/USD, FRAX/USDT, USDC/USD, USDT/USD] + +*Rinkeby*: [BOBA/USDT, BTC/USD, ETH/USD, FRAX/USDT, FXS/USDT, OMG/BTC, OMG/ETH, OMG/USDT, USDC/USD, USDT/USD] + +*Quick-Link*: https://feeds.witnet.io/ + +### I want my contracts to receive data + +It's just as easy to make your contracts listen to Witnet's price feed. Please refer to Witnet's official guide [here](https://docs.witnet.io/ethereum/price-feeds/) + +## 3. Turing + +*Note: Turing is currently in testing on Boba Rinkeby* + +Turing is Boba's off-chain compute system, and among many other things - you can fetch real-world market price data too! Turing gives you the flexibility to select and set up your own data source, if your use case demands it. Or even select and work with any other reliable service that can help provide such data + +In the background, Turing works with a modified L2Geth, by intercepting and injecting the tx with real world responses. Learn more about Turing [here](https://github.com/omgnetwork/optimism-v2/tree/develop/packages/boba/turing) + +Note: Unlike a feed contract where every data query remains on-chain, Turing requests are a call to the external endpoint to retrieve the price data - which are subject to unavailability or distortion. Best practices include using multiple on-chain oracles and/or off-chain 'augmentation' where off-chain compute is used to estimate the reliability of on-chain oracles. + +#### Feeds supported: + +*Rinkeby*: [potentially everything, dependent on your source] + +*Fee*: 0.01 BOBA for one Turing request + +*Quick-Link*: https://github.com/omgnetwork/optimism-v2/tree/develop/packages/boba/turing#feature-highlight-2-using-turing-to-access-real-time-trading-data-from-within-your-solidity-smart-contract + +### I want my contracts to receive data + +To use Turing, deploy your TuringHelper and add credits on behalf of your helper on the TuringCredit contract. With the TuringHelper added, register your contract that would make use of Turing calls. Your contract can now use Turing to query off-chain price data, through the helper. For example, + +```javascript +interface Helper { + function TuringTx(string memory, bytes memory) external returns (bytes memory); +} + +contract MyContract { + +address public helperAddr; + + function getCurrentQuote(string memory _url, string memory pair) public returns (uint256, uint256) { + Helper myHelper = Helper(helperAddr); + bytes memory encRequest = abi.encode(pair); + bytes memory encResponse = myHelper.TuringTx(_url, encRequest); + + (uint256 market_price, uint256 time) = abi.decode(encResponse,(uint256,uint256)); + + } + +} +``` + +`_url` is your personal data source + +For a more detailed walk through, refer to: + +[[guide]](https://github.com/omgnetwork/optimism-v2/blob/develop/packages/boba/turing/README.md) + +[[examples]](https://github.com/omgnetwork/optimism-v2/blob/develop/packages/boba/turing/contracts/Lending.sol) \ No newline at end of file diff --git a/boba_documentation/Readme.md b/boba_documentation/Readme.md deleted file mode 100644 index b5743d8e6..000000000 --- a/boba_documentation/Readme.md +++ /dev/null @@ -1,140 +0,0 @@ -- [Starting a local basic Optimism L1/L2 with Boba contracts and services](#starting-a-local-basic-optimism-l1-l2-with-boba-contracts-and-services) - * [Starting a local basic Optimism L1/L2](#starting-a-local-basic-optimism-l1-l2) - + [Overall Setup](#overall-setup) - * [(Re)Building the entire system or parts of the base L1/L2](#-re-building-the-entire-system-or-parts-of-the-base-l1-l2) - * [(Re)Building the entire system or parts of the Boba contracts and services](#-re-building-the-entire-system-or-parts-of-the-boba-contracts-and-services) - - [Viewing docker container logs](#viewing-docker-container-logs) - + [Running unit tests](#running-unit-tests) - + [Running integration tests](#running-integration-tests) - -# Overall Setup - -Clone the repository, open it, and install nodejs packages with `yarn`: - -```bash -git clone git@github.com:omgnetwork/optimism.git -cd optimism -yarn clean -yarn install -yarn build -``` -With all this done we can move on to actually spinning up a local version of the Optimism L1/L2. - -**NOTE: You should recompile all packages whenever you move from one branch to another.** -Use the below commands to recompile the packages. - -Note: _Running out of space on your Docker, or having other having hard to debug issues_? Try running `docker system prune -a --volumes` and then rebuild the images. - -## Starting a local basic Optimism L1/L2 - -You can change the BUILD and DAEMON values to control if everything is rebuilt (`BUILD=1`, very slow), and if you want to see all the debug information (`DAEMON=0`) - -**Before running any Docker related commands make sure you have Docker up and running.** - -```bash -cd ops -export COMPOSE_DOCKER_CLI_BUILD=1 # these environment variables significantly speed up build time -export DOCKER_BUILDKIT=1 -docker-compose build -docker-compose up -V -``` - - -## (Re)Building the entire system or parts of the base L1/L2 - -If you want to run an Optimistic Ethereum node OR **if you want to run the integration tests**, you'll need to build the rest of the system. - -If you want to make a change to a container, you'll need to take it down and rebuild it. -For example, if you make a change in l2geth: - -```bash -cd ops -docker-compose stop -- l2geth -docker-compose build -- l2geth -docker-compose start l2geth -``` - -For the typescript services, you'll need to rebuild the `builder` so that the compiled -files are re-generated, and then your service, e.g. for the batch submitter - -```bash -cd ops -docker-compose stop -- batch_submitter -docker-compose build -- builder batch_submitter -docker-compose start batch_submitter -``` - -Source code changes can have an impact on more than one container. -**If you're unsure about which containers to rebuild, just rebuild them all**: - -```bash -cd ops -docker-compose down -docker-compose build -docker-compose up -``` - -Finally, **if you're running into weird problems and nothing seems to be working**, run: - -```bash -cd optimism -yarn clean -yarn build -cd ops -docker-compose down -v -docker-compose build -docker-compose up -``` - -## (Re)Building the entire system or parts of the Boba contracts and services - -```bash -cd ops -export COMPOSE_DOCKER_CLI_BUILD=1 # these environment variables significantly speed up build time -export DOCKER_BUILDKIT=1 -docker-compose build -docker-compose -f docker-compose.yml up -V -``` - -To build individual Boba services: - -```bash -docker-compose build -- boba_message-relayer-fast -``` - -**Note: First you will have to comment out various dependencies in the `docker-compose.yml`.** - -#### Viewing docker container logs - -By default, the `docker-compose up` command will show logs from all services, and that -can be hard to filter through. In order to view the logs from a specific service, you can run: - -```bash -docker-compose logs --follow -``` - -### Running unit tests - -Before running tests: **follow the above instructions to get everything built.** Run unit tests for all packages in parallel via: - -```bash -yarn test -``` - -To run unit tests for a specific package: - -```bash -cd packages/package-to-test -yarn test -``` - -### Running integration tests - -Follow above instructions for building the whole stack. Build and run the integration tests: - -```bash -cd integration-tests -yarn build:integration -yarn test:integration -``` - diff --git a/boba_documentation/Service_maintenance.md b/boba_documentation/Service_maintenance.md deleted file mode 100644 index 85d809b60..000000000 --- a/boba_documentation/Service_maintenance.md +++ /dev/null @@ -1,168 +0,0 @@ -# Service maintenance - -## Docker containers - -We have six main containers and five secondary containers that provide the monitor and subgraph services. - -### Main containers - -* [bobanetwork/deployer-rinkeby](https://hub.docker.com/layers/bobanetwork/deployer-rinkeby/production-v1/images/sha256-8ca509eb7a830ee862318225a2d5558f868d139a745edaff448ec3ccb90965e8?context=repo) - - It serves `addresses.json` and `state-dump.latest.json` files so that l2geth container and data-transport-layer can fetch the `ADDRESS_MANAGER_ADDRESS` and `ABI` of L1 pre-deployed contracts. - - Normally, this container uses about **15MB** memory. - -* [bobanetwork/l2geth](https://hub.docker.com/layers/156092279/bobanetwork/l2geth/production-v1/images/sha256-d5f099b01629da9ca93af25705d326d90bb7d100695e0a66cc920871705ff890?context=repo) - - The l2geth container takes around 500MB memory. For safety and maintenance reasons, we should allocate **1GB** of memory to this service. - - > Note: We didn't see a large increase in memory usage of **l2geth** when we ran the performance test. - -* [bobanetwork/data-transport-layer](https://hub.docker.com/layers/156092207/bobanetwork/data-transport-layer/production-v1/images/sha256-07d4415aab46863b8c7996c1c40f6221f3ac3f697485ccc262a3a6f0478aa4fb?context=repo) - - The data-transport-layer syncs L1 and provides the index service. It only uses about **50MB** of memory. - -* [bobanetwork/batch-submitter](https://hub.docker.com/layers/156091606/bobanetwork/batch-submitter/production-v1/images/sha256-b3e61c1350b94cca73853867e1267e6f0e197ffbf7661f76c5c373e85eb3e70f?context=repo) - - The batch submitter submits TX and state root batches to CTC and SCC contracts. It takes about **100MB** of memory. - -* [bobanetwork/message-relayer](https://hub.docker.com/layers/156091959/bobanetwork/message-relayer/production-v1/images/sha256-52ae4dbe41895c331ee3dc05955ad8c50c1319f91aaf3b4747d3ded2305382b4?context=repo) and [bobanetwork/message-relayer-fast](https://hub.docker.com/layers/156091184/bobanetwork/message-relayer-fast/production-v1/images/sha256-4e973130ca9cd5704ae3ce83f8c01682851b73835753268203bba91df7213167?context=repo) - - Both message relayers need at least **1GB** of memory. - -### Secondary containers - -Our main services won't be affected by these secondary services, so it's safe for them to reboot when they have any problems. - -* Graph-node, postgres, ipfs -* bobanetwork/gas-oracle -* bobanetwork/transaction-monitor -* enyalabs/bobanetwork-monitor - -## Memory usage and recommendation - -| Container | Minimum memory usage | Recommanded memory allocation | -| :-----------------------: | :------------------: | :---------------------------: | -| bobanetwork/deployer-rinkeby | 15MB | 128MB | -| bobanetwork/l2geth | 500MB | **2GB** | -| bobanetwork/data-transport-layer | 100MB | 512MB | -| bobanetwork/batch-submitter | 1GB | **2GB** | -| bobanetwork/message-relayer | 1GB | **2GB** | -| bobanetwork/message-relayer-fast | 1GB | **2GB** | - -> NOTE: -> -> `bobanetwork/l2geth`: it's the most important service, so we should give as much memory as we can. - -## Possible errors - -* [bobanetwork/batch-submitter](https://hub.docker.com/layers/156091606/bobanetwork/batch-submitter/production-v1/images/sha256-b3e61c1350b94cca73853867e1267e6f0e197ffbf7661f76c5c373e85eb3e70f?context=repo) - - The queued data in the `CTC-queue` contract might not match to the data of the L1 block. We have noticed the following situations: - - * `The timestamp of the queued element` >` timestamp of L1 block` and `block number of the queued element` === `block number of L1 block`. - * `The timestamp of the queued element` >` timestamp of L1 block` and `block number of the queued element` > `block number of L1 block`. - - The second issue can be fixed by enabling the [AUTO_FIX_BATCH_OPTIONS_CONF](https://github.com/omgnetwork/optimism/blob/8fd511e608744f182f8a10e6fb5aa5d27f581860/packages/batch-submitter/src/exec/run-batch-submitter.ts#L241) to `fixMonotonicity`. - - Please comment out [fixedBatch.push(ele)](https://github.com/omgnetwork/optimism/blob/8fd511e608744f182f8a10e6fb5aa5d27f581860/packages/batch-submitter/src/batch-submitter/tx-batch-submitter.ts#L492) and enable [AUTO_FIX_BATCH_OPTIONS_CONF](https://github.com/omgnetwork/optimism/blob/8fd511e608744f182f8a10e6fb5aa5d27f581860/packages/batch-submitter/src/exec/run-batch-submitter.ts#L241) to `fixSkippedDeposits` for the first issue. - - > NOTE: - > - > You don't have to stop the batch-submitter in EC2 or ECS to fix the issue. Please add `.env` file to `packages/batch-submitter` and fix it via running the batch-submitter locally: - > - > ```bash - > yarn build - > yarn start - > ``` - > - > Once the local batch submitter pushes the correct queued elements to CTC, the production one will start to work. - - -L2 geth genesis structure: - -```go -// Genesis specifies the header fields, state of a genesis block. It also defines hard -// fork switch-over blocks through the chain configuration. -type Genesis struct { - Config *params.ChainConfig `json:"config"` - Nonce uint64 `json:"nonce"` - Timestamp uint64 `json:"timestamp"` - ExtraData []byte `json:"extraData"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - Difficulty *big.Int `json:"difficulty" gencodec:"required"` - Mixhash common.Hash `json:"mixHash"` - Coinbase common.Address `json:"coinbase"` - Alloc GenesisAlloc `json:"alloc" gencodec:"required"` - - // These fields are used for consensus tests. Please don't use them - // in actual genesis blocks. - Number uint64 `json:"number"` - GasUsed uint64 `json:"gasUsed"` - ParentHash common.Hash `json:"parentHash"` - - // OVM Specific, used to initialize the l1XDomainMessengerAddress - // in the genesis state - L1FeeWalletAddress common.Address `json:"-"` - L1CrossDomainMessengerAddress common.Address `json:"-"` - AddressManagerOwnerAddress common.Address `json:"-"` - GasPriceOracleOwnerAddress common.Address `json:"-"` - L1StandardBridgeAddress common.Address `json:"-"` - ChainID *big.Int `json:"-"` -} -``` - -## How to restart Mainnet Service - -### Connect to EC2 Instance - -``` -ssh -i "KEY.pem" ubuntu@IP.compute-1.amazonaws.com -``` - -### Update Parameters - -All docker configuration files are in `bobanetwork-mainnet/production-v1`. There are four files: - -* `docker-compose-gas-oracle.yml` - Gas Oracle Service - -* `docker-compose-mainnet.yml` - Main Service - - It has `deployer`, `bobanetwork-deployer`, `data-transport-layer` and `l2geth` services - -* `docker-compose-mainnet-relative.yml` - Secondary service - - It has `batch-submitter`, `message-relayer` and `message-relayer-fast` service - -* `docker-compose-transaction-monitor.yml` - Main Monitor service - -* `docker-compose-monitor.yml` - Datadog Monitor Service - -If you don't update or add the `FROM_L2_TRANSACTION_INDEX` in `docker-compose-mainnet-relative.yml` before restarting the service, the `message relayer` and `message relayer fast` will scan from the L2 0 block or L2 block number that is set up last time. It takes a really long time to sync up the l2 block. - -[**RECOMMENDATION**] - -The `FROM_L2_TRANSACTION_INDEX` should be set to the correct L2 block which doesn‘t have any pending messages before that block. Thus, the `FROM_L2_TRANSACTION_INDEX` variables for the `message relayer` and `message relayer fast` are different. - -### Restart Services - -```bash -cd boba-mainnet/production-v1 -docker-compose -f [docker-compose.yml] down -``` - -If you want to delete volume of dtl, please run - -```bash -cd /mnt/efs -sudo rm -rf ./dtl -``` - -Restart services via: - -```bash -docker-compose -f [docker-compose.yml] up -d -``` - -> NEVER DELETE `geth` FOLDER IN `/mnt/efs` ! - diff --git a/boba_examples/boba-straw/README.md b/boba_examples/boba-straw/README.md index cda8e1c59..accd4d153 100644 --- a/boba_examples/boba-straw/README.md +++ b/boba_examples/boba-straw/README.md @@ -38,6 +38,7 @@ Adjust the ETH, BOBA, OMG or WBTC prices that you want to provide on Rinkeby yarn install yarn submit ``` + To submit prices for selective tokens ```bash yarn install diff --git a/boba_examples/truffle-erc20/README.md b/boba_examples/truffle-erc20/README.md index 815497bdd..fd2f6ad68 100644 --- a/boba_examples/truffle-erc20/README.md +++ b/boba_examples/truffle-erc20/README.md @@ -1,4 +1,4 @@ -# Getting Started with Boba and Optimistic Ethereum v2: Simple ERC20 Token Truffle Tutorial +# Getting Started with Boba: Simple ERC20 Token Truffle Tutorial Hi there! Welcome to our ERC20 Truffle example. If you're interested in writing your first L2 smart contract using Truffle as your smart contract testing framework, then you've come to the right place. This repo serves as an example for how go through and compile/test/deploy your contracts on Ethereum and the Boba L2. diff --git a/integration-tests/test/rpc.spec.ts b/integration-tests/test/rpc.spec.ts index 7a8e833fd..3bfe22cdf 100644 --- a/integration-tests/test/rpc.spec.ts +++ b/integration-tests/test/rpc.spec.ts @@ -11,6 +11,7 @@ import { L2_CHAINID, isLiveNetwork, gasPriceForL2, + replicaProvider, } from './shared/utils' import chaiAsPromised from 'chai-as-promised' import { OptimismEnv } from './shared/env' @@ -27,8 +28,10 @@ chai.use(solidity) describe('Basic RPC tests', () => { let env: OptimismEnv let wallet: Wallet + let replicaWallet: Wallet const provider = injectL2Context(l2Provider) + const l2ReplicaProvider = injectL2Context(replicaProvider) let Reverter: Contract let revertMessage: string @@ -38,6 +41,8 @@ describe('Basic RPC tests', () => { before(async () => { env = await OptimismEnv.new() wallet = env.l2Wallet + replicaWallet = env.l2Wallet_2.connect(env.replicaProvider) + const Factory__Reverter = await ethers.getContractFactory( 'Reverter', wallet @@ -437,4 +442,94 @@ describe('Basic RPC tests', () => { expect(BigNumber.from(result.l2GasPrice)).to.deep.eq(l2GasPrice) }) }) + + describe('Replica RPC forward test', () => { + it('should correctly process a valid transaction', async () => { + const tx = defaultTransactionFactory() + tx.gasPrice = await gasPriceForL2() + const nonce = await replicaWallet.getTransactionCount() + const result = await replicaWallet.sendTransaction(tx) + await result.wait() + + expect(result.from).to.equal(replicaWallet.address) + expect(result.nonce).to.equal(nonce) + expect(result.gasLimit.toNumber()).to.equal(tx.gasLimit) + expect(result.gasPrice.toNumber()).to.equal(tx.gasPrice) + expect(result.data).to.equal(tx.data) + }) + + it('should not accept a transaction with the wrong chain ID', async () => { + const tx = { + ...defaultTransactionFactory(), + gasPrice: await gasPriceForL2(), + chainId: (await replicaWallet.getChainId()) + 1, + } + + await expect( + l2ReplicaProvider.sendTransaction( + await replicaWallet.signTransaction(tx) + ) + ).to.be.rejectedWith('invalid transaction: invalid sender') + }) + + it('should accept a transaction without a chain ID', async () => { + const tx = { + ...defaultTransactionFactory(), + nonce: await replicaWallet.getTransactionCount(), + gasPrice: await gasPriceForL2(), + chainId: null, // Disables EIP155 transaction signing. + } + const signed = await replicaWallet.signTransaction(tx) + const response = await l2ReplicaProvider.sendTransaction(signed) + await response.wait() + + expect(response.chainId).to.equal(0) + const v = response.v + expect(v === 27 || v === 28).to.be.true + }) + + it('should accept a transaction with a value', async () => { + const tx = { + ...defaultTransactionFactory(), + gasPrice: await gasPriceForL2(), + chainId: await replicaWallet.getChainId(), + data: '0x', + value: ethers.utils.parseEther('0.1'), + } + + const balanceBefore = await l2ReplicaProvider.getBalance( + replicaWallet.address + ) + const result = await replicaWallet.sendTransaction(tx) + const receipt = await result.wait() + expect(receipt.status).to.deep.equal(1) + + const balAfter = await l2ReplicaProvider.getBalance(replicaWallet.address) + expect(balAfter.lte(balanceBefore.sub(ethers.utils.parseEther('0.1')))).to + .be.true + }) + + it('should reject a transaction with higher value than user balance', async () => { + const balance = await replicaWallet.getBalance() + const tx = { + ...defaultTransactionFactory(), + gasPrice: await gasPriceForL2(), + chainId: await replicaWallet.getChainId(), + data: '0x', + value: balance.add(ethers.utils.parseEther('1')), + } + + await expect(replicaWallet.sendTransaction(tx)).to.be.rejectedWith( + 'invalid transaction: insufficient funds for gas * price + value' + ) + }) + + it('should correctly report OOG for contract creations', async () => { + const factory = await ethers.getContractFactory('TestOOGInConstructor') + + await expect(factory.connect(replicaWallet).deploy()).to.be.rejectedWith( + 'gas required exceeds allowance' + ) + }) + }) }) diff --git a/l2geth/CHANGELOG.md b/l2geth/CHANGELOG.md index 9f1c1dfea..e370688f4 100644 --- a/l2geth/CHANGELOG.md +++ b/l2geth/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 0.5.11 + +### Patch Changes + +- 9ef215b8: Various small changes to reduce our upstream Geth diff + +## 0.5.10 + +### Patch Changes + +- 2e7f6a55: Fixes incorrect timestamp handling for L1 syncing verifiers +- 81d90563: Bring back RPC methods that were previously blocked + ## 0.5.9 ### Patch Changes diff --git a/l2geth/Makefile b/l2geth/Makefile index ffcf38a22..3ac6a784f 100644 --- a/l2geth/Makefile +++ b/l2geth/Makefile @@ -11,7 +11,7 @@ GOBIN = ./build/bin GO ?= latest GORUN = env GO111MODULE=on go run -GOTESTRUN = env GO111MODULE=on EMERGENCY_FORK_NUMBER=0 go run +GOTESTRUN = env GO111MODULE=on go run geth: $(GORUN) build/ci.go install ./cmd/geth diff --git a/l2geth/README.md b/l2geth/README.md index 3a4127436..b2f26bc8a 100644 --- a/l2geth/README.md +++ b/l2geth/README.md @@ -16,7 +16,7 @@ configuration will determine the mode of operation. The configuration flags can be configured using either environment variables or passed at runtime as flags. -A prebuilt Docker image is available at `ethereumoptimism/go-ethereum`. +A prebuilt Docker image is available at `bobanetwork/l2geth`. To compile the code, run: ``` @@ -25,46 +25,39 @@ $ make geth ### Running a Sequencer -Running a sequencer requires the [Data Transport Layer](https://github.com/ethereum-optimism/data-transport-layer) -to be synced. The data transport layer is responsible for indexing transactions -from Layer One concurrently. The sequencer pulls in transactions from the data -transport layer and executes them. The URL of the data transport layer should be +Running a sequencer that ingests L1 to L2 transactions requires running the +[Data Transport Layer](https://github.com/ethereum-optimism/data-transport-layer). +The data transport layer is responsible for indexing transactions +from layer one Ethereum. It is possible to run a local development sequencer +without the data transport layer by turning off the sync service. To turn on +the sync service, use the config flag `--eth1.syncservice` or +`ETH1_SYNC_SERVICE_ENABLE`. The URL of the data transport layer should be used for the sequencer config option `--rollup.clienthttp`. -See the script `scripts/start.sh`. It sets many of the config options -and accepts CLI flags. For usage, run the command: +The `scripts` directory contains some scripts that make it easy to run a +local sequencer for development purposes. + +First, the genesis block must be initialized. This is because there are +predeployed contracts in the L2 state. The scripts to generate the genesis +block can be found in the `contracts` package. Be sure to run those first. ```bash -$ ./scripts/start.sh -h +$ ./scripts/init.sh ``` -This may be suitable for simple usecases, users that need more flexibility -with their configuration can run the command: +This script can be ran with the `DEVELOPMENT` env var set which will add +a prefunded account to the genesis state that can be used for development. + +The `start.sh` script is used to start `geth`. It hardcodes a bunch of +common config values for when running `geth`. ```bash -$ USING_OVM=true ./build/bin/geth \ - --rollup.clienthttp $ROLLUP_CLIENT_HTTP \ - --rollup.pollinterval 3s \ - --eth1.ctcdeploymentheight $CTC_DEPLOY_HEIGHT \ - --eth1.syncservice \ - --rpc \ - --dev \ - --rpcaddr "0.0.0.0" \ - --rpccorsdomain '*' \ - --wsaddr "0.0.0.0" \ - --wsport 8546 \ - --wsorigins '*' \ - --rpcapi 'eth,net,rollup,web3' \ - --gasprice '0' \ - --targetgaslimit '8000000' \ - --nousb \ - --gcmode=archive \ - --ipcdisable +$ ./scripts/start.sh ``` -To persist the database, pass the `--datadir` with a path to the directory for -the database to be persisted in. Without this flag, an in memory database will -be used. To tune the log level, use the `--verbosity` flag with an integer. +This script can be modified to work with `dlv` by prefixing the `$cmd` +with `dlv exec` and being sure to prefix the `geth` arguments with `--` +so they are interpreted as arguments to `geth` instead of `dlv`. ### Running a Verifier diff --git a/l2geth/accounts/abi/abi.go b/l2geth/accounts/abi/abi.go index 4bbb6e756..a5a44aa32 100644 --- a/l2geth/accounts/abi/abi.go +++ b/l2geth/accounts/abi/abi.go @@ -34,7 +34,6 @@ type ABI struct { Constructor Method Methods map[string]Method Events map[string]Event - MethodsById map[[4]byte]*Method } // JSON returns a parsed ABI interface and error if it failed. @@ -123,13 +122,6 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { return err } abi.Methods = make(map[string]Method) - // UsingOVM specific changes - // Create a cache of methods when running under the OVM because - // looking up methods based on the 4 byte selector is part of the hot - // code path. Without this cache, it was observed that 50% of the CPU - // time during syncing was spent hashing the function selectors - // during the call to `abi.MethodsById` - abi.MethodsById = make(map[[4]byte]*Method) abi.Events = make(map[string]Event) for _, field := range fields { switch field.Type { @@ -146,18 +138,13 @@ func (abi *ABI) UnmarshalJSON(data []byte) error { _, ok = abi.Methods[name] } isConst := field.Constant || field.StateMutability == "pure" || field.StateMutability == "view" - method := Method{ + abi.Methods[name] = Method{ Name: name, RawName: field.Name, Const: isConst, Inputs: field.Inputs, Outputs: field.Outputs, } - abi.Methods[name] = method - // UsingOVM specific changes - // Add method to the id cache - sigdata := method.ID() - abi.MethodsById[[4]byte{sigdata[0], sigdata[1], sigdata[2], sigdata[3]}] = &method case "event": name := field.Name _, ok := abi.Events[name] @@ -183,15 +170,12 @@ func (abi *ABI) MethodById(sigdata []byte) (*Method, error) { if len(sigdata) < 4 { return nil, fmt.Errorf("data too short (%d bytes) for abi method lookup", len(sigdata)) } - - // UsingOVM specific changes - // Use the method cache to prevent the need to iterate and hash - // each method in the ABI - method, exist := abi.MethodsById[[4]byte{sigdata[0], sigdata[1], sigdata[2], sigdata[3]}] - if !exist { - return nil, fmt.Errorf("no method with id: %#x", sigdata[:4]) + for _, method := range abi.Methods { + if bytes.Equal(method.ID(), sigdata[:4]) { + return &method, nil + } } - return method, nil + return nil, fmt.Errorf("no method with id: %#x", sigdata[:4]) } // EventByID looks an event up by its topic hash in the diff --git a/l2geth/accounts/abi/bind/bind_test.go b/l2geth/accounts/abi/bind/bind_test.go index cadefbdda..882fc8b13 100644 --- a/l2geth/accounts/abi/bind/bind_test.go +++ b/l2geth/accounts/abi/bind/bind_test.go @@ -494,8 +494,6 @@ var bindTests = []struct { "github.com/ethereum-optimism/optimism/l2geth/crypto" `, ` - t.Skip("OVM breaks this... SKIPPING: CallFrom test. CALLER must be transpiled for this test to work properly.") - // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth := bind.NewKeyedTransactor(key) @@ -543,8 +541,6 @@ var bindTests = []struct { "github.com/ethereum-optimism/optimism/l2geth/core" `, ` - t.Skip("OVM breaks this... SKIPPING: NonExistent contract test. This should be fixed & should pass if we returned the correct error messages.") - // Create a simulator and wrap a non-deployed contract sim := backends.NewSimulatedBackend(core.GenesisAlloc{}, uint64(10000000000)) @@ -643,8 +639,6 @@ var bindTests = []struct { "github.com/ethereum-optimism/optimism/l2geth/crypto" `, ` - t.Skip("OVM breaks this... SKIPPING: CallFrom test. CALLER must be transpiled for this test to work properly.") - // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth := bind.NewKeyedTransactor(key) @@ -1281,8 +1275,6 @@ var bindTests = []struct { "github.com/ethereum-optimism/optimism/l2geth/crypto" `, ` - t.Skip("OVM breaks this... SKIPPING: UseLibrary test.") - // Generate a new random account and a funded simulator key, _ := crypto.GenerateKey() auth := bind.NewKeyedTransactor(key) @@ -1500,8 +1492,6 @@ var bindTests = []struct { "github.com/ethereum-optimism/optimism/l2geth/core" `, ` - t.Skip("OVM breaks this... SKIPPING: MultiContracts test.") - key, _ := crypto.GenerateKey() addr := crypto.PubkeyToAddress(key.PublicKey) diff --git a/l2geth/build/update-license.go b/l2geth/build/update-license.go index 00c66bda0..aa4d6100d 100644 --- a/l2geth/build/update-license.go +++ b/l2geth/build/update-license.go @@ -77,7 +77,7 @@ var ( "signer/rules/deps", // skip special licenses - "crypto/secp256k1", // Relicensed to BSD-3 via https://github.com/ethereum-optimism/optimism/l2geth/pull/17225 + "crypto/secp256k1", // Relicensed to BSD-3 via https://github.com/ethereum/go-ethereum/pull/17225 } // paths with this prefix are licensed as GPL. all other files are LGPL. diff --git a/l2geth/cmd/faucet/faucet.go b/l2geth/cmd/faucet/faucet.go index a79f30626..72e1f8c89 100644 --- a/l2geth/cmd/faucet/faucet.go +++ b/l2geth/cmd/faucet/faucet.go @@ -467,7 +467,7 @@ func (f *faucet) apiHandler(w http.ResponseWriter, r *http.Request) { username, avatar, address, err = authNoAuth(msg.URL) default: //lint:ignore ST1005 This error is to be displayed in the browser - err = errors.New("Something funky happened, please open an issue at https://github.com/ethereum-optimism/optimism/l2geth/issues") + err = errors.New("Something funky happened, please open an issue at https://github.com/ethereum-optimism/optimism/issues") } if err != nil { if err = sendError(conn, err); err != nil { diff --git a/l2geth/cmd/geth/accountcmd_test.go b/l2geth/cmd/geth/accountcmd_test.go index aac012260..e36f26c09 100644 --- a/l2geth/cmd/geth/accountcmd_test.go +++ b/l2geth/cmd/geth/accountcmd_test.go @@ -183,7 +183,7 @@ Fatal: Failed to unlock account f466859ead1932d743d622cb74fc058882e8648a (could `) } -// https://github.com/ethereum-optimism/optimism/l2geth/issues/1785 +// https://github.com/ethereum/go-ethereum/l2geth/issues/1785 func TestUnlockFlagMultiIndex(t *testing.T) { datadir := tmpDatadirWithKeystore(t) geth := runGeth(t, diff --git a/l2geth/cmd/geth/chaincmd.go b/l2geth/cmd/geth/chaincmd.go index 637a1a933..6cfc64f2e 100644 --- a/l2geth/cmd/geth/chaincmd.go +++ b/l2geth/cmd/geth/chaincmd.go @@ -641,7 +641,7 @@ func hashish(x string) bool { func fetchGenesis(url string) ([]byte, error) { client := &http.Client{ - Timeout: 10 * time.Second, + Timeout: 60 * time.Second, } resp, err := client.Get(url) if err != nil { diff --git a/l2geth/contracts/checkpointoracle/oracle_test.go b/l2geth/contracts/checkpointoracle/oracle_test.go index 4e02b87d1..86ca24c4b 100644 --- a/l2geth/contracts/checkpointoracle/oracle_test.go +++ b/l2geth/contracts/checkpointoracle/oracle_test.go @@ -165,8 +165,6 @@ func (a Accounts) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a Accounts) Less(i, j int) bool { return bytes.Compare(a[i].addr.Bytes(), a[j].addr.Bytes()) < 0 } func TestCheckpointRegister(t *testing.T) { - t.Skip("OVM breaks this with invalid number of events, probably because the CheckpointOracle must be transpiled to function properly.") - // Initialize test accounts var accounts Accounts for i := 0; i < 3; i++ { diff --git a/l2geth/core/blockchain_test.go b/l2geth/core/blockchain_test.go index 209e3c415..ba6775d06 100644 --- a/l2geth/core/blockchain_test.go +++ b/l2geth/core/blockchain_test.go @@ -982,8 +982,6 @@ func TestLogReorgs(t *testing.T) { } func TestLogRebirth(t *testing.T) { - t.Skip("OVM Genesis breaks this test because it adds the OVM contracts to the state.") - var ( key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") addr1 = crypto.PubkeyToAddress(key1.PublicKey) @@ -1422,8 +1420,6 @@ func TestEIP155Transition(t *testing.T) { } func TestEIP161AccountRemoval(t *testing.T) { - t.Skip("OVM breaks with `expected account to exist`, probably based on some unknown transaction failure.") - // Configure and generate a sample block chain var ( db = rawdb.NewMemoryDatabase() @@ -1494,7 +1490,7 @@ func TestEIP161AccountRemoval(t *testing.T) { // tests that under weird reorg conditions the blockchain and its internal header- // chain return the same latest block/header. // -// https://github.com/ethereum-optimism/optimism/l2geth/pull/15941 +// https://github.com/ethereum/go-ethereum/pull/15941 func TestBlockchainHeaderchainReorgConsistency(t *testing.T) { // Generate a canonical chain to act as the main dataset engine := ethash.NewFaker() @@ -1756,7 +1752,7 @@ func TestIncompleteAncientReceiptChainInsertion(t *testing.T) { // // Details at: // - https://github.com/ethereum-optimism/optimism/l2geth/issues/18977 -// - https://github.com/ethereum-optimism/optimism/l2geth/pull/18988 +// - https://github.com/ethereum/go-ethereum/pull/18988 func TestLowDiffLongChain(t *testing.T) { // Generate a canonical chain to act as the main dataset engine := ethash.NewFaker() diff --git a/l2geth/core/genesis_test.go b/l2geth/core/genesis_test.go index b563db1b8..07a70be44 100644 --- a/l2geth/core/genesis_test.go +++ b/l2geth/core/genesis_test.go @@ -31,8 +31,6 @@ import ( ) func TestDefaultGenesisBlock(t *testing.T) { - t.Skip("OVM breaks this test because it adds the OVM contracts to the Genesis state.") - block := DefaultGenesisBlock().ToBlock(nil) if block.Hash() != params.MainnetGenesisHash { t.Errorf("wrong mainnet genesis hash, got %v, want %v", block.Hash(), params.MainnetGenesisHash) diff --git a/l2geth/core/state/statedb.go b/l2geth/core/state/statedb.go index 4d2c768aa..91dd6f4b4 100644 --- a/l2geth/core/state/statedb.go +++ b/l2geth/core/state/statedb.go @@ -706,7 +706,7 @@ func (s *StateDB) Copy() *StateDB { } // Copy the dirty states, logs, and preimages for addr := range s.journal.dirties { - // As documented [here](https://github.com/ethereum-optimism/optimism/l2geth/pull/16485#issuecomment-380438527), + // As documented [here](https://github.com/ethereum/go-ethereum/pull/16485#issuecomment-380438527), // and in the Finalise-method, there is a case where an object is in the journal but not // in the stateObjects: OOG after touch on ripeMD prior to Byzantium. Thus, we need to check for // nil diff --git a/l2geth/core/state/statedb_test.go b/l2geth/core/state/statedb_test.go index 638b304b5..5770ad8d0 100644 --- a/l2geth/core/state/statedb_test.go +++ b/l2geth/core/state/statedb_test.go @@ -146,7 +146,7 @@ func TestIntermediateLeaks(t *testing.T) { // TestCopy tests that copying a statedb object indeed makes the original and // the copy independent of each other. This test is a regression test against -// https://github.com/ethereum-optimism/optimism/l2geth/pull/15549. +// https://github.com/ethereum/go-ethereum/pull/15549. func TestCopy(t *testing.T) { // Create a random state test to copy and modify "independently" orig, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase())) @@ -475,7 +475,7 @@ func TestTouchDelete(t *testing.T) { } // TestCopyOfCopy tests that modified objects are carried over to the copy, and the copy of the copy. -// See https://github.com/ethereum-optimism/optimism/l2geth/pull/15225#issuecomment-380191512 +// See https://github.com/ethereum/go-ethereum/pull/15225#issuecomment-380191512 func TestCopyOfCopy(t *testing.T) { state, _ := New(common.Hash{}, NewDatabase(rawdb.NewMemoryDatabase())) addr := common.HexToAddress("aaaa") diff --git a/l2geth/core/state_processor.go b/l2geth/core/state_processor.go index 11df8d4f7..82de3bf3d 100644 --- a/l2geth/core/state_processor.go +++ b/l2geth/core/state_processor.go @@ -109,9 +109,9 @@ func ApplyTransaction(config *params.ChainConfig, bc ChainContext, author *commo // Apply the transaction to the current state (included in the env) _, gas, failed, err := ApplyMessage(vmenv, msg, gp) - if err == vm.ErrTuringWouldBlock { - return nil, ErrTuringRetry // this is in "core", not "core/vm" - } + // if err == vm.ErrTuringWouldBlock { + // return nil, ErrTuringRetry // this is in "core", not "core/vm" + // } // TURING Update the tx metadata, if a Turing call took place... if len(vmenv.Context.Turing) > 1 { diff --git a/l2geth/core/state_transition.go b/l2geth/core/state_transition.go index 99ab72daa..1b9860701 100644 --- a/l2geth/core/state_transition.go +++ b/l2geth/core/state_transition.go @@ -273,12 +273,12 @@ func (st *StateTransition) TransitionDb() (ret []byte, usedGas uint64, failed bo ret, st.gas, vmerr = evm.Call(sender, st.to(), st.data, st.gas, st.value) } - if vmerr == vm.ErrTuringWouldBlock { - // Roll back the nonce (FIXME - also ensure that all gas accounting etc. has been rolled back) - log.Debug("TURING evm.Call returned ErrTuringWouldBlock") - st.state.SetNonce(msg.From(), st.state.GetNonce(msg.From())-1) - return nil, 0, true, vmerr - } + // if vmerr == vm.ErrTuringWouldBlock { + // // Roll back the nonce (FIXME - also ensure that all gas accounting etc. has been rolled back) + // log.Debug("TURING evm.Call returned ErrTuringWouldBlock") + // st.state.SetNonce(msg.From(), st.state.GetNonce(msg.From())-1) + // return nil, 0, true, vmerr + // } if vmerr != nil { log.Debug("VM returned with error", "err", vmerr, "ret", hexutil.Encode(ret)) diff --git a/l2geth/core/types/transaction_meta.go b/l2geth/core/types/transaction_meta.go index 64982cd0f..1aaa97fda 100644 --- a/l2geth/core/types/transaction_meta.go +++ b/l2geth/core/types/transaction_meta.go @@ -153,7 +153,7 @@ func TxMetaDecode(input []byte) (*TransactionMeta, error) { turing, err := common.ReadVarBytes(b, 0, 2048, "Turing") // The "Turing" fieldName string is not important and is only used in error messages if err != nil { if errors.Is(err, io.EOF) { - log.Debug("Legacy format decode - no Turing field - setting to nil") + log.Debug("Legacy block decode - no Turing field - setting to nil") meta.L1Turing = nil } else { return nil, err diff --git a/l2geth/core/vm/evm.go b/l2geth/core/vm/evm.go index bd22ff2ba..e2f5b5ed1 100644 --- a/l2geth/core/vm/evm.go +++ b/l2geth/core/vm/evm.go @@ -21,7 +21,6 @@ import ( "crypto/rand" "fmt" "math/big" - "sync" "sync/atomic" "time" @@ -274,20 +273,20 @@ func bobaTuringRandom(input []byte, caller common.Address) hexutil.Bytes { return ret } -type turingCacheEntry struct { - expires time.Time - value []byte -} +// type turingCacheEntry struct { +// expires time.Time +// value []byte +// } -var turingCache struct { - lock sync.RWMutex - entries map[common.Hash]*turingCacheEntry -} +// var turingCache struct { +// lock sync.RWMutex +// entries map[common.Hash]*turingCacheEntry +// } // In response to an off-chain Turing request, obtain the requested data and // rewrite the parameters so that the contract can be called without reverting. // caller is the address of the TuringHelper contract -func bobaTuringCall(input []byte, caller common.Address, mayBlock bool) (hexutil.Bytes, int) { +func bobaTuringCall(input []byte, caller common.Address) (hexutil.Bytes, int) { log.Debug("TURING bobaTuringCall:Caller", "caller", caller.String()) @@ -334,52 +333,52 @@ func bobaTuringCall(input []byte, caller common.Address, mayBlock bool) (hexutil return retError, 11 } - // Now check for a cached result - ret := []byte{} - - hasher := sha3.NewLegacyKeccak256() - hasher.Write(common.LeftPadBytes(caller.Bytes(), 32)) // FIXME - add account nonce, contract ID, etc? - hasher.Write(input) - key := common.BytesToHash(hasher.Sum(nil)) - - log.Debug("TURING Cache key", "key", key, "mayBlock", mayBlock) - turingCache.lock.Lock() - - if turingCache.entries == nil { - log.Debug("TURING Cache init") // FIXME - move the init code elsewhere - turingCache.entries = make(map[common.Hash]*turingCacheEntry) - } - - if ent, hit := turingCache.entries[key]; hit { - if time.Now().Before(ent.expires) { - log.Debug("TURING Cache hit", "key", key, "expires", ent.expires) - ret = ent.value - } else { - log.Debug("TURING Cache expired", "key", key, "expires", ent.expires) - delete(turingCache.entries, key) - } - } - turingCache.lock.Unlock() - - if len(ret) != 0 { - return ret, 0 - } - - if len(ret) == 0 { - log.Debug("TURING Missing cache entry", "mayBlock", mayBlock) - if mayBlock { - // Since no Boba credit is consumed in an estimateGas call, we put a - // "failed" entry into the cache here so that a failed offchain call - // can't be called repeatedly as a DoS attack. - turingCache.lock.Lock() - newEnt := &turingCacheEntry{value: retError, expires: time.Now().Add(2 * time.Second)} - turingCache.entries[key] = newEnt - turingCache.lock.Unlock() - } else { - retError[35] = 20 // Missing cache entry - return retError, 20 - } - } + // // Now check for a cached result + // ret := []byte{} + + // hasher := sha3.NewLegacyKeccak256() + // hasher.Write(common.LeftPadBytes(caller.Bytes(), 32)) // FIXME - add account nonce, contract ID, etc? + // hasher.Write(input) + // key := common.BytesToHash(hasher.Sum(nil)) + + // log.Debug("TURING Cache key", "key", key, "mayBlock", mayBlock) + // turingCache.lock.Lock() + + // if turingCache.entries == nil { + // log.Debug("TURING Cache init") // FIXME - move the init code elsewhere + // turingCache.entries = make(map[common.Hash]*turingCacheEntry) + // } + + // if ent, hit := turingCache.entries[key]; hit { + // if time.Now().Before(ent.expires) { + // log.Debug("TURING Cache hit", "key", key, "expires", ent.expires) + // ret = ent.value + // } else { + // log.Debug("TURING Cache expired", "key", key, "expires", ent.expires) + // delete(turingCache.entries, key) + // } + // } + // turingCache.lock.Unlock() + + // if len(ret) != 0 { + // return ret, 0 + // } + + // if len(ret) == 0 { + // log.Debug("TURING Missing cache entry", "mayBlock", mayBlock) + // if mayBlock { + // // Since no Boba credit is consumed in an estimateGas call, we put a + // // "failed" entry into the cache here so that a failed offchain call + // // can't be called repeatedly as a DoS attack. + // turingCache.lock.Lock() + // newEnt := &turingCacheEntry{value: retError, expires: time.Now().Add(2 * time.Second)} + // turingCache.entries[key] = newEnt + // turingCache.lock.Unlock() + // } else { + // retError[35] = 20 // Missing cache entry + // return retError, 20 + // } + // } // A micro-ABI decoder... this works because we know that all these numbers can never exceed 256 // Since the rType is 32 bytes and the three headers are 32 bytes each, the max possible value @@ -480,7 +479,7 @@ func bobaTuringCall(input []byte, caller common.Address, mayBlock bool) (hexutil "ResponseString", responseString) // build the modified calldata - ret = make([]byte, startIDXpayload+4) + ret := make([]byte, startIDXpayload+4) copy(ret, inputHexUtil[0:startIDXpayload+4]) // take the original input ret[35] = 2 // change byte 3 + 32 = 35 (rType) to indicate a valid response ret = append(ret, responseString...) // and tack on the payload @@ -488,11 +487,11 @@ func bobaTuringCall(input []byte, caller common.Address, mayBlock bool) (hexutil log.Debug("TURING bobaTuringCall:Modified parameters", "newValue", hexutil.Bytes(ret)) - turingCache.lock.Lock() - newEnt := &turingCacheEntry{value: ret, expires: time.Now().Add(2 * time.Second)} - turingCache.entries[key] = newEnt - log.Debug("TURING Cache insert", "key", key, "expires", newEnt.expires) - turingCache.lock.Unlock() + // turingCache.lock.Lock() + // newEnt := &turingCacheEntry{value: ret, expires: time.Now().Add(2 * time.Second)} + // turingCache.entries[key] = newEnt + // log.Debug("TURING Cache insert", "key", key, "expires", newEnt.expires) + // turingCache.lock.Unlock() return ret, 0 } @@ -573,7 +572,7 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas // TuringCall takes the original calldata, figures out what needs // to be done, and then synthesizes a 'updated_input' calldata var updated_input hexutil.Bytes - var turingErr int + // var turingErr int // Sanity and depth checks if isTuring2 || isGetRand2 { @@ -598,17 +597,17 @@ func (evm *EVM) Call(caller ContractRef, addr common.Address, input []byte, gas // A real modified callData is always much much > 1 byte // This case _should_ never happen in Verifier/Replica mode, since the sequencer will already have run the Turing call if isTuring2 { - // If called from the real sequencer thread, Turing must find a cache entry to avoid blocking other users. - // As a hack, look for a zero GasPrice to infer that we are in an eth_estimateGas call stack. - mayBlock := (evm.Context.GasPrice.Cmp(bigZero) == 0) - log.Debug("TURING preCall", "mayBlock", mayBlock, "gasPrice", evm.Context.GasPrice) + // // If called from the real sequencer thread, Turing must find a cache entry to avoid blocking other users. + // // As a hack, look for a zero GasPrice to infer that we are in an eth_estimateGas call stack. + // mayBlock := (evm.Context.GasPrice.Cmp(bigZero) == 0) + // log.Debug("TURING preCall", "mayBlock", mayBlock, "gasPrice", evm.Context.GasPrice) - updated_input, turingErr = bobaTuringCall(input, caller.Address(), mayBlock) + updated_input, _ = bobaTuringCall(input, caller.Address()) - if turingErr == 20 { - log.Debug("TURING returning ErrTuringWouldBlock") - return nil, gas, ErrTuringWouldBlock - } + // if turingErr == 20 { + // log.Debug("TURING returning ErrTuringWouldBlock") + // return nil, gas, ErrTuringWouldBlock + // } } else if isGetRand2 { updated_input = bobaTuringRandom(input, caller.Address()) } // there is no other option diff --git a/l2geth/core/vm/instructions.go b/l2geth/core/vm/instructions.go index 48675de7d..608e0a284 100644 --- a/l2geth/core/vm/instructions.go +++ b/l2geth/core/vm/instructions.go @@ -763,9 +763,9 @@ func opCall(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory } ret, returnGas, err := interpreter.evm.Call(contract, toAddr, args, gas, value) - if err == ErrTuringWouldBlock { - return nil, err - } + // if err == ErrTuringWouldBlock { + // return nil, err + // } if err != nil { stack.push(interpreter.intPool.getZero()) @@ -889,7 +889,7 @@ func opSuicide(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memo interpreter.evm.StateDB.AddBalance(common.BigToAddress(stack.pop()), balance) interpreter.evm.StateDB.Suicide(contract.Address()) - if rcfg.UsingOVM && interpreter.evm.BlockNumber.Uint64() > rcfg.SuicideForkNumber { + if rcfg.UsingOVM && interpreter.evm.chainConfig.IsSDUpdate(interpreter.evm.BlockNumber) { interpreter.evm.StateDB.SubBalance(contract.Address(), balance) } return nil, nil diff --git a/l2geth/eth/handler_test.go b/l2geth/eth/handler_test.go index d782063eb..47d329ddd 100644 --- a/l2geth/eth/handler_test.go +++ b/l2geth/eth/handler_test.go @@ -274,8 +274,6 @@ func TestGetNodeData63(t *testing.T) { testGetNodeData(t, 63) } func TestGetNodeData64(t *testing.T) { testGetNodeData(t, 64) } func testGetNodeData(t *testing.T, protocol int) { - t.Skip("OVM breaks this test with error: `account does not exist`") - // Define three accounts to simulate transactions with acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") acc2Key, _ := crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") @@ -373,8 +371,6 @@ func TestGetReceipt63(t *testing.T) { testGetReceipt(t, 63) } func TestGetReceipt64(t *testing.T) { testGetReceipt(t, 64) } func testGetReceipt(t *testing.T, protocol int) { - t.Skip("OVM breaks this test with error: `account does not exist`") - // Define three accounts to simulate transactions with acc1Key, _ := crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") acc2Key, _ := crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") diff --git a/l2geth/eth/tracers/tracers_test.go b/l2geth/eth/tracers/tracers_test.go index 56e19ec07..3ba038241 100644 --- a/l2geth/eth/tracers/tracers_test.go +++ b/l2geth/eth/tracers/tracers_test.go @@ -121,8 +121,6 @@ type callTracerTest struct { } func TestPrestateTracerCreate2(t *testing.T) { - t.Skip("OVM breaks this with `cannot read property` error, probably related to state manager.") - unsignedTx := types.NewTransaction(1, common.HexToAddress("0x00000000000000000000000000000000deadbeef"), new(big.Int), 5000000, big.NewInt(1), []byte{}) privateKeyECDSA, err := ecdsa.GenerateKey(crypto.S256(), rand.Reader) @@ -203,8 +201,6 @@ func TestPrestateTracerCreate2(t *testing.T) { // Iterates over all the input-output datasets in the tracer test harness and // runs the JavaScript tracers against them. func TestCallTracer(t *testing.T) { - t.Skip("OVM breaks this with `execution reverted` error, probably some execution mismatch.") - files, err := ioutil.ReadDir("testdata") if err != nil { t.Fatalf("failed to retrieve tracer test suite: %v", err) diff --git a/l2geth/internal/ethapi/api.go b/l2geth/internal/ethapi/api.go index f496a25a5..e3b45cb2e 100644 --- a/l2geth/internal/ethapi/api.go +++ b/l2geth/internal/ethapi/api.go @@ -1740,29 +1740,32 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod ret, err := SubmitTransaction(ctx, s.b, tx) - if err != nil && err.Error() == "turing retry needed" { - blockNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) - tdBytes := hexutil.Bytes(tx.Data()) - - callArgs := CallArgs{ - From: nil, // FIXME? Is this required? - To: tx.To(), - GasPrice: nil, - Value: (*hexutil.Big)(tx.Value()), - Data: &tdBytes, - } - - _, _, failed, err2 := DoCall(ctx, s.b, callArgs, blockNrOrHash, nil, &vm.Config{}, 0, new(big.Int).SetUint64(8000000)) - if failed { - log.Error("TURING api.go gasEstimate failed", "err", err2) - return common.Hash{}, err - } - - log.Debug("TURING ethapi/api.go calling again after gasEstimate") - ret, err = SubmitTransaction(ctx, s.b, tx) - - log.Debug("TURING ethapi/api.go second call is done", "ret", ret, "err", err) - } + // if err != nil && err.Error() == "turing retry needed" { + // blockNrOrHash := rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber) + // tdBytes := hexutil.Bytes(tx.Data()) + + // signer := types.MakeSigner(s.b.ChainConfig(), s.b.CurrentBlock().Number()) + // from, err := types.Sender(signer, tx) + + // callArgs := CallArgs{ + // From: &from, + // To: tx.To(), + // GasPrice: (*hexutil.Big)(tx.GasPrice()), + // Value: (*hexutil.Big)(tx.Value()), + // Data: &tdBytes, + // } + + // _, _, failed, err2 := DoCall(ctx, s.b, callArgs, blockNrOrHash, nil, &vm.Config{}, 0, new(big.Int).SetUint64(8000000)) + // if failed { + // log.Error("TURING api.go gasEstimate failed", "err", err2) + // return common.Hash{}, err + // } + + // log.Debug("TURING ethapi/api.go calling again after gasEstimate") + // ret, err = SubmitTransaction(ctx, s.b, tx) + + // log.Debug("TURING ethapi/api.go second call is done", "ret", ret, "err", err) + // } return ret, err } diff --git a/l2geth/les/handler_test.go b/l2geth/les/handler_test.go index 7e1980a23..0a833aad0 100644 --- a/l2geth/les/handler_test.go +++ b/l2geth/les/handler_test.go @@ -51,8 +51,6 @@ func TestGetBlockHeadersLes2(t *testing.T) { testGetBlockHeaders(t, 2) } func TestGetBlockHeadersLes3(t *testing.T) { testGetBlockHeaders(t, 3) } func testGetBlockHeaders(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - server, tearDown := newServerEnv(t, downloader.MaxHashFetch+15, protocol, nil, false, true, 0) defer tearDown() @@ -183,8 +181,6 @@ func TestGetBlockBodiesLes2(t *testing.T) { testGetBlockBodies(t, 2) } func TestGetBlockBodiesLes3(t *testing.T) { testGetBlockBodies(t, 3) } func testGetBlockBodies(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - server, tearDown := newServerEnv(t, downloader.MaxBlockFetch+15, protocol, nil, false, true, 0) defer tearDown() @@ -263,8 +259,6 @@ func TestGetCodeLes2(t *testing.T) { testGetCode(t, 2) } func TestGetCodeLes3(t *testing.T) { testGetCode(t, 3) } func testGetCode(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - // Assemble the test environment server, tearDown := newServerEnv(t, 4, protocol, nil, false, true, 0) defer tearDown() @@ -296,8 +290,6 @@ func TestGetStaleCodeLes2(t *testing.T) { testGetStaleCode(t, 2) } func TestGetStaleCodeLes3(t *testing.T) { testGetStaleCode(t, 3) } func testGetStaleCode(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - server, tearDown := newServerEnv(t, core.TriesInMemory+4, protocol, nil, false, true, 0) defer tearDown() bc := server.handler.blockchain @@ -323,8 +315,6 @@ func TestGetReceiptLes2(t *testing.T) { testGetReceipt(t, 2) } func TestGetReceiptLes3(t *testing.T) { testGetReceipt(t, 3) } func testGetReceipt(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - // Assemble the test environment server, tearDown := newServerEnv(t, 4, protocol, nil, false, true, 0) defer tearDown() @@ -353,8 +343,6 @@ func TestGetProofsLes2(t *testing.T) { testGetProofs(t, 2) } func TestGetProofsLes3(t *testing.T) { testGetProofs(t, 3) } func testGetProofs(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - // Assemble the test environment server, tearDown := newServerEnv(t, 4, protocol, nil, false, true, 0) defer tearDown() @@ -391,8 +379,6 @@ func TestGetStaleProofLes2(t *testing.T) { testGetStaleProof(t, 2) } func TestGetStaleProofLes3(t *testing.T) { testGetStaleProof(t, 3) } func testGetStaleProof(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - server, tearDown := newServerEnv(t, core.TriesInMemory+4, protocol, nil, false, true, 0) defer tearDown() bc := server.handler.blockchain @@ -430,8 +416,6 @@ func TestGetCHTProofsLes2(t *testing.T) { testGetCHTProofs(t, 2) } func TestGetCHTProofsLes3(t *testing.T) { testGetCHTProofs(t, 3) } func testGetCHTProofs(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - config := light.TestServerIndexerConfig waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) { @@ -481,8 +465,6 @@ func TestGetBloombitsProofsLes3(t *testing.T) { testGetBloombitsProofs(t, 3) } // Tests that bloombits proofs can be correctly retrieved. func testGetBloombitsProofs(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - config := light.TestServerIndexerConfig waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) { @@ -532,8 +514,6 @@ func TestTransactionStatusLes2(t *testing.T) { testTransactionStatus(t, 2) } func TestTransactionStatusLes3(t *testing.T) { testTransactionStatus(t, 3) } func testTransactionStatus(t *testing.T, protocol int) { - t.Skip("SKIPPING (OVM)") - server, tearDown := newServerEnv(t, 0, protocol, nil, false, true, 0) defer tearDown() server.handler.addTxsSync = true diff --git a/l2geth/les/odr_test.go b/l2geth/les/odr_test.go index 6621b518e..c8bba8d37 100644 --- a/l2geth/les/odr_test.go +++ b/l2geth/les/odr_test.go @@ -182,8 +182,6 @@ func odrTxStatus(ctx context.Context, db ethdb.Database, config *params.ChainCon // testOdr tests odr requests whose validation guaranteed by block headers. func testOdr(t *testing.T, protocol int, expFail uint64, checkCached bool, fn odrTestFn) { - t.Skip("OVM breaks this with `insufficient balance for transfer`, probably because transfers don't work.") - // Assemble the test environment server, client, tearDown := newClientServerEnv(t, 4, protocol, nil, nil, 0, false, true) defer tearDown() diff --git a/l2geth/les/request_test.go b/l2geth/les/request_test.go index 4b2ad995f..cfb71ff63 100644 --- a/l2geth/les/request_test.go +++ b/l2geth/les/request_test.go @@ -78,8 +78,6 @@ func tfCodeAccess(db ethdb.Database, bhash common.Hash, num uint64) light.OdrReq } func testAccess(t *testing.T, protocol int, fn accessTestFn) { - t.Skip("OVM breaks this with `insufficient balance for transfer`, probably because transfers don't work.") - // Assemble the test environment server, client, tearDown := newClientServerEnv(t, 4, protocol, nil, nil, 0, false, true) defer tearDown() diff --git a/l2geth/les/sync_test.go b/l2geth/les/sync_test.go index 99682f7ec..94ee4bf71 100644 --- a/l2geth/les/sync_test.go +++ b/l2geth/les/sync_test.go @@ -41,8 +41,6 @@ func TestLegacyCheckpointSyncingLes3(t *testing.T) { testCheckpointSyncing(t, 3, func TestCheckpointSyncingLes3(t *testing.T) { testCheckpointSyncing(t, 3, 2) } func testCheckpointSyncing(t *testing.T, protocol int, syncMode int) { - t.Skip("OVM breaks this with `insufficient balance for transfer`, probably because transfers don't work.") - config := light.TestServerIndexerConfig waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) { @@ -135,8 +133,6 @@ func TestMissOracleBackend(t *testing.T) { testMissOracleBackend(t, func TestMissOracleBackendNoCheckpoint(t *testing.T) { testMissOracleBackend(t, false) } func testMissOracleBackend(t *testing.T, hasCheckpoint bool) { - t.Skip("OVM breaks this with `insufficient balance for transfer`, probably because transfers don't work.") - config := light.TestServerIndexerConfig waitIndexers := func(cIndexer, bIndexer, btIndexer *core.ChainIndexer) { diff --git a/l2geth/light/odr_test.go b/l2geth/light/odr_test.go index 3fb3901b2..f716a1f6b 100644 --- a/l2geth/light/odr_test.go +++ b/l2geth/light/odr_test.go @@ -249,8 +249,6 @@ func testChainGen(i int, block *core.BlockGen) { } func testChainOdr(t *testing.T, protocol int, fn odrTestFn) { - t.Skip("OVM breaks this with `insufficient balance for transfer`, probably because transfers don't work.") - var ( sdb = rawdb.NewMemoryDatabase() ldb = rawdb.NewMemoryDatabase() diff --git a/l2geth/miner/worker.go b/l2geth/miner/worker.go index e6253c5f7..4333f7233 100644 --- a/l2geth/miner/worker.go +++ b/l2geth/miner/worker.go @@ -515,11 +515,6 @@ func (w *worker) mainLoop() { delete(w.pendingTasks, h) } w.pendingMu.Unlock() - } else if err.Error() == "turing retry needed" { - // no error message here - if ev.ErrCh != nil { - ev.ErrCh <- err - } } else { log.Error("Problem committing transaction", "msg", err) if ev.ErrCh != nil { @@ -875,11 +870,11 @@ func (w *worker) commitTransactions(txs *types.TransactionsByPriceAndNonce, coin w.current.tcount++ txs.Shift() - case core.ErrTuringRetry: - // Turing transaction needs to be retried after populating the cache. This special - // error code rolls back the first attempt as if it had never happened. - txs.Shift() - return 2 + // case core.ErrTuringRetry: + // // Turing transaction needs to be retried after populating the cache. This special + // // error code rolls back the first attempt as if it had never happened. + // txs.Shift() + // return 2 default: // Strange error, discard the transaction and get the next in line (note, the @@ -932,18 +927,7 @@ func (w *worker) commitNewTx(tx *types.Transaction) error { // Preserve liveliness as best as possible. Must panic on L1 to L2 // transactions as the timestamp cannot be malleated if parent.Time() > tx.L1Timestamp() { - log.Error("Monotonicity violation", "index", num) - if tx.QueueOrigin() == types.QueueOriginSequencer { - tx.SetL1Timestamp(parent.Time()) - prev := parent.Transactions() - if len(prev) == 1 { - tx.SetL1BlockNumber(prev[0].L1BlockNumber().Uint64()) - } else { - log.Error("Cannot recover L1 Blocknumber") - } - } else { - log.Error("Cannot recover from monotonicity violation") - } + log.Error("Monotonicity violation", "index", num, "parent", parent.Time(), "tx", tx.L1Timestamp()) } // Fill in the index field in the tx meta if it is `nil`. @@ -979,9 +963,6 @@ func (w *worker) commitNewTx(tx *types.Transaction) error { wCt := w.commitTransactions(txs, w.coinbase, nil) if wCt == 1 { return errors.New("Cannot commit transaction in miner") - } else if wCt == 2 { - log.Debug("TURING w.commitTransactions returned Turing retry code") - return core.ErrTuringRetry } return w.commit(nil, w.fullTaskHook, tstart) } diff --git a/l2geth/mobile/types.go b/l2geth/mobile/types.go index a444a69c5..1e823934d 100644 --- a/l2geth/mobile/types.go +++ b/l2geth/mobile/types.go @@ -197,6 +197,12 @@ type Transaction struct { tx *types.Transaction } +// NewContractCreation creates a new transaction for deploying a new contract with +// the given properties. +func NewContractCreation(nonce int64, amount *BigInt, gasLimit int64, gasPrice *BigInt, data []byte) *Transaction { + return &Transaction{types.NewContractCreation(uint64(nonce), amount.bigint, uint64(gasLimit), gasPrice.bigint, common.CopyBytes(data))} +} + // NewTransaction creates a new transaction with the given properties. Contracts // can be created by transacting with a nil recipient. func NewTransaction(nonce int64, to *Address, amount *BigInt, gasLimit int64, gasPrice *BigInt, data []byte) *Transaction { diff --git a/l2geth/node/config_test.go b/l2geth/node/config_test.go index 0c0c43c36..43eee5a36 100644 --- a/l2geth/node/config_test.go +++ b/l2geth/node/config_test.go @@ -77,7 +77,6 @@ func TestDatadirCreation(t *testing.T) { // Tests that IPC paths are correctly resolved to valid endpoints of different // platforms. func TestIPCPathResolution(t *testing.T) { - t.Skip("Skipping for now") var tests = []struct { DataDir string IPCPath string diff --git a/l2geth/package.json b/l2geth/package.json index 41bc33057..a85ada101 100644 --- a/l2geth/package.json +++ b/l2geth/package.json @@ -1,6 +1,6 @@ { "name": "@eth-optimism/l2geth", - "version": "0.5.9", + "version": "0.5.11", "private": true, "devDependencies": {} } diff --git a/l2geth/params/config.go b/l2geth/params/config.go index 8a91cfe5b..4682fa87a 100644 --- a/l2geth/params/config.go +++ b/l2geth/params/config.go @@ -226,6 +226,18 @@ var ( TestChainConfig = &ChainConfig{big.NewInt(1), big.NewInt(0), nil, false, big.NewInt(0), common.Hash{}, big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), big.NewInt(0), nil, nil, new(EthashConfig), nil} TestRules = TestChainConfig.Rules(new(big.Int)) + + // OpMainnetChainID is the ID of Boba's mainnet chain. + OpMainnetChainID = big.NewInt(288) + + // OpRinkebyChainID is the ID of Boba's Rinkeby testnet chain. + OpRinkebyChainID = big.NewInt(28) + + // OpMainnetSDUpdateForkNum is the height at which the SD update fork activates on Mainnet. + OpMainnetSDUpdateForkNum = big.NewInt(310215) + + // OpRinkebySDUpdateForkNum is the height at which the SD update fork activates on Rinkeby. + OpRinkebySDUpdateForkNum = big.NewInt(147805) ) // TrustedCheckpoint represents a set of post-processed trie roots (CHT and @@ -414,6 +426,17 @@ func (c *ChainConfig) IsEWASM(num *big.Int) bool { return isForked(c.EWASMBlock, num) } +// IsSDUpdate returns whether num represents a block number after the SD update fork +func (c *ChainConfig) IsSDUpdate(num *big.Int) bool { + if c.ChainID.Cmp(OpMainnetChainID) == 0 { + return isForked(OpMainnetSDUpdateForkNum, num) + } + if c.ChainID.Cmp(OpRinkebyChainID) == 0 { + return isForked(OpRinkebySDUpdateForkNum, num) + } + return true +} + // CheckCompatible checks whether scheduled fork transitions have been imported // with a mismatching chain configuration. func (c *ChainConfig) CheckCompatible(newcfg *ChainConfig, height uint64) *ConfigCompatError { diff --git a/l2geth/rollup/rcfg/config.go b/l2geth/rollup/rcfg/config.go index fc6df01ca..03b87106f 100644 --- a/l2geth/rollup/rcfg/config.go +++ b/l2geth/rollup/rcfg/config.go @@ -3,15 +3,13 @@ package rcfg import ( "math/big" "os" - "strconv" "github.com/ethereum-optimism/optimism/l2geth/common" ) // UsingOVM is used to enable or disable functionality necessary for the OVM. var ( - UsingOVM bool - SuicideForkNumber uint64 + UsingOVM bool ) var OvmTuringCreditAddress common.Address @@ -44,15 +42,5 @@ var ( func init() { UsingOVM = os.Getenv("USING_OVM") == "true" - suicideForkNumber := os.Getenv("EMERGENCY_FORK_NUMBER") - if suicideForkNumber == "" { - panic("SECURITY ALERT: MISSING EMERGENCY_FORK_NUMBER") - } else { - parsed, err := strconv.ParseUint(suicideForkNumber, 0, 64) - if err != nil { - panic(err) - } - SuicideForkNumber = parsed - } OvmTuringCreditAddress = common.HexToAddress(os.Getenv("TURING_CREDIT_ADDRESS")) } diff --git a/l2geth/rollup/sync_service.go b/l2geth/rollup/sync_service.go index d5ae922b7..5af978dde 100644 --- a/l2geth/rollup/sync_service.go +++ b/l2geth/rollup/sync_service.go @@ -825,13 +825,14 @@ func (s *SyncService) applyTransactionToTip(tx *types.Transaction) error { if now.Sub(current) > s.timestampRefreshThreshold { current = now } + log.Info("Updating latest timestamp", "timestamp", current, "unix", current.Unix()) tx.SetL1Timestamp(uint64(current.Unix())) } else if tx.L1Timestamp() == 0 && s.verifier { // This should never happen log.Error("No tx timestamp found when running as verifier", "hash", tx.Hash().Hex()) - } else if tx.L1Timestamp() < s.GetLatestL1Timestamp() { + } else if tx.L1Timestamp() < ts { // This should never happen, but sometimes does - log.Error("Timestamp monotonicity violation", "hash", tx.Hash().Hex()) + log.Error("Timestamp monotonicity violation", "hash", tx.Hash().Hex(), "latest", ts, "tx", tx.L1Timestamp()) } l1BlockNumber := tx.L1BlockNumber() @@ -883,11 +884,11 @@ func (s *SyncService) applyTransactionToTip(tx *types.Transaction) error { select { case err := <-errCh: - if err.Error() == "turing retry needed" { - log.Debug("TURING sync_service intercepted ErrTuringRetry") - tx.GetMeta().Index = nil - return err - } + // if err.Error() == "turing retry needed" { + // log.Debug("TURING sync_service intercepted ErrTuringRetry") + // tx.GetMeta().Index = nil + // return err + // } log.Error("Got error waiting for transaction to be added to chain", "msg", err) s.SetLatestL1Timestamp(ts) s.SetLatestL1BlockNumber(bn) diff --git a/l2geth/tests/block_test.go b/l2geth/tests/block_test.go index 451879263..3a55e4c34 100644 --- a/l2geth/tests/block_test.go +++ b/l2geth/tests/block_test.go @@ -17,7 +17,6 @@ package tests import ( - "fmt" "testing" ) @@ -29,8 +28,6 @@ func TestBlockchain(t *testing.T) { bt.skipLoad(`^GeneralStateTests/`) // Skip random failures due to selfish mining test bt.skipLoad(`.*bcForgedTest/bcForkUncle\.json`) - // Skip these tests because the OVM gas limit will be different - bt.skipLoad(`InvalidBlocks/bcInvalidHeaderTest/wrongGasLimit.json`) // Slow tests bt.slow(`.*bcExploitTest/DelegateCallSpam.json`) @@ -43,19 +40,12 @@ func TestBlockchain(t *testing.T) { // Very slow test bt.skipLoad(`.*/stTimeConsuming/.*`) - // OVM breaks these tests - bt.skipLoad(`^InvalidBlocks`) - bt.skipLoad(`^ValidBlocks`) - bt.skipLoad(`^TransitionTests`) - bt.skipLoad(`^randomStatetest391.json`) - // test takes a lot for time and goes easily OOM because of sha3 calculation on a huge range, // using 4.6 TGas bt.skipLoad(`.*randomStatetest94.json.*`) bt.walk(t, blockTestDir, func(t *testing.T, name string, test *BlockTest) { if err := bt.checkFailure(t, name, test.Run()); err != nil { - fmt.Println("******* NAME: ", name) t.Error(err) } }) diff --git a/l2geth/tests/state_test.go b/l2geth/tests/state_test.go index 28a1760ca..a615a89e0 100644 --- a/l2geth/tests/state_test.go +++ b/l2geth/tests/state_test.go @@ -44,9 +44,6 @@ func TestState(t *testing.T) { // Very time consuming st.skipLoad(`^stTimeConsuming/`) - // OVM changes break these tests - st.skipLoad(`^st`) - // Broken tests: // Expected failures: //st.fails(`^stRevertTest/RevertPrecompiledTouch(_storage)?\.json/Byzantium/0`, "bug in test") diff --git a/l2geth/tests/transaction_test.go b/l2geth/tests/transaction_test.go index 9713bfe16..846d5d548 100644 --- a/l2geth/tests/transaction_test.go +++ b/l2geth/tests/transaction_test.go @@ -45,7 +45,6 @@ func TestTransaction(t *testing.T) { // Geth accepts it, which is not a consensus issue since we use big.Int's // internally to calculate the cost txt.skipLoad("^ttValue/TransactionWithHighValueOverflow.json") - txt.skipLoad("^ttSignature/TransactionWithTooManyRLPElements.json") txt.walk(t, transactionTestDir, func(t *testing.T, name string, test *TransactionTest) { cfg := params.MainnetChainConfig if err := txt.checkFailure(t, name, test.Run(cfg)); err != nil { diff --git a/ops/docker-compose-side.yml b/ops/docker-compose-side.yml index 0872ac894..2575aedf4 100644 --- a/ops/docker-compose-side.yml +++ b/ops/docker-compose-side.yml @@ -154,6 +154,7 @@ services: depends_on: - l1_chain - dtl + - l2geth image: bobanetwork/l2geth:latest deploy: replicas: 1 @@ -167,6 +168,7 @@ services: ETH1_HTTP: http://l1_chain:8545 ROLLUP_STATE_DUMP_PATH: http://dtl:8081/state-dump.latest.json ROLLUP_CLIENT_HTTP: http://dtl:7878 + SEQUENCER_CLIENT_HTTP: http://l2geth:8545 ROLLUP_BACKEND: 'l2' ROLLUP_VERIFIER_ENABLE: 'true' ETH1_CTC_DEPLOYMENT_HEIGHT: 8 diff --git a/ops/docker-compose.yml b/ops/docker-compose.yml index a034a1c92..f8b0dc419 100644 --- a/ops/docker-compose.yml +++ b/ops/docker-compose.yml @@ -370,6 +370,7 @@ services: replica: depends_on: - dtl + - l2geth image: bobanetwork/l2geth:latest deploy: replicas: 1 @@ -392,6 +393,7 @@ services: BLOCK_SIGNER_ADDRESS: "0x00000398232E2064F896018496b4b44b3D62751F" ROLLUP_POLL_INTERVAL_FLAG: "10s" TURING_CREDIT_ADDRESS: "0x4200000000000000000000000000000000000020" + SEQUENCER_CLIENT_HTTP: http://l2geth:8545 EMERGENCY_FORK_NUMBER: 0 ports: - ${L2GETH_HTTP_PORT:-8549}:8545 diff --git a/ops/docker/Dockerfile.monorepo b/ops/docker/Dockerfile.monorepo index 291ffc73a..d9e4b12a9 100644 --- a/ops/docker/Dockerfile.monorepo +++ b/ops/docker/Dockerfile.monorepo @@ -5,7 +5,7 @@ # We do not use Alpine because there's a regression causing it to be very slow # when used with typescript/hardhat: https://github.com/nomiclabs/hardhat/issues/1219 FROM node:14-buster-slim as node -RUN apt-get update -y && apt-get install -y git +RUN apt-get update -y && apt-get install -y git && apt-get install -y python3 && apt-get install -y build-essential # Pre-download the compilers so that they do not need to be downloaded inside # the image when building diff --git a/packages/boba/gateway/public/index.html b/packages/boba/gateway/public/index.html index 15301d38d..76f00a367 100644 --- a/packages/boba/gateway/public/index.html +++ b/packages/boba/gateway/public/index.html @@ -13,7 +13,7 @@ - BOBA Gateway + Boba Gateway diff --git a/packages/boba/gateway/public/manifest.json b/packages/boba/gateway/public/manifest.json index ffb212586..d770ef293 100644 --- a/packages/boba/gateway/public/manifest.json +++ b/packages/boba/gateway/public/manifest.json @@ -1,6 +1,6 @@ { - "short_name": "OMGX Web Wallet", - "name": "OMGX Web Wallet", + "short_name": "Boba Gateway", + "name": "Boba Gateway", "icons": [ { "src": "favicon.png", diff --git a/packages/boba/turing/test.js b/packages/boba/turing/test.js index d5a24f31f..b00765b1a 100644 --- a/packages/boba/turing/test.js +++ b/packages/boba/turing/test.js @@ -1,67 +1,89 @@ var Web3 = require('web3') - var web3 = new Web3('http://localhost:8545') -web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', 0).then(result => { - console.log("Owner address:", result) -}); +var web3Replica = new Web3('http://localhost:8549') +var web3Verifier = new Web3('http://localhost:8547') -newKey = web3.utils.soliditySha3("0x0000000000000000000000004200000000000000000000000000000000000022", 1); -web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', newKey).then(function(res){ - console.log("0x22 balance:", parseInt(res, 16)) -}) +// web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', 4).then(result => { +// console.log("Owner balance:",web3.utils.toBN(result).toString()) +// }) + +//web3Replica.getBlock('latest') -web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', 2).then(result => { - console.log("Fee token address:", result) +web3.eth.getBlock('latest').then(block => { + console.log("Latest L2Geth block:",block.number) }) -web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', 3).then(result => { - console.log("Price:", web3.utils.toBN(result).toString()) +web3Replica.eth.getBlock('latest').then(block => { + console.log("Latest replica block:",block.number) }) -web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', 4).then(result => { - console.log("Owner balance:",web3.utils.toBN(result).toString()) +web3Verifier.eth.getBlock('latest').then(block => { + console.log("Latest verifier block:",block.number) }) -/* - { - "astId": 393, - "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", - "label": "_owner", - "offset": 0, - "slot": "0", - "type": "t_address" - }, - { - "astId": 6119, - "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", - "label": "prepaidBalance", - "offset": 0, - "slot": "1", - "type": "t_mapping(t_address,t_uint256)" - }, - { - "astId": 6121, - "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", - "label": "turingToken", - "offset": 0, - "slot": "2", - "type": "t_address" - }, - { - "astId": 6123, - "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", - "label": "turingPrice", - "offset": 0, - "slot": "3", - "type": "t_uint256" - }, - { - "astId": 6125, - "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", - "label": "ownerRevenue", - "offset": 0, - "slot": "4", - "type": "t_uint256" - } - */ \ No newline at end of file +//getLatestTransacton() + +// web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', 0).then(result => { +// console.log("Owner address:", result) +// }); + +// newKey = web3.utils.soliditySha3("0x0000000000000000000000004200000000000000000000000000000000000022", 1); +// web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', newKey).then(function(res){ +// console.log("0x22 balance:", parseInt(res, 16)) +// }) + +// web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', 2).then(result => { +// console.log("Fee token address:", result) +// }) + +// web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', 3).then(result => { +// console.log("Price:", web3.utils.toBN(result).toString()) +// }) + +// web3.eth.getStorageAt('0x4200000000000000000000000000000000000020', 4).then(result => { +// console.log("Owner balance:",web3.utils.toBN(result).toString()) +// }) + + +// { +// "astId": 393, +// "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", +// "label": "_owner", +// "offset": 0, +// "slot": "0", +// "type": "t_address" +// }, +// { +// "astId": 6119, +// "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", +// "label": "prepaidBalance", +// "offset": 0, +// "slot": "1", +// "type": "t_mapping(t_address,t_uint256)" +// }, +// { +// "astId": 6121, +// "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", +// "label": "turingToken", +// "offset": 0, +// "slot": "2", +// "type": "t_address" +// }, +// { +// "astId": 6123, +// "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", +// "label": "turingPrice", +// "offset": 0, +// "slot": "3", +// "type": "t_uint256" +// }, +// { +// "astId": 6125, +// "contract": "contracts/L2/predeploys/BobaTuringCredit.sol:BobaTuringCredit", +// "label": "ownerRevenue", +// "offset": 0, +// "slot": "4", +// "type": "t_uint256" +// } +// \ No newline at end of file diff --git a/packages/boba/turing/test/003_stable_swap.ts b/packages/boba/turing/test/003_stable_swap.ts index 24dcd8d74..ee5af29e3 100644 --- a/packages/boba/turing/test/003_stable_swap.ts +++ b/packages/boba/turing/test/003_stable_swap.ts @@ -140,7 +140,7 @@ describe("Stableswap at AWS Lambda", function () { it("should correctly swap X in for Y out", async () => { //testing with 800, y=1200, A=5 - this also sets the k - await stable.estimateGas.swap_x(urlStr, 12, gasOverride) + //await stable.estimateGas.swap_x(urlStr, 12, gasOverride) const tr = await stable.swap_x(urlStr, 12, gasOverride) const res = await tr.wait() expect(res).to.be.ok diff --git a/packages/boba/turing/test/005_lending.ts b/packages/boba/turing/test/005_lending.ts index 3a6c50992..7b5519ba5 100644 --- a/packages/boba/turing/test/005_lending.ts +++ b/packages/boba/turing/test/005_lending.ts @@ -133,7 +133,7 @@ describe("Pull Bitcoin - USD quote", function () { expect(postBalance).to.be.deep.eq(preBalance.add(depositAmount)) }) it("should get the current Bitcoin - USD price", async () => { - await lending.estimateGas.getCurrentQuote(urlStr, "BTC/USD", gasOverride) + //await lending.estimateGas.getCurrentQuote(urlStr, "BTC/USD", gasOverride) const tr = await lending.getCurrentQuote(urlStr, "BTC/USD", gasOverride) const res = await tr.wait() expect(res).to.be.ok diff --git a/packages/data-transport-layer/src/client/client.ts b/packages/data-transport-layer/src/client/client.ts index 724c72c30..64a629f21 100644 --- a/packages/data-transport-layer/src/client/client.ts +++ b/packages/data-transport-layer/src/client/client.ts @@ -36,7 +36,7 @@ export class L1DataTransportClient { return this._get(`/transaction/index/${index}`) } - public async getLatestTransacton(): Promise { + public async getLatestTransaction(): Promise { return this._get(`/transaction/latest`) } diff --git a/packages/data-transport-layer/src/services/l1-ingestion/handlers/sequencer-batch-appended.ts b/packages/data-transport-layer/src/services/l1-ingestion/handlers/sequencer-batch-appended.ts index 2b2e864e6..1fd8e97e5 100644 --- a/packages/data-transport-layer/src/services/l1-ingestion/handlers/sequencer-batch-appended.ts +++ b/packages/data-transport-layer/src/services/l1-ingestion/handlers/sequencer-batch-appended.ts @@ -289,10 +289,10 @@ const turingParse = ( // methodID for GetResponse is 7d93616c -> [125 147 97 108] // methodID for GetRandom is 493d57d6 -> [ 73 61 87 214] - console.log('Turing:', { - turingVersion, - turingLength, - }) + // console.log('Turing:', { + // turingVersion, + // turingLength, + // }) if ( turingVersion === 1 && @@ -303,18 +303,18 @@ const turingParse = ( toHexString(sequencerTransaction.slice(-turingLength)) ) const turingCall = turingCandidate.slice(0, 8).toLowerCase() - console.log('turingCall', { turingCall }) + // console.log('turingCall', { turingCall }) if (turingCall === '7d93616c' || turingCall === '493d57d6') { // we are all set! // we have a Turing v1 payload turing = sequencerTransaction.slice(-turingLength) sequencerTransaction = sequencerTransaction.slice(3, -turingLength) // The `3` chops off the Turing length header field, and the `-turingLength` chops off the Turing bytes - console.log('Found a Turing payload:', { - turingLength, - turing: toHexString(turing), - restoredSequencerTransaction: toHexString(sequencerTransaction), - }) + // console.log('Found a Turing payload:', { + // turingLength, + // turing: toHexString(turing), + // restoredSequencerTransaction: toHexString(sequencerTransaction), + // }) } else { // unknown/corrupted/legacy format // In this case, will add '0x', the default, by doing nothing @@ -322,17 +322,17 @@ const turingParse = ( } else if (turingVersion === 1 && turingLength === 0) { // The `3` chops off the Turing version and length header field, which is in this case (0: 01 1: 00 2: 00) sequencerTransaction = sequencerTransaction.slice(3) - console.log('Found a normal TX:', { - turingLength, - turing: '0x', // this will be '0x' - restoredSequencerTransaction: toHexString(sequencerTransaction), - }) + // console.log('Found a normal TX:', { + // turingLength, + // turing: '0x', // this will be '0x' + // restoredSequencerTransaction: toHexString(sequencerTransaction), + // }) } else { - console.log('Found a LEGACY TX:', { - turingLength, - turing: '0x', // this will be '0x' - restoredSequencerTransaction: toHexString(sequencerTransaction), - }) + // console.log('Found a LEGACY TX:', { + // turingLength, + // turing: '0x', // this will be '0x' + // restoredSequencerTransaction: toHexString(sequencerTransaction), + // }) } return [sequencerTransaction, turing] }