-
Notifications
You must be signed in to change notification settings - Fork 763
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement t8ntool to use for execution-spec-tests (#3603)
* tx: implement strict 7702 validation * vm: update 7702 tx validation * evm: update 7702 [no ci] * tx: add / fix 7702 tests * vm: fix test encoding of authorization lists [no ci] * vm: correctly put authority nonce * vm: add test 7702 extcodehash/extcodesize evm: fix extcodehash/extcodesize for delegated accounts * vm: expand extcode* tests 7702 [no ci] * tx/vm: update tests [no ci] * evm/vm: update opcodes and fix tests 7702 * fix cspell [no ci] * Implement t8n * cleanup * make start.sh executable * remove console.log [no ci] * change readme [no ci] * update t8n [no ci] * add sample (delete me later) * update t8n [no ci] * update t8n to correctly output alloc [no ci] * remove console.logs [no ci] * fix certain values for expected output [no ci] * some t8n fixes regarding output * lint [no ci] * t8n fixes for paris format [no ci] * vm: get params from tx for 7702 [no ci] * t8n console.log dumps [no ci] * vm: 7702 correctly apply the refund [no ci] * vm: 7702: correctly handle self-sponsored txs [no ci] * tx: throw if authorization list is empty * vm: requests do not throw if code is non-existant * evm: ensure correct extcodehash reporting if account is delegated to a non-existing account * update t8n to generate logs [no ci] * t8n correctly output log format [no ci] * change t8ntool start script name [no ci] * putcode log * vm: 7702 ensure delegated accounts are not deleted [no ci] * t8n: output CLrequests [no ci] * t8n: add initKzg / blob tx support * t8n: add blockhash support * t8n: produce allocation for system contracts * vm/buildBlock: take parentHash from headerData if present * t8n: lint [no ci] * vm: exit early if system contract has no code [no ci] * t8n: use mcl instead of noble for bls [no ci] * remove console.logs * evm: 7702 correctly check for gas on delegated code * evm: add verkle gas logic for 7702 * t8n: delete unwanted files [no ci] * vm/tx: fix 7702 tests * tx: throw if 7702-tx has no `to` field * vm/tx: fix 7702 tests * t8n: first cleanup * t8ntool: WIP [no ci] * VM: exit early on non-existing system contracts * VM: exit early on non-existing system contracts * backup [no ci] * t8ntool: do not delete coinbase * correctly exit early on requests * backup * 7702: add delegated account to warm address * 7702: add delegated account to warm address * increase memory limit * export node options * vm: requests do restore system account * vm: requests do restore system account * t8ntool: convert edge cases to correct values * 7702: continue processing once auth ecrecover is invalid * evm/vm: add 7702 delegation constant * vm: fix requests * vm: unduplify 3607 error msg * update wip t8n cleanup [no ci] * add TODO to buildblock * update t8ntool to use createVM [no ci] * update clean version as well [no ci] * fix example * t8ntool attempt to cleanup * t8ntool: cleanup * t8ntool fix import * remove old files * use noble bls t8ntool * add loggers to t8n args * add readme [no ci] * add t8ntool test * fix cspell * add deprecated output.body * make tsc happy * vm: fix 2935 test * Skip t8n tests in browser --------- Co-authored-by: acolytec3 <[email protected]>
- Loading branch information
1 parent
2cf4ddb
commit d4d9b37
Showing
21 changed files
with
917 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
} | ||
], | ||
"words": [ | ||
"t8ntool", | ||
"!Json", | ||
"!Rpc", | ||
"Hardfork", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,4 @@ | ||
.cachedb | ||
benchmarks/*.js | ||
test/t8n/testdata/output/allocTEST.json | ||
test/t8n/testdata/output/resultTEST.json |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import { readFileSync } from 'fs' | ||
import { assert, describe, it } from 'vitest' | ||
|
||
import { TransitionTool } from '../../t8n/t8ntool.js' | ||
|
||
import type { T8NOptions } from '../../t8n/types.js' | ||
|
||
const t8nDir = 'test/t8n/testdata/' | ||
|
||
const args: T8NOptions = { | ||
state: { | ||
fork: 'shanghai', | ||
reward: BigInt(0), | ||
chainid: BigInt(1), | ||
}, | ||
input: { | ||
alloc: `${t8nDir}input/alloc.json`, | ||
txs: `${t8nDir}input/txs.json`, | ||
env: `${t8nDir}input/env.json`, | ||
}, | ||
output: { | ||
basedir: t8nDir, | ||
result: `output/resultTEST.json`, | ||
alloc: `output/allocTEST.json`, | ||
}, | ||
log: false, | ||
} | ||
|
||
// This test is generated using `execution-spec-tests` commit 88cab2521322191b2ec7ef7d548740c0b0a264fc, running: | ||
// fill -k test_push0_contracts[fork_Shanghai-blockchain_test-key_sstore] --fork Shanghai tests/shanghai/eip3855_push0 --evm-bin=<ETHEREUMJS_T8NTOOL_LAUNCHER.sh> | ||
|
||
// The test will run the TransitionTool using the inputs, and then compare if the output matches | ||
|
||
describe('test runner config tests', () => { | ||
it('should run t8ntool with inputs and report the expected output', async () => { | ||
await TransitionTool.run(args) | ||
const expectedResult = JSON.parse(readFileSync(`${t8nDir}/output/result.json`).toString()) | ||
const expectedAlloc = JSON.parse(readFileSync(`${t8nDir}/output/alloc.json`).toString()) | ||
const reportedResult = JSON.parse(readFileSync(`${t8nDir}/output/resultTEST.json`).toString()) | ||
const reportedAlloc = JSON.parse(readFileSync(`${t8nDir}/output/allocTEST.json`).toString()) | ||
assert.deepStrictEqual(reportedResult, expectedResult, 'result matches expected result') | ||
assert.deepStrictEqual(reportedAlloc, expectedAlloc, 'alloc matches expected alloc') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# EVM T8NTool | ||
|
||
T8NTool, or Transition Tool, is a tool used to "fill tests" by test runners, for instance <https://github.com/ethereum/execution-spec-tests/>. These files take an input allocation (the pre-state), which contains the accounts (their balances, nonces, storage and code). It also provides an environment, which holds relevant data as current timestamp, previous block hashes, current gas limit, etc. Finally, it also provides a transactions file, which are the transactions to run on top of this pre-state and environment. It outputs the post-state and relevant other artifacts, such as tx receipts and their logs. Test fillers will take this output to generate relevant tests, such as Blockchain tests or State tests, which can then be directly ran in other clients, or using EthereumJS `npm run test:blockchain` or `npm run test:state`. | ||
|
||
## Using T8Ntool to fill `execution-spec-tests` | ||
|
||
To fill `execution-spec-tests` (or write own tests, and test those against the monorepo), follow these steps: | ||
|
||
1. Clone <https://github.com/ethereum/execution-spec-tests/>. | ||
2. Follow the installation steps: <https://github.com/ethereum/execution-spec-tests?tab=readme-ov-file#quick-start>. | ||
|
||
To fill tests, such as the EIP-1153 TSTORE/TLOAD tests, run: | ||
|
||
- `fill -vv -x --fork Cancun tests/cancun/eip1153_tstore/ --evm-bin=../ethereumjs-monorepo/packages/vm/test/t8n/ethereumjs-t8ntool.sh` | ||
|
||
Breaking down these arguments: | ||
|
||
- `-vv`: Verbose output | ||
- `-x`: Fail early if any of the test fillers fails | ||
- `--fork`: Fork to fill for | ||
- `--evm-bin`: relative/absolute path to t8ns `ethereumjs-t8ntool.sh` | ||
|
||
Optionally, it is also possible to add the `-k <TEST>` option which will only fill this certain test. | ||
|
||
## Debugging T8NTool with `execution-spec-tests` | ||
|
||
Sometimes it is unclear why a test fails, and one wants more verbose output (from the EthereumJS side). To do so, raw output from `execution-spec-tests` can be dumped by adding the `evm-dump-dir=<DIR>` flag to the `fill` command above. This will output `stdout`, `stderr`, the raw output allocation and the raw results (logs, receipts, etc.) to the `evm-dump-dir`. Additionally, if traces are wanted in `stdout`, add the `--log` flag to `ethereumjs-t8ntool.sh`, i.e. `tsx "$SCRIPT_DIR/launchT8N.ts" "$@" --log`. | ||
|
||
This will produce small EVM traces, like this: | ||
|
||
```typescript | ||
Processing new transaction... | ||
{ | ||
gasLeft: '9976184', | ||
stack: [], | ||
opName: 'CALLDATASIZE', | ||
depth: 0, | ||
address: '0x0000000000000000000000000000000000001000' | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/bin/bash | ||
if [[ "$1" == "--version" ]]; then | ||
echo "ethereumjs t8n v1" | ||
exit 0 | ||
fi | ||
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) | ||
export NODE_OPTIONS="--max-old-space-size=4096" | ||
tsx "$SCRIPT_DIR/launchT8N.ts" "$@" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import yargs from 'yargs' | ||
import { hideBin } from 'yargs/helpers' | ||
|
||
import type { T8NOptions } from './types.js' | ||
|
||
export function getArguments() { | ||
const argsParsed = yargs(hideBin(process.argv)) | ||
.parserConfiguration({ | ||
'dot-notation': false, | ||
}) | ||
.option('state.fork', { | ||
describe: 'Fork to use', | ||
type: 'string', | ||
demandOption: true, | ||
}) | ||
.option('state.chainid', { | ||
describe: 'ChainID to use', | ||
type: 'string', | ||
default: '1', | ||
}) | ||
.option('state.reward', { | ||
describe: | ||
'Coinbase reward after running txs. If 0: coinbase account is touched and rewarded 0 wei. If -1, the coinbase account is not touched (default)', | ||
type: 'string', | ||
default: '-1', | ||
}) | ||
.option('input.alloc', { | ||
describe: 'Initial state allocation', | ||
type: 'string', | ||
demandOption: true, | ||
}) | ||
.option('input.txs', { | ||
describe: 'JSON input of txs to run on top of the initial state allocation', | ||
type: 'string', | ||
demandOption: true, | ||
}) | ||
.option('input.env', { | ||
describe: 'Input environment (coinbase, difficulty, etc.)', | ||
type: 'string', | ||
demandOption: true, | ||
}) | ||
.option('output.basedir', { | ||
describe: 'Base directory to write output to', | ||
type: 'string', | ||
demandOption: true, | ||
}) | ||
.option('output.result', { | ||
describe: 'File to write output results to (relative to `output.basedir`)', | ||
type: 'string', | ||
demandOption: true, | ||
}) | ||
.option('output.alloc', { | ||
describe: 'File to write output allocation to (after running the transactions)', | ||
type: 'string', | ||
demandOption: true, | ||
}) | ||
.option('output.body', { | ||
deprecate: true, | ||
description: 'File to write transaction RLPs to (currently unused)', | ||
type: 'string', | ||
}) | ||
.option('log', { | ||
describe: 'Optionally write light-trace logs to stdout', | ||
type: 'boolean', | ||
default: false, | ||
}) | ||
.strict() | ||
.help().argv | ||
|
||
const args = argsParsed as any as T8NOptions | ||
|
||
args.input = { | ||
alloc: (<any>args)['input.alloc'], | ||
txs: (<any>args)['input.txs'], | ||
env: (<any>args)['input.env'], | ||
} | ||
args.output = { | ||
basedir: (<any>args)['output.basedir'], | ||
result: (<any>args)['output.result'], | ||
alloc: (<any>args)['output.alloc'], | ||
} | ||
args.state = { | ||
fork: (<any>args)['state.fork'], | ||
reward: BigInt((<any>args)['state.reward']), | ||
chainid: BigInt((<any>args)['state.chainid']), | ||
} | ||
|
||
return args | ||
} | ||
|
||
/** | ||
* This function accepts an `inputs.env` which converts non-hex-prefixed numbers | ||
* to a BigInt value, to avoid errors when converting non-prefixed hex strings to | ||
* numbers | ||
* @param input | ||
* @returns converted input | ||
*/ | ||
export function normalizeNumbers(input: any) { | ||
const keys = [ | ||
'currentGasLimit', | ||
'currentNumber', | ||
'currentTimestamp', | ||
'currentRandom', | ||
'currentDifficulty', | ||
'currentBaseFee', | ||
'currentBlobGasUsed', | ||
'currentExcessBlobGas', | ||
'parentDifficulty', | ||
'parentTimestamp', | ||
'parentBaseFee', | ||
'parentGasUsed', | ||
'parentGasLimit', | ||
'parentBlobGasUsed', | ||
'parentExcessBlobGas', | ||
] | ||
|
||
for (const key of keys) { | ||
const value = input[key] | ||
if (value !== undefined) { | ||
if (value.substring(0, 2) !== '0x') { | ||
input[key] = BigInt(value) | ||
} | ||
} | ||
} | ||
return input | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
import { getArguments } from './helpers.js' | ||
import { TransitionTool } from './t8ntool.js' | ||
|
||
await TransitionTool.run(getArguments()) |
Oops, something went wrong.