diff --git a/.circleci/config.yml b/.circleci/config.yml index 1e5c8f0c52f1..6bbc75373cd8 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -79,7 +79,6 @@ jobs: key: yarn-packages-v2-{{ checksum "yarn.lock" }} paths: - "node_modules" - - "packages/actor-tests/node_modules" - "packages/balance-monitor/node_modules" - "packages/chain-mon/node_modules" - "packages/common-ts/node_modules" @@ -1116,13 +1115,6 @@ workflows: - op-bindings-build: requires: - yarn-monorepo - - js-lint-test: - name: actor-tests-tests - coverage_flag: actor-tests-tests - package_name: actor-tests - dependencies: "(core-utils|sdk)" - requires: - - yarn-monorepo - js-lint-test: name: contracts-periphery-tests coverage_flag: contracts-periphery-tests diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 746d023fc89c..04b75c62dffd 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,6 +1,5 @@ # Legacy codebases /l2geth @ethereum-optimism/legacy-reviewers -/packages/actor-tests @ethereum-optimism/legacy-reviewers /packages/common-ts @ethereum-optimism/typescript-reviewers /packages/contracts @ethereum-optimism/contract-reviewers /packages/contracts-bedrock @ethereum-optimism/contract-reviewers diff --git a/cloudbuild.yaml b/cloudbuild.yaml index da07be0feba8..2cf6dfb333bb 100644 --- a/cloudbuild.yaml +++ b/cloudbuild.yaml @@ -8,14 +8,5 @@ steps: - --cache=true - --cache-ttl=48h waitFor: ['-'] - - name: 'gcr.io/kaniko-project/executor:latest' - args: - - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/actor-tests-bedrock:$_TAG - - --destination=us-central1-docker.pkg.dev/$PROJECT_ID/images/actor-tests-bedrock:$COMMIT_SHA - - --dockerfile=./ops/docker/Dockerfile.packages - - --target=actor-tests-bedrock - - --cache=true - - --cache-ttl=48h - waitFor: ['-'] options: machineType: N1_HIGHCPU_32 diff --git a/codecov.yml b/codecov.yml index 7f4ae79be789..73c7ed3438f5 100644 --- a/codecov.yml +++ b/codecov.yml @@ -34,7 +34,6 @@ flag_management: - name: common-ts-tests - name: contracts-tests - name: core-utils-tests - - name: actor-tests-tests - name: contracts-periphery-tests - name: dtl-tests - name: chain-mon-tests diff --git a/ops/docker/Dockerfile.packages b/ops/docker/Dockerfile.packages index 465c0fd301ad..dcb71838dc0b 100644 --- a/ops/docker/Dockerfile.packages +++ b/ops/docker/Dockerfile.packages @@ -69,10 +69,6 @@ COPY ./packages ./packages RUN yarn build -FROM base as actor-tests-bedrock -WORKDIR /opt/optimism/packages/actor-tests -ENTRYPOINT ["yarn", "run:bedrock"] - FROM base as fault-detector WORKDIR /opt/optimism/packages/fault-detector COPY ./ops/scripts/detector.sh . diff --git a/packages/actor-tests/.depcheckrc b/packages/actor-tests/.depcheckrc deleted file mode 100644 index 124f96a24bf9..000000000000 --- a/packages/actor-tests/.depcheckrc +++ /dev/null @@ -1,3 +0,0 @@ -ignores: [ - "typescript" -] diff --git a/packages/actor-tests/.eslintrc.js b/packages/actor-tests/.eslintrc.js deleted file mode 100644 index bfd2057be80b..000000000000 --- a/packages/actor-tests/.eslintrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - extends: '../../.eslintrc.js', -} diff --git a/packages/actor-tests/.lintstagedrc.yml b/packages/actor-tests/.lintstagedrc.yml deleted file mode 100644 index 4552e46e5568..000000000000 --- a/packages/actor-tests/.lintstagedrc.yml +++ /dev/null @@ -1,3 +0,0 @@ -"*.{ts,js}": - - eslint - diff --git a/packages/actor-tests/.prettierrc.js b/packages/actor-tests/.prettierrc.js deleted file mode 100644 index 2d293bab8925..000000000000 --- a/packages/actor-tests/.prettierrc.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - ...require('../../.prettierrc.js'), -} diff --git a/packages/actor-tests/CHANGELOG.md b/packages/actor-tests/CHANGELOG.md deleted file mode 100644 index 509d4d0a8c14..000000000000 --- a/packages/actor-tests/CHANGELOG.md +++ /dev/null @@ -1,298 +0,0 @@ -# @eth-optimism/actor-tests - -## 0.0.25 - -### Patch Changes - -- Updated dependencies [f1e867177] -- Updated dependencies [a1b7ff9e3] -- Updated dependencies [197884eae] -- Updated dependencies [8133872ed] -- Updated dependencies [6eb05430d] -- Updated dependencies [afc2ab8c9] -- Updated dependencies [5063a69fb] -- Updated dependencies [aa854bdd8] - - @eth-optimism/contracts-bedrock@0.14.0 - - @eth-optimism/sdk@2.1.0 - -## 0.0.24 - -### Patch Changes - -- Updated dependencies [b16067a9f] -- Updated dependencies [be3315689] -- Updated dependencies [9a02079eb] -- Updated dependencies [98fbe9d22] - - @eth-optimism/contracts-bedrock@0.13.2 - - @eth-optimism/sdk@2.0.2 - -## 0.0.23 - -### Patch Changes - -- Updated dependencies [22c3885f5] -- Updated dependencies [66cafc00a] -- Updated dependencies [f52c07529] - - @eth-optimism/contracts-bedrock@0.13.1 - - @eth-optimism/sdk@2.0.1 - -## 0.0.22 - -### Patch Changes - -- Updated dependencies [cb19e2f9c] - - @eth-optimism/sdk@2.0.0 - - @eth-optimism/contracts-bedrock@0.13.0 - -## 0.0.21 - -### Patch Changes - -- Updated dependencies [80f2271f5] - - @eth-optimism/contracts-bedrock@0.12.1 - - @eth-optimism/sdk@1.10.4 - -## 0.0.20 - -### Patch Changes - -- Updated dependencies [7c0a2cc37] -- Updated dependencies [2865dd9b4] -- Updated dependencies [efc98d261] -- Updated dependencies [388f2c25a] - - @eth-optimism/contracts-bedrock@0.12.0 - - @eth-optimism/sdk@1.10.3 - -## 0.0.19 - -### Patch Changes - -- Updated dependencies [3c22333b8] -- Updated dependencies [5372c9f5b] - - @eth-optimism/contracts-bedrock@0.11.4 - - @eth-optimism/sdk@1.10.2 - -## 0.0.18 - -### Patch Changes - -- Updated dependencies [4964be480] - - @eth-optimism/contracts-bedrock@0.11.3 - - @eth-optimism/sdk@1.10.1 - -## 0.0.17 - -### Patch Changes - -- Updated dependencies [8784bc0bc] - - @eth-optimism/contracts-bedrock@0.11.2 - - @eth-optimism/sdk@1.9.1 - -## 0.0.16 - -### Patch Changes - -- Updated dependencies [fe80a9488] -- Updated dependencies [827fc7b04] -- Updated dependencies [a2166dcad] -- Updated dependencies [ff09ec22d] -- Updated dependencies [85dfa9fe2] -- Updated dependencies [ba8b94a60] -- Updated dependencies [d1f9098f9] -- Updated dependencies [0f8fc58ad] -- Updated dependencies [89f70c591] -- Updated dependencies [03940c3cb] - - @eth-optimism/contracts-bedrock@0.11.1 - - @eth-optimism/sdk@1.9.0 - -## 0.0.15 - -### Patch Changes - -- 1d3c749a2: Bumps the version of ts-node used -- 1d3c749a2: Updates the version of TypeScript -- Updated dependencies [43f33f39f] -- Updated dependencies [237a351f1] -- Updated dependencies [1d3c749a2] -- Updated dependencies [767585b07] -- Updated dependencies [c975c9620] -- Updated dependencies [1594678e0] -- Updated dependencies [1d3c749a2] -- Updated dependencies [136ea1785] -- Updated dependencies [4d13f0afe] -- Updated dependencies [7300a7ca7] - - @eth-optimism/contracts-bedrock@0.11.0 - - @eth-optimism/sdk@1.8.0 - - @eth-optimism/core-utils@0.12.0 - -## 0.0.14 - -### Patch Changes - -- Updated dependencies [c025a1153] -- Updated dependencies [f8697a607] -- Updated dependencies [59adcaa09] -- Updated dependencies [c71500a7e] -- Updated dependencies [f49b71d50] -- Updated dependencies [1bfe79f20] -- Updated dependencies [ccaf5bc83] - - @eth-optimism/contracts-bedrock@0.10.0 - - @eth-optimism/sdk@1.7.0 - -## 0.0.13 - -### Patch Changes - -- Updated dependencies [52079cc12] -- Updated dependencies [13bfafb21] -- Updated dependencies [eeae96941] -- Updated dependencies [427831d86] - - @eth-optimism/contracts-bedrock@0.9.1 - - @eth-optimism/sdk@1.6.11 - -## 0.0.12 - -### Patch Changes - -- Updated dependencies [1e76cdb86] -- Updated dependencies [c02831144] -- Updated dependencies [d58b0a397] -- Updated dependencies [ff860ecf3] -- Updated dependencies [cc5adbc61] -- Updated dependencies [31c91ea74] -- Updated dependencies [87702c741] - - @eth-optimism/core-utils@0.11.0 - - @eth-optimism/contracts-bedrock@0.9.0 - - @eth-optimism/sdk@1.6.10 - -## 0.0.11 - -### Patch Changes - -- Updated dependencies [db84317b] -- Updated dependencies [9b90c732] - - @eth-optimism/contracts-bedrock@0.8.3 - - @eth-optimism/sdk@1.6.9 - -## 0.0.10 - -### Patch Changes - -- Updated dependencies [7d7d9ba8] - - @eth-optimism/contracts-bedrock@0.8.2 - - @eth-optimism/sdk@1.6.8 - -## 0.0.9 - -### Patch Changes - -- Updated dependencies [35a7bb5e] -- Updated dependencies [b40913b1] -- Updated dependencies [a5e715c3] -- Updated dependencies [d18b8aa3] - - @eth-optimism/contracts-bedrock@0.8.1 - - @eth-optimism/sdk@1.6.7 - -## 0.0.8 - -### Patch Changes - -- Updated dependencies [6ed68fa3] -- Updated dependencies [3d4e8529] -- Updated dependencies [caf5dd3e] -- Updated dependencies [a6cbfee2] -- Updated dependencies [394a26ec] - - @eth-optimism/contracts-bedrock@0.8.0 - - @eth-optimism/sdk@1.6.6 - -## 0.0.7 - -### Patch Changes - -- Updated dependencies [cb5fed67] -- Updated dependencies [e2faaa8b] -- Updated dependencies [c427f0c0] -- Updated dependencies [e2faaa8b] -- Updated dependencies [d28ad592] -- Updated dependencies [76c8ee2d] - - @eth-optimism/contracts-bedrock@0.7.0 - - @eth-optimism/sdk@1.6.5 - -## 0.0.6 - -### Patch Changes - -- 7215f4ce: Bump ethers to 5.7.0 globally -- Updated dependencies [88dde7c8] -- Updated dependencies [7215f4ce] -- Updated dependencies [249a8ed6] -- Updated dependencies [7d7c4fdf] -- Updated dependencies [e164e22e] -- Updated dependencies [0bc1be45] -- Updated dependencies [af3e56b1] -- Updated dependencies [206f6033] -- Updated dependencies [88dde7c8] -- Updated dependencies [d7679ca4] -- Updated dependencies [8790156c] -- Updated dependencies [515685f4] - - @eth-optimism/contracts-bedrock@0.6.3 - - @eth-optimism/core-utils@0.10.1 - - @eth-optimism/sdk@1.6.4 - -## 0.0.5 - -### Patch Changes - -- Updated dependencies [651a2883] - - @eth-optimism/contracts-bedrock@0.6.2 - - @eth-optimism/sdk@1.6.3 - -## 0.0.4 - -### Patch Changes - -- Updated dependencies [85232179] -- Updated dependencies [593f1cfb] -- Updated dependencies [cfa81f88] -- Updated dependencies [f78eb056] - - @eth-optimism/contracts-bedrock@0.6.1 - - @eth-optimism/sdk@1.6.2 - -## 0.0.3 - -### Patch Changes - -- Updated dependencies [7fdc490c] -- Updated dependencies [b27d0fa7] -- Updated dependencies [3d228a0e] -- Updated dependencies [dbfea116] -- Updated dependencies [63ef1949] - - @eth-optimism/contracts-bedrock@0.6.0 - - @eth-optimism/sdk@1.6.1 - - @eth-optimism/core-utils@0.10.0 - -## 0.0.2 - -### Patch Changes - -- Updated dependencies [a095d544] -- Updated dependencies [cdf2163e] -- Updated dependencies [791f30bc] -- Updated dependencies [193befed] -- Updated dependencies [02420db0] -- Updated dependencies [94a8f287] -- Updated dependencies [3df66a9a] -- Updated dependencies [8323407f] -- Updated dependencies [3af9c7a9] -- Updated dependencies [7d03c5c0] -- Updated dependencies [fec22bfe] -- Updated dependencies [aa2949ef] -- Updated dependencies [9272253e] -- Updated dependencies [a1a73e64] -- Updated dependencies [f53c30b9] -- Updated dependencies [c025f418] -- Updated dependencies [329d21b6] -- Updated dependencies [35eafed0] -- Updated dependencies [3cde9205] - - @eth-optimism/contracts-bedrock@0.5.4 - - @eth-optimism/sdk@1.6.0 diff --git a/packages/actor-tests/LICENSE b/packages/actor-tests/LICENSE deleted file mode 100644 index 6a7da5218bb2..000000000000 --- a/packages/actor-tests/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/actor-tests/README.md b/packages/actor-tests/README.md deleted file mode 100644 index 603c25c60911..000000000000 --- a/packages/actor-tests/README.md +++ /dev/null @@ -1,170 +0,0 @@ -# Actor Tests - -[![codecov](https://codecov.io/gh/ethereum-optimism/optimism/branch/develop/graph/badge.svg?token=0VTG7PG7YR&flag=actor-tests-tests)](https://codecov.io/gh/ethereum-optimism/optimism) - -This README describes how to use the actor testing library to write new tests. If you're just looking for how to run test cases, check out the README [in the root of the repo](../README.md). - -## Introduction - -An "actor test" is a test case that simulates how a user might interact with Optimism. For example, an actor test might automate a user minting NFTs or swapping on Uniswap. Multiple actor tests are composed together in order to simulate real-world usage and help us optimize network performance under realistic load. - -Actor tests are designed to catch race conditions, resource leaks, and performance regressions. They aren't a replacement for standard unit/integration tests, and aren't executed on every pull request since they take time to run. - -This directory contains the actor testing framework as well as the tests themselves. The framework lives in `lib` and the tests live in this directory with `.test.ts` prefixes. Read on to find out more about how to use the framework to write actor tests of your own. - -## CLI - -Use the following command to run actor tests from the CLI: - -``` -ts-node actor-tests/lib/runner.ts -f -c -r -t --think-time -``` - -You can also run `ts-node actor-tests/lib/runner.ts --help` for a full list of options with documentation. - -**Arguments:** - -- `path-to-test-file`: A path to the TS file containing the actor test. -- `concurrency`: How many workers to spawn. -- `run-for`: How long, in milliseconds, the worker should run. -- `think-time`: How long the runner should pause between test runs. Defaults to zero, meaning runs execute as fast as possible. - -## Usage - -### Test DSL - -Actor tests are defined using a Mocha-like DSL. Follow along using the example below: - -```typescript -import { actor, setupRun, setupActor, run } from './lib/convenience' - -interface Context { - wallet: Wallet -} - -actor('Value sender', () => { - let env: OptimismEnv - - setupActor(async () => { - env = await OptimismEnv.new() - }) - - setupRun(async () => { - const wallet = Wallet.createRandom() - const tx = await env.l2Wallet.sendTransaction({ - to: wallet.address, - value: utils.parseEther('0.01'), - }) - await tx.wait() - return { - wallet: wallet.connect(env.l2Wallet.provider), - } - }) - - run(async (b, ctx: Context) => { - const randWallet = Wallet.createRandom().connect(env.l2Wallet.provider) - await b.bench('send funds', async () => { - const tx = await ctx.wallet.sendTransaction({ - to: randWallet.address, - value: 0x42, - }) - await tx.wait() - }) - expect(await randWallet.getBalance()).to.deep.equal(BigNumber.from(0x42)) - }) -}) -``` - -#### `actor(name: string, cb: () => void)` - -Defines a new actor. - -**Arguments:** - -- `name`: Sets the actor's name. Used in logs and in outputted metrics. -- `cb`: The body of the actor. Cannot be async. All the other DSL methods (i.e. `setup*`, `run`) must be called within this callback. - -#### `setupActor(cb: () => Promise)` - -Defines a setup method that gets called after the actor is instantiated but before any workers are spawned. Useful to set variables that need to be shared across all worker instances. - -**Note:** Any variables set using `setupActor` must be thread-safe. Don't use `setupActor` to define a shared `Provider` instance, for example, since this will introduce nonce errors. Use `setupRun` to define a test context instead. - -#### `setupRun(cb: () => Promise)` - -Defines a setup method that gets called inside each worker after it is instantiated but before any runs have executed. The value returned by the `setupRun` method becomes the worker's test context, which will be described in more detail below. - -**Note:** While `setupRun` is called once in each worker, invocations of the `setupRun` callback are executed serially. This makes `setupRun` useful for nonce-dependent setup tasks like funding worker wallets. - -#### `run(cb: (b: Benchmarker, ctx: T) => Promise)` - -Defines what the actor actually does. The test runner will execute the `run` method multiple times depending on its configuration. - -**Benchmarker** - -Sections of the `run` method can be benchmarked using the `Benchmarker` argument to the `run` callback. Use the `Benchmarker` like this: - -```typescript -b.bench('bench name', async () => { - // benchmarked code here -}) -``` - -A summary of the benchmark's runtime and a count of how many times it succeeded/failed across each worker will be recorded in the run's metrics. - -**Context** - -The value returned by `setupRun` will be passed into the `ctx` argument to the `run` callback. Use the test context for values that need to be local to a particular worker. In the example, we use it to pass around the worker's wallet. - -### Error Handling - -Errors in setup methods cause the test process to crash. Errors in the `run` method are recorded in the test's metrics, and cause the run to be retried. The runtime of failed runs are not recorded. - -It's useful to use `expect`/`assert` to make sure that actors are executing properly. - -### Test Runner - -The test runner is responsible for executing actor tests and managing their lifecycle. It can run in one of two modes: - -1. Fixed run mode, which will execute the `run` method a fixed number of times. -2. Timed mode, which will will execute the `run` method as many times as possible until a period of time has elapsed. - -Test lifecycle is as follows: - -1. The runner collects all the actors it needs to run. - - > Actors automatically register themselves with the default instance of the runner upon being `require()`d. -2. The runner executes each actor's `setupActor` method. -3. The runner spawns `n` workers. -4. The runner executes the `setupRun` method in each worker. The runner will wait for all `setupRun` methods to complete before continuing. -5. The runner executes the `run` method according to the mode described above. - -## Metrics - -The test runner prints metrics about each run to `stdout` on exit. This output can then be piped into Prometheus for visualization in Grafana or similar tools. Example metrics output might looks like: - -``` -# HELP actor_successful_bench_runs_total Count of total successful bench runs. -# TYPE actor_successful_bench_runs_total counter -actor_successful_bench_runs_total{actor_name="value_sender",bench_name="send_funds",worker_id="0"} 20 -actor_successful_bench_runs_total{actor_name="value_sender",bench_name="send_funds",worker_id="1"} 20 - -# HELP actor_failed_bench_runs_total Count of total failed bench runs. -# TYPE actor_failed_bench_runs_total counter - -# HELP actor_step_durations_ms_summary Summary of successful bench durations. -# TYPE actor_step_durations_ms_summary summary -actor_step_durations_ms_summary{quantile="0.5",actor_name="value_sender",bench_name="send_funds"} 1278.0819790065289 -actor_step_durations_ms_summary{quantile="0.9",actor_name="value_sender",bench_name="send_funds"} 1318.4640210270882 -actor_step_durations_ms_summary{quantile="0.95",actor_name="value_sender",bench_name="send_funds"} 1329.5195834636688 -actor_step_durations_ms_summary{quantile="0.99",actor_name="value_sender",bench_name="send_funds"} 1338.0024159550667 -actor_step_durations_ms_summary_sum{actor_name="value_sender",bench_name="send_funds"} 51318.10741400719 -actor_step_durations_ms_summary_count{actor_name="value_sender",bench_name="send_funds"} 40 - -# HELP actor_successful_actor_runs_total Count of total successful actor runs. -# TYPE actor_successful_actor_runs_total counter -actor_successful_actor_runs_total{actor_name="value_sender"} 40 - -# HELP actor_failed_actor_runs_total Count of total failed actor runs. -# TYPE actor_failed_actor_runs_total counter -``` diff --git a/packages/actor-tests/bedrock/account-sends.ts b/packages/actor-tests/bedrock/account-sends.ts deleted file mode 100644 index 0b32bfa3bd3a..000000000000 --- a/packages/actor-tests/bedrock/account-sends.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { Wallet } from 'ethers' -import { expect } from 'chai' - -import { actor, setupActor, run, setupRun } from '../lib/convenience' -import { devWalletsL2, l2Provider } from './utils' -import { Faucet } from '../lib/faucet' - -interface Context { - wallet: Wallet -} - -actor('Sender', () => { - let destWallet: Wallet - - setupActor(async () => { - const devWallets = devWalletsL2() - destWallet = devWallets[0] - }) - - setupRun(async () => { - const faucet = new Faucet(process.env.FAUCET_URL, l2Provider) - const wallet = Wallet.createRandom().connect(l2Provider) - await faucet.drip(wallet.address) - return { - wallet, - } - }) - - run(async (b, ctx: Context, logger) => { - const { wallet } = ctx - logger.log(`Sending funds to ${destWallet.address}.`) - const tx = await wallet.sendTransaction({ - to: destWallet.address, - value: 0x42, - }) - logger.log(`Awaiting receipt for send tx ${tx.hash}.`) - const receipt = await tx.wait() - expect(receipt.status).to.eq(1) - logger.log(`Send completed in block ${receipt.blockNumber}.`) - }) -}) diff --git a/packages/actor-tests/bedrock/contracts/ERC20.json b/packages/actor-tests/bedrock/contracts/ERC20.json deleted file mode 100644 index e73ea8389514..000000000000 --- a/packages/actor-tests/bedrock/contracts/ERC20.json +++ /dev/null @@ -1,309 +0,0 @@ -{ - "_format": "hh-sol-artifact-1", - "contractName": "ERC20", - "sourceName": "contracts/ERC20.sol", - "abi": [ - { - "inputs": [ - { - "internalType": "uint256", - "name": "_initialAmount", - "type": "uint256" - }, - { - "internalType": "string", - "name": "_tokenName", - "type": "string" - }, - { - "internalType": "uint8", - "name": "_decimalUnits", - "type": "uint8" - }, - { - "internalType": "string", - "name": "_tokenSymbol", - "type": "string" - } - ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_spender", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "Approval", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "indexed": true, - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "indexed": false, - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "Transfer", - "type": "event" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - }, - { - "internalType": "address", - "name": "_spender", - "type": "address" - } - ], - "name": "allowance", - "outputs": [ - { - "internalType": "uint256", - "name": "remaining", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - }, - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "allowed", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_spender", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "approve", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_owner", - "type": "address" - } - ], - "name": "balanceOf", - "outputs": [ - { - "internalType": "uint256", - "name": "balance", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "name": "balances", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "decimals", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "destroy", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "name", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "symbol", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "totalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "transfer", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_from", - "type": "address" - }, - { - "internalType": "address", - "name": "_to", - "type": "address" - }, - { - "internalType": "uint256", - "name": "_value", - "type": "uint256" - } - ], - "name": "transferFrom", - "outputs": [ - { - "internalType": "bool", - "name": "success", - "type": "bool" - } - ], - "stateMutability": "nonpayable", - "type": "function" - } - ], - "bytecode": "0x60806040523480156200001157600080fd5b5060405162000a0c38038062000a0c833981016040819052620000349162000203565b336000908152602081815260409091208590556005859055835162000060916002919086019062000090565b506003805460ff191660ff841617905580516200008590600490602084019062000090565b5050505050620002cf565b8280546200009e9062000292565b90600052602060002090601f016020900481019282620000c257600085556200010d565b82601f10620000dd57805160ff19168380011785556200010d565b828001600101855582156200010d579182015b828111156200010d578251825591602001919060010190620000f0565b506200011b9291506200011f565b5090565b5b808211156200011b576000815560010162000120565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200015e57600080fd5b81516001600160401b03808211156200017b576200017b62000136565b604051601f8301601f19908116603f01168101908282118183101715620001a657620001a662000136565b81604052838152602092508683858801011115620001c357600080fd5b600091505b83821015620001e75785820183015181830184015290820190620001c8565b83821115620001f95760008385830101525b9695505050505050565b600080600080608085870312156200021a57600080fd5b845160208601519094506001600160401b03808211156200023a57600080fd5b62000248888389016200014c565b94506040870151915060ff821682146200026157600080fd5b6060870151919350808211156200027757600080fd5b5062000286878288016200014c565b91505092959194509250565b600181811c90821680620002a757607f821691505b60208210811415620002c957634e487b7160e01b600052602260045260246000fd5b50919050565b61072d80620002df6000396000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c80635c658165116100715780635c6581651461016357806370a082311461018e57806383197ef0146101b757806395d89b41146101bf578063a9059cbb146101c7578063dd62ed3e146101da57600080fd5b806306fdde03146100b9578063095ea7b3146100d757806318160ddd146100fa57806323b872dd1461011157806327e235e314610124578063313ce56714610144575b600080fd5b6100c1610213565b6040516100ce9190610574565b60405180910390f35b6100ea6100e53660046105e5565b6102a1565b60405190151581526020016100ce565b61010360055481565b6040519081526020016100ce565b6100ea61011f36600461060f565b61030d565b61010361013236600461064b565b60006020819052908152604090205481565b6003546101519060ff1681565b60405160ff90911681526020016100ce565b61010361017136600461066d565b600160209081526000928352604080842090915290825290205481565b61010361019c36600461064b565b6001600160a01b031660009081526020819052604090205490565b6101bd33ff5b005b6100c1610483565b6100ea6101d53660046105e5565b610490565b6101036101e836600461066d565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60028054610220906106a0565b80601f016020809104026020016040519081016040528092919081815260200182805461024c906106a0565b80156102995780601f1061026e57610100808354040283529160200191610299565b820191906000526020600020905b81548152906001019060200180831161027c57829003601f168201915b505050505081565b3360008181526001602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102fc9086815260200190565b60405180910390a350600192915050565b6001600160a01b038316600081815260016020908152604080832033845282528083205493835290829052812054909190831180159061034d5750828110155b61038e5760405162461bcd60e51b815260206004820152600d60248201526c62616420616c6c6f77616e636560981b60448201526064015b60405180910390fd5b6001600160a01b038416600090815260208190526040812080548592906103b69084906106f1565b90915550506001600160a01b038516600090815260208190526040812080548592906103e3908490610709565b909155505060001981101561042b576001600160a01b038516600090815260016020908152604080832033845290915281208054859290610425908490610709565b90915550505b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161047091815260200190565b60405180910390a3506001949350505050565b60048054610220906106a0565b336000908152602081905260408120548211156104e65760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b6044820152606401610385565b3360009081526020819052604081208054849290610505908490610709565b90915550506001600160a01b038316600090815260208190526040812080548492906105329084906106f1565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016102fc565b600060208083528351808285015260005b818110156105a157858101830151858201604001528201610585565b818111156105b3576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146105e057600080fd5b919050565b600080604083850312156105f857600080fd5b610601836105c9565b946020939093013593505050565b60008060006060848603121561062457600080fd5b61062d846105c9565b925061063b602085016105c9565b9150604084013590509250925092565b60006020828403121561065d57600080fd5b610666826105c9565b9392505050565b6000806040838503121561068057600080fd5b610689836105c9565b9150610697602084016105c9565b90509250929050565b600181811c908216806106b457607f821691505b602082108114156106d557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115610704576107046106db565b500190565b60008282101561071b5761071b6106db565b50039056fea164736f6c6343000809000a", - "deployedBytecode": "0x608060405234801561001057600080fd5b50600436106100b45760003560e01c80635c658165116100715780635c6581651461016357806370a082311461018e57806383197ef0146101b757806395d89b41146101bf578063a9059cbb146101c7578063dd62ed3e146101da57600080fd5b806306fdde03146100b9578063095ea7b3146100d757806318160ddd146100fa57806323b872dd1461011157806327e235e314610124578063313ce56714610144575b600080fd5b6100c1610213565b6040516100ce9190610574565b60405180910390f35b6100ea6100e53660046105e5565b6102a1565b60405190151581526020016100ce565b61010360055481565b6040519081526020016100ce565b6100ea61011f36600461060f565b61030d565b61010361013236600461064b565b60006020819052908152604090205481565b6003546101519060ff1681565b60405160ff90911681526020016100ce565b61010361017136600461066d565b600160209081526000928352604080842090915290825290205481565b61010361019c36600461064b565b6001600160a01b031660009081526020819052604090205490565b6101bd33ff5b005b6100c1610483565b6100ea6101d53660046105e5565b610490565b6101036101e836600461066d565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b60028054610220906106a0565b80601f016020809104026020016040519081016040528092919081815260200182805461024c906106a0565b80156102995780601f1061026e57610100808354040283529160200191610299565b820191906000526020600020905b81548152906001019060200180831161027c57829003601f168201915b505050505081565b3360008181526001602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906102fc9086815260200190565b60405180910390a350600192915050565b6001600160a01b038316600081815260016020908152604080832033845282528083205493835290829052812054909190831180159061034d5750828110155b61038e5760405162461bcd60e51b815260206004820152600d60248201526c62616420616c6c6f77616e636560981b60448201526064015b60405180910390fd5b6001600160a01b038416600090815260208190526040812080548592906103b69084906106f1565b90915550506001600160a01b038516600090815260208190526040812080548592906103e3908490610709565b909155505060001981101561042b576001600160a01b038516600090815260016020908152604080832033845290915281208054859290610425908490610709565b90915550505b836001600160a01b0316856001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161047091815260200190565b60405180910390a3506001949350505050565b60048054610220906106a0565b336000908152602081905260408120548211156104e65760405162461bcd60e51b8152602060048201526014602482015273696e73756666696369656e742062616c616e636560601b6044820152606401610385565b3360009081526020819052604081208054849290610505908490610709565b90915550506001600160a01b038316600090815260208190526040812080548492906105329084906106f1565b90915550506040518281526001600160a01b0384169033907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906020016102fc565b600060208083528351808285015260005b818110156105a157858101830151858201604001528201610585565b818111156105b3576000604083870101525b50601f01601f1916929092016040019392505050565b80356001600160a01b03811681146105e057600080fd5b919050565b600080604083850312156105f857600080fd5b610601836105c9565b946020939093013593505050565b60008060006060848603121561062457600080fd5b61062d846105c9565b925061063b602085016105c9565b9150604084013590509250925092565b60006020828403121561065d57600080fd5b610666826105c9565b9392505050565b6000806040838503121561068057600080fd5b610689836105c9565b9150610697602084016105c9565b90509250929050565b600181811c908216806106b457607f821691505b602082108114156106d557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115610704576107046106db565b500190565b60008282101561071b5761071b6106db565b50039056fea164736f6c6343000809000a", - "linkReferences": {}, - "deployedLinkReferences": {} -} diff --git a/packages/actor-tests/bedrock/deployments.ts b/packages/actor-tests/bedrock/deployments.ts deleted file mode 100644 index 71618fec0969..000000000000 --- a/packages/actor-tests/bedrock/deployments.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { Wallet, ContractFactory } from 'ethers' - -import { actor, setupActor, run } from '../lib/convenience' -import { devWalletsL2 } from './utils' -import * as ERC20 from './contracts/ERC20.json' - -actor('Deployer', () => { - let wallets: Wallet[] - - setupActor(async () => { - wallets = devWalletsL2() - }) - - run(async (b, ctx, logger) => { - const sender = wallets[Math.floor(Math.random() * wallets.length)] - const contract = new ContractFactory(ERC20.abi, ERC20.bytecode).connect( - sender - ) - logger.log(`Deploying contract with ${sender.address}.`) - const deployment = await contract.deploy( - Math.floor(1_000_000 * Math.random()), - 'Test Token', - 18, - 'OP' - ) - logger.log( - `Awaiting receipt for deployment tx ${deployment.deployTransaction.hash}.` - ) - await deployment.deployed() - const receipt = await sender.provider.getTransactionReceipt( - deployment.deployTransaction.hash - ) - logger.log(`Deployment completed in block ${receipt.blockNumber}.`) - }) -}) diff --git a/packages/actor-tests/bedrock/deposit-eth.ts b/packages/actor-tests/bedrock/deposit-eth.ts deleted file mode 100644 index f9d74c2bca7b..000000000000 --- a/packages/actor-tests/bedrock/deposit-eth.ts +++ /dev/null @@ -1,88 +0,0 @@ -import { utils, Wallet, constants } from 'ethers' -import { - CrossChainMessenger, - ETHBridgeAdapter, - StandardBridgeAdapter, -} from '@eth-optimism/sdk' -import { predeploys } from '@eth-optimism/contracts-bedrock' -import { sleep } from '@eth-optimism/core-utils' - -import { actor, setupActor, run, setupRun } from '../lib/convenience' -import { l1Provider, l2Provider } from './utils' -import { Faucet } from '../lib/faucet' - -interface Context { - wallet: Wallet - messenger: CrossChainMessenger -} - -actor('Depositor', () => { - let contracts: any - - setupActor(async () => { - contracts = require(process.env.CONTRACTS_JSON_PATH) - }) - - setupRun(async () => { - const wallet = Wallet.createRandom().connect(l1Provider) - const faucet = new Faucet(process.env.FAUCET_URL, l1Provider) - await faucet.drip(wallet.address) - - return { - wallet, - messenger: new CrossChainMessenger({ - l1SignerOrProvider: wallet.connect(l1Provider), - l2SignerOrProvider: wallet.connect(l2Provider), - l1ChainId: (await l1Provider.getNetwork()).chainId, - l2ChainId: (await l2Provider.getNetwork()).chainId, - bridges: { - Standard: { - Adapter: StandardBridgeAdapter, - l1Bridge: contracts.L1StandardBridgeProxy, - l2Bridge: predeploys.L2StandardBridge, - }, - ETH: { - Adapter: ETHBridgeAdapter, - l1Bridge: contracts.L1StandardBridgeProxy, - l2Bridge: predeploys.L2StandardBridge, - }, - }, - contracts: { - l1: { - AddressManager: constants.AddressZero, - StateCommitmentChain: constants.AddressZero, - CanonicalTransactionChain: constants.AddressZero, - BondManager: constants.AddressZero, - L1StandardBridge: contracts.L1StandardBridgeProxy, - L1CrossDomainMessenger: contracts.L1CrossDomainMessengerProxy, - L2OutputOracle: contracts.L2OutputOracleProxy, - OptimismPortal: contracts.OptimismPortalProxy, - }, - }, - bedrock: true, - }), - } - }) - - run(async (b, ctx: Context, logger) => { - const { messenger } = ctx - const recipient = Wallet.createRandom().connect(l2Provider) - logger.log(`Depositing funds to ${recipient.address}.`) - const depositTx = await messenger.depositETH(utils.parseEther('0.000001'), { - recipient: recipient.address, - }) - logger.log(`Awaiting receipt for deposit tx ${depositTx.hash}.`) - await depositTx.wait() - // Temporary until this is supported in the SDK. - for (let i = 0; i < 60; i++) { - const recipBal = await recipient.getBalance() - logger.log(`Polling L2 for deposit completion.`) - if (recipBal.eq(utils.parseEther('0.000001'))) { - logger.log('Deposit successful.') - return - } - await sleep(1000) - } - throw new Error('Timed out.') - }) -}) diff --git a/packages/actor-tests/bedrock/utils.ts b/packages/actor-tests/bedrock/utils.ts deleted file mode 100644 index 5c7be8fa11ab..000000000000 --- a/packages/actor-tests/bedrock/utils.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { providers, Wallet } from 'ethers' - -const DEV_MNEMONIC = - 'test test test test test test test test test test test junk' - -export const l1Provider = new providers.JsonRpcProvider(process.env.L1_RPC) -export const l2Provider = new providers.JsonRpcProvider(process.env.L2_RPC) - -export const devWalletsL2 = () => { - const wallets = [] - for (let i = 0; i < 20; i++) { - wallets.push( - Wallet.fromMnemonic(DEV_MNEMONIC, `m/44'/60'/0'/0/${i}`).connect( - l2Provider - ) - ) - } - return wallets -} diff --git a/packages/actor-tests/lib/actor.ts b/packages/actor-tests/lib/actor.ts deleted file mode 100644 index 2f6ef018bb13..000000000000 --- a/packages/actor-tests/lib/actor.ts +++ /dev/null @@ -1,305 +0,0 @@ -import { performance } from 'perf_hooks' - -import { Mutex } from 'async-mutex' -import { sleep } from '@eth-optimism/core-utils' - -import { - sanitizeForMetrics, - benchDurationsSummary, - successfulBenchRunsTotal, - failedActorRunsTotal, - successfulActorRunsTotal, - failedBenchRunsTotal, -} from './metrics' -import { ActorLogger, WorkerLogger } from './logger' - -// eslint-disable-next-line @typescript-eslint/no-empty-function -const asyncNoop = async () => {} - -export type AsyncCB = () => Promise - -export interface Bencher { - bench: (name: string, cb: () => Promise) => Promise -} - -export type RunCB = ( - b: Bencher, - ctx: C, - logger: WorkerLogger -) => Promise - -export interface RunOpts { - runs: number | null - runFor: number | null - concurrency: number - thinkTime: number -} - -class Latch { - private n: number - - private p: Promise - - private resolver: () => void - - constructor(n: number) { - this.n = n - this.p = new Promise((resolve) => { - this.resolver = resolve - }) - } - - countDown() { - this.n-- - if (this.n === 0) { - this.resolver() - } - } - - wait() { - return this.p - } -} - -export class Runner { - private readonly workerId: number - - private readonly actor: Actor - - private readonly mtx: Mutex - - private readonly readyLatch: Latch - - private readonly stepper: Bencher - - private readonly logger: WorkerLogger - - constructor(workerId: number, actor: Actor, mtx: Mutex, readyLatch: Latch) { - this.workerId = workerId - this.actor = actor - this.mtx = mtx - this.readyLatch = readyLatch - this.stepper = { - bench: this.bench, - } - this.logger = new WorkerLogger(this.actor.name, workerId) - } - - bench = async (name: string, cb: () => Promise) => { - const metricLabels = { - actor_name: sanitizeForMetrics(this.actor.name), - bench_name: sanitizeForMetrics(name), - } - const start = performance.now() - let res - try { - res = await cb() - } catch (e) { - failedBenchRunsTotal.inc({ - ...metricLabels, - worker_id: this.workerId, - }) - throw e - } - benchDurationsSummary.observe(metricLabels, performance.now() - start) - successfulBenchRunsTotal.inc({ - ...metricLabels, - worker_id: this.workerId, - }) - return res - } - - async run(opts: RunOpts) { - const actor = this.actor - - this.logger.log('Setting up.') - let ctx - try { - ctx = await this.mtx.runExclusive(this.actor.setupRun) - } finally { - this.readyLatch.countDown() - } - this.logger.log('Waiting for other workers to finish setup.') - await this.readyLatch.wait() - - this.logger.log('Executing.') - const benchStart = performance.now() - let lastDurPrint = benchStart - let i = 0 - const metricLabels = { - actor_name: sanitizeForMetrics(this.actor.name), - } - - while (true) { - const now = performance.now() - - if ( - (opts.runs && i === opts.runs) || - (opts.runFor && now - benchStart >= opts.runFor) - ) { - this.logger.log(`Worker exited.`) - break - } - - try { - await this.actor.run(this.stepper, ctx, this.logger) - } catch (e) { - console.error('Error in actor run:') - console.error(`Benchmark name: ${actor.name}`) - console.error(`Worker ID: ${this.workerId}`) - console.error(`Run index: ${i}`) - console.error('Stack trace:') - console.error(e) - failedActorRunsTotal.inc(metricLabels) - await sleep(1000) - continue - } - - successfulActorRunsTotal.inc(metricLabels) - - i++ - - if ( - (opts.runs && (i % 10 === 0 || i === opts.runs)) || - now - lastDurPrint > 10000 - ) { - this.logger.log(`Completed run ${i} of ${opts.runs}.`) - } - - if (opts.runFor && now - lastDurPrint > 10000) { - const runningFor = Math.floor(now - benchStart) - this.logger.log(`Running for ${runningFor} of ${opts.runFor} ms.`) - lastDurPrint = now - } - - if (opts.thinkTime > 0) { - await sleep(opts.thinkTime) - } - } - - await this.mtx.runExclusive(() => this.actor.tearDownRun(ctx)) - } -} - -export class Actor { - public readonly name: string - - private _setupEnv: AsyncCB = asyncNoop - - private _tearDownEnv: AsyncCB = asyncNoop - - private _setupRun: () => Promise = asyncNoop as any - - private _tearDownRun: (ctx: C) => Promise = asyncNoop as any - - // eslint-disable-next-line @typescript-eslint/no-empty-function - private _run: (b: Bencher, ctx: C, logger: WorkerLogger) => Promise = - asyncNoop - - private logger: ActorLogger - - constructor(name: string) { - this.name = name - this.logger = new ActorLogger(this.name) - } - - get setupEnv(): AsyncCB { - return this._setupEnv - } - - set setupEnv(value: AsyncCB) { - this._setupEnv = value - } - - get tearDownEnv(): AsyncCB { - return this._tearDownEnv - } - - set tearDownEnv(value: AsyncCB) { - this._tearDownEnv = value - } - - get setupRun(): () => Promise { - return this._setupRun - } - - set setupRun(value: () => Promise) { - this._setupRun = value - } - - get tearDownRun(): (ctx: C) => Promise { - return this._tearDownRun - } - - set tearDownRun(value: (ctx: any) => Promise) { - this._tearDownRun = value - } - - get run(): RunCB { - return this._run - } - - set run(cb: RunCB) { - this._run = cb - } - - async exec(opts: RunOpts) { - this.logger.log('Setting up.') - - try { - await this.setupEnv() - } catch (e) { - console.error(`Error in setupEnv hook for actor "${this.name}":`) - console.error(e) - return - } - - this.logger.log('Starting.') - - const parallelRuns = [] - const mtx = new Mutex() - const latch = new Latch(opts.concurrency) - for (let i = 0; i < opts.concurrency; i++) { - const runner = new Runner(i, this, mtx, latch) - parallelRuns.push(runner.run(opts)) - } - await Promise.all(parallelRuns) - - this.logger.log('Tearing down.') - - try { - await this.tearDownEnv() - } catch (e) { - console.error(`Error in after hook for benchmark "${this.name}":`) - console.error(e) - return - } - - this.logger.log('Teardown complete.') - } -} - -export class Runtime { - private actors: Actor[] = [] - - addActor(actor: Actor) { - this.actors.push(actor) - } - - async run(opts: Partial) { - opts = { - runs: 1, - concurrency: 1, - runFor: null, - thinkTime: 0, - ...(opts || {}), - } - if (opts.runFor) { - opts.runs = null - } - - for (const actor of this.actors) { - await actor.exec(opts as RunOpts) - } - } -} diff --git a/packages/actor-tests/lib/convenience.ts b/packages/actor-tests/lib/convenience.ts deleted file mode 100644 index a9682cc268fd..000000000000 --- a/packages/actor-tests/lib/convenience.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { AsyncCB, Actor, RunCB, Runtime } from './actor' - -export const defaultRuntime = new Runtime() - -let currBenchmark: Actor | null = null - -export const actor = (name: string, cb: () => void) => { - if (currBenchmark) { - throw new Error('Cannot call actor within actor.') - } - - currBenchmark = new Actor(name) - cb() - defaultRuntime.addActor(currBenchmark) - currBenchmark = null -} - -export const setupActor = (cb: AsyncCB) => { - if (!currBenchmark) { - throw new Error('Cannot call setupEnv outside of actor.') - } - currBenchmark.setupEnv = cb -} - -export const setupRun = (cb: () => Promise) => { - if (!currBenchmark) { - throw new Error('Cannot call setupRun outside of actor.') - } - currBenchmark.setupRun = cb -} - -export const tearDownRun = (cb: AsyncCB) => { - if (!currBenchmark) { - throw new Error('Cannot call tearDownRun outside of actor.') - } - currBenchmark.tearDownRun = cb -} - -export const run = (cb: RunCB) => { - if (!currBenchmark) { - throw new Error('Cannot call run outside of actor.') - } - currBenchmark.run = cb -} - -export const retryOnGasTooLow = async (cb: () => Promise) => { - while (true) { - try { - return await cb() - } catch (e) { - if (e.toString().includes('gas price too low')) { - await new Promise((resolve) => setTimeout(resolve, 100)) - continue - } - - throw e - } - } -} diff --git a/packages/actor-tests/lib/faucet.ts b/packages/actor-tests/lib/faucet.ts deleted file mode 100644 index f8cdc85749e0..000000000000 --- a/packages/actor-tests/lib/faucet.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { ethers, providers } from 'ethers' -import { fetchJson, getAddress } from 'ethers/lib/utils' - -export class Faucet { - private url: string - - private provider: providers.Provider - - constructor(url: string, provider: providers.Provider) { - this.url = url - this.provider = provider - } - - public async drip( - recipient: string - ): Promise { - const res = await fetchJson( - `${this.url}/api/claim`, - JSON.stringify({ - address: getAddress(recipient), - }) - ) - - const txHash = res.tx_hash - return this.provider.waitForTransaction(txHash, 0, 30000) - } -} diff --git a/packages/actor-tests/lib/logger.ts b/packages/actor-tests/lib/logger.ts deleted file mode 100644 index 2cb58b5129f4..000000000000 --- a/packages/actor-tests/lib/logger.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { sanitizeForMetrics } from './metrics' - -abstract class Logger { - log(msg: string) { - const date = new Date() - process.stderr.write(`[${date.toISOString()}] ${msg}\n`) - } -} - -export class ActorLogger extends Logger { - private readonly name: string - - constructor(name: string) { - super() - this.name = name - } - - log(msg: string) { - super.log(`[actor:${sanitizeForMetrics(this.name)}] ${msg}`) - } -} - -export class WorkerLogger extends Logger { - private readonly name: string - - private readonly workerId: number - - constructor(name: string, workerId: number) { - super() - this.name = name - this.workerId = workerId - } - - log(msg: string) { - super.log( - `[bench:${sanitizeForMetrics(this.name)}] [wid:${this.workerId}] ${msg}` - ) - } -} diff --git a/packages/actor-tests/lib/metrics.ts b/packages/actor-tests/lib/metrics.ts deleted file mode 100644 index ae307accf756..000000000000 --- a/packages/actor-tests/lib/metrics.ts +++ /dev/null @@ -1,73 +0,0 @@ -import fs from 'fs' -import http from 'http' -import url from 'url' - -import client from 'prom-client' - -export const metricsRegistry = new client.Registry() - -const metricName = (name: string) => { - return `actor_${name}` -} - -export const successfulBenchRunsTotal = new client.Counter({ - name: metricName('successful_bench_runs_total'), - help: 'Count of total successful bench runs.', - labelNames: ['actor_name', 'bench_name', 'worker_id'] as const, - registers: [metricsRegistry], -}) - -export const failedBenchRunsTotal = new client.Counter({ - name: metricName('failed_bench_runs_total'), - help: 'Count of total failed bench runs.', - labelNames: ['actor_name', 'bench_name', 'worker_id'] as const, - registers: [metricsRegistry], -}) - -export const benchDurationsSummary = new client.Summary({ - name: metricName('step_durations_ms_summary'), - help: 'Summary of successful bench durations.', - percentiles: [0.5, 0.9, 0.95, 0.99], - labelNames: ['actor_name', 'bench_name'] as const, - registers: [metricsRegistry], -}) - -export const successfulActorRunsTotal = new client.Counter({ - name: metricName('successful_actor_runs_total'), - help: 'Count of total successful actor runs.', - labelNames: ['actor_name'] as const, - registers: [metricsRegistry], -}) - -export const failedActorRunsTotal = new client.Counter({ - name: metricName('failed_actor_runs_total'), - help: 'Count of total failed actor runs.', - labelNames: ['actor_name'] as const, - registers: [metricsRegistry], -}) - -export const sanitizeForMetrics = (input: string) => { - return input.toLowerCase().replace(/ /gi, '_') -} - -export const dumpMetrics = async (filename: string) => { - const metrics = await metricsRegistry.metrics() - await fs.promises.writeFile(filename, metrics, { - flag: 'w+', - }) -} - -export const serveMetrics = (port: number) => { - const server = http.createServer(async (req, res) => { - const route = url.parse(req.url).pathname - if (route !== '/metrics') { - res.writeHead(404) - res.end() - return - } - - res.setHeader('Content-Type', metricsRegistry.contentType) - res.end(await metricsRegistry.metrics()) - }) - server.listen(port) -} diff --git a/packages/actor-tests/lib/runner.ts b/packages/actor-tests/lib/runner.ts deleted file mode 100644 index 4228b9c0e96d..000000000000 --- a/packages/actor-tests/lib/runner.ts +++ /dev/null @@ -1,85 +0,0 @@ -import * as path from 'path' - -import { Command } from 'commander' - -import { defaultRuntime } from './convenience' -import { RunOpts } from './actor' -import { serveMetrics } from './metrics' -import pkg from '../package.json' - -const program = new Command() -program.version(pkg.version) -program.name('actor-tests') - -program - .requiredOption('-f, --file ', 'test file to run') - .option('-r, --runs ', 'number of runs. cannot be use with -t/--time') - .option( - '-t, --time ', - 'how long to run in milliseconds. cannot be used with -r/--runs' - ) - .option('-c, --concurrency ', 'number of concurrent workers to spawn', '1') - .option('--think-time ', 'how long to wait between each run', '0') - .option( - '-s, --serve [port]', - 'Serve metrics with optional port number', - '8545' - ) - -program.parse(process.argv) - -const options = program.opts() -const testFile = options.file -const runsNum = Number(options.runs) -const timeNum = Number(options.time) -const concNum = Number(options.concurrency) -const thinkNum = Number(options.thinkTime) -const shouldServeMetrics = options.serve !== undefined -const metricsPort = options.serve || 8545 - -if (isNaN(runsNum) && isNaN(timeNum)) { - console.error('Must define either a number of runs or how long to run.') - process.exit(1) -} - -if (isNaN(concNum) || concNum <= 0) { - console.error('Invalid concurrency value.') - process.exit(1) -} - -if (isNaN(thinkNum) || thinkNum < 0) { - console.error('Invalid think time value.') - process.exit(1) -} - -try { - require(path.resolve(path.join(process.cwd(), testFile))) -} catch (e) { - console.error(`Invalid test file ${testFile}:`) - console.error(e) - process.exit(1) -} - -const opts: Partial = { - runFor: timeNum, - concurrency: concNum, - thinkTime: thinkNum, - runs: runsNum, -} - -if (shouldServeMetrics) { - process.stderr.write(`Serving metrics on http://0.0.0.0:${metricsPort}.\n`) - serveMetrics(metricsPort) -} - -defaultRuntime - .run(opts) - .then(() => { - process.stderr.write('Run complete.\n') - process.exit(0) - }) - .catch((err) => { - console.error('Error:') - console.error(err) - process.exit(1) - }) diff --git a/packages/actor-tests/package.json b/packages/actor-tests/package.json deleted file mode 100644 index 1a5601cd05fe..000000000000 --- a/packages/actor-tests/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "@eth-optimism/actor-tests", - "version": "0.0.25", - "description": "A library and suite of tests to stress test Optimism Bedrock.", - "license": "MIT", - "author": "", - "main": "index.js", - "directories": { - "lib": "lib" - }, - "scripts": { - "lint": "yarn lint:fix && yarn lint:check", - "lint:check": "eslint . --max-warnings=0", - "lint:fix": "yarn lint:check --fix", - "pre-commit": "lint-staged", - "run:bedrock": "ts-node ./lib/runner.ts -f", - "test": "echo 'No tests specified.'", - "test:coverage": "yarn test" - }, - "dependencies": { - "@eth-optimism/contracts-bedrock": "0.14.0", - "@eth-optimism/core-utils": "^0.12.0", - "@eth-optimism/sdk": "^2.1.0", - "@types/chai": "^4.2.18", - "@types/chai-as-promised": "^7.1.4", - "async-mutex": "^0.3.2", - "chai": "^4.3.4", - "chai-as-promised": "^7.1.1", - "commander": "^8.3.0", - "eslint": "^7.27.0", - "eslint-config-prettier": "^8.3.0", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jsdoc": "^35.1.2", - "eslint-plugin-prefer-arrow": "^1.2.3", - "eslint-plugin-prettier": "^3.4.0", - "ethers": "^5.7.0", - "prom-client": "^14.0.1", - "typescript": "^4.9.3" - } -} diff --git a/packages/actor-tests/tsconfig.json b/packages/actor-tests/tsconfig.json deleted file mode 100644 index 793fdea19963..000000000000 --- a/packages/actor-tests/tsconfig.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "resolveJsonModule": true - }, - "include": [ - "./lib/**/*.ts", - "./bedrock/**/*.(ts|json)", - "./package.json" - ] -}