diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 0000000..e17baa4 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,48 @@ +name: Lint + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + lint: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Deno + uses: denoland/setup-deno@v2 + with: + deno-version: v2.x + + - name: Run linter + run: deno task lint + + - name: Check contracts + run: | + echo "Download the resolc binary" + wget -O resolc https://github.com/paritytech/revive/releases/download/v0.3.0/resolc-x86_64-unknown-linux-musl -q + chmod +x resolc + sudo mv resolc /usr/local/bin + resolc --version + + echo "Installing solc" + wget https://github.com/ethereum/solidity/releases/download/v0.8.30/solc-static-linux -q + chmod +x solc-static-linux + sudo mv solc-static-linux /usr/local/bin/solc + + echo "Building fixture contracts" + deno task build + deno fmt + + echo "Verifying no new files were created (bytecode should be committed)" + if [ -n "$(git status --porcelain)" ]; then + echo "Error: Build created new or modified files. All bytecode should be committed." + git status + exit 1 + fi + echo "Success: All contract bytecode is up to date" diff --git a/.gitignore b/.gitignore index 96ccea9..529be5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,6 @@ # Logs logs *.log -abi/* -pvm/* -evm/* npm-debug.log* yarn-debug.log* yarn-error.log* @@ -14,9 +11,6 @@ node_modules dist dist-ssr *.local -abi/* -evm/* -pvm/* !.gitkeep src/samples diff --git a/README.md b/README.md index 29e23d7..d0a48e4 100644 --- a/README.md +++ b/README.md @@ -4,14 +4,11 @@ This repository contains a test suite for Ethereum rpc methods. ## Prerequisites -- [Deno](https://deno.land/) runtime installed (v1.40 or higher recommended) +- [Deno](https://deno.land/) runtime installed (v1.40 or higher recommended) ## Running Tests ```bash -# build the contracts -deno task build - # start revive and eth rpc, then run tests with pvm bytecode deno task test:pvm # start revive and eth rpc, then run tests with evm bytecode @@ -20,6 +17,14 @@ deno task test:evm deno task test:geth ``` +## Building contracts + +Contracts bytecode and abi is checked in into this repository, if you need to add new contracts, you can simply run the build command: + +```bash +deno task build +``` + ### Linting To check code formatting and run linter: @@ -32,8 +37,8 @@ deno task lint Tests are configured via environment variables: -- `START_GETH=1` - Automatically start Geth -- `START_REVIVE_DEV_NODE=1` - Automatically start Revive dev node -- `START_ETH_RPC=1` - Automatically start ETH RPC server -- `USE_GETH=1` - Run tests against Geth (uses EVM bytecode) -- `USE_ETH_RPC=1` - Run tests against ETH RPC with both PVM and EVM bytecode +- `START_GETH=1` - Automatically start Geth +- `START_REVIVE_DEV_NODE=1` - Automatically start Revive dev node +- `START_ETH_RPC=1` - Automatically start ETH RPC server +- `USE_GETH=1` - Run tests against Geth (uses EVM bytecode) +- `USE_ETH_RPC=1` - Run tests against ETH RPC with both PVM and EVM bytecode diff --git a/abi/Errors.json b/abi/Errors.json new file mode 100644 index 0000000..22e9076 --- /dev/null +++ b/abi/Errors.json @@ -0,0 +1,106 @@ +[ + { + "inputs": [ + { + "internalType": "string", + "name": "message", + "type": "string" + } + ], + "name": "CustomError", + "type": "error" + }, + { + "inputs": [ + { + "internalType": "bool", + "name": "newState", + "type": "bool" + } + ], + "name": "setState", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "state", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "triggerAssertError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerCustomError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerDivisionByZero", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerOutOfBoundsError", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerRequireError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [], + "name": "triggerRevertError", + "outputs": [], + "stateMutability": "pure", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "value", + "type": "uint256" + } + ], + "name": "valueMatch", + "outputs": [], + "stateMutability": "payable", + "type": "function" + } +] diff --git a/abi/Errors.ts b/abi/Errors.ts new file mode 100644 index 0000000..36e8816 --- /dev/null +++ b/abi/Errors.ts @@ -0,0 +1,106 @@ +export const ErrorsAbi = [ + { + 'inputs': [ + { + 'internalType': 'string', + 'name': 'message', + 'type': 'string', + }, + ], + 'name': 'CustomError', + 'type': 'error', + }, + { + 'inputs': [ + { + 'internalType': 'bool', + 'name': 'newState', + 'type': 'bool', + }, + ], + 'name': 'setState', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'state', + 'outputs': [ + { + 'internalType': 'bool', + 'name': '', + 'type': 'bool', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'triggerAssertError', + 'outputs': [], + 'stateMutability': 'pure', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'triggerCustomError', + 'outputs': [], + 'stateMutability': 'pure', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'triggerDivisionByZero', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'pure', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'triggerOutOfBoundsError', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'pure', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'triggerRequireError', + 'outputs': [], + 'stateMutability': 'pure', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'triggerRevertError', + 'outputs': [], + 'stateMutability': 'pure', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'uint256', + 'name': 'value', + 'type': 'uint256', + }, + ], + 'name': 'valueMatch', + 'outputs': [], + 'stateMutability': 'payable', + 'type': 'function', + }, +] as const diff --git a/abi/EventExample.json b/abi/EventExample.json new file mode 100644 index 0000000..aed83c0 --- /dev/null +++ b/abi/EventExample.json @@ -0,0 +1,34 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "sender", + "type": "address" + }, + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "message", + "type": "string" + } + ], + "name": "ExampleEvent", + "type": "event" + }, + { + "inputs": [], + "name": "triggerEvent", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/EventExample.ts b/abi/EventExample.ts new file mode 100644 index 0000000..66e88f9 --- /dev/null +++ b/abi/EventExample.ts @@ -0,0 +1,34 @@ +export const EventExampleAbi = [ + { + 'anonymous': false, + 'inputs': [ + { + 'indexed': true, + 'internalType': 'address', + 'name': 'sender', + 'type': 'address', + }, + { + 'indexed': false, + 'internalType': 'uint256', + 'name': 'value', + 'type': 'uint256', + }, + { + 'indexed': false, + 'internalType': 'string', + 'name': 'message', + 'type': 'string', + }, + ], + 'name': 'ExampleEvent', + 'type': 'event', + }, + { + 'inputs': [], + 'name': 'triggerEvent', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, +] as const diff --git a/abi/Flipper.json b/abi/Flipper.json new file mode 100644 index 0000000..844fea8 --- /dev/null +++ b/abi/Flipper.json @@ -0,0 +1,40 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "flip", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "getValue", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "value", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/Flipper.ts b/abi/Flipper.ts new file mode 100644 index 0000000..8ef3a50 --- /dev/null +++ b/abi/Flipper.ts @@ -0,0 +1,40 @@ +export const FlipperAbi = [ + { + 'inputs': [], + 'stateMutability': 'nonpayable', + 'type': 'constructor', + }, + { + 'inputs': [], + 'name': 'flip', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'getValue', + 'outputs': [ + { + 'internalType': 'bool', + 'name': '', + 'type': 'bool', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'value', + 'outputs': [ + { + 'internalType': 'bool', + 'name': '', + 'type': 'bool', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, +] as const diff --git a/abi/FlipperCaller.json b/abi/FlipperCaller.json new file mode 100644 index 0000000..6061ffd --- /dev/null +++ b/abi/FlipperCaller.json @@ -0,0 +1,46 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_flipperAddress", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "callFlip", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "callGetValue", + "outputs": [ + { + "internalType": "bool", + "name": "", + "type": "bool" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "flipperAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/FlipperCaller.ts b/abi/FlipperCaller.ts new file mode 100644 index 0000000..81d2ebe --- /dev/null +++ b/abi/FlipperCaller.ts @@ -0,0 +1,46 @@ +export const FlipperCallerAbi = [ + { + 'inputs': [ + { + 'internalType': 'address', + 'name': '_flipperAddress', + 'type': 'address', + }, + ], + 'stateMutability': 'nonpayable', + 'type': 'constructor', + }, + { + 'inputs': [], + 'name': 'callFlip', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'callGetValue', + 'outputs': [ + { + 'internalType': 'bool', + 'name': '', + 'type': 'bool', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'flipperAddress', + 'outputs': [ + { + 'internalType': 'address', + 'name': '', + 'type': 'address', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, +] as const diff --git a/abi/PiggyBank.json b/abi/PiggyBank.json new file mode 100644 index 0000000..f338585 --- /dev/null +++ b/abi/PiggyBank.json @@ -0,0 +1,65 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getDeposit", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "owner", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "withdrawAmount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [ + { + "internalType": "uint256", + "name": "remainingBal", + "type": "uint256" + } + ], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/PiggyBank.ts b/abi/PiggyBank.ts new file mode 100644 index 0000000..44c91f3 --- /dev/null +++ b/abi/PiggyBank.ts @@ -0,0 +1,65 @@ +export const PiggyBankAbi = [ + { + 'inputs': [], + 'stateMutability': 'nonpayable', + 'type': 'constructor', + }, + { + 'inputs': [], + 'name': 'deposit', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'payable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'getDeposit', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'owner', + 'outputs': [ + { + 'internalType': 'address', + 'name': '', + 'type': 'address', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'uint256', + 'name': 'withdrawAmount', + 'type': 'uint256', + }, + ], + 'name': 'withdraw', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': 'remainingBal', + 'type': 'uint256', + }, + ], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, +] as const diff --git a/abi/PretraceFixture.json b/abi/PretraceFixture.json new file mode 100644 index 0000000..1b4d466 --- /dev/null +++ b/abi/PretraceFixture.json @@ -0,0 +1,174 @@ +[ + { + "inputs": [], + "stateMutability": "payable", + "type": "constructor" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "name": "balances", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "childAddr", + "type": "address" + } + ], + "name": "callContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "createChild", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "childAddr", + "type": "address" + } + ], + "name": "delegatecallContract", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "deposit", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "inputs": [], + "name": "getContractBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "account", + "type": "address" + } + ], + "name": "getExternalBalance", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "readStorage", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "str", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "value", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" + } + ], + "name": "withdraw", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_value", + "type": "uint256" + }, + { + "internalType": "string", + "name": "_str", + "type": "string" + } + ], + "name": "writeStorage", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/PretraceFixture.ts b/abi/PretraceFixture.ts new file mode 100644 index 0000000..2dbea5d --- /dev/null +++ b/abi/PretraceFixture.ts @@ -0,0 +1,174 @@ +export const PretraceFixtureAbi = [ + { + 'inputs': [], + 'stateMutability': 'payable', + 'type': 'constructor', + }, + { + 'inputs': [ + { + 'internalType': 'address', + 'name': '', + 'type': 'address', + }, + ], + 'name': 'balances', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'address', + 'name': 'childAddr', + 'type': 'address', + }, + ], + 'name': 'callContract', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'createChild', + 'outputs': [ + { + 'internalType': 'address', + 'name': '', + 'type': 'address', + }, + ], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'address', + 'name': 'childAddr', + 'type': 'address', + }, + ], + 'name': 'delegatecallContract', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'deposit', + 'outputs': [], + 'stateMutability': 'payable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'getContractBalance', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'address', + 'name': 'account', + 'type': 'address', + }, + ], + 'name': 'getExternalBalance', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'readStorage', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'str', + 'outputs': [ + { + 'internalType': 'string', + 'name': '', + 'type': 'string', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'value', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'uint256', + 'name': 'amount', + 'type': 'uint256', + }, + ], + 'name': 'withdraw', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'uint256', + 'name': '_value', + 'type': 'uint256', + }, + { + 'internalType': 'string', + 'name': '_str', + 'type': 'string', + }, + ], + 'name': 'writeStorage', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, +] as const diff --git a/abi/PretraceFixtureChild.json b/abi/PretraceFixtureChild.json new file mode 100644 index 0000000..a002fe8 --- /dev/null +++ b/abi/PretraceFixtureChild.json @@ -0,0 +1,22 @@ +[ + { + "inputs": [], + "name": "increment", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "value", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/PretraceFixtureChild.ts b/abi/PretraceFixtureChild.ts new file mode 100644 index 0000000..32b6741 --- /dev/null +++ b/abi/PretraceFixtureChild.ts @@ -0,0 +1,22 @@ +export const PretraceFixtureChildAbi = [ + { + 'inputs': [], + 'name': 'increment', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'value', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, +] as const diff --git a/abi/Storage.json b/abi/Storage.json new file mode 100644 index 0000000..1e97d0b --- /dev/null +++ b/abi/Storage.json @@ -0,0 +1,59 @@ +[ + { + "inputs": [], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "n1", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "n2", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "num", + "type": "uint256" + } + ], + "name": "write_n1_read_n2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "num", + "type": "uint256" + } + ], + "name": "write_n2", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/Storage.ts b/abi/Storage.ts new file mode 100644 index 0000000..13875d6 --- /dev/null +++ b/abi/Storage.ts @@ -0,0 +1,59 @@ +export const StorageAbi = [ + { + 'inputs': [], + 'stateMutability': 'nonpayable', + 'type': 'constructor', + }, + { + 'inputs': [], + 'name': 'n1', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'n2', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'uint256', + 'name': 'num', + 'type': 'uint256', + }, + ], + 'name': 'write_n1_read_n2', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'uint256', + 'name': 'num', + 'type': 'uint256', + }, + ], + 'name': 'write_n2', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, +] as const diff --git a/abi/Tester.json b/abi/Tester.json new file mode 100644 index 0000000..1c2cb13 --- /dev/null +++ b/abi/Tester.json @@ -0,0 +1,72 @@ +[ + { + "inputs": [], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "address", + "name": "creator", + "type": "address" + } + ], + "name": "TesterDeployed", + "type": "event" + }, + { + "inputs": [], + "name": "name", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "v", + "type": "string" + } + ], + "name": "setName", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "v", + "type": "uint256" + } + ], + "name": "setValue", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "value", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + } +] diff --git a/abi/Tester.ts b/abi/Tester.ts new file mode 100644 index 0000000..4b3e7ed --- /dev/null +++ b/abi/Tester.ts @@ -0,0 +1,72 @@ +export const TesterAbi = [ + { + 'inputs': [], + 'stateMutability': 'payable', + 'type': 'constructor', + }, + { + 'anonymous': false, + 'inputs': [ + { + 'indexed': true, + 'internalType': 'address', + 'name': 'creator', + 'type': 'address', + }, + ], + 'name': 'TesterDeployed', + 'type': 'event', + }, + { + 'inputs': [], + 'name': 'name', + 'outputs': [ + { + 'internalType': 'string', + 'name': '', + 'type': 'string', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'string', + 'name': 'v', + 'type': 'string', + }, + ], + 'name': 'setName', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'uint256', + 'name': 'v', + 'type': 'uint256', + }, + ], + 'name': 'setValue', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'value', + 'outputs': [ + { + 'internalType': 'uint256', + 'name': '', + 'type': 'uint256', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, +] as const diff --git a/abi/TracingCallee.json b/abi/TracingCallee.json new file mode 100644 index 0000000..16a5abf --- /dev/null +++ b/abi/TracingCallee.json @@ -0,0 +1,39 @@ +[ + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "counter", + "type": "uint256" + } + ], + "name": "CalleeCalled", + "type": "event" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + } + ], + "name": "consumeGas", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "failingFunction", + "outputs": [], + "stateMutability": "payable", + "type": "function" + }, + { + "stateMutability": "payable", + "type": "receive" + } +] diff --git a/abi/TracingCallee.ts b/abi/TracingCallee.ts new file mode 100644 index 0000000..cdb3018 --- /dev/null +++ b/abi/TracingCallee.ts @@ -0,0 +1,39 @@ +export const TracingCalleeAbi = [ + { + 'anonymous': false, + 'inputs': [ + { + 'indexed': false, + 'internalType': 'uint256', + 'name': 'counter', + 'type': 'uint256', + }, + ], + 'name': 'CalleeCalled', + 'type': 'event', + }, + { + 'inputs': [ + { + 'internalType': 'uint256', + 'name': 'counter', + 'type': 'uint256', + }, + ], + 'name': 'consumeGas', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'failingFunction', + 'outputs': [], + 'stateMutability': 'payable', + 'type': 'function', + }, + { + 'stateMutability': 'payable', + 'type': 'receive', + }, +] as const diff --git a/abi/TracingCaller.json b/abi/TracingCaller.json new file mode 100644 index 0000000..f43c4bd --- /dev/null +++ b/abi/TracingCaller.json @@ -0,0 +1,84 @@ +[ + { + "inputs": [ + { + "internalType": "address payable", + "name": "_callee", + "type": "address" + } + ], + "stateMutability": "payable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "value", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "string", + "name": "message", + "type": "string" + } + ], + "name": "TraceEvent", + "type": "event" + }, + { + "inputs": [], + "name": "callee", + "outputs": [ + { + "internalType": "address payable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "create", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "create2", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "counter", + "type": "uint256" + } + ], + "name": "start", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + } +] diff --git a/abi/TracingCaller.ts b/abi/TracingCaller.ts new file mode 100644 index 0000000..c494048 --- /dev/null +++ b/abi/TracingCaller.ts @@ -0,0 +1,84 @@ +export const TracingCallerAbi = [ + { + 'inputs': [ + { + 'internalType': 'address payable', + 'name': '_callee', + 'type': 'address', + }, + ], + 'stateMutability': 'payable', + 'type': 'constructor', + }, + { + 'anonymous': false, + 'inputs': [ + { + 'indexed': false, + 'internalType': 'uint256', + 'name': 'value', + 'type': 'uint256', + }, + { + 'indexed': false, + 'internalType': 'string', + 'name': 'message', + 'type': 'string', + }, + ], + 'name': 'TraceEvent', + 'type': 'event', + }, + { + 'inputs': [], + 'name': 'callee', + 'outputs': [ + { + 'internalType': 'address payable', + 'name': '', + 'type': 'address', + }, + ], + 'stateMutability': 'view', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'create', + 'outputs': [ + { + 'internalType': 'address', + 'name': '', + 'type': 'address', + }, + ], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [], + 'name': 'create2', + 'outputs': [ + { + 'internalType': 'address', + 'name': '', + 'type': 'address', + }, + ], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, + { + 'inputs': [ + { + 'internalType': 'uint256', + 'name': 'counter', + 'type': 'uint256', + }, + ], + 'name': 'start', + 'outputs': [], + 'stateMutability': 'nonpayable', + 'type': 'function', + }, +] as const diff --git a/contracts/PiggyBank.sol b/contracts/PiggyBank.sol deleted file mode 100644 index c50f551..0000000 --- a/contracts/PiggyBank.sol +++ /dev/null @@ -1,32 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.0; - -contract PiggyBank { - uint256 private balance; - address public owner; - - constructor() { - owner = msg.sender; - balance = 0; - } - - function deposit() public payable returns (uint256) { - balance += msg.value; - return balance; - } - - function getDeposit() public view returns (uint256) { - return balance; - } - - function withdraw( - uint256 withdrawAmount - ) public returns (uint256 remainingBal) { - require(msg.sender == owner, 'You are not the owner'); - balance -= withdrawAmount; - (bool success, ) = payable(msg.sender).call{value: withdrawAmount}(''); - require(success, 'Transfer failed'); - - return balance; - } -} diff --git a/contracts/Storage.sol b/contracts/Storage.sol deleted file mode 100644 index 4d6ed2f..0000000 --- a/contracts/Storage.sol +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: GPL-3.0 - -pragma solidity >=0.8.2 <0.9.0; - -/** - * @title Storage - * @dev Store & retrieve value in a variable - * @custom:dev-run-script ./scripts/deploy_with_ethers.ts - */ -contract Storage { - uint256 public n1; - uint256 public n2; - - constructor() { - n1 = 42; - n2 = 100; - } - - /** - * @dev Store value in variable - * @param num value to store - */ - function write_n1_read_n2(uint256 num) public { - n1 = num + n2; - } - - function write_n2(uint256 num) public { - n2 = num; - } -} diff --git a/evm/Errors.bin b/evm/Errors.bin new file mode 100644 index 0000000..2d17f69 Binary files /dev/null and b/evm/Errors.bin differ diff --git a/evm/EventExample.bin b/evm/EventExample.bin new file mode 100644 index 0000000..3f3274e Binary files /dev/null and b/evm/EventExample.bin differ diff --git a/evm/Flipper.bin b/evm/Flipper.bin new file mode 100644 index 0000000..bb043d7 Binary files /dev/null and b/evm/Flipper.bin differ diff --git a/evm/FlipperCaller.bin b/evm/FlipperCaller.bin new file mode 100644 index 0000000..b31ee15 Binary files /dev/null and b/evm/FlipperCaller.bin differ diff --git a/evm/PretraceFixture.bin b/evm/PretraceFixture.bin new file mode 100644 index 0000000..492961a Binary files /dev/null and b/evm/PretraceFixture.bin differ diff --git a/evm/PretraceFixtureChild.bin b/evm/PretraceFixtureChild.bin new file mode 100644 index 0000000..e8bb622 Binary files /dev/null and b/evm/PretraceFixtureChild.bin differ diff --git a/evm/Tester.bin b/evm/Tester.bin new file mode 100644 index 0000000..dfa0cb1 Binary files /dev/null and b/evm/Tester.bin differ diff --git a/evm/TracingCallee.bin b/evm/TracingCallee.bin new file mode 100644 index 0000000..d485015 Binary files /dev/null and b/evm/TracingCallee.bin differ diff --git a/evm/TracingCaller.bin b/evm/TracingCaller.bin new file mode 100644 index 0000000..42007d2 Binary files /dev/null and b/evm/TracingCaller.bin differ diff --git a/pvm/Errors.polkavm b/pvm/Errors.polkavm new file mode 100644 index 0000000..336f3ff Binary files /dev/null and b/pvm/Errors.polkavm differ diff --git a/pvm/EventExample.polkavm b/pvm/EventExample.polkavm new file mode 100644 index 0000000..33703d2 Binary files /dev/null and b/pvm/EventExample.polkavm differ diff --git a/pvm/Flipper.polkavm b/pvm/Flipper.polkavm new file mode 100644 index 0000000..d2d9753 Binary files /dev/null and b/pvm/Flipper.polkavm differ diff --git a/pvm/FlipperCaller.polkavm b/pvm/FlipperCaller.polkavm new file mode 100644 index 0000000..87f4d9e Binary files /dev/null and b/pvm/FlipperCaller.polkavm differ diff --git a/pvm/PiggyBank.polkavm b/pvm/PiggyBank.polkavm new file mode 100644 index 0000000..f501efa Binary files /dev/null and b/pvm/PiggyBank.polkavm differ diff --git a/pvm/PretraceFixture.polkavm b/pvm/PretraceFixture.polkavm new file mode 100644 index 0000000..780ec04 Binary files /dev/null and b/pvm/PretraceFixture.polkavm differ diff --git a/pvm/PretraceFixtureChild.polkavm b/pvm/PretraceFixtureChild.polkavm new file mode 100644 index 0000000..40c7036 Binary files /dev/null and b/pvm/PretraceFixtureChild.polkavm differ diff --git a/pvm/Storage.polkavm b/pvm/Storage.polkavm new file mode 100644 index 0000000..d587442 Binary files /dev/null and b/pvm/Storage.polkavm differ diff --git a/pvm/Tester.polkavm b/pvm/Tester.polkavm new file mode 100644 index 0000000..fb92e9c Binary files /dev/null and b/pvm/Tester.polkavm differ diff --git a/pvm/TracingCallee.polkavm b/pvm/TracingCallee.polkavm new file mode 100644 index 0000000..c8d7383 Binary files /dev/null and b/pvm/TracingCallee.polkavm differ diff --git a/pvm/TracingCaller.polkavm b/pvm/TracingCaller.polkavm new file mode 100644 index 0000000..c614839 Binary files /dev/null and b/pvm/TracingCaller.polkavm differ diff --git a/src/methods.test.ts b/src/methods.test.ts index 9a83ae5..a63517e 100644 --- a/src/methods.test.ts +++ b/src/methods.test.ts @@ -22,8 +22,7 @@ const getTesterReceipt = memoizedTx(env, () => abi: TesterAbi, bytecode: getByteCode('Tester', env.evm), value: parseEther('2'), - }) -) + })) const getTesterAddr = () => getTesterReceipt().then((r) => r.contractAddress!) Deno.test('eth_accounts', opts, async () => { @@ -109,7 +108,7 @@ Deno.test( expect(byNumber).toEqual(byHash) expect(byNumber).toBeGreaterThanOrEqual(1) - } + }, ) Deno.test('eth_getCode', opts, async () => { @@ -173,7 +172,7 @@ Deno.test('eth_getStorageAt', opts, async () => { // revive store value as little endian. When this change in the compiler, or the runtime API, we can amend this test expect(storage).toEqual( - '0x48656c6c6f20776f726c64000000000000000000000000000000000000000016' + '0x48656c6c6f20776f726c64000000000000000000000000000000000000000016', ) }) @@ -199,12 +198,12 @@ Deno.test( index, }) expect(byBlockNumber).toEqual(byTxHash) - } + }, ) Deno.test('eth_getTransactionCount', opts, async () => { const count = await env.serverWallet.getTransactionCount( - env.serverWallet.account + env.serverWallet.account, ) expect(count).toBeGreaterThanOrEqual(1) }) @@ -284,6 +283,6 @@ Deno.test('eth_feeHistory', opts, async () => { expect(feeHistory.reward?.length).toEqual(feeHistory.gasUsedRatio.length) expect(feeHistory.baseFeePerGas).toHaveLength( - feeHistory.gasUsedRatio.length + 1 + feeHistory.gasUsedRatio.length + 1, ) }) diff --git a/src/test-setup.ts b/src/test-setup.ts index 1573b4e..79377d3 100644 --- a/src/test-setup.ts +++ b/src/test-setup.ts @@ -41,8 +41,7 @@ export async function setupTests() { ] await killProcessOnPort(9944) - const nodePath = - Deno.env.get('REVIVE_DEV_NODE_PATH') ?? + const nodePath = Deno.env.get('REVIVE_DEV_NODE_PATH') ?? `${Deno.env.get('HOME')}/polkadot-sdk/target/debug/revive-dev-node` console.log('🚀 Start dev-node ...') const devNodeProcess = new Deno.Command(nodePath, { @@ -62,8 +61,7 @@ export async function setupTests() { ] await killProcessOnPort(8545) - const ethRpcPath = - Deno.env.get('ETH_RPC_PATH') ?? + const ethRpcPath = Deno.env.get('ETH_RPC_PATH') ?? `${Deno.env.get('HOME')}/polkadot-sdk/target/debug/eth-rpc` console.log('🚀 Start eth-rpc ...') const ethRpcProcess = new Deno.Command(ethRpcPath, { diff --git a/src/tracing-call-trace.test.ts b/src/tracing-call-trace.test.ts index 7e54a2c..ea66b22 100644 --- a/src/tracing-call-trace.test.ts +++ b/src/tracing-call-trace.test.ts @@ -9,10 +9,7 @@ import { } from './util.ts' import { assertSnapshot } from '@std/testing/snapshot' import { expect } from '@std/expect' -import { - encodeFunctionData, - parseEther, -} from 'viem' +import { encodeFunctionData, parseEther } from 'viem' import { TracingCallerAbi } from '../abi/TracingCaller.ts' import { TracingCalleeAbi } from '../abi/TracingCallee.ts' diff --git a/src/tracing-prestate.test.ts b/src/tracing-prestate.test.ts index d0033d4..8c20b81 100644 --- a/src/tracing-prestate.test.ts +++ b/src/tracing-prestate.test.ts @@ -18,12 +18,14 @@ import { PretraceFixtureChildAbi } from '../abi/PretraceFixtureChild.ts' // Initialize test environment const env = await getEnv() -const getPretraceFixture = memoizedTx(env, () => - env.accountWallet.deployContract({ - abi: PretraceFixtureAbi, - bytecode: getByteCode('PretraceFixture', env.evm), - value: parseEther('10'), - }) +const getPretraceFixture = memoizedTx( + env, + () => + env.accountWallet.deployContract({ + abi: PretraceFixtureAbi, + bytecode: getByteCode('PretraceFixture', env.evm), + value: parseEther('10'), + }), ) const getAddr = () => getPretraceFixture().then((r) => r.contractAddress!) @@ -33,8 +35,7 @@ const getAddr2 = memoizedDeploy(env, () => env.accountWallet.deployContract({ abi: PretraceFixtureChildAbi, bytecode: getByteCode('PretraceFixtureChild', env.evm), - }) -) + })) const getBlock = memoized(async () => { await getPretraceFixture() @@ -50,7 +51,7 @@ const getVisitor = async (): Promise => { const { miner: coinbaseAddr } = block const walletbalanceStorageSlot = computeMappingSlot( env.accountWallet.account.address, - 1 + 1, ) const mappedKeys = { [walletbalanceStorageSlot]: ``, @@ -95,7 +96,7 @@ const matchFixture = async ( t: Deno.TestContext, res: unknown, fixtureName: string, - diffMode: string + diffMode: string, ) => { const visitor = await getVisitor() if (Deno.env.get('DEBUG')) { @@ -104,7 +105,7 @@ const matchFixture = async ( await Deno.mkdir(dir, { recursive: true }) await Deno.writeTextFile( `${dir}${fixtureName}.${env.chain.name}.${diffMode}.json`, - JSON.stringify(res, null, 2) + JSON.stringify(res, null, 2), ) } @@ -118,8 +119,8 @@ const withDiffModes = ( testFn: ( t: Deno.TestContext, config: { diffMode: boolean }, - diffMode: string - ) => Promise + diffMode: string, + ) => Promise, ) => { return async (t: Deno.TestContext) => { for (const config of [{ diffMode: true }, { diffMode: false }]) { @@ -140,10 +141,10 @@ Deno.test( const res = await env.debugClient.traceTransaction( receiptHash, 'prestateTracer', - config + config, ) await matchFixture(t, res, 'deploy_contract', diffMode) - }) + }), ) Deno.test( @@ -164,11 +165,11 @@ Deno.test( config, ( await getBlock() - ).hash! + ).hash!, ) await matchFixture(t, res, 'write_storage', diffMode) - }) + }), ) Deno.test( @@ -188,11 +189,11 @@ Deno.test( config, ( await getBlock() - ).hash! + ).hash!, ) await matchFixture(t, res, 'write_storage_from_0', diffMode) - }) + }), ) Deno.test( @@ -212,11 +213,11 @@ Deno.test( config, ( await getBlock() - ).hash! + ).hash!, ) await matchFixture(t, res, 'read_storage', diffMode) - }) + }), ) Deno.test( @@ -237,11 +238,11 @@ Deno.test( config, ( await getBlock() - ).hash! + ).hash!, ) await matchFixture(t, res, 'deposit', diffMode) - }) + }), ) Deno.test( @@ -262,11 +263,11 @@ Deno.test( config, ( await getBlock() - ).hash! + ).hash!, ) await matchFixture(t, res, 'withdraw', diffMode) - }) + }), ) Deno.test( @@ -286,11 +287,11 @@ Deno.test( config, ( await getBlock() - ).hash! + ).hash!, ) await matchFixture(t, res, 'get_balance', diffMode) - }) + }), ) Deno.test( @@ -311,7 +312,7 @@ Deno.test( config, ( await getBlock() - ).hash! + ).hash!, )) as Record // Geth is missing addr2 just add it back to make test pass @@ -322,7 +323,7 @@ Deno.test( } await matchFixture(t, res, 'get_external_balance', diffMode) - }) + }), ) Deno.test( @@ -343,11 +344,11 @@ Deno.test( config, ( await getBlock() - ).hash! + ).hash!, ) await matchFixture(t, res, 'instantiate_child', diffMode) - }) + }), ) Deno.test( @@ -365,11 +366,11 @@ Deno.test( }), }, 'prestateTracer', - config + config, ) await matchFixture(t, res, 'call_contract', diffMode) - }) + }), ) Deno.test( @@ -390,11 +391,11 @@ Deno.test( config, ( await getBlock() - ).hash! + ).hash!, ) await matchFixture(t, res, 'delegate_call_contract', diffMode) - }) + }), ) Deno.test( @@ -402,7 +403,7 @@ Deno.test( opts, withDiffModes(async (t, config, diffMode) => { const nonce = await env.accountWallet.getTransactionCount( - env.accountWallet.account + env.accountWallet.account, ) const value = await env.accountWallet.readContract({ @@ -429,7 +430,7 @@ Deno.test( const receipts = await Promise.all( hashes.map((hash) => env.accountWallet.waitForTransactionReceipt(hash) - ) + ), ) expect(receipts).toHaveLength(2) @@ -441,14 +442,14 @@ Deno.test( const res = await env.debugClient.traceBlock( receipts[0].blockNumber, 'prestateTracer', - config + config, ) await matchFixture( t, res, 'trace_block_write_storage_twice', - diffMode + diffMode, ) } @@ -457,10 +458,10 @@ Deno.test( const res = await env.debugClient.traceTransaction( receipts[1].transactionHash, 'prestateTracer', - config + config, ) await matchFixture(t, res, 'trace_tx_write_storage_twice', diffMode) } - }) + }), ) diff --git a/src/util.ts b/src/util.ts index 4e58090..ef88419 100644 --- a/src/util.ts +++ b/src/util.ts @@ -27,9 +27,11 @@ export function getByteCode(name: string, evm: boolean): Hex { const bytecode = evm ? Deno.readFileSync(`evm/${name}.bin`) : Deno.readFileSync(`pvm/${name}.polkavm`) - return `0x${Array.from(bytecode) - .map((b: number) => b.toString(16).padStart(2, '0')) - .join('')}` as Hex + return `0x${ + Array.from(bytecode) + .map((b: number) => b.toString(16).padStart(2, '0')) + .join('') + }` as Hex } export type JsonRpcError = { @@ -86,7 +88,7 @@ function getEnvName(): EnvName { return 'revive-evm' } else { throw new Error( - 'No environment specified. Set USE_GETH or USE_REVIVE (pvm|evm)' + 'No environment specified. Set USE_GETH or USE_REVIVE (pvm|evm)', ) } } @@ -148,7 +150,7 @@ export async function getEnv() { async waitForTransactionReceipt( hash: Hex, pollingInterval = 100, - timeout = 30000 + timeout = 30000, ): Promise { const startTime = Date.now() while (true) { @@ -159,7 +161,7 @@ export async function getEnv() { const errorStr = String(error) if ( !errorStr.includes( - 'transaction indexing is in progress' + 'transaction indexing is in progress', ) && !errorStr.includes('transaction not found') && !errorStr.includes('TransactionReceiptNotFoundError') @@ -170,7 +172,7 @@ export async function getEnv() { } if (Date.now() - startTime > timeout) { throw new Error( - `Transaction receipt timeout after ${timeout}ms for hash ${hash}` + `Transaction receipt timeout after ${timeout}ms for hash ${hash}`, ) } await new Promise((resolve) => @@ -197,7 +199,7 @@ export async function getEnv() { const accountWallet = createWalletClient({ account: privateKeyToAccount( '0x5fb92d6e98884f76de468fa3f6278f8807c48bebc13595d45af5bdc4da702133', - { nonceManager } + { nonceManager }, ), transport, chain, @@ -222,7 +224,7 @@ export async function getEnv() { const emptyWallet = createWalletClient({ account: privateKeyToAccount( '0x4450c571bae82da0528ecf76fcf7079e12ecc46dc873c9cacb6db8b75ed22f41', - { nonceManager } + { nonceManager }, ), transport, chain, @@ -249,7 +251,7 @@ export async function getEnv() { traceTransaction( txHash: Hex, tracer: Tracer, - tracerConfig?: TracerConfig[Tracer] + tracerConfig?: TracerConfig[Tracer], ): Promise { return client.request({ method: 'debug_traceTransaction' as 'eth_chainId', @@ -259,7 +261,7 @@ export async function getEnv() { traceBlock( blockNumber: bigint, tracer: Tracer, - tracerConfig?: TracerConfig[Tracer] + tracerConfig?: TracerConfig[Tracer], ): Promise { return client.request({ method: 'debug_traceBlockByNumber' as 'eth_chainId', @@ -274,7 +276,7 @@ export async function getEnv() { args: TransactionRequest, tracer: Tracer, tracerConfig: TracerConfig[Tracer], - blockOrTag: 'latest' | Hex = 'latest' + blockOrTag: 'latest' | Hex = 'latest', ): Promise { return client.request({ method: 'debug_traceCall' as 'eth_chainId', @@ -349,7 +351,7 @@ export function waitForHealth(url: string) { export function visit( obj: unknown, - callback: (key: string, value: unknown) => [string, unknown] | null + callback: (key: string, value: unknown) => [string, unknown] | null, ): unknown { if (Array.isArray(obj)) { return obj.map((item) => visit(item, callback))