diff --git a/.github/workflows/integration.yml b/.github/workflows/integration.yml
index cf63567842c9c..939301f04501f 100644
--- a/.github/workflows/integration.yml
+++ b/.github/workflows/integration.yml
@@ -20,9 +20,6 @@ jobs:
- 5000:5000
strategy:
matrix:
- batch-submitter:
- - ts-batch-submitter
- - go-batch-submitter
batch-type:
- zlib
- legacy
@@ -53,7 +50,7 @@ jobs:
working-directory: ./ops
run: |
./scripts/stats.sh &
- docker-compose -f docker-compose.yml -f docker-compose.${{ matrix.batch-submitter }}.yml up -d
+ docker-compose -f docker-compose.yml up -d
- name: Wait for the Sequencer node
working-directory: ./ops
diff --git a/.github/workflows/ts-packages.yml b/.github/workflows/ts-packages.yml
index 8968fcb73999f..4cc40266ce455 100644
--- a/.github/workflows/ts-packages.yml
+++ b/.github/workflows/ts-packages.yml
@@ -113,12 +113,6 @@ jobs:
fail_ci_if_error: false
verbose: true
flags: core-utils
- - uses: codecov/codecov-action@v1
- with:
- files: ./packages/batch-submitter/coverage.json
- fail_ci_if_error: false
- verbose: true
- flags: batch-submitter
- uses: codecov/codecov-action@v1
with:
files: ./packages/data-transport-layer/coverage.json
@@ -170,10 +164,6 @@ jobs:
# if: steps.yarn-cache.outputs.cache-hit != 'true'
run: yarn install
- - name: Check packages/batch-submitter
- working-directory: ./packages/batch-submitter
- run: npx depcheck
-
- name: Check packages/contracts
working-directory: ./packages/contracts
run: npx depcheck
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0413bff6c1231..5485a08be4d99 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -116,7 +116,7 @@ This will build the following containers:
* [`l2geth`](https://hub.docker.com/r/ethereumoptimism/l2geth): L2 geth node running in Sequencer mode
* [`verifier`](https://hub.docker.com/r/ethereumoptimism/go-ethereum): L2 geth node running in Verifier mode
* [`relayer`](https://hub.docker.com/r/ethereumoptimism/message-relayer): helper process that relays messages between L1 and L2
-* [`batch_submitter`](https://hub.docker.com/r/ethereumoptimism/batch-submitter): service that submits batches of Sequencer transactions to the L1 chain
+* [`batch_submitter`](https://hub.docker.com/r/ethereumoptimism/batch-submitter-service): service that submits batches of Sequencer transactions to the L1 chain
* [`integration_tests`](https://hub.docker.com/r/ethereumoptimism/integration-tests): integration tests in a box
If you want to make a change to a container, you'll need to take it down and rebuild it.
diff --git a/README.md b/README.md
index 7c47621536388..d899873cc62c4 100644
--- a/README.md
+++ b/README.md
@@ -35,7 +35,6 @@ root
│ ├── core-utils: Low-level utilities that make building Optimism easier
│ ├── common-ts: Common tools for building apps in TypeScript
│ ├── data-transport-layer: Service for indexing Optimism-related L1 data
-│ ├── batch-submitter: Service for submitting batches of transactions and results to L1
│ ├── message-relayer: Tool for automatically relaying L1<>L2 messages in development
│ └── replica-healthcheck: Service for monitoring the health of a replica node
├── go
diff --git a/ops/Makefile b/ops/Makefile
index 4d4dd82503f37..7ff3285bd1b04 100644
--- a/ops/Makefile
+++ b/ops/Makefile
@@ -1,7 +1,5 @@
-BATCH_SUBMITTER ?= docker-compose.ts-batch-submitter.yml
DOCKER_COMPOSE_CMD := docker-compose \
- -f docker-compose.yml \
- -f $(BATCH_SUBMITTER)
+ -f docker-compose.yml
build:
DOCKER_BUILDKIT=1 \
diff --git a/ops/README.md b/ops/README.md
index 90c175577d057..d3b46276d6259 100644
--- a/ops/README.md
+++ b/ops/README.md
@@ -26,7 +26,6 @@ The base stack can be started and stopped with a command like this:
```
docker-compose \
-f docker-compose.yml \
- -f docker-compose.ts-batch-submitter.yml \
up --build --detach
```
@@ -40,7 +39,6 @@ To start the stack with monitoring enabled, just add the metric composition file
```
docker-compose \
-f docker-compose.yml \
- -f docker-compose.ts-batch-submitter.yml \
-f docker-compose-metrics.yml \
up --build --detach
```
@@ -50,7 +48,6 @@ Optionally, run a verifier along the rest of the stack. Run a replica with the s
```
docker-compose
-f docker-compose.yml \
- -f docker-compose.ts-batch-submitter.yml \
up --scale \
verifier=1 \
--build --detach
@@ -71,24 +68,6 @@ Fees can be turned off at runtime by setting the environment variable
ROLLUP_ENFORCE_FEES=false docker-compose up
```
-## Using the Go Batch Submitter
-
-The existing Typescript batch submitter is in the process of being reimplemented
-in Go. During this transition, the user is required to specify which batch
-submitter to use with docker-compose.
-
-The commands above all use the Typescript batch submitter, by specifying
-`-f docker-compose.ts-batch-submitter.yml`. This can be swapped out for the go
-batch submitter by supplying `-f docker-compose.go-batch-submitter.yml` instead.
-
-Additionally, the `make` targets assume the use of the Typescript batch
-submitter. This can be overridden by setting the `BATCH_SUBMITTER` environment
-variable, e.g. `BATCH_SUBMITTER=docker-compose.go-batch-submitter.yml make up`.
-
-Once the transition is complete, specifying the desired batch submitter will be
-obsolete, and the Go batch submitter will be selected by default from the
-`docker-compose.yml` file and `Makefile`.
-
## Cross domain communication
By default, the `message-relayer` service is turned off. This means that
diff --git a/ops/docker-compose-nobuild.yml b/ops/docker-compose-nobuild.yml
index 128d706706c4c..3988f589fda4f 100644
--- a/ops/docker-compose-nobuild.yml
+++ b/ops/docker-compose-nobuild.yml
@@ -85,16 +85,17 @@ services:
- l1_chain
- deployer
- l2geth
- image: ethereumoptimism/batch-submitter:${DOCKER_TAG:-prerelease-0.5.0-rc-7-ee217ce}
- entrypoint: ./batches.sh
+ image: ethereumoptimism/batch-submitter-service:${DOCKER_TAG:-prerelease-0.5.0-rc-7-ee217ce}
+ entrypoint: ./batch-submitter.sh
env_file:
- - ./envs/batches.env
+ - ./envs/batch-submitter.env
environment:
- L1_NODE_WEB3_URL: http://l1_chain:8545
- L2_NODE_WEB3_URL: http://l2geth:8545
- URL: http://deployer:8081/addresses.json
- SEQUENCER_PRIVATE_KEY: "0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d"
- PROPOSER_PRIVATE_KEY: "0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a"
+ L1_ETH_RPC: http://l1_chain:8545
+ L2_ETH_RPC: http://l2geth:8545
+ URL: http://deployer:8081/addresses.json
+ BATCH_SUBMITTER_SEQUENCER_PRIVATE_KEY: '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'
+ BATCH_SUBMITTER_PROPOSER_PRIVATE_KEY: '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a'
+ BATCH_SUBMITTER_SEQUENCER_BATCH_TYPE: ${BATCH_SUBMITTER_SEQUENCER_BATCH_TYPE:-zlib}
verifier:
depends_on:
diff --git a/ops/docker-compose.go-batch-submitter.yml b/ops/docker-compose.go-batch-submitter.yml
deleted file mode 100644
index ea8f5dfd664c2..0000000000000
--- a/ops/docker-compose.go-batch-submitter.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-services:
- batch_submitter:
- depends_on:
- - l1_chain
- - deployer
- - l2geth
- build:
- context: ..
- dockerfile: ./ops/docker/Dockerfile.batch-submitter-service
- entrypoint: ./batch-submitter.sh
- env_file:
- - ./envs/batch-submitter.env
- environment:
- L1_ETH_RPC: http://l1_chain:8545
- L2_ETH_RPC: http://l2geth:8545
- URL: http://deployer:8081/addresses.json
- BATCH_SUBMITTER_SEQUENCER_PRIVATE_KEY: '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'
- BATCH_SUBMITTER_PROPOSER_PRIVATE_KEY: '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a'
- BATCH_SUBMITTER_SEQUENCER_BATCH_TYPE: ${BATCH_SUBMITTER_SEQUENCER_BATCH_TYPE:-zlib}
diff --git a/ops/docker-compose.ts-batch-submitter.yml b/ops/docker-compose.ts-batch-submitter.yml
deleted file mode 100644
index da0b3b7e9c477..0000000000000
--- a/ops/docker-compose.ts-batch-submitter.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-services:
- batch_submitter:
- depends_on:
- - l1_chain
- - deployer
- - l2geth
- build:
- context: ..
- dockerfile: ./ops/docker/Dockerfile.packages
- target: batch-submitter
- entrypoint: ./batches.sh
- env_file:
- - ./envs/batches.env
- environment:
- L1_NODE_WEB3_URL: http://l1_chain:8545
- L2_NODE_WEB3_URL: http://l2geth:8545
- URL: http://deployer:8081/addresses.json
- SEQUENCER_PRIVATE_KEY: '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'
- PROPOSER_PRIVATE_KEY: '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a'
- BATCH_SUBMITTER_SEQUENCER_BATCH_TYPE: ${BATCH_SUBMITTER_SEQUENCER_BATCH_TYPE:-zlib}
diff --git a/ops/docker-compose.yml b/ops/docker-compose.yml
index 03469de8a2628..2e40b3bd8b04e 100644
--- a/ops/docker-compose.yml
+++ b/ops/docker-compose.yml
@@ -212,3 +212,22 @@ services:
GAS_PRICE_ORACLE_ETHEREUM_HTTP_URL: http://l2geth:8545
# Default hardhat account 5
GAS_PRICE_ORACLE_PRIVATE_KEY: '0x8b3a350cf5c34c9194ca85829a2df0ec3153be0318b5e2d3348e872092edffba'
+
+ batch_submitter:
+ depends_on:
+ - l1_chain
+ - deployer
+ - l2geth
+ build:
+ context: ..
+ dockerfile: ./ops/docker/Dockerfile.batch-submitter-service
+ entrypoint: ./batch-submitter.sh
+ env_file:
+ - ./envs/batch-submitter.env
+ environment:
+ L1_ETH_RPC: http://l1_chain:8545
+ L2_ETH_RPC: http://l2geth:8545
+ URL: http://deployer:8081/addresses.json
+ BATCH_SUBMITTER_SEQUENCER_PRIVATE_KEY: '0x59c6995e998f97a5a0044966f0945389dc9e86dae88c7a8412f4603b6b78690d'
+ BATCH_SUBMITTER_PROPOSER_PRIVATE_KEY: '0x5de4111afa1a4b94908f83103eb1f1706367c2e68ca870fc3fb9a804cdab365a'
+ BATCH_SUBMITTER_SEQUENCER_BATCH_TYPE: ${BATCH_SUBMITTER_SEQUENCER_BATCH_TYPE:-zlib}
diff --git a/ops/docker/Dockerfile.batch-submitter b/ops/docker/Dockerfile.batch-submitter
deleted file mode 100644
index a0b84461c5847..0000000000000
--- a/ops/docker/Dockerfile.batch-submitter
+++ /dev/null
@@ -1,35 +0,0 @@
-ARG LOCAL_REGISTRY=docker.io
-ARG BUILDER_TAG=latest
-FROM ${LOCAL_REGISTRY}/ethereumoptimism/builder:${BUILDER_TAG} AS builder
-
-FROM node:16-alpine
-
-RUN apk add --no-cache curl bash jq
-
-WORKDIR /opt/optimism
-
-# copy top level files
-COPY --from=builder /optimism/*.json /optimism/yarn.lock ./
-COPY --from=builder /optimism/node_modules ./node_modules
-
-# copy deps (would have been nice if docker followed the symlinks required)
-COPY --from=builder /optimism/packages/core-utils/package.json ./packages/core-utils/package.json
-COPY --from=builder /optimism/packages/core-utils/dist ./packages/core-utils/dist
-COPY --from=builder /optimism/packages/common-ts/package.json ./packages/common-ts/package.json
-COPY --from=builder /optimism/packages/common-ts/dist ./packages/common-ts/dist
-
-COPY --from=builder /optimism/packages/contracts/package.json ./packages/contracts/package.json
-COPY --from=builder /optimism/packages/contracts/deployments ./packages/contracts/deployments
-COPY --from=builder /optimism/packages/contracts/dist ./packages/contracts/dist
-COPY --from=builder /optimism/packages/contracts/artifacts ./packages/contracts/artifacts
-
-# copy the service
-WORKDIR /opt/optimism/packages/batch-submitter
-COPY --from=builder /optimism/packages/batch-submitter/package.json ./
-COPY --from=builder /optimism/packages/batch-submitter/dist ./dist
-COPY --from=builder /optimism/packages/batch-submitter/exec ./exec
-COPY --from=builder /optimism/packages/batch-submitter/node_modules ./node_modules
-
-# copy this over in case you want to run alongside other services
-COPY ./ops/scripts/batches.sh .
-ENTRYPOINT ["npm", "run", "start"]
diff --git a/ops/docker/Dockerfile.monorepo b/ops/docker/Dockerfile.monorepo
index 63762076ada8a..e3b07a6a27df6 100644
--- a/ops/docker/Dockerfile.monorepo
+++ b/ops/docker/Dockerfile.monorepo
@@ -29,7 +29,6 @@ COPY packages/core-utils/package.json ./packages/core-utils/package.json
COPY packages/common-ts/package.json ./packages/common-ts/package.json
COPY packages/contracts/package.json ./packages/contracts/package.json
COPY packages/data-transport-layer/package.json ./packages/data-transport-layer/package.json
-COPY packages/batch-submitter/package.json ./packages/batch-submitter/package.json
COPY packages/message-relayer/package.json ./packages/message-relayer/package.json
COPY packages/replica-healthcheck/package.json ./packages/replica-healthcheck/package.json
COPY integration-tests/package.json ./integration-tests/package.json
diff --git a/ops/docker/Dockerfile.packages b/ops/docker/Dockerfile.packages
index 119f94f046a09..e06cb37949b07 100644
--- a/ops/docker/Dockerfile.packages
+++ b/ops/docker/Dockerfile.packages
@@ -18,7 +18,6 @@ COPY packages/core-utils/package.json ./packages/core-utils/package.json
COPY packages/common-ts/package.json ./packages/common-ts/package.json
COPY packages/contracts/package.json ./packages/contracts/package.json
COPY packages/data-transport-layer/package.json ./packages/data-transport-layer/package.json
-COPY packages/batch-submitter/package.json ./packages/batch-submitter/package.json
COPY packages/message-relayer/package.json ./packages/message-relayer/package.json
COPY packages/replica-healthcheck/package.json ./packages/replica-healthcheck/package.json
COPY integration-tests/package.json ./integration-tests/package.json
@@ -38,12 +37,6 @@ COPY ./ops/scripts/deployer.sh .
CMD ["yarn", "run", "deploy"]
-FROM base as batch-submitter
-WORKDIR /opt/optimism/packages/batch-submitter
-COPY ./ops/scripts/batches.sh .
-CMD ["npm", "run", "start"]
-
-
FROM base as data-transport-layer
WORKDIR /opt/optimism/packages/data-transport-layer
COPY ./ops/scripts/dtl.sh .
diff --git a/ops/envs/batches.env b/ops/envs/batches.env
deleted file mode 100644
index 13017d3e6f7e7..0000000000000
--- a/ops/envs/batches.env
+++ /dev/null
@@ -1,19 +0,0 @@
-ADDRESS_MANAGER_ADDRESS=
-
-DEBUG=info*,error*,warn*,debug*
-
-MAX_L1_TX_SIZE=90000
-MIN_L1_TX_SIZE=32
-MAX_TX_BATCH_COUNT=50
-MAX_STATE_BATCH_COUNT=50
-
-POLL_INTERVAL=500
-NUM_CONFIRMATIONS=0
-RESUBMISSION_TIMEOUT=1
-FINALITY_CONFIRMATIONS=0
-RUN_TX_BATCH_SUBMITTER=true
-RUN_STATE_BATCH_SUBMITTER=true
-MAX_BATCH_SUBMISSION_TIME=0
-SAFE_MINIMUM_ETHER_BALANCE=0
-CLEAR_PENDING_TXS=false
-RETRIES=80
diff --git a/ops/scripts/batches.sh b/ops/scripts/batches.sh
deleted file mode 100755
index 09c77db93c5c3..0000000000000
--- a/ops/scripts/batches.sh
+++ /dev/null
@@ -1,25 +0,0 @@
-#!/bin/bash
-
-set -e
-
-RETRIES=${RETRIES:-40}
-
-if [[ ! -z "$URL" ]]; then
- # get the addrs from the URL provided
- ADDRESSES=$(curl --fail --show-error --silent --retry-connrefused --retry $RETRIES --retry-delay 5 $URL)
- # set the env
- export ADDRESS_MANAGER_ADDRESS=$(echo $ADDRESSES | jq -r '.AddressManager')
-fi
-
-# waits for l2geth to be up
-curl --fail \
- --show-error \
- --silent \
- --retry-connrefused \
- --retry $RETRIES \
- --retry-delay 1 \
- --output /dev/null \
- $L2_NODE_WEB3_URL
-
-# go
-exec node ./exec/run-batch-submitter.js
diff --git a/ops/scripts/build-ci.sh b/ops/scripts/build-ci.sh
index db85d1e80ec9e..682f29450730b 100755
--- a/ops/scripts/build-ci.sh
+++ b/ops/scripts/build-ci.sh
@@ -43,7 +43,6 @@ docker tag localhost:5000/ethereumoptimism/builder:latest ethereumoptimism/build
build deployer "ethereumoptimism/deployer:latest" "./ops/docker/Dockerfile.deployer" .
build dtl "ethereumoptimism/data-transport-layer:latest" "./ops/docker/Dockerfile.data-transport-layer" .
-build batch_submitter "ethereumoptimism/batch-submitter:latest" "./ops/docker/Dockerfile.batch-submitter" .
build relayer "ethereumoptimism/message-relayer:latest" "./ops/docker/Dockerfile.message-relayer" .
build integration-tests "ethereumoptimism/integration-tests:latest" "./ops/docker/Dockerfile.integration-tests" .
diff --git a/packages/batch-submitter/.env.example b/packages/batch-submitter/.env.example
deleted file mode 100644
index 10789fa468153..0000000000000
--- a/packages/batch-submitter/.env.example
+++ /dev/null
@@ -1,43 +0,0 @@
-# Environment
-NODE_ENV=development
-# Leave blank during local development
-ETH_NETWORK_NAME=
-# Logging & monitoring
-DEBUG=info*,error*,warn*,debug*
-RUN_METRICS_SERVER=
-METRICS_PORT=
-METRICS_HOSTNAME=
-# Leave the SENTRY_DSN variable unset during local development
-SENTRY_DSN=
-SENTRY_TRACE_RATE=
-USE_SENTRY=
-
-L1_NODE_WEB3_URL=http://localhost:9545
-L2_NODE_WEB3_URL=http://localhost:8545
-
-MAX_L1_TX_SIZE=90000
-MIN_L1_TX_SIZE=32
-MAX_TX_BATCH_SIZE=50
-MAX_STATE_BATCH_COUNT=2000
-MAX_TX_BATCH_COUNT=250
-MAX_BATCH_SUBMISSION_TIME=0
-POLL_INTERVAL=15000
-NUM_CONFIRMATIONS=0
-RESUBMISSION_TIMEOUT=300 # in seconds
-FINALITY_CONFIRMATIONS=0
-RUN_TX_BATCH_SUBMITTER=true
-RUN_STATE_BATCH_SUBMITTER=true
-SAFE_MINIMUM_ETHER_BALANCE=0
-CLEAR_PENDING_TXS=false
-ADDRESS_MANAGER_ADDRESS=
-
-USE_HARDHAT=
-DEBUG_IMPERSONATE_SEQUENCER_ADDRESS=
-DEBUG_IMPERSONATE_PROPOSER_ADDRESS=
-
-# Optional gas settings
-MAX_GAS_PRICE_IN_GWEI=200
-GAS_RETRY_INCREMENT=5
-GAS_THRESHOLD_IN_GWEI=100
-
-SEQUENCER_PRIVATE_KEY=0xd2ab07f7c10ac88d5f86f1b4c1035d5195e81f27dbe62ad65e59cbf88205629b
diff --git a/packages/batch-submitter/.eslintrc.js b/packages/batch-submitter/.eslintrc.js
deleted file mode 100644
index bfd2057be80bd..0000000000000
--- a/packages/batch-submitter/.eslintrc.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = {
- extends: '../../.eslintrc.js',
-}
diff --git a/packages/batch-submitter/.lintstagedrc.yml b/packages/batch-submitter/.lintstagedrc.yml
deleted file mode 100644
index a3035a2299b26..0000000000000
--- a/packages/batch-submitter/.lintstagedrc.yml
+++ /dev/null
@@ -1,2 +0,0 @@
-"*.{ts,js}":
- - eslint
diff --git a/packages/batch-submitter/.prettierrc.js b/packages/batch-submitter/.prettierrc.js
deleted file mode 100644
index 6b3fa8e2ce237..0000000000000
--- a/packages/batch-submitter/.prettierrc.js
+++ /dev/null
@@ -1,3 +0,0 @@
-module.exports = {
- ...require('../../.prettierrc.js'),
-};
\ No newline at end of file
diff --git a/packages/batch-submitter/CHANGELOG.md b/packages/batch-submitter/CHANGELOG.md
deleted file mode 100644
index 79dcba9af3aa2..0000000000000
--- a/packages/batch-submitter/CHANGELOG.md
+++ /dev/null
@@ -1,596 +0,0 @@
-# Changelog
-
-## 0.4.20
-
-### Patch Changes
-
-- d3d70291: Use asL2Provider instead of injectL2Context in bss and healthcheck service.
-- Updated dependencies [f37c283c]
-- Updated dependencies [3f4d3c13]
-- Updated dependencies [0b4453f7]
-- Updated dependencies [78298782]
-- Updated dependencies [0c54e60e]
- - @eth-optimism/sdk@0.2.3
- - @eth-optimism/core-utils@0.8.0
- - @eth-optimism/contracts@0.5.15
-
-## 0.4.19
-
-### Patch Changes
-
-- Updated dependencies [b4165299]
-- Updated dependencies [3c2acd91]
- - @eth-optimism/core-utils@0.7.7
- - @eth-optimism/contracts@0.5.14
-
-## 0.4.18
-
-### Patch Changes
-
-- Updated dependencies [438bc78a]
- - @eth-optimism/contracts@0.5.13
-
-## 0.4.17
-
-### Patch Changes
-
-- fcce5b67: Updates batch submitter to also include separate timestamps for deposit transactions"
-- ba14c59d: Updates various ethers dependencies to their latest versions
-- Updated dependencies [ba14c59d]
- - @eth-optimism/contracts@0.5.12
- - @eth-optimism/core-utils@0.7.6
-
-## 0.4.16
-
-### Patch Changes
-
-- Updated dependencies [e631c39c]
- - @eth-optimism/contracts@0.5.11
-
-## 0.4.15
-
-### Patch Changes
-
-- ae4a90d9: Adds a fix for the BSS to account for new timestamp logic in L2Geth
-- ca547c4e: Import performance to not couple batch submitter to version of nodejs that has performance as a builtin
-- Updated dependencies [ad94b9d1]
- - @eth-optimism/core-utils@0.7.5
- - @eth-optimism/contracts@0.5.10
-
-## 0.4.14
-
-### Patch Changes
-
-- Updated dependencies [ba96a455]
-- Updated dependencies [c3e85fef]
- - @eth-optimism/core-utils@0.7.4
- - @eth-optimism/contracts@0.5.9
-
-## 0.4.13
-
-### Patch Changes
-
-- 9fe09f70: Properly clear state root batch txs on startup
-- Updated dependencies [b3efb8b7]
-- Updated dependencies [279603e5]
-- Updated dependencies [b6040bb3]
- - @eth-optimism/contracts@0.5.8
-
-## 0.4.12
-
-### Patch Changes
-
-- 07f1ad01: Fix the numTxPerBatch metric
-
-## 0.4.11
-
-### Patch Changes
-
-- 3eb5590b: adds batchTxBuildTime gauge
-- Updated dependencies [b6f89fad]
- - @eth-optimism/contracts@0.5.7
-
-## 0.4.10
-
-### Patch Changes
-
-- Updated dependencies [bbd42e03]
-- Updated dependencies [453f0774]
- - @eth-optimism/contracts@0.5.6
-
-## 0.4.9
-
-### Patch Changes
-
-- 57d5b8f9: Build docker images with node.js version 16
-
-## 0.4.8
-
-### Patch Changes
-
-- 0ab37fc9: Update to node.js version 16
-
-## 0.4.7
-
-### Patch Changes
-
-- Updated dependencies [584cbc25]
- - @eth-optimism/core-utils@0.7.3
- - @eth-optimism/contracts@0.5.5
-
-## 0.4.6
-
-### Patch Changes
-
-- 39607e7c: Trigger release of the batch submitter with yatm retry fix
-
-## 0.4.5
-
-### Patch Changes
-
-- 85f68bd3: Immediately reject on nonce errors to stop falling behind
-
-## 0.4.4
-
-### Patch Changes
-
-- 8e634b49: Fix package JSON issues
-- Updated dependencies [8e634b49]
- - @eth-optimism/core-utils@0.7.2
- - @eth-optimism/contracts@0.5.4
-
-## 0.4.3
-
-### Patch Changes
-
-- Updated dependencies [b9049406]
-- Updated dependencies [a8b14a7d]
- - @eth-optimism/contracts@0.5.3
-
-## 0.4.2
-
-### Patch Changes
-
-- 526d7e51: Throw an error when sequencer and proposer have the same address.
-- 243f33e5: Standardize package json file format
-- Updated dependencies [243f33e5]
- - @eth-optimism/common-ts@0.2.1
- - @eth-optimism/contracts@0.5.2
- - @eth-optimism/core-utils@0.7.1
-
-## 0.4.1
-
-### Patch Changes
-
-- Updated dependencies [c0fc7fee]
- - @eth-optimism/contracts@0.5.1
-
-## 0.4.0
-
-### Minor Changes
-
-- 3f590e33: Remove the "OVM" Prefix from contract names
-- 81ccd6e4: `regenesis/0.5.0` release
-
-### Patch Changes
-
-- ac63235a: Default tx batch validation to false
-- bfeb7fba: Add `VALIDATE_TX_BATCH` config option that can disable batch validation
-- 222a3eef: Add 'User-Agent' to the http headers for ethers providers
-- 71f8de9c: Handle error case more explicity when creating invalid batch
-- 970f421e: Ensure empty batches are not submitted
-- b70ee70c: upgraded to solidity 0.8.9
-- a98a1884: Fixes dependencies instead of using caret constraints
-- Updated dependencies [e4a1129c]
-- Updated dependencies [64ea3ac9]
-- Updated dependencies [3ce62c81]
-- Updated dependencies [299a459e]
-- Updated dependencies [8c8807c0]
-- Updated dependencies [d7978cfc]
-- Updated dependencies [e16d41c0]
-- Updated dependencies [5db50b3d]
-- Updated dependencies [cee2a464]
-- Updated dependencies [66bf56a6]
-- Updated dependencies [2c91ca00]
-- Updated dependencies [d5036826]
-- Updated dependencies [222a3eef]
-- Updated dependencies [dfc784e8]
-- Updated dependencies [896168e2]
-- Updated dependencies [436c48fd]
-- Updated dependencies [7c352b1e]
-- Updated dependencies [2ade9a79]
-- Updated dependencies [0272a536]
-- Updated dependencies [6ee7423f]
-- Updated dependencies [3f590e33]
-- Updated dependencies [e20deca0]
-- Updated dependencies [2a731e0d]
-- Updated dependencies [199e895e]
-- Updated dependencies [872f5976]
-- Updated dependencies [9c1443a4]
-- Updated dependencies [26906518]
-- Updated dependencies [c53b3587]
-- Updated dependencies [1b917041]
-- Updated dependencies [483f561b]
-- Updated dependencies [b70ee70c]
-- Updated dependencies [c38e4b57]
-- Updated dependencies [a98a1884]
-- Updated dependencies [b744b6ea]
-- Updated dependencies [20c8969b]
-- Updated dependencies [d2eb8ae0]
-- Updated dependencies [1e63ffa0]
-- Updated dependencies [ff266e9c]
-- Updated dependencies [b56dd079]
-- Updated dependencies [56fe3793]
-- Updated dependencies [3e2aa16a]
-- Updated dependencies [d3cb1b86]
-- Updated dependencies [3e41df63]
-- Updated dependencies [973589da]
-- Updated dependencies [83a449c4]
-- Updated dependencies [9c63e9bd]
-- Updated dependencies [81ccd6e4]
-- Updated dependencies [f38b8000]
-- Updated dependencies [d5f012ab]
-- Updated dependencies [76c84f21]
-- Updated dependencies [6d32d701]
-- Updated dependencies [3605b963]
-- Updated dependencies [3f28385a]
-- Updated dependencies [280f348c]
-- Updated dependencies [a0947c3f]
-- Updated dependencies [51821d8f]
-- Updated dependencies [29f1c228]
-- Updated dependencies [8f4cb337]
-- Updated dependencies [beb6c977]
-- Updated dependencies [33abe73d]
-- Updated dependencies [71de86d6]
- - @eth-optimism/contracts@0.5.0
- - @eth-optimism/core-utils@0.7.0
- - @eth-optimism/common-ts@0.2.0
-
-## 0.3.15
-
-### Patch Changes
-
-- 6d3e1d7f: Update dependencies
-- Updated dependencies [6d3e1d7f]
-- Updated dependencies [2e929aa9]
- - @eth-optimism/common-ts@0.1.6
- - @eth-optimism/contracts@0.4.14
- - @eth-optimism/core-utils@0.6.1
-
-## 0.3.14
-
-### Patch Changes
-
-- 39cea8fd: Removes the call to `appendQueueBatch` from the batch submitter
-- Updated dependencies [e0be02e1]
-- Updated dependencies [7f7f35c3]
-- Updated dependencies [8da04505]
- - @eth-optimism/core-utils@0.6.0
- - @eth-optimism/contracts@0.4.13
-
-## 0.3.13
-
-### Patch Changes
-
-- 7482d09c: Fixes a bug in the batch submitted that would cause it to submit transactions with increasing nonces
-
-## 0.3.12
-
-### Patch Changes
-
-- 21b17edd: Added coverage for packages
-- 78ca518b: Add loglines for eip1559 related fields before sending a transaction
-- Updated dependencies [888dafca]
-- Updated dependencies [eb0854e7]
-- Updated dependencies [21b17edd]
-- Updated dependencies [dfe3598f]
- - @eth-optimism/contracts@0.4.11
- - @eth-optimism/core-utils@0.5.5
-
-## 0.3.11
-
-### Patch Changes
-
-- 918c08ca: Bump ethers dependency to 5.4.x to support eip1559
-- Updated dependencies [918c08ca]
- - @eth-optimism/contracts@0.4.10
- - @eth-optimism/core-utils@0.5.2
-
-## 0.3.10
-
-### Patch Changes
-
-- b5b9fd89: Migrate to using `ethers.StaticJsonRpcProvider`
-- Updated dependencies [ecc2f8c1]
- - @eth-optimism/contracts@0.4.9
-
-## 0.3.9
-
-### Patch Changes
-
-- 3b132974: Fix tx resubmission estimateGas bug in batch submitter
-- Updated dependencies [7f26667d]
-- Updated dependencies [77511b68]
- - @eth-optimism/contracts@0.4.7
-
-## 0.3.8
-
-### Patch Changes
-
-- c73c3939: Update the typescript version to `4.3.5`
-- Updated dependencies [c73c3939]
- - @eth-optimism/common-ts@0.1.5
- - @eth-optimism/contracts@0.4.5
- - @eth-optimism/core-utils@0.5.1
-
-## 0.3.7
-
-### Patch Changes
-
-- 8a1e63dd: Prevent batch submitter from submitting batches if low on ETH
-- Updated dependencies [0313794b]
-- Updated dependencies [049200f4]
-- Updated dependencies [21e47e1f]
- - @eth-optimism/contracts@0.4.2
- - @eth-optimism/core-utils@0.5.0
-
-## 0.3.6
-
-### Patch Changes
-
-- f87a2d00: Use dashes instead of colons in contract names
-- 52d02b14: Add failure metrics to batch submitter
-- 31f517a2: Improved logging of batch submission timeout logs
-- 5c89c45f: Move the metric prefix string to a label #1047
-- Updated dependencies [25f09abd]
-- Updated dependencies [dd8edc7b]
-- Updated dependencies [c87e4c74]
-- Updated dependencies [db0dbfb2]
-- Updated dependencies [7f5936a8]
-- Updated dependencies [f87a2d00]
-- Updated dependencies [85da4979]
-- Updated dependencies [57ca21a2]
-- Updated dependencies [5fc728da]
-- Updated dependencies [2e72fd90]
-- Updated dependencies [c43b33ec]
-- Updated dependencies [26bc63ad]
-- Updated dependencies [a0d9e565]
-- Updated dependencies [2bd49730]
-- Updated dependencies [38355a3b]
-- Updated dependencies [3c2c32e1]
-- Updated dependencies [d9644c34]
-- Updated dependencies [48ece14c]
-- Updated dependencies [e04de624]
-- Updated dependencies [014dea71]
-- Updated dependencies [fa29b03e]
-- Updated dependencies [6b46c8ba]
-- Updated dependencies [e045f582]
-- Updated dependencies [5c89c45f]
-- Updated dependencies [df5ff890]
-- Updated dependencies [e29fab10]
-- Updated dependencies [c2a04893]
-- Updated dependencies [baacda34]
- - @eth-optimism/contracts@0.4.0
- - @eth-optimism/core-utils@0.4.6
- - @eth-optimism/common-ts@0.1.4
-
-## 0.3.5
-
-### Patch Changes
-
-- 7cce55a9: Add status to generic error log to disambiguate errors
-
-## 0.3.4
-
-### Patch Changes
-
-- baa3b761: Improve Sentry support, initializing as needed and ensuring ERROR logs route to Sentry
-- cc742715: Fix typo in USE_HARDHAT config
-- 98b7839f: Change monotonicity band-aid code to log warnings not errors
-- c520100d: Fix a bug in fixMonotonicity auto healer
-- 85362d44: Log additional data in monotonicity violation
-- Updated dependencies [baa3b761]
- - @eth-optimism/common-ts@0.1.3
-
-## 0.3.3
-
-### Patch Changes
-
-- 750a5021: Remove dead imports from core-utils
-- Updated dependencies [a64f8161]
-- Updated dependencies [4e03f8a9]
-- Updated dependencies [8e2bfd07]
-- Updated dependencies [750a5021]
-- Updated dependencies [c2b6e14b]
-- Updated dependencies [245136f1]
- - @eth-optimism/core-utils@0.4.5
- - @eth-optimism/contracts@0.3.5
-
-## 0.3.2
-
-### Patch Changes
-
-- 4340bb1: Fix: correctly read Batch Submitter env var defaults
-
-## 0.3.1
-
-### Patch Changes
-
-- c79dc8b: Add impersonate account debug config.
-- 0c16805: add metrics server to common-ts and batch submitter
-- fa4898a: Explicitly log error messages so that they do not show as empty objects
-- 96a586e: Updates the configuration to use bcfg in a backwards compatible way
-- c79dc8b: Make BLOCK_OFFSET configurable.
-- Updated dependencies [96a586e]
-- Updated dependencies [0c16805]
-- Updated dependencies [775118a]
- - @eth-optimism/core-utils@0.4.3
- - @eth-optimism/common-ts@0.1.2
- - @eth-optimism/contracts@0.3.1
-
-## 0.3.0
-
-### Minor Changes
-
-- b799caa: Updates to use RLP encoded transactions in batches for the `v0.3.0` release
-
-### Patch Changes
-
-- 751e2be: Add the support for different sequencer & proposer keys in the batch submitter.
-- Updated dependencies [b799caa]
-- Updated dependencies [6132e7a]
-- Updated dependencies [b799caa]
-- Updated dependencies [b799caa]
-- Updated dependencies [b799caa]
-- Updated dependencies [20747fd]
-- Updated dependencies [b799caa]
-- Updated dependencies [b799caa]
- - @eth-optimism/contracts@0.3.0
- - @eth-optimism/core-utils@0.4.2
-
-## 0.2.5
-
-### Patch Changes
-
-- 1d40586: Removed various unused dependencies
-- Updated dependencies [1d40586]
-- Updated dependencies [ce7fa52]
-- Updated dependencies [575bcf6]
-- Updated dependencies [6dc1877]
- - @eth-optimism/common-ts@0.1.1
- - @eth-optimism/contracts@0.2.10
- - @eth-optimism/core-utils@0.4.1
-
-## 0.2.4
-
-### Patch Changes
-
-- 12dbd81: add key metrics to batch submitter
-- 28dc442: move metrics, logger, and base-service to new common-ts package
-- 79df44e: Add skipped deposit auto heal
-- Updated dependencies [28dc442]
-- Updated dependencies [d2091d4]
-- Updated dependencies [a0a0052]
-- Updated dependencies [0ef3069]
- - @eth-optimism/common-ts@0.1.0
- - @eth-optimism/core-utils@0.4.0
- - @eth-optimism/contracts@0.2.9
-
-## 0.2.3
-
-### Patch Changes
-
-- 6daa408: update hardhat versions so that solc is resolved correctly
-- dee74ef: migrate batch submitter types to core-utils
-- d64b66d: reformat error context for Sentry
-- Updated dependencies [6daa408]
-- Updated dependencies [ea4041b]
-- Updated dependencies [f1f5bf2]
-- Updated dependencies [dee74ef]
-- Updated dependencies [9ec3ec0]
-- Updated dependencies [d64b66d]
-- Updated dependencies [5f376ee]
-- Updated dependencies [eef1df4]
-- Updated dependencies [a76cde5]
-- Updated dependencies [e713cd0]
-- Updated dependencies [572dcbc]
-- Updated dependencies [6014ec0]
- - @eth-optimism/contracts@0.2.8
- - @eth-optimism/core-utils@0.3.2
-
-## 0.2.2
-
-### Patch Changes
-
-- 6d31324: Update release tag for Sentry compatability
-- a2f6e83: add default metrics to all batch submitters
-
-## 0.2.1
-
-### Patch Changes
-
-- ab285e4: properly start the batch submitter instead of instantly exiting
-
-## 0.2.0
-
-### Minor Changes
-
-- 5077441: - Use raw transaction in batch submitter -- incompatible with L2Geth v0.1.2.1
- - Pass through raw transaction in l2context
-
-### Patch Changes
-
-- a3dc553: Adds a release version to batch-submitter and data-transport-layer usage of Sentry
-- b95dc22: log errors for monotonicity violations
-- c7bc0ce: Correctly formatted error object to log exceptions
-- Updated dependencies [ce5d596]
-- Updated dependencies [1a55f64]
-- Updated dependencies [6e8fe1b]
-- Updated dependencies [8d4aae4]
-- Updated dependencies [c75a0fc]
-- Updated dependencies [d4ee2d7]
-- Updated dependencies [edb4346]
-- Updated dependencies [5077441]
- - @eth-optimism/contracts@0.2.6
- - @eth-optimism/core-utils@0.3.1
-
-## 0.1.12
-
-### Patch Changes
-
-- a0a7956: initialize Sentry and streams in Logger, remove Sentry from Batch Submitter
-- Updated dependencies [91460d9]
-- Updated dependencies [a0a7956]
-- Updated dependencies [0497d7d]
- - @eth-optimism/core-utils@0.3.0
- - @eth-optimism/contracts@0.2.5
-
-## 0.1.11
-
-### Patch Changes
-
-- 35b99b0: add Sentry to TypeScript services for error tracking
-- Updated dependencies [35b99b0]
- - @eth-optimism/core-utils@0.2.3
-
-## 0.1.10
-
-### Patch Changes
-
-- 962e31b: removed unused l1 block number logic, added debug logging to batch submitter
-
-## 0.1.9
-
-### Patch Changes
-
-- 3b00b7c: bump private package versions to try triggering a tag
-
-## 0.1.8
-
-### Patch Changes
-
-- 6cbc54d: allow injecting L2 transaction and block context via core-utils (this removes the need to import the now deprecated @eth-optimism/provider package)
-- Updated dependencies [6cbc54d]
- - @eth-optimism/core-utils@0.2.0
- - @eth-optimism/contracts@0.2.2
-
-## v0.1.3
-
-- Add tx resubmission logic
-- Log when the batch submitter runs low on ETH
-
-## v0.1.2
-
-Adds mnemonic config parsing
-
-## v0.1.1
-
-Final fixes before minnet release.
-
-- Add batch submission timeout
-- Log sequencer address
-- remove ssh
-
-## v0.1.0
-
-The inital release
diff --git a/packages/batch-submitter/LICENSE b/packages/batch-submitter/LICENSE
deleted file mode 100644
index 6a7da5218bb25..0000000000000
--- a/packages/batch-submitter/LICENSE
+++ /dev/null
@@ -1,22 +0,0 @@
-(The MIT License)
-
-Copyright 2020-2021 Optimism
-
-Permission is hereby granted, free of charge, to any person obtaining
-a copy of this software and associated documentation files (the
-"Software"), to deal in the Software without restriction, including
-without limitation the rights to use, copy, modify, merge, publish,
-distribute, sublicense, and/or sell copies of the Software, and to
-permit persons to whom the Software is furnished to do so, subject to
-the following conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
-IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
-TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
-SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/packages/batch-submitter/README.md b/packages/batch-submitter/README.md
deleted file mode 100644
index 1a8f5ad3e241b..0000000000000
--- a/packages/batch-submitter/README.md
+++ /dev/null
@@ -1,45 +0,0 @@
-[](https://codecov.io/gh/ethereum-optimism/optimism)
-# Batch Submitter
-
-Contains an executable batch submitter service which watches L1 and a local L2 node and submits batches to the
-`CanonicalTransactionChain` & `StateCommitmentChain` based on its local information.
-
-## Configuration
-All configuration is done via environment variables. See all variables at [.env.example](.env.example); copy into a `.env` file before running.
-
-## Building & Running
-1. Make sure dependencies are installed just run `yarn` in the base directory
-2. Build `yarn build`
-3. Run `yarn start`
-
-## Controlling log output verbosity
-Before running, set the `DEBUG` environment variable to specify the verbosity level. It must be made up of comma-separated values of patterns to match in debug logs. Here's a few common options:
-* `debug*` - Will match all debug statements -- very verbose
-* `info*` - Will match all info statements -- less verbose, useful in most cases
-* `warn*` - Will match all warnings -- recommended at a minimum
-* `error*` - Will match all errors -- would not omit this
-
-Examples:
-* Everything but debug: `export DEBUG=info*,error*,warn*`
-* Most verbose: `export DEBUG=info*,error*,warn*,debug*`
-
-## Testing & linting
-
-### Local
-
-- Run unit tests with `yarn test`
-- See lint errors with `yarn lint`; auto-fix with `yarn lint --fix`
-
-### Submission
-
-You may test a submission locally against a local Hardhat fork.
-
-1. Follow the instructions [here](https://github.com/ethereum-optimism/hardhat) to run a Hardhat node.
-2. Change the Batch Submitter `.env` field `L1_NODE_WEB3_URL` to the local Hardhat url. Depending on which network you are using, update `ADDRESS_MANAGER_ADDRESS` according to the [Regenesis repo](https://github.com/ethereum-optimism/regenesis).
-3. Also check `L2_NODE_WEB3_URL` is correctly set and has transactions to submit.
-3. Run `yarn build` to build your changes.
-4. Start Batch Submitter with `yarn start`. It will automatically start submitting pending transactions from L2.
-
-## Observability in production
-
-When deploying Batch Submitter to production / a live ETH network, populate the environment variables `NODE_ENV` (`development`, `production`, or `test`) and `ETH_NETWORK_NAME` (`mainnet`, `kovan`, `goerli`). This enables Batch Submitter to capture more context in logs and metrics, and initializes [Sentry](https://docs.sentry.io/platforms/node/) to track errors.
diff --git a/packages/batch-submitter/exec/run-batch-submitter.js b/packages/batch-submitter/exec/run-batch-submitter.js
deleted file mode 100755
index 4241cf3e5aee1..0000000000000
--- a/packages/batch-submitter/exec/run-batch-submitter.js
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/usr/bin/env node
-
-const batchSubmitter = require('../dist/src/exec/run-batch-submitter')
-
-batchSubmitter.run()
diff --git a/packages/batch-submitter/hardhat.config.ts b/packages/batch-submitter/hardhat.config.ts
deleted file mode 100644
index b49f641649589..0000000000000
--- a/packages/batch-submitter/hardhat.config.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import '@nomiclabs/hardhat-waffle'
-import { HardhatUserConfig } from 'hardhat/config'
-
-import {
- DEFAULT_ACCOUNTS_HARDHAT,
- RUN_OVM_TEST_GAS,
-} from './test/helpers/constants'
-
-import '@nomiclabs/hardhat-ethers'
-
-const config: HardhatUserConfig = {
- networks: {
- hardhat: {
- accounts: DEFAULT_ACCOUNTS_HARDHAT,
- blockGasLimit: RUN_OVM_TEST_GAS * 2,
- },
- },
- mocha: {
- timeout: 50000,
- },
- solidity: {
- version: '0.7.0',
- settings: {
- optimizer: {
- enabled: true,
- runs: 200,
- },
- metadata: {
- bytecodeHash: 'none',
- },
- outputSelection: {
- '*': {
- '*': ['metadata', 'storageLayout'],
- },
- },
- },
- },
-}
-
-export default config
diff --git a/packages/batch-submitter/index.ts b/packages/batch-submitter/index.ts
deleted file mode 100644
index 4627ee1cefffb..0000000000000
--- a/packages/batch-submitter/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-const rootPath = __dirname
-
-export { rootPath }
diff --git a/packages/batch-submitter/package.json b/packages/batch-submitter/package.json
deleted file mode 100644
index 17abede61036e..0000000000000
--- a/packages/batch-submitter/package.json
+++ /dev/null
@@ -1,90 +0,0 @@
-{
- "private": true,
- "name": "@eth-optimism/batch-submitter",
- "version": "0.4.20",
- "description": "[Optimism] Service for submitting transactions and transaction results",
- "main": "dist/index",
- "types": "dist/index",
- "files": [
- "dist/*"
- ],
- "scripts": {
- "start": "node ./exec/run-batch-submitter.js",
- "build": "tsc -p ./tsconfig.build.json",
- "clean": "rimraf cache/ dist/ ./tsconfig.build.tsbuildinfo",
- "lint": "yarn lint:fix && yarn lint:check",
- "pre-commit": "lint-staged",
- "lint:fix": "yarn lint:check --fix",
- "lint:check": "eslint . --max-warnings=0",
- "test": "hardhat test --show-stack-traces",
- "test:coverage": "nyc hardhat test && nyc merge .nyc_output coverage.json"
- },
- "keywords": [
- "optimism",
- "ethereum",
- "sequencer",
- "aggregator"
- ],
- "homepage": "https://github.com/ethereum-optimism/optimism/tree/develop/packages/batch-submitter#readme",
- "license": "MIT",
- "author": "Optimism PBC",
- "repository": {
- "type": "git",
- "url": "https://github.com/ethereum-optimism/optimism.git"
- },
- "dependencies": {
- "@eth-optimism/common-ts": "0.2.1",
- "@eth-optimism/contracts": "0.5.15",
- "@eth-optimism/core-utils": "0.8.0",
- "@eth-optimism/sdk": "^0.2.3",
- "@eth-optimism/ynatm": "^0.2.2",
- "@ethersproject/abstract-provider": "^5.5.1",
- "@ethersproject/providers": "^5.5.3",
- "@sentry/node": "^6.3.1",
- "bcfg": "^0.1.6",
- "bluebird": "^3.7.2",
- "dotenv": "^10.0.0",
- "ethers": "^5.5.4",
- "old-contracts": "npm:@eth-optimism/contracts@^0.0.2-alpha.7",
- "prom-client": "^13.1.0"
- },
- "devDependencies": {
- "@eth-optimism/smock": "1.1.10",
- "@nomiclabs/hardhat-ethers": "^2.0.2",
- "@nomiclabs/hardhat-waffle": "^2.0.1",
- "@types/bluebird": "^3.5.34",
- "@types/chai": "^4.2.18",
- "@types/mocha": "^8.2.2",
- "@types/node": "^15.12.2",
- "@types/sinon": "^9.0.10",
- "@types/sinon-chai": "^3.2.5",
- "@typescript-eslint/eslint-plugin": "^4.26.0",
- "@typescript-eslint/parser": "^4.26.0",
- "babel-eslint": "^10.1.0",
- "chai": "^4.3.4",
- "eslint": "^7.27.0",
- "eslint-config-prettier": "^8.3.0",
- "eslint-plugin-import": "^2.23.4",
- "eslint-plugin-jsdoc": "^35.1.2",
- "eslint-plugin-prefer-arrow": "^1.2.3",
- "eslint-plugin-prettier": "^3.4.0",
- "eslint-plugin-react": "^7.24.0",
- "eslint-plugin-unicorn": "^32.0.1",
- "ethereum-waffle": "^3.3.0",
- "hardhat": "^2.3.0",
- "lint-staged": "11.0.0",
- "mocha": "^8.4.0",
- "prettier": "^2.3.1",
- "rimraf": "^3.0.2",
- "sinon": "^9.2.4",
- "sinon-chai": "^3.5.0",
- "typescript": "^4.3.5"
- },
- "resolutions": {
- "ganache-core": "^2.13.2",
- "**/@sentry/node": "^6.2.5"
- },
- "publishConfig": {
- "access": "public"
- }
-}
diff --git a/packages/batch-submitter/src/batch-submitter/batch-submitter.ts b/packages/batch-submitter/src/batch-submitter/batch-submitter.ts
deleted file mode 100644
index 40418adcd0f76..0000000000000
--- a/packages/batch-submitter/src/batch-submitter/batch-submitter.ts
+++ /dev/null
@@ -1,305 +0,0 @@
-/* External Imports */
-import {
- Contract,
- Signer,
- utils,
- providers,
- PopulatedTransaction,
-} from 'ethers'
-import {
- TransactionReceipt,
- TransactionResponse,
-} from '@ethersproject/abstract-provider'
-import { Gauge, Histogram, Counter } from 'prom-client'
-import { RollupInfo, sleep } from '@eth-optimism/core-utils'
-import { Logger, Metrics } from '@eth-optimism/common-ts'
-import { getContractFactory } from 'old-contracts'
-
-/* Internal Imports */
-import { TxSubmissionHooks } from '..'
-
-export interface BlockRange {
- start: number
- end: number
-}
-
-interface BatchSubmitterMetrics {
- batchSubmitterETHBalance: Gauge
- batchSizeInBytes: Histogram
- numTxPerBatch: Histogram
- submissionTimestamp: Histogram
- submissionGasUsed: Histogram
- batchesSubmitted: Counter
- failedSubmissions: Counter
- malformedBatches: Counter
- batchTxBuildTime: Gauge
-}
-
-export abstract class BatchSubmitter {
- protected rollupInfo: RollupInfo
- protected chainContract: Contract
- protected l2ChainId: number
- protected syncing: boolean
- protected lastBatchSubmissionTimestamp: number = 0
- protected metrics: BatchSubmitterMetrics
-
- constructor(
- readonly signer: Signer,
- readonly l2Provider: providers.StaticJsonRpcProvider,
- readonly minTxSize: number,
- readonly maxTxSize: number,
- readonly maxBatchSize: number,
- readonly maxBatchSubmissionTime: number,
- readonly numConfirmations: number,
- readonly resubmissionTimeout: number,
- readonly finalityConfirmations: number,
- readonly addressManagerAddress: string,
- readonly minBalanceEther: number,
- readonly blockOffset: number,
- readonly logger: Logger,
- readonly defaultMetrics: Metrics
- ) {
- this.metrics = this._registerMetrics(defaultMetrics)
- }
-
- public abstract _submitBatch(
- startBlock: number,
- endBlock: number
- ): Promise
- public abstract _onSync(): Promise
- public abstract _getBatchStartAndEnd(): Promise
- public abstract _updateChainInfo(): Promise
-
- public async submitNextBatch(): Promise {
- if (typeof this.l2ChainId === 'undefined') {
- this.l2ChainId = await this._getL2ChainId()
- }
- await this._updateChainInfo()
-
- if (!(await this._hasEnoughETHToCoverGasCosts())) {
- await sleep(this.resubmissionTimeout)
- return
- }
-
- this.logger.info('Readying to submit next batch...', {
- l2ChainId: this.l2ChainId,
- batchSubmitterAddress: await this.signer.getAddress(),
- })
-
- if (this.syncing === true) {
- this.logger.info(
- 'Syncing mode enabled! Skipping batch submission and clearing queue...'
- )
- return this._onSync()
- }
- const range = await this._getBatchStartAndEnd()
- if (!range) {
- return
- }
-
- return this._submitBatch(range.start, range.end)
- }
-
- protected async _hasEnoughETHToCoverGasCosts(): Promise {
- const address = await this.signer.getAddress()
- const balance = await this.signer.getBalance()
- const ether = utils.formatEther(balance)
- const num = parseFloat(ether)
-
- this.logger.info('Checked balance', {
- address,
- ether,
- })
-
- this.metrics.batchSubmitterETHBalance.set(num)
-
- if (num < this.minBalanceEther) {
- this.logger.fatal('Current balance lower than min safe balance', {
- current: num,
- safeBalance: this.minBalanceEther,
- })
- return false
- }
-
- return true
- }
-
- protected async _getRollupInfo(): Promise {
- return this.l2Provider.send('rollup_getInfo', [])
- }
-
- protected async _getL2ChainId(): Promise {
- return this.l2Provider.send('eth_chainId', [])
- }
-
- protected async _getChainAddresses(): Promise<{
- ctcAddress: string
- sccAddress: string
- }> {
- const addressManager = (
- await getContractFactory('Lib_AddressManager', this.signer)
- ).attach(this.addressManagerAddress)
- const sccAddress = await addressManager.getAddress('StateCommitmentChain')
- const ctcAddress = await addressManager.getAddress(
- 'CanonicalTransactionChain'
- )
- return {
- ctcAddress,
- sccAddress,
- }
- }
-
- protected _shouldSubmitBatch(batchSizeInBytes: number): boolean {
- const currentTimestamp = Date.now()
- if (batchSizeInBytes < this.minTxSize) {
- const timeSinceLastSubmission =
- currentTimestamp - this.lastBatchSubmissionTimestamp
- if (timeSinceLastSubmission < this.maxBatchSubmissionTime) {
- this.logger.info(
- 'Skipping batch submission. Batch too small & max submission timeout not reached.',
- {
- batchSizeInBytes,
- timeSinceLastSubmission,
- maxBatchSubmissionTime: this.maxBatchSubmissionTime,
- minTxSize: this.minTxSize,
- lastBatchSubmissionTimestamp: this.lastBatchSubmissionTimestamp,
- currentTimestamp,
- }
- )
- return false
- }
- this.logger.info('Timeout reached, proceeding with batch submission.', {
- batchSizeInBytes,
- timeSinceLastSubmission,
- maxBatchSubmissionTime: this.maxBatchSubmissionTime,
- lastBatchSubmissionTimestamp: this.lastBatchSubmissionTimestamp,
- currentTimestamp,
- })
- this.metrics.batchSizeInBytes.observe(batchSizeInBytes)
- return true
- }
- this.logger.info(
- 'Sufficient batch size, proceeding with batch submission.',
- {
- batchSizeInBytes,
- lastBatchSubmissionTimestamp: this.lastBatchSubmissionTimestamp,
- currentTimestamp,
- }
- )
- this.metrics.batchSizeInBytes.observe(batchSizeInBytes)
- return true
- }
-
- protected _makeHooks(txName: string): TxSubmissionHooks {
- return {
- beforeSendTransaction: (tx: PopulatedTransaction) => {
- this.logger.info(`Submitting ${txName} transaction`, {
- gasPrice: tx.gasPrice,
- maxFeePerGas: tx.maxFeePerGas,
- maxPriorityFeePerGas: tx.maxPriorityFeePerGas,
- gasLimit: tx.gasLimit,
- nonce: tx.nonce,
- contractAddr: this.chainContract.address,
- })
- },
- onTransactionResponse: (txResponse: TransactionResponse) => {
- this.logger.info(`Submitted ${txName} transaction`, {
- txHash: txResponse.hash,
- from: txResponse.from,
- })
- this.logger.debug(`${txName} transaction data`, {
- data: txResponse.data,
- })
- },
- }
- }
-
- protected async _submitAndLogTx(
- submitTransaction: () => Promise,
- successMessage: string
- ): Promise {
- this.lastBatchSubmissionTimestamp = Date.now()
- this.logger.debug('Submitting transaction & waiting for receipt...')
-
- let receipt: TransactionReceipt
- try {
- receipt = await submitTransaction()
- } catch (err) {
- this.metrics.failedSubmissions.inc()
- if (err.reason) {
- this.logger.error(`Transaction invalid: ${err.reason}, aborting`, {
- message: err.toString(),
- stack: err.stack,
- code: err.code,
- })
- return
- }
-
- this.logger.error('Encountered error at submission, aborting', {
- message: err.toString(),
- stack: err.stack,
- code: err.code,
- })
- return
- }
-
- this.logger.info('Received transaction receipt', { receipt })
- this.logger.info(successMessage)
- this.metrics.batchesSubmitted.inc()
- this.metrics.submissionGasUsed.observe(receipt.gasUsed.toNumber())
- this.metrics.submissionTimestamp.observe(Date.now())
- return receipt
- }
-
- private _registerMetrics(metrics: Metrics): BatchSubmitterMetrics {
- metrics.registry.clear()
-
- return {
- batchSubmitterETHBalance: new metrics.client.Gauge({
- name: 'batch_submitter_eth_balance',
- help: 'ETH balance of the batch submitter',
- registers: [metrics.registry],
- }),
- batchSizeInBytes: new metrics.client.Histogram({
- name: 'batch_size_in_bytes',
- help: 'Size of batches in bytes',
- registers: [metrics.registry],
- }),
- numTxPerBatch: new metrics.client.Histogram({
- name: 'num_txs_per_batch',
- help: 'Number of transactions in each batch',
- registers: [metrics.registry],
- }),
- submissionTimestamp: new metrics.client.Histogram({
- name: 'submission_timestamp',
- help: 'Timestamp of each batch submitter submission',
- registers: [metrics.registry],
- }),
- submissionGasUsed: new metrics.client.Histogram({
- name: 'submission_gash_used',
- help: 'Gas used to submit each batch',
- registers: [metrics.registry],
- }),
- batchesSubmitted: new metrics.client.Counter({
- name: 'batches_submitted',
- help: 'Count of batches submitted',
- registers: [metrics.registry],
- }),
- failedSubmissions: new metrics.client.Counter({
- name: 'failed_submissions',
- help: 'Count of failed batch submissions',
- registers: [metrics.registry],
- }),
- malformedBatches: new metrics.client.Counter({
- name: 'malformed_batches',
- help: 'Count of malformed batches',
- registers: [metrics.registry],
- }),
- batchTxBuildTime: new metrics.client.Gauge({
- name: 'batch_tx_build_time',
- help: 'Time to construct batch transaction',
- registers: [metrics.registry],
- }),
- }
- }
-}
diff --git a/packages/batch-submitter/src/batch-submitter/index.ts b/packages/batch-submitter/src/batch-submitter/index.ts
deleted file mode 100644
index 0b96dc9a09d38..0000000000000
--- a/packages/batch-submitter/src/batch-submitter/index.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-export * from './batch-submitter'
-export * from './tx-batch-submitter'
-export * from './state-batch-submitter'
-
-export const TX_BATCH_SUBMITTER_LOG_TAG = 'oe:batch_submitter:tx_chain'
-export const STATE_BATCH_SUBMITTER_LOG_TAG = 'oe:batch_submitter:state_chain'
diff --git a/packages/batch-submitter/src/batch-submitter/state-batch-submitter.ts b/packages/batch-submitter/src/batch-submitter/state-batch-submitter.ts
deleted file mode 100644
index 15c452c52dbb4..0000000000000
--- a/packages/batch-submitter/src/batch-submitter/state-batch-submitter.ts
+++ /dev/null
@@ -1,253 +0,0 @@
-/* External Imports */
-import { performance } from 'perf_hooks'
-
-import { Promise as bPromise } from 'bluebird'
-import { Contract, Signer, providers } from 'ethers'
-import { TransactionReceipt } from '@ethersproject/abstract-provider'
-import { getContractFactory } from 'old-contracts'
-import {
- L2Block,
- RollupInfo,
- Bytes32,
- remove0x,
-} from '@eth-optimism/core-utils'
-import { Logger, Metrics } from '@eth-optimism/common-ts'
-
-/* Internal Imports */
-import { TransactionSubmitter } from '../utils'
-import { BlockRange, BatchSubmitter } from '.'
-
-export class StateBatchSubmitter extends BatchSubmitter {
- // TODO: Change this so that we calculate start = scc.totalElements() and end = ctc.totalElements()!
- // Not based on the length of the L2 chain -- that is only used in the batch submitter
- // Note this means we've got to change the state / end calc logic
-
- protected l2ChainId: number
- protected syncing: boolean
- protected ctcContract: Contract
- private fraudSubmissionAddress: string
- private transactionSubmitter: TransactionSubmitter
-
- constructor(
- signer: Signer,
- l2Provider: providers.StaticJsonRpcProvider,
- minTxSize: number,
- maxTxSize: number,
- maxBatchSize: number,
- maxBatchSubmissionTime: number,
- numConfirmations: number,
- resubmissionTimeout: number,
- finalityConfirmations: number,
- addressManagerAddress: string,
- minBalanceEther: number,
- transactionSubmitter: TransactionSubmitter,
- blockOffset: number,
- logger: Logger,
- metrics: Metrics,
- fraudSubmissionAddress: string
- ) {
- super(
- signer,
- l2Provider,
- minTxSize,
- maxTxSize,
- maxBatchSize,
- maxBatchSubmissionTime,
- numConfirmations,
- resubmissionTimeout,
- finalityConfirmations,
- addressManagerAddress,
- minBalanceEther,
- blockOffset,
- logger,
- metrics
- )
- this.fraudSubmissionAddress = fraudSubmissionAddress
- this.transactionSubmitter = transactionSubmitter
- }
-
- /*****************************
- * Batch Submitter Overrides *
- ****************************/
-
- public async _updateChainInfo(): Promise {
- const info: RollupInfo = await this._getRollupInfo()
- if (info.mode === 'verifier') {
- this.logger.error(
- 'Verifier mode enabled! Batch submitter only compatible with sequencer mode'
- )
- process.exit(1)
- }
- this.syncing = info.syncing
- const addrs = await this._getChainAddresses()
- const sccAddress = addrs.sccAddress
- const ctcAddress = addrs.ctcAddress
-
- if (
- typeof this.chainContract !== 'undefined' &&
- sccAddress === this.chainContract.address &&
- ctcAddress === this.ctcContract.address
- ) {
- this.logger.debug('Chain contract already initialized', {
- sccAddress,
- ctcAddress,
- })
- return
- }
-
- this.chainContract = (
- await getContractFactory('OVM_StateCommitmentChain', this.signer)
- ).attach(sccAddress)
- this.ctcContract = (
- await getContractFactory('OVM_CanonicalTransactionChain', this.signer)
- ).attach(ctcAddress)
-
- this.logger.info('Connected Optimism contracts', {
- stateCommitmentChain: this.chainContract.address,
- canonicalTransactionChain: this.ctcContract.address,
- })
- return
- }
-
- public async _onSync(): Promise {
- this.logger.info('Syncing mode enabled! Skipping state batch submission...')
- return
- }
-
- public async _getBatchStartAndEnd(): Promise {
- this.logger.info('Getting batch start and end for state batch submitter...')
- const startBlock: number =
- (await this.chainContract.getTotalElements()).toNumber() +
- this.blockOffset
- this.logger.info('Retrieved start block number from SCC', {
- startBlock,
- })
-
- // We will submit state roots for txs which have been in the tx chain for a while.
- const totalElements: number =
- (await this.ctcContract.getTotalElements()).toNumber() + this.blockOffset
- this.logger.info('Retrieved total elements from CTC', {
- totalElements,
- })
-
- const endBlock: number = Math.min(
- startBlock + this.maxBatchSize,
- totalElements
- )
-
- if (startBlock >= endBlock) {
- if (startBlock > endBlock) {
- this.logger.error(
- 'State commitment chain is larger than transaction chain. This should never happen!'
- )
- }
- this.logger.info(
- 'No state commitments to submit. Skipping batch submission...'
- )
- return
- }
- return {
- start: startBlock,
- end: endBlock,
- }
- }
-
- public async _submitBatch(
- startBlock: number,
- endBlock: number
- ): Promise {
- const batchTxBuildStart = performance.now()
-
- const batch = await this._generateStateCommitmentBatch(startBlock, endBlock)
- const calldata = this.chainContract.interface.encodeFunctionData(
- 'appendStateBatch',
- [batch, startBlock]
- )
- const batchSizeInBytes = remove0x(calldata).length / 2
- this.logger.debug('State batch generated', {
- batchSizeInBytes,
- calldata,
- })
-
- if (!this._shouldSubmitBatch(batchSizeInBytes)) {
- return
- }
-
- const batchTxBuildEnd = performance.now()
- this.metrics.batchTxBuildTime.set(batchTxBuildEnd - batchTxBuildStart)
-
- const offsetStartsAtIndex = startBlock - this.blockOffset
- this.logger.debug('Submitting batch.', { calldata })
-
- // Generate the transaction we will repeatedly submit
- const nonce = await this.signer.getTransactionCount()
- const tx = await this.chainContract.populateTransaction.appendStateBatch(
- batch,
- offsetStartsAtIndex,
- { nonce }
- )
- const submitTransaction = (): Promise => {
- return this.transactionSubmitter.submitTransaction(
- tx,
- this._makeHooks('appendStateBatch')
- )
- }
- return this._submitAndLogTx(
- submitTransaction,
- 'Submitted state root batch!'
- )
- }
-
- /*********************
- * Private Functions *
- ********************/
-
- private async _generateStateCommitmentBatch(
- startBlock: number,
- endBlock: number
- ): Promise {
- const blockRange = endBlock - startBlock
- const batch: Bytes32[] = await bPromise.map(
- [...Array(blockRange).keys()],
- async (i: number) => {
- this.logger.debug('Fetching L2BatchElement', {
- blockNo: startBlock + i,
- })
- const block = (await this.l2Provider.getBlockWithTransactions(
- startBlock + i
- )) as L2Block
- const blockTx = block.transactions[0]
- if (blockTx.from === this.fraudSubmissionAddress) {
- this.logger.warn('Found transaction from fraud submission address', {
- txHash: blockTx.hash,
- fraudSubmissionAddress: this.fraudSubmissionAddress,
- })
- this.fraudSubmissionAddress = 'no fraud'
- return '0xbad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1bad1'
- }
- return block.stateRoot
- },
- { concurrency: 100 }
- )
-
- let tx = this.chainContract.interface.encodeFunctionData(
- 'appendStateBatch',
- [batch, startBlock]
- )
- while (remove0x(tx).length / 2 > this.maxTxSize) {
- batch.splice(Math.ceil((batch.length * 2) / 3)) // Delete 1/3rd of all of the batch elements
- this.logger.debug('Splicing batch...', {
- batchSizeInBytes: tx.length / 2,
- })
- tx = this.chainContract.interface.encodeFunctionData('appendStateBatch', [
- batch,
- startBlock,
- ])
- }
-
- this.logger.info('Generated state commitment batch', {
- batch, // list of stateRoots
- })
- return batch
- }
-}
diff --git a/packages/batch-submitter/src/batch-submitter/tx-batch-submitter.ts b/packages/batch-submitter/src/batch-submitter/tx-batch-submitter.ts
deleted file mode 100644
index 60e73c85d8ae6..0000000000000
--- a/packages/batch-submitter/src/batch-submitter/tx-batch-submitter.ts
+++ /dev/null
@@ -1,803 +0,0 @@
-/* External Imports */
-import { performance } from 'perf_hooks'
-
-import { Promise as bPromise } from 'bluebird'
-import { Signer, ethers, Contract, providers } from 'ethers'
-import { TransactionReceipt } from '@ethersproject/abstract-provider'
-import { getContractInterface, getContractFactory } from 'old-contracts'
-import { getContractInterface as getNewContractInterface } from '@eth-optimism/contracts'
-import {
- L2Block,
- RollupInfo,
- BatchElement,
- Batch,
- QueueOrigin,
- BatchType,
-} from '@eth-optimism/core-utils'
-import { Logger, Metrics } from '@eth-optimism/common-ts'
-
-/* Internal Imports */
-import {
- CanonicalTransactionChainContract,
- encodeAppendSequencerBatch,
- BatchContext,
- AppendSequencerBatchParams,
-} from '../transaction-chain-contract'
-import { TransactionSubmitter } from '../utils'
-import { BlockRange, BatchSubmitter } from '.'
-
-export interface AutoFixBatchOptions {
- fixDoublePlayedDeposits: boolean
- fixMonotonicity: boolean
- fixSkippedDeposits: boolean
-}
-
-export class TransactionBatchSubmitter extends BatchSubmitter {
- protected chainContract: CanonicalTransactionChainContract
- protected l2ChainId: number
- protected syncing: boolean
- private autoFixBatchOptions: AutoFixBatchOptions
- private validateBatch: boolean
- private transactionSubmitter: TransactionSubmitter
- private gasThresholdInGwei: number
- private batchType: BatchType
-
- constructor(
- signer: Signer,
- l2Provider: providers.StaticJsonRpcProvider,
- minTxSize: number,
- maxTxSize: number,
- maxBatchSize: number,
- maxBatchSubmissionTime: number,
- numConfirmations: number,
- resubmissionTimeout: number,
- addressManagerAddress: string,
- minBalanceEther: number,
- gasThresholdInGwei: number,
- transactionSubmitter: TransactionSubmitter,
- blockOffset: number,
- validateBatch: boolean,
- logger: Logger,
- metrics: Metrics,
- autoFixBatchOptions: AutoFixBatchOptions = {
- fixDoublePlayedDeposits: false,
- fixMonotonicity: false,
- fixSkippedDeposits: false,
- }, // TODO: Remove this
- batchType: string
- ) {
- super(
- signer,
- l2Provider,
- minTxSize,
- maxTxSize,
- maxBatchSize,
- maxBatchSubmissionTime,
- numConfirmations,
- resubmissionTimeout,
- 0, // Supply dummy value because it is not used.
- addressManagerAddress,
- minBalanceEther,
- blockOffset,
- logger,
- metrics
- )
- this.validateBatch = validateBatch
- this.autoFixBatchOptions = autoFixBatchOptions
- this.gasThresholdInGwei = gasThresholdInGwei
- this.transactionSubmitter = transactionSubmitter
-
- if (batchType === 'legacy') {
- this.batchType = BatchType.LEGACY
- } else if (batchType === 'zlib') {
- this.batchType = BatchType.ZLIB
- } else {
- throw new Error(`Invalid batch type: ${batchType}`)
- }
-
- this.logger.info('Batch options', {
- autoFixBatchOptions,
- validateBatch,
- batchType: BatchType[this.batchType],
- })
- }
-
- /*****************************
- * Batch Submitter Overrides *
- ****************************/
-
- public async _updateChainInfo(): Promise {
- const info: RollupInfo = await this._getRollupInfo()
- if (info.mode === 'verifier') {
- this.logger.error(
- 'Verifier mode enabled! Batch submitter only compatible with sequencer mode'
- )
- process.exit(1)
- }
- this.syncing = info.syncing
- const addrs = await this._getChainAddresses()
- const ctcAddress = addrs.ctcAddress
-
- if (
- typeof this.chainContract !== 'undefined' &&
- ctcAddress === this.chainContract.address
- ) {
- this.logger.debug('Chain contract already initialized', {
- ctcAddress,
- })
- return
- }
-
- const unwrapped_OVM_CanonicalTransactionChain = (
- await getContractFactory('OVM_CanonicalTransactionChain', this.signer)
- ).attach(ctcAddress)
-
- this.chainContract = new CanonicalTransactionChainContract(
- unwrapped_OVM_CanonicalTransactionChain.address,
- getContractInterface('OVM_CanonicalTransactionChain'),
- this.signer
- )
- this.logger.info('Initialized new CTC', {
- address: this.chainContract.address,
- })
- return
- }
-
- public async _onSync(): Promise {
- const pendingQueueElements =
- await this.chainContract.getNumPendingQueueElements()
- this.logger.debug('Got number of pending queue elements', {
- pendingQueueElements,
- })
-
- if (pendingQueueElements !== 0) {
- this.logger.info(
- 'Syncing mode enabled! Skipping batch submission and clearing queue elements',
- { pendingQueueElements }
- )
- }
-
- this.logger.info('Syncing mode enabled but queue is empty. Skipping...')
- return
- }
-
- public async _getBatchStartAndEnd(): Promise {
- this.logger.info(
- 'Getting batch start and end for transaction batch submitter...'
- )
- const startBlock =
- (await this.chainContract.getTotalElements()).toNumber() +
- this.blockOffset
- this.logger.info('Retrieved start block number from CTC', {
- startBlock,
- })
-
- const endBlock =
- Math.min(
- startBlock + this.maxBatchSize,
- await this.l2Provider.getBlockNumber()
- ) + 1 // +1 because the `endBlock` is *exclusive*
- this.logger.info('Retrieved end block number from L2 sequencer', {
- endBlock,
- })
-
- if (startBlock >= endBlock) {
- if (startBlock > endBlock) {
- this.logger
- .error(`More chain elements in L1 (${startBlock}) than in the L2 node (${endBlock}).
- This shouldn't happen because we don't submit batches if the sequencer is syncing.`)
- }
- this.logger.info('No txs to submit. Skipping batch submission...')
- return
- }
- return {
- start: startBlock,
- end: endBlock,
- }
- }
-
- public async _submitBatch(
- startBlock: number,
- endBlock: number
- ): Promise {
- // Do not submit batch if gas price above threshold
- const gasPriceInGwei = parseInt(
- ethers.utils.formatUnits(await this.signer.getGasPrice(), 'gwei'),
- 10
- )
- if (gasPriceInGwei > this.gasThresholdInGwei) {
- this.logger.warn(
- 'Gas price is higher than gas price threshold; aborting batch submission',
- {
- gasPriceInGwei,
- gasThresholdInGwei: this.gasThresholdInGwei,
- }
- )
- return
- }
-
- const batchTxBuildStart = performance.now()
-
- const params = await this._generateSequencerBatchParams(
- startBlock,
- endBlock
- )
- if (!params) {
- throw new Error(
- `Cannot create sequencer batch with params start ${startBlock} and end ${endBlock}`
- )
- }
-
- const [batchParams, wasBatchTruncated] = params
- const batchSizeInBytes = encodeAppendSequencerBatch(batchParams).length / 2
- this.logger.debug('Sequencer batch generated', {
- batchSizeInBytes,
- })
-
- // Only submit batch if one of the following is true:
- // 1. it was truncated
- // 2. it is large enough
- // 3. enough time has passed since last submission
- if (!wasBatchTruncated && !this._shouldSubmitBatch(batchSizeInBytes)) {
- return
- }
-
- const batchTxBuildEnd = performance.now()
- this.metrics.batchTxBuildTime.set(batchTxBuildEnd - batchTxBuildStart)
-
- this.metrics.numTxPerBatch.observe(batchParams.totalElementsToAppend)
- const l1tipHeight = await this.signer.provider.getBlockNumber()
- this.logger.debug('Submitting batch.', {
- calldata: batchParams,
- l1tipHeight,
- })
-
- return this.submitAppendSequencerBatch(batchParams)
- }
-
- /*********************
- * Private Functions *
- ********************/
-
- private async submitAppendSequencerBatch(
- batchParams: AppendSequencerBatchParams
- ): Promise {
- const tx =
- await this.chainContract.customPopulateTransaction.appendSequencerBatch(
- batchParams
- )
- const submitTransaction = (): Promise => {
- return this.transactionSubmitter.submitTransaction(
- tx,
- this._makeHooks('appendSequencerBatch')
- )
- }
- return this._submitAndLogTx(submitTransaction, 'Submitted batch!')
- }
-
- private async _generateSequencerBatchParams(
- startBlock: number,
- endBlock: number
- ): Promise<[AppendSequencerBatchParams, boolean]> {
- // Get all L2 BatchElements for the given range
- const blockRange = endBlock - startBlock
- let batch: Batch = await bPromise.map(
- [...Array(blockRange).keys()],
- (i) => {
- this.logger.debug('Fetching L2BatchElement', {
- blockNo: startBlock + i,
- })
- return this._getL2BatchElement(startBlock + i)
- },
- { concurrency: 100 }
- )
-
- // Fix our batches if we are configured to. This will not
- // modify the batch unless an autoFixBatchOption is set
- batch = await this._fixBatch(batch)
- if (this.validateBatch) {
- this.logger.info('Validating batch')
- if (!(await this._validateBatch(batch))) {
- this.metrics.malformedBatches.inc()
- return
- }
- }
-
- let sequencerBatchParams = await this._getSequencerBatchParams(
- startBlock,
- batch
- )
-
- let wasBatchTruncated = false
- let encoded = encodeAppendSequencerBatch(sequencerBatchParams)
- while (encoded.length / 2 > this.maxTxSize) {
- this.logger.debug('Splicing batch...', {
- batchSizeInBytes: encoded.length / 2,
- })
- batch.splice(Math.ceil((batch.length * 2) / 3)) // Delete 1/3rd of all of the batch elements
- sequencerBatchParams = await this._getSequencerBatchParams(
- startBlock,
- batch
- )
- encoded = encodeAppendSequencerBatch(sequencerBatchParams)
- // This is to prevent against the case where a batch is oversized,
- // but then gets truncated to the point where it is under the minimum size.
- // In this case, we want to submit regardless of the batch's size.
- wasBatchTruncated = true
- }
-
- // Set the batch type so that it is serialized correctly
- sequencerBatchParams.type = this.batchType
-
- this.logger.info('Generated sequencer batch params', {
- contexts: sequencerBatchParams.contexts,
- transactions: sequencerBatchParams.transactions,
- wasBatchTruncated,
- type: BatchType[sequencerBatchParams.type],
- })
- return [sequencerBatchParams, wasBatchTruncated]
- }
-
- /**
- * Returns true if the batch is valid.
- */
- protected async _validateBatch(batch: Batch): Promise {
- // Verify all of the queue elements are what we expect
- let nextQueueIndex = await this.chainContract.getNextQueueIndex()
- for (const ele of batch) {
- this.logger.debug('Verifying batch element', { ele })
- if (!ele.isSequencerTx) {
- this.logger.debug('Checking queue equality against L1 queue index', {
- nextQueueIndex,
- })
- if (!(await this._doesQueueElementMatchL1(nextQueueIndex, ele))) {
- return false
- }
- nextQueueIndex++
- }
- }
-
- // Verify all of the batch elements are monotonic
- let lastTimestamp: number
- let lastBlockNumber: number
- for (const [idx, ele] of batch.entries()) {
- if (ele.timestamp < lastTimestamp) {
- this.logger.error('Timestamp monotonicity violated! Element', {
- idx,
- ele,
- })
- return false
- }
- if (ele.blockNumber < lastBlockNumber) {
- this.logger.error('Block Number monotonicity violated! Element', {
- idx,
- ele,
- })
- return false
- }
- lastTimestamp = ele.timestamp
- lastBlockNumber = ele.blockNumber
- }
- return true
- }
-
- private async _doesQueueElementMatchL1(
- queueIndex: number,
- queueElement: BatchElement
- ): Promise {
- const logEqualityError = (name, index, expected, got) => {
- this.logger.error('Observed mismatched values', {
- index,
- expected,
- got,
- })
- }
-
- let isEqual = true
- const [, timestamp, blockNumber] = await this.chainContract.getQueueElement(
- queueIndex
- )
-
- // TODO: Verify queue element hash equality. The queue element hash can be computed with:
- // keccak256( abi.encode( msg.sender, _target, _gasLimit, _data))
-
- // Check timestamp & blockNumber equality
- if (timestamp !== queueElement.timestamp) {
- isEqual = false
- logEqualityError(
- 'Timestamp',
- queueIndex,
- timestamp,
- queueElement.timestamp
- )
- }
- if (blockNumber !== queueElement.blockNumber) {
- isEqual = false
- logEqualityError(
- 'Block Number',
- queueIndex,
- blockNumber,
- queueElement.blockNumber
- )
- }
- return isEqual
- }
-
- /**
- * Takes in a batch which is potentially malformed & returns corrected version.
- * Current fixes that are supported:
- * - Double played deposits.
- */
- private async _fixBatch(batch: Batch): Promise {
- const fixDoublePlayedDeposits = async (b: Batch): Promise => {
- let nextQueueIndex = await this.chainContract.getNextQueueIndex()
- const fixedBatch: Batch = []
- for (const ele of b) {
- if (!ele.isSequencerTx) {
- if (!(await this._doesQueueElementMatchL1(nextQueueIndex, ele))) {
- this.logger.warn('Fixing double played queue element.', {
- nextQueueIndex,
- })
- fixedBatch.push(
- await this._fixDoublePlayedDepositQueueElement(
- nextQueueIndex,
- ele
- )
- )
- continue
- }
- nextQueueIndex++
- }
- fixedBatch.push(ele)
- }
- return fixedBatch
- }
-
- const fixSkippedDeposits = async (b: Batch): Promise => {
- this.logger.debug('Fixing skipped deposits...')
- let nextQueueIndex = await this.chainContract.getNextQueueIndex()
- const fixedBatch: Batch = []
- for (const ele of b) {
- // Look for skipped deposits
- while (true) {
- const pendingQueueElements =
- await this.chainContract.getNumPendingQueueElements()
- const nextRemoteQueueElements =
- await this.chainContract.getNextQueueIndex()
- const totalQueueElements =
- pendingQueueElements + nextRemoteQueueElements
- // No more queue elements so we clearly haven't skipped anything
- if (nextQueueIndex >= totalQueueElements) {
- break
- }
- const [, timestamp, blockNumber] =
- await this.chainContract.getQueueElement(nextQueueIndex)
-
- if (timestamp < ele.timestamp || blockNumber < ele.blockNumber) {
- this.logger.warn('Fixing skipped deposit', {
- badTimestamp: ele.timestamp,
- skippedQueueTimestamp: timestamp,
- badBlockNumber: ele.blockNumber,
- skippedQueueBlockNumber: blockNumber,
- })
- // Push a dummy queue element
- fixedBatch.push({
- stateRoot: ele.stateRoot,
- isSequencerTx: false,
- rawTransaction: undefined,
- timestamp,
- blockNumber,
- })
- nextQueueIndex++
- } else {
- // The next queue element's timestamp is after this batch element so
- // we must not have skipped anything.
- break
- }
- }
- fixedBatch.push(ele)
- if (!ele.isSequencerTx) {
- nextQueueIndex++
- }
- }
- return fixedBatch
- }
-
- // TODO: Remove this super complex logic and rely on Geth to actually supply correct block data.
- const fixMonotonicity = async (b: Batch): Promise => {
- this.logger.debug('Fixing monotonicity...')
- // The earliest allowed timestamp/blockNumber is the last timestamp submitted on chain.
- const { lastTimestamp, lastBlockNumber } =
- await this._getLastTimestampAndBlockNumber()
- let earliestTimestamp = lastTimestamp
- let earliestBlockNumber = lastBlockNumber
- this.logger.debug('Determined earliest timestamp and blockNumber', {
- earliestTimestamp,
- earliestBlockNumber,
- })
-
- // The latest allowed timestamp/blockNumber is the next queue element!
- let nextQueueIndex = await this.chainContract.getNextQueueIndex()
- let latestTimestamp: number
- let latestBlockNumber: number
-
- // updateLatestTimestampAndBlockNumber is a helper which updates
- // the latest timestamp and block number based on the pending queue elements.
- const updateLatestTimestampAndBlockNumber = async () => {
- const pendingQueueElements =
- await this.chainContract.getNumPendingQueueElements()
- const nextRemoteQueueElements =
- await this.chainContract.getNextQueueIndex()
- const totalQueueElements =
- pendingQueueElements + nextRemoteQueueElements
- if (nextQueueIndex < totalQueueElements) {
- const [, queueTimestamp, queueBlockNumber] =
- await this.chainContract.getQueueElement(nextQueueIndex)
- latestTimestamp = queueTimestamp
- latestBlockNumber = queueBlockNumber
- } else {
- // If there are no queue elements left then just allow any timestamp/blocknumber
- latestTimestamp = Number.MAX_SAFE_INTEGER
- latestBlockNumber = Number.MAX_SAFE_INTEGER
- }
- }
- // Actually update the latest timestamp and block number
- await updateLatestTimestampAndBlockNumber()
- this.logger.debug('Determined latest timestamp and blockNumber', {
- latestTimestamp,
- latestBlockNumber,
- })
-
- // Now go through our batch and fix the timestamps and block numbers
- // to automatically enforce monotonicity.
- const fixedBatch: Batch = []
- for (const ele of b) {
- if (!ele.isSequencerTx) {
- // Set the earliest allowed timestamp to the old latest and set the new latest
- // to the next queue element's timestamp / blockNumber
- earliestTimestamp = latestTimestamp
- earliestBlockNumber = latestBlockNumber
- nextQueueIndex++
- await updateLatestTimestampAndBlockNumber()
- }
- // Fix the element if its timestammp/blockNumber is too small
- if (
- ele.timestamp < earliestTimestamp ||
- ele.blockNumber < earliestBlockNumber
- ) {
- this.logger.warn('Fixing timestamp/blockNumber too small', {
- oldTimestamp: ele.timestamp,
- newTimestamp: earliestTimestamp,
- oldBlockNumber: ele.blockNumber,
- newBlockNumber: earliestBlockNumber,
- })
- ele.timestamp = earliestTimestamp
- ele.blockNumber = earliestBlockNumber
- }
- // Fix the element if its timestammp/blockNumber is too large
- if (
- ele.timestamp > latestTimestamp ||
- ele.blockNumber > latestBlockNumber
- ) {
- this.logger.warn('Fixing timestamp/blockNumber too large.', {
- oldTimestamp: ele.timestamp,
- newTimestamp: latestTimestamp,
- oldBlockNumber: ele.blockNumber,
- newBlockNumber: latestBlockNumber,
- })
- ele.timestamp = latestTimestamp
- ele.blockNumber = latestBlockNumber
- }
- earliestTimestamp = ele.timestamp
- earliestBlockNumber = ele.blockNumber
- fixedBatch.push(ele)
- }
- return fixedBatch
- }
-
- // NOTE: It is unsafe to combine multiple autoFix options.
- // If you must combine them, manually verify the output before proceeding.
- if (this.autoFixBatchOptions.fixDoublePlayedDeposits) {
- this.logger.info('Fixing double played deposits')
- batch = await fixDoublePlayedDeposits(batch)
- }
- if (this.autoFixBatchOptions.fixMonotonicity) {
- this.logger.info('Fixing monotonicity')
- batch = await fixMonotonicity(batch)
- }
- if (this.autoFixBatchOptions.fixSkippedDeposits) {
- this.logger.info('Fixing skipped deposits')
- batch = await fixSkippedDeposits(batch)
- }
- return batch
- }
-
- private async _getLastTimestampAndBlockNumber(): Promise<{
- lastTimestamp: number
- lastBlockNumber: number
- }> {
- const manager = new Contract(
- this.addressManagerAddress,
- getNewContractInterface('Lib_AddressManager'),
- this.signer.provider
- )
-
- const addr = await manager.getAddress('ChainStorageContainer-CTC-batches')
-
- const container = new Contract(
- addr,
- getNewContractInterface('IChainStorageContainer'),
- this.signer.provider
- )
-
- let meta = await container.getGlobalMetadata()
- // remove 0x
- meta = meta.slice(2)
- // convert to bytes27
- meta = meta.slice(10)
-
- const lastTimestamp = parseInt(meta.slice(-30, -20), 16)
- const lastBlockNumber = parseInt(meta.slice(-40, -30), 16)
- this.logger.debug('Retrieved timestamp and block number from CTC', {
- lastTimestamp,
- lastBlockNumber,
- })
-
- return { lastTimestamp, lastBlockNumber }
- }
-
- private async _fixDoublePlayedDepositQueueElement(
- queueIndex: number,
- queueElement: BatchElement
- ): Promise {
- const [, timestamp, blockNumber] = await this.chainContract.getQueueElement(
- queueIndex
- )
-
- if (
- timestamp > queueElement.timestamp &&
- blockNumber > queueElement.blockNumber
- ) {
- this.logger.warn(
- 'Double deposit detected. Fixing by skipping the deposit & replacing with a dummy tx.',
- {
- timestamp,
- blockNumber,
- queueElementTimestamp: queueElement.timestamp,
- queueElementBlockNumber: queueElement.blockNumber,
- }
- )
- const dummyTx: string = '0x1234'
- return {
- stateRoot: queueElement.stateRoot,
- isSequencerTx: true,
- rawTransaction: dummyTx,
- timestamp: queueElement.timestamp,
- blockNumber: queueElement.blockNumber,
- }
- }
- if (
- timestamp < queueElement.timestamp &&
- blockNumber < queueElement.blockNumber
- ) {
- this.logger.error('A deposit seems to have been skipped!')
- throw new Error('Skipped deposit?!')
- }
- throw new Error('Unable to fix queue element!')
- }
-
- private async _getSequencerBatchParams(
- shouldStartAtIndex: number,
- blocks: Batch
- ): Promise {
- const totalElementsToAppend = blocks.length
-
- // Generate contexts
- const contexts: BatchContext[] = []
- let lastBlockIsSequencerTx = false
- let lastTimestamp = 0
- let lastBlockNumber = 0
- const groupedBlocks: Array<{
- sequenced: BatchElement[]
- queued: BatchElement[]
- }> = []
- for (const block of blocks) {
- // Create a new context in certain situations
- if (
- // If there are no contexts yet, create a new context.
- groupedBlocks.length === 0 ||
- // If the last block was an L1 to L2 transaction, but the next block is a Sequencer
- // transaction, create a new context.
- (lastBlockIsSequencerTx === false && block.isSequencerTx === true) ||
- // If the timestamp of the last block differs from the timestamp of the current block,
- // create a new context. Applies to both L1 to L2 transactions and Sequencer transactions.
- block.timestamp !== lastTimestamp ||
- // If the block number of the last block differs from the block number of the current block,
- // create a new context. ONLY applies to Sequencer transactions.
- (block.blockNumber !== lastBlockNumber && block.isSequencerTx === true)
- ) {
- groupedBlocks.push({
- sequenced: [],
- queued: [],
- })
- }
-
- const cur = groupedBlocks.length - 1
- block.isSequencerTx
- ? groupedBlocks[cur].sequenced.push(block)
- : groupedBlocks[cur].queued.push(block)
- lastBlockIsSequencerTx = block.isSequencerTx
- lastTimestamp = block.timestamp
- lastBlockNumber = block.blockNumber
- }
- for (const groupedBlock of groupedBlocks) {
- if (
- groupedBlock.sequenced.length === 0 &&
- groupedBlock.queued.length === 0
- ) {
- throw new Error(
- 'Attempted to generate batch context with 0 queued and 0 sequenced txs!'
- )
- }
- contexts.push({
- numSequencedTransactions: groupedBlock.sequenced.length,
- numSubsequentQueueTransactions: groupedBlock.queued.length,
- timestamp:
- groupedBlock.sequenced.length > 0
- ? groupedBlock.sequenced[0].timestamp
- : groupedBlock.queued[0].timestamp,
- blockNumber:
- groupedBlock.sequenced.length > 0
- ? groupedBlock.sequenced[0].blockNumber
- : groupedBlock.queued[0].blockNumber,
- })
- }
-
- // Generate sequencer transactions
- const transactions: string[] = []
- for (const block of blocks) {
- if (!block.isSequencerTx) {
- continue
- }
- transactions.push(block.rawTransaction)
- }
-
- return {
- shouldStartAtElement: shouldStartAtIndex - this.blockOffset,
- totalElementsToAppend,
- contexts,
- transactions,
- }
- }
-
- private async _getL2BatchElement(blockNumber: number): Promise {
- const block = await this._getBlock(blockNumber)
- this.logger.debug('Fetched L2 block', {
- block,
- })
-
- const batchElement = {
- stateRoot: block.stateRoot,
- timestamp: block.timestamp,
- blockNumber: block.transactions[0].l1BlockNumber,
- isSequencerTx: false,
- rawTransaction: undefined,
- }
-
- if (this._isSequencerTx(block)) {
- batchElement.isSequencerTx = true
- batchElement.rawTransaction = block.transactions[0].rawTransaction
- }
-
- return batchElement
- }
-
- private async _getBlock(blockNumber: number): Promise {
- const p = this.l2Provider.getBlockWithTransactions(blockNumber)
- return p as Promise
- }
-
- private _isSequencerTx(block: L2Block): boolean {
- return block.transactions[0].queueOrigin === QueueOrigin.Sequencer
- }
-}
diff --git a/packages/batch-submitter/src/exec/run-batch-submitter.ts b/packages/batch-submitter/src/exec/run-batch-submitter.ts
deleted file mode 100644
index b1184dc553c4e..0000000000000
--- a/packages/batch-submitter/src/exec/run-batch-submitter.ts
+++ /dev/null
@@ -1,538 +0,0 @@
-/* External Imports */
-import { exit } from 'process'
-
-import { Bcfg } from '@eth-optimism/core-utils'
-import { asL2Provider } from '@eth-optimism/sdk'
-import * as Sentry from '@sentry/node'
-import { Logger, Metrics, createMetricsServer } from '@eth-optimism/common-ts'
-import { Signer, Wallet } from 'ethers'
-import {
- StaticJsonRpcProvider,
- TransactionReceipt,
-} from '@ethersproject/providers'
-import * as dotenv from 'dotenv'
-import Config from 'bcfg'
-
-/* Internal Imports */
-import {
- TransactionBatchSubmitter,
- AutoFixBatchOptions,
- StateBatchSubmitter,
- STATE_BATCH_SUBMITTER_LOG_TAG,
- TX_BATCH_SUBMITTER_LOG_TAG,
-} from '..'
-import {
- TransactionSubmitter,
- YnatmTransactionSubmitter,
- ResubmissionConfig,
-} from '../utils'
-
-interface RequiredEnvVars {
- // The HTTP provider URL for L1.
- L1_NODE_WEB3_URL: string
- // The HTTP provider URL for L2.
- L2_NODE_WEB3_URL: string
- // The layer one address manager address
- ADDRESS_MANAGER_ADDRESS: string
- // The minimum size in bytes of any L1 transactions generated by the batch submitter.
- MIN_L1_TX_SIZE: number
- // The maximum size in bytes of any L1 transactions generated by the batch submitter.
- MAX_L1_TX_SIZE: number
- // The maximum number of L2 transactions that can ever be in a batch.
- MAX_TX_BATCH_COUNT: number
- // The maximum number of L2 state roots that can ever be in a batch.
- MAX_STATE_BATCH_COUNT: number
- // The maximum amount of time (seconds) that we will wait before submitting an under-sized batch.
- MAX_BATCH_SUBMISSION_TIME: number
- // The delay in milliseconds between querying L2 for more transactions / to create a new batch.
- POLL_INTERVAL: number
- // The number of confirmations which we will wait after appending new batches.
- NUM_CONFIRMATIONS: number
- // The number of seconds to wait before resubmitting a transaction.
- RESUBMISSION_TIMEOUT: number
- // The number of confirmations that we should wait before submitting state roots for CTC elements.
- FINALITY_CONFIRMATIONS: number
- // Whether or not to run the tx batch submitter.
- RUN_TX_BATCH_SUBMITTER: boolean
- // Whether or not to run the state batch submitter.
- RUN_STATE_BATCH_SUBMITTER: boolean
- // The safe minimum amount of ether the batch submitter key should
- // hold before it starts to log errors.
- SAFE_MINIMUM_ETHER_BALANCE: number
- // A boolean to clear the pending transactions in the mempool
- // on start up.
- CLEAR_PENDING_TXS: boolean
-}
-
-/* Optional Env Vars
- * FRAUD_SUBMISSION_ADDRESS
- * SEQUENCER_PRIVATE_KEY
- * PROPOSER_PRIVATE_KEY
- * MNEMONIC
- * SEQUENCER_MNEMONIC
- * PROPOSER_MNEMONIC
- * SEQUENCER_HD_PATH
- * PROPOSER_HD_PATH
- * BLOCK_OFFSET
- * VALIDATE_TX_BATCH
- * USE_HARDHAT
- * DEBUG_IMPERSONATE_SEQUENCER_ADDRESS
- * DEBUG_IMPERSONATE_PROPOSER_ADDRESS
- * RUN_METRICS_SERVER
- */
-
-export const run = async () => {
- dotenv.config()
-
- const config: Bcfg = new Config('batch-submitter')
- config.load({
- env: true,
- argv: true,
- })
-
- // Parse config
- const env = process.env
- const environment = config.str('node-env', env.NODE_ENV)
- const network = config.str('eth-network-name', env.ETH_NETWORK_NAME)
- const service = `batch-submitter`
- const release = `batch-submitter@${env.npm_package_version}`
- const sentryDsn = config.str('sentry-dsn', env.SENTRY_DSN)
- const sentryTraceRate = config.ufloat(
- 'sentry-trace-rate',
- parseFloat(env.SENTRY_TRACE_RATE) || 0.05
- )
-
- // Default is 1 because Geth normally has 1 more block than L1
- const BLOCK_OFFSET = config.uint(
- 'block-offset',
- parseInt(env.BLOCK_OFFSET, 10) || 1
- )
-
- /* Logger */
- const name = 'oe:batch_submitter:init'
- let logger
-
- if (config.bool('use-sentry', env.USE_SENTRY === 'true')) {
- const sentryOptions = {
- release,
- dsn: sentryDsn,
- tracesSampleRate: sentryTraceRate,
- environment: network,
- }
- Sentry.init(sentryOptions)
- // Initialize Sentry for Batch Submitter deployed to a network
- logger = new Logger({
- name,
- sentryOptions,
- })
- } else {
- // Skip initializing Sentry
- logger = new Logger({ name })
- }
-
- const useHardhat = config.bool('use-hardhat', !!env.USE_HARDHAT)
- const DEBUG_IMPERSONATE_SEQUENCER_ADDRESS = config.str(
- 'debug-impersonate-sequencer-address',
- env.DEBUG_IMPERSONATE_SEQUENCER_ADDRESS
- )
- const DEBUG_IMPERSONATE_PROPOSER_ADDRESS = config.str(
- 'debug-impersonate-proposer-address',
- env.DEBUG_IMPERSONATE_PROPOSER_ADDRESS
- )
-
- const getSequencerSigner = async (): Promise => {
- const l1Provider = new StaticJsonRpcProvider({
- url: requiredEnvVars.L1_NODE_WEB3_URL,
- headers: { 'User-Agent': 'batch-submitter' },
- })
-
- if (useHardhat) {
- if (!DEBUG_IMPERSONATE_SEQUENCER_ADDRESS) {
- throw new Error('Must pass DEBUG_IMPERSONATE_SEQUENCER_ADDRESS')
- }
- await l1Provider.send('hardhat_impersonateAccount', [
- DEBUG_IMPERSONATE_SEQUENCER_ADDRESS,
- ])
- return l1Provider.getSigner(DEBUG_IMPERSONATE_SEQUENCER_ADDRESS)
- }
-
- if (SEQUENCER_PRIVATE_KEY) {
- return new Wallet(SEQUENCER_PRIVATE_KEY, l1Provider)
- } else if (SEQUENCER_MNEMONIC) {
- return Wallet.fromMnemonic(SEQUENCER_MNEMONIC, SEQUENCER_HD_PATH).connect(
- l1Provider
- )
- }
- throw new Error(
- 'Must pass one of SEQUENCER_PRIVATE_KEY, MNEMONIC, or SEQUENCER_MNEMONIC'
- )
- }
-
- const getProposerSigner = async (): Promise => {
- const l1Provider = new StaticJsonRpcProvider({
- url: requiredEnvVars.L1_NODE_WEB3_URL,
- headers: { 'User-Agent': 'batch-submitter' },
- })
-
- if (useHardhat) {
- if (!DEBUG_IMPERSONATE_PROPOSER_ADDRESS) {
- throw new Error('Must pass DEBUG_IMPERSONATE_PROPOSER_ADDRESS')
- }
- await l1Provider.send('hardhat_impersonateAccount', [
- DEBUG_IMPERSONATE_PROPOSER_ADDRESS,
- ])
- return l1Provider.getSigner(DEBUG_IMPERSONATE_PROPOSER_ADDRESS)
- }
-
- if (PROPOSER_PRIVATE_KEY) {
- return new Wallet(PROPOSER_PRIVATE_KEY, l1Provider)
- } else if (PROPOSER_MNEMONIC) {
- return Wallet.fromMnemonic(PROPOSER_MNEMONIC, PROPOSER_HD_PATH).connect(
- l1Provider
- )
- }
- throw new Error(
- 'Must pass one of PROPOSER_PRIVATE_KEY, MNEMONIC, or PROPOSER_MNEMONIC'
- )
- }
-
- /* Metrics */
- const metrics = new Metrics({
- labels: { environment, release, network, service },
- })
-
- const FRAUD_SUBMISSION_ADDRESS = config.str(
- 'fraud-submisison-address',
- env.FRAUD_SUBMISSION_ADDRESS || 'no fraud'
- )
- const MIN_GAS_PRICE_IN_GWEI = config.uint(
- 'min-gas-price-in-gwei',
- parseInt(env.MIN_GAS_PRICE_IN_GWEI, 10) || 0
- )
- const GAS_RETRY_INCREMENT = config.uint(
- 'gas-retry-increment',
- parseInt(env.GAS_RETRY_INCREMENT, 10) || 5
- )
- const GAS_THRESHOLD_IN_GWEI = config.uint(
- 'gas-threshold-in-gwei',
- parseInt(env.GAS_THRESHOLD_IN_GWEI, 10) || 100
- )
-
- // Private keys & mnemonics
- const SEQUENCER_PRIVATE_KEY = config.str(
- 'sequencer-private-key',
- env.SEQUENCER_PRIVATE_KEY
- )
- // Kept for backwards compatibility
- const PROPOSER_PRIVATE_KEY = config.str(
- 'proposer-private-key',
- env.PROPOSER_PRIVATE_KEY || env.SEQUENCER_PRIVATE_KEY
- )
- const SEQUENCER_MNEMONIC = config.str(
- 'sequencer-mnemonic',
- env.SEQUENCER_MNEMONIC || env.MNEMONIC
- )
- const PROPOSER_MNEMONIC = config.str(
- 'proposer-mnemonic',
- env.PROPOSER_MNEMONIC || env.MNEMONIC
- )
- const SEQUENCER_HD_PATH = config.str(
- 'sequencer-hd-path',
- env.SEQUENCER_HD_PATH || env.HD_PATH
- )
- const PROPOSER_HD_PATH = config.str(
- 'proposer-hd-path',
- env.PROPOSER_HD_PATH || env.HD_PATH
- )
-
- const VALIDATE_TX_BATCH = config.bool(
- 'validate-tx-batch',
- env.VALIDATE_TX_BATCH ? env.VALIDATE_TX_BATCH === 'true' : false
- )
-
- const SEQUENCER_BATCH_TYPE = config.str(
- 'sequencer-batch-type',
- env.SEQUENCER_BATCH_TYPE || 'legacy'
- )
-
- // Auto fix batch options -- TODO: Remove this very hacky config
- const AUTO_FIX_BATCH_OPTIONS_CONF = config.str(
- 'auto-fix-batch-conf',
- env.AUTO_FIX_BATCH_OPTIONS_CONF || ''
- )
- const autoFixBatchOptions: AutoFixBatchOptions = {
- fixDoublePlayedDeposits: AUTO_FIX_BATCH_OPTIONS_CONF
- ? AUTO_FIX_BATCH_OPTIONS_CONF.includes('fixDoublePlayedDeposits')
- : false,
- fixMonotonicity: AUTO_FIX_BATCH_OPTIONS_CONF
- ? AUTO_FIX_BATCH_OPTIONS_CONF.includes('fixMonotonicity')
- : false,
- fixSkippedDeposits: AUTO_FIX_BATCH_OPTIONS_CONF
- ? AUTO_FIX_BATCH_OPTIONS_CONF.includes('fixSkippedDeposits')
- : false,
- }
-
- logger.info('Starting batch submitter...')
-
- const requiredEnvVars: RequiredEnvVars = {
- L1_NODE_WEB3_URL: config.str('l1-node-web3-url', env.L1_NODE_WEB3_URL),
- L2_NODE_WEB3_URL: config.str('l2-node-web3-url', env.L2_NODE_WEB3_URL),
- ADDRESS_MANAGER_ADDRESS: config.str(
- 'address-manager-address',
- env.ADDRESS_MANAGER_ADDRESS
- ),
- MIN_L1_TX_SIZE: config.uint(
- 'min-l1-tx-size',
- parseInt(env.MIN_L1_TX_SIZE, 10)
- ),
- MAX_L1_TX_SIZE: config.uint(
- 'max-l1-tx-size',
- parseInt(env.MAX_L1_TX_SIZE, 10)
- ),
- MAX_TX_BATCH_COUNT: config.uint(
- 'max-tx-batch-count',
- parseInt(env.MAX_TX_BATCH_COUNT, 10)
- ),
- MAX_STATE_BATCH_COUNT: config.uint(
- 'max-state-batch-count',
- parseInt(env.MAX_STATE_BATCH_COUNT, 10)
- ),
- MAX_BATCH_SUBMISSION_TIME: config.uint(
- 'max-batch-submisison-time',
- parseInt(env.MAX_BATCH_SUBMISSION_TIME, 10)
- ),
- POLL_INTERVAL: config.uint(
- 'poll-interval',
- parseInt(env.POLL_INTERVAL, 10)
- ),
- NUM_CONFIRMATIONS: config.uint(
- 'num-confirmations',
- parseInt(env.NUM_CONFIRMATIONS, 10)
- ),
- RESUBMISSION_TIMEOUT: config.uint(
- 'resubmission-timeout',
- parseInt(env.RESUBMISSION_TIMEOUT, 10)
- ),
- FINALITY_CONFIRMATIONS: config.uint(
- 'finality-confirmations',
- parseInt(env.FINALITY_CONFIRMATIONS, 10)
- ),
- RUN_TX_BATCH_SUBMITTER: config.bool(
- 'run-tx-batch-submitter',
- env.RUN_TX_BATCH_SUBMITTER === 'true'
- ),
- RUN_STATE_BATCH_SUBMITTER: config.bool(
- 'run-state-batch-submitter',
- env.RUN_STATE_BATCH_SUBMITTER === 'true'
- ),
- SAFE_MINIMUM_ETHER_BALANCE: config.ufloat(
- 'safe-minimum-ether-balance',
- parseFloat(env.SAFE_MINIMUM_ETHER_BALANCE)
- ),
- CLEAR_PENDING_TXS: config.bool(
- 'clear-pending-txs',
- env.CLEAR_PENDING_TXS === 'true'
- ),
- }
-
- for (const [key, val] of Object.entries(requiredEnvVars)) {
- if (val === null || val === undefined) {
- logger.warn('Missing environment variable', {
- key,
- value: val,
- })
- exit(1)
- }
- }
-
- if (requiredEnvVars.MIN_L1_TX_SIZE === 0) {
- logger.error('Must configure a MIN_L1_TX_SIZE greater than 0')
- process.exit(1)
- }
-
- const clearPendingTxs = requiredEnvVars.CLEAR_PENDING_TXS
-
- const l2Provider = asL2Provider(
- new StaticJsonRpcProvider({
- url: requiredEnvVars.L2_NODE_WEB3_URL,
- headers: { 'User-Agent': 'batch-submitter' },
- })
- )
-
- const sequencerSigner: Signer = await getSequencerSigner()
- let proposerSigner: Signer = await getProposerSigner()
-
- const sequencerAddress = await sequencerSigner.getAddress()
- const proposerAddress = await proposerSigner.getAddress()
- // If the sequencer & proposer are the same, use a single wallet
- if (sequencerAddress === proposerAddress) {
- proposerSigner = sequencerSigner
- throw new Error(
- 'Sequencer and proposer have the same address, multiple transactions may be sent with the same nonce.'
- )
- }
-
- logger.info('Configured batch submitter addresses', {
- sequencerAddress,
- proposerAddress,
- addressManagerAddress: requiredEnvVars.ADDRESS_MANAGER_ADDRESS,
- })
-
- const resubmissionConfig: ResubmissionConfig = {
- resubmissionTimeout: requiredEnvVars.RESUBMISSION_TIMEOUT * 1_000,
- minGasPriceInGwei: MIN_GAS_PRICE_IN_GWEI,
- maxGasPriceInGwei: GAS_THRESHOLD_IN_GWEI,
- gasRetryIncrement: GAS_RETRY_INCREMENT,
- }
- const txBatchTxSubmitter: TransactionSubmitter =
- new YnatmTransactionSubmitter(
- sequencerSigner,
- resubmissionConfig,
- requiredEnvVars.NUM_CONFIRMATIONS
- )
- const txBatchSubmitter = new TransactionBatchSubmitter(
- sequencerSigner,
- l2Provider,
- requiredEnvVars.MIN_L1_TX_SIZE,
- requiredEnvVars.MAX_L1_TX_SIZE,
- requiredEnvVars.MAX_TX_BATCH_COUNT,
- requiredEnvVars.MAX_BATCH_SUBMISSION_TIME * 1_000,
- requiredEnvVars.NUM_CONFIRMATIONS,
- requiredEnvVars.RESUBMISSION_TIMEOUT * 1_000,
- requiredEnvVars.ADDRESS_MANAGER_ADDRESS,
- requiredEnvVars.SAFE_MINIMUM_ETHER_BALANCE,
- GAS_THRESHOLD_IN_GWEI,
- txBatchTxSubmitter,
- BLOCK_OFFSET,
- VALIDATE_TX_BATCH,
- logger.child({ name: TX_BATCH_SUBMITTER_LOG_TAG }),
- metrics,
- autoFixBatchOptions,
- SEQUENCER_BATCH_TYPE
- )
-
- const stateBatchTxSubmitter: TransactionSubmitter =
- new YnatmTransactionSubmitter(
- proposerSigner,
- resubmissionConfig,
- requiredEnvVars.NUM_CONFIRMATIONS
- )
- const stateBatchSubmitter = new StateBatchSubmitter(
- proposerSigner,
- l2Provider,
- requiredEnvVars.MIN_L1_TX_SIZE,
- requiredEnvVars.MAX_L1_TX_SIZE,
- requiredEnvVars.MAX_STATE_BATCH_COUNT,
- requiredEnvVars.MAX_BATCH_SUBMISSION_TIME * 1_000,
- requiredEnvVars.NUM_CONFIRMATIONS,
- requiredEnvVars.RESUBMISSION_TIMEOUT * 1_000,
- requiredEnvVars.FINALITY_CONFIRMATIONS,
- requiredEnvVars.ADDRESS_MANAGER_ADDRESS,
- requiredEnvVars.SAFE_MINIMUM_ETHER_BALANCE,
- stateBatchTxSubmitter,
- BLOCK_OFFSET,
- logger.child({ name: STATE_BATCH_SUBMITTER_LOG_TAG }),
- metrics,
- FRAUD_SUBMISSION_ADDRESS
- )
-
- // Loops infinitely!
- const loop = async (
- func: () => Promise,
- signer: Signer
- ): Promise => {
- // Clear all pending transactions
- if (clearPendingTxs) {
- try {
- const pendingTxs = await signer.getTransactionCount('pending')
- const latestTxs = await signer.getTransactionCount('latest')
- if (pendingTxs > latestTxs) {
- logger.info(
- 'Detected pending transactions. Clearing all transactions!'
- )
- for (let i = latestTxs; i < pendingTxs; i++) {
- const response = await signer.sendTransaction({
- to: await signer.getAddress(),
- value: 0,
- nonce: i,
- })
- logger.info('Submitted empty transaction', {
- nonce: i,
- txHash: response.hash,
- to: response.to,
- from: response.from,
- })
- logger.debug('empty transaction data', {
- data: response.data,
- })
- await signer.provider.waitForTransaction(
- response.hash,
- requiredEnvVars.NUM_CONFIRMATIONS
- )
- }
- }
- } catch (err) {
- logger.error('Cannot clear transactions', {
- message: err.toString(),
- stack: err.stack,
- code: err.code,
- })
- process.exit(1)
- }
- }
-
- while (true) {
- try {
- await func()
- } catch (err) {
- switch (err.code) {
- case 'SERVER_ERROR':
- logger.error(`Encountered server error with status ${err.status}`, {
- message: err.toString(),
- stack: err.stack,
- code: err.code,
- })
- break
- case 'NETWORK_ERROR':
- logger.error('Could not detect network', {
- message: err.toString(),
- stack: err.stack,
- code: err.code,
- })
- break
- default:
- logger.error('Unhandled exception during batch submission', {
- message: err.toString(),
- stack: err.stack,
- code: err.code,
- })
- break
- }
- logger.info('Retrying...')
- }
- // Sleep
- await new Promise((r) => setTimeout(r, requiredEnvVars.POLL_INTERVAL))
- }
- }
-
- // Run batch submitters in two seperate infinite loops!
- if (requiredEnvVars.RUN_TX_BATCH_SUBMITTER) {
- loop(() => txBatchSubmitter.submitNextBatch(), sequencerSigner)
- }
- if (requiredEnvVars.RUN_STATE_BATCH_SUBMITTER) {
- loop(() => stateBatchSubmitter.submitNextBatch(), proposerSigner)
- }
-
- if (config.bool('run-metrics-server', env.RUN_METRICS_SERVER === 'true')) {
- // Initialize metrics server
- await createMetricsServer({
- logger,
- registry: metrics.registry,
- port: config.uint('metrics-port', parseInt(env.METRICS_PORT, 10) || 7300),
- hostname: config.str(
- 'metrics-hostname',
- env.METRICS_HOSTNAME || '127.0.0.1'
- ),
- })
- }
-}
diff --git a/packages/batch-submitter/src/index.ts b/packages/batch-submitter/src/index.ts
deleted file mode 100644
index 3f90392136db8..0000000000000
--- a/packages/batch-submitter/src/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './batch-submitter'
-export * from './utils'
-export * from './transaction-chain-contract'
diff --git a/packages/batch-submitter/src/transaction-chain-contract.ts b/packages/batch-submitter/src/transaction-chain-contract.ts
deleted file mode 100644
index dde1be08b84ae..0000000000000
--- a/packages/batch-submitter/src/transaction-chain-contract.ts
+++ /dev/null
@@ -1,68 +0,0 @@
-/* External Imports */
-import { Contract, ethers } from 'ethers'
-import {
- TransactionResponse,
- TransactionRequest,
-} from '@ethersproject/abstract-provider'
-import {
- AppendSequencerBatchParams,
- BatchContext,
- encodeAppendSequencerBatch,
- sequencerBatch,
-} from '@eth-optimism/core-utils'
-
-export { encodeAppendSequencerBatch, BatchContext, AppendSequencerBatchParams }
-
-/*
- * OVM_CanonicalTransactionChainContract is a wrapper around a normal Ethers contract
- * where the `appendSequencerBatch(...)` function uses a specialized encoding for improved efficiency.
- */
-export class CanonicalTransactionChainContract extends Contract {
- public customPopulateTransaction = {
- appendSequencerBatch: async (
- batch: AppendSequencerBatchParams
- ): Promise => {
- const nonce = await this.signer.getTransactionCount()
- const to = this.address
- const data = getEncodedCalldata(batch)
- const gasLimit = await this.signer.provider.estimateGas({
- to,
- from: await this.signer.getAddress(),
- data,
- })
-
- return {
- nonce,
- to,
- data,
- gasLimit,
- }
- },
- }
- public async appendSequencerBatch(
- batch: AppendSequencerBatchParams,
- options?: TransactionRequest
- ): Promise {
- return appendSequencerBatch(this, batch, options)
- }
-}
-
-/**********************
- * Internal Functions *
- *********************/
-
-const appendSequencerBatch = async (
- OVM_CanonicalTransactionChain: Contract,
- batch: AppendSequencerBatchParams,
- options?: TransactionRequest
-): Promise => {
- return OVM_CanonicalTransactionChain.signer.sendTransaction({
- to: OVM_CanonicalTransactionChain.address,
- data: getEncodedCalldata(batch),
- ...options,
- })
-}
-
-const getEncodedCalldata = (params: AppendSequencerBatchParams): string => {
- return sequencerBatch.encode(params)
-}
diff --git a/packages/batch-submitter/src/utils/index.ts b/packages/batch-submitter/src/utils/index.ts
deleted file mode 100644
index 0913963320f7a..0000000000000
--- a/packages/batch-submitter/src/utils/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './tx-submission'
diff --git a/packages/batch-submitter/src/utils/tx-submission.ts b/packages/batch-submitter/src/utils/tx-submission.ts
deleted file mode 100644
index f39a8b86c2d08..0000000000000
--- a/packages/batch-submitter/src/utils/tx-submission.ts
+++ /dev/null
@@ -1,110 +0,0 @@
-import { Signer, ethers, PopulatedTransaction } from 'ethers'
-import {
- TransactionReceipt,
- TransactionResponse,
-} from '@ethersproject/abstract-provider'
-import * as ynatm from '@eth-optimism/ynatm'
-
-export interface ResubmissionConfig {
- resubmissionTimeout: number
- minGasPriceInGwei: number
- maxGasPriceInGwei: number
- gasRetryIncrement: number
-}
-
-export type SubmitTransactionFn = (
- tx: PopulatedTransaction
-) => Promise
-
-export interface TxSubmissionHooks {
- beforeSendTransaction: (tx: PopulatedTransaction) => void
- onTransactionResponse: (txResponse: TransactionResponse) => void
-}
-
-const getGasPriceInGwei = async (signer: Signer): Promise => {
- return parseInt(
- ethers.utils.formatUnits(await signer.getGasPrice(), 'gwei'),
- 10
- )
-}
-
-export const ynatmRejectOn = (e) => {
- // taken almost verbatim from the readme,
- // see https://github.com/ethereum-optimism/ynatm.
- // immediately rejects on reverts and nonce errors
- const errMsg = e.toString().toLowerCase()
- const conditions = ['revert', 'nonce']
- for (const cond of conditions) {
- if (errMsg.includes(cond)) {
- return true
- }
- }
-
- return false
-}
-
-export const submitTransactionWithYNATM = async (
- tx: PopulatedTransaction,
- signer: Signer,
- config: ResubmissionConfig,
- numConfirmations: number,
- hooks: TxSubmissionHooks
-): Promise => {
- const sendTxAndWaitForReceipt = async (
- gasPrice
- ): Promise => {
- const fullTx = {
- ...tx,
- gasPrice,
- }
- hooks.beforeSendTransaction(fullTx)
- const txResponse = await signer.sendTransaction(fullTx)
- hooks.onTransactionResponse(txResponse)
- return signer.provider.waitForTransaction(txResponse.hash, numConfirmations)
- }
-
- const minGasPrice = await getGasPriceInGwei(signer)
- const receipt = await ynatm.send({
- sendTransactionFunction: sendTxAndWaitForReceipt,
- minGasPrice: ynatm.toGwei(minGasPrice),
- maxGasPrice: ynatm.toGwei(config.maxGasPriceInGwei),
- gasPriceScalingFunction: ynatm.LINEAR(config.gasRetryIncrement),
- delay: config.resubmissionTimeout,
- rejectImmediatelyOnCondition: ynatmRejectOn,
- })
- return receipt
-}
-
-export interface TransactionSubmitter {
- submitTransaction(
- tx: PopulatedTransaction,
- hooks?: TxSubmissionHooks
- ): Promise
-}
-
-export class YnatmTransactionSubmitter implements TransactionSubmitter {
- constructor(
- readonly signer: Signer,
- readonly ynatmConfig: ResubmissionConfig,
- readonly numConfirmations: number
- ) {}
-
- public async submitTransaction(
- tx: PopulatedTransaction,
- hooks?: TxSubmissionHooks
- ): Promise {
- if (!hooks) {
- hooks = {
- beforeSendTransaction: () => undefined,
- onTransactionResponse: () => undefined,
- }
- }
- return submitTransactionWithYNATM(
- tx,
- this.signer,
- this.ynatmConfig,
- this.numConfirmations,
- hooks
- )
- }
-}
diff --git a/packages/batch-submitter/test/batch-submitter/batch-submitter.spec.ts b/packages/batch-submitter/test/batch-submitter/batch-submitter.spec.ts
deleted file mode 100644
index 4d575afd3ac4a..0000000000000
--- a/packages/batch-submitter/test/batch-submitter/batch-submitter.spec.ts
+++ /dev/null
@@ -1,475 +0,0 @@
-/* External Imports */
-import { ethers } from 'hardhat'
-import '@nomiclabs/hardhat-ethers'
-import { Signer, ContractFactory, Contract, BigNumber } from 'ethers'
-import sinon from 'sinon'
-import scc from '@eth-optimism/contracts/artifacts/contracts/L1/rollup/StateCommitmentChain.sol/StateCommitmentChain.json'
-import { getContractInterface } from '@eth-optimism/contracts'
-import { smockit, MockContract } from '@eth-optimism/smock'
-import { getContractFactory } from 'old-contracts'
-import { QueueOrigin, Batch, remove0x } from '@eth-optimism/core-utils'
-import { Logger, Metrics } from '@eth-optimism/common-ts'
-
-/* Internal Imports */
-import { MockchainProvider } from './mockchain-provider'
-import { expect } from '../setup'
-import {
- CanonicalTransactionChainContract,
- TransactionBatchSubmitter as RealTransactionBatchSubmitter,
- StateBatchSubmitter,
- TX_BATCH_SUBMITTER_LOG_TAG,
- STATE_BATCH_SUBMITTER_LOG_TAG,
- YnatmTransactionSubmitter,
- ResubmissionConfig,
-} from '../../src'
-import {
- makeAddressManager,
- setProxyTarget,
- FORCE_INCLUSION_PERIOD_SECONDS,
-} from '../helpers'
-
-const EXAMPLE_STATE_ROOT =
- '0x16b7f83f409c7195b1f4fde5652f1b54a4477eacb6db7927691becafba5f8801'
-const MAX_GAS_LIMIT = 8_000_000
-const MAX_TX_SIZE = 100_000
-const MIN_TX_SIZE = 1_000
-const MIN_GAS_PRICE_IN_GWEI = 1
-const GAS_RETRY_INCREMENT = 5
-const GAS_THRESHOLD_IN_GWEI = 120
-
-// Helper functions
-interface QueueElement {
- queueRoot: string
- timestamp: number
- blockNumber: number
-}
-const getQueueElement = async (
- ctcContract: Contract,
- nextQueueIndex?: number
-): Promise => {
- if (!nextQueueIndex) {
- nextQueueIndex = await ctcContract.getNextQueueIndex()
- }
- const nextQueueElement = await ctcContract.getQueueElement(nextQueueIndex)
- return nextQueueElement
-}
-// A transaction batch submitter which skips the validate batch check
-class TransactionBatchSubmitter extends RealTransactionBatchSubmitter {
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- protected async _validateBatch(batch: Batch): Promise {
- return true
- }
-}
-const testMetrics = new Metrics({ prefix: 'bs_test' })
-
-describe('BatchSubmitter', () => {
- let signer: Signer
- let sequencer: Signer
- before(async () => {
- ;[signer, sequencer] = await ethers.getSigners()
- })
-
- let AddressManager: Contract
- let Mock__OVM_ExecutionManager: MockContract
- let Mock__OVM_BondManager: MockContract
- let Mock__OVM_StateCommitmentChain: MockContract
- before(async () => {
- AddressManager = await makeAddressManager()
- await AddressManager.setAddress(
- 'OVM_Sequencer',
- await sequencer.getAddress()
- )
-
- Mock__OVM_ExecutionManager = await smockit(
- await getContractFactory('OVM_ExecutionManager')
- )
-
- Mock__OVM_BondManager = await smockit(
- await getContractFactory('OVM_BondManager')
- )
-
- Mock__OVM_StateCommitmentChain = await smockit(
- await getContractFactory('OVM_StateCommitmentChain')
- )
-
- await setProxyTarget(
- AddressManager,
- 'OVM_ExecutionManager',
- Mock__OVM_ExecutionManager
- )
-
- await setProxyTarget(
- AddressManager,
- 'OVM_BondManager',
- Mock__OVM_BondManager
- )
-
- await setProxyTarget(
- AddressManager,
- 'OVM_StateCommitmentChain',
- Mock__OVM_StateCommitmentChain
- )
-
- Mock__OVM_StateCommitmentChain.smocked.canOverwrite.will.return.with(false)
- Mock__OVM_ExecutionManager.smocked.getMaxTransactionGasLimit.will.return.with(
- MAX_GAS_LIMIT
- )
- Mock__OVM_BondManager.smocked.isCollateralized.will.return.with(true)
- })
-
- let Factory__OVM_CanonicalTransactionChain: ContractFactory
- let Factory__OVM_StateCommitmentChain: ContractFactory
- before(async () => {
- Factory__OVM_CanonicalTransactionChain = await getContractFactory(
- 'OVM_CanonicalTransactionChain'
- )
-
- Factory__OVM_CanonicalTransactionChain =
- Factory__OVM_CanonicalTransactionChain.connect(signer)
-
- Factory__OVM_StateCommitmentChain = await getContractFactory(
- 'OVM_StateCommitmentChain'
- )
-
- Factory__OVM_StateCommitmentChain =
- Factory__OVM_StateCommitmentChain.connect(signer)
- })
-
- let OVM_CanonicalTransactionChain: CanonicalTransactionChainContract
- let OVM_StateCommitmentChain: Contract
- let l2Provider: MockchainProvider
- beforeEach(async () => {
- const unwrapped_OVM_CanonicalTransactionChain =
- await Factory__OVM_CanonicalTransactionChain.deploy(
- AddressManager.address,
- FORCE_INCLUSION_PERIOD_SECONDS
- )
-
- await unwrapped_OVM_CanonicalTransactionChain.init()
-
- await AddressManager.setAddress(
- 'OVM_CanonicalTransactionChain',
- unwrapped_OVM_CanonicalTransactionChain.address
- )
-
- await AddressManager.setAddress(
- 'CanonicalTransactionChain',
- unwrapped_OVM_CanonicalTransactionChain.address
- )
-
- OVM_CanonicalTransactionChain = new CanonicalTransactionChainContract(
- unwrapped_OVM_CanonicalTransactionChain.address,
- getContractInterface('CanonicalTransactionChain'),
- sequencer
- )
-
- const unwrapped_OVM_StateCommitmentChain =
- await Factory__OVM_StateCommitmentChain.deploy(
- AddressManager.address,
- 0, // fraudProofWindowSeconds
- 0 // sequencerPublishWindowSeconds
- )
-
- await unwrapped_OVM_StateCommitmentChain.init()
-
- await AddressManager.setAddress(
- 'OVM_StateCommitmentChain',
- unwrapped_OVM_StateCommitmentChain.address
- )
-
- await AddressManager.setAddress(
- 'StateCommitmentChain',
- unwrapped_OVM_StateCommitmentChain.address
- )
-
- OVM_StateCommitmentChain = new Contract(
- unwrapped_OVM_StateCommitmentChain.address,
- getContractInterface('StateCommitmentChain'),
- sequencer
- )
-
- l2Provider = new MockchainProvider(
- OVM_CanonicalTransactionChain.address,
- OVM_StateCommitmentChain.address
- )
- })
-
- afterEach(() => {
- sinon.restore()
- })
-
- const createBatchSubmitter = (timeout: number): TransactionBatchSubmitter => {
- const resubmissionConfig: ResubmissionConfig = {
- resubmissionTimeout: 100000,
- minGasPriceInGwei: MIN_GAS_PRICE_IN_GWEI,
- maxGasPriceInGwei: GAS_THRESHOLD_IN_GWEI,
- gasRetryIncrement: GAS_RETRY_INCREMENT,
- }
- const txBatchTxSubmitter = new YnatmTransactionSubmitter(
- sequencer,
- resubmissionConfig,
- 1
- )
- return new TransactionBatchSubmitter(
- sequencer,
- l2Provider as any,
- MIN_TX_SIZE,
- MAX_TX_SIZE,
- 10,
- timeout,
- 1,
- 100000,
- AddressManager.address,
- 1,
- GAS_THRESHOLD_IN_GWEI,
- txBatchTxSubmitter,
- 1,
- false,
- new Logger({ name: TX_BATCH_SUBMITTER_LOG_TAG }),
- testMetrics,
- {
- fixDoublePlayedDeposits: false,
- fixMonotonicity: false,
- fixSkippedDeposits: false,
- },
- 'legacy'
- )
- }
-
- describe('TransactionBatchSubmitter', () => {
- describe('submitNextBatch', () => {
- let batchSubmitter
- beforeEach(async () => {
- for (let i = 1; i < 15; i++) {
- await OVM_CanonicalTransactionChain.enqueue(
- '0x' + '01'.repeat(20),
- 50_000,
- '0x' + i.toString().repeat(64),
- {
- gasLimit: 1_000_000,
- }
- )
- }
- batchSubmitter = createBatchSubmitter(0)
- })
-
- it('should submit a sequencer batch correctly', async () => {
- l2Provider.setNumBlocksToReturn(5)
- const nextQueueElement = await getQueueElement(
- OVM_CanonicalTransactionChain
- )
- l2Provider.setL2BlockData(
- {
- rawTransaction: '0x1234',
- l1BlockNumber: nextQueueElement.blockNumber - 1,
- txType: 0,
- queueOrigin: QueueOrigin.Sequencer,
- l1TxOrigin: null,
- } as any,
- nextQueueElement.timestamp - 1
- )
- let receipt = await batchSubmitter.submitNextBatch()
- let logData = remove0x(receipt.logs[1].data)
- expect(parseInt(logData.slice(64 * 0, 64 * 1), 16)).to.equal(0) // _startingQueueIndex
- expect(parseInt(logData.slice(64 * 1, 64 * 2), 16)).to.equal(0) // _numQueueElements
- expect(parseInt(logData.slice(64 * 2, 64 * 3), 16)).to.equal(6) // _totalElements
- receipt = await batchSubmitter.submitNextBatch()
- logData = remove0x(receipt.logs[1].data)
- expect(parseInt(logData.slice(64 * 0, 64 * 1), 16)).to.equal(0) // _startingQueueIndex
- expect(parseInt(logData.slice(64 * 1, 64 * 2), 16)).to.equal(0) // _numQueueElements
- expect(parseInt(logData.slice(64 * 2, 64 * 3), 16)).to.equal(11) // _totalElements
- })
-
- it('should submit a queue batch correctly', async () => {
- l2Provider.setNumBlocksToReturn(5)
- l2Provider.setL2BlockData({
- queueOrigin: QueueOrigin.L1ToL2,
- } as any)
- let receipt = await batchSubmitter.submitNextBatch()
- let logData = remove0x(receipt.logs[1].data)
- expect(parseInt(logData.slice(64 * 0, 64 * 1), 16)).to.equal(0) // _startingQueueIndex
- expect(parseInt(logData.slice(64 * 1, 64 * 2), 16)).to.equal(6) // _numQueueElements
- expect(parseInt(logData.slice(64 * 2, 64 * 3), 16)).to.equal(6) // _totalElements
- receipt = await batchSubmitter.submitNextBatch()
- logData = remove0x(receipt.logs[1].data)
- expect(parseInt(logData.slice(64 * 0, 64 * 1), 16)).to.equal(6) // _startingQueueIndex
- expect(parseInt(logData.slice(64 * 1, 64 * 2), 16)).to.equal(5) // _numQueueElements
- expect(parseInt(logData.slice(64 * 2, 64 * 3), 16)).to.equal(11) // _totalElements
- })
-
- it('should submit a batch with both queue and sequencer chain elements', async () => {
- l2Provider.setNumBlocksToReturn(10) // For this batch we'll return 10 elements!
- l2Provider.setL2BlockData({
- queueOrigin: QueueOrigin.L1ToL2,
- } as any)
- // Turn blocks 3-5 into sequencer txs
- const nextQueueElement = await getQueueElement(
- OVM_CanonicalTransactionChain,
- 2
- )
- l2Provider.setL2BlockData(
- {
- rawTransaction: '0x1234',
- l1BlockNumber: nextQueueElement.blockNumber - 1,
- txType: 1,
- queueOrigin: QueueOrigin.Sequencer,
- l1TxOrigin: null,
- } as any,
- nextQueueElement.timestamp - 1,
- '', // blank stateRoot
- 3,
- 6
- )
- const receipt = await batchSubmitter.submitNextBatch()
- const logData = remove0x(receipt.logs[1].data)
- expect(parseInt(logData.slice(64 * 0, 64 * 1), 16)).to.equal(0) // _startingQueueIndex
- expect(parseInt(logData.slice(64 * 1, 64 * 2), 16)).to.equal(8) // _numQueueElements
- expect(parseInt(logData.slice(64 * 2, 64 * 3), 16)).to.equal(11) // _totalElements
- })
-
- it('should submit a small batch only after the timeout', async () => {
- l2Provider.setNumBlocksToReturn(2)
- l2Provider.setL2BlockData({
- queueOrigin: QueueOrigin.L1ToL2,
- } as any)
-
- // Create a batch submitter with a long timeout & make sure it doesn't submit the batches one after another
- const longTimeout = 10_000
- batchSubmitter = createBatchSubmitter(longTimeout)
- let receipt = await batchSubmitter.submitNextBatch()
- expect(receipt).to.not.be.undefined
- receipt = await batchSubmitter.submitNextBatch()
- // The receipt should be undefined because that means it didn't submit
- expect(receipt).to.be.undefined
-
- // This time create a batch submitter with a short timeout & it should submit batches after the timeout is reached
- const shortTimeout = 5
- batchSubmitter = createBatchSubmitter(shortTimeout)
- receipt = await batchSubmitter.submitNextBatch()
- expect(receipt).to.not.be.undefined
- // Sleep for the short timeout
- await new Promise((r) => setTimeout(r, shortTimeout))
- receipt = await batchSubmitter.submitNextBatch()
- // The receipt should NOT be undefined because that means it successfully submitted!
- expect(receipt).to.not.be.undefined
- })
-
- it('should not submit if gas price is over threshold', async () => {
- l2Provider.setNumBlocksToReturn(2)
- l2Provider.setL2BlockData({
- queueOrigin: QueueOrigin.L1ToL2,
- } as any)
-
- const highGasPriceWei = BigNumber.from(200).mul(1_000_000_000)
-
- sinon
- .stub(sequencer, 'getGasPrice')
- .callsFake(async () => highGasPriceWei)
-
- const receipt = await batchSubmitter.submitNextBatch()
- expect(sequencer.getGasPrice).to.have.been.calledOnce
- expect(receipt).to.be.undefined
- })
-
- it('should submit if gas price is not over threshold', async () => {
- l2Provider.setNumBlocksToReturn(2)
- l2Provider.setL2BlockData({
- queueOrigin: QueueOrigin.L1ToL2,
- } as any)
-
- const lowGasPriceWei = BigNumber.from(2).mul(1_000_000_000)
-
- sinon
- .stub(sequencer, 'getGasPrice')
- .callsFake(async () => lowGasPriceWei)
-
- const receipt = await batchSubmitter.submitNextBatch()
- expect(sequencer.getGasPrice).to.have.been.calledTwice
- expect(receipt).to.not.be.undefined
- })
- })
- })
-
- describe('StateBatchSubmitter', () => {
- let txBatchSubmitter
- let stateBatchSubmitter
- beforeEach(async () => {
- for (let i = 1; i < 15; i++) {
- await OVM_CanonicalTransactionChain.enqueue(
- '0x' + '01'.repeat(20),
- 50_000,
- '0x' + i.toString().repeat(64),
- {
- gasLimit: 1_000_000,
- }
- )
- }
-
- txBatchSubmitter = createBatchSubmitter(0)
-
- l2Provider.setNumBlocksToReturn(5)
- const nextQueueElement = await getQueueElement(
- OVM_CanonicalTransactionChain
- )
- l2Provider.setL2BlockData(
- {
- rawTransaction: '0x1234',
- l1BlockNumber: nextQueueElement.blockNumber - 1,
- txType: 0,
- queueOrigin: QueueOrigin.Sequencer,
- l1TxOrigin: null,
- } as any,
- nextQueueElement.timestamp - 1,
- EXAMPLE_STATE_ROOT // example stateRoot
- )
-
- // submit a batch of transactions to enable state batch submission
- await txBatchSubmitter.submitNextBatch()
-
- const resubmissionConfig: ResubmissionConfig = {
- resubmissionTimeout: 100000,
- minGasPriceInGwei: MIN_GAS_PRICE_IN_GWEI,
- maxGasPriceInGwei: GAS_THRESHOLD_IN_GWEI,
- gasRetryIncrement: GAS_RETRY_INCREMENT,
- }
- const stateBatchTxSubmitter = new YnatmTransactionSubmitter(
- sequencer,
- resubmissionConfig,
- 1
- )
- stateBatchSubmitter = new StateBatchSubmitter(
- sequencer,
- l2Provider as any,
- MIN_TX_SIZE,
- MAX_TX_SIZE,
- 10, // maxBatchSize
- 0,
- 1,
- 100000,
- 0, // finalityConfirmations
- AddressManager.address,
- 1,
- stateBatchTxSubmitter,
- 1,
- new Logger({ name: STATE_BATCH_SUBMITTER_LOG_TAG }),
- testMetrics,
- '0x' + '01'.repeat(20) // placeholder for fraudSubmissionAddress
- )
- })
-
- describe('submitNextBatch', () => {
- it('should submit a state batch after a transaction batch', async () => {
- const receipt = await stateBatchSubmitter.submitNextBatch()
- expect(receipt).to.not.be.undefined
-
- const iface = new ethers.utils.Interface(scc.abi)
- const parsedLogs = iface.parseLog(receipt.logs[0])
-
- expect(parsedLogs.eventFragment.name).to.eq('StateBatchAppended')
- expect(parsedLogs.args._batchIndex.toNumber()).to.eq(0)
- expect(parsedLogs.args._batchSize.toNumber()).to.eq(6)
- expect(parsedLogs.args._prevTotalElements.toNumber()).to.eq(0)
- })
- })
- })
-})
diff --git a/packages/batch-submitter/test/batch-submitter/mockchain-provider.ts b/packages/batch-submitter/test/batch-submitter/mockchain-provider.ts
deleted file mode 100644
index d936daf9c77da..0000000000000
--- a/packages/batch-submitter/test/batch-submitter/mockchain-provider.ts
+++ /dev/null
@@ -1,966 +0,0 @@
-/* External Imports */
-import { providers, BigNumber } from 'ethers'
-import {
- BlockWithTransactions,
- TransactionResponse,
-} from '@ethersproject/abstract-provider'
-import { L2Transaction, L2Block, RollupInfo } from '@eth-optimism/core-utils'
-
-/**
- * Unformatted Transaction & Blocks. This exists because Geth currently
- * does not return the correct fields & so this code renames those
- * poorly named fields
- */
-interface UnformattedL2Transaction extends TransactionResponse {
- l1BlockNumber: string
- l1MessageSender: string
- signatureHashType: string
- queueOrigin: string
- rawTransaction: string
-}
-
-interface UnformattedL2Block extends BlockWithTransactions {
- stateRoot: string
- transactions: [UnformattedL2Transaction]
-}
-
-export class MockchainProvider extends providers.JsonRpcProvider {
- public mockBlockNumber: number = 1
- public numBlocksToReturn: number = 2
- public mockBlocks: L2Block[] = []
- public ctcAddr: string
- public sccAddr: string
-
- constructor(ctcAddr: string, sccAddr: string) {
- super('https://optimism.io')
- for (const block of BLOCKS) {
- if (block.number === 0) {
- // No need to convert genesis to an L2Block because it has no txs
- this.mockBlocks.push(block)
- continue
- }
- this.mockBlocks.push(this._toL2Block(block))
- this.ctcAddr = ctcAddr
- this.sccAddr = sccAddr
- }
- }
-
- public async getBlockNumber(): Promise {
- // Increment our mock block number every time
- if (
- this.mockBlockNumber + this.numBlocksToReturn <
- this.mockBlocks.length
- ) {
- this.mockBlockNumber += this.numBlocksToReturn
- } else {
- return this.mockBlocks.length - 1
- }
- return this.mockBlockNumber
- }
-
- public async send(endpoint: string, params: []): Promise {
- switch (endpoint) {
- case 'eth_chainId':
- return this.chainId()
- case 'rollup_getInfo':
- const info: RollupInfo = {
- mode: 'sequencer',
- syncing: false,
- ethContext: {
- timestamp: 0,
- blockNumber: 0,
- },
- rollupContext: {
- index: 0,
- queueIndex: 0,
- },
- }
- return info
- case 'eth_getBlockByNumber':
- if (params.length === 0) {
- throw new Error(`Invalid params for ${endpoint}`)
- }
- const blockNumber = BigNumber.from((params as any)[0]).toNumber()
- return this.mockBlocks[blockNumber]
- default:
- throw new Error('Unsupported endpoint!')
- }
- }
-
- public setNumBlocksToReturn(numBlocks: number): void {
- this.numBlocksToReturn = numBlocks
- }
-
- public setL2BlockData(
- tx: L2Transaction,
- timestamp?: number,
- stateRoot?: string,
- start: number = 1,
- end: number = this.mockBlocks.length
- ) {
- for (let i = start; i < end; i++) {
- this.mockBlocks[i].timestamp = timestamp
- ? timestamp
- : this.mockBlocks[i].timestamp
- this.mockBlocks[i].transactions[0] = {
- ...this.mockBlocks[i].transactions[0],
- ...tx,
- }
- this.mockBlocks[i].stateRoot = stateRoot
- }
- }
-
- public async getBlockWithTransactions(blockNumber: number): Promise {
- return this.mockBlocks[blockNumber]
- }
-
- public chainId(): number {
- // We know that mockBlocks will always have at least 1 value
- return this.mockBlocks[1].transactions[0].chainId
- }
-
- private _toL2Block(block: UnformattedL2Block): L2Block {
- const l1BlockNumber: number = parseInt(
- block.transactions[0].l1BlockNumber,
- 10
- )
- const queueOrigin: string = block.transactions[0].queueOrigin
- const l1TxOrigin: string = block.transactions[0].l1MessageSender
- const l2Transaction: L2Transaction = {
- ...block.transactions[0],
- // Rename the incorrectly named fields
- l1TxOrigin,
- queueOrigin,
- l1BlockNumber,
- }
- // Add an interface here to fix the type casing into L2Block during Object.assign
- interface PartialL2Block {
- transactions: [L2Transaction]
- }
- const partialBlock: PartialL2Block = {
- transactions: [l2Transaction],
- }
- const l2Block: L2Block = { ...block, ...partialBlock }
- return l2Block
- }
-}
-
-const BLOCKS = JSON.parse(`
-[
- {
- "hash":"0xbc27fdbd1fee6e001438709ef57210bb7b2b1b8c23b65acb2d79161f4dc3cf05",
- "parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000",
- "number":0,
- "timestamp":1603651804,
- "nonce":"0x0000000000000042",
- "difficulty":1,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0x0000000000000000000000000000000000000000",
- "extraData":"0x1234",
- "transactions":[
- ]
- },
- {
- "hash":"0x05a7f5c5fce57346f59355184daa58822f97a32e4327fe6ef4a1c37dfd36f2f0",
- "parentHash":"0x64e89492b3ea72b9f9f0f4566e5198e19d7bfa583619c54c33872c7112aec9cd",
- "number":1,
- "timestamp":1603404102,
- "nonce":"0x0000000000000042",
- "difficulty":131072,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x688ddd1acc3cbccd9112018eac6c78744f43140d408128b8ed0392c7ee28966e",
- "blockHash":"0x05a7f5c5fce57346f59355184daa58822f97a32e4327fe6ef4a1c37dfd36f2f0",
- "blockNumber":1,
- "transactionIndex":0,
- "confirmations":16,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x05bc67"
- },
- "to":null,
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":0,
- "data":"0x608060405234801561001057600080fd5b50600080546001600160a01b03191633178082556040516001600160a01b039190911691907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a361056a806100696000396000f3fe608060405234801561001057600080fd5b50600436106100575760003560e01c8063715018a61461005c5780638da5cb5b146100665780639b2ea4bd1461008a578063bf40fac11461013b578063f2fde38b146101e1575b600080fd5b610064610207565b005b61006e6102b0565b604080516001600160a01b039092168252519081900360200190f35b610064600480360360408110156100a057600080fd5b8101906020810181356401000000008111156100bb57600080fd5b8201836020820111156100cd57600080fd5b803590602001918460018302840111640100000000831117156100ef57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550505090356001600160a01b031691506102bf9050565b61006e6004803603602081101561015157600080fd5b81019060208101813564010000000081111561016c57600080fd5b82018360208201111561017e57600080fd5b803590602001918460018302840111640100000000831117156101a057600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929550610362945050505050565b610064600480360360208110156101f757600080fd5b50356001600160a01b0316610391565b6000546001600160a01b03163314610266576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319169055565b6000546001600160a01b031681565b6000546001600160a01b0316331461031e576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b806001600061032c85610490565b815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050565b60006001600061037184610490565b81526020810191909152604001600020546001600160a01b031692915050565b6000546001600160a01b031633146103f0576040805162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015290519081900360640190fd5b6001600160a01b0381166104355760405162461bcd60e51b815260040180806020018281038252602d815260200180610508602d913960400191505060405180910390fd5b600080546040516001600160a01b03808516939216917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a3600080546001600160a01b0319166001600160a01b0392909216919091179055565b6000816040516020018082805190602001908083835b602083106104c55780518252601f1990920191602091820191016104a6565b6001836020036101000a03801982511681845116808217855250505050505090500191505060405160208183030381529060405280519060200120905091905056fe4f776e61626c653a206e6577206f776e65722063616e6e6f7420626520746865207a65726f2061646472657373a26469706673582212204367ffc2e6671623708150e2d0cff4c12cf566722a26b4748555d789953e2d2264736f6c63430007000033",
- "r":"0x2babe370e2e422a38386a5a96cd3bf16772ddbbf8c9dab8aadf4416fff557756",
- "s":"0x213ab994b50ed4a38e2de390f851d88cb66dd238a27d89246616b34eb8e859df",
- "v":62710,
- "creates":"0xA193E42526F1FEA8C99AF609dcEabf30C1c29fAA",
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0xb5903854b196abb9b7d1e3c2f5f8f9519b4fedefc21d72f3d92c74f128afcd46",
- "parentHash":"0x05a7f5c5fce57346f59355184daa58822f97a32e4327fe6ef4a1c37dfd36f2f0",
- "number":2,
- "timestamp":1603404103,
- "nonce":"0x0000000000000042",
- "difficulty":131136,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0xeae52be001bfea0b3d8de2de5edff5c0c39d26f6e6ab0fc6623cd24913dbf150",
- "blockHash":"0xb5903854b196abb9b7d1e3c2f5f8f9519b4fedefc21d72f3d92c74f128afcd46",
- "blockNumber":2,
- "transactionIndex":0,
- "confirmations":15,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0xaeab"
- },
- "to":"0xA193E42526F1FEA8C99AF609dcEabf30C1c29fAA",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":1,
- "data":"0x9b2ea4bd000000000000000000000000000000000000000000000000000000000000004000000000000000000000000063fc2ad3d021a4d7e64323529a55a9442c444da0000000000000000000000000000000000000000000000000000000000000000d4f564d5f53657175656e63657200000000000000000000000000000000000000",
- "r":"0x530be666add21a30fe9a0fadee8072d4d8ccb2b80a9fe07c7e0591c5a1e5f375",
- "s":"0x5954b17cd0f6299ee54f20853bcfdfc870f2fc271f0433fd592b8b0fc0329aa4",
- "v":62709,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x7504e7104a2d80e810758c1cc2736028ffe5632a2ec988da740c93b3cfa03945",
- "parentHash":"0xb5903854b196abb9b7d1e3c2f5f8f9519b4fedefc21d72f3d92c74f128afcd46",
- "number":3,
- "timestamp":1603404104,
- "nonce":"0x0000000000000042",
- "difficulty":131200,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x79f4dc191018a37a8b71b4a5aff02ce501b0341fc72708c8095845e61be15c02",
- "blockHash":"0x7504e7104a2d80e810758c1cc2736028ffe5632a2ec988da740c93b3cfa03945",
- "blockNumber":3,
- "transactionIndex":0,
- "confirmations":14,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0xafb0"
- },
- "to":"0xA193E42526F1FEA8C99AF609dcEabf30C1c29fAA",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":2,
- "data":"0x9b2ea4bd0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000420000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000224f564d5f4465636f6d7072657373696f6e507265636f6d70696c6541646472657373000000000000000000000000000000000000000000000000000000000000",
- "r":"0x388b6b7e4fe10128e92507042971b864edd535d8f3cb70c61247daed1dc734c1",
- "s":"0x6ad11366b26fa59ce73bc73fa320560f46ffb6df3142adbd16ebce0bcc3ba9f5",
- "v":62710,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x6587aa5da64944673741bdd3299c0d2471c2fdbfcd94713d511ab7240d127bbb",
- "parentHash":"0x7504e7104a2d80e810758c1cc2736028ffe5632a2ec988da740c93b3cfa03945",
- "number":4,
- "timestamp":1603404105,
- "nonce":"0x0000000000000042",
- "difficulty":131264,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x0584fbd34096ffc0fc96dbdf1d8ee574c3eda9e07bf85aed9862542416b1a007",
- "blockHash":"0x6587aa5da64944673741bdd3299c0d2471c2fdbfcd94713d511ab7240d127bbb",
- "blockNumber":4,
- "transactionIndex":0,
- "confirmations":13,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02e294"
- },
- "to":null,
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":3,
- "data":"0x608060405234801561001057600080fd5b50600080546001600160a01b03191633179055610213806100326000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063776d1a0114610077575b60015460408051602036601f8101829004820283018201909352828252610075936001600160a01b0316926000918190840183828082843760009201919091525061009d92505050565b005b6100756004803603602081101561008d57600080fd5b50356001600160a01b031661015d565b60006060836001600160a01b0316836040518082805190602001908083835b602083106100db5780518252601f1990920191602091820191016100bc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461013d576040519150601f19603f3d011682016040523d82523d6000602084013e610142565b606091505b5091509150811561015557805160208201f35b805160208201fd5b6000546001600160a01b031633141561019057600180546001600160a01b0319166001600160a01b0383161790556101da565b60015460408051602036601f81018290048202830182019093528282526101da936001600160a01b0316926000918190840183828082843760009201919091525061009d92505050565b5056fea2646970667358221220293887d48c4c1c34de868edf3e9a6be82327946c76d71f7c2023e67f556c6ecb64736f6c63430007000033",
- "r":"0x2e420851664bb81c0d5d0bd1a805661fc1f83922b92e1d9e0e57c9184eddec0e",
- "s":"0x5e00184c9b50ed54e714231af904caed92cf47ee309fc3604793d7d32a9f4988",
- "v":62709,
- "creates":"0x94BA4d5Ebb0e05A50e977FFbF6e1a1Ee3D89299c",
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x7a215669ab018e508473ef76b42d19cc4228cc5cc855089dc04cb22555fcf555",
- "parentHash":"0x6587aa5da64944673741bdd3299c0d2471c2fdbfcd94713d511ab7240d127bbb",
- "number":5,
- "timestamp":1603404106,
- "nonce":"0x0000000000000042",
- "difficulty":131328,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0xc8243d8b9bf79624f8930527a983be3581cb7d969ae76d3e5962f9db2be7b71a",
- "blockHash":"0x7a215669ab018e508473ef76b42d19cc4228cc5cc855089dc04cb22555fcf555",
- "blockNumber":5,
- "transactionIndex":0,
- "confirmations":12,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0xa93c"
- },
- "to":"0x94BA4d5Ebb0e05A50e977FFbF6e1a1Ee3D89299c",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":4,
- "data":"0x776d1a01000000000000000000000000e9a9a643588daa154de182f88a5b04e8745909c2",
- "r":"0x2de73fc5aec124cc9cf0fa54fc8492692a48b8921a32d31f46f5d431fdeea7a0",
- "s":"0x4e813ae50bc7705fb023d79429ed6cc92367cb5209460e6ea3904c014b06cd4d",
- "v":62709,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0xb4c01e6e867856dce9b451ba67273f86bdc584ff398ed5b8c46f70ea37b1002f",
- "parentHash":"0x7a215669ab018e508473ef76b42d19cc4228cc5cc855089dc04cb22555fcf555",
- "number":6,
- "timestamp":1603404107,
- "nonce":"0x0000000000000042",
- "difficulty":131392,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0xa5bf13c2638f1d99a26c4c7d867f1bc64a34ebf141524b35840c879536e69d69",
- "blockHash":"0xb4c01e6e867856dce9b451ba67273f86bdc584ff398ed5b8c46f70ea37b1002f",
- "blockNumber":6,
- "transactionIndex":0,
- "confirmations":11,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0xaeff"
- },
- "to":"0xA193E42526F1FEA8C99AF609dcEabf30C1c29fAA",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":5,
- "data":"0x9b2ea4bd000000000000000000000000000000000000000000000000000000000000004000000000000000000000000094ba4d5ebb0e05a50e977ffbf6e1a1ee3d89299c00000000000000000000000000000000000000000000000000000000000000144f564d5f457865637574696f6e4d616e61676572000000000000000000000000",
- "r":"0x42a7ca8603050e58d948df4573374746fabc8542c3fabc1d3b03391c2e50ae3b",
- "s":"0x99b52df93bddbd15393ec9b6649c569ec9f65b1e7dda62b7a81baf32bd951a36",
- "v":62709,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x9f8a3aae03d0f8f769d5af64583c1ee32458bd5b63bf6436147e624ef3297c69",
- "parentHash":"0xb4c01e6e867856dce9b451ba67273f86bdc584ff398ed5b8c46f70ea37b1002f",
- "number":7,
- "timestamp":1603404108,
- "nonce":"0x0000000000000042",
- "difficulty":131456,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x967c90bfcb19090f0b73b0d0ca4d5f866160d7628d84412fada18abc50e3da69",
- "blockHash":"0x9f8a3aae03d0f8f769d5af64583c1ee32458bd5b63bf6436147e624ef3297c69",
- "blockNumber":7,
- "transactionIndex":0,
- "confirmations":10,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02e294"
- },
- "to":null,
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":6,
- "data":"0x608060405234801561001057600080fd5b50600080546001600160a01b03191633179055610213806100326000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063776d1a0114610077575b60015460408051602036601f8101829004820283018201909352828252610075936001600160a01b0316926000918190840183828082843760009201919091525061009d92505050565b005b6100756004803603602081101561008d57600080fd5b50356001600160a01b031661015d565b60006060836001600160a01b0316836040518082805190602001908083835b602083106100db5780518252601f1990920191602091820191016100bc565b6001836020036101000a0380198251168184511680821785525050505050509050019150506000604051808303816000865af19150503d806000811461013d576040519150601f19603f3d011682016040523d82523d6000602084013e610142565b606091505b5091509150811561015557805160208201f35b805160208201fd5b6000546001600160a01b031633141561019057600180546001600160a01b0319166001600160a01b0383161790556101da565b60015460408051602036601f81018290048202830182019093528282526101da936001600160a01b0316926000918190840183828082843760009201919091525061009d92505050565b5056fea2646970667358221220293887d48c4c1c34de868edf3e9a6be82327946c76d71f7c2023e67f556c6ecb64736f6c63430007000033",
- "r":"0x16f49916bda30884d49df7f83c60ca49899fd21311e4cd4b464ac52bfa722b40",
- "s":"0x3a2873207cbcba218ff71bb7e3916ea809c393c2407c03a70bbf4e393cbebfcb",
- "v":62709,
- "creates":"0x956dA338C1518a7FB213042b70c60c021aeBd554",
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x808315e40a80d00bf171b8ba924b451fb7936d446177c9e3545303b2ef830801",
- "parentHash":"0x9f8a3aae03d0f8f769d5af64583c1ee32458bd5b63bf6436147e624ef3297c69",
- "number":8,
- "timestamp":1603404109,
- "nonce":"0x0000000000000042",
- "difficulty":131520,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x3dabdb84873e50c3b26df28ead1c053451a340b20d945a8cf8bddf5b5ff11775",
- "blockHash":"0x808315e40a80d00bf171b8ba924b451fb7936d446177c9e3545303b2ef830801",
- "blockNumber":8,
- "transactionIndex":0,
- "confirmations":9,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0xa93c"
- },
- "to":"0x956dA338C1518a7FB213042b70c60c021aeBd554",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":7,
- "data":"0x776d1a01000000000000000000000000048b45c16e9631d3f630106c6086ec21a30cdf60",
- "r":"0x553525e3656dfb41299a9f2a0d1a0058445e017bb98992de6d9b762203cf975a",
- "s":"0x74b9f344513fa2881cfcec5a4c20027bb905de5c52a8e584da6767d946cd465d",
- "v":62710,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0xed13ac7f6bf594309a325c1558e4a3032f745e66ee0ffc2f95a701562b53dd13",
- "parentHash":"0x808315e40a80d00bf171b8ba924b451fb7936d446177c9e3545303b2ef830801",
- "number":9,
- "timestamp":1603404110,
- "nonce":"0x0000000000000042",
- "difficulty":131584,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x2b9e216b390804c731f3ffc0630e522865bff35d0c539f377d204e94a346eddd",
- "blockHash":"0xed13ac7f6bf594309a325c1558e4a3032f745e66ee0ffc2f95a701562b53dd13",
- "blockNumber":9,
- "transactionIndex":0,
- "confirmations":8,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0xaf2f"
- },
- "to":"0xA193E42526F1FEA8C99AF609dcEabf30C1c29fAA",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":8,
- "data":"0x9b2ea4bd0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000956da338c1518a7fb213042b70c60c021aebd55400000000000000000000000000000000000000000000000000000000000000184f564d5f5374617465436f6d6d69746d656e74436861696e0000000000000000",
- "r":"0x6318ce7714d7aefc9add30ebcf9d657a01b50c308c689c6f7d5567d806b6914e",
- "s":"0xfe4d90d895f4b18b89309d768a383334bf5d622d367051079ac0e401b23960e0",
- "v":62709,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x65f3831f69d1e746f30d07a3def1eefdcc6650ee0714cbac795c2be3ce9430a2",
- "parentHash":"0xed13ac7f6bf594309a325c1558e4a3032f745e66ee0ffc2f95a701562b53dd13",
- "number":10,
- "timestamp":1603404111,
- "nonce":"0x0000000000000042",
- "difficulty":131648,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0xa77aca829b5bc91a16c11efb4dee280345851fccbd83b1469f746349894a46ab",
- "blockHash":"0x65f3831f69d1e746f30d07a3def1eefdcc6650ee0714cbac795c2be3ce9430a2",
- "blockNumber":10,
- "transactionIndex":0,
- "confirmations":7,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x24f27e"
- },
- "to":null,
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":9,
- "data":"0x12345678",
- "r":"0x06e79a060942823dc5b328a5b059b58cf42372c03617122139deb5b7844c043d",
- "s":"0xfabd07fab3f36816397917ae8c048a4675d34d4ca3f7b06ca6595796a159d359",
- "v":62710,
- "creates":"0x6454C9d69a4721feBA60e26A367bD4D56196Ee7c",
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x709bb2a24ac6120a12bf56e806cfcf3ceab71a41408b0685892800eebc4e3a45",
- "parentHash":"0x65f3831f69d1e746f30d07a3def1eefdcc6650ee0714cbac795c2be3ce9430a2",
- "number":11,
- "timestamp":1603404112,
- "nonce":"0x0000000000000042",
- "difficulty":131712,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x2b5cd67036954f3c4cce09951c076adb3d0517750167e712562abba7910bd536",
- "blockHash":"0x709bb2a24ac6120a12bf56e806cfcf3ceab71a41408b0685892800eebc4e3a45",
- "blockNumber":11,
- "transactionIndex":0,
- "confirmations":6,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x0f4240"
- },
- "to":"0x6454C9d69a4721feBA60e26A367bD4D56196Ee7c",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":10,
- "data":"0x6fee07e00000000000000000000000000101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000c350000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000201111111111111111111111111111111111111111111111111111111111111111",
- "r":"0x7538f2153c482a762f133f1438b30c8874887f6da52f04adeba5cc65632ee661",
- "s":"0x3dc3a219d164b159ad61f874ccb5c75766cb1d73954196eaba142d890b299d0e",
- "v":62710,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x13e683738bac942ae739e45b0a0e451b20d7e986d9463a2dac0acf2015e8d09b",
- "parentHash":"0x709bb2a24ac6120a12bf56e806cfcf3ceab71a41408b0685892800eebc4e3a45",
- "number":12,
- "timestamp":1603404113,
- "nonce":"0x0000000000000042",
- "difficulty":131776,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x339282191d55c5b9fc53d68f199c53ea9b946c9975ed34f15312acd8a70054f7",
- "blockHash":"0x13e683738bac942ae739e45b0a0e451b20d7e986d9463a2dac0acf2015e8d09b",
- "blockNumber":12,
- "transactionIndex":0,
- "confirmations":5,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x0f4240"
- },
- "to":"0x6454C9d69a4721feBA60e26A367bD4D56196Ee7c",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":11,
- "data":"0x6fee07e00000000000000000000000000101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000c350000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000202222222222222222222222222222222222222222222222222222222222222222",
- "r":"0x4ab1b83146fbfa4f0cce0110149c2c52e57971ce7cbe5b97a3fd3086bf9f0935",
- "s":"0x11dac6b6c1e1d66a89d833ddd230120e6ecdedf49ae9fb38496f4385cb80057d",
- "v":62709,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x382c468636dafe28d7b3aad0f0521c2e7b9395fc0146b16502d85fa2a49ffe7b",
- "parentHash":"0x13e683738bac942ae739e45b0a0e451b20d7e986d9463a2dac0acf2015e8d09b",
- "number":13,
- "timestamp":1603404114,
- "nonce":"0x0000000000000042",
- "difficulty":131840,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x8c260f877daaaaeba12b41da6763ce2a641a55ec2e545c4dcbc211b340480e93",
- "blockHash":"0x382c468636dafe28d7b3aad0f0521c2e7b9395fc0146b16502d85fa2a49ffe7b",
- "blockNumber":13,
- "transactionIndex":0,
- "confirmations":4,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x0f4240"
- },
- "to":"0x6454C9d69a4721feBA60e26A367bD4D56196Ee7c",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":12,
- "data":"0x6fee07e00000000000000000000000000101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000c350000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000203333333333333333333333333333333333333333333333333333333333333333",
- "r":"0x52f5316fc04aafc95110ac6be222ed656cd0a4ace50fac3e09384408c8b7e32a",
- "s":"0x03de7779650526057629e842c45017cfd2dc19137d309cd99f244c0ce9b13186",
- "v":62709,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x5e5f592a3c96a45bc7fceea8681d066af84709dc155d305fe4e3d68f0bb7bd63",
- "parentHash":"0x382c468636dafe28d7b3aad0f0521c2e7b9395fc0146b16502d85fa2a49ffe7b",
- "number":14,
- "timestamp":1603404115,
- "nonce":"0x0000000000000042",
- "difficulty":131904,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x2fbd6a3a19c6e5778762619ecfd849b4c3beb35bce0c99b1f357077f3380fa9e",
- "blockHash":"0x5e5f592a3c96a45bc7fceea8681d066af84709dc155d305fe4e3d68f0bb7bd63",
- "blockNumber":14,
- "transactionIndex":0,
- "confirmations":3,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x0f4240"
- },
- "to":"0x6454C9d69a4721feBA60e26A367bD4D56196Ee7c",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":13,
- "data":"0x6fee07e00000000000000000000000000101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000c350000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000204444444444444444444444444444444444444444444444444444444444444444",
- "r":"0x546c5a59b1753dd9b9f1f7ff0ae10f6f7fe07bfadf9882e140a021b0ca1a8ab4",
- "s":"0x8b6c62b492ea8cf8e7dc8e8236ce7283a24e18370ce7950bda5f450fb7993547",
- "v":62709,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- },
- {
- "hash":"0x13be1ecbdbaae00332acaa341ea3168781b112e7aff368a8bab060fa102085f4",
- "parentHash":"0x5e5f592a3c96a45bc7fceea8681d066af84709dc155d305fe4e3d68f0bb7bd63",
- "number":15,
- "timestamp":1603404116,
- "nonce":"0x0000000000000042",
- "difficulty":131968,
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x02625a00"
- },
- "gasUsed":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "miner":"0xC014BA5EC014ba5ec014Ba5EC014ba5Ec014bA5E",
- "extraData":"0x",
- "transactions":[
- {
- "hash":"0x3a60f459be600341f831b6e9b6b75a242cd31d1e4ae6b0bbd763a6b56054ef7b",
- "blockHash":"0x13be1ecbdbaae00332acaa341ea3168781b112e7aff368a8bab060fa102085f4",
- "blockNumber":15,
- "transactionIndex":0,
- "confirmations":2,
- "from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff",
- "gasPrice":{
- "type":"BigNumber",
- "hex":"0x01dcd65000"
- },
- "gasLimit":{
- "type":"BigNumber",
- "hex":"0x0f4240"
- },
- "to":"0x6454C9d69a4721feBA60e26A367bD4D56196Ee7c",
- "value":{
- "type":"BigNumber",
- "hex":"0x00"
- },
- "nonce":14,
- "data":"0x6fee07e00000000000000000000000000101010101010101010101010101010101010101000000000000000000000000000000000000000000000000000000000000c350000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000205555555555555555555555555555555555555555555555555555555555555555",
- "r":"0x3b214ae35181aaf5542f970325ef36ca881db2fc1b145524534a4fb6885b05d7",
- "s":"0xdf4fd847db5d5a246f4cedd2dee14e15e70ff469a7d88cdc86efa7c6d61d7cad",
- "v":62709,
- "creates":null,
- "l1BlockNumber":"1",
- "l1TxOrigin":"0x3333333333333333333333333333333333333333",
- "rawTransaction":"0x420420",
- "signatureHashType":"0",
- "queueOrigin":"sequencer",
- "chainId":31337
- }
- ]
- }
- ]
-`)
diff --git a/packages/batch-submitter/test/helpers/constants.ts b/packages/batch-submitter/test/helpers/constants.ts
deleted file mode 100644
index a197c8f50c461..0000000000000
--- a/packages/batch-submitter/test/helpers/constants.ts
+++ /dev/null
@@ -1,14 +0,0 @@
-/* External Imports */
-import { defaultAccounts } from 'ethereum-waffle'
-
-export const FORCE_INCLUSION_PERIOD_SECONDS = 600
-export const DEFAULT_ACCOUNTS = defaultAccounts
-export const DEFAULT_ACCOUNTS_HARDHAT = defaultAccounts.map((account) => {
- return {
- balance: account.balance,
- privateKey: account.secretKey,
- }
-})
-
-export const OVM_TX_GAS_LIMIT = 10_000_000
-export const RUN_OVM_TEST_GAS = 20_000_000
diff --git a/packages/batch-submitter/test/helpers/dummy/bytecode.ts b/packages/batch-submitter/test/helpers/dummy/bytecode.ts
deleted file mode 100644
index 7388c78ad87cd..0000000000000
--- a/packages/batch-submitter/test/helpers/dummy/bytecode.ts
+++ /dev/null
@@ -1,6 +0,0 @@
-/* External Imports */
-import { keccak256 } from 'ethers/lib/utils'
-
-export const DUMMY_BYTECODE = '0x123412341234'
-export const DUMMY_BYTECODE_BYTELEN = 6
-export const DUMMY_BYTECODE_HASH = keccak256(DUMMY_BYTECODE)
diff --git a/packages/batch-submitter/test/helpers/dummy/bytes32.ts b/packages/batch-submitter/test/helpers/dummy/bytes32.ts
deleted file mode 100644
index 070ac1a0f2fd7..0000000000000
--- a/packages/batch-submitter/test/helpers/dummy/bytes32.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-/* External Imports */
-import { ethers } from 'ethers'
-
-export const DUMMY_BYTES32: string[] = Array.from(
- {
- length: 10,
- },
- (_, i) => {
- return ethers.utils.keccak256(`0x0${i}`)
- }
-)
diff --git a/packages/batch-submitter/test/helpers/dummy/index.ts b/packages/batch-submitter/test/helpers/dummy/index.ts
deleted file mode 100644
index f0e9687669436..0000000000000
--- a/packages/batch-submitter/test/helpers/dummy/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from './bytes32'
-export * from './bytecode'
diff --git a/packages/batch-submitter/test/helpers/index.ts b/packages/batch-submitter/test/helpers/index.ts
deleted file mode 100644
index 0473fe33e25ef..0000000000000
--- a/packages/batch-submitter/test/helpers/index.ts
+++ /dev/null
@@ -1,3 +0,0 @@
-export * from './dummy'
-export * from './constants'
-export * from './resolver'
diff --git a/packages/batch-submitter/test/helpers/resolver/address-manager.ts b/packages/batch-submitter/test/helpers/resolver/address-manager.ts
deleted file mode 100644
index 41716acae9fc5..0000000000000
--- a/packages/batch-submitter/test/helpers/resolver/address-manager.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-/* External Imports */
-import { ethers } from 'hardhat'
-import { Contract } from 'ethers'
-import { getContractFactory as ctFactory } from 'old-contracts'
-
-export const getContractFactory = async (contract: string) =>
- ctFactory(contract, (await ethers.getSigners())[0])
-
-export const setProxyTarget = async (
- AddressManager: Contract,
- name: string,
- target: Contract
-): Promise => {
- const SimpleProxy: Contract = await (
- await getContractFactory('Helper_SimpleProxy')
- ).deploy()
-
- await SimpleProxy.setTarget(target.address)
- await AddressManager.setAddress(name, SimpleProxy.address)
-}
-
-export const makeAddressManager = async (): Promise => {
- return (await getContractFactory('Lib_AddressManager')).deploy()
-}
diff --git a/packages/batch-submitter/test/helpers/resolver/index.ts b/packages/batch-submitter/test/helpers/resolver/index.ts
deleted file mode 100644
index 52516689c177d..0000000000000
--- a/packages/batch-submitter/test/helpers/resolver/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './address-manager'
diff --git a/packages/batch-submitter/test/setup.ts b/packages/batch-submitter/test/setup.ts
deleted file mode 100644
index 290684bb3c4d5..0000000000000
--- a/packages/batch-submitter/test/setup.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-/* External Imports */
-import chai = require('chai')
-import sinonChai from 'sinon-chai'
-import Mocha from 'mocha'
-
-const should = chai.should()
-const expect = chai.expect
-chai.use(sinonChai)
-
-export { should, expect, chai, Mocha }
diff --git a/packages/batch-submitter/test/utils/tx-submission.spec.ts b/packages/batch-submitter/test/utils/tx-submission.spec.ts
deleted file mode 100644
index 756b7afe67b78..0000000000000
--- a/packages/batch-submitter/test/utils/tx-submission.spec.ts
+++ /dev/null
@@ -1,165 +0,0 @@
-import { ethers, BigNumber, Signer } from 'ethers'
-import {
- TransactionReceipt,
- TransactionResponse,
-} from '@ethersproject/abstract-provider'
-
-import { expect } from '../setup'
-import { submitTransactionWithYNATM } from '../../src/utils/tx-submission'
-import { ResubmissionConfig } from '../../src'
-
-const nullFunction = () => undefined
-const nullHooks = {
- beforeSendTransaction: nullFunction,
- onTransactionResponse: nullFunction,
-}
-
-describe('submitTransactionWithYNATM', async () => {
- it('calls sendTransaction, waitForTransaction, and hooks with correct inputs', async () => {
- const called = {
- sendTransaction: false,
- waitForTransaction: false,
- beforeSendTransaction: false,
- onTransactionResponse: false,
- }
- const dummyHash = 'dummy hash'
- const numConfirmations = 3
- const tx = {
- data: 'we here though',
- } as ethers.PopulatedTransaction
- const sendTransaction = async (
- _tx: ethers.PopulatedTransaction
- ): Promise => {
- called.sendTransaction = true
- expect(_tx.data).to.equal(tx.data)
- return {
- hash: dummyHash,
- } as TransactionResponse
- }
- const waitForTransaction = async (
- hash: string,
- _numConfirmations: number
- ): Promise => {
- called.waitForTransaction = true
- expect(hash).to.equal(dummyHash)
- expect(_numConfirmations).to.equal(numConfirmations)
- return {
- to: '',
- from: '',
- status: 1,
- } as TransactionReceipt
- }
- const signer = {
- getGasPrice: async () => ethers.BigNumber.from(0),
- sendTransaction,
- provider: {
- waitForTransaction,
- },
- } as Signer
- const hooks = {
- beforeSendTransaction: (submittingTx: ethers.PopulatedTransaction) => {
- called.beforeSendTransaction = true
- expect(submittingTx.data).to.equal(tx.data)
- },
- onTransactionResponse: (txResponse: TransactionResponse) => {
- called.onTransactionResponse = true
- expect(txResponse.hash).to.equal(dummyHash)
- },
- }
- const config: ResubmissionConfig = {
- resubmissionTimeout: 1000,
- minGasPriceInGwei: 0,
- maxGasPriceInGwei: 0,
- gasRetryIncrement: 1,
- }
- await submitTransactionWithYNATM(
- tx,
- signer,
- config,
- numConfirmations,
- hooks
- )
- expect(called.sendTransaction).to.be.true
- expect(called.waitForTransaction).to.be.true
- expect(called.beforeSendTransaction).to.be.true
- expect(called.onTransactionResponse).to.be.true
- })
-
- it('repeatedly increases the gas limit of the transaction when wait takes too long', async () => {
- // Make transactions take longer to be included
- // than our resubmission timeout
- const resubmissionTimeout = 100
- const txReceiptDelay = resubmissionTimeout * 3
- let lastGasPrice = BigNumber.from(0)
- // Create a transaction which has a gas price that we will watch increment
- const tx = {
- gasPrice: lastGasPrice.add(1),
- data: 'hello world!',
- } as ethers.PopulatedTransaction
- const sendTransaction = async (
- _tx: ethers.PopulatedTransaction
- ): Promise => {
- // Ensure the gas price is always increasing
- expect(_tx.gasPrice > lastGasPrice).to.be.true
- lastGasPrice = _tx.gasPrice
- return {
- hash: 'dummy hash',
- } as TransactionResponse
- }
- const waitForTransaction = async (): Promise => {
- await new Promise((r) => setTimeout(r, txReceiptDelay))
- return {} as TransactionReceipt
- }
- const signer = {
- getGasPrice: async () => ethers.BigNumber.from(0),
- sendTransaction,
- provider: {
- waitForTransaction: waitForTransaction as any,
- },
- } as Signer
- const config: ResubmissionConfig = {
- resubmissionTimeout,
- minGasPriceInGwei: 0,
- maxGasPriceInGwei: 1000,
- gasRetryIncrement: 1,
- }
- await submitTransactionWithYNATM(tx, signer, config, 0, nullHooks)
- })
-
- it('should immediately reject if a nonce error is encountered', async () => {
- const tx = {
- gasPrice: BigNumber.from(1),
- data: 'hello world!',
- } as ethers.PopulatedTransaction
-
- let txCount = 0
- const waitForTransaction = async (): Promise => {
- return {} as TransactionReceipt
- }
- const sendTransaction = async () => {
- txCount++
- throw new Error('Transaction nonce is too low.')
- }
- const signer = {
- getGasPrice: async () => BigNumber.from(1),
- sendTransaction: sendTransaction as any,
- provider: {
- waitForTransaction: waitForTransaction as any,
- },
- } as Signer
-
- const config: ResubmissionConfig = {
- resubmissionTimeout: 100,
- minGasPriceInGwei: 0,
- maxGasPriceInGwei: 1000,
- gasRetryIncrement: 1,
- }
- try {
- await submitTransactionWithYNATM(tx, signer, config, 0, nullHooks)
- } catch (e) {
- expect(txCount).to.equal(1)
- return
- }
- expect.fail('Expected an error.')
- })
-})
diff --git a/packages/batch-submitter/tsconfig.build.json b/packages/batch-submitter/tsconfig.build.json
deleted file mode 100644
index dcd3fe90606d7..0000000000000
--- a/packages/batch-submitter/tsconfig.build.json
+++ /dev/null
@@ -1,11 +0,0 @@
-{
- "extends": "../../tsconfig.build.json",
-
- "compilerOptions": {
- "outDir": "./dist"
- },
-
- "include": [
- "src/**/*"
- ]
-}
diff --git a/packages/batch-submitter/tsconfig.json b/packages/batch-submitter/tsconfig.json
deleted file mode 100644
index 578447f2ea578..0000000000000
--- a/packages/batch-submitter/tsconfig.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "extends": "../../tsconfig.json",
- "compilerOptions": {
- "resolveJsonModule": true
- }
-}
diff --git a/yarn.lock b/yarn.lock
index ce81c8d2d276f..39181d7466042 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -514,28 +514,6 @@
"@eth-optimism/core-utils" "^0.5.1"
bn.js "^5.2.0"
-"@eth-optimism/solc@^0.6.12-alpha.1":
- version "0.6.12-alpha.1"
- resolved "https://registry.yarnpkg.com/@eth-optimism/solc/-/solc-0.6.12-alpha.1.tgz#041876f83b34c6afe2f19dfe9626568df6ed8590"
- integrity sha512-Ky73mo+2iNJs/VTaT751nMeZ7hXns0TBAlffTOxIOsScjAZ/zi/KWsDUo3r89aV2JKXcYAU/bLidxF40MVJeUw==
- dependencies:
- command-exists "^1.2.8"
- commander "3.0.2"
- follow-redirects "^1.12.1"
- fs-extra "^0.30.0"
- js-sha3 "0.8.0"
- memorystream "^0.3.1"
- require-from-string "^2.0.0"
- semver "^5.5.0"
- tmp "0.0.33"
-
-"@eth-optimism/ynatm@^0.2.2":
- version "0.2.2"
- resolved "https://registry.yarnpkg.com/@eth-optimism/ynatm/-/ynatm-0.2.2.tgz#b1f165c3149188f184b66329228746260ae18677"
- integrity sha512-R/hIAFWEj2sjf3inNEGCffmGofqMFY/7PS/Hh4A/62Kg0wMM8rsyMyW8pXngMnD/EQAjR8WTtKDutq/L5vSMTQ==
- dependencies:
- bluebird "^3.7.2"
-
"@ethereum-waffle/chai@^3.4.0":
version "3.4.0"
resolved "https://registry.yarnpkg.com/@ethereum-waffle/chai/-/chai-3.4.0.tgz#2477877410a96bf370edd64df905b04fb9aba9d5"
@@ -689,7 +667,7 @@
"@ethersproject/properties" "^5.0.3"
"@ethersproject/strings" "^5.0.4"
-"@ethersproject/abi@5.4.0", "@ethersproject/abi@^5.0.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.1", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.4.0":
+"@ethersproject/abi@5.4.0", "@ethersproject/abi@^5.0.0-beta.146", "@ethersproject/abi@^5.0.1", "@ethersproject/abi@^5.1.2", "@ethersproject/abi@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/abi/-/abi-5.4.0.tgz#a6d63bdb3672f738398846d4279fa6b6c9818242"
integrity sha512-9gU2H+/yK1j2eVMdzm6xvHSnMxk8waIHQGYCZg5uvAyH0rsAzxkModzBSpbAkAuhKFEovC2S9hM4nPuLym8IZw==
@@ -734,7 +712,7 @@
"@ethersproject/properties" "^5.4.0"
"@ethersproject/strings" "^5.4.0"
-"@ethersproject/abstract-provider@5.4.1", "@ethersproject/abstract-provider@^5.0.0", "@ethersproject/abstract-provider@^5.4.0", "@ethersproject/abstract-provider@^5.4.1":
+"@ethersproject/abstract-provider@5.4.1", "@ethersproject/abstract-provider@^5.4.0", "@ethersproject/abstract-provider@^5.4.1":
version "5.4.1"
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-provider/-/abstract-provider-5.4.1.tgz#e404309a29f771bd4d28dbafadcaa184668c2a6e"
integrity sha512-3EedfKI3LVpjSKgAxoUaI+gB27frKsxzm+r21w9G60Ugk+3wVLQwhi1LsEJAKNV7WoZc8CIpNrATlL1QFABjtQ==
@@ -760,7 +738,7 @@
"@ethersproject/transactions" "^5.5.0"
"@ethersproject/web" "^5.5.0"
-"@ethersproject/abstract-signer@5.4.1", "@ethersproject/abstract-signer@^5.0.0", "@ethersproject/abstract-signer@^5.4.0", "@ethersproject/abstract-signer@^5.4.1":
+"@ethersproject/abstract-signer@5.4.1", "@ethersproject/abstract-signer@^5.4.0", "@ethersproject/abstract-signer@^5.4.1":
version "5.4.1"
resolved "https://registry.yarnpkg.com/@ethersproject/abstract-signer/-/abstract-signer-5.4.1.tgz#e4e9abcf4dd4f1ba0db7dff9746a5f78f355ea81"
integrity sha512-SkkFL5HVq1k4/25dM+NWP9MILgohJCgGv5xT5AcRruGz4ILpfHeBtO/y6j+Z3UN/PAjDeb4P7E51Yh8wcGNLGA==
@@ -782,7 +760,7 @@
"@ethersproject/logger" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
-"@ethersproject/address@5.4.0", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.0", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.4.0":
+"@ethersproject/address@5.4.0", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.2", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.4.0.tgz#ba2d00a0f8c4c0854933b963b9a3a9f6eb4a37a3"
integrity sha512-SD0VgOEkcACEG/C6xavlU1Hy3m5DGSXW3CUHkaaEHbAPPsgi0coP5oNPsxau8eTlZOk/bpa/hKeCNoK5IzVI2Q==
@@ -804,7 +782,7 @@
"@ethersproject/logger" "^5.5.0"
"@ethersproject/rlp" "^5.5.0"
-"@ethersproject/base64@5.4.0", "@ethersproject/base64@^5.0.0", "@ethersproject/base64@^5.4.0":
+"@ethersproject/base64@5.4.0", "@ethersproject/base64@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/base64/-/base64-5.4.0.tgz#7252bf65295954c9048c7ca5f43e5c86441b2a9a"
integrity sha512-CjQw6E17QDSSC5jiM9YpF7N1aSCHmYGMt9bWD8PWv6YPMxjsys2/Q8xLrROKI3IWJ7sFfZ8B3flKDTM5wlWuZQ==
@@ -834,7 +812,7 @@
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/properties" "^5.5.0"
-"@ethersproject/bignumber@5.4.1", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.0", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.4.0":
+"@ethersproject/bignumber@5.4.1", "@ethersproject/bignumber@>=5.0.0-beta.130", "@ethersproject/bignumber@^5.0.7", "@ethersproject/bignumber@^5.4.0":
version "5.4.1"
resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.4.1.tgz#64399d3b9ae80aa83d483e550ba57ea062c1042d"
integrity sha512-fJhdxqoQNuDOk6epfM7yD6J8Pol4NUCy1vkaGAkuujZm0+lNow//MKu1hLhRiYV4BsOHyBv5/lsTjF+7hWwhJg==
@@ -861,7 +839,7 @@
"@ethersproject/logger" "^5.4.0"
bn.js "^4.11.9"
-"@ethersproject/bytes@5.4.0", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.0", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.4.0":
+"@ethersproject/bytes@5.4.0", "@ethersproject/bytes@>=5.0.0-beta.129", "@ethersproject/bytes@^5.0.4", "@ethersproject/bytes@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.4.0.tgz#56fa32ce3bf67153756dbaefda921d1d4774404e"
integrity sha512-H60ceqgTHbhzOj4uRc/83SCN9d+BSUnOkrr2intevqdtEMO1JFVZ1XL84OEZV+QjV36OaZYxtnt4lGmxcGsPfA==
@@ -875,7 +853,7 @@
dependencies:
"@ethersproject/logger" "^5.5.0"
-"@ethersproject/constants@5.4.0", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.0", "@ethersproject/constants@^5.0.4", "@ethersproject/constants@^5.4.0":
+"@ethersproject/constants@5.4.0", "@ethersproject/constants@>=5.0.0-beta.128", "@ethersproject/constants@^5.0.4", "@ethersproject/constants@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/constants/-/constants-5.4.0.tgz#ee0bdcb30bf1b532d2353c977bf2ef1ee117958a"
integrity sha512-tzjn6S7sj9+DIIeKTJLjK9WGN2Tj0P++Z8ONEIlZjyoTkBuODN+0VfhAyYksKi43l1Sx9tX2VlFfzjfmr5Wl3Q==
@@ -889,7 +867,7 @@
dependencies:
"@ethersproject/bignumber" "^5.5.0"
-"@ethersproject/contracts@5.4.1", "@ethersproject/contracts@^5.0.0", "@ethersproject/contracts@^5.0.5", "@ethersproject/contracts@^5.4.1":
+"@ethersproject/contracts@5.4.1", "@ethersproject/contracts@^5.4.1":
version "5.4.1"
resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.4.1.tgz#3eb4f35b7fe60a962a75804ada2746494df3e470"
integrity sha512-m+z2ZgPy4pyR15Je//dUaymRUZq5MtDajF6GwFbGAVmKz/RF+DNIPwF0k5qEcL3wPGVqUjFg2/krlCRVTU4T5w==
@@ -921,18 +899,6 @@
"@ethersproject/properties" "^5.5.0"
"@ethersproject/transactions" "^5.5.0"
-"@ethersproject/hardware-wallets@^5.0.8":
- version "5.4.0"
- resolved "https://registry.yarnpkg.com/@ethersproject/hardware-wallets/-/hardware-wallets-5.4.0.tgz#bce275b395e26b6f50481095331157614490a473"
- integrity sha512-Ea4ymm4etZoSWy93OcEGZkuVqyYdl/RjMlaXY6yQIYjsGi75sm4apbTiBA8DA9uajkv1FVakJZEBBTaVGgnBLA==
- dependencies:
- "@ledgerhq/hw-app-eth" "5.27.2"
- "@ledgerhq/hw-transport" "5.26.0"
- "@ledgerhq/hw-transport-u2f" "5.26.0"
- ethers "^5.4.0"
- optionalDependencies:
- "@ledgerhq/hw-transport-node-hid" "5.26.0"
-
"@ethersproject/hardware-wallets@^5.5.0":
version "5.5.0"
resolved "https://registry.yarnpkg.com/@ethersproject/hardware-wallets/-/hardware-wallets-5.5.0.tgz#b4a3bc99a843c3b78b133cdf94485a567ba17b8d"
@@ -945,7 +911,7 @@
optionalDependencies:
"@ledgerhq/hw-transport-node-hid" "5.26.0"
-"@ethersproject/hash@5.4.0", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.0", "@ethersproject/hash@^5.0.4", "@ethersproject/hash@^5.4.0":
+"@ethersproject/hash@5.4.0", "@ethersproject/hash@>=5.0.0-beta.128", "@ethersproject/hash@^5.0.4", "@ethersproject/hash@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/hash/-/hash-5.4.0.tgz#d18a8e927e828e22860a011f39e429d388344ae0"
integrity sha512-xymAM9tmikKgbktOCjW60Z5sdouiIIurkZUr9oW5NOex5uwxrbsYG09kb5bMcNjlVeJD3yPivTNzViIs1GCbqA==
@@ -973,7 +939,7 @@
"@ethersproject/properties" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
-"@ethersproject/hdnode@5.4.0", "@ethersproject/hdnode@^5.0.0", "@ethersproject/hdnode@^5.4.0":
+"@ethersproject/hdnode@5.4.0", "@ethersproject/hdnode@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/hdnode/-/hdnode-5.4.0.tgz#4bc9999b9a12eb5ce80c5faa83114a57e4107cac"
integrity sha512-pKxdS0KAaeVGfZPp1KOiDLB0jba11tG6OP1u11QnYfb7pXn6IZx0xceqWRr6ygke8+Kw74IpOoSi7/DwANhy8Q==
@@ -1009,7 +975,7 @@
"@ethersproject/transactions" "^5.5.0"
"@ethersproject/wordlists" "^5.5.0"
-"@ethersproject/json-wallets@5.4.0", "@ethersproject/json-wallets@^5.0.0", "@ethersproject/json-wallets@^5.4.0":
+"@ethersproject/json-wallets@5.4.0", "@ethersproject/json-wallets@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/json-wallets/-/json-wallets-5.4.0.tgz#2583341cfe313fc9856642e8ace3080154145e95"
integrity sha512-igWcu3fx4aiczrzEHwG1xJZo9l1cFfQOWzTqwRw/xcvxTk58q4f9M7cjh51EKphMHvrJtcezJ1gf1q1AUOfEQQ==
@@ -1047,7 +1013,7 @@
aes-js "3.0.0"
scrypt-js "3.0.1"
-"@ethersproject/keccak256@5.4.0", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.0", "@ethersproject/keccak256@^5.0.3", "@ethersproject/keccak256@^5.4.0":
+"@ethersproject/keccak256@5.4.0", "@ethersproject/keccak256@>=5.0.0-beta.127", "@ethersproject/keccak256@^5.0.3", "@ethersproject/keccak256@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.4.0.tgz#7143b8eea4976080241d2bd92e3b1f1bf7025318"
integrity sha512-FBI1plWet+dPUvAzPAeHzRKiPpETQzqSUWR1wXJGHVWi4i8bOSrpC3NwpkPjgeXG7MnugVc1B42VbfnQikyC/A==
@@ -1063,7 +1029,7 @@
"@ethersproject/bytes" "^5.5.0"
js-sha3 "0.8.0"
-"@ethersproject/logger@5.4.0", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.0", "@ethersproject/logger@^5.0.5", "@ethersproject/logger@^5.4.0":
+"@ethersproject/logger@5.4.0", "@ethersproject/logger@>=5.0.0-beta.129", "@ethersproject/logger@^5.0.5", "@ethersproject/logger@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.4.0.tgz#f39adadf62ad610c420bcd156fd41270e91b3ca9"
integrity sha512-xYdWGGQ9P2cxBayt64d8LC8aPFJk6yWCawQi/4eJ4+oJdMMjEBMrIcIMZ9AxhwpPVmnBPrsB10PcXGmGAqgUEQ==
@@ -1073,7 +1039,7 @@
resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.5.0.tgz#0c2caebeff98e10aefa5aef27d7441c7fd18cf5d"
integrity sha512-rIY/6WPm7T8n3qS2vuHTUBPdXHl+rGxWxW5okDfo9J4Z0+gRRZT0msvUdIJkE4/HS29GUMziwGaaKO2bWONBrg==
-"@ethersproject/networks@5.4.2", "@ethersproject/networks@^5.0.0", "@ethersproject/networks@^5.4.0":
+"@ethersproject/networks@5.4.2", "@ethersproject/networks@^5.4.0":
version "5.4.2"
resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.4.2.tgz#2247d977626e97e2c3b8ee73cd2457babde0ce35"
integrity sha512-eekOhvJyBnuibfJnhtK46b8HimBc5+4gqpvd1/H9LEl7Q7/qhsIhM81dI9Fcnjpk3jB1aTy6bj0hz3cifhNeYw==
@@ -1087,7 +1053,7 @@
dependencies:
"@ethersproject/logger" "^5.5.0"
-"@ethersproject/pbkdf2@5.4.0", "@ethersproject/pbkdf2@^5.0.0", "@ethersproject/pbkdf2@^5.4.0":
+"@ethersproject/pbkdf2@5.4.0", "@ethersproject/pbkdf2@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.4.0.tgz#ed88782a67fda1594c22d60d0ca911a9d669641c"
integrity sha512-x94aIv6tiA04g6BnazZSLoRXqyusawRyZWlUhKip2jvoLpzJuLb//KtMM6PEovE47pMbW+Qe1uw+68ameJjB7g==
@@ -1103,7 +1069,7 @@
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/sha2" "^5.5.0"
-"@ethersproject/properties@5.4.0", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.0", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.4.0":
+"@ethersproject/properties@5.4.0", "@ethersproject/properties@>=5.0.0-beta.131", "@ethersproject/properties@^5.0.3", "@ethersproject/properties@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/properties/-/properties-5.4.0.tgz#38ba20539b44dcc5d5f80c45ad902017dcdbefe7"
integrity sha512-7jczalGVRAJ+XSRvNA6D5sAwT4gavLq3OXPuV/74o3Rd2wuzSL035IMpIMgei4CYyBdialJMrTqkOnzccLHn4A==
@@ -1117,7 +1083,7 @@
dependencies:
"@ethersproject/logger" "^5.5.0"
-"@ethersproject/providers@5.4.4", "@ethersproject/providers@^5.0.0":
+"@ethersproject/providers@5.4.4":
version "5.4.4"
resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.4.4.tgz#6729120317942fc0ab0ecdb35e944ec6bbedb795"
integrity sha512-mQevyXj2X2D3l8p/JGDYFZbODhZjW6On15DnCK4Xc9y6b+P0vqorQC/j46omWSm4cyo7BQ/rgfhXNYmvAfyZoQ==
@@ -1192,7 +1158,7 @@
bech32 "1.1.4"
ws "7.4.6"
-"@ethersproject/random@5.4.0", "@ethersproject/random@^5.0.0", "@ethersproject/random@^5.4.0":
+"@ethersproject/random@5.4.0", "@ethersproject/random@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.4.0.tgz#9cdde60e160d024be39cc16f8de3b9ce39191e16"
integrity sha512-pnpWNQlf0VAZDEOVp1rsYQosmv2o0ITS/PecNw+mS2/btF8eYdspkN0vIXrCMtkX09EAh9bdk8GoXmFXM1eAKw==
@@ -1216,7 +1182,7 @@
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
-"@ethersproject/rlp@5.4.0", "@ethersproject/rlp@^5.0.0", "@ethersproject/rlp@^5.4.0":
+"@ethersproject/rlp@5.4.0", "@ethersproject/rlp@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.4.0.tgz#de61afda5ff979454e76d3b3310a6c32ad060931"
integrity sha512-0I7MZKfi+T5+G8atId9QaQKHRvvasM/kqLyAH4XxBCBchAooH2EX5rL9kYZWwcm3awYV+XC7VF6nLhfeQFKVPg==
@@ -1232,7 +1198,7 @@
"@ethersproject/bytes" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
-"@ethersproject/sha2@5.4.0", "@ethersproject/sha2@^5.0.0", "@ethersproject/sha2@^5.4.0":
+"@ethersproject/sha2@5.4.0", "@ethersproject/sha2@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/sha2/-/sha2-5.4.0.tgz#c9a8db1037014cbc4e9482bd662f86c090440371"
integrity sha512-siheo36r1WD7Cy+bDdE1BJ8y0bDtqXCOxRMzPa4bV1TGt/eTUUt03BHoJNB6reWJD8A30E/pdJ8WFkq+/uz4Gg==
@@ -1250,7 +1216,7 @@
"@ethersproject/logger" "^5.5.0"
hash.js "1.1.7"
-"@ethersproject/signing-key@5.4.0", "@ethersproject/signing-key@^5.0.0", "@ethersproject/signing-key@^5.4.0":
+"@ethersproject/signing-key@5.4.0", "@ethersproject/signing-key@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/signing-key/-/signing-key-5.4.0.tgz#2f05120984e81cf89a3d5f6dec5c68ee0894fbec"
integrity sha512-q8POUeywx6AKg2/jX9qBYZIAmKSB4ubGXdQ88l40hmATj29JnG5pp331nAWwwxPn2Qao4JpWHNZsQN+bPiSW9A==
@@ -1274,7 +1240,7 @@
elliptic "6.5.4"
hash.js "1.1.7"
-"@ethersproject/solidity@5.4.0", "@ethersproject/solidity@^5.0.0", "@ethersproject/solidity@^5.0.9", "@ethersproject/solidity@^5.4.0":
+"@ethersproject/solidity@5.4.0", "@ethersproject/solidity@^5.0.9", "@ethersproject/solidity@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.4.0.tgz#1305e058ea02dc4891df18b33232b11a14ece9ec"
integrity sha512-XFQTZ7wFSHOhHcV1DpcWj7VXECEiSrBuv7JErJvB9Uo+KfCdc3QtUZV+Vjh/AAaYgezUEKbCtE6Khjm44seevQ==
@@ -1297,7 +1263,7 @@
"@ethersproject/sha2" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
-"@ethersproject/strings@5.4.0", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.0", "@ethersproject/strings@^5.0.4", "@ethersproject/strings@^5.4.0":
+"@ethersproject/strings@5.4.0", "@ethersproject/strings@>=5.0.0-beta.130", "@ethersproject/strings@^5.0.4", "@ethersproject/strings@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/strings/-/strings-5.4.0.tgz#fb12270132dd84b02906a8d895ae7e7fa3d07d9a"
integrity sha512-k/9DkH5UGDhv7aReXLluFG5ExurwtIpUfnDNhQA29w896Dw3i4uDTz01Quaptbks1Uj9kI8wo9tmW73wcIEaWA==
@@ -1315,7 +1281,7 @@
"@ethersproject/constants" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
-"@ethersproject/transactions@5.4.0", "@ethersproject/transactions@^5.0.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.4.0":
+"@ethersproject/transactions@5.4.0", "@ethersproject/transactions@^5.0.0-beta.135", "@ethersproject/transactions@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/transactions/-/transactions-5.4.0.tgz#a159d035179334bd92f340ce0f77e83e9e1522e0"
integrity sha512-s3EjZZt7xa4BkLknJZ98QGoIza94rVjaEed0rzZ/jB9WrIuu/1+tjvYCWzVrystXtDswy7TPBeIepyXwSYa4WQ==
@@ -1345,7 +1311,7 @@
"@ethersproject/rlp" "^5.5.0"
"@ethersproject/signing-key" "^5.5.0"
-"@ethersproject/units@5.4.0", "@ethersproject/units@^5.0.0":
+"@ethersproject/units@5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/units/-/units-5.4.0.tgz#d57477a4498b14b88b10396062c8cbbaf20c79fe"
integrity sha512-Z88krX40KCp+JqPCP5oPv5p750g+uU6gopDYRTBGcDvOASh6qhiEYCRatuM/suC4S2XW9Zz90QI35MfSrTIaFg==
@@ -1363,7 +1329,7 @@
"@ethersproject/constants" "^5.5.0"
"@ethersproject/logger" "^5.5.0"
-"@ethersproject/wallet@5.4.0", "@ethersproject/wallet@^5.0.0", "@ethersproject/wallet@^5.4.0":
+"@ethersproject/wallet@5.4.0", "@ethersproject/wallet@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/wallet/-/wallet-5.4.0.tgz#fa5b59830b42e9be56eadd45a16a2e0933ad9353"
integrity sha512-wU29majLjM6AjCjpat21mPPviG+EpK7wY1+jzKD0fg3ui5fgedf2zEu1RDgpfIMsfn8fJHJuzM4zXZ2+hSHaSQ==
@@ -1405,7 +1371,7 @@
"@ethersproject/transactions" "^5.5.0"
"@ethersproject/wordlists" "^5.5.0"
-"@ethersproject/web@5.4.0", "@ethersproject/web@^5.0.0", "@ethersproject/web@^5.4.0":
+"@ethersproject/web@5.4.0", "@ethersproject/web@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.4.0.tgz#49fac173b96992334ed36a175538ba07a7413d1f"
integrity sha512-1bUusGmcoRLYgMn6c1BLk1tOKUIFuTg8j+6N8lYlbMpDesnle+i3pGSagGNvwjaiLo4Y5gBibwctpPRmjrh4Og==
@@ -1427,7 +1393,7 @@
"@ethersproject/properties" "^5.5.0"
"@ethersproject/strings" "^5.5.0"
-"@ethersproject/wordlists@5.4.0", "@ethersproject/wordlists@^5.0.0", "@ethersproject/wordlists@^5.4.0":
+"@ethersproject/wordlists@5.4.0", "@ethersproject/wordlists@^5.4.0":
version "5.4.0"
resolved "https://registry.yarnpkg.com/@ethersproject/wordlists/-/wordlists-5.4.0.tgz#f34205ec3bbc9e2c49cadaee774cf0b07e7573d7"
integrity sha512-FemEkf6a+EBKEPxlzeVgUaVSodU7G0Na89jqKjmWMlDB0tomoU8RlEMgUvXyqtrg8N4cwpLh8nyRnm1Nay1isA==
@@ -2523,11 +2489,6 @@
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.2.tgz#ff80affd6d352dbe1bbc5b4e1833c41afd6283b6"
integrity sha512-AybF1cesONZStg5kWf6ao9OlqTZuPqddvprc0ky7lrUVOjXeKpmQ2Y9FK+6ygxasb+4aic4O5pneFBfwVsRRRg==
-"@openzeppelin/contracts@^3.3.0":
- version "3.4.2"
- resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-3.4.2.tgz#d81f786fda2871d1eb8a8c5a73e455753ba53527"
- integrity sha512-z0zMCjyhhp4y7XKAcDAi3Vgms4T2PstwBdahiO0+9NaGICQKjynK3wduSRplTgk4LXmoO1yfDGO5RbjKYxtuxA==
-
"@openzeppelin/contracts@^4.3.2":
version "4.3.3"
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.3.3.tgz#ff6ee919fc2a1abaf72b22814bfb72ed129ec137"
@@ -2723,20 +2684,13 @@
resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea"
integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==
-"@sinonjs/commons@^1.6.0", "@sinonjs/commons@^1.7.0", "@sinonjs/commons@^1.8.1":
+"@sinonjs/commons@^1.7.0":
version "1.8.3"
resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.3.tgz#3802ddd21a50a949b6721ddd72da36e67e7f1b2d"
integrity sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==
dependencies:
type-detect "4.0.8"
-"@sinonjs/fake-timers@^6.0.0", "@sinonjs/fake-timers@^6.0.1":
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40"
- integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==
- dependencies:
- "@sinonjs/commons" "^1.7.0"
-
"@sinonjs/fake-timers@^7.1.0":
version "7.1.2"
resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-7.1.2.tgz#2524eae70c4910edccf99b2f4e6efc5894aff7b5"
@@ -2744,20 +2698,6 @@
dependencies:
"@sinonjs/commons" "^1.7.0"
-"@sinonjs/samsam@^5.3.1":
- version "5.3.1"
- resolved "https://registry.yarnpkg.com/@sinonjs/samsam/-/samsam-5.3.1.tgz#375a45fe6ed4e92fca2fb920e007c48232a6507f"
- integrity sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==
- dependencies:
- "@sinonjs/commons" "^1.6.0"
- lodash.get "^4.4.2"
- type-detect "^4.0.8"
-
-"@sinonjs/text-encoding@^0.7.1":
- version "0.7.1"
- resolved "https://registry.yarnpkg.com/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz#8da5c6530915653f3a1f38fd5f101d8c3f8079c5"
- integrity sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==
-
"@solidity-parser/parser@^0.11.0":
version "0.11.1"
resolved "https://registry.yarnpkg.com/@solidity-parser/parser/-/parser-0.11.1.tgz#fa840af64840c930f24a9c82c08d4a092a068add"
@@ -2864,11 +2804,6 @@
resolved "https://registry.yarnpkg.com/@types/abstract-leveldown/-/abstract-leveldown-5.0.2.tgz#ee81917fe38f770e29eec8139b6f16ee4a8b0a5f"
integrity sha512-+jA1XXF3jsz+Z7FcuiNqgK53hTa/luglT2TyTpKPqoYbxVY+mCPF22Rm+q3KPBrMHJwNXFrTViHszBOfU4vftQ==
-"@types/bluebird@^3.5.34":
- version "3.5.36"
- resolved "https://registry.yarnpkg.com/@types/bluebird/-/bluebird-3.5.36.tgz#00d9301d4dc35c2f6465a8aec634bb533674c652"
- integrity sha512-HBNx4lhkxN7bx6P0++W8E289foSu8kO8GCk2unhuVggO+cE7rh9DhZUyPhUxNRG9m+5B5BTKxZQ5ZP92x/mx9Q==
-
"@types/bn.js@*", "@types/bn.js@^5.1.0":
version "5.1.0"
resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-5.1.0.tgz#32c5d271503a12653c62cf4d2b45e6eab8cebc68"
@@ -3175,7 +3110,7 @@
"@types/mime" "^1"
"@types/node" "*"
-"@types/sinon-chai@^3.2.3", "@types/sinon-chai@^3.2.5":
+"@types/sinon-chai@^3.2.3":
version "3.2.5"
resolved "https://registry.yarnpkg.com/@types/sinon-chai/-/sinon-chai-3.2.5.tgz#df21ae57b10757da0b26f512145c065f2ad45c48"
integrity sha512-bKQqIpew7mmIGNRlxW6Zli/QVyc3zikpGzCa797B/tRnD9OtHvZ/ts8sYXV+Ilj9u3QRaUEM8xrjgd1gwm1BpQ==
@@ -3190,18 +3125,6 @@
dependencies:
"@sinonjs/fake-timers" "^7.1.0"
-"@types/sinon@^9.0.10":
- version "9.0.11"
- resolved "https://registry.yarnpkg.com/@types/sinon/-/sinon-9.0.11.tgz#7af202dda5253a847b511c929d8b6dda170562eb"
- integrity sha512-PwP4UY33SeeVKodNE37ZlOsR9cReypbMJOhZ7BVE0lB+Hix3efCOxiJWiE5Ia+yL9Cn2Ch72EjFTRze8RZsNtg==
- dependencies:
- "@types/sinonjs__fake-timers" "*"
-
-"@types/sinonjs__fake-timers@*":
- version "6.0.3"
- resolved "https://registry.yarnpkg.com/@types/sinonjs__fake-timers/-/sinonjs__fake-timers-6.0.3.tgz#79df6f358ae8f79e628fe35a63608a0ea8e7cf08"
- integrity sha512-E1dU4fzC9wN2QK2Cr1MLCfyHM8BoNnRFvuf45LYMPNDA+WqbNzC45S4UzPxvp1fFJ1rvSGU0bPvdd35VLmXG8g==
-
"@types/tz-offset@*":
version "0.0.0"
resolved "https://registry.yarnpkg.com/@types/tz-offset/-/tz-offset-0.0.0.tgz#d58f1cebd794148d245420f8f0660305d320e565"
@@ -4594,7 +4517,7 @@ blakejs@^1.1.0:
resolved "https://registry.yarnpkg.com/blakejs/-/blakejs-1.1.1.tgz#bf313053978b2cd4c444a48795710be05c785702"
integrity sha512-bLG6PHOCZJKNshTjGRBvET0vTciwQE6zFKOKKXPDJfwFBd4Ac0yBfPZqcGvGJap50l7ktvlpFqc2jGVaUgbJgg==
-bluebird@^3.5.0, bluebird@^3.5.2, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.2:
+bluebird@^3.5.0, bluebird@^3.5.2, bluebird@^3.5.3, bluebird@^3.5.5:
version "3.7.2"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
@@ -6165,7 +6088,7 @@ diff@5.0.0, diff@^5.0.0:
resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b"
integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==
-diff@^4.0.1, diff@^4.0.2:
+diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==
@@ -7238,41 +7161,6 @@ ethereumjs-wallet@0.6.5:
utf8 "^3.0.0"
uuid "^3.3.2"
-ethers@5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.0.0.tgz#76558a3020766f310a49f4e1a4c6c1e331761abd"
- integrity sha512-uOSACd2E8dg8XuiOewpL42uFH7SvrkA5k0oGkHoqSJl2lflrMPV+7ciWzyuPBjyHnOFvAPPJUpsXrwpFKaLFww==
- dependencies:
- "@ethersproject/abi" "^5.0.0"
- "@ethersproject/abstract-provider" "^5.0.0"
- "@ethersproject/abstract-signer" "^5.0.0"
- "@ethersproject/address" "^5.0.0"
- "@ethersproject/base64" "^5.0.0"
- "@ethersproject/bignumber" "^5.0.0"
- "@ethersproject/bytes" "^5.0.0"
- "@ethersproject/constants" "^5.0.0"
- "@ethersproject/contracts" "^5.0.0"
- "@ethersproject/hash" "^5.0.0"
- "@ethersproject/hdnode" "^5.0.0"
- "@ethersproject/json-wallets" "^5.0.0"
- "@ethersproject/keccak256" "^5.0.0"
- "@ethersproject/logger" "^5.0.0"
- "@ethersproject/networks" "^5.0.0"
- "@ethersproject/pbkdf2" "^5.0.0"
- "@ethersproject/properties" "^5.0.0"
- "@ethersproject/providers" "^5.0.0"
- "@ethersproject/random" "^5.0.0"
- "@ethersproject/rlp" "^5.0.0"
- "@ethersproject/sha2" "^5.0.0"
- "@ethersproject/signing-key" "^5.0.0"
- "@ethersproject/solidity" "^5.0.0"
- "@ethersproject/strings" "^5.0.0"
- "@ethersproject/transactions" "^5.0.0"
- "@ethersproject/units" "^5.0.0"
- "@ethersproject/wallet" "^5.0.0"
- "@ethersproject/web" "^5.0.0"
- "@ethersproject/wordlists" "^5.0.0"
-
ethers@^4.0.32, ethers@^4.0.40:
version "4.0.49"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-4.0.49.tgz#0eb0e9161a0c8b4761be547396bbe2fb121a8894"
@@ -7288,7 +7176,7 @@ ethers@^4.0.32, ethers@^4.0.40:
uuid "2.0.1"
xmlhttprequest "1.8.0"
-ethers@^5.0.0, ethers@^5.0.1, ethers@^5.0.2, ethers@^5.4.0, ethers@^5.4.5:
+ethers@^5.0.0, ethers@^5.0.1, ethers@^5.0.2, ethers@^5.4.5:
version "5.4.5"
resolved "https://registry.yarnpkg.com/ethers/-/ethers-5.4.5.tgz#cec133b9f5b514dc55e2561ee7aa7218c33affd7"
integrity sha512-PPZ6flOAj230sXEWf/r/It6ZZ5c7EOVWx+PU87Glkbg79OtT7pLE1WgL4MRdwx6iF7HzSOvUUI+8cAmcdzo12w==
@@ -8069,7 +7957,7 @@ ganache-cli@^6.12.2:
source-map-support "0.5.12"
yargs "13.2.4"
-ganache-core@^2.12.1, ganache-core@^2.13.2:
+ganache-core@^2.13.2:
version "2.13.2"
resolved "https://registry.yarnpkg.com/ganache-core/-/ganache-core-2.13.2.tgz#27e6fc5417c10e6e76e2e646671869d7665814a3"
integrity sha512-tIF5cR+ANQz0+3pHWxHjIwHqFXcVo0Mb+kcsNhglNFALcYo49aQpnS9dqHartqPfMFjiHh/qFoD3mYK0d/qGgw==
@@ -9865,11 +9753,6 @@ jsprim@^1.2.2:
array-includes "^3.1.2"
object.assign "^4.1.2"
-just-extend@^4.0.2:
- version "4.2.1"
- resolved "https://registry.yarnpkg.com/just-extend/-/just-extend-4.2.1.tgz#ef5e589afb61e5d66b24eca749409a8939a8c744"
- integrity sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==
-
keccak@3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.1.tgz#ae30a0e94dbe43414f741375cff6d64c8bea0bff"
@@ -10377,11 +10260,6 @@ lodash.flattendeep@^4.4.0:
resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2"
integrity sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=
-lodash.get@^4.4.2:
- version "4.4.2"
- resolved "https://registry.yarnpkg.com/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99"
- integrity sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=
-
lodash.isequal@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
@@ -11363,17 +11241,6 @@ nice-try@^1.0.4:
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
-nise@^4.0.4:
- version "4.1.0"
- resolved "https://registry.yarnpkg.com/nise/-/nise-4.1.0.tgz#8fb75a26e90b99202fa1e63f448f58efbcdedaf6"
- integrity sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==
- dependencies:
- "@sinonjs/commons" "^1.7.0"
- "@sinonjs/fake-timers" "^6.0.0"
- "@sinonjs/text-encoding" "^0.7.1"
- just-extend "^4.0.2"
- path-to-regexp "^1.7.0"
-
node-abi@^2.18.0, node-abi@^2.21.0, node-abi@^2.7.0:
version "2.30.0"
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.30.0.tgz#8be53bf3e7945a34eea10e0fc9a5982776cf550b"
@@ -11877,18 +11744,6 @@ oboe@2.1.5:
dependencies:
http-https "^1.0.0"
-"old-contracts@npm:@eth-optimism/contracts@^0.0.2-alpha.7":
- version "0.0.2-alpha.15"
- resolved "https://registry.yarnpkg.com/@eth-optimism/contracts/-/contracts-0.0.2-alpha.15.tgz#d602bdb6f1186d111ce9f7c282fc80e023086892"
- integrity sha512-upJfYHDWQY7nM0AYT9MKQiuOus2uMUhvqS962qiBq3Ly/9GUq5mS0UALynsrZBGbzT6pflOMKFFEv7jQEORGmA==
- dependencies:
- "@eth-optimism/solc" "^0.6.12-alpha.1"
- "@ethersproject/contracts" "^5.0.5"
- "@ethersproject/hardware-wallets" "^5.0.8"
- "@openzeppelin/contracts" "^3.3.0"
- ethers "5.0.0"
- ganache-core "^2.12.1"
-
on-finished@^2.3.0, on-finished@~2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
@@ -12349,13 +12204,6 @@ path-to-regexp@0.1.7:
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c"
integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=
-path-to-regexp@^1.7.0:
- version "1.8.0"
- resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a"
- integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==
- dependencies:
- isarray "0.0.1"
-
path-type@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441"
@@ -13889,23 +13737,6 @@ simple-get@^3.0.3:
once "^1.3.1"
simple-concat "^1.0.0"
-sinon-chai@^3.5.0:
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/sinon-chai/-/sinon-chai-3.7.0.tgz#cfb7dec1c50990ed18c153f1840721cf13139783"
- integrity sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==
-
-sinon@^9.2.4:
- version "9.2.4"
- resolved "https://registry.yarnpkg.com/sinon/-/sinon-9.2.4.tgz#e55af4d3b174a4443a8762fa8421c2976683752b"
- integrity sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==
- dependencies:
- "@sinonjs/commons" "^1.8.1"
- "@sinonjs/fake-timers" "^6.0.1"
- "@sinonjs/samsam" "^5.3.1"
- diff "^4.0.2"
- nise "^4.0.4"
- supports-color "^7.1.0"
-
slash@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55"
@@ -15203,7 +15034,7 @@ type-check@~0.3.2:
dependencies:
prelude-ls "~1.1.2"
-type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5, type-detect@^4.0.8:
+type-detect@4.0.8, type-detect@^4.0.0, type-detect@^4.0.5:
version "4.0.8"
resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c"
integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==