From 2e981492fdeb7ba77d2028064a98e1cb5d11d8d5 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 25 Apr 2025 02:51:08 +0700 Subject: [PATCH 01/22] compare merged base forks. (#87) * Doc Updates: Yet another round (EVM / VM / Other) (#3999) * EVM README updates * VM README updates * Minor update * More README doc updates * Update packages/evm/README.md * Update packages/vm/README.md --------- Co-authored-by: Gabriel Rocheleau * monorepo: clean up more test data (#4001) * monorepo: clean up more test data * chore: linting * vm: fix example * util: prefixed hex string type improvements (#3995) * chore: revert startsWith0x * util: fix hexToBytes in usage * util: remoe redundant byte checking * chore: more type adjustments * format: linting * monorepo: more type issues * util: undo remove undefined * chore: more type fixes * client: remove typecasting * client: simplify typecasting * common: remove typecasting * chore: remove unused import * chore: address review comments * chore: remove unused var * chore: strictEqual * monorepo: npm audit fix (#4003) * EVM: cleanup error messages and fix styling (#3994) * evm/vm: use constant as string to ref for `EVMError` * Remove unused EOFError key-values * Remove unused SimpleErrors * Remove unused EVMErrorMessages elements * Rename EvmErrorResult to EVMErrorResult * Rename Evm to EVM in comments and strings * Make EVMErrorMessages a static field in EVMError --------- Co-authored-by: Amir * fix: ethash test script (#4007) * util: remove undefined handling from bytesToHex (#4004) * util: document and remove undefined handling from bytesToHex * util: remove typecasting * util: refactor account handling * chore: simplify handling * util: deprecate account constructor and update docs * vm: fix event test * client: fix client tests * lint: remove console olgs * client: fix more client tests * lint: remove empty block * client: remove unnecessary optional chaining * client: remove it.only * feat(block): Add CLRequests test, example, and documentation (#4008) * feat(block): add CLRequests test, example, and documentation * fix(block): update CLRequests examples to use bytesToHex * chore: specify Node.js 20 in .nvmrc * util: replace unnecessary toBytes usage (#4014) * util: replace some toBytes usage * client: more hexToBytes * chore: remove more toBytes * chore: remove toBytes usage * lint: remove unused imports * chore: remove unused import * chore: remove unused import * Docs Cleanup / Cautious Restructuring / README ToCs (#4010) * A somewhat more useful EVM EIP activation example (now with 7702 being active by default) * Same for VM * Add prominent v10 README header additions * Add README ToC, eventually restructure (binarytree) * Add README ToC, eventually restructure (block) * Add README ToC, eventually restructure (blockchain) * Add README ToC, eventually restructure (common) * Add README ToC, eventually restructure (devp2p) * Add README ToC, eventually restructure (era) * Add README ToC, eventually restructure (ethash) * Some EVM README section reordering * Add README ToC, eventually restructure (EVM) * Add README ToC, eventually restructure (genesis) * Add README ToC, eventually restructure (mpt) * Add README ToC, eventually restructure (rlp) * Add README ToC, eventually restructure (statemanager) * Add README ToC, eventually restructure (tx) * Add sub-ToC for tx types * Add README ToC, eventually restructure (util) * Add README ToC, eventually restructure (verkle) * Add README ToC, eventually restructure (vm) * Add README ToC, eventually restructure (wallet) * Undo robot nonsense * evm: upgrade noble curves to 1.9.0 (#4018) --------- Co-authored-by: Holger Drewes Co-authored-by: Gabriel Rocheleau Co-authored-by: Jochem Brouwer Co-authored-by: Amir Co-authored-by: avdhesh.eth <49278246+avdheshcharjan@users.noreply.github.com> --- .nvmrc | 1 + package-lock.json | 55 +++-- packages/binarytree/README.md | 8 +- .../binarytree/test/node/internalNode.spec.ts | 5 +- .../binarytree/test/node/stemNode.spec.ts | 8 +- packages/block/README.md | 58 +++++- packages/block/examples/1559.ts | 2 +- packages/block/examples/clrequests.ts | 57 +++++ packages/block/src/block/constructors.ts | 6 +- packages/block/test/block.spec.ts | 38 ++-- packages/block/test/clrequests.spec.ts | 133 ++++++++++++ packages/block/test/header.spec.ts | 2 +- packages/blockchain/README.md | 22 +- packages/blockchain/test/index.spec.ts | 7 +- packages/client/bin/utils.ts | 5 +- packages/client/src/miner/pendingBlock.ts | 26 ++- packages/client/src/net/peerpool.ts | 2 +- packages/client/src/rpc/modules/admin.ts | 7 +- .../client/src/rpc/modules/engine/engine.ts | 3 +- packages/client/src/rpc/modules/web3.ts | 4 +- .../client/src/sync/fetcher/accountfetcher.ts | 14 +- .../src/sync/fetcher/trienodefetcher.ts | 6 +- packages/client/src/util/vkt.ts | 10 +- .../client/test/integration/miner.spec.ts | 10 +- packages/client/test/integration/pow.spec.ts | 14 +- packages/client/test/miner/miner.spec.ts | 4 +- .../client/test/rpc/admin/addPeer.spec.ts | 2 +- .../client/test/rpc/eth/getFeeHistory.spec.ts | 19 +- packages/client/test/rpc/mockBlockchain.ts | 22 +- packages/client/test/sim/snapsync.spec.ts | 2 +- .../test/sync/fetcher/accountfetcher.spec.ts | 43 ++-- .../test/sync/fetcher/storagefetcher.spec.ts | 8 +- packages/client/test/sync/skeleton.spec.ts | 6 +- packages/common/README.md | 33 +-- packages/common/examples/customChain.ts | 7 +- packages/common/examples/fromGeth.ts | 8 +- .../examples/genesisData/post-merge.json | 36 ---- .../common/examples/genesisData/testnet.json | 59 ------ .../common/examples/genesisData/testnet2.json | 59 ------ packages/common/src/gethGenesis.ts | 18 +- packages/common/test/hardforks.spec.ts | 10 +- packages/devp2p/README.md | 31 +-- packages/era/README.md | 45 ++-- packages/era/test/exportHistory.spec.ts | 4 +- packages/ethash/README.md | 12 +- packages/ethash/package.json | 2 +- packages/evm/README.md | 178 ++++++++-------- packages/evm/examples/eips.ts | 8 +- packages/evm/package.json | 2 +- packages/evm/src/eof/errors.ts | 34 --- packages/evm/src/errors.ts | 10 +- packages/evm/src/evm.ts | 30 +-- packages/evm/src/index.ts | 3 +- packages/evm/src/interpreter.ts | 38 ++-- packages/evm/src/opcodes/EIP2200.ts | 4 +- packages/evm/src/opcodes/functions.ts | 62 +++--- packages/evm/src/opcodes/gas.ts | 40 ++-- packages/evm/src/opcodes/util.ts | 2 +- packages/evm/src/precompiles/06-bn254-add.ts | 4 +- packages/evm/src/precompiles/07-bn254-mul.ts | 4 +- .../evm/src/precompiles/08-bn254-pairing.ts | 8 +- packages/evm/src/precompiles/09-blake2f.ts | 6 +- .../precompiles/0a-kzg-point-evaluation.ts | 14 +- .../evm/src/precompiles/0b-bls12-g1add.ts | 14 +- .../evm/src/precompiles/0c-bls12-g1msm.ts | 23 ++- .../evm/src/precompiles/0d-bls12-g2add.ts | 14 +- .../evm/src/precompiles/0e-bls12-g2msm.ts | 19 +- .../evm/src/precompiles/0f-bls12-pairing.ts | 19 +- .../src/precompiles/10-bls12-map-fp-to-g1.ts | 26 +-- .../src/precompiles/11-bls12-map-fp2-to-g2.ts | 14 +- packages/evm/src/precompiles/bls12_381/mcl.ts | 16 +- .../evm/src/precompiles/bls12_381/noble.ts | 12 +- packages/evm/src/precompiles/bn254/noble.ts | 8 +- packages/evm/src/stack.ts | 18 +- packages/evm/test/eips/eip-5450.spec.ts | 4 +- packages/evm/test/eips/eip-5656.spec.ts | 2 +- packages/evm/test/runCall.spec.ts | 17 +- packages/evm/test/runCode.spec.ts | 7 +- packages/evm/test/stack.spec.ts | 11 +- packages/evm/test/verkle.spec.ts | 7 +- packages/genesis/README.md | 11 +- packages/mpt/README.md | 30 ++- packages/mpt/src/util/encoding.ts | 7 +- packages/mpt/src/util/nibbles.ts | 9 +- packages/mpt/test/proof/range.spec.ts | 16 +- packages/mpt/test/trie/trie.spec.ts | 11 +- packages/rlp/README.md | 12 +- packages/statemanager/README.md | 105 +++++----- .../src/statefulBinaryTreeStateManager.ts | 12 +- .../src/statefulVerkleStateManager.ts | 12 +- .../src/statelessVerkleStateManager.ts | 4 +- packages/testdata/src/blocks/index.ts | 4 +- .../src/blocks/preLondonTestDataBlocks1.ts | 162 --------------- .../src/blocks/preLondonTestDataBlocks1RLP.ts | 11 + .../src/blocks/preLondonTestDataBlocks2.ts | 194 ------------------ .../src/blocks/preLondonTestDataBlocks2RLP.ts | 12 ++ .../invalidSpuriousDragonGethGenesis.ts | 2 +- .../src/gethGenesis/withdrawalsGethGenesis.ts | 4 +- packages/tx/README.md | 78 ++++--- packages/tx/examples/custom-chain-id-tx.ts | 4 +- packages/tx/src/legacy/tx.ts | 5 +- packages/tx/src/types.ts | 14 +- packages/tx/test/base.spec.ts | 13 +- packages/tx/test/t9n.spec.ts | 2 +- packages/util/README.md | 60 ++++-- packages/util/src/account.ts | 124 ++++------- packages/util/src/binaryTree.ts | 3 +- packages/util/src/bytes.ts | 13 +- packages/util/src/signature.ts | 7 +- packages/util/src/verkle.ts | 5 +- packages/util/test/account.spec.ts | 166 +++++++-------- packages/util/test/address.spec.ts | 5 +- packages/util/test/bytes.spec.ts | 24 ++- packages/util/test/types.spec.ts | 4 +- packages/verkle/README.md | 16 +- packages/verkle/test/util.spec.ts | 4 +- packages/vm/README.md | 144 ++++--------- .../helpers/blockchain-mock-data.json | 93 --------- .../examples/helpers/blockchain-mock-data.ts | 96 +++++++++ packages/vm/examples/run-blockchain.ts | 37 ++-- packages/vm/examples/run-solidity-contract.ts | 5 +- packages/vm/examples/runGoerliBlock.ts | 14 +- .../vm/examples/testData/goerliBlock2.json | 22 -- packages/vm/examples/vmWith4844.ts | 3 +- packages/vm/examples/vmWithEIPs.ts | 8 +- packages/vm/examples/vmWithGenesisState.ts | 7 +- .../eip-2935-historical-block-hashes.spec.ts | 4 +- packages/vm/test/api/EIPs/eip-3855.spec.ts | 6 +- packages/vm/test/api/buildBlock.spec.ts | 6 +- packages/vm/test/api/customChain.spec.ts | 2 +- packages/vm/test/api/events.spec.ts | 6 +- .../vm/test/api/istanbul/eip-1344.spec.ts | 4 +- .../vm/test/api/istanbul/eip-1884.spec.ts | 4 +- packages/vm/test/api/runBlock.spec.ts | 3 +- packages/vm/test/t8n/stateTracker.ts | 2 +- packages/vm/test/t8n/t8ntool.ts | 2 +- .../tester/runners/BlockchainTestsRunner.ts | 3 +- packages/wallet/README.md | 26 +-- 138 files changed, 1542 insertions(+), 1731 deletions(-) create mode 100644 .nvmrc create mode 100644 packages/block/examples/clrequests.ts create mode 100644 packages/block/test/clrequests.spec.ts delete mode 100644 packages/common/examples/genesisData/post-merge.json delete mode 100644 packages/common/examples/genesisData/testnet.json delete mode 100644 packages/common/examples/genesisData/testnet2.json delete mode 100644 packages/testdata/src/blocks/preLondonTestDataBlocks1.ts create mode 100644 packages/testdata/src/blocks/preLondonTestDataBlocks1RLP.ts delete mode 100644 packages/testdata/src/blocks/preLondonTestDataBlocks2.ts create mode 100644 packages/testdata/src/blocks/preLondonTestDataBlocks2RLP.ts delete mode 100644 packages/vm/examples/helpers/blockchain-mock-data.json create mode 100644 packages/vm/examples/helpers/blockchain-mock-data.ts delete mode 100644 packages/vm/examples/testData/goerliBlock2.json diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000000..58172ab353f --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +20 \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index d38f9d49ec0..5741d70e058 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16323,15 +16323,18 @@ } }, "node_modules/vite": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz", - "integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==", + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.2.tgz", + "integrity": "sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", + "fdir": "^6.4.3", + "picomatch": "^4.0.2", "postcss": "^8.5.3", - "rollup": "^4.30.1" + "rollup": "^4.34.9", + "tinyglobby": "^0.2.12" }, "bin": { "vite": "bin/vite.js" @@ -16456,6 +16459,34 @@ "vite": "^2 || ^3 || ^4 || ^5 || ^6" } }, + "node_modules/vite/node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/vitest": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz", @@ -17643,7 +17674,7 @@ "@ethereumjs/statemanager": "^10.0.0-rc.1", "@ethereumjs/util": "^10.0.0-rc.1", "@ethereumjs/verkle": "^10.0.0-dev-rc.1", - "@noble/curves": "^1.8.2", + "@noble/curves": "^1.9.0", "@types/debug": "^4.1.12", "debug": "^4.4.0", "ethereum-cryptography": "^3.1.0", @@ -17672,12 +17703,12 @@ } }, "packages/evm/node_modules/@noble/curves": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.8.2.tgz", - "integrity": "sha512-vnI7V6lFNe0tLAuJMu+2sX+FcL14TaCWy1qiczg1VwRmPrpQCdq5ESXQMqUc2tluRNf6irBXrWbl1mGN8uaU/g==", + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@noble/curves/-/curves-1.9.0.tgz", + "integrity": "sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==", "license": "MIT", "dependencies": { - "@noble/hashes": "1.7.2" + "@noble/hashes": "1.8.0" }, "engines": { "node": "^14.21.3 || >=16" @@ -17687,9 +17718,9 @@ } }, "packages/evm/node_modules/@noble/hashes": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.7.2.tgz", - "integrity": "sha512-biZ0NUSxyjLLqo6KxEJ1b+C2NAx0wtDoFvCaXHGgUkeHzf3Xc1xKumFKREuT7f7DARNZ/slvYUwFG6B0f2b6hQ==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", "license": "MIT", "engines": { "node": "^14.21.3 || >=16" diff --git a/packages/binarytree/README.md b/packages/binarytree/README.md index 46c5fcaec20..22156e4d323 100644 --- a/packages/binarytree/README.md +++ b/packages/binarytree/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/binarytree +# @ethereumjs/binarytree `v10` [![NPM Package][binarytree-npm-badge]][binarytree-npm-link] [![GitHub Issues][binarytree-issues-badge]][binarytree-issues-link] @@ -13,6 +13,12 @@ This package is currently in early alpha and is a work in progress. It is not intended for use in production environments, but rather for research and development purposes. Any help in improving the package is very much welcome. +## Table of Contents + +- [Installation](#installation) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Installation To obtain the latest version, simply install the project using `npm`: diff --git a/packages/binarytree/test/node/internalNode.spec.ts b/packages/binarytree/test/node/internalNode.spec.ts index 6c3e5890d51..c62d76f3601 100644 --- a/packages/binarytree/test/node/internalNode.spec.ts +++ b/packages/binarytree/test/node/internalNode.spec.ts @@ -2,17 +2,16 @@ import { equalsBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { BinaryNodeType, InternalBinaryNode, decodeBinaryNode } from '../../src/index.ts' -import {} from '../../src/types.ts' describe('InternalBinaryNode', () => { it('should round-trip encode and decode an internal node', () => { // Create dummy child pointers: const leftCanonicalChild = { - hash: hexToBytes('0x' + '11'.repeat(32)), + hash: hexToBytes(`0x${'11'.repeat(32)}`), path: [0, 1, 1, 0, 1, 0], } const rightCanonicalChild = { - hash: hexToBytes('0x' + '22'.repeat(32)), + hash: hexToBytes(`0x${'22'.repeat(32)}`), path: [1, 1, 0, 0], } const node = InternalBinaryNode.create([leftCanonicalChild, rightCanonicalChild]) diff --git a/packages/binarytree/test/node/stemNode.spec.ts b/packages/binarytree/test/node/stemNode.spec.ts index 941ce9a6612..d55436e3744 100644 --- a/packages/binarytree/test/node/stemNode.spec.ts +++ b/packages/binarytree/test/node/stemNode.spec.ts @@ -7,14 +7,14 @@ import { StemBinaryNode } from '../../src/node/stemNode.ts' describe('StemBinaryNode', () => { it('should round-trip encode and decode a stem node', () => { // Create a 31-byte stem (for example, all 0x01 bytes) - const stem = hexToBytes('0x' + '01'.repeat(31)) + const stem = hexToBytes(`0x${'01'.repeat(31)}`) // Create an array of 256 possible values (initially all null) const values: (Uint8Array | null)[] = new Array(256).fill(null) // Set a few non-null values at specific indices - const value3 = hexToBytes('0x' + '02'.repeat(32)) - const value100 = hexToBytes('0x' + '03'.repeat(32)) - const value255 = hexToBytes('0x' + '04'.repeat(32)) + const value3 = hexToBytes(`0x${'02'.repeat(32)}`) + const value100 = hexToBytes(`0x${'03'.repeat(32)}`) + const value255 = hexToBytes(`0x${'04'.repeat(32)}`) values[3] = value3 values[100] = value100 values[255] = value255 diff --git a/packages/block/README.md b/packages/block/README.md index 638f415f504..15e7ad0bc48 100644 --- a/packages/block/README.md +++ b/packages/block/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/block +# @ethereumjs/block `v10` [![NPM Package][block-npm-badge]][block-npm-link] [![GitHub Issues][block-issues-badge]][block-issues-link] @@ -9,6 +9,17 @@ | Implements schema and functions related to Ethereum blocks. | | ----------------------------------------------------------- | +## Table of Contents + +- [Installation](#installation) +- [Getting Started](#getting-started) +- [EIP Integrations](#eip-integrations) +- [Consensus Types](#consensus-types) +- [Browser](#browser) +- [API](#api) +- [Testing](#testing) +- [EthereumJS](#ethereumjs) +- [License](#license) ## Installation @@ -20,9 +31,9 @@ npm install @ethereumjs/block **Note:** If you want to work with `EIP-4844` related functionality, you will have additional initialization steps for the **KZG setup**, see related section below. -## Usage +## Getting Started -### Introduction +### Instantiation There are several standalone functions to instantiate a `Block`: @@ -82,7 +93,9 @@ try { This library by default uses JavaScript implementations for the basic standard crypto primitives like hashing or signature verification (for included txs). See `@ethereumjs/common` [README](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/common) for instructions on how to replace with e.g. a more performant WASM implementation by using a shared `common` instance. -### EIP-1559 Blocks +## EIP Integrations + +### Blocks with an EIP-1559 Fee Market By default (since `Hardfork.London`) blocks created with this library are [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) compatible. @@ -141,7 +154,7 @@ try { } ``` -### EIP-4895 Beacon Chain Withdrawals Blocks +### Blocks with EIP-4895 Beacon Chain Withdrawals Starting with the `v4.1.0` release there is support for [EIP-4895](https://eips.ethereum.org/EIPS/eip-4895) beacon chain withdrawals (`Hardfork.Shanghai` or higher). To create a block containing system-level withdrawals, the `withdrawals` data option together with a matching `withdrawalsRoot` can be used: @@ -182,7 +195,7 @@ console.log(`Block with ${block.withdrawals!.length} withdrawal(s) created`) Validation of the withdrawals trie can be manually triggered with the newly introduced async `Block.withdrawalsTrieIsValid()` method. -### EIP-4844 Shard Blob Transaction Blocks +### Blocks with EIP-4844 Shard Blob Transactions This library supports the blob transaction type introduced with [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) (`Hardfork.Cancun` or higher), see the following example: @@ -240,6 +253,39 @@ void main() Starting with v10 this library supports requests to the consensus layer which have been introduced with [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685) (`Hardfork.Prague` or higher). See the `@ethereumjs/util` [Request](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/util#module-request) README section for an overview of current request types. +```ts +// ./examples/clrequests.ts + +import { Common, Hardfork, Mainnet } from '@ethereumjs/common' +import { createCLRequest, CLRequestType, hexToBytes, bytesToHex } from '@ethereumjs/util' +import { sha256 } from 'ethereum-cryptography/sha256.js' + +import { createBlock, genRequestsRoot } from '../src' + +// Enable EIP-7685 to support CLRequests +const common = new Common({ chain: Mainnet, hardfork: Hardfork.Cancun, eips: [7685] }) + +// Create the three CLRequest types (Deposit, Withdrawal, Consolidation) +const depositData = hexToBytes('0x00...') // Deposit request data +const depositRequest = createCLRequest(depositData) + +const withdrawalData = hexToBytes('0x01...') // Withdrawal request data +const withdrawalRequest = createCLRequest(withdrawalData) + +const consolidationData = hexToBytes('0x02...') // Consolidation request data +const consolidationRequest = createCLRequest(consolidationData) + +// CLRequests must be sorted by type (Deposit=0, Withdrawal=1, Consolidation=2) +const requests = [depositRequest, withdrawalRequest, consolidationRequest] + +// Generate the requestsHash +const requestsHash = genRequestsRoot(requests, sha256) + +// Create a block with the CLRequests hash +const block = createBlock({ header: { requestsHash } }, { common }) +console.log(`Created block with CLRequests hash: 0x${bytesToHex(block.hash())}`) +``` + ### Consensus Types ### Proof-of-Stake diff --git a/packages/block/examples/1559.ts b/packages/block/examples/1559.ts index e5139a9766b..f695abcb587 100644 --- a/packages/block/examples/1559.ts +++ b/packages/block/examples/1559.ts @@ -1,5 +1,5 @@ import { createBlock } from '@ethereumjs/block' -import { Common, Hardfork, Mainnet } from '@ethereumjs/common' +import { Common, Mainnet } from '@ethereumjs/common' import { createTx } from '@ethereumjs/tx' const common = new Common({ chain: Mainnet }) diff --git a/packages/block/examples/clrequests.ts b/packages/block/examples/clrequests.ts new file mode 100644 index 00000000000..308e4b3dd7c --- /dev/null +++ b/packages/block/examples/clrequests.ts @@ -0,0 +1,57 @@ +import { Common, Hardfork, Mainnet } from '@ethereumjs/common' +import { CLRequestType, bytesToHex, createCLRequest, hexToBytes } from '@ethereumjs/util' +import { sha256 } from 'ethereum-cryptography/sha256.js' + +import { createBlock, genRequestsRoot } from '../src' + +// Enable EIP-7685 to support CLRequests +const common = new Common({ chain: Mainnet, hardfork: Hardfork.Cancun, eips: [7685] }) + +// Create examples of the three CLRequest types +const createExampleRequests = () => { + // Create a deposit request (type 0) + const depositData = hexToBytes( + '0x00ac842878bb70009552a4cfcad801d6e659c50bd50d7d03306790cb455ce7363c5b6972f0159d170f625a99b2064dbefc010000000000000000000000818ccb1c4eda80270b04d6df822b1e72dd83c3030040597307000000a747f75c72d0cf0d2b52504c7385b516f0523e2f0842416399f42b4aee5c6384a5674f6426b1cc3d0827886fa9b909e616f5c9f61f986013ed2b9bf37071cbae951136265b549f44e3c8e26233c0433e9124b7fd0dc86e82f9fedfc0a179d7690000000000000000', + ) + const depositRequest = createCLRequest(depositData) + + // Create a withdrawal request (type 1) + const withdrawalData = hexToBytes( + '0x01000000000000000000000000000000000000000001000000000000000000000de0b6b3a7640000', + ) + const withdrawalRequest = createCLRequest(withdrawalData) + + // Create a consolidation request (type 2) + const consolidationData = hexToBytes('0x020000000100000000000000000000000000000000000001') + const consolidationRequest = createCLRequest(consolidationData) + + // CLRequests must be sorted by type (Deposit=0, Withdrawal=1, Consolidation=2) + return [depositRequest, withdrawalRequest, consolidationRequest] +} + +// Generate a block with CLRequests +function createBlockWithCLRequests() { + const requests = createExampleRequests() + console.log(`Created ${requests.length} CLRequests:`) + + for (const req of requests) { + console.log( + `- Type: ${req.type} (${Object.keys(CLRequestType).find( + (k) => CLRequestType[k as keyof typeof CLRequestType] === req.type, + )})`, + ) + } + + // Generate the requestsHash by hashing all the CLRequests + const requestsHash = genRequestsRoot(requests, sha256) + console.log(`Generated requestsHash: 0x${bytesToHex(requestsHash)}`) + + // Create a block with the CLRequests hash + const block = createBlock({ header: { requestsHash } }, { common }) + console.log(`Created block hash: 0x${bytesToHex(block.hash())}`) + + return block +} + +// Execute +createBlockWithCLRequests() diff --git a/packages/block/src/block/constructors.ts b/packages/block/src/block/constructors.ts index 8f876eb2f51..65b23ad8007 100644 --- a/packages/block/src/block/constructors.ts +++ b/packages/block/src/block/constructors.ts @@ -31,7 +31,7 @@ import { executionPayloadFromBeaconPayload, } from '../index.ts' -import type { EthersProvider, PrefixedHexString, WithdrawalBytes } from '@ethereumjs/util' +import type { EthersProvider, WithdrawalBytes } from '@ethereumjs/util' import type { BeaconPayloadJSON } from '../from-beacon-payload.ts' import type { BlockBytes, @@ -339,7 +339,7 @@ export async function createBlockFromExecutionPayload( const txs = [] for (const [index, serializedTx] of transactions.entries()) { try { - const tx = createTxFromRLP(hexToBytes(serializedTx as PrefixedHexString), { + const tx = createTxFromRLP(hexToBytes(serializedTx), { common: opts?.common, }) txs.push(tx) @@ -377,7 +377,7 @@ export async function createBlockFromExecutionPayload( throw Error('Missing executionWitness for EIP-6800 activated executionPayload') } // Verify blockHash matches payload - if (!equalsBytes(block.hash(), hexToBytes(payload.blockHash as PrefixedHexString))) { + if (!equalsBytes(block.hash(), hexToBytes(payload.blockHash))) { const validationError = `Invalid blockHash, expected: ${ payload.blockHash }, received: ${bytesToHex(block.hash())}` diff --git a/packages/block/test/block.spec.ts b/packages/block/test/block.spec.ts index 89e25f2d3ec..c005ea44d22 100644 --- a/packages/block/test/block.spec.ts +++ b/packages/block/test/block.spec.ts @@ -2,12 +2,12 @@ import { Common, Hardfork, Mainnet, createCustomCommon } from '@ethereumjs/commo import { RLP } from '@ethereumjs/rlp' import { goerliChainConfig, - preLondonTestDataBlocks1, - preLondonTestDataBlocks2, + preLondonTestDataBlocks1RLP, + preLondonTestDataBlocks2RLP, testnetMergeChainConfig, } from '@ethereumjs/testdata' import { createLegacyTx } from '@ethereumjs/tx' -import { KECCAK256_RLP_ARRAY, bytesToHex, equalsBytes, hexToBytes, toBytes } from '@ethereumjs/util' +import { KECCAK256_RLP_ARRAY, bytesToHex, equalsBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { genTransactionsTrieRoot } from '../src/helpers.ts' @@ -25,7 +25,7 @@ import { import { genesisHashesTestData } from './testdata/genesisHashesTest.ts' import { testdataFromRPCGoerliData } from './testdata/testdata-from-rpc-goerli.ts' -import type { NestedUint8Array, PrefixedHexString } from '@ethereumjs/util' +import type { NestedUint8Array } from '@ethereumjs/util' describe('[Block]: block functions', () => { it('should test block initialization', () => { @@ -137,7 +137,7 @@ describe('[Block]: block functions', () => { it('should test block validation on pow chain', async () => { const common = new Common({ chain: Mainnet, hardfork: Hardfork.Istanbul }) - const blockRlp = hexToBytes(preLondonTestDataBlocks1.blocks[0].rlp as PrefixedHexString) + const blockRlp = hexToBytes(preLondonTestDataBlocks1RLP.blockRLP) try { createBlockFromRLP(blockRlp, { common }) assert.isTrue(true, 'should pass') @@ -163,7 +163,7 @@ describe('[Block]: block functions', () => { } it('should test transaction validation - invalid tx trie', async () => { - const blockRlp = hexToBytes(preLondonTestDataBlocks1.blocks[0].rlp as PrefixedHexString) + const blockRlp = hexToBytes(preLondonTestDataBlocks1RLP.blockRLP) const common = new Common({ chain: Mainnet, hardfork: Hardfork.London }) const block = createBlockFromRLP(blockRlp, { common, freeze: false }) await testTransactionValidation(block) @@ -205,7 +205,7 @@ describe('[Block]: block functions', () => { it('should test transaction validation with legacy tx in london', async () => { const common = new Common({ chain: Mainnet, hardfork: Hardfork.London }) - const blockRlp = hexToBytes(preLondonTestDataBlocks1.blocks[0].rlp as PrefixedHexString) + const blockRlp = hexToBytes(preLondonTestDataBlocks1RLP.blockRLP) const block = createBlockFromRLP(blockRlp, { common, freeze: false }) await testTransactionValidation(block) // @ts-expect-error -- Assigning to read-only property @@ -219,7 +219,7 @@ describe('[Block]: block functions', () => { it('should test uncles hash validation', async () => { const common = new Common({ chain: Mainnet, hardfork: Hardfork.Istanbul }) - const blockRlp = hexToBytes(preLondonTestDataBlocks2.blocks[2].rlp as PrefixedHexString) + const blockRlp = hexToBytes(preLondonTestDataBlocks2RLP.block2RLP) const block = createBlockFromRLP(blockRlp, { common, freeze: false }) assert.equal(block.uncleHashIsValid(), true) // @ts-expect-error -- Assigning to read-only property @@ -356,31 +356,23 @@ describe('[Block]: block functions', () => { it('should return the same block data from raw()', () => { const common = new Common({ chain: Mainnet, hardfork: Hardfork.Istanbul }) - const block = createBlockFromRLP( - toBytes(preLondonTestDataBlocks2.blocks[2].rlp as PrefixedHexString), - { - common, - }, - ) + const block = createBlockFromRLP(hexToBytes(preLondonTestDataBlocks2RLP.block2RLP), { + common, + }) const createBlockFromRaw = createBlockFromBytesArray(block.raw(), { common }) assert.isTrue(equalsBytes(block.hash(), createBlockFromRaw.hash())) }) it('should test toJSON', () => { const common = new Common({ chain: Mainnet, hardfork: Hardfork.Istanbul }) - const block = createBlockFromRLP( - toBytes(preLondonTestDataBlocks2.blocks[2].rlp as PrefixedHexString), - { - common, - }, - ) + const block = createBlockFromRLP(hexToBytes(preLondonTestDataBlocks2RLP.block2RLP), { + common, + }) assert.equal(typeof block.toJSON(), 'object') }) it('DAO hardfork', () => { - const blockData = RLP.decode( - preLondonTestDataBlocks2.blocks[0].rlp as PrefixedHexString, - ) as NestedUint8Array + const blockData = RLP.decode(preLondonTestDataBlocks2RLP.block0RLP) as NestedUint8Array // Set block number from test block to mainnet DAO fork block 1920000 blockData[0][8] = hexToBytes('0x1D4C00') diff --git a/packages/block/test/clrequests.spec.ts b/packages/block/test/clrequests.spec.ts new file mode 100644 index 00000000000..d3ee90ec1c0 --- /dev/null +++ b/packages/block/test/clrequests.spec.ts @@ -0,0 +1,133 @@ +import { Common, Hardfork, Mainnet } from '@ethereumjs/common' +import { CLRequestType, createCLRequest, equalsBytes, hexToBytes } from '@ethereumjs/util' +import { sha256 } from 'ethereum-cryptography/sha256.js' +import { assert, describe, it } from 'vitest' + +import { createBlock, genRequestsRoot } from '../src/index.ts' + +import type { CLRequest } from '@ethereumjs/util' + +describe('[Block]: CLRequests tests', () => { + // Common with EIP-7685 enabled (CLRequests) + const common = new Common({ chain: Mainnet, hardfork: Hardfork.Cancun, eips: [7685] }) + + function createDepositRequest(): CLRequest { + // Example deposit data + const sampleDepositRequest = hexToBytes( + '0x00ac842878bb70009552a4cfcad801d6e659c50bd50d7d03306790cb455ce7363c5b6972f0159d170f625a99b2064dbefc010000000000000000000000818ccb1c4eda80270b04d6df822b1e72dd83c3030040597307000000a747f75c72d0cf0d2b52504c7385b516f0523e2f0842416399f42b4aee5c6384a5674f6426b1cc3d0827886fa9b909e616f5c9f61f986013ed2b9bf37071cbae951136265b549f44e3c8e26233c0433e9124b7fd0dc86e82f9fedfc0a179d7690000000000000000', + ) + return createCLRequest(sampleDepositRequest) + } + + function createWithdrawalRequest(): CLRequest { + // Type 1 (Withdrawal) + example data + const withdrawalData = hexToBytes( + '0x01000000000000000000000000000000000000000001000000000000000000000de0b6b3a7640000', + ) + return createCLRequest(withdrawalData) + } + + function createConsolidationRequest(): CLRequest { + // Type 2 (Consolidation) + example data + const consolidationData = hexToBytes('0x020000000100000000000000000000000000000000000001') + return createCLRequest(consolidationData) + } + + it('should create a block with deposit request', () => { + const depositRequest = createDepositRequest() + assert.equal(depositRequest.type, CLRequestType.Deposit, 'should be a deposit request') + + const requestsHash = genRequestsRoot([depositRequest], sha256) + const block = createBlock( + { + header: { requestsHash }, + }, + { common }, + ) + + assert.isDefined(block.header.requestsHash, 'block should have requestsHash') + assert.isTrue( + equalsBytes(block.header.requestsHash!, requestsHash), + 'requestsHash should match the expected value', + ) + }) + + it('should create a block with withdrawal request', () => { + const withdrawalRequest = createWithdrawalRequest() + assert.equal(withdrawalRequest.type, CLRequestType.Withdrawal, 'should be a withdrawal request') + + const requestsHash = genRequestsRoot([withdrawalRequest], sha256) + const block = createBlock( + { + header: { requestsHash }, + }, + { common }, + ) + + assert.isDefined(block.header.requestsHash, 'block should have requestsHash') + assert.isTrue( + equalsBytes(block.header.requestsHash!, requestsHash), + 'requestsHash should match the expected value', + ) + }) + + it('should create a block with consolidation request', () => { + const consolidationRequest = createConsolidationRequest() + assert.equal( + consolidationRequest.type, + CLRequestType.Consolidation, + 'should be a consolidation request', + ) + + const requestsHash = genRequestsRoot([consolidationRequest], sha256) + const block = createBlock( + { + header: { requestsHash }, + }, + { common }, + ) + + assert.isDefined(block.header.requestsHash, 'block should have requestsHash') + assert.isTrue( + equalsBytes(block.header.requestsHash!, requestsHash), + 'requestsHash should match the expected value', + ) + }) + + it('should create a block with multiple CLRequests', () => { + const depositRequest = createDepositRequest() + const withdrawalRequest = createWithdrawalRequest() + const consolidationRequest = createConsolidationRequest() + + // Requests should be sorted by type + const requests = [depositRequest, withdrawalRequest, consolidationRequest] + const requestsHash = genRequestsRoot(requests, sha256) + + const block = createBlock( + { + header: { requestsHash }, + }, + { common }, + ) + + assert.isDefined(block.header.requestsHash, 'block should have requestsHash') + assert.isTrue( + equalsBytes(block.header.requestsHash!, requestsHash), + 'requestsHash should match the expected value', + ) + }) + + it('should validate the requests are sorted by type', () => { + const depositRequest = createDepositRequest() + const withdrawalRequest = createWithdrawalRequest() + + // Requests in wrong order should throw + const requests = [withdrawalRequest, depositRequest] + + assert.throws( + () => genRequestsRoot(requests, sha256), + 'requests are not sorted in ascending order', + 'should throw when requests are not sorted by type', + ) + }) +}) diff --git a/packages/block/test/header.spec.ts b/packages/block/test/header.spec.ts index 5c71e7c2d0a..8b4882c6fbc 100644 --- a/packages/block/test/header.spec.ts +++ b/packages/block/test/header.spec.ts @@ -320,7 +320,7 @@ describe('[Block]: Header functions', () => { const common = new Common({ chain: goerliChainConfig, hardfork: Hardfork.Istanbul }) const blockchain = new Mockchain() - const genesisRlp = toBytes(testDataPreLondon.genesisRLP) + const genesisRlp = hexToBytes(testDataPreLondon.genesisRLP) const block = createBlockFromRLP(genesisRlp, { common }) await blockchain.putBlock(block) diff --git a/packages/blockchain/README.md b/packages/blockchain/README.md index 6e77fed5385..7fcfc98aa3a 100644 --- a/packages/blockchain/README.md +++ b/packages/blockchain/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/blockchain +# @ethereumjs/blockchain `v10` [![NPM Package][blockchain-npm-badge]][blockchain-npm-link] [![GitHub Issues][blockchain-issues-badge]][blockchain-issues-link] @@ -9,6 +9,18 @@ | A module to store and interact with blocks. | | ------------------------------------------- | +## Table of Contents + +- [Installation](#installation) +- [Getting Started](#getting-started) +- [EIP Integrations](#eip-integrations) +- [Consensus Types](#consensus-types) +- [Browser](#browser) +- [API](#api) +- [Testing](#testing) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Installation To obtain the latest version, simply install the project using `npm`: @@ -19,7 +31,7 @@ npm install @ethereumjs/blockchain **Note:** If you want to work with `EIP-4844` related functionality, you will have additional initialization steps for the **KZG setup**, see related section below. -## Usage +## Getting Started ### Introduction @@ -29,7 +41,7 @@ New blocks can be added to the blockchain. Validation ensures that the block for The library also supports reorg scenarios e.g. by allowing to add a new block with `Blockchain.putBlock()` which follows a different canonical path to the head than given by the current canonical head block. -## Example +## Examples The following is an example to instantiate a simple Blockchain object, put blocks into the blockchain and then iterate through the blocks added: @@ -88,6 +100,10 @@ const main = async () => { void main() ``` +More examples can be found in the [examples](./examples/) folder. + +## Setup + ### Block Storage For storing blocks different backends can be used. The database needs to conform to the [DB](https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/util/src/db.ts) interface provided in the `@ethereumjs/util` package (since this is used in other places as well). diff --git a/packages/blockchain/test/index.spec.ts b/packages/blockchain/test/index.spec.ts index 2a1c0ef784b..356b6a37552 100644 --- a/packages/blockchain/test/index.spec.ts +++ b/packages/blockchain/test/index.spec.ts @@ -5,7 +5,7 @@ import { createBlockHeaderFromBytesArray, } from '@ethereumjs/block' import { Common, Hardfork, Holesky, Mainnet, Sepolia } from '@ethereumjs/common' -import { goerliChainConfig, mainnetBlocks, preLondonTestDataBlocks1 } from '@ethereumjs/testdata' +import { goerliChainConfig, mainnetBlocks, preLondonTestDataBlocks1RLP } from '@ethereumjs/testdata' import { MapDB, bytesToHex, equalsBytes, hexToBytes, utf8ToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -14,7 +14,6 @@ import { Blockchain, createBlockchain, createBlockchainFromBlocksData } from '.. import { createTestDB, generateBlockchain, generateBlocks, isConsecutive } from './util.ts' import type { Block, BlockOptions } from '@ethereumjs/block' -import type { PrefixedHexString } from '@ethereumjs/util' describe('blockchain test', () => { it('should not crash on getting head of a blockchain without a genesis', async () => { @@ -581,7 +580,7 @@ describe('blockchain test', () => { it('should add block with body', async () => { const common = new Common({ chain: Mainnet, hardfork: Hardfork.Istanbul }) - const genesisRlp = hexToBytes(preLondonTestDataBlocks1.genesisRLP as PrefixedHexString) + const genesisRlp = hexToBytes(preLondonTestDataBlocks1RLP.genesisRLP) const genesisBlock = createBlockFromRLP(genesisRlp, { common }) const blockchain = await createBlockchain({ validateBlocks: true, @@ -589,7 +588,7 @@ describe('blockchain test', () => { genesisBlock, }) - const blockRlp = hexToBytes(preLondonTestDataBlocks1.blocks[0].rlp as PrefixedHexString) + const blockRlp = hexToBytes(preLondonTestDataBlocks1RLP.blockRLP) const block = createBlockFromRLP(blockRlp, { common }) await blockchain.putBlock(block) }) diff --git a/packages/client/bin/utils.ts b/packages/client/bin/utils.ts index e4aca62147c..2c034967fad 100644 --- a/packages/client/bin/utils.ts +++ b/packages/client/bin/utils.ts @@ -52,7 +52,7 @@ import { Event } from '../src/types.ts' import { parseMultiaddrs } from '../src/util/index.ts' import { setupMetrics } from '../src/util/metrics.ts' -import type { CustomCrypto, GenesisState } from '@ethereumjs/common' +import type { CustomCrypto, GenesisState, GethGenesis } from '@ethereumjs/common' import type { Address, PrefixedHexString } from '@ethereumjs/util' import type { Logger } from '../src/logging.ts' import type { ClientOpts } from '../src/types.ts' @@ -495,7 +495,7 @@ async function setupDevnet(prefundAddress: Address, args: ClientOpts) { epoch: 30000, }, } - const defaultChainData = { + const defaultChainData: GethGenesis = { config: { chainId: 123456, homesteadBlock: 0, @@ -521,6 +521,7 @@ async function setupDevnet(prefundAddress: Address, args: ClientOpts) { gasUsed: '0x0', parentHash: '0x0000000000000000000000000000000000000000000000000000000000000000', baseFeePerGas: 7, + alloc: {}, } const extraData = args.dev === 'pow' ? '0x' + '0'.repeat(32) : '0x' + '0'.repeat(64) + addr + '0'.repeat(130) diff --git a/packages/client/src/miner/pendingBlock.ts b/packages/client/src/miner/pendingBlock.ts index 47e606e0a34..5f92dae3027 100644 --- a/packages/client/src/miner/pendingBlock.ts +++ b/packages/client/src/miner/pendingBlock.ts @@ -9,7 +9,6 @@ import { concatBytes, createZeroAddress, equalsBytes, - toBytes, toType, } from '@ethereumjs/util' import { BuildStatus, buildBlock } from '@ethereumjs/vm' @@ -145,19 +144,18 @@ export class PendingBlock { const keccakFunction = this.config.chainCommon.customCrypto.keccak256 ?? keccak256 - const payloadIdBytes = toBytes( - keccakFunction( - concatBytes( - parentBlock.hash(), - mixHashBuf, - timestampBuf, - gasLimitBuf, - parentBeaconBlockRootBuf, - coinbaseBuf, - withdrawalsBuf, - ), - ).subarray(0, 8), - ) + const payloadIdBytes = keccakFunction( + concatBytes( + parentBlock.hash(), + mixHashBuf, + timestampBuf, + gasLimitBuf, + parentBeaconBlockRootBuf, + coinbaseBuf, + withdrawalsBuf, + ), + ).subarray(0, 8) + const payloadId = bytesToHex(payloadIdBytes) // If payload has already been triggered, then return the payloadid diff --git a/packages/client/src/net/peerpool.ts b/packages/client/src/net/peerpool.ts index 8921a96ccf7..30727277d44 100644 --- a/packages/client/src/net/peerpool.ts +++ b/packages/client/src/net/peerpool.ts @@ -213,7 +213,7 @@ export class PeerPool { * @emits {@link Event.POOL_PEER_ADDED} */ add(peer?: Peer) { - if (peer && peer.id && !this.pool.get(peer.id)) { + if (peer?.id !== undefined && !this.pool.get(peer.id)) { this.pool.set(peer.id, peer) peer.pooled = true this.config.events.emit(Event.POOL_PEER_ADDED, peer) diff --git a/packages/client/src/rpc/modules/admin.ts b/packages/client/src/rpc/modules/admin.ts index 3546fb1bbed..093158637dc 100644 --- a/packages/client/src/rpc/modules/admin.ts +++ b/packages/client/src/rpc/modules/admin.ts @@ -95,9 +95,10 @@ export class Admin { name: peer.rlpxPeer?.['_hello']?.clientId ?? null, protocols: { eth: { - head: peer.eth?.updatedBestHeader - ? bytesToHex(peer.eth.updatedBestHeader?.hash()) - : bytesToHex(peer.eth?.status.bestHash), + head: + peer.eth?.updatedBestHeader !== undefined + ? bytesToHex(peer.eth.updatedBestHeader.hash()) + : bytesToHex(peer.eth?.status.bestHash ?? new Uint8Array()), difficulty: peer.eth?.status.td.toString(10), version: peer.eth?.['versions'].slice(-1)[0] ?? null, }, diff --git a/packages/client/src/rpc/modules/engine/engine.ts b/packages/client/src/rpc/modules/engine/engine.ts index 9bcd21d67dc..9c9b2f9dc95 100644 --- a/packages/client/src/rpc/modules/engine/engine.ts +++ b/packages/client/src/rpc/modules/engine/engine.ts @@ -6,7 +6,6 @@ import { bytesToUnprefixedHex, equalsBytes, hexToBytes, - toBytes, } from '@ethereumjs/util' import { ExecStatus } from '../../../execution/index.ts' @@ -911,7 +910,7 @@ export class Engine { */ let headBlock: Block | undefined try { - const head = toBytes(headBlockHash) + const head = hexToBytes(headBlockHash) headBlock = this.remoteBlocks.get(headBlockHash.slice(2)) ?? (await this.skeleton.getBlockByHash(head, true)) ?? diff --git a/packages/client/src/rpc/modules/web3.ts b/packages/client/src/rpc/modules/web3.ts index 13e53b7dce1..afcf9aa3c4e 100644 --- a/packages/client/src/rpc/modules/web3.ts +++ b/packages/client/src/rpc/modules/web3.ts @@ -1,4 +1,4 @@ -import { bytesToHex, hexToBytes, toBytes } from '@ethereumjs/util' +import { bytesToHex, hexToBytes } from '@ethereumjs/util' import { keccak256 } from 'ethereum-cryptography/keccak.js' import { getClientVersion } from '../../util/index.ts' @@ -45,7 +45,7 @@ export class Web3 { * @param params The data to convert into a SHA3 hash */ sha3(params: PrefixedHexString[]): PrefixedHexString { - const hexEncodedDigest = bytesToHex(keccak256(toBytes(hexToBytes(params[0])))) + const hexEncodedDigest = bytesToHex(keccak256(hexToBytes(params[0]))) return hexEncodedDigest } } diff --git a/packages/client/src/sync/fetcher/accountfetcher.ts b/packages/client/src/sync/fetcher/accountfetcher.ts index 2ae370c7e48..431dc3822f4 100644 --- a/packages/client/src/sync/fetcher/accountfetcher.ts +++ b/packages/client/src/sync/fetcher/accountfetcher.ts @@ -337,9 +337,10 @@ export class AccountFetcher extends Fetcher const { task, partialResult } = job const { first } = task // Snap protocol will automatically pad it with 32 bytes left, so we don't need to worry - const origin = partialResult - ? bigIntToBytes(bytesToBigInt(partialResult[partialResult.length - 1].hash) + BIGINT_1) - : bigIntToBytes(first) + const origin = + partialResult !== undefined + ? bigIntToBytes(bytesToBigInt(partialResult[partialResult.length - 1].hash) + BIGINT_1) + : bigIntToBytes(first) return setLengthLeft(origin, 32) } @@ -470,9 +471,12 @@ export class AccountFetcher extends Fetcher const fullResult = (job.partialResult ?? []).concat(result) // update highest known hash - const highestReceivedhash = result.at(-1)?.hash as Uint8Array + const highestReceivedhash = result.at(-1)?.hash if (this.highestKnownHash) { - if (compareBytes(highestReceivedhash, this.highestKnownHash) > 0) { + if ( + highestReceivedhash !== undefined && + compareBytes(highestReceivedhash, this.highestKnownHash) > 0 + ) { this.highestKnownHash = highestReceivedhash } } else { diff --git a/packages/client/src/sync/fetcher/trienodefetcher.ts b/packages/client/src/sync/fetcher/trienodefetcher.ts index c37bdd76e85..429691f3fc3 100644 --- a/packages/client/src/sync/fetcher/trienodefetcher.ts +++ b/packages/client/src/sync/fetcher/trienodefetcher.ts @@ -347,7 +347,7 @@ export class TrieNodeFetcher extends Fetcher // add account node data to account trie const node = decodeMPTNode(nodeData) if (node instanceof LeafMPTNode) { - const key = bytesToUnprefixedHex(pathToHexKey(path, node.key(), 'keybyte')) + const key = bytesToHex(pathToHexKey(path, node.key(), 'keybyte')) ops.push({ type: 'put', key: hexToBytes(key), @@ -365,9 +365,7 @@ export class TrieNodeFetcher extends Fetcher for (const [path, data] of pathToStorageNode) { const storageNode = decodeMPTNode(data) if (storageNode instanceof LeafMPTNode) { - const storageKey = bytesToUnprefixedHex( - pathToHexKey(path, storageNode.key(), 'keybyte'), - ) + const storageKey = bytesToHex(pathToHexKey(path, storageNode.key(), 'keybyte')) storageTrieOps.push({ type: 'put', key: hexToBytes(storageKey), diff --git a/packages/client/src/util/vkt.ts b/packages/client/src/util/vkt.ts index eb0fda71482..5d516b51b48 100644 --- a/packages/client/src/util/vkt.ts +++ b/packages/client/src/util/vkt.ts @@ -16,9 +16,11 @@ export async function generateVKTStateRoot(genesisState: GenesisState, common: C const state = new StatefulVerkleStateManager({ common }) await state['_trie'].createRootNode() await state.checkpoint() - for (const addressStr of Object.keys(genesisState)) { + for (const addressStr of Object.keys(genesisState) as PrefixedHexString[]) { const addrState = genesisState[addressStr] - let nonce, balance, code + let nonce: PrefixedHexString | undefined + let balance: PrefixedHexString | bigint + let code: PrefixedHexString | undefined let storage: StoragePair[] | undefined if (Array.isArray(addrState)) { ;[balance, code, storage, nonce] = addrState @@ -51,8 +53,8 @@ export async function generateVKTStateRoot(genesisState: GenesisState, common: C // Put account data const account = createPartialAccount({ - nonce: nonce as PrefixedHexString, - balance: balance as PrefixedHexString, + nonce, + balance, codeHash, codeSize: codeBuf.byteLength, }) diff --git a/packages/client/test/integration/miner.spec.ts b/packages/client/test/integration/miner.spec.ts index 0a26b2525f3..d97f3a2acc0 100644 --- a/packages/client/test/integration/miner.spec.ts +++ b/packages/client/test/integration/miner.spec.ts @@ -1,4 +1,9 @@ -import { Hardfork, createCommonFromGethGenesis, parseGethGenesisState } from '@ethereumjs/common' +import { + type GethGenesis, + Hardfork, + createCommonFromGethGenesis, + parseGethGenesisState, +} from '@ethereumjs/common' import { Address, bytesToHex, concatBytes, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -12,7 +17,7 @@ import type { EthereumClient } from '../../src/index.ts' async function setupDevnet(prefundAddress: Address) { const addr = prefundAddress.toString().slice(2) - const defaultChainData = { + const defaultChainData: GethGenesis = { config: { chainId: 123456, homesteadBlock: 0, @@ -37,6 +42,7 @@ async function setupDevnet(prefundAddress: Address) { gasUsed: '0x0', parentHash: '0x0000000000000000000000000000000000000000000000000000000000000000', baseFeePerGas: 7, + alloc: {}, } const extraData = concatBytes(new Uint8Array(32), prefundAddress.toBytes(), new Uint8Array(65)) diff --git a/packages/client/test/integration/pow.spec.ts b/packages/client/test/integration/pow.spec.ts index 8c4dc444b69..ae003244e09 100644 --- a/packages/client/test/integration/pow.spec.ts +++ b/packages/client/test/integration/pow.spec.ts @@ -1,5 +1,10 @@ import { rmSync } from 'fs' -import { Hardfork, createCommonFromGethGenesis, parseGethGenesisState } from '@ethereumjs/common' +import { + type GethGenesis, + Hardfork, + createCommonFromGethGenesis, + parseGethGenesisState, +} from '@ethereumjs/common' import { assert, describe, it } from 'vitest' import { Config } from '../../src/index.ts' @@ -18,7 +23,7 @@ async function setupPowDevnet(prefundAddress: Address, cleanStart: boolean) { const addr = prefundAddress.toString().slice(2) const consensusConfig = { ethash: true } - const defaultChainData = { + const defaultChainData: GethGenesis = { config: { chainId: 123456, homesteadBlock: 0, @@ -44,9 +49,10 @@ async function setupPowDevnet(prefundAddress: Address, cleanStart: boolean) { gasUsed: '0x0', parentHash: '0x0000000000000000000000000000000000000000000000000000000000000000', baseFeePerGas: 7, + alloc: {}, } - const extraData = '0x' + '0'.repeat(32) - const chainData = { + const extraData = `0x${'0'.repeat(32)}` + const chainData: GethGenesis = { ...defaultChainData, extraData, alloc: { [addr]: { balance: '0x10000000000000000000' } }, diff --git a/packages/client/test/miner/miner.spec.ts b/packages/client/test/miner/miner.spec.ts index 18728919473..fafe1a31482 100644 --- a/packages/client/test/miner/miner.spec.ts +++ b/packages/client/test/miner/miner.spec.ts @@ -1,6 +1,7 @@ import { BlockHeader, createBlock, createBlockHeader } from '@ethereumjs/block' import { Common, + type GethGenesis, Hardfork, createCommonFromGethGenesis, createCustomCommon, @@ -101,7 +102,7 @@ const consensusConfig = { epoch: 30000, }, } -const defaultChainData = { +const defaultChainData: GethGenesis = { config: { chainId: 123456, homesteadBlock: 0, @@ -127,6 +128,7 @@ const defaultChainData = { gasUsed: '0x0', parentHash: '0x0000000000000000000000000000000000000000000000000000000000000000', baseFeePerGas: 7, + alloc: {}, } const addr = A.address.toString().slice(2) diff --git a/packages/client/test/rpc/admin/addPeer.spec.ts b/packages/client/test/rpc/admin/addPeer.spec.ts index 3a5c23cc291..c4b3184f9c4 100644 --- a/packages/client/test/rpc/admin/addPeer.spec.ts +++ b/packages/client/test/rpc/admin/addPeer.spec.ts @@ -13,7 +13,7 @@ const peerPort = 30304 // NOTE: the `privateKey` currently cannot be 0x-prefixed in `./net/server/server.ts` const privateKey = 'dc6457099f127cf0bac78de8b297df04951281909db4f58b43def7c7151e765d' -const privateKeyBytes = hexToBytes('0x' + privateKey) +const privateKeyBytes = hexToBytes(`0x${privateKey}`) describe(method, () => { it('works', async () => { diff --git a/packages/client/test/rpc/eth/getFeeHistory.spec.ts b/packages/client/test/rpc/eth/getFeeHistory.spec.ts index f3a56eb5a12..6c98400a071 100644 --- a/packages/client/test/rpc/eth/getFeeHistory.spec.ts +++ b/packages/client/test/rpc/eth/getFeeHistory.spec.ts @@ -203,9 +203,9 @@ describe(method, () => { // Expect to retrieve the blocks [2,3] const res = await rpc.request(method, ['0x2', 'latest', []]) const [firstBaseFee, previousBaseFee, nextBaseFee] = res.result.baseFeePerGas as [ - string, - string, - string, + PrefixedHexString, + PrefixedHexString, + PrefixedHexString, ] const increase = Number( @@ -244,7 +244,11 @@ describe(method, () => { const rpc = getRPCClient(server) const res = await rpc.request(method, ['0x2', 'latest', []]) - const [, previousBaseFee, nextBaseFee] = res.result.baseFeePerGas as [string, string, string] + const [, previousBaseFee, nextBaseFee] = res.result.baseFeePerGas as [ + PrefixedHexString, + PrefixedHexString, + PrefixedHexString, + ] const decrease = Number( (1000n * @@ -270,7 +274,7 @@ describe(method, () => { const res = await rpc.request(method, ['0x1', 'latest', []]) - const [baseFee] = res.result.baseFeePerGas as [string] + const [baseFee] = res.result.baseFeePerGas as [PrefixedHexString] assert.equal(bytesToBigInt(hexToBytes(baseFee)), initialBaseFee) }) @@ -285,7 +289,10 @@ describe(method, () => { const res = await rpc.request(method, ['0x1', 'latest', []]) - const [previousBaseFee, nextBaseFee] = res.result.baseFeePerGas as [string, string] + const [previousBaseFee, nextBaseFee] = res.result.baseFeePerGas as [ + PrefixedHexString, + PrefixedHexString, + ] assert.equal(previousBaseFee, '0x0') assert.equal(nextBaseFee, '0x0') diff --git a/packages/client/test/rpc/mockBlockchain.ts b/packages/client/test/rpc/mockBlockchain.ts index 5607591f9b1..7f815045c52 100644 --- a/packages/client/test/rpc/mockBlockchain.ts +++ b/packages/client/test/rpc/mockBlockchain.ts @@ -1,27 +1,33 @@ import { createBlock } from '@ethereumjs/block' import { createLegacyTx } from '@ethereumjs/tx' -import { equalsBytes, toBytes } from '@ethereumjs/util' +import { type PrefixedHexString, equalsBytes, hexToBytes } from '@ethereumjs/util' import { dummy } from './helpers.ts' -import type { LegacyTx } from '@ethereumjs/tx' +import type { JSONTx, LegacyTx, TypedTransaction } from '@ethereumjs/tx' -export function mockBlockchain(options: any = {}) { - const number = options.number ?? '0x444444' - const blockHash = +export function mockBlockchain( + options: { + number?: PrefixedHexString + hash?: PrefixedHexString + transactions?: TypedTransaction[] | JSONTx[] + } = {}, +) { + const number: PrefixedHexString = options.number ?? '0x444444' + const blockHash: PrefixedHexString = options.hash ?? '0x910abca1728c53e8d6df870dd7af5352e974357dc58205dea1676be17ba6becf' const transactions = options.transactions ?? [createLegacyTx({}).sign(dummy.privKey)] const block = { - hash: () => toBytes(blockHash), + hash: () => hexToBytes(blockHash), serialize: () => createBlock({ header: { number }, transactions }).serialize(), header: { number: BigInt(number), - hash: () => toBytes(blockHash), + hash: () => hexToBytes(blockHash), }, toJSON: () => ({ ...createBlock({ header: { number } }).toJSON(), hash: options.hash ?? blockHash, - transactions: transactions.map((t: LegacyTx) => t.toJSON()), + transactions: transactions.map((t) => (t as LegacyTx).toJSON()), }), transactions, uncleHeaders: [], diff --git a/packages/client/test/sim/snapsync.spec.ts b/packages/client/test/sim/snapsync.spec.ts index 1ed0836d47b..72bed624dac 100644 --- a/packages/client/test/sim/snapsync.spec.ts +++ b/packages/client/test/sim/snapsync.spec.ts @@ -249,7 +249,7 @@ describe('simple mainnet test run', async () => { ;(customGenesisState[sender][0] as any) = `0x${senderBalance.toString(16)}` } - for (const addressString of Object.keys(customGenesisState)) { + for (const addressString of Object.keys(customGenesisState) as PrefixedHexString[]) { const address = createAddressFromString(addressString) const account = await stateManager?.getAccount(address) assert.equal( diff --git a/packages/client/test/sync/fetcher/accountfetcher.spec.ts b/packages/client/test/sync/fetcher/accountfetcher.spec.ts index 64d71d5ce31..a4b48406923 100644 --- a/packages/client/test/sync/fetcher/accountfetcher.spec.ts +++ b/packages/client/test/sync/fetcher/accountfetcher.spec.ts @@ -188,20 +188,19 @@ describe('[AccountFetcher]', async () => { address: 'random', latest: vi.fn(), } - const partialResult: any = [ - [ - { - hash: new Uint8Array(0), - body: [new Uint8Array(0), new Uint8Array(0), new Uint8Array(0), new Uint8Array(0)], - }, - { - hash: new Uint8Array(0), - body: [new Uint8Array(0), new Uint8Array(0), new Uint8Array(0), new Uint8Array(0)], - }, - ], + const partialResult = [ + { + hash: new Uint8Array(0), + body: [new Uint8Array(0), new Uint8Array(0), new Uint8Array(0), new Uint8Array(0)], + }, + { + hash: new Uint8Array(0), + body: [new Uint8Array(0), new Uint8Array(0), new Uint8Array(0), new Uint8Array(0)], + }, ] const job = { peer, partialResult, task } - const result = (await fetcher.request(job as any)) as any + const result = await fetcher.request(job as any) + assert.isDefined(result) assert.equal( JSON.stringify(result[0]), JSON.stringify({ skipped: true }), @@ -219,17 +218,15 @@ describe('[AccountFetcher]', async () => { first: BigInt(1), count: BigInt(3), }) - const partialResult: any = [ - [ - { - hash: new Uint8Array(0), - body: [new Uint8Array(0), new Uint8Array(0), new Uint8Array(0), new Uint8Array(0)], - }, - { - hash: new Uint8Array(0), - body: [new Uint8Array(0), new Uint8Array(0), new Uint8Array(0), new Uint8Array(0)], - }, - ], + const partialResult = [ + { + hash: new Uint8Array(0), + body: [new Uint8Array(0), new Uint8Array(0), new Uint8Array(0), new Uint8Array(0)], + }, + { + hash: new Uint8Array(0), + body: [new Uint8Array(0), new Uint8Array(0), new Uint8Array(0), new Uint8Array(0)], + }, ] const task = { count: 3, first: BigInt(1) } diff --git a/packages/client/test/sync/fetcher/storagefetcher.spec.ts b/packages/client/test/sync/fetcher/storagefetcher.spec.ts index d89644123ba..672fd5d681b 100644 --- a/packages/client/test/sync/fetcher/storagefetcher.spec.ts +++ b/packages/client/test/sync/fetcher/storagefetcher.spec.ts @@ -255,10 +255,10 @@ describe('[StorageFetcher]', async () => { pool, root: utf8ToBytes(''), } as StorageFetcherOptions) - const partialResult: any = [ + const partialResult = [ [ - [{ hash: utf8ToBytes(''), body: utf8ToBytes('') }], - [{ hash: utf8ToBytes(''), body: utf8ToBytes('') }], + { hash: utf8ToBytes(''), body: utf8ToBytes('') }, + { hash: utf8ToBytes(''), body: utf8ToBytes('') }, ], ] @@ -276,7 +276,7 @@ describe('[StorageFetcher]', async () => { }, ], } - const resData = RLP.decode(hexToBytes(_storageRangesRLP)) as unknown + const resData = RLP.decode(hexToBytes(_storageRangesRLP)) const res = p.decode( p.messages.filter((message) => message.name === 'StorageRanges')[0], resData, diff --git a/packages/client/test/sync/skeleton.spec.ts b/packages/client/test/sync/skeleton.spec.ts index e00d9f81f11..b018938664e 100644 --- a/packages/client/test/sync/skeleton.spec.ts +++ b/packages/client/test/sync/skeleton.spec.ts @@ -1,6 +1,7 @@ import { createBlock } from '@ethereumjs/block' import { Common, + type GethGenesis, Mainnet, createCommonFromGethGenesis, createCustomCommon, @@ -405,7 +406,7 @@ describe('[Skeleton] / setHead', async () => { } it(`skeleton init should throw error if merge not set`, async () => { - const genesis = { + const genesis: GethGenesis = { ...postMergeGethGenesis, config: { ...postMergeGethGenesis.config, @@ -420,7 +421,8 @@ describe('[Skeleton] / setHead', async () => { const common = createCommonFromGethGenesis(genesis, { chain: 'merge-not-set' }) const config = new Config({ common }) const chain = await Chain.create({ config }) - ;(chain.blockchain['_validateBlocks'] as any) = false + // @ts-expect-error -- Assigning to read-only property + chain.blockchain['_validateBlocks'] = false try { new Skeleton({ chain, config, metaDB: new MemoryLevel() }) } catch { diff --git a/packages/common/README.md b/packages/common/README.md index efd34a0632c..af39837aea3 100644 --- a/packages/common/README.md +++ b/packages/common/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/common +# @ethereumjs/common `v10` [![NPM Package][common-npm-badge]][common-npm-link] [![GitHub Issues][common-issues-badge]][common-issues-link] @@ -9,6 +9,21 @@ | Resources common to all EthereumJS implementations. | | --------------------------------------------------- | +## Table of Contents + +- [Installation](#installation) +- [Getting Started](#getting-started) +- [Custom Cryptography Primitives (WASM)](#custom-cryptography-primitives-wasm) +- [Browser](#browser) +- [API](#api) +- [Events](#events) +- [Chains and Genesis](#chains-and-genesis) +- [Working with Private/Custom Chains](#working-with-privatecustom-chains) +- [Hardfork Support and Usage](#hardfork-support-and-usage) +- [Supported EIPs](#supported-eips) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Installation To obtain the latest version, simply require the project using `npm`: @@ -17,7 +32,7 @@ To obtain the latest version, simply require the project using `npm`: npm install @ethereumjs/common ``` -## Usage +## Getting Started ### import / require @@ -71,7 +86,7 @@ const commonWithCustomChainId = createCustomCommon({ chainId: 1234 }, Mainnet) console.log(`The current chain ID is ${commonWithCustomChainId.chainId()}`) ``` -### Custom Cryptography Primitives (WASM) +## Custom Cryptography Primitives (WASM) All EthereumJS packages use cryptographic primitives from the audited `ethereum-cryptography` library by default. These primitives, including `keccak256`, `sha256`, and elliptic curve signature methods, are all written in native JavaScript and therefore have the potential downside of being less performant than alternative cryptography modules written in other languages and then compiled to WASM. If cryptography performance is a bottleneck in your usage of the EthereumJS libraries, you can provide your own primitives to the `Common` constructor and they will be used in place of the defaults. Depending on how your preferred primitives are implemented, you may need to write wrapper methods around them so they conform to the interface exposed by the [`common.customCrypto` property](./src/types.ts). @@ -170,9 +185,7 @@ The `Common` class has a public property `events` which contains an `EventEmitte | ----------------- | ---------------------------------------------------------- | | `hardforkChanged` | Emitted when a hardfork change occurs in the Common object | -## Setup - -### Chains +### Chains and Genesis The `chain` can be set in the constructor like this: @@ -255,7 +268,7 @@ common.setForkHashes(genesisHash) console.log(`The London forkhash for this custom chain is ${common.forkHash('london')}`) ``` -### Hardforks +## Hardfork Support and Usage The `hardfork` can be set in constructor like this: @@ -309,7 +322,7 @@ See one of the hardfork configurations in the `hardforks.ts` file for an overview. For consistency, the chain start (`chainstart`) is considered an own hardfork. -### EIPs +## Supported EIPs EIPs are native citizens within the library and can be activated like this: @@ -356,10 +369,6 @@ The following EIPs are currently supported: - [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) - Set EOA account code (Prague) - [EIP-7709](https://eips.ethereum.org/EIPS/eip-7709) - Read BLOCKHASH from storage and update cost (Verkle) -### Bootstrap Nodes - -You can use `common.bootstrapNodes()` function to get nodes for a specific chain/network. - ## EthereumJS See our organizational [documentation](https://ethereumjs.readthedocs.io) for an introduction to `EthereumJS` as well as information on current standards and best practices. If you want to join for work or carry out improvements on the libraries, please review our [contribution guidelines](https://ethereumjs.readthedocs.io/en/latest/contributing.html) first. diff --git a/packages/common/examples/customChain.ts b/packages/common/examples/customChain.ts index b473517c1b4..8ee8af1ff7f 100644 --- a/packages/common/examples/customChain.ts +++ b/packages/common/examples/customChain.ts @@ -1,7 +1,6 @@ -import { Common, Mainnet, createCustomCommon } from '@ethereumjs/common' - -import myCustomChain1 from './genesisData/testnet.json' +import { Mainnet, createCustomCommon } from '@ethereumjs/common' +import { customChainConfig } from '@ethereumjs/testdata' // Add custom chain config -const common1 = createCustomCommon(myCustomChain1, Mainnet) +const common1 = createCustomCommon(customChainConfig, Mainnet) console.log(`Common is instantiated with custom chain parameters - ${common1.chainName()}`) diff --git a/packages/common/examples/fromGeth.ts b/packages/common/examples/fromGeth.ts index 6bad8a5f369..ad7ea992b21 100644 --- a/packages/common/examples/fromGeth.ts +++ b/packages/common/examples/fromGeth.ts @@ -1,11 +1,13 @@ import { createCommonFromGethGenesis } from '@ethereumjs/common' +import { postMergeGethGenesis } from '@ethereumjs/testdata' import { hexToBytes } from '@ethereumjs/util' -import genesisJSON from './genesisData/post-merge.json' - const genesisHash = hexToBytes('0x3b8fb240d288781d4aac94d3fd16809ee413bc99294a085798a589dae51ddd4a') // Load geth genesis JSON file into lets say `genesisJSON` and optional `chain` and `genesisHash` -const common = createCommonFromGethGenesis(genesisJSON, { chain: 'customChain', genesisHash }) +const common = createCommonFromGethGenesis(postMergeGethGenesis, { + chain: 'customChain', + genesisHash, +}) // If you don't have `genesisHash` while initiating common, you can later configure common (for e.g. // after calculating it via `blockchain`) common.setForkHashes(genesisHash) diff --git a/packages/common/examples/genesisData/post-merge.json b/packages/common/examples/genesisData/post-merge.json deleted file mode 100644 index 32f5f093d3a..00000000000 --- a/packages/common/examples/genesisData/post-merge.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "config": { - "chainId": 1, - "homesteadBlock": 0, - "eip150Block": 0, - "eip155Block": 0, - "eip158Block": 0, - "byzantiumBlock": 0, - "constantinopleBlock": 0, - "petersburgBlock": 0, - "istanbulBlock": 0, - "muirGlacierBlock": 0, - "berlinBlock": 0, - "londonBlock": 0, - "clique": { - "period": 5, - "epoch": 30000 - }, - "terminalTotalDifficulty": 0, - "terminalTotalDifficultyPassed": true - }, - "nonce": "0x42", - "timestamp": "0x0", - "extraData": "0x0000000000000000000000000000000000000000000000000000000000000000a94f5374fce5edbc8e2a8697c15331677e6ebf0b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "gasLimit": "0x1C9C380", - "difficulty": "0x400000000", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x0000000000000000000000000000000000000000", - "alloc": { - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { "balance": "0x6d6172697573766477000000" } - }, - "number": "0x0", - "gasUsed": "0x0", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "baseFeePerGas": "0x7" -} diff --git a/packages/common/examples/genesisData/testnet.json b/packages/common/examples/genesisData/testnet.json deleted file mode 100644 index bfb6fe4974d..00000000000 --- a/packages/common/examples/genesisData/testnet.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "testnet1", - "chainId": 22222, - "defaultHardfork": "istanbul", - "consensus": { - "type": "poa", - "algorithm": "clique", - "clique": { - "period": 15, - "epoch": 30000 - } - }, - "comment": "Private test network", - "url": "[TESTNET_URL]", - "genesis": { - "gasLimit": 1000000, - "difficulty": 1, - "nonce": "0xbb00000000000000", - "extraData": "0xcc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - }, - "hardforks": [ - { - "name": "chainstart", - "block": 0 - }, - { - "name": "homestead", - "block": 1 - }, - { - "name": "tangerineWhistle", - "block": 2 - }, - { - "name": "spuriousDragon", - "block": 3 - }, - { - "name": "istanbul", - "block": 10 - } - ], - "bootstrapNodes": [ - { - "ip": "10.0.0.1", - "port": 30303, - "id": "11000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "location": "", - "comment": "" - }, - { - "ip": "10.0.0.2", - "port": 30303, - "id": "22000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "location": "", - "comment": "" - } - ] -} diff --git a/packages/common/examples/genesisData/testnet2.json b/packages/common/examples/genesisData/testnet2.json deleted file mode 100644 index 5eec2f59ce6..00000000000 --- a/packages/common/examples/genesisData/testnet2.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "testnet2", - "chainId": 33333, - "defaultHardfork": "istanbul", - "consensus": { - "type": "poa", - "algorithm": "clique", - "clique": { - "period": 15, - "epoch": 30000 - } - }, - "comment": "Private test network", - "url": "[TESTNET_URL]", - "genesis": { - "gasLimit": 1000000, - "difficulty": 1, - "nonce": "0xbb00000000000000", - "extraData": "0xcc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" - }, - "hardforks": [ - { - "name": "chainstart", - "block": 0 - }, - { - "name": "homestead", - "block": 1 - }, - { - "name": "tangerineWhistle", - "block": 2 - }, - { - "name": "spuriousDragon", - "block": 3 - }, - { - "name": "istanbul", - "block": 10 - } - ], - "bootstrapNodes": [ - { - "ip": "10.0.0.1", - "port": 30303, - "id": "11000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "location": "", - "comment": "" - }, - { - "ip": "10.0.0.2", - "port": 30303, - "id": "22000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "location": "", - "comment": "" - } - ] -} diff --git a/packages/common/src/gethGenesis.ts b/packages/common/src/gethGenesis.ts index 2ecee25dc2a..cbcceaef8f9 100644 --- a/packages/common/src/gethGenesis.ts +++ b/packages/common/src/gethGenesis.ts @@ -87,15 +87,15 @@ export interface GethGenesis { nonce: string timestamp: string extraData?: string - gasLimit: string - difficulty?: string - mixHash?: string - coinbase?: string + gasLimit: PrefixedHexString + difficulty?: PrefixedHexString + mixHash?: PrefixedHexString + coinbase?: PrefixedHexString alloc: GethGenesisAlloc - number?: string - gasUsed?: string - parentHash?: string - baseFeePerGas?: string | number | null + number?: PrefixedHexString + gasUsed?: PrefixedHexString + parentHash?: PrefixedHexString + baseFeePerGas?: PrefixedHexString | number | null } /** @@ -141,7 +141,7 @@ export type AccountState = [ * ``` */ export interface GenesisState { - [key: string]: PrefixedHexString | AccountState + [key: PrefixedHexString]: PrefixedHexString | AccountState } /** diff --git a/packages/common/test/hardforks.spec.ts b/packages/common/test/hardforks.spec.ts index de4db399f28..ba130fadd23 100644 --- a/packages/common/test/hardforks.spec.ts +++ b/packages/common/test/hardforks.spec.ts @@ -15,7 +15,7 @@ import { createCustomCommon, } from '../src/index.ts' -import type { ChainConfig } from '../src/index.ts' +import type { ChainConfig, GethGenesis, GethGenesisConfig } from '../src/index.ts' describe('[Common]: Hardfork logic', () => { it('Hardfork access', () => { @@ -283,7 +283,7 @@ describe('[Common]: Hardfork logic', () => { it('forkHash(): should not change forkHash if timestamp is at genesis timestamp', () => { // Setup default config - const defaultConfig = { + const defaultConfig: GethGenesis = { timestamp: '10', config: { ethash: {}, @@ -305,10 +305,10 @@ describe('[Common]: Hardfork logic', () => { terminalTotalDifficulty: 0, shanghaiTime: 0, cancunTime: 0, - }, - difficulty: '100', + } as GethGenesisConfig, + difficulty: '0x100', alloc: {}, - gasLimit: '5000', + gasLimit: '0x5000', nonce: '', } const gethConfig = { diff --git a/packages/devp2p/README.md b/packages/devp2p/README.md index 19ea07924bf..ef61e0ae9d8 100644 --- a/packages/devp2p/README.md +++ b/packages/devp2p/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/devp2p +# @ethereumjs/devp2p `v10` [![NPM Status][devp2p-npm-badge]][devp2p-npm-link] [![GitHub Issues][devp2p-issues-badge]][devp2p-issues-link] @@ -6,15 +6,27 @@ [![Coverage Status][devp2p-coverage-badge]][devp2p-coverage-link] [![Discord][discord-badge]][discord-link] -## Introduction - This library bundles different components for lower-level peer-to-peer connection and message exchange: - Distributed Peer Table (DPT) / v4 Node Discovery / DNS Discovery - RLPx Transport Protocol - Ethereum Wire Protocol (ETH/68) -## Usage +## Table of Contents + +- [Getting Started](#getting-started) +- [Examples](#examples) +- [API](#api) +- [Distributed Peer Table (DPT) / Node Discovery](#distributed-peer-table-dpt--node-discovery) +- [RLPx Transport Protocol](#rlpx-transport-protocol) +- [Ethereum Wire Protocol (ETH)](#ethereum-wire-protocol-eth) +- [Debugging](#debugging) +- [Developer](#developer) +- [General References](#general-references) +- [EthereumJS](#ethereumjs) +- [License](#license) + +## Getting Started All components of this library have a public `events` property containing an `EventEmitter` object (using [EventEmitter3](https://github.com/primus/eventemitter3)) and make heavy use of the Node.js network stack. @@ -43,7 +55,7 @@ Run an example with: DEBUG=ethjs,devp2p:* node -r tsx/register ./examples/peer-communication.cts ``` -## Docs +## API For a complete API reference see the generated [documentation](./docs). @@ -337,10 +349,6 @@ Events emitted: | message | Message received | | status | Status info received | -### Reference - -- [Light client protocol](https://ethereum.org/en/developers/docs/nodes-and-clients/#light-node) - ## Debugging ### Introduction @@ -453,11 +461,6 @@ The following is a list of major implementations of the `devp2p` stack in other - Python: [pydevp2p](https://github.com/ethereum/pydevp2p) - Go: [Go Ethereum](https://github.com/ethereum/go-ethereum/tree/master/p2p) -- Elixir: [Exthereum](https://github.com/exthereum/exth_crypto) - -### Links - -- [Blog article series](https://ocalog.com/post/10/) on implementing Ethereum protocol stack ## EthereumJS diff --git a/packages/era/README.md b/packages/era/README.md index 9c62e0c14ae..32fef48c2a8 100644 --- a/packages/era/README.md +++ b/packages/era/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/era +# @ethereumjs/era `v10` [![NPM Package][era-npm-badge]][era-npm-link] [![GitHub Issues][era-issues-badge]][era-issues-link] @@ -9,6 +9,13 @@ | A collection of utility functions for Ethereum. | | ----------------------------------------------- | +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Installation To obtain the latest version, simply require the project using `npm`: @@ -22,7 +29,7 @@ npm install @ethereumjs/era All helpers are re-exported from the root level and deep imports are not necessary. So an import can be done like this: ```ts -import { formatEntry } from "@ethereumjs/era"; +import { formatEntry } from "@ethereumjs/era" ``` ### Export History as Era1 @@ -30,13 +37,13 @@ import { formatEntry } from "@ethereumjs/era"; Export history in epochs of 8192 blocks as Era1 files ```ts -import { exportEpochAsEra1 } from "@ethereumjs/era"; +import { exportEpochAsEra1 } from "@ethereumjs/era" -const dataDir = PATH_TO_ETHEREUMJS_CLIENT_DB; -const epoch = 0; +const dataDir = PATH_TO_ETHEREUMJS_CLIENT_DB +const epoch = 0 // generates ${dataDir}/era1/epoch-0.era1 -await exportEpochAsEra1(epoch, dataDir); +await exportEpochAsEra1(epoch, dataDir) ``` ### Read Era1 file @@ -52,37 +59,37 @@ import { blockFromTuple, getHeaderRecords, EpochAccumulator, -} from "@ethereumjs/era"; +} from "@ethereumjs/era" -const era1File = readBinaryFile(PATH_TO_ERA1_FILE); +const era1File = readBinaryFile(PATH_TO_ERA1_FILE) // validate era1 file -const isValid = validateERA1(era1File); +const isValid = validateERA1(era1File) // read blocks from era1 file -const blocks = readERA1(era1File); +const blocks = readERA1(era1File) for await (const blockTuple of blocks) { - const { header, body, receipts } = await parseBlockTuple(blockTuple); - const block = blockFromTuple({ header, body }); - console.log(block.header.number); + const { header, body, receipts } = await parseBlockTuple(blockTuple) + const block = blockFromTuple({ header, body }) + console.log(block.header.number) } // reconstruct epoch accumulator -const headerRecords = await getHeaderRecords(era1File); -const epochAccumulator = EpochAccumulator.encode(headerRecords); -const epochAccumulatorRoot = EpochAccumulator.merkleRoot(headerRecords); +const headerRecords = await getHeaderRecords(era1File) +const epochAccumulator = EpochAccumulator.encode(headerRecords) +const epochAccumulatorRoot = EpochAccumulator.merkleRoot(headerRecords) ``` ### Read Era file ```ts -import { readBeaconState } from "@ethereumjs/era"; +import { readBeaconState } from "@ethereumjs/era" -const eraFile = readBinaryFile(PATH_TO_ERA_FILE); +const eraFile = readBinaryFile(PATH_TO_ERA_FILE) // Extract BeaconState -const state = await readBeaconState(eraFile); +const state = await readBeaconState(eraFile) console.log(state.slot) // Read Beacon Blocks from era file diff --git a/packages/era/test/exportHistory.spec.ts b/packages/era/test/exportHistory.spec.ts index 00d7924eb3c..a399811d55b 100644 --- a/packages/era/test/exportHistory.spec.ts +++ b/packages/era/test/exportHistory.spec.ts @@ -1,9 +1,9 @@ -import { bytesToBigInt64, hexToBytes } from '@ethereumjs/util' +import { type PrefixedHexString, bytesToBigInt64, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { compressData, formatEntry } from '../src/index.ts' describe('era1', async () => { - const test = { + const test: { compressed: PrefixedHexString; decompressed: PrefixedHexString } = { compressed: '0xff060000734e6150705900cb0000ec6da9a6970410f90214a0007a010088a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d4934794004a4200f043a0d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0567a210004b9014a7800fe0100fe0100fe0100b6010004850401f098808213888080a011bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa82ea0120880000000000000042', decompressed: diff --git a/packages/ethash/README.md b/packages/ethash/README.md index ac418bd1c14..b87f7ff6664 100644 --- a/packages/ethash/README.md +++ b/packages/ethash/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/ethash +# @ethereumjs/ethash `v10` [![NPM Package][ethash-npm-badge]][ethash-npm-link] [![GitHub Issues][ethash-issues-badge]][ethash-issues-link] @@ -9,6 +9,14 @@ | [Ethash](https://github.com/ethereum/wiki/wiki/Ethash) implementation in TypeScript. | | ------------------------------------------------------------------------------------ | +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [API](#api) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Installation To obtain the latest version, simply require the project using `npm`: @@ -106,7 +114,7 @@ Using ESM will give you additional advantages over CJS beyond browser usage like See our organizational [documentation](https://ethereumjs.readthedocs.io) for an introduction to `EthereumJS` as well as information on current standards and best practices. If you want to join for work or carry out improvements on the libraries, please review our [contribution guidelines](https://ethereumjs.readthedocs.io/en/latest/contributing.html) first. -# LICENSE +## License [MPL-2.0]() diff --git a/packages/ethash/package.json b/packages/ethash/package.json index 7e11904ebb9..b59b041213a 100644 --- a/packages/ethash/package.json +++ b/packages/ethash/package.json @@ -44,7 +44,7 @@ "spellcheck": "npm run spellcheck:ts && npm run spellcheck:md", "spellcheck:ts": "npx cspell --gitignore -c ../../config/cspell-ts.json \"./**/*.ts\" --cache --show-suggestions --show-context", "spellcheck:md": "npx cspell --gitignore -c ../../config/cspell-md.json \"**.md\" --cache --show-suggestions --show-context", - "test": "npx vitest run -c ../../config/vitest.config.mts", + "test": "npx vitest run -c ./vite.config.ts", "tsc": "../../config/cli/ts-compile.sh" }, "dependencies": { diff --git a/packages/evm/README.md b/packages/evm/README.md index e9ea7cc015d..3be7ebc9335 100644 --- a/packages/evm/README.md +++ b/packages/evm/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/evm +# @ethereumjs/evm `v10` [![NPM Package][evm-npm-badge]][evm-npm-link] [![GitHub Issues][evm-issues-badge]][evm-issues-link] @@ -9,6 +9,25 @@ | TypeScript implementation of the Ethereum EVM. | | ---------------------------------------------- | +## Table of Contents + +- [Installation](#installation) +- [Getting Started](#getting-started) +- [Examples](#examples) +- [Browser](#browser) +- [API](#api) +- [Architecture](#architecture) +- [Supported Hardforks](#supported-hardforks) +- [Supported EIPs](#supported-eips) +- [Precompiles](#precompiles) +- [Events](#events) +- [Understanding the EVM](#understanding-the-evm) +- [Profiling the EVM](#profiling-the-evm) +- [Development](#development) +- [EthereumJS](#ethereumjs) +- [License](#license) + + ## Installation To obtain the latest version, simply require the project using `npm`: @@ -19,15 +38,13 @@ npm install @ethereumjs/evm This package provides the core Ethereum Virtual Machine (EVM) implementation which is capable of executing EVM-compatible bytecode. The package has been extracted from the [@ethereumjs/vm](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/vm) package along the VM `v6` release. -**Note:** Starting with the Dencun hardfork `EIP-4844` related functionality will become an integrated part of the EVM functionality with the activation of the point evaluation precompile. It is therefore strongly recommended to _always_ run the EVM with a KZG library installed and initialized, see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions. +**Note:** Starting with the Dencun hardfork `EIP-4844` related functionality has become an integrated part of the EVM functionality with the activation of the point evaluation precompile. For this precompile to work a separate installation of the KZG library is necessary (we decided not to bundle due to large bundle sizes), see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions. -## Usage +## Getting Started ### Basic -With the v2 release (Summer 2023) the EVM/VM packages have been further decoupled and it now possible to run the EVM package in isolation with reasonable defaults. - -The following is the simplest example for an EVM instantiation: +The following is the simplest example for an EVM instantiation with reasonable defaults for state and blockchain information (like blockhashes): ```ts // ./examples/simple.ts @@ -44,8 +61,6 @@ const main = async () => { void main() ``` -Note: with the switch from v2 to v3 the old direct `new EVM()` constructor usage has been deprecated and an `EVM` now has to be instantiated with the async static `EVM.create()` constructor. - ### Blockchain, State and Events If the EVM should run on a certain state an `@ethereumjs/statemanager` is needed. An `@ethereumjs/blockchain` instance can be passed in to provide access to external interface information like a blockhash: @@ -99,67 +114,13 @@ void main() Additionally this usage example shows the use of events to listen on the inner workings and procedural updates (`step` event) of the EVM. -### Precompiles - -This library support all EVM precompiles up to the `Prague` hardfork. - -The following code allows to run precompiles in isolation, e.g. for testing purposes: - -```ts -// ./examples/precompile.ts - -import { Common, Hardfork, Mainnet } from '@ethereumjs/common' -import { createEVM, getActivePrecompiles } from '@ethereumjs/evm' -import { bytesToHex, hexToBytes } from '@ethereumjs/util' - -const main = async () => { - const common = new Common({ chain: Mainnet, hardfork: Hardfork.Prague }) - - // Taken from test/eips/precompiles/bls/add_G1_bls.json - const data = hexToBytes( - '0x0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21', - ) - const gasLimit = BigInt(5000000) - - const evm = await createEVM({ common }) - const precompile = getActivePrecompiles(common).get('000000000000000000000000000000000000000b')! - - const callData = { - data, - gasLimit, - common, - _EVM: evm, - } - const result = await precompile(callData) - console.log(`Precompile result:${bytesToHex(result.returnValue)}`) -} - -void main() -``` - -### EIP-2537 BLS Precompiles (Prague) - -Starting with `v3.1.0` the EVM support the BLS precompiles introduced with [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537). These precompiles run natively using the [@noble/curves](https://github.com/paulmillr/noble-curves) library (❤️ to `@paulmillr`!). - -An alternative WASM implementation (using [bls-wasm](https://github.com/herumi/bls-wasm)) can be optionally used like this if needed for performance reasons: - -```ts -import { EVM, MCLBLS } from '@ethereumjs/evm' +### WASM Crypto Support -const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Prague }) -await mcl.init(mcl.BLS12_381) -const mclbls = new MCLBLS(mcl) -const evm = await EVM.create({ common, bls }) -``` +This library by default uses JavaScript implementations for the basic standard crypto primitives like hashing or signature verification (for included txs). See `@ethereumjs/common` [README](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/common) for instructions on how to replace with e.g. a more performant WASM implementation by using a shared `common` instance. ## Examples -This projects contain the following examples: - -1. [./examples/decode-opcodes](./examples/decode-opcodes.ts): Decodes a binary EVM program into its opcodes. -1. [./examples/runCode](./examples/runCode.ts): Show how to use this library in a browser. - -All of the examples have their own `README.md` explaining how to run them. +See the [examples](./examples/) folder for different meaningful examples on how to use the EVM package and invoke certain aspects of it, e.g. running a bytecode snippet, listening to events or activate an EVM with a certain EIP for experimental purposes. ## Browser @@ -209,9 +170,7 @@ The interfaces (in a non-TypeScript sense) between these packages have been simp This allows for both a standalone EVM instantiation with reasonable defaults as well as for a simplified EVM -> VM passing if a customized EVM is needed. -## Setup - -### Hardfork Support +## Supported Hardforks The EthereumJS EVM implements all hardforks from `Frontier` (`chainstart`) up to the latest active mainnet hardfork. @@ -232,26 +191,27 @@ Currently the following hardfork rules are supported: - `merge` - `shanghai` (`v2.0.0`+) - `cancun` (`v2.0.0`+) +- `prague` (`v10`+) -Default: `shanghai` (taken from `Common.DEFAULT_HARDFORK`) +Default: `prague` (taken from `Common.DEFAULT_HARDFORK`) A specific hardfork EVM ruleset can be activated by passing in the hardfork along the `Common` instance to the outer `@ethereumjs/vm` instance. -### EIP Support +## Supported EIPs If you want to activate an EIP not currently active on the hardfork your `common` instance is set to, it is possible to individually activate EIP support in the EVM by specifying the desired EIPs using the `eips` property in your `CommonOpts` setup, e.g.: ```ts // ./examples/eips.ts -import { Common, Mainnet } from '@ethereumjs/common' +import { Common, Hardfork, Mainnet } from '@ethereumjs/common' import { createEVM } from '@ethereumjs/evm' const main = async () => { - const common = new Common({ chain: Mainnet, eips: [7702] }) + const common = new Common({ chain: Mainnet, hardfork: Hardfork.Cancun, eips: [7702] }) const evm = await createEVM({ common }) - console.log(`EIP 7702 is active - ${evm.common.isActivatedEIP(7702)}`) + console.log(`EIP 7702 is active in isolation on top of the Cancun HF - ${evm.common.isActivatedEIP(7702)}`) } void main() @@ -296,30 +256,66 @@ Currently supported EIPs: - [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) - Set EOA account code (Prague) - [EIP-7709](https://eips.ethereum.org/EIPS/eip-7709) - Read BLOCKHASH from storage and update cost (Verkle) -### WASM Crypto Support +### EIP-4844 Shard Blob Transactions Support (Cancun) -This library by default uses JavaScript implementations for the basic standard crypto primitives like hashing or signature verification (for included txs). See `@ethereumjs/common` [README](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/common) for instructions on how to replace with e.g. a more performant WASM implementation by using a shared `common` instance. +This library supports the blob transaction type introduced with [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844). EIP-4844 comes with a dedicated opcode `BLOBHASH` and has added a new point evaluation precompile at address `0x0a`. -### EIP-4844 Shard Blob Transactions Support +**Note:** Usage of the point evaluation precompile needs a manual KZG library installation and global initialization, see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions. -This library supports the blob transaction type introduced with [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844). +## Precompiles -#### Initialization +This library support all EVM precompiles up to the `Prague` hardfork. -To run EVM related EIP-4844 functionality you have to active the EIP in the associated `@ethereumjs/common` library: +The following code allows to run precompiles in isolation, e.g. for testing purposes: ```ts -// ./examples/4844.ts +// ./examples/precompile.ts import { Common, Hardfork, Mainnet } from '@ethereumjs/common' +import { createEVM, getActivePrecompiles } from '@ethereumjs/evm' +import { bytesToHex, hexToBytes } from '@ethereumjs/util' -const common = new Common({ chain: Mainnet, hardfork: Hardfork.Shanghai, eips: [4844] }) +const main = async () => { + const common = new Common({ chain: Mainnet, hardfork: Hardfork.Prague }) + + // Taken from test/eips/precompiles/bls/add_G1_bls.json + const data = hexToBytes( + '0x0000000000000000000000000000000017f1d3a73197d7942695638c4fa9ac0fc3688c4f9774b905a14e3a3f171bac586c55e83ff97a1aeffb3af00adb22c6bb0000000000000000000000000000000008b3f481e3aaa0f1a09e30ed741d8ae4fcf5e095d5d00af600db18cb2c04b3edd03cc744a2888ae40caa232946c5e7e100000000000000000000000000000000112b98340eee2777cc3c14163dea3ec97977ac3dc5c70da32e6e87578f44912e902ccef9efe28d4a78b8999dfbca942600000000000000000000000000000000186b28d92356c4dfec4b5201ad099dbdede3781f8998ddf929b4cd7756192185ca7b8f4ef7088f813270ac3d48868a21', + ) + const gasLimit = BigInt(5000000) + + const evm = await createEVM({ common }) + const precompile = getActivePrecompiles(common).get('000000000000000000000000000000000000000b')! + + const callData = { + data, + gasLimit, + common, + _EVM: evm, + } + const result = await precompile(callData) + console.log(`Precompile result:${bytesToHex(result.returnValue)}`) +} + +void main() ``` -EIP-4844 comes with a new opcode `BLOBHASH` (Attention! Renamed from `DATAHASH`) and adds a new point evaluation precompile at address `0x0a` -(moved from `0x14` at some point along spec updates). +### EIP-2537 BLS Precompiles (Prague) -**Note:** Usage of the point evaluation precompile needs a manual KZG library installation and global initialization, see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions. +Starting with `v10` the EVM supports the BLS precompiles introduced with [EIP-2537](https://eips.ethereum.org/EIPS/eip-2537) in its final version introduced with the `Prague` hardfork. These precompiles run natively using the [@noble/curves](https://github.com/paulmillr/noble-curves) library (❤️ to `@paulmillr`!). + +An alternative WASM implementation (using [bls-wasm](https://github.com/herumi/bls-wasm)) can be optionally used like this if needed for performance reasons: + +```ts +import { EVM, MCLBLS } from '@ethereumjs/evm' + +const common = new Common({ chain: Chain.Mainnet, hardfork: Hardfork.Prague }) +await mcl.init(mcl.BLS12_381) +const mclbls = new MCLBLS(mcl) +const evm = await createEVM({ common, bls }) +``` + +## Events ### Tracing Events @@ -370,11 +366,11 @@ The following loggers are currently available: | Logger | Description | | ---------------------------------- | --------------------------------------------------- | -| `evm:evm` |  EVM control flow, CALL or CREATE message execution | -| `evm:gas` |  EVM gas logger | -| `evm:precompiles` |  EVM precompiles logger | -| `evm:journal` |  EVM journal logger | -| `evm:ops` |  Opcode traces | +| `evm:evm` | EVM control flow, CALL or CREATE message execution | +| `evm:gas` | EVM gas logger | +| `evm:precompiles` | EVM precompiles logger | +| `evm:journal` | EVM journal logger | +| `evm:ops` | Opcode traces | | `evm:ops:[Lower-case opcode name]` | Traces on a specific opcode | Here are some examples for useful logger combinations. @@ -441,9 +437,9 @@ TODO: this section likely needs an update. ## Profiling the EVM -Starting with the `v2.1.0` release the EVM comes with build-in profiling capabilities to detect performance bottlenecks and to generally support the targeted evolution of the JavaScript EVM performance. +The EthereumJS EVM comes with build-in profiling capabilities to detect performance bottlenecks and to generally support the targeted evolution of the JavaScript EVM performance. -While the EVM now has a dedicated `profiler` setting to activate, the profiler can best and most useful be run through the EthereumJS [client](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/client) since this gives the most realistic conditions providing both real-world txs and a meaningful state size. +While the EVM has a dedicated `profiler` setting to activate, the profiler can best and most useful be run through the EthereumJS [client](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/client) since this gives the most realistic conditions providing both real-world txs and a meaningful state size. To repeatedly run the EVM profiler within the client sync the client on mainnet or a larger testnet to the desired block. Then the profiler should be run without sync (to not distort the results) by using the `--executeBlocks` and the `--vmProfileBlocks` (or `--vmProfileTxs`) flags in conjunction like: diff --git a/packages/evm/examples/eips.ts b/packages/evm/examples/eips.ts index 4d405bcf120..986ce6ed8c7 100644 --- a/packages/evm/examples/eips.ts +++ b/packages/evm/examples/eips.ts @@ -1,10 +1,12 @@ -import { Common, Mainnet } from '@ethereumjs/common' +import { Common, Hardfork, Mainnet } from '@ethereumjs/common' import { createEVM } from '@ethereumjs/evm' const main = async () => { - const common = new Common({ chain: Mainnet, eips: [7702] }) + const common = new Common({ chain: Mainnet, hardfork: Hardfork.Cancun, eips: [7702] }) const evm = await createEVM({ common }) - console.log(`EIP 7702 is active - ${evm.common.isActivatedEIP(7702)}`) + console.log( + `EIP 7702 is active in isolation on top of the Cancun HF - ${evm.common.isActivatedEIP(7702)}`, + ) } void main() diff --git a/packages/evm/package.json b/packages/evm/package.json index ea6ac3773b4..1b3c7c0ca5a 100644 --- a/packages/evm/package.json +++ b/packages/evm/package.json @@ -59,7 +59,7 @@ "@ethereumjs/statemanager": "^10.0.0-rc.1", "@ethereumjs/util": "^10.0.0-rc.1", "@ethereumjs/verkle": "^10.0.0-dev-rc.1", - "@noble/curves": "^1.8.2", + "@noble/curves": "^1.9.0", "@types/debug": "^4.1.12", "debug": "^4.4.0", "ethereum-cryptography": "^3.1.0", diff --git a/packages/evm/src/eof/errors.ts b/packages/evm/src/eof/errors.ts index 1ab73edb1f6..50989e06a2f 100644 --- a/packages/evm/src/eof/errors.ts +++ b/packages/evm/src/eof/errors.ts @@ -32,7 +32,6 @@ export const EOFError = { MAX_STACK_HEIGHT: 'expected maxStackHeight', MAX_STACK_HEIGHT_LIMIT: 'stack height limit of 1024 exceeded: ', MIN_CODE_SECTIONS: 'should have at least 1 code section', - MAX_CODE_SECTIONS: 'can have at most 1024 code sections', CODE_SECTION: 'expected a code section', DATA_SECTION: 'Expected data section', CONTAINER_SECTION: 'expected a container section', @@ -66,39 +65,6 @@ export const EOFError = { RETURN_STACK_OVERFLOW: 'Return stack overflow', INVALID_EXTCALL_TARGET: 'invalid extcall target: address > 20 bytes', INVALID_RETURN_CONTRACT_DATA_SIZE: 'invalid RETURNCONTRACT: data size lower than expected', - INVALID_EOF_FORMAT: 'invalid EOF format', -} as const - -export type SimpleErrors = (typeof SimpleErrors)[keyof typeof SimpleErrors] - -export const SimpleErrors = { - MIN_CONTAINER_SIZE: 'err: container size less than minimum valid size', - INVALID_CONTAINER_SIZE: 'err: invalid container size', - TYPE_SIZE: 'err: type section size invalid', - CODE0_MSH: 'err: computed max stack height for code section 0 does not match expect', - UNDERFLOW: 'err: stack underflow', - CODE0_IO: 'err: input and output of first code section must be 0', - VERIFY_UINT: 'Uint does not match expected value ', - VERIFY_BYTES: 'Bytes do not match expected value', - INVALID_TYPE_SIZE: 'err: type section invalid', - CODE_SIZE: 'missing code size', - CODE_SECTION_SIZE: 'code section should be at least one byte', - INVALID_CODE_SIZE: 'code size does not match type size', - DATA_SIZE: 'missing data size', - TYPE_SECTIONS: 'need to have a type section for each code section', - INPUTS: 'expected inputs', - OUTPUTS: 'expected outputs', - MAX_INPUTS: 'inputs exceeds 127, the maximum, got: ', - MAX_OUTPUTS: 'outputs exceeds 127, the maximum, got: ', - CODE0_INPUTS: 'first code section should have 0 inputs', - CODE0_OUTPUTS: 'first code section should have 0 outputs', - MAX_STACK_HEIGHT: 'expected maxStackHeight', - MAX_STACK_HEIGHT_LIMIT: 'stack height limit of 1024 exceeded: ', - MIN_CODE_SECTIONS: 'should have at least 1 code section', - MAX_CODE_SECTIONS: 'can have at most 1024 code sections', - CODE_SECTION: 'expected a code section', - DATA_SECTION: 'Expected data section', - DANGLING_BYTES: 'got dangling bytes in body', } as const export function validationErrorMsg(type: EOFError, ...args: any) { diff --git a/packages/evm/src/errors.ts b/packages/evm/src/errors.ts index 14521f144c2..ebed1bd8aab 100644 --- a/packages/evm/src/errors.ts +++ b/packages/evm/src/errors.ts @@ -1,6 +1,8 @@ export type EVMErrorType = (typeof EVMErrorMessages)[keyof typeof EVMErrorMessages] -export const EVMErrorMessages = { +export const EVMErrorTypeString = 'EVMError' + +const EVMErrorMessages = { OUT_OF_GAS: 'out of gas', CODESTORE_OUT_OF_GAS: 'code store out of gas', CODESIZE_EXCEEDS_MAXIMUM: 'code size to deposit exceeds maximum code size', @@ -17,9 +19,6 @@ export const EVMErrorMessages = { REFUND_EXHAUSTED: 'refund exhausted', VALUE_OVERFLOW: 'value overflow', INSUFFICIENT_BALANCE: 'insufficient balance', - INVALID_BEGINSUB: 'invalid BEGINSUB', - INVALID_RETURNSUB: 'invalid RETURNSUB', - INVALID_JUMPSUB: 'invalid JUMPSUB', INVALID_BYTECODE_RESULT: 'invalid bytecode deployed', INITCODE_SIZE_VIOLATION: 'initcode exceeds max initcode size', INVALID_INPUT_LENGTH: 'invalid input length', @@ -37,9 +36,10 @@ export const EVMErrorMessages = { export class EVMError { error: EVMErrorType errorType: string + static errorMessages: Record = EVMErrorMessages constructor(error: EVMErrorType) { this.error = error - this.errorType = 'EVMError' + this.errorType = EVMErrorTypeString } } diff --git a/packages/evm/src/evm.ts b/packages/evm/src/evm.ts index d6298e998a7..7ea57352aa3 100644 --- a/packages/evm/src/evm.ts +++ b/packages/evm/src/evm.ts @@ -21,7 +21,7 @@ import { EventEmitter } from 'eventemitter3' import { FORMAT } from './eof/constants.ts' import { isEOF } from './eof/util.ts' -import { EVMError, EVMErrorMessages } from './errors.ts' +import { EVMError } from './errors.ts' import { Interpreter } from './interpreter.ts' import { Journal } from './journal.ts' import { EVMPerformanceLogger } from './logger.ts' @@ -64,7 +64,7 @@ export function OOGResult(gasLimit: bigint): ExecResult { return { returnValue: new Uint8Array(0), executionGasUsed: gasLimit, - exceptionError: new EVMError(EVMErrorMessages.OUT_OF_GAS), + exceptionError: new EVMError(EVMError.errorMessages.OUT_OF_GAS), } } // CodeDeposit OOG Result @@ -72,7 +72,7 @@ export function COOGResult(gasUsedCreateCode: bigint): ExecResult { return { returnValue: new Uint8Array(0), executionGasUsed: gasUsedCreateCode, - exceptionError: new EVMError(EVMErrorMessages.CODESTORE_OUT_OF_GAS), + exceptionError: new EVMError(EVMError.errorMessages.CODESTORE_OUT_OF_GAS), } } @@ -80,7 +80,7 @@ export function INVALID_BYTECODE_RESULT(gasLimit: bigint): ExecResult { return { returnValue: new Uint8Array(0), executionGasUsed: gasLimit, - exceptionError: new EVMError(EVMErrorMessages.INVALID_BYTECODE_RESULT), + exceptionError: new EVMError(EVMError.errorMessages.INVALID_BYTECODE_RESULT), } } @@ -88,7 +88,7 @@ export function INVALID_EOF_RESULT(gasLimit: bigint): ExecResult { return { returnValue: new Uint8Array(0), executionGasUsed: gasLimit, - exceptionError: new EVMError(EVMErrorMessages.INVALID_EOF_FORMAT), + exceptionError: new EVMError(EVMError.errorMessages.INVALID_EOF_FORMAT), } } @@ -96,11 +96,11 @@ export function CodesizeExceedsMaximumError(gasUsed: bigint): ExecResult { return { returnValue: new Uint8Array(0), executionGasUsed: gasUsed, - exceptionError: new EVMError(EVMErrorMessages.CODESIZE_EXCEEDS_MAXIMUM), + exceptionError: new EVMError(EVMError.errorMessages.CODESIZE_EXCEEDS_MAXIMUM), } } -export function EvmErrorResult(error: EVMError, gasUsed: bigint): ExecResult { +export function EVMErrorResult(error: EVMError, gasUsed: bigint): ExecResult { return { returnValue: new Uint8Array(0), executionGasUsed: gasUsed, @@ -508,7 +508,7 @@ export class EVM implements EVMInterface { createdAddress: message.to, execResult: { returnValue: new Uint8Array(0), - exceptionError: new EVMError(EVMErrorMessages.INITCODE_SIZE_VIOLATION), + exceptionError: new EVMError(EVMError.errorMessages.INITCODE_SIZE_VIOLATION), executionGasUsed: message.gasLimit, }, } @@ -567,7 +567,7 @@ export class EVM implements EVMInterface { createdAddress: message.to, execResult: { returnValue: new Uint8Array(0), - exceptionError: new EVMError(EVMErrorMessages.CREATE_COLLISION), + exceptionError: new EVMError(EVMError.errorMessages.CREATE_COLLISION), executionGasUsed: message.gasLimit, }, } @@ -871,8 +871,8 @@ export class EVM implements EVMInterface { let gasUsed = message.gasLimit - interpreterRes.runState!.gasLeft if (interpreterRes.exceptionError) { if ( - interpreterRes.exceptionError.error !== EVMErrorMessages.REVERT && - interpreterRes.exceptionError.error !== EVMErrorMessages.INVALID_EOF_FORMAT + interpreterRes.exceptionError.error !== EVMError.errorMessages.REVERT && + interpreterRes.exceptionError.error !== EVMError.errorMessages.INVALID_EOF_FORMAT ) { gasUsed = message.gasLimit } @@ -1019,7 +1019,7 @@ export class EVM implements EVMInterface { // There is one exception: if the CODESTORE_OUT_OF_GAS error is thrown // (this only happens the Frontier/Chainstart fork) // then the error is dismissed - if (err && err.error !== EVMErrorMessages.CODESTORE_OUT_OF_GAS) { + if (err && err.error !== EVMError.errorMessages.CODESTORE_OUT_OF_GAS) { result.execResult.selfdestruct = new Set() result.execResult.createdAddresses = new Set() result.execResult.gasRefund = BIGINT_0 @@ -1028,7 +1028,7 @@ export class EVM implements EVMInterface { err && !( this.common.hardfork() === Hardfork.Chainstart && - err.error === EVMErrorMessages.CODESTORE_OUT_OF_GAS + err.error === EVMError.errorMessages.CODESTORE_OUT_OF_GAS ) ) { result.execResult.logs = [] @@ -1159,7 +1159,7 @@ export class EVM implements EVMInterface { protected async _reduceSenderBalance(account: Account, message: Message): Promise { account.balance -= message.value if (account.balance < BIGINT_0) { - throw new EVMError(EVMErrorMessages.INSUFFICIENT_BALANCE) + throw new EVMError(EVMError.errorMessages.INSUFFICIENT_BALANCE) } const result = this.journal.putAccount(message.caller, account) if (this.DEBUG) { @@ -1171,7 +1171,7 @@ export class EVM implements EVMInterface { protected async _addToBalance(toAccount: Account, message: MessageWithTo): Promise { const newBalance = toAccount.balance + message.value if (newBalance > MAX_INTEGER) { - throw new EVMError(EVMErrorMessages.VALUE_OVERFLOW) + throw new EVMError(EVMError.errorMessages.VALUE_OVERFLOW) } toAccount.balance = newBalance // putAccount as the nonce may have changed for contract creation diff --git a/packages/evm/src/index.ts b/packages/evm/src/index.ts index b12391fa890..df97e14cdc1 100644 --- a/packages/evm/src/index.ts +++ b/packages/evm/src/index.ts @@ -1,5 +1,5 @@ import { EOFContainer, validateEOF } from './eof/container.ts' -import { EVMError, EVMErrorMessages } from './errors.ts' +import { EVMError } from './errors.ts' import { EVM } from './evm.ts' import { Message } from './message.ts' import { getOpcodesForHF } from './opcodes/index.ts' @@ -47,7 +47,6 @@ export { EOFContainer, EVM, EVMError, - EVMErrorMessages, EVMMockBlockchain, getActivePrecompiles, getOpcodesForHF, diff --git a/packages/evm/src/interpreter.ts b/packages/evm/src/interpreter.ts index 75d4df4d7c9..f4a0a1c3574 100644 --- a/packages/evm/src/interpreter.ts +++ b/packages/evm/src/interpreter.ts @@ -18,7 +18,7 @@ import { FORMAT, MAGIC, VERSION } from './eof/constants.ts' import { EOFContainerMode, validateEOF } from './eof/container.ts' import { setupEOF } from './eof/setup.ts' import { ContainerSectionType } from './eof/verify.ts' -import { EVMError, EVMErrorMessages } from './errors.ts' +import { EVMError, EVMErrorTypeString } from './errors.ts' import { type EVMPerformanceLogger, type Timer } from './logger.ts' import { Memory } from './memory.ts' import { Message } from './message.ts' @@ -219,14 +219,14 @@ export class Interpreter { // Bytecode contains invalid EOF magic byte return { runState: this._runState, - exceptionError: new EVMError(EVMErrorMessages.INVALID_BYTECODE_RESULT), + exceptionError: new EVMError(EVMError.errorMessages.INVALID_BYTECODE_RESULT), } } if (code[2] !== VERSION) { // Bytecode contains invalid EOF version number return { runState: this._runState, - exceptionError: new EVMError(EVMErrorMessages.INVALID_EOF_FORMAT), + exceptionError: new EVMError(EVMError.errorMessages.INVALID_EOF_FORMAT), } } this._runState.code = code @@ -239,7 +239,7 @@ export class Interpreter { } catch { return { runState: this._runState, - exceptionError: new EVMError(EVMErrorMessages.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed + exceptionError: new EVMError(EVMError.errorMessages.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed } } @@ -256,7 +256,7 @@ export class Interpreter { // Trying to deploy an invalid EOF container return { runState: this._runState, - exceptionError: new EVMError(EVMErrorMessages.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed + exceptionError: new EVMError(EVMError.errorMessages.INVALID_EOF_FORMAT), // TODO: verify if all gas should be consumed } } } @@ -336,11 +336,11 @@ export class Interpreter { this.performanceLogger.unpauseTimer(overheadTimer) } // re-throw on non-VM errors - if (!('errorType' in e && e.errorType === 'EVMError')) { + if (!('errorType' in e && e.errorType === EVMErrorTypeString)) { throw e } // STOP is not an exception - if (e.error !== EVMErrorMessages.STOP) { + if (e.error !== EVMError.errorMessages.STOP) { err = e } break @@ -403,7 +403,7 @@ export class Interpreter { // Check for invalid opcode if (opInfo.isInvalid) { - throw new EVMError(EVMErrorMessages.INVALID_OPCODE) + throw new EVMError(EVMError.errorMessages.INVALID_OPCODE) } // Reduce opcode's base fee @@ -563,7 +563,7 @@ export class Interpreter { } if (this._runState.gasLeft < BIGINT_0) { this._runState.gasLeft = BIGINT_0 - trap(EVMErrorMessages.OUT_OF_GAS) + trap(EVMError.errorMessages.OUT_OF_GAS) } } @@ -599,7 +599,7 @@ export class Interpreter { this._runState.gasRefund -= amount if (this._runState.gasRefund < BIGINT_0) { this._runState.gasRefund = BIGINT_0 - trap(EVMErrorMessages.REFUND_EXHAUSTED) + trap(EVMError.errorMessages.REFUND_EXHAUSTED) } } @@ -681,7 +681,7 @@ export class Interpreter { */ finish(returnData: Uint8Array): void { this._result.returnValue = returnData - trap(EVMErrorMessages.STOP) + trap(EVMError.errorMessages.STOP) } /** @@ -691,7 +691,7 @@ export class Interpreter { */ revert(returnData: Uint8Array): void { this._result.returnValue = returnData - trap(EVMErrorMessages.REVERT) + trap(EVMError.errorMessages.REVERT) } /** @@ -1016,7 +1016,7 @@ export class Interpreter { if ( results.execResult.returnValue !== undefined && (!results.execResult.exceptionError || - results.execResult.exceptionError.error === EVMErrorMessages.REVERT) + results.execResult.exceptionError.error === EVMError.errorMessages.REVERT) ) { this._runState.returnBytes = results.execResult.returnValue } @@ -1117,14 +1117,14 @@ export class Interpreter { // Set return buffer in case revert happened if ( results.execResult.exceptionError && - results.execResult.exceptionError.error === EVMErrorMessages.REVERT + results.execResult.exceptionError.error === EVMError.errorMessages.REVERT ) { this._runState.returnBytes = results.execResult.returnValue } if ( !results.execResult.exceptionError || - results.execResult.exceptionError.error === EVMErrorMessages.CODESTORE_OUT_OF_GAS + results.execResult.exceptionError.error === EVMError.errorMessages.CODESTORE_OUT_OF_GAS ) { for (const addressToSelfdestructHex of selfdestruct) { this._result.selfdestruct.add(addressToSelfdestructHex) @@ -1230,7 +1230,7 @@ export class Interpreter { }) } - trap(EVMErrorMessages.STOP) + trap(EVMError.errorMessages.STOP) } /** @@ -1238,11 +1238,11 @@ export class Interpreter { */ log(data: Uint8Array, numberOfTopics: number, topics: Uint8Array[]): void { if (numberOfTopics < 0 || numberOfTopics > 4) { - trap(EVMErrorMessages.OUT_OF_RANGE) + trap(EVMError.errorMessages.OUT_OF_RANGE) } if (topics.length !== numberOfTopics) { - trap(EVMErrorMessages.INTERNAL_ERROR) + trap(EVMError.errorMessages.INTERNAL_ERROR) } const log: Log = [this._env.address.bytes, topics, data] @@ -1259,7 +1259,7 @@ export class Interpreter { } else { // EOF mode, call was either EXTCALL / EXTDELEGATECALL / EXTSTATICCALL if (results.execResult.exceptionError !== undefined) { - if (results.execResult.exceptionError.error === EVMErrorMessages.REVERT) { + if (results.execResult.exceptionError.error === EVMError.errorMessages.REVERT) { // Revert return BIGINT_1 } else { diff --git a/packages/evm/src/opcodes/EIP2200.ts b/packages/evm/src/opcodes/EIP2200.ts index 9c6cbccfff7..6ac2436f069 100644 --- a/packages/evm/src/opcodes/EIP2200.ts +++ b/packages/evm/src/opcodes/EIP2200.ts @@ -1,6 +1,6 @@ import { equalsBytes } from '@ethereumjs/util' -import { EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import { adjustSstoreGasEIP2929 } from './EIP2929.ts' import { trap } from './util.ts' @@ -27,7 +27,7 @@ export function updateSstoreGasEIP2200( ) { // Fail if not enough gas is left if (runState.interpreter.getGasLeft() <= common.param('sstoreSentryEIP2200Gas')) { - trap(EVMErrorMessages.OUT_OF_GAS) + trap(EVMError.errorMessages.OUT_OF_GAS) } // Noop diff --git a/packages/evm/src/opcodes/functions.ts b/packages/evm/src/opcodes/functions.ts index e726c32b394..eef2d636b08 100644 --- a/packages/evm/src/opcodes/functions.ts +++ b/packages/evm/src/opcodes/functions.ts @@ -31,7 +31,7 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { EOFContainer, EOFContainerMode } from '../eof/container.ts' import { EOFError } from '../eof/errors.ts' import { EOFBYTES, EOFHASH, isEOF } from '../eof/util.ts' -import { EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import { createAddressFromStackBigInt, @@ -65,7 +65,7 @@ export const handlers: Map = new Map([ [ 0x00, function () { - trap(EVMErrorMessages.STOP) + trap(EVMError.errorMessages.STOP) }, ], // 0x01: ADD @@ -810,13 +810,13 @@ export const handlers: Map = new Map([ function (runState) { const dest = runState.stack.pop() if (dest > runState.interpreter.getCodeSize()) { - trap(EVMErrorMessages.INVALID_JUMP + ' at ' + describeLocation(runState)) + trap(EVMError.errorMessages.INVALID_JUMP + ' at ' + describeLocation(runState)) } const destNum = Number(dest) if (!jumpIsValid(runState, destNum)) { - trap(EVMErrorMessages.INVALID_JUMP + ' at ' + describeLocation(runState)) + trap(EVMError.errorMessages.INVALID_JUMP + ' at ' + describeLocation(runState)) } runState.programCounter = destNum @@ -829,13 +829,13 @@ export const handlers: Map = new Map([ const [dest, cond] = runState.stack.popN(2) if (cond !== BIGINT_0) { if (dest > runState.interpreter.getCodeSize()) { - trap(EVMErrorMessages.INVALID_JUMP + ' at ' + describeLocation(runState)) + trap(EVMError.errorMessages.INVALID_JUMP + ' at ' + describeLocation(runState)) } const destNum = Number(dest) if (!jumpIsValid(runState, destNum)) { - trap(EVMErrorMessages.INVALID_JUMP + ' at ' + describeLocation(runState)) + trap(EVMError.errorMessages.INVALID_JUMP + ' at ' + describeLocation(runState)) } runState.programCounter = destNum @@ -882,7 +882,7 @@ export const handlers: Map = new Map([ function (runState) { // TSTORE if (runState.interpreter.isStatic()) { - trap(EVMErrorMessages.STATIC_STATE_CHANGE) + trap(EVMError.errorMessages.STATIC_STATE_CHANGE) } const [key, val] = runState.stack.popN(2) @@ -995,7 +995,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } const pos = runState.stack.pop() if (pos > runState.env.eof!.container.body.dataSection.length) { @@ -1020,7 +1020,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } const toLoad = Number( bytesToBigInt(runState.code.subarray(runState.programCounter, runState.programCounter + 2)), @@ -1038,7 +1038,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } runState.stack.push(BigInt(runState.env.eof!.container.body.dataSection.length)) }, @@ -1049,7 +1049,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } const [memOffset, offset, size] = runState.stack.popN(3) if (size !== BIGINT_0) { @@ -1066,7 +1066,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } else { const code = runState.env.code const rjumpDest = new DataView(code.buffer).getInt16(runState.programCounter) @@ -1080,7 +1080,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } else { const cond = runState.stack.pop() // Move PC to the PC post instruction @@ -1100,7 +1100,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } else { const code = runState.env.code const jumptableEntries = code[runState.programCounter] @@ -1127,7 +1127,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } const sectionTarget = bytesToInt( runState.code.slice(runState.programCounter, runState.programCounter + 2), @@ -1152,7 +1152,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } const newPc = runState.env.eof!.eofRunState.returnStack.pop() if (newPc === undefined) { @@ -1168,7 +1168,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } // NOTE: (and also TODO) this code is exactly the same as CALLF, except pushing to the return stack is now skipped // (and also the return stack overflow check) @@ -1196,7 +1196,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } const toDup = Number( @@ -1214,7 +1214,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } const toSwap = Number( @@ -1232,7 +1232,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } const toExchange = Number( bytesToBigInt(runState.code.subarray(runState.programCounter, runState.programCounter + 1)), @@ -1249,10 +1249,10 @@ export const handlers: Map = new Map([ async function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } else { if (runState.interpreter.isStatic()) { - trap(EVMErrorMessages.STATIC_STATE_CHANGE) + trap(EVMError.errorMessages.STATIC_STATE_CHANGE) } // Read container index const containerIndex = runState.env.code[runState.programCounter] @@ -1288,7 +1288,7 @@ export const handlers: Map = new Map([ async function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } else { // Read container index const containerIndex = runState.env.code[runState.programCounter] @@ -1316,7 +1316,7 @@ export const handlers: Map = new Map([ if (actualSectionSize > 0xffff) { // Data section size is now larger than the max data section size // Temp: trap OOG? - trap(EVMErrorMessages.OUT_OF_GAS) + trap(EVMError.errorMessages.OUT_OF_GAS) } const newSize = setLengthLeft(bigIntToBytes(BigInt(actualSectionSize)), 2) @@ -1344,7 +1344,7 @@ export const handlers: Map = new Map([ length > Number(common.param('maxInitCodeSize')) && !runState.interpreter._evm.allowUnlimitedInitCodeSize ) { - trap(EVMErrorMessages.INITCODE_SIZE_VIOLATION) + trap(EVMError.errorMessages.INITCODE_SIZE_VIOLATION) } const gasLimit = runState.messageGasLimit! @@ -1370,7 +1370,7 @@ export const handlers: Map = new Map([ 0xf5, async function (runState, common) { if (runState.interpreter.isStatic()) { - trap(EVMErrorMessages.STATIC_STATE_CHANGE) + trap(EVMError.errorMessages.STATIC_STATE_CHANGE) } const [value, offset, length, salt] = runState.stack.popN(4) @@ -1380,7 +1380,7 @@ export const handlers: Map = new Map([ length > Number(common.param('maxInitCodeSize')) && !runState.interpreter._evm.allowUnlimitedInitCodeSize ) { - trap(EVMErrorMessages.INITCODE_SIZE_VIOLATION) + trap(EVMError.errorMessages.INITCODE_SIZE_VIOLATION) } const gasLimit = runState.messageGasLimit! @@ -1491,7 +1491,7 @@ export const handlers: Map = new Map([ function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } const pos = runState.stack.pop() if (pos > runState.interpreter.getReturnDataSize()) { @@ -1515,7 +1515,7 @@ export const handlers: Map = new Map([ async function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } else { const [toAddr, inOffset, inLength, value] = runState.stack.popN(4) @@ -1549,7 +1549,7 @@ export const handlers: Map = new Map([ async function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } else { const value = runState.interpreter.getCallValue() const [toAddr, inOffset, inLength] = runState.stack.popN(3) @@ -1614,7 +1614,7 @@ export const handlers: Map = new Map([ async function (runState) { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } else { const value = BIGINT_0 const [toAddr, inOffset, inLength] = runState.stack.popN(3) diff --git a/packages/evm/src/opcodes/gas.ts b/packages/evm/src/opcodes/gas.ts index 31ba27ab896..d55d9094299 100644 --- a/packages/evm/src/opcodes/gas.ts +++ b/packages/evm/src/opcodes/gas.ts @@ -12,7 +12,7 @@ import { } from '@ethereumjs/util' import { EOFError } from '../eof/errors.ts' -import { EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import { DELEGATION_7702_FLAG } from '../types.ts' import { updateSstoreGasEIP1283 } from './EIP1283.ts' @@ -79,7 +79,7 @@ export const dynamicGasHandlers: Map 32) { - trap(EVMErrorMessages.OUT_OF_RANGE) + trap(EVMError.errorMessages.OUT_OF_RANGE) } const expPricePerByte = common.param('expByteGas') gas += BigInt(byteLength) * expPricePerByte @@ -244,7 +244,7 @@ export const dynamicGasHandlers: Map { if (runState.interpreter.isStatic()) { - trap(EVMErrorMessages.STATIC_STATE_CHANGE) + trap(EVMError.errorMessages.STATIC_STATE_CHANGE) } const [key, val] = runState.stack.peek(2) @@ -415,7 +415,7 @@ export const dynamicGasHandlers: Map { if (runState.interpreter.isStatic()) { - trap(EVMErrorMessages.STATIC_STATE_CHANGE) + trap(EVMError.errorMessages.STATIC_STATE_CHANGE) } const [memOffset, memLength] = runState.stack.peek(2) @@ -423,7 +423,7 @@ export const dynamicGasHandlers: Map 4) { - trap(EVMErrorMessages.OUT_OF_RANGE) + trap(EVMError.errorMessages.OUT_OF_RANGE) } gas += subMemUsage(runState, memOffset, memLength, common) @@ -438,7 +438,7 @@ export const dynamicGasHandlers: Map { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } // Note: TX_CREATE_COST is in the base fee (this is 32000 and same as CREATE / CREATE2) @@ -514,7 +514,7 @@ export const dynamicGasHandlers: Map { if (runState.interpreter.isStatic()) { - trap(EVMErrorMessages.STATIC_STATE_CHANGE) + trap(EVMError.errorMessages.STATIC_STATE_CHANGE) } const [_value, offset, length] = runState.stack.peek(3) @@ -549,7 +549,7 @@ export const dynamicGasHandlers: Map runState.interpreter.getGasLeft() - gas) { - trap(EVMErrorMessages.OUT_OF_GAS) + trap(EVMError.errorMessages.OUT_OF_GAS) } if (gas > runState.interpreter.getGasLeft()) { - trap(EVMErrorMessages.OUT_OF_GAS) + trap(EVMError.errorMessages.OUT_OF_GAS) } runState.messageGasLimit = gasLimit @@ -669,7 +669,7 @@ export const dynamicGasHandlers: Map runState.interpreter.getGasLeft() - gas) { - trap(EVMErrorMessages.OUT_OF_GAS) + trap(EVMError.errorMessages.OUT_OF_GAS) } runState.messageGasLimit = gasLimit @@ -729,7 +729,7 @@ export const dynamicGasHandlers: Map runState.interpreter.getGasLeft() - gas) { - trap(EVMErrorMessages.OUT_OF_GAS) + trap(EVMError.errorMessages.OUT_OF_GAS) } runState.messageGasLimit = gasLimit @@ -741,7 +741,7 @@ export const dynamicGasHandlers: Map { if (runState.interpreter.isStatic()) { - trap(EVMErrorMessages.STATIC_STATE_CHANGE) + trap(EVMError.errorMessages.STATIC_STATE_CHANGE) } const [_value, offset, length, _salt] = runState.stack.peek(4) @@ -774,7 +774,7 @@ export const dynamicGasHandlers: Map { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } // Charge WARM_STORAGE_READ_COST (100) -> done in accessAddressEIP2929 @@ -783,7 +783,7 @@ export const dynamicGasHandlers: Map 0, charge CALL_VALUE_COST @@ -851,7 +851,7 @@ export const dynamicGasHandlers: Map { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } // Charge WARM_STORAGE_READ_COST (100) -> done in accessAddressEIP2929 @@ -955,7 +955,7 @@ export const dynamicGasHandlers: Map { if (runState.env.eof === undefined) { // Opcode not available in legacy contracts - trap(EVMErrorMessages.INVALID_OPCODE) + trap(EVMError.errorMessages.INVALID_OPCODE) } // Charge WARM_STORAGE_READ_COST (100) -> done in accessAddressEIP2929 @@ -1016,7 +1016,7 @@ export const dynamicGasHandlers: Map { if (runState.interpreter.isStatic()) { - trap(EVMErrorMessages.STATIC_STATE_CHANGE) + trap(EVMError.errorMessages.STATIC_STATE_CHANGE) } const selfdestructToaddressBigInt = runState.stack.peek()[0] diff --git a/packages/evm/src/opcodes/util.ts b/packages/evm/src/opcodes/util.ts index b118528f42d..5b4af7775dd 100644 --- a/packages/evm/src/opcodes/util.ts +++ b/packages/evm/src/opcodes/util.ts @@ -85,7 +85,7 @@ export function setLengthLeftStorage(value: Uint8Array) { } /** - * Wraps error message as EvmError + * Wraps error message as EVMError */ export function trap(err: string) { // TODO: facilitate extra data along with errors diff --git a/packages/evm/src/precompiles/06-bn254-add.ts b/packages/evm/src/precompiles/06-bn254-add.ts index f4006ddf1e6..8892cfee681 100644 --- a/packages/evm/src/precompiles/06-bn254-add.ts +++ b/packages/evm/src/precompiles/06-bn254-add.ts @@ -1,6 +1,6 @@ import { bytesToHex, setLengthRight } from '@ethereumjs/util' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { getPrecompileName } from './index.ts' import { gasLimitCheck } from './util.ts' @@ -27,7 +27,7 @@ export function precompile06(opts: PrecompileInput): ExecResult { if (opts._debug !== undefined) { opts._debug(`${pName} failed: ${e.message}`) } - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } // check ecadd success or failure by comparing the output length diff --git a/packages/evm/src/precompiles/07-bn254-mul.ts b/packages/evm/src/precompiles/07-bn254-mul.ts index 76f5312bc06..25618e2fd68 100644 --- a/packages/evm/src/precompiles/07-bn254-mul.ts +++ b/packages/evm/src/precompiles/07-bn254-mul.ts @@ -1,6 +1,6 @@ import { bytesToHex, setLengthRight } from '@ethereumjs/util' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { getPrecompileName } from './index.ts' import { gasLimitCheck } from './util.ts' @@ -27,7 +27,7 @@ export function precompile07(opts: PrecompileInput): ExecResult { if (opts._debug !== undefined) { opts._debug(`${pName} failed: ${e.message}`) } - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } // check ecmul success or failure by comparing the output length diff --git a/packages/evm/src/precompiles/08-bn254-pairing.ts b/packages/evm/src/precompiles/08-bn254-pairing.ts index 7da55488157..48b0a335f83 100644 --- a/packages/evm/src/precompiles/08-bn254-pairing.ts +++ b/packages/evm/src/precompiles/08-bn254-pairing.ts @@ -1,7 +1,7 @@ import { bytesToHex } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMError } from '../errors.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { getPrecompileName } from './index.ts' import { gasLimitCheck, moduloLengthCheck } from './util.ts' @@ -13,7 +13,7 @@ import type { PrecompileInput } from './types.ts' export function precompile08(opts: PrecompileInput): ExecResult { const pName = getPrecompileName('08') if (!moduloLengthCheck(opts, 192, pName)) { - return EvmErrorResult(new EVMError(EVMErrorMessages.INVALID_INPUT_LENGTH), opts.gasLimit) + return EVMErrorResult(new EVMError(EVMError.errorMessages.INVALID_INPUT_LENGTH), opts.gasLimit) } const inputDataSize = BigInt(Math.floor(opts.data.length / 192)) @@ -31,7 +31,7 @@ export function precompile08(opts: PrecompileInput): ExecResult { if (opts._debug !== undefined) { opts._debug(`${pName} failed: ${e.message}`) } - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } // check ecpairing success or failure by comparing the output length diff --git a/packages/evm/src/precompiles/09-blake2f.ts b/packages/evm/src/precompiles/09-blake2f.ts index 34a04476f61..319e41dd62e 100644 --- a/packages/evm/src/precompiles/09-blake2f.ts +++ b/packages/evm/src/precompiles/09-blake2f.ts @@ -1,6 +1,6 @@ import { bytesToHex } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import { OOGResult } from '../evm.ts' import { getPrecompileName } from './index.ts' @@ -181,7 +181,7 @@ export function precompile09(opts: PrecompileInput): ExecResult { return { returnValue: new Uint8Array(0), executionGasUsed: opts.gasLimit, - exceptionError: new EVMError(EVMErrorMessages.OUT_OF_RANGE), + exceptionError: new EVMError(EVMError.errorMessages.OUT_OF_RANGE), } } const lastByte = data.subarray(212, 213)[0] @@ -192,7 +192,7 @@ export function precompile09(opts: PrecompileInput): ExecResult { return { returnValue: new Uint8Array(0), executionGasUsed: opts.gasLimit, - exceptionError: new EVMError(EVMErrorMessages.OUT_OF_RANGE), + exceptionError: new EVMError(EVMError.errorMessages.OUT_OF_RANGE), } } diff --git a/packages/evm/src/precompiles/0a-kzg-point-evaluation.ts b/packages/evm/src/precompiles/0a-kzg-point-evaluation.ts index 80f60acf50f..fea3b925ff3 100644 --- a/packages/evm/src/precompiles/0a-kzg-point-evaluation.ts +++ b/packages/evm/src/precompiles/0a-kzg-point-evaluation.ts @@ -7,8 +7,8 @@ import { setLengthLeft, } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMError } from '../errors.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { getPrecompileName } from './index.ts' import { gasLimitCheck } from './util.ts' @@ -33,7 +33,7 @@ export async function precompile0a(opts: PrecompileInput): Promise { } if (opts.data.length !== 192) { - return EvmErrorResult(new EVMError(EVMErrorMessages.INVALID_INPUT_LENGTH), opts.gasLimit) + return EVMErrorResult(new EVMError(EVMError.errorMessages.INVALID_INPUT_LENGTH), opts.gasLimit) } const version = Number(opts.common.param('blobCommitmentVersionKzg')) @@ -48,7 +48,7 @@ export async function precompile0a(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: INVALID_COMMITMENT`) } - return EvmErrorResult(new EVMError(EVMErrorMessages.INVALID_COMMITMENT), opts.gasLimit) + return EVMErrorResult(new EVMError(EVMError.errorMessages.INVALID_COMMITMENT), opts.gasLimit) } if (opts._debug !== undefined) { @@ -61,19 +61,19 @@ export async function precompile0a(opts: PrecompileInput): Promise { try { const res = opts.common.customCrypto?.kzg?.verifyProof(commitment, z, y, kzgProof) if (res === false) { - return EvmErrorResult(new EVMError(EVMErrorMessages.INVALID_PROOF), opts.gasLimit) + return EVMErrorResult(new EVMError(EVMError.errorMessages.INVALID_PROOF), opts.gasLimit) } } catch (err: any) { if (((err.message.includes('C_KZG_BADARGS') === true) === true) === true) { if (opts._debug !== undefined) { opts._debug(`${pName} failed: INVALID_INPUTS`) } - return EvmErrorResult(new EVMError(EVMErrorMessages.INVALID_INPUTS), opts.gasLimit) + return EVMErrorResult(new EVMError(EVMError.errorMessages.INVALID_INPUTS), opts.gasLimit) } if (opts._debug !== undefined) { opts._debug(`${pName} failed: Unknown error - ${err.message}`) } - return EvmErrorResult(new EVMError(EVMErrorMessages.REVERT), opts.gasLimit) + return EVMErrorResult(new EVMError(EVMError.errorMessages.REVERT), opts.gasLimit) } // Return value - FIELD_ELEMENTS_PER_BLOB and BLS_MODULUS as padded 32 byte big endian values diff --git a/packages/evm/src/precompiles/0b-bls12-g1add.ts b/packages/evm/src/precompiles/0b-bls12-g1add.ts index e408ffc81c8..f1a620db89d 100644 --- a/packages/evm/src/precompiles/0b-bls12-g1add.ts +++ b/packages/evm/src/precompiles/0b-bls12-g1add.ts @@ -1,8 +1,8 @@ import { bytesToHex } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import type { EVM } from '../evm.ts' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { leading16ZeroBytesCheck } from './bls12_381/index.ts' import { getPrecompileName } from './index.ts' @@ -22,8 +22,8 @@ export async function precompile0b(opts: PrecompileInput): Promise { } if (!equalityLengthCheck(opts, 256, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_INVALID_INPUT_LENGTH), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INVALID_INPUT_LENGTH), opts.gasLimit, ) } @@ -36,8 +36,8 @@ export async function precompile0b(opts: PrecompileInput): Promise { [192, 208], ] if (!leading16ZeroBytesCheck(opts, zeroByteRanges, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE), opts.gasLimit, ) } @@ -49,7 +49,7 @@ export async function precompile0b(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: ${e.message}`) } - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } if (opts._debug !== undefined) { diff --git a/packages/evm/src/precompiles/0c-bls12-g1msm.ts b/packages/evm/src/precompiles/0c-bls12-g1msm.ts index 96c86a9c7a8..c4e8e5169e3 100644 --- a/packages/evm/src/precompiles/0c-bls12-g1msm.ts +++ b/packages/evm/src/precompiles/0c-bls12-g1msm.ts @@ -1,8 +1,8 @@ import { bytesToHex } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import type { EVM } from '../evm.ts' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { BLS_GAS_DISCOUNT_PAIRS_G1, @@ -25,7 +25,10 @@ export async function precompile0c(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: Empty input`) } - return EvmErrorResult(new EVMError(EVMErrorMessages.BLS_12_381_INPUT_EMPTY), opts.gasLimit) // follow Geth's implementation + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INPUT_EMPTY), + opts.gasLimit, + ) // follow Geth's implementation } // TODO: Double-check respectively confirm that this order is really correct that the gas check @@ -43,14 +46,14 @@ export async function precompile0c(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: Invalid input length length=${inputData.length}`) } - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_INVALID_INPUT_LENGTH), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INVALID_INPUT_LENGTH), opts.gasLimit, ) } if (!moduloLengthCheck(opts, 160, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_INVALID_INPUT_LENGTH), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INVALID_INPUT_LENGTH), opts.gasLimit, ) } @@ -65,8 +68,8 @@ export async function precompile0c(opts: PrecompileInput): Promise { // zero bytes check const pairStart = 160 * k if (!leading16ZeroBytesCheck(opts, zeroByteRanges, pName, pairStart)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE), opts.gasLimit, ) } @@ -79,7 +82,7 @@ export async function precompile0c(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: ${e.message}`) } - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } if (opts._debug !== undefined) { diff --git a/packages/evm/src/precompiles/0d-bls12-g2add.ts b/packages/evm/src/precompiles/0d-bls12-g2add.ts index c279487c2bf..93946b595e0 100644 --- a/packages/evm/src/precompiles/0d-bls12-g2add.ts +++ b/packages/evm/src/precompiles/0d-bls12-g2add.ts @@ -1,8 +1,8 @@ import { bytesToHex } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import type { EVM } from '../evm.ts' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { leading16ZeroBytesCheck } from './bls12_381/index.ts' import { getPrecompileName } from './index.ts' @@ -22,8 +22,8 @@ export async function precompile0d(opts: PrecompileInput): Promise { } if (!equalityLengthCheck(opts, 512, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_INVALID_INPUT_LENGTH), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INVALID_INPUT_LENGTH), opts.gasLimit, ) } @@ -40,8 +40,8 @@ export async function precompile0d(opts: PrecompileInput): Promise { [448, 464], ] if (!leading16ZeroBytesCheck(opts, zeroByteRanges, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE), opts.gasLimit, ) } @@ -52,7 +52,7 @@ export async function precompile0d(opts: PrecompileInput): Promise { try { returnValue = bls.addG2(opts.data) } catch (e: any) { - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } if (opts._debug !== undefined) { diff --git a/packages/evm/src/precompiles/0e-bls12-g2msm.ts b/packages/evm/src/precompiles/0e-bls12-g2msm.ts index 10ba60ecd04..0b71ba4af76 100644 --- a/packages/evm/src/precompiles/0e-bls12-g2msm.ts +++ b/packages/evm/src/precompiles/0e-bls12-g2msm.ts @@ -1,8 +1,8 @@ import { bytesToHex } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import type { EVM } from '../evm.ts' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { BLS_GAS_DISCOUNT_PAIRS_G2, @@ -23,7 +23,10 @@ export async function precompile0e(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: Empty input`) } - return EvmErrorResult(new EVMError(EVMErrorMessages.BLS_12_381_INPUT_EMPTY), opts.gasLimit) // follow Geth's implementation + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INPUT_EMPTY), + opts.gasLimit, + ) // follow Geth's implementation } const numPairs = Math.floor(opts.data.length / 288) @@ -35,8 +38,8 @@ export async function precompile0e(opts: PrecompileInput): Promise { } if (!moduloLengthCheck(opts, 288, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_INVALID_INPUT_LENGTH), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INVALID_INPUT_LENGTH), opts.gasLimit, ) } @@ -53,8 +56,8 @@ export async function precompile0e(opts: PrecompileInput): Promise { // zero bytes check const pairStart = 288 * k if (!leading16ZeroBytesCheck(opts, zeroByteRanges, pName, pairStart)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE), opts.gasLimit, ) } @@ -67,7 +70,7 @@ export async function precompile0e(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: ${e.message}`) } - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } if (opts._debug !== undefined) { diff --git a/packages/evm/src/precompiles/0f-bls12-pairing.ts b/packages/evm/src/precompiles/0f-bls12-pairing.ts index 72b69450a4d..63e1124dfc8 100644 --- a/packages/evm/src/precompiles/0f-bls12-pairing.ts +++ b/packages/evm/src/precompiles/0f-bls12-pairing.ts @@ -1,8 +1,8 @@ import { bytesToHex } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import type { EVM } from '../evm.ts' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { leading16ZeroBytesCheck } from './bls12_381/index.ts' import { getPrecompileName } from './index.ts' @@ -22,7 +22,10 @@ export async function precompile0f(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: Empty input`) } - return EvmErrorResult(new EVMError(EVMErrorMessages.BLS_12_381_INPUT_EMPTY), opts.gasLimit) + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INPUT_EMPTY), + opts.gasLimit, + ) } const gasUsedPerPair = opts.common.param('bls12381PairingPerPairGas') ?? BigInt(0) @@ -31,8 +34,8 @@ export async function precompile0f(opts: PrecompileInput): Promise { // gas check. I will keep it there to not side-change the existing implementation, but we should // check (respectively Jochem can maybe have a word) if this is something intended or not if (!moduloLengthCheck(opts, 384, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_INVALID_INPUT_LENGTH), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INVALID_INPUT_LENGTH), opts.gasLimit, ) } @@ -55,8 +58,8 @@ export async function precompile0f(opts: PrecompileInput): Promise { // zero bytes check const pairStart = 384 * k if (!leading16ZeroBytesCheck(opts, zeroByteRanges, pName, pairStart)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE), opts.gasLimit, ) } @@ -69,7 +72,7 @@ export async function precompile0f(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: ${e.message}`) } - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } if (opts._debug !== undefined) { diff --git a/packages/evm/src/precompiles/10-bls12-map-fp-to-g1.ts b/packages/evm/src/precompiles/10-bls12-map-fp-to-g1.ts index ce816ae2ec1..42690e00076 100644 --- a/packages/evm/src/precompiles/10-bls12-map-fp-to-g1.ts +++ b/packages/evm/src/precompiles/10-bls12-map-fp-to-g1.ts @@ -1,8 +1,8 @@ import { bytesToHex } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import type { EVM } from '../evm.ts' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { leading16ZeroBytesCheck } from './bls12_381/index.ts' import { getPrecompileName } from './index.ts' @@ -22,8 +22,8 @@ export async function precompile10(opts: PrecompileInput): Promise { } if (!equalityLengthCheck(opts, 64, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_INVALID_INPUT_LENGTH), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INVALID_INPUT_LENGTH), opts.gasLimit, ) } @@ -31,8 +31,8 @@ export async function precompile10(opts: PrecompileInput): Promise { // check if some parts of input are zero bytes. const zeroByteRanges = [[0, 16]] if (!leading16ZeroBytesCheck(opts, zeroByteRanges, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE), opts.gasLimit, ) } @@ -44,19 +44,7 @@ export async function precompile10(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: ${e.message}`) } - // noble‑curves throws this for inputs that map to the point at infinity - if (e.message === 'bad point: ZERO') { - // return two zeroed field elements (x & y), each the same length as the input - const zeroPoint = new Uint8Array(opts.data.length * 2) - if (opts._debug !== undefined) { - opts._debug(`${pName} mapping to ZERO point, returning zero-filled output`) - } - return { - executionGasUsed: gasUsed, - returnValue: zeroPoint, - } - } - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } if (opts._debug !== undefined) { diff --git a/packages/evm/src/precompiles/11-bls12-map-fp2-to-g2.ts b/packages/evm/src/precompiles/11-bls12-map-fp2-to-g2.ts index 9ec579e92b0..8cb7aded655 100644 --- a/packages/evm/src/precompiles/11-bls12-map-fp2-to-g2.ts +++ b/packages/evm/src/precompiles/11-bls12-map-fp2-to-g2.ts @@ -1,8 +1,8 @@ import { bytesToHex } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../errors.ts' +import { EVMError } from '../errors.ts' import type { EVM } from '../evm.ts' -import { EvmErrorResult, OOGResult } from '../evm.ts' +import { EVMErrorResult, OOGResult } from '../evm.ts' import { leading16ZeroBytesCheck } from './bls12_381/index.ts' import { getPrecompileName } from './index.ts' @@ -22,8 +22,8 @@ export async function precompile11(opts: PrecompileInput): Promise { } if (!equalityLengthCheck(opts, 128, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_INVALID_INPUT_LENGTH), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_INVALID_INPUT_LENGTH), opts.gasLimit, ) } @@ -34,8 +34,8 @@ export async function precompile11(opts: PrecompileInput): Promise { [64, 80], ] if (!leading16ZeroBytesCheck(opts, zeroByteRanges, pName)) { - return EvmErrorResult( - new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE), + return EVMErrorResult( + new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE), opts.gasLimit, ) } @@ -47,7 +47,7 @@ export async function precompile11(opts: PrecompileInput): Promise { if (opts._debug !== undefined) { opts._debug(`${pName} failed: ${e.message}`) } - return EvmErrorResult(e, opts.gasLimit) + return EVMErrorResult(e, opts.gasLimit) } if (opts._debug !== undefined) { diff --git a/packages/evm/src/precompiles/bls12_381/mcl.ts b/packages/evm/src/precompiles/bls12_381/mcl.ts index 2f253dd1b1f..65ed1389352 100644 --- a/packages/evm/src/precompiles/bls12_381/mcl.ts +++ b/packages/evm/src/precompiles/bls12_381/mcl.ts @@ -7,7 +7,7 @@ import { unprefixedHexToBytes, } from '@ethereumjs/util' -import { EVMError, EVMErrorMessages } from '../../errors.ts' +import { EVMError } from '../../errors.ts' import { BLS_FIELD_MODULUS, @@ -53,12 +53,12 @@ function BLS12_381_ToG1Point(input: Uint8Array, mcl: any, verifyOrder = true): a mcl.verifyOrderG1(verifyOrder) if (verifyOrder && G1.isValidOrder() === false) { - throw new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE) + throw new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE) } // Check if these coordinates are actually on the curve. if (G1.isValid() === false) { - throw new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE) + throw new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE) } return G1 @@ -87,10 +87,10 @@ function BLS12_381_FromG1Point(input: any): Uint8Array { function BLS12_381_ToFp2Point(fpXCoordinate: Uint8Array, fpYCoordinate: Uint8Array, mcl: any): any { // check if the coordinates are in the field if (bytesToBigInt(fpXCoordinate) >= BLS_FIELD_MODULUS) { - throw new EVMError(EVMErrorMessages.BLS_12_381_FP_NOT_IN_FIELD) + throw new EVMError(EVMError.errorMessages.BLS_12_381_FP_NOT_IN_FIELD) } if (bytesToBigInt(fpYCoordinate) >= BLS_FIELD_MODULUS) { - throw new EVMError(EVMErrorMessages.BLS_12_381_FP_NOT_IN_FIELD) + throw new EVMError(EVMError.errorMessages.BLS_12_381_FP_NOT_IN_FIELD) } const fp_x = new mcl.Fp() @@ -146,11 +146,11 @@ function BLS12_381_ToG2Point(input: Uint8Array, mcl: any, verifyOrder = true): a mcl.verifyOrderG2(verifyOrder) if (verifyOrder && p.isValidOrder() === false) { - throw new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE) + throw new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE) } if (p.isValid() === false) { - throw new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE) + throw new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE) } return p @@ -190,7 +190,7 @@ function BLS12_381_ToFrPoint(input: Uint8Array, mcl: any): any { function BLS12_381_ToFpPoint(fpCoordinate: Uint8Array, mcl: any): any { // check if point is in field if (bytesToBigInt(fpCoordinate) >= BLS_FIELD_MODULUS) { - throw new EVMError(EVMErrorMessages.BLS_12_381_FP_NOT_IN_FIELD) + throw new EVMError(EVMError.errorMessages.BLS_12_381_FP_NOT_IN_FIELD) } const fp = new mcl.Fp() diff --git a/packages/evm/src/precompiles/bls12_381/noble.ts b/packages/evm/src/precompiles/bls12_381/noble.ts index 7be334127e0..b5cb37ba851 100644 --- a/packages/evm/src/precompiles/bls12_381/noble.ts +++ b/packages/evm/src/precompiles/bls12_381/noble.ts @@ -8,7 +8,7 @@ import { } from '@ethereumjs/util' import { bls12_381 } from '@noble/curves/bls12-381' -import { EVMError, EVMErrorMessages } from '../../errors.ts' +import { EVMError } from '../../errors.ts' import { BLS_FIELD_MODULUS, @@ -30,10 +30,10 @@ const G2_ZERO = bls12_381.G2.ProjectivePoint.ZERO function BLS12_381_ToFp2Point(fpXCoordinate: Uint8Array, fpYCoordinate: Uint8Array) { // check if the coordinates are in the field if (bytesToBigInt(fpXCoordinate) >= BLS_FIELD_MODULUS) { - throw new EVMError(EVMErrorMessages.BLS_12_381_FP_NOT_IN_FIELD) + throw new EVMError(EVMError.errorMessages.BLS_12_381_FP_NOT_IN_FIELD) } if (bytesToBigInt(fpYCoordinate) >= BLS_FIELD_MODULUS) { - throw new EVMError(EVMErrorMessages.BLS_12_381_FP_NOT_IN_FIELD) + throw new EVMError(EVMError.errorMessages.BLS_12_381_FP_NOT_IN_FIELD) } const fpBytes = concatBytes(fpXCoordinate.subarray(16), fpYCoordinate.subarray(16)) @@ -65,7 +65,7 @@ function BLS12_381_ToG1Point(input: Uint8Array, verifyOrder = true) { G1.assertValidity() } catch (e) { if (verifyOrder || (e as Error).message !== 'bad point: not in prime-order subgroup') - throw new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE) + throw new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE) } return G1 @@ -108,7 +108,7 @@ function BLS12_381_ToG2Point(input: Uint8Array, verifyOrder = true) { pG2.assertValidity() } catch (e) { if (verifyOrder || (e as Error).message !== 'bad point: not in prime-order subgroup') - throw new EVMError(EVMErrorMessages.BLS_12_381_POINT_NOT_ON_CURVE) + throw new EVMError(EVMError.errorMessages.BLS_12_381_POINT_NOT_ON_CURVE) } return pG2 @@ -159,7 +159,7 @@ function BLS12_381_ToFrPoint(input: Uint8Array): bigint { function BLS12_381_ToFpPoint(fpCoordinate: Uint8Array) { // check if point is in field if (bytesToBigInt(fpCoordinate) >= BLS_FIELD_MODULUS) { - throw new EVMError(EVMErrorMessages.BLS_12_381_FP_NOT_IN_FIELD) + throw new EVMError(EVMError.errorMessages.BLS_12_381_FP_NOT_IN_FIELD) } const FP = bls12_381.fields.Fp.fromBytes(fpCoordinate.slice(16)) return FP diff --git a/packages/evm/src/precompiles/bn254/noble.ts b/packages/evm/src/precompiles/bn254/noble.ts index 2a6a06a4579..73ffc5f4c04 100644 --- a/packages/evm/src/precompiles/bn254/noble.ts +++ b/packages/evm/src/precompiles/bn254/noble.ts @@ -9,7 +9,7 @@ import { } from '@ethereumjs/util' import { bn254 } from '@noble/curves/bn254' -import { EVMError, EVMErrorMessages } from '../../errors.ts' +import { EVMError } from '../../errors.ts' import type { AffinePoint } from '@noble/curves/abstract/weierstrass' import type { EVMBN254Interface } from '../../types.ts' @@ -64,10 +64,10 @@ function toFrPoint(input: Uint8Array): bigint { function toFp2Point(fpXCoordinate: Uint8Array, fpYCoordinate: Uint8Array) { if (bytesToBigInt(fpXCoordinate) >= bn254.fields.Fp2.ORDER) { - throw new EVMError(EVMErrorMessages.BN254_FP_NOT_IN_FIELD) + throw new EVMError(EVMError.errorMessages.BN254_FP_NOT_IN_FIELD) } if (bytesToBigInt(fpYCoordinate) >= bn254.fields.Fp2.ORDER) { - throw new EVMError(EVMErrorMessages.BN254_FP_NOT_IN_FIELD) + throw new EVMError(EVMError.errorMessages.BN254_FP_NOT_IN_FIELD) } const fpBytes = concatBytes(fpXCoordinate, fpYCoordinate) @@ -96,7 +96,7 @@ function toG2Point(input: Uint8Array) { for (const p of [p_x_1, p_x_2, p_y_1, p_y_2]) { const pB = bytesToBigInt(p) if (bn254.fields.Fp.create(pB) !== pB) { - throw new EVMError(EVMErrorMessages.BN254_FP_NOT_IN_FIELD) + throw new EVMError(EVMError.errorMessages.BN254_FP_NOT_IN_FIELD) } } diff --git a/packages/evm/src/stack.ts b/packages/evm/src/stack.ts index c4e50247a27..810e1ea0d91 100644 --- a/packages/evm/src/stack.ts +++ b/packages/evm/src/stack.ts @@ -1,4 +1,4 @@ -import { EVMError, EVMErrorMessages } from './errors.ts' +import { EVMError } from './errors.ts' /** * Implementation of the stack used in evm. @@ -23,7 +23,7 @@ export class Stack { push(value: bigint) { if (this._len >= this._maxHeight) { - throw new EVMError(EVMErrorMessages.STACK_OVERFLOW) + throw new EVMError(EVMError.errorMessages.STACK_OVERFLOW) } // Read current length, set `_store` to value, and then increase the length @@ -32,7 +32,7 @@ export class Stack { pop(): bigint { if (this._len < 1) { - throw new EVMError(EVMErrorMessages.STACK_UNDERFLOW) + throw new EVMError(EVMError.errorMessages.STACK_UNDERFLOW) } // Length is checked above, so pop shouldn't return undefined @@ -49,7 +49,7 @@ export class Stack { */ popN(num: number = 1): bigint[] { if (this._len < num) { - throw new EVMError(EVMErrorMessages.STACK_UNDERFLOW) + throw new EVMError(EVMError.errorMessages.STACK_UNDERFLOW) } if (num === 0) { @@ -79,7 +79,7 @@ export class Stack { for (let peek = 0; peek < num; peek++) { const index = --start if (index < 0) { - throw new EVMError(EVMErrorMessages.STACK_UNDERFLOW) + throw new EVMError(EVMError.errorMessages.STACK_UNDERFLOW) } peekArray[peek] = this._store[index] } @@ -92,7 +92,7 @@ export class Stack { */ swap(position: number) { if (this._len <= position) { - throw new EVMError(EVMErrorMessages.STACK_UNDERFLOW) + throw new EVMError(EVMError.errorMessages.STACK_UNDERFLOW) } const head = this._len - 1 @@ -115,12 +115,12 @@ export class Stack { dup(position: number) { const len = this._len if (len < position) { - throw new EVMError(EVMErrorMessages.STACK_UNDERFLOW) + throw new EVMError(EVMError.errorMessages.STACK_UNDERFLOW) } // Note: this code is borrowed from `push()` (avoids a call) if (len >= this._maxHeight) { - throw new EVMError(EVMErrorMessages.STACK_OVERFLOW) + throw new EVMError(EVMError.errorMessages.STACK_OVERFLOW) } const i = len - position @@ -139,7 +139,7 @@ export class Stack { // Stack underflow is not possible in EOF if (exchangeIndex1 < 0 || exchangeIndex2 < 0) { - throw new EVMError(EVMErrorMessages.STACK_UNDERFLOW) + throw new EVMError(EVMError.errorMessages.STACK_UNDERFLOW) } const cache = this._store[exchangeIndex2] diff --git a/packages/evm/test/eips/eip-5450.spec.ts b/packages/evm/test/eips/eip-5450.spec.ts index 7c498fd32dd..54216458d81 100644 --- a/packages/evm/test/eips/eip-5450.spec.ts +++ b/packages/evm/test/eips/eip-5450.spec.ts @@ -1,4 +1,4 @@ -import { hexToBytes } from '@ethereumjs/util' +import { type PrefixedHexString, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { default as testData } from '../../../ethereum-tests/EOFTests/EIP5450/validInvalid.json' with { @@ -22,7 +22,7 @@ describe('EIP 5450 tests', async () => { for (const key in testData.validInvalid.vectors) { it(`Container validation tests ${key}`, () => { const input = testData.validInvalid.vectors[key as keyof typeof testData.validInvalid.vectors] - const code = hexToBytes(input.code) + const code = hexToBytes(input.code as PrefixedHexString) const expected = input.results.Osaka.result diff --git a/packages/evm/test/eips/eip-5656.spec.ts b/packages/evm/test/eips/eip-5656.spec.ts index b07247ff5dd..d26950d1b5c 100644 --- a/packages/evm/test/eips/eip-5656.spec.ts +++ b/packages/evm/test/eips/eip-5656.spec.ts @@ -62,7 +62,7 @@ describe('should test mcopy', () => { for (const situation of situations) { it('should produce correct output', async () => { // create bytecode - let bytecode: PrefixedHexString = '0x' + let bytecode = '0x' // prepare the memory for (let i = 0; i < situation.pre.length / 2; i++) { const start = i * 2 diff --git a/packages/evm/test/runCall.spec.ts b/packages/evm/test/runCall.spec.ts index 2c4e9953e6d..bcb26d3e3aa 100644 --- a/packages/evm/test/runCall.spec.ts +++ b/packages/evm/test/runCall.spec.ts @@ -17,7 +17,7 @@ import { import { keccak256 } from 'ethereum-cryptography/keccak.js' import { assert, describe, it } from 'vitest' -import { EVMErrorMessages } from '../src/errors.ts' +import { EVMError } from '../src/errors.ts' import { defaultBlock } from '../src/evm.ts' import { createEVM } from '../src/index.ts' @@ -273,7 +273,7 @@ describe('RunCall tests', () => { assert.equal(result.execResult.gasRefund, BigInt(0), 'gas refund correct') assert.equal( result.execResult.exceptionError?.error, - EVMErrorMessages.OUT_OF_GAS, + EVMError.errorMessages.OUT_OF_GAS, 'call went out of gas', ) }) @@ -541,7 +541,7 @@ describe('RunCall tests', () => { const result = await evm.runCall(runCallArgs) assert.equal( result.execResult.exceptionError?.error, - EVMErrorMessages.CODESIZE_EXCEEDS_MAXIMUM, + EVMError.errorMessages.CODESIZE_EXCEEDS_MAXIMUM, 'reported error is correct', ) }) @@ -652,7 +652,10 @@ describe('RunCall tests', () => { } const res = await evm.runCall(runCallArgs) - assert.equal(res.execResult.exceptionError?.error, EVMErrorMessages.CODESIZE_EXCEEDS_MAXIMUM) + assert.equal( + res.execResult.exceptionError?.error, + EVMError.errorMessages.CODESIZE_EXCEEDS_MAXIMUM, + ) // Create a contract which goes OOG when creating const runCallArgs2 = { @@ -661,7 +664,7 @@ describe('RunCall tests', () => { } const res2 = await evm.runCall(runCallArgs2) - assert.equal(res2.execResult.exceptionError?.error, EVMErrorMessages.OUT_OF_GAS) + assert.equal(res2.execResult.exceptionError?.error, EVMError.errorMessages.OUT_OF_GAS) }) it('ensure code deposit errors are logged correctly (Frontier)', async () => { @@ -675,7 +678,7 @@ describe('RunCall tests', () => { } const res = await evm.runCall(runCallArgs) - assert.equal(res.execResult.exceptionError?.error, EVMErrorMessages.CODESTORE_OUT_OF_GAS) + assert.equal(res.execResult.exceptionError?.error, EVMError.errorMessages.CODESTORE_OUT_OF_GAS) // Create a contract which goes OOG when creating const runCallArgs2 = { @@ -684,7 +687,7 @@ describe('RunCall tests', () => { } const res2 = await evm.runCall(runCallArgs2) - assert.equal(res2.execResult.exceptionError?.error, EVMErrorMessages.OUT_OF_GAS) + assert.equal(res2.execResult.exceptionError?.error, EVMError.errorMessages.OUT_OF_GAS) }) it('ensure call and callcode handle gas stipend correctly', async () => { diff --git a/packages/evm/test/runCode.spec.ts b/packages/evm/test/runCode.spec.ts index 34782e2ab8d..fb9587798ca 100644 --- a/packages/evm/test/runCode.spec.ts +++ b/packages/evm/test/runCode.spec.ts @@ -1,6 +1,7 @@ import { Account, createAddressFromString, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' +import { EVMErrorTypeString } from '../src/errors.ts' import { createEVM } from '../src/index.ts' const PUSH1 = '60' @@ -56,7 +57,7 @@ describe('VM.runCode: initial program counter', () => { }) describe('VM.runCode: interpreter', () => { - it('should return a EvmError as an exceptionError on the result', async () => { + it('should return a EVMError as an exceptionError on the result', async () => { const evm = await createEVM() const INVALID_opcode = 'fe' @@ -71,11 +72,11 @@ describe('VM.runCode: interpreter', () => { } catch { assert.fail('should not throw error') } - assert.equal(result?.exceptionError?.errorType, 'EVMError') + assert.equal(result?.exceptionError?.errorType, EVMErrorTypeString) assert.isTrue(result?.exceptionError?.error.includes('invalid opcode')) }) - it('should throw on non-EvmError', async () => { + it('should throw on non-EVMError', async () => { const evm = await createEVM() // NOTE: due to now throwing on `getStorage` if account does not exist // this now means that if `runCode` is called and the address it runs on (default: zero address) diff --git a/packages/evm/test/stack.spec.ts b/packages/evm/test/stack.spec.ts index 79c5ae45a00..fd8b725a4ca 100644 --- a/packages/evm/test/stack.spec.ts +++ b/packages/evm/test/stack.spec.ts @@ -161,22 +161,19 @@ describe('Stack', () => { const evm = await createEVM() for (let pushN = 0x60; pushN <= 0x7f; pushN++) { - // PUSHx 01 - const code = `0x${pushN.toString(16)}01` - // PUSH 0x03 JUMP JUMPDEST < PUSHx 01 > - const codeWithJumps = `0x6003565B${pushN.toString(16)}01` - const expectedStack = new Stack(1024) expectedStack.push(bytesToBigInt(setLengthRight(new Uint8Array([0x01]), pushN - 0x5f))) const resWithoutJumps = await evm.runCall({ - data: hexToBytes(code), + // PUSHx 01 + data: hexToBytes(`0x${pushN.toString(16)}01`), }) const executionStack = resWithoutJumps.execResult.runState?.stack assert.deepEqual(executionStack, expectedStack, 'code without jumps ok') const resWithJumps = await evm.runCall({ - data: hexToBytes(codeWithJumps), + // PUSH 0x03 JUMP JUMPDEST < PUSHx 01 > + data: hexToBytes(`0x6003565B${pushN.toString(16)}01`), }) const executionStackWithJumps = resWithJumps.execResult.runState?.stack assert.deepEqual(executionStackWithJumps, expectedStack, 'code with jumps ok') diff --git a/packages/evm/test/verkle.spec.ts b/packages/evm/test/verkle.spec.ts index 963ace154dd..f2108c9e387 100644 --- a/packages/evm/test/verkle.spec.ts +++ b/packages/evm/test/verkle.spec.ts @@ -1,6 +1,7 @@ import { Common, Hardfork, Mainnet } from '@ethereumjs/common' import { StatefulVerkleStateManager } from '@ethereumjs/statemanager' import { + type PrefixedHexString, bigIntToBytes, bytesToHex, createAccount, @@ -114,7 +115,7 @@ describe('verkle tests', () => { }) describe('generate an execution witness', () => { it('should generate the correct execution witness from a prestate and changes', async () => { - const preStateVKT = { + const preStateVKT: Record = { '0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d00': '0x00000000000000000000000000000000000000000000003635c9adc5dea00000', '0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d01': @@ -152,7 +153,7 @@ describe('generate an execution witness', () => { const trie = await createVerkleTree() // Setup prestate for (const [key, value] of Object.entries(preStateVKT)) { - const stem = hexToBytes(key).slice(0, 31) + const stem = hexToBytes(key as PrefixedHexString).slice(0, 31) const suffix = parseInt(key.slice(64), 16) await trie.put(stem, [suffix], [hexToBytes(value)]) } @@ -167,7 +168,7 @@ describe('generate an execution witness', () => { }) // Run tx await evm.runCall({ - code: hexToBytes(tx.input), + code: hexToBytes(tx.input as PrefixedHexString), caller: createAddressFromString(tx.sender), to: createAddressFromString(tx.to), gasLimit: BigInt(tx.gas), diff --git a/packages/genesis/README.md b/packages/genesis/README.md index 58cdefc7bcd..c4590acbaa1 100644 --- a/packages/genesis/README.md +++ b/packages/genesis/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/genesis +# @ethereumjs/genesis `v10` [![NPM Package][genesis-npm-badge]][genesis-npm-link] [![GitHub Issues][genesis-issues-badge]][genesis-issues-link] @@ -16,6 +16,15 @@ This module provides access to Ethereum genesis state for the following networks - Holesky - Hoodi +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [EthereumJS](#ethereumjs) +- [License](#license) + +## Installation + The package can be install with: ```shell diff --git a/packages/mpt/README.md b/packages/mpt/README.md index 78398ac16ad..86fed2fbe91 100644 --- a/packages/mpt/README.md +++ b/packages/mpt/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/mpt +# @ethereumjs/mpt `v10` [![NPM Package][mpt-npm-badge]][mpt-npm-link] [![GitHub Issues][mpt-issues-badge]][mpt-issues-link] @@ -11,6 +11,22 @@ > The modified Merkle Patricia tree (mpt) provides a persistent data structure to map between arbitrary-length binary data (byte arrays). It is defined in terms of a mutable data structure to map between 256-bit binary fragments and arbitrary-length binary data. The core of the mpt, and its sole requirement in terms of the protocol specification, is to provide a single 32-byte value that identifies a given set of key-value pairs. +## Table of Contents + +- [Installation](#installation) +- [Getting Started](#getting-started) +- [Merkle Patricia Tries](#merkle-patricia-tries) +- [Proofs](#proofs) +- [Examples](#examples) +- [Browser](#browser) +- [API](#api) +- [Benchmarking](#benchmarking) +- [Debugging](#debugging) +- [References](#references) +- [EthereumJS](#ethereumjs) +- [License](#license) + + ## Installation To obtain the latest version, simply require the project using `npm`: @@ -19,7 +35,7 @@ To obtain the latest version, simply require the project using `npm`: npm install @ethereumjs/mpt ``` -## Usage +## Getting Started This class implements the basic [Modified Merkle Patricia Trie](https://ethereum.org/en/developers/docs/data-structures-and-encoding/patricia-merkle-mpt/) in the `Trie` base class, which you can use with the `useKeyHashing` option set to `true` to create a Merkle Patricia Trie which stores values under the `keccak256` hash of its keys (this is the Trie flavor which is used in Ethereum production systems). @@ -158,9 +174,9 @@ async function main() { void main() ``` -### `MerklePatriciaTrie` Configuration Options +## Merkle Patricia Tries -#### Database Options +### Database Options The `DB` opt in the `MPTOpts` allows you to use any database that conforms to the `DB` interface to store the trie data in. We provide several [examples](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/examples) for database implementations. The [level.js](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/examples/level.js) example is used in the `ethereumjs client` while [lmdb.js](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/examples/lmdb.js) is an alternative implementation that uses the popular [LMDB](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database) as its underlying database. @@ -168,7 +184,7 @@ If no `db` option is provided, an in-memory database powered by [a Javascript Ma If you want to use an alternative database, you can integrate your own by writing a DB wrapper that conforms to the [`DB` interface](https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/util/src/db.ts) (in `@ethereumjs/util`). The `DB` interface defines the methods `get`, `put`, `del`, `batch` and `copy` that a concrete implementation of the `DB` interface will need to implement. -##### LevelDB +#### LevelDB As an example, to leverage `LevelDB` for all operations then you should create a file with the [following implementation from our recipes](./recipes//level.ts) in your project. Then instantiate your DB and trie as below: @@ -182,11 +198,11 @@ async function main() { console.log(trie.database().db) // LevelDB { ... ``` -#### Node Deletion (Pruning) +### Node Deletion (Pruning) By default, the deletion of trie nodes from the underlying database does not occur in order to avoid corrupting older trie states (as of `v4.2.0`). Should you only wish to work with the latest state of a trie, you can switch to a delete behavior (for example, if you wish to save disk space) by using the `useNodePruning` constructor option (see related release notes in the changelog for further details). -#### Root Persistence +### Root Persistence You can enable persistence by setting the `useRootPersistence` option to `true` when constructing a trie through the `createMPT` function. As such, this value is preserved when creating copies of the trie and is incapable of being modified once a trie is instantiated. diff --git a/packages/mpt/src/util/encoding.ts b/packages/mpt/src/util/encoding.ts index a18443a0301..6df59bbbfe0 100644 --- a/packages/mpt/src/util/encoding.ts +++ b/packages/mpt/src/util/encoding.ts @@ -1,4 +1,4 @@ -import { concatBytes, hexToBytes, toBytes, unprefixedHexToBytes } from '@ethereumjs/util' +import { concatBytes, hexToBytes, unprefixedHexToBytes } from '@ethereumjs/util' import { nibblesTypeToPackedBytes } from './nibbles.ts' @@ -129,12 +129,11 @@ export const nibbleTypeToByteType = (arr: Nibbles): Uint8Array => { * @returns Nibble typed nibble array */ export const byteTypeToNibbleType = (key: Uint8Array): Nibbles => { - const bKey = toBytes(key) const nibbles = [] as Nibbles - for (let i = 0; i < bKey.length; i++) { + for (let i = 0; i < key.length; i++) { const q = i - nibbles[q] = bKey[i] % 16 + nibbles[q] = key[i] % 16 } return nibbles diff --git a/packages/mpt/src/util/nibbles.ts b/packages/mpt/src/util/nibbles.ts index 980edfa2b68..1a333a06635 100644 --- a/packages/mpt/src/util/nibbles.ts +++ b/packages/mpt/src/util/nibbles.ts @@ -1,5 +1,3 @@ -import { toBytes } from '@ethereumjs/util' - import type { Nibbles } from '../types.ts' /** @@ -8,14 +6,13 @@ import type { Nibbles } from '../types.ts' * @param key */ export function bytesToNibbles(key: Uint8Array): Nibbles { - const bKey = toBytes(key) const nibbles = [] as Nibbles - for (let i = 0; i < bKey.length; i++) { + for (let i = 0; i < key.length; i++) { let q = i * 2 - nibbles[q] = bKey[i] >> 4 + nibbles[q] = key[i] >> 4 ++q - nibbles[q] = bKey[i] % 16 + nibbles[q] = key[i] % 16 } return nibbles diff --git a/packages/mpt/test/proof/range.spec.ts b/packages/mpt/test/proof/range.spec.ts index 5fce15fafa2..0da1f447ea8 100644 --- a/packages/mpt/test/proof/range.spec.ts +++ b/packages/mpt/test/proof/range.spec.ts @@ -3,9 +3,9 @@ import { compareBytes, concatBytes, hexToBytes, + intToBytes, randomBytes, setLengthLeft, - toBytes, } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -28,8 +28,9 @@ async function randomTrie(db: DB, addKey: boolean = true) { if (addKey) { for (let i = 0; i < 100; i++) { - const key = setLengthLeft(toBytes(i), 32) - const val = toBytes(i) + const indexBytes = intToBytes(i) + const key = setLengthLeft(indexBytes, 32) + const val = indexBytes await trie.put(key, val) entries.push([key, val]) } @@ -62,7 +63,7 @@ function getRandomIntInclusive(min: number, max: number): number { function decreaseKey(key: Uint8Array) { for (let i = key.length - 1; i >= 0; i--) { if (key[i] > 0) { - return concatBytes(key.slice(0, i), toBytes(key[i] - 1), key.slice(i + 1)) + return concatBytes(key.slice(0, i), intToBytes(key[i] - 1), key.slice(i + 1)) } } } @@ -70,7 +71,7 @@ function decreaseKey(key: Uint8Array) { function increaseKey(key: Uint8Array) { for (let i = key.length - 1; i >= 0; i--) { if (key[i] < 255) { - return concatBytes(key.slice(0, i), toBytes(key[i] + 1), key.slice(i + 1)) + return concatBytes(key.slice(0, i), intToBytes(key[i] + 1), key.slice(i + 1)) } } } @@ -323,8 +324,9 @@ describe('simple merkle range proofs generation and verification', () => { const trie = new MerklePatriciaTrie() const entries: [Uint8Array, Uint8Array][] = [] for (let i = 0; i < 10; i++) { - const key = setLengthLeft(toBytes(i), 32) - const val = toBytes(i) + const indexBytes = intToBytes(i) + const key = setLengthLeft(indexBytes, 32) + const val = indexBytes await trie.put(key, val) entries.push([key, val]) } diff --git a/packages/mpt/test/trie/trie.spec.ts b/packages/mpt/test/trie/trie.spec.ts index cb6320021db..046b44c4e8e 100644 --- a/packages/mpt/test/trie/trie.spec.ts +++ b/packages/mpt/test/trie/trie.spec.ts @@ -4,6 +4,7 @@ import { BIGINT_2, KECCAK256_RLP, MapDB, + type PrefixedHexString, bigIntToBytes, bytesToBigInt, bytesToHex, @@ -277,10 +278,10 @@ describe('keyHashingFunction', async () => { describe('getValueMap', async () => { const trie = await createMPT({}) - const entries: [Uint8Array, string][] = [ - [bigIntToBytes(0x01n), '0x' + '0a'.repeat(32)], - [bigIntToBytes(0x02n), '0x' + '0b'.repeat(32)], - [bigIntToBytes(0x03n), '0x' + '0c'.repeat(32)], + const entries: [Uint8Array, PrefixedHexString][] = [ + [bigIntToBytes(0x01n), `0x${'0a'.repeat(32)}`], + [bigIntToBytes(0x02n), `0x${'0b'.repeat(32)}`], + [bigIntToBytes(0x03n), `0x${'0c'.repeat(32)}`], ] for (const entry of entries) { await trie.put(entry[0], hexToBytes(entry[1])) @@ -348,7 +349,7 @@ describe('getValueMap', async () => { const KEYS = 1000 const KEY_LEN = 3 // Keys are of equal length const gotKeys = new Set() - const entries: [Uint8Array, string][] = [] + const entries: [Uint8Array, PrefixedHexString][] = [] for (let i = 0; i < KEYS; i++) { const key = randomBytes(KEY_LEN) const keyBigInt = bytesToBigInt(key) diff --git a/packages/rlp/README.md b/packages/rlp/README.md index 9913f4152da..bfffacd408f 100644 --- a/packages/rlp/README.md +++ b/packages/rlp/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/rlp +# @ethereumjs/rlp `v10` [![NPM Package][rlp-npm-badge]][rlp-npm-link] [![GitHub Issues][rlp-issues-badge]][rlp-issues-link] @@ -9,6 +9,16 @@ | [Recursive Length Prefix](https://ethereum.org/en/developers/docs/data-structures-and-encoding/rlp) encoding for Node.js and the browser. | | ----------------------------------------------------------------------------------------------------------------------------------------- | +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [Browser](#browser) +- [API](#api) +- [CLI](#cli) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Installation To obtain the latest version, simply require the project using `npm`: diff --git a/packages/statemanager/README.md b/packages/statemanager/README.md index a796375904a..f9f2a296fcd 100644 --- a/packages/statemanager/README.md +++ b/packages/statemanager/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/statemanager +# @ethereumjs/statemanager `v10` [![NPM Package][statemanager-npm-badge]][statemanager-npm-link] [![GitHub Issues][statemanager-issues-badge]][statemanager-issues-link] @@ -9,6 +9,21 @@ | Library to provide high level access to Ethereum State | | ------------------------------------------------------ | +## Table of Contents + +- [Installation](#installation) +- [Getting Started](#getting-started) +- [MerkleStateManager](#merklestatemanager) +- [SimpleStateManager](#simplestatemanager) +- [RPCStateManager](#rpcstatemanager) +- [Verkle (experimental)](#verkle-state-managers-experimental) +- [Browser](#browser) +- [API](#api) +- [Development](#development) +- [EthereumJS](#ethereumjs) +- [License](#license) + + ## Installation To obtain the latest version, simply require the project using `npm`: @@ -17,9 +32,9 @@ To obtain the latest version, simply require the project using `npm`: npm install @ethereumjs/statemanager ``` -## Usage +## Getting Started -### Introduction +### Overview The `StateManager` provides high-level access and manipulation methods to and for the Ethereum state, thinking in terms of accounts or contract code rather then the storage operations of the underlying data structure (e.g. a [Trie](../trie/)). @@ -33,9 +48,13 @@ This library includes several different implementations that all implement the ` It also includes a checkpoint/revert/commit mechanism to either persist or revert state changes and provides a sophisticated caching mechanism under the hood to reduce the need reading state accesses from disk. -### `MerkleStateManager` +### WASM Crypto Support + +This library by default uses JavaScript implementations for the basic standard crypto primitives like hashing for underlying trie keys. See `@ethereumjs/common` [README](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/common) for instructions on how to replace with e.g. a more performant WASM implementation by using a shared `common` instance. + +## `MerkleStateManager` -#### Usage example +### Usage example ```ts // ./examples/basicUsage.ts @@ -62,7 +81,7 @@ const main = async () => { void main() ``` -#### Account, Storage and Code Caches +### Account, Storage and Code Caches Starting with the v2 release and complemented by the v2.1 release the StateManager comes with a significantly more elaborate caching mechanism for account, storage and code caches. @@ -72,34 +91,7 @@ Caches now "survive" a flush operation and especially long-lived usage scenarios Have a look at the extended `CacheOptions` on how to use and leverage the new cache system. -### `SimpleStateManager` - -The `SimpleStateManager` is a dependency-minimized simple state manager implementation. While this state manager implementation lacks the implementations of some non-core functionality as well as proof related logic (e.g. `setStateRoot()`) it is suitable for a lot use cases where things like sophisticated caching or state root handling is not needed. - -This state manager can be instantiated and used as follows: - -```ts -// ./examples/simple.ts - -import { Account, createAddressFromPrivateKey, randomBytes } from '@ethereumjs/util' - -import { SimpleStateManager } from '../src/index.ts' - -const main = async () => { - const sm = new SimpleStateManager() - const address = createAddressFromPrivateKey(randomBytes(32)) - const account = new Account(0n, 0xfffffn) - await sm.putAccount(address, account) - console.log(await sm.getAccount(address)) -} - -void main() - -``` - -### `MerkleStateManager` -> Proofs - -#### Instantiating from a Proof +### Instantiating from Proofs The `MerkleStateManager` has a standalone constructor function `fromMerkleStateProof` that accepts one or more [EIP-1186](https://eips.ethereum.org/EIPS/eip-1186) [proofs](./src/stateManager.ts) and will instantiate a `MerkleStateManager` with a partial trie containing the state provided by the proof(s). Be aware that this constructor accepts the `StateManagerOpts` dictionary as a third parameter (i.e. `fromMerkleStateProof(proof, safe, opts)`). @@ -168,7 +160,32 @@ const main = async () => { void main() ``` -### `RPCStateManager` +## `SimpleStateManager` + +The `SimpleStateManager` is a dependency-minimized simple state manager implementation. While this state manager implementation lacks the implementations of some non-core functionality as well as proof related logic (e.g. `setStateRoot()`) it is suitable for a lot use cases where things like sophisticated caching or state root handling is not needed. + +This state manager can be instantiated and used as follows: + +```ts +// ./examples/simple.ts + +import { Account, createAddressFromPrivateKey, randomBytes } from '@ethereumjs/util' + +import { SimpleStateManager } from '../src/index.ts' + +const main = async () => { + const sm = new SimpleStateManager() + const address = createAddressFromPrivateKey(randomBytes(32)) + const account = new Account(0n, 0xfffffn) + await sm.putAccount(address, account) + console.log(await sm.getAccount(address)) +} + +void main() + +``` + +## `RPCStateManager` The `RPCStateManager` can be be used with any JSON-RPC provider that supports the `eth` namespace. Instantiate the `VM` and pass in an `RPCStateManager` to run transactions against accounts sourced from the provider or to run blocks pulled from the provider at any specified block height. @@ -196,9 +213,9 @@ void main() **Note:** Usage of this StateManager can cause a heavy load regarding state request API calls, so be careful (or at least: aware) if used in combination with a JSON-RPC provider connecting to a third-party API service like Infura! -#### Points on `RPCStateManager` usage +### Points on `RPCStateManager` usage -##### Instantiating the EVM +#### Instantiating the EVM In order to have an EVM instance that supports the BLOCKHASH opcode (which requires access to block history), you must instantiate both the `RPCStateManager` and the `RpcBlockChain` and use that when initializing your EVM instance as below: @@ -224,37 +241,33 @@ void main() Note: Failing to provide the `RPCBlockChain` instance when instantiating the EVM means that the `BLOCKHASH` opcode will fail to work correctly during EVM execution. -##### Provider selection +#### Provider selection - The provider you select must support the `eth_getProof`, `eth_getCode`, and `eth_getStorageAt` RPC methods. - Not all providers support retrieving state from all block heights so refer to your provider's documentation. Trying to use a block height not supported by your provider (e.g. any block older than the last 256 for CloudFlare) will result in RPC errors when using the state manager. -##### Block Tag selection +#### Block Tag selection - You have to pass a block number or `earliest` in the constructor that specifies the block height you want to pull state from. - The `latest`/`pending` values supported by the Ethereum JSON-RPC are not supported as longer running scripts run the risk of state values changing as blocks are mined while your script is running. - If using a very recent block as your block tag, be aware that reorgs could occur and potentially alter the state you are interacting with. - If you want to rerun transactions from block X or run block X, you need to specify the block tag as X-1 in the state manager constructor to ensure you are pulling the state values at the point in time the transactions or block was run. -##### Potential gotchas +#### Potential gotchas - The RPC State Manager cannot compute valid state roots when running blocks as it does not have access to the entire Ethereum state trie so can not compute correct state roots, either for the account trie or for storage tries. - If you are replaying mainnet transactions and an account or account storage is touched by multiple transactions in a block, you must replay those transactions in order (with regard to their position in that block) or calculated gas will likely be different than actual gas consumed. -##### Further reference +#### Further reference Refer to [this test script](./test/rpcStateManager.spec.ts) for complete examples of running transactions and blocks in the `vm` with data sourced from a provider. -### `StatefulVerkleStateManager`/`StatelessVerkleStateManager` (experimental) +## Verkle (experimental) There are two new verkle related state managers integrated into the code base. These state managers are very experimental and meant to be used for connecting to early [Verkle Tree](https://eips.ethereum.org/EIPS/eip-6800) test networks (Kaustinen). These state managers are not yet sufficiently tested and APIs are not yet stable and it therefore should not be used in production. See [PRs around Verkle](https://github.com/search?q=repo%3Aethereumjs%2Fethereumjs-monorepo+verkle&type=pullrequests) in our monorepo for an entrypoint if you are interested in our current Verkle related work. -### WASM Crypto Support - -This library by default uses JavaScript implementations for the basic standard crypto primitives like hashing for underlying trie keys. See `@ethereumjs/common` [README](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/common) for instructions on how to replace with e.g. a more performant WASM implementation by using a shared `common` instance. - ## Browser We provide hybrid ESM/CJS builds for all our libraries. With the v10 breaking release round from Spring 2025, all libraries are "pure-JS" by default and we have eliminated all hard-wired WASM code. Additionally we have substantially lowered the bundle sizes, reduced the number of dependencies, and cut out all usages of Node.js-specific primitives (like the Node.js event emitter). diff --git a/packages/statemanager/src/statefulBinaryTreeStateManager.ts b/packages/statemanager/src/statefulBinaryTreeStateManager.ts index 163ada1a61e..700377ea9d1 100644 --- a/packages/statemanager/src/statefulBinaryTreeStateManager.ts +++ b/packages/statemanager/src/statefulBinaryTreeStateManager.ts @@ -741,9 +741,11 @@ export class StatefulBinaryTreeStateManager implements StateManagerInterface { async generateCanonicalGenesis(genesisState: GenesisState) { await this._tree.createRootNode() await this.checkpoint() - for (const addressStr of Object.keys(genesisState)) { + for (const addressStr of Object.keys(genesisState) as PrefixedHexString[]) { const addrState = genesisState[addressStr] - let nonce, balance, code + let nonce: PrefixedHexString | undefined + let balance: PrefixedHexString | bigint + let code: PrefixedHexString | undefined let storage: StoragePair[] | undefined = [] if (Array.isArray(addrState)) { ;[balance, code, storage, nonce] = addrState @@ -754,7 +756,7 @@ export class StatefulBinaryTreeStateManager implements StateManagerInterface { } const address = createAddressFromString(addressStr) await this.putAccount(address, new Account()) - const codeBuf = hexToBytes((code as string) ?? '0x') + const codeBuf = hexToBytes(code ?? '0x') const codeHash = this.keccakFunction(codeBuf) @@ -774,8 +776,8 @@ export class StatefulBinaryTreeStateManager implements StateManagerInterface { // Put account data const account = createPartialAccount({ - nonce: nonce as PrefixedHexString, - balance: balance as PrefixedHexString, + nonce, + balance, codeHash, codeSize: codeBuf.byteLength, }) diff --git a/packages/statemanager/src/statefulVerkleStateManager.ts b/packages/statemanager/src/statefulVerkleStateManager.ts index 595eb126ea6..cc3d8e2fb7b 100644 --- a/packages/statemanager/src/statefulVerkleStateManager.ts +++ b/packages/statemanager/src/statefulVerkleStateManager.ts @@ -745,9 +745,11 @@ export class StatefulVerkleStateManager implements StateManagerInterface { async generateCanonicalGenesis(genesisState: GenesisState) { await this._trie.createRootNode() await this.checkpoint() - for (const addressStr of Object.keys(genesisState)) { + for (const addressStr of Object.keys(genesisState) as PrefixedHexString[]) { const addrState = genesisState[addressStr] - let nonce, balance, code + let nonce: PrefixedHexString | undefined + let balance: PrefixedHexString | bigint + let code: PrefixedHexString | undefined let storage: StoragePair[] | undefined = [] if (Array.isArray(addrState)) { ;[balance, code, storage, nonce] = addrState @@ -758,7 +760,7 @@ export class StatefulVerkleStateManager implements StateManagerInterface { } const address = createAddressFromString(addressStr) await this.putAccount(address, new Account()) - const codeBuf = hexToBytes((code as string) ?? '0x') + const codeBuf = hexToBytes(code ?? '0x') if (this.common.customCrypto?.keccak256 === undefined) { throw Error('keccak256 required') } @@ -780,8 +782,8 @@ export class StatefulVerkleStateManager implements StateManagerInterface { // Put account data const account = createPartialAccount({ - nonce: nonce as PrefixedHexString, - balance: balance as PrefixedHexString, + nonce, + balance, codeHash, codeSize: codeBuf.byteLength, }) diff --git a/packages/statemanager/src/statelessVerkleStateManager.ts b/packages/statemanager/src/statelessVerkleStateManager.ts index 6c148c68658..69a47f4e4e1 100644 --- a/packages/statemanager/src/statelessVerkleStateManager.ts +++ b/packages/statemanager/src/statelessVerkleStateManager.ts @@ -21,7 +21,6 @@ import { setLengthLeft, setLengthRight, short, - toBytes, } from '@ethereumjs/util' import debugDefault from 'debug' import { keccak256 } from 'ethereum-cryptography/keccak.js' @@ -351,7 +350,8 @@ export class StatelessVerkleStateManager implements StateManagerInterface { BigInt(bytesToHex(key)), this.verkleCrypto, ) - const storageValue = toBytes(this._state[bytesToHex(storageKey)]) + const rawStorageValue = this._state[bytesToHex(storageKey)] + const storageValue = rawStorageValue === null ? new Uint8Array() : hexToBytes(rawStorageValue) this._caches?.storage?.put(address, key, storageValue ?? hexToBytes('0x80')) diff --git a/packages/testdata/src/blocks/index.ts b/packages/testdata/src/blocks/index.ts index 9fbc60b8acb..e286aaa6f5b 100644 --- a/packages/testdata/src/blocks/index.ts +++ b/packages/testdata/src/blocks/index.ts @@ -1,5 +1,5 @@ export * from './mainnetBlocks.ts' export * from './goerliBlocks.ts' -export * from './preLondonTestDataBlocks1.ts' -export * from './preLondonTestDataBlocks2.ts' +export * from './preLondonTestDataBlocks1RLP.ts' +export * from './preLondonTestDataBlocks2RLP.ts' export * from './verkleKaustinen6Block72.ts' diff --git a/packages/testdata/src/blocks/preLondonTestDataBlocks1.ts b/packages/testdata/src/blocks/preLondonTestDataBlocks1.ts deleted file mode 100644 index fbd6174a39d..00000000000 --- a/packages/testdata/src/blocks/preLondonTestDataBlocks1.ts +++ /dev/null @@ -1,162 +0,0 @@ -export const preLondonTestDataBlocks1 = { - blocks: [ - { - blockHeader: { - bloom: - '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - coinbase: '0x8888f1f195afa192cfee860698584c030f4c9db1', - difficulty: '0x020000', - extraData: '0x', - gasLimit: '0x023ec6', - gasUsed: '0x021536', - hash: '0xf53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3', - mixHash: '0x29f07836e4e59229b3a065913afc27702642c683bba689910b2b2fd45db310d3', - nonce: '0x8957e6d004a31802', - number: '0x01', - parentHash: '0xce1f26f798dd03c8782d63b3e42e79a64eaea5694ea686ac5d7ce3df5171d1ae', - receiptTrie: '0x5c5b4fc43c2d45787f54e1ae7d27afdb4ad16dfc567c5692070d5c4556e0b1d7', - stateRoot: '0xa65c2364cd0f1542d761823dc0109c6b072f14c20459598c5455c274601438f4', - timestamp: '0x56851097', - transactionsTrie: '0x70616ebd7ad2ed6fb7860cf7e9df00163842351c38a87cac2c1cb193895035a2', - uncleHash: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', - }, - rlp: '0xf904a8f901faa0ce1f26f798dd03c8782d63b3e42e79a64eaea5694ea686ac5d7ce3df5171d1aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a65c2364cd0f1542d761823dc0109c6b072f14c20459598c5455c274601438f4a070616ebd7ad2ed6fb7860cf7e9df00163842351c38a87cac2c1cb193895035a2a05c5b4fc43c2d45787f54e1ae7d27afdb4ad16dfc567c5692070d5c4556e0b1d7b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000183023ec683021536845685109780a029f07836e4e59229b3a065913afc27702642c683bba689910b2b2fd45db310d3888957e6d004a31802f902a7f85f800a8255f094aaaf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca0575da4e21b66fa764be5f74da9389e67693d066fb0d1312e19e17e501da00ecda06baf5a5327595f6619dfc2fcb3f2e6fb410b5810af3cb52d0e7508038e91a188f85f010a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba04fa966bf34b93abc1bcd665554b7f316b50f928477b50be0f3285ead29d18c5ba017bba0eeec1625ab433746955e125d46d80b7fdc97386c51266f842d8e02192ef85f020a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca004377418ae981cc32b1312b4a427a1d69a821b28db8584f5f2bd8c6d42458adaa053a1dba1af177fac92f3b6af0a9fa46a22adf56e686c93794b6a012bf254abf5f85f030a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca04fe13febd28a05f4fcb2f451d7ddc2dda56486d9f8c79a62b0ba4da775122615a0651b2382dd402df9ebc27f8cb4b2e0f3cea68dda2dca0ee9603608f0b6f51668f85f040a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba078e6a0ba086a08f8450e208a399bb2f2d2a0d984acd2517c7c7df66ccfab567da013254002cd45a97fac049ae00afbc43ed0d9961d0c56a3b2382c80ce41c198ddf85f050a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba0a7174d8f43ea71c8e3ca9477691add8d80ac8e0ed89d8d8b572041eef81f4a54a0534ea2e28ec4da3b5b944b18c51ec84a5cf35f5b3343c5fb86521fd2d388f506f85f060a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba034bd04065833536a10c77ee2a43a5371bc6d34837088b861dd9d4b7f44074b59a078807715786a13876d3455716a6b9cb2186b7a4887a5c31160fc877454958616c0', - transactions: [ - { - data: '0x', - gasLimit: '0x55f0', - gasPrice: '0x0a', - nonce: '0x', - r: '0x575da4e21b66fa764be5f74da9389e67693d066fb0d1312e19e17e501da00ecd', - s: '0x6baf5a5327595f6619dfc2fcb3f2e6fb410b5810af3cb52d0e7508038e91a188', - to: '0xaaaf5374fce5edbc8e2a8697c15331677e6ebf0b', - v: '0x1c', - value: '0x0a', - }, - { - data: '0x', - gasLimit: '0x5208', - gasPrice: '0x0a', - nonce: '0x01', - r: '0x4fa966bf34b93abc1bcd665554b7f316b50f928477b50be0f3285ead29d18c5b', - s: '0x17bba0eeec1625ab433746955e125d46d80b7fdc97386c51266f842d8e02192e', - to: '0xbbbf5374fce5edbc8e2a8697c15331677e6ebf0b', - v: '0x1b', - value: '0x0a', - }, - { - data: '0x', - gasLimit: '0x5208', - gasPrice: '0x0a', - nonce: '0x02', - r: '0x04377418ae981cc32b1312b4a427a1d69a821b28db8584f5f2bd8c6d42458ada', - s: '0x53a1dba1af177fac92f3b6af0a9fa46a22adf56e686c93794b6a012bf254abf5', - to: 'bbbf5374fce5edbc8e2a8697c15331677e6ebf0b', - v: '0x1c', - value: '0x0a', - }, - { - data: '0x', - gasLimit: '0x5208', - gasPrice: '0x0a', - nonce: '0x03', - r: '0x4fe13febd28a05f4fcb2f451d7ddc2dda56486d9f8c79a62b0ba4da775122615', - s: '0x651b2382dd402df9ebc27f8cb4b2e0f3cea68dda2dca0ee9603608f0b6f51668', - to: '0xbbbf5374fce5edbc8e2a8697c15331677e6ebf0b', - v: '0x1c', - value: '0x0a', - }, - { - data: '0x', - gasLimit: '0x5208', - gasPrice: '0x0a', - nonce: '0x04', - r: '0x78e6a0ba086a08f8450e208a399bb2f2d2a0d984acd2517c7c7df66ccfab567d', - s: '0x13254002cd45a97fac049ae00afbc43ed0d9961d0c56a3b2382c80ce41c198dd', - to: '0xbbbf5374fce5edbc8e2a8697c15331677e6ebf0b', - v: '0x1b', - value: '0x0a', - }, - { - data: '0x', - gasLimit: '0x5208', - gasPrice: '0x0a', - nonce: '0x05', - r: '0xa7174d8f43ea71c8e3ca9477691add8d80ac8e0ed89d8d8b572041eef81f4a54', - s: '0x534ea2e28ec4da3b5b944b18c51ec84a5cf35f5b3343c5fb86521fd2d388f506', - to: '0xbbbf5374fce5edbc8e2a8697c15331677e6ebf0b', - v: '0x1b', - value: '0x0a', - }, - { - data: '0x', - gasLimit: '0x5208', - gasPrice: '0x0a', - nonce: '0x06', - r: '0x34bd04065833536a10c77ee2a43a5371bc6d34837088b861dd9d4b7f44074b59', - s: '0x78807715786a13876d3455716a6b9cb2186b7a4887a5c31160fc877454958616', - to: '0xbbbf5374fce5edbc8e2a8697c15331677e6ebf0b', - v: '0x1b', - value: '0x0a', - }, - ], - uncleHeaders: [], - }, - ], - genesisBlockHeader: { - bloom: - '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - coinbase: '0x8888f1f195afa192cfee860698584c030f4c9db1', - difficulty: '0x020000', - extraData: '0x42', - gasLimit: '0x023e38', - gasUsed: '0x00', - hash: '0xce1f26f798dd03c8782d63b3e42e79a64eaea5694ea686ac5d7ce3df5171d1ae', - mixHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - nonce: '0x0102030405060708', - number: '0x00', - parentHash: '0x0000000000000000000000000000000000000000000000000000000000000000', - receiptTrie: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - stateRoot: '0xaf81e09f8c46ca322193edfda764fa7e88e81923f802f1d325ec0b0308ac2cd0', - timestamp: '0x54c98c81', - transactionsTrie: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - uncleHash: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', - }, - genesisRLP: - '0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0af81e09f8c46ca322193edfda764fa7e88e81923f802f1d325ec0b0308ac2cd0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083023e38808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0', - lastblockhash: '0xf53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3', - postState: { - '8888f1f195afa192cfee860698584c030f4c9db1': { - balance: '0x456391824508d41c', - code: '0x', - nonce: '0x', - storage: {}, - }, - a94f5374fce5edbc8e2a8697c15331677e6ebf0b: { - balance: '0x4a723dc6b40b8cedf70fa8', - code: '0x', - nonce: '0x07', - storage: {}, - }, - bbbf5374fce5edbc8e2a8697c15331677e6ebf0b: { - balance: '0x3c', - code: '0x', - nonce: '0x', - storage: {}, - }, - }, - pre: { - a94f5374fce5edbc8e2a8697c15331677e6ebf0b: { - balance: '0x4a723dc6b40b8a9a000000', - code: '0x', - nonce: '0x', - storage: {}, - }, - aaaf5374fce5edbc8e2a8697c15331677e6ebf0b: { - balance: '0x02540be400', - code: '0x73a94f5374fce5edbc8e2a8697c15331677e6ebf0bff', - nonce: '0x', - storage: {}, - }, - }, -} diff --git a/packages/testdata/src/blocks/preLondonTestDataBlocks1RLP.ts b/packages/testdata/src/blocks/preLondonTestDataBlocks1RLP.ts new file mode 100644 index 00000000000..0e8ee1b876b --- /dev/null +++ b/packages/testdata/src/blocks/preLondonTestDataBlocks1RLP.ts @@ -0,0 +1,11 @@ +import type { PrefixedHexString } from '@ethereumjs/util' + +export const preLondonTestDataBlocks1RLP: { + blockRLP: PrefixedHexString + genesisRLP: PrefixedHexString +} = { + blockRLP: + '0xf904a8f901faa0ce1f26f798dd03c8782d63b3e42e79a64eaea5694ea686ac5d7ce3df5171d1aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a65c2364cd0f1542d761823dc0109c6b072f14c20459598c5455c274601438f4a070616ebd7ad2ed6fb7860cf7e9df00163842351c38a87cac2c1cb193895035a2a05c5b4fc43c2d45787f54e1ae7d27afdb4ad16dfc567c5692070d5c4556e0b1d7b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000183023ec683021536845685109780a029f07836e4e59229b3a065913afc27702642c683bba689910b2b2fd45db310d3888957e6d004a31802f902a7f85f800a8255f094aaaf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca0575da4e21b66fa764be5f74da9389e67693d066fb0d1312e19e17e501da00ecda06baf5a5327595f6619dfc2fcb3f2e6fb410b5810af3cb52d0e7508038e91a188f85f010a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba04fa966bf34b93abc1bcd665554b7f316b50f928477b50be0f3285ead29d18c5ba017bba0eeec1625ab433746955e125d46d80b7fdc97386c51266f842d8e02192ef85f020a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca004377418ae981cc32b1312b4a427a1d69a821b28db8584f5f2bd8c6d42458adaa053a1dba1af177fac92f3b6af0a9fa46a22adf56e686c93794b6a012bf254abf5f85f030a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca04fe13febd28a05f4fcb2f451d7ddc2dda56486d9f8c79a62b0ba4da775122615a0651b2382dd402df9ebc27f8cb4b2e0f3cea68dda2dca0ee9603608f0b6f51668f85f040a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba078e6a0ba086a08f8450e208a399bb2f2d2a0d984acd2517c7c7df66ccfab567da013254002cd45a97fac049ae00afbc43ed0d9961d0c56a3b2382c80ce41c198ddf85f050a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba0a7174d8f43ea71c8e3ca9477691add8d80ac8e0ed89d8d8b572041eef81f4a54a0534ea2e28ec4da3b5b944b18c51ec84a5cf35f5b3343c5fb86521fd2d388f506f85f060a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba034bd04065833536a10c77ee2a43a5371bc6d34837088b861dd9d4b7f44074b59a078807715786a13876d3455716a6b9cb2186b7a4887a5c31160fc877454958616c0', + genesisRLP: + '0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0af81e09f8c46ca322193edfda764fa7e88e81923f802f1d325ec0b0308ac2cd0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083023e38808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0', +} diff --git a/packages/testdata/src/blocks/preLondonTestDataBlocks2.ts b/packages/testdata/src/blocks/preLondonTestDataBlocks2.ts deleted file mode 100644 index 89f461c3a60..00000000000 --- a/packages/testdata/src/blocks/preLondonTestDataBlocks2.ts +++ /dev/null @@ -1,194 +0,0 @@ -export const preLondonTestDataBlocks2 = { - _info: { - comment: '', - filledwith: 'cpp-1.3.0+commit.26123543.Linux.g++', - source: '/src/BlockchainTestsFiller/bcUncleHeaderValiditiy/correctFiller.json', // cspell:disable-line - }, - blocks: [ - { - blockHeader: { - bloom: - '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - coinbase: '0x8888f1f195afa192cfee860698584c030f4c9db1', - difficulty: '0x020000', - extraData: '', - gasLimit: '0x2fefba', - gasUsed: '0x5208', - hash: '0xca028b1318795714d130a99d8023bd7463cf8084f31d2f95f1a2d9eb342e9cac', - mixHash: '0xc62911f4c54474a95c8f49044e4cf77aa7bb4c6534887d80ddc1a1ccdad9d3e8', - nonce: '0x4e379cdf33222ddf', - number: '0x01', - parentHash: '0x5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae', - receiptTrie: '0xe9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313', - stateRoot: '0xcb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878', - timestamp: '0x5982d2cb', - transactionsTrie: '0x5c9151c2413d1cd25c51ffb4ac38948acc1359bf08c6b49f283660e9bcf0f516', - uncleHash: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', - }, - rlp: '0xf90261f901f9a05a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a05c9151c2413d1cd25c51ffb4ac38948acc1359bf08c6b49f283660e9bcf0f516a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba825208845982d2cb80a0c62911f4c54474a95c8f49044e4cf77aa7bb4c6534887d80ddc1a1ccdad9d3e8884e379cdf33222ddff862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba077c7cd36820c71821c1aed59de46e70e701c4a8dd89c9ba508ab722210f60da8a03f29825d40c7c3f7bff3ca69267e0f3fb74b2d18b8c2c4e3c135b5d3b06e288dc0', - transactions: [ - { - data: '', - gasLimit: '0x04cb2f', - gasPrice: '0x01', - nonce: '0x', - r: '0x77c7cd36820c71821c1aed59de46e70e701c4a8dd89c9ba508ab722210f60da8', - s: '0x3f29825d40c7c3f7bff3ca69267e0f3fb74b2d18b8c2c4e3c135b5d3b06e288d', - to: '0x095e7baea6a6c7c4c2dfeb977efac326af552d87', - v: '0x1b', - value: '0x0a', - }, - ], - uncleHeaders: [], - }, - { - blockHeader: { - bloom: - '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - coinbase: '0x8888f1f195afa192cfee860698584c030f4c9db1', - difficulty: '0x020040', - extraData: '', - gasLimit: '0x2fefba', - gasUsed: '0x5208', - hash: '0x2b530c31b2556d8ad5e12311658f0ec47e35a4ceffecd83d06e7cd918d3a85f1', - mixHash: '0x6695294f40e94ba1641fad8c4827dfa8929c8b5b6df64bf79dae8067ae5809ca', - nonce: '0xb4fca9b7d3af4ecc', - number: '0x02', - parentHash: '0xca028b1318795714d130a99d8023bd7463cf8084f31d2f95f1a2d9eb342e9cac', - receiptTrie: '0x5ea1a8b24652fed0ecab4738edd9211891eb8c4353c345973b78a02cc0f32f6b', - stateRoot: '0xe7e4760f75476ec7f51869d8bdce5c693058fd5a95c77ea9c0bf7ced1e50d70e', - timestamp: '0x5982d2cd', - transactionsTrie: '0xc673e076264c4669a5c2e479f1757b78e42511efe33b5fd2c0a23b929c7f87f5', - uncleHash: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', - }, - rlp: '0xf90260f901f9a0ca028b1318795714d130a99d8023bd7463cf8084f31d2f95f1a2d9eb342e9caca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0e7e4760f75476ec7f51869d8bdce5c693058fd5a95c77ea9c0bf7ced1e50d70ea0c673e076264c4669a5c2e479f1757b78e42511efe33b5fd2c0a23b929c7f87f5a05ea1a8b24652fed0ecab4738edd9211891eb8c4353c345973b78a02cc0f32f6bb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefba825208845982d2cd80a06695294f40e94ba1641fad8c4827dfa8929c8b5b6df64bf79dae8067ae5809ca88b4fca9b7d3af4eccf861f85f01018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba033c86e64d708c97c6b135cadff79dbf45985aa0b53694789e90d15f756765f239f1d0f8caa2a16405148c9d85581be5814960010f3cba938b5501590cea1f7cfc0', - transactions: [ - { - data: '', - gasLimit: '0x04cb2f', - gasPrice: '0x01', - nonce: '0x01', - r: '0x33c86e64d708c97c6b135cadff79dbf45985aa0b53694789e90d15f756765f23', - s: '0x1d0f8caa2a16405148c9d85581be5814960010f3cba938b5501590cea1f7cf', - to: '0x095e7baea6a6c7c4c2dfeb977efac326af552d87', - v: '0x1b', - value: '0x0a', - }, - ], - uncleHeaders: [], - }, - { - blockHeader: { - bloom: - '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - coinbase: '0x8888f1f195afa192cfee860698584c030f4c9db1', - difficulty: '0x020080', - extraData: '', - gasLimit: '0x2fefba', - gasUsed: '0x5208', - hash: '0xc6208f30be1fb9053b073c49cc16795001bd07c6d2650b28d2e4a37a5eb2dde2', - mixHash: '0x16bd3db367a3b218565e6744de193fb601587af40ba093e8e3cf9b29f0aa4ff1', - nonce: '0xf5c0d237b1a07faa', - number: '0x03', - parentHash: '0x2b530c31b2556d8ad5e12311658f0ec47e35a4ceffecd83d06e7cd918d3a85f1', - receiptTrie: '0x4ede0225773c7a517b91994aca65ade45124e7ef4b8be1e6097c9773a11920af', - stateRoot: '0x77f96f4c766c10cd0207e2672b1b747c741ed75bc94e7be7abacb71cdca3c8fb', - timestamp: '0x5982d2d1', - transactionsTrie: '0x1722b8a91bfc4f5614ce36ee77c7cce6620ab4af36d3c54baa66d7dbeb7bce1a', - uncleHash: '0xbeb175854a56183e630cd77e1c6dcd50a8bab221f81f2376919c649b33c500e0', - }, - rlp: '0xf9045df901f9a02b530c31b2556d8ad5e12311658f0ec47e35a4ceffecd83d06e7cd918d3a85f1a0beb175854a56183e630cd77e1c6dcd50a8bab221f81f2376919c649b33c500e0948888f1f195afa192cfee860698584c030f4c9db1a077f96f4c766c10cd0207e2672b1b747c741ed75bc94e7be7abacb71cdca3c8fba01722b8a91bfc4f5614ce36ee77c7cce6620ab4af36d3c54baa66d7dbeb7bce1aa04ede0225773c7a517b91994aca65ade45124e7ef4b8be1e6097c9773a11920afb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba825208845982d2d180a016bd3db367a3b218565e6744de193fb601587af40ba093e8e3cf9b29f0aa4ff188f5c0d237b1a07faaf862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca015eb1cc916728b9799e55c489857727669afb2986433d5f54cde11faaed9f0eea05d36f6d06c34aae8d0a2a5895c8ba4a17ad46a5fa59f361cb3e7e01a23030e38f901faf901f7a0ca028b1318795714d130a99d8023bd7463cf8084f31d2f95f1a2d9eb342e9caca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefba80845982d2cf80a0b5488407bc8b147a9b3c4811864ebfc5bdb568fc8f91dcf9232ed6b7429c52f8882b9b47250942c14e', - transactions: [ - { - data: '', - gasLimit: '0x04cb2f', - gasPrice: '0x01', - nonce: '0x02', - r: '0x15eb1cc916728b9799e55c489857727669afb2986433d5f54cde11faaed9f0ee', - s: '0x5d36f6d06c34aae8d0a2a5895c8ba4a17ad46a5fa59f361cb3e7e01a23030e38', - to: '0x095e7baea6a6c7c4c2dfeb977efac326af552d87', - v: '0x1c', - value: '0x0a', - }, - ], - uncleHeaders: [ - { - bloom: - '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - coinbase: '0x0000000000000000000000000000000000000000', - difficulty: '0x020040', - extraData: '', - gasLimit: '0x2fefba', - gasUsed: '0x00', - hash: '0xcac5903348d2b4ca370227f7bd24bc3101b327a05172a3d7d3106a11d2019c16', - mixHash: '0xb5488407bc8b147a9b3c4811864ebfc5bdb568fc8f91dcf9232ed6b7429c52f8', - nonce: '0x2b9b47250942c14e', - number: '0x02', - parentHash: '0xca028b1318795714d130a99d8023bd7463cf8084f31d2f95f1a2d9eb342e9cac', - receiptTrie: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - stateRoot: '0xcb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878', - timestamp: '0x5982d2cf', - transactionsTrie: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - uncleHash: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', - }, - ], - }, - ], - genesisBlockHeader: { - bloom: - '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', - coinbase: '0x8888f1f195afa192cfee860698584c030f4c9db1', - difficulty: '0x020000', - extraData: '0x42', - gasLimit: '0x2fefd8', - gasUsed: '0x00', - hash: '0x5a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5ae', - mixHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - nonce: '0x0102030405060708', - number: '0x00', - parentHash: '0x0000000000000000000000000000000000000000000000000000000000000000', - receiptTrie: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - stateRoot: '0x7dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1', - timestamp: '0x54c98c81', - transactionsTrie: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', - uncleHash: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', - }, - genesisRLP: - '0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0', - lastblockhash: '0xc6208f30be1fb9053b073c49cc16795001bd07c6d2650b28d2e4a37a5eb2dde2', - network: 'EIP150', - postState: { - '0x0000000000000000000000000000000000000000': { - balance: '0x3cb71f51fc558000', - code: '', - nonce: '0x', - storage: {}, - }, - '0x095e7baea6a6c7c4c2dfeb977efac326af552d87': { - balance: '0x1e', - code: '', - nonce: '0x', - storage: {}, - }, - '0x8888f1f195afa192cfee860698584c030f4c9db1': { - balance: '0xd255d112e1049618', - code: '', - nonce: '0x', - storage: {}, - }, - '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b': { - balance: '0x09184e71a9ca', - code: '', - nonce: '0x03', - storage: {}, - }, - }, - pre: { - '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b': { - balance: '0x09184e72a000', - code: '', - nonce: '0x', - storage: {}, - }, - }, -} diff --git a/packages/testdata/src/blocks/preLondonTestDataBlocks2RLP.ts b/packages/testdata/src/blocks/preLondonTestDataBlocks2RLP.ts new file mode 100644 index 00000000000..03302f9b10a --- /dev/null +++ b/packages/testdata/src/blocks/preLondonTestDataBlocks2RLP.ts @@ -0,0 +1,12 @@ +import type { PrefixedHexString } from '@ethereumjs/util' + +export const preLondonTestDataBlocks2RLP: Record = { + block0RLP: + '0xf90261f901f9a05a39ed1020c04d4d84539975b893a4e7c53eab6c2965db8bc3468093a31bc5aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a05c9151c2413d1cd25c51ffb4ac38948acc1359bf08c6b49f283660e9bcf0f516a0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefba825208845982d2cb80a0c62911f4c54474a95c8f49044e4cf77aa7bb4c6534887d80ddc1a1ccdad9d3e8884e379cdf33222ddff862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba077c7cd36820c71821c1aed59de46e70e701c4a8dd89c9ba508ab722210f60da8a03f29825d40c7c3f7bff3ca69267e0f3fb74b2d18b8c2c4e3c135b5d3b06e288dc0', + block1RLP: + '0xf90260f901f9a0ca028b1318795714d130a99d8023bd7463cf8084f31d2f95f1a2d9eb342e9caca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0e7e4760f75476ec7f51869d8bdce5c693058fd5a95c77ea9c0bf7ced1e50d70ea0c673e076264c4669a5c2e479f1757b78e42511efe33b5fd2c0a23b929c7f87f5a05ea1a8b24652fed0ecab4738edd9211891eb8c4353c345973b78a02cc0f32f6bb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefba825208845982d2cd80a06695294f40e94ba1641fad8c4827dfa8929c8b5b6df64bf79dae8067ae5809ca88b4fca9b7d3af4eccf861f85f01018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba033c86e64d708c97c6b135cadff79dbf45985aa0b53694789e90d15f756765f239f1d0f8caa2a16405148c9d85581be5814960010f3cba938b5501590cea1f7cfc0', + block2RLP: + '0xf9045df901f9a02b530c31b2556d8ad5e12311658f0ec47e35a4ceffecd83d06e7cd918d3a85f1a0beb175854a56183e630cd77e1c6dcd50a8bab221f81f2376919c649b33c500e0948888f1f195afa192cfee860698584c030f4c9db1a077f96f4c766c10cd0207e2672b1b747c741ed75bc94e7be7abacb71cdca3c8fba01722b8a91bfc4f5614ce36ee77c7cce6620ab4af36d3c54baa66d7dbeb7bce1aa04ede0225773c7a517b91994aca65ade45124e7ef4b8be1e6097c9773a11920afb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba825208845982d2d180a016bd3db367a3b218565e6744de193fb601587af40ba093e8e3cf9b29f0aa4ff188f5c0d237b1a07faaf862f86002018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca015eb1cc916728b9799e55c489857727669afb2986433d5f54cde11faaed9f0eea05d36f6d06c34aae8d0a2a5895c8ba4a17ad46a5fa59f361cb3e7e01a23030e38f901faf901f7a0ca028b1318795714d130a99d8023bd7463cf8084f31d2f95f1a2d9eb342e9caca01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347940000000000000000000000000000000000000000a0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefba80845982d2cf80a0b5488407bc8b147a9b3c4811864ebfc5bdb568fc8f91dcf9232ed6b7429c52f8882b9b47250942c14e', + genesisRLP: + '0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0', +} diff --git a/packages/testdata/src/gethGenesis/invalidSpuriousDragonGethGenesis.ts b/packages/testdata/src/gethGenesis/invalidSpuriousDragonGethGenesis.ts index 29196700957..253513efc47 100644 --- a/packages/testdata/src/gethGenesis/invalidSpuriousDragonGethGenesis.ts +++ b/packages/testdata/src/gethGenesis/invalidSpuriousDragonGethGenesis.ts @@ -32,4 +32,4 @@ export const invalidSpuriousDragonGethGenesis: GethGenesis = { gasUsed: '0x0', parentHash: '0x0000000000000000000000000000000000000000000000000000000000000000', baseFeePerGas: null, -} as GethGenesis +} as unknown as GethGenesis diff --git a/packages/testdata/src/gethGenesis/withdrawalsGethGenesis.ts b/packages/testdata/src/gethGenesis/withdrawalsGethGenesis.ts index ce397d83ffc..62a67a1bd86 100644 --- a/packages/testdata/src/gethGenesis/withdrawalsGethGenesis.ts +++ b/packages/testdata/src/gethGenesis/withdrawalsGethGenesis.ts @@ -1,4 +1,6 @@ -export const withdrawalsGethGenesis = { +import type { GethGenesis } from '@ethereumjs/common' + +export const withdrawalsGethGenesis: GethGenesis = { config: { chainId: 1, homesteadBlock: 0, diff --git a/packages/tx/README.md b/packages/tx/README.md index 10415dea702..dfb4ecce32f 100644 --- a/packages/tx/README.md +++ b/packages/tx/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/tx +# @ethereumjs/tx `v10` [![NPM Package][tx-npm-badge]][tx-npm-link] [![GitHub Issues][tx-issues-badge]][tx-issues-link] @@ -9,9 +9,22 @@ | Implements schema and functions for the different Ethereum transaction types | | ---------------------------------------------------------------------------- | -## Installation +## Table of Contents + +- [Installation](#installation) +- [Getting Started](#getting-started) +- [Chain and Hardfork Support](#chain-and-hardfork-support) +- [Transaction Types](#transaction-types) +- [Transaction Factory](#transaction-factory) +- [KZG Setup](#kzg-setup) +- [Sending a Transaction](#sending-a-transaction) +- [Browser](#browser) +- [Hardware Wallets](#hardware-wallets) +- [API](#api) +- [EthereumJS](#ethereumjs) +- [License](#license) -### General +## Installation To obtain the latest version, simply require the project using `npm`: @@ -19,7 +32,7 @@ To obtain the latest version, simply require the project using `npm`: npm install @ethereumjs/tx ``` -## Usage +## Getting Started ### Static Constructor Methods @@ -33,7 +46,11 @@ See one of the code examples on the tx types below on how to use. All types of transaction objects are frozen with `Object.freeze()` which gives you enhanced security and consistency properties when working with the instantiated object. This behavior can be modified using the `freeze` option in the constructor if needed. -### Chain and Hardfork Support +### WASM Crypto Support + +This library by default uses JavaScript implementations for the basic standard crypto primitives like hashing or signature verification. See `@ethereumjs/common` [README](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/common) for instructions on how to replace with e.g. a more performant WASM implementation by using a shared `common` instance. + +## Chain and Hardfork Support To use a chain other than the default Mainnet chain, or a different hardfork than the default [`@ethereumjs/common`](https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/common) hardfork (`Hardfork.Prague`), provide a `common` object in the constructor of the tx. @@ -43,30 +60,30 @@ Hardforks adding features and/or tx types: | Hardfork | Introduced | Description | | ---------------- | ---------- | ------------------------------------------------------------------------------------------------------- | -| `spuriousDragon` |  `v2.0.0` |  `EIP-155` replay protection (disable by setting HF pre-`spuriousDragon`) | -| `istanbul` |  `v2.1.1`  | Support for reduced non-zero call blob gas prices ([EIP-2028](https://eips.ethereum.org/EIPS/eip-2028)) | -| `muirGlacier` |  `v2.1.2` |  - | -| `berlin` | `v3.1.0` |  `EIP-2718` Typed Transactions, Optional Access Lists Tx Type `EIP-2930` | +| `spuriousDragon` | `v2.0.0` | `EIP-155` replay protection (disable by setting HF pre-`spuriousDragon`) | +| `istanbul` | `v2.1.1` | Support for reduced non-zero call blob gas prices ([EIP-2028](https://eips.ethereum.org/EIPS/eip-2028)) | +| `muirGlacier` | `v2.1.2` | - | +| `berlin` | `v3.1.0` | `EIP-2718` Typed Transactions, Optional Access Lists Tx Type `EIP-2930` | | `london` | `v3.2.0` | `EIP-1559` Transactions | | `cancun` | `v5.0.0` | `EIP-4844` Transactions | +| `prague` | `v10.0.0` | `EIP-7702` Transactions | -### WASM Crypto Support +## Transaction Types -This library by default uses JavaScript implementations for the basic standard crypto primitives like hashing or signature verification. See `@ethereumjs/common` [README](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/common) for instructions on how to replace with e.g. a more performant WASM implementation by using a shared `common` instance. - -### Transaction Types +### Table of Contents This library supports the following transaction types ([EIP-2718](https://eips.ethereum.org/EIPS/eip-2718)): -- `FeeMarketEIP1559Tx` ([EIP-1559](https://eips.ethereum.org/EIPS/eip-1559), gas fee market) -- `AccessListEIP2930Tx` ([EIP-2930](https://eips.ethereum.org/EIPS/eip-2930), optional access lists) -- `BlobEIP4844Tx` ([EIP-4844](https://eips.ethereum.org/EIPS/eip-4844), blob transactions) -- `EOACodeEIP7702Tx` ([EIP-7702](https://eips.ethereum.org/EIPS/eip-7702), EOA code delegation) -- `LegacyTx`, the Ethereum standard tx up to `berlin`, now referred to as legacy txs with the introduction of tx types +- [Gas Fee Market Transactions (EIP-1559)](#gas-fee-market-transactions-eip-1559) +- [Access List Transactions (EIP-2930)](#access-list-transactions-eip-2930) +- [Blob Transactions (EIP-4844)](#blob-transactions-eip-4844) +- [EOA Code Transaction (EIP-7702)](#eoa-code-transaction-eip-7702) +- [Legacy Transactions](#legacy-transactions) (original Ethereum txs) -#### Gas Fee Market Transactions (EIP-1559) +### Gas Fee Market Transactions (EIP-1559) - Class: `FeeMarketEIP1559Tx` +- EIP: [EIP-1559](https://eips.ethereum.org/EIPS/eip-1559) - Activation: `london` - Type: `2` @@ -101,9 +118,10 @@ const tx = createFeeMarket1559Tx(txData, { common }) console.log(bytesToHex(tx.hash())) // 0x6f9ef69ccb1de1aea64e511efd6542541008ced321887937c95b03779358ec8a ``` -#### Access List Transactions (EIP-2930) +### Access List Transactions (EIP-2930) - Class: `AccessListEIP2930Tx` +- EIP: [EIP-2930](https://eips.ethereum.org/EIPS/eip-2930) - Activation: `berlin` - Type: `1` @@ -148,9 +166,10 @@ console.log(bytesToHex(tx.hash())) // 0x9150cdebad74e88b038e6c6b964d99af705f9c08 For generating access lists from tx data based on a certain network state there is a `reportAccessList` option on the `Vm.runTx()` method of the `@ethereumjs/vm` `TypeScript` VM implementation. -#### Blob Transactions (EIP-4844) +### Blob Transactions (EIP-4844) - Class: `BlobEIP4844Tx` +- EIP: [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844) - Activation: `cancun` - Type: `3` @@ -158,8 +177,6 @@ This library supports the blob transaction type introduced with [EIP-4844](https **Note:** This functionality needs a manual KZG library installation and global initialization, see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions. -##### Usage - See the following code snipped for an example on how to instantiate: ```ts @@ -212,9 +229,10 @@ Alternatively, you can pass a `blobsData` property with an array of strings corr See the [Blob Transaction Tests](./test/eip4844.spec.ts) for examples of usage in instantiating, serializing, and deserializing these transactions. -#### EOA Code Transaction (EIP-7702) +### EOA Code Transaction (EIP-7702) - Class: `EOACodeEIP7702Tx` +- EIP: [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) - Activation: `prague` - Type: `4` @@ -291,7 +309,7 @@ console.log(bytesToHex(signedTx.hash())) // 0x894b72d87f8333fccd29d1b3aca39af69d ``` -### Transaction Factory +## Transaction Factory If you only know on runtime which tx type will be used within your code or if you want to keep your code transparent to tx types, this library comes with a `TransactionFactory` for your convenience which can be used as follows: @@ -324,7 +342,7 @@ The correct tx type class for instantiation will then be chosen on runtime based - `public static fromBlockBodyData(data: Uint8Array | Uint8Array[], txOptions: TxOptions = {})` - `public static async fromJsonRpcProvider(provider: string | EthersProvider, txHash: string, txOptions?: TxOptions)` -### KZG Setup +## KZG Setup This library fully supports `EIP-4844` blob transactions. For blob transactions and other KZG related proof functionality (e.g. for EVM precompiles) KZG has to be manually installed and initialized in the `common` instance to be used in instantiating blob transactions. @@ -354,9 +372,9 @@ void main() Note: We did not want to directly bundle because bundle sizes are large due to the large trusted setup inclusion (especially for the mainnet trusted setup). -### Sending a Transaction +## Sending a Transaction -#### L2 Support +### L2 Support This library has been tested to work with various L2 networks. To set an associated chainID, use the `createCustomCommon()` constructor from our `Common` library. The following is a simple example to send a tx to the xDai chain: @@ -391,9 +409,9 @@ We provide hybrid ESM/CJS builds for all our libraries. With the v10 breaking re It is easily possible to run a browser build of one of the EthereumJS libraries within a modern browser using the provided ESM build. For a setup example see [./examples/browser.html](./examples/browser.html). -## Special Topics +## Hardware Wallets -### Signing with a hardware or external wallet +### Ledger To sign a tx with a hardware or external wallet use `tx.getMessageToSign()` to return an [EIP-155](https://eips.ethereum.org/EIPS/eip-155) compliant unsigned tx. diff --git a/packages/tx/examples/custom-chain-id-tx.ts b/packages/tx/examples/custom-chain-id-tx.ts index 50a65adabbb..74ec92197b1 100644 --- a/packages/tx/examples/custom-chain-id-tx.ts +++ b/packages/tx/examples/custom-chain-id-tx.ts @@ -1,8 +1,8 @@ import { Hardfork, Mainnet, createCustomCommon } from '@ethereumjs/common' import { createLegacyTxFromRLP } from '@ethereumjs/tx' -import { toBytes } from '@ethereumjs/util' +import { hexToBytes, toBytes } from '@ethereumjs/util' -const txData = toBytes( +const txData = hexToBytes( '0xf9010b82930284d09dc30083419ce0942d18de92e0f9aee1a29770c3b15c6cf8ac5498e580b8a42f43f4fb0000000000000000000000000000000000000000000000000000016b78998da900000000000000000000000000000000000000000000000000000000000cb1b70000000000000000000000000000000000000000000000000000000000000fa00000000000000000000000000000000000000000000000000000000001363e4f00000000000000000000000000000000000000000000000000000000000186a029a0fac36e66d329af0e831b2e61179b3ec8d7c7a8a2179e303cfed3364aff2bc3e4a07cb73d56e561ccbd838818dd3dea5fa0b5158577ffc61c0e6ec1f0ed55716891', ) diff --git a/packages/tx/src/legacy/tx.ts b/packages/tx/src/legacy/tx.ts index 02a8ad26c99..7d90b8bab68 100644 --- a/packages/tx/src/legacy/tx.ts +++ b/packages/tx/src/legacy/tx.ts @@ -6,6 +6,7 @@ import { bigIntToHex, bigIntToUnpaddedBytes, bytesToBigInt, + intToBytes, toBytes, unpadBytes, } from '@ethereumjs/util' @@ -256,8 +257,8 @@ export class LegacyTx implements TransactionInterface { it('createWithdrawalFromBytesArray()', () => { let rlpData: any = legacyTxs[0].raw() - rlpData[0] = toBytes('0x0') + rlpData[0] = hexToBytes('0x0') try { createLegacyTxFromBytesArray(rlpData) assert.fail('should have thrown when nonce has leading zeroes') @@ -196,8 +195,8 @@ describe('[BaseTransaction]', () => { 'should throw with nonce with leading zeroes', ) } - rlpData[0] = toBytes('0x') - rlpData[6] = toBytes('0x0') + rlpData[0] = hexToBytes('0x') + rlpData[6] = hexToBytes('0x0') try { createLegacyTxFromBytesArray(rlpData) assert.fail('should have thrown when v has leading zeroes') @@ -208,7 +207,7 @@ describe('[BaseTransaction]', () => { ) } rlpData = eip2930Txs[0].raw() - rlpData[3] = toBytes('0x0') + rlpData[3] = hexToBytes('0x0') try { createAccessList2930TxFromBytesArray(rlpData) assert.fail('should have thrown when gasLimit has leading zeroes') @@ -219,7 +218,7 @@ describe('[BaseTransaction]', () => { ) } rlpData = eip1559Txs[0].raw() - rlpData[2] = toBytes('0x0') + rlpData[2] = hexToBytes('0x0') try { create1559FeeMarketTxFromBytesArray(rlpData) assert.fail('should have thrown when maxPriorityFeePerGas has leading zeroes') @@ -414,7 +413,7 @@ describe('[BaseTransaction]', () => { }) it('initialization with defaults', () => { - const bufferZero = toBytes('0x') + const bufferZero = hexToBytes('0x') const tx = createLegacyTx({ nonce: undefined, gasLimit: undefined, diff --git a/packages/tx/test/t9n.spec.ts b/packages/tx/test/t9n.spec.ts index 2ba4fdfe9d5..ff93cba2754 100644 --- a/packages/tx/test/t9n.spec.ts +++ b/packages/tx/test/t9n.spec.ts @@ -77,7 +77,7 @@ function runTests(filePath: string) { for (const testName in tests) { const test = tests[testName] - const txBytes = hexToBytes(test.txbytes) + const txBytes = hexToBytes(test.txbytes as PrefixedHexString) for (const fork in test.result) { it(`${testName} [${getFork(fork)}]`, () => { diff --git a/packages/util/README.md b/packages/util/README.md index b6395405afa..9e864e51f7a 100644 --- a/packages/util/README.md +++ b/packages/util/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/util +# @ethereumjs/util `v10` [![NPM Package][util-npm-badge]][util-npm-link] [![GitHub Issues][util-issues-badge]][util-issues-link] @@ -9,6 +9,30 @@ | A collection of utility functions for Ethereum. | | ----------------------------------------------- | +## Table of Contents + +- [Installation](#installation) +- [Getting Started](#getting-started) +- [Module: [account]](#module-account) +- [Module: [address]](#module-address) +- [Module: [blobs]](#module-blobs) +- [Module: [bytes]](#module-bytes) +- [Module: [constants]](#module-constants) +- [Module: [db]](#module-db) +- [Module: [genesis]](#module-genesis) +- [Module: [internal]](#module-internal) +- [Module: [kzg]](#module-kzg) +- [Module: [mapDB]](#module-mapdb) +- [Module: [request]](#module-request) +- [Module: [signature]](#module-signature) +- [Module: [types]](#module-types) +- [Module: [verkle]](#module-verkle) +- [Module: [withdrawal]](#module-withdrawal) +- [Browser](#browser) +- [API](#api) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Installation To obtain the latest version, simply require the project using `npm`: @@ -17,7 +41,7 @@ To obtain the latest version, simply require the project using `npm`: npm install @ethereumjs/util ``` -## Usage +## Getting Started This package contains the following modules providing respective helper methods, classes and commonly re-used constants. @@ -27,9 +51,9 @@ All helpers are re-exported from the root level and deep imports are not necessa import { hexToBytes, isValidChecksumAddress } from '@ethereumjs/util' ``` -### Module: [account](src/account.ts) +## Module: [account](src/account.ts) -Class representing an `Account` and providing private/public key and address-related functionality (creation, validation, conversion). +Class representing an `Account` and providing private/public key and address-related functionality (creation, validation, conversion). It is not recommended to use this constructor directly. Instead use the static factory methods to assist in creating an Account from varying data types. ```ts // ./examples/account.ts @@ -59,7 +83,7 @@ const account = createPartialAccount({ console.log(`Partial account with nonce=${account.nonce} and balance=${account.balance} created`) ``` -### Module: [address](src/address.ts) +## Module: [address](src/address.ts) Class representing an Ethereum `Address` with instantiation helpers and validation methods. @@ -72,7 +96,7 @@ const address = createAddressFromString('0x2f015c60e0be116b1f0cd534704db9c92118f console.log(`Ethereum address ${address.toString()} created`) ``` -### Module: [blobs](src/blobs.ts) +## Module: [blobs](src/blobs.ts) Module providing helpers for 4844 blobs and versioned hashes. @@ -93,7 +117,7 @@ const versionedHash = computeVersionedHash(commitment, blobCommitmentVersion) console.log(`Versioned hash ${versionedHash} computed`) ``` -### Module: [bytes](src/bytes.ts) +## Module: [bytes](src/bytes.ts) Byte-related helper and conversion functions. @@ -108,7 +132,7 @@ const bigIntValue = bytesToBigInt(bytesValue) console.log(`Converted value: ${bigIntValue}`) ``` -### Module: [constants](src/constants.ts) +## Module: [constants](src/constants.ts) Exposed constants (e.g. `KECCAK256_NULL_S` for string representation of Keccak-256 hash of null) @@ -121,27 +145,27 @@ console.log(`The keccak-256 hash of null: ${KECCAK256_NULL_S}`) console.log(`BigInt constants (performance), e.g. BIGINT_2EXP96: ${BIGINT_2EXP96}`) ``` -### Module: [db](src/db.ts) +## Module: [db](src/db.ts) DB interface for database abstraction (Blockchain, Trie), see e.g. [@ethereumjs/trie recipes](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/trie/recipes/level.ts)) for usage. -### Module: [genesis](src/genesis.ts) +## Module: [genesis](src/genesis.ts) Genesis related interfaces and helpers. -### Module: [internal](src/internal.ts) +## Module: [internal](src/internal.ts) Internalized simple helper methods like `isHexString`. Note that methods from this module might get deprecated in the future. -### Module: [kzg](src/kzg.ts) +## Module: [kzg](src/kzg.ts) KZG interface (used for 4844 blob txs), see [@ethereumjs/tx](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) README for main usage instructions. -### Module: [mapDB](src/mapDB.ts) +## Module: [mapDB](src/mapDB.ts) Simple map DB implementation using the `DB` interface (see above). -### Module: [request](src/request.ts) +## Module: [request](src/request.ts) Module with a compact generic request class for [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685) general purpose execution layer requests to the CL (Prague hardfork) with the possibility to set `data` and a `type` conforming to the following request types: @@ -151,7 +175,7 @@ Module with a compact generic request class for [EIP-7685](https://eips.ethereum These request types are mainly used within the [@ethereumjs/block](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/block) library where applied usage instructions are provided in the README. -### Module: [signature](src/signature.ts) +## Module: [signature](src/signature.ts) Small helpers around signature validation, conversion, recovery as well as selected convenience wrappers for calls to the underlying crypo libraries, using the cryptographic primitive implementations from the [Noble](https://paulmillr.com/noble/) crypto library set. If possible for your use case it is recommended to use the underlying crypto libraries directly for robustness. @@ -172,11 +196,11 @@ const pubkey = ecrecover(ecHash, v, r, s, chainId) console.log(`Recovered public key ${bytesToHex(pubkey)} from valid signature values`) ``` -### Module: [types](src/types.ts) +## Module: [types](src/types.ts) Various TypeScript types. Direct usage is not recommended, type structure might change in the future. -### Module: [verkle](src/verkle.ts) +## Module: [verkle](src/verkle.ts) Various functions for accessing verkle state: @@ -212,7 +236,7 @@ const basicData = decodeVerkleLeafBasicData(hexToBytes(basicDataRaw!)) console.log(basicData) // { version: 1, nonce: 1n, codeSize: 0, balance: 1n } ``` -### Module: [withdrawal](src/withdrawal.ts) +## Module: [withdrawal](src/withdrawal.ts) Class representing an `EIP-4895` `Withdrawal` with different constructors as well as conversion and output helpers. diff --git a/packages/util/src/account.ts b/packages/util/src/account.ts index 6a6e30544e3..3f4fa0b4ec4 100644 --- a/packages/util/src/account.ts +++ b/packages/util/src/account.ts @@ -19,7 +19,7 @@ import { EthereumJSErrorWithoutCode } from './errors.ts' import { assertIsBytes, assertIsHexString, assertIsString } from './helpers.ts' import { stripHexPrefix } from './internal.ts' -import type { BigIntLike, BytesLike, PrefixedHexString } from './types.ts' +import type { BigIntLike, BytesLike, NestedUint8Array, PrefixedHexString } from './types.ts' export interface AccountData { nonce?: BigIntLike @@ -39,6 +39,35 @@ export interface PartialAccountData { export type AccountBodyBytes = [Uint8Array, Uint8Array, Uint8Array, Uint8Array] +/** + * Handles the null indicator for RLP encoded accounts + * @returns {null} is the null indicator is 0 + * @returns The unchanged value is the null indicator is 1 + * @throws if the null indicator is > 1 + * @throws if the length of values is < 2 + * @param value The value to convert + * @returns The converted value + */ +function handleNullIndicator(values: NestedUint8Array | Uint8Array): Uint8Array | null { + // Needed if some values are not provided to the array (e.g. partial account RLP) + if (values[0] === undefined) { + return null + } + + const nullIndicator = bytesToInt(values[0] as Uint8Array) + + if (nullIndicator === 0) { + return null + } + if (nullIndicator > 1) { + throw EthereumJSErrorWithoutCode(`Invalid isNullIndicator=${nullIndicator}`) + } + if (values.length < 2) { + throw EthereumJSErrorWithoutCode(`Invalid values length=${values.length}`) + } + return values[1] as Uint8Array +} + /** * Account class to load and maintain the basic account objects. * Supports partial loading and access required for verkle with null @@ -126,8 +155,10 @@ export class Account { /** * This constructor assigns and validates the values. - * Use the static factory methods to assist in creating an Account from varying data types. - * undefined get assigned with the defaults present, but null args are retained as is + * It is not recommended to use this constructor directly. Instead use the static + * factory methods to assist in creating an Account from varying data types. + * undefined get assigned with the defaults, but null args are retained as is + * @deprecated */ constructor( nonce: bigint | null = BIGINT_0, @@ -325,91 +356,26 @@ export function createAccountFromRLP(serialized: Uint8Array) { } export function createPartialAccountFromRLP(serialized: Uint8Array) { - const values = RLP.decode(serialized) as Uint8Array[][] + const values = RLP.decode(serialized) if (!Array.isArray(values)) { throw EthereumJSErrorWithoutCode('Invalid serialized account input. Must be array') } - let nonce = null - if (!Array.isArray(values[0])) { - throw EthereumJSErrorWithoutCode('Invalid partial nonce encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[0][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw EthereumJSErrorWithoutCode(`Invalid isNullIndicator=${isNotNullIndicator} for nonce`) - } - if (isNotNullIndicator === 1) { - nonce = bytesToBigInt(values[0][1]) + for (const value of values) { + // Ensure that each array item is an array + if (!Array.isArray(value)) { + throw EthereumJSErrorWithoutCode('Invalid partial encoding. Each item must be an array') } } - let balance = null - if (!Array.isArray(values[1])) { - throw EthereumJSErrorWithoutCode('Invalid partial balance encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[1][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw EthereumJSErrorWithoutCode(`Invalid isNullIndicator=${isNotNullIndicator} for balance`) - } - if (isNotNullIndicator === 1) { - balance = bytesToBigInt(values[1][1]) - } - } + const [nonceRaw, balanceRaw, storageRoot, codeHash, codeSizeRaw, versionRaw] = + values.map(handleNullIndicator) - let storageRoot = null - if (!Array.isArray(values[2])) { - throw EthereumJSErrorWithoutCode('Invalid partial storageRoot encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[2][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw EthereumJSErrorWithoutCode( - `Invalid isNullIndicator=${isNotNullIndicator} for storageRoot`, - ) - } - if (isNotNullIndicator === 1) { - storageRoot = values[2][1] - } - } - - let codeHash = null - if (!Array.isArray(values[3])) { - throw EthereumJSErrorWithoutCode('Invalid partial codeHash encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[3][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw EthereumJSErrorWithoutCode(`Invalid isNullIndicator=${isNotNullIndicator} for codeHash`) - } - if (isNotNullIndicator === 1) { - codeHash = values[3][1] - } - } - - let codeSize = null - if (!Array.isArray(values[4])) { - throw EthereumJSErrorWithoutCode('Invalid partial codeSize encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[4][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw EthereumJSErrorWithoutCode(`Invalid isNullIndicator=${isNotNullIndicator} for codeSize`) - } - if (isNotNullIndicator === 1) { - codeSize = bytesToInt(values[4][1]) - } - } - - let version = null - if (!Array.isArray(values[5])) { - throw EthereumJSErrorWithoutCode('Invalid partial version encoding. Must be array') - } else { - const isNotNullIndicator = bytesToInt(values[5][0]) - if (isNotNullIndicator !== 0 && isNotNullIndicator !== 1) { - throw EthereumJSErrorWithoutCode(`Invalid isNullIndicator=${isNotNullIndicator} for version`) - } - if (isNotNullIndicator === 1) { - version = bytesToInt(values[5][1]) - } - } + const nonce = nonceRaw === null ? null : bytesToBigInt(nonceRaw) + const balance = balanceRaw === null ? null : bytesToBigInt(balanceRaw) + const codeSize = codeSizeRaw === null ? null : bytesToInt(codeSizeRaw) + const version = versionRaw === null ? null : bytesToInt(versionRaw) return createPartialAccount({ balance, nonce, storageRoot, codeHash, codeSize, version }) } diff --git a/packages/util/src/binaryTree.ts b/packages/util/src/binaryTree.ts index 9750fef65bf..59956948407 100644 --- a/packages/util/src/binaryTree.ts +++ b/packages/util/src/binaryTree.ts @@ -7,7 +7,6 @@ import { intToBytes, setLengthLeft, setLengthRight, - toBytes, } from './bytes.ts' import type { Account } from './account.ts' @@ -173,7 +172,7 @@ export const getBinaryTreeKeyForCodeChunk = ( hashFunction: (input: Uint8Array) => Uint8Array, ) => { const { treeIndex, subIndex } = getBinaryTreeIndicesForCodeChunk(chunkId) - return concatBytes(getBinaryTreeStem(hashFunction, address, treeIndex), toBytes(subIndex)) + return concatBytes(getBinaryTreeStem(hashFunction, address, treeIndex), intToBytes(subIndex)) } // This code was written by robots based on the reference implementation in EIP-7864 diff --git a/packages/util/src/bytes.ts b/packages/util/src/bytes.ts index c7dd3834107..bd9d1a20696 100644 --- a/packages/util/src/bytes.ts +++ b/packages/util/src/bytes.ts @@ -24,7 +24,7 @@ export const bytesToUnprefixedHex = _bytesToUnprefixedHex * @returns {Uint8Array} The converted bytes * @throws If the input is not a valid 0x-prefixed hex string */ -export const hexToBytes = (hex: string): Uint8Array => { +export const hexToBytes = (hex: PrefixedHexString): Uint8Array => { if (!hex.startsWith('0x')) throw EthereumJSErrorWithoutCode('input string must be 0x prefixed') return nobleH2B(padToEven(stripHexPrefix(hex))) } @@ -34,8 +34,13 @@ export const unprefixedHexToBytes = (hex: string): Uint8Array => { return nobleH2B(padToEven(hex)) } +/** + * Converts a {@link Uint8Array} to a {@link PrefixedHexString} + * @param {Uint8Array} bytes the bytes to convert + * @returns {PrefixedHexString} the hex string + * @dev Returns `0x` if provided an empty Uint8Array + */ export const bytesToHex = (bytes: Uint8Array): PrefixedHexString => { - if (bytes === undefined || bytes.length === 0) return '0x' const unprefixedHex = bytesToUnprefixedHex(bytes) return `0x${unprefixedHex}` } @@ -92,7 +97,7 @@ export const intToHex = (i: number): PrefixedHexString => { if (!Number.isSafeInteger(i) || i < 0) { throw EthereumJSErrorWithoutCode(`Received an invalid integer type: ${i}`) } - return ('0x' + i.toString(16)) as PrefixedHexString + return `0x${i.toString(16)}` } /** @@ -111,7 +116,7 @@ export const intToBytes = (i: number): Uint8Array => { * @returns {Uint8Array} */ export const bigIntToBytes = (num: bigint, littleEndian = false): Uint8Array => { - const bytes = toBytes(`0x${padToEven(num.toString(16))}`) + const bytes = hexToBytes(`0x${padToEven(num.toString(16))}`) return littleEndian ? bytes.reverse() : bytes } diff --git a/packages/util/src/signature.ts b/packages/util/src/signature.ts index 25cc264400a..8b6eb9fe7ae 100644 --- a/packages/util/src/signature.ts +++ b/packages/util/src/signature.ts @@ -2,12 +2,13 @@ import { keccak256 } from 'ethereum-cryptography/keccak.js' import { secp256k1 } from 'ethereum-cryptography/secp256k1.js' import { + bigIntToBytes, bytesToBigInt, bytesToHex, bytesToInt, concatBytes, + hexToBytes, setLengthLeft, - toBytes, utf8ToBytes, } from './bytes.ts' import { @@ -77,7 +78,7 @@ export const toRPCSig = function ( // geth (and the RPC eth_sign method) uses the 65 byte format used by Bitcoin - return bytesToHex(concatBytes(setLengthLeft(r, 32), setLengthLeft(s, 32), toBytes(v))) + return bytesToHex(concatBytes(setLengthLeft(r, 32), setLengthLeft(s, 32), bigIntToBytes(v))) } /** @@ -117,7 +118,7 @@ export const fromRPCSig = function (sig: PrefixedHexString): { r: Uint8Array s: Uint8Array } { - const bytes: Uint8Array = toBytes(sig) + const bytes: Uint8Array = hexToBytes(sig) let r: Uint8Array let s: Uint8Array diff --git a/packages/util/src/verkle.ts b/packages/util/src/verkle.ts index 7acb0b37792..3de4e9418f6 100644 --- a/packages/util/src/verkle.ts +++ b/packages/util/src/verkle.ts @@ -7,7 +7,6 @@ import { intToBytes, setLengthLeft, setLengthRight, - toBytes, } from './bytes.ts' import type { Account } from './account.ts' @@ -237,7 +236,7 @@ export const getVerkleTreeKeyForCodeChunk = async ( verkleCrypto: VerkleCrypto, ) => { const { treeIndex, subIndex } = getVerkleTreeIndicesForCodeChunk(chunkId) - return concatBytes(getVerkleStem(verkleCrypto, address, treeIndex), toBytes(subIndex)) + return concatBytes(getVerkleStem(verkleCrypto, address, treeIndex), intToBytes(subIndex)) } // This code was written by robots based on the reference implementation in EIP-6800 @@ -295,7 +294,7 @@ export const getVerkleTreeKeyForStorageSlot = async ( ) => { const { treeIndex, subIndex } = getVerkleTreeIndicesForStorageSlot(storageKey) - return concatBytes(getVerkleStem(verkleCrypto, address, treeIndex), toBytes(subIndex)) + return concatBytes(getVerkleStem(verkleCrypto, address, treeIndex), intToBytes(subIndex)) } /** diff --git a/packages/util/test/account.spec.ts b/packages/util/test/account.spec.ts index 79b01bcc9dd..4757413a231 100644 --- a/packages/util/test/account.spec.ts +++ b/packages/util/test/account.spec.ts @@ -9,6 +9,7 @@ import { accountBodyFromSlim, accountBodyToRLP, accountBodyToSlim, + bigIntToBytes, bigIntToUnpaddedBytes, bytesToBigInt, bytesToHex, @@ -33,7 +34,6 @@ import { privateToAddress, privateToPublic, publicToAddress, - toBytes, toChecksumAddress, utf8ToBytes, } from '../src/index.ts' @@ -488,7 +488,7 @@ describe('Utility Functions', () => { it('generateAddress', () => { const addr = generateAddress( utf8ToBytes('990ccf8a0de58091c028d6ff76bb235ee67c1c39'), - toBytes(14), + intToBytes(14), ) assert.equal( bytesToHex(addr), @@ -498,7 +498,10 @@ describe('Utility Functions', () => { }) it('generateAddress with hex prefix', () => { - const addr = generateAddress(toBytes('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39'), toBytes(14)) + const addr = generateAddress( + hexToBytes('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39'), + intToBytes(14), + ) assert.equal( bytesToHex(addr), '0xd658a4b8247c14868f3c512fa5cbb6e458e4a989', @@ -509,7 +512,10 @@ describe('Utility Functions', () => { // cspell:disable it('generateAddress wt.testh nonce 0 (special case)', () => { // cspell:enable - const addr = generateAddress(toBytes('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39'), toBytes(0)) + const addr = generateAddress( + hexToBytes('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39'), + intToBytes(0), + ) assert.equal( bytesToHex(addr), '0xbfa69ba91385206bfdd2d8b9c1a5d6c10097a85b', @@ -524,7 +530,7 @@ describe('Utility Functions', () => { function () { generateAddress( ('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39') as Uint8Array, - toBytes(0), + intToBytes(0), ) }, undefined, @@ -535,7 +541,7 @@ describe('Utility Functions', () => { assert.throws( function () { generateAddress( - toBytes('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39'), + hexToBytes('0x990ccf8a0de58091c028d6ff76bb235ee67c1c39'), (0) as Uint8Array, ) }, @@ -886,7 +892,7 @@ describe('createPartialAccount', () => { describe('createPartialAccountFromRLP', () => { it('should throw an error for invalid serialized account input (non-array)', () => { - const invalidSerialized = toBytes(1n) + const invalidSerialized = bigIntToBytes(1n) assert.throws( () => createPartialAccountFromRLP(invalidSerialized), /Invalid serialized account input/, @@ -897,12 +903,12 @@ describe('createPartialAccountFromRLP', () => { { description: 'should handle a mix of null and non-null values correctly', data: [ - [toBytes(1), toBytes(1)], // Nonce: 1 - [toBytes(0)], // Balance: null - [toBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP - [toBytes(0)], // CodeHash: null - [toBytes(1), toBytes(10)], // CodeSize: 10 - [toBytes(0)], // Version: null + [intToBytes(1), intToBytes(1)], // Nonce: 1 + [intToBytes(0)], // Balance: null + [intToBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP + [intToBytes(0)], // CodeHash: null + [intToBytes(1), intToBytes(10)], // CodeSize: 10 + [intToBytes(0)], // Version: null ], shouldThrow: false, expected: new Account(BigInt(1), null, KECCAK256_RLP, null, 10, null), @@ -911,12 +917,12 @@ describe('createPartialAccountFromRLP', () => { { description: 'should throw when all fields are null', data: [ - [toBytes(0)], // Nonce: null - [toBytes(0)], // Balance: null - [toBytes(0)], // StorageRoot: null - [toBytes(0)], // CodeHash: null - [toBytes(0)], // CodeSize: null - [toBytes(0)], // Version: null + [intToBytes(0)], // Nonce: null + [intToBytes(0)], // Balance: null + [intToBytes(0)], // StorageRoot: null + [intToBytes(0)], // CodeHash: null + [intToBytes(0)], // CodeSize: null + [intToBytes(0)], // Version: null ], shouldThrow: true, expected: null, @@ -925,12 +931,12 @@ describe('createPartialAccountFromRLP', () => { { description: 'should handle all non-null fields correctly', data: [ - [toBytes(1), toBytes(2)], // Nonce: 2 - [toBytes(1), toBytes(1000)], // Balance: 1000 - [toBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP - [toBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP - [toBytes(1), toBytes(50)], // CodeSize: 50 - [toBytes(1), toBytes(1)], // Version: 1 + [intToBytes(1), intToBytes(2)], // Nonce: 2 + [intToBytes(1), intToBytes(1000)], // Balance: 1000 + [intToBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP + [intToBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP + [intToBytes(1), intToBytes(50)], // CodeSize: 50 + [intToBytes(1), intToBytes(1)], // Version: 1 ], shouldThrow: false, expected: new Account(BigInt(2), BigInt(1000), KECCAK256_RLP, KECCAK256_RLP, 50, 1), @@ -940,12 +946,12 @@ describe('createPartialAccountFromRLP', () => { description: 'should return partial account with non-null fields when isNotNullIndicator is 1', data: [ - [toBytes(1), toBytes(2)], // Nonce: 2 - [toBytes(1), toBytes(1000)], // Balance: 1000 - [toBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP - [toBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP - [toBytes(1), toBytes(50)], // CodeSize: 50 - [toBytes(1), toBytes(1)], // Version: 1 + [intToBytes(1), intToBytes(2)], // Nonce: 2 + [intToBytes(1), intToBytes(1000)], // Balance: 1000 + [intToBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP + [intToBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP + [intToBytes(1), intToBytes(50)], // CodeSize: 50 + [intToBytes(1), intToBytes(1)], // Version: 1 ], shouldThrow: false, expected: new Account(BigInt(2), BigInt(1000), KECCAK256_RLP, KECCAK256_RLP, 50, 1), @@ -954,12 +960,12 @@ describe('createPartialAccountFromRLP', () => { { description: 'should return a mix of null and non-null fields based on isNotNullIndicator', data: [ - [toBytes(1), toBytes(2)], // Nonce: 2 - [toBytes(0)], // Balance: null - [toBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP - [toBytes(0)], // CodeHash: null - [toBytes(1), toBytes(50)], // CodeSize: 50 - [toBytes(0)], // Version: null + [intToBytes(1), intToBytes(2)], // Nonce: 2 + [intToBytes(0)], // Balance: null + [intToBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP + [intToBytes(0)], // CodeHash: null + [intToBytes(1), intToBytes(50)], // CodeSize: 50 + [intToBytes(0)], // Version: null ], shouldThrow: false, expected: new Account(BigInt(2), null, KECCAK256_RLP, null, 50, null), @@ -969,12 +975,12 @@ describe('createPartialAccountFromRLP', () => { description: 'should handle cases where some fields are non-null and others are null correctly', data: [ - [toBytes(1), toBytes(2)], // Nonce: 2 - [toBytes(0)], // Balance: null - [toBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP - [toBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP - [toBytes(0)], // CodeSize: null - [toBytes(0)], // Version: null + [intToBytes(1), intToBytes(2)], // Nonce: 2 + [intToBytes(0)], // Balance: null + [intToBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP + [intToBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP + [intToBytes(0)], // CodeSize: null + [intToBytes(0)], // Version: null ], shouldThrow: false, expected: new Account(BigInt(2), null, KECCAK256_RLP, KECCAK256_RLP, null, null), @@ -984,7 +990,7 @@ describe('createPartialAccountFromRLP', () => { description: 'should handle fields with empty arrays (isNullIndicator=0) correctly', data: [ [], // nonce -> empty array => null - [toBytes(1), toBytes(1000)], // balance: 1000 + [intToBytes(1), intToBytes(1000)], // balance: 1000 [], // storageRoot -> null [], // codeHash -> null [], // codeSize -> null @@ -999,84 +1005,84 @@ describe('createPartialAccountFromRLP', () => { data: [KECCAK256_RLP, [], [], [], [], []], shouldThrow: true, expected: null, - errorRegex: /Invalid partial nonce encoding/, + errorRegex: /Invalid partial encoding. Each item must be an array/, }, { description: 'should throw: invalid partial balance encoding', data: [[], KECCAK256_RLP, [], [], [], []], shouldThrow: true, expected: null, - errorRegex: /Invalid partial balance encoding/, + errorRegex: /Invalid partial encoding. Each item must be an array/, }, { description: 'should throw: invalid partial storageRoot encoding', data: [[], [], KECCAK256_RLP, [], [], []], shouldThrow: true, expected: null, - errorRegex: /Invalid partial storageRoot encoding/, + errorRegex: /Invalid partial encoding. Each item must be an array/, }, { description: 'should throw: invalid partial codeHash encoding', data: [[], [], [], KECCAK256_RLP, [], []], shouldThrow: true, expected: null, - errorRegex: /Invalid partial codeHash encoding/, + errorRegex: /Invalid partial encoding. Each item must be an array/, }, { description: 'should throw: invalid partial codeSize encoding', data: [[], [], [], [], KECCAK256_RLP, []], shouldThrow: true, expected: null, - errorRegex: /Invalid partial codeSize encoding/, + errorRegex: /Invalid partial encoding. Each item must be an array/, }, { description: 'should throw: invalid partial version encoding', data: [[], [], [], [], [], KECCAK256_RLP], shouldThrow: true, expected: null, - errorRegex: /Invalid partial version encoding/, + errorRegex: /Invalid partial encoding. Each item must be an array/, }, { description: 'should throw: invalid isNullIndicator=2 for nonce', - data: [[toBytes(2)], [], [], [], [], []], + data: [[intToBytes(2)], [], [], [], [], []], shouldThrow: true, expected: null, - errorRegex: /Invalid isNullIndicator=2 for nonce/, + errorRegex: /Invalid isNullIndicator=2/, }, { description: 'should throw: invalid isNullIndicator=2 for balance', - data: [[], [toBytes(2)], [], [], [], []], + data: [[], [intToBytes(2)], [], [], [], []], shouldThrow: true, expected: null, - errorRegex: /Invalid isNullIndicator=2 for balance/, + errorRegex: /Invalid isNullIndicator=2/, }, { description: 'should throw: invalid isNullIndicator=2 for storageRoot', - data: [[], [], [toBytes(2)], [], [], []], + data: [[], [], [intToBytes(2)], [], [], []], shouldThrow: true, expected: null, - errorRegex: /Invalid isNullIndicator=2 for storageRoot/, + errorRegex: /Invalid isNullIndicator=2/, }, { description: 'should throw: invalid isNullIndicator=2 for codeHash', - data: [[], [], [], [toBytes(2)], [], []], + data: [[], [], [], [intToBytes(2)], [], []], shouldThrow: true, expected: null, - errorRegex: /Invalid isNullIndicator=2 for codeHash/, + errorRegex: /Invalid isNullIndicator=2/, }, { description: 'should throw: invalid isNullIndicator=2 for codeSize', - data: [[], [], [], [], [toBytes(2)], []], + data: [[], [], [], [], [intToBytes(2)], []], shouldThrow: true, expected: null, - errorRegex: /Invalid isNullIndicator=2 for codeSize/, + errorRegex: /Invalid isNullIndicator=2/, }, { description: 'should throw: invalid isNullIndicator=2 for version', - data: [[], [], [], [], [], [toBytes(2)]], + data: [[], [], [], [], [], [intToBytes(2)]], shouldThrow: true, expected: null, - errorRegex: /Invalid isNullIndicator=2 for version/, + errorRegex: /Invalid isNullIndicator=2/, }, ] @@ -1111,23 +1117,23 @@ describe('serializeWithPartialInfo', () => { description: 'should serialize all fields as non-null (isNotNullIndicator=1)', account: new Account(BigInt(2), Units.ether(1), KECCAK256_RLP, KECCAK256_RLP, 50, 1), expectedDecoded: [ - [toBytes(1), bigIntToUnpaddedBytes(BigInt(2))], // Nonce: 2 - [toBytes(1), bigIntToUnpaddedBytes(Units.ether(1))], // Balance: 1000 - [toBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP - [toBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP - [toBytes(1), intToUnpaddedBytes(50)], // CodeSize: 50 - [toBytes(1), intToUnpaddedBytes(1)], // Version: 1 + [intToBytes(1), bigIntToUnpaddedBytes(BigInt(2))], // Nonce: 2 + [intToBytes(1), bigIntToUnpaddedBytes(Units.ether(1))], // Balance: 1000 + [intToBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP + [intToBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP + [intToBytes(1), intToUnpaddedBytes(50)], // CodeSize: 50 + [intToBytes(1), intToUnpaddedBytes(1)], // Version: 1 ], }, { description: 'should serialize mixed null and non-null fields', account: new Account(BigInt(2), null, KECCAK256_RLP, null, 50, null), expectedDecoded: [ - [toBytes(1), bigIntToUnpaddedBytes(BigInt(2))], // Nonce: 2 + [intToBytes(1), bigIntToUnpaddedBytes(BigInt(2))], // Nonce: 2 [new Uint8Array()], // Balance: null - [toBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP + [intToBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP [new Uint8Array()], // CodeHash: null - [toBytes(1), intToUnpaddedBytes(50)], // CodeSize: 50 + [intToBytes(1), intToUnpaddedBytes(50)], // CodeSize: 50 [new Uint8Array()], // Version: null ], }, @@ -1136,24 +1142,24 @@ describe('serializeWithPartialInfo', () => { 'should correctly handle serialization of null hash for storageRoot and codeHash', account: new Account(BigInt(2), Units.ether(1), KECCAK256_RLP, KECCAK256_RLP, 50, 1), expectedDecoded: [ - [toBytes(1), bigIntToUnpaddedBytes(BigInt(2))], // Nonce: 2 - [toBytes(1), bigIntToUnpaddedBytes(Units.ether(1))], // Balance: 1000 - [toBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP - [toBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP - [toBytes(1), intToUnpaddedBytes(50)], // CodeSize: 50 - [toBytes(1), intToUnpaddedBytes(1)], // Version: 1 + [intToBytes(1), bigIntToUnpaddedBytes(BigInt(2))], // Nonce: 2 + [intToBytes(1), bigIntToUnpaddedBytes(Units.ether(1))], // Balance: 1000 + [intToBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP + [intToBytes(1), KECCAK256_RLP], // CodeHash: KECCAK256_RLP + [intToBytes(1), intToUnpaddedBytes(50)], // CodeSize: 50 + [intToBytes(1), intToUnpaddedBytes(1)], // Version: 1 ], }, { description: 'should correctly serialize when only some fields are provided', account: new Account(BigInt(123), null, KECCAK256_RLP, null, null, 42), expectedDecoded: [ - [toBytes(1), bigIntToUnpaddedBytes(BigInt(123))], // Nonce: 123 + [intToBytes(1), bigIntToUnpaddedBytes(BigInt(123))], // Nonce: 123 [new Uint8Array()], // Balance: null - [toBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP + [intToBytes(1), KECCAK256_RLP], // StorageRoot: KECCAK256_RLP [new Uint8Array()], // CodeHash: null [new Uint8Array()], // CodeSize: null - [toBytes(1), intToUnpaddedBytes(42)], // Version: 42 + [intToBytes(1), intToUnpaddedBytes(42)], // Version: 42 ], }, ] diff --git a/packages/util/test/address.spec.ts b/packages/util/test/address.spec.ts index 37d9490303b..bc48d9e01a0 100644 --- a/packages/util/test/address.spec.ts +++ b/packages/util/test/address.spec.ts @@ -11,7 +11,6 @@ import { createZeroAddress, equalsBytes, hexToBytes, - toBytes, } from '../src/index.ts' import { eip1404ExamplesData } from './testdata/eip1014Examples.ts' @@ -26,13 +25,13 @@ describe('Address', () => { assert.throws(() => createAddressFromString(str)) const shortStr = '0x2f015c60e0be116b1f0cd534704db9c92118fb' assert.throws(() => createAddressFromString(shortStr)) - const buf = toBytes(str) + const buf = hexToBytes(str) assert.throws(() => new Address(buf)) }) it('should generate a zero address', () => { const addr = createZeroAddress() - assert.deepEqual(addr.bytes, toBytes(ZERO_ADDR_S)) + assert.deepEqual(addr.bytes, hexToBytes(ZERO_ADDR_S)) assert.equal(addr.toString(), ZERO_ADDR_S) }) diff --git a/packages/util/test/bytes.spec.ts b/packages/util/test/bytes.spec.ts index db50cde211e..521551b6b41 100644 --- a/packages/util/test/bytes.spec.ts +++ b/packages/util/test/bytes.spec.ts @@ -58,9 +58,9 @@ describe('is zero address', () => { describe('unpadBytes', () => { it('should unpad a Uint8Array', () => { - const bytes = toBytes('0x0000000006600') + const bytes = hexToBytes('0x0000000006600') const r = unpadBytes(bytes) - assert.deepEqual(r, toBytes('0x6600')) + assert.deepEqual(r, hexToBytes('0x6600')) }) it('should throw if input is not a Uint8Array', () => { assert.throws(function () { @@ -251,8 +251,10 @@ describe('toBytes', () => { }) it('should fail with non 0x-prefixed hex strings', () => { - assert.throws(() => toBytes('11' as any), '11') - assert.throws(() => toBytes('' as any)) + // @ts-expect-error -- Testing wrong input + assert.throws(() => toBytes('11'), '11') + // @ts-expect-error -- Testing wrong input + assert.throws(() => toBytes('')) assert.throws(() => toBytes('0xR'), '0xR') }) @@ -308,19 +310,19 @@ describe('intToBytes and intToHex', () => { describe('validateNoLeadingZeroes', () => { const noLeadingZeroes = { - a: toBytes('0x123'), + a: hexToBytes('0x123'), } const noLeadingZeroBytes = { - a: toBytes('0x01'), + a: hexToBytes('0x01'), } const leadingZeroBytes = { - a: toBytes('0x001'), + a: hexToBytes('0x001'), } const onlyZeroes = { - a: toBytes('0x0'), + a: hexToBytes('0x0'), } const emptyBuffer = { - a: toBytes('0x'), + a: hexToBytes('0x'), } const undefinedValue = { @@ -364,7 +366,7 @@ describe('validateNoLeadingZeroes', () => { describe('bytesToBigInt', () => { it('should pass on correct input', () => { - const buf = toBytes('0x123') + const buf = hexToBytes('0x123') assert.equal(BigInt(0x123), bytesToBigInt(buf)) }) }) @@ -372,7 +374,7 @@ describe('bytesToBigInt', () => { describe('bigIntToBytes', () => { it('should pass on correct input', () => { const num = BigInt(0x123) - assert.deepEqual(toBytes('0x123'), bigIntToBytes(num)) + assert.deepEqual(hexToBytes('0x123'), bigIntToBytes(num)) }) }) diff --git a/packages/util/test/types.spec.ts b/packages/util/test/types.spec.ts index b2c5b7423ba..5feaaefe492 100644 --- a/packages/util/test/types.spec.ts +++ b/packages/util/test/types.spec.ts @@ -6,9 +6,9 @@ import { bigIntToHex, bytesToBigInt, bytesToHex, + hexToBytes, intToBytes, intToHex, - toBytes, toType, } from '../src/index.ts' @@ -91,7 +91,7 @@ describe('toType', () => { assert.strictEqual(bigIntToHex(result), num) result = toType(num, TypeOutput.Uint8Array) - assert.deepEqual(result, toBytes(num)) + assert.deepEqual(result, hexToBytes(num)) assert.throws(() => { //@ts-expect-error -- Testing invalid input diff --git a/packages/verkle/README.md b/packages/verkle/README.md index a7472b380cd..1e490db988e 100644 --- a/packages/verkle/README.md +++ b/packages/verkle/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/verkle +# @ethereumjs/verkle `v10` [![NPM Package][verkle-npm-badge]][verkle-npm-link] [![GitHub Issues][verkle-issues-badge]][verkle-issues-link] @@ -13,6 +13,18 @@ This package is currently in early alpha and is a work in progress. It is not intended for use in production environments, but rather for research and development purposes. Any help in improving the package is very much welcome. +## Table of Contents + +- [Installation](#installation) +- [Getting Started](#getting-started) +- [Proofs](#proofs) +- [Browser](#browser) +- [API](#api) +- [Debugging](#debugging) +- [References](#references) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Installation To obtain the latest version, simply require the project using `npm`: @@ -21,7 +33,7 @@ To obtain the latest version, simply require the project using `npm`: npm install @ethereumjs/verkle ``` -## Usage +## Getting Started ### Initialization diff --git a/packages/verkle/test/util.spec.ts b/packages/verkle/test/util.spec.ts index b72e97e1a81..89fac9627b0 100644 --- a/packages/verkle/test/util.spec.ts +++ b/packages/verkle/test/util.spec.ts @@ -1,11 +1,11 @@ -import { bytesToHex, hexToBytes } from '@ethereumjs/util' +import { type PrefixedHexString, bytesToHex, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { createVerkleTree } from '../src/index.ts' import { dumpLeafValues, dumpNodeHashes } from '../src/util.ts' // Values taken from verkle fixtures -const values = [ +const values: PrefixedHexString[][] = [ [ '0x0365b079a274a1808d56484ce5bd97914629907d75767f51439102e22cd50d00', '0x00000000000000000000000000000001000000000000003635c9adc5de9ccbaa', diff --git a/packages/vm/README.md b/packages/vm/README.md index a9d4c0d7732..034e33bfe86 100644 --- a/packages/vm/README.md +++ b/packages/vm/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/vm +# @ethereumjs/vm `v10` [![NPM Package][vm-npm-badge]][vm-npm-link] [![GitHub Issues][vm-issues-badge]][vm-issues-link] @@ -18,6 +18,23 @@ and update a blockchain state accordingly. Note that up till `v5` this package also was the bundled package for the EVM implementation itself. +## Table of Contents + +- [Installation](#installation) +- [Usage](#usage) +- [Examples](#examples) +- [Browser](#browser) +- [API](#api) +- [Architecture](#architecture) +- [Setup](#setup) +- [Supported EIPs](#supported-eips) +- [Events](#events) +- [Understanding the VM](#understanding-the-vm) +- [Internal Structure](#internal-structure) +- [Development](#development) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Installation To obtain the latest version, simply require the project using `npm`: @@ -26,7 +43,7 @@ To obtain the latest version, simply require the project using `npm`: npm install @ethereumjs/vm ``` -**Note:** Starting with the Dencun hardfork `EIP-4844` related functionality will become an integrated part of the EVM functionality with the activation of the point evaluation precompile. It is therefore strongly recommended to _always_ run the EVM with a KZG library installed and initialized, see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions. +**Note:** Starting with the Dencun hardfork `EIP-4844` related functionality has become an integrated part of the EVM functionality with the activation of the point evaluation precompile. For this precompile to work a separate installation of the KGZ library is necessary (we decided not to bundle due to large bundle sizes), see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions. ## Usage @@ -62,8 +79,6 @@ void main() Additionally to the `VM.runTx()` method there is an API method `VM.runBlock()` which allows to run the whole block and execute all included transactions along. -Note: with the switch from v7 to v8 the old direct `new VM()` constructor usage has been fully deprecated and a `VM` can now solely be instantiated with the async static `VM.create()` constructor. This also goes for the underlying `EVM` if you use a custom `EVM`. - ### Building a Block The VM package can also be used to construct a new valid block by executing and then integrating txs one-by-one. @@ -122,14 +137,12 @@ void main() This library by default uses JavaScript implementations for the basic standard crypto primitives like hashing or signature verification (for included txs). See `@ethereumjs/common` [README](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/common) for instructions on how to replace with e.g. a more performant WASM implementation by using a shared `common` instance. -## Example +## Examples -This projects contain the following examples: +See the [examples](./examples/) folder for different meaningful examples on how to use the VM package and invoke certain aspects of it, e.g. running a complete block, a certain tx or using event listeners, among others. Some noteworthy examples to point out: 1. [./examples/run-blockchain](./examples/run-blockchain.ts): Loads tests data, including accounts and blocks, and runs all of them in the VM. -1. [./examples/run-solidity-contract](./examples/run-solidity-contract.ts): Compiles a Solidity contract, and calls constant and non-constant functions. - -All of the examples have their own `README.md` explaining how to run them. +2. [./examples/run-solidity-contract](./examples/run-solidity-contract.ts): Compiles a Solidity contract, and calls constant and non-constant functions. ## Browser @@ -186,44 +199,10 @@ With `VM` v6 the previously included `StateManager` has been extracted to its ow ## Setup -### Chain Support - -Starting with `v5.1.0` the VM supports running both `Ethash/PoW` and `Clique/PoA` blocks and transactions. Clique support has been added along the work on PR [#1032](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1032) and follow-up PRs and (block) validation checks and the switch of the execution context now happens correctly. - -### Ethash/PoW Chains - -`@ethereumjs/blockchain` validates the PoW algorithm with `@ethereumjs/ethash` and validates blocks' difficulty to match their canonical difficulty. - -### Clique/PoA Chains - -The following is a simple example for a block run on `Goerli`: - -```ts -// ./examples/runGoerliBlock.ts - -import { createBlockFromRPC } from '@ethereumjs/block' -import { Common } from '@ethereumjs/common' -import { bytesToHex } from '@ethereumjs/util' - -import { createVM, runBlock } from '../src/index.ts' -import { Goerli } from '../test/api/testdata/goerliCommon.ts' +### Chains +Beside the default Proof-of-Stake setup coming with the `Common` library default, the VM also support the execution of both `Ethash/PoW` and `Clique/PoA` blocks and transactions to allow to re-execute blocks from older hardforks or testnets. -import goerliBlock2 from './testData/goerliBlock2.json' - -const main = async () => { - const common = new Common({ chain: Goerli, hardfork: 'london' }) - const vm = await createVM({ common, setHardfork: true }) - - const block = createBlockFromRPC(goerliBlock2, undefined, { common }) - const result = await runBlock(vm, { block, generate: true, skipHeaderValidation: true }) // we skip header validation since we are running a block without the full Ethereum history available - console.log(`The state root for Goerli block 2 is ${bytesToHex(result.stateRoot)}`) -} - -void main() - -``` - -### Hardfork Support +### Hardforks For hardfork support see the [Hardfork Support](../evm#hardfork-support) section from the underlying `@ethereumjs/evm` instance. @@ -242,13 +221,7 @@ const main = async () => { const vm = await createVM({ common }) ``` -### Custom genesis state support - -#### Genesis in v7 (removed genesis dependency) - -Genesis state was huge and had previously been bundled with the `Blockchain` package with the burden going over to the VM, since `Blockchain` is a dependency. - -Starting with the v7 release genesis state has been removed from `blockchain` and moved into its own auxiliary package [@ethereumjs/genesis](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/genesis), from which it can be included if needed (for most - especially VM - use cases it is not necessary), see PR [#2844](https://github.com/ethereumjs/ethereumjs-monorepo/pull/2844). +### Custom Genesis State For initializing a custom genesis state you can use the `genesisState` constructor option in the `Blockchain` and `VM` library in a similar way this had been done in the `Common` library before. @@ -284,13 +257,7 @@ void main() Genesis state can be configured to contain both EOAs as well as (system) contracts with initial storage values set. -#### Genesis in v6 - -For the v6 release responsibility for setting up a custom genesis state moved from the [Common](../common/) library to the `Blockchain` package, see PR [#1924](https://github.com/ethereumjs/ethereumjs-monorepo/pull/1924) for some work context. - -A genesis state can be set along `Blockchain` creation by passing in a custom `genesisBlock` and `genesisState`. For `mainnet` and the official test networks like `sepolia` or `goerli` genesis is already provided with the block data coming from `@ethereumjs/common`. The genesis state is being integrated in the `Blockchain` library (see `genesisStates` folder). - -### EIP Support +## Supported EIPs It is possible to individually activate EIP support in the VM by instantiate the `Common` instance passed with the respective EIPs, e.g.: @@ -298,67 +265,40 @@ with the respective EIPs, e.g.: ```ts // ./examples/vmWithEIPs.ts -import { Common, Mainnet } from '@ethereumjs/common' +import { Common, Hardfork, Mainnet } from '@ethereumjs/common' import { createVM } from '@ethereumjs/vm' const main = async () => { - const common = new Common({ chain: Mainnet, eips: [7702] }) + const common = new Common({ chain: Mainnet, hardfork: Hardfork.Cancun, eips: [7702] }) const vm = await createVM({ common }) - console.log(`EIP 7702 is active in the VM - ${vm.common.isActivatedEIP(7702)}`) + console.log(`EIP 7702 is active in isolation on top of the Cancun HF - ${vm.common.isActivatedEIP(7702)}`) } void main() ``` For a list with supported EIPs see the [@ethereumjs/evm](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/evm) documentation. -### EIP-4844 Shard Blob Transactions Support - -This library supports the blob transaction type introduced with [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844). +### EIP-4844 Shard Blob Transactions Support (Cancun) -### EIP-7702 EAO Code Transactions Support (outdated) +This library supports the blob transaction type introduced with [EIP-4844](https://eips.ethereum.org/EIPS/eip-4844). EIP-4844 comes with a dedicated opcode `BLOBHASH` and has added a new point evaluation precompile at address `0x0a`. -This library support the execution of [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) EOA code transactions (see tx library for full documentation) with `runTx()` or the wrapping `runBlock()` execution methods starting with `v3.1.0`, see [this test setup](https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/vm/test/api/EIPs/eip-7702.spec.ts) for a more complete example setup on how to run code from an EOA. +**Note:** Usage of the point evaluation precompile needs a manual KZG library installation and global initialization, see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions. -Note: Things move fast with `EIP-7702` and the currently released implementation is based on [this](https://github.com/ethereum/EIPs/blob/14400434e1199c57d912082127b1d22643788d11/EIPS/eip-7702.md) commit and therefore already outdated. An up-to-date version will be released along our breaking release round planned for early September 2024. +### EIP-7702 EAO Code Transactions Support (Prague) -### EIP-7685 Requests Support +This library support the execution of [EIP-7702](https://eips.ethereum.org/EIPS/eip-7702) EOA code transactions (see tx library for full documentation) with `runTx()` or the wrapping `runBlock()` execution methods, see [this test setup](https://github.com/ethereumjs/ethereumjs-monorepo/blob/master/packages/vm/test/api/EIPs/eip-7702.spec.ts) for a more complete example setup on how to run code from an EOA. -This library supports blocks including the following [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685) requests: +### EIP-7685 Requests Support (Prague) -- [EIP-6110](https://eips.ethereum.org/EIPS/eip-6110) - Deposit Requests (`v7.3.0`+) -- [EIP-7002](https://eips.ethereum.org/EIPS/eip-7002) - Withdrawal Requests (`v7.3.0`+) -- [EIP-7251](https://eips.ethereum.org/EIPS/eip-7251) - Consolidation Requests (`v7.3.0`+) +This library supports blocks including [EIP-7685](https://eips.ethereum.org/EIPS/eip-7685) requests to the consensus layer. ### EIP-2935 Serve Historical Block Hashes from State (Prague) -Starting with `v8.1.0` the VM supports [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) which stores the latest 8192 block hashes in the storage of a system contract, see PR [#3475](https://github.com/ethereumjs/ethereumjs-monorepo/pull/3475) as the major integration PR (while work on this has already been done in previous PRs). - -This EIP will be activated along the Prague hardfork. Note that this EIP has no effect on the resolution of the `BLOCKHASH` opcode, which will be a separate activation taking place by the integration of [EIP-7709](https://eips.ethereum.org/EIPS/eip-7709) in the following Osaka hardfork. - -#### Initialization - -To run VM/EVM related EIP-4844 functionality you have to activate the EIP in the associated `@ethereumjs/common` library: - -```ts -// ./examples/vmWith4844.ts - -import { Common, Hardfork, Mainnet } from '@ethereumjs/common' - -import { createVM } from '../src/index.ts' - -const main = async () => { - const common = new Common({ chain: Mainnet, hardfork: Hardfork.Shanghai, eips: [4844] }) - const vm = await createVM({ common }) - console.log(`4844 is active in the VM - ${vm.common.isActivatedEIP(4844)}`) -} - -void main() - -``` +Starting with `v8.1.0` the VM supports [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) which stores the latest 8192 block hashes in the storage of a system contract. -EIP-4844 comes with a new opcode `BLOBHASH` and adds a new point evaluation precompile at address `0x14` in the underlying `@ethereumjs/evm` package. +Note that this EIP has no effect on the resolution of the `BLOCKHASH` opcode, which will be a separate activation taking place by the integration of [EIP-7709](https://eips.ethereum.org/EIPS/eip-7709) in a respective Verkle/Stateless hardfork. -**Note:** Usage of the point evaluation precompile needs a manual KZG library installation and global initialization, see [KZG Setup](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/tx/README.md#kzg-setup) for instructions. +## Events ### Tracing Events @@ -390,7 +330,7 @@ vm.events.on('afterTx', (event) => { Please note that there are additional EVM-specific events in the [@ethereumjs/evm](https://github.com/ethereumjs/ethereumjs-monorepo/tree/master/packages/evm) package. -#### Asynchronous event handlers +### Asynchronous event handlers You can perform asynchronous operations from within an event handler and prevent the VM to keep running until they finish. @@ -404,7 +344,7 @@ handler or a function called by it, the exception will bubble into the VM and interrupt it, possibly corrupting its state. It's strongly recommended not to do that. -#### Synchronous event handlers +### Synchronous event handlers If you want to perform synchronous operations, you don't need to receive a function as the handler's second argument, nor call it. diff --git a/packages/vm/examples/helpers/blockchain-mock-data.json b/packages/vm/examples/helpers/blockchain-mock-data.json deleted file mode 100644 index 7a16b1f9a33..00000000000 --- a/packages/vm/examples/helpers/blockchain-mock-data.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "_info": { - "comment": "", - "filledwith": "cpp-1.3.0+commit.70e7d177.Linux.g++", - "source": "../../tests/src/BlockchainTestsFiller/bcValidBlockTest/SimpleTxFiller.json" - }, - "blocks": [ - { - "blockHeader": { - "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty": "0x020000", - "extraData": "", - "gasLimit": "0x2fefd8", - "gasUsed": "0x5208", - "hash": "0x117545e24e3d1e1836bb92e3d6f3e77ac5b2ecd171a535830bf9b5afb8f522e5", - "mixHash": "0x0a55dc80ced5e71738a5a15e12f63be192a65c5cb257f8ee10c875c9599b5b52", - "nonce": "0xba58e9414abfa06f", - "number": "0x01", - "parentHash": "0x7285abd5b24742f184ad676e31f6054663b3529bc35ea2fcad8a3e0f642a46f7", - "receiptTrie": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "stateRoot": "0xecc60e00b3fe5ce9f6e1a10e5469764daf51f1fe93c22ec3f9a7583a80357217", - "timestamp": "0x59af0178", - "transactionsTrie": "0x53d5b71a8fbb9590de82d69dfa4ac31923b0c8afce0d30d0d8d1e931f25030dc", - "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "rlp": "0xf90260f901f9a07285abd5b24742f184ad676e31f6054663b3529bc35ea2fcad8a3e0f642a46f7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ecc60e00b3fe5ce9f6e1a10e5469764daf51f1fe93c22ec3f9a7583a80357217a053d5b71a8fbb9590de82d69dfa4ac31923b0c8afce0d30d0d8d1e931f25030dca0056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd88252088459af017880a00a55dc80ced5e71738a5a15e12f63be192a65c5cb257f8ee10c875c9599b5b5288ba58e9414abfa06ff861f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0f3266921c93d600c43f6fa4724b7abae079b35b9e95df592f95f9f3445e94c88a012f977552ebdb7a492cf35f3106df16ccb4576ebad4113056ee1f52cbe4978c1c0", - "transactions": [ - { - "data": "", - "gasLimit": "0xc350", - "gasPrice": "0x0a", - "nonce": "0x00", - "r": "0xf3266921c93d600c43f6fa4724b7abae079b35b9e95df592f95f9f3445e94c88", - "s": "0x12f977552ebdb7a492cf35f3106df16ccb4576ebad4113056ee1f52cbe4978c1", - "to": "0x095e7baea6a6c7c4c2dfeb977efac326af552d87", - "v": "0x1b", - "value": "0x0a" - } - ], - "uncleHeaders": [] - } - ], - "genesisBlockHeader": { - "bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "coinbase": "0x8888f1f195afa192cfee860698584c030f4c9db1", - "difficulty": "0x020000", - "extraData": "0x42", - "gasLimit": "0x2fefd8", - "gasUsed": "0x00", - "hash": "0x7285abd5b24742f184ad676e31f6054663b3529bc35ea2fcad8a3e0f642a46f7", - "mixHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "nonce": "0x0102030405060708", - "number": "0x00", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "stateRoot": "0xcafd881ab193703b83816c49ff6c2bf6ba6f464a1be560c42106128c8dbc35e7", - "timestamp": "0x54c98c81", - "transactionsTrie": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncleHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" - }, - "genesisRLP": "0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0cafd881ab193703b83816c49ff6c2bf6ba6f464a1be560c42106128c8dbc35e7a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0", - "lastblockhash": "0x117545e24e3d1e1836bb92e3d6f3e77ac5b2ecd171a535830bf9b5afb8f522e5", - "network": "Byzantium", - "postState": { - "0x095e7baea6a6c7c4c2dfeb977efac326af552d87": { - "balance": "0x0a", - "code": "", - "nonce": "0x00", - "storage": {} - }, - "0x8888f1f195afa192cfee860698584c030f4c9db1": { - "balance": "0x29a2241af62f3450", - "code": "", - "nonce": "0x00", - "storage": {} - }, - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { - "balance": "0x025408afa6", - "code": "", - "nonce": "0x01", - "storage": {} - } - }, - "pre": { - "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { - "balance": "0x02540be400", - "code": "", - "nonce": "0x00", - "storage": {} - } - } -} diff --git a/packages/vm/examples/helpers/blockchain-mock-data.ts b/packages/vm/examples/helpers/blockchain-mock-data.ts new file mode 100644 index 00000000000..b4838cc9f42 --- /dev/null +++ b/packages/vm/examples/helpers/blockchain-mock-data.ts @@ -0,0 +1,96 @@ +export const blockchainMockData = { + _info: { + comment: '', + filledwith: 'cpp-1.3.0+commit.70e7d177.Linux.g++', + source: '../../tests/src/BlockchainTestsFiller/bcValidBlockTest/SimpleTxFiller.json', + }, + blocks: [ + { + blockHeader: { + bloom: + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + coinbase: '0x8888f1f195afa192cfee860698584c030f4c9db1', + difficulty: '0x020000', + extraData: '', + gasLimit: '0x2fefd8', + gasUsed: '0x5208', + hash: '0x117545e24e3d1e1836bb92e3d6f3e77ac5b2ecd171a535830bf9b5afb8f522e5', + mixHash: '0x0a55dc80ced5e71738a5a15e12f63be192a65c5cb257f8ee10c875c9599b5b52', + nonce: '0xba58e9414abfa06f', + number: '0x01', + parentHash: '0x7285abd5b24742f184ad676e31f6054663b3529bc35ea2fcad8a3e0f642a46f7', + receiptTrie: '0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2', + stateRoot: '0xecc60e00b3fe5ce9f6e1a10e5469764daf51f1fe93c22ec3f9a7583a80357217', + timestamp: '0x59af0178', + transactionsTrie: '0x53d5b71a8fbb9590de82d69dfa4ac31923b0c8afce0d30d0d8d1e931f25030dc', + uncleHash: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', + }, + rlp: '0xf90260f901f9a07285abd5b24742f184ad676e31f6054663b3529bc35ea2fcad8a3e0f642a46f7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ecc60e00b3fe5ce9f6e1a10e5469764daf51f1fe93c22ec3f9a7583a80357217a053d5b71a8fbb9590de82d69dfa4ac31923b0c8afce0d30d0d8d1e931f25030dca0056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd88252088459af017880a00a55dc80ced5e71738a5a15e12f63be192a65c5cb257f8ee10c875c9599b5b5288ba58e9414abfa06ff861f85f800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d870a801ba0f3266921c93d600c43f6fa4724b7abae079b35b9e95df592f95f9f3445e94c88a012f977552ebdb7a492cf35f3106df16ccb4576ebad4113056ee1f52cbe4978c1c0', + transactions: [ + { + data: '', + gasLimit: '0xc350', + gasPrice: '0x0a', + nonce: '0x00', + r: '0xf3266921c93d600c43f6fa4724b7abae079b35b9e95df592f95f9f3445e94c88', + s: '0x12f977552ebdb7a492cf35f3106df16ccb4576ebad4113056ee1f52cbe4978c1', + to: '0x095e7baea6a6c7c4c2dfeb977efac326af552d87', + v: '0x1b', + value: '0x0a', + }, + ], + uncleHeaders: [], + }, + ], + genesisBlockHeader: { + bloom: + '0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000', + coinbase: '0x8888f1f195afa192cfee860698584c030f4c9db1', + difficulty: '0x020000', + extraData: '0x42', + gasLimit: '0x2fefd8', + gasUsed: '0x00', + hash: '0x7285abd5b24742f184ad676e31f6054663b3529bc35ea2fcad8a3e0f642a46f7', + mixHash: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + nonce: '0x0102030405060708', + number: '0x00', + parentHash: '0x0000000000000000000000000000000000000000000000000000000000000000', + receiptTrie: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + stateRoot: '0xcafd881ab193703b83816c49ff6c2bf6ba6f464a1be560c42106128c8dbc35e7', + timestamp: '0x54c98c81', + transactionsTrie: '0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421', + uncleHash: '0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347', + }, + genesisRLP: + '0xf901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0cafd881ab193703b83816c49ff6c2bf6ba6f464a1be560c42106128c8dbc35e7a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0', + lastblockhash: '0x117545e24e3d1e1836bb92e3d6f3e77ac5b2ecd171a535830bf9b5afb8f522e5', + network: 'Byzantium', + postState: { + '0x095e7baea6a6c7c4c2dfeb977efac326af552d87': { + balance: '0x0a', + code: '', + nonce: '0x00', + storage: {}, + }, + '0x8888f1f195afa192cfee860698584c030f4c9db1': { + balance: '0x29a2241af62f3450', + code: '', + nonce: '0x00', + storage: {}, + }, + '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b': { + balance: '0x025408afa6', + code: '', + nonce: '0x01', + storage: {}, + }, + }, + pre: { + '0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b': { + balance: '0x02540be400', + code: '', + nonce: '0x00', + storage: {}, + }, + }, +} diff --git a/packages/vm/examples/run-blockchain.ts b/packages/vm/examples/run-blockchain.ts index a5350df5c0d..6725bee235d 100644 --- a/packages/vm/examples/run-blockchain.ts +++ b/packages/vm/examples/run-blockchain.ts @@ -10,20 +10,14 @@ import { createBlock, createBlockFromRLP } from '@ethereumjs/block' import { EthashConsensus, createBlockchain } from '@ethereumjs/blockchain' import { Common, ConsensusAlgorithm, ConsensusType, Mainnet } from '@ethereumjs/common' import { Ethash } from '@ethereumjs/ethash' -import { - Address, - bytesToHex, - createAccount, - hexToBytes, - setLengthLeft, - toBytes, -} from '@ethereumjs/util' +import { Address, bytesToHex, createAccount, hexToBytes, setLengthLeft } from '@ethereumjs/util' import { createVM, runBlock } from '@ethereumjs/vm' -import testData from './helpers/blockchain-mock-data.json' +import { blockchainMockData } from './helpers/blockchain-mock-data.ts' -import type { Block } from '@ethereumjs/block' +import type { Block, HeaderData } from '@ethereumjs/block' import type { Blockchain, ConsensusDict } from '@ethereumjs/blockchain' +import type { PrefixedHexString } from '@ethereumjs/util' import type { VM } from '@ethereumjs/vm' async function setupPreConditions(vm: VM, data: any) { @@ -38,31 +32,34 @@ async function setupPreConditions(vm: VM, data: any) { for (const [key, val] of Object.entries(storage)) { const storageKey = setLengthLeft(hexToBytes(key), 32) - const storageVal = hexToBytes(val as string) + const storageVal = hexToBytes(val as PrefixedHexString) await vm.stateManager.putStorage(address, storageKey, storageVal) } - const codeBuf = hexToBytes('0x' + code) + const codeBuf = hexToBytes(`0x${code}`) await vm.stateManager.putCode(address, codeBuf) } await vm.stateManager.commit() } -async function putBlocks(blockchain: Blockchain, common: Common, data: typeof testData) { +async function putBlocks(blockchain: Blockchain, common: Common, data: typeof blockchainMockData) { for (const blockData of data.blocks) { - const blockRlp = toBytes(blockData.rlp) + const blockRlp = hexToBytes(blockData.rlp as PrefixedHexString) const block = createBlockFromRLP(blockRlp, { common }) await blockchain.putBlock(block) } } async function main() { - const common = new Common({ chain: Mainnet, hardfork: testData.network.toLowerCase() }) + const common = new Common({ chain: Mainnet, hardfork: blockchainMockData.network.toLowerCase() }) const validatePow = common.consensusType() === ConsensusType.ProofOfWork const validateBlocks = true - const genesisBlock = createBlock({ header: testData.genesisBlockHeader }, { common }) + const genesisBlock = createBlock( + { header: blockchainMockData.genesisBlockHeader as HeaderData }, + { common }, + ) const consensusDict: ConsensusDict = {} consensusDict[ConsensusAlgorithm.Ethash] = new EthashConsensus(new Ethash()) @@ -76,9 +73,9 @@ async function main() { const vm = await createVM({ blockchain, common }) - await setupPreConditions(vm, testData) + await setupPreConditions(vm, blockchainMockData) - await putBlocks(blockchain, common, testData) + await putBlocks(blockchain, common, blockchainMockData) await blockchain.iterator('vm', async (block: Block, _reorg: boolean) => { const parentBlock = await blockchain!.getBlock(block.header.parentHash) @@ -87,11 +84,11 @@ async function main() { await runBlock(vm, { block, root: parentState, skipHardForkValidation: true }) }) - const blockchainHead = await vm.blockchain.getIteratorHead!() + const blockchainHead = await vm.blockchain['getIteratorHead']() console.log('--- Finished processing the Blockchain ---') console.log('New head:', bytesToHex(blockchainHead.hash())) - console.log('Expected:', testData.lastblockhash) + console.log('Expected:', blockchainMockData.lastblockhash) } void main() diff --git a/packages/vm/examples/run-solidity-contract.ts b/packages/vm/examples/run-solidity-contract.ts index bf102c22df3..e03448eeba1 100644 --- a/packages/vm/examples/run-solidity-contract.ts +++ b/packages/vm/examples/run-solidity-contract.ts @@ -12,7 +12,7 @@ import solc from 'solc' import { getAccountNonce, insertAccount } from './helpers/account-utils.ts' import { buildTransaction, encodeDeployment, encodeFunction } from './helpers/tx-builder.ts' -import type { Address } from '@ethereumjs/util' +import type { Address, PrefixedHexString } from '@ethereumjs/util' import type { VM } from '@ethereumjs/vm' const INITIAL_GREETING = 'Hello, World!' @@ -147,7 +147,8 @@ async function setGreeting( } async function getGreeting(vm: VM, contractAddress: Address, caller: Address) { - const sigHash = new Interface(['function greet()']).getFunction('greet')!.selector + const sigHash = new Interface(['function greet()']).getFunction('greet')! + .selector as PrefixedHexString const greetResult = await vm.evm.runCall({ to: contractAddress, diff --git a/packages/vm/examples/runGoerliBlock.ts b/packages/vm/examples/runGoerliBlock.ts index 4bc191377dc..ce95ed347a9 100644 --- a/packages/vm/examples/runGoerliBlock.ts +++ b/packages/vm/examples/runGoerliBlock.ts @@ -1,20 +1,16 @@ -import type { JSONRPCBlock } from '@ethereumjs/block' -import { createBlockFromRPC } from '@ethereumjs/block' +import { createBlock } from '@ethereumjs/block' import { Common } from '@ethereumjs/common' -import { goerliChainConfig } from '@ethereumjs/testdata' +import { goerliBlocks, goerliChainConfig } from '@ethereumjs/testdata' import { bytesToHex } from '@ethereumjs/util' - -import { createVM, runBlock } from '../src/index.ts' - -import goerliBlock2 from './testData/goerliBlock2.json' +import { createVM, runBlock } from '@ethereumjs/vm' const main = async () => { const common = new Common({ chain: goerliChainConfig, hardfork: 'london' }) const vm = await createVM({ common, setHardfork: true }) - const block = createBlockFromRPC(goerliBlock2 as JSONRPCBlock, undefined, { common }) + const block = createBlock(goerliBlocks[0], { common }) const result = await runBlock(vm, { block, generate: true, skipHeaderValidation: true }) // we skip header validation since we are running a block without the full Ethereum history available - console.log(`The state root for Goerli block 2 is ${bytesToHex(result.stateRoot)}`) + console.log(`The state root for the block is ${bytesToHex(result.stateRoot)}`) } void main() diff --git a/packages/vm/examples/testData/goerliBlock2.json b/packages/vm/examples/testData/goerliBlock2.json deleted file mode 100644 index 53d0febceea..00000000000 --- a/packages/vm/examples/testData/goerliBlock2.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "number": "0x2", - "hash": "0xe675f1362d82cdd1ec260b16fb046c17f61d8a84808150f5d715ccce775f575e", - "transactions": [], - "difficulty": "0x2", - "extraData": "0x506172697479205465636820417574686f726974790000000000000000000000fdd66d441eff7d4116fe987f0f10812fc68b06cc500ff71c492234b9a7b8b2f45597190d97cd85f6daa45ac9518bef9f715f4bd414504b1a21d8c681654055df00", - "gasLimit": "0x9fb00c", - "gasUsed": "0x0", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "miner": "0x0000000000000000000000000000000000000000", - "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "nonce": "0x0000000000000000", - "parentHash": "0x8f5bab218b6bb34476f51ca588e9f4553a3a7ce5e13a66c660a5283e97e9a85a", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x25e", - "stateRoot": "0x5d6cded585e73c4e322c30c2f782a336316f17dd85a4863b9d838d2d4b8b3008", - "timestamp": "0x5c53100c", - "totalDifficulty": "0x5", - "transactionsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "uncles": [] -} diff --git a/packages/vm/examples/vmWith4844.ts b/packages/vm/examples/vmWith4844.ts index c96401348fb..85701745199 100644 --- a/packages/vm/examples/vmWith4844.ts +++ b/packages/vm/examples/vmWith4844.ts @@ -1,6 +1,5 @@ import { Common, Hardfork, Mainnet } from '@ethereumjs/common' - -import { createVM } from '../src/index.ts' +import { createVM } from '@ethereumjs/vm' const main = async () => { const common = new Common({ chain: Mainnet, hardfork: Hardfork.Shanghai, eips: [4844] }) diff --git a/packages/vm/examples/vmWithEIPs.ts b/packages/vm/examples/vmWithEIPs.ts index 0a8368a1605..e833fcf5533 100644 --- a/packages/vm/examples/vmWithEIPs.ts +++ b/packages/vm/examples/vmWithEIPs.ts @@ -1,9 +1,11 @@ -import { Common, Mainnet } from '@ethereumjs/common' +import { Common, Hardfork, Mainnet } from '@ethereumjs/common' import { createVM } from '@ethereumjs/vm' const main = async () => { - const common = new Common({ chain: Mainnet, eips: [7702] }) + const common = new Common({ chain: Mainnet, hardfork: Hardfork.Cancun, eips: [7702] }) const vm = await createVM({ common }) - console.log(`EIP 7702 is active in the VM - ${vm.common.isActivatedEIP(7702)}`) + console.log( + `EIP 7702 is active in isolation on top of the Cancun HF - ${vm.common.isActivatedEIP(7702)}`, + ) } void main() diff --git a/packages/vm/examples/vmWithGenesisState.ts b/packages/vm/examples/vmWithGenesisState.ts index 63c90c10664..3e03ea76bb2 100644 --- a/packages/vm/examples/vmWithGenesisState.ts +++ b/packages/vm/examples/vmWithGenesisState.ts @@ -8,16 +8,15 @@ const main = async () => { const vm = await createVM() await vm.stateManager.generateCanonicalGenesis!(genesisState) - const account = await vm.stateManager.getAccount( - createAddressFromString('0x000d836201318ec6899a67540690382780743280'), - ) + const accountAddress = '0x000d836201318ec6899a67540690382780743280' + const account = await vm.stateManager.getAccount(createAddressFromString(accountAddress)) if (account === undefined) { throw new Error('Account does not exist: failed to import genesis state') } console.log( - `This balance for account 0x000d836201318ec6899a67540690382780743280 in this chain's genesis state is ${Number( + `This balance for account ${accountAddress} in this chain's genesis state is ${Number( account?.balance, )}`, ) diff --git a/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts b/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts index 49fa30be1e5..cf5874679b2 100644 --- a/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts +++ b/packages/vm/test/api/EIPs/eip-2935-historical-block-hashes.spec.ts @@ -136,7 +136,7 @@ describe('EIP 2935: historical block hashes', () => { const historyAddress = createAddressFromString(deployedToAddress) const historyAddressBigInt = bytesToBigInt(historyAddress.bytes) - const contract2935Code = hexToBytes(contract2935CodeHex as string) + const contract2935Code = hexToBytes(contract2935CodeHex as PrefixedHexString) async function testBlockhashContract(vm: VM, block: Block, i: bigint): Promise { const tx = createLegacyTx({ @@ -284,7 +284,7 @@ describe('EIP 2935: historical block hashes', () => { // Code: RETURN the BLOCKHASH of block i // PUSH(i) BLOCKHASH PUSH(32) MSTORE PUSH(64) PUSH(0) RETURN // Note: need to return a contract with starting zero bytes to avoid non-deployable contracts by EIP 3540 - data: hexToBytes('0x61' + i.toString(16).padStart(4, '0') + '4060205260406000F3'), + data: hexToBytes(`0x61${i.toString(16).padStart(4, '0')}4060205260406000F3`), block: lastBlock, }) diff --git a/packages/vm/test/api/EIPs/eip-3855.spec.ts b/packages/vm/test/api/EIPs/eip-3855.spec.ts index 55a75ef5be4..261112d157f 100644 --- a/packages/vm/test/api/EIPs/eip-3855.spec.ts +++ b/packages/vm/test/api/EIPs/eip-3855.spec.ts @@ -1,8 +1,8 @@ import { Common, Hardfork, Mainnet } from '@ethereumjs/common' -import { EVMErrorMessages } from '@ethereumjs/evm' import { hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' +import { EVMError } from '@ethereumjs/evm' import { createVM } from '../../../src/index.ts' describe('EIP 3855 tests', () => { @@ -65,7 +65,7 @@ describe('EIP 3855 tests', () => { gasLimit: BigInt(10000), }) - assert.equal(result.exceptionError?.error, EVMErrorMessages.STACK_OVERFLOW) + assert.equal(result.exceptionError?.error, EVMError.errorMessages.STACK_OVERFLOW) }) it('push0 is not available if EIP3855 is not activated', async () => { @@ -76,6 +76,6 @@ describe('EIP 3855 tests', () => { gasLimit: BigInt(10000), }) - assert.equal(result.exceptionError!.error, EVMErrorMessages.INVALID_OPCODE) + assert.equal(result.exceptionError!.error, EVMError.errorMessages.INVALID_OPCODE) }) }) diff --git a/packages/vm/test/api/buildBlock.spec.ts b/packages/vm/test/api/buildBlock.spec.ts index c8d43bf16e3..b169f4aaddb 100644 --- a/packages/vm/test/api/buildBlock.spec.ts +++ b/packages/vm/test/api/buildBlock.spec.ts @@ -8,6 +8,7 @@ import { EthashConsensus, createBlockchain } from '@ethereumjs/blockchain' import { Common, ConsensusAlgorithm, + type GethGenesis, Hardfork, Mainnet, createCommonFromGethGenesis, @@ -157,7 +158,7 @@ describe('BlockBuilder', () => { epoch: 30000, }, } - const defaultChainData = { + const defaultChainData: GethGenesis = { config: { chainId: 123456, homesteadBlock: 0, @@ -183,6 +184,7 @@ describe('BlockBuilder', () => { gasUsed: '0x0', parentHash: '0x0000000000000000000000000000000000000000000000000000000000000000', baseFeePerGas: 7, + alloc: {}, } const A = { @@ -191,7 +193,7 @@ describe('BlockBuilder', () => { } const addr = A.address.toString().slice(2) - const extraData2 = '0x' + '0'.repeat(64) + addr + '0'.repeat(130) + const extraData2 = `0x${'0'.repeat(64)}${addr}${'0'.repeat(130)}` const chainData = { ...defaultChainData, extraData: extraData2, diff --git a/packages/vm/test/api/customChain.spec.ts b/packages/vm/test/api/customChain.spec.ts index da2186bb960..5f7efd8822a 100644 --- a/packages/vm/test/api/customChain.spec.ts +++ b/packages/vm/test/api/customChain.spec.ts @@ -100,7 +100,7 @@ describe('VM initialized with custom state', () => { const callResult = await vm.evm.runCall({ to: createAddressFromString(contractAddress), - data: hexToBytes(calldata), + data: hexToBytes(calldata as PrefixedHexString), caller: createAddressFromPrivateKey(privateKey), }) diff --git a/packages/vm/test/api/events.spec.ts b/packages/vm/test/api/events.spec.ts index 05c8fa27c58..8e032ccb3a4 100644 --- a/packages/vm/test/api/events.spec.ts +++ b/packages/vm/test/api/events.spec.ts @@ -1,12 +1,12 @@ import { Block } from '@ethereumjs/block' import { createFeeMarket1559Tx } from '@ethereumjs/tx' -import { Account, bytesToHex, createAddressFromPrivateKey, toBytes } from '@ethereumjs/util' +import { Account, bytesToHex, createAddressFromPrivateKey, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' import { createVM, runBlock, runTx } from '../../src/index.ts' describe('VM events', () => { - const privKey = toBytes('0xa5737ecdc1b89ca0091647e727ba082ed8953f29182e94adc397210dda643b07') + const privKey = hexToBytes('0xa5737ecdc1b89ca0091647e727ba082ed8953f29182e94adc397210dda643b07') it('should emit the Block before running it', async () => { const vm = await createVM() @@ -129,7 +129,7 @@ describe('VM events', () => { await runTx(vm, { tx, skipBalance: true, skipHardForkValidation: true }) - assert.equal(bytesToHex(emitted.createdAddress), '0x') + assert.equal(bytesToHex(emitted.execResult.returnValue), '0x') }) it('should emit InterpreterStep on each step', async () => { diff --git a/packages/vm/test/api/istanbul/eip-1344.spec.ts b/packages/vm/test/api/istanbul/eip-1344.spec.ts index 1e6b358bdda..3f5971ef016 100644 --- a/packages/vm/test/api/istanbul/eip-1344.spec.ts +++ b/packages/vm/test/api/istanbul/eip-1344.spec.ts @@ -1,5 +1,5 @@ import { Common, Hardfork, Mainnet } from '@ethereumjs/common' -import { EVMErrorMessages } from '@ethereumjs/evm' +import { EVMError } from '@ethereumjs/evm' import { bytesToBigInt, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -7,7 +7,7 @@ import { createVM } from '../../../src/index.ts' const testCases = [ { chain: Mainnet, hardfork: Hardfork.Istanbul, chainId: BigInt(1) }, - { chain: Mainnet, hardfork: Hardfork.Constantinople, err: EVMErrorMessages.INVALID_OPCODE }, + { chain: Mainnet, hardfork: Hardfork.Constantinople, err: EVMError.errorMessages.INVALID_OPCODE }, ] // CHAINID PUSH8 0x00 MSTORE8 PUSH8 0x01 PUSH8 0x00 RETURN diff --git a/packages/vm/test/api/istanbul/eip-1884.spec.ts b/packages/vm/test/api/istanbul/eip-1884.spec.ts index 6cd2abf5bd0..c5d3ebc9fbf 100644 --- a/packages/vm/test/api/istanbul/eip-1884.spec.ts +++ b/packages/vm/test/api/istanbul/eip-1884.spec.ts @@ -1,5 +1,5 @@ import { Common, Hardfork, Mainnet } from '@ethereumjs/common' -import { EVMErrorMessages } from '@ethereumjs/evm' +import { EVMError } from '@ethereumjs/evm' import { Address, bytesToBigInt, hexToBytes } from '@ethereumjs/util' import { assert, describe, it } from 'vitest' @@ -8,7 +8,7 @@ import { createAccountWithDefaults } from '../utils.ts' const testCases = [ { chain: Mainnet, hardfork: Hardfork.Istanbul, selfbalance: '0xf1' }, - { chain: Mainnet, hardfork: Hardfork.Constantinople, err: EVMErrorMessages.INVALID_OPCODE }, + { chain: Mainnet, hardfork: Hardfork.Constantinople, err: EVMError.errorMessages.INVALID_OPCODE }, ] // SELFBALANCE PUSH8 0x00 MSTORE8 PUSH8 0x01 PUSH8 0x00 RETURN diff --git a/packages/vm/test/api/runBlock.spec.ts b/packages/vm/test/api/runBlock.spec.ts index 5eeada1418b..55c05a9898d 100644 --- a/packages/vm/test/api/runBlock.spec.ts +++ b/packages/vm/test/api/runBlock.spec.ts @@ -30,7 +30,6 @@ import { equalsBytes, hexToBytes, privateToAddress, - toBytes, unpadBytes, utf8ToBytes, } from '@ethereumjs/util' @@ -113,7 +112,7 @@ describe('runBlock() -> successful API parameter usage', async () => { skipHardForkValidation: true, }) - const block3Rlp = toBytes(uncleData.blocks[2].rlp as PrefixedHexString) + const block3Rlp = hexToBytes(uncleData.blocks[2].rlp as PrefixedHexString) const block3 = createBlockFromRLP(block3Rlp, { common }) await runBlock(vm, { block: block3, diff --git a/packages/vm/test/t8n/stateTracker.ts b/packages/vm/test/t8n/stateTracker.ts index 4e98d3966b3..f0932be661f 100644 --- a/packages/vm/test/t8n/stateTracker.ts +++ b/packages/vm/test/t8n/stateTracker.ts @@ -86,7 +86,7 @@ export class StateTracker { outputAlloc[addressString].balance = bigIntToHex(account.balance) outputAlloc[addressString].code = bytesToHex(await this.vm.stateManager.getCode(address)) - const storage = this.allocTracker[addressString].storage + const storage = this.allocTracker[addressString].storage as PrefixedHexString[] outputAlloc[addressString].storage = outputAlloc[addressString].storage ?? {} for (const key of storage) { diff --git a/packages/vm/test/t8n/t8ntool.ts b/packages/vm/test/t8n/t8ntool.ts index e53bdb5a776..e6252d9bb1e 100644 --- a/packages/vm/test/t8n/t8ntool.ts +++ b/packages/vm/test/t8n/t8ntool.ts @@ -43,7 +43,7 @@ function getBlockchain(inputEnv: T8NEnv) { if (Number(key) === number) { return { hash() { - return hexToBytes(inputEnv.blockHashes[key]) + return hexToBytes(inputEnv.blockHashes[key] as PrefixedHexString) }, } } diff --git a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts index 91557937781..ef6a2fea525 100644 --- a/packages/vm/test/tester/runners/BlockchainTestsRunner.ts +++ b/packages/vm/test/tester/runners/BlockchainTestsRunner.ts @@ -13,7 +13,6 @@ import { hexToBytes, isHexString, stripHexPrefix, - toBytes, } from '@ethereumjs/util' import { createVerkleTree } from '@ethereumjs/verkle' @@ -84,7 +83,7 @@ export async function runBlockchainTest(options: any, testData: any, t: tape.Tes const genesisBlock = createBlock(blockData, { common }) if (typeof testData.genesisRLP === 'string') { - const rlp = toBytes(testData.genesisRLP) + const rlp = hexToBytes(testData.genesisRLP) t.deepEquals(genesisBlock.serialize(), rlp, 'correct genesis RLP') } diff --git a/packages/wallet/README.md b/packages/wallet/README.md index bdd4ba03cc3..1fe2c200a0c 100644 --- a/packages/wallet/README.md +++ b/packages/wallet/README.md @@ -1,4 +1,4 @@ -# @ethereumjs/wallet +# @ethereumjs/wallet `v10` [![NPM Package][npm-badge]][npm-link] [![Actions Status][actions-badge]][actions-link] @@ -26,6 +26,16 @@ Features not supported: - signing transactions - managing storage (neither in node.js or the browser) +## Table of Contents + +- [Installation](#installation) +- [Wallet API](#wallet-api) +- [Thirdparty API](#thirdparty-api) +- [HD Wallet API](#hd-wallet-api) +- [Special Topics](#special-topics) +- [EthereumJS](#ethereumjs) +- [License](#license) + ## Wallet API For information about the Wallet's API, please go to [./docs/classes/wallet.md](./docs/classes/wallet.md). @@ -114,17 +124,9 @@ console.log(wallet.getWallet().getAddressString()) // Should print an Ethereum a Please go to [./docs/classes/ethereumhdkey.md](./docs/classes/ethereumhdkey.md) for more info. -## Provider Engine - -Provider Engine is -[not very actively maintained](https://github.com/MetaMask/web3-provider-engine#web3-providerengine) -and support has been removed along `v1.0.0` release, see -issue [#115](https://github.com/ethereumjs/ethereumjs-wallet/issues/115) for context. - -You can use the the old `src/provider-engine.ts` code (see associated PR) as some boilerplate -for your own integration if needed. +## Special Topics -## Remarks about `toV3` +### Remarks about `toV3` The `options` is an optional object hash, where all the serialization parameters can be fine tuned: @@ -157,7 +159,7 @@ The following settings are favoured by the Go Ethereum implementation and we def - `p`: `1` - `cipher`: `aes-128-ctr` -# EthereumJS +## EthereumJS See our organizational [documentation](https://ethereumjs.readthedocs.io) for an introduction to `EthereumJS` as well as information on current standards and best practices. From 9bc333c30e288eb17c5db1ecc9bac90ef4641a11 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 25 Apr 2025 04:08:13 +0700 Subject: [PATCH 02/22] Create jekyll-gh-pages.yml (#88) Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/jekyll-gh-pages.yml | 51 +++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/jekyll-gh-pages.yml diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/jekyll-gh-pages.yml new file mode 100644 index 00000000000..0ebd768bf2a --- /dev/null +++ b/.github/workflows/jekyll-gh-pages.yml @@ -0,0 +1,51 @@ +# Sample workflow for building and deploying a Jekyll site to GitHub Pages +name: Deploy Jekyll with GitHub Pages dependencies preinstalled + +on: + # Runs on pushes targeting the default branch + push: + branches: ["master"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Setup Pages + uses: actions/configure-pages@v5 + - name: Build with Jekyll + uses: actions/jekyll-build-pages@v1 + with: + source: ./ + destination: ./_site + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 From 4b4b168bebb677d84a28e88ffb8a8cf663b21eb9 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 25 Apr 2025 10:30:47 +0700 Subject: [PATCH 03/22] Revert "Create google.yml (#52)" (#90) This reverts commit e5e71041d510ad958278bfa0e212d5f2757f7979. From 2147bd5a653c0c227be9a9221765592fa3ccd739 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 25 Apr 2025 14:34:59 +0700 Subject: [PATCH 04/22] Revert "monorepo: npm audit fix (#4003)" (#91) This reverts commit 20cae2bfd5f1ba83fb2ab2beafb92f5d65788126. --- package-lock.json | 39 ++++----------------------------------- 1 file changed, 4 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index 5741d70e058..492efed7019 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16323,18 +16323,15 @@ } }, "node_modules/vite": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.2.tgz", - "integrity": "sha512-ZSvGOXKGceizRQIZSz7TGJ0pS3QLlVY/9hwxVh17W3re67je1RKYzFHivZ/t0tubU78Vkyb9WnHPENSBCzbckg==", + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz", + "integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", - "fdir": "^6.4.3", - "picomatch": "^4.0.2", "postcss": "^8.5.3", - "rollup": "^4.34.9", - "tinyglobby": "^0.2.12" + "rollup": "^4.30.1" }, "bin": { "vite": "bin/vite.js" @@ -16459,34 +16456,6 @@ "vite": "^2 || ^3 || ^4 || ^5 || ^6" } }, - "node_modules/vite/node_modules/fdir": { - "version": "6.4.4", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", - "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "picomatch": "^3 || ^4" - }, - "peerDependenciesMeta": { - "picomatch": { - "optional": true - } - } - }, - "node_modules/vite/node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/vitest": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz", From 7bee6f5c9a62ed6729ba78c5205bb0c7a9dadfed Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 25 Apr 2025 07:55:31 +0000 Subject: [PATCH 05/22] build(deps-dev): bump vite in the npm_and_yarn group across 1 directory Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite). Updates `vite` from 6.2.4 to 6.3.3 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v6.3.3/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 6.3.3 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] --- package-lock.json | 53 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 492efed7019..2f720983e12 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15697,13 +15697,13 @@ "license": "MIT" }, "node_modules/tinyglobby": { - "version": "0.2.12", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.12.tgz", - "integrity": "sha512-qkf4trmKSIiMTs/E63cxH+ojC2unam7rJ0WrauAzpT3ECNTxGRMlaXxVbfxMUC/w0LaYk6jQ4y/nGR9uBO3tww==", + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", + "integrity": "sha512-mEwzpUgrLySlveBwEVDMKk5B57bhLPYovRfPAXD5gA/98Opn0rCDj3GtLwFvCvH5RK9uPCExUROW5NjDwvqkxw==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.3", + "fdir": "^6.4.4", "picomatch": "^4.0.2" }, "engines": { @@ -15714,9 +15714,9 @@ } }, "node_modules/tinyglobby/node_modules/fdir": { - "version": "6.4.3", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.3.tgz", - "integrity": "sha512-PMXmW2y1hDDfTSRc9gaXIuCCRpuoz3Kaz8cUelp3smouvfT632ozg2vrT6lJsHKKOF59YLbOGfAWGUcKEfRMQw==", + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", "dev": true, "license": "MIT", "peerDependencies": { @@ -16323,15 +16323,18 @@ } }, "node_modules/vite": { - "version": "6.2.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.4.tgz", - "integrity": "sha512-veHMSew8CcRzhL5o8ONjy8gkfmFJAd5Ac16oxBUjlwgX3Gq2Wqr+qNC3TjPIpy7TPV/KporLga5GT9HqdrCizw==", + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz", + "integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==", "dev": true, "license": "MIT", "dependencies": { "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", "postcss": "^8.5.3", - "rollup": "^4.30.1" + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" }, "bin": { "vite": "bin/vite.js" @@ -16456,6 +16459,34 @@ "vite": "^2 || ^3 || ^4 || ^5 || ^6" } }, + "node_modules/vite/node_modules/fdir": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.4.tgz", + "integrity": "sha512-1NZP+GK4GfuAv3PqKvxQRDMjdSRZjnkq7KfhlNrCNNlZ0ygQFpebfrnfnq/W7fpUnAv9aGWmY1zKx7FYL3gwhg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, "node_modules/vitest": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.0.8.tgz", From e02ef16e69c646c14e434b69eaeeda0339bb63ba Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 25 Apr 2025 15:00:19 +0700 Subject: [PATCH 06/22] Add .circleci/config.yml --- .circleci/config.yml | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .circleci/config.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000000..62291703e26 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,31 @@ +# Use the latest 2.1 version of CircleCI pipeline process engine. +# See: https://circleci.com/docs/configuration-reference +version: 2.1 + +# Define a job to be invoked later in a workflow. +# See: https://circleci.com/docs/jobs-steps/#jobs-overview & https://circleci.com/docs/configuration-reference/#jobs +jobs: + say-hello: + # Specify the execution environment. You can specify an image from Docker Hub or use one of our convenience images from CircleCI's Developer Hub. + # See: https://circleci.com/docs/executor-intro/ & https://circleci.com/docs/configuration-reference/#executor-job + docker: + # Specify the version you desire here + # See: https://circleci.com/developer/images/image/cimg/base + - image: cimg/base:current + + # Add steps to the job + # See: https://circleci.com/docs/jobs-steps/#steps-overview & https://circleci.com/docs/configuration-reference/#steps + steps: + # Checkout the code as the first step. + - checkout + - run: + name: "Say hello" + command: "echo Hello, World!" + +# Orchestrate jobs using workflows +# See: https://circleci.com/docs/workflows/ & https://circleci.com/docs/configuration-reference/#workflows +workflows: + say-hello-workflow: # This is the name of the workflow, feel free to change it to better match your workflow. + # Inside the workflow, you define the jobs you want to run. + jobs: + - say-hello \ No newline at end of file From c402ccdc5e1d172c3e611f9067a6cbd6a07aa909 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Fri, 25 Apr 2025 20:01:09 +0700 Subject: [PATCH 07/22] Update docker-image.yml (#96) Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/docker-image.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 4d4b850e719..f09deb0e00f 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -39,11 +39,10 @@ jobs: - run: npm i working-directory: ${{ github.workspace }} - - - name: Build & Push + - name: Build & Push uses: docker/build-push-action@v5 with: context: . push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} - tags: ghcr.io/${{ github.repository_owner }}/ethereumjs-monorepo:latest - provenance: false \ No newline at end of file + tags: ghcr.io/${{ github.repository_owner | toLower }}/ethereumjs-monorepo:latest + provenance: false From 4bd1e19af47865ca86fa985544a628211d2dddc6 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Sat, 26 Apr 2025 03:35:27 +0700 Subject: [PATCH 08/22] Update docker-image.yml Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/docker-image.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index f09deb0e00f..00d88946ce2 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -44,5 +44,5 @@ jobs: with: context: . push: ${{ github.event_name == 'push' && github.ref == 'refs/heads/master' }} - tags: ghcr.io/${{ github.repository_owner | toLower }}/ethereumjs-monorepo:latest + tags: ghcr.io/${{ github.repository_owner/ethereumjs-monorepo:latest provenance: false From eab38a58e0a5012d08a7c9988b95fb4ab6ca0a58 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Sat, 26 Apr 2025 05:22:45 +0700 Subject: [PATCH 09/22] Create mdbook.yml Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/mdbook.yml | 60 ++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 .github/workflows/mdbook.yml diff --git a/.github/workflows/mdbook.yml b/.github/workflows/mdbook.yml new file mode 100644 index 00000000000..109cc83360a --- /dev/null +++ b/.github/workflows/mdbook.yml @@ -0,0 +1,60 @@ +# Sample workflow for building and deploying a mdBook site to GitHub Pages +# +# To get started with mdBook see: https://rust-lang.github.io/mdBook/index.html +# +name: Deploy mdBook site to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["master"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + env: + MDBOOK_VERSION: 0.4.36 + steps: + - uses: actions/checkout@v4 + - name: Install mdBook + run: | + curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf -y | sh + rustup update + cargo install --version ${MDBOOK_VERSION} mdbook + - name: Setup Pages + id: pages + uses: actions/configure-pages@v5 + - name: Build with mdBook + run: mdbook build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./book + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 From 15dd222ace5d66a06f9b59e02a748aa43ed13e63 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Sat, 26 Apr 2025 05:32:36 +0700 Subject: [PATCH 10/22] Create nextjs.yml Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/nextjs.yml | 93 ++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 .github/workflows/nextjs.yml diff --git a/.github/workflows/nextjs.yml b/.github/workflows/nextjs.yml new file mode 100644 index 00000000000..974fcb99950 --- /dev/null +++ b/.github/workflows/nextjs.yml @@ -0,0 +1,93 @@ +# Sample workflow for building and deploying a Next.js site to GitHub Pages +# +# To get started with Next.js see: https://nextjs.org/docs/getting-started +# +name: Deploy Next.js site to Pages + +on: + # Runs on pushes targeting the default branch + push: + branches: ["master"] + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages +permissions: + contents: read + pages: write + id-token: write + +# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. +# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. +concurrency: + group: "pages" + cancel-in-progress: false + +jobs: + # Build job + build: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Detect package manager + id: detect-package-manager + run: | + if [ -f "${{ github.workspace }}/yarn.lock" ]; then + echo "manager=yarn" >> $GITHUB_OUTPUT + echo "command=install" >> $GITHUB_OUTPUT + echo "runner=yarn" >> $GITHUB_OUTPUT + exit 0 + elif [ -f "${{ github.workspace }}/package.json" ]; then + echo "manager=npm" >> $GITHUB_OUTPUT + echo "command=ci" >> $GITHUB_OUTPUT + echo "runner=npx --no-install" >> $GITHUB_OUTPUT + exit 0 + else + echo "Unable to determine package manager" + exit 1 + fi + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "20" + cache: ${{ steps.detect-package-manager.outputs.manager }} + - name: Setup Pages + uses: actions/configure-pages@v5 + with: + # Automatically inject basePath in your Next.js configuration file and disable + # server side image optimization (https://nextjs.org/docs/api-reference/next/image#unoptimized). + # + # You may remove this line if you want to manage the configuration yourself. + static_site_generator: next + - name: Restore cache + uses: actions/cache@v4 + with: + path: | + .next/cache + # Generate a new cache whenever packages or source files change. + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}-${{ hashFiles('**.[jt]s', '**.[jt]sx') }} + # If source files changed but packages didn't, rebuild from a prior cache. + restore-keys: | + ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json', '**/yarn.lock') }}- + - name: Install dependencies + run: ${{ steps.detect-package-manager.outputs.manager }} ${{ steps.detect-package-manager.outputs.command }} + - name: Build with Next.js + run: ${{ steps.detect-package-manager.outputs.runner }} next build + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: ./out + + # Deployment job + deploy: + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + needs: build + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v4 From 8798bfbd36ba1f3454936230d1abb409f4c471d3 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Sat, 26 Apr 2025 06:48:33 +0700 Subject: [PATCH 11/22] Update vm-pr.yml (#106) Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/vm-pr.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/vm-pr.yml b/.github/workflows/vm-pr.yml index 8068dfd02e4..aa5a0400818 100644 --- a/.github/workflows/vm-pr.yml +++ b/.github/workflows/vm-pr.yml @@ -326,10 +326,10 @@ jobs: run: npm ci working-directory: ${{ github.workspace }} - - run: npm run build:benchmarks + - run: npm run lint:benchmarks working-directory: ${{ env.cwd }} - - run: npm run benchmarks -- mainnetBlocks:10 | tee output.txt + - run: npm run coverage -- mainnetBlocks:10 | tee output.txt working-directory: ${{ env.cwd }} # Run git stash in case github-action-benchmark has trouble switching to gh-pages branch due to differing package-locks @@ -342,13 +342,13 @@ jobs: # Where the output from the benchmark tool is stored output-file-path: ${{ env.cwd }}/output.txt # Location of data in gh-pages branch - benchmark-data-dir-path: dev/bench/vm + benchmark-data-dir-path: vm-benchmarks # Enable alert commit comment (default alert threshold: 200%) comment-on-alert: true # GitHub API token to make a commit comment github-token: ${{ secrets.GITHUB_TOKEN }} # Push and deploy to GitHub pages branch automatically (if on master) - auto-push: 'false' + auto-push: 'true' # Re-apply git stash to prepare for saving back to cache. # Avoids exit code 1 by checking if there are changes to be stashed first From de859fdf65a0ef75a8ada7ab53b3185e0e045231 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Sat, 26 Apr 2025 07:37:10 +0700 Subject: [PATCH 12/22] Update vm-pr.yml (#107) Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> From 1bb3cc5223fd5db0225c7457c5c815a5a6e9c7c0 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Sat, 26 Apr 2025 07:49:12 +0700 Subject: [PATCH 13/22] Merge pull request #97 from Dargon789/master (#98) From ba3f7b91be4e1768c760ccbc3999a790298a7060 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Sat, 26 Apr 2025 07:50:33 +0700 Subject: [PATCH 14/22] Update vm-pr.yml (#108) Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/vm-pr.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/vm-pr.yml b/.github/workflows/vm-pr.yml index aa5a0400818..a76769355de 100644 --- a/.github/workflows/vm-pr.yml +++ b/.github/workflows/vm-pr.yml @@ -326,10 +326,10 @@ jobs: run: npm ci working-directory: ${{ github.workspace }} - - run: npm run lint:benchmarks + - run: npm run build:benchmarks working-directory: ${{ env.cwd }} - - run: npm run coverage -- mainnetBlocks:10 | tee output.txt + - run: npm run benchmarks -- mainnetBlocks:10 | tee output.txt working-directory: ${{ env.cwd }} # Run git stash in case github-action-benchmark has trouble switching to gh-pages branch due to differing package-locks From dc317af3e4f9e2d322b70f3b83e44f2d24a41652 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Sat, 26 Apr 2025 09:19:12 +0700 Subject: [PATCH 15/22] Update vm-pr.yml Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/vm-pr.yml | 215 +++++++----------------------------- 1 file changed, 38 insertions(+), 177 deletions(-) diff --git a/.github/workflows/vm-pr.yml b/.github/workflows/vm-pr.yml index a76769355de..15cd31d8c13 100644 --- a/.github/workflows/vm-pr.yml +++ b/.github/workflows/vm-pr.yml @@ -1,21 +1,8 @@ name: VM on: - workflow_call: - inputs: - dep-cache-key: - required: true - type: string - submodule-cache-key: - required: true - type: string + pull_request: + types: [opened, reopened, synchronize] workflow_dispatch: - inputs: - dep-cache-key: - required: false - default: 'none' - submodule-cache-key: - required: false - default: 'none' env: cwd: ${{github.workspace}}/packages/vm @@ -25,52 +12,31 @@ defaults: working-directory: packages/vm concurrency: - group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}-vm-pr + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: vm-api: runs-on: ubuntu-latest steps: - # We clone the repo and submodules if triggered from work-flow dispatch - - if: inputs.submodule-cache-key == 'none' - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: submodules: recursive - # We restore the code/deps from cache if triggered from workflow_call (i.e. have valid cache key) - - if: inputs.dep-cache-key != 'none' - uses: actions/cache/restore@v4 - id: dep-cache + - uses: actions/setup-node@v4 with: - path: ${{github.workspace}} - key: ${{ inputs.dep-cache-key }} - - - name: Use Node.js 20 - uses: actions/setup-node@v4 - with: - node-version: 20 + node-version: 18 cache: 'npm' - - name: Install Dependencies (if not restored from cache) - if: steps.dep-cache.outputs.cache-hit != 'true' - run: npm ci - working-directory: ${{ github.workspace }} - - - if: inputs.submodule-cache-key != 'none' - uses: actions/cache/restore@v4 - name: Initialize ethereum-tests - id: submodules-cache - with: - path: ${{github.workspace}}/packages/ethereum-tests - key: ${{ inputs.submodule-cache-key}} - fail-on-cache-miss: true + - run: npm ci + working-directory: ${{github.workspace}} + - run: npm run lint - run: npm run coverage + # - run: npm run test:API:browser -- disabled until we fix browser tests for vitest - - uses: codecov/codecov-action@v4 + - uses: codecov/codecov-action@v3 with: - token: ${{ secrets.CODECOV_TOKEN }} files: ${{ env.cwd }}/coverage/lcov.info flags: vm @@ -81,40 +47,18 @@ jobs: fork: ['Berlin', 'London', 'Paris', 'Shanghai', 'Cancun'] fail-fast: false steps: - # We clone the repo and submodules if triggered from work-flow dispatch - - if: inputs.submodule-cache-key == 'none' - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: submodules: recursive - # We restore the code/deps from cache if triggered from workflow_call (i.e. have valid cache key) - - if: inputs.dep-cache-key != 'none' - uses: actions/cache/restore@v4 - id: dep-cache + - uses: actions/setup-node@v4 with: - path: ${{github.workspace}} - key: ${{ inputs.dep-cache-key }} - - - name: Use Node.js 20 - uses: actions/setup-node@v4 - with: - node-version: 20 + node-version: 18 cache: 'npm' - - name: Install Dependencies (if not restored from cache) - if: steps.dep-cache.outputs.cache-hit != 'true' - run: npm ci - working-directory: ${{ github.workspace }} + - run: npm ci + working-directory: ${{github.workspace}} - - if: inputs.submodule-cache-key != 'none' - uses: actions/cache/restore@v4 - name: Initialize ethereum-tests - id: submodules-cache - with: - path: ${{github.workspace}}/packages/ethereum-tests - key: ${{ inputs.submodule-cache-key}} - fail-on-cache-miss: true - - run: npm run test:state -- --fork=${{ matrix.fork }} --verify-test-amount-alltests vm-state-extended: @@ -141,41 +85,16 @@ jobs: ] fail-fast: false steps: - # We clone the repo and submodules if triggered from work-flow dispatch - - if: inputs.submodule-cache-key == 'none' - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: submodules: recursive - - # We restore the code/deps from cache if triggered from workflow_call (i.e. have valid cache key) - - if: inputs.dep-cache-key != 'none' - uses: actions/cache/restore@v4 - id: dep-cache - with: - path: ${{github.workspace}} - key: ${{ inputs.dep-cache-key }} - - - name: Use Node.js 20 - uses: actions/setup-node@v4 + - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 18 cache: 'npm' - - name: Install Dependencies (if not restored from cache) - if: steps.dep-cache.outputs.cache-hit != 'true' - run: npm ci - working-directory: ${{ github.workspace }} - - - - if: inputs.submodule-cache-key != 'none' - uses: actions/cache/restore@v4 - name: Initialize ethereum-tests - id: submodules-cache - with: - path: ${{github.workspace}}/packages/ethereum-tests - key: ${{ inputs.submodule-cache-key}} - fail-on-cache-miss: true - + - run: npm ci + working-directory: ${{github.workspace}} - run: npm run test:state -- --fork=${{ matrix.fork }} --verify-test-amount-alltests @@ -197,39 +116,17 @@ jobs: ] fail-fast: false steps: - # We clone the repo and submodules if triggered from work-flow dispatch - - if: inputs.submodule-cache-key == 'none' - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: submodules: recursive - # We restore the code/deps from cache if triggered from workflow_call (i.e. have valid cache key) - - if: inputs.dep-cache-key != 'none' - uses: actions/cache/restore@v4 - id: dep-cache - with: - path: ${{github.workspace}} - key: ${{ inputs.dep-cache-key }} - - - name: Use Node.js 20 - uses: actions/setup-node@v4 + - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 18 cache: 'npm' - - name: Install Dependencies (if not restored from cache) - if: steps.dep-cache.outputs.cache-hit != 'true' - run: npm ci - working-directory: ${{ github.workspace }} - - - if: inputs.submodule-cache-key != 'none' - uses: actions/cache/restore@v4 - name: Initialize ethereum-tests - id: submodules-cache - with: - path: ${{github.workspace}}/packages/ethereum-tests - key: ${{ inputs.submodule-cache-key}} - fail-on-cache-miss: true + - run: npm ci + working-directory: ${{github.workspace}} - run: npm run test:blockchain -- ${{ matrix.args }} @@ -264,67 +161,31 @@ jobs: ] fail-fast: false steps: - # We clone the repo and submodules if triggered from work-flow dispatch - - if: inputs.submodule-cache-key == 'none' - uses: actions/checkout@v4 + - uses: actions/checkout@v4 with: submodules: recursive - - # We restore the code/deps from cache if triggered from workflow_call (i.e. have valid cache key) - - if: inputs.dep-cache-key != 'none' - uses: actions/cache/restore@v4 - id: dep-cache + - uses: actions/setup-node@v4 with: - path: ${{github.workspace}} - key: ${{ inputs.dep-cache-key }} - - - name: Use Node.js 20 - uses: actions/setup-node@v4 - with: - node-version: 20 + node-version: 18 cache: 'npm' - - name: Install Dependencies (if not restored from cache) - if: steps.dep-cache.outputs.cache-hit != 'true' - run: npm ci - working-directory: ${{ github.workspace }} - - - if: inputs.submodule-cache-key != 'none' - uses: actions/cache/restore@v4 - name: Initialize ethereum-tests - id: submodules-cache - with: - path: ${{github.workspace}}/packages/ethereum-tests - key: ${{ inputs.submodule-cache-key}} - fail-on-cache-miss: true + - run: npm ci + working-directory: ${{github.workspace}} - run: npm run test:blockchain -- ${{ matrix.args }} vm-benchmarks: runs-on: ubuntu-latest steps: - # We clone the repo and submodules if triggered from work-flow dispatch - - if: inputs.submodule-cache-key == 'none' - uses: actions/checkout@v4 - - # We restore the code/deps from cache if triggered from workflow_call (i.e. have valid cache key) - - if: inputs.dep-cache-key != 'none' - uses: actions/cache/restore@v4 - id: dep-cache - with: - path: ${{github.workspace}} - key: ${{ inputs.dep-cache-key }} + - uses: actions/checkout@v4 - - name: Use Node.js 20 - uses: actions/setup-node@v4 + - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 18 cache: 'npm' - - name: Install Dependencies (if not restored from cache) - if: steps.dep-cache.outputs.cache-hit != 'true' - run: npm ci - working-directory: ${{ github.workspace }} + - run: npm ci + working-directory: ${{github.workspace}} - run: npm run build:benchmarks working-directory: ${{ env.cwd }} @@ -342,13 +203,13 @@ jobs: # Where the output from the benchmark tool is stored output-file-path: ${{ env.cwd }}/output.txt # Location of data in gh-pages branch - benchmark-data-dir-path: vm-benchmarks + benchmark-data-dir-path: dev/bench/vm # Enable alert commit comment (default alert threshold: 200%) comment-on-alert: true # GitHub API token to make a commit comment github-token: ${{ secrets.GITHUB_TOKEN }} # Push and deploy to GitHub pages branch automatically (if on master) - auto-push: 'true' + auto-push: 'false' # Re-apply git stash to prepare for saving back to cache. # Avoids exit code 1 by checking if there are changes to be stashed first From 55c0756a2e3d05fdcc8fcf9a38774900fbfbc3b8 Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Sun, 27 Apr 2025 04:39:57 +0700 Subject: [PATCH 16/22] Create devcontainer.json Signed-off-by: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> --- .devcontainer/devcontainer.json | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000000..39bbd2681d7 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,4 @@ +{ + "image": "mcr.microsoft.com/devcontainers/universal:2", + "features": {} +} From 379b494c6a5e1a07637fda865ab3ead66e5cb0ef Mon Sep 17 00:00:00 2001 From: AU_gdev_19 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 28 Apr 2025 11:13:41 +0700 Subject: [PATCH 17/22] Update issue templates (#119) --- .github/ISSUE_TEMPLATE/bug_report.md | 38 +++++++++++++++++++ .github/ISSUE_TEMPLATE/custom.md | 10 +++++ .github/ISSUE_TEMPLATE/feature_request.md | 20 ++++++++++ .github/ISSUE_TEMPLATE/general.md | 3 ++ .../package--ethereumjs-binarytree.md | 5 ++- .../package--ethereumjs-block.md | 5 ++- .../package--ethereumjs-blockchain.md | 5 ++- .../package--ethereumjs-client.md | 5 ++- .../package--ethereumjs-common.md | 5 ++- .../package--ethereumjs-devp2p.md | 5 ++- .../package--ethereumjs-ethash.md | 5 ++- .../ISSUE_TEMPLATE/package--ethereumjs-evm.md | 5 ++- .../ISSUE_TEMPLATE/package--ethereumjs-mpt.md | 5 ++- .../package--ethereumjs-statemanager.md | 5 ++- .../ISSUE_TEMPLATE/package--ethereumjs-tx.md | 5 ++- .../package--ethereumjs-util.md | 5 ++- .../package--ethereumjs-verkle.md | 5 ++- .../ISSUE_TEMPLATE/package--ethereumjs-vm.md | 5 ++- .github/ISSUE_TEMPLATE/package--monorepo.md | 5 ++- .github/ISSUE_TEMPLATE/package--rlp.md | 5 ++- 20 files changed, 135 insertions(+), 16 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/custom.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000000..dd84ea7824f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,38 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. iOS] + - Browser [e.g. chrome, safari] + - Version [e.g. 22] + +**Smartphone (please complete the following information):** + - Device: [e.g. iPhone6] + - OS: [e.g. iOS8.1] + - Browser [e.g. stock browser, safari] + - Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md new file mode 100644 index 00000000000..48d5f81fa42 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -0,0 +1,10 @@ +--- +name: Custom issue template +about: Describe this issue template's purpose here. +title: '' +labels: '' +assignees: '' + +--- + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000000..bbcbbe7d615 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/general.md b/.github/ISSUE_TEMPLATE/general.md index 4d2162ca4d3..a57d7dc41f6 100644 --- a/.github/ISSUE_TEMPLATE/general.md +++ b/.github/ISSUE_TEMPLATE/general.md @@ -4,4 +4,7 @@ about: Open blank issue title: '' labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-binarytree.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-binarytree.md index 403c1f82a3a..0c2e00b9258 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-binarytree.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-binarytree.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/binarytree' about: Create issue for @ethereumjs/binarytree package title: '' -labels: 'package: binarytree' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-block.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-block.md index 2f1dc84e205..1c6081233a9 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-block.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-block.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/block' about: Create issue for @ethereumjs/block title: '' -labels: 'package: block' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-blockchain.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-blockchain.md index c0bda30bfa1..c54aac9ea1b 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-blockchain.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-blockchain.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/blockchain' about: Create issue for @ethereumjs/blockchain package title: '' -labels: 'package: blockchain' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-client.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-client.md index a1c7fbdb400..136d2033749 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-client.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-client.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/client' about: Create issue for @ethereumjs/client title: '' -labels: 'package: client' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-common.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-common.md index 160ffdbb249..2eadc33b00c 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-common.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-common.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/common' about: Create issue for @ethereumjs/common package title: '' -labels: 'package: common' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-devp2p.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-devp2p.md index 59a0d64c163..91a8d97dbcc 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-devp2p.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-devp2p.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/devp2p' about: Create issue for @ethereumjs/devp2p title: '' -labels: 'package: devp2p' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-ethash.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-ethash.md index 91fe5070d25..16e1fac1103 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-ethash.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-ethash.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/ethash' about: Create issue for @ethereumjs/ethash title: '' -labels: 'package: ethash' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-evm.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-evm.md index a5a4a1b145a..b85e916cea9 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-evm.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-evm.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/evm' about: Create issue for @ethereumjs/evm package title: '' -labels: 'package: evm' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-mpt.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-mpt.md index e1ab99c688e..d746fb9fe03 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-mpt.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-mpt.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/mpt' about: Create issue for @ethereumjs/mpt package title: '' -labels: 'package: mpt' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-statemanager.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-statemanager.md index 5446af1f114..59d1b99a57b 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-statemanager.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-statemanager.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/statemanager' about: Create issue for @ethereumjs/statemanager title: '' -labels: 'package: statemanager' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-tx.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-tx.md index 3249e0203eb..2340cb3f551 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-tx.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-tx.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/tx' about: Create issue for @ethereumjs/tx package title: '' -labels: 'package: tx' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-util.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-util.md index 0875544bd30..fed0de8c55f 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-util.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-util.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/util' about: Create issue for @ethereumjs/util package title: '' -labels: 'package: util' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-verkle.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-verkle.md index fbe58a562d8..5d7fd303f5d 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-verkle.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-verkle.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/verkle' about: Create issue for @ethereumjs/verkle package title: '' -labels: 'package: verkle' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--ethereumjs-vm.md b/.github/ISSUE_TEMPLATE/package--ethereumjs-vm.md index 42d8feba617..3835e8bb6ae 100644 --- a/.github/ISSUE_TEMPLATE/package--ethereumjs-vm.md +++ b/.github/ISSUE_TEMPLATE/package--ethereumjs-vm.md @@ -2,6 +2,9 @@ name: 'Package: @ethereumjs/vm' about: Create issue for @ethereumjs/vm package title: '' -labels: 'package: vm' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--monorepo.md b/.github/ISSUE_TEMPLATE/package--monorepo.md index 8ffedbb6f97..d8dc1826c2e 100644 --- a/.github/ISSUE_TEMPLATE/package--monorepo.md +++ b/.github/ISSUE_TEMPLATE/package--monorepo.md @@ -2,6 +2,9 @@ name: 'Package: Monorepo' about: Create a monorepo-wide issue (e.g. on CI or docs) title: '' -labels: 'package: monorepo' +labels: '' assignees: '' + --- + + diff --git a/.github/ISSUE_TEMPLATE/package--rlp.md b/.github/ISSUE_TEMPLATE/package--rlp.md index 7f1793e8c6e..bc9961bfa13 100644 --- a/.github/ISSUE_TEMPLATE/package--rlp.md +++ b/.github/ISSUE_TEMPLATE/package--rlp.md @@ -2,6 +2,9 @@ name: 'Package: rlp' about: Create issue for rlp package title: '' -labels: 'package: rlp' +labels: '' assignees: '' + --- + + From 78bcd0980a4ff8d76da74529157988bb31263a51 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 2 May 2025 09:24:55 +0700 Subject: [PATCH 18/22] build(deps-dev): bump vite in the npm_and_yarn group across 1 directory (#120) Bumps the npm_and_yarn group with 1 update in the / directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite). Updates `vite` from 6.3.3 to 6.3.4 - [Release notes](https://github.com/vitejs/vite/releases) - [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md) - [Commits](https://github.com/vitejs/vite/commits/v6.3.4/packages/vite) --- updated-dependencies: - dependency-name: vite dependency-version: 6.3.4 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index f31a6946e7c..2bddbd458a6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16323,9 +16323,9 @@ } }, "node_modules/vite": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.3.tgz", - "integrity": "sha512-5nXH+QsELbFKhsEfWLkHrvgRpTdGJzqOZ+utSdmPTvwHmvU6ITTm3xx+mRusihkcI8GeC7lCDyn3kDtiki9scw==", + "version": "6.3.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.4.tgz", + "integrity": "sha512-BiReIiMS2fyFqbqNT/Qqt4CVITDU9M9vE+DKcVAsB+ZV0wvTKd+3hMbkpxz1b+NmEDMegpVbisKiAZOnvO92Sw==", "dev": true, "license": "MIT", "dependencies": { From c3b1f30132dd171be632ac2f37ff919a4857f03a Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:09:58 +0000 Subject: [PATCH 19/22] Update devcontainer.json (#241) Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- .devcontainer/devcontainer.json | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 39bbd2681d7..058cb8e06f4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,4 +1,22 @@ { - "image": "mcr.microsoft.com/devcontainers/universal:2", - "features": {} + "name": "Hardhat", + "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "features": { + "ghcr.io/devcontainers/features/node:1": { + "version": "18" + } + }, + "postCreateCommand": "scripts/setup.sh", + "containerEnv": { + "ALCHEMY_URL": "${localEnv:ALCHEMY_URL}", + "INFURA_URL": "${localEnv:INFURA_URL}" + }, + "customizations": { + "vscode": { + "extensions": [ + "esbenp.prettier-vscode", + "NomicFoundation.hardhat-solidity" + ] + } + } } From 5044789cadf473a4066262e7a6e4815cdb8b7b1a Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Tue, 21 Oct 2025 15:13:28 +0000 Subject: [PATCH 20/22] Update .github/workflows/mdbook.yml Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- .github/workflows/mdbook.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/mdbook.yml b/.github/workflows/mdbook.yml index 109cc83360a..d2160bb53d3 100644 --- a/.github/workflows/mdbook.yml +++ b/.github/workflows/mdbook.yml @@ -41,7 +41,9 @@ jobs: id: pages uses: actions/configure-pages@v5 - name: Build with mdBook - run: mdbook build + run: | + export PATH="$HOME/.cargo/bin:$PATH" + mdbook build - name: Upload artifact uses: actions/upload-pages-artifact@v3 with: From 21d6a03a829da29748a97a3a6a4317159e00df27 Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 26 Jan 2026 03:41:32 +0700 Subject: [PATCH 21/22] Update .github/ISSUE_TEMPLATE/bug_report.md Co-authored-by: sourcery-ai[bot] <58596630+sourcery-ai[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea7824f..59cbfced368 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -29,7 +29,7 @@ If applicable, add screenshots to help explain your problem. - Version [e.g. 22] **Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] + - Device: [e.g. iPhone 6] - OS: [e.g. iOS8.1] - Browser [e.g. stock browser, safari] - Version [e.g. 22] From a4e7e0128c4f3d43a7099cf021326302ca0399ce Mon Sep 17 00:00:00 2001 From: Dargon789 <64915515+Dargon789@users.noreply.github.com> Date: Mon, 26 Jan 2026 03:41:56 +0700 Subject: [PATCH 22/22] Update .devcontainer/devcontainer.json Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> Signed-off-by: Dargon789 <64915515+Dargon789@users.noreply.github.com> --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 058cb8e06f4..e15aace5b22 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,6 +1,6 @@ { "name": "Hardhat", - "image": "mcr.microsoft.com/devcontainers/base:bullseye", + "image": "mcr.microsoft.com/devcontainers/base:1-bullseye", "features": { "ghcr.io/devcontainers/features/node:1": { "version": "18"